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

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

Issue 887783002: reorg some path routines, preparing to switch arcs to conics (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 10 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 | « no previous file | no next file » | 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 2006 The Android Open Source Project 2 * Copyright 2006 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 "SkBuffer.h" 8 #include "SkBuffer.h"
9 #include "SkErrorInternals.h" 9 #include "SkErrorInternals.h"
10 #include "SkGeometry.h" 10 #include "SkGeometry.h"
(...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 if (close) { 887 if (close) {
888 ed.growForVerb(kClose_Verb); 888 ed.growForVerb(kClose_Verb);
889 } 889 }
890 890
891 DIRTY_AFTER_EDIT; 891 DIRTY_AFTER_EDIT;
892 SkDEBUGCODE(this->validate();) 892 SkDEBUGCODE(this->validate();)
893 } 893 }
894 894
895 #include "SkGeometry.h" 895 #include "SkGeometry.h"
896 896
897 static int build_arc_points(const SkRect& oval, SkScalar startAngle, 897 static bool arc_is_lone_point(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
898 SkScalar sweepAngle, 898 SkPoint* pt) {
899 SkPoint pts[kSkBuildQuadArcStorage]) { 899 if (0 == sweepAngle && (0 == startAngle || SkIntToScalar(360) == startAngle) ) {
900
901 if (0 == sweepAngle &&
902 (0 == startAngle || SkIntToScalar(360) == startAngle)) {
903 // Chrome uses this path to move into and out of ovals. If not 900 // Chrome uses this path to move into and out of ovals. If not
904 // treated as a special case the moves can distort the oval's 901 // treated as a special case the moves can distort the oval's
905 // bounding box (and break the circle special case). 902 // bounding box (and break the circle special case).
906 pts[0].set(oval.fRight, oval.centerY()); 903 pt->set(oval.fRight, oval.centerY());
907 return 1; 904 return true;
908 } else if (0 == oval.width() && 0 == oval.height()) { 905 } else if (0 == oval.width() && 0 == oval.height()) {
909 // Chrome will sometimes create 0 radius round rects. Having degenerate 906 // Chrome will sometimes create 0 radius round rects. Having degenerate
910 // quad segments in the path prevents the path from being recognized as 907 // quad segments in the path prevents the path from being recognized as
911 // a rect. 908 // a rect.
912 // TODO: optimizing the case where only one of width or height is zero 909 // TODO: optimizing the case where only one of width or height is zero
913 // should also be considered. This case, however, doesn't seem to be 910 // should also be considered. This case, however, doesn't seem to be
914 // as common as the single point case. 911 // as common as the single point case.
915 pts[0].set(oval.fRight, oval.fTop); 912 pt->set(oval.fRight, oval.fTop);
916 return 1; 913 return true;
917 } 914 }
915 return false;
916 }
918 917
918 static int build_arc_points(const SkRect& oval, SkScalar startAngle, SkScalar sw eepAngle,
919 SkPoint pts[kSkBuildQuadArcStorage]) {
919 SkVector start, stop; 920 SkVector start, stop;
920 921
921 start.fY = SkScalarSinCos(SkDegreesToRadians(startAngle), &start.fX); 922 start.fY = SkScalarSinCos(SkDegreesToRadians(startAngle), &start.fX);
922 stop.fY = SkScalarSinCos(SkDegreesToRadians(startAngle + sweepAngle), 923 stop.fY = SkScalarSinCos(SkDegreesToRadians(startAngle + sweepAngle),
923 &stop.fX); 924 &stop.fX);
924 925
925 /* If the sweep angle is nearly (but less than) 360, then due to precision 926 /* If the sweep angle is nearly (but less than) 360, then due to precision
926 loss in radians-conversion and/or sin/cos, we may end up with coincident 927 loss in radians-conversion and/or sin/cos, we may end up with coincident
927 vectors, which will fool SkBuildQuadArc into doing nothing (bad) instead 928 vectors, which will fool SkBuildQuadArc into doing nothing (bad) instead
928 of drawing a nearly complete circle (good). 929 of drawing a nearly complete circle (good).
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 this->addOval(rect, dir); 1303 this->addOval(rect, dir);
1303 } 1304 }
1304 } 1305 }
1305 1306
1306 void SkPath::arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, 1307 void SkPath::arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
1307 bool forceMoveTo) { 1308 bool forceMoveTo) {
1308 if (oval.width() < 0 || oval.height() < 0) { 1309 if (oval.width() < 0 || oval.height() < 0) {
1309 return; 1310 return;
1310 } 1311 }
1311 1312
1313 if (fPathRef->countVerbs() == 0) {
1314 forceMoveTo = true;
1315 }
1316
1317 SkPoint lonePt;
1318 if (arc_is_lone_point(oval, startAngle, sweepAngle, &lonePt)) {
1319 forceMoveTo ? this->moveTo(lonePt) : this->lineTo(lonePt);
1320 return;
1321 }
1322
1312 SkPoint pts[kSkBuildQuadArcStorage]; 1323 SkPoint pts[kSkBuildQuadArcStorage];
1313 int count = build_arc_points(oval, startAngle, sweepAngle, pts); 1324 int count = build_arc_points(oval, startAngle, sweepAngle, pts);
1314 SkASSERT((count & 1) == 1); 1325 SkASSERT((count & 1) == 1);
1315 1326
1316 if (fPathRef->countVerbs() == 0) {
1317 forceMoveTo = true;
1318 }
1319 this->incReserve(count); 1327 this->incReserve(count);
1320 forceMoveTo ? this->moveTo(pts[0]) : this->lineTo(pts[0]); 1328 forceMoveTo ? this->moveTo(pts[0]) : this->lineTo(pts[0]);
1321 for (int i = 1; i < count; i += 2) { 1329 for (int i = 1; i < count; i += 2) {
1322 this->quadTo(pts[i], pts[i+1]); 1330 this->quadTo(pts[i], pts[i+1]);
1323 } 1331 }
1324 } 1332 }
1325 1333
1326 void SkPath::addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle ) { 1334 void SkPath::addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle ) {
1327 if (oval.isEmpty() || 0 == sweepAngle) { 1335 if (oval.isEmpty() || 0 == sweepAngle) {
1328 return; 1336 return;
1329 } 1337 }
1330 1338
1331 const SkScalar kFullCircleAngle = SkIntToScalar(360); 1339 const SkScalar kFullCircleAngle = SkIntToScalar(360);
1332 1340
1333 if (sweepAngle >= kFullCircleAngle || sweepAngle <= -kFullCircleAngle) { 1341 if (sweepAngle >= kFullCircleAngle || sweepAngle <= -kFullCircleAngle) {
1334 this->addOval(oval, sweepAngle > 0 ? kCW_Direction : kCCW_Direction); 1342 this->addOval(oval, sweepAngle > 0 ? kCW_Direction : kCCW_Direction);
1335 return; 1343 return;
1336 } 1344 }
1337 1345
1346 SkPoint lonePt;
1347 if (arc_is_lone_point(oval, startAngle, sweepAngle, &lonePt)) {
1348 this->moveTo(lonePt);
1349 return;
1350 }
1351
1338 SkPoint pts[kSkBuildQuadArcStorage]; 1352 SkPoint pts[kSkBuildQuadArcStorage];
1339 int count = build_arc_points(oval, startAngle, sweepAngle, pts); 1353 int count = build_arc_points(oval, startAngle, sweepAngle, pts);
1340 1354
1341 SkDEBUGCODE(this->validate();) 1355 SkDEBUGCODE(this->validate();)
1342 SkASSERT(count & 1); 1356 SkASSERT(count & 1);
1343 1357
1344 fLastMoveToIndex = fPathRef->countPoints(); 1358 fLastMoveToIndex = fPathRef->countPoints();
1345 1359
1346 SkPathRef::Editor ed(&fPathRef, 1+(count-1)/2, count); 1360 SkPathRef::Editor ed(&fPathRef, 1+(count-1)/2, count);
1347 1361
(...skipping 1579 matching lines...) Expand 10 before | Expand all | Expand 10 after
2927 switch (this->getFillType()) { 2941 switch (this->getFillType()) {
2928 case SkPath::kEvenOdd_FillType: 2942 case SkPath::kEvenOdd_FillType:
2929 case SkPath::kInverseEvenOdd_FillType: 2943 case SkPath::kInverseEvenOdd_FillType:
2930 w &= 1; 2944 w &= 1;
2931 break; 2945 break;
2932 default: 2946 default:
2933 break; 2947 break;
2934 } 2948 }
2935 return SkToBool(w); 2949 return SkToBool(w);
2936 } 2950 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698