[Fontconfig] fontconfig: Branch 'master'
Akira TAGOH
tagoh at kemper.freedesktop.org
Thu Mar 21 00:36:01 PDT 2013
fontconfig/fontconfig.h | 1
src/fcfreetype.c | 49 +++++++++++++++++++++++++++
src/fcint.h | 6 +++
src/fcmatch.c | 21 +++++++++++
src/fcobjs.h | 1
src/fcstr.c | 85 +++++++++++++++++++++++++++---------------------
6 files changed, 125 insertions(+), 38 deletions(-)
New commits:
commit b561ff2016ce84eef3c81f16dfb0481be6a13f9b
Author: Akira TAGOH <akira at tagoh.org>
Date: Fri Jan 18 11:30:10 2013 +0900
Bug 38737 - Wishlist: support FC_POSTSCRIPT_NAME
Add the PostScript name into the cache and the matcher.
Scoring the better font against the PostScript name by
the forward-matching.
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index fc0ed1a..1949965 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -116,6 +116,7 @@ typedef int FcBool;
#define FC_NAMELANG "namelang" /* String RFC 3866 langs */
#define FC_PRGNAME "prgname" /* String */
#define FC_HASH "hash" /* String */
+#define FC_POSTSCRIPT_NAME "postscriptname" /* String */
#define FC_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION
#define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION
diff --git a/src/fcfreetype.c b/src/fcfreetype.c
index 9bd789c..8a037c0 100644
--- a/src/fcfreetype.c
+++ b/src/fcfreetype.c
@@ -1101,6 +1101,8 @@ FcFreeTypeQueryFace (const FT_Face face,
FcChar8 *style = 0;
int st;
+ char psname[256];
+ const char *tmp;
FcChar8 *hashstr;
@@ -1201,7 +1203,6 @@ FcFreeTypeQueryFace (const FT_Face face,
case TT_NAME_ID_PREFERRED_FAMILY:
case TT_NAME_ID_FONT_FAMILY:
#if 0
- case TT_NAME_ID_PS_NAME:
case TT_NAME_ID_UNIQUE_ID:
#endif
if (FcDebug () & FC_DBG_SCANV)
@@ -1347,6 +1348,52 @@ FcFreeTypeQueryFace (const FT_Face face,
++nfamily;
}
+ /* Add the PostScript name into the cache */
+ tmp = FT_Get_Postscript_Name (face);
+ if (!tmp)
+ {
+ FcChar8 *family, *familylang = NULL;
+ size_t len;
+ int n = 0;
+
+ /* Workaround when FT_Get_Postscript_Name didn't give any name.
+ * try to find out the English family name and convert.
+ */
+ while (FcPatternObjectGetString (pat, FC_FAMILYLANG_OBJECT, n, &familylang) == FcResultMatch)
+ {
+ if (FcStrCmp (familylang, (const FcChar8 *)"en") == 0)
+ break;
+ n++;
+ familylang = NULL;
+ }
+ if (!familylang)
+ n = 0;
+
+ if (FcPatternObjectGetString (pat, FC_FAMILY_OBJECT, n, &family) != FcResultMatch)
+ goto bail1;
+ len = strlen ((const char *)family);
+ /* the literal name in PostScript Language is limited to 127 characters though,
+ * It is the architectural limit. so assuming 255 characters may works enough.
+ */
+ for (i = 0; i < len && i < 255; i++)
+ {
+ /* those characters are not allowed to be the literal name in PostScript */
+ static const char exclusive_chars[] = "\x04()/<>[]{}\t\f\r\n ";
+
+ if (strchr(exclusive_chars, family[i]) != NULL)
+ psname[i] = '-';
+ else
+ psname[i] = family[i];
+ }
+ psname[i] = 0;
+ }
+ else
+ {
+ strcpy (psname, tmp);
+ }
+ if (!FcPatternAddString (pat, FC_POSTSCRIPT_NAME, (const FcChar8 *)psname))
+ goto bail1;
+
if (!FcPatternAddString (pat, FC_FILE, file))
goto bail1;
diff --git a/src/fcint.h b/src/fcint.h
index d5a7217..c45075e 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -1063,6 +1063,9 @@ FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
FcPrivate int
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
+FcPrivate int
+FcStrCmpIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims);
+
FcPrivate FcBool
FcStrRegexCmp (const FcChar8 *s, const FcChar8 *regex);
@@ -1078,6 +1081,9 @@ FcStrContainsIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
FcPrivate const FcChar8 *
FcStrContainsWord (const FcChar8 *s1, const FcChar8 *s2);
+FcPrivate int
+FcStrMatchIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims);
+
FcPrivate FcBool
FcStrUsesHome (const FcChar8 *s);
diff --git a/src/fcmatch.c b/src/fcmatch.c
index 7993b81..68f39ae 100644
--- a/src/fcmatch.c
+++ b/src/fcmatch.c
@@ -77,6 +77,24 @@ FcCompareFamily (FcValue *v1, FcValue *v2)
}
static double
+FcComparePostScript (FcValue *v1, FcValue *v2)
+{
+ const FcChar8 *v1_string = FcValueString (v1);
+ const FcChar8 *v2_string = FcValueString (v2);
+ int n;
+ size_t len;
+
+ if (FcToLower (*v1_string) != FcToLower (*v2_string) &&
+ *v1_string != ' ' && *v2_string != ' ')
+ return 1.0;
+
+ n = FcStrMatchIgnoreCaseAndDelims (v1_string, v2_string, (const FcChar8 *)" -");
+ len = strlen ((const char *)v1_string);
+
+ return (double)(len - n) / (double)len;
+}
+
+static double
FcCompareLang (FcValue *v1, FcValue *v2)
{
FcLangResult result;
@@ -198,6 +216,7 @@ FcCompareFilename (FcValue *v1, FcValue *v2)
#define PRI_FcCompareFilename(n) PRI1(n)
#define PRI_FcCompareCharSet(n) PRI1(n)
#define PRI_FcCompareLang(n) PRI1(n)
+#define PRI_FcComparePostScript(n) PRI1(n)
#define FC_OBJECT(NAME, Type, Cmp) PRI_##Cmp(NAME)
@@ -219,8 +238,10 @@ typedef enum _FcMatcherPriority {
PRI1(CHARSET),
PRI_FAMILY_STRONG,
PRI_LANG_STRONG,
+ PRI_POSTSCRIPT_NAME_STRONG,
PRI_LANG_WEAK,
PRI_FAMILY_WEAK,
+ PRI_POSTSCRIPT_NAME_WEAK,
PRI1(SPACING),
PRI1(PIXEL_SIZE),
PRI1(STYLE),
diff --git a/src/fcobjs.h b/src/fcobjs.h
index 4c1138a..b735401 100644
--- a/src/fcobjs.h
+++ b/src/fcobjs.h
@@ -44,4 +44,5 @@ FC_OBJECT (NAMELANG, FcTypeString, NULL)
FC_OBJECT (FONT_FEATURES, FcTypeString, NULL)
FC_OBJECT (PRGNAME, FcTypeString, NULL)
FC_OBJECT (HASH, FcTypeString, FcCompareString)
+FC_OBJECT (POSTSCRIPT_NAME, FcTypeString, FcComparePostScript)
/* ^-------------- Add new objects here. */
diff --git a/src/fcstr.c b/src/fcstr.c
index 4d11a4c..339a346 100644
--- a/src/fcstr.c
+++ b/src/fcstr.c
@@ -137,27 +137,7 @@ FcStrCaseWalkerLong (FcCaseWalker *w, FcChar8 r)
}
static FcChar8
-FcStrCaseWalkerNext (FcCaseWalker *w)
-{
- FcChar8 r;
-
- if (w->read)
- {
- if ((r = *w->read++))
- return r;
- w->read = 0;
- }
- r = *w->src++;
-
- if ((r & 0xc0) == 0xc0)
- return FcStrCaseWalkerLong (w, r);
- if ('A' <= r && r <= 'Z')
- r = r - 'A' + 'a';
- return r;
-}
-
-static FcChar8
-FcStrCaseWalkerNextIgnoreBlanks (FcCaseWalker *w)
+FcStrCaseWalkerNext (FcCaseWalker *w, const char *delims)
{
FcChar8 r;
@@ -170,7 +150,7 @@ FcStrCaseWalkerNextIgnoreBlanks (FcCaseWalker *w)
do
{
r = *w->src++;
- } while (r == ' ');
+ } while (r != 0 && delims && strchr (delims, r));
if ((r & 0xc0) == 0xc0)
return FcStrCaseWalkerLong (w, r);
@@ -187,13 +167,13 @@ FcStrDowncase (const FcChar8 *s)
FcChar8 *dst, *d;
FcStrCaseWalkerInit (s, &w);
- while (FcStrCaseWalkerNext (&w))
+ while (FcStrCaseWalkerNext (&w, NULL))
len++;
d = dst = malloc (len + 1);
if (!d)
return 0;
FcStrCaseWalkerInit (s, &w);
- while ((*d++ = FcStrCaseWalkerNext (&w)));
+ while ((*d++ = FcStrCaseWalkerNext (&w, NULL)));
return dst;
}
@@ -210,8 +190,8 @@ FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;)
{
- c1 = FcStrCaseWalkerNext (&w1);
- c2 = FcStrCaseWalkerNext (&w2);
+ c1 = FcStrCaseWalkerNext (&w1, NULL);
+ c2 = FcStrCaseWalkerNext (&w2, NULL);
if (!c1 || (c1 != c2))
break;
}
@@ -221,6 +201,12 @@ FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
int
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
{
+ return FcStrCmpIgnoreCaseAndDelims (s1, s2, (const FcChar8 *)" ");
+}
+
+int
+FcStrCmpIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims)
+{
FcCaseWalker w1, w2;
FcChar8 c1, c2;
@@ -231,8 +217,8 @@ FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;)
{
- c1 = FcStrCaseWalkerNextIgnoreBlanks (&w1);
- c2 = FcStrCaseWalkerNextIgnoreBlanks (&w2);
+ c1 = FcStrCaseWalkerNext (&w1, (const char *)delims);
+ c2 = FcStrCaseWalkerNext (&w2, (const char *)delims);
if (!c1 || (c1 != c2))
break;
}
@@ -317,7 +303,7 @@ FcStrHashIgnoreCase (const FcChar8 *s)
FcChar8 c;
FcStrCaseWalkerInit (s, &w);
- while ((c = FcStrCaseWalkerNext (&w)))
+ while ((c = FcStrCaseWalkerNext (&w, NULL)))
h = ((h << 3) ^ (h >> 3)) ^ c;
return h;
}
@@ -337,8 +323,8 @@ FcStrIsAtIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;)
{
- c1 = FcStrCaseWalkerNextIgnoreBlanks (&w1);
- c2 = FcStrCaseWalkerNextIgnoreBlanks (&w2);
+ c1 = FcStrCaseWalkerNext (&w1, " ");
+ c2 = FcStrCaseWalkerNext (&w2, " ");
if (!c1 || (c1 != c2))
break;
}
@@ -396,8 +382,8 @@ FcStrIsAtIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;)
{
- c1 = FcStrCaseWalkerNext (&w1);
- c2 = FcStrCaseWalkerNext (&w2);
+ c1 = FcStrCaseWalkerNext (&w1, NULL);
+ c2 = FcStrCaseWalkerNext (&w2, NULL);
if (!c1 || (c1 != c2))
break;
}
@@ -448,6 +434,31 @@ FcStrContainsWord (const FcChar8 *s1, const FcChar8 *s2)
return 0;
}
+/*
+ * returns the number of strings (ignoring delimitors and case) being matched
+ */
+
+int
+FcStrMatchIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims)
+{
+ FcCaseWalker w1, w2;
+ FcChar8 c1, c2;
+
+ if (s1 == s2) return 0;
+
+ FcStrCaseWalkerInit (s1, &w1);
+ FcStrCaseWalkerInit (s2, &w2);
+
+ for (;;)
+ {
+ c1 = FcStrCaseWalkerNext (&w1, (const char *)delims);
+ c2 = FcStrCaseWalkerNext (&w2, (const char *)delims);
+ if (!c1 || (c1 != c2))
+ break;
+ }
+ return w1.src - s1 - 1;
+}
+
const FcChar8 *
FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
{
@@ -464,12 +475,12 @@ FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
FcStrCaseWalkerInit (s1, &w1);
FcStrCaseWalkerInit (s2, &w2);
- c2 = FcStrCaseWalkerNext (&w2);
+ c2 = FcStrCaseWalkerNext (&w2, NULL);
for (;;)
{
cur = w1.src;
- c1 = FcStrCaseWalkerNext (&w1);
+ c1 = FcStrCaseWalkerNext (&w1, NULL);
if (!c1)
break;
if (c1 == c2)
@@ -480,8 +491,8 @@ FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;)
{
- c1t = FcStrCaseWalkerNext (&w1t);
- c2t = FcStrCaseWalkerNext (&w2t);
+ c1t = FcStrCaseWalkerNext (&w1t, NULL);
+ c2t = FcStrCaseWalkerNext (&w2t, NULL);
if (!c2t)
return cur;
More information about the Fontconfig
mailing list