Author: ken
Date: 2008-03-01 02:18:20 -0800 (Sat, 01 Mar 2008)
New Revision: 8572

Modified:
   trunk/gs/src/gdevpdfb.h
   trunk/gs/src/gdevpdfx.h
   trunk/gs/src/gdevpdti.c
   trunk/gs/src/gdevpdtt.c
Log:
Fix (pdfwrite): problems with type 3 fonts executing 'show'.

Details:
Bug #689685 "OpenType font incorrectly converted to PDF".

The File is from Quark XPress and contains a type 3 font which
executes a 'show' and a 'charpath stroke' with a glyph from a type
1 font. Further, it executes a 'charpath' on this type 3 glyph.

Pdfwrite was unaware, when processing the 'show' that this was
inside a charpath operation, and emitted the shown glyph.

Modified pdfwrtite to be aware that a charpath is in operation, and
to have the graphics library handle any show operations.

(gdevpdfx.h) Add a new flag 'type3charpath' to the gx_device_pdf
  structure.

(gdevpdfb.h) Add an initialiser for the type3charpath flag (also for
  the last_charpath_op which was missed in that change)

(gdevpdtt.c) In gdev_pdf_text_begin, if type3charpath is true, go
straight to the default text processing. Otherwise, check to see
if this is a type 3 font, and the operation is 'charpath'. If so
then create a pdfwrite text enumerator to process the text.

In pdf_text_process, if we have a type 3 font, the operation is charpath
and type3charpath is false, set it to true and go straight to the 
default text handler. When the enumerator is completed, if type3charpath
is true, set it to false.

In pdf_text_process, while handling text, do not start accumulating a
charparoc if type3charpath is set.

Finally, in pdf_text_set_cache, if type3charpath is set, simply execute
the standard cache routine.

EXPECTED DIFFERENCES:
None.


Modified: trunk/gs/src/gdevpdfb.h
===================================================================
--- trunk/gs/src/gdevpdfb.h	2008-03-01 10:15:02 UTC (rev 8571)
+++ trunk/gs/src/gdevpdfb.h	2008-03-01 10:18:20 UTC (rev 8572)
@@ -234,6 +234,8 @@
  NULL,				/* pres_soft_mask_dict */
  {0, 0},			/* objname */
  0,				/* OPDFRead_procset_length */
- 0				/* find_resource_param */
+ 0,				/* find_resource_param */
+ 0,				/* last_charpath_op */
+ 0				/* type3charpath */
 };
 

Modified: trunk/gs/src/gdevpdfx.h
===================================================================
--- trunk/gs/src/gdevpdfx.h	2008-03-01 10:15:02 UTC (rev 8571)
+++ trunk/gs/src/gdevpdfx.h	2008-03-01 10:18:20 UTC (rev 8572)
@@ -652,6 +652,7 @@
     int OPDFRead_procset_length;      /* PS2WRITE only. */
     void *find_resource_param; /* WARNING : not visible for garbager. */
     int last_charpath_op; /* true or false state of last charpath */
+    bool type3charpath;
 };
 
 #define is_in_page(pdev)\

Modified: trunk/gs/src/gdevpdti.c
===================================================================
--- trunk/gs/src/gdevpdti.c	2008-03-01 10:15:02 UTC (rev 8571)
+++ trunk/gs/src/gdevpdti.c	2008-03-01 10:18:20 UTC (rev 8572)
@@ -614,6 +614,9 @@
     pdev->context = PDF_IN_STREAM;
     pdev->accumulating_substream_resource = pres;
     pdev->last_charpath_op = 0;
+    /* Do not alter type3charpath, inherit the current value. We need to know if */
+    /* we are inside a charpath operation, and only reset this when the charpath */
+    /* is complete */
     pdf_reset_graphics(pdev);
     *ppres = pres;
     return 0;

Modified: trunk/gs/src/gdevpdtt.c
===================================================================
--- trunk/gs/src/gdevpdtt.c	2008-03-01 10:15:02 UTC (rev 8571)
+++ trunk/gs/src/gdevpdtt.c	2008-03-01 10:18:20 UTC (rev 8572)
@@ -96,6 +96,9 @@
     pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
     gx_device_pdf *pdev = (gx_device_pdf *)pte->dev;
 
