]> git.wh0rd.org - fontconfig.git/commitdiff
Work around for bitmap-only TrueType fonts that are missing the glyf table.
authorKeith Packard <keithp@keithp.com>
Sun, 4 May 2008 00:19:43 +0000 (17:19 -0700)
committerKeith Packard <keithp@keithp.com>
Sun, 4 May 2008 00:20:34 +0000 (17:20 -0700)
Bitmap-only TrueType fonts without a glyf table will not load a glyph when
FT_LOAD_NO_SCALE is set. Work around this by identifying TrueType fonts that have no
glyphs and select a single strike to measure the glyph map with.

src/fcfreetype.c

index c5d5251d9a6d87e9060463f409499a4725a6db8a..0612c17398c6a83bc29ce58d49d0b0b5fce9c0f0 100644 (file)
@@ -2501,11 +2501,15 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4)
 static FcBool
 FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4, 
                      FT_UInt glyph, FcBlanks *blanks,
-                     FT_Pos *advance)
+                     FT_Pos *advance,
+                     FcBool using_strike)
 {
     FT_Int         load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
     FT_GlyphSlot    slot;
     
+    if (using_strike)
+       load_flags &= ~FT_LOAD_NO_SCALE;
+
     /*
      * When using scalable fonts, only report those glyphs
      * which can be scaled; otherwise those fonts will
@@ -2559,8 +2563,8 @@ FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4,
 #define FC_ABS(a)   ((a) < 0 ? -(a) : (a))
 #define APPROXIMATELY_EQUAL(x,y) (FC_ABS ((x) - (y)) <= FC_MAX (FC_ABS (x), FC_ABS (y)) / 33)
 
-FcCharSet *
-FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
+static FcCharSet *
+FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing, FT_Int strike_index)
 {
     FcChar32       page, off, ucs4;
 #ifdef CHECK
@@ -2574,11 +2578,18 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
     FT_UInt        glyph;
     FT_Pos         advance, advance_one = 0, advance_two = 0;
     FcBool         has_advance = FcFalse, fixed_advance = FcTrue, dual_advance = FcFalse;
+    FcBool         using_strike = FcFalse;
 
     fcs = FcCharSetCreate ();
     if (!fcs)
        goto bail0;
     
+    if (strike_index >= 0) {
+       if (FT_Select_Size (face, strike_index) != FT_Err_Ok)
+           goto bail1;
+       using_strike = FcTrue;
+    }
+
 #ifdef CHECK
     printf ("Family %s style %s\n", face->family_name, face->style_name);
 #endif
@@ -2598,7 +2609,7 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
                ucs4 = map->ent[i].bmp;
                glyph = FT_Get_Char_Index (face, map->ent[i].encode);
                if (glyph && 
-                   FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
+                   FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
                {
                    /* 
                     * ignore glyphs with zero advance. They’re
@@ -2646,7 +2657,7 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
             ucs4 = FT_Get_First_Char (face, &glyph);
             while (glyph != 0)
            {
-               if (FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
+               if (FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
                {
                    if (advance)
                    {
@@ -2713,7 +2724,7 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
            {
                ucs4 = FcGlyphNameToUcs4 (name_buf);
                if (ucs4 != 0xffff && 
-                   FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
+                   FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
                {
                    if (advance)
                    {
@@ -2756,7 +2767,7 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
 
        if (has_char && !has_bit)
        {
-           if (!FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
+           if (!FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
                printf ("Bitmap missing broken char 0x%x\n", ucs4);
            else
                printf ("Bitmap missing char 0x%x\n", ucs4);
@@ -2778,6 +2789,39 @@ bail0:
     return 0;
 }
 
+FcCharSet *
+FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
+{
+    FcCharSet  *cs;
+    
+    cs = FcFreeTypeCharSetAndSpacingForSize (face, blanks, spacing, -1);
+    /*
+     * Check for bitmap-only ttf fonts that are missing the glyf table.
+     * In that case, pick a size and look for glyphs in that size instead
+     */
+    if (FcCharSetCount (cs) == 0) 
+    {
+       /* Check for non-scalable TT fonts */
+       if (!(face->face_flags & FT_FACE_FLAG_SCALABLE) &&
+           face->num_fixed_sizes > 0 &&
+           FT_Get_Sfnt_Table (face, ft_sfnt_head))
+       {
+           FT_Int  strike_index = 0;
+           int     i;
+
+           /* Select the face closest to 16 pixels tall */
+           for (i = 1; i < face->num_fixed_sizes; i++) {
+               if (abs (face->available_sizes[i].height - 16) < 
+                   abs (face->available_sizes[strike_index].height - 16))
+                   strike_index = i;
+           }
+           FcCharSetDestroy (cs);
+           cs = FcFreeTypeCharSetAndSpacingForSize (face, blanks, spacing, strike_index);
+       }
+    }
+    return cs;
+}
+
 FcCharSet *
 FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
 {