[gs-cvs] rev 6995 - trunk/gs/src

leonardo at ghostscript.com leonardo at ghostscript.com
Wed Aug 16 10:23:11 PDT 2006


Author: leonardo
Date: 2006-08-16 10:23:10 -0700 (Wed, 16 Aug 2006)
New Revision: 6995

Modified:
   trunk/gs/src/gstype42.c
   trunk/gs/src/gxfont42.h
   trunk/gs/src/int.mak
   trunk/gs/src/lib.mak
   trunk/gs/src/zchar1.c
   trunk/gs/src/zchar42.c
Log:
Fix (font renderer) : Clean up the character cache after a character rendering fails.

DETAILS :

When a character rendering fails, the old code leaves 
character data allocated in the cache but the character
is not added to the hash table. It breaks a global invariant
(1 to 1 correspondence of hash table entries and cached characters),
which is assumed by other cache accessors. As a result it 
causes an infinite loop when the function alloc_char_in_chunk 
is later called for another character and needs to release cache 
space from the "incomplete" character. 
Thanks to Peter L. Deutsch for analyzis.

The infinite loop occurance looks pretty stochastic because 
it depends on many factors, such as cache size and sizes rendered of glyphs.

The new code performs a cache cleanup 
when leaving a character rendering with error code.
See comments in code for more details.

This fix changes the prototype of gs_type42_append,
which is called from the PCL interpreter.
It should fix the problem with True Type fonts
in the PCL interpreter.

For type 1 fonts the cleanup code is a part of the PS interpreter
rather than a part of the graphics library.
It is not harmful because PCL interpreter doesn't render Type 1 fonts.
A better fix needs to modify the prototype of 
type1_exec_init and store the gs_show_enum pointer into the gs_type1_state instance,
to provide the cleanup in type1_continue_dispatch.
It would look ugly, so we don't do it now without a strong necessity.

Debugged with CET tests 13-12.PS, 13-22.PS .

EXPECTED DIFFERENCES :

This patch may (not surely) cause a difference with Bug688308.ps due to the bug 688837.


Modified: trunk/gs/src/gstype42.c
===================================================================
--- trunk/gs/src/gstype42.c	2006-08-16 00:09:37 UTC (rev 6994)
+++ trunk/gs/src/gstype42.c	2006-08-16 17:23:10 UTC (rev 6995)
@@ -28,8 +28,11 @@
 #include "gxfont42.h"
 #include "gxttf.h"
 #include "gxttfb.h"
+#include "gxtext.h"
+#include "gxchar.h"
 #include "gxfcache.h"
 #include "gxistate.h"
+#include "gzstate.h"
 #include "stream.h"
 
 /* Structure descriptor */
@@ -802,20 +805,37 @@
 /* Append a TrueType outline to a path. */
 /* Note that this does not append the final moveto for the width. */
 int
