]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcfreetype.c
Use explicit platform/nameid order when scanning ttf files.
[fontconfig.git] / src / fcfreetype.c
index 83c58d6013bd9a36809902dba59b72bf8ea6add8..8ca14d79bed7af75a1eb6651869819938230d35f 100644 (file)
@@ -1043,6 +1043,25 @@ FcStringInPatternElement (FcPattern *pat, const char *elt, FcChar8 *string)
     return FcFalse;
 }
 
+static const FT_UShort platform_order[] = {
+    TT_PLATFORM_MICROSOFT,
+    TT_PLATFORM_APPLE_UNICODE,
+    TT_PLATFORM_MACINTOSH,
+};
+#define NUM_PLATFORM_ORDER (sizeof (platform_order) / sizeof (platform_order[0]))
+
+static const FT_UShort nameid_order[] = {
+    TT_NAME_ID_PREFERRED_FAMILY,
+    TT_NAME_ID_FONT_FAMILY,
+    TT_NAME_ID_MAC_FULL_NAME,
+    TT_NAME_ID_FULL_NAME,
+    TT_NAME_ID_PREFERRED_SUBFAMILY,
+    TT_NAME_ID_FONT_SUBFAMILY,
+    TT_NAME_ID_TRADEMARK,
+    TT_NAME_ID_MANUFACTURER,
+};
+
+#define NUM_NAMEID_ORDER  (sizeof (nameid_order) / sizeof (nameid_order[0]))
 FcPattern *
 FcFreeTypeQuery (const FcChar8 *file,
                 int            id,
@@ -1083,6 +1102,8 @@ FcFreeTypeQuery (const FcChar8    *file,
     int                    nstyle_lang = 0;
     int                    nfullname = 0;
     int                    nfullname_lang = 0;
+    int                    p, platform;
+    int                    n, nameid;
 
     FcChar8        *style = 0;
     int                    st;
@@ -1132,105 +1153,145 @@ FcFreeTypeQuery (const FcChar8        *file,
      * of them
      */
     snamec = FT_Get_Sfnt_Name_Count (face);
-    for (snamei = 0; snamei < snamec; snamei++)
+    for (p = 0; p <= NUM_PLATFORM_ORDER; p++)
     {
-       FcChar8         *utf8;
-       const FcChar8   *lang;
-       const char      *elt = 0, *eltlang = 0;
-       int             *np = 0, *nlangp = 0;
-
-       if (FT_Get_Sfnt_Name (face, snamei, &sname) != 0)
-           continue;
-       
-       utf8 = FcSfntNameTranscode (&sname);
-       lang = FcSfntNameLanguage (&sname);
+       if (p < NUM_PLATFORM_ORDER)
+           platform = platform_order[p];
+       else
+           platform = 0xffff;
 
-       if (!utf8)
-           continue;
-       
-       switch (sname.name_id) {
-       case TT_NAME_ID_FONT_FAMILY:
-#if 0      
-       case TT_NAME_ID_PS_NAME:
-       case TT_NAME_ID_UNIQUE_ID:
-#endif
-           if (FcDebug () & FC_DBG_SCANV)
-               printf ("found family (n %2d p %d e %d l 0x%04x) %s\n",
-                   sname.name_id, sname.platform_id,
-                   sname.encoding_id, sname.language_id,
-                   utf8);
-    
-           elt = FC_FAMILY;
-           eltlang = FC_FAMILYLANG;
-           np = &nfamily;
-           nlangp = &nfamily_lang;
-           break;
-       case TT_NAME_ID_FULL_NAME:
-       case TT_NAME_ID_MAC_FULL_NAME:
-           if (FcDebug () & FC_DBG_SCANV)
-               printf ("found full   (n %2d p %d e %d l 0x%04x) %s\n",
-                   sname.name_id, sname.platform_id,
-                   sname.encoding_id, sname.language_id,
-                   utf8);
-    
-           elt = FC_FULLNAME;
-           eltlang = FC_FULLNAMELANG;
-           np = &nfullname;
-           nlangp = &nfullname_lang;
-           break;
-       case TT_NAME_ID_FONT_SUBFAMILY:
-           if (FcDebug () & FC_DBG_SCANV)
-               printf ("found style  (n %2d p %d e %d l 0x%04x) %s\n",
-                   sname.name_id, sname.platform_id,
-                   sname.encoding_id, sname.language_id,
-                   utf8);
-    
-           elt = FC_STYLE;
-           eltlang = FC_STYLELANG;
-           np = &nstyle;
-           nlangp = &nstyle_lang;
-           break;
-        case TT_NAME_ID_TRADEMARK:
-        case TT_NAME_ID_MANUFACTURER:
-           /* If the foundry wasn't found in the OS/2 table, look here */
-            if(!foundry)
-                foundry = FcNoticeFoundry((FT_String *) utf8);
-            break;
-       }
-       if (elt)
+       /*
+        * Order nameids so preferred names appear first
+        * in the resulting list
+        */
+       for (n = 0; n < NUM_NAMEID_ORDER; n++)
        {
-           if (FcStringInPatternElement (pat, elt, utf8))
-           {
-               free (utf8);
-               continue;
-           }
+           nameid = nameid_order[n];
 
-           /* add new element */
-           if (!FcPatternAddString (pat, elt, utf8))
-           {
-               free (utf8);
-               goto bail1;
-           }
-           free (utf8);
-           if (lang)
+           for (snamei = 0; snamei < snamec; snamei++)
            {
-               /* pad lang list with 'xx' to line up with elt */
-               while (*nlangp < *np)
+               FcChar8         *utf8;
+               const FcChar8   *lang;
+               const char      *elt = 0, *eltlang = 0;
+               int             *np = 0, *nlangp = 0;
+
+               if (FT_Get_Sfnt_Name (face, snamei, &sname) != 0)
+                   continue;
+               if (sname.name_id != nameid)
+                   continue;
+
+               /*
+                * Sort platforms in preference order, accepting
+                * all other platforms last
+                */
+               if (p < NUM_PLATFORM_ORDER)
+               {
+                   if (sname.platform_id != platform)
+                       continue;
+               }
+               else
+               {
+                   int     sp;
+
+                   for (sp = 0; sp < NUM_PLATFORM_ORDER; sp++)
+                       if (sname.platform_id == platform_order[sp])
+                           break;
+                   if (sp != NUM_PLATFORM_ORDER)
+                       continue;
+               }
+               utf8 = FcSfntNameTranscode (&sname);
+               lang = FcSfntNameLanguage (&sname);
+
+               if (!utf8)
+                   continue;
+
+               switch (sname.name_id) {
+               case TT_NAME_ID_PREFERRED_FAMILY:
+               case TT_NAME_ID_FONT_FAMILY:
+#if 0      
+               case TT_NAME_ID_PS_NAME:
+               case TT_NAME_ID_UNIQUE_ID:
+#endif
+                   if (FcDebug () & FC_DBG_SCANV)
+                       printf ("found family (n %2d p %d e %d l 0x%04x) %s\n",
+                               sname.name_id, sname.platform_id,
+                               sname.encoding_id, sname.language_id,
+                               utf8);
+
+                   elt = FC_FAMILY;
+                   eltlang = FC_FAMILYLANG;
+                   np = &nfamily;
+                   nlangp = &nfamily_lang;
+                   break;
+               case TT_NAME_ID_MAC_FULL_NAME:
+               case TT_NAME_ID_FULL_NAME:
+                   if (FcDebug () & FC_DBG_SCANV)
+                       printf ("found full   (n %2d p %d e %d l 0x%04x) %s\n",
+                               sname.name_id, sname.platform_id,
+                               sname.encoding_id, sname.language_id,
+                               utf8);
+
+                   elt = FC_FULLNAME;
+                   eltlang = FC_FULLNAMELANG;
+                   np = &nfullname;
+                   nlangp = &nfullname_lang;
+                   break;
+               case TT_NAME_ID_PREFERRED_SUBFAMILY:
+               case TT_NAME_ID_FONT_SUBFAMILY:
+                   if (FcDebug () & FC_DBG_SCANV)
+                       printf ("found style  (n %2d p %d e %d l 0x%04x) %s\n",
+                               sname.name_id, sname.platform_id,
+                               sname.encoding_id, sname.language_id,
+                               utf8);
+
+                   elt = FC_STYLE;
+                   eltlang = FC_STYLELANG;
+                   np = &nstyle;
+                   nlangp = &nstyle_lang;
+                   break;
+               case TT_NAME_ID_TRADEMARK:
+               case TT_NAME_ID_MANUFACTURER:
+                   /* If the foundry wasn't found in the OS/2 table, look here */
+                   if(!foundry)
+                       foundry = FcNoticeFoundry((FT_String *) utf8);
+                   break;
+               }
+               if (elt)
                {
-                   if (!FcPatternAddString (pat, eltlang, (FcChar8 *) "xx"))
+                   if (FcStringInPatternElement (pat, elt, utf8))
+                   {
+                       free (utf8);
+                       continue;
+                   }
+
+                   /* add new element */
+                   if (!FcPatternAddString (pat, elt, utf8))
+                   {
+                       free (utf8);
                        goto bail1;
-                   ++*nlangp;
+                   }
+                   free (utf8);
+                   if (lang)
+                   {
+                       /* pad lang list with 'xx' to line up with elt */
+                       while (*nlangp < *np)
+                       {
+                           if (!FcPatternAddString (pat, eltlang, (FcChar8 *) "xx"))
+                               goto bail1;
+                           ++*nlangp;
+                       }
+                       if (!FcPatternAddString (pat, eltlang, lang))
+                           goto bail1;
+                       ++*nlangp;
+                   }
+                   ++*np;
                }
-               if (!FcPatternAddString (pat, eltlang, lang))
-                   goto bail1;
-               ++*nlangp;
+               else
+                   free (utf8);
            }
-           ++*np;
        }
-        else
-           free (utf8);
     }
-    
+
     if (!nfamily && face->family_name && 
        FcStrCmpIgnoreBlanksAndCase ((FcChar8 *) face->family_name, (FcChar8 *) "") != 0)
     {