src/fcdir.c | 40 +++++++++++++++++++++++++---- src/fcfreetype.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 102 insertions(+), 12 deletions(-) New commits: commit 27d61f1ddcda5543e9c6440a0f8794caa0b1eac7 Author: Behdad Esfahbod <behdad@xxxxxxxxxx> Date: Sun Aug 9 00:59:31 2015 +0200 [GX] Enumerate all named-instances in TrueType GX fonts diff --git a/src/fcdir.c b/src/fcdir.c index 40d8071..81c98b6 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -72,14 +72,16 @@ FcFileScanFontConfig (FcFontSet *set, FT_Face face; FcPattern *font; FcBool ret = FcTrue; - int id; int num_faces = 0; + int num_instances = 0; + int face_num = 0; + int instance_num = 0; + int id; const FcChar8 *sysroot = FcConfigGetSysRoot (config); if (FT_Init_FreeType (&ftLibrary)) return FcFalse; - id = 0; do { font = 0; @@ -92,9 +94,11 @@ FcFileScanFontConfig (FcFontSet *set, fflush (stdout); } + id = ((instance_num << 16) + face_num); if (FT_New_Face (ftLibrary, (char *) file, id, &face)) return FcFalse; num_faces = face->num_faces; + num_instances = face->style_flags >> 16; font = FcFreeTypeQueryFace (face, file, id, blanks); FT_Done_Face (face); @@ -152,8 +156,15 @@ FcFileScanFontConfig (FcFontSet *set, } else ret = FcFalse; - id++; - } while (font && ret && id < num_faces); + + if (instance_num < num_instances) + instance_num++; + else + { + face_num++; + instance_num = 0; + } + } while (font && ret && face_num < num_faces); FT_Done_FreeType (ftLibrary); commit 00c8408c6a82a79388f8119c4afce6e721b693f7 Author: Behdad Esfahbod <behdad@xxxxxxxxxx> Date: Sun Aug 9 09:06:37 2015 +0200 [GX] Support instance weight, width, and style name diff --git a/src/fcfreetype.c b/src/fcfreetype.c index 73c8809..b63e630 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -62,6 +62,7 @@ #include FT_BDF_H #include FT_MODULE_H #endif +#include FT_MULTIPLE_MASTERS_H #include "ftglue.h" @@ -1172,6 +1173,13 @@ FcFreeTypeQueryFace (const FT_Face face, FcChar8 *complex_, *foundry_ = NULL; const FcChar8 *foundry = 0; int spacing; + + /* Support for glyph-variation named-instances. */ + FT_MM_Var *master = NULL; + FT_Var_Named_Style *instance = NULL; + double weight_mult = 1.0; + double width_mult = 1.0; + TT_OS2 *os2; #if HAVE_FT_GET_PS_FONT_INFO PS_FontInfoRec psfontinfo; @@ -1231,6 +1239,35 @@ FcFreeTypeQueryFace (const FT_Face face, goto bail1; } + if (id >> 16) + { + if (!FT_Get_MM_Var (face, &master)) + instance = &master->namedstyle[(id >> 16) - 1]; + + if (instance) + { + /* Pull out weight and width from named-instance. */ + unsigned int i; + + for (i = 0; i < master->num_axis; i++) + { + double value = instance->coords[i] / (double) (1 << 16); + //printf ("named-instance, axis %d tag %lx value %g\n", i, master->axis[i].tag, value); + switch (master->axis[i].tag) + { + case FT_MAKE_TAG ('w','g','h','t'): + weight_mult = value; + break; + + case FT_MAKE_TAG ('w','d','t','h'): + width_mult = value; + break; + + /* TODO optical size! */ + } + } + } + } /* * Get the OS/2 table @@ -1289,6 +1326,19 @@ FcFreeTypeQueryFace (const FT_Face face, if (FT_Get_Sfnt_Name (face, snamei, &sname) != 0) continue; + + if (instance) + { + /* For named-instances, we regular style nameIDs, + * and map the instance's strid to FONT_SUBFAMILY. */ + if (sname.name_id == TT_NAME_ID_WWS_SUBFAMILY || + sname.name_id == TT_NAME_ID_PREFERRED_SUBFAMILY || + sname.name_id == TT_NAME_ID_FONT_SUBFAMILY) + continue; + if (sname.name_id == instance->strid) + sname.name_id = TT_NAME_ID_FONT_SUBFAMILY; + } + if (sname.name_id != nameid) continue; @@ -1428,6 +1478,8 @@ FcFreeTypeQueryFace (const FT_Face face, printf ("using FreeType family \"%s\"\n", face->family_name); if (!FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) face->family_name)) goto bail1; + if (!FcPatternAddString (pat, FC_STYLELANG, (FcChar8 *) "en")) + goto bail1; ++nfamily; } @@ -1438,6 +1490,8 @@ FcFreeTypeQueryFace (const FT_Face face, printf ("using FreeType style \"%s\"\n", face->style_name); if (!FcPatternAddString (pat, FC_STYLE, (FcChar8 *) face->style_name)) goto bail1; + if (!FcPatternAddString (pat, FC_STYLELANG, (FcChar8 *) "en")) + goto bail1; ++nstyle; } @@ -1583,12 +1637,15 @@ FcFreeTypeQueryFace (const FT_Face face, if (os2 && os2->version != 0xffff) { - weight = FcWeightFromOpenType (os2->usWeightClass); + weight = FcWeightFromOpenType ((int) (os2->usWeightClass * weight_mult + .5)); if ((FcDebug() & FC_DBG_SCANV) && weight != -1) - printf ("\tos2 weight class %d maps to weight %d\n", - os2->usWeightClass, weight); + printf ("\tos2 weight class %d multiplier %g maps to weight %d\n", + os2->usWeightClass, weight_mult, weight); - switch (os2->usWidthClass) { + /* TODO: + * Add FcWidthFromOpenType and FcWidthToOpenType, + * and apply width_mult post-conversion? */ + switch ((int) (os2->usWidthClass * width_mult + .5)) { case 1: width = FC_WIDTH_ULTRACONDENSED; break; case 2: width = FC_WIDTH_EXTRACONDENSED; break; case 3: width = FC_WIDTH_CONDENSED; break; @@ -1600,8 +1657,8 @@ FcFreeTypeQueryFace (const FT_Face face, case 9: width = FC_WIDTH_ULTRAEXPANDED; break; } if ((FcDebug() & FC_DBG_SCANV) && width != -1) - printf ("\tos2 width class %d maps to width %d\n", - os2->usWidthClass, width); + printf ("\tos2 width class %d multiplier %g maps to width %d\n", + os2->usWidthClass, width_mult, width); } if (os2 && (complex_ = FcFontCapabilities(face))) { @@ -1881,6 +1938,11 @@ FcFreeTypeQueryFace (const FT_Face face, if (foundry_) free (foundry_); + if (master) + { + /* TODO: How to free master?! */ + } + return pat; bail2: commit 28f62d1bb892e1c86eb0d5afaf125bfe0e34cbe9 Author: Behdad Esfahbod <behdad@xxxxxxxxxx> Date: Sun Aug 9 00:45:01 2015 +0200 Call FcFreeTypeQueryFace() from fcdir.c, instead of FcFreeTypeQuery() Need for upcoming work. No functional change expected. diff --git a/src/fcdir.c b/src/fcdir.c index a046eae..40d8071 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -23,6 +23,9 @@ */ #include "fcint.h" +#include "fcftint.h" +#include <ft2build.h> +#include FT_FREETYPE_H #include <dirent.h> FcBool @@ -65,12 +68,17 @@ FcFileScanFontConfig (FcFontSet *set, const FcChar8 *file, FcConfig *config) { + FT_Library ftLibrary; + FT_Face face; FcPattern *font; FcBool ret = FcTrue; int id; - int count = 0; + int num_faces = 0; const FcChar8 *sysroot = FcConfigGetSysRoot (config); + if (FT_Init_FreeType (&ftLibrary)) + return FcFalse; + id = 0; do { @@ -83,14 +91,20 @@ FcFileScanFontConfig (FcFontSet *set, printf ("\tScanning file %s...", file); fflush (stdout); } - font = FcFreeTypeQuery (file, id, blanks, &count); + + if (FT_New_Face (ftLibrary, (char *) file, id, &face)) + return FcFalse; + num_faces = face->num_faces; + font = FcFreeTypeQueryFace (face, file, id, blanks); + FT_Done_Face (face); + if (FcDebug () & FC_DBG_SCAN) printf ("done\n"); /* * Get rid of sysroot here so that targeting scan rule may contains FC_FILE pattern * and they should usually expect without sysroot. */ - if (sysroot) + if (font && sysroot) { size_t len = strlen ((const char *)sysroot); FcChar8 *f = NULL; @@ -139,7 +153,10 @@ FcFileScanFontConfig (FcFontSet *set, else ret = FcFalse; id++; - } while (font && ret && id < count); + } while (font && ret && id < num_faces); + + FT_Done_FreeType (ftLibrary); + return ret; } _______________________________________________ Fontconfig mailing list Fontconfig@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/fontconfig