OLD | NEW |
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 "Sk2x.h" | 10 #include "Sk2x.h" |
11 | 11 |
12 static Sk2s from_point(const SkPoint& point) { | 12 static Sk2s from_point(const SkPoint& point) { |
13 return Sk2s::Load(&point.fX); | 13 return Sk2s::Load(&point.fX); |
14 } | 14 } |
15 | 15 |
16 static SkPoint to_point(const Sk2s& x) { | 16 static SkPoint to_point(const Sk2s& x) { |
17 SkPoint point; | 17 SkPoint point; |
18 x.store(&point.fX); | 18 x.store(&point.fX); |
19 return point; | 19 return point; |
20 } | 20 } |
21 | 21 |
22 static SkVector to_vector(const Sk2s& x) { | 22 static SkVector to_vector(const Sk2s& x) { |
23 SkVector vector; | 23 SkVector vector; |
24 x.store(&vector.fX); | 24 x.store(&vector.fX); |
25 return vector; | 25 return vector; |
26 } | 26 } |
27 | 27 |
28 #if 0 | |
29 static Sk2s divide(const Sk2s& numer, const Sk2s& denom) { | |
30 SkScalar numerStorage[2], denomStorage[2]; | |
31 numer.store(numerStorage); | |
32 denom.store(denomStorage); | |
33 numerStorage[0] /= denomStorage[0]; | |
34 numerStorage[1] /= denomStorage[1]; | |
35 return Sk2s::Load(numerStorage); | |
36 } | |
37 #endif | |
38 | |
39 /** If defined, this makes eval_quad and eval_cubic do more setup (sometimes | 28 /** If defined, this makes eval_quad and eval_cubic do more setup (sometimes |
40 involving integer multiplies by 2 or 3, but fewer calls to SkScalarMul. | 29 involving integer multiplies by 2 or 3, but fewer calls to SkScalarMul. |
41 May also introduce overflow of fixed when we compute our setup. | 30 May also introduce overflow of fixed when we compute our setup. |
42 */ | 31 */ |
43 // #define DIRECT_EVAL_OF_POLYNOMIALS | 32 // #define DIRECT_EVAL_OF_POLYNOMIALS |
44 | 33 |
45 //////////////////////////////////////////////////////////////////////// | 34 //////////////////////////////////////////////////////////////////////// |
46 | 35 |
47 static int is_not_monotonic(SkScalar a, SkScalar b, SkScalar c) { | 36 static int is_not_monotonic(SkScalar a, SkScalar b, SkScalar c) { |
48 SkScalar ab = a - b; | 37 SkScalar ab = a - b; |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 static inline Sk2s interp(const Sk2s& v0, const Sk2s& v1, const Sk2s& t) { | 200 static inline Sk2s interp(const Sk2s& v0, const Sk2s& v1, const Sk2s& t) { |
212 return v0 + (v1 - v0) * t; | 201 return v0 + (v1 - v0) * t; |
213 } | 202 } |
214 | 203 |
215 void SkChopQuadAt2(const SkPoint src[3], SkPoint dst[5], SkScalar t) { | 204 void SkChopQuadAt2(const SkPoint src[3], SkPoint dst[5], SkScalar t) { |
216 SkASSERT(t > 0 && t < SK_Scalar1); | 205 SkASSERT(t > 0 && t < SK_Scalar1); |
217 | 206 |
218 Sk2s p0 = from_point(src[0]); | 207 Sk2s p0 = from_point(src[0]); |
219 Sk2s p1 = from_point(src[1]); | 208 Sk2s p1 = from_point(src[1]); |
220 Sk2s p2 = from_point(src[2]); | 209 Sk2s p2 = from_point(src[2]); |
221 Sk2s tt = Sk2s(t); | 210 Sk2s tt(t); |
222 | 211 |
223 Sk2s p01 = interp(p0, p1, tt); | 212 Sk2s p01 = interp(p0, p1, tt); |
224 Sk2s p12 = interp(p1, p2, tt); | 213 Sk2s p12 = interp(p1, p2, tt); |
225 | 214 |
226 dst[0] = to_point(p0); | 215 dst[0] = to_point(p0); |
227 dst[1] = to_point(p01); | 216 dst[1] = to_point(p01); |
228 dst[2] = to_point(interp(p01, p12, tt)); | 217 dst[2] = to_point(interp(p01, p12, tt)); |
229 dst[3] = to_point(p12); | 218 dst[3] = to_point(p12); |
230 dst[4] = to_point(p2); | 219 dst[4] = to_point(p2); |
231 } | 220 } |
(...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 } | 1268 } |
1280 | 1269 |
1281 static Sk2s times_2(const Sk2s& value) { | 1270 static Sk2s times_2(const Sk2s& value) { |
1282 return value + value; | 1271 return value + value; |
1283 } | 1272 } |
1284 | 1273 |
1285 SkPoint SkConic::evalAt(SkScalar t) const { | 1274 SkPoint SkConic::evalAt(SkScalar t) const { |
1286 Sk2s p0 = from_point(fPts[0]); | 1275 Sk2s p0 = from_point(fPts[0]); |
1287 Sk2s p1 = from_point(fPts[1]); | 1276 Sk2s p1 = from_point(fPts[1]); |
1288 Sk2s p2 = from_point(fPts[2]); | 1277 Sk2s p2 = from_point(fPts[2]); |
1289 Sk2s tt = Sk2s(t); | 1278 Sk2s tt(t); |
1290 Sk2s ww = Sk2s(fW); | 1279 Sk2s ww(fW); |
1291 Sk2s one = Sk2s(1); | 1280 Sk2s one(1); |
1292 | 1281 |
1293 Sk2s p1w = p1 * ww; | 1282 Sk2s p1w = p1 * ww; |
1294 Sk2s C = p0; | 1283 Sk2s C = p0; |
1295 Sk2s A = p2 - times_2(p1w) + p0; | 1284 Sk2s A = p2 - times_2(p1w) + p0; |
1296 Sk2s B = times_2(p1w - C); | 1285 Sk2s B = times_2(p1w - C); |
1297 Sk2s numer = quad_poly_eval(A, B, C, tt); | 1286 Sk2s numer = quad_poly_eval(A, B, C, tt); |
1298 | 1287 |
1299 B = times_2(ww - one); | 1288 B = times_2(ww - one); |
1300 A = -B; | 1289 A = -B; |
1301 Sk2s denom = quad_poly_eval(A, B, one, tt); | 1290 Sk2s denom = quad_poly_eval(A, B, one, tt); |
1302 | 1291 |
1303 return to_point(numer / denom); | 1292 return to_point(numer / denom); |
1304 } | 1293 } |
1305 | 1294 |
1306 SkVector SkConic::evalTangentAt(SkScalar t) const { | 1295 SkVector SkConic::evalTangentAt(SkScalar t) const { |
1307 Sk2s p0 = from_point(fPts[0]); | 1296 Sk2s p0 = from_point(fPts[0]); |
1308 Sk2s p1 = from_point(fPts[1]); | 1297 Sk2s p1 = from_point(fPts[1]); |
1309 Sk2s p2 = from_point(fPts[2]); | 1298 Sk2s p2 = from_point(fPts[2]); |
1310 Sk2s ww = Sk2s(fW); | 1299 Sk2s ww(fW); |
1311 | 1300 |
1312 Sk2s p20 = p2 - p0; | 1301 Sk2s p20 = p2 - p0; |
1313 Sk2s p10 = p1 - p0; | 1302 Sk2s p10 = p1 - p0; |
1314 | 1303 |
1315 Sk2s C = ww * p10; | 1304 Sk2s C = ww * p10; |
1316 Sk2s A = ww * p20 - p20; | 1305 Sk2s A = ww * p20 - p20; |
1317 Sk2s B = p20 - C - C; | 1306 Sk2s B = p20 - C - C; |
1318 | 1307 |
1319 return to_vector(quad_poly_eval(A, B, C, Sk2s(t))); | 1308 return to_vector(quad_poly_eval(A, B, C, Sk2s(t))); |
1320 #if 0 | 1309 #if 0 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1355 | 1344 |
1356 dst[1].fPts[0].set(mx, my); | 1345 dst[1].fPts[0].set(mx, my); |
1357 dst[1].fPts[1].set((p1x + fPts[2].fX) * scale, | 1346 dst[1].fPts[1].set((p1x + fPts[2].fX) * scale, |
1358 (p1y + fPts[2].fY) * scale); | 1347 (p1y + fPts[2].fY) * scale); |
1359 dst[1].fPts[2] = fPts[2]; | 1348 dst[1].fPts[2] = fPts[2]; |
1360 | 1349 |
1361 dst[0].fW = dst[1].fW = subdivide_w_value(fW); | 1350 dst[0].fW = dst[1].fW = subdivide_w_value(fW); |
1362 } | 1351 } |
1363 | 1352 |
1364 void SkConic::chop2(SkConic * SK_RESTRICT dst) const { | 1353 void SkConic::chop2(SkConic * SK_RESTRICT dst) const { |
1365 Sk2s scale(SkScalarInvert(SK_Scalar1 + fW)); | 1354 Sk2s scale = Sk2s(SK_Scalar1 + fW).invert(); // approxInvert is wicked fa
ster!!! |
1366 // Sk2s scale = Sk2s(SK_Scalar1 + fW).invert(); | |
1367 SkScalar newW = subdivide_w_value(fW); | 1355 SkScalar newW = subdivide_w_value(fW); |
1368 | 1356 |
1369 Sk2s p0 = from_point(fPts[0]); | 1357 Sk2s p0 = from_point(fPts[0]); |
1370 Sk2s p1 = from_point(fPts[1]); | 1358 Sk2s p1 = from_point(fPts[1]); |
1371 Sk2s p2 = from_point(fPts[2]); | 1359 Sk2s p2 = from_point(fPts[2]); |
1372 Sk2s ww = Sk2s(fW); | 1360 Sk2s ww(fW); |
1373 Sk2s half = Sk2s(0.5f); | 1361 Sk2s half(0.5f); |
1374 | 1362 |
1375 Sk2s wp1 = ww * p1; | 1363 Sk2s wp1 = ww * p1; |
1376 Sk2s m = ((p0 + wp1 + wp1 + p2) * half) * scale; | 1364 Sk2s m = ((p0 + wp1 + wp1 + p2) * half) * scale; |
1377 | 1365 |
1378 dst[0].fPts[0] = fPts[0]; | 1366 dst[0].fPts[0] = fPts[0]; |
1379 dst[0].fPts[1] = to_point((p0 + wp1) * scale); | 1367 dst[0].fPts[1] = to_point((p0 + wp1) * scale); |
1380 dst[0].fPts[2] = dst[1].fPts[0] = to_point(m); | 1368 dst[0].fPts[2] = dst[1].fPts[0] = to_point(m); |
1381 dst[1].fPts[1] = to_point((wp1 + p2) * scale); | 1369 dst[1].fPts[1] = to_point((wp1 + p2) * scale); |
1382 dst[1].fPts[2] = fPts[2]; | 1370 dst[1].fPts[2] = fPts[2]; |
1383 | 1371 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1626 matrix.preScale(SK_Scalar1, -SK_Scalar1); | 1614 matrix.preScale(SK_Scalar1, -SK_Scalar1); |
1627 } | 1615 } |
1628 if (userMatrix) { | 1616 if (userMatrix) { |
1629 matrix.postConcat(*userMatrix); | 1617 matrix.postConcat(*userMatrix); |
1630 } | 1618 } |
1631 for (int i = 0; i < conicCount; ++i) { | 1619 for (int i = 0; i < conicCount; ++i) { |
1632 matrix.mapPoints(dst[i].fPts, 3); | 1620 matrix.mapPoints(dst[i].fPts, 3); |
1633 } | 1621 } |
1634 return conicCount; | 1622 return conicCount; |
1635 } | 1623 } |
OLD | NEW |