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 ++++++++++++++---------- mupdf/pdf_interpret.c | 4 ++-- 3 files changed, 24 insertions(+), 17 deletions(-) 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; diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c index f33a7ef4..e8cdf20d 100644 --- a/mupdf/pdf_interpret.c +++ b/mupdf/pdf_interpret.c @@ -1330,7 +1330,7 @@ defaultcase: return fz_okay; syntaxerror: - return fz_throw("syntaxerror near '%s'", buf); + return fz_throw("syntax error near '%s' with %d items on the stack", buf, csi->top); } static fz_error @@ -1460,7 +1460,7 @@ pdf_runcsifile(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen { error = pdf_runkeyword(csi, rdb, buf); if (error) - return fz_rethrow(error, "cannot run '%s'", buf); + return fz_rethrow(error, "cannot run keyword '%s'", buf); pdf_clearstack(csi); } break; -- cgit v1.2.3