+    if (pdev->type3charpath)
+	return gs_text_set_cache(penum->pte_default, pw, control);
+
     switch (control) {
     case TEXT_SET_CHAR_WIDTH:
     case TEXT_SET_CACHE_DEVICE:
@@ -339,28 +342,31 @@
 
     pdev->last_charpath_op = 0;
     if ((text->operation & TEXT_DO_ANY_CHARPATH) && !path0->first_subpath) {
-	if(pdf_compare_text_state_for_charpath(pdev->text->text_state, pdev, pis, font, text))
+	if (pdf_compare_text_state_for_charpath(pdev->text->text_state, pdev, pis, font, text))
 	    pdev->last_charpath_op = text->operation & TEXT_DO_ANY_CHARPATH;
     }
 
-    if (font->FontType == ft_user_defined &&
-	(text->operation & TEXT_DO_NONE) && (text->operation & TEXT_RETURN_WIDTH)) {
-	/* This is stringwidth, see gx_default_text_begin.
-	 * We need to prevent writing characters to PS cache,
-	 * otherwise the font converts to bitmaps.
-	 * So pass through even with stringwidth.
-	 */
-	code = gx_hld_stringwidth_begin(pis, &path);
-	if (code < 0)
-	    return code;
-    } else if ((!(text->operation & TEXT_DO_DRAW) && pis->text_rendering_mode != 3) 
-		|| path == 0 || gx_path_current_point(path, &cpt) < 0
-	    )
-	return gx_default_text_begin(dev, pis, text, font, path, pdcolor,
+    if (font->FontType != ft_user_defined || !(text->operation & TEXT_DO_ANY_CHARPATH)) {
+        if (font->FontType == ft_user_defined &&
+	    (text->operation & TEXT_DO_NONE) && (text->operation & TEXT_RETURN_WIDTH)) {
+	    /* This is stringwidth, see gx_default_text_begin.
+	     * We need to prevent writing characters to PS cache,
+	     * otherwise the font converts to bitmaps.
+	     * So pass through even with stringwidth.
+	     */
+	    code = gx_hld_stringwidth_begin(pis, &path);
+	    if (code < 0)
+		return code;
+	} else if ((!(text->operation & TEXT_DO_DRAW) && pis->text_rendering_mode != 3) 
+/*		    || path == 0 || gx_path_current_point(path, &cpt) < 0 */
+		    || path == 0 || path_position_valid(path) < 0
+		    || pdev->type3charpath) 
+	    return gx_default_text_begin(dev, pis, text, font, path, pdcolor,
 					 pcpath, mem, ppte);
-    else if (text->operation & TEXT_DO_ANY_CHARPATH)
-	return gx_default_text_begin(dev, pis, text, font, path, pdcolor,
+	else if (text->operation & TEXT_DO_ANY_CHARPATH)
+	    return gx_default_text_begin(dev, pis, text, font, path, pdcolor,
 					 pcpath, mem, ppte);
+    }
 
     /* Allocate and initialize the enumerator. */
 
@@ -2408,6 +2414,12 @@
 	    penum->current_font = penum->orig_font;
 	}
     }
+    if (penum->current_font->FontType == ft_user_defined && (penum->text.operation & TEXT_DO_ANY_CHARPATH)
+	&& !pdev->type3charpath) {
+	pdev->type3charpath = true;
+	goto default_impl;
+    }
+
     code = -1;		/* to force default implementation */
 
     /*
@@ -2459,7 +2471,7 @@
 	code = gs_text_process(pte_default);
 	pdev->pte = NULL;	 /* CAUTION: See comment in gdevpdfx.h . */
 	pdev->charproc_just_accumulated = false;
-	if (code == TEXT_PROCESS_RENDER) {
+	if (code == TEXT_PROCESS_RENDER && !pdev->type3charpath) {
 	    penum->returned.current_char = pte_default->returned.current_char;
 	    penum->returned.current_glyph = pte_default->returned.current_glyph;
 	    pdev->charproc_ctm = penum->pis->ctm;
@@ -2511,6 +2523,8 @@
 	    return code;
 	gs_text_release(pte_default, "pdf_text_process");
 	penum->pte_default = 0;
+	if (pdev->type3charpath)
+	    pdev->type3charpath = false;
 	return 0;
     }
     {

_______________________________________________
gs-cvs mailing list
gs-cvs@ghostscript.com
http://www.ghostscript.com/mailman/listinfo/gs-cvs
