[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