diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc index 4657c07..0e754fe 100644 --- a/poppler/GlobalParams.cc +++ b/poppler/GlobalParams.cc @@ -103,6 +103,12 @@ extern XpdfPluginVecTable xpdfPluginVecTable; # endif #endif +#if WITH_FONTCONFIGURATION_FONTCONFIG && HAVE_FREETYPE_H +#include +#include FT_FREETYPE_H +#include FT_TRUETYPE_TABLES_H +#endif + //------------------------------------------------------------------------ #define cidToUnicodeCacheSize 4 @@ -1184,7 +1190,7 @@ DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) { char * ext; FcResult res; FcFontSet *set; - int i; + int i, j; p = buildFcPattern(font); if (!p) @@ -1194,29 +1200,77 @@ DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) { set = FcFontSort(NULL, p, FcFalse, NULL, &res); if (!set) goto fin; - for (i = 0; i < set->nfont; ++i) + + /* scan twice the candidates: */ + /* 1st scan: considering serif style */ + /* 2nd scan: ignoring serif style (1st scan cannot be resolved) */ + for (j = 0; j < 2; ++j) { - res = FcPatternGetString(set->fonts[i], FC_FILE, 0, &s); - if (res != FcResultMatch || !s) + FT_Library ft_lib = NULL; + FT_Face ft_face = NULL; + if ( j || FT_Init_FreeType( &ft_lib ) ) continue; - ext = strrchr((char*)s,'.'); - if (!ext) - continue; - if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4)) - { - dfp = new DisplayFontParam(fontName->copy(), displayFontTT); - dfp->tt.fileName = new GooString((char*)s); - FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, &(dfp->tt.faceIndex)); - } - else if (!strncasecmp(ext,".pfa",4) || !strncasecmp(ext,".pfb",4)) + + for (i = 0; i < set->nfont; ++i) { - dfp = new DisplayFontParam(fontName->copy(), displayFontT1); - dfp->t1.fileName = new GooString((char*)s); + res = FcPatternGetString(set->fonts[i], FC_FILE, 0, &s); + if (res != FcResultMatch || !s) + continue; + ext = strrchr((char*)s,'.'); + + /* XXX: MacOS suitcase font without extension should be supported? */ + if (!ext) + continue; + + /* XXX: MacOS .dfont should be supported? */ + if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4)) + { + int face_idx = 0; + bool found_ttf = false; + + FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, &face_idx); + + if ( j ) + found_ttf = true; + else if ( ft_lib && !FT_New_Face( ft_lib, (const char*)s, face_idx, &ft_face ) ) + { + TT_OS2* ft_os2 = (TT_OS2*)FT_Get_Sfnt_Table( ft_face, ft_sfnt_os2 ); + if ( ft_os2 ) + { + fprintf( stderr, "serif=%d font[%d]/%d: %s panose[0]=%d panose[1]=%d\n", + font->isSerif() ? 1 : 0, + i, set->nfont, + s, + ft_os2->panose[0], + ft_os2->panose[1] ); + if ( font->isSerif() && ft_os2->panose[0] == 2 && 1 < ft_os2->panose[1] && ft_os2->panose[1] < 11 ) + found_ttf = true; + if ( !font->isSerif() && ft_os2->panose[0] == 2 && 10 < ft_os2->panose[1] ) + found_ttf = true; + /* XXX IBM family class matching is expected */ + FT_Done_Face( ft_face ); + } + } + + if ( !found_ttf ) + continue; + + dfp = new DisplayFontParam(fontName->copy(), displayFontTT); + dfp->tt.fileName = new GooString((char*)s); + dfp->tt.faceIndex = face_idx; + } + else if (j && ( !strncasecmp(ext,".pfa",4) || !strncasecmp(ext,".pfb",4)) ) + { + dfp = new DisplayFontParam(fontName->copy(), displayFontT1); + dfp->t1.fileName = new GooString((char*)s); + } + else + continue; + font->dfp = dfp; + break; } - else - continue; - font->dfp = dfp; - break; + if (ft_lib) + FT_Done_FreeType(ft_lib); } FcFontSetDestroy(set); }