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 "SkNx.h" | 10 #include "SkNx.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 SkTSwap<SkScalar>(roots[0], roots[1]); | 97 SkTSwap<SkScalar>(roots[0], roots[1]); |
98 else if (roots[0] == roots[1]) // nearly-equal? | 98 else if (roots[0] == roots[1]) // nearly-equal? |
99 r -= 1; // skip the double root | 99 r -= 1; // skip the double root |
100 } | 100 } |
101 return (int)(r - roots); | 101 return (int)(r - roots); |
102 } | 102 } |
103 | 103 |
104 /////////////////////////////////////////////////////////////////////////////// | 104 /////////////////////////////////////////////////////////////////////////////// |
105 /////////////////////////////////////////////////////////////////////////////// | 105 /////////////////////////////////////////////////////////////////////////////// |
106 | 106 |
107 static Sk2s quad_poly_eval(const Sk2s& A, const Sk2s& B, const Sk2s& C, const Sk
2s& t) { | |
108 return (A * t + B) * t + C; | |
109 } | |
110 | |
111 static SkScalar eval_quad(const SkScalar src[], SkScalar t) { | |
112 SkASSERT(src); | |
113 SkASSERT(t >= 0 && t <= SK_Scalar1); | |
114 | |
115 #ifdef DIRECT_EVAL_OF_POLYNOMIALS | |
116 SkScalar C = src[0]; | |
117 SkScalar A = src[4] - 2 * src[2] + C; | |
118 SkScalar B = 2 * (src[2] - C); | |
119 return SkScalarMulAdd(SkScalarMulAdd(A, t, B), t, C); | |
120 #else | |
121 SkScalar ab = SkScalarInterp(src[0], src[2], t); | |
122 SkScalar bc = SkScalarInterp(src[2], src[4], t); | |
123 return SkScalarInterp(ab, bc, t); | |
124 #endif | |
125 } | |
126 | |
127 void SkQuadToCoeff(const SkPoint pts[3], SkPoint coeff[3]) { | |
128 Sk2s p0 = from_point(pts[0]); | |
129 Sk2s p1 = from_point(pts[1]); | |
130 Sk2s p2 = from_point(pts[2]); | |
131 | |
132 Sk2s p1minus2 = p1 - p0; | |
133 | |
134 coeff[0] = to_point(p2 - p1 - p1 + p0); // A * t^2 | |
135 coeff[1] = to_point(p1minus2 + p1minus2); // B * t | |
136 coeff[2] = pts[0]; // C | |
137 } | |
138 | |
139 void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, SkVector* tange
nt) { | 107 void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, SkVector* tange
nt) { |
140 SkASSERT(src); | 108 SkASSERT(src); |
141 SkASSERT(t >= 0 && t <= SK_Scalar1); | 109 SkASSERT(t >= 0 && t <= SK_Scalar1); |
142 | 110 |
143 if (pt) { | 111 if (pt) { |
144 pt->set(eval_quad(&src[0].fX, t), eval_quad(&src[0].fY, t)); | 112 *pt = SkEvalQuadAt(src, t); |
145 } | 113 } |
146 if (tangent) { | 114 if (tangent) { |
147 *tangent = SkEvalQuadTangentAt(src, t); | 115 *tangent = SkEvalQuadTangentAt(src, t); |
148 } | 116 } |
149 } | 117 } |
150 | 118 |
151 SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t) { | 119 SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t) { |
152 SkASSERT(src); | 120 return to_point(SkQuadCoeff(src).eval(t)); |
153 SkASSERT(t >= 0 && t <= SK_Scalar1); | |
154 | |
155 const Sk2s t2(t); | |
156 | |
157 Sk2s P0 = from_point(src[0]); | |
158 Sk2s P1 = from_point(src[1]); | |
159 Sk2s P2 = from_point(src[2]); | |
160 | |
161 Sk2s B = P1 - P0; | |
162 Sk2s A = P2 - P1 - B; | |
163 | |
164 return to_point((A * t2 + B+B) * t2 + P0); | |
165 } | 121 } |
166 | 122 |
167 SkVector SkEvalQuadTangentAt(const SkPoint src[3], SkScalar t) { | 123 SkVector SkEvalQuadTangentAt(const SkPoint src[3], SkScalar t) { |
168 // The derivative equation is 2(b - a +(a - 2b +c)t). This returns a | 124 // The derivative equation is 2(b - a +(a - 2b +c)t). This returns a |
169 // zero tangent vector when t is 0 or 1, and the control point is equal | 125 // zero tangent vector when t is 0 or 1, and the control point is equal |
170 // to the end point. In this case, use the quad end points to compute the ta
ngent. | 126 // to the end point. In this case, use the quad end points to compute the ta
ngent. |
171 if ((t == 0 && src[0] == src[1]) || (t == 1 && src[1] == src[2])) { | 127 if ((t == 0 && src[0] == src[1]) || (t == 1 && src[1] == src[2])) { |
172 return src[2] - src[0]; | 128 return src[2] - src[0]; |
173 } | 129 } |
174 SkASSERT(src); | 130 SkASSERT(src); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 dst[0] = src[0]; | 282 dst[0] = src[0]; |
327 dst[1] = to_point(s0 + (s1 - s0) * scale); | 283 dst[1] = to_point(s0 + (s1 - s0) * scale); |
328 dst[2] = to_point(s2 + (s1 - s2) * scale); | 284 dst[2] = to_point(s2 + (s1 - s2) * scale); |
329 dst[3] = src[2]; | 285 dst[3] = src[2]; |
330 } | 286 } |
331 | 287 |
332 ////////////////////////////////////////////////////////////////////////////// | 288 ////////////////////////////////////////////////////////////////////////////// |
333 ///// CUBICS // CUBICS // CUBICS // CUBICS // CUBICS // CUBICS // CUBICS ///// | 289 ///// CUBICS // CUBICS // CUBICS // CUBICS // CUBICS // CUBICS // CUBICS ///// |
334 ////////////////////////////////////////////////////////////////////////////// | 290 ////////////////////////////////////////////////////////////////////////////// |
335 | 291 |
| 292 #ifdef SK_SUPPORT_LEGACY_EVAL_CUBIC |
336 static SkScalar eval_cubic(const SkScalar src[], SkScalar t) { | 293 static SkScalar eval_cubic(const SkScalar src[], SkScalar t) { |
337 SkASSERT(src); | 294 SkASSERT(src); |
338 SkASSERT(t >= 0 && t <= SK_Scalar1); | 295 SkASSERT(t >= 0 && t <= SK_Scalar1); |
339 | 296 |
340 if (t == 0) { | 297 if (t == 0) { |
341 return src[0]; | 298 return src[0]; |
342 } | 299 } |
343 | 300 |
344 #ifdef DIRECT_EVAL_OF_POLYNOMIALS | 301 #ifdef DIRECT_EVAL_OF_POLYNOMIALS |
345 SkScalar D = src[0]; | 302 SkScalar D = src[0]; |
346 SkScalar A = src[6] + 3*(src[2] - src[4]) - D; | 303 SkScalar A = src[6] + 3*(src[2] - src[4]) - D; |
347 SkScalar B = 3*(src[4] - src[2] - src[2] + D); | 304 SkScalar B = 3*(src[4] - src[2] - src[2] + D); |
348 SkScalar C = 3*(src[2] - D); | 305 SkScalar C = 3*(src[2] - D); |
349 | 306 |
350 return SkScalarMulAdd(SkScalarMulAdd(SkScalarMulAdd(A, t, B), t, C), t, D); | 307 return SkScalarMulAdd(SkScalarMulAdd(SkScalarMulAdd(A, t, B), t, C), t, D); |
351 #else | 308 #else |
352 SkScalar ab = SkScalarInterp(src[0], src[2], t); | 309 SkScalar ab = SkScalarInterp(src[0], src[2], t); |
353 SkScalar bc = SkScalarInterp(src[2], src[4], t); | 310 SkScalar bc = SkScalarInterp(src[2], src[4], t); |
354 SkScalar cd = SkScalarInterp(src[4], src[6], t); | 311 SkScalar cd = SkScalarInterp(src[4], src[6], t); |
355 SkScalar abc = SkScalarInterp(ab, bc, t); | 312 SkScalar abc = SkScalarInterp(ab, bc, t); |
356 SkScalar bcd = SkScalarInterp(bc, cd, t); | 313 SkScalar bcd = SkScalarInterp(bc, cd, t); |
357 return SkScalarInterp(abc, bcd, t); | 314 return SkScalarInterp(abc, bcd, t); |
358 #endif | 315 #endif |
359 } | 316 } |
| 317 #endif |
360 | 318 |
361 /** return At^2 + Bt + C | 319 static SkVector eval_cubic_derivative(const SkPoint src[4], SkScalar t) { |
362 */ | 320 SkQuadCoeff coeff; |
363 static SkScalar eval_quadratic(SkScalar A, SkScalar B, SkScalar C, SkScalar t) { | 321 Sk2s P0 = from_point(src[0]); |
364 SkASSERT(t >= 0 && t <= SK_Scalar1); | 322 Sk2s P1 = from_point(src[1]); |
| 323 Sk2s P2 = from_point(src[2]); |
| 324 Sk2s P3 = from_point(src[3]); |
365 | 325 |
366 return SkScalarMulAdd(SkScalarMulAdd(A, t, B), t, C); | 326 coeff.fA = P3 + Sk2s(3) * (P1 - P2) - P0; |
| 327 coeff.fB = times_2(P2 - times_2(P1) + P0); |
| 328 coeff.fC = P1 - P0; |
| 329 return to_vector(coeff.eval(t)); |
367 } | 330 } |
368 | 331 |
369 static SkScalar eval_cubic_derivative(const SkScalar src[], SkScalar t) { | 332 static SkVector eval_cubic_2ndDerivative(const SkPoint src[4], SkScalar t) { |
370 SkScalar A = src[6] + 3*(src[2] - src[4]) - src[0]; | 333 Sk2s P0 = from_point(src[0]); |
371 SkScalar B = 2*(src[4] - 2 * src[2] + src[0]); | 334 Sk2s P1 = from_point(src[1]); |
372 SkScalar C = src[2] - src[0]; | 335 Sk2s P2 = from_point(src[2]); |
| 336 Sk2s P3 = from_point(src[3]); |
| 337 Sk2s A = P3 + Sk2s(3) * (P1 - P2) - P0; |
| 338 Sk2s B = P2 - times_2(P1) + P0; |
373 | 339 |
374 return eval_quadratic(A, B, C, t); | 340 return to_vector(A * Sk2s(t) + B); |
375 } | |
376 | |
377 static SkScalar eval_cubic_2ndDerivative(const SkScalar src[], SkScalar t) { | |
378 SkScalar A = src[6] + 3*(src[2] - src[4]) - src[0]; | |
379 SkScalar B = src[4] - 2 * src[2] + src[0]; | |
380 | |
381 return SkScalarMulAdd(A, t, B); | |
382 } | 341 } |
383 | 342 |
384 void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* loc, | 343 void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* loc, |
385 SkVector* tangent, SkVector* curvature) { | 344 SkVector* tangent, SkVector* curvature) { |
386 SkASSERT(src); | 345 SkASSERT(src); |
387 SkASSERT(t >= 0 && t <= SK_Scalar1); | 346 SkASSERT(t >= 0 && t <= SK_Scalar1); |
388 | 347 |
389 if (loc) { | 348 if (loc) { |
| 349 #ifdef SK_SUPPORT_LEGACY_EVAL_CUBIC |
390 loc->set(eval_cubic(&src[0].fX, t), eval_cubic(&src[0].fY, t)); | 350 loc->set(eval_cubic(&src[0].fX, t), eval_cubic(&src[0].fY, t)); |
| 351 #else |
| 352 *loc = to_point(SkCubicCoeff(src).eval(t)); |
| 353 #endif |
391 } | 354 } |
392 if (tangent) { | 355 if (tangent) { |
393 // The derivative equation returns a zero tangent vector when t is 0 or
1, and the | 356 // The derivative equation returns a zero tangent vector when t is 0 or
1, and the |
394 // adjacent control point is equal to the end point. In this case, use t
he | 357 // adjacent control point is equal to the end point. In this case, use t
he |
395 // next control point or the end points to compute the tangent. | 358 // next control point or the end points to compute the tangent. |
396 if ((t == 0 && src[0] == src[1]) || (t == 1 && src[2] == src[3])) { | 359 if ((t == 0 && src[0] == src[1]) || (t == 1 && src[2] == src[3])) { |
397 if (t == 0) { | 360 if (t == 0) { |
398 *tangent = src[2] - src[0]; | 361 *tangent = src[2] - src[0]; |
399 } else { | 362 } else { |
400 *tangent = src[3] - src[1]; | 363 *tangent = src[3] - src[1]; |
401 } | 364 } |
402 if (!tangent->fX && !tangent->fY) { | 365 if (!tangent->fX && !tangent->fY) { |
403 *tangent = src[3] - src[0]; | 366 *tangent = src[3] - src[0]; |
404 } | 367 } |
405 } else { | 368 } else { |
406 tangent->set(eval_cubic_derivative(&src[0].fX, t), | 369 *tangent = eval_cubic_derivative(src, t); |
407 eval_cubic_derivative(&src[0].fY, t)); | |
408 } | 370 } |
409 } | 371 } |
410 if (curvature) { | 372 if (curvature) { |
411 curvature->set(eval_cubic_2ndDerivative(&src[0].fX, t), | 373 *curvature = eval_cubic_2ndDerivative(src, t); |
412 eval_cubic_2ndDerivative(&src[0].fY, t)); | |
413 } | 374 } |
414 } | 375 } |
415 | 376 |
416 /** Cubic'(t) = At^2 + Bt + C, where | 377 /** Cubic'(t) = At^2 + Bt + C, where |
417 A = 3(-a + 3(b - c) + d) | 378 A = 3(-a + 3(b - c) + d) |
418 B = 6(a - 2b + c) | 379 B = 6(a - 2b + c) |
419 C = 3(b - a) | 380 C = 3(b - a) |
420 Solve for t, keeping only those that fit betwee 0 < t < 1 | 381 Solve for t, keeping only those that fit betwee 0 < t < 1 |
421 */ | 382 */ |
422 int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d, | 383 int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d, |
(...skipping 24 matching lines...) Expand all Loading... |
447 | 408 |
448 dst[0] = src[0]; | 409 dst[0] = src[0]; |
449 dst[1] = to_point(ab); | 410 dst[1] = to_point(ab); |
450 dst[2] = to_point(abc); | 411 dst[2] = to_point(abc); |
451 dst[3] = to_point(abcd); | 412 dst[3] = to_point(abcd); |
452 dst[4] = to_point(bcd); | 413 dst[4] = to_point(bcd); |
453 dst[5] = to_point(cd); | 414 dst[5] = to_point(cd); |
454 dst[6] = src[3]; | 415 dst[6] = src[3]; |
455 } | 416 } |
456 | 417 |
457 void SkCubicToCoeff(const SkPoint pts[4], SkPoint coeff[4]) { | |
458 Sk2s p0 = from_point(pts[0]); | |
459 Sk2s p1 = from_point(pts[1]); | |
460 Sk2s p2 = from_point(pts[2]); | |
461 Sk2s p3 = from_point(pts[3]); | |
462 | |
463 const Sk2s three(3); | |
464 Sk2s p1minusp2 = p1 - p2; | |
465 | |
466 Sk2s D = p0; | |
467 Sk2s A = p3 + three * p1minusp2 - D; | |
468 Sk2s B = three * (D - p1minusp2 - p1); | |
469 Sk2s C = three * (p1 - D); | |
470 | |
471 coeff[0] = to_point(A); | |
472 coeff[1] = to_point(B); | |
473 coeff[2] = to_point(C); | |
474 coeff[3] = to_point(D); | |
475 } | |
476 | |
477 /* http://code.google.com/p/skia/issues/detail?id=32 | 418 /* http://code.google.com/p/skia/issues/detail?id=32 |
478 | 419 |
479 This test code would fail when we didn't check the return result of | 420 This test code would fail when we didn't check the return result of |
480 valid_unit_divide in SkChopCubicAt(... tValues[], int roots). The reason is | 421 valid_unit_divide in SkChopCubicAt(... tValues[], int roots). The reason is |
481 that after the first chop, the parameters to valid_unit_divide are equal | 422 that after the first chop, the parameters to valid_unit_divide are equal |
482 (thanks to finite float precision and rounding in the subtracts). Thus | 423 (thanks to finite float precision and rounding in the subtracts). Thus |
483 even though the 2nd tValue looks < 1.0, after we renormalize it, we end | 424 even though the 2nd tValue looks < 1.0, after we renormalize it, we end |
484 up with 1.0, hence the need to check and just return the last cubic as | 425 up with 1.0, hence the need to check and just return the last cubic as |
485 a degenerate clump of 4 points in the sampe place. | 426 a degenerate clump of 4 points in the sampe place. |
486 | 427 |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1085 Sk2s bXY = times_2(dXY) - (aXY + cXY) * Sk2s(0.5f); | 1026 Sk2s bXY = times_2(dXY) - (aXY + cXY) * Sk2s(0.5f); |
1086 Sk2s bZZ = times_2(dZZ) - (aZZ + cZZ) * Sk2s(0.5f); | 1027 Sk2s bZZ = times_2(dZZ) - (aZZ + cZZ) * Sk2s(0.5f); |
1087 dst->fPts[0] = to_point(aXY / aZZ); | 1028 dst->fPts[0] = to_point(aXY / aZZ); |
1088 dst->fPts[1] = to_point(bXY / bZZ); | 1029 dst->fPts[1] = to_point(bXY / bZZ); |
1089 dst->fPts[2] = to_point(cXY / cZZ); | 1030 dst->fPts[2] = to_point(cXY / cZZ); |
1090 Sk2s ww = bZZ / (aZZ * cZZ).sqrt(); | 1031 Sk2s ww = bZZ / (aZZ * cZZ).sqrt(); |
1091 dst->fW = ww.kth<0>(); | 1032 dst->fW = ww.kth<0>(); |
1092 } | 1033 } |
1093 | 1034 |
1094 SkPoint SkConic::evalAt(SkScalar t) const { | 1035 SkPoint SkConic::evalAt(SkScalar t) const { |
1095 Sk2s p0 = from_point(fPts[0]); | 1036 return to_point(SkConicCoeff(*this).eval(t)); |
1096 Sk2s p1 = from_point(fPts[1]); | |
1097 Sk2s p2 = from_point(fPts[2]); | |
1098 Sk2s tt(t); | |
1099 Sk2s ww(fW); | |
1100 Sk2s one(1); | |
1101 | |
1102 Sk2s p1w = p1 * ww; | |
1103 Sk2s C = p0; | |
1104 Sk2s A = p2 - times_2(p1w) + p0; | |
1105 Sk2s B = times_2(p1w - C); | |
1106 Sk2s numer = quad_poly_eval(A, B, C, tt); | |
1107 | |
1108 B = times_2(ww - one); | |
1109 A = Sk2s(0)-B; | |
1110 Sk2s denom = quad_poly_eval(A, B, one, tt); | |
1111 | |
1112 return to_point(numer / denom); | |
1113 } | 1037 } |
1114 | 1038 |
1115 SkVector SkConic::evalTangentAt(SkScalar t) const { | 1039 SkVector SkConic::evalTangentAt(SkScalar t) const { |
1116 // The derivative equation returns a zero tangent vector when t is 0 or 1, | 1040 // The derivative equation returns a zero tangent vector when t is 0 or 1, |
1117 // and the control point is equal to the end point. | 1041 // and the control point is equal to the end point. |
1118 // In this case, use the conic endpoints to compute the tangent. | 1042 // In this case, use the conic endpoints to compute the tangent. |
1119 if ((t == 0 && fPts[0] == fPts[1]) || (t == 1 && fPts[1] == fPts[2])) { | 1043 if ((t == 0 && fPts[0] == fPts[1]) || (t == 1 && fPts[1] == fPts[2])) { |
1120 return fPts[2] - fPts[0]; | 1044 return fPts[2] - fPts[0]; |
1121 } | 1045 } |
1122 Sk2s p0 = from_point(fPts[0]); | 1046 Sk2s p0 = from_point(fPts[0]); |
1123 Sk2s p1 = from_point(fPts[1]); | 1047 Sk2s p1 = from_point(fPts[1]); |
1124 Sk2s p2 = from_point(fPts[2]); | 1048 Sk2s p2 = from_point(fPts[2]); |
1125 Sk2s ww(fW); | 1049 Sk2s ww(fW); |
1126 | 1050 |
1127 Sk2s p20 = p2 - p0; | 1051 Sk2s p20 = p2 - p0; |
1128 Sk2s p10 = p1 - p0; | 1052 Sk2s p10 = p1 - p0; |
1129 | 1053 |
1130 Sk2s C = ww * p10; | 1054 Sk2s C = ww * p10; |
1131 Sk2s A = ww * p20 - p20; | 1055 Sk2s A = ww * p20 - p20; |
1132 Sk2s B = p20 - C - C; | 1056 Sk2s B = p20 - C - C; |
1133 | 1057 |
1134 return to_vector(quad_poly_eval(A, B, C, Sk2s(t))); | 1058 return to_vector(SkQuadCoeff(A, B, C).eval(t)); |
1135 } | 1059 } |
1136 | 1060 |
1137 void SkConic::evalAt(SkScalar t, SkPoint* pt, SkVector* tangent) const { | 1061 void SkConic::evalAt(SkScalar t, SkPoint* pt, SkVector* tangent) const { |
1138 SkASSERT(t >= 0 && t <= SK_Scalar1); | 1062 SkASSERT(t >= 0 && t <= SK_Scalar1); |
1139 | 1063 |
1140 if (pt) { | 1064 if (pt) { |
1141 *pt = this->evalAt(t); | 1065 *pt = this->evalAt(t); |
1142 } | 1066 } |
1143 if (tangent) { | 1067 if (tangent) { |
1144 *tangent = this->evalTangentAt(t); | 1068 *tangent = this->evalTangentAt(t); |
1145 } | 1069 } |
1146 } | 1070 } |
1147 | 1071 |
1148 static SkScalar subdivide_w_value(SkScalar w) { | 1072 static SkScalar subdivide_w_value(SkScalar w) { |
1149 return SkScalarSqrt(SK_ScalarHalf + w * SK_ScalarHalf); | 1073 return SkScalarSqrt(SK_ScalarHalf + w * SK_ScalarHalf); |
1150 } | 1074 } |
1151 | 1075 |
1152 static Sk2s twice(const Sk2s& value) { | |
1153 return value + value; | |
1154 } | |
1155 | |
1156 void SkConic::chop(SkConic * SK_RESTRICT dst) const { | 1076 void SkConic::chop(SkConic * SK_RESTRICT dst) const { |
1157 Sk2s scale = Sk2s(SkScalarInvert(SK_Scalar1 + fW)); | 1077 Sk2s scale = Sk2s(SkScalarInvert(SK_Scalar1 + fW)); |
1158 SkScalar newW = subdivide_w_value(fW); | 1078 SkScalar newW = subdivide_w_value(fW); |
1159 | 1079 |
1160 Sk2s p0 = from_point(fPts[0]); | 1080 Sk2s p0 = from_point(fPts[0]); |
1161 Sk2s p1 = from_point(fPts[1]); | 1081 Sk2s p1 = from_point(fPts[1]); |
1162 Sk2s p2 = from_point(fPts[2]); | 1082 Sk2s p2 = from_point(fPts[2]); |
1163 Sk2s ww(fW); | 1083 Sk2s ww(fW); |
1164 | 1084 |
1165 Sk2s wp1 = ww * p1; | 1085 Sk2s wp1 = ww * p1; |
1166 Sk2s m = (p0 + twice(wp1) + p2) * scale * Sk2s(0.5f); | 1086 Sk2s m = (p0 + times_2(wp1) + p2) * scale * Sk2s(0.5f); |
1167 | 1087 |
1168 dst[0].fPts[0] = fPts[0]; | 1088 dst[0].fPts[0] = fPts[0]; |
1169 dst[0].fPts[1] = to_point((p0 + wp1) * scale); | 1089 dst[0].fPts[1] = to_point((p0 + wp1) * scale); |
1170 dst[0].fPts[2] = dst[1].fPts[0] = to_point(m); | 1090 dst[0].fPts[2] = dst[1].fPts[0] = to_point(m); |
1171 dst[1].fPts[1] = to_point((wp1 + p2) * scale); | 1091 dst[1].fPts[1] = to_point((wp1 + p2) * scale); |
1172 dst[1].fPts[2] = fPts[2]; | 1092 dst[1].fPts[2] = fPts[2]; |
1173 | 1093 |
1174 dst[0].fW = dst[1].fW = newW; | 1094 dst[0].fW = dst[1].fW = newW; |
1175 } | 1095 } |
1176 | 1096 |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1418 matrix.preScale(SK_Scalar1, -SK_Scalar1); | 1338 matrix.preScale(SK_Scalar1, -SK_Scalar1); |
1419 } | 1339 } |
1420 if (userMatrix) { | 1340 if (userMatrix) { |
1421 matrix.postConcat(*userMatrix); | 1341 matrix.postConcat(*userMatrix); |
1422 } | 1342 } |
1423 for (int i = 0; i < conicCount; ++i) { | 1343 for (int i = 0; i < conicCount; ++i) { |
1424 matrix.mapPoints(dst[i].fPts, 3); | 1344 matrix.mapPoints(dst[i].fPts, 3); |
1425 } | 1345 } |
1426 return conicCount; | 1346 return conicCount; |
1427 } | 1347 } |
OLD | NEW |