| Index: src/core/SkPath.cpp
|
| diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
|
| index 6dc056e81f09c32ec63775b7dcd7d770783120c7..6e09af78dd1a03a5ac80f5aa0d87dfc379f19465 100644
|
| --- a/src/core/SkPath.cpp
|
| +++ b/src/core/SkPath.cpp
|
| @@ -1,4 +1,3 @@
|
| -
|
| /*
|
| * Copyright 2006 The Android Open Source Project
|
| *
|
| @@ -6,15 +5,17 @@
|
| * found in the LICENSE file.
|
| */
|
|
|
| -
|
| #include "SkBuffer.h"
|
| #include "SkErrorInternals.h"
|
| +#include "SkGeometry.h"
|
| #include "SkMath.h"
|
| #include "SkPath.h"
|
| #include "SkPathRef.h"
|
| #include "SkRRect.h"
|
| #include "SkThread.h"
|
|
|
| +#define SK_SUPPORT_LEGACY_ADDOVAL
|
| +
|
| ////////////////////////////////////////////////////////////////////////////
|
|
|
| /**
|
| @@ -282,8 +283,23 @@ bool SkPath::conservativelyContainsRect(const SkRect& rect) const {
|
| SkDEBUGFAIL("unknown verb");
|
| }
|
| if (-1 != nextPt) {
|
| - if (!check_edge_against_rect(prevPt, pts[nextPt], rect, direction)) {
|
| - return false;
|
| + if (SkPath::kConic_Verb == verb) {
|
| + SkConic orig;
|
| + orig.set(pts, iter.conicWeight());
|
| + SkPoint quadPts[5];
|
| + int count = orig.chopIntoQuadsPOW2(quadPts, 1);
|
| + SK_ALWAYSBREAK(2 == count);
|
| +
|
| + if (!check_edge_against_rect(quadPts[0], quadPts[2], rect, direction)) {
|
| + return false;
|
| + }
|
| + if (!check_edge_against_rect(quadPts[2], quadPts[4], rect, direction)) {
|
| + return false;
|
| + }
|
| + } else {
|
| + if (!check_edge_against_rect(prevPt, pts[nextPt], rect, direction)) {
|
| + return false;
|
| + }
|
| }
|
| prevPt = pts[nextPt];
|
| }
|
| @@ -1173,6 +1189,7 @@ void SkPath::addOval(const SkRect& oval, Direction dir) {
|
|
|
| SkAutoPathBoundsUpdate apbu(this, oval);
|
|
|
| +#ifdef SK_SUPPORT_LEGACY_ADDOVAL
|
| SkScalar cx = oval.centerX();
|
| SkScalar cy = oval.centerY();
|
| SkScalar rx = SkScalarHalf(oval.width());
|
| @@ -1184,11 +1201,11 @@ void SkPath::addOval(const SkRect& oval, Direction dir) {
|
| SkScalar my = SkScalarMul(ry, SK_ScalarRoot2Over2);
|
|
|
| /*
|
| - To handle imprecision in computing the center and radii, we revert to
|
| - the provided bounds when we can (i.e. use oval.fLeft instead of cx-rx)
|
| - to ensure that we don't exceed the oval's bounds *ever*, since we want
|
| - to use oval for our fast-bounds, rather than have to recompute it.
|
| - */
|
| + To handle imprecision in computing the center and radii, we revert to
|
| + the provided bounds when we can (i.e. use oval.fLeft instead of cx-rx)
|
| + to ensure that we don't exceed the oval's bounds *ever*, since we want
|
| + to use oval for our fast-bounds, rather than have to recompute it.
|
| + */
|
| const SkScalar L = oval.fLeft; // cx - rx
|
| const SkScalar T = oval.fTop; // cy - ry
|
| const SkScalar R = oval.fRight; // cx + rx
|
| @@ -1215,6 +1232,29 @@ void SkPath::addOval(const SkRect& oval, Direction dir) {
|
| this->quadTo(cx + sx, T, cx + mx, cy - my);
|
| this->quadTo( R, cy - sy, R, cy );
|
| }
|
| +#else
|
| + const SkScalar L = oval.fLeft;
|
| + const SkScalar T = oval.fTop;
|
| + const SkScalar R = oval.fRight;
|
| + const SkScalar B = oval.fBottom;
|
| + const SkScalar cx = oval.centerX();
|
| + const SkScalar cy = oval.centerY();
|
| + const SkScalar weight = SK_ScalarRoot2Over2;
|
| +
|
| + this->incReserve(9); // move + 4 conics
|
| + this->moveTo(R, cy);
|
| + if (dir == kCCW_Direction) {
|
| + this->conicTo(R, T, cx, T, weight);
|
| + this->conicTo(L, T, L, cy, weight);
|
| + this->conicTo(L, B, cx, B, weight);
|
| + this->conicTo(R, B, R, cy, weight);
|
| + } else {
|
| + this->conicTo(R, B, cx, B, weight);
|
| + this->conicTo(L, B, L, cy, weight);
|
| + this->conicTo(L, T, cx, T, weight);
|
| + this->conicTo(R, T, R, cy, weight);
|
| + }
|
| +#endif
|
| this->close();
|
|
|
| SkPathRef::Editor ed(&fPathRef);
|
| @@ -1530,21 +1570,6 @@ void SkPath::offset(SkScalar dx, SkScalar dy, SkPath* dst) const {
|
| this->transform(matrix, dst);
|
| }
|
|
|
| -#include "SkGeometry.h"
|
| -
|
| -static void subdivide_quad_to(SkPath* path, const SkPoint pts[3],
|
| - int level = 2) {
|
| - if (--level >= 0) {
|
| - SkPoint tmp[5];
|
| -
|
| - SkChopQuadAtHalf(pts, tmp);
|
| - subdivide_quad_to(path, &tmp[0], level);
|
| - subdivide_quad_to(path, &tmp[2], level);
|
| - } else {
|
| - path->quadTo(pts[1], pts[2]);
|
| - }
|
| -}
|
| -
|
| static void subdivide_cubic_to(SkPath* path, const SkPoint pts[4],
|
| int level = 2) {
|
| if (--level >= 0) {
|
| @@ -1581,11 +1606,13 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const {
|
| tmp.lineTo(pts[1]);
|
| break;
|
| case kQuad_Verb:
|
| - subdivide_quad_to(&tmp, pts);
|
| + // promote the quad to a conic
|
| + tmp.conicTo(pts[1], pts[2],
|
| + SkConic::TransformW(pts, SK_Scalar1, matrix));
|
| break;
|
| case kConic_Verb:
|
| - SkDEBUGFAIL("TODO: compute new weight");
|
| - tmp.conicTo(pts[1], pts[2], iter.conicWeight());
|
| + tmp.conicTo(pts[1], pts[2],
|
| + SkConic::TransformW(pts, iter.conicWeight(), matrix));
|
| break;
|
| case kCubic_Verb:
|
| subdivide_cubic_to(&tmp, pts);
|
|
|