aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkGeometry.cpp
diff options
context:
space:
mode:
authorGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-11-17 18:47:52 +0000
committerGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-11-17 18:47:52 +0000
commit77f0ef726f1f8b6769ed2509171afce8bac00b23 (patch)
tree4c2506498fc0506fd1df67ce49a706f12b90b4b1 /src/core/SkGeometry.cpp
parent4e753558fc8cc2f77cbcd46fba80d8612e836a1e (diff)
add quadclipping utility, plus sample test
git-svn-id: http://skia.googlecode.com/svn/trunk@429 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkGeometry.cpp')
-rw-r--r--src/core/SkGeometry.cpp47
1 files changed, 34 insertions, 13 deletions
diff --git a/src/core/SkGeometry.cpp b/src/core/SkGeometry.cpp
index 2775543919..483c08e35b 100644
--- a/src/core/SkGeometry.cpp
+++ b/src/core/SkGeometry.cpp
@@ -260,22 +260,14 @@ static inline void flatten_double_quad_extrema(SkScalar coords[14])
coords[2] = coords[6] = coords[4];
}
-static inline void force_quad_monotonic_in_y(SkPoint pts[3])
-{
- // zap pts[1].fY to the nearest value
- SkScalar ab = SkScalarAbs(pts[0].fY - pts[1].fY);
- SkScalar bc = SkScalarAbs(pts[1].fY - pts[2].fY);
- pts[1].fY = ab < bc ? pts[0].fY : pts[2].fY;
-}
-
/* Returns 0 for 1 quad, and 1 for two quads, either way the answer is
- stored in dst[]. Guarantees that the 1/2 quads will be monotonic.
-*/
+ stored in dst[]. Guarantees that the 1/2 quads will be monotonic.
+ */
int SkChopQuadAtYExtrema(const SkPoint src[3], SkPoint dst[5])
{
SkASSERT(src);
SkASSERT(dst);
-
+
#if 0
static bool once = true;
if (once)
@@ -288,11 +280,11 @@ int SkChopQuadAtYExtrema(const SkPoint src[3], SkPoint dst[5])
SkDebugf("chop=%d, Y=[%x %x %x %x %x %x]\n", n, d[0].fY, d[1].fY, d[2].fY, d[3].fY, d[4].fY, d[5].fY);
}
#endif
-
+
SkScalar a = src[0].fY;
SkScalar b = src[1].fY;
SkScalar c = src[2].fY;
-
+
if (is_not_monotonic(a, b, c))
{
SkScalar tValue;
@@ -312,6 +304,35 @@ int SkChopQuadAtYExtrema(const SkPoint src[3], SkPoint dst[5])
return 0;
}
+/* Returns 0 for 1 quad, and 1 for two quads, either way the answer is
+ stored in dst[]. Guarantees that the 1/2 quads will be monotonic.
+ */
+int SkChopQuadAtXExtrema(const SkPoint src[3], SkPoint dst[5])
+{
+ SkASSERT(src);
+ SkASSERT(dst);
+
+ SkScalar a = src[0].fX;
+ SkScalar b = src[1].fX;
+ SkScalar c = src[2].fX;
+
+ if (is_not_monotonic(a, b, c)) {
+ SkScalar tValue;
+ if (valid_unit_divide(a - b, a - b - b + c, &tValue)) {
+ SkChopQuadAt(src, dst, tValue);
+ flatten_double_quad_extrema(&dst[0].fX);
+ return 1;
+ }
+ // if we get here, we need to force dst to be monotonic, even though
+ // we couldn't compute a unit_divide value (probably underflow).
+ b = SkScalarAbs(a - b) < SkScalarAbs(b - c) ? a : c;
+ }
+ dst[0].set(a, src[0].fY);
+ dst[1].set(b, src[1].fY);
+ dst[2].set(c, src[2].fY);
+ return 0;
+}
+
// F(t) = a (1 - t) ^ 2 + 2 b t (1 - t) + c t ^ 2
// F'(t) = 2 (b - a) + 2 (a - 2b + c) t
// F''(t) = 2 (a - 2b + c)