OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 The Android Open Source Project |
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 | 7 |
8 #include "SkStrokerPriv.h" | 8 #include "SkStrokerPriv.h" |
9 #include "SkGeometry.h" | 9 #include "SkGeometry.h" |
10 #include "SkPath.h" | 10 #include "SkPath.h" |
(...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 #endif | 898 #endif |
899 | 899 |
900 this->postJoinTo(pt2, normalBC, unitBC); | 900 this->postJoinTo(pt2, normalBC, unitBC); |
901 } | 901 } |
902 | 902 |
903 #ifdef SK_QUAD_STROKE_APPROXIMATION | 903 #ifdef SK_QUAD_STROKE_APPROXIMATION |
904 // Given a point on the curve and its derivative, scale the derivative by the ra
dius, and | 904 // Given a point on the curve and its derivative, scale the derivative by the ra
dius, and |
905 // compute the perpendicular point and its tangent. | 905 // compute the perpendicular point and its tangent. |
906 void SkPathStroker::setRayPts(const SkPoint& tPt, SkVector* dxy, SkPoint* onPt, | 906 void SkPathStroker::setRayPts(const SkPoint& tPt, SkVector* dxy, SkPoint* onPt, |
907 SkPoint* tangent) const { | 907 SkPoint* tangent) const { |
| 908 SkPoint oldDxy = *dxy; |
908 if (!dxy->setLength(fRadius)) { // consider moving double logic into SkPoin
t::setLength | 909 if (!dxy->setLength(fRadius)) { // consider moving double logic into SkPoin
t::setLength |
909 double xx = dxy->fX; | 910 double xx = oldDxy.fX; |
910 double yy = dxy->fY; | 911 double yy = oldDxy.fY; |
911 double dscale = fRadius / sqrt(xx * xx + yy * yy); | 912 double dscale = fRadius / sqrt(xx * xx + yy * yy); |
912 dxy->fX = SkDoubleToScalar(xx * dscale); | 913 dxy->fX = SkDoubleToScalar(xx * dscale); |
913 dxy->fY = SkDoubleToScalar(yy * dscale); | 914 dxy->fY = SkDoubleToScalar(yy * dscale); |
914 } | 915 } |
915 SkScalar axisFlip = SkIntToScalar(fStrokeType); // go opposite ways for out
er, inner | 916 SkScalar axisFlip = SkIntToScalar(fStrokeType); // go opposite ways for out
er, inner |
916 onPt->fX = tPt.fX + axisFlip * dxy->fY; | 917 onPt->fX = tPt.fX + axisFlip * dxy->fY; |
917 onPt->fY = tPt.fY - axisFlip * dxy->fX; | 918 onPt->fY = tPt.fY - axisFlip * dxy->fX; |
918 if (tangent) { | 919 if (tangent) { |
919 tangent->fX = onPt->fX + dxy->fX; | 920 tangent->fX = onPt->fX + dxy->fX; |
920 tangent->fY = onPt->fY + dxy->fY; | 921 tangent->fY = onPt->fY + dxy->fY; |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1405 SkVector normalAB, unitAB, normalCD, unitCD; | 1406 SkVector normalAB, unitAB, normalCD, unitCD; |
1406 this->preJoinTo(*tangentPt, &normalAB, &unitAB, false); | 1407 this->preJoinTo(*tangentPt, &normalAB, &unitAB, false); |
1407 SkScalar tValues[2]; | 1408 SkScalar tValues[2]; |
1408 int count = SkFindCubicInflections(cubic, tValues); | 1409 int count = SkFindCubicInflections(cubic, tValues); |
1409 SkScalar lastT = 0; | 1410 SkScalar lastT = 0; |
1410 for (int index = 0; index <= count; ++index) { | 1411 for (int index = 0; index <= count; ++index) { |
1411 SkScalar nextT = index < count ? tValues[index] : 1; | 1412 SkScalar nextT = index < count ? tValues[index] : 1; |
1412 SkQuadConstruct quadPts; | 1413 SkQuadConstruct quadPts; |
1413 this->init(kOuter_StrokeType, &quadPts, lastT, nextT); | 1414 this->init(kOuter_StrokeType, &quadPts, lastT, nextT); |
1414 if (!this->cubicStroke(cubic, &quadPts)) { | 1415 if (!this->cubicStroke(cubic, &quadPts)) { |
1415 return; | 1416 break; |
1416 } | 1417 } |
1417 this->init(kInner_StrokeType, &quadPts, lastT, nextT); | 1418 this->init(kInner_StrokeType, &quadPts, lastT, nextT); |
1418 if (!this->cubicStroke(cubic, &quadPts)) { | 1419 if (!this->cubicStroke(cubic, &quadPts)) { |
1419 return; | 1420 break; |
1420 } | 1421 } |
1421 lastT = nextT; | 1422 lastT = nextT; |
1422 } | 1423 } |
| 1424 // emit the join even if one stroke succeeded but the last one failed |
| 1425 // this avoids reversing an inner stroke with a partial path followed by ano
ther moveto |
1423 this->setCubicEndNormal(cubic, normalAB, unitAB, &normalCD, &unitCD); | 1426 this->setCubicEndNormal(cubic, normalAB, unitAB, &normalCD, &unitCD); |
1424 #else | 1427 #else |
1425 bool degenerateAB = SkPath::IsLineDegenerate(fPrevPt, pt1); | 1428 bool degenerateAB = SkPath::IsLineDegenerate(fPrevPt, pt1); |
1426 bool degenerateBC = SkPath::IsLineDegenerate(pt1, pt2); | 1429 bool degenerateBC = SkPath::IsLineDegenerate(pt1, pt2); |
1427 bool degenerateCD = SkPath::IsLineDegenerate(pt2, pt3); | 1430 bool degenerateCD = SkPath::IsLineDegenerate(pt2, pt3); |
1428 | 1431 |
1429 if (degenerateAB + degenerateBC + degenerateCD >= 2 | 1432 if (degenerateAB + degenerateBC + degenerateCD >= 2 |
1430 || (degenerateAB && SkPath::IsLineDegenerate(fPrevPt, pt2))) { | 1433 || (degenerateAB && SkPath::IsLineDegenerate(fPrevPt, pt2))) { |
1431 this->lineTo(pt3); | 1434 this->lineTo(pt3); |
1432 return; | 1435 return; |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1736 default: | 1739 default: |
1737 break; | 1740 break; |
1738 } | 1741 } |
1739 | 1742 |
1740 if (fWidth < SkMinScalar(rw, rh) && !fDoFill) { | 1743 if (fWidth < SkMinScalar(rw, rh) && !fDoFill) { |
1741 r = rect; | 1744 r = rect; |
1742 r.inset(radius, radius); | 1745 r.inset(radius, radius); |
1743 dst->addRect(r, reverse_direction(dir)); | 1746 dst->addRect(r, reverse_direction(dir)); |
1744 } | 1747 } |
1745 } | 1748 } |
OLD | NEW |