[gs-cvs] rev 7542 - in trunk/gs: doc src

leonardo at ghostscript.com leonardo at ghostscript.com
Sun Dec 31 09:50:42 PST 2006


Author: leonardo
Date: 2006-12-31 09:50:40 -0800 (Sun, 31 Dec 2006)
New Revision: 7542

Modified:
   trunk/gs/doc/pscet_status.txt
   trunk/gs/src/gstext.c
   trunk/gs/src/gxchar.c
   trunk/gs/src/zchar.c
   trunk/gs/src/zcharx.c
Log:
Fix : Early check a text to font compatibility.

DETAILS :

Running CET 14-03.PS page 2, CPSI trows a rangechek with no painitng charaters.
However Ghostscript performs the check immediately before
rendering a character. If the check fails in a middle of the text,
the preceding charaters are painted. 

The new code scans entire text before rendering a character.
We do so in CPSI compatibility mode only,
because we don't want a performance flaw for
dual scanning in the Ghostscript native mode.

1. gs_text_size is renemed into gs_text_count_chars 
   for a better reflection of its semantics.

2. The check in zyshow is made conditional
   depending on CPSI_mode. This is an improvement
   for the last patch, which is not related to 
   the current problem (zcharx.c).

3. Inserted the text scanning into op_show_finish_setup
   (zchar.c).

4. After we did all bove, 14-01.PS got cycled in alloc_char_in_chunk.
   This effect occasionally depends on 1-3 because 
   they change the cache memory map.
   Fixed with inserting the call to gx_free_cached_char into gxchar.c .

5. gs_text_count_chars was implemented with gs_text_begin,
   which appears too heavy for the simple text decomposition.
   Particularly it caused a proiblem with stringwidth,
   because gs_text_begin establishes an extra save level
   for stringwidth. The new code calls gs_text_enum_init 
   instead gs_text_begin. Due to that gs_text_count_chars 
   is moved to gxchar.c, which defines default_text_procs privately. 

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/doc/pscet_status.txt
===================================================================
--- trunk/gs/doc/pscet_status.txt	2006-12-30 22:58:47 UTC (rev 7541)
+++ trunk/gs/doc/pscet_status.txt	2006-12-31 17:50:40 UTC (rev 7542)
@@ -2797,10 +2797,7 @@
 
 13-01-1  OK	Minor differences visually reviewed by RJJ
 
-13-01-2  DIFF	cpsi keeps the operands on the stack for the last 4 errors (one
-                nocurrentpoint, 3 rangecheck), gs does not.  Also, gs displays 
-                an 'A' for the first rangecheck error, cpsi does not.
-                assign Peter.
+13-01-2  OK
 
 13-01-3  OK	Minor differences visually reviewed by RJJ
 
@@ -2822,8 +2819,7 @@
 
 13-02-4  OK	
 
-13-02-5  DIFF	same as 13-01-2
-                assign Peter.
+13-02-5  DIFF	awidthshow error incomformity. assign: Alex.
 
 13-02-6  OK	Minor differences visually reviewed by RJJ
 
@@ -2835,10 +2831,7 @@
 
 13-03-1  OK	
 
-13-03-2  DIFF	Last 2 tests missing in cpsi.  Perhaps the output of
-                the previous test (different than gs) pushes the
-                missing text out of the clipping region.
-                assign Ray.
+13-03-2  DIFF	show error incomformity. assign: Alex.
 
 13-03-3  OK	Minor differences visually reviewed by RJJ
 
@@ -3079,9 +3072,7 @@
 		indicates [T]. - ADC
                 assign Alex.
 
-13-22-1  DIFF	Different error messages.  CPSI indicates errors are in
-		--show--.  GS indicates various local functions. - ADC
-                assign Raph.
+13-22-1  OK
 
 13-22-2  OK	Minor differences visually reviewed by RJJ
 
