OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
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 "GrPathUtils.h" | 8 #include "GrPathUtils.h" |
9 | 9 |
10 #include "GrTypes.h" | 10 #include "GrTypes.h" |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 degQuad[1] = p[0]; | 398 degQuad[1] = p[0]; |
399 degQuad[2] = p[3]; | 399 degQuad[2] = p[3]; |
400 return; | 400 return; |
401 } | 401 } |
402 ab = p[2] - p[0]; | 402 ab = p[2] - p[0]; |
403 } | 403 } |
404 if (dc.isZero()) { | 404 if (dc.isZero()) { |
405 dc = p[1] - p[3]; | 405 dc = p[1] - p[3]; |
406 } | 406 } |
407 | 407 |
408 // When the ab and cd tangents are nearly parallel with vector from d to a t
he constraint that | 408 // When the ab and cd tangents are degenerate or nearly parallel with vector
from d to a the |
409 // the quad point falls between the tangents becomes hard to enforce and we
are likely to hit | 409 // constraint that the quad point falls between the tangents becomes hard to
enforce and we are |
410 // the max subdivision count. However, in this case the cubic is approaching
a line and the | 410 // likely to hit the max subdivision count. However, in this case the cubic
is approaching a |
411 // accuracy of the quad point isn't so important. We check if the two middle
cubic control | 411 // line and the accuracy of the quad point isn't so important. We check if t
he two middle cubic |
412 // points are very close to the baseline vector. If so then we just pick qua
dratic points on the | 412 // control points are very close to the baseline vector. If so then we just
pick quadratic |
413 // control polygon. | 413 // points on the control polygon. |
414 | 414 |
415 if (constrainWithinTangents) { | 415 if (constrainWithinTangents) { |
416 SkVector da = p[0] - p[3]; | 416 SkVector da = p[0] - p[3]; |
417 SkScalar invDALengthSqd = da.lengthSqd(); | 417 bool doQuads = dc.lengthSqd() < SK_ScalarNearlyZero || |
418 if (invDALengthSqd > SK_ScalarNearlyZero) { | 418 ab.lengthSqd() < SK_ScalarNearlyZero; |
419 invDALengthSqd = SkScalarInvert(invDALengthSqd); | 419 if (!doQuads) { |
420 // cross(ab, da)^2/length(da)^2 == sqd distance from b to line from
d to a. | 420 SkScalar invDALengthSqd = da.lengthSqd(); |
421 // same goed for point c using vector cd. | 421 if (invDALengthSqd > SK_ScalarNearlyZero) { |
422 SkScalar detABSqd = ab.cross(da); | 422 invDALengthSqd = SkScalarInvert(invDALengthSqd); |
423 detABSqd = SkScalarSquare(detABSqd); | 423 // cross(ab, da)^2/length(da)^2 == sqd distance from b to line f
rom d to a. |
424 SkScalar detDCSqd = dc.cross(da); | 424 // same goes for point c using vector cd. |
425 detDCSqd = SkScalarSquare(detDCSqd); | 425 SkScalar detABSqd = ab.cross(da); |
426 if (SkScalarMul(detABSqd, invDALengthSqd) < toleranceSqd && | 426 detABSqd = SkScalarSquare(detABSqd); |
427 SkScalarMul(detDCSqd, invDALengthSqd) < toleranceSqd) { | 427 SkScalar detDCSqd = dc.cross(da); |
428 SkPoint b = p[0] + ab; | 428 detDCSqd = SkScalarSquare(detDCSqd); |
429 SkPoint c = p[3] + dc; | 429 if (SkScalarMul(detABSqd, invDALengthSqd) < toleranceSqd && |
430 SkPoint mid = b + c; | 430 SkScalarMul(detDCSqd, invDALengthSqd) < toleranceSqd) { |
431 mid.scale(SK_ScalarHalf); | 431 doQuads = true; |
432 // Insert two quadratics to cover the case when ab points away f
rom d and/or dc | |
433 // points away from a. | |
434 if (SkVector::DotProduct(da, dc) < 0 || SkVector::DotProduct(ab,
da) > 0) { | |
435 SkPoint* qpts = quads->push_back_n(6); | |
436 qpts[0] = p[0]; | |
437 qpts[1] = b; | |
438 qpts[2] = mid; | |
439 qpts[3] = mid; | |
440 qpts[4] = c; | |
441 qpts[5] = p[3]; | |
442 } else { | |
443 SkPoint* qpts = quads->push_back_n(3); | |
444 qpts[0] = p[0]; | |
445 qpts[1] = mid; | |
446 qpts[2] = p[3]; | |
447 } | 432 } |
448 return; | |
449 } | 433 } |
450 } | 434 } |
| 435 if (doQuads) { |
| 436 SkPoint b = p[0] + ab; |
| 437 SkPoint c = p[3] + dc; |
| 438 SkPoint mid = b + c; |
| 439 mid.scale(SK_ScalarHalf); |
| 440 // Insert two quadratics to cover the case when ab points away from
d and/or dc |
| 441 // points away from a. |
| 442 if (SkVector::DotProduct(da, dc) < 0 || SkVector::DotProduct(ab,da)
> 0) { |
| 443 SkPoint* qpts = quads->push_back_n(6); |
| 444 qpts[0] = p[0]; |
| 445 qpts[1] = b; |
| 446 qpts[2] = mid; |
| 447 qpts[3] = mid; |
| 448 qpts[4] = c; |
| 449 qpts[5] = p[3]; |
| 450 } else { |
| 451 SkPoint* qpts = quads->push_back_n(3); |
| 452 qpts[0] = p[0]; |
| 453 qpts[1] = mid; |
| 454 qpts[2] = p[3]; |
| 455 } |
| 456 return; |
| 457 } |
451 } | 458 } |
452 | 459 |
453 static const SkScalar kLengthScale = 3 * SK_Scalar1 / 2; | 460 static const SkScalar kLengthScale = 3 * SK_Scalar1 / 2; |
454 static const int kMaxSubdivs = 10; | 461 static const int kMaxSubdivs = 10; |
455 | 462 |
456 ab.scale(kLengthScale); | 463 ab.scale(kLengthScale); |
457 dc.scale(kLengthScale); | 464 dc.scale(kLengthScale); |
458 | 465 |
459 // e0 and e1 are extrapolations along vectors ab and dc. | 466 // e0 and e1 are extrapolations along vectors ab and dc. |
460 SkVector c0 = p[0]; | 467 SkVector c0 = p[0]; |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 set_loop_klm(d, controlK, controlL, controlM); | 866 set_loop_klm(d, controlK, controlL, controlM); |
860 } else if (kCusp_CubicType == cType) { | 867 } else if (kCusp_CubicType == cType) { |
861 SkASSERT(0.f == d[0]); | 868 SkASSERT(0.f == d[0]); |
862 set_cusp_klm(d, controlK, controlL, controlM); | 869 set_cusp_klm(d, controlK, controlL, controlM); |
863 } else if (kQuadratic_CubicType == cType) { | 870 } else if (kQuadratic_CubicType == cType) { |
864 set_quadratic_klm(d, controlK, controlL, controlM); | 871 set_quadratic_klm(d, controlK, controlL, controlM); |
865 } | 872 } |
866 | 873 |
867 calc_cubic_klm(p, controlK, controlL, controlM, klm, &klm[3], &klm[6]); | 874 calc_cubic_klm(p, controlK, controlL, controlM, klm, &klm[3], &klm[6]); |
868 } | 875 } |
OLD | NEW |