| 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 |