summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2014-01-13 18:11:51 +0000
committerRobin Watts <robin.watts@artifex.com>2014-01-13 18:20:36 +0000
commitc3305e7280d446737fbad0dba13712385becf7ad (patch)
tree0ce600578101b976c5b1ce58da1f9c0743c24f15 /source
parenta8c6cc692288d6778dfcfe2c29545721e3829b8c (diff)
downloadmupdf-c3305e7280d446737fbad0dba13712385becf7ad.tar.xz
Avoid rendering errors caused by linejoins on tiny distances.
If we perform a linejoin that ends up being over an impossibly small distance, we can get a rendering error. This is caused by trying to calculate scale = linewidth/sqrtf(len), where len < FLT_EPSILON. Avoid this by rearranging the code slightly - no extra calculations required. Also given that sn == bn at all times within the stroking code, just remove bn. Credit for spotting this problem goes to Simon for tracking the problem with rounding_artifact_due_to_closepath.pdf. My fix just fixes the problem at a lower level than his does.
Diffstat (limited to 'source')
-rw-r--r--source/fitz/draw-path.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/source/fitz/draw-path.c b/source/fitz/draw-path.c
index b33ea8b4..b1bcb11b 100644
--- a/source/fitz/draw-path.c
+++ b/source/fitz/draw-path.c
@@ -134,7 +134,7 @@ struct sctx
float miterlimit;
fz_point beg[2];
fz_point seg[2];
- int sn, bn;
+ int sn;
int dot;
int from_bezier;
@@ -249,18 +249,31 @@ fz_add_line_join(struct sctx *s, fz_point a, fz_point b, fz_point c, int join_un
len0 = dx0 * dx0 + dy0 * dy0;
if (len0 < FLT_EPSILON)
+ {
linejoin = FZ_LINEJOIN_BEVEL;
+ dlx0 = 0;
+ dly0 = 0;
+ }
+ else
+ {
+ scale = linewidth / sqrtf(len0);
+ dlx0 = dy0 * scale;
+ dly0 = -dx0 * scale;
+ }
+
len1 = dx1 * dx1 + dy1 * dy1;
if (len1 < FLT_EPSILON)
+ {
linejoin = FZ_LINEJOIN_BEVEL;
-
- scale = linewidth / sqrtf(len0);
- dlx0 = dy0 * scale;
- dly0 = -dx0 * scale;
-
- scale = linewidth / sqrtf(len1);
- dlx1 = dy1 * scale;
- dly1 = -dx1 * scale;
+ dlx1 = 0;
+ dly1 = 0;
+ }
+ else
+ {
+ scale = linewidth / sqrtf(len1);
+ dlx1 = dy1 * scale;
+ dly1 = -dx1 * scale;
+ }
dmx = (dlx0 + dlx1) * 0.5f;
dmy = (dly0 + dly1) * 0.5f;
@@ -429,7 +442,6 @@ fz_stroke_moveto(struct sctx *s, fz_point cur)
s->seg[0] = cur;
s->beg[0] = cur;
s->sn = 1;
- s->bn = 1;
s->dot = 0;
s->from_bezier = 0;
}
@@ -455,12 +467,13 @@ fz_stroke_lineto(struct sctx *s, fz_point cur, int from_bezier)
s->seg[0] = s->seg[1];
s->seg[1] = cur;
}
+ else
+ {
+ s->seg[1] = cur;
+ s->beg[1] = cur;
+ s->sn = 2;
+ }
s->from_bezier = from_bezier;
-
- if (s->sn == 1)
- s->seg[s->sn++] = cur;
- if (s->bn == 1)
- s->beg[s->bn++] = cur;
}
static void
@@ -480,7 +493,6 @@ fz_stroke_closepath(struct sctx *s)
}
s->seg[0] = s->beg[0];
- s->bn = 1;
s->sn = 1;
s->dot = 0;
s->from_bezier = 0;
@@ -558,7 +570,6 @@ fz_flatten_stroke_path(fz_gel *gel, fz_path *path, const fz_stroke_state *stroke
s.linewidth = linewidth * 0.5f; /* hairlines use a different value from the path value */
s.miterlimit = stroke->miterlimit;
s.sn = 0;
- s.bn = 0;
s.dot = 0;
s.dash_list = NULL;
@@ -952,7 +963,6 @@ fz_flatten_dash_path(fz_gel *gel, fz_path *path, const fz_stroke_state *stroke,
s.linewidth = linewidth * 0.5f;
s.miterlimit = stroke->miterlimit;
s.sn = 0;
- s.bn = 0;
s.dot = 0;
s.dash_list = stroke->dash_list;