From 575707186d519303704f37cd958e530e20cf2c84 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 18 Aug 2010 13:21:40 +0000 Subject: Put a hard limit on bezier subdivision in case precision limits make the flatness check fail. --- draw/pathfill.c | 13 ++++++++----- draw/pathstroke.c | 24 ++++++++++++++---------- 2 files changed, 22 insertions(+), 15 deletions(-) (limited to 'draw') diff --git a/draw/pathfill.c b/draw/pathfill.c index 62d4ac59..f20f0946 100644 --- a/draw/pathfill.c +++ b/draw/pathfill.c @@ -1,5 +1,7 @@ #include "fitz.h" +#define MAXDEPTH 8 + static void line(fz_gel *gel, fz_matrix *ctm, float x0, float y0, float x1, float y1) { @@ -15,7 +17,7 @@ bezier(fz_gel *gel, fz_matrix *ctm, float flatness, float xa, float ya, float xb, float yb, float xc, float yc, - float xd, float yd) + float xd, float yd, int depth) { float dmax; float xab, yab; @@ -30,7 +32,8 @@ bezier(fz_gel *gel, fz_matrix *ctm, float flatness, dmax = MAX(dmax, ABS(ya - yb)); dmax = MAX(dmax, ABS(xd - xc)); dmax = MAX(dmax, ABS(yd - yc)); - if (dmax < flatness) { + if (dmax < flatness || depth >= MAXDEPTH) + { line(gel, ctm, xa, ya, xd, yd); return; } @@ -59,8 +62,8 @@ bezier(fz_gel *gel, fz_matrix *ctm, float flatness, xabcd *= 0.125f; yabcd *= 0.125f; - bezier(gel, ctm, flatness, xa, ya, xab, yab, xabc, yabc, xabcd, yabcd); - bezier(gel, ctm, flatness, xabcd, yabcd, xbcd, ybcd, xcd, ycd, xd, yd); + bezier(gel, ctm, flatness, xa, ya, xab, yab, xabc, yabc, xabcd, yabcd, depth + 1); + bezier(gel, ctm, flatness, xabcd, yabcd, xbcd, ybcd, xcd, ycd, xd, yd, depth + 1); } void @@ -102,7 +105,7 @@ fz_fillpath(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness) y2 = path->els[i++].v; x3 = path->els[i++].v; y3 = path->els[i++].v; - bezier(gel, &ctm, flatness, cx, cy, x1, y1, x2, y2, x3, y3); + bezier(gel, &ctm, flatness, cx, cy, x1, y1, x2, y2, x3, y3, 0); cx = x3; cy = y3; break; diff --git a/draw/pathstroke.c b/draw/pathstroke.c index b68dcd4f..50343b3f 100644 --- a/draw/pathstroke.c +++ b/draw/pathstroke.c @@ -1,5 +1,7 @@ #include "fitz.h" +#define MAXDEPTH 8 + enum { BUTT = 0, ROUND = 1, SQUARE = 2, MITER = 0, BEVEL = 2 }; struct sctx @@ -336,7 +338,7 @@ fz_strokebezier(struct sctx *s, float xa, float ya, float xb, float yb, float xc, float yc, - float xd, float yd) + float xd, float yd, int depth) { float dmax; float xab, yab; @@ -351,7 +353,8 @@ fz_strokebezier(struct sctx *s, dmax = MAX(dmax, ABS(ya - yb)); dmax = MAX(dmax, ABS(xd - xc)); dmax = MAX(dmax, ABS(yd - yc)); - if (dmax < s->flatness) { + if (dmax < s->flatness || depth >= MAXDEPTH) + { fz_point p; p.x = xd; p.y = yd; @@ -383,8 +386,8 @@ fz_strokebezier(struct sctx *s, xabcd *= 0.125f; yabcd *= 0.125f; - fz_strokebezier(s, xa, ya, xab, yab, xabc, yabc, xabcd, yabcd); - fz_strokebezier(s, xabcd, yabcd, xbcd, ybcd, xcd, ycd, xd, yd); + fz_strokebezier(s, xa, ya, xab, yab, xabc, yabc, xabcd, yabcd, depth + 1); + fz_strokebezier(s, xabcd, yabcd, xbcd, ybcd, xcd, ycd, xd, yd, depth + 1); } void @@ -441,7 +444,7 @@ fz_strokepath(fz_gel *gel, fz_path *path, fz_strokestate *stroke, fz_matrix ctm, p2.y = path->els[i++].v; p3.x = path->els[i++].v; p3.y = path->els[i++].v; - fz_strokebezier(&s, p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + fz_strokebezier(&s, p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, 0); p0 = p3; break; @@ -522,7 +525,7 @@ fz_dashbezier(struct sctx *s, float xa, float ya, float xb, float yb, float xc, float yc, - float xd, float yd) + float xd, float yd, int depth) { float dmax; float xab, yab; @@ -537,7 +540,8 @@ fz_dashbezier(struct sctx *s, dmax = MAX(dmax, ABS(ya - yb)); dmax = MAX(dmax, ABS(xd - xc)); dmax = MAX(dmax, ABS(yd - yc)); - if (dmax < s->flatness) { + if (dmax < s->flatness || depth >= MAXDEPTH) + { fz_point p; p.x = xd; p.y = yd; @@ -569,8 +573,8 @@ fz_dashbezier(struct sctx *s, xabcd *= 0.125f; yabcd *= 0.125f; - fz_dashbezier(s, xa, ya, xab, yab, xabc, yabc, xabcd, yabcd); - fz_dashbezier(s, xabcd, yabcd, xbcd, ybcd, xcd, ycd, xd, yd); + fz_dashbezier(s, xa, ya, xab, yab, xabc, yabc, xabcd, yabcd, depth + 1); + fz_dashbezier(s, xabcd, yabcd, xbcd, ybcd, xcd, ycd, xd, yd, depth + 1); } void @@ -634,7 +638,7 @@ fz_dashpath(fz_gel *gel, fz_path *path, fz_strokestate *stroke, fz_matrix ctm, f p2.y = path->els[i++].v; p3.x = path->els[i++].v; p3.y = path->els[i++].v; - fz_dashbezier(&s, p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + fz_dashbezier(&s, p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, 0); p0 = p3; break; -- cgit v1.2.3