@@ -3101,11 +3092,7 @@
 		I don't know what to do with it, so passing to Ray.
                 assign: Ray.
 
-13-24-1  DIFF	An inconforming ostack after an error in 'show'. Analyzed by Igor.
-		Igor assigns this to Raph.
-	Patch for fixing ostack is in the pipeline. Still need to report
-	error object as cshow rather than %op_show_continue. Assigning
-	the latter problem to Peter. - Raph
+13-24-1  OK
 
 13-24-2  AOK	An unimportant difference in the character cache logics. Analyzed by Igor.
 
@@ -3237,8 +3224,7 @@
 
 14-03-1  OK	Minor differences visually reviewed by RJJ
 
-14-03-2  DIFF	We paint glyphs when CPSI doesn't.
-                assign: Igor.
+14-03-2  OK
 
 14-03-3  OK	Minor differences visually reviewed by RJJ
 

Modified: trunk/gs/src/gstext.c
===================================================================
--- trunk/gs/src/gstext.c	2006-12-30 22:58:47 UTC (rev 7541)
+++ trunk/gs/src/gstext.c	2006-12-31 17:50:40 UTC (rev 7542)
@@ -351,38 +351,6 @@
     return gs_text_begin(pgs, &text, mem, ppte);
 }
 
-/* Compute the number of characters in a text. */
-int
-gs_text_size(gs_state * pgs, gs_text_params_t *text, gs_memory_t * mem)
-{
-    font_proc_next_char_glyph((*next_proc)) = pgs->font->procs.next_char_glyph;
-
-    if (next_proc == gs_default_next_char_glyph)
-	return text->size;
-    else {
-	/* Do it the hard way. */
-	gs_text_enum_t *pte;	/* use a separate enumerator */
-	gs_char tchr;
-	gs_glyph tglyph;
-	int size = 0;
-	int code;
-
-	size = 0;
-	code = gs_text_begin(pgs, text, mem, &pte);
-	if (code < 0)
-	    return code;
-	while ((code = (*next_proc)(pte, &tchr, &tglyph)) != 2) {
-	    if (code < 0)
-		break;
-	    ++size;
-	}
-	gs_free_object(mem, pte, "gs_xyshow_begin");
-	if (code < 0)
-	    return code;
-	return size;
-    }
-}
-
 /* Retrieve text params from enumerator. */
 gs_text_params_t *
 gs_get_text_params(gs_text_enum_t *pte)
@@ -414,7 +382,7 @@
      * must use the font's next_char_glyph procedure to determine how many
      * characters there are in the string.
      */
-    code = gs_text_size(pgs, &text, mem);
+    code = gs_text_count_chars(pgs, &text, mem);
     if (code < 0)
 	return code;
     widths_needed = code;

Modified: trunk/gs/src/gxchar.c
===================================================================
--- trunk/gs/src/gxchar.c	2006-12-30 22:58:47 UTC (rev 7541)
+++ trunk/gs/src/gxchar.c	2006-12-31 17:50:40 UTC (rev 7542)
@@ -213,6 +213,40 @@
     return 0;
 }
 
+/* Compute the number of characters in a text. */
+int
+gs_text_count_chars(gs_state * pgs, gs_text_params_t *text, gs_memory_t * mem)
+{
+    font_proc_next_char_glyph((*next_proc)) = pgs->font->procs.next_char_glyph;
+
+    if (next_proc == gs_default_next_char_glyph)
+	return text->size;
+    else {
+	/* Do it the hard way. */
+	gs_text_enum_t tenum;	/* use a separate enumerator */
+	gs_char tchr;
+	gs_glyph tglyph;
+	int size = 0;
+	int code;
+
+	size = 0;
+
+        code = gs_text_enum_init(&tenum, &default_text_procs,
+			     NULL, NULL, text, pgs->root_font, 
+			     NULL, NULL, NULL, mem);
+	if (code < 0)
+	    return code;
+	while ((code = (*next_proc)(&tenum, &tchr, &tglyph)) != 2) {
+	    if (code < 0)
+		break;
+	    ++size;
+	}
+	if (code < 0)
+	    return code;
+	return size;
+    }
+}
+
 /* An auxiliary functions for pdfwrite to process type 3 fonts. */
 int
 gx_hld_stringwidth_begin(gs_imager_state * pis, gx_path **path)
