| 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 "SkOpAngle.h" | 8 #include "SkOpAngle.h" |
| 9 #include "SkOpSegment.h" | 9 #include "SkOpSegment.h" |
| 10 #include "SkPathOpsCurve.h" | 10 #include "SkPathOpsCurve.h" |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 SkOpAngle rhLonger = rh; | 113 SkOpAngle rhLonger = rh; |
| 114 if ((longer.lengthen(rh) | rhLonger.lengthen(*this)) // lengthen both | 114 if ((longer.lengthen(rh) | rhLonger.lengthen(*this)) // lengthen both |
| 115 && (fUnorderable || !longer.fUnorderable) | 115 && (fUnorderable || !longer.fUnorderable) |
| 116 && (rh.fUnorderable || !rhLonger.fUnorderable)) { | 116 && (rh.fUnorderable || !rhLonger.fUnorderable)) { |
| 117 #if DEBUG_ANGLE | 117 #if DEBUG_ANGLE |
| 118 bugOut.prepend(" "); | 118 bugOut.prepend(" "); |
| 119 #endif | 119 #endif |
| 120 return COMPARE_RESULT("10 longer.lengthen(rh) ...", longer < rhLonge
r); | 120 return COMPARE_RESULT("10 longer.lengthen(rh) ...", longer < rhLonge
r); |
| 121 } | 121 } |
| 122 } | 122 } |
| 123 SkPath::Verb verb = fSegment->verb(); |
| 124 SkPath::Verb rVerb = rh.fSegment->verb(); |
| 123 if (y_ry != 0) { // if they aren't coincident, look for a stable cross produ
ct | 125 if (y_ry != 0) { // if they aren't coincident, look for a stable cross produ
ct |
| 124 // at this point, y's are the same sign, neither is zero | 126 // at this point, y's are the same sign, neither is zero |
| 125 // and x's are the same sign, or one (or both) is zero | 127 // and x's are the same sign, or one (or both) is zero |
| 126 double x_ry = x * ry; | 128 double x_ry = x * ry; |
| 127 double rx_y = rx * y; | 129 double rx_y = rx * y; |
| 128 if (!fComputed && !rh.fComputed) { | 130 if (!fComputed && !rh.fComputed) { |
| 129 if (!AlmostEqualUlps(x_ry, rx_y)) { | 131 if (!SkDLine::NearRay(x, y, rx, ry) && x_ry != rx_y) { |
| 130 return COMPARE_RESULT("7 !fComputed && !rh.fComputed", x_ry < rx
_y); | 132 return COMPARE_RESULT("7 !fComputed && !rh.fComputed", x_ry < rx
_y); |
| 131 } | 133 } |
| 132 } else { | 134 } else { |
| 133 // if the vector was a result of subdividing a curve, see if it is s
table | 135 // if the vector was a result of subdividing a curve, see if it is s
table |
| 134 bool sloppy1 = x_ry < rx_y; | 136 bool sloppy1 = x_ry < rx_y; |
| 135 bool sloppy2 = !sloppy1; | 137 bool sloppy2 = !sloppy1; |
| 136 if ((!fComputed || calcSlop(x, y, rx, ry, &sloppy1)) | 138 if ((!fComputed || calcSlop(x, y, rx, ry, &sloppy1)) |
| 137 && (!rh.fComputed || rh.calcSlop(rx, ry, x, y, &sloppy2)) | 139 && (!rh.fComputed || rh.calcSlop(rx, ry, x, y, &sloppy2)) |
| 138 && sloppy1 != sloppy2) { | 140 && sloppy1 != sloppy2) { |
| 139 return COMPARE_RESULT("8 CalcSlop(x, y ...", sloppy1); | 141 return COMPARE_RESULT("8 CalcSlop(x, y ...", sloppy1); |
| 140 } | 142 } |
| 141 } | 143 } |
| 142 } | 144 } |
| 143 if (fSide * rh.fSide == 0) { | 145 if (fSide2 * rh.fSide2 == 0) { |
| 144 SkASSERT(fSide + rh.fSide != 0); // hitting this assert means coincidenc
e was undetected | 146 // SkASSERT(fSide2 + rh.fSide2 != 0); // hitting this assert means coinci
dence was undetected |
| 145 return COMPARE_RESULT("9 fSide * rh.fSide == 0 ...", fSide < rh.fSide); | 147 return COMPARE_RESULT("9a fSide2 * rh.fSide2 == 0 ...", fSide2 < rh.fSid
e2); |
| 146 } | 148 } |
| 147 // at this point, the initial tangent line is nearly coincident | 149 // at this point, the initial tangent line is nearly coincident |
| 148 // see if edges curl away from each other | 150 // see if edges curl away from each other |
| 149 if (fSide * rh.fSide < 0 && (!approximately_zero(fSide) || !approximately_ze
ro(rh.fSide))) { | 151 if (fSide * rh.fSide < 0 && (!approximately_zero(fSide) || !approximately_ze
ro(rh.fSide))) { |
| 150 return COMPARE_RESULT("9b fSide * rh.fSide < 0 ...", fSide < rh.fSide); | 152 return COMPARE_RESULT("9b fSide * rh.fSide < 0 ...", fSide < rh.fSide); |
| 151 } | 153 } |
| 152 if (fUnsortable || rh.fUnsortable) { | 154 if (fUnsortable || rh.fUnsortable) { |
| 153 // even with no solution, return a stable sort | 155 // even with no solution, return a stable sort |
| 154 return COMPARE_RESULT("11 fUnsortable || rh.fUnsortable", this < &rh); | 156 return COMPARE_RESULT("11 fUnsortable || rh.fUnsortable", this < &rh); |
| 155 } | 157 } |
| 156 SkPath::Verb verb = fSegment->verb(); | |
| 157 SkPath::Verb rVerb = rh.fSegment->verb(); | |
| 158 if ((verb == SkPath::kLine_Verb && approximately_zero(y) && approximately_ze
ro(x)) | 158 if ((verb == SkPath::kLine_Verb && approximately_zero(y) && approximately_ze
ro(x)) |
| 159 || (rVerb == SkPath::kLine_Verb | 159 || (rVerb == SkPath::kLine_Verb |
| 160 && approximately_zero(ry) && approximately_zero(rx))) { | 160 && approximately_zero(ry) && approximately_zero(rx))) { |
| 161 // See general unsortable comment below. This case can happen when | 161 // See general unsortable comment below. This case can happen when |
| 162 // one line has a non-zero change in t but no change in x and y. | 162 // one line has a non-zero change in t but no change in x and y. |
| 163 fUnsortable = true; | 163 fUnsortable = true; |
| 164 return COMPARE_RESULT("12 verb == SkPath::kLine_Verb ...", this < &rh); | 164 return COMPARE_RESULT("12 verb == SkPath::kLine_Verb ...", this < &rh); |
| 165 } | 165 } |
| 166 if (fSegment->isTiny(this) || rh.fSegment->isTiny(&rh)) { | 166 if (fSegment->isTiny(this) || rh.fSegment->isTiny(&rh)) { |
| 167 fUnsortable = true; | 167 fUnsortable = true; |
| 168 return COMPARE_RESULT("13 verb == fSegment->isTiny(this) ...", this < &r
h); | 168 return COMPARE_RESULT("13 verb == fSegment->isTiny(this) ...", this < &r
h); |
| 169 } | 169 } |
| 170 SkASSERT(verb >= SkPath::kQuad_Verb); | 170 SkASSERT(verb >= SkPath::kQuad_Verb); |
| 171 SkASSERT(rVerb >= SkPath::kQuad_Verb); | 171 SkASSERT(rVerb >= SkPath::kQuad_Verb); |
| 172 // FIXME: until I can think of something better, project a ray from the | 172 // FIXME: until I can think of something better, project a ray from the |
| 173 // end of the shorter tangent to midway between the end points | 173 // end of the shorter tangent to midway between the end points |
| 174 // through both curves and use the resulting angle to sort | 174 // through both curves and use the resulting angle to sort |
| 175 // FIXME: some of this setup can be moved to set() if it works, or cached if
it's expensive | 175 // FIXME: some of this setup can be moved to set() if it works, or cached if
it's expensive |
| 176 double len = fTangent1.normalSquared(); | 176 double len = fTangentPart.normalSquared(); |
| 177 double rlen = rh.fTangent1.normalSquared(); | 177 double rlen = rh.fTangentPart.normalSquared(); |
| 178 SkDLine ray; | 178 SkDLine ray; |
| 179 SkIntersections i, ri; | 179 SkIntersections i, ri; |
| 180 int roots, rroots; | 180 int roots, rroots; |
| 181 bool flip = false; | 181 bool flip = false; |
| 182 bool useThis; | 182 bool useThis; |
| 183 bool leftLessThanRight = fSide > 0; | 183 bool leftLessThanRight = fSide > 0; |
| 184 do { | 184 do { |
| 185 useThis = (len < rlen) ^ flip; | 185 useThis = (len < rlen) ^ flip; |
| 186 const SkDCubic& part = useThis ? fCurvePart : rh.fCurvePart; | 186 const SkDCubic& part = useThis ? fCurvePart : rh.fCurvePart; |
| 187 SkPath::Verb partVerb = useThis ? verb : rVerb; | 187 SkPath::Verb partVerb = useThis ? verb : rVerb; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 } | 262 } |
| 263 | 263 |
| 264 void SkOpAngle::set(const SkOpSegment* segment, int start, int end) { | 264 void SkOpAngle::set(const SkOpSegment* segment, int start, int end) { |
| 265 fSegment = segment; | 265 fSegment = segment; |
| 266 fStart = start; | 266 fStart = start; |
| 267 fEnd = end; | 267 fEnd = end; |
| 268 setSpans(); | 268 setSpans(); |
| 269 } | 269 } |
| 270 | 270 |
| 271 void SkOpAngle::setSpans() { | 271 void SkOpAngle::setSpans() { |
| 272 fUnorderable = false; | 272 fUnorderable = fSegment->isTiny(this); |
| 273 if (fSegment->verb() == SkPath::kLine_Verb) { | 273 fLastMarked = NULL; |
| 274 fUnsortable = false; | 274 fUnsortable = false; |
| 275 } else { | 275 const SkPoint* pts = fSegment->pts(); |
| 276 // if start-1 exists and is tiny, then start pt may have moved | 276 if (fSegment->verb() != SkPath::kLine_Verb) { |
| 277 int smaller = SkMin32(fStart, fEnd); | 277 fComputed = fSegment->subDivide(fStart, fEnd, &fCurvePart); |
| 278 int tinyCheck = smaller; | 278 fSegment->subDivide(fStart, fStart < fEnd ? fSegment->count() - 1 : 0, &
fCurveHalf); |
| 279 while (tinyCheck > 0 && fSegment->isTiny(tinyCheck - 1)) { | |
| 280 --tinyCheck; | |
| 281 } | |
| 282 if ((fUnsortable = smaller > 0 && tinyCheck == 0)) { | |
| 283 return; | |
| 284 } | |
| 285 int larger = SkMax32(fStart, fEnd); | |
| 286 tinyCheck = larger; | |
| 287 int max = fSegment->count() - 1; | |
| 288 while (tinyCheck < max && fSegment->isTiny(tinyCheck + 1)) { | |
| 289 ++tinyCheck; | |
| 290 } | |
| 291 if ((fUnsortable = larger < max && tinyCheck == max)) { | |
| 292 return; | |
| 293 } | |
| 294 } | 279 } |
| 295 fComputed = fSegment->subDivide(fStart, fEnd, &fCurvePart); | |
| 296 // FIXME: slight errors in subdivision cause sort trouble later on. As an ex
periment, try | 280 // FIXME: slight errors in subdivision cause sort trouble later on. As an ex
periment, try |
| 297 // rounding the curve part to float precision here | 281 // rounding the curve part to float precision here |
| 298 // fCurvePart.round(fSegment->verb()); | 282 // fCurvePart.round(fSegment->verb()); |
| 299 switch (fSegment->verb()) { | 283 switch (fSegment->verb()) { |
| 300 case SkPath::kLine_Verb: { | 284 case SkPath::kLine_Verb: { |
| 301 // OPTIMIZATION: for pure line compares, we never need fTangent1.c | 285 SkASSERT(fStart != fEnd); |
| 302 fTangent1.lineEndPoints(*SkTCast<SkDLine*>(&fCurvePart)); | 286 fCurvePart[0].set(pts[fStart > fEnd]); |
| 287 fCurvePart[1].set(pts[fStart < fEnd]); |
| 288 fComputed = false; |
| 289 // OPTIMIZATION: for pure line compares, we never need fTangentPart.c |
| 290 fTangentPart.lineEndPoints(*SkTCast<SkDLine*>(&fCurvePart)); |
| 303 fSide = 0; | 291 fSide = 0; |
| 292 fSide2 = 0; |
| 304 } break; | 293 } break; |
| 305 case SkPath::kQuad_Verb: { | 294 case SkPath::kQuad_Verb: { |
| 295 fSide2 = -fTangentHalf.quadPart(*SkTCast<SkDQuad*>(&fCurveHalf)); |
| 306 SkDQuad& quad = *SkTCast<SkDQuad*>(&fCurvePart); | 296 SkDQuad& quad = *SkTCast<SkDQuad*>(&fCurvePart); |
| 307 fTangent1.quadEndPoints(quad); | 297 fTangentPart.quadEndPoints(quad); |
| 308 fSide = -fTangent1.pointDistance(fCurvePart[2]); // not normalized -- c
ompare sign only | 298 fSide = -fTangentPart.pointDistance(fCurvePart[2]); // not normalized -
- compare sign only |
| 309 if (fComputed && dx() > 0 && approximately_zero(dy())) { | 299 if (fComputed && dx() > 0 && approximately_zero(dy())) { |
| 310 SkDCubic origCurve; // can't use segment's curve in place since it m
ay be flipped | 300 SkDCubic origCurve; // can't use segment's curve in place since it m
ay be flipped |
| 311 int last = fSegment->count() - 1; | 301 int last = fSegment->count() - 1; |
| 312 fSegment->subDivide(fStart < fEnd ? 0 : last, fStart < fEnd ? last :
0, &origCurve); | 302 fSegment->subDivide(fStart < fEnd ? 0 : last, fStart < fEnd ? last :
0, &origCurve); |
| 313 SkLineParameters origTan; | 303 SkLineParameters origTan; |
| 314 origTan.quadEndPoints(*SkTCast<SkDQuad*>(&origCurve)); | 304 origTan.quadEndPoints(*SkTCast<SkDQuad*>(&origCurve)); |
| 315 if ((fUnorderable = origTan.dx() <= 0 | 305 if (origTan.dx() <= 0 |
| 316 || (dy() != origTan.dy() && dy() * origTan.dy() <= 0))) { //
signs match? | 306 || (dy() != origTan.dy() && dy() * origTan.dy() <= 0)) { //
signs match? |
| 307 fUnorderable = true; |
| 317 return; | 308 return; |
| 318 } | 309 } |
| 319 } | 310 } |
| 320 } break; | 311 } break; |
| 321 case SkPath::kCubic_Verb: { | 312 case SkPath::kCubic_Verb: { |
| 322 fTangent1.cubicEndPoints(fCurvePart); | 313 double startT = fSegment->t(fStart); |
| 314 fSide2 = -fTangentHalf.cubicPart(fCurveHalf); |
| 315 fTangentPart.cubicEndPoints(fCurvePart); |
| 323 double testTs[4]; | 316 double testTs[4]; |
| 324 // OPTIMIZATION: keep inflections precomputed with cubic segment? | 317 // OPTIMIZATION: keep inflections precomputed with cubic segment? |
| 325 const SkPoint* pts = fSegment->pts(); | |
| 326 int testCount = SkDCubic::FindInflections(pts, testTs); | 318 int testCount = SkDCubic::FindInflections(pts, testTs); |
| 327 double startT = fSegment->t(fStart); | |
| 328 double endT = fSegment->t(fEnd); | 319 double endT = fSegment->t(fEnd); |
| 329 double limitT = endT; | 320 double limitT = endT; |
| 330 int index; | 321 int index; |
| 331 for (index = 0; index < testCount; ++index) { | 322 for (index = 0; index < testCount; ++index) { |
| 332 if (!between(startT, testTs[index], limitT)) { | 323 if (!between(startT, testTs[index], limitT)) { |
| 333 testTs[index] = -1; | 324 testTs[index] = -1; |
| 334 } | 325 } |
| 335 } | 326 } |
| 336 testTs[testCount++] = startT; | 327 testTs[testCount++] = startT; |
| 337 testTs[testCount++] = endT; | 328 testTs[testCount++] = endT; |
| 338 SkTQSort<double>(testTs, &testTs[testCount - 1]); | 329 SkTQSort<double>(testTs, &testTs[testCount - 1]); |
| 339 double bestSide = 0; | 330 double bestSide = 0; |
| 340 int testCases = (testCount << 1) - 1; | 331 int testCases = (testCount << 1) - 1; |
| 341 index = 0; | 332 index = 0; |
| 342 while (testTs[index] < 0) { | 333 while (testTs[index] < 0) { |
| 343 ++index; | 334 ++index; |
| 344 } | 335 } |
| 345 index <<= 1; | 336 index <<= 1; |
| 346 for (; index < testCases; ++index) { | 337 for (; index < testCases; ++index) { |
| 347 int testIndex = index >> 1; | 338 int testIndex = index >> 1; |
| 348 double testT = testTs[testIndex]; | 339 double testT = testTs[testIndex]; |
| 349 if (index & 1) { | 340 if (index & 1) { |
| 350 testT = (testT + testTs[testIndex + 1]) / 2; | 341 testT = (testT + testTs[testIndex + 1]) / 2; |
| 351 } | 342 } |
| 352 // OPTIMIZE: could avoid call for t == startT, endT | 343 // OPTIMIZE: could avoid call for t == startT, endT |
| 353 SkDPoint pt = dcubic_xy_at_t(pts, testT); | 344 SkDPoint pt = dcubic_xy_at_t(pts, testT); |
| 354 double testSide = fTangent1.pointDistance(pt); | 345 double testSide = fTangentPart.pointDistance(pt); |
| 355 if (fabs(bestSide) < fabs(testSide)) { | 346 if (fabs(bestSide) < fabs(testSide)) { |
| 356 bestSide = testSide; | 347 bestSide = testSide; |
| 357 } | 348 } |
| 358 } | 349 } |
| 359 fSide = -bestSide; // compare sign only | 350 fSide = -bestSide; // compare sign only |
| 351 SkASSERT(fSide == 0 || fSide2 != 0); |
| 360 if (fComputed && dx() > 0 && approximately_zero(dy())) { | 352 if (fComputed && dx() > 0 && approximately_zero(dy())) { |
| 361 SkDCubic origCurve; // can't use segment's curve in place since it m
ay be flipped | 353 SkDCubic origCurve; // can't use segment's curve in place since it m
ay be flipped |
| 362 int last = fSegment->count() - 1; | 354 int last = fSegment->count() - 1; |
| 363 fSegment->subDivide(fStart < fEnd ? 0 : last, fStart < fEnd ? last :
0, &origCurve); | 355 fSegment->subDivide(fStart < fEnd ? 0 : last, fStart < fEnd ? last :
0, &origCurve); |
| 364 SkLineParameters origTan; | 356 SkDCubicPair split = origCurve.chopAt(startT); |
| 365 origTan.cubicEndPoints(origCurve); | 357 SkLineParameters splitTan; |
| 366 if ((fUnorderable = origTan.dx() <= 0)) { | 358 splitTan.cubicEndPoints(fStart < fEnd ? split.second() : split.first
()); |
| 359 if (splitTan.dx() <= 0) { |
| 360 fUnorderable = true; |
| 367 fUnsortable = fSegment->isTiny(this); | 361 fUnsortable = fSegment->isTiny(this); |
| 368 return; | 362 return; |
| 369 } | 363 } |
| 370 // if one is < 0 and the other is >= 0 | 364 // if one is < 0 and the other is >= 0 |
| 371 if ((fUnorderable = (dy() < 0) ^ (origTan.dy() < 0))) { | 365 if (dy() * splitTan.dy() < 0) { |
| 366 fUnorderable = true; |
| 372 fUnsortable = fSegment->isTiny(this); | 367 fUnsortable = fSegment->isTiny(this); |
| 373 return; | 368 return; |
| 374 } | 369 } |
| 375 SkDCubicPair split = origCurve.chopAt(startT); | |
| 376 SkLineParameters splitTan; | |
| 377 splitTan.cubicEndPoints(fStart < fEnd ? split.second() : split.first
()); | |
| 378 if ((fUnorderable = splitTan.dx() <= 0)) { | |
| 379 fUnsortable = fSegment->isTiny(this); | |
| 380 return; | |
| 381 } | |
| 382 // if one is < 0 and the other is >= 0 | |
| 383 if ((fUnorderable = (dy() < 0) ^ (splitTan.dy() < 0))) { | |
| 384 fUnsortable = fSegment->isTiny(this); | |
| 385 return; | |
| 386 } | |
| 387 } | 370 } |
| 388 } break; | 371 } break; |
| 389 default: | 372 default: |
| 390 SkASSERT(0); | 373 SkASSERT(0); |
| 391 } | 374 } |
| 392 if ((fUnsortable = approximately_zero(dx()) && approximately_zero(dy()))) { | 375 if ((fUnsortable = approximately_zero(dx()) && approximately_zero(dy()))) { |
| 393 return; | 376 return; |
| 394 } | 377 } |
| 378 if (fSegment->verb() == SkPath::kLine_Verb) { |
| 379 return; |
| 380 } |
| 395 SkASSERT(fStart != fEnd); | 381 SkASSERT(fStart != fEnd); |
| 396 int step = fStart < fEnd ? 1 : -1; // OPTIMIZE: worth fStart - fEnd >> 31 t
ype macro? | 382 int smaller = SkMin32(fStart, fEnd); |
| 397 for (int index = fStart; index != fEnd; index += step) { | 383 int larger = SkMax32(fStart, fEnd); |
| 398 #if 1 | 384 while (smaller < larger && fSegment->span(smaller).fTiny) { |
| 399 const SkOpSpan& thisSpan = fSegment->span(index); | 385 ++smaller; |
| 400 const SkOpSpan& nextSpan = fSegment->span(index + step); | 386 } |
| 401 if (thisSpan.fTiny || precisely_equal(thisSpan.fT, nextSpan.fT)) { | 387 if (precisely_equal(fSegment->span(smaller).fT, fSegment->span(larger).fT))
{ |
| 402 continue; | 388 #if DEBUG_UNSORTABLE |
| 403 } | 389 SkPoint iPt = fSegment->xyAtT(fStart); |
| 404 fUnsortable = step > 0 ? thisSpan.fUnsortableStart : nextSpan.fUnsortabl
eEnd; | 390 SkPoint ePt = fSegment->xyAtT(fEnd); |
| 391 SkDebugf("%s all tiny unsortable [%d] (%1.9g,%1.9g) [%d] (%1.9g,%1.9g)\n
", __FUNCTION__, |
| 392 fStart, iPt.fX, iPt.fY, fEnd, ePt.fX, ePt.fY); |
| 393 #endif |
| 394 fUnsortable = true; |
| 395 return; |
| 396 } |
| 397 fUnsortable = fStart < fEnd ? fSegment->span(smaller).fUnsortableStart |
| 398 : fSegment->span(larger).fUnsortableEnd; |
| 405 #if DEBUG_UNSORTABLE | 399 #if DEBUG_UNSORTABLE |
| 406 if (fUnsortable) { | 400 if (fUnsortable) { |
| 407 SkPoint iPt = fSegment->xyAtT(index); | 401 SkPoint iPt = fSegment->xyAtT(smaller); |
| 408 SkPoint ePt = fSegment->xyAtT(index + step); | 402 SkPoint ePt = fSegment->xyAtT(larger); |
| 409 SkDebugf("%s unsortable [%d] (%1.9g,%1.9g) [%d] (%1.9g,%1.9g)\n", __
FUNCTION__, | 403 SkDebugf("%s unsortable [%d] (%1.9g,%1.9g) [%d] (%1.9g,%1.9g)\n", __FUNC
TION__, |
| 410 index, iPt.fX, iPt.fY, fEnd, ePt.fX, ePt.fY); | 404 smaller, iPt.fX, iPt.fY, fEnd, ePt.fX, ePt.fY); |
| 411 } | 405 } |
| 412 #endif | 406 #endif |
| 413 return; | 407 return; |
| 414 #else | 408 } |
| 415 if ((*fSpans)[index].fUnsortableStart) { | 409 |
| 416 fUnsortable = true; | 410 #ifdef SK_DEBUG |
| 417 return; | 411 void SkOpAngle::dump() const { |
| 418 } | 412 SkDebugf("id=%d (%1.9g,%1.9g) start=%d (%1.9g) end=%d (%1.9g)\n", fSegment->
debugID(), |
| 413 fSegment->xAtT(fStart), fSegment->yAtT(fStart), fStart, fSegment->sp
an(fStart).fT, |
| 414 fEnd, fSegment->span(fEnd).fT); |
| 415 } |
| 419 #endif | 416 #endif |
| 420 } | |
| 421 #if 1 | |
| 422 #if DEBUG_UNSORTABLE | |
| 423 SkPoint iPt = fSegment->xyAtT(fStart); | |
| 424 SkPoint ePt = fSegment->xyAtT(fEnd); | |
| 425 SkDebugf("%s all tiny unsortable [%d] (%1.9g,%1.9g) [%d] (%1.9g,%1.9g)\n", _
_FUNCTION__, | |
| 426 fStart, iPt.fX, iPt.fY, fEnd, ePt.fX, ePt.fY); | |
| 427 #endif | |
| 428 fUnsortable = true; | |
| 429 #endif | |
| 430 } | |
| OLD | NEW |