Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2008 The Android Open Source Project
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkMathPriv.h"
      9 #include "SkFixed.h"
     10 #include "SkFloatBits.h"
     11 #include "SkFloatingPoint.h"
     12 #include "SkScalar.h"
     13 
     14 #define sub_shift(zeros, x, n)  \
     15     zeros -= n;                 \
     16     x >>= n
     17 
     18 int SkCLZ_portable(uint32_t x) {
     19     if (x == 0) {
     20         return 32;
     21     }
     22 
     23     int zeros = 31;
     24     if (x & 0xFFFF0000) {
     25         sub_shift(zeros, x, 16);
     26     }
     27     if (x & 0xFF00) {
     28         sub_shift(zeros, x, 8);
     29     }
     30     if (x & 0xF0) {
     31         sub_shift(zeros, x, 4);
     32     }
     33     if (x & 0xC) {
     34         sub_shift(zeros, x, 2);
     35     }
     36     if (x & 0x2) {
     37         sub_shift(zeros, x, 1);
     38     }
     39 
     40     return zeros;
     41 }
     42 
     43 ///////////////////////////////////////////////////////////////////////////////
     44 
     45 /* www.worldserver.com/turk/computergraphics/FixedSqrt.pdf
     46 */
     47 int32_t SkSqrtBits(int32_t x, int count) {
     48     SkASSERT(x >= 0 && count > 0 && (unsigned)count <= 30);
     49 
     50     uint32_t    root = 0;
     51     uint32_t    remHi = 0;
     52     uint32_t    remLo = x;
     53 
     54     do {
     55         root <<= 1;
     56 
     57         remHi = (remHi<<2) | (remLo>>30);
     58         remLo <<= 2;
     59 
     60         uint32_t testDiv = (root << 1) + 1;
     61         if (remHi >= testDiv) {
     62             remHi -= testDiv;
     63             root++;
     64         }
     65     } while (--count >= 0);
     66 
     67     return root;
     68 }
     69 
     70 ///////////////////////////////////////////////////////////////////////////////
     71 
     72 float SkScalarSinCos(float radians, float* cosValue) {
     73     float sinValue = sk_float_sin(radians);
     74 
     75     if (cosValue) {
     76         *cosValue = sk_float_cos(radians);
     77         if (SkScalarNearlyZero(*cosValue)) {
     78             *cosValue = 0;
     79         }
     80     }
     81 
     82     if (SkScalarNearlyZero(sinValue)) {
     83         sinValue = 0;
     84     }
     85     return sinValue;
     86 }
     87