[gs-cvs] rev 8518 - in trunk/gs: lib src

ken at ghostscript.com ken at ghostscript.com
Thu Feb 7 01:33:23 PST 2008


Author: ken
Date: 2008-02-07 01:33:22 -0800 (Thu, 07 Feb 2008)
New Revision: 8518

Modified:
   trunk/gs/lib/pdf_ops.ps
   trunk/gs/src/gdevpdts.c
   trunk/gs/src/gdevpdtt.c
Log:
Fix (pdfwrite): problems with unusual PDF text rendering modes.

Details:
Bug #689596 "Generated PDF loses an image from original".

Although the PDF interpreter stores both stroke and fill colours,
there is no way to pass both these colours to the graphics library.
The PostScript graphics state may only contain a single colour, and the
device interface only allows for a single colour to be passed.

The old code set the text rendering mode, and assumed that if the
current device was pdfwrite this would be sufficient. However the
need to set both colours causes this to fail.

Modified the pdf_ops to set a show/colour/charpath/stroke combination
instead. The existing code will spot text followed by a charpath of
the same text and collapse it back.

A number of other problems with text rendering modes were also addressed
at the same time, but in a less than optimal fashion. This patch
is a temporary fix while an enhancement is coded to better address
the problem.

(gdevpdts.c) pdf_render_mode_uses_stroke, was checking for render mode
not 0 (fill). Altered to check against the actual stroking modes.

(gdevpdtt.c) pdf_update_text_state was setting the text rendering mode
to 0 (fill) under most conditions. Altered this to set the mode from
the graphics state, unless the current font PaintType is 2 (stroke),
and the render mode is 0, in which case set render mode to 1 (stroke).

(pdf_ops.ps) Modify setshowstate to provide better methods of implementing
various text rendering modes to pdfwrite. Rendering is unaffected by
this change.

EXPECTED DIFFERENCES:
None.


Modified: trunk/gs/lib/pdf_ops.ps
===================================================================
--- trunk/gs/lib/pdf_ops.ps	2008-02-04 22:18:08 UTC (rev 8517)
+++ trunk/gs/lib/pdf_ops.ps	2008-02-07 09:33:22 UTC (rev 8518)
@@ -655,41 +655,70 @@
    { gsave tB grestore tW }
    { tW }
 ] readonly def
