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 |