]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcfreetype.c
Oops. Left debugging printf in previous commit.
[fontconfig.git] / src / fcfreetype.c
index 83c58d6013bd9a36809902dba59b72bf8ea6add8..da2aa803daa42f3ae4cb00c8c48a6b99dcd1086c 100644 (file)
  */
 
 static const struct {
-    int                    bit;
-    const FcChar8   *lang;
+    char           bit;
+    const FcChar8   lang[6];
 } FcCodePageRange[] = {
-    { 17,      (const FcChar8 *) "ja" },
-    { 18,      (const FcChar8 *) "zh-cn" },
-    { 19,      (const FcChar8 *) "ko" },
-    { 20,      (const FcChar8 *) "zh-tw" },
+    { 17,      "ja" },
+    { 18,      "zh-cn" },
+    { 19,      "ko" },
+    { 20,      "zh-tw" },
 };
 
 #define NUM_CODE_PAGE_RANGE (int) (sizeof FcCodePageRange / sizeof FcCodePageRange[0])
@@ -801,29 +801,47 @@ FcSfntNameLanguage (FT_SfntName *sname)
 /* Order is significant.  For example, some B&H fonts are hinted by
    URW++, and both strings appear in the notice. */
 
-static const struct {
-    const FT_String *notice;
-    const FcChar8   *foundry;
-} FcNoticeFoundries[] = {
-    { (const FT_String *) "Bigelow",   (const FcChar8 *) "b&h" },
-    { (const FT_String *) "Adobe",     (const FcChar8 *) "adobe" },
-    { (const FT_String *) "Bitstream", (const FcChar8 *) "bitstream" },
-    { (const FT_String *) "Monotype",  (const FcChar8 *) "monotype" },
-    { (const FT_String *) "Linotype",  (const FcChar8 *) "linotype" },
-    { (const FT_String *) "LINOTYPE-HELL",
-                                       (const FcChar8 *) "linotype" },
-    { (const FT_String *) "IBM",       (const FcChar8 *) "ibm" },
-    { (const FT_String *) "URW",       (const FcChar8 *) "urw" },
-    { (const FT_String *) "International Typeface Corporation", 
-                                       (const FcChar8 *) "itc" },
-    { (const FT_String *) "Tiro Typeworks",
-                                       (const FcChar8 *) "tiro" },
-    { (const FT_String *) "XFree86",   (const FcChar8 *) "xfree86" },
-    { (const FT_String *) "Microsoft", (const FcChar8 *) "microsoft" },
-    { (const FT_String *) "Omega",     (const FcChar8 *) "omega" },
-    { (const FT_String *) "Font21",    (const FcChar8 *) "hwan" },
-    { (const FT_String *) "HanYang System",
-                                       (const FcChar8 *) "hanyang" }
+static const char notice_foundry_data[] =
+       "Bigelow\0b&h\0"
+       "Adobe\0adobe\0"
+       "Bitstream\0bitstream\0"
+       "Monotype\0monotype\0"
+       "Linotype\0linotype\0"
+       "LINOTYPE-HELL\0linotype\0"
+       "IBM\0ibm\0"
+       "URW\0urw\0"
+       "International Typeface Corporation\0itc\0"
+       "Tiro Typeworks\0tiro\0"
+       "XFree86\0xfree86\0"
+       "Microsoft\0microsoft\0"
+       "Omega\0omega\0"
+       "Font21\0hwan\0"
+       "HanYang System\0hanyang";
+
+struct _notice_foundry {
+    /* these are the offsets into the
+     * notice_foundry_data array.
+     */
+    unsigned char notice_offset;
+    unsigned char foundry_offset;
+};
+
+static const struct _notice_foundry FcNoticeFoundries[] = {
+    { 0, 8 },
+    { 12, 18 },
+    { 24, 34 },
+    { 44, 53 },
+    { 62, 71 },
+    { 80, 94 },
+    { 103, 107 },
+    { 111, 115 },
+    { 119, 154 },
+    { 158, 173 },
+    { 178, 186 },
+    { 194, 204 },
+    { 214, 220 },
+    { 226, 233 },
+    { 238, 253 }
 };
 
 #define NUM_NOTICE_FOUNDRIES   (int) (sizeof (FcNoticeFoundries) / sizeof (FcNoticeFoundries[0]))
@@ -835,8 +853,14 @@ FcNoticeFoundry(const FT_String *notice)
 
     if (notice)
        for(i = 0; i < NUM_NOTICE_FOUNDRIES; i++)
-           if (strstr ((const char *) notice, (const char *) FcNoticeFoundries[i].notice))
-               return FcNoticeFoundries[i].foundry;
+        {
+            const struct _notice_foundry *nf = &FcNoticeFoundries[i];
+            const char *n = notice_foundry_data + nf->notice_offset;
+            const char *f = notice_foundry_data + nf->foundry_offset;
+
+           if (strstr ((const char *) notice, n))
+               return (const FcChar8 *) f;
+        }
     return 0;
 }
 
