Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: src/pathops/SkPathOpsTypes.h

Issue 1002693002: pathops version two (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix arm 64 inspired coincident handling Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pathops/SkPathOpsTriangle.cpp ('k') | src/pathops/SkQuarticRoot.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 #include <math.h> // for fabs, sqrt 11 #include <math.h> // for fabs, sqrt
12 12
13 #include "SkFloatingPoint.h" 13 #include "SkFloatingPoint.h"
14 #include "SkPath.h" 14 #include "SkPath.h"
15 #include "SkPathOps.h" 15 #include "SkPathOps.h"
16 #include "SkPathOpsDebug.h" 16 #include "SkPathOpsDebug.h"
17 #include "SkScalar.h" 17 #include "SkScalar.h"
18 18
19 enum SkPathOpsMask { 19 enum SkPathOpsMask {
20 kWinding_PathOpsMask = -1, 20 kWinding_PathOpsMask = -1,
21 kNo_PathOpsMask = 0, 21 kNo_PathOpsMask = 0,
22 kEvenOdd_PathOpsMask = 1 22 kEvenOdd_PathOpsMask = 1
23 }; 23 };
24 24
25 class SkOpCoincidence;
26 class SkOpContour;
27
28 class SkOpGlobalState {
29 public:
30 SkOpGlobalState(SkOpCoincidence* coincidence PATH_OPS_DEBUG_PARAMS(SkOpCont our* head))
31 : fCoincidence(coincidence)
32 , fWindingFailed(false)
33 , fAngleCoincidence(false)
34 #if DEBUG_VALIDATE
35 , fPhase(kIntersecting)
36 #endif
37 PATH_OPS_DEBUG_PARAMS(fHead(head))
38 PATH_OPS_DEBUG_PARAMS(fAngleID(0))
39 PATH_OPS_DEBUG_PARAMS(fContourID(0))
40 PATH_OPS_DEBUG_PARAMS(fPtTID(0))
41 PATH_OPS_DEBUG_PARAMS(fSegmentID(0))
42 PATH_OPS_DEBUG_PARAMS(fSpanID(0)) {
43 }
44
45 #if DEBUG_VALIDATE
46 enum Phase {
47 kIntersecting,
48 kWalking
49 };
50 #endif
51
52 bool angleCoincidence() {
53 return fAngleCoincidence;
54 }
55
56 SkOpCoincidence* coincidence() {
57 return fCoincidence;
58 }
59
60 #ifdef SK_DEBUG
61 const struct SkOpAngle* debugAngle(int id) const;
62 SkOpContour* debugContour(int id);
63 const class SkOpPtT* debugPtT(int id) const;
64 const class SkOpSegment* debugSegment(int id) const;
65 const class SkOpSpanBase* debugSpan(int id) const;
66
67 int nextAngleID() {
68 return ++fAngleID;
69 }
70
71 int nextContourID() {
72 return ++fContourID;
73 }
74 int nextPtTID() {
75 return ++fPtTID;
76 }
77
78 int nextSegmentID() {
79 return ++fSegmentID;
80 }
81
82 int nextSpanID() {
83 return ++fSpanID;
84 }
85 #endif
86
87 #if DEBUG_VALIDATE
88 Phase phase() const {
89 return fPhase;
90 }
91 #endif
92
93 void setAngleCoincidence() {
94 fAngleCoincidence = true;
95 }
96
97 #if DEBUG_VALIDATE
98 void setPhase(Phase phase) {
99 SkASSERT(fPhase != phase);
100 fPhase = phase;
101 }
102 #endif
103
104 // called in very rare cases where angles are sorted incorrectly -- signfies op will fail
105 void setWindingFailed() {
106 fWindingFailed = true;
107 }
108
109 bool windingFailed() const {
110 return fWindingFailed;
111 }
112
113 private:
114 SkOpCoincidence* fCoincidence;
115 bool fWindingFailed;
116 bool fAngleCoincidence;
117 #if DEBUG_VALIDATE
118 Phase fPhase;
119 #endif
120 #ifdef SK_DEBUG
121 SkOpContour* fHead;
122 int fAngleID;
123 int fContourID;
124 int fPtTID;
125 int fSegmentID;
126 int fSpanID;
127 #endif
128 };
129
25 // Use Almost Equal when comparing coordinates. Use epsilon to compare T values. 130 // Use Almost Equal when comparing coordinates. Use epsilon to compare T values.
26 bool AlmostEqualUlps(float a, float b); 131 bool AlmostEqualUlps(float a, float b);
27 inline bool AlmostEqualUlps(double a, double b) { 132 inline bool AlmostEqualUlps(double a, double b) {
28 return AlmostEqualUlps(SkDoubleToScalar(a), SkDoubleToScalar(b)); 133 return AlmostEqualUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
29 } 134 }
30 135
31 // Use Almost Dequal when comparing should not special case denormalized values. 136 // Use Almost Dequal when comparing should not special case denormalized values.
32 bool AlmostDequalUlps(float a, float b); 137 bool AlmostDequalUlps(float a, float b);
33 bool AlmostDequalUlps(double a, double b); 138 bool AlmostDequalUlps(double a, double b);
34 139
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 const double FLT_EPSILON_DOUBLE = FLT_EPSILON * 2; 190 const double FLT_EPSILON_DOUBLE = FLT_EPSILON * 2;
86 const double FLT_EPSILON_ORDERABLE_ERR = FLT_EPSILON * 16; 191 const double FLT_EPSILON_ORDERABLE_ERR = FLT_EPSILON * 16;
87 const double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON; 192 const double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON;
88 const double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON); 193 const double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON);
89 const double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON; 194 const double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON;
90 const double DBL_EPSILON_ERR = DBL_EPSILON * 4; // FIXME: tune -- allow a few b its of error 195 const double DBL_EPSILON_ERR = DBL_EPSILON * 4; // FIXME: tune -- allow a few b its of error
91 const double DBL_EPSILON_SUBDIVIDE_ERR = DBL_EPSILON * 16; 196 const double DBL_EPSILON_SUBDIVIDE_ERR = DBL_EPSILON * 16;
92 const double ROUGH_EPSILON = FLT_EPSILON * 64; 197 const double ROUGH_EPSILON = FLT_EPSILON * 64;
93 const double MORE_ROUGH_EPSILON = FLT_EPSILON * 256; 198 const double MORE_ROUGH_EPSILON = FLT_EPSILON * 256;
94 const double WAY_ROUGH_EPSILON = FLT_EPSILON * 2048; 199 const double WAY_ROUGH_EPSILON = FLT_EPSILON * 2048;
200 const double BUMP_EPSILON = FLT_EPSILON * 4096;
95 201
96 inline bool zero_or_one(double x) { 202 inline bool zero_or_one(double x) {
97 return x == 0 || x == 1; 203 return x == 0 || x == 1;
98 } 204 }
99 205
100 inline bool approximately_zero(double x) { 206 inline bool approximately_zero(double x) {
101 return fabs(x) < FLT_EPSILON; 207 return fabs(x) < FLT_EPSILON;
102 } 208 }
103 209
104 inline bool precisely_zero(double x) { 210 inline bool precisely_zero(double x) {
(...skipping 29 matching lines...) Expand all
134 } 240 }
135 241
136 inline bool approximately_zero_sqrt(double x) { 242 inline bool approximately_zero_sqrt(double x) {
137 return fabs(x) < FLT_EPSILON_SQRT; 243 return fabs(x) < FLT_EPSILON_SQRT;
138 } 244 }
139 245
140 inline bool roughly_zero(double x) { 246 inline bool roughly_zero(double x) {
141 return fabs(x) < ROUGH_EPSILON; 247 return fabs(x) < ROUGH_EPSILON;
142 } 248 }
143 249
144 #if 0 // unused for now
145 inline bool way_roughly_zero(double x) {
146 return fabs(x) < WAY_ROUGH_EPSILON;
147 }
148 #endif
149
150 inline bool approximately_zero_inverse(double x) { 250 inline bool approximately_zero_inverse(double x) {
151 return fabs(x) > FLT_EPSILON_INVERSE; 251 return fabs(x) > FLT_EPSILON_INVERSE;
152 } 252 }
153 253
154 // OPTIMIZATION: if called multiple times with the same denom, we want to pass 1 /y instead 254 // OPTIMIZATION: if called multiple times with the same denom, we want to pass 1 /y instead
155 inline bool approximately_zero_when_compared_to(double x, double y) { 255 inline bool approximately_zero_when_compared_to(double x, double y) {
156 return x == 0 || fabs(x) < fabs(y * FLT_EPSILON); 256 return x == 0 || fabs(x) < fabs(y * FLT_EPSILON);
157 } 257 }
158 258
259 inline bool precisely_zero_when_compared_to(double x, double y) {
260 return x == 0 || fabs(x) < fabs(y * DBL_EPSILON);
261 }
262
159 // Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use 263 // Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use
160 // AlmostEqualUlps instead. 264 // AlmostEqualUlps instead.
161 inline bool approximately_equal(double x, double y) { 265 inline bool approximately_equal(double x, double y) {
162 return approximately_zero(x - y); 266 return approximately_zero(x - y);
163 } 267 }
164 268
165 inline bool precisely_equal(double x, double y) { 269 inline bool precisely_equal(double x, double y) {
166 return precisely_zero(x - y); 270 return precisely_zero(x - y);
167 } 271 }
168 272
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 : approximately_negative(b - a) && approximately_negative(c - b); 401 : approximately_negative(b - a) && approximately_negative(c - b);
298 } 402 }
299 403
300 inline bool precisely_between(double a, double b, double c) { 404 inline bool precisely_between(double a, double b, double c) {
301 return a <= c ? precisely_negative(a - b) && precisely_negative(b - c) 405 return a <= c ? precisely_negative(a - b) && precisely_negative(b - c)
302 : precisely_negative(b - a) && precisely_negative(c - b); 406 : precisely_negative(b - a) && precisely_negative(c - b);
303 } 407 }
304 408
305 // returns true if (a <= b <= c) || (a >= b >= c) 409 // returns true if (a <= b <= c) || (a >= b >= c)
306 inline bool between(double a, double b, double c) { 410 inline bool between(double a, double b, double c) {
307 SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0)); 411 SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0)
412 || (precisely_zero(a) && precisely_zero(b) && precisely_zero(c)));
308 return (a - b) * (c - b) <= 0; 413 return (a - b) * (c - b) <= 0;
309 } 414 }
310 415
311 inline bool roughly_equal(double x, double y) { 416 inline bool roughly_equal(double x, double y) {
312 return fabs(x - y) < ROUGH_EPSILON; 417 return fabs(x - y) < ROUGH_EPSILON;
313 } 418 }
314 419
420 inline bool roughly_negative(double x) {
421 return x < ROUGH_EPSILON;
422 }
423
424 inline bool roughly_between(double a, double b, double c) {
425 return a <= c ? roughly_negative(a - b) && roughly_negative(b - c)
426 : roughly_negative(b - a) && roughly_negative(c - b);
427 }
428
315 inline bool more_roughly_equal(double x, double y) { 429 inline bool more_roughly_equal(double x, double y) {
316 return fabs(x - y) < MORE_ROUGH_EPSILON; 430 return fabs(x - y) < MORE_ROUGH_EPSILON;
317 } 431 }
318 432
319 inline bool way_roughly_equal(double x, double y) { 433 inline bool way_roughly_equal(double x, double y) {
320 return fabs(x - y) < WAY_ROUGH_EPSILON; 434 return fabs(x - y) < WAY_ROUGH_EPSILON;
321 } 435 }
322 436
323 struct SkDPoint; 437 struct SkDPoint;
324 struct SkDVector; 438 struct SkDVector;
325 struct SkDLine; 439 struct SkDLine;
326 struct SkDQuad; 440 struct SkDQuad;
327 struct SkDTriangle;
328 struct SkDCubic; 441 struct SkDCubic;
329 struct SkDRect; 442 struct SkDRect;
330 443
331 inline SkPath::Verb SkPathOpsPointsToVerb(int points) { 444 inline SkPath::Verb SkPathOpsPointsToVerb(int points) {
332 int verb = (1 << points) >> 1; 445 int verb = (1 << points) >> 1;
333 #ifdef SK_DEBUG 446 #ifdef SK_DEBUG
334 switch (points) { 447 switch (points) {
335 case 0: SkASSERT(SkPath::kMove_Verb == verb); break; 448 case 0: SkASSERT(SkPath::kMove_Verb == verb); break;
336 case 1: SkASSERT(SkPath::kLine_Verb == verb); break; 449 case 1: SkASSERT(SkPath::kLine_Verb == verb); break;
337 case 2: SkASSERT(SkPath::kQuad_Verb == verb); break; 450 case 2: SkASSERT(SkPath::kQuad_Verb == verb); break;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 */ 490 */
378 inline int SkDSideBit(double x) { 491 inline int SkDSideBit(double x) {
379 return 1 << SKDSide(x); 492 return 1 << SKDSide(x);
380 } 493 }
381 494
382 inline double SkPinT(double t) { 495 inline double SkPinT(double t) {
383 return precisely_less_than_zero(t) ? 0 : precisely_greater_than_one(t) ? 1 : t; 496 return precisely_less_than_zero(t) ? 0 : precisely_greater_than_one(t) ? 1 : t;
384 } 497 }
385 498
386 #endif 499 #endif
OLDNEW
« no previous file with comments | « src/pathops/SkPathOpsTriangle.cpp ('k') | src/pathops/SkQuarticRoot.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698