Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(449)

Side by Side Diff: src/core/SkStroke.cpp

Issue 2006653006: pin before calling acos (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: always compute a cubic normal Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkGeometry.cpp ('k') | src/pathops/SkPathOpsCubic.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "SkPathPriv.h" 10 #include "SkPathPriv.h"
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 166
167 enum StrokeType { 167 enum StrokeType {
168 kOuter_StrokeType = 1, // use sign-opposite values later to flip pe rpendicular axis 168 kOuter_StrokeType = 1, // use sign-opposite values later to flip pe rpendicular axis
169 kInner_StrokeType = -1 169 kInner_StrokeType = -1
170 } fStrokeType; 170 } fStrokeType;
171 171
172 enum ResultType { 172 enum ResultType {
173 kSplit_ResultType, // the caller should split the quad stroke i n two 173 kSplit_ResultType, // the caller should split the quad stroke i n two
174 kDegenerate_ResultType, // the caller should add a line 174 kDegenerate_ResultType, // the caller should add a line
175 kQuad_ResultType, // the caller should (continue to try to) ad d a quad stroke 175 kQuad_ResultType, // the caller should (continue to try to) ad d a quad stroke
176 kNormalError_ResultType, // the cubic's normal couldn't be computed - - abort
177 }; 176 };
178 177
179 enum ReductionType { 178 enum ReductionType {
180 kPoint_ReductionType, // all curve points are practically identica l 179 kPoint_ReductionType, // all curve points are practically identica l
181 kLine_ReductionType, // the control point is on the line between the ends 180 kLine_ReductionType, // the control point is on the line between the ends
182 kQuad_ReductionType, // the control point is outside the line bet ween the ends 181 kQuad_ReductionType, // the control point is outside the line bet ween the ends
183 kDegenerate_ReductionType, // the control point is on the line but outs ide the ends 182 kDegenerate_ReductionType, // the control point is on the line but outs ide the ends
184 kDegenerate2_ReductionType, // two control points are on the line but ou tside ends (cubic) 183 kDegenerate2_ReductionType, // two control points are on the line but ou tside ends (cubic)
185 kDegenerate3_ReductionType, // three areas of max curvature found (for c ubic) 184 kDegenerate3_ReductionType, // three areas of max curvature found (for c ubic)
186 }; 185 };
(...skipping 13 matching lines...) Expand all
200 const SkPoint** tanPtPtr); 199 const SkPoint** tanPtPtr);
201 static ReductionType CheckQuadLinear(const SkPoint quad[3], SkPoint* reducti on); 200 static ReductionType CheckQuadLinear(const SkPoint quad[3], SkPoint* reducti on);
202 ResultType compareQuadConic(const SkConic& , SkQuadConstruct* ) const; 201 ResultType compareQuadConic(const SkConic& , SkQuadConstruct* ) const;
203 ResultType compareQuadCubic(const SkPoint cubic[4], SkQuadConstruct* ); 202 ResultType compareQuadCubic(const SkPoint cubic[4], SkQuadConstruct* );
204 ResultType compareQuadQuad(const SkPoint quad[3], SkQuadConstruct* ); 203 ResultType compareQuadQuad(const SkPoint quad[3], SkQuadConstruct* );
205 void conicPerpRay(const SkConic& , SkScalar t, SkPoint* tPt, SkPoint* onPt, 204 void conicPerpRay(const SkConic& , SkScalar t, SkPoint* tPt, SkPoint* onPt,
206 SkPoint* tangent) const; 205 SkPoint* tangent) const;
207 void conicQuadEnds(const SkConic& , SkQuadConstruct* ) const; 206 void conicQuadEnds(const SkConic& , SkQuadConstruct* ) const;
208 bool conicStroke(const SkConic& , SkQuadConstruct* ); 207 bool conicStroke(const SkConic& , SkQuadConstruct* );
209 bool cubicMidOnLine(const SkPoint cubic[4], const SkQuadConstruct* ) const; 208 bool cubicMidOnLine(const SkPoint cubic[4], const SkQuadConstruct* ) const;
210 bool cubicPerpRay(const SkPoint cubic[4], SkScalar t, SkPoint* tPt, SkPoint* onPt, 209 void cubicPerpRay(const SkPoint cubic[4], SkScalar t, SkPoint* tPt, SkPoint* onPt,
211 SkPoint* tangent) const; 210 SkPoint* tangent) const;
212 bool cubicQuadEnds(const SkPoint cubic[4], SkQuadConstruct* ); 211 void cubicQuadEnds(const SkPoint cubic[4], SkQuadConstruct* );
213 bool cubicQuadMid(const SkPoint cubic[4], const SkQuadConstruct* , SkPoint* mid) const; 212 void cubicQuadMid(const SkPoint cubic[4], const SkQuadConstruct* , SkPoint* mid) const;
214 bool cubicStroke(const SkPoint cubic[4], SkQuadConstruct* ); 213 bool cubicStroke(const SkPoint cubic[4], SkQuadConstruct* );
215 void init(StrokeType strokeType, SkQuadConstruct* , SkScalar tStart, SkScala r tEnd); 214 void init(StrokeType strokeType, SkQuadConstruct* , SkScalar tStart, SkScala r tEnd);
216 ResultType intersectRay(SkQuadConstruct* , IntersectRayType STROKER_DEBUG_P ARAMS(int) ) const; 215 ResultType intersectRay(SkQuadConstruct* , IntersectRayType STROKER_DEBUG_P ARAMS(int) ) const;
217 bool ptInQuadBounds(const SkPoint quad[3], const SkPoint& pt) const; 216 bool ptInQuadBounds(const SkPoint quad[3], const SkPoint& pt) const;
218 void quadPerpRay(const SkPoint quad[3], SkScalar t, SkPoint* tPt, SkPoint* o nPt, 217 void quadPerpRay(const SkPoint quad[3], SkScalar t, SkPoint* tPt, SkPoint* o nPt,
219 SkPoint* tangent) const; 218 SkPoint* tangent) const;
220 bool quadStroke(const SkPoint quad[3], SkQuadConstruct* ); 219 bool quadStroke(const SkPoint quad[3], SkQuadConstruct* );
221 void setConicEndNormal(const SkConic& , 220 void setConicEndNormal(const SkConic& ,
222 const SkVector& normalAB, const SkVector& unitNormalA B, 221 const SkVector& normalAB, const SkVector& unitNormalA B,
223 SkVector* normalBC, SkVector* unitNormalBC); 222 SkVector* normalBC, SkVector* unitNormalBC);
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 if (!quadPts->fEndSet) { 778 if (!quadPts->fEndSet) {
780 SkPoint conicEndPt; 779 SkPoint conicEndPt;
781 this->conicPerpRay(conic, quadPts->fEndT, &conicEndPt, &quadPts->fQuad[2 ], 780 this->conicPerpRay(conic, quadPts->fEndT, &conicEndPt, &quadPts->fQuad[2 ],
782 &quadPts->fTangentEnd); 781 &quadPts->fTangentEnd);
783 quadPts->fEndSet = true; 782 quadPts->fEndSet = true;
784 } 783 }
785 } 784 }
786 785
787 786
788 // Given a cubic and t, return the point on curve, its perpendicular, and the pe rpendicular tangent. 787 // Given a cubic and t, return the point on curve, its perpendicular, and the pe rpendicular tangent.
789 // Returns false if the perpendicular could not be computed (because the derivat ive collapsed to 0) 788 void SkPathStroker::cubicPerpRay(const SkPoint cubic[4], SkScalar t, SkPoint* tP t, SkPoint* onPt,
790 bool SkPathStroker::cubicPerpRay(const SkPoint cubic[4], SkScalar t, SkPoint* tP t, SkPoint* onPt,
791 SkPoint* tangent) const { 789 SkPoint* tangent) const {
792 SkVector dxy; 790 SkVector dxy;
791 SkPoint chopped[7];
793 SkEvalCubicAt(cubic, t, tPt, &dxy, nullptr); 792 SkEvalCubicAt(cubic, t, tPt, &dxy, nullptr);
794 if (dxy.fX == 0 && dxy.fY == 0) { 793 if (dxy.fX == 0 && dxy.fY == 0) {
794 const SkPoint* cPts = cubic;
795 if (SkScalarNearlyZero(t)) { 795 if (SkScalarNearlyZero(t)) {
796 dxy = cubic[2] - cubic[0]; 796 dxy = cubic[2] - cubic[0];
797 } else if (SkScalarNearlyZero(1 - t)) { 797 } else if (SkScalarNearlyZero(1 - t)) {
798 dxy = cubic[3] - cubic[1]; 798 dxy = cubic[3] - cubic[1];
799 } else { 799 } else {
800 return false; 800 // If the cubic inflection falls on the cusp, subdivide the cubic
801 // to find the tangent at that point.
802 SkChopCubicAt(cubic, chopped, t);
803 dxy = chopped[3] - chopped[2];
804 if (dxy.fX == 0 && dxy.fY == 0) {
805 dxy = chopped[3] - chopped[1];
806 cPts = chopped;
807 }
801 } 808 }
802 if (dxy.fX == 0 && dxy.fY == 0) { 809 if (dxy.fX == 0 && dxy.fY == 0) {
803 dxy = cubic[3] - cubic[0]; 810 dxy = cPts[3] - cPts[0];
804 } 811 }
805 } 812 }
806 setRayPts(*tPt, &dxy, onPt, tangent); 813 setRayPts(*tPt, &dxy, onPt, tangent);
807 return true;
808 } 814 }
809 815
810 // Given a cubic and a t range, find the start and end if they haven't been foun d already. 816 // Given a cubic and a t range, find the start and end if they haven't been foun d already.
811 bool SkPathStroker::cubicQuadEnds(const SkPoint cubic[4], SkQuadConstruct* quadP ts) { 817 void SkPathStroker::cubicQuadEnds(const SkPoint cubic[4], SkQuadConstruct* quadP ts) {
812 if (!quadPts->fStartSet) { 818 if (!quadPts->fStartSet) {
813 SkPoint cubicStartPt; 819 SkPoint cubicStartPt;
814 if (!this->cubicPerpRay(cubic, quadPts->fStartT, &cubicStartPt, &quadPts ->fQuad[0], 820 this->cubicPerpRay(cubic, quadPts->fStartT, &cubicStartPt, &quadPts->fQu ad[0],
815 &quadPts->fTangentStart)) { 821 &quadPts->fTangentStart);
816 return false;
817 }
818 quadPts->fStartSet = true; 822 quadPts->fStartSet = true;
819 } 823 }
820 if (!quadPts->fEndSet) { 824 if (!quadPts->fEndSet) {
821 SkPoint cubicEndPt; 825 SkPoint cubicEndPt;
822 if (!this->cubicPerpRay(cubic, quadPts->fEndT, &cubicEndPt, &quadPts->fQ uad[2], 826 this->cubicPerpRay(cubic, quadPts->fEndT, &cubicEndPt, &quadPts->fQuad[2 ],
823 &quadPts->fTangentEnd)) { 827 &quadPts->fTangentEnd);
824 return false;
825 }
826 quadPts->fEndSet = true; 828 quadPts->fEndSet = true;
827 } 829 }
828 return true;
829 } 830 }
830 831
831 bool SkPathStroker::cubicQuadMid(const SkPoint cubic[4], const SkQuadConstruct* quadPts, 832 void SkPathStroker::cubicQuadMid(const SkPoint cubic[4], const SkQuadConstruct* quadPts,
832 SkPoint* mid) const { 833 SkPoint* mid) const {
833 SkPoint cubicMidPt; 834 SkPoint cubicMidPt;
834 return this->cubicPerpRay(cubic, quadPts->fMidT, &cubicMidPt, mid, nullptr); 835 this->cubicPerpRay(cubic, quadPts->fMidT, &cubicMidPt, mid, nullptr);
835 } 836 }
836 837
837 // Given a quad and t, return the point on curve, its perpendicular, and the per pendicular tangent. 838 // Given a quad and t, return the point on curve, its perpendicular, and the per pendicular tangent.
838 void SkPathStroker::quadPerpRay(const SkPoint quad[3], SkScalar t, SkPoint* tPt, SkPoint* onPt, 839 void SkPathStroker::quadPerpRay(const SkPoint quad[3], SkScalar t, SkPoint* tPt, SkPoint* onPt,
839 SkPoint* tangent) const { 840 SkPoint* tangent) const {
840 SkVector dxy; 841 SkVector dxy;
841 SkEvalQuadAt(quad, t, tPt, &dxy); 842 SkEvalQuadAt(quad, t, tPt, &dxy);
842 if (dxy.fX == 0 && dxy.fY == 0) { 843 if (dxy.fX == 0 && dxy.fY == 0) {
843 dxy = quad[2] - quad[0]; 844 dxy = quad[2] - quad[0];
844 } 845 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 } 899 }
899 quadPts->fOppositeTangents = aLen.dot(bLen) < 0; 900 quadPts->fOppositeTangents = aLen.dot(bLen) < 0;
900 // if the lines are parallel, straight line is good enough 901 // if the lines are parallel, straight line is good enough
901 return STROKER_RESULT(kDegenerate_ResultType, depth, quadPts, 902 return STROKER_RESULT(kDegenerate_ResultType, depth, quadPts,
902 "SkScalarNearlyZero(denom=%g)", denom); 903 "SkScalarNearlyZero(denom=%g)", denom);
903 } 904 }
904 905
905 // Given a cubic and a t-range, determine if the stroke can be described by a qu adratic. 906 // Given a cubic and a t-range, determine if the stroke can be described by a qu adratic.
906 SkPathStroker::ResultType SkPathStroker::tangentsMeet(const SkPoint cubic[4], 907 SkPathStroker::ResultType SkPathStroker::tangentsMeet(const SkPoint cubic[4],
907 SkQuadConstruct* quadPts) { 908 SkQuadConstruct* quadPts) {
908 if (!this->cubicQuadEnds(cubic, quadPts)) { 909 this->cubicQuadEnds(cubic, quadPts);
909 return kNormalError_ResultType;
910 }
911 return this->intersectRay(quadPts, kResultType_RayType STROKER_DEBUG_PARAMS (fRecursionDepth)); 910 return this->intersectRay(quadPts, kResultType_RayType STROKER_DEBUG_PARAMS (fRecursionDepth));
912 } 911 }
913 912
914 // Intersect the line with the quad and return the t values on the quad where th e line crosses. 913 // Intersect the line with the quad and return the t values on the quad where th e line crosses.
915 static int intersect_quad_ray(const SkPoint line[2], const SkPoint quad[3], SkSc alar roots[2]) { 914 static int intersect_quad_ray(const SkPoint line[2], const SkPoint quad[3], SkSc alar roots[2]) {
916 SkVector vec = line[1] - line[0]; 915 SkVector vec = line[1] - line[0];
917 SkScalar r[3]; 916 SkScalar r[3];
918 for (int n = 0; n < 3; ++n) { 917 for (int n = 0; n < 3; ++n) {
919 r[n] = (quad[n].fY - line[0].fY) * vec.fX - (quad[n].fX - line[0].fX) * vec.fY; 918 r[n] = (quad[n].fY - line[0].fY) * vec.fX - (quad[n].fX - line[0].fX) * vec.fY;
920 } 919 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 "points_within_dist(ray[0]=%g,%g, quadPt=%g,%g, error=%g)", 1011 "points_within_dist(ray[0]=%g,%g, quadPt=%g,%g, error=%g)",
1013 ray[0].fX, ray[0].fY, quadPt.fX, quadPt.fY, error); 1012 ray[0].fX, ray[0].fY, quadPt.fX, quadPt.fY, error);
1014 } 1013 }
1015 // otherwise, subdivide 1014 // otherwise, subdivide
1016 return STROKER_RESULT(kSplit_ResultType, depth, quadPts, "%s", "fall through "); 1015 return STROKER_RESULT(kSplit_ResultType, depth, quadPts, "%s", "fall through ");
1017 } 1016 }
1018 1017
1019 SkPathStroker::ResultType SkPathStroker::compareQuadCubic(const SkPoint cubic[4] , 1018 SkPathStroker::ResultType SkPathStroker::compareQuadCubic(const SkPoint cubic[4] ,
1020 SkQuadConstruct* quadPts) { 1019 SkQuadConstruct* quadPts) {
1021 // get the quadratic approximation of the stroke 1020 // get the quadratic approximation of the stroke
1022 if (!this->cubicQuadEnds(cubic, quadPts)) { 1021 this->cubicQuadEnds(cubic, quadPts);
1023 return kNormalError_ResultType;
1024 }
1025 ResultType resultType = this->intersectRay(quadPts, kCtrlPt_RayType 1022 ResultType resultType = this->intersectRay(quadPts, kCtrlPt_RayType
1026 STROKER_DEBUG_PARAMS(fRecursionDepth) ); 1023 STROKER_DEBUG_PARAMS(fRecursionDepth) );
1027 if (resultType != kQuad_ResultType) { 1024 if (resultType != kQuad_ResultType) {
1028 return resultType; 1025 return resultType;
1029 } 1026 }
1030 // project a ray from the curve to the stroke 1027 // project a ray from the curve to the stroke
1031 SkPoint ray[2]; // points near midpoint on quad, midpoint on cubic 1028 SkPoint ray[2]; // points near midpoint on quad, midpoint on cubic
1032 if (!this->cubicPerpRay(cubic, quadPts->fMidT, &ray[1], &ray[0], nullptr)) { 1029 this->cubicPerpRay(cubic, quadPts->fMidT, &ray[1], &ray[0], nullptr);
1033 return kNormalError_ResultType;
1034 }
1035 return this->strokeCloseEnough(quadPts->fQuad, ray, quadPts 1030 return this->strokeCloseEnough(quadPts->fQuad, ray, quadPts
1036 STROKER_DEBUG_PARAMS(fRecursionDepth)); 1031 STROKER_DEBUG_PARAMS(fRecursionDepth));
1037 } 1032 }
1038 1033
1039 SkPathStroker::ResultType SkPathStroker::compareQuadConic(const SkConic& conic, 1034 SkPathStroker::ResultType SkPathStroker::compareQuadConic(const SkConic& conic,
1040 SkQuadConstruct* quadPts) const { 1035 SkQuadConstruct* quadPts) const {
1041 // get the quadratic approximation of the stroke 1036 // get the quadratic approximation of the stroke
1042 this->conicQuadEnds(conic, quadPts); 1037 this->conicQuadEnds(conic, quadPts);
1043 ResultType resultType = this->intersectRay(quadPts, kCtrlPt_RayType 1038 ResultType resultType = this->intersectRay(quadPts, kCtrlPt_RayType
1044 STROKER_DEBUG_PARAMS(fRecursionDepth) ); 1039 STROKER_DEBUG_PARAMS(fRecursionDepth) );
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 } 1075 }
1081 1076
1082 void SkPathStroker::addDegenerateLine(const SkQuadConstruct* quadPts) { 1077 void SkPathStroker::addDegenerateLine(const SkQuadConstruct* quadPts) {
1083 const SkPoint* quad = quadPts->fQuad; 1078 const SkPoint* quad = quadPts->fQuad;
1084 SkPath* path = fStrokeType == kOuter_StrokeType ? &fOuter : &fInner; 1079 SkPath* path = fStrokeType == kOuter_StrokeType ? &fOuter : &fInner;
1085 path->lineTo(quad[2].fX, quad[2].fY); 1080 path->lineTo(quad[2].fX, quad[2].fY);
1086 } 1081 }
1087 1082
1088 bool SkPathStroker::cubicMidOnLine(const SkPoint cubic[4], const SkQuadConstruct * quadPts) const { 1083 bool SkPathStroker::cubicMidOnLine(const SkPoint cubic[4], const SkQuadConstruct * quadPts) const {
1089 SkPoint strokeMid; 1084 SkPoint strokeMid;
1090 if (!cubicQuadMid(cubic, quadPts, &strokeMid)) { 1085 this->cubicQuadMid(cubic, quadPts, &strokeMid);
1091 return false;
1092 }
1093 SkScalar dist = pt_to_line(strokeMid, quadPts->fQuad[0], quadPts->fQuad[2]); 1086 SkScalar dist = pt_to_line(strokeMid, quadPts->fQuad[0], quadPts->fQuad[2]);
1094 return dist < fInvResScaleSquared; 1087 return dist < fInvResScaleSquared;
1095 } 1088 }
1096 1089
1097 bool SkPathStroker::cubicStroke(const SkPoint cubic[4], SkQuadConstruct* quadPts ) { 1090 bool SkPathStroker::cubicStroke(const SkPoint cubic[4], SkQuadConstruct* quadPts ) {
1098 if (!fFoundTangents) { 1091 if (!fFoundTangents) {
1099 ResultType resultType = this->tangentsMeet(cubic, quadPts); 1092 ResultType resultType = this->tangentsMeet(cubic, quadPts);
1100 if (kQuad_ResultType != resultType) { 1093 if (kQuad_ResultType != resultType) {
1101 if (kNormalError_ResultType == resultType) {
1102 return false;
1103 }
1104 if ((kDegenerate_ResultType == resultType 1094 if ((kDegenerate_ResultType == resultType
1105 || points_within_dist(quadPts->fQuad[0], quadPts->fQuad[2], 1095 || points_within_dist(quadPts->fQuad[0], quadPts->fQuad[2],
1106 fInvResScale)) && cubicMidOnLine(cubic, quadPts)) { 1096 fInvResScale)) && cubicMidOnLine(cubic, quadPts)) {
1107 addDegenerateLine(quadPts); 1097 addDegenerateLine(quadPts);
1108 return true; 1098 return true;
1109 } 1099 }
1110 } else { 1100 } else {
1111 fFoundTangents = true; 1101 fFoundTangents = true;
1112 } 1102 }
1113 } 1103 }
1114 if (fFoundTangents) { 1104 if (fFoundTangents) {
1115 ResultType resultType = this->compareQuadCubic(cubic, quadPts); 1105 ResultType resultType = this->compareQuadCubic(cubic, quadPts);
1116 if (kQuad_ResultType == resultType) { 1106 if (kQuad_ResultType == resultType) {
1117 SkPath* path = fStrokeType == kOuter_StrokeType ? &fOuter : &fInner; 1107 SkPath* path = fStrokeType == kOuter_StrokeType ? &fOuter : &fInner;
1118 const SkPoint* stroke = quadPts->fQuad; 1108 const SkPoint* stroke = quadPts->fQuad;
1119 path->quadTo(stroke[1].fX, stroke[1].fY, stroke[2].fX, stroke[2].fY) ; 1109 path->quadTo(stroke[1].fX, stroke[1].fY, stroke[2].fX, stroke[2].fY) ;
1120 return true; 1110 return true;
1121 } 1111 }
1122 if (kDegenerate_ResultType == resultType) { 1112 if (kDegenerate_ResultType == resultType) {
1123 if (!quadPts->fOppositeTangents) { 1113 if (!quadPts->fOppositeTangents) {
1124 addDegenerateLine(quadPts); 1114 addDegenerateLine(quadPts);
1125 return true; 1115 return true;
1126 } 1116 }
1127 } 1117 }
1128 if (kNormalError_ResultType == resultType) {
1129 return false;
1130 }
1131 } 1118 }
1132 if (!SkScalarIsFinite(quadPts->fQuad[2].fX) || !SkScalarIsFinite(quadPts->fQ uad[2].fY)) { 1119 if (!SkScalarIsFinite(quadPts->fQuad[2].fX) || !SkScalarIsFinite(quadPts->fQ uad[2].fY)) {
1133 return false; // just abort if projected quad isn't representable 1120 return false; // just abort if projected quad isn't representable
1134 } 1121 }
1135 SkDEBUGCODE(gMaxRecursion[fFoundTangents] = SkTMax(gMaxRecursion[fFoundTange nts], 1122 SkDEBUGCODE(gMaxRecursion[fFoundTangents] = SkTMax(gMaxRecursion[fFoundTange nts],
1136 fRecursionDepth + 1)); 1123 fRecursionDepth + 1));
1137 if (++fRecursionDepth > kRecursiveLimits[fFoundTangents]) { 1124 if (++fRecursionDepth > kRecursiveLimits[fFoundTangents]) {
1138 return false; // just abort if projected quad isn't representable 1125 return false; // just abort if projected quad isn't representable
1139 } 1126 }
1140 SkQuadConstruct half; 1127 SkQuadConstruct half;
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
1537 default: 1524 default:
1538 break; 1525 break;
1539 } 1526 }
1540 1527
1541 if (fWidth < SkMinScalar(rw, rh) && !fDoFill) { 1528 if (fWidth < SkMinScalar(rw, rh) && !fDoFill) {
1542 r = rect; 1529 r = rect;
1543 r.inset(radius, radius); 1530 r.inset(radius, radius);
1544 dst->addRect(r, reverse_direction(dir)); 1531 dst->addRect(r, reverse_direction(dir));
1545 } 1532 }
1546 } 1533 }
OLDNEW
« no previous file with comments | « src/core/SkGeometry.cpp ('k') | src/pathops/SkPathOpsCubic.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698