@@ -861,38 +885,38 @@ FcVendorMatch(const FT_Char vendor[4], const FT_Char *vendor_string)
    entries for padding both with spaces and NULs. */
 
 static const struct {
-    const FT_Char   *vendor;
-    const FcChar8   *foundry;
+    const FT_Char   vendor[5];
+    const FcChar8   foundry[13];
 } FcVendorFoundries[] = {
-    { (const FT_Char *) "ADBE", (const FcChar8 *) "adobe"},
-    { (const FT_Char *) "AGFA", (const FcChar8 *) "agfa"},
-    { (const FT_Char *) "ALTS", (const FcChar8 *) "altsys"},
-    { (const FT_Char *) "APPL", (const FcChar8 *) "apple"},
-    { (const FT_Char *) "ARPH", (const FcChar8 *) "arphic"},
-    { (const FT_Char *) "ATEC", (const FcChar8 *) "alltype"},
-    { (const FT_Char *) "B&H",  (const FcChar8 *) "b&h"},
-    { (const FT_Char *) "BITS", (const FcChar8 *) "bitstream"},
-    { (const FT_Char *) "CANO", (const FcChar8 *) "cannon"},
-    { (const FT_Char *) "DYNA", (const FcChar8 *) "dynalab"},
-    { (const FT_Char *) "EPSN", (const FcChar8 *) "epson"},
-    { (const FT_Char *) "FJ",   (const FcChar8 *) "fujitsu"},
-    { (const FT_Char *) "IBM",  (const FcChar8 *) "ibm"},
-    { (const FT_Char *) "ITC",  (const FcChar8 *) "itc"},
-    { (const FT_Char *) "IMPR", (const FcChar8 *) "impress"},
-    { (const FT_Char *) "LARA", (const FcChar8 *) "larabiefonts"},
-    { (const FT_Char *) "LEAF", (const FcChar8 *) "interleaf"},
-    { (const FT_Char *) "LETR", (const FcChar8 *) "letraset"},
-    { (const FT_Char *) "LINO", (const FcChar8 *) "linotype"},
-    { (const FT_Char *) "MACR", (const FcChar8 *) "macromedia"},
-    { (const FT_Char *) "MONO", (const FcChar8 *) "monotype"},
-    { (const FT_Char *) "MS",   (const FcChar8 *) "microsoft"},
-    { (const FT_Char *) "MT",   (const FcChar8 *) "monotype"},
-    { (const FT_Char *) "NEC",  (const FcChar8 *) "nec"},
-    { (const FT_Char *) "PARA", (const FcChar8 *) "paratype"},
-    { (const FT_Char *) "QMSI", (const FcChar8 *) "qms"},
-    { (const FT_Char *) "RICO", (const FcChar8 *) "ricoh"},
-    { (const FT_Char *) "URW",  (const FcChar8 *) "urw"},
-    { (const FT_Char *) "Y&Y",  (const FcChar8 *) "y&y"}
+    { "ADBE", "adobe"},
+    { "AGFA", "agfa"},
+    { "ALTS", "altsys"},
+    { "APPL", "apple"},
+    { "ARPH", "arphic"},
+    { "ATEC", "alltype"},
+    { "B&H",  "b&h"},
+    { "BITS", "bitstream"},
+    { "CANO", "cannon"},
+    { "DYNA", "dynalab"},
+    { "EPSN", "epson"},
+    { "FJ",   "fujitsu"},
+    { "IBM",  "ibm"},
+    { "ITC",  "itc"},
+    { "IMPR", "impress"},
+    { "LARA", "larabiefonts"},
+    { "LEAF", "interleaf"},
+    { "LETR", "letraset"},
+    { "LINO", "linotype"},
+    { "MACR", "macromedia"},
+    { "MONO", "monotype"},
+    { "MS",   "microsoft"},
+    { "MT",   "monotype"},
+    { "NEC",  "nec"},
+    { "PARA", "paratype"},
+    { "QMSI", "qms"},
+    { "RICO", "ricoh"},
+    { "URW",  "urw"},
+    { "Y&Y",  "y&y"}
 };
 
 #define NUM_VENDOR_FOUNDRIES   (int) (sizeof (FcVendorFoundries) / sizeof (FcVendorFoundries[0]))
