summaryrefslogtreecommitdiff
path: root/draw
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-08-18 13:21:40 +0000
committerTor Andersson <tor@ghostscript.com>2010-08-18 13:21:40 +0000
commit575707186d519303704f37cd958e530e20cf2c84 (patch)
treeb9a4ef9ec858b88d5e8599204ede27cd72f1ce0d /draw
parentafa20014d16e23890e74973946eafe17bc86a7f0 (diff)
downloadmupdf-575707186d519303704f37cd958e530e20cf2c84.tar.xz
Put a hard limit on bezier subdivision in case precision limits make the flatness check fail.
Diffstat (limited to 'draw')
-rw-r--r--draw/pathfill.c13
-rw-r--r--draw/pathstroke.c24
2 files changed, 22 insertions, 15 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;