| 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 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 return bestTIndex; | 1291 return bestTIndex; |
| 1292 } | 1292 } |
| 1293 if (fBounds.fLeft == fBounds.fRight) { | 1293 if (fBounds.fLeft == fBounds.fRight) { |
| 1294 // if vertical, and directly above test point, wait for another one | 1294 // if vertical, and directly above test point, wait for another one |
| 1295 return AlmostEqualUlps(basePt.fX, fBounds.fLeft) ? SK_MinS32 : bestTInde
x; | 1295 return AlmostEqualUlps(basePt.fX, fBounds.fLeft) ? SK_MinS32 : bestTInde
x; |
| 1296 } | 1296 } |
| 1297 // intersect ray starting at basePt with edge | 1297 // intersect ray starting at basePt with edge |
| 1298 SkIntersections intersections; | 1298 SkIntersections intersections; |
| 1299 // OPTIMIZE: use specialty function that intersects ray with curve, | 1299 // OPTIMIZE: use specialty function that intersects ray with curve, |
| 1300 // returning t values only for curve (we don't care about t on ray) | 1300 // returning t values only for curve (we don't care about t on ray) |
| 1301 intersections.allowNear(false); |
| 1301 int pts = (intersections.*CurveVertical[SkPathOpsVerbToPoints(fVerb)]) | 1302 int pts = (intersections.*CurveVertical[SkPathOpsVerbToPoints(fVerb)]) |
| 1302 (fPts, top, bottom, basePt.fX, false); | 1303 (fPts, top, bottom, basePt.fX, false); |
| 1303 if (pts == 0 || (current && pts == 1)) { | 1304 if (pts == 0 || (current && pts == 1)) { |
| 1304 return bestTIndex; | 1305 return bestTIndex; |
| 1305 } | 1306 } |
| 1306 if (current) { | 1307 if (current) { |
| 1307 SkASSERT(pts > 1); | 1308 SkASSERT(pts > 1); |
| 1308 int closestIdx = 0; | 1309 int closestIdx = 0; |
| 1309 double closest = fabs(intersections[0][0] - mid); | 1310 double closest = fabs(intersections[0][0] - mid); |
| 1310 for (int idx = 1; idx < pts; ++idx) { | 1311 for (int idx = 1; idx < pts; ++idx) { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1413 ; | 1414 ; |
| 1414 int otherCount = other->fTs.count(); | 1415 int otherCount = other->fTs.count(); |
| 1415 int peekLast = span.fOtherIndex; | 1416 int peekLast = span.fOtherIndex; |
| 1416 while (++peekLast < otherCount && other->fTs[peekLast].fT == otherT) | 1417 while (++peekLast < otherCount && other->fTs[peekLast].fT == otherT) |
| 1417 ; | 1418 ; |
| 1418 if (++peekStart == --peekLast) { // if there isn't a range, there's noth
ing to do | 1419 if (++peekStart == --peekLast) { // if there isn't a range, there's noth
ing to do |
| 1419 continue; | 1420 continue; |
| 1420 } | 1421 } |
| 1421 // t start/last describe the range of spans that match the t of this spa
n | 1422 // t start/last describe the range of spans that match the t of this spa
n |
| 1422 double t = span.fT; | 1423 double t = span.fT; |
| 1423 int tStart = index; | 1424 double tBottom = -1; |
| 1424 while (--tStart >= 0 && (t == fTs[tStart].fT || fTs[tStart].fTiny)) | 1425 int tStart = -1; |
| 1425 ; | 1426 int tLast = count; |
| 1426 int tLast = index; | 1427 bool lastSmall = false; |
| 1427 while (fTs[tLast].fTiny) { | 1428 double afterT = t; |
| 1428 ++tLast; | 1429 for (int inner = 0; inner < count; ++inner) { |
| 1430 double innerT = fTs[inner].fT; |
| 1431 if (innerT <= t && innerT > tBottom) { |
| 1432 if (innerT < t || !lastSmall) { |
| 1433 tStart = inner - 1; |
| 1434 } |
| 1435 tBottom = innerT; |
| 1436 } |
| 1437 if (innerT > afterT) { |
| 1438 if (t == afterT && lastSmall) { |
| 1439 afterT = innerT; |
| 1440 } else { |
| 1441 tLast = inner; |
| 1442 break; |
| 1443 } |
| 1444 } |
| 1445 lastSmall = innerT <= t ? fTs[inner].fSmall : false; |
| 1429 } | 1446 } |
| 1430 while (++tLast < count && t == fTs[tLast].fT) | |
| 1431 ; | |
| 1432 for (int peekIndex = peekStart; peekIndex <= peekLast; ++peekIndex) { | 1447 for (int peekIndex = peekStart; peekIndex <= peekLast; ++peekIndex) { |
| 1433 if (peekIndex == span.fOtherIndex) { // skip the other span pointed
to by this span | 1448 if (peekIndex == span.fOtherIndex) { // skip the other span pointed
to by this span |
| 1434 continue; | 1449 continue; |
| 1435 } | 1450 } |
| 1436 const SkOpSpan& peekSpan = other->fTs[peekIndex]; | 1451 const SkOpSpan& peekSpan = other->fTs[peekIndex]; |
| 1437 SkOpSegment* match = peekSpan.fOther; | 1452 SkOpSegment* match = peekSpan.fOther; |
| 1438 if (match->done()) { | 1453 if (match->done()) { |
| 1439 continue; // if the edge has already been eaten (likely coincid
ence), ignore it | 1454 continue; // if the edge has already been eaten (likely coincid
ence), ignore it |
| 1440 } | 1455 } |
| 1441 const double matchT = peekSpan.fOtherT; | 1456 const double matchT = peekSpan.fOtherT; |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1689 MissingSpan& missing = missingSpans[index]; | 1704 MissingSpan& missing = missingSpans[index]; |
| 1690 missing.fSegment->addTPair(missing.fT, missing.fOther, missing.fOtherT,
false, missing.fPt); | 1705 missing.fSegment->addTPair(missing.fT, missing.fOther, missing.fOtherT,
false, missing.fPt); |
| 1691 } | 1706 } |
| 1692 for (int index = 0; index < missingCount; ++index) { | 1707 for (int index = 0; index < missingCount; ++index) { |
| 1693 MissingSpan& missing = missingSpans[index]; | 1708 MissingSpan& missing = missingSpans[index]; |
| 1694 missing.fSegment->fixOtherTIndex(); | 1709 missing.fSegment->fixOtherTIndex(); |
| 1695 missing.fOther->fixOtherTIndex(); | 1710 missing.fOther->fixOtherTIndex(); |
| 1696 } | 1711 } |
| 1697 } | 1712 } |
| 1698 | 1713 |
| 1714 bool SkOpSegment::findCoincidentMatch(const SkOpSpan* span, const SkOpSegment* o
ther, int oStart, |
| 1715 int oEnd, int step, SkPoint* startPt, SkPoint* endPt, double* endT) cons
t { |
| 1716 SkASSERT(span->fT == 0 || span->fT == 1); |
| 1717 SkASSERT(span->fOtherT == 0 || span->fOtherT == 1); |
| 1718 const SkOpSpan* otherSpan = &other->span(oEnd); |
| 1719 double refT = otherSpan->fT; |
| 1720 const SkPoint& refPt = otherSpan->fPt; |
| 1721 const SkOpSpan* lastSpan = &other->span(step > 0 ? other->count() - 1 : 0); |
| 1722 do { |
| 1723 const SkOpSegment* match = span->fOther; |
| 1724 if (match == otherSpan->fOther) { |
| 1725 // find start of respective spans and see if both have winding |
| 1726 int startIndex, endIndex; |
| 1727 if (span->fOtherT == 1) { |
| 1728 endIndex = span->fOtherIndex; |
| 1729 startIndex = match->nextExactSpan(endIndex, -1); |
| 1730 } else { |
| 1731 startIndex = span->fOtherIndex; |
| 1732 endIndex = match->nextExactSpan(startIndex, 1); |
| 1733 } |
| 1734 const SkOpSpan& startSpan = match->span(startIndex); |
| 1735 if (startSpan.fWindValue != 0) { |
| 1736 // draw ray from endSpan.fPt perpendicular to end tangent and me
asure distance |
| 1737 // to other segment. |
| 1738 const SkOpSpan& endSpan = match->span(endIndex); |
| 1739 SkDLine ray; |
| 1740 SkVector dxdy; |
| 1741 if (span->fOtherT == 1) { |
| 1742 ray.fPts[0].set(startSpan.fPt); |
| 1743 dxdy = match->dxdy(startIndex); |
| 1744 } else { |
| 1745 ray.fPts[0].set(endSpan.fPt); |
| 1746 dxdy = match->dxdy(endIndex); |
| 1747 } |
| 1748 ray.fPts[1].fX = ray.fPts[0].fX + dxdy.fY; |
| 1749 ray.fPts[1].fY = ray.fPts[0].fY - dxdy.fX; |
| 1750 SkIntersections i; |
| 1751 int roots = (i.*CurveRay[SkPathOpsVerbToPoints(other->verb())])(
other->pts(), ray); |
| 1752 for (int index = 0; index < roots; ++index) { |
| 1753 if (ray.fPts[0].approximatelyEqual(i.pt(index))) { |
| 1754 double matchMidT = (match->span(startIndex).fT |
| 1755 + match->span(endIndex).fT) / 2; |
| 1756 SkPoint matchMidPt = match->ptAtT(matchMidT); |
| 1757 double otherMidT = (i[0][index] + other->span(oStart).fT
) / 2; |
| 1758 SkPoint otherMidPt = other->ptAtT(otherMidT); |
| 1759 if (SkDPoint::ApproximatelyEqual(matchMidPt, otherMidPt)
) { |
| 1760 *startPt = startSpan.fPt; |
| 1761 *endPt = endSpan.fPt; |
| 1762 *endT = endSpan.fT; |
| 1763 return true; |
| 1764 } |
| 1765 } |
| 1766 } |
| 1767 } |
| 1768 return false; |
| 1769 } |
| 1770 if (otherSpan == lastSpan) { |
| 1771 break; |
| 1772 } |
| 1773 otherSpan += step; |
| 1774 } while (otherSpan->fT == refT || otherSpan->fPt == refPt); |
| 1775 return false; |
| 1776 } |
| 1777 |
| 1699 /* | 1778 /* |
| 1700 The M and S variable name parts stand for the operators. | 1779 The M and S variable name parts stand for the operators. |
| 1701 Mi stands for Minuend (see wiki subtraction, analogous to difference) | 1780 Mi stands for Minuend (see wiki subtraction, analogous to difference) |
| 1702 Su stands for Subtrahend | 1781 Su stands for Subtrahend |
| 1703 The Opp variable name part designates that the value is for the Opposite operat
or. | 1782 The Opp variable name part designates that the value is for the Opposite operat
or. |
| 1704 Opposite values result from combining coincident spans. | 1783 Opposite values result from combining coincident spans. |
| 1705 */ | 1784 */ |
| 1706 SkOpSegment* SkOpSegment::findNextOp(SkTDArray<SkOpSpan*>* chase, int* nextStart
, int* nextEnd, | 1785 SkOpSegment* SkOpSegment::findNextOp(SkTDArray<SkOpSpan*>* chase, int* nextStart
, int* nextEnd, |
| 1707 bool* unsortable, SkPathOp op, const int xo
rMiMask, | 1786 bool* unsortable, SkPathOp op, const int xo
rMiMask, |
| 1708 const int xorSuMask) { | 1787 const int xorSuMask) { |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2069 const SkOpAngle* angle = sorted[angleIndex]; | 2148 const SkOpAngle* angle = sorted[angleIndex]; |
| 2070 if (angle->segment() == this && angle->start() == end && | 2149 if (angle->segment() == this && angle->start() == end && |
| 2071 angle->end() == start) { | 2150 angle->end() == start) { |
| 2072 firstIndex = angleIndex; | 2151 firstIndex = angleIndex; |
| 2073 break; | 2152 break; |
| 2074 } | 2153 } |
| 2075 } | 2154 } |
| 2076 return firstIndex; | 2155 return firstIndex; |
| 2077 } | 2156 } |
| 2078 | 2157 |
| 2158 int SkOpSegment::findT(double t, const SkOpSegment* match) const { |
| 2159 int count = this->count(); |
| 2160 for (int index = 0; index < count; ++index) { |
| 2161 const SkOpSpan& span = fTs[index]; |
| 2162 if (span.fT == t && span.fOther == match) { |
| 2163 return index; |
| 2164 } |
| 2165 } |
| 2166 SkASSERT(0); |
| 2167 return -1; |
| 2168 } |
| 2169 |
| 2079 // FIXME: either: | 2170 // FIXME: either: |
| 2080 // a) mark spans with either end unsortable as done, or | 2171 // a) mark spans with either end unsortable as done, or |
| 2081 // b) rewrite findTop / findTopSegment / findTopContour to iterate further | 2172 // b) rewrite findTop / findTopSegment / findTopContour to iterate further |
| 2082 // when encountering an unsortable span | 2173 // when encountering an unsortable span |
| 2083 | 2174 |
| 2084 // OPTIMIZATION : for a pair of lines, can we compute points at T (cached) | 2175 // OPTIMIZATION : for a pair of lines, can we compute points at T (cached) |
| 2085 // and use more concise logic like the old edge walker code? | 2176 // and use more concise logic like the old edge walker code? |
| 2086 // FIXME: this needs to deal with coincident edges | 2177 // FIXME: this needs to deal with coincident edges |
| 2087 SkOpSegment* SkOpSegment::findTop(int* tIndexPtr, int* endIndexPtr, bool* unsort
able, | 2178 SkOpSegment* SkOpSegment::findTop(int* tIndexPtr, int* endIndexPtr, bool* unsort
able, |
| 2088 bool onlySortable) { | 2179 bool onlySortable) { |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2292 double t = fTs[end].fT; | 2383 double t = fTs[end].fT; |
| 2293 if (approximately_less_than_zero(t)) { | 2384 if (approximately_less_than_zero(t)) { |
| 2294 return !approximately_less_than_zero(fTs[1].fT); | 2385 return !approximately_less_than_zero(fTs[1].fT); |
| 2295 } | 2386 } |
| 2296 if (approximately_greater_than_one(t)) { | 2387 if (approximately_greater_than_one(t)) { |
| 2297 return !approximately_greater_than_one(fTs[count - 2].fT); | 2388 return !approximately_greater_than_one(fTs[count - 2].fT); |
| 2298 } | 2389 } |
| 2299 return false; | 2390 return false; |
| 2300 } | 2391 } |
| 2301 | 2392 |
| 2393 bool SkOpSegment::isTiny(const SkOpAngle* angle) const { |
| 2394 int start = angle->start(); |
| 2395 int end = angle->end(); |
| 2396 const SkOpSpan& mSpan = fTs[SkMin32(start, end)]; |
| 2397 return mSpan.fTiny; |
| 2398 } |
| 2399 |
| 2400 bool SkOpSegment::isTiny(int index) const { |
| 2401 return fTs[index].fTiny; |
| 2402 } |
| 2403 |
| 2404 // look pair of active edges going away from coincident edge |
| 2405 // one of them should be the continuation of other |
| 2406 // if both are active, look to see if they both the connect to another coinciden
t pair |
| 2407 // if one at least one is a line, then make the pair coincident |
| 2408 // if neither is a line, test for coincidence |
| 2409 bool SkOpSegment::joinCoincidence(bool end, SkOpSegment* other, double otherT, i
nt step, |
| 2410 bool cancel) { |
| 2411 int otherTIndex = other->findT(otherT, this); |
| 2412 int next = other->nextExactSpan(otherTIndex, step); |
| 2413 int otherMin = SkTMin(otherTIndex, next); |
| 2414 int otherWind = other->span(otherMin).fWindValue; |
| 2415 if (otherWind == 0) { |
| 2416 return false; |
| 2417 } |
| 2418 SkASSERT(next >= 0); |
| 2419 if (end) { |
| 2420 int tIndex = count() - 1; |
| 2421 do { |
| 2422 SkOpSpan* test = &fTs[tIndex]; |
| 2423 SkASSERT(test->fT == 1); |
| 2424 if (test->fOther == other || test->fOtherT != 0) { |
| 2425 continue; |
| 2426 } |
| 2427 SkPoint startPt, endPt; |
| 2428 double endT; |
| 2429 if (findCoincidentMatch(test, other, otherTIndex, next, step, &start
Pt, &endPt, &endT)) { |
| 2430 SkOpSegment* match = test->fOther; |
| 2431 if (cancel) { |
| 2432 match->addTCancel(startPt, endPt, other); |
| 2433 } else { |
| 2434 match->addTCoincident(startPt, endPt, endT, other); |
| 2435 } |
| 2436 return true; |
| 2437 } |
| 2438 } while (fTs[--tIndex].fT == 1); |
| 2439 } else { |
| 2440 int tIndex = 0; |
| 2441 do { |
| 2442 SkOpSpan* test = &fTs[tIndex]; |
| 2443 SkASSERT(test->fT == 0); |
| 2444 if (test->fOther == other || test->fOtherT != 1) { |
| 2445 continue; |
| 2446 } |
| 2447 SkPoint startPt, endPt; |
| 2448 double endT; |
| 2449 if (findCoincidentMatch(test, other, otherTIndex, next, step, &start
Pt, &endPt, &endT)) { |
| 2450 SkOpSegment* match = test->fOther; |
| 2451 if (cancel) { |
| 2452 match->addTCancel(startPt, endPt, other); |
| 2453 } else { |
| 2454 match->addTCoincident(startPt, endPt, endT, other); |
| 2455 } |
| 2456 return true; |
| 2457 } |
| 2458 } while (fTs[++tIndex].fT == 0); |
| 2459 } |
| 2460 return false; |
| 2461 } |
| 2462 |
| 2302 // this span is excluded by the winding rule -- chase the ends | 2463 // this span is excluded by the winding rule -- chase the ends |
| 2303 // as long as they are unambiguous to mark connections as done | 2464 // as long as they are unambiguous to mark connections as done |
| 2304 // and give them the same winding value | 2465 // and give them the same winding value |
| 2305 SkOpSpan* SkOpSegment::markAndChaseDone(int index, int endIndex, int winding) { | 2466 SkOpSpan* SkOpSegment::markAndChaseDone(int index, int endIndex, int winding) { |
| 2306 int step = SkSign32(endIndex - index); | 2467 int step = SkSign32(endIndex - index); |
| 2307 int min = SkMin32(index, endIndex); | 2468 int min = SkMin32(index, endIndex); |
| 2308 markDone(min, winding); | 2469 markDone(min, winding); |
| 2309 SkOpSpan* last; | 2470 SkOpSpan* last; |
| 2310 SkOpSegment* other = this; | 2471 SkOpSegment* other = this; |
| 2311 while ((other = other->nextChase(&index, step, &min, &last))) { | 2472 while ((other = other->nextChase(&index, step, &min, &last))) { |
| (...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3011 } | 3172 } |
| 3012 return true; | 3173 return true; |
| 3013 } | 3174 } |
| 3014 | 3175 |
| 3015 void SkOpSegment::subDivideBounds(int start, int end, SkPathOpsBounds* bounds) c
onst { | 3176 void SkOpSegment::subDivideBounds(int start, int end, SkPathOpsBounds* bounds) c
onst { |
| 3016 SkPoint edge[4]; | 3177 SkPoint edge[4]; |
| 3017 subDivide(start, end, edge); | 3178 subDivide(start, end, edge); |
| 3018 (bounds->*SetCurveBounds[SkPathOpsVerbToPoints(fVerb)])(edge); | 3179 (bounds->*SetCurveBounds[SkPathOpsVerbToPoints(fVerb)])(edge); |
| 3019 } | 3180 } |
| 3020 | 3181 |
| 3021 bool SkOpSegment::isTiny(const SkOpAngle* angle) const { | |
| 3022 int start = angle->start(); | |
| 3023 int end = angle->end(); | |
| 3024 const SkOpSpan& mSpan = fTs[SkMin32(start, end)]; | |
| 3025 return mSpan.fTiny; | |
| 3026 } | |
| 3027 | |
| 3028 bool SkOpSegment::isTiny(int index) const { | |
| 3029 return fTs[index].fTiny; | |
| 3030 } | |
| 3031 | |
| 3032 void SkOpSegment::TrackOutsidePair(SkTArray<SkPoint, true>* outsidePts, const Sk
Point& endPt, | 3182 void SkOpSegment::TrackOutsidePair(SkTArray<SkPoint, true>* outsidePts, const Sk
Point& endPt, |
| 3033 const SkPoint& startPt) { | 3183 const SkPoint& startPt) { |
| 3034 int outCount = outsidePts->count(); | 3184 int outCount = outsidePts->count(); |
| 3035 if (outCount == 0 || endPt != (*outsidePts)[outCount - 2]) { | 3185 if (outCount == 0 || endPt != (*outsidePts)[outCount - 2]) { |
| 3036 outsidePts->push_back(endPt); | 3186 outsidePts->push_back(endPt); |
| 3037 outsidePts->push_back(startPt); | 3187 outsidePts->push_back(startPt); |
| 3038 } | 3188 } |
| 3039 } | 3189 } |
| 3040 | 3190 |
| 3041 void SkOpSegment::TrackOutside(SkTArray<SkPoint, true>* outsidePts, const SkPoin
t& startPt) { | 3191 void SkOpSegment::TrackOutside(SkTArray<SkPoint, true>* outsidePts, const SkPoin
t& startPt) { |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3551 SkASSERT(done == fDoneSpans); | 3701 SkASSERT(done == fDoneSpans); |
| 3552 #endif | 3702 #endif |
| 3553 } | 3703 } |
| 3554 | 3704 |
| 3555 #ifdef SK_DEBUG | 3705 #ifdef SK_DEBUG |
| 3556 void SkOpSegment::dumpPts() const { | 3706 void SkOpSegment::dumpPts() const { |
| 3557 int last = SkPathOpsVerbToPoints(fVerb); | 3707 int last = SkPathOpsVerbToPoints(fVerb); |
| 3558 SkDebugf("{{"); | 3708 SkDebugf("{{"); |
| 3559 int index = 0; | 3709 int index = 0; |
| 3560 do { | 3710 do { |
| 3561 SkDPoint::DumpSkPoint(fPts[index]); | 3711 SkDPoint::dump(fPts[index]); |
| 3562 SkDebugf(", "); | 3712 SkDebugf(", "); |
| 3563 } while (++index < last); | 3713 } while (++index < last); |
| 3564 SkDPoint::DumpSkPoint(fPts[index]); | 3714 SkDPoint::dump(fPts[index]); |
| 3565 SkDebugf("}}\n"); | 3715 SkDebugf("}}\n"); |
| 3566 } | 3716 } |
| 3567 | 3717 |
| 3568 void SkOpSegment::dumpDPts() const { | 3718 void SkOpSegment::dumpDPts() const { |
| 3569 int count = SkPathOpsVerbToPoints(fVerb); | 3719 int count = SkPathOpsVerbToPoints(fVerb); |
| 3570 SkDebugf("{{"); | 3720 SkDebugf("{{"); |
| 3571 int index = 0; | 3721 int index = 0; |
| 3572 do { | 3722 do { |
| 3573 SkDPoint dPt = {fPts[index].fX, fPts[index].fY}; | 3723 SkDPoint dPt = {fPts[index].fX, fPts[index].fY}; |
| 3574 dPt.dump(); | 3724 dPt.dump(); |
| 3575 if (index != count) { | 3725 if (index != count) { |
| 3576 SkDebugf(", "); | 3726 SkDebugf(", "); |
| 3577 } | 3727 } |
| 3578 } while (++index <= count); | 3728 } while (++index <= count); |
| 3579 SkDebugf("}}\n"); | 3729 SkDebugf("}}\n"); |
| 3580 } | 3730 } |
| 3581 | 3731 |
| 3582 void SkOpSegment::dumpSpans() const { | 3732 void SkOpSegment::dumpSpans() const { |
| 3583 int count = this->count(); | 3733 int count = this->count(); |
| 3584 for (int index = 0; index < count; ++index) { | 3734 for (int index = 0; index < count; ++index) { |
| 3585 const SkOpSpan& span = this->span(index); | 3735 const SkOpSpan& span = this->span(index); |
| 3586 SkDebugf("[%d] ", index); | 3736 SkDebugf("[%d] ", index); |
| 3587 span.dump(); | 3737 span.dump(); |
| 3588 } | 3738 } |
| 3589 } | 3739 } |
| 3590 #endif | 3740 #endif |
| OLD | NEW |