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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 } | 126 } |
127 { | 127 { |
128 const SkPoint& xy = xyAtT(&span); | 128 const SkPoint& xy = xyAtT(&span); |
129 if (topPt.fY > xy.fY || (topPt.fY == xy.fY && topPt.fX > xy.fX)) { | 129 if (topPt.fY > xy.fY || (topPt.fY == xy.fY && topPt.fX > xy.fX)) { |
130 topPt = xy; | 130 topPt = xy; |
131 if (firstT) { | 131 if (firstT) { |
132 *firstT = index; | 132 *firstT = index; |
133 } | 133 } |
134 } | 134 } |
135 if (fVerb != SkPath::kLine_Verb && !lastDone) { | 135 if (fVerb != SkPath::kLine_Verb && !lastDone) { |
136 SkPoint curveTop = (*CurveTop[fVerb])(fPts, lastT, span.fT); | 136 SkPoint curveTop = (*CurveTop[SkPathOpsVerbToPoints(fVerb)])(fPt
s, lastT, span.fT); |
137 if (topPt.fY > curveTop.fY || (topPt.fY == curveTop.fY | 137 if (topPt.fY > curveTop.fY || (topPt.fY == curveTop.fY |
138 && topPt.fX > curveTop.fX)) { | 138 && topPt.fX > curveTop.fX)) { |
139 topPt = curveTop; | 139 topPt = curveTop; |
140 if (firstT) { | 140 if (firstT) { |
141 *firstT = index; | 141 *firstT = index; |
142 } | 142 } |
143 } | 143 } |
144 } | 144 } |
145 lastT = span.fT; | 145 lastT = span.fT; |
146 } | 146 } |
(...skipping 56 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 SkPoint angle0Pt = (*CurvePointAtT[SkPathOpsVerbToPoints(angles[0].verb(
))])(angles[0].pts(), |
214 (*angles[0].spans())[angles[0].start()].fT); | 214 (*angles[0].spans())[angles[0].start()].fT); |
215 SkPoint newPt = (*CurvePointAtT[fVerb])(fPts, fTs[start].fT); | 215 SkPoint newPt = (*CurvePointAtT[SkPathOpsVerbToPoints(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); |
225 } | 225 } |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 if (lastT < 0 || (start == 0 && end == lastT) || (start == lastT && end == 0
)) { | 347 if (lastT < 0 || (start == 0 && end == lastT) || (start == lastT && end == 0
)) { |
348 ePtr = fPts; | 348 ePtr = fPts; |
349 } else { | 349 } else { |
350 // OPTIMIZE? if not active, skip remainder and return xyAtT(end) | 350 // OPTIMIZE? if not active, skip remainder and return xyAtT(end) |
351 subDivide(start, end, edge); | 351 subDivide(start, end, edge); |
352 ePtr = edge; | 352 ePtr = edge; |
353 } | 353 } |
354 if (active) { | 354 if (active) { |
355 bool reverse = ePtr == fPts && start != 0; | 355 bool reverse = ePtr == fPts && start != 0; |
356 if (reverse) { | 356 if (reverse) { |
357 path->deferredMoveLine(ePtr[fVerb]); | 357 path->deferredMoveLine(ePtr[SkPathOpsVerbToPoints(fVerb)]); |
358 switch (fVerb) { | 358 switch (fVerb) { |
359 case SkPath::kLine_Verb: | 359 case SkPath::kLine_Verb: |
360 path->deferredLine(ePtr[0]); | 360 path->deferredLine(ePtr[0]); |
361 break; | 361 break; |
362 case SkPath::kQuad_Verb: | 362 case SkPath::kQuad_Verb: |
363 path->quadTo(ePtr[1], ePtr[0]); | 363 path->quadTo(ePtr[1], ePtr[0]); |
364 break; | 364 break; |
365 case SkPath::kCubic_Verb: | 365 case SkPath::kCubic_Verb: |
366 path->cubicTo(ePtr[2], ePtr[1], ePtr[0]); | 366 path->cubicTo(ePtr[2], ePtr[1], ePtr[0]); |
367 break; | 367 break; |
(...skipping 11 matching lines...) Expand all Loading... |
379 path->quadTo(ePtr[1], ePtr[2]); | 379 path->quadTo(ePtr[1], ePtr[2]); |
380 break; | 380 break; |
381 case SkPath::kCubic_Verb: | 381 case SkPath::kCubic_Verb: |
382 path->cubicTo(ePtr[1], ePtr[2], ePtr[3]); | 382 path->cubicTo(ePtr[1], ePtr[2], ePtr[3]); |
383 break; | 383 break; |
384 default: | 384 default: |
385 SkASSERT(0); | 385 SkASSERT(0); |
386 } | 386 } |
387 } | 387 } |
388 } | 388 } |
389 // return ePtr[fVerb]; | 389 // return ePtr[SkPathOpsVerbToPoints(fVerb)]; |
390 } | 390 } |
391 | 391 |
392 void SkOpSegment::addLine(const SkPoint pts[2], bool operand, bool evenOdd) { | 392 void SkOpSegment::addLine(const SkPoint pts[2], bool operand, bool evenOdd) { |
393 init(pts, SkPath::kLine_Verb, operand, evenOdd); | 393 init(pts, SkPath::kLine_Verb, operand, evenOdd); |
394 fBounds.set(pts, 2); | 394 fBounds.set(pts, 2); |
395 } | 395 } |
396 | 396 |
397 // add 2 to edge or out of range values to get T extremes | 397 // add 2 to edge or out of range values to get T extremes |
398 void SkOpSegment::addOtherT(int index, double otherT, int otherIndex) { | 398 void SkOpSegment::addOtherT(int index, double otherT, int otherIndex) { |
399 SkOpSpan& span = fTs[index]; | 399 SkOpSpan& span = fTs[index]; |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 return bestTIndex; | 972 return bestTIndex; |
973 } | 973 } |
974 if (fBounds.fLeft == fBounds.fRight) { | 974 if (fBounds.fLeft == fBounds.fRight) { |
975 // if vertical, and directly above test point, wait for another one | 975 // if vertical, and directly above test point, wait for another one |
976 return AlmostEqualUlps(basePt.fX, fBounds.fLeft) ? SK_MinS32 : bestTInde
x; | 976 return AlmostEqualUlps(basePt.fX, fBounds.fLeft) ? SK_MinS32 : bestTInde
x; |
977 } | 977 } |
978 // intersect ray starting at basePt with edge | 978 // intersect ray starting at basePt with edge |
979 SkIntersections intersections; | 979 SkIntersections intersections; |
980 // OPTIMIZE: use specialty function that intersects ray with curve, | 980 // OPTIMIZE: use specialty function that intersects ray with curve, |
981 // returning t values only for curve (we don't care about t on ray) | 981 // returning t values only for curve (we don't care about t on ray) |
982 int pts = (intersections.*CurveVertical[fVerb])(fPts, top, bottom, basePt.fX
, false); | 982 int pts = (intersections.*CurveVertical[SkPathOpsVerbToPoints(fVerb)])(fPts,
top, bottom, basePt.fX, false); |
983 if (pts == 0 || (current && pts == 1)) { | 983 if (pts == 0 || (current && pts == 1)) { |
984 return bestTIndex; | 984 return bestTIndex; |
985 } | 985 } |
986 if (current) { | 986 if (current) { |
987 SkASSERT(pts > 1); | 987 SkASSERT(pts > 1); |
988 int closestIdx = 0; | 988 int closestIdx = 0; |
989 double closest = fabs(intersections[0][0] - mid); | 989 double closest = fabs(intersections[0][0] - mid); |
990 for (int idx = 1; idx < pts; ++idx) { | 990 for (int idx = 1; idx < pts; ++idx) { |
991 double test = fabs(intersections[0][idx] - mid); | 991 double test = fabs(intersections[0][idx] - mid); |
992 if (closest > test) { | 992 if (closest > test) { |
993 closestIdx = idx; | 993 closestIdx = idx; |
994 closest = test; | 994 closest = test; |
995 } | 995 } |
996 } | 996 } |
997 intersections.quickRemoveOne(closestIdx, --pts); | 997 intersections.quickRemoveOne(closestIdx, --pts); |
998 } | 998 } |
999 double bestT = -1; | 999 double bestT = -1; |
1000 for (int index = 0; index < pts; ++index) { | 1000 for (int index = 0; index < pts; ++index) { |
1001 double foundT = intersections[0][index]; | 1001 double foundT = intersections[0][index]; |
1002 if (approximately_less_than_zero(foundT) | 1002 if (approximately_less_than_zero(foundT) |
1003 || approximately_greater_than_one(foundT)) { | 1003 || approximately_greater_than_one(foundT)) { |
1004 continue; | 1004 continue; |
1005 } | 1005 } |
1006 SkScalar testY = (*CurvePointAtT[fVerb])(fPts, foundT).fY; | 1006 SkScalar testY = (*CurvePointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, fo
undT).fY; |
1007 if (approximately_negative(testY - *bestY) | 1007 if (approximately_negative(testY - *bestY) |
1008 || approximately_negative(basePt.fY - testY)) { | 1008 || approximately_negative(basePt.fY - testY)) { |
1009 continue; | 1009 continue; |
1010 } | 1010 } |
1011 if (pts > 1 && fVerb == SkPath::kLine_Verb) { | 1011 if (pts > 1 && fVerb == SkPath::kLine_Verb) { |
1012 return SK_MinS32; // if the intersection is edge on, wait for anoth
er one | 1012 return SK_MinS32; // if the intersection is edge on, wait for anoth
er one |
1013 } | 1013 } |
1014 if (fVerb > SkPath::kLine_Verb) { | 1014 if (fVerb > SkPath::kLine_Verb) { |
1015 SkScalar dx = (*CurveSlopeAtT[fVerb])(fPts, foundT).fX; | 1015 SkScalar dx = (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, f
oundT).fX; |
1016 if (approximately_zero(dx)) { | 1016 if (approximately_zero(dx)) { |
1017 return SK_MinS32; // hit vertical, wait for another one | 1017 return SK_MinS32; // hit vertical, wait for another one |
1018 } | 1018 } |
1019 } | 1019 } |
1020 *bestY = testY; | 1020 *bestY = testY; |
1021 bestT = foundT; | 1021 bestT = foundT; |
1022 } | 1022 } |
1023 if (bestT < 0) { | 1023 if (bestT < 0) { |
1024 return bestTIndex; | 1024 return bestTIndex; |
1025 } | 1025 } |
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1731 the left or the right of vertical. This determines if we need to add the span's | 1731 the left or the right of vertical. This determines if we need to add the span's |
1732 sign or not. However, this isn't enough. | 1732 sign or not. However, this isn't enough. |
1733 If the supplied sign (winding) is zero, then we didn't hit another vertical span
, so dx is needed. | 1733 If the supplied sign (winding) is zero, then we didn't hit another vertical span
, so dx is needed. |
1734 If there was a winding, then it may or may not need adjusting. If the span the w
inding was borrowed | 1734 If there was a winding, then it may or may not need adjusting. If the span the w
inding was borrowed |
1735 from has the same x direction as this span, the winding should change. If the dx
is opposite, then | 1735 from has the same x direction as this span, the winding should change. If the dx
is opposite, then |
1736 the same winding is shared by both. | 1736 the same winding is shared by both. |
1737 */ | 1737 */ |
1738 void SkOpSegment::initWinding(int start, int end, double tHit, int winding, SkSc
alar hitDx, | 1738 void SkOpSegment::initWinding(int start, int end, double tHit, int winding, SkSc
alar hitDx, |
1739 int oppWind, SkScalar hitOppDx) { | 1739 int oppWind, SkScalar hitOppDx) { |
1740 SkASSERT(hitDx || !winding); | 1740 SkASSERT(hitDx || !winding); |
1741 SkScalar dx = (*CurveSlopeAtT[fVerb])(fPts, tHit).fX; | 1741 SkScalar dx = (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, tHit).fX; |
1742 SkASSERT(dx); | 1742 SkASSERT(dx); |
1743 int windVal = windValue(SkMin32(start, end)); | 1743 int windVal = windValue(SkMin32(start, end)); |
1744 #if DEBUG_WINDING_AT_T | 1744 #if DEBUG_WINDING_AT_T |
1745 SkDebugf("%s oldWinding=%d hitDx=%c dx=%c windVal=%d", __FUNCTION__, winding
, | 1745 SkDebugf("%s oldWinding=%d hitDx=%c dx=%c windVal=%d", __FUNCTION__, winding
, |
1746 hitDx ? hitDx > 0 ? '+' : '-' : '0', dx > 0 ? '+' : '-', windVal); | 1746 hitDx ? hitDx > 0 ? '+' : '-' : '0', dx > 0 ? '+' : '-', windVal); |
1747 #endif | 1747 #endif |
1748 if (!winding) { | 1748 if (!winding) { |
1749 winding = dx < 0 ? windVal : -windVal; | 1749 winding = dx < 0 ? windVal : -windVal; |
1750 } else if (winding * dx < 0) { | 1750 } else if (winding * dx < 0) { |
1751 int sideWind = winding + (dx < 0 ? windVal : -windVal); | 1751 int sideWind = winding + (dx < 0 ? windVal : -windVal); |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2074 #endif | 2074 #endif |
2075 span.fOppSum = oppWinding; | 2075 span.fOppSum = oppWinding; |
2076 return &span; | 2076 return &span; |
2077 } | 2077 } |
2078 | 2078 |
2079 // from http://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of
-polygon-points-are-in-clockwise-order | 2079 // from http://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of
-polygon-points-are-in-clockwise-order |
2080 bool SkOpSegment::clockwise(int tStart, int tEnd) const { | 2080 bool SkOpSegment::clockwise(int tStart, int tEnd) const { |
2081 SkASSERT(fVerb != SkPath::kLine_Verb); | 2081 SkASSERT(fVerb != SkPath::kLine_Verb); |
2082 SkPoint edge[4]; | 2082 SkPoint edge[4]; |
2083 subDivide(tStart, tEnd, edge); | 2083 subDivide(tStart, tEnd, edge); |
2084 double sum = (edge[0].fX - edge[fVerb].fX) * (edge[0].fY + edge[fVerb].fY); | 2084 double sum = (edge[0].fX - edge[SkPathOpsVerbToPoints(fVerb)].fX) * (edge[0]
.fY + edge[SkPathOpsVerbToPoints(fVerb)].fY); |
2085 if (fVerb == SkPath::kCubic_Verb) { | 2085 if (fVerb == SkPath::kCubic_Verb) { |
2086 SkScalar lesser = SkTMin<SkScalar>(edge[0].fY, edge[3].fY); | 2086 SkScalar lesser = SkTMin<SkScalar>(edge[0].fY, edge[3].fY); |
2087 if (edge[1].fY < lesser && edge[2].fY < lesser) { | 2087 if (edge[1].fY < lesser && edge[2].fY < lesser) { |
2088 SkDLine tangent1 = {{ {edge[0].fX, edge[0].fY}, {edge[1].fX, edge[1]
.fY} }}; | 2088 SkDLine tangent1 = {{ {edge[0].fX, edge[0].fY}, {edge[1].fX, edge[1]
.fY} }}; |
2089 SkDLine tangent2 = {{ {edge[2].fX, edge[2].fY}, {edge[3].fX, edge[3]
.fY} }}; | 2089 SkDLine tangent2 = {{ {edge[2].fX, edge[2].fY}, {edge[3].fX, edge[3]
.fY} }}; |
2090 if (SkIntersections::Test(tangent1, tangent2)) { | 2090 if (SkIntersections::Test(tangent1, tangent2)) { |
2091 SkPoint topPt = cubic_top(fPts, fTs[tStart].fT, fTs[tEnd].fT); | 2091 SkPoint topPt = cubic_top(fPts, fTs[tStart].fT, fTs[tEnd].fT); |
2092 sum += (topPt.fX - edge[0].fX) * (topPt.fY + edge[0].fY); | 2092 sum += (topPt.fX - edge[0].fX) * (topPt.fY + edge[0].fY); |
2093 sum += (edge[3].fX - topPt.fX) * (edge[3].fY + topPt.fY); | 2093 sum += (edge[3].fX - topPt.fX) * (edge[3].fY + topPt.fY); |
2094 return sum <= 0; | 2094 return sum <= 0; |
2095 } | 2095 } |
2096 } | 2096 } |
2097 } | 2097 } |
2098 for (int idx = 0; idx < fVerb; ++idx){ | 2098 for (int idx = 0; idx < SkPathOpsVerbToPoints(fVerb); ++idx){ |
2099 sum += (edge[idx + 1].fX - edge[idx].fX) * (edge[idx + 1].fY + edge[idx]
.fY); | 2099 sum += (edge[idx + 1].fX - edge[idx].fX) * (edge[idx + 1].fY + edge[idx]
.fY); |
2100 } | 2100 } |
2101 return sum <= 0; | 2101 return sum <= 0; |
2102 } | 2102 } |
2103 | 2103 |
2104 bool SkOpSegment::monotonicInY(int tStart, int tEnd) const { | 2104 bool SkOpSegment::monotonicInY(int tStart, int tEnd) const { |
2105 if (fVerb == SkPath::kLine_Verb) { | 2105 if (fVerb == SkPath::kLine_Verb) { |
2106 return false; | 2106 return false; |
2107 } | 2107 } |
2108 if (fVerb == SkPath::kQuad_Verb) { | 2108 if (fVerb == SkPath::kQuad_Verb) { |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2358 for (angleIndex = 0; angleIndex < angleCount; ++angleIndex) { | 2358 for (angleIndex = 0; angleIndex < angleCount; ++angleIndex) { |
2359 const SkOpAngle& angle = angles[angleIndex]; | 2359 const SkOpAngle& angle = angles[angleIndex]; |
2360 angle.segment()->markUnsortable(angle.start(), angle.end()); | 2360 angle.segment()->markUnsortable(angle.start(), angle.end()); |
2361 } | 2361 } |
2362 } | 2362 } |
2363 return sortable; | 2363 return sortable; |
2364 } | 2364 } |
2365 | 2365 |
2366 void SkOpSegment::subDivide(int start, int end, SkPoint edge[4]) const { | 2366 void SkOpSegment::subDivide(int start, int end, SkPoint edge[4]) const { |
2367 edge[0] = fTs[start].fPt; | 2367 edge[0] = fTs[start].fPt; |
2368 edge[fVerb] = fTs[end].fPt; | 2368 edge[SkPathOpsVerbToPoints(fVerb)] = fTs[end].fPt; |
2369 if (fVerb == SkPath::kQuad_Verb || fVerb == SkPath::kCubic_Verb) { | 2369 if (fVerb == SkPath::kQuad_Verb || fVerb == SkPath::kCubic_Verb) { |
2370 SkDPoint sub[2] = {{ edge[0].fX, edge[0].fY}, {edge[fVerb].fX, edge[fVer
b].fY }}; | 2370 SkDPoint sub[2] = {{ edge[0].fX, edge[0].fY}, {edge[SkPathOpsVerbToPoint
s(fVerb)].fX, edge[SkPathOpsVerbToPoints(fVerb)].fY }}; |
2371 if (fVerb == SkPath::kQuad_Verb) { | 2371 if (fVerb == SkPath::kQuad_Verb) { |
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::subDivideBounds(int start, int end, SkPathOpsBounds* bounds) c
onst { | 2382 void SkOpSegment::subDivideBounds(int start, int end, SkPathOpsBounds* bounds) c
onst { |
2383 SkPoint edge[4]; | 2383 SkPoint edge[4]; |
2384 subDivide(start, end, edge); | 2384 subDivide(start, end, edge); |
2385 (bounds->*SetCurveBounds[fVerb])(edge); | 2385 (bounds->*SetCurveBounds[SkPathOpsVerbToPoints(fVerb)])(edge); |
2386 } | 2386 } |
2387 | 2387 |
2388 bool SkOpSegment::tiny(const SkOpAngle* angle) const { | 2388 bool SkOpSegment::tiny(const SkOpAngle* angle) const { |
2389 int start = angle->start(); | 2389 int start = angle->start(); |
2390 int end = angle->end(); | 2390 int end = angle->end(); |
2391 const SkOpSpan& mSpan = fTs[SkMin32(start, end)]; | 2391 const SkOpSpan& mSpan = fTs[SkMin32(start, end)]; |
2392 return mSpan.fTiny; | 2392 return mSpan.fTiny; |
2393 } | 2393 } |
2394 | 2394 |
2395 void SkOpSegment::TrackOutside(SkTDArray<double>* outsideTs, double end, double
start) { | 2395 void SkOpSegment::TrackOutside(SkTDArray<double>* outsideTs, double end, double
start) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2466 if (approximately_zero(tHit - t(tIndex))) { // if we hit the end of a span,
disregard | 2466 if (approximately_zero(tHit - t(tIndex))) { // if we hit the end of a span,
disregard |
2467 return SK_MinS32; | 2467 return SK_MinS32; |
2468 } | 2468 } |
2469 int winding = crossOpp ? oppSum(tIndex) : windSum(tIndex); | 2469 int winding = crossOpp ? oppSum(tIndex) : windSum(tIndex); |
2470 SkASSERT(winding != SK_MinS32); | 2470 SkASSERT(winding != SK_MinS32); |
2471 int windVal = crossOpp ? oppValue(tIndex) : windValue(tIndex); | 2471 int windVal = crossOpp ? oppValue(tIndex) : windValue(tIndex); |
2472 #if DEBUG_WINDING_AT_T | 2472 #if DEBUG_WINDING_AT_T |
2473 SkDebugf("%s oldWinding=%d windValue=%d", __FUNCTION__, winding, windVal); | 2473 SkDebugf("%s oldWinding=%d windValue=%d", __FUNCTION__, winding, windVal); |
2474 #endif | 2474 #endif |
2475 // see if a + change in T results in a +/- change in X (compute x'(T)) | 2475 // see if a + change in T results in a +/- change in X (compute x'(T)) |
2476 *dx = (*CurveSlopeAtT[fVerb])(fPts, tHit).fX; | 2476 *dx = (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, tHit).fX; |
2477 if (fVerb > SkPath::kLine_Verb && approximately_zero(*dx)) { | 2477 if (fVerb > SkPath::kLine_Verb && approximately_zero(*dx)) { |
2478 *dx = fPts[2].fX - fPts[1].fX - *dx; | 2478 *dx = fPts[2].fX - fPts[1].fX - *dx; |
2479 } | 2479 } |
2480 if (*dx == 0) { | 2480 if (*dx == 0) { |
2481 #if DEBUG_WINDING_AT_T | 2481 #if DEBUG_WINDING_AT_T |
2482 SkDebugf(" dx=0 winding=SK_MinS32\n"); | 2482 SkDebugf(" dx=0 winding=SK_MinS32\n"); |
2483 #endif | 2483 #endif |
2484 return SK_MinS32; | 2484 return SK_MinS32; |
2485 } | 2485 } |
2486 if (winding * *dx > 0) { // if same signs, result is negative | 2486 if (winding * *dx > 0) { // if same signs, result is negative |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2604 SkASSERT(i < fTs.count() - 1); | 2604 SkASSERT(i < fTs.count() - 1); |
2605 #if DEBUG_ACTIVE_SPANS_SHORT_FORM | 2605 #if DEBUG_ACTIVE_SPANS_SHORT_FORM |
2606 if (lastId == fID && lastT == fTs[i].fT) { | 2606 if (lastId == fID && lastT == fTs[i].fT) { |
2607 continue; | 2607 continue; |
2608 } | 2608 } |
2609 lastId = fID; | 2609 lastId = fID; |
2610 lastT = fTs[i].fT; | 2610 lastT = fTs[i].fT; |
2611 #endif | 2611 #endif |
2612 SkDebugf("%s id=%d", __FUNCTION__, fID); | 2612 SkDebugf("%s id=%d", __FUNCTION__, fID); |
2613 SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY); | 2613 SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY); |
2614 for (int vIndex = 1; vIndex <= fVerb; ++vIndex) { | 2614 for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) { |
2615 SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY); | 2615 SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY); |
2616 } | 2616 } |
2617 const SkOpSpan* span = &fTs[i]; | 2617 const SkOpSpan* span = &fTs[i]; |
2618 SkDebugf(") t=%1.9g (%1.9g,%1.9g)", span->fT, xAtT(span), yAtT(span)); | 2618 SkDebugf(") t=%1.9g (%1.9g,%1.9g)", span->fT, xAtT(span), yAtT(span)); |
2619 int iEnd = i + 1; | 2619 int iEnd = i + 1; |
2620 while (fTs[iEnd].fT < 1 && approximately_equal(fTs[i].fT, fTs[iEnd].fT))
{ | 2620 while (fTs[iEnd].fT < 1 && approximately_equal(fTs[i].fT, fTs[iEnd].fT))
{ |
2621 ++iEnd; | 2621 ++iEnd; |
2622 } | 2622 } |
2623 SkDebugf(" tEnd=%1.9g", fTs[iEnd].fT); | 2623 SkDebugf(" tEnd=%1.9g", fTs[iEnd].fT); |
2624 const SkOpSegment* other = fTs[i].fOther; | 2624 const SkOpSegment* other = fTs[i].fOther; |
2625 SkDebugf(" other=%d otherT=%1.9g otherIndex=%d windSum=", | 2625 SkDebugf(" other=%d otherT=%1.9g otherIndex=%d windSum=", |
2626 other->fID, fTs[i].fOtherT, fTs[i].fOtherIndex); | 2626 other->fID, fTs[i].fOtherT, fTs[i].fOtherIndex); |
2627 if (fTs[i].fWindSum == SK_MinS32) { | 2627 if (fTs[i].fWindSum == SK_MinS32) { |
2628 SkDebugf("?"); | 2628 SkDebugf("?"); |
2629 } else { | 2629 } else { |
2630 SkDebugf("%d", fTs[i].fWindSum); | 2630 SkDebugf("%d", fTs[i].fWindSum); |
2631 } | 2631 } |
2632 SkDebugf(" windValue=%d oppValue=%d\n", fTs[i].fWindValue, fTs[i].fOppVa
lue); | 2632 SkDebugf(" windValue=%d oppValue=%d\n", fTs[i].fWindValue, fTs[i].fOppVa
lue); |
2633 } | 2633 } |
2634 } | 2634 } |
2635 #endif | 2635 #endif |
2636 | 2636 |
2637 | 2637 |
2638 #if DEBUG_MARK_DONE || DEBUG_UNSORTABLE | 2638 #if DEBUG_MARK_DONE || DEBUG_UNSORTABLE |
2639 void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int
winding) { | 2639 void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int
winding) { |
2640 const SkPoint& pt = xyAtT(&span); | 2640 const SkPoint& pt = xyAtT(&span); |
2641 SkDebugf("%s id=%d", fun, fID); | 2641 SkDebugf("%s id=%d", fun, fID); |
2642 SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY); | 2642 SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY); |
2643 for (int vIndex = 1; vIndex <= fVerb; ++vIndex) { | 2643 for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) { |
2644 SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY); | 2644 SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY); |
2645 } | 2645 } |
2646 SkASSERT(&span == &span.fOther->fTs[span.fOtherIndex].fOther-> | 2646 SkASSERT(&span == &span.fOther->fTs[span.fOtherIndex].fOther-> |
2647 fTs[span.fOther->fTs[span.fOtherIndex].fOtherIndex]); | 2647 fTs[span.fOther->fTs[span.fOtherIndex].fOtherIndex]); |
2648 SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=%d windSum=", | 2648 SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=%d windSum=", |
2649 span.fT, span.fOther->fTs[span.fOtherIndex].fOtherIndex, pt.fX, pt.f
Y, | 2649 span.fT, span.fOther->fTs[span.fOtherIndex].fOtherIndex, pt.fX, pt.f
Y, |
2650 (&span)[1].fT, winding); | 2650 (&span)[1].fT, winding); |
2651 if (span.fWindSum == SK_MinS32) { | 2651 if (span.fWindSum == SK_MinS32) { |
2652 SkDebugf("?"); | 2652 SkDebugf("?"); |
2653 } else { | 2653 } else { |
2654 SkDebugf("%d", span.fWindSum); | 2654 SkDebugf("%d", span.fWindSum); |
2655 } | 2655 } |
2656 SkDebugf(" windValue=%d\n", span.fWindValue); | 2656 SkDebugf(" windValue=%d\n", span.fWindValue); |
2657 } | 2657 } |
2658 | 2658 |
2659 void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int
winding, | 2659 void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int
winding, |
2660 int oppWinding) { | 2660 int oppWinding) { |
2661 const SkPoint& pt = xyAtT(&span); | 2661 const SkPoint& pt = xyAtT(&span); |
2662 SkDebugf("%s id=%d", fun, fID); | 2662 SkDebugf("%s id=%d", fun, fID); |
2663 SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY); | 2663 SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY); |
2664 for (int vIndex = 1; vIndex <= fVerb; ++vIndex) { | 2664 for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) { |
2665 SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY); | 2665 SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY); |
2666 } | 2666 } |
2667 SkASSERT(&span == &span.fOther->fTs[span.fOtherIndex].fOther-> | 2667 SkASSERT(&span == &span.fOther->fTs[span.fOtherIndex].fOther-> |
2668 fTs[span.fOther->fTs[span.fOtherIndex].fOtherIndex]); | 2668 fTs[span.fOther->fTs[span.fOtherIndex].fOtherIndex]); |
2669 SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=%d newOppSum=%d
oppSum=", | 2669 SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=%d newOppSum=%d
oppSum=", |
2670 span.fT, span.fOther->fTs[span.fOtherIndex].fOtherIndex, pt.fX, pt.f
Y, | 2670 span.fT, span.fOther->fTs[span.fOtherIndex].fOtherIndex, pt.fX, pt.f
Y, |
2671 (&span)[1].fT, winding, oppWinding); | 2671 (&span)[1].fT, winding, oppWinding); |
2672 if (span.fOppSum == SK_MinS32) { | 2672 if (span.fOppSum == SK_MinS32) { |
2673 SkDebugf("?"); | 2673 SkDebugf("?"); |
2674 } else { | 2674 } else { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2730 if (oppoSign) { | 2730 if (oppoSign) { |
2731 oppLastSum = oppWindSum; | 2731 oppLastSum = oppWindSum; |
2732 oppWindSum -= oppoSign; | 2732 oppWindSum -= oppoSign; |
2733 } | 2733 } |
2734 } | 2734 } |
2735 } | 2735 } |
2736 SkDebugf("%s [%d] %s", __FUNCTION__, index, | 2736 SkDebugf("%s [%d] %s", __FUNCTION__, index, |
2737 angle.unsortable() ? "*** UNSORTABLE *** " : ""); | 2737 angle.unsortable() ? "*** UNSORTABLE *** " : ""); |
2738 #if COMPACT_DEBUG_SORT | 2738 #if COMPACT_DEBUG_SORT |
2739 SkDebugf("id=%d %s start=%d (%1.9g,%,1.9g) end=%d (%1.9g,%,1.9g)", | 2739 SkDebugf("id=%d %s start=%d (%1.9g,%,1.9g) end=%d (%1.9g,%,1.9g)", |
2740 segment.fID, kLVerbStr[segment.fVerb], | 2740 segment.fID, kLVerbStr[SkPathOpsVerbToPoints(segment.fVerb)], |
2741 start, segment.xAtT(&sSpan), segment.yAtT(&sSpan), end, | 2741 start, segment.xAtT(&sSpan), segment.yAtT(&sSpan), end, |
2742 segment.xAtT(&eSpan), segment.yAtT(&eSpan)); | 2742 segment.xAtT(&eSpan), segment.yAtT(&eSpan)); |
2743 #else | 2743 #else |
2744 switch (segment.fVerb) { | 2744 switch (segment.fVerb) { |
2745 case SkPath::kLine_Verb: | 2745 case SkPath::kLine_Verb: |
2746 SkDebugf(LINE_DEBUG_STR, LINE_DEBUG_DATA(segment.fPts)); | 2746 SkDebugf(LINE_DEBUG_STR, LINE_DEBUG_DATA(segment.fPts)); |
2747 break; | 2747 break; |
2748 case SkPath::kQuad_Verb: | 2748 case SkPath::kQuad_Verb: |
2749 SkDebugf(QUAD_DEBUG_STR, QUAD_DEBUG_DATA(segment.fPts)); | 2749 SkDebugf(QUAD_DEBUG_STR, QUAD_DEBUG_DATA(segment.fPts)); |
2750 break; | 2750 break; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2820 sum += fTs[i].fWindValue; | 2820 sum += fTs[i].fWindValue; |
2821 slots[fTs[i].fOther->fID - 1] = as_digit(fTs[i].fWindValue); | 2821 slots[fTs[i].fOther->fID - 1] = as_digit(fTs[i].fWindValue); |
2822 sum += fTs[i].fOppValue; | 2822 sum += fTs[i].fOppValue; |
2823 slots[slotCount + fTs[i].fOther->fID - 1] = as_digit(fTs[i].fOppValue); | 2823 slots[slotCount + fTs[i].fOther->fID - 1] = as_digit(fTs[i].fOppValue); |
2824 } | 2824 } |
2825 SkDebugf("%s id=%2d %.*s | %.*s\n", __FUNCTION__, fID, slotCount, slots.begi
n(), slotCount, | 2825 SkDebugf("%s id=%2d %.*s | %.*s\n", __FUNCTION__, fID, slotCount, slots.begi
n(), slotCount, |
2826 slots.begin() + slotCount); | 2826 slots.begin() + slotCount); |
2827 return sum; | 2827 return sum; |
2828 } | 2828 } |
2829 #endif | 2829 #endif |
OLD | NEW |