[gs-cvs] rev 6934 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Thu Jul 27 23:22:57 PDT 2006
Author: leonardo
Date: 2006-07-27 23:22:57 -0700 (Thu, 27 Jul 2006)
New Revision: 6934
Modified:
trunk/gs/src/gdevpdfd.c
trunk/gs/src/gdevpdfi.c
trunk/gs/src/gdevpdfx.h
Log:
Fix (pdfwrite) : Incorrect image conversion with CompatibilityLevel=1.2 .
DETAILS :
Bug 688766 "Wrong graphics after ps2ps2 conversion."
Bug 688772 "Bad PDF generated with -dCompatibilityLevel=1.2"
Patch from SaGS.
1. pdf_begin_typed_image() did not synchronize the clipping path in some cases (gdevpdfi.c).
2. Delayed the synchronization for after checking the matrix singularity
against writing an unuseful clipping before a skipped image.
2. write_image_with_clip improiperly placed the 2nd and further subimages
due to dropping the image's 'cm' with the subimage's 'Q'.
3. gx_image_enum_begin computed a wrong clipping box.
In the new code pdf_setup_masked_image_converter installs
a better get_clipping_box method, which is implemented
with the new function lcvd_get_clipping_box_shifted_from_mdev.
4. pdf_image3_make_mcde passed the clipping path to a memory device,
which uses a different coordinate system. The new code does not
pass the clipping path (gdevpdfi.c) and uses the device clipping box instead.
For more details see Bug 688766.
EXPECTED DIFFERENCES :
None.
Modified: trunk/gs/src/gdevpdfd.c
===================================================================
--- trunk/gs/src/gdevpdfd.c 2006-07-28 01:23:29 UTC (rev 6933)
+++ trunk/gs/src/gdevpdfd.c 2006-07-28 06:22:57 UTC (rev 6934)
@@ -525,6 +525,20 @@
(*dev_proc(mdev->target, get_clipping_box))(mdev->target, pbox);
}
+private void
+lcvd_get_clipping_box_shifted_from_mdev(gx_device *dev, gs_fixed_rect *pbox)
+{
+ fixed ofs;
+ pdf_lcvd_t *cvd = (pdf_lcvd_t *)dev;
+
+ cvd->std_get_clipping_box((gx_device *)&cvd->mdev, pbox);
+ ofs = int2fixed(cvd->mdev.mapped_x);
+ pbox->p.x += ofs;
+ pbox->q.x += ofs;
+ ofs = int2fixed(cvd->mdev.mapped_y);
+ pbox->p.y += ofs;
+ pbox->q.y += ofs;
+}
private int
lcvd_pattern_manage(gx_device *pdev1, gx_bitmap_id id,
gs_pattern1_instance_t *pinst, pattern_manage_t function)
@@ -756,7 +770,7 @@
int code, code1;
if (cvd->write_matrix)
- pdf_put_matrix(pdev, NULL, &cvd->m, " cm\n");
+ pdf_put_matrix(pdev, NULL, &cvd->m, " cm q\n");
for(;;) {
int x1, y1;
@@ -786,6 +800,8 @@
y = y1;
}
}
+ if (cvd->write_matrix)
+ stream_puts(pdev->strm, "Q\n");
return 0;
}
@@ -967,13 +983,16 @@
}
cvd->std_fill_rectangle = dev_proc(&cvd->mdev, fill_rectangle);
cvd->std_close_device = dev_proc(&cvd->mdev, close_device);
+ cvd->std_get_clipping_box = dev_proc(&cvd->mdev, get_clipping_box);
if (!write_on_close) {
/* Type 3 images will write to the mask directly. */
dev_proc(&cvd->mdev, fill_rectangle) = (need_mask ? lcvd_fill_rectangle_shifted2
: lcvd_fill_rectangle_shifted);
- } else
+ dev_proc(&cvd->mdev, get_clipping_box) = lcvd_get_clipping_box_from_target;
+ } else {
dev_proc(&cvd->mdev, fill_rectangle) = lcvd_fill_rectangle_shifted_from_mdev;
- dev_proc(&cvd->mdev, get_clipping_box) = lcvd_get_clipping_box_from_target;
+ dev_proc(&cvd->mdev, get_clipping_box) = lcvd_get_clipping_box_shifted_from_mdev;
+ }
dev_proc(&cvd->mdev, pattern_manage) = lcvd_pattern_manage;
dev_proc(&cvd->mdev, fill_path) = lcvd_handle_fill_path_as_shading_coverage;
cvd->m = *m;
Modified: trunk/gs/src/gdevpdfi.c
===================================================================
--- trunk/gs/src/gdevpdfi.c 2006-07-28 01:23:29 UTC (rev 6933)
+++ trunk/gs/src/gdevpdfi.c 2006-07-28 06:22:57 UTC (rev 6934)
@@ -383,6 +383,15 @@
prect->q.y == pim3->Height))
goto nyi;
if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
+ if (pdf_must_put_clip_path(pdev, pcpath))
+ code = pdf_unclip(pdev);
+ else
+ code = pdf_open_page(pdev, PDF_IN_STREAM);
+ if (code < 0)
+ return code;
+ code = pdf_put_clip_path(pdev, pcpath);
+ if (code < 0)
+ return code;
gs_make_identity(&m);
pmat1 = &m;
m.tx = floor(pis->ctm.tx + 0.5); /* Round the origin against the image size distorsions */
@@ -471,6 +480,15 @@
gs_matrix m, m1, mi;
gs_image4_t pi4 = *(const gs_image4_t *)pic;
+ if (pdf_must_put_clip_path(pdev, pcpath))
+ code = pdf_unclip(pdev);
+ else
+ code = pdf_open_page(pdev, PDF_IN_STREAM);
+ if (code < 0)
+ return code;
+ code = pdf_put_clip_path(pdev, pcpath);
+ if (code < 0)
+ return code;
gs_make_identity(&m1);
gs_matrix_invert(&pic->ImageMatrix, &mi);
gs_matrix_multiply(&mi, &ctm_only(pis), &m);
@@ -539,9 +557,6 @@
code = pdf_prepare_image(pdev, pis);
if (code < 0)
goto nyi;
- code = pdf_put_clip_path(pdev, pcpath);
- if (code < 0)
- return code;
if (prect)
rect = *prect;
else {
@@ -610,6 +625,9 @@
goto nyi;
}
}
+ code = pdf_put_clip_path(pdev, pcpath);
+ if (code < 0)
+ return code;
pdf_image_writer_init(&pie->writer);
pie->writer.alt_writer_count = (in_line ||
(pim->Width <= 64 && pim->Height <= 64) ||
@@ -1187,7 +1205,7 @@
cvd->mdev.mapped_y = origin->y;
*pmcdev = (gx_device *)&cvd->mdev;
code = gx_default_begin_typed_image
- ((gx_device *)&cvd->mdev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
+ ((gx_device *)&cvd->mdev, pis, pmat, pic, prect, pdcolor, NULL, mem,
pinfo);
} else {
code = pdf_make_mxd(pmcdev, midev, mem);
Modified: trunk/gs/src/gdevpdfx.h
===================================================================
--- trunk/gs/src/gdevpdfx.h 2006-07-28 01:23:29 UTC (rev 6933)
+++ trunk/gs/src/gdevpdfx.h 2006-07-28 06:22:57 UTC (rev 6934)
@@ -933,6 +933,7 @@
gx_device_pdf *pdev;
dev_t_proc_fill_rectangle((*std_fill_rectangle), gx_device);
dev_t_proc_close_device((*std_close_device), gx_device);
+ dev_t_proc_get_clipping_box((*std_get_clipping_box), gx_device);
bool mask_is_empty;
bool path_is_empty;
bool mask_is_clean;
More information about the gs-cvs
mailing list