-gs_type42_append(uint glyph_index, gs_imager_state * pis,
-		 gx_path * ppath, const gs_log2_scale_point * pscale,
-		 bool charpath_flag, int paint_type, cached_fm_pair *pair)
+gs_type42_append(uint glyph_index, gs_state * pgs,
+		 gx_path * ppath, gs_text_enum_t *penum, gs_font *pfont,
+		 bool charpath_flag)
 {
-    int code = append_outline_fitted(glyph_index, &ctm_only(pis), ppath, 
+    const gs_log2_scale_point * pscale = &penum->log2_scale;
+    cached_fm_pair *pair = penum->pair;
+    int code = append_outline_fitted(glyph_index, &ctm_only(pgs), ppath, 
 			pair, pscale, charpath_flag);
 
-    if (code < 0)
+    if (code < 0) {
+	if (pgs->in_cachedevice == CACHE_DEVICE_CACHING) {
+	    /* Perform the cache cleanup, when the cached character data 
+	       has been allocated (gx_alloc_char_bits) but
+	       the character has not been added to the cache (gx_add_cached_char)
+	       due to a falure in the character renderer.
+	     */
+	    gs_show_enum *const penum_s = (gs_show_enum *)penum;
+
+	    if (penum_s->cc != NULL) {
+		gx_free_cached_char(pfont->dir, penum_s->cc);
+		penum_s->cc = NULL;
+	    }
+	}
 	return code;
-    code = gx_setcurrentpoint_from_path(pis, ppath);
+    }
+    code = gx_setcurrentpoint_from_path((gs_imager_state *)pgs, ppath);
     if (code < 0)
 	return code;
     /* Set the flatness for curve rendering. */
-    return gs_imager_setflat(pis, gs_char_flatness(pis, 1.0));
+    return gs_imager_setflat((gs_imager_state *)pgs, 
+		gs_char_flatness((gs_imager_state *)pgs, 1.0));
 }
 
 /* Add 2nd degree Bezier to the path */

Modified: trunk/gs/src/gxfont42.h
===================================================================
--- trunk/gs/src/gxfont42.h	2006-08-16 00:09:37 UTC (rev 6994)
+++ trunk/gs/src/gxfont42.h	2006-08-16 17:23:10 UTC (rev 6995)
@@ -105,9 +105,9 @@
 int gs_type42_font_init(gs_font_type42 *);
 
 /* Append the outline of a TrueType character to a path. */
-int gs_type42_append(uint glyph_index, gs_imager_state * pis,
-		 gx_path * ppath, const gs_log2_scale_point * pscale,
-		 bool charpath_flag, int paint_type, cached_fm_pair *pair);
+int gs_type42_append(uint glyph_index, gs_state * pgs,
+		 gx_path * ppath, gs_text_enum_t *penum, gs_font *pfont,
+		 bool charpath_flag);
 
 /* Get the metrics of a TrueType character. */
 int gs_type42_get_metrics(gs_font_type42 * pfont, uint glyph_index,

Modified: trunk/gs/src/int.mak
===================================================================
--- trunk/gs/src/int.mak	2006-08-16 00:09:37 UTC (rev 6994)
+++ trunk/gs/src/int.mak	2006-08-16 17:23:10 UTC (rev 6995)
@@ -727,7 +727,7 @@
 $(PSOBJ)zchar1.$(OBJ) : $(PSSRC)zchar1.c $(OP) $(memory__h)\
  $(gscencs_h) $(gspaint_h) $(gspath_h) $(gsrect_h) $(gsstruct_h)\
  $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h)\
- $(gxfont_h) $(gxfont1_h) $(gxtype1_h) $(gzstate_h)\
+ $(gxfont_h) $(gxfont1_h) $(gxtype1_h) $(gxchar_h) $(gzstate_h)\
  $(estack_h) $(ialloc_h) $(ichar_h) $(ichar1_h) $(icharout_h)\
  $(idict_h) $(ifont_h) $(igstate_h) $(iname_h) $(iutil_h) $(store_h)
 	$(PSCC) $(PSO_)zchar1.$(OBJ) $(C_) $(PSSRC)zchar1.c

Modified: trunk/gs/src/lib.mak
===================================================================
--- trunk/gs/src/lib.mak	2006-08-16 00:09:37 UTC (rev 6994)
+++ trunk/gs/src/lib.mak	2006-08-16 17:23:10 UTC (rev 6995)
@@ -1876,8 +1876,9 @@
 
 $(GLOBJ)gstype42.$(OBJ) : $(GLSRC)gstype42.c $(GXERR) $(memory__h)\
  $(gsccode_h) $(gsline_h) $(gsmatrix_h) $(gsstruct_h) $(gsutil_h)\
- $(gxchrout_h) $(gxfixed_h) $(gxfont_h) $(gxfont42_h) $(gxistate_h)\
- $(gxpath_h) $(gxttf_h) $(gxttfb_h) $(gxfcache_h) $(stream_h)
+ $(gxchrout_h) $(gxfixed_h) $(gxfont_h) $(gxfont42_h)\
+ $(gxpath_h) $(gxttf_h) $(gxttfb_h) $(gxtext_h) $(gxchar_h) $(gxfcache_h)\
+ $(gxistate_h) $(gzstate_h) $(stream_h)
 	$(GLCC) $(GLO_)gstype42.$(OBJ) $(C_) $(GLSRC)gstype42.c
 
 ttfsfnt_h=$(GLSRC)ttfsfnt.h $(stdint__h)

Modified: trunk/gs/src/zchar1.c
===================================================================
--- trunk/gs/src/zchar1.c	2006-08-16 00:09:37 UTC (rev 6994)
+++ trunk/gs/src/zchar1.c	2006-08-16 17:23:10 UTC (rev 6995)
@@ -23,6 +23,7 @@
 #include "gxfont.h"
 #include "gxfont1.h"
 #include "gxtype1.h"
+#include "gxchar.h"
 #include "gzstate.h"		/* for path for gs_type1_init */
 				/* (should only be gsstate.h) */
 #include "gscencs.h"
@@ -173,25 +174,17 @@
     return charstring_execchar(i_ctx_p, (1 << (int)ft_encrypted) |
 			       (1 << (int)ft_disk_based));
 }
