Commit 56054f310b49cac58f31210da099d21eda7806fe

David Turner 2002-03-30T16:32:47

fixing the function that computes an ASCII face name

diff --git a/ChangeLog b/ChangeLog
index 19c96b2..9b4146a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 2002-03-30  David Turner  <david@freetype.org>
 
+        * src/sfnt/sfobjs.c (tt_face_get_name): bug-fix
+
         * include/freetype/internal/tttypes.h: adding comments to some of
           the TT_FaceRec fields.
 
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 5d866ee..21d4d71 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -38,6 +38,94 @@
 #define FT_COMPONENT  trace_sfobjs
 
 
+
+ /* convert a UTF-16 name entry to ASCII */
+  static FT_String*
+  tt_name_entry_ascii_from_utf16( TT_NameEntry   entry,
+                                  FT_Memory      memory )
+  {
+    FT_String*  string;
+    FT_UInt     len, code, n;
+    FT_Byte*    read = (FT_Byte*) entry->string;
+    
+    len = (FT_UInt) entry->stringLength/2;
+    
+    if ( FT_MEM_NEW_ARRAY( string, len+1 ) )
+      return NULL;
+    
+    for ( n = 0; n < len; n++ )
+    {
+      code = FT_NEXT_USHORT(read);
+      if ( code < 32 || code > 127 )
+        code = '?';
+        
+      string[n] = (char)code;
+    }
+
+    string[len] = 0;
+    
+    return string;
+  }                                   
+
+
+ /* convert a UCS-4 name entry to ASCII */
+  static FT_String*
+  tt_name_entry_ascii_from_ucs4( TT_NameEntry  entry,
+                                 FT_Memory     memory )
+  {
+    FT_String*  string;
+    FT_UInt     len, code, n;
+    FT_Byte*    read = (FT_Byte*) entry->string;
+    
+    len = (FT_UInt) entry->stringLength/4;
+    
+    if ( FT_MEM_NEW_ARRAY( string, len+1 ) )
+      return NULL;
+    
+    for ( n = 0; n < len; n++ )
+    {
+      code = FT_NEXT_ULONG(read);
+      if ( code < 32 || code > 127 )
+        code = '?';
+        
+      string[n] = (char)code;
+    }
+
+    string[len] = 0;
+    
+    return string;
+  }                                 
+
+
+ /* convert an Apple Roman or symbol name entry to ASCII */
+  static FT_String*
+  tt_name_entry_ascii_from_other( TT_NameEntry  entry,
+                                  FT_Memory     memory )
+  {
+    FT_String*  string;
+    FT_UInt     len, code, n;
+    FT_Byte*    read = (FT_Byte*) entry->string;
+    
+    len = (FT_UInt) entry->stringLength;
+    
+    if ( FT_MEM_NEW_ARRAY( string, len+1 ) )
+      return NULL;
+    
+    for ( n = 0; n < len; n++ )
+    {
+      code = *read++;
+      if ( code < 32 || code > 127 )
+        code = '?';
+        
+      string[n] = (char)code;
+    }
+
+    string[len] = 0;
+    
+    return string;
+  }                                  
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -56,34 +144,48 @@
   /*                                                                       */
   static FT_String*
   tt_face_get_name( TT_Face    face,
-            FT_UShort  nameid )
+                    FT_UShort  nameid )
   {
-    FT_Memory    memory = face->root.memory;
-    FT_UShort    n;
+    FT_Memory         memory = face->root.memory;
+    FT_String*        result = NULL;
+    FT_UShort         n;
     TT_NameEntryRec*  rec;
-    FT_Bool      wide_chars    = 1;
-    FT_Int       found_apple   = -1;
-    FT_Int       found_win     = -1;
-    FT_Int       found_unicode = -1;
-    FT_Int       found;
+    FT_Int            found_apple   = -1;
+    FT_Int            found_win     = -1;
+    FT_Int            found_unicode = -1;
 
 
     rec = face->name_table.names;
     for ( n = 0; n < face->name_table.numNameRecords; n++, rec++ )
     {
+      /* according to the OpenType 1.3 specification, only Microsoft of */
+      /* Apple platform ids might be used in the 'name' table. The      */
+      /* 'Unicode' platform is reserved for the 'cmap' table, and       */
+      /* the 'Iso' one is deprecated                                    */
+
+      /* however the Apple TrueType specification doesn't says the same  */
+      /* thing and goes to suggest that all Unicode 'name' table entries */
+      /* should be coded in UTF-16 (in big-endian format I suppose)      */
+      /*                                                                 */
       if ( rec->nameID == nameid && rec->string )
       {
         switch ( rec->platformID )
         {
+
           case TT_PLATFORM_APPLE_UNICODE:
+          case TT_PLATFORM_ISO:
             {
+              /* there is 'languageID' to check there. We should use this */
+              /* field only as a last solution when nothing else is       */
+              /* available..                                              */
+              /*                                                          */
               found_unicode = n;
               break;
             }
-            
+          
           case TT_PLATFORM_MACINTOSH:
             {
-              if ( rec->languageID == TT_MAC_ID_ROMAN )
+              if ( rec->languageID == TT_MAC_LANGID_ENGLISH )
                 found_apple = n;
               
               break;
@@ -91,10 +193,22 @@
             
           case TT_PLATFORM_MICROSOFT:
             {
-              if (  rec->encodingID <= TT_MS_ID_UNICODE_CS &&
-                   (rec->languageID & 0x3FF) == 0x009      )
+              /* we only take a non-English name when there is nothing */
+              /* else available in the font..                          */
+              /*                                                       */
+              if ( found_win == -1 || (rec->languageID & 0x3FF) == 0x009 )
               {
-                found_win = n;
+                switch ( rec->encodingID )
+                {
+                  case TT_MS_ID_SYMBOL_CS:
+                  case TT_MS_ID_UNICODE_CS:
+                  case TT_MS_ID_UCS_4:
+                    found_win = n;
+                    break;
+                    
+                  default:
+                    ;
+                }
               }
               break;
             }
@@ -109,49 +223,40 @@
     /* we will thus favor name encoded in Windows formats when they're   */
     /* available..                                                       */
     /*                                                                   */
-    found = found_win;
-    if ( found < 0 )
+    if ( found_win >= 0 )
     {
-      found = found_apple;
-      if ( found_apple < 0 )
-        found = found_unicode;
-      else
-        wide_chars = 0;
-    }
-
-    /* found a Unicode name */
-    if ( found >= 0 )
-    {
-      FT_String*  string;
-      FT_UInt     len;
-
-      rec = face->name_table.names + found;
-      if ( wide_chars )
-      {
-        FT_UInt   m;
-
-
-        len = (FT_UInt)rec->stringLength / 2;
-        if ( FT_MEM_ALLOC( string, len + 1 ) )
-          return NULL;
-
-        for ( m = 0; m < len; m ++ )
-          string[m] = rec->string[2 * m + 1];
-      }
-      else
+      rec = face->name_table.names + found_win;
+      switch ( rec->encodingID )
       {
-        len = rec->stringLength;
-        if ( FT_MEM_ALLOC( string, len + 1 ) )
-          return NULL;
-
-        FT_MEM_COPY( string, rec->string, len );
+        case TT_MS_ID_UNICODE_CS:
+        case TT_MS_ID_SYMBOL_CS:
+          {
+            result = tt_name_entry_ascii_from_utf16( rec, memory );
+            break;
+          }
+          
+        case TT_MS_ID_UCS_4:
+          {
+            result = tt_name_entry_ascii_from_ucs4( rec, memory );
+            break;
+          }
+        
+        default:
+          ;
       }
-
-      string[len] = '\0';
-      return string;
     }
-
-    return NULL;
+    else if ( found_apple >= 0 )
+    {
+      rec    = face->name_table.names + found_apple;
+      result = tt_name_entry_ascii_from_other( rec, memory );
+    }
+    else if ( found_unicode >= 0 )
+    {
+      rec    = face->name_table.names + found_unicode;
+      result = tt_name_entry_ascii_from_utf16( rec, memory );
+    }
+    
+    return result;
   }