aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkEdgeClipper.cpp
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2016-07-20 10:06:59 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-07-20 10:06:59 -0700
commit158fabb071f2cb275bc88c139e88e8eb3bf140ee (patch)
treebdb0a34b1bd54f38df6ec4835cdbc879423dc9b7 /src/core/SkEdgeClipper.cpp
parent1f790aaeef47b02fe72b9b62d1e8c7ead85ae442 (diff)
re-chop if we fail on a big-bad-cubic
Diffstat (limited to 'src/core/SkEdgeClipper.cpp')
-rw-r--r--src/core/SkEdgeClipper.cpp20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/core/SkEdgeClipper.cpp b/src/core/SkEdgeClipper.cpp
index 85c519d364..b5ac27ae59 100644
--- a/src/core/SkEdgeClipper.cpp
+++ b/src/core/SkEdgeClipper.cpp
@@ -263,9 +263,25 @@ static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) {
if (pts[0].fY < clip.fTop) {
SkPoint tmp[7];
chop_mono_cubic_at_y(pts, clip.fTop, tmp);
+
+ /*
+ * For a large range in the points, we can do a poor job of chopping, such that the t
+ * we computed resulted in the lower cubic still being partly above the clip.
+ *
+ * If just the first or first 2 Y values are above the fTop, we can just smash them
+ * down. If the first 3 Ys are above fTop, we can't smash all 3, as that can really
+ * distort the cubic. In this case, we take the first output (tmp[3..6] and treat it as
+ * a guess, and re-chop against fTop. Then we fall through to checking if we need to
+ * smash the first 1 or 2 Y values.
+ */
+ if (tmp[3].fY < clip.fTop && tmp[4].fY < clip.fTop && tmp[5].fY < clip.fTop) {
+ SkPoint tmp2[4];
+ memcpy(tmp2, &tmp[3].fX, 4 * sizeof(SkPoint));
+ chop_mono_cubic_at_y(tmp2, 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
+ // 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);