Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Unified Diff: src/core/SkEdgeClipper.cpp

Issue 1303873003: fix cubic clip in y (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix override Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gm/cubicpaths.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « gm/cubicpaths.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698