summaryrefslogtreecommitdiff
path: root/draw
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-01-23 20:23:50 +0000
committerRobin Watts <robin.watts@artifex.com>2012-01-23 20:23:50 +0000
commitc29b6a615260d140c2dc04a05fa47c43e66d6f35 (patch)
tree2ec429817d0ee6b3aa6e8368a8aa2cb3d30d8869 /draw
parent2591d91ebeab0e2243a3b8262b4710ce262929ad (diff)
downloadmupdf-c29b6a615260d140c2dc04a05fa47c43e66d6f35.tar.xz
Do XPS mitering properly.
Modified version of Sumatras patch. Thanks for this.
Diffstat (limited to 'draw')
-rw-r--r--draw/draw_path.c66
1 files changed, 38 insertions, 28 deletions
diff --git a/draw/draw_path.c b/draw/draw_path.c
index 29614ec5..de616ef7 100644
--- a/draw/draw_path.c
+++ b/draw/draw_path.c
@@ -225,6 +225,7 @@ fz_add_line_join(struct sctx *s, fz_point a, fz_point b, fz_point c)
float dmr2;
float scale;
float cross;
+ float len0, len1;
dx0 = b.x - a.x;
dy0 = b.y - a.y;
@@ -242,16 +243,18 @@ fz_add_line_join(struct sctx *s, fz_point a, fz_point b, fz_point c)
cross = -cross;
}
- if (dx0 * dx0 + dy0 * dy0 < FLT_EPSILON)
+ len0 = dx0 * dx0 + dy0 * dy0;
+ if (len0 < FLT_EPSILON)
linejoin = FZ_LINEJOIN_BEVEL;
- if (dx1 * dx1 + dy1 * dy1 < FLT_EPSILON)
+ len1 = dx1 * dx1 + dy1 * dy1;
+ if (len1 < FLT_EPSILON)
linejoin = FZ_LINEJOIN_BEVEL;
- scale = linewidth / sqrtf(dx0 * dx0 + dy0 * dy0);
+ scale = linewidth / sqrtf(len0);
dlx0 = dy0 * scale;
dly0 = -dx0 * scale;
- scale = linewidth / sqrtf(dx1 * dx1 + dy1 * dy1);
+ scale = linewidth / sqrtf(len1);
dlx1 = dy1 * scale;
dly1 = -dx1 * scale;
@@ -262,15 +265,35 @@ fz_add_line_join(struct sctx *s, fz_point a, fz_point b, fz_point c)
if (cross * cross < FLT_EPSILON && dx0 * dx1 + dy0 * dy1 >= 0)
linejoin = FZ_LINEJOIN_BEVEL;
- if (linejoin == FZ_LINEJOIN_MITER)
- if (dmr2 * miterlimit * miterlimit < linewidth * linewidth)
+ /* XPS miter joins are clipped at miterlength, rather than simply
+ * being converted to bevelled joins. */
+ if (linejoin == FZ_LINEJOIN_MITER_XPS)
+ {
+ if (cross == 0)
linejoin = FZ_LINEJOIN_BEVEL;
+ else if (dmr2 * miterlimit * miterlimit >= linewidth * linewidth)
+ linejoin = FZ_LINEJOIN_MITER;
+ else
+ {
+ float k, t0x, t0y, t1x, t1y;
+ scale = linewidth * linewidth / dmr2;
+ dmx *= scale;
+ dmy *= scale;
+ k = (scale - linewidth * miterlimit / sqrtf(dmr2)) / (scale - 1);
+ t0x = b.x - dmx + k * (dmx - dlx0);
+ t0y = b.y - dmy + k * (dmy - dly0);
+ t1x = b.x - dmx + k * (dmx - dlx1);
+ t1y = b.y - dmy + k * (dmy - dly1);
- if (linejoin == FZ_LINEJOIN_BEVEL)
- {
- fz_add_line(s, b.x - dlx0, b.y - dly0, b.x - dlx1, b.y - dly1);
- fz_add_line(s, b.x + dlx1, b.y + dly1, b.x + dlx0, b.y + dly0);
+ fz_add_line(s, b.x + dlx1, b.y + dly1, b.x + dlx0, b.y + dly0);
+ fz_add_line(s, b.x - dlx0, b.y - dly0, t0x, t0y);
+ fz_add_line(s, t0x, t0y, t1x, t1y);
+ fz_add_line(s, t1x, t1y, b.x - dlx1, b.y - dly1);
+ }
}
+ else if (linejoin == FZ_LINEJOIN_MITER)
+ if (dmr2 * miterlimit * miterlimit < linewidth * linewidth)
+ linejoin = FZ_LINEJOIN_BEVEL;
if (linejoin == FZ_LINEJOIN_MITER)
{
@@ -283,27 +306,14 @@ fz_add_line_join(struct sctx *s, fz_point a, fz_point b, fz_point c)
fz_add_line(s, b.x - dmx, b.y - dmy, b.x - dlx1, b.y - dly1);
}
- /* XPS miter joins are clipped at miterlength, rather than simply
- * being converted to bevelled joins. */
- if (linejoin == FZ_LINEJOIN_MITER_XPS)
- {
- scale = linewidth * linewidth / dmr2;
- dmx *= scale;
- dmy *= scale;
- if (cross == 0)
- {
- fz_add_line(s, b.x + dlx1, b.y + dly1, b.x + dlx0, b.y + dly0);
- fz_add_line(s, b.x - dlx0, b.y - dly0, b.x - dlx1, b.y - dly1);
- }
- else
- {
- fz_add_line(s, b.x + dlx1, b.y + dly1, b.x + dlx0, b.y + dly0);
- fz_add_line(s, b.x - dlx0, b.y - dly0, b.x - dmx, b.y - dmy);
- fz_add_line(s, b.x - dmx, b.y - dmy, b.x - dlx1, b.y - dly1);
- }
+ if (linejoin == FZ_LINEJOIN_BEVEL)
+ {
+ fz_add_line(s, b.x - dlx0, b.y - dly0, b.x - dlx1, b.y - dly1);
+ fz_add_line(s, b.x + dlx1, b.y + dly1, b.x + dlx0, b.y + dly0);
}
+
if (linejoin == FZ_LINEJOIN_ROUND)
{
fz_add_line(s, b.x + dlx1, b.y + dly1, b.x + dlx0, b.y + dly0);