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 #include "SkAddIntersections.h" | 7 #include "SkAddIntersections.h" |
8 #include "SkOpCoincidence.h" | 8 #include "SkOpCoincidence.h" |
9 #include "SkOpEdgeBuilder.h" | 9 #include "SkOpEdgeBuilder.h" |
10 #include "SkPathOpsCommon.h" | 10 #include "SkPathOpsCommon.h" |
11 #include "SkPathWriter.h" | 11 #include "SkPathWriter.h" |
12 #include "SkTSort.h" | 12 #include "SkTSort.h" |
13 | 13 |
14 const SkOpAngle* AngleWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* windi
ngPtr, | 14 const SkOpAngle* AngleWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* windi
ngPtr, |
15 bool* sortablePtr) { | 15 bool* sortablePtr) { |
16 // find first angle, initialize winding to computed fWindSum | 16 // find first angle, initialize winding to computed fWindSum |
17 SkOpSegment* segment = start->segment(); | 17 SkOpSegment* segment = start->segment(); |
18 const SkOpAngle* angle = segment->spanToAngle(start, end); | 18 const SkOpAngle* angle = segment->spanToAngle(start, end); |
19 if (!angle) { | 19 if (!angle) { |
20 *windingPtr = SK_MinS32; | 20 *windingPtr = SK_MinS32; |
21 return NULL; | 21 return nullptr; |
22 } | 22 } |
23 bool computeWinding = false; | 23 bool computeWinding = false; |
24 const SkOpAngle* firstAngle = angle; | 24 const SkOpAngle* firstAngle = angle; |
25 bool loop = false; | 25 bool loop = false; |
26 bool unorderable = false; | 26 bool unorderable = false; |
27 int winding = SK_MinS32; | 27 int winding = SK_MinS32; |
28 do { | 28 do { |
29 angle = angle->next(); | 29 angle = angle->next(); |
30 unorderable |= angle->unorderable(); | 30 unorderable |= angle->unorderable(); |
31 if ((computeWinding = unorderable || (angle == firstAngle && loop))) { | 31 if ((computeWinding = unorderable || (angle == firstAngle && loop))) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 SkOpSegment* FindUndone(SkOpContourHead* contourList, SkOpSpanBase** startPtr, | 63 SkOpSegment* FindUndone(SkOpContourHead* contourList, SkOpSpanBase** startPtr, |
64 SkOpSpanBase** endPtr) { | 64 SkOpSpanBase** endPtr) { |
65 SkOpSegment* result; | 65 SkOpSegment* result; |
66 SkOpContour* contour = contourList; | 66 SkOpContour* contour = contourList; |
67 do { | 67 do { |
68 result = contour->undoneSegment(startPtr, endPtr); | 68 result = contour->undoneSegment(startPtr, endPtr); |
69 if (result) { | 69 if (result) { |
70 return result; | 70 return result; |
71 } | 71 } |
72 } while ((contour = contour->next())); | 72 } while ((contour = contour->next())); |
73 return NULL; | 73 return nullptr; |
74 } | 74 } |
75 | 75 |
76 SkOpSegment* FindChase(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** startPtr, | 76 SkOpSegment* FindChase(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** startPtr, |
77 SkOpSpanBase** endPtr) { | 77 SkOpSpanBase** endPtr) { |
78 while (chase->count()) { | 78 while (chase->count()) { |
79 SkOpSpanBase* span; | 79 SkOpSpanBase* span; |
80 chase->pop(&span); | 80 chase->pop(&span); |
81 SkOpSegment* segment = span->segment(); | 81 SkOpSegment* segment = span->segment(); |
82 *startPtr = span->ptT()->next()->span(); | 82 *startPtr = span->ptT()->next()->span(); |
83 bool done = true; | 83 bool done = true; |
84 *endPtr = NULL; | 84 *endPtr = nullptr; |
85 if (SkOpAngle* last = segment->activeAngle(*startPtr, startPtr, endPtr,
&done)) { | 85 if (SkOpAngle* last = segment->activeAngle(*startPtr, startPtr, endPtr,
&done)) { |
86 *startPtr = last->start(); | 86 *startPtr = last->start(); |
87 *endPtr = last->end(); | 87 *endPtr = last->end(); |
88 #if TRY_ROTATE | 88 #if TRY_ROTATE |
89 *chase->insert(0) = span; | 89 *chase->insert(0) = span; |
90 #else | 90 #else |
91 *chase->append() = span; | 91 *chase->append() = span; |
92 #endif | 92 #endif |
93 return last->segment(); | 93 return last->segment(); |
94 } | 94 } |
95 if (done) { | 95 if (done) { |
96 continue; | 96 continue; |
97 } | 97 } |
98 // find first angle, initialize winding to computed wind sum | 98 // find first angle, initialize winding to computed wind sum |
99 int winding; | 99 int winding; |
100 bool sortable; | 100 bool sortable; |
101 const SkOpAngle* angle = AngleWinding(*startPtr, *endPtr, &winding, &sor
table); | 101 const SkOpAngle* angle = AngleWinding(*startPtr, *endPtr, &winding, &sor
table); |
102 if (winding == SK_MinS32) { | 102 if (winding == SK_MinS32) { |
103 continue; | 103 continue; |
104 } | 104 } |
105 int sumWinding SK_INIT_TO_AVOID_WARNING; | 105 int sumWinding SK_INIT_TO_AVOID_WARNING; |
106 if (sortable) { | 106 if (sortable) { |
107 segment = angle->segment(); | 107 segment = angle->segment(); |
108 sumWinding = segment->updateWindingReverse(angle); | 108 sumWinding = segment->updateWindingReverse(angle); |
109 } | 109 } |
110 SkOpSegment* first = NULL; | 110 SkOpSegment* first = nullptr; |
111 const SkOpAngle* firstAngle = angle; | 111 const SkOpAngle* firstAngle = angle; |
112 while ((angle = angle->next()) != firstAngle) { | 112 while ((angle = angle->next()) != firstAngle) { |
113 segment = angle->segment(); | 113 segment = angle->segment(); |
114 SkOpSpanBase* start = angle->start(); | 114 SkOpSpanBase* start = angle->start(); |
115 SkOpSpanBase* end = angle->end(); | 115 SkOpSpanBase* end = angle->end(); |
116 int maxWinding; | 116 int maxWinding; |
117 if (sortable) { | 117 if (sortable) { |
118 segment->setUpWinding(start, end, &maxWinding, &sumWinding); | 118 segment->setUpWinding(start, end, &maxWinding, &sumWinding); |
119 } | 119 } |
120 if (!segment->done(angle)) { | 120 if (!segment->done(angle)) { |
(...skipping 10 matching lines...) Expand all Loading... |
131 } | 131 } |
132 if (first) { | 132 if (first) { |
133 #if TRY_ROTATE | 133 #if TRY_ROTATE |
134 *chase->insert(0) = span; | 134 *chase->insert(0) = span; |
135 #else | 135 #else |
136 *chase->append() = span; | 136 *chase->append() = span; |
137 #endif | 137 #endif |
138 return first; | 138 return first; |
139 } | 139 } |
140 } | 140 } |
141 return NULL; | 141 return nullptr; |
142 } | 142 } |
143 | 143 |
144 #if DEBUG_ACTIVE_SPANS | 144 #if DEBUG_ACTIVE_SPANS |
145 void DebugShowActiveSpans(SkOpContourHead* contourList) { | 145 void DebugShowActiveSpans(SkOpContourHead* contourList) { |
146 SkOpContour* contour = contourList; | 146 SkOpContour* contour = contourList; |
147 do { | 147 do { |
148 contour->debugShowActiveSpans(); | 148 contour->debugShowActiveSpans(); |
149 } while ((contour = contour->next())); | 149 } while ((contour = contour->next())); |
150 } | 150 } |
151 #endif | 151 #endif |
(...skipping 16 matching lines...) Expand all Loading... |
168 } | 168 } |
169 contour = list[0]; | 169 contour = list[0]; |
170 SkOpContourHead* contourHead = static_cast<SkOpContourHead*>(contour); | 170 SkOpContourHead* contourHead = static_cast<SkOpContourHead*>(contour); |
171 contour->globalState()->setContourHead(contourHead); | 171 contour->globalState()->setContourHead(contourHead); |
172 *contourList = contourHead; | 172 *contourList = contourHead; |
173 for (int index = 1; index < count; ++index) { | 173 for (int index = 1; index < count; ++index) { |
174 SkOpContour* next = list[index]; | 174 SkOpContour* next = list[index]; |
175 contour->setNext(next); | 175 contour->setNext(next); |
176 contour = next; | 176 contour = next; |
177 } | 177 } |
178 contour->setNext(NULL); | 178 contour->setNext(nullptr); |
179 return true; | 179 return true; |
180 } | 180 } |
181 | 181 |
182 class DistanceLessThan { | 182 class DistanceLessThan { |
183 public: | 183 public: |
184 DistanceLessThan(double* distances) : fDistances(distances) { } | 184 DistanceLessThan(double* distances) : fDistances(distances) { } |
185 double* fDistances; | 185 double* fDistances; |
186 bool operator()(const int one, const int two) { | 186 bool operator()(const int one, const int two) { |
187 return fDistances[one] < fDistances[two]; | 187 return fDistances[one] < fDistances[two]; |
188 } | 188 } |
189 }; | 189 }; |
190 | 190 |
191 /* | 191 /* |
192 check start and end of each contour | 192 check start and end of each contour |
193 if not the same, record them | 193 if not the same, record them |
194 match them up | 194 match them up |
195 connect closest | 195 connect closest |
196 reassemble contour pieces into new path | 196 reassemble contour pieces into new path |
197 */ | 197 */ |
198 void Assemble(const SkPathWriter& path, SkPathWriter* simple) { | 198 void Assemble(const SkPathWriter& path, SkPathWriter* simple) { |
199 SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune | 199 SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune |
200 SkOpContourHead contour; | 200 SkOpContourHead contour; |
201 SkOpGlobalState globalState(NULL, &contour SkDEBUGPARAMS(NULL)); | 201 SkOpGlobalState globalState(nullptr, &contour SkDEBUGPARAMS(nullptr)); |
202 #if DEBUG_SHOW_TEST_NAME | 202 #if DEBUG_SHOW_TEST_NAME |
203 SkDebugf("</div>\n"); | 203 SkDebugf("</div>\n"); |
204 #endif | 204 #endif |
205 #if DEBUG_PATH_CONSTRUCTION | 205 #if DEBUG_PATH_CONSTRUCTION |
206 SkDebugf("%s\n", __FUNCTION__); | 206 SkDebugf("%s\n", __FUNCTION__); |
207 #endif | 207 #endif |
208 SkOpEdgeBuilder builder(path, &contour, &allocator, &globalState); | 208 SkOpEdgeBuilder builder(path, &contour, &allocator, &globalState); |
209 builder.finish(&allocator); | 209 builder.finish(&allocator); |
210 SkTDArray<const SkOpContour* > runs; // indices of partial contours | 210 SkTDArray<const SkOpContour* > runs; // indices of partial contours |
211 const SkOpContour* eContour = builder.head(); | 211 const SkOpContour* eContour = builder.head(); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 if (!coincidence->apply()) { | 494 if (!coincidence->apply()) { |
495 return false; | 495 return false; |
496 } | 496 } |
497 } | 497 } |
498 #if DEBUG_ACTIVE_SPANS | 498 #if DEBUG_ACTIVE_SPANS |
499 coincidence->debugShowCoincidence(); | 499 coincidence->debugShowCoincidence(); |
500 DebugShowActiveSpans(contourList); | 500 DebugShowActiveSpans(contourList); |
501 #endif | 501 #endif |
502 return true; | 502 return true; |
503 } | 503 } |
OLD | NEW |