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

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

Issue 2368993002: allow conic chop to fail (Closed)
Patch Set: address comment Created 4 years, 2 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.h ('k') | src/core/SkPathMeasure.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 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 "SkGeometry.h" 8 #include "SkGeometry.h"
9 #include "SkMatrix.h" 9 #include "SkMatrix.h"
10 #include "SkNx.h" 10 #include "SkNx.h"
(...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 dst[3] = SkScalarInterp(ab, bc, t); 968 dst[3] = SkScalarInterp(ab, bc, t);
969 dst[6] = bc; 969 dst[6] = bc;
970 } 970 }
971 971
972 static void ratquad_mapTo3D(const SkPoint src[3], SkScalar w, SkP3D dst[]) { 972 static void ratquad_mapTo3D(const SkPoint src[3], SkScalar w, SkP3D dst[]) {
973 dst[0].set(src[0].fX * 1, src[0].fY * 1, 1); 973 dst[0].set(src[0].fX * 1, src[0].fY * 1, 1);
974 dst[1].set(src[1].fX * w, src[1].fY * w, w); 974 dst[1].set(src[1].fX * w, src[1].fY * w, w);
975 dst[2].set(src[2].fX * 1, src[2].fY * 1, 1); 975 dst[2].set(src[2].fX * 1, src[2].fY * 1, 1);
976 } 976 }
977 977
978 void SkConic::chopAt(SkScalar t, SkConic dst[2]) const { 978 // return false if infinity or NaN is generated; caller must check
979 bool SkConic::chopAt(SkScalar t, SkConic dst[2]) const {
979 SkP3D tmp[3], tmp2[3]; 980 SkP3D tmp[3], tmp2[3];
980 981
981 ratquad_mapTo3D(fPts, fW, tmp); 982 ratquad_mapTo3D(fPts, fW, tmp);
982 983
983 p3d_interp(&tmp[0].fX, &tmp2[0].fX, t); 984 p3d_interp(&tmp[0].fX, &tmp2[0].fX, t);
984 p3d_interp(&tmp[0].fY, &tmp2[0].fY, t); 985 p3d_interp(&tmp[0].fY, &tmp2[0].fY, t);
985 p3d_interp(&tmp[0].fZ, &tmp2[0].fZ, t); 986 p3d_interp(&tmp[0].fZ, &tmp2[0].fZ, t);
986 987
987 dst[0].fPts[0] = fPts[0]; 988 dst[0].fPts[0] = fPts[0];
988 tmp2[0].projectDown(&dst[0].fPts[1]); 989 tmp2[0].projectDown(&dst[0].fPts[1]);
989 tmp2[1].projectDown(&dst[0].fPts[2]); dst[1].fPts[0] = dst[0].fPts[2]; 990 tmp2[1].projectDown(&dst[0].fPts[2]); dst[1].fPts[0] = dst[0].fPts[2];
990 tmp2[2].projectDown(&dst[1].fPts[1]); 991 tmp2[2].projectDown(&dst[1].fPts[1]);
991 dst[1].fPts[2] = fPts[2]; 992 dst[1].fPts[2] = fPts[2];
992 993
993 // to put in "standard form", where w0 and w2 are both 1, we compute the 994 // to put in "standard form", where w0 and w2 are both 1, we compute the
994 // new w1 as sqrt(w1*w1/w0*w2) 995 // new w1 as sqrt(w1*w1/w0*w2)
995 // or 996 // or
996 // w1 /= sqrt(w0*w2) 997 // w1 /= sqrt(w0*w2)
997 // 998 //
998 // However, in our case, we know that for dst[0]: 999 // However, in our case, we know that for dst[0]:
999 // w0 == 1, and for dst[1], w2 == 1 1000 // w0 == 1, and for dst[1], w2 == 1
1000 // 1001 //
1001 SkScalar root = SkScalarSqrt(tmp2[1].fZ); 1002 SkScalar root = SkScalarSqrt(tmp2[1].fZ);
1002 dst[0].fW = tmp2[0].fZ / root; 1003 dst[0].fW = tmp2[0].fZ / root;
1003 dst[1].fW = tmp2[2].fZ / root; 1004 dst[1].fW = tmp2[2].fZ / root;
1005 SkASSERT(sizeof(dst[0]) == sizeof(SkScalar) * 7);
1006 SkASSERT(0 == offsetof(SkConic, fPts[0].fX));
1007 return SkScalarsAreFinite(&dst[0].fPts[0].fX, 7 * 2);
1004 } 1008 }
1005 1009
1006 void SkConic::chopAt(SkScalar t1, SkScalar t2, SkConic* dst) const { 1010 void SkConic::chopAt(SkScalar t1, SkScalar t2, SkConic* dst) const {
1007 if (0 == t1 || 1 == t2) { 1011 if (0 == t1 || 1 == t2) {
1008 if (0 == t1 && 1 == t2) { 1012 if (0 == t1 && 1 == t2) {
1009 *dst = *this; 1013 *dst = *this;
1014 return;
1010 } else { 1015 } else {
1011 SkConic pair[2]; 1016 SkConic pair[2];
1012 this->chopAt(t1 ? t1 : t2, pair); 1017 if (this->chopAt(t1 ? t1 : t2, pair)) {
1013 *dst = pair[SkToBool(t1)]; 1018 *dst = pair[SkToBool(t1)];
1019 return;
1020 }
1014 } 1021 }
1015 return;
1016 } 1022 }
1017 SkConicCoeff coeff(*this); 1023 SkConicCoeff coeff(*this);
1018 Sk2s tt1(t1); 1024 Sk2s tt1(t1);
1019 Sk2s aXY = coeff.fNumer.eval(tt1); 1025 Sk2s aXY = coeff.fNumer.eval(tt1);
1020 Sk2s aZZ = coeff.fDenom.eval(tt1); 1026 Sk2s aZZ = coeff.fDenom.eval(tt1);
1021 Sk2s midTT((t1 + t2) / 2); 1027 Sk2s midTT((t1 + t2) / 2);
1022 Sk2s dXY = coeff.fNumer.eval(midTT); 1028 Sk2s dXY = coeff.fNumer.eval(midTT);
1023 Sk2s dZZ = coeff.fDenom.eval(midTT); 1029 Sk2s dZZ = coeff.fDenom.eval(midTT);
1024 Sk2s tt2(t2); 1030 Sk2s tt2(t2);
1025 Sk2s cXY = coeff.fNumer.eval(tt2); 1031 Sk2s cXY = coeff.fNumer.eval(tt2);
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 return conic_find_extrema(&fPts[0].fX, fW, t); 1242 return conic_find_extrema(&fPts[0].fX, fW, t);
1237 } 1243 }
1238 1244
1239 bool SkConic::findYExtrema(SkScalar* t) const { 1245 bool SkConic::findYExtrema(SkScalar* t) const {
1240 return conic_find_extrema(&fPts[0].fY, fW, t); 1246 return conic_find_extrema(&fPts[0].fY, fW, t);
1241 } 1247 }
1242 1248
1243 bool SkConic::chopAtXExtrema(SkConic dst[2]) const { 1249 bool SkConic::chopAtXExtrema(SkConic dst[2]) const {
1244 SkScalar t; 1250 SkScalar t;
1245 if (this->findXExtrema(&t)) { 1251 if (this->findXExtrema(&t)) {
1246 this->chopAt(t, dst); 1252 if (!this->chopAt(t, dst)) {
1253 // if chop can't return finite values, don't chop
1254 return false;
1255 }
1247 // now clean-up the middle, since we know t was meant to be at 1256 // now clean-up the middle, since we know t was meant to be at
1248 // an X-extrema 1257 // an X-extrema
1249 SkScalar value = dst[0].fPts[2].fX; 1258 SkScalar value = dst[0].fPts[2].fX;
1250 dst[0].fPts[1].fX = value; 1259 dst[0].fPts[1].fX = value;
1251 dst[1].fPts[0].fX = value; 1260 dst[1].fPts[0].fX = value;
1252 dst[1].fPts[1].fX = value; 1261 dst[1].fPts[1].fX = value;
1253 return true; 1262 return true;
1254 } 1263 }
1255 return false; 1264 return false;
1256 } 1265 }
1257 1266
1258 bool SkConic::chopAtYExtrema(SkConic dst[2]) const { 1267 bool SkConic::chopAtYExtrema(SkConic dst[2]) const {
1259 SkScalar t; 1268 SkScalar t;
1260 if (this->findYExtrema(&t)) { 1269 if (this->findYExtrema(&t)) {
1261 this->chopAt(t, dst); 1270 if (!this->chopAt(t, dst)) {
1271 // if chop can't return finite values, don't chop
1272 return false;
1273 }
1262 // now clean-up the middle, since we know t was meant to be at 1274 // now clean-up the middle, since we know t was meant to be at
1263 // an Y-extrema 1275 // an Y-extrema
1264 SkScalar value = dst[0].fPts[2].fY; 1276 SkScalar value = dst[0].fPts[2].fY;
1265 dst[0].fPts[1].fY = value; 1277 dst[0].fPts[1].fY = value;
1266 dst[1].fPts[0].fY = value; 1278 dst[1].fPts[0].fY = value;
1267 dst[1].fPts[1].fY = value; 1279 dst[1].fPts[1].fY = value;
1268 return true; 1280 return true;
1269 } 1281 }
1270 return false; 1282 return false;
1271 } 1283 }
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1397 matrix.preScale(SK_Scalar1, -SK_Scalar1); 1409 matrix.preScale(SK_Scalar1, -SK_Scalar1);
1398 } 1410 }
1399 if (userMatrix) { 1411 if (userMatrix) {
1400 matrix.postConcat(*userMatrix); 1412 matrix.postConcat(*userMatrix);
1401 } 1413 }
1402 for (int i = 0; i < conicCount; ++i) { 1414 for (int i = 0; i < conicCount; ++i) {
1403 matrix.mapPoints(dst[i].fPts, 3); 1415 matrix.mapPoints(dst[i].fPts, 3);
1404 } 1416 }
1405 return conicCount; 1417 return conicCount;
1406 } 1418 }
OLDNEW
« no previous file with comments | « src/core/SkGeometry.h ('k') | src/core/SkPathMeasure.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698