Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2012 Google Inc. | |
| 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 #ifndef SkPathOpsTypes_DEFINED | |
| 8 #define SkPathOpsTypes_DEFINED | |
| 9 | |
| 10 #include <float.h> // for FLT_EPSILON | |
| 11 #include <math.h> // for fabs, sqrt | |
| 12 | |
| 13 #include "SkFloatingPoint.h" | |
| 14 #include "SkPathOpsDebug.h" | |
| 15 #include "SkScalar.h" | |
| 16 | |
| 17 // FIXME: move these into SkTypes.h | |
| 18 template <typename T> inline T SkTMax(T a, T b) { | |
| 19 if (a < b) | |
|
whunt
2013/03/22 18:16:06
min and max can be performance critical operations
caryclark
2013/03/22 19:38:51
Noted.
| |
| 20 a = b; | |
| 21 return a; | |
| 22 } | |
| 23 | |
| 24 template <typename T> inline T SkTMin(T a, T b) { | |
| 25 if (a > b) | |
| 26 a = b; | |
| 27 return a; | |
| 28 } | |
| 29 | |
| 30 // FIXME: move this into SkFloatingPoint.h | |
| 31 #define sk_double_isnan(a) sk_float_isnan(a) | |
| 32 | |
| 33 // FIXME: move this into SkPaths.h or just use the equivalent in SkRegion.h | |
| 34 enum SkPathOp { | |
| 35 kDifference_PathOp, //!< subtract the op region from the first region | |
| 36 kIntersect_PathOp, //!< intersect the two regions | |
| 37 kUnion_PathOp, //!< union (inclusive-or) the two regions | |
| 38 kXOR_PathOp, //!< exclusive-or the two regions | |
| 39 /** subtract the first region from the op region */ | |
| 40 kReverseDifference_PathOp, // FIXME: unsupported | |
| 41 kReplace_PathOp //!< replace the dst region with the op region FIXME: u nsupported | |
| 42 }; | |
| 43 | |
| 44 enum SkPathOpsMask { | |
| 45 kWinding_PathOpsMask = -1, | |
| 46 kNo_PathOpsMask = 0, | |
| 47 kEvenOdd_PathOpsMask = 1 | |
| 48 }; | |
| 49 | |
| 50 extern bool AlmostEqualUlps(float A, float B); | |
| 51 inline bool AlmostEqualUlps(double A, double B) { | |
| 52 return AlmostEqualUlps(SkDoubleToScalar(A), SkDoubleToScalar(B)); | |
| 53 } | |
| 54 | |
| 55 // FLT_EPSILON == 1.19209290E-07 == 1 / (2 ^ 23) | |
| 56 // DBL_EPSILON == 2.22045e-16 | |
| 57 const double FLT_EPSILON_CUBED = FLT_EPSILON * FLT_EPSILON * FLT_EPSILON; | |
| 58 const double FLT_EPSILON_HALF = FLT_EPSILON / 2; | |
| 59 const double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON; | |
| 60 const double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON); | |
| 61 const double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON; | |
| 62 const double DBL_EPSILON_ERR = DBL_EPSILON * 4; // FIXME: tune -- allow a few b its of error | |
| 63 const double ROUGH_EPSILON = FLT_EPSILON * 64; | |
| 64 const double MORE_ROUGH_EPSILON = FLT_EPSILON * 256; | |
| 65 | |
| 66 inline bool approximately_zero(double x) { | |
| 67 return fabs(x) < FLT_EPSILON; | |
| 68 } | |
| 69 | |
| 70 inline bool precisely_zero(double x) { | |
| 71 return fabs(x) < DBL_EPSILON_ERR; | |
| 72 } | |
| 73 | |
| 74 inline bool approximately_zero(float x) { | |
| 75 return fabs(x) < FLT_EPSILON; | |
| 76 } | |
| 77 | |
| 78 inline bool approximately_zero_cubed(double x) { | |
| 79 return fabs(x) < FLT_EPSILON_CUBED; | |
| 80 } | |
| 81 | |
| 82 inline bool approximately_zero_half(double x) { | |
| 83 return fabs(x) < FLT_EPSILON_HALF; | |
| 84 } | |
| 85 | |
| 86 inline bool approximately_zero_squared(double x) { | |
| 87 return fabs(x) < FLT_EPSILON_SQUARED; | |
| 88 } | |
| 89 | |
| 90 inline bool approximately_zero_sqrt(double x) { | |
| 91 return fabs(x) < FLT_EPSILON_SQRT; | |
| 92 } | |
| 93 | |
| 94 inline bool approximately_zero_inverse(double x) { | |
| 95 return fabs(x) > FLT_EPSILON_INVERSE; | |
| 96 } | |
| 97 | |
| 98 // OPTIMIZATION: if called multiple times with the same denom, we want to pass 1 /y instead | |
| 99 inline bool approximately_zero_when_compared_to(double x, double y) { | |
| 100 return x == 0 || fabs(x / y) < FLT_EPSILON; | |
| 101 } | |
| 102 | |
| 103 // Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use | |
| 104 // AlmostEqualUlps instead. | |
| 105 inline bool approximately_equal(double x, double y) { | |
| 106 return approximately_zero(x - y); | |
| 107 } | |
| 108 | |
| 109 inline bool precisely_equal(double x, double y) { | |
| 110 return precisely_zero(x - y); | |
| 111 } | |
| 112 | |
| 113 inline bool approximately_equal_half(double x, double y) { | |
| 114 return approximately_zero_half(x - y); | |
| 115 } | |
| 116 | |
| 117 inline bool approximately_equal_squared(double x, double y) { | |
| 118 return approximately_equal(x, y); | |
| 119 } | |
| 120 | |
| 121 inline bool approximately_greater(double x, double y) { | |
| 122 return x - FLT_EPSILON >= y; | |
| 123 } | |
| 124 | |
| 125 inline bool approximately_greater_or_equal(double x, double y) { | |
| 126 return x + FLT_EPSILON > y; | |
| 127 } | |
| 128 | |
| 129 inline bool approximately_lesser(double x, double y) { | |
| 130 return x + FLT_EPSILON <= y; | |
| 131 } | |
| 132 | |
| 133 inline bool approximately_lesser_or_equal(double x, double y) { | |
| 134 return x - FLT_EPSILON < y; | |
| 135 } | |
| 136 | |
| 137 inline double approximately_pin(double x) { | |
| 138 return approximately_zero(x) ? 0 : x; | |
| 139 } | |
| 140 | |
| 141 inline float approximately_pin(float x) { | |
| 142 return approximately_zero(x) ? 0 : x; | |
| 143 } | |
| 144 | |
| 145 inline bool approximately_greater_than_one(double x) { | |
| 146 return x > 1 - FLT_EPSILON; | |
| 147 } | |
| 148 | |
| 149 inline bool precisely_greater_than_one(double x) { | |
| 150 return x > 1 - DBL_EPSILON_ERR; | |
| 151 } | |
| 152 | |
| 153 inline bool approximately_less_than_zero(double x) { | |
| 154 return x < FLT_EPSILON; | |
| 155 } | |
| 156 | |
| 157 inline bool precisely_less_than_zero(double x) { | |
| 158 return x < DBL_EPSILON_ERR; | |
| 159 } | |
| 160 | |
| 161 inline bool approximately_negative(double x) { | |
| 162 return x < FLT_EPSILON; | |
| 163 } | |
| 164 | |
| 165 inline bool precisely_negative(double x) { | |
| 166 return x < DBL_EPSILON_ERR; | |
| 167 } | |
| 168 | |
| 169 inline bool approximately_one_or_less(double x) { | |
| 170 return x < 1 + FLT_EPSILON; | |
| 171 } | |
| 172 | |
| 173 inline bool approximately_positive(double x) { | |
| 174 return x > -FLT_EPSILON; | |
| 175 } | |
| 176 | |
| 177 inline bool approximately_positive_squared(double x) { | |
| 178 return x > -(FLT_EPSILON_SQUARED); | |
| 179 } | |
| 180 | |
| 181 inline bool approximately_zero_or_more(double x) { | |
| 182 return x > -FLT_EPSILON; | |
| 183 } | |
| 184 | |
| 185 inline bool approximately_between(double a, double b, double c) { | |
| 186 return a <= c ? approximately_negative(a - b) && approximately_negative(b - c) | |
| 187 : approximately_negative(b - a) && approximately_negative(c - b); | |
| 188 } | |
| 189 | |
| 190 // returns true if (a <= b <= c) || (a >= b >= c) | |
| 191 inline bool between(double a, double b, double c) { | |
| 192 SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0)); | |
| 193 return (a - b) * (c - b) <= 0; | |
| 194 } | |
| 195 | |
| 196 inline bool more_roughly_equal(double x, double y) { | |
| 197 return fabs(x - y) < MORE_ROUGH_EPSILON; | |
| 198 } | |
| 199 | |
| 200 inline bool roughly_equal(double x, double y) { | |
| 201 return fabs(x - y) < ROUGH_EPSILON; | |
| 202 } | |
| 203 | |
| 204 struct SkDPoint; | |
| 205 struct SkDVector; | |
| 206 struct SkDLine; | |
| 207 struct SkDQuad; | |
| 208 struct SkDTriangle; | |
| 209 struct SkDCubic; | |
| 210 struct SkDRect; | |
| 211 | |
| 212 inline double SkDInterp(double A, double B, double t) { | |
| 213 return A + (B - A) * t; | |
| 214 } | |
| 215 | |
| 216 double SkDCubeRoot(double x); | |
| 217 | |
| 218 /* Returns -1 if negative, 0 if zero, 1 if positive | |
| 219 */ | |
| 220 inline int SkDSign(double x) { | |
| 221 return (x > 0) - (x < 0); | |
| 222 } | |
| 223 | |
| 224 /* Returns 0 if negative, 1 if zero, 2 if positive | |
| 225 */ | |
| 226 inline int SKDSide(double x) { | |
| 227 return (x > 0) + (x >= 0); | |
| 228 } | |
| 229 | |
| 230 /* Returns 1 if negative, 2 if zero, 4 if positive | |
| 231 */ | |
| 232 inline int SkDSideBit(double x) { | |
| 233 return 1 << SKDSide(x); | |
| 234 } | |
| 235 | |
| 236 /* Given the set [0, 1, 2, 3], and two of the four members, compute an XOR mask | |
| 237 that computes the other two. Note that: | |
| 238 | |
| 239 one ^ two == 3 for (0, 3), (1, 2) | |
| 240 one ^ two < 3 for (0, 1), (0, 2), (1, 3), (2, 3) | |
| 241 3 - (one ^ two) is either 0, 1, or 2 | |
| 242 1 >> 3 - (one ^ two) is either 0 or 1 | |
| 243 thus: | |
| 244 returned == 2 for (0, 3), (1, 2) | |
| 245 returned == 3 for (0, 1), (0, 2), (1, 3), (2, 3) | |
| 246 given that: | |
| 247 (0, 3) ^ 2 -> (2, 1) (1, 2) ^ 2 -> (3, 0) | |
| 248 (0, 1) ^ 3 -> (3, 2) (0, 2) ^ 3 -> (3, 1) (1, 3) ^ 3 -> (2, 0) (2, 3) ^ 3 -> (1, 0) | |
| 249 */ | |
| 250 inline int SkOtherTwo(int one, int two) { | |
| 251 return 1 >> 3 - (one ^ two) ^ 3; | |
|
whunt
2013/03/22 18:16:06
I believe:
((one ^ two) & 1) + 1
will yield you th
caryclark
2013/03/22 19:38:51
This function is no longer used. It's been removed
whunt
2013/03/22 19:50:10
Sad =(, it was an interesting bit-twiddling proble
| |
| 252 } | |
| 253 | |
| 254 #endif | |
| OLD | NEW |