summaryrefslogtreecommitdiff
path: root/pdf/pdf_interpret.c
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2011-07-06 13:58:16 +0100
committerRobin Watts <Robin.Watts@artifex.com>2011-07-06 14:57:54 +0100
commit2f8acb0010c469c46682a298d66b108cc4c6cdd0 (patch)
tree7e6f07c13df5037e29203d00d115981638cb802d /pdf/pdf_interpret.c
parent28e88083d782eba796ec9af2469e57011dc4aa89 (diff)
downloadmupdf-2f8acb0010c469c46682a298d66b108cc4c6cdd0.tar.xz
Tweak mupdf clip path handling.
In the existing mupdf clip path code, it would be possible for us to render incorrectly; consider the following fragment of a content stream: 0 0 100 100 re W 50 50 100 100 re f That should set the clip path to the (0, 0) -> (100, 100) rectangle, and then attempt to fill both the (0,0) -> (100,100) rectangle and the (50,50) -> (150,150) rectangle, resulting in just the (0,0) -> (100,100) rectangle being filled. In the existing mupdf code, it would actually fill both rectangles as the path after the W operation (the addition of the second rectangle) would also affect the stored clip path. We solve this by doing the clip operation on the W operator, rather than deferred to when the path is actually disposed of.
Diffstat (limited to 'pdf/pdf_interpret.c')
-rw-r--r--pdf/pdf_interpret.c29
1 files changed, 12 insertions, 17 deletions
diff --git a/pdf/pdf_interpret.c b/pdf/pdf_interpret.c
index 9887ee6f..7d2caed2 100644
--- a/pdf/pdf_interpret.c
+++ b/pdf/pdf_interpret.c
@@ -83,8 +83,6 @@ struct pdf_csi_s
/* path object state */
fz_path *path;
- int clip;
- int clip_even_odd;
/* text object state */
fz_text *text;
@@ -243,6 +241,14 @@ pdf_show_image(pdf_csi *csi, fz_pixmap *image)
pdf_end_group(csi);
}
+static void pdf_show_clip(pdf_csi *csi, int even_odd)
+{
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+
+ gstate->clip_depth++;
+ fz_clip_path(csi->dev, csi->path, even_odd, gstate->ctm);
+}
+
static void
pdf_show_path(pdf_csi *csi, int doclose, int dofill, int dostroke, int even_odd)
{
@@ -261,13 +267,6 @@ pdf_show_path(pdf_csi *csi, int doclose, int dofill, int dostroke, int even_odd)
else
bbox = fz_bound_path(path, NULL, gstate->ctm);
- if (csi->clip)
- {
- gstate->clip_depth++;
- fz_clip_path(csi->dev, path, even_odd, gstate->ctm);
- csi->clip = 0;
- }
-
pdf_begin_group(csi, bbox);
if (dofill)
@@ -669,8 +668,6 @@ pdf_new_csi(pdf_xref *xref, fz_device *dev, fz_matrix ctm, char *target)
csi->in_array = 0;
csi->path = fz_new_path();
- csi->clip = 0;
- csi->clip_even_odd = 0;
csi->text = NULL;
csi->tlm = fz_identity;
@@ -1071,7 +1068,7 @@ pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix tr
fz_lineto(csi->path, xobj->bbox.x1, xobj->bbox.y1);
fz_lineto(csi->path, xobj->bbox.x0, xobj->bbox.y1);
fz_closepath(csi->path);
- csi->clip = 1;
+ pdf_show_clip(csi, 0);
pdf_show_path(csi, 0, 0, 0, 0);
/* run contents */
@@ -1717,14 +1714,12 @@ static void pdf_run_TJ(pdf_csi *csi)
static void pdf_run_W(pdf_csi *csi)
{
- csi->clip = 1;
- csi->clip_even_odd = 0;
+ pdf_show_clip(csi, 0);
}
static void pdf_run_Wstar(pdf_csi *csi)
{
- csi->clip = 1;
- csi->clip_even_odd = 1;
+ pdf_show_clip(csi, 1);
}
static void pdf_run_b(pdf_csi *csi)
@@ -1860,7 +1855,7 @@ static void pdf_run_m(pdf_csi *csi)
static void pdf_run_n(pdf_csi *csi)
{
- pdf_show_path(csi, 0, 0, 0, csi->clip_even_odd);
+ pdf_show_path(csi, 0, 0, 0, 0);
}
static void pdf_run_q(pdf_csi *csi)