+
+/pdfwrite_textrenderingprocs [
+	{ setfillstate show } bind
+	{ setstrokestate show } bind
+	{ gsave 0 .settextrenderingmode 
+	  setfillstate dup show currentpoint 3 -1 roll 
+	  grestore gsave setstrokestate false charpath stroke 
+	  grestore moveto
+	} bind
+	{ setfillstate show } bind
+	{ gsave 0 .settextrenderingmode 
+	  setfillstate dup show grestore true charpath } bind
+	{ gsave 1 .settextrenderingmode 
+	  setstrokestate dup show grestore
+	  true charpath } bind
+	{ gsave 0 .settextrenderingmode 
+	  setfillstate dup show grestore gsave dup 
+	  setstrokestate false charpath stroke grestore 
+	  true charpath } bind
+	{ true charpath } bind
+] readonly def
+
 /setshowstate
  { WordSpacing 0 eq TextSpacing 0 eq and FontMatrixNonHV not and
-    { TextRenderingMode 0 eq currentdevice .devicename /pdfwrite eq or {
-        { setfillstate show }
-      } {
-        TextRenderingMode 3 eq {
-            	% Some PDF files execute 'tm' with a singular matrix,
-		% and then use the text rendering mode 3.
-		% The graphics library currently cannot handle text
-		% operations when the CTM is singular.
-		% Work around this here.
-	  {	
-            matrix currentmatrix dup dup
-            dup 0 get 0 eq 1 index 1 get 0 eq and {
-              dup dup 2 get 0 eq { 0 }{ 1 } ifelse 1 put
-            } if
-            dup 2 get 0 eq 1 index 3 get 0 eq and {
-              dup dup 1 get 0 eq { 3 }{ 2 } ifelse 1 put
-            } if
-            setmatrix
-            2 index setfillstate show % Tr was set to graphic state.
-            setmatrix 
-	    % now set the currentpoint using the original matrix
-            gsave nulldevice
-            setmatrix
-            false charpath currentpoint newpath 
-            grestore
-            moveto
-          }
-        } {
-          { false charpath textrenderingprocs TextRenderingMode get exec }
-        } ifelse
-      } ifelse
+    { 
+	currentdevice .devicename /pdfwrite eq 
+	{
+		pdfwrite_textrenderingprocs TextRenderingMode get
+	}
+	{
+		TextRenderingMode 0 eq {
+	        { setfillstate show }
+	      } {
+	        TextRenderingMode 3 eq {
+	            	% Some PDF files execute 'tm' with a singular matrix,
+			% and then use the text rendering mode 3.
+			% The graphics library currently cannot handle text
+			% operations when the CTM is singular.
+			% Work around this here.
+		  {	
+	            matrix currentmatrix dup dup
+	            dup 0 get 0 eq 1 index 1 get 0 eq and {
+	              dup dup 2 get 0 eq { 0 }{ 1 } ifelse 1 put
+	            } if
+	            dup 2 get 0 eq 1 index 3 get 0 eq and {
+	              dup dup 1 get 0 eq { 3 }{ 2 } ifelse 1 put
+	            } if
+	            setmatrix
+	            2 index setfillstate show % Tr was set to graphic state.
+	            setmatrix 
+		    % now set the currentpoint using the original matrix
+	            gsave nulldevice
+	            setmatrix
+	            false charpath currentpoint newpath 
+	            grestore
+	            moveto
+	          }
+	        } {
+	          { false charpath textrenderingprocs TextRenderingMode get exec }
+	        } ifelse
+	      } ifelse
+	} ifelse
     }
-    { TextRenderingMode 0 eq TextRenderingMode 3 eq or currentdevice .devicename /pdfwrite eq or
+    { TextRenderingMode 0 eq TextRenderingMode 3 eq or
        % Tr was set to graphic state.
        { FontMatrixNonHV {
            {

Modified: trunk/gs/src/gdevpdts.c
===================================================================
--- trunk/gs/src/gdevpdts.c	2008-02-04 22:18:08 UTC (rev 8517)
+++ trunk/gs/src/gdevpdts.c	2008-02-07 09:33:22 UTC (rev 8518)
@@ -520,7 +520,8 @@
 			    const pdf_text_state_values_t *ptsv)
 {
     return (pdev->text->text_state->in.render_mode != ptsv->render_mode &&
-	    ptsv->render_mode != 0);
+	    ptsv->render_mode == 1 || ptsv->render_mode == 2 ||
+	    ptsv->render_mode == 5 || ptsv->render_mode == 6);
 }
 
 /*

Modified: trunk/gs/src/gdevpdtt.c
===================================================================
--- trunk/gs/src/gdevpdtt.c	2008-02-04 22:18:08 UTC (rev 8517)
+++ trunk/gs/src/gdevpdtt.c	2008-02-07 09:33:22 UTC (rev 8518)
@@ -2011,13 +2011,29 @@
     ppts->values.pdfont = pdfont;
     ppts->values.size = size;
     ppts->values.matrix = tmat;
-    ppts->values.render_mode = (penum->pis->text_rendering_mode == 3 ? 3 : 
-				font->PaintType == 0 ? 0 : penum->pis->text_rendering_mode);
+    ppts->values.render_mode = penum->pis->text_rendering_mode;
     ppts->values.word_spacing = w_s;
     ppts->font = font;
 
-    code = pdf_set_text_process_state(pdev, (const gs_text_enum_t *)penum,
+    if (font->PaintType == 2 && penum->pis->text_rendering_mode == 0)
+    {
+	gs_imager_state *pis = penum->pis;
+	double scaled_width = font->StrokeWidth != 0 ? font->StrokeWidth : 0.001;
+	double saved_width = pis->line_params.half_width;
+
+	if (font->FontMatrix.yy != 0)
+	    scaled_width *= fabs(font->FontMatrix.yy);
+	else
+	    scaled_width *= fabs(font->FontMatrix.xy);
+	ppts->values.render_mode = 1;
+	pis->line_params.half_width = scaled_width / 2;
+        code = pdf_set_text_process_state(pdev, (const gs_text_enum_t *)penum,
 				      ppts);
+	pis->line_params.half_width = saved_width;
+    } else {
+	code = pdf_set_text_process_state(pdev, (const gs_text_enum_t *)penum,
+				      ppts);
+    }
     return (code < 0 ? code : mask);
 }
 
@@ -2046,19 +2062,8 @@
 	/* Write all the parameters for stroking. */
 	gs_imager_state *pis = pte->pis;
 	float save_width = pis->line_params.half_width;
-	const gs_font *font = ppts->font;
-	double scaled_width = font->StrokeWidth;
 	int code;
 
-	/* Note that we compute pis->line_params.half_width in device space,
-	 * even though it logically represents a value in user space.  
-	 * The 'scale' value compensates for this.
-	 */
-	scaled_width *= font_matrix_scaling(font);
-	scaled_width *= min(hypot(pte->pis->ctm.xx, pte->pis->ctm.yx) / 
-                                pdev->HWResolution[0] * pdev->HWResolution[1],
-                            hypot(pte->pis->ctm.xy, pte->pis->ctm.yy));
-	pis->line_params.half_width = scaled_width / 2;
 	code = pdf_prepare_stroke(pdev, pis);
 	if (code >= 0) {
 	    /*



More information about the gs-cvs mailing list