@@ -781,6 +815,7 @@
 	    /* We have to check for this by comparing levels. */
 	    switch (pgs->level - penum->level) {
 		default:
+		    gx_free_cached_char(penum->orig_font->dir, penum->cc);
 		    return_error(gs_error_invalidfont);		/* WRONG */
 		case 2:
 		    code = gs_grestore(pgs);

Modified: trunk/gs/src/zchar.c
===================================================================
--- trunk/gs/src/zchar.c	2006-12-30 22:58:47 UTC (rev 7541)
+++ trunk/gs/src/zchar.c	2006-12-31 17:50:40 UTC (rev 7542)
@@ -401,7 +401,17 @@
     gs_text_enum_t *osenum = op_show_find(i_ctx_p);
     es_ptr ep = esp + snumpush;
     gs_glyph glyph;
+    extern bool CPSI_mode;
 
+    if (CPSI_mode) {
+	/* CET 14-03.PS page 2 emits rangecheck before rendering a character.
+	   Early check the text to font compatibility 
+	   with decomposing the text into characters.*/
+	int code = gs_text_count_chars(igs, gs_get_text_params(penum), imemory);
+
+	if (code < 0)
+	    return code;
+    }
     /*
      * If we are in the procedure of a cshow for a CID font and this is
      * a show operator, do something special, per the Red Book.

Modified: trunk/gs/src/zcharx.c
===================================================================
--- trunk/gs/src/zcharx.c	2006-12-30 22:58:47 UTC (rev 7541)
+++ trunk/gs/src/zcharx.c	2006-12-31 17:50:40 UTC (rev 7542)
@@ -94,6 +94,7 @@
     int format;
     uint i, size, widths_needed;
     float *values;
+    extern bool CPSI_mode;
 
     if (code != 0)
 	return code;
@@ -104,7 +105,8 @@
     values = (float *)ialloc_byte_array(size, sizeof(float), "moveshow");
     if (values == 0)
 	return_error(e_VMerror);
-    memset(values, 0, size * sizeof(values[0]));
+    if (CPSI_mode)
+	memset(values, 0, size * sizeof(values[0])); /* Safety. */
     if ((code = gs_xyshow_begin(igs, op[-1].value.bytes, r_size(op - 1),
 				(have_x ? values : (float *)0),
 				(have_y ? values : (float *)0),
@@ -112,16 +114,19 @@
 	ifree_object(values, "moveshow");
 	return code;
     }
-    /* CET 13-29.PS page 2 defines a longer width array
-       then the text requires, and CPSI silently ignores extra elements.
-       So we need to compute exact number of characters 
-       to know how many elements to load and type check. */
-    code = gs_text_size(igs, gs_get_text_params(penum), imemory);
-    if (code < 0)
-	return code;
-    widths_needed = code;
-    if (have_x && have_y)
-	widths_needed <<= 1;
+    if (CPSI_mode) {
+	/* CET 13-29.PS page 2 defines a longer width array
+	   then the text requires, and CPSI silently ignores extra elements.
+	   So we need to compute exact number of characters 
+	   to know how many elements to load and type check. */
+	code = gs_text_count_chars(igs, gs_get_text_params(penum), imemory);
+	if (code < 0)
+	    return code;
+	widths_needed = code;
+	if (have_x && have_y)
+	    widths_needed <<= 1;
+    } else
+	widths_needed = size;
     for (i = 0; i < widths_needed; ++i) {
 	ref value;
 



More information about the gs-cvs mailing list