| Index: src/core/SkEdgeClipper.cpp
|
| diff --git a/src/core/SkEdgeClipper.cpp b/src/core/SkEdgeClipper.cpp
|
| index 02fb4530fdf375ca866ab7f76f1c2997aa6e3b28..c6a4fb2971312217fa2eb4eb988e9b5594f671b7 100644
|
| --- a/src/core/SkEdgeClipper.cpp
|
| +++ b/src/core/SkEdgeClipper.cpp
|
| @@ -225,63 +225,15 @@ bool SkEdgeClipper::clipQuad(const SkPoint srcPts[3], const SkRect& clip) {
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -// Modify pts[] in place so that it is clipped in Y to the clip rect
|
| -static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) {
|
| -
|
| - // are we partially above
|
| - if (pts[0].fY < clip.fTop) {
|
| - SkPoint tmp[7];
|
| - if (SkChopMonoCubicAtY(pts, clip.fTop, tmp)) {
|
| - // tmp[3, 4].fY should all be to the below clip.fTop.
|
| - // Since we can't trust the numerics of
|
| - // the chopper, we force those conditions now
|
| - tmp[3].fY = clip.fTop;
|
| - clamp_ge(tmp[4].fY, clip.fTop);
|
| -
|
| - pts[0] = tmp[3];
|
| - pts[1] = tmp[4];
|
| - pts[2] = tmp[5];
|
| - } else {
|
| - // if chopMonoCubicAtY failed, then we may have hit inexact numerics
|
| - // so we just clamp against the top
|
| - for (int i = 0; i < 4; i++) {
|
| - clamp_ge(pts[i].fY, clip.fTop);
|
| - }
|
| - }
|
| - }
|
| -
|
| - // are we partially below
|
| - if (pts[3].fY > clip.fBottom) {
|
| - SkPoint tmp[7];
|
| - if (SkChopMonoCubicAtY(pts, clip.fBottom, tmp)) {
|
| - tmp[3].fY = clip.fBottom;
|
| - clamp_le(tmp[2].fY, clip.fBottom);
|
| -
|
| - pts[1] = tmp[1];
|
| - pts[2] = tmp[2];
|
| - pts[3] = tmp[3];
|
| - } else {
|
| - // if chopMonoCubicAtY failed, then we may have hit inexact numerics
|
| - // so we just clamp against the bottom
|
| - for (int i = 0; i < 4; i++) {
|
| - clamp_le(pts[i].fY, clip.fBottom);
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -static void chop_mono_cubic_at_x(SkPoint pts[4], SkScalar x, SkPoint tmp[7]) {
|
| - if (SkChopMonoCubicAtX(pts, x, tmp)) {
|
| - return;
|
| - }
|
| +static SkScalar mono_cubic_closestT(const SkScalar src[], SkScalar x) {
|
| SkScalar t = 0.5f;
|
| SkScalar lastT;
|
| SkScalar bestT SK_INIT_TO_AVOID_WARNING;
|
| SkScalar step = 0.25f;
|
| - SkScalar D = pts[0].fX;
|
| - SkScalar A = pts[3].fX + 3*(pts[1].fX - pts[2].fX) - D;
|
| - SkScalar B = 3*(pts[2].fX - pts[1].fX - pts[1].fX + D);
|
| - SkScalar C = 3*(pts[1].fX - D);
|
| + SkScalar D = src[0];
|
| + SkScalar A = src[6] + 3*(src[2] - src[4]) - D;
|
| + SkScalar B = 3*(src[4] - src[2] - src[2] + D);
|
| + SkScalar C = 3*(src[2] - D);
|
| x -= D;
|
| SkScalar closest = SK_ScalarMax;
|
| do {
|
| @@ -295,7 +247,52 @@ static void chop_mono_cubic_at_x(SkPoint pts[4], SkScalar x, SkPoint tmp[7]) {
|
| t += loc < x ? step : -step;
|
| step *= 0.5f;
|
| } while (closest > 0.25f && lastT != t);
|
| - SkChopCubicAt(pts, tmp, bestT);
|
| + return bestT;
|
| +}
|
| +
|
| +static void chop_mono_cubic_at_y(SkPoint src[4], SkScalar y, SkPoint dst[7]) {
|
| + if (SkChopMonoCubicAtY(src, y, dst)) {
|
| + return;
|
| + }
|
| + SkChopCubicAt(src, dst, mono_cubic_closestT(&src->fY, y));
|
| +}
|
| +
|
| +// Modify pts[] in place so that it is clipped in Y to the clip rect
|
| +static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) {
|
| +
|
| + // are we partially above
|
| + if (pts[0].fY < clip.fTop) {
|
| + SkPoint tmp[7];
|
| + chop_mono_cubic_at_y(pts, clip.fTop, tmp);
|
| + // tmp[3, 4].fY should all be to the below clip.fTop.
|
| + // Since we can't trust the numerics of
|
| + // the chopper, we force those conditions now
|
| + tmp[3].fY = clip.fTop;
|
| + clamp_ge(tmp[4].fY, clip.fTop);
|
| +
|
| + pts[0] = tmp[3];
|
| + pts[1] = tmp[4];
|
| + pts[2] = tmp[5];
|
| + }
|
| +
|
| + // are we partially below
|
| + if (pts[3].fY > clip.fBottom) {
|
| + SkPoint tmp[7];
|
| + chop_mono_cubic_at_y(pts, clip.fBottom, tmp);
|
| + tmp[3].fY = clip.fBottom;
|
| + clamp_le(tmp[2].fY, clip.fBottom);
|
| +
|
| + pts[1] = tmp[1];
|
| + pts[2] = tmp[2];
|
| + pts[3] = tmp[3];
|
| + }
|
| +}
|
| +
|
| +static void chop_mono_cubic_at_x(SkPoint src[4], SkScalar x, SkPoint dst[7]) {
|
| + if (SkChopMonoCubicAtX(src, x, dst)) {
|
| + return;
|
| + }
|
| + SkChopCubicAt(src, dst, mono_cubic_closestT(&src->fX, x));
|
| }
|
|
|
| // srcPts[] must be monotonic in X and Y
|
|
|