@@ -1043,13 +1067,31 @@ 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,
-                FcBlanks       *blanks,
-                int            *count)
+FcFreeTypeQueryFace (const FT_Face  face,
+                    const FcChar8  *file,
+                    int            id,
+                    FcBlanks       *blanks)
 {
-    FT_Face        face;
     FcPattern      *pat;
     int                    slant = -1;
     int                    weight = -1;
@@ -1058,7 +1100,6 @@ FcFreeTypeQuery (const FcChar8    *file,
     int                    i;
     FcCharSet      *cs;
     FcLangSet      *ls;
-    FT_Library     ftLibrary;
 #if 0
     FcChar8        *family = 0;
 #endif
@@ -1083,18 +1124,12 @@ 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;
     
-    if (FT_Init_FreeType (&ftLibrary))
-       return 0;
-    
-    if (FT_New_Face (ftLibrary, (char *) file, id, &face))
-       goto bail;
-
-    *count = face->num_faces;
-
     pat = FcPatternCreate ();
     if (!pat)
        goto bail0;
@@ -1132,105 +1167,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))
+           for (snamei = 0; snamei < snamec; snamei++)
            {
-               free (utf8);
-               goto bail1;
-           }
-           free (utf8);
-           if (lang)
-           {
-               /* 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
                {
-                   if (!FcPatternAddString (pat, eltlang, (FcChar8 *) "xx"))
+                   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 (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)
     {
@@ -1279,70 +1354,6 @@ FcFreeTypeQuery (const FcChar8   *file,
        ++nfamily;
     }
 
-    /*
-     * Walk through FC_FULLNAME entries eliding those in FC_FAMILY
-     * or which are simply a FC_FAMILY and FC_STYLE glued together
-     */
-    {
-       int     fn, fa;
-       FcChar8 *full;
-       FcChar8 *fam;
-       FcChar8 *style;
-
-       for (fn = 0; FcPatternGetString (pat, FC_FULLNAME, fn, &full) == FcResultMatch; fn++)
-       {
-           FcBool  remove = FcFalse;
-           /*
-            * Check each family
-            */
-           for (fa = 0; !remove && 
-                FcPatternGetString (pat, FC_FAMILY, 
-                                    fa, &fam) == FcResultMatch;
-                fa++)
-           {
-               /*
-                * for exact match
-                */
-               if (!FcStrCmpIgnoreBlanksAndCase (full, fam))
-               {
-                   remove = FcTrue;
-                   break;
-               }
-               /*
-                * If the family is in the full name, check the
-                * combination of this family with every style
-                */
-               if (!FcStrContainsIgnoreBlanksAndCase (full, fam))
-                   continue;
-               for (st = 0; !remove && 
-                    FcPatternGetString (pat, FC_STYLE, 
-                                        st, &style) == FcResultMatch;
-                    st++)
-               {
-                   FcChar8     *both = FcStrPlus (fam, style);
-
-                   if (both)
-                   {
-                       if (FcStrCmpIgnoreBlanksAndCase (full, both) == 0)
-                           remove = FcTrue;
-                       free (both);
-                   }
-               }
-           }
-           if (remove)
-           {
-               FcPatternRemove (pat, FC_FULLNAME, fn);
-               FcPatternRemove (pat, FC_FULLNAMELANG, fn);
-               fn--;
-               nfullname--;
-               nfullname_lang--;
-           }
-       }
-       if (FcDebug () & FC_DBG_SCANV)
-           for (fn = 0; FcPatternGetString (pat, FC_FULLNAME, fn, &full) == FcResultMatch; fn++)
-               printf ("Saving unique fullname %s\n", full);
-    }
-
     if (!FcPatternAddString (pat, FC_FILE, file))
        goto bail1;
 
@@ -1724,12 +1735,6 @@ FcFreeTypeQuery (const FcChar8   *file,
      */
     FcCharSetDestroy (cs);
     
-    /*
-     * Deallocate family/style values
-     */
-    
-    FT_Done_Face (face);
-    FT_Done_FreeType (ftLibrary);
     return pat;
 
 bail2:
@@ -1737,13 +1742,35 @@ bail2:
 bail1:
     FcPatternDestroy (pat);
 bail0:
+    return NULL;
+}
+
+FcPattern *
+FcFreeTypeQuery(const FcChar8  *file,
+               int             id,
+               FcBlanks        *blanks,
+               int             *count)
+{
+    FT_Face        face;
+    FT_Library     ftLibrary;
+    FcPattern      *pat = NULL;
+    
+    if (FT_Init_FreeType (&ftLibrary))
+       return NULL;
+    
+    if (FT_New_Face (ftLibrary, (char *) file, id, &face))
+       goto bail;
+
+    *count = face->num_faces;
+
+    pat = FcFreeTypeQueryFace (face, file, id, blanks);
+
     FT_Done_Face (face);
 bail:
     FT_Done_FreeType (ftLibrary);
-    return 0;
+    return pat;
 }
 
-
 /*
  * For our purposes, this approximation is sufficient
  */
@@ -2301,12 +2328,12 @@ FcUcs4ToGlyphName (FcChar32 ucs4)
 {
     int                i = (int) (ucs4 % FC_GLYPHNAME_HASH);
     int                r = 0;
-    const FcGlyphName  *gn;
+    FcGlyphId  gn;
 
-    while ((gn = ucs_to_name[i]))
+    while ((gn = ucs_to_name[i]) != -1)
     {
-       if (gn->ucs == ucs4)
-           return gn->name;
+       if (glyphs[gn].ucs == ucs4)
+           return glyphs[gn].name;
        if (!r) 
        {
            r = (int) (ucs4 % FC_GLYPHNAME_REHASH);
@@ -2326,12 +2353,12 @@ FcGlyphNameToUcs4 (FcChar8 *name)
     FcChar32   h = FcHashGlyphName (name);
     int                i = (int) (h % FC_GLYPHNAME_HASH);
     int                r = 0;
-    const FcGlyphName  *gn;
+    FcGlyphId  gn;
 
-    while ((gn = name_to_ucs[i]))
+    while ((gn = name_to_ucs[i]) != -1)
     {
-       if (!strcmp ((char *) name, (char *) gn->name))
-           return gn->ucs;
+       if (!strcmp ((char *) name, (char *) glyphs[gn].name))
+           return glyphs[gn].ucs;
        if (!r) 
        {
            r = (int) (h % FC_GLYPHNAME_REHASH);
@@ -2345,6 +2372,19 @@ FcGlyphNameToUcs4 (FcChar8 *name)
     return 0xffff;
 }
 
+/*
+ * Work around a bug in some FreeType versions which fail
+ * to correctly bounds check glyph name buffers and overwrite
+ * the stack. As Postscript names have a limit of 127 characters,
+ * this should be sufficient.
+ */
+
+#if FC_GLYPHNAME_MAXLEN < 127
+# define FC_GLYPHNAME_BUFLEN 127
+#else
+# define FC_GLYPHNAME_BUFLEN FC_GLYPHNAME_MAXLEN
+#endif
+
 /*
  * Search through a font for a glyph by name.  This is
  * currently a linear search as there doesn't appear to be
@@ -2354,11 +2394,11 @@ static FT_UInt
 FcFreeTypeGlyphNameIndex (FT_Face face, const FcChar8 *name)
 {
     FT_UInt gindex;
-    FcChar8 name_buf[FC_GLYPHNAME_MAXLEN + 2];
+    FcChar8 name_buf[FC_GLYPHNAME_BUFLEN + 2];
 
     for (gindex = 0; gindex < (FT_UInt) face->num_glyphs; gindex++)
     {
-       if (FT_Get_Glyph_Name (face, gindex, name_buf, FC_GLYPHNAME_MAXLEN+1) == 0)
+       if (FT_Get_Glyph_Name (face, gindex, name_buf, FC_GLYPHNAME_BUFLEN+1) == 0)
            if (!strcmp ((char *) name, (char *) name_buf))
                return gindex;
     }
@@ -2648,11 +2688,11 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
      */
     if (FcFreeTypeUseNames (face))
     {
-       FcChar8 name_buf[FC_GLYPHNAME_MAXLEN + 2];
+       FcChar8 name_buf[FC_GLYPHNAME_BUFLEN + 2];
 
        for (glyph = 0; glyph < (FT_UInt) face->num_glyphs; glyph++)
        {
-           if (FT_Get_Glyph_Name (face, glyph, name_buf, FC_GLYPHNAME_MAXLEN+1) == 0)
+           if (FT_Get_Glyph_Name (face, glyph, name_buf, FC_GLYPHNAME_BUFLEN+1) == 0)
            {
                ucs4 = FcGlyphNameToUcs4 (name_buf);
                if (ucs4 != 0xffff &&