Commit 9b067facf1e2ffc011591752a055fbc70b62d6f6

Werner Lemberg 2003-12-11T17:55:58

Use implementation specific SID value 0xFFFF to indicate that a dictionary element is missing. * src/cff/cffload.c (cff_subfont_load): Initialize all fields which hold SIDs to 0xFFFF. (cff_index_get_sid_string): Handle SID value 0xFFFF. Handle case where `psnames' is zero. (cff_font_load): Updated. Don't load encoding for CID-keyed CFFs. * src/cff/cffobjs.c (cff_face_init): Updated. Don't check for PSNames module if font is CID-keyed. Compute style name properly (using the same algorithm as in the CID driver). Fix computation of style flags. * src/cff/cfftoken.h: Comment out handling of base_font_name. Rename `postscript' field to `embedded_postscript' * src/cff/cfftypes.h (CFF_FontRecDictRec): Remove `base_font_name' and `postscript'.

diff --git a/ChangeLog b/ChangeLog
index 32a07ed..97c19ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2003-12-10  Werner Lemberg  <wl@gnu.org>
+
+	Use implementation specific SID value 0xFFFF to indicate that
+	a dictionary element is missing.
+
+	* src/cff/cffload.c (cff_subfont_load): Initialize all fields
+	which hold SIDs to 0xFFFF.
+	(cff_index_get_sid_string): Handle SID value 0xFFFF.
+	Handle case where `psnames' is zero.
+	(cff_font_load): Updated.
+	Don't load encoding for CID-keyed CFFs.
+
+	* src/cff/cffobjs.c (cff_face_init): Updated.
+	Don't check for PSNames module if font is CID-keyed.
+	Compute style name properly (using the same algorithm as in the
+	CID driver).
+	Fix computation of style flags.
+
+	* src/cff/cfftoken.h: Comment out handling of base_font_name.
+	Rename `postscript' field to `embedded_postscript'
+	* src/cff/cfftypes.h (CFF_FontRecDictRec): Remove `base_font_name'
+	and `postscript'.
+
 2003-12-10  Detlef Würkner  <TetiSoft@apg.lahn.de>
 
 	* src/pcf/pcfdrivr.c (pcf_get_charset_id): New function (a clone
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 43d6849..63db54a 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -2362,7 +2362,7 @@
       cff_builder_done( &decoder.builder );
     }
 
- #ifdef FT_CONFIG_OPTION_INCREMENTAL
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
 
     /* Incremental fonts can optionally override the metrics. */
     if ( !error                                                              &&
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index e6c27d8..dcfe99a 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -1172,7 +1172,7 @@
   }
 
 
- /* allocate a table containing pointers to an index's elements */
+  /* allocate a table containing pointers to an index's elements */
   static FT_Error
   cff_index_get_pointers( CFF_Index   idx,
                           FT_Byte***  table )
