| 1 | /* | 
|---|
| 2 | * Copyright 2006 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 | #ifndef SkScalar_DEFINED | 
|---|
| 9 | #define SkScalar_DEFINED | 
|---|
| 10 |  | 
|---|
| 11 | #include "include/private/SkFloatingPoint.h" | 
|---|
| 12 |  | 
|---|
| 13 | #undef SK_SCALAR_IS_FLOAT | 
|---|
| 14 | #define SK_SCALAR_IS_FLOAT  1 | 
|---|
| 15 |  | 
|---|
| 16 | typedef float SkScalar; | 
|---|
| 17 |  | 
|---|
| 18 | #define SK_Scalar1                  1.0f | 
|---|
| 19 | #define SK_ScalarHalf               0.5f | 
|---|
| 20 | #define SK_ScalarSqrt2              SK_FloatSqrt2 | 
|---|
| 21 | #define SK_ScalarPI                 SK_FloatPI | 
|---|
| 22 | #define SK_ScalarTanPIOver8         0.414213562f | 
|---|
| 23 | #define SK_ScalarRoot2Over2         0.707106781f | 
|---|
| 24 | #define SK_ScalarMax                3.402823466e+38f | 
|---|
| 25 | #define SK_ScalarInfinity           SK_FloatInfinity | 
|---|
| 26 | #define SK_ScalarNegativeInfinity   SK_FloatNegativeInfinity | 
|---|
| 27 | #define SK_ScalarNaN                SK_FloatNaN | 
|---|
| 28 |  | 
|---|
| 29 | #define SkScalarFloorToScalar(x)    sk_float_floor(x) | 
|---|
| 30 | #define SkScalarCeilToScalar(x)     sk_float_ceil(x) | 
|---|
| 31 | #define SkScalarRoundToScalar(x)    sk_float_floor((x) + 0.5f) | 
|---|
| 32 | #define SkScalarTruncToScalar(x)    sk_float_trunc(x) | 
|---|
| 33 |  | 
|---|
| 34 | #define SkScalarFloorToInt(x)       sk_float_floor2int(x) | 
|---|
| 35 | #define SkScalarCeilToInt(x)        sk_float_ceil2int(x) | 
|---|
| 36 | #define SkScalarRoundToInt(x)       sk_float_round2int(x) | 
|---|
| 37 |  | 
|---|
| 38 | #define SkScalarAbs(x)              sk_float_abs(x) | 
|---|
| 39 | #define SkScalarCopySign(x, y)      sk_float_copysign(x, y) | 
|---|
| 40 | #define SkScalarMod(x, y)           sk_float_mod(x,y) | 
|---|
| 41 | #define SkScalarSqrt(x)             sk_float_sqrt(x) | 
|---|
| 42 | #define SkScalarPow(b, e)           sk_float_pow(b, e) | 
|---|
| 43 |  | 
|---|
| 44 | #define SkScalarSin(radians)        (float)sk_float_sin(radians) | 
|---|
| 45 | #define SkScalarCos(radians)        (float)sk_float_cos(radians) | 
|---|
| 46 | #define SkScalarTan(radians)        (float)sk_float_tan(radians) | 
|---|
| 47 | #define SkScalarASin(val)           (float)sk_float_asin(val) | 
|---|
| 48 | #define SkScalarACos(val)           (float)sk_float_acos(val) | 
|---|
| 49 | #define SkScalarATan2(y, x)         (float)sk_float_atan2(y,x) | 
|---|
| 50 | #define SkScalarExp(x)              (float)sk_float_exp(x) | 
|---|
| 51 | #define SkScalarLog(x)              (float)sk_float_log(x) | 
|---|
| 52 | #define SkScalarLog2(x)             (float)sk_float_log2(x) | 
|---|
| 53 |  | 
|---|
| 54 | ////////////////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| 55 |  | 
|---|
| 56 | #define SkIntToScalar(x)        static_cast<SkScalar>(x) | 
|---|
| 57 | #define SkIntToFloat(x)         static_cast<float>(x) | 
|---|
| 58 | #define SkScalarTruncToInt(x)   sk_float_saturate2int(x) | 
|---|
| 59 |  | 
|---|
| 60 | #define SkScalarToFloat(x)      static_cast<float>(x) | 
|---|
| 61 | #define SkFloatToScalar(x)      static_cast<SkScalar>(x) | 
|---|
| 62 | #define SkScalarToDouble(x)     static_cast<double>(x) | 
|---|
| 63 | #define SkDoubleToScalar(x)     sk_double_to_float(x) | 
|---|
| 64 |  | 
|---|
| 65 | #define SK_ScalarMin            (-SK_ScalarMax) | 
|---|
| 66 |  | 
|---|
| 67 | static inline bool SkScalarIsNaN(SkScalar x) { return x != x; } | 
|---|
| 68 |  | 
|---|
| 69 | /** Returns true if x is not NaN and not infinite | 
|---|
| 70 | */ | 
|---|
| 71 | static inline bool SkScalarIsFinite(SkScalar x) { return sk_float_isfinite(x); } | 
|---|
| 72 |  | 
|---|
| 73 | static inline bool SkScalarsAreFinite(SkScalar a, SkScalar b) { | 
|---|
| 74 | return sk_floats_are_finite(a, b); | 
|---|
| 75 | } | 
|---|
| 76 |  | 
|---|
| 77 | static inline bool SkScalarsAreFinite(const SkScalar array[], int count) { | 
|---|
| 78 | return sk_floats_are_finite(array, count); | 
|---|
| 79 | } | 
|---|
| 80 |  | 
|---|
| 81 | /** | 
|---|
| 82 | *  Variant of SkScalarRoundToInt, that performs the rounding step (adding 0.5) explicitly using | 
|---|
| 83 | *  double, to avoid possibly losing the low bit(s) of the answer before calling floor(). | 
|---|
| 84 | * | 
|---|
| 85 | *  This routine will likely be slower than SkScalarRoundToInt(), and should only be used when the | 
|---|
| 86 | *  extra precision is known to be valuable. | 
|---|
| 87 | * | 
|---|
| 88 | *  In particular, this catches the following case: | 
|---|
| 89 | *      SkScalar x = 0.49999997; | 
|---|
| 90 | *      int ix = SkScalarRoundToInt(x); | 
|---|
| 91 | *      SkASSERT(0 == ix);    // <--- fails | 
|---|
| 92 | *      ix = SkDScalarRoundToInt(x); | 
|---|
| 93 | *      SkASSERT(0 == ix);    // <--- succeeds | 
|---|
| 94 | */ | 
|---|
| 95 | static inline int SkDScalarRoundToInt(SkScalar x) { | 
|---|
| 96 | double xx = x; | 
|---|
| 97 | xx += 0.5; | 
|---|
| 98 | return (int)floor(xx); | 
|---|
| 99 | } | 
|---|
| 100 |  | 
|---|
| 101 | /** Returns the fractional part of the scalar. */ | 
|---|
| 102 | static inline SkScalar SkScalarFraction(SkScalar x) { | 
|---|
| 103 | return x - SkScalarTruncToScalar(x); | 
|---|
| 104 | } | 
|---|
| 105 |  | 
|---|
| 106 | static inline SkScalar SkScalarSquare(SkScalar x) { return x * x; } | 
|---|
| 107 |  | 
|---|
| 108 | #define SkScalarInvert(x)           sk_ieee_float_divide_TODO_IS_DIVIDE_BY_ZERO_SAFE_HERE(SK_Scalar1, (x)) | 
|---|
| 109 | #define SkScalarAve(a, b)           (((a) + (b)) * SK_ScalarHalf) | 
|---|
| 110 | #define SkScalarHalf(a)             ((a) * SK_ScalarHalf) | 
|---|
| 111 |  | 
|---|
| 112 | #define SkDegreesToRadians(degrees) ((degrees) * (SK_ScalarPI / 180)) | 
|---|
| 113 | #define SkRadiansToDegrees(radians) ((radians) * (180 / SK_ScalarPI)) | 
|---|
| 114 |  | 
|---|
| 115 | static inline bool SkScalarIsInt(SkScalar x) { | 
|---|
| 116 | return x == SkScalarFloorToScalar(x); | 
|---|
| 117 | } | 
|---|
| 118 |  | 
|---|
| 119 | /** | 
|---|
| 120 | *  Returns -1 || 0 || 1 depending on the sign of value: | 
|---|
| 121 | *  -1 if x < 0 | 
|---|
| 122 | *   0 if x == 0 | 
|---|
| 123 | *   1 if x > 0 | 
|---|
| 124 | */ | 
|---|
| 125 | static inline int SkScalarSignAsInt(SkScalar x) { | 
|---|
| 126 | return x < 0 ? -1 : (x > 0); | 
|---|
| 127 | } | 
|---|
| 128 |  | 
|---|
| 129 | // Scalar result version of above | 
|---|
| 130 | static inline SkScalar SkScalarSignAsScalar(SkScalar x) { | 
|---|
| 131 | return x < 0 ? -SK_Scalar1 : ((x > 0) ? SK_Scalar1 : 0); | 
|---|
| 132 | } | 
|---|
| 133 |  | 
|---|
| 134 | #define SK_ScalarNearlyZero         (SK_Scalar1 / (1 << 12)) | 
|---|
| 135 |  | 
|---|
| 136 | static inline bool SkScalarNearlyZero(SkScalar x, | 
|---|
| 137 | SkScalar tolerance = SK_ScalarNearlyZero) { | 
|---|
| 138 | SkASSERT(tolerance >= 0); | 
|---|
| 139 | return SkScalarAbs(x) <= tolerance; | 
|---|
| 140 | } | 
|---|
| 141 |  | 
|---|
| 142 | static inline bool SkScalarNearlyEqual(SkScalar x, SkScalar y, | 
|---|
| 143 | SkScalar tolerance = SK_ScalarNearlyZero) { | 
|---|
| 144 | SkASSERT(tolerance >= 0); | 
|---|
| 145 | return SkScalarAbs(x-y) <= tolerance; | 
|---|
| 146 | } | 
|---|
| 147 |  | 
|---|
| 148 | static inline float SkScalarSinSnapToZero(SkScalar radians) { | 
|---|
| 149 | float v = SkScalarSin(radians); | 
|---|
| 150 | return SkScalarNearlyZero(v) ? 0.0f : v; | 
|---|
| 151 | } | 
|---|
| 152 |  | 
|---|
| 153 | static inline float SkScalarCosSnapToZero(SkScalar radians) { | 
|---|
| 154 | float v = SkScalarCos(radians); | 
|---|
| 155 | return SkScalarNearlyZero(v) ? 0.0f : v; | 
|---|
| 156 | } | 
|---|
| 157 |  | 
|---|
| 158 | /** Linearly interpolate between A and B, based on t. | 
|---|
| 159 | If t is 0, return A | 
|---|
| 160 | If t is 1, return B | 
|---|
| 161 | else interpolate. | 
|---|
| 162 | t must be [0..SK_Scalar1] | 
|---|
| 163 | */ | 
|---|
| 164 | static inline SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t) { | 
|---|
| 165 | SkASSERT(t >= 0 && t <= SK_Scalar1); | 
|---|
| 166 | return A + (B - A) * t; | 
|---|
| 167 | } | 
|---|
| 168 |  | 
|---|
| 169 | /** Interpolate along the function described by (keys[length], values[length]) | 
|---|
| 170 | for the passed searchKey.  SearchKeys outside the range keys[0]-keys[Length] | 
|---|
| 171 | clamp to the min or max value.  This function was inspired by a desire | 
|---|
| 172 | to change the multiplier for thickness in fakeBold; therefore it assumes | 
|---|
| 173 | the number of pairs (length) will be small, and a linear search is used. | 
|---|
| 174 | Repeated keys are allowed for discontinuous functions (so long as keys is | 
|---|
| 175 | monotonically increasing), and if key is the value of a repeated scalar in | 
|---|
| 176 | keys, the first one will be used.  However, that may change if a binary | 
|---|
| 177 | search is used. | 
|---|
| 178 | */ | 
|---|
| 179 | SkScalar SkScalarInterpFunc(SkScalar searchKey, const SkScalar keys[], | 
|---|
| 180 | const SkScalar values[], int length); | 
|---|
| 181 |  | 
|---|
| 182 | /* | 
|---|
| 183 | *  Helper to compare an array of scalars. | 
|---|
| 184 | */ | 
|---|
| 185 | static inline bool SkScalarsEqual(const SkScalar a[], const SkScalar b[], int n) { | 
|---|
| 186 | SkASSERT(n >= 0); | 
|---|
| 187 | for (int i = 0; i < n; ++i) { | 
|---|
| 188 | if (a[i] != b[i]) { | 
|---|
| 189 | return false; | 
|---|
| 190 | } | 
|---|
| 191 | } | 
|---|
| 192 | return true; | 
|---|
| 193 | } | 
|---|
| 194 |  | 
|---|
| 195 | #endif | 
|---|
| 196 |  | 
|---|