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 "SkSafeMath.h"
     13 #include "SkScalar.h"
     14 
     15 #define sub_shift(zeros, x, n)  \
     16     zeros -= n;                 \
     17     x >>= n
     18 
     19 int SkCLZ_portable(uint32_t x) {
     20     if (x == 0) {
     21         return 32;
     22     }
     23 
     24     int zeros = 31;
     25     if (x & 0xFFFF0000) {
     26         sub_shift(zeros, x, 16);
     27     }
     28     if (x & 0xFF00) {
     29         sub_shift(zeros, x, 8);
     30     }
     31     if (x & 0xF0) {
     32         sub_shift(zeros, x, 4);
     33     }
     34     if (x & 0xC) {
     35         sub_shift(zeros, x, 2);
     36     }
     37     if (x & 0x2) {
     38         sub_shift(zeros, x, 1);
     39     }
     40 
     41     return zeros;
     42 }
     43 
     44 ///////////////////////////////////////////////////////////////////////////////
     45 
     46 /* www.worldserver.com/turk/computergraphics/FixedSqrt.pdf
     47 */
     48 int32_t SkSqrtBits(int32_t x, int count) {
     49     SkASSERT(x >= 0 && count > 0 && (unsigned)count <= 30);
     50 
     51     uint32_t    root = 0;
     52     uint32_t    remHi = 0;
     53     uint32_t    remLo = x;
     54 
     55     do {
     56         root <<= 1;
     57 
     58         remHi = (remHi<<2) | (remLo>>30);
     59         remLo <<= 2;
     60 
     61         uint32_t testDiv = (root << 1) + 1;
     62         if (remHi >= testDiv) {
     63             remHi -= testDiv;
     64             root++;
     65         }
     66     } while (--count >= 0);
     67 
     68     return root;
     69 }
     70 
     71 float SkScalarSinCos(float radians, float* cosValue) {
     72     float sinValue = sk_float_sin(radians);
     73 
     74     if (cosValue) {
     75         *cosValue = sk_float_cos(radians);
     76         if (SkScalarNearlyZero(*cosValue)) {
     77             *cosValue = 0;
     78         }
     79     }
     80 
     81     if (SkScalarNearlyZero(sinValue)) {
     82         sinValue = 0;
     83     }
     84     return sinValue;
     85 }
     86 
     87 ///////////////////////////////////////////////////////////////////////////////////////////////////
     88 
     89 size_t SkSafeMath::Add(size_t x, size_t y) {
     90     SkSafeMath tmp;
     91     size_t sum = tmp.add(x, y);
     92     return tmp.ok() ? sum : SK_MaxSizeT;
     93 }
     94 
     95 size_t SkSafeMath::Mul(size_t x, size_t y) {
     96     SkSafeMath tmp;
     97     size_t prod = tmp.mul(x, y);
     98     return tmp.ok() ? prod : SK_MaxSizeT;
     99 }
    100