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" |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
172 Sk2s P1 = from_point(src[1]); | 172 Sk2s P1 = from_point(src[1]); |
173 Sk2s P2 = from_point(src[2]); | 173 Sk2s P2 = from_point(src[2]); |
174 | 174 |
175 Sk2s B = P1 - P0; | 175 Sk2s B = P1 - P0; |
176 Sk2s A = P2 - P1 - B; | 176 Sk2s A = P2 - P1 - B; |
177 Sk2s T = A * Sk2s(t) + B; | 177 Sk2s T = A * Sk2s(t) + B; |
178 | 178 |
179 return to_vector(T + T); | 179 return to_vector(T + T); |
180 } | 180 } |
181 | 181 |
182 static void interp_quad_coords(const SkScalar* src, SkScalar* dst, SkScalar t) { | |
183 SkScalar ab = SkScalarInterp(src[0], src[2], t); | |
184 SkScalar bc = SkScalarInterp(src[2], src[4], t); | |
185 | |
186 dst[0] = src[0]; | |
187 dst[2] = ab; | |
188 dst[4] = SkScalarInterp(ab, bc, t); | |
189 dst[6] = bc; | |
190 dst[8] = src[4]; | |
191 } | |
192 | |
193 void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t) { | |
194 SkASSERT(t > 0 && t < SK_Scalar1); | |
195 | |
196 interp_quad_coords(&src[0].fX, &dst[0].fX, t); | |
197 interp_quad_coords(&src[0].fY, &dst[0].fY, t); | |
198 } | |
199 | |
200 static inline Sk2s interp(const Sk2s& v0, const Sk2s& v1, const Sk2s& t) { | 182 static inline Sk2s interp(const Sk2s& v0, const Sk2s& v1, const Sk2s& t) { |
201 return v0 + (v1 - v0) * t; | 183 return v0 + (v1 - v0) * t; |
202 } | 184 } |
203 | 185 |
204 void SkChopQuadAt2(const SkPoint src[3], SkPoint dst[5], SkScalar t) { | 186 void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t) { |
205 SkASSERT(t > 0 && t < SK_Scalar1); | 187 SkASSERT(t > 0 && t < SK_Scalar1); |
206 | 188 |
207 Sk2s p0 = from_point(src[0]); | 189 Sk2s p0 = from_point(src[0]); |
208 Sk2s p1 = from_point(src[1]); | 190 Sk2s p1 = from_point(src[1]); |
209 Sk2s p2 = from_point(src[2]); | 191 Sk2s p2 = from_point(src[2]); |
210 Sk2s tt(t); | 192 Sk2s tt(t); |
211 | 193 |
212 Sk2s p01 = interp(p0, p1, tt); | 194 Sk2s p01 = interp(p0, p1, tt); |
213 Sk2s p12 = interp(p1, p2, tt); | 195 Sk2s p12 = interp(p1, p2, tt); |
214 | 196 |
215 dst[0] = to_point(p0); | 197 dst[0] = to_point(p0); |
216 dst[1] = to_point(p01); | 198 dst[1] = to_point(p01); |
217 dst[2] = to_point(interp(p01, p12, tt)); | 199 dst[2] = to_point(interp(p01, p12, tt)); |
218 dst[3] = to_point(p12); | 200 dst[3] = to_point(p12); |
219 dst[4] = to_point(p2); | 201 dst[4] = to_point(p2); |
220 } | 202 } |
221 | 203 |
222 void SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5]) { | 204 void SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5]) { |
223 SkScalar x01 = SkScalarAve(src[0].fX, src[1].fX); | 205 SkChopQuadAt(src, dst, 0.5f); return; |
mtklein
2015/03/26 14:24:30
No need for return?
| |
224 SkScalar y01 = SkScalarAve(src[0].fY, src[1].fY); | |
225 SkScalar x12 = SkScalarAve(src[1].fX, src[2].fX); | |
226 SkScalar y12 = SkScalarAve(src[1].fY, src[2].fY); | |
227 | |
228 dst[0] = src[0]; | |
229 dst[1].set(x01, y01); | |
230 dst[2].set(SkScalarAve(x01, x12), SkScalarAve(y01, y12)); | |
231 dst[3].set(x12, y12); | |
232 dst[4] = src[2]; | |
233 } | 206 } |
234 | 207 |
235 /** Quad'(t) = At + B, where | 208 /** Quad'(t) = At + B, where |
236 A = 2(a - 2b + c) | 209 A = 2(a - 2b + c) |
237 B = 2(b - a) | 210 B = 2(b - a) |
238 Solve for t, only if it fits between 0 < t < 1 | 211 Solve for t, only if it fits between 0 < t < 1 |
239 */ | 212 */ |
240 int SkFindQuadExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar tValue[1]) { | 213 int SkFindQuadExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar tValue[1]) { |
241 /* At + B == 0 | 214 /* At + B == 0 |
242 t = -B / A | 215 t = -B / A |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d, | 420 int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d, |
448 SkScalar tValues[2]) { | 421 SkScalar tValues[2]) { |
449 // we divide A,B,C by 3 to simplify | 422 // we divide A,B,C by 3 to simplify |
450 SkScalar A = d - a + 3*(b - c); | 423 SkScalar A = d - a + 3*(b - c); |
451 SkScalar B = 2*(a - b - b + c); | 424 SkScalar B = 2*(a - b - b + c); |
452 SkScalar C = b - a; | 425 SkScalar C = b - a; |
453 | 426 |
454 return SkFindUnitQuadRoots(A, B, C, tValues); | 427 return SkFindUnitQuadRoots(A, B, C, tValues); |
455 } | 428 } |
456 | 429 |
457 static void interp_cubic_coords(const SkScalar* src, SkScalar* dst, | |
458 SkScalar t) { | |
459 SkScalar ab = SkScalarInterp(src[0], src[2], t); | |
460 SkScalar bc = SkScalarInterp(src[2], src[4], t); | |
461 SkScalar cd = SkScalarInterp(src[4], src[6], t); | |
462 SkScalar abc = SkScalarInterp(ab, bc, t); | |
463 SkScalar bcd = SkScalarInterp(bc, cd, t); | |
464 SkScalar abcd = SkScalarInterp(abc, bcd, t); | |
465 | |
466 dst[0] = src[0]; | |
467 dst[2] = ab; | |
468 dst[4] = abc; | |
469 dst[6] = abcd; | |
470 dst[8] = bcd; | |
471 dst[10] = cd; | |
472 dst[12] = src[6]; | |
473 } | |
474 | |
475 void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t) { | 430 void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t) { |
476 SkASSERT(t > 0 && t < SK_Scalar1); | 431 SkASSERT(t > 0 && t < SK_Scalar1); |
477 | 432 |
478 interp_cubic_coords(&src[0].fX, &dst[0].fX, t); | |
479 interp_cubic_coords(&src[0].fY, &dst[0].fY, t); | |
480 } | |
481 | |
482 void SkChopCubicAt2(const SkPoint src[4], SkPoint dst[7], SkScalar t) { | |
483 SkASSERT(t > 0 && t < SK_Scalar1); | |
484 | |
485 Sk2s p0 = from_point(src[0]); | 433 Sk2s p0 = from_point(src[0]); |
486 Sk2s p1 = from_point(src[1]); | 434 Sk2s p1 = from_point(src[1]); |
487 Sk2s p2 = from_point(src[2]); | 435 Sk2s p2 = from_point(src[2]); |
488 Sk2s p3 = from_point(src[3]); | 436 Sk2s p3 = from_point(src[3]); |
489 Sk2s tt(t); | 437 Sk2s tt(t); |
490 | 438 |
491 Sk2s ab = interp(p0, p1, tt); | 439 Sk2s ab = interp(p0, p1, tt); |
492 Sk2s bc = interp(p1, p2, tt); | 440 Sk2s bc = interp(p1, p2, tt); |
493 Sk2s cd = interp(p2, p3, tt); | 441 Sk2s cd = interp(p2, p3, tt); |
494 Sk2s abc = interp(ab, bc, tt); | 442 Sk2s abc = interp(ab, bc, tt); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
564 // if we can't, just create a degenerate cubic | 512 // if we can't, just create a degenerate cubic |
565 dst[4] = dst[5] = dst[6] = src[3]; | 513 dst[4] = dst[5] = dst[6] = src[3]; |
566 break; | 514 break; |
567 } | 515 } |
568 } | 516 } |
569 } | 517 } |
570 } | 518 } |
571 } | 519 } |
572 | 520 |
573 void SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7]) { | 521 void SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7]) { |
574 SkScalar x01 = SkScalarAve(src[0].fX, src[1].fX); | 522 SkChopCubicAt(src, dst, 0.5f); |
575 SkScalar y01 = SkScalarAve(src[0].fY, src[1].fY); | |
576 SkScalar x12 = SkScalarAve(src[1].fX, src[2].fX); | |
577 SkScalar y12 = SkScalarAve(src[1].fY, src[2].fY); | |
578 SkScalar x23 = SkScalarAve(src[2].fX, src[3].fX); | |
579 SkScalar y23 = SkScalarAve(src[2].fY, src[3].fY); | |
580 | |
581 SkScalar x012 = SkScalarAve(x01, x12); | |
582 SkScalar y012 = SkScalarAve(y01, y12); | |
583 SkScalar x123 = SkScalarAve(x12, x23); | |
584 SkScalar y123 = SkScalarAve(y12, y23); | |
585 | |
586 dst[0] = src[0]; | |
587 dst[1].set(x01, y01); | |
588 dst[2].set(x012, y012); | |
589 dst[3].set(SkScalarAve(x012, x123), SkScalarAve(y012, y123)); | |
590 dst[4].set(x123, y123); | |
591 dst[5].set(x23, y23); | |
592 dst[6] = src[3]; | |
593 } | 523 } |
594 | 524 |
595 static void flatten_double_cubic_extrema(SkScalar coords[14]) { | 525 static void flatten_double_cubic_extrema(SkScalar coords[14]) { |
596 coords[4] = coords[8] = coords[6]; | 526 coords[4] = coords[8] = coords[6]; |
597 } | 527 } |
598 | 528 |
599 /** Given 4 points on a cubic bezier, chop it into 1, 2, 3 beziers such that | 529 /** Given 4 points on a cubic bezier, chop it into 1, 2, 3 beziers such that |
600 the resulting beziers are monotonic in Y. This is called by the scan | 530 the resulting beziers are monotonic in Y. This is called by the scan |
601 converter. Depending on what is returned, dst[] is treated as follows: | 531 converter. Depending on what is returned, dst[] is treated as follows: |
602 0 dst[0..3] is the original cubic | 532 0 dst[0..3] is the original cubic |
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1639 matrix.preScale(SK_Scalar1, -SK_Scalar1); | 1569 matrix.preScale(SK_Scalar1, -SK_Scalar1); |
1640 } | 1570 } |
1641 if (userMatrix) { | 1571 if (userMatrix) { |
1642 matrix.postConcat(*userMatrix); | 1572 matrix.postConcat(*userMatrix); |
1643 } | 1573 } |
1644 for (int i = 0; i < conicCount; ++i) { | 1574 for (int i = 0; i < conicCount; ++i) { |
1645 matrix.mapPoints(dst[i].fPts, 3); | 1575 matrix.mapPoints(dst[i].fPts, 3); |
1646 } | 1576 } |
1647 return conicCount; | 1577 return conicCount; |
1648 } | 1578 } |
OLD | NEW |