-int
-charstring_execchar(i_ctx_t *i_ctx_p, int font_type_mask)
+private int
+charstring_execchar_aux(i_ctx_t *i_ctx_p, gs_text_enum_t *penum, gs_font *pfont)
 {
     os_ptr op = osp;
-    gs_font *pfont;
-    int code = font_param(op - 3, &pfont);
     gs_font_base *const pbfont = (gs_font_base *) pfont;
     gs_font_type1 *const pfont1 = (gs_font_type1 *) pfont;
     const gs_type1_data *pdata;
-    gs_text_enum_t *penum = op_show_find(i_ctx_p);
     gs_type1exec_state cxs;
     gs_type1_state *const pcis = &cxs.cis;
+    int code;
 
-    if (code < 0)
-	return code;
-    if (penum == 0 ||
-	pfont->FontType >= sizeof(font_type_mask) * 8 ||
-	!(font_type_mask & (1 << (int)pfont->FontType)))
-	return_error(e_undefined);
     pdata = &pfont1->data;
     /*
      * Any reasonable implementation would execute something like
@@ -296,6 +289,37 @@
     }
 }
 
+int
+charstring_execchar(i_ctx_t *i_ctx_p, int font_type_mask)
+{
+    gs_text_enum_t *penum = op_show_find(i_ctx_p);
+    gs_font *pfont;
+    os_ptr op = osp;
+    int code = font_param(op - 3, &pfont);
+
+    if (code < 0)
+	return code;
+    if (penum == 0 ||
+	pfont->FontType >= sizeof(font_type_mask) * 8 ||
+	!(font_type_mask & (1 << (int)pfont->FontType)))
+	return_error(e_undefined);
+    code = charstring_execchar_aux(i_ctx_p, penum, pfont);
+    if (code < 0 && igs->in_cachedevice == CACHE_DEVICE_CACHING) {
+	/* Perform the cache cleanup, when the cached character data 
+	   has been allocated (gx_alloc_char_bits) but
+	   the character has not been added to the cache (gx_add_cached_char)
+	   due to a falure in the character renderer.
+	 */
+	gs_show_enum *const penum_s = (gs_show_enum *)penum;
+
+	if (penum_s->cc != NULL) {
+	    gx_free_cached_char(pfont->dir, penum_s->cc);
+	    penum_s->cc = NULL;
+	}
+    }
+    return code;
+}
+
 /* -------- bbox case -------- */
 
 /* Do all the work for the case where we have a bounding box. */

Modified: trunk/gs/src/zchar42.c
===================================================================
--- trunk/gs/src/zchar42.c	2006-08-16 00:09:37 UTC (rev 6994)
+++ trunk/gs/src/zchar42.c	2006-08-16 17:23:10 UTC (rev 6995)
@@ -201,10 +201,9 @@
      * the current gstate and path.  This is a design bug that we will
      * have to address someday!
      */
-    code = gs_type42_append((uint)opc->value.intval, (gs_imager_state *)igs,
-			    igs->path, &penum->log2_scale,
-			    (penum->text.operation & TEXT_DO_ANY_CHARPATH) != 0,
-			    pfont->PaintType, penum->pair);
+    code = gs_type42_append((uint)opc->value.intval, igs,
+			    igs->path, penum, pfont,
+			    (penum->text.operation & TEXT_DO_ANY_CHARPATH) != 0);
     if (code < 0)
 	return code;
     pop((psbpt == 0 ? 4 : 6));



More information about the gs-cvs mailing list