| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 #ifndef SkPathOpsTypes_DEFINED | 7 #ifndef SkPathOpsTypes_DEFINED |
| 8 #define SkPathOpsTypes_DEFINED | 8 #define SkPathOpsTypes_DEFINED |
| 9 | 9 |
| 10 #include <float.h> // for FLT_EPSILON | 10 #include <float.h> // for FLT_EPSILON |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 int UlpsDistance(float a, float b); | 78 int UlpsDistance(float a, float b); |
| 79 inline int UlpsDistance(double a, double b) { | 79 inline int UlpsDistance(double a, double b) { |
| 80 return UlpsDistance(SkDoubleToScalar(a), SkDoubleToScalar(b)); | 80 return UlpsDistance(SkDoubleToScalar(a), SkDoubleToScalar(b)); |
| 81 } | 81 } |
| 82 | 82 |
| 83 // FLT_EPSILON == 1.19209290E-07 == 1 / (2 ^ 23) | 83 // FLT_EPSILON == 1.19209290E-07 == 1 / (2 ^ 23) |
| 84 // DBL_EPSILON == 2.22045e-16 | 84 // DBL_EPSILON == 2.22045e-16 |
| 85 const double FLT_EPSILON_CUBED = FLT_EPSILON * FLT_EPSILON * FLT_EPSILON; | 85 const double FLT_EPSILON_CUBED = FLT_EPSILON * FLT_EPSILON * FLT_EPSILON; |
| 86 const double FLT_EPSILON_HALF = FLT_EPSILON / 2; | 86 const double FLT_EPSILON_HALF = FLT_EPSILON / 2; |
| 87 const double FLT_EPSILON_DOUBLE = FLT_EPSILON * 2; | 87 const double FLT_EPSILON_DOUBLE = FLT_EPSILON * 2; |
| 88 const double FLT_EPSILON_ORDERABLE_ERR = FLT_EPSILON * 16; |
| 88 const double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON; | 89 const double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON; |
| 89 const double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON); | 90 const double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON); |
| 90 const double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON; | 91 const double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON; |
| 91 const double DBL_EPSILON_ERR = DBL_EPSILON * 4; // FIXME: tune -- allow a few b
its of error | 92 const double DBL_EPSILON_ERR = DBL_EPSILON * 4; // FIXME: tune -- allow a few b
its of error |
| 92 const double DBL_EPSILON_SUBDIVIDE_ERR = DBL_EPSILON * 16; | 93 const double DBL_EPSILON_SUBDIVIDE_ERR = DBL_EPSILON * 16; |
| 93 const double ROUGH_EPSILON = FLT_EPSILON * 64; | 94 const double ROUGH_EPSILON = FLT_EPSILON * 64; |
| 94 const double MORE_ROUGH_EPSILON = FLT_EPSILON * 256; | 95 const double MORE_ROUGH_EPSILON = FLT_EPSILON * 256; |
| 95 | 96 |
| 96 inline bool approximately_zero(double x) { | 97 inline bool approximately_zero(double x) { |
| 97 return fabs(x) < FLT_EPSILON; | 98 return fabs(x) < FLT_EPSILON; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 114 } | 115 } |
| 115 | 116 |
| 116 inline bool approximately_zero_half(double x) { | 117 inline bool approximately_zero_half(double x) { |
| 117 return fabs(x) < FLT_EPSILON_HALF; | 118 return fabs(x) < FLT_EPSILON_HALF; |
| 118 } | 119 } |
| 119 | 120 |
| 120 inline bool approximately_zero_double(double x) { | 121 inline bool approximately_zero_double(double x) { |
| 121 return fabs(x) < FLT_EPSILON_DOUBLE; | 122 return fabs(x) < FLT_EPSILON_DOUBLE; |
| 122 } | 123 } |
| 123 | 124 |
| 125 inline bool approximately_zero_orderable(double x) { |
| 126 return fabs(x) < FLT_EPSILON_ORDERABLE_ERR; |
| 127 } |
| 128 |
| 124 inline bool approximately_zero_squared(double x) { | 129 inline bool approximately_zero_squared(double x) { |
| 125 return fabs(x) < FLT_EPSILON_SQUARED; | 130 return fabs(x) < FLT_EPSILON_SQUARED; |
| 126 } | 131 } |
| 127 | 132 |
| 128 inline bool approximately_zero_sqrt(double x) { | 133 inline bool approximately_zero_sqrt(double x) { |
| 129 return fabs(x) < FLT_EPSILON_SQRT; | 134 return fabs(x) < FLT_EPSILON_SQRT; |
| 130 } | 135 } |
| 131 | 136 |
| 132 inline bool roughly_zero(double x) { | 137 inline bool roughly_zero(double x) { |
| 133 return fabs(x) < ROUGH_EPSILON; | 138 return fabs(x) < ROUGH_EPSILON; |
| 134 } | 139 } |
| 135 | 140 |
| 136 inline bool approximately_zero_inverse(double x) { | 141 inline bool approximately_zero_inverse(double x) { |
| 137 return fabs(x) > FLT_EPSILON_INVERSE; | 142 return fabs(x) > FLT_EPSILON_INVERSE; |
| 138 } | 143 } |
| 139 | 144 |
| 140 // OPTIMIZATION: if called multiple times with the same denom, we want to pass 1
/y instead | 145 // OPTIMIZATION: if called multiple times with the same denom, we want to pass 1
/y instead |
| 141 inline bool approximately_zero_when_compared_to(double x, double y) { | 146 inline bool approximately_zero_when_compared_to(double x, double y) { |
| 142 return x == 0 || fabs(x / y) < FLT_EPSILON; | 147 return x == 0 || fabs(x) < fabs(y * FLT_EPSILON); |
| 143 } | 148 } |
| 144 | 149 |
| 145 // Use this for comparing Ts in the range of 0 to 1. For general numbers (larger
and smaller) use | 150 // Use this for comparing Ts in the range of 0 to 1. For general numbers (larger
and smaller) use |
| 146 // AlmostEqualUlps instead. | 151 // AlmostEqualUlps instead. |
| 147 inline bool approximately_equal(double x, double y) { | 152 inline bool approximately_equal(double x, double y) { |
| 148 return approximately_zero(x - y); | 153 return approximately_zero(x - y); |
| 149 } | 154 } |
| 150 | 155 |
| 151 inline bool precisely_equal(double x, double y) { | 156 inline bool precisely_equal(double x, double y) { |
| 152 return precisely_zero(x - y); | 157 return precisely_zero(x - y); |
| 153 } | 158 } |
| 154 | 159 |
| 155 inline bool precisely_subdivide_equal(double x, double y) { | 160 inline bool precisely_subdivide_equal(double x, double y) { |
| 156 return precisely_subdivide_zero(x - y); | 161 return precisely_subdivide_zero(x - y); |
| 157 } | 162 } |
| 158 | 163 |
| 159 inline bool approximately_equal_half(double x, double y) { | 164 inline bool approximately_equal_half(double x, double y) { |
| 160 return approximately_zero_half(x - y); | 165 return approximately_zero_half(x - y); |
| 161 } | 166 } |
| 162 | 167 |
| 163 inline bool approximately_equal_double(double x, double y) { | 168 inline bool approximately_equal_double(double x, double y) { |
| 164 return approximately_zero_double(x - y); | 169 return approximately_zero_double(x - y); |
| 165 } | 170 } |
| 166 | 171 |
| 172 inline bool approximately_equal_orderable(double x, double y) { |
| 173 return approximately_zero_orderable(x - y); |
| 174 } |
| 175 |
| 167 inline bool approximately_equal_squared(double x, double y) { | 176 inline bool approximately_equal_squared(double x, double y) { |
| 168 return approximately_equal(x, y); | 177 return approximately_equal(x, y); |
| 169 } | 178 } |
| 170 | 179 |
| 171 inline bool approximately_greater(double x, double y) { | 180 inline bool approximately_greater(double x, double y) { |
| 172 return x - FLT_EPSILON >= y; | 181 return x - FLT_EPSILON >= y; |
| 173 } | 182 } |
| 174 | 183 |
| 184 inline bool approximately_greater_double(double x, double y) { |
| 185 return x - FLT_EPSILON_DOUBLE >= y; |
| 186 } |
| 187 |
| 188 inline bool approximately_greater_orderable(double x, double y) { |
| 189 return x - FLT_EPSILON_ORDERABLE_ERR >= y; |
| 190 } |
| 191 |
| 175 inline bool approximately_greater_or_equal(double x, double y) { | 192 inline bool approximately_greater_or_equal(double x, double y) { |
| 176 return x + FLT_EPSILON > y; | 193 return x + FLT_EPSILON > y; |
| 177 } | 194 } |
| 178 | 195 |
| 196 inline bool approximately_greater_or_equal_double(double x, double y) { |
| 197 return x + FLT_EPSILON_DOUBLE > y; |
| 198 } |
| 199 |
| 200 inline bool approximately_greater_or_equal_orderable(double x, double y) { |
| 201 return x + FLT_EPSILON_ORDERABLE_ERR > y; |
| 202 } |
| 203 |
| 179 inline bool approximately_lesser(double x, double y) { | 204 inline bool approximately_lesser(double x, double y) { |
| 180 return x + FLT_EPSILON <= y; | 205 return x + FLT_EPSILON <= y; |
| 181 } | 206 } |
| 182 | 207 |
| 208 inline bool approximately_lesser_double(double x, double y) { |
| 209 return x + FLT_EPSILON_DOUBLE <= y; |
| 210 } |
| 211 |
| 212 inline bool approximately_lesser_orderable(double x, double y) { |
| 213 return x + FLT_EPSILON_ORDERABLE_ERR <= y; |
| 214 } |
| 215 |
| 183 inline bool approximately_lesser_or_equal(double x, double y) { | 216 inline bool approximately_lesser_or_equal(double x, double y) { |
| 184 return x - FLT_EPSILON < y; | 217 return x - FLT_EPSILON < y; |
| 185 } | 218 } |
| 186 | 219 |
| 220 inline bool approximately_lesser_or_equal_double(double x, double y) { |
| 221 return x - FLT_EPSILON_DOUBLE < y; |
| 222 } |
| 223 |
| 224 inline bool approximately_lesser_or_equal_orderable(double x, double y) { |
| 225 return x - FLT_EPSILON_ORDERABLE_ERR < y; |
| 226 } |
| 227 |
| 187 inline bool approximately_greater_than_one(double x) { | 228 inline bool approximately_greater_than_one(double x) { |
| 188 return x > 1 - FLT_EPSILON; | 229 return x > 1 - FLT_EPSILON; |
| 189 } | 230 } |
| 190 | 231 |
| 191 inline bool precisely_greater_than_one(double x) { | 232 inline bool precisely_greater_than_one(double x) { |
| 192 return x > 1 - DBL_EPSILON_ERR; | 233 return x > 1 - DBL_EPSILON_ERR; |
| 193 } | 234 } |
| 194 | 235 |
| 195 inline bool approximately_less_than_zero(double x) { | 236 inline bool approximately_less_than_zero(double x) { |
| 196 return x < FLT_EPSILON; | 237 return x < FLT_EPSILON; |
| 197 } | 238 } |
| 198 | 239 |
| 199 inline bool precisely_less_than_zero(double x) { | 240 inline bool precisely_less_than_zero(double x) { |
| 200 return x < DBL_EPSILON_ERR; | 241 return x < DBL_EPSILON_ERR; |
| 201 } | 242 } |
| 202 | 243 |
| 203 inline bool approximately_negative(double x) { | 244 inline bool approximately_negative(double x) { |
| 204 return x < FLT_EPSILON; | 245 return x < FLT_EPSILON; |
| 205 } | 246 } |
| 206 | 247 |
| 248 inline bool approximately_negative_orderable(double x) { |
| 249 return x < FLT_EPSILON_ORDERABLE_ERR; |
| 250 } |
| 251 |
| 207 inline bool precisely_negative(double x) { | 252 inline bool precisely_negative(double x) { |
| 208 return x < DBL_EPSILON_ERR; | 253 return x < DBL_EPSILON_ERR; |
| 209 } | 254 } |
| 210 | 255 |
| 211 inline bool approximately_one_or_less(double x) { | 256 inline bool approximately_one_or_less(double x) { |
| 212 return x < 1 + FLT_EPSILON; | 257 return x < 1 + FLT_EPSILON; |
| 213 } | 258 } |
| 214 | 259 |
| 260 inline bool approximately_one_or_less_double(double x) { |
| 261 return x < 1 + FLT_EPSILON_DOUBLE; |
| 262 } |
| 263 |
| 215 inline bool approximately_positive(double x) { | 264 inline bool approximately_positive(double x) { |
| 216 return x > -FLT_EPSILON; | 265 return x > -FLT_EPSILON; |
| 217 } | 266 } |
| 218 | 267 |
| 219 inline bool approximately_positive_squared(double x) { | 268 inline bool approximately_positive_squared(double x) { |
| 220 return x > -(FLT_EPSILON_SQUARED); | 269 return x > -(FLT_EPSILON_SQUARED); |
| 221 } | 270 } |
| 222 | 271 |
| 223 inline bool approximately_zero_or_more(double x) { | 272 inline bool approximately_zero_or_more(double x) { |
| 224 return x > -FLT_EPSILON; | 273 return x > -FLT_EPSILON; |
| 225 } | 274 } |
| 226 | 275 |
| 276 inline bool approximately_zero_or_more_double(double x) { |
| 277 return x > -FLT_EPSILON_DOUBLE; |
| 278 } |
| 279 |
| 280 inline bool approximately_between_orderable(double a, double b, double c) { |
| 281 return a <= c |
| 282 ? approximately_negative_orderable(a - b) && approximately_negative_
orderable(b - c) |
| 283 : approximately_negative_orderable(b - a) && approximately_negative_
orderable(c - b); |
| 284 } |
| 285 |
| 227 inline bool approximately_between(double a, double b, double c) { | 286 inline bool approximately_between(double a, double b, double c) { |
| 228 return a <= c ? approximately_negative(a - b) && approximately_negative(b -
c) | 287 return a <= c ? approximately_negative(a - b) && approximately_negative(b -
c) |
| 229 : approximately_negative(b - a) && approximately_negative(c - b); | 288 : approximately_negative(b - a) && approximately_negative(c - b); |
| 230 } | 289 } |
| 231 | 290 |
| 232 inline bool precisely_between(double a, double b, double c) { | 291 inline bool precisely_between(double a, double b, double c) { |
| 233 return a <= c ? precisely_negative(a - b) && precisely_negative(b - c) | 292 return a <= c ? precisely_negative(a - b) && precisely_negative(b - c) |
| 234 : precisely_negative(b - a) && precisely_negative(c - b); | 293 : precisely_negative(b - a) && precisely_negative(c - b); |
| 235 } | 294 } |
| 236 | 295 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 /* Returns 1 if negative, 2 if zero, 4 if positive | 363 /* Returns 1 if negative, 2 if zero, 4 if positive |
| 305 */ | 364 */ |
| 306 inline int SkDSideBit(double x) { | 365 inline int SkDSideBit(double x) { |
| 307 return 1 << SKDSide(x); | 366 return 1 << SKDSide(x); |
| 308 } | 367 } |
| 309 | 368 |
| 310 inline double SkPinT(double t) { | 369 inline double SkPinT(double t) { |
| 311 return precisely_less_than_zero(t) ? 0 : precisely_greater_than_one(t) ? 1 :
t; | 370 return precisely_less_than_zero(t) ? 0 : precisely_greater_than_one(t) ? 1 :
t; |
| 312 } | 371 } |
| 313 | 372 |
| 314 #ifdef SK_DEBUG | |
| 315 inline void DebugDumpDouble(double x) { | |
| 316 if (x == floor(x)) { | |
| 317 SkDebugf("%.0f", x); | |
| 318 } else { | |
| 319 SkDebugf("%1.17g", x); | |
| 320 } | |
| 321 } | |
| 322 | |
| 323 inline void DebugDumpFloat(float x) { | |
| 324 if (x == floorf(x)) { | |
| 325 SkDebugf("%.0f", x); | |
| 326 } else { | |
| 327 SkDebugf("%1.9gf", x); | |
| 328 } | |
| 329 } | |
| 330 #endif | 373 #endif |
| 331 | |
| 332 #endif | |
| OLD | NEW |