[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