@@ -1211,7 +1211,7 @@
                             FT_Byte**  pbytes,
                             FT_ULong*  pbyte_len )
   {
-    FT_Error  error = 0;
+    FT_Error  error = CFF_Err_Ok;
 
 
     if ( idx && idx->count > element )
@@ -1316,10 +1316,18 @@
                             FT_UInt             sid,
                             FT_Service_PsCMaps  psnames )
   {
+    /* value 0xFFFFU indicates a missing dictionary entry */
+    if ( sid == 0xFFFFU )
+      return 0;
+
     /* if it is not a standard string, return it */
     if ( sid > 390 )
       return cff_index_get_name( idx, sid - 391 );
 
+    /* CID-keyed CFF fonts don't have glyph names */
+    if ( !psnames )
+      return 0;
+
     /* that's a standard string, fetch a copy from the PSName module */
     {
       FT_String*   name       = 0;
@@ -1967,6 +1975,20 @@
     top->font_matrix.yy      = 0x10000L;
     top->cid_count           = 8720;
 
+    /* we use the implementation specific SID value 0xFFFF to indicate */
+    /* missing entries                                                 */
+    top->version             = 0xFFFFU;
+    top->notice              = 0xFFFFU;
+    top->copyright           = 0xFFFFU;
+    top->full_name           = 0xFFFFU;
+    top->family_name         = 0xFFFFU;
+    top->weight              = 0xFFFFU;
+    top->embedded_postscript = 0xFFFFU;
+
+    top->cid_registry        = 0xFFFFU;
+    top->cid_ordering        = 0xFFFFU;
+    top->cid_font_name       = 0xFFFFU;
+
     error = cff_index_access_element( idx, font_index, &dict, &dict_len ) ||
             cff_parser_run( &parser, dict, dict + dict_len );
 
@@ -1976,7 +1998,7 @@
       goto Exit;
 
     /* if it is a CID font, we stop there */
-    if ( top->cid_registry )
+    if ( top->cid_registry != 0xFFFFU )
       goto Exit;
 
     /* parse the private dictionary, if any */
@@ -2118,7 +2140,7 @@
       goto Exit;
 
     /* now, check for a CID font */
-    if ( dict->cid_registry )
+    if ( dict->cid_registry != 0xFFFFU )
     {
       CFF_IndexRec  fd_index;
       CFF_SubFont   sub;
@@ -2199,7 +2221,7 @@
     if ( error )
       goto Exit;
 
-    /* read the Charset and Encoding tables when available */
+    /* read the Charset and Encoding tables if available */
     if ( font->num_glyphs > 0 )
     {
       error = cff_charset_load( &font->charset, font->num_glyphs, stream,
@@ -2207,17 +2229,22 @@
       if ( error )
         goto Exit;
 
-      error = cff_encoding_load( &font->encoding,
-                                 &font->charset,
-                                 font->num_glyphs,
-                                 stream,
-                                 base_offset,
-                                 dict->encoding_offset );
-      if ( error )
-        goto Exit;
+      /* CID-keyed CFFs don't have an encoding */
+      if ( dict->cid_registry == 0xFFFFU )
+      {
+        error = cff_encoding_load( &font->encoding,
+                                   &font->charset,
+                                   font->num_glyphs,
+                                   stream,
+                                   base_offset,
+                                   dict->encoding_offset );
+        if ( error )
+          goto Exit;
+      }
     }
 
-    /* get the font name */
+    /* get the font name (/CIDFontName for CID-keyed fonts, */
+    /* /FontName otherwise)                                 */
     font->font_name = cff_index_get_name( &font->name_index, face_index );
 
   Exit:
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index 90c34db..8c4f07e 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -244,8 +244,6 @@
   }
 
 
-
-
   FT_LOCAL_DEF( FT_Error )
   cff_face_init( FT_Stream      stream,
                  CFF_Face       face,
@@ -300,7 +298,7 @@
       sfnt_format = 1;
 
       /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
-      /* font; in the later case it doesn't have a `head' table          */
+      /* font; in the latter case it doesn't have a `head' table         */
       error = face->goto_table( face, TTAG_head, stream, 0 );
       if ( !error )
       {
@@ -365,10 +363,12 @@
       if ( pure_cff )
       {
         CFF_FontRecDict  dict = &cff->top_font.font_dict;
+        char*            style_name;
 
 
         /* we need the `PSNames' module for pure-CFF and CEF formats */
-        if ( !psnames )
+        /* which aren't CID-keyed                                    */
+        if ( dict->cid_registry == 0xFFFFU && !psnames )
         {
           FT_ERROR(( "cff_face_init:" ));
           FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
@@ -381,7 +381,7 @@
         root->num_faces = cff->num_faces;
 
         /* compute number of glyphs */
-        if ( dict->cid_registry )
+        if ( dict->cid_registry != 0xFFFFU )
           root->num_glyphs = dict->cid_count;
         else
           root->num_glyphs = cff->charstrings_index.count;
@@ -392,7 +392,6 @@
         root->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16;
         root->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16;
 
-
         root->ascender  = (FT_Short)( root->bbox.yMax );
         root->descender = (FT_Short)( root->bbox.yMin );
         root->height    = (FT_Short)(
@@ -409,13 +408,59 @@
           (FT_Short)( dict->underline_thickness >> 16 );
 
         /* retrieve font family & style name */
-        root->family_name  = cff_index_get_name( &cff->name_index, face_index );
-        if ( dict->cid_registry )
-          root->style_name = cff_strcpy( memory, "Regular" );  /* XXXX */
+        root->family_name = cff_index_get_name( &cff->name_index,
+                                                face_index );
+
+        /* assume "Regular" style if we don't know better */
+        style_name = (char *)"Regular";
+
+        if ( root->family_name )
+        {
+          char*  full   = cff_index_get_sid_string( &cff->string_index,
+                                                    dict->full_name,
+                                                    psnames );
+          char*  family = root->family_name;
+
+
+          if ( full )
+          {
+            while ( *full )
+            {
+              if ( *full == *family )
+              {
+                family++;
+                full++;
+              }
+              else
+              {
+                if ( *full == ' ' || *full == '-' )
+                  full++;
+                else if ( *family == ' ' || *family == '-' )
+                  family++;
+                else
+                {
+                  if ( !*family )
+                    style_name = full;
+                  break;
+                }
+              }
+            }
+          }
+        }
         else
-          root->style_name = cff_index_get_sid_string( &cff->string_index,
-                                                       dict->weight,
-                                                       psnames );
+        {
+          char  *cid_font_name =
+                   cff_index_get_sid_string( &cff->string_index,
+                                             dict->cid_font_name,
+                                             psnames );
+
+
+          /* do we have a `/FontName' for a CID-keyed font? */
+          if ( cid_font_name )
+            root->family_name = cid_font_name;
+        }
+
+        root->style_name = cff_strcpy( memory, style_name );
 
         /*******************************************************************/
         /*                                                                 */
@@ -453,9 +498,17 @@
         if ( dict->italic_angle )
           flags |= FT_STYLE_FLAG_ITALIC;
 
-        /* XXX: may not be correct */
-        if ( cff->top_font.private_dict.force_bold )
-          flags |= FT_STYLE_FLAG_BOLD;
+        {
+          char  *weight = cff_index_get_sid_string( &cff->string_index,
+                                                    dict->weight,
+                                                    psnames );
+
+
+          if ( weight )
+            if ( !ft_strcmp( weight, "Bold"  ) ||
+                 !ft_strcmp( weight, "Black" ) )
+              flags |= FT_STYLE_FLAG_BOLD;
+        }
 
         root->style_flags = flags;
       }
diff --git a/src/cff/cfftoken.h b/src/cff/cfftoken.h
index 65a8468..659d157 100644
--- a/src/cff/cfftoken.h
+++ b/src/cff/cfftoken.h
@@ -43,10 +43,10 @@
   CFF_FIELD_NUM     ( 17,    charstrings_offset )
   CFF_FIELD_CALLBACK( 18,    private_dict )
   CFF_FIELD_NUM     ( 0x114, synthetic_base )
-  CFF_FIELD_STRING  ( 0x115, postscript )
-  CFF_FIELD_STRING  ( 0x116, base_font_name )
+  CFF_FIELD_STRING  ( 0x115, embedded_postscript )
 
 #if 0
+  CFF_FIELD_STRING  ( 0x116, base_font_name )
   CFF_FIELD_DELTA   ( 0x117, base_font_blend, 16 )
   CFF_FIELD_CALLBACK( 0x118, multiple_master )
   CFF_FIELD_CALLBACK( 0x119, blend_axit_types )
diff --git a/src/cff/cfftypes.h b/src/cff/cfftypes.h
index e19e593..d7a7cb0 100644
--- a/src/cff/cfftypes.h
+++ b/src/cff/cfftypes.h
@@ -113,8 +113,6 @@ FT_BEGIN_HEADER
     FT_ULong   private_size;
     FT_Long    synthetic_base;
     FT_UInt    embedded_postscript;
-    FT_UInt    base_font_name;
-    FT_UInt    postscript;
 
     /* these should only be used for the top-level font dictionary */
     FT_UInt    cid_registry;