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 "SkIntersections.h" | 7 #include "SkIntersections.h" |
8 #include "SkOpSegment.h" | 8 #include "SkOpSegment.h" |
9 #include "SkPathWriter.h" | 9 #include "SkPathWriter.h" |
10 #include "SkTSort.h" | 10 #include "SkTSort.h" |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 bool result = gUnaryActiveEdge[from][to]; | 203 bool result = gUnaryActiveEdge[from][to]; |
204 return result; | 204 return result; |
205 } | 205 } |
206 | 206 |
207 void SkOpSegment::addAngle(SkTDArray<SkOpAngle>* anglesPtr, int start, int end)
const { | 207 void SkOpSegment::addAngle(SkTDArray<SkOpAngle>* anglesPtr, int start, int end)
const { |
208 SkASSERT(start != end); | 208 SkASSERT(start != end); |
209 SkOpAngle* angle = anglesPtr->append(); | 209 SkOpAngle* angle = anglesPtr->append(); |
210 #if DEBUG_ANGLE | 210 #if DEBUG_ANGLE |
211 SkTDArray<SkOpAngle>& angles = *anglesPtr; | 211 SkTDArray<SkOpAngle>& angles = *anglesPtr; |
212 if (angles.count() > 1 && !fTs[start].fTiny) { | 212 if (angles.count() > 1 && !fTs[start].fTiny) { |
213 SkPoint angle0Pt = (*CurvePointAtT[angles[0].verb()])(angles[0].pts(), | 213 const SkOpSegment* aSeg = angles[0].segment(); |
214 (*angles[0].spans())[angles[0].start()].fT); | 214 const SkPoint& angle0Pt = aSeg->xyAtT(angles[0].start()); |
215 SkPoint newPt = (*CurvePointAtT[fVerb])(fPts, fTs[start].fT); | 215 SkPoint newPt = (*CurvePointAtT[fVerb])(fPts, fTs[start].fT); |
216 bool match = AlmostEqualUlps(angle0Pt.fX, newPt.fX); | 216 bool match = AlmostEqualUlps(angle0Pt.fX, newPt.fX); |
217 match &= AlmostEqualUlps(angle0Pt.fY, newPt.fY); | 217 match &= AlmostEqualUlps(angle0Pt.fY, newPt.fY); |
218 if (!match) { | 218 if (!match) { |
219 SkDebugf("%s no match\n", __FUNCTION__); | 219 SkDebugf("%s no match\n", __FUNCTION__); |
220 SkASSERT(0); | 220 SkASSERT(0); |
221 } | 221 } |
222 } | 222 } |
223 #endif | 223 #endif |
224 angle->set(fPts, fVerb, this, start, end, fTs); | 224 angle->set(fPts, fVerb, this, start, end, fTs); |
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 } | 1170 } |
1171 const SkOpAngle* nextAngle = sorted[nextIndex]; | 1171 const SkOpAngle* nextAngle = sorted[nextIndex]; |
1172 nextSegment = nextAngle->segment(); | 1172 nextSegment = nextAngle->segment(); |
1173 int maxWinding, sumWinding, oppMaxWinding, oppSumWinding; | 1173 int maxWinding, sumWinding, oppMaxWinding, oppSumWinding; |
1174 bool activeAngle = nextSegment->activeOp(xorMiMask, xorSuMask, nextAngle
->start(), | 1174 bool activeAngle = nextSegment->activeOp(xorMiMask, xorSuMask, nextAngle
->start(), |
1175 nextAngle->end(), op, &sumMiWinding, &sumSuWinding, | 1175 nextAngle->end(), op, &sumMiWinding, &sumSuWinding, |
1176 &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding); | 1176 &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding); |
1177 if (activeAngle) { | 1177 if (activeAngle) { |
1178 ++activeCount; | 1178 ++activeCount; |
1179 if (!foundAngle || (foundDone && activeCount & 1)) { | 1179 if (!foundAngle || (foundDone && activeCount & 1)) { |
1180 if (nextSegment->tiny(nextAngle)) { | 1180 if (nextSegment->isTiny(nextAngle)) { |
1181 *unsortable = true; | 1181 *unsortable = true; |
1182 return NULL; | 1182 return NULL; |
1183 } | 1183 } |
1184 foundAngle = nextAngle; | 1184 foundAngle = nextAngle; |
1185 foundDone = nextSegment->done(nextAngle) && !nextSegment->tiny(n
extAngle); | 1185 foundDone = nextSegment->done(nextAngle) && !nextSegment->isTiny
(nextAngle); |
1186 } | 1186 } |
1187 } | 1187 } |
1188 if (nextSegment->done()) { | 1188 if (nextSegment->done()) { |
1189 continue; | 1189 continue; |
1190 } | 1190 } |
1191 if (nextSegment->windSum(nextAngle) != SK_MinS32) { | 1191 if (nextSegment->windSum(nextAngle) != SK_MinS32) { |
1192 continue; | 1192 continue; |
1193 } | 1193 } |
1194 SkOpSpan* last = nextSegment->markAngle(maxWinding, sumWinding, oppMaxWi
nding, | 1194 SkOpSpan* last = nextSegment->markAngle(maxWinding, sumWinding, oppMaxWi
nding, |
1195 oppSumWinding, activeAngle, nextAngle); | 1195 oppSumWinding, activeAngle, nextAngle); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1287 nextIndex = 0; | 1287 nextIndex = 0; |
1288 } | 1288 } |
1289 const SkOpAngle* nextAngle = sorted[nextIndex]; | 1289 const SkOpAngle* nextAngle = sorted[nextIndex]; |
1290 nextSegment = nextAngle->segment(); | 1290 nextSegment = nextAngle->segment(); |
1291 int maxWinding; | 1291 int maxWinding; |
1292 bool activeAngle = nextSegment->activeWinding(nextAngle->start(), nextAn
gle->end(), | 1292 bool activeAngle = nextSegment->activeWinding(nextAngle->start(), nextAn
gle->end(), |
1293 &maxWinding, &sumWinding); | 1293 &maxWinding, &sumWinding); |
1294 if (activeAngle) { | 1294 if (activeAngle) { |
1295 ++activeCount; | 1295 ++activeCount; |
1296 if (!foundAngle || (foundDone && activeCount & 1)) { | 1296 if (!foundAngle || (foundDone && activeCount & 1)) { |
1297 if (nextSegment->tiny(nextAngle)) { | 1297 if (nextSegment->isTiny(nextAngle)) { |
1298 *unsortable = true; | 1298 *unsortable = true; |
1299 return NULL; | 1299 return NULL; |
1300 } | 1300 } |
1301 foundAngle = nextAngle; | 1301 foundAngle = nextAngle; |
1302 foundDone = nextSegment->done(nextAngle); | 1302 foundDone = nextSegment->done(nextAngle); |
1303 } | 1303 } |
1304 } | 1304 } |
1305 if (nextSegment->done()) { | 1305 if (nextSegment->done()) { |
1306 continue; | 1306 continue; |
1307 } | 1307 } |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 int activeCount = 0; | 1409 int activeCount = 0; |
1410 do { | 1410 do { |
1411 SkASSERT(nextIndex != firstIndex); | 1411 SkASSERT(nextIndex != firstIndex); |
1412 if (nextIndex == angleCount) { | 1412 if (nextIndex == angleCount) { |
1413 nextIndex = 0; | 1413 nextIndex = 0; |
1414 } | 1414 } |
1415 const SkOpAngle* nextAngle = sorted[nextIndex]; | 1415 const SkOpAngle* nextAngle = sorted[nextIndex]; |
1416 nextSegment = nextAngle->segment(); | 1416 nextSegment = nextAngle->segment(); |
1417 ++activeCount; | 1417 ++activeCount; |
1418 if (!foundAngle || (foundDone && activeCount & 1)) { | 1418 if (!foundAngle || (foundDone && activeCount & 1)) { |
1419 if (nextSegment->tiny(nextAngle)) { | 1419 if (nextSegment->isTiny(nextAngle)) { |
1420 *unsortable = true; | 1420 *unsortable = true; |
1421 return NULL; | 1421 return NULL; |
1422 } | 1422 } |
1423 foundAngle = nextAngle; | 1423 foundAngle = nextAngle; |
1424 foundDone = nextSegment->done(nextAngle); | 1424 foundDone = nextSegment->done(nextAngle); |
1425 } | 1425 } |
1426 if (nextSegment->done()) { | 1426 if (nextSegment->done()) { |
1427 continue; | 1427 continue; |
1428 } | 1428 } |
1429 } while (++nextIndex != lastIndex); | 1429 } while (++nextIndex != lastIndex); |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2372 edge[1] = SkDQuad::SubDivide(fPts, sub[0], sub[1], fTs[start].fT, | 2372 edge[1] = SkDQuad::SubDivide(fPts, sub[0], sub[1], fTs[start].fT, |
2373 fTs[end].fT).asSkPoint(); | 2373 fTs[end].fT).asSkPoint(); |
2374 } else { | 2374 } else { |
2375 SkDCubic::SubDivide(fPts, sub[0], sub[1], fTs[start].fT, fTs[end].fT
, sub); | 2375 SkDCubic::SubDivide(fPts, sub[0], sub[1], fTs[start].fT, fTs[end].fT
, sub); |
2376 edge[1] = sub[0].asSkPoint(); | 2376 edge[1] = sub[0].asSkPoint(); |
2377 edge[2] = sub[1].asSkPoint(); | 2377 edge[2] = sub[1].asSkPoint(); |
2378 } | 2378 } |
2379 } | 2379 } |
2380 } | 2380 } |
2381 | 2381 |
| 2382 void SkOpSegment::subDivide(int start, int end, SkDCubic* result) const { |
| 2383 (*result)[0].set(fTs[start].fPt); |
| 2384 (*result)[fVerb].set(fTs[end].fPt); |
| 2385 if (fVerb == SkPath::kQuad_Verb) { |
| 2386 (*result)[1] = SkDQuad::SubDivide(fPts, (*result)[0], (*result)[2], fTs[
start].fT, |
| 2387 fTs[end].fT); |
| 2388 } else if (fVerb == SkPath::kCubic_Verb) { |
| 2389 SkDCubic::SubDivide(fPts, (*result)[0], (*result)[3], fTs[start].fT, fTs
[end].fT, |
| 2390 &(*result)[1]); |
| 2391 } |
| 2392 } |
| 2393 |
2382 void SkOpSegment::subDivideBounds(int start, int end, SkPathOpsBounds* bounds) c
onst { | 2394 void SkOpSegment::subDivideBounds(int start, int end, SkPathOpsBounds* bounds) c
onst { |
2383 SkPoint edge[4]; | 2395 SkPoint edge[4]; |
2384 subDivide(start, end, edge); | 2396 subDivide(start, end, edge); |
2385 (bounds->*SetCurveBounds[fVerb])(edge); | 2397 (bounds->*SetCurveBounds[fVerb])(edge); |
2386 } | 2398 } |
2387 | 2399 |
2388 bool SkOpSegment::tiny(const SkOpAngle* angle) const { | 2400 bool SkOpSegment::isTiny(const SkOpAngle* angle) const { |
2389 int start = angle->start(); | 2401 int start = angle->start(); |
2390 int end = angle->end(); | 2402 int end = angle->end(); |
2391 const SkOpSpan& mSpan = fTs[SkMin32(start, end)]; | 2403 const SkOpSpan& mSpan = fTs[SkMin32(start, end)]; |
2392 return mSpan.fTiny; | 2404 return mSpan.fTiny; |
2393 } | 2405 } |
2394 | 2406 |
2395 void SkOpSegment::TrackOutside(SkTDArray<double>* outsideTs, double end, double
start) { | 2407 void SkOpSegment::TrackOutside(SkTDArray<double>* outsideTs, double end, double
start) { |
2396 int outCount = outsideTs->count(); | 2408 int outCount = outsideTs->count(); |
2397 if (outCount == 0 || !approximately_negative(end - (*outsideTs)[outCount - 2
])) { | 2409 if (outCount == 0 || !approximately_negative(end - (*outsideTs)[outCount - 2
])) { |
2398 *outsideTs->append() = end; | 2410 *outsideTs->append() = end; |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2728 lastSum = windSum; | 2740 lastSum = windSum; |
2729 windSum -= segment.spanSign(&angle); | 2741 windSum -= segment.spanSign(&angle); |
2730 if (oppoSign) { | 2742 if (oppoSign) { |
2731 oppLastSum = oppWindSum; | 2743 oppLastSum = oppWindSum; |
2732 oppWindSum -= oppoSign; | 2744 oppWindSum -= oppoSign; |
2733 } | 2745 } |
2734 } | 2746 } |
2735 } | 2747 } |
2736 SkDebugf("%s [%d] %s", __FUNCTION__, index, | 2748 SkDebugf("%s [%d] %s", __FUNCTION__, index, |
2737 angle.unsortable() ? "*** UNSORTABLE *** " : ""); | 2749 angle.unsortable() ? "*** UNSORTABLE *** " : ""); |
2738 #if COMPACT_DEBUG_SORT | 2750 #if DEBUG_SORT_COMPACT |
2739 SkDebugf("id=%d %s start=%d (%1.9g,%,1.9g) end=%d (%1.9g,%,1.9g)", | 2751 SkDebugf("id=%d %s start=%d (%1.9g,%,1.9g) end=%d (%1.9g,%,1.9g)", |
2740 segment.fID, kLVerbStr[segment.fVerb], | 2752 segment.fID, kLVerbStr[segment.fVerb], |
2741 start, segment.xAtT(&sSpan), segment.yAtT(&sSpan), end, | 2753 start, segment.xAtT(&sSpan), segment.yAtT(&sSpan), end, |
2742 segment.xAtT(&eSpan), segment.yAtT(&eSpan)); | 2754 segment.xAtT(&eSpan), segment.yAtT(&eSpan)); |
2743 #else | 2755 #else |
2744 switch (segment.fVerb) { | 2756 switch (segment.fVerb) { |
2745 case SkPath::kLine_Verb: | 2757 case SkPath::kLine_Verb: |
2746 SkDebugf(LINE_DEBUG_STR, LINE_DEBUG_DATA(segment.fPts)); | 2758 SkDebugf(LINE_DEBUG_STR, LINE_DEBUG_DATA(segment.fPts)); |
2747 break; | 2759 break; |
2748 case SkPath::kQuad_Verb: | 2760 case SkPath::kQuad_Verb: |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2820 sum += fTs[i].fWindValue; | 2832 sum += fTs[i].fWindValue; |
2821 slots[fTs[i].fOther->fID - 1] = as_digit(fTs[i].fWindValue); | 2833 slots[fTs[i].fOther->fID - 1] = as_digit(fTs[i].fWindValue); |
2822 sum += fTs[i].fOppValue; | 2834 sum += fTs[i].fOppValue; |
2823 slots[slotCount + fTs[i].fOther->fID - 1] = as_digit(fTs[i].fOppValue); | 2835 slots[slotCount + fTs[i].fOther->fID - 1] = as_digit(fTs[i].fOppValue); |
2824 } | 2836 } |
2825 SkDebugf("%s id=%2d %.*s | %.*s\n", __FUNCTION__, fID, slotCount, slots.begi
n(), slotCount, | 2837 SkDebugf("%s id=%2d %.*s | %.*s\n", __FUNCTION__, fID, slotCount, slots.begi
n(), slotCount, |
2826 slots.begin() + slotCount); | 2838 slots.begin() + slotCount); |
2827 return sum; | 2839 return sum; |
2828 } | 2840 } |
2829 #endif | 2841 #endif |
OLD | NEW |