| OLD | NEW |
| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 SkScalar b = pts[0].fY - SkScalarMul(slope, pts[0].fX); | 61 SkScalar b = pts[0].fY - SkScalarMul(slope, pts[0].fX); |
| 62 // Solve for x coordinate at y = pt.fY | 62 // Solve for x coordinate at y = pt.fY |
| 63 SkScalar x = SkScalarDiv(pt.fY - b, slope); | 63 SkScalar x = SkScalarDiv(pt.fY - b, slope); |
| 64 return pt.fX <= x; | 64 return pt.fX <= x; |
| 65 } | 65 } |
| 66 | 66 |
| 67 /** If defined, this makes eval_quad and eval_cubic do more setup (sometimes | 67 /** If defined, this makes eval_quad and eval_cubic do more setup (sometimes |
| 68 involving integer multiplies by 2 or 3, but fewer calls to SkScalarMul. | 68 involving integer multiplies by 2 or 3, but fewer calls to SkScalarMul. |
| 69 May also introduce overflow of fixed when we compute our setup. | 69 May also introduce overflow of fixed when we compute our setup. |
| 70 */ | 70 */ |
| 71 #ifdef SK_SCALAR_IS_FIXED | 71 // #define DIRECT_EVAL_OF_POLYNOMIALS |
| 72 #define DIRECT_EVAL_OF_POLYNOMIALS | |
| 73 #endif | |
| 74 | 72 |
| 75 //////////////////////////////////////////////////////////////////////// | 73 //////////////////////////////////////////////////////////////////////// |
| 76 | 74 |
| 77 #ifdef SK_SCALAR_IS_FIXED | 75 static int is_not_monotonic(float a, float b, float c) { |
| 78 static int is_not_monotonic(int a, int b, int c, int d) | 76 float ab = a - b; |
| 79 { | 77 float bc = b - c; |
| 80 return (((a - b) | (b - c) | (c - d)) & ((b - a) | (c - b) | (d - c))) >
> 31; | 78 if (ab < 0) { |
| 79 bc = -bc; |
| 81 } | 80 } |
| 82 | 81 return ab == 0 || bc < 0; |
| 83 static int is_not_monotonic(int a, int b, int c) | 82 } |
| 84 { | |
| 85 return (((a - b) | (b - c)) & ((b - a) | (c - b))) >> 31; | |
| 86 } | |
| 87 #else | |
| 88 static int is_not_monotonic(float a, float b, float c) | |
| 89 { | |
| 90 float ab = a - b; | |
| 91 float bc = b - c; | |
| 92 if (ab < 0) | |
| 93 bc = -bc; | |
| 94 return ab == 0 || bc < 0; | |
| 95 } | |
| 96 #endif | |
| 97 | 83 |
| 98 //////////////////////////////////////////////////////////////////////// | 84 //////////////////////////////////////////////////////////////////////// |
| 99 | 85 |
| 100 static bool is_unit_interval(SkScalar x) | 86 static bool is_unit_interval(SkScalar x) |
| 101 { | 87 { |
| 102 return x > 0 && x < SK_Scalar1; | 88 return x > 0 && x < SK_Scalar1; |
| 103 } | 89 } |
| 104 | 90 |
| 105 static int valid_unit_divide(SkScalar numer, SkScalar denom, SkScalar* ratio) | 91 static int valid_unit_divide(SkScalar numer, SkScalar denom, SkScalar* ratio) |
| 106 { | 92 { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 134 */ | 120 */ |
| 135 int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]) | 121 int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]) |
| 136 { | 122 { |
| 137 SkASSERT(roots); | 123 SkASSERT(roots); |
| 138 | 124 |
| 139 if (A == 0) | 125 if (A == 0) |
| 140 return valid_unit_divide(-C, B, roots); | 126 return valid_unit_divide(-C, B, roots); |
| 141 | 127 |
| 142 SkScalar* r = roots; | 128 SkScalar* r = roots; |
| 143 | 129 |
| 144 #ifdef SK_SCALAR_IS_FLOAT | |
| 145 float R = B*B - 4*A*C; | 130 float R = B*B - 4*A*C; |
| 146 if (R < 0 || SkScalarIsNaN(R)) { // complex roots | 131 if (R < 0 || SkScalarIsNaN(R)) { // complex roots |
| 147 return 0; | 132 return 0; |
| 148 } | 133 } |
| 149 R = sk_float_sqrt(R); | 134 R = sk_float_sqrt(R); |
| 150 #else | |
| 151 Sk64 RR, tmp; | |
| 152 | |
| 153 RR.setMul(B,B); | |
| 154 tmp.setMul(A,C); | |
| 155 tmp.shiftLeft(2); | |
| 156 RR.sub(tmp); | |
| 157 if (RR.isNeg()) | |
| 158 return 0; | |
| 159 SkFixed R = RR.getSqrt(); | |
| 160 #endif | |
| 161 | 135 |
| 162 SkScalar Q = (B < 0) ? -(B-R)/2 : -(B+R)/2; | 136 SkScalar Q = (B < 0) ? -(B-R)/2 : -(B+R)/2; |
| 163 r += valid_unit_divide(Q, A, r); | 137 r += valid_unit_divide(Q, A, r); |
| 164 r += valid_unit_divide(C, Q, r); | 138 r += valid_unit_divide(C, Q, r); |
| 165 if (r - roots == 2) | 139 if (r - roots == 2) |
| 166 { | 140 { |
| 167 if (roots[0] > roots[1]) | 141 if (roots[0] > roots[1]) |
| 168 SkTSwap<SkScalar>(roots[0], roots[1]); | 142 SkTSwap<SkScalar>(roots[0], roots[1]); |
| 169 else if (roots[0] == roots[1]) // nearly-equal? | 143 else if (roots[0] == roots[1]) // nearly-equal? |
| 170 r -= 1; // skip the double root | 144 r -= 1; // skip the double root |
| 171 } | 145 } |
| 172 return (int)(r - roots); | 146 return (int)(r - roots); |
| 173 } | 147 } |
| 174 | 148 |
| 175 #ifdef SK_SCALAR_IS_FIXED | 149 /////////////////////////////////////////////////////////////////////////////// |
| 176 /** Trim A/B/C down so that they are all <= 32bits | 150 /////////////////////////////////////////////////////////////////////////////// |
| 177 and then call SkFindUnitQuadRoots() | |
| 178 */ | |
| 179 static int Sk64FindFixedQuadRoots(const Sk64& A, const Sk64& B, const Sk64& C, S
kFixed roots[2]) | |
| 180 { | |
| 181 int na = A.shiftToMake32(); | |
| 182 int nb = B.shiftToMake32(); | |
| 183 int nc = C.shiftToMake32(); | |
| 184 | |
| 185 int shift = SkMax32(na, SkMax32(nb, nc)); | |
| 186 SkASSERT(shift >= 0); | |
| 187 | |
| 188 return SkFindUnitQuadRoots(A.getShiftRight(shift), B.getShiftRight(shift), C
.getShiftRight(shift), roots); | |
| 189 } | |
| 190 #endif | |
| 191 | |
| 192 ////////////////////////////////////////////////////////////////////////////////
///// | |
| 193 ////////////////////////////////////////////////////////////////////////////////
///// | |
| 194 | 151 |
| 195 static SkScalar eval_quad(const SkScalar src[], SkScalar t) | 152 static SkScalar eval_quad(const SkScalar src[], SkScalar t) |
| 196 { | 153 { |
| 197 SkASSERT(src); | 154 SkASSERT(src); |
| 198 SkASSERT(t >= 0 && t <= SK_Scalar1); | 155 SkASSERT(t >= 0 && t <= SK_Scalar1); |
| 199 | 156 |
| 200 #ifdef DIRECT_EVAL_OF_POLYNOMIALS | 157 #ifdef DIRECT_EVAL_OF_POLYNOMIALS |
| 201 SkScalar C = src[0]; | 158 SkScalar C = src[0]; |
| 202 SkScalar A = src[4] - 2 * src[2] + C; | 159 SkScalar A = src[4] - 2 * src[2] + C; |
| 203 SkScalar B = 2 * (src[2] - C); | 160 SkScalar B = 2 * (src[2] - C); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 /** Quad'(t) = At + B, where | 247 /** Quad'(t) = At + B, where |
| 291 A = 2(a - 2b + c) | 248 A = 2(a - 2b + c) |
| 292 B = 2(b - a) | 249 B = 2(b - a) |
| 293 Solve for t, only if it fits between 0 < t < 1 | 250 Solve for t, only if it fits between 0 < t < 1 |
| 294 */ | 251 */ |
| 295 int SkFindQuadExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar tValue[1]) | 252 int SkFindQuadExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar tValue[1]) |
| 296 { | 253 { |
| 297 /* At + B == 0 | 254 /* At + B == 0 |
| 298 t = -B / A | 255 t = -B / A |
| 299 */ | 256 */ |
| 300 #ifdef SK_SCALAR_IS_FIXED | |
| 301 return is_not_monotonic(a, b, c) && valid_unit_divide(a - b, a - b - b + c,
tValue); | |
| 302 #else | |
| 303 return valid_unit_divide(a - b, a - b - b + c, tValue); | 257 return valid_unit_divide(a - b, a - b - b + c, tValue); |
| 304 #endif | |
| 305 } | 258 } |
| 306 | 259 |
| 307 static inline void flatten_double_quad_extrema(SkScalar coords[14]) | 260 static inline void flatten_double_quad_extrema(SkScalar coords[14]) |
| 308 { | 261 { |
| 309 coords[2] = coords[6] = coords[4]; | 262 coords[2] = coords[6] = coords[4]; |
| 310 } | 263 } |
| 311 | 264 |
| 312 /* Returns 0 for 1 quad, and 1 for two quads, either way the answer is | 265 /* Returns 0 for 1 quad, and 1 for two quads, either way the answer is |
| 313 stored in dst[]. Guarantees that the 1/2 quads will be monotonic. | 266 stored in dst[]. Guarantees that the 1/2 quads will be monotonic. |
| 314 */ | 267 */ |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 // | 347 // |
| 395 // t = - (Ax Bx + Ay By) / (Bx ^ 2 + By ^ 2) | 348 // t = - (Ax Bx + Ay By) / (Bx ^ 2 + By ^ 2) |
| 396 // | 349 // |
| 397 float SkFindQuadMaxCurvature(const SkPoint src[3]) { | 350 float SkFindQuadMaxCurvature(const SkPoint src[3]) { |
| 398 SkScalar Ax = src[1].fX - src[0].fX; | 351 SkScalar Ax = src[1].fX - src[0].fX; |
| 399 SkScalar Ay = src[1].fY - src[0].fY; | 352 SkScalar Ay = src[1].fY - src[0].fY; |
| 400 SkScalar Bx = src[0].fX - src[1].fX - src[1].fX + src[2].fX; | 353 SkScalar Bx = src[0].fX - src[1].fX - src[1].fX + src[2].fX; |
| 401 SkScalar By = src[0].fY - src[1].fY - src[1].fY + src[2].fY; | 354 SkScalar By = src[0].fY - src[1].fY - src[1].fY + src[2].fY; |
| 402 SkScalar t = 0; // 0 means don't chop | 355 SkScalar t = 0; // 0 means don't chop |
| 403 | 356 |
| 404 #ifdef SK_SCALAR_IS_FLOAT | |
| 405 (void)valid_unit_divide(-(Ax * Bx + Ay * By), Bx * Bx + By * By, &t); | 357 (void)valid_unit_divide(-(Ax * Bx + Ay * By), Bx * Bx + By * By, &t); |
| 406 #else | |
| 407 // !!! should I use SkFloat here? seems like it | |
| 408 Sk64 numer, denom, tmp; | |
| 409 | |
| 410 numer.setMul(Ax, -Bx); | |
| 411 tmp.setMul(Ay, -By); | |
| 412 numer.add(tmp); | |
| 413 | |
| 414 if (numer.isPos()) // do nothing if numer <= 0 | |
| 415 { | |
| 416 denom.setMul(Bx, Bx); | |
| 417 tmp.setMul(By, By); | |
| 418 denom.add(tmp); | |
| 419 SkASSERT(!denom.isNeg()); | |
| 420 if (numer < denom) | |
| 421 { | |
| 422 t = numer.getFixedDiv(denom); | |
| 423 SkASSERT(t >= 0 && t <= SK_Fixed1); // assert that we're numeric
ally stable (ha!) | |
| 424 if ((unsigned)t >= SK_Fixed1) // runtime check for numeric
al stability | |
| 425 t = 0; // ignore the chop | |
| 426 } | |
| 427 } | |
| 428 #endif | |
| 429 return t; | 358 return t; |
| 430 } | 359 } |
| 431 | 360 |
| 432 int SkChopQuadAtMaxCurvature(const SkPoint src[3], SkPoint dst[5]) | 361 int SkChopQuadAtMaxCurvature(const SkPoint src[3], SkPoint dst[5]) |
| 433 { | 362 { |
| 434 SkScalar t = SkFindQuadMaxCurvature(src); | 363 SkScalar t = SkFindQuadMaxCurvature(src); |
| 435 if (t == 0) { | 364 if (t == 0) { |
| 436 memcpy(dst, src, 3 * sizeof(SkPoint)); | 365 memcpy(dst, src, 3 * sizeof(SkPoint)); |
| 437 return 1; | 366 return 1; |
| 438 } else { | 367 } else { |
| 439 SkChopQuadAt(src, dst, t); | 368 SkChopQuadAt(src, dst, t); |
| 440 return 2; | 369 return 2; |
| 441 } | 370 } |
| 442 } | 371 } |
| 443 | 372 |
| 444 #ifdef SK_SCALAR_IS_FLOAT | 373 #define SK_ScalarTwoThirds (0.666666666f) |
| 445 #define SK_ScalarTwoThirds (0.666666666f) | |
| 446 #else | |
| 447 #define SK_ScalarTwoThirds ((SkFixed)(43691)) | |
| 448 #endif | |
| 449 | 374 |
| 450 void SkConvertQuadToCubic(const SkPoint src[3], SkPoint dst[4]) { | 375 void SkConvertQuadToCubic(const SkPoint src[3], SkPoint dst[4]) { |
| 451 const SkScalar scale = SK_ScalarTwoThirds; | 376 const SkScalar scale = SK_ScalarTwoThirds; |
| 452 dst[0] = src[0]; | 377 dst[0] = src[0]; |
| 453 dst[1].set(src[0].fX + SkScalarMul(src[1].fX - src[0].fX, scale), | 378 dst[1].set(src[0].fX + SkScalarMul(src[1].fX - src[0].fX, scale), |
| 454 src[0].fY + SkScalarMul(src[1].fY - src[0].fY, scale)); | 379 src[0].fY + SkScalarMul(src[1].fY - src[0].fY, scale)); |
| 455 dst[2].set(src[2].fX + SkScalarMul(src[1].fX - src[2].fX, scale), | 380 dst[2].set(src[2].fX + SkScalarMul(src[1].fX - src[2].fX, scale), |
| 456 src[2].fY + SkScalarMul(src[1].fY - src[2].fY, scale)); | 381 src[2].fY + SkScalarMul(src[1].fY - src[2].fY, scale)); |
| 457 dst[3] = src[2]; | 382 dst[3] = src[2]; |
| 458 } | 383 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 } | 471 } |
| 547 | 472 |
| 548 /** Cubic'(t) = At^2 + Bt + C, where | 473 /** Cubic'(t) = At^2 + Bt + C, where |
| 549 A = 3(-a + 3(b - c) + d) | 474 A = 3(-a + 3(b - c) + d) |
| 550 B = 6(a - 2b + c) | 475 B = 6(a - 2b + c) |
| 551 C = 3(b - a) | 476 C = 3(b - a) |
| 552 Solve for t, keeping only those that fit betwee 0 < t < 1 | 477 Solve for t, keeping only those that fit betwee 0 < t < 1 |
| 553 */ | 478 */ |
| 554 int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d, SkScalar
tValues[2]) | 479 int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d, SkScalar
tValues[2]) |
| 555 { | 480 { |
| 556 #ifdef SK_SCALAR_IS_FIXED | |
| 557 if (!is_not_monotonic(a, b, c, d)) | |
| 558 return 0; | |
| 559 #endif | |
| 560 | |
| 561 // we divide A,B,C by 3 to simplify | 481 // we divide A,B,C by 3 to simplify |
| 562 SkScalar A = d - a + 3*(b - c); | 482 SkScalar A = d - a + 3*(b - c); |
| 563 SkScalar B = 2*(a - b - b + c); | 483 SkScalar B = 2*(a - b - b + c); |
| 564 SkScalar C = b - a; | 484 SkScalar C = b - a; |
| 565 | 485 |
| 566 return SkFindUnitQuadRoots(A, B, C, tValues); | 486 return SkFindUnitQuadRoots(A, B, C, tValues); |
| 567 } | 487 } |
| 568 | 488 |
| 569 static void interp_cubic_coords(const SkScalar* src, SkScalar* dst, SkScalar t) | 489 static void interp_cubic_coords(const SkScalar* src, SkScalar* dst, SkScalar t) |
| 570 { | 490 { |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 (BxCy - ByCx)t^2 + (AxCy - AyCx)t + AxBy - AyBx == 0 | 660 (BxCy - ByCx)t^2 + (AxCy - AyCx)t + AxBy - AyBx == 0 |
| 741 */ | 661 */ |
| 742 int SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[]) | 662 int SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[]) |
| 743 { | 663 { |
| 744 SkScalar Ax = src[1].fX - src[0].fX; | 664 SkScalar Ax = src[1].fX - src[0].fX; |
| 745 SkScalar Ay = src[1].fY - src[0].fY; | 665 SkScalar Ay = src[1].fY - src[0].fY; |
| 746 SkScalar Bx = src[2].fX - 2 * src[1].fX + src[0].fX; | 666 SkScalar Bx = src[2].fX - 2 * src[1].fX + src[0].fX; |
| 747 SkScalar By = src[2].fY - 2 * src[1].fY + src[0].fY; | 667 SkScalar By = src[2].fY - 2 * src[1].fY + src[0].fY; |
| 748 SkScalar Cx = src[3].fX + 3 * (src[1].fX - src[2].fX) - src[0].fX; | 668 SkScalar Cx = src[3].fX + 3 * (src[1].fX - src[2].fX) - src[0].fX; |
| 749 SkScalar Cy = src[3].fY + 3 * (src[1].fY - src[2].fY) - src[0].fY; | 669 SkScalar Cy = src[3].fY + 3 * (src[1].fY - src[2].fY) - src[0].fY; |
| 750 int count; | |
| 751 | 670 |
| 752 #ifdef SK_SCALAR_IS_FLOAT | 671 return SkFindUnitQuadRoots(Bx*Cy - By*Cx, Ax*Cy - Ay*Cx, Ax*By - Ay*Bx, tVal
ues); |
| 753 count = SkFindUnitQuadRoots(Bx*Cy - By*Cx, Ax*Cy - Ay*Cx, Ax*By - Ay*Bx, tVa
lues); | |
| 754 #else | |
| 755 Sk64 A, B, C, tmp; | |
| 756 | |
| 757 A.setMul(Bx, Cy); | |
| 758 tmp.setMul(By, Cx); | |
| 759 A.sub(tmp); | |
| 760 | |
| 761 B.setMul(Ax, Cy); | |
| 762 tmp.setMul(Ay, Cx); | |
| 763 B.sub(tmp); | |
| 764 | |
| 765 C.setMul(Ax, By); | |
| 766 tmp.setMul(Ay, Bx); | |
| 767 C.sub(tmp); | |
| 768 | |
| 769 count = Sk64FindFixedQuadRoots(A, B, C, tValues); | |
| 770 #endif | |
| 771 | |
| 772 return count; | |
| 773 } | 672 } |
| 774 | 673 |
| 775 int SkChopCubicAtInflections(const SkPoint src[], SkPoint dst[10]) | 674 int SkChopCubicAtInflections(const SkPoint src[], SkPoint dst[10]) |
| 776 { | 675 { |
| 777 SkScalar tValues[2]; | 676 SkScalar tValues[2]; |
| 778 int count = SkFindCubicInflections(src, tValues); | 677 int count = SkFindCubicInflections(src, tValues); |
| 779 | 678 |
| 780 if (dst) | 679 if (dst) |
| 781 { | 680 { |
| 782 if (count == 0) | 681 if (count == 0) |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 memcpy(dst, data[i].fData, data[i].fCount * sizeof(dst[0])); | 783 memcpy(dst, data[i].fData, data[i].fCount * sizeof(dst[0])); |
| 885 int count = collaps_duplicates(dst, data[i].fCount); | 784 int count = collaps_duplicates(dst, data[i].fCount); |
| 886 SkASSERT(data[i].fCollapsedCount == count); | 785 SkASSERT(data[i].fCollapsedCount == count); |
| 887 for (int j = 1; j < count; ++j) { | 786 for (int j = 1; j < count; ++j) { |
| 888 SkASSERT(dst[j-1] < dst[j]); | 787 SkASSERT(dst[j-1] < dst[j]); |
| 889 } | 788 } |
| 890 } | 789 } |
| 891 } | 790 } |
| 892 #endif | 791 #endif |
| 893 | 792 |
| 894 #if defined _WIN32 && _MSC_VER >= 1300 && defined SK_SCALAR_IS_FIXED // disable
warning : unreachable code if building fixed point for windows desktop | |
| 895 #pragma warning ( disable : 4702 ) | |
| 896 #endif | |
| 897 | |
| 898 static SkScalar SkScalarCubeRoot(SkScalar x) { | 793 static SkScalar SkScalarCubeRoot(SkScalar x) { |
| 899 return sk_float_pow(x, 0.3333333f); | 794 return sk_float_pow(x, 0.3333333f); |
| 900 } | 795 } |
| 901 | 796 |
| 902 /* Solve coeff(t) == 0, returning the number of roots that | 797 /* Solve coeff(t) == 0, returning the number of roots that |
| 903 lie withing 0 < t < 1. | 798 lie withing 0 < t < 1. |
| 904 coeff[0]t^3 + coeff[1]t^2 + coeff[2]t + coeff[3] | 799 coeff[0]t^3 + coeff[1]t^2 + coeff[2]t + coeff[3] |
| 905 | 800 |
| 906 Eliminates repeated roots (so that all tValues are distinct, and are always | 801 Eliminates repeated roots (so that all tValues are distinct, and are always |
| 907 in increasing order. | 802 in increasing order. |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1628 } | 1523 } |
| 1629 if (this->findYExtrema(&t)) { | 1524 if (this->findYExtrema(&t)) { |
| 1630 this->evalAt(t, &pts[count++]); | 1525 this->evalAt(t, &pts[count++]); |
| 1631 } | 1526 } |
| 1632 bounds->set(pts, count); | 1527 bounds->set(pts, count); |
| 1633 } | 1528 } |
| 1634 | 1529 |
| 1635 void SkConic::computeFastBounds(SkRect* bounds) const { | 1530 void SkConic::computeFastBounds(SkRect* bounds) const { |
| 1636 bounds->set(fPts, 3); | 1531 bounds->set(fPts, 3); |
| 1637 } | 1532 } |
| OLD | NEW |