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

leonardo at ghostscript.com leonardo at ghostscript.com
Mon Apr 23 06:27:55 PDT 2007


Author: leonardo
Date: 2007-04-23 06:27:47 -0700 (Mon, 23 Apr 2007)
New Revision: 7873

Modified:
   trunk/gs/doc/Language.htm
   trunk/gs/lib/gs_ciddc.ps
   trunk/gs/src/zcid.c
Log:
Fix : Provide alternative char codes in a CIDDecoding resource.

DETAILS : 

Bug 689168 "Wrong Symbol displayed from MS-PGothic".
See the documentation change.

Note : FAPI implemented this feature with Decoding resource a long ago,
but it was not documented in Language.htm .

The old documentation about CIDDecoding in Language.htm appears incorrect.
The dictionary values were not strings.
They were arrays of integers.

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/doc/Language.htm
===================================================================
--- trunk/gs/doc/Language.htm	2007-04-23 06:42:08 UTC (rev 7872)
+++ trunk/gs/doc/Language.htm	2007-04-23 13:27:47 UTC (rev 7873)
@@ -2147,12 +2147,15 @@
 specifying TrueType font names or files in <a href="../lib/Fontmap">lib/Fontmap</a>.
 </li>
 <p>
-<b><tt>Decoding</tt></b> resources are not current used by the native font renderer.
+<b><tt>Decoding</tt></b> resources are not currently used by the native font renderer.
 
 <p>
 An instance of the <b><tt>Decoding</tt></b> resource category is
 a dictionary. The dictionary keys are PostScript glyph names and the
-values are character codes. The name of the resource instance should
+values are either character codes, or arrays of character codes.
+Arrays are used when a single name may be mapped to various character codes -
+in this case Ghostscript tries all alternatives until a success.
+The name of the resource instance should
 reflect the character set for which it maps. For example,
 <b><tt>/Unicode</tt></b> <b><tt>/Decoding</tt></b> resource maps to
 Unicode UTF-16.
@@ -2176,20 +2179,23 @@
 
 <p>
 <b><tt>CIDDecoding</tt></b> resources are similar to <b><tt>Decoding</tt></b>
-resources, except they map Charaacter Identifiers (CIDs) rather than glyph names.
-Another difference is that the native Ghostscript font renderer already uses 
-<b><tt>CIDDecoding</tt></b> resources while emulate CID fonts with TrueType.
+resources, except they map Character Identifiers (CIDs) rather than glyph names.
+Another difference is that the native Ghostscript font renderer uses 
+<b><tt>CIDDecoding</tt></b> resources while emulate CID fonts with TrueType or OpenType fonts.
 
 <p>
 An instance of the <b><tt>CIDDecoding</tt></b> resource category is
-a dictionary of strings. Keys in the dictionary are integers,
-which correspond to high order byte of a CID. Values are
-512-bytes strings. Each string represents 256 character codes,
-corresponding various values of the lower byte of CID.
-Each character code ocupies 2 bytes, high order byte first.
-Two zero bytes represent mapping to the default character.
+a dictionary of arrays. Keys in the dictionary are integers,
+which correspond to high order byte of a CID. 
+Values are 256-element arrays, and their indices correspond to the low order byte of a CID.
+Each elemet of an array is either null, or character code (integer), or an array
+of character codes (integers). The zero code represents mapping to the default character.
 
 <p>
+The dictionary includes the additional key <b><tt>CIDCount</tt></b>.
+Its value is the maximal CID defined, plus one.
+
+<p>
 The Ghostscript library is capable of generating some <b><tt>CIDDecoding</tt></b>
 instances automatically, using the appropriate <b><tt>CMap</tt></b> (character map)
 resources. This covers most of practical cases if the neccessary <b><tt>CMap</tt></b>

Modified: trunk/gs/lib/gs_ciddc.ps
===================================================================
--- trunk/gs/lib/gs_ciddc.ps	2007-04-23 06:42:08 UTC (rev 7872)
+++ trunk/gs/lib/gs_ciddc.ps	2007-04-23 13:27:47 UTC (rev 7873)
@@ -95,7 +95,23 @@
     } if                                    % b I I0
     //.Ranges exch get                      % b I [Range]
     exch 256 mod                            % b [Range] I1
-    3 2 roll put                            %
+    2 copy get                              % b [Range] I1 e
+    dup //null ne {
+      % We've got char code duplicates for same CID.
+      dup type /integertype eq {
+        4 3 roll                            % [Range] I1 e b
+        2 array astore put                  %
+      } {
+        dup length 1 add dup dup array dup  % b [Range] I1 D l l D' D'
+        3 2 roll 0 exch getinterval         % b [Range] I1 D l D' D''
+        4 3 roll exch copy pop              % b [Range] I1 l D'
+        dup 3 2 roll 1 sub                  % b [Range] I1 D' D' l-1
+        6 5 roll                            % [Range] I1 D' D' l-1 b
+        put put                             %
+      } ifelse
+    } {
+      pop 3 2 roll put                      %
+    } ifelse
   } bind def
 
   /endcidrange

Modified: trunk/gs/src/zcid.c
===================================================================
--- trunk/gs/src/zcid.c	2007-04-23 06:42:08 UTC (rev 7872)
+++ trunk/gs/src/zcid.c	2007-04-23 13:27:47 UTC (rev 7873)
@@ -51,26 +51,36 @@
 private bool 
 TT_char_code_from_CID_no_subst(const gs_memory_t *mem, 
 			       const ref *Decoding, const ref *TT_cmap, uint nCID, uint *c)
-{   ref *DecodingArray, char_code, ih, glyph_index;
+{   ref *DecodingArray, char_code, char_code1, ih, glyph_index, *Duplicates;
+    bool found = false;
+    int i = nCID % 256, n;
 
     make_int(&ih, nCID / 256);
     if (dict_find(Decoding, &ih, &DecodingArray) <= 0 || 
 	    !r_has_type(DecodingArray, t_array) ||
-	    array_get(mem, DecodingArray, nCID % 256, &char_code) < 0 || 
-	    !r_has_type(&char_code, t_integer)) {
-	/* fixme : Generally, a single char_code can be insufficient. 
-	   It could be an array. Fix lib/gs_ciddc.ps as well.  */
-        return false;
-    } 
-    if (TT_cmap == NULL) {
-	*c = char_code.value.intval;
-	return true;
+	    array_get(mem, DecodingArray, i, &char_code) < 0)
+	return false;
+    if (r_has_type(&char_code, t_integer))
+	n = 1; 
+    else if (r_has_type(&char_code, t_array)) {
+	DecodingArray = &char_code;
+	i = 0;
+	n = r_size(DecodingArray);
+    } else
+	return false; /* Must not happen. */
+    for (;n--; i++) {
+	if (array_get(mem, DecodingArray, i, &char_code1) < 0 ||
+	    !r_has_type(&char_code1, t_integer))
+	    return false; /* Must not happen. */
+	if (array_get(mem, TT_cmap, char_code1.value.intval, &glyph_index) >= 0 &&
+		r_has_type(&glyph_index, t_integer)) {
+	    *c = glyph_index.value.intval;
+	    found = true;
+	    if (*c != 0)
+		return true;
+	}
     }
-    if (array_get(mem, TT_cmap, char_code.value.intval, &glyph_index) < 0 ||
-	    !r_has_type(&glyph_index, t_integer))
-	return false;
-    *c = glyph_index.value.intval;
-    return true;
+    return found;
 }
 
 /* Convert a CID into a TT char code or into a TT glyph index, using SubstNWP. */



More information about the gs-cvs mailing list