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

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

Issue 18271003: GM (and fix) for drawArc capping issue (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « gyp/gmslides.gypi ('k') | 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 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #include "SkGeometry.h" 10 #include "SkGeometry.h"
(...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 SkScalar B = 2 * (b - a); 1198 SkScalar B = 2 * (b - a);
1199 SkScalar C = a - d; 1199 SkScalar C = a - d;
1200 1200
1201 SkScalar roots[2]; 1201 SkScalar roots[2];
1202 int count = SkFindUnitQuadRoots(A, B, C, roots); 1202 int count = SkFindUnitQuadRoots(A, B, C, roots);
1203 1203
1204 SkASSERT(count <= 1); 1204 SkASSERT(count <= 1);
1205 return count == 1 ? roots[0] : 0; 1205 return count == 1 ? roots[0] : 0;
1206 } 1206 }
1207 1207
1208 /* given a quad-curve and a point (x,y), chop the quad at that point and return 1208 /* given a quad-curve and a point (x,y), chop the quad at that point and place
1209 the new quad's offCurve point. Should only return false if the computed pos 1209 the new off-curve point and endpoint into 'dest'. The new end point is used
1210 is the start of the curve (i.e. root == 0) 1210 (rather than (x,y)) to compensate for numerical inaccuracies.
1211 Should only return false if the computed pos is the start of the curve
1212 (i.e. root == 0)
1211 */ 1213 */
1212 static bool quad_pt2OffCurve(const SkPoint quad[3], SkScalar x, SkScalar y, SkPo int* offCurve) 1214 static bool truncate_last_curve(const SkPoint quad[3], SkScalar x, SkScalar y, S kPoint* dest)
1213 { 1215 {
1214 const SkScalar* base; 1216 const SkScalar* base;
1215 SkScalar value; 1217 SkScalar value;
1216 1218
1217 if (SkScalarAbs(x) < SkScalarAbs(y)) { 1219 if (SkScalarAbs(x) < SkScalarAbs(y)) {
1218 base = &quad[0].fX; 1220 base = &quad[0].fX;
1219 value = x; 1221 value = x;
1220 } else { 1222 } else {
1221 base = &quad[0].fY; 1223 base = &quad[0].fY;
1222 value = y; 1224 value = y;
1223 } 1225 }
1224 1226
1225 // note: this returns 0 if it thinks value is out of range, meaning the 1227 // note: this returns 0 if it thinks value is out of range, meaning the
1226 // root might return something outside of [0, 1) 1228 // root might return something outside of [0, 1)
1227 SkScalar t = quad_solve(base[0], base[2], base[4], value); 1229 SkScalar t = quad_solve(base[0], base[2], base[4], value);
1228 1230
1229 if (t > 0) 1231 if (t > 0)
1230 { 1232 {
1231 SkPoint tmp[5]; 1233 SkPoint tmp[5];
1232 SkChopQuadAt(quad, tmp, t); 1234 SkChopQuadAt(quad, tmp, t);
1233 *offCurve = tmp[1]; 1235 dest[0] = tmp[1];
1236 dest[1] = tmp[2];
1234 return true; 1237 return true;
1235 } else { 1238 } else {
1236 /* t == 0 means either the value triggered a root outside of [0, 1) 1239 /* t == 0 means either the value triggered a root outside of [0, 1)
1237 For our purposes, we can ignore the <= 0 roots, but we want to 1240 For our purposes, we can ignore the <= 0 roots, but we want to
1238 catch the >= 1 roots (which given our caller, will basically mean 1241 catch the >= 1 roots (which given our caller, will basically mean
1239 a root of 1, give-or-take numerical instability). If we are in the 1242 a root of 1, give-or-take numerical instability). If we are in the
1240 >= 1 case, return the existing offCurve point. 1243 >= 1 case, return the existing offCurve point.
1241 1244
1242 The test below checks to see if we are close to the "end" of the 1245 The test below checks to see if we are close to the "end" of the
1243 curve (near base[4]). Rather than specifying a tolerance, I just 1246 curve (near base[4]). Rather than specifying a tolerance, I just
1244 check to see if value is on to the right/left of the middle point 1247 check to see if value is on to the right/left of the middle point
1245 (depending on the direction/sign of the end points). 1248 (depending on the direction/sign of the end points).
1246 */ 1249 */
1247 if ((base[0] < base[4] && value > base[2]) || 1250 if ((base[0] < base[4] && value > base[2]) ||
1248 (base[0] > base[4] && value < base[2])) // should root have been 1 1251 (base[0] > base[4] && value < base[2])) // should root have been 1
1249 { 1252 {
1250 *offCurve = quad[1]; 1253 dest[0] = quad[1];
1254 dest[1].set(x, y);
1251 return true; 1255 return true;
1252 } 1256 }
1253 } 1257 }
1254 return false; 1258 return false;
1255 } 1259 }
1256 1260
1257 #ifdef SK_SCALAR_IS_FLOAT 1261 #ifdef SK_SCALAR_IS_FLOAT
1258 1262
1259 // Due to floating point issues (i.e., 1.0f - SK_ScalarRoot2Over2 != 1263 // Due to floating point issues (i.e., 1.0f - SK_ScalarRoot2Over2 !=
1260 // SK_ScalarRoot2Over2 - SK_ScalarTanPIOver8) a cruder root2over2 1264 // SK_ScalarRoot2Over2 - SK_ScalarTanPIOver8) a cruder root2over2
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1353 sameSign = false; 1357 sameSign = false;
1354 } 1358 }
1355 if ((absX < absY) == sameSign) 1359 if ((absX < absY) == sameSign)
1356 oct += 1; 1360 oct += 1;
1357 } 1361 }
1358 1362
1359 int wholeCount = oct << 1; 1363 int wholeCount = oct << 1;
1360 memcpy(quadPoints, gQuadCirclePts, (wholeCount + 1) * sizeof(SkPoint)); 1364 memcpy(quadPoints, gQuadCirclePts, (wholeCount + 1) * sizeof(SkPoint));
1361 1365
1362 const SkPoint* arc = &gQuadCirclePts[wholeCount]; 1366 const SkPoint* arc = &gQuadCirclePts[wholeCount];
1363 if (quad_pt2OffCurve(arc, x, y, &quadPoints[wholeCount + 1])) 1367 if (truncate_last_curve(arc, x, y, &quadPoints[wholeCount + 1]))
1364 { 1368 {
1365 quadPoints[wholeCount + 2].set(x, y);
1366 wholeCount += 2; 1369 wholeCount += 2;
1367 } 1370 }
1368 pointCount = wholeCount + 1; 1371 pointCount = wholeCount + 1;
1369 } 1372 }
1370 1373
1371 // now handle counter-clockwise and the initial unitStart rotation 1374 // now handle counter-clockwise and the initial unitStart rotation
1372 SkMatrix matrix; 1375 SkMatrix matrix;
1373 matrix.setSinCos(uStart.fY, uStart.fX); 1376 matrix.setSinCos(uStart.fY, uStart.fX);
1374 if (dir == kCCW_SkRotationDirection) { 1377 if (dir == kCCW_SkRotationDirection) {
1375 matrix.preScale(SK_Scalar1, -SK_Scalar1); 1378 matrix.preScale(SK_Scalar1, -SK_Scalar1);
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 } 1658 }
1656 if (this->findYExtrema(&t)) { 1659 if (this->findYExtrema(&t)) {
1657 this->evalAt(t, &pts[count++]); 1660 this->evalAt(t, &pts[count++]);
1658 } 1661 }
1659 bounds->set(pts, count); 1662 bounds->set(pts, count);
1660 } 1663 }
1661 1664
1662 void SkConic::computeFastBounds(SkRect* bounds) const { 1665 void SkConic::computeFastBounds(SkRect* bounds) const {
1663 bounds->set(fPts, 3); 1666 bounds->set(fPts, 3);
1664 } 1667 }
OLDNEW
« no previous file with comments | « gyp/gmslides.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698