diff options
author | Akira TAGOH <akira@tagoh.org> | 2013-09-18 18:55:53 +0900 |
---|---|---|
committer | Akira TAGOH <akira@tagoh.org> | 2017-07-11 15:39:55 +0900 |
commit | a1f249360b76526a801df7213497c960a9c969fe (patch) | |
tree | 1d498e68a82f7eb36d8c0bb77cb94cd1cf23b3d2 | |
parent | 5b6af242e1eb0a6456fe9ab9a99efa3ba42f83c6 (diff) |
Add familyclass object to categorize against sFamilyClass and Panose.
https://bugs.freedesktop.org/show_bug.cgi?id=29497
-rw-r--r-- | conf.d/48-familyclass.conf | 21 | ||||
-rw-r--r-- | fontconfig/fontconfig.h | 1 | ||||
-rw-r--r-- | fonts.conf.in | 36 | ||||
-rw-r--r-- | src/fcfreetype.c | 133 | ||||
-rw-r--r-- | src/fcmatch.c | 2 | ||||
-rw-r--r-- | src/fcobjs.h | 1 |
6 files changed, 192 insertions, 2 deletions
diff --git a/conf.d/48-familyclass.conf b/conf.d/48-familyclass.conf new file mode 100644 index 00000000..d5782f7a --- /dev/null +++ b/conf.d/48-familyclass.conf @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!DOCTYPE fontconfig SYSTEM "fonts.dtd"> +<fontconfig> + <match target="pattern"> + <test qual="all" name="familyclass" compare="not_eq"> + <string></string> + </test> + <test qual="all" name="family" compare="not_eq"> + <string>sans-serif</string> + </test> + <test qual="all" name="family" compare="not_eq"> + <string>serif</string> + </test> + <test qual="all" name="family" compare="not_eq"> + <string>monospace</string> + </test> + <edit name="family" mode="append_last"> + <name>familyclass</name> + </edit> + </match> +</fontconfig> diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index 00ab409e..2e050db7 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -123,6 +123,7 @@ typedef int FcBool; #define FC_PRGNAME "prgname" /* String */ #define FC_HASH "hash" /* String (deprecated) */ #define FC_POSTSCRIPT_NAME "postscriptname" /* String */ +#define FC_FAMILY_CLASS "familyclass" /* String */ #define FC_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION #define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION diff --git a/fonts.conf.in b/fonts.conf.in index 7c16a707..dd06b849 100644 --- a/fonts.conf.in +++ b/fonts.conf.in @@ -66,6 +66,42 @@ </match> <!-- + Accept deprecated 'mono' alias, replacing it with 'monospace' +--> + <match target="pattern"> + <test qual="any" name="familyclass"> + <string>mono</string> + </test> + <edit name="familyclass" mode="assign" binding="same"> + <string>monospace</string> + </edit> + </match> + +<!-- + Accept alternate 'sans serif' spelling, replacing it with 'sans-serif' +--> + <match target="pattern"> + <test qual="any" name="familyclass"> + <string>sans serif</string> + </test> + <edit name="familyclass" mode="assign" binding="same"> + <string>sans-serif</string> + </edit> + </match> + +<!-- + Accept deprecated 'sans' alias, replacing it with 'sans-serif' +--> + <match target="pattern"> + <test qual="any" name="familyclass"> + <string>sans</string> + </test> + <edit name="familyclass" mode="assign" binding="same"> + <string>sans-serif</string> + </edit> + </match> + +<!-- Load local system customization file --> <include ignore_missing="yes">@CONFIGDIR@</include> diff --git a/src/fcfreetype.c b/src/fcfreetype.c index b4d926d4..46999748 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -1164,7 +1164,7 @@ FcFreeTypeQueryFace (const FT_Face face, int weight = -1; int width = -1; FcBool decorative = FcFalse; - int i; + int i, j; FcCharSet *cs; FcLangSet *ls; #if 0 @@ -1207,7 +1207,18 @@ FcFreeTypeQueryFace (const FT_Face face, const char *tmp; FcRange *r = NULL; - + const char *fclass[16] = { "", "sans-serif", "serif", "monospace", "cursive", "fantasy" }; + int fclass_bits = 0; + FcChar8 *fcls; + enum _fc_fclass { + FC_FCLASS_UNKNOWN = 0, + FC_FCLASS_SANS = 1 << 0, + FC_FCLASS_SERIF = 1 << 1, + FC_FCLASS_MONO = 1 << 2, + FC_FCLASS_CURSIVE = 1 << 3, + FC_FCLASS_FANTASY = 1 << 4, + FC_FCLASS_END + }; FcBool symbol = FcFalse; FcInitDebug (); /* We might be called with no initizalization whatsoever. */ @@ -1276,6 +1287,109 @@ FcFreeTypeQueryFace (const FT_Face face, */ os2 = (TT_OS2 *) FT_Get_Sfnt_Table (face, ft_sfnt_os2); + if (os2) + { + FT_Byte cls_id, subcls_id; + + /* See http://www.microsoft.com/typography/otspec/os2.htm#fc + * and http://www.microsoft.com/typography/otspec/ibmfc.htm + * for the reference of sFamilyClass. + */ + cls_id = (os2->sFamilyClass >> 8) & 0xff; + subcls_id = os2->sFamilyClass & 0xff; + if (FcDebug () & FC_DBG_SCANV) + printf ("%s: class id: %d, subclass id: %d, panose: [%d %d %d %d %d %d %d %d %d %d]\n", file, cls_id, subcls_id, os2->panose[0], os2->panose[1], os2->panose[2], os2->panose[3], os2->panose[4], os2->panose[5], os2->panose[6], os2->panose[7], os2->panose[8], os2->panose[9]); + switch (cls_id) + { + case 0: /* No Classification */ + case 6: /* reserved for future use */ + case 11: /* reserved for future use */ + case 13: /* Reserved */ + case 14: /* Reserved */ + break; + case 1: /* Oldstyle Serifs */ + fclass_bits |= FC_FCLASS_SERIF; + if (subcls_id == 8) /* Calligraphic */ + fclass_bits |= FC_FCLASS_CURSIVE; + break; + case 2: /* Trasitional Serifs */ + case 3: /* Modern Serifs */ + fclass_bits |= FC_FCLASS_SERIF; + if (subcls_id == 2) /* Script */ + fclass_bits |= FC_FCLASS_CURSIVE; + break; + case 4: /* Clarendon Serifs */ + case 5: /* Slab Serifs */ + case 7: /* Freeform Serifs */ + fclass_bits |= FC_FCLASS_SERIF; + break; + case 8: /* Sans Serif */ + fclass_bits |= FC_FCLASS_SANS; + break; + case 9: /* Ornamentals */ + case 12: /* Symbolic */ + fclass_bits |= FC_FCLASS_FANTASY; + break; + case 10: /* Scripts */ + fclass_bits |= FC_FCLASS_CURSIVE; + break; + default: + break; + } + /* See http://www.monotypeimaging.com/ProductsServices/pan1.aspx + * for the reference of Panose + */ + if (os2->panose[0] == 3) + { + /* Latin Hand Written */ + fclass_bits |= FC_FCLASS_CURSIVE; + } + else if (os2->panose[0] >= 4 && + os2->panose[0] <= 5) + { + /* 4...Latin Decorative + * 5...Latin Symbol + */ + fclass_bits |= FC_FCLASS_FANTASY; + } + else if (os2->panose[0] == 2 && + ((os2->panose[1] >= 11 && + os2->panose[1] <= 13) || + os2->panose[1] == 15)) + { + /* 2...Latin Text */ + /* 11...Normal Sans + * 12...Obtuse Sans + * 13...Perpendicular Sans + * 15...Pounded + */ + fclass_bits |= FC_FCLASS_SANS; + } + else if (os2->panose[0] == 1) + { + /* "Not Fit" in the family kind should be ignored. */ + } + else if (os2->panose[0] == 0 && + os2->panose[1] == 1) + { + /* Unable to determine the family class */ + } + else + { + fclass_bits |= FC_FCLASS_SERIF; + } + if ((os2->panose[0] == 2 && + os2->panose[3] == 9) || + (os2->panose[0] == 3 && + os2->panose[3] == 3) || + (os2->panose[0] == 4 && + os2->panose[3] == 9) || + (os2->panose[0] == 5 && + os2->panose[3] == 3)) + { + fclass_bits |= FC_FCLASS_MONO; + } + } /* * Look first in the OS/2 table for the foundry, if * not found here, the various notices will be searched for @@ -1947,6 +2061,21 @@ FcFreeTypeQueryFace (const FT_Face face, if (foundry_) free (foundry_); + /* family class */ + for (i = FC_FCLASS_SANS, j = 1; i < FC_FCLASS_END; i <<= 1, j++) + { + if ((fclass_bits & i) == i) + { + if (!FcPatternAddString (pat, FC_FAMILY_CLASS, (const FcChar8 *) fclass[j])) + goto bail1; + } + } + if (FcPatternGetString (pat, FC_FAMILY_CLASS, 0, &fcls) != FcResultMatch) + { + if (!FcPatternAddString (pat, FC_FAMILY_CLASS, (const FcChar8 *) "unknown")) + goto bail1; + } + if (master) { /* TODO: How to free master?! */ diff --git a/src/fcmatch.c b/src/fcmatch.c index 40efbd3f..41881a2d 100644 --- a/src/fcmatch.c +++ b/src/fcmatch.c @@ -287,9 +287,11 @@ typedef enum _FcMatcherPriority { PRI1(COLOR), PRI1(FOUNDRY), PRI1(CHARSET), + PRI_FAMILY_CLASS_STRONG, PRI_FAMILY_STRONG, PRI_POSTSCRIPT_NAME_STRONG, PRI1(LANG), + PRI_FAMILY_CLASS_WEAK, PRI_FAMILY_WEAK, PRI_POSTSCRIPT_NAME_WEAK, PRI1(SYMBOL), diff --git a/src/fcobjs.h b/src/fcobjs.h index d27864be..8e71ae28 100644 --- a/src/fcobjs.h +++ b/src/fcobjs.h @@ -70,4 +70,5 @@ FC_OBJECT (HASH, FcTypeString, NULL) /* deprecated */ FC_OBJECT (POSTSCRIPT_NAME, FcTypeString, FcComparePostScript) FC_OBJECT (COLOR, FcTypeBool, FcCompareBool) FC_OBJECT (SYMBOL, FcTypeBool, FcCompareBool) +FC_OBJECT (FAMILY_CLASS, FcTypeString, FcCompareString) /* ^-------------- Add new objects here. */ |