hi I noticed that the fc-cache utility does not support SFNT ttf(or otf) format well. It will output a fonts.cache-1 file with wrong font information. The specific sfnt font I tested is WenQuanYi''s bitmap CJK font, which is generated with fontforge, and can be download here http://prdownloads.sourceforge.net/wqy/wqy-bitmapfont-ttf-0.7.0-4.tar.gz?download If I create fonts.cache-1 manually with hand-written font information, "fc-cache -f" will overwrite it with erroneous info. I found a couple of Sfnt calls from fcfreetype.c unit, seems it is designed to support this format. I am wondering if anyone can give me some insight on what might cause the failure of recognition of wenquanyi''s font. meanwhile, in fc-cache.c, I don''t know if it possible to add a skipping flag under "-f" option, for example, if fc-cache finds a file named fonts.cache-forceskip under the current directory, it will skip this font folder under any condition. I think this might be helpful if font developers want to put some specific settings and don''t want system to overwrite. thanks Qianqian
mpsuzuki@hiroshima-u.ac.jp
2006-Aug-21 00:06 UTC
[Fontconfig] SFNT TTF support in fontconfig
Hi, On Sat, 19 Aug 2006 12:51:29 -0400 "Qianqian Fang" <fangq@nmr.mgh.harvard.edu> wrote:>I noticed that the fc-cache utility does not support SFNT ttf(or otf) >format well. It will output a fonts.cache-1 file with wrong font information.I guess fontconfig is designed for outline font, and bitmap-only fonts are left in the cold.>http://prdownloads.sourceforge.net/wqy/wqy-bitmapfont-ttf-0.7.0-4.tar.gz?downloadAs the name tells, WQY fonts include collection of bitmap fonts for 12/13/15/16 pixels, and its glyf table includes single glyph only (for undefined character). If you built fontconfig-2.2.3 with additional "-DCHECK" CFLAGS and run fc-cache with debug environment variable (e.g. FC_DEBUG=9999), you will receive following result: Scanning file cjk-bitmap/wqy-bsong.ttf..."WenQuanYi Bitmap Song" "medium" TT_Load_Simple_Glyph: Too many instructions! 0x0000000d FT says 1 FC says 0 0x00000021 FT says 1 FC says 0 0x00000022 FT says 1 FC says 0 [snip] 0x0000ffe3 FT says 1 FC says 0 0x0000ffe5 FT says 1 FC says 0 33987 glyphs 4 encoded Bitmap missing char 0xd [snip] Bitmap missing char 0x2fd5 done caching, 1 fonts, 0 dirs "0x0000000d FT says 1 FC says 0" means that FreeType2 can load glyph for UCS2 codepoint 0x000d, but fontconfig ignores it. The line generating "0x00000022 FT says 1 FC says 0" is here: fcfreetype.c 1704 #ifdef CHECK 1705 for (ucs4 = 0; ucs4 < 0x10000; ucs4++) 1706 { 1707 FcBool FT_Has, FC_Has; 1708 1709 FT_Has = FT_Get_Char_Index (face, ucs4) != 0; 1710 FC_Has = FcCharSetHasChar (fcs, ucs4); 1711 if (FT_Has != FC_Has) 1712 { 1713 printf ("0x%08x FT says %d FC says %d\n", ucs4, FT_Has, FC_Has); 1714 } 1715 } 1716 #endif FT_Get_Char_Index() returns glyphID for given charcode, but it does not care about outline or bitmap. Therefore, "FT_Has" means if the font has anything to render "ucs4" (outline or bitmap). On the other hand, FcCharSetHasChar() checks whether given charcode is registered in fontconfig''s charset database "fcs". Yes, you can remind "charset=" entry in fonts.cache-1. Where "fcs" comes from? Check FcFreeTypeCharSetAndSpacing(). 1592 FcCharSet * 1593 FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing) 1594 { ... 1668 while (gindex) 1669 { 1670 page = ucs4 >> 8; 1671 leaf = 0; 1672 while ((ucs4 >> 8) == page) 1673 { 1674 glyph = FT_Get_Char_Index (face, ucs4); 1675 if (glyph && FcFreeTypeCheckGlyph (face, ucs4, 1676 glyph, blanks, &advance)) ... What FcFreeTypeCharSetAndSpacing() does? fcfreetype.c 1537 FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4, 1538 FT_UInt glyph, FcBlanks *blanks, 1539 FT_Pos *advance) 1540 { 1541 FT_Int load_flags = FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; 1542 FT_GlyphSlot slot; 1543 1544 /* 1545 * When using scalable fonts, only report those glyphs 1546 * which can be scaled; otherwise those fonts will 1547 * only be available at some sizes, and never when 1548 * transformed. Avoid this by simply reporting bitmap-only 1549 * glyphs as missing 1550 */ 1551 if (face->face_flags & FT_FACE_FLAG_SCALABLE) 1552 load_flags |= FT_LOAD_NO_BITMAP; Here is the important part. face->face_flags is set by FreeType2 to notice the information about font, the detail of flags are found at: http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FACE_FLAG_XXX You can find that FT_FACE_FLAG_SCALABLE means that the font includes vector glyph data (with no care about how many). Since WQY font has glyf table, the condition at #1551 is true. Then, load_cflags is set to ignore included bitmap data. Why? The reason is noted in above. The fontconfig designer wanted to avoid following scenario: 1. fontconfig make fc-charset info as superset of outline & bitmap data. 2. application expects as all character in fc-charset were scalable. 3. application tries to load a glyph image at arbitrary pixel size, but the font does not include vector data for the glyph and application is forced to use "scaled bitmap" which looks ugly. I''m trying to remove glyf table from WQY and notice to fontconfig that WQY is not "scalable", but not success yet. Regards, mpsuzuki
mpsuzuki@hiroshima-u.ac.jp
2006-Aug-31 20:26 UTC
[Fontconfig] Support of bitmap-only TTF (Re: SFNT TTF support in fontconfig)
Hi, I suppose the request of additional work for bitmap-only TTF is too late, here I wrote a patch to scan a strike instead of glyf table (specified by setting environmental variable FC_BITMAP_SIZE), by hooking FcFreeTypeCheckGlyph(). Although I wrote for obsolete fontconfig-2.2.3, but I suppose it can be applicable to latest fontconfig. By this patch, bitmap-only TTF can be recognized by fontconfig, but registered as scalable font, so there would be troubles in the applications who ignores bitmap glyph data. There''s any better expression in database for such bitmap- only TTF in fontconfig database? For a font format including single strike, fontconfig works well, but I''m not sure about a font including multiple strike. BTW, I wish if FcFreeTypeCheckGlyph() is exposed as public symbol. If I could override the function by LD_PRELOAD, more user-defined checking can be implemented easily. Usage ----- When environmental variable is set as FC_BITMAP_SIZE="12,14,0,16,18", fc-cache lookups 12pixel strike for first. If the font provide it, fc-cache checks the glyph availability by glyph data by 12pixel strike. If the font has no 12pixel strike, fc-cache lookups 14pixel in next. If the font has no 12/14pixel strikes, fc-cache lookups vector data in next. If the font has no 12/14pixel strike or vector data, fc-cache lookups 16pixel strike in next... At present, no cross-checking of glyph availablity among each strike and vector data is implemented. diff -Burb fontconfig-2.2.3.orig/src/fcfreetype.c fontconfig-2.2.3/src/fcfreetype.c --- fontconfig-2.2.3.orig/src/fcfreetype.c Tue Aug 22 12:26:07 2006 +++ fontconfig-2.2.3/src/fcfreetype.c Wed Aug 23 12:02:38 2006 @@ -1538,8 +1538,53 @@ FT_UInt glyph, FcBlanks *blanks, FT_Pos *advance) { - FT_Int load_flags = FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + FT_Int load_flags = FT_LOAD_NO_HINTING; FT_GlyphSlot slot; + char *s0, *s1; + FT_Int bitmap_size = -1; + + + s0 = getenv( "FC_BITMAP_SIZE" ); + /* lookup strike_index for given bitmap pixel size */ + while ( s0 != NULL && ''\0'' != s0[0] ) + { + bitmap_size = strtol( s0, &s1, 10 ); + if ( 0 == bitmap_size && 0 != ( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) + { + load_flags |= ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ); + goto verify_loading; + } + else if ( LONG_MIN != bitmap_size && LONG_MAX != bitmap_size ) + { +#ifdef HAVE_FT_SELECT_SIZE + int i; + for ( i = 0; i < face->num_fixed_sizes; i++ ) + { + if ( bitmap_size == face->available_sizes[i].height ) + { + if ( FT_Err_Ok == FT_Select_Size( face, i ) ) + goto verify_loading; + } + } +#else + /* + * XXX: DANGER HOOK FOR LEGACY FREETYPE-2.1.X + * To check the exist of bitmap glyph at specified size + * switch FT_FACE_FLAG_SCALABLE off forcibly. As a result, + * FT_Set_Pixel_Sizes() cannot use outline glyph for fallback. + */ + FT_Error status; + FT_Long orig_face_flags = face->face_flags; + face->face_flags = face->face_flags ^ FT_FACE_FLAG_SCALABLE ; + status = FT_Set_Pixel_Sizes( face, bitmap_size, bitmap_size ) ; + face->face_flags = orig_face_flags ; + if ( FT_Err_Ok == status ) + goto verify_loading; +#endif + } + s0 = strpbrk( s1, "0123456789" ); + } + load_flags |= FT_LOAD_NO_SCALE; /* * When using scalable fonts, only report those glyphs @@ -1551,6 +1596,7 @@ if (face->face_flags & FT_FACE_FLAG_SCALABLE) load_flags |= FT_LOAD_NO_BITMAP; +verify_loading: if (FT_Load_Glyph (face, glyph, load_flags)) return FcFalse; @@ -1569,6 +1615,12 @@ */ return FcTrue; case ft_glyph_format_outline: + /* + * Exclude fallback outline data when we tried to + * load bitmap data. + */ + if ( 0 == ( load_flags & FT_LOAD_NO_SCALE ) ) + return FcFalse; /* * Glyphs with contours are always OK */ On Mon, 21 Aug 2006 15:59:37 +0900 mpsuzuki@hiroshima-u.ac.jp wrote:>Hi, > >On Sat, 19 Aug 2006 12:51:29 -0400 >"Qianqian Fang" <fangq@nmr.mgh.harvard.edu> wrote: >>I noticed that the fc-cache utility does not support SFNT ttf(or otf) >>format well. It will output a fonts.cache-1 file with wrong font information. > >I guess fontconfig is designed for outline font, and bitmap-only >fonts are left in the cold. > >>http://prdownloads.sourceforge.net/wqy/wqy-bitmapfont-ttf-0.7.0-4.tar.gz?download > >As the name tells, WQY fonts include collection of bitmap fonts >for 12/13/15/16 pixels, and its glyf table includes single glyph >only (for undefined character). > >If you built fontconfig-2.2.3 with additional "-DCHECK" CFLAGS and >run fc-cache with debug environment variable (e.g. FC_DEBUG=9999), >you will receive following result: > > Scanning file cjk-bitmap/wqy-bsong.ttf..."WenQuanYi Bitmap Song" "medium" TT_Load_Simple_Glyph: Too many instructions! > 0x0000000d FT says 1 FC says 0 > 0x00000021 FT says 1 FC says 0 > 0x00000022 FT says 1 FC says 0 > > [snip] > > 0x0000ffe3 FT says 1 FC says 0 > 0x0000ffe5 FT says 1 FC says 0 > 33987 glyphs 4 encoded > Bitmap missing char 0xd > > [snip] > > Bitmap missing char 0x2fd5 > done > caching, 1 fonts, 0 dirs > >"0x0000000d FT says 1 FC says 0" means that FreeType2 can load >glyph for UCS2 codepoint 0x000d, but fontconfig ignores it. > >The line generating "0x00000022 FT says 1 FC says 0" is here: >fcfreetype.c > 1704 #ifdef CHECK > 1705 for (ucs4 = 0; ucs4 < 0x10000; ucs4++) > 1706 { > 1707 FcBool FT_Has, FC_Has; > 1708 > 1709 FT_Has = FT_Get_Char_Index (face, ucs4) != 0; > 1710 FC_Has = FcCharSetHasChar (fcs, ucs4); > 1711 if (FT_Has != FC_Has) > 1712 { > 1713 printf ("0x%08x FT says %d FC says %d\n", ucs4, FT_Has, FC_Has); > 1714 } > 1715 } > 1716 #endif > >FT_Get_Char_Index() returns glyphID for given charcode, but it >does not care about outline or bitmap. Therefore, "FT_Has" means >if the font has anything to render "ucs4" (outline or bitmap). > >On the other hand, FcCharSetHasChar() checks whether given charcode >is registered in fontconfig''s charset database "fcs". Yes, you >can remind "charset=" entry in fonts.cache-1. > >Where "fcs" comes from? Check FcFreeTypeCharSetAndSpacing(). > > 1592 FcCharSet * > 1593 FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing) > 1594 { > > ... > > 1668 while (gindex) > 1669 { > 1670 page = ucs4 >> 8; > 1671 leaf = 0; > 1672 while ((ucs4 >> 8) == page) > 1673 { > 1674 glyph = FT_Get_Char_Index (face, ucs4); > 1675 if (glyph && FcFreeTypeCheckGlyph (face, ucs4, > 1676 glyph, blanks, &advance)) > > ... > >What FcFreeTypeCharSetAndSpacing() does? > >fcfreetype.c > 1537 FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4, > 1538 FT_UInt glyph, FcBlanks *blanks, > 1539 FT_Pos *advance) > 1540 { > 1541 FT_Int load_flags = FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; > 1542 FT_GlyphSlot slot; > 1543 > 1544 /* > 1545 * When using scalable fonts, only report those glyphs > 1546 * which can be scaled; otherwise those fonts will > 1547 * only be available at some sizes, and never when > 1548 * transformed. Avoid this by simply reporting bitmap-only > 1549 * glyphs as missing > 1550 */ > 1551 if (face->face_flags & FT_FACE_FLAG_SCALABLE) > 1552 load_flags |= FT_LOAD_NO_BITMAP; > >Here is the important part. face->face_flags is set by FreeType2 >to notice the information about font, the detail of flags are found >at: > > http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FACE_FLAG_XXX > >You can find that FT_FACE_FLAG_SCALABLE means that the font includes >vector glyph data (with no care about how many). Since WQY font has >glyf table, the condition at #1551 is true. Then, load_cflags is >set to ignore included bitmap data. Why? The reason is noted in above. >The fontconfig designer wanted to avoid following scenario: > >1. fontconfig make fc-charset info as superset of outline & bitmap data. > >2. application expects as all character in fc-charset were scalable. > >3. application tries to load a glyph image at arbitrary pixel size, > but the font does not include vector data for the glyph and > application is forced to use "scaled bitmap" which looks ugly. > >I''m trying to remove glyf table from WQY and notice to fontconfig >that WQY is not "scalable", but not success yet. > >Regards, >mpsuzuki >_______________________________________________ >Fontconfig mailing list >Fontconfig@lists.freedesktop.org >http://lists.freedesktop.org/mailman/listinfo/fontconfig
Keith Packard
2006-Aug-31 22:32 UTC
[Fontconfig] Support of bitmap-only TTF (Re: SFNT TTF support in fontconfig)
On Fri, 2006-09-01 at 12:25 +0900, mpsuzuki@hiroshima-u.ac.jp wrote:> Hi, > > I suppose the request of additional work for bitmap-only > TTF is too late, here I wrote a patch to scan a strike > instead of glyf tableWe''ve got a BDF->TTF font converter that generates bitmap-only TTFs, and those work fine with fontconfig. What fonts are you having trouble with here? -- keith.packard@intel.com -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part Url : http://lists.freedesktop.org/archives/fontconfig/attachments/20060831/c6957a16/attachment-0001.pgp