summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira TAGOH <akira@tagoh.org>2013-09-18 18:55:53 +0900
committerAkira TAGOH <akira@tagoh.org>2017-07-11 15:39:55 +0900
commita1f249360b76526a801df7213497c960a9c969fe (patch)
tree1d498e68a82f7eb36d8c0bb77cb94cd1cf23b3d2
parent5b6af242e1eb0a6456fe9ab9a99efa3ba42f83c6 (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.conf21
-rw-r--r--fontconfig/fontconfig.h1
-rw-r--r--fonts.conf.in36
-rw-r--r--src/fcfreetype.c133
-rw-r--r--src/fcmatch.c2
-rw-r--r--src/fcobjs.h1
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. */