[Fontconfig] Patch to improve support for localized font family and style names

Mike FABIAN mfabian at suse.de
Thu Oct 20 00:12:05 EST 2005


Reply-to: mfabian at suse.de
X-Face: "';oPz9V1+<,`}1ZuxRv~EiSusWq*{Yjr"Sdvbhq'?q=2R\\6Y9O/,SAE`{J|6I=|w/sQg<
 rW_N'E3IV6~f8?\l#Es`]S`mv',PY(`8{$$R?+gLu}Qv/Mn>)?uladFjJ at yl!_p_Jh;5QxlD6zL:?r
 IXe4FfK$C^mWhh$o`yt;.r.FLZLQOWBt><!;-.DYZ)Nu&1?~*:\36\BGz]"L;nue;l\%sJ/]l{is5O
 Ew?0CF}dPS(ezG0xqUR)xa(L&&c;x{By"`oKvM&i!%+
From: Mike FABIAN <mfabian at suse.de>
Date: Wed, 19 Oct 2005 16:12:05 +0200
Message-ID: <s3ty84p4mve.fsf at magellan.suse.de>
User-Agent: Gnus/5.1006 (Gnus v5.10.6) XEmacs/21.5 (cucumber, linux)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
--text follows this line--
--=-=-=

Here is a patch by Zhe Su <zsu at novell.com> to improve support
for localized font family and style names.

For details see:

http://bugzilla.novell.com/show_bug.cgi?id=128930


--=-=-=
Content-Type: text/x-patch
Content-Disposition: inline;
  filename=bugzilla-128930-support-localized-family-and-style-names.patch

diff -ur fontconfig-2.3.91.20051007.old/src/fcdefault.c fontconfig-2.3.91.20051007/src/fcdefault.c
--- fontconfig-2.3.91.20051007.old/src/fcdefault.c	2005-10-17 22:40:43.000000000 +0800
+++ fontconfig-2.3.91.20051007/src/fcdefault.c	2005-10-17 23:24:44.000000000 +0800
@@ -38,6 +38,67 @@
 
 #define NUM_FC_BOOL_DEFAULTS	(int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0])
 
+FcChar8 *
+FcGetDefaultLang (void)
+{
+    static char	lang_local [128] = {0};
+    char        *ctype;
+    char        *territory;
+    char        *after;
+    int         lang_len, territory_len;
+
+    if (lang_local [0])
+	return (FcChar8 *) lang_local;
+
+    ctype = setlocale (LC_CTYPE, NULL);
+
+    /*
+     * Check if setlocale (LC_ALL, "") has been called
+     */
+    if (!ctype || !strcmp (ctype, "C"))
+    {
+	ctype = getenv ("LC_ALL");
+	if (!ctype)
+	{
+	    ctype = getenv ("LC_CTYPE");
+	    if (!ctype)
+		ctype = getenv ("LANG");
+	}
+    }
+
+    /* ignore missing or empty ctype */
+    if (ctype && *ctype != '\0')
+    {
+	territory = strchr (ctype, '_');
+	if (territory)
+	{
+	    lang_len = territory - ctype;
+	    territory = territory + 1;
+	    after = strchr (territory, '.');
+	    if (!after)
+	    {
+		after = strchr (territory, '@');
+		if (!after)
+		    after = territory + strlen (territory);
+	    }
+	    territory_len = after - territory;
+	    if (lang_len + 1 + territory_len + 1 <= (int) sizeof (lang_local))
+	    {
+		strncpy (lang_local, ctype, lang_len);
+		lang_local[lang_len] = '-';
+		strncpy (lang_local + lang_len + 1, territory, territory_len);
+		lang_local[lang_len + 1 + territory_len] = '\0';
+	    }
+	}
+    }
+
+    /* set default lang to en */
+    if (!lang_local [0])
+	strcpy (lang_local, "en");
+
+    return (FcChar8 *) lang_local;
+}
+
 void
 FcDefaultSubstitute (FcPattern *pattern)
 {
@@ -92,55 +153,7 @@
 
     if (FcPatternGet (pattern, FC_LANG, 0, &v) == FcResultNoMatch)
     {
-	char	*lang;
-	char	*territory;
-	char	*after;
-	int	lang_len, territory_len;
-	char	lang_local[128];
-	char	*ctype = setlocale (LC_CTYPE, NULL);
-
-	/*
-	 * Check if setlocale (LC_ALL, "") has been called
-	 */
-	if (!ctype || !strcmp (ctype, "C"))
-	{
-	    ctype = getenv ("LC_ALL");
-	    if (!ctype)
-	    {
-		ctype = getenv ("LC_CTYPE");
-		if (!ctype)
-		    ctype = getenv ("LANG");
-	    }
-	}
-	/* ignore missing or empty ctype */
-	if (ctype && *ctype != '\0')
-	{
-	    lang = ctype;
-	    territory = strchr (ctype, '_');
-	    if (territory)
-	    {
-		lang_len = territory - lang;
-		territory = territory + 1;
-		after = strchr (territory, '.');
-		if (!after)
-		{
-		    after = strchr (territory, '@');
-		    if (!after)
-			after = territory + strlen (territory);
-		}
-		territory_len = after - territory;
-		if (lang_len + 1 + territory_len + 1 <= (int) sizeof (lang_local))
-		{
-		    strncpy (lang_local, lang, lang_len);
-		    lang_local[lang_len] = '-';
-		    strncpy (lang_local + lang_len + 1, territory, territory_len);
-		    lang_local[lang_len + 1 + territory_len] = '\0';
-		    FcPatternAddString (pattern, FC_LANG, (FcChar8 *) lang_local);
-		}
-	    }
-	    else
-		FcPatternAddString (pattern, FC_LANG, (FcChar8 *) lang);
-	}
+	FcPatternAddString (pattern, FC_LANG, FcGetDefaultLang ());
     }
     if (FcPatternGet (pattern, FC_FONTVERSION, 0, &v) == FcResultNoMatch)
     {
diff -ur fontconfig-2.3.91.20051007.old/src/fcint.h fontconfig-2.3.91.20051007/src/fcint.h
--- fontconfig-2.3.91.20051007.old/src/fcint.h	2005-10-07 19:00:55.000000000 +0800
+++ fontconfig-2.3.91.20051007/src/fcint.h	2005-10-18 09:57:14.000000000 +0800
@@ -571,6 +571,10 @@
 int
 FcDebug (void);
 
+/* fcdefault.c */
+FcChar8 *
+FcGetDefaultLang (void);
+
 /* fcdir.c */
 
 FcBool
diff -ur fontconfig-2.3.91.20051007.old/src/fclist.c fontconfig-2.3.91.20051007/src/fclist.c
--- fontconfig-2.3.91.20051007.old/src/fclist.c	2005-10-07 19:00:55.000000000 +0800
+++ fontconfig-2.3.91.20051007/src/fclist.c	2005-10-18 12:43:54.000000000 +0800
@@ -337,6 +337,37 @@
     table->entries = 0;
 }
 
+static int
+FcGetDefaultObjectLangIndex (FcPattern *font, const char *object)
+{
+    FcChar8	   *lang = FcGetDefaultLang ();
+    FcPatternElt   *e = FcPatternFindElt (font, object);
+    FcValueListPtr  v;
+    FcValue         value;
+    int             idx = -1;
+    int             i;
+    int             langlen = strlen (lang);
+
+    if (e)
+    {
+	for (v = e->values, i = 0; FcValueListPtrU(v); v = FcValueListPtrU(v)->next, ++i)
+	{
+	    value = FcValueCanonicalize (&FcValueListPtrU (v)->value);
+
+	    if ((value.type & ~FC_STORAGE_STATIC) == FcTypeString)
+	    {
+		FcLangResult res = FcLangCompare (value.u.s, lang);
+		if (res == FcLangEqual)
+		    idx = i;
+		else if (res == FcLangDifferentCountry && strlen (value.u.s) < langlen && idx < 0)
+		    idx = i;
+	    }
+	}
+    }
+
+    return (idx > 0) ? idx : 0;
+}
+
 static FcBool
 FcListAppend (FcListHashTable	*table,
 	      FcPattern		*font,
@@ -347,6 +378,11 @@
     FcValueListPtr  v;
     FcChar32	    hash;
     FcListBucket    **prev, *bucket;
+    int             familyidx = -1;
+    int             fullnameidx = -1;
+    int             styleidx = -1;
+    int             defidx = 0;
+    int             idx;
 
     hash = FcListPatternHash (font, os);
     for (prev = &table->buckets[hash % FC_LIST_HASH_SIZE];
@@ -368,15 +404,36 @@
     
     for (o = 0; o < os->nobject; o++)
     {
+	if (!strcmp (os->objects[o], FC_FAMILY) || !strcmp (os->objects[o], FC_FAMILYLANG))
+	{
+	    if (familyidx < 0)
+		familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG);
+	    defidx = familyidx;
+	}
+	else if (!strcmp (os->objects[o], FC_FULLNAME) || !strcmp (os->objects[o], FC_FULLNAMELANG))
+	{
+	    if (fullnameidx < 0)
+		fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG);
+	    defidx = fullnameidx;
+	}
+	else if (!strcmp (os->objects[o], FC_STYLE) || !strcmp (os->objects[o], FC_STYLELANG))
+	{
+	    if (styleidx < 0)
+		styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG);
+	    defidx = styleidx;
+	}
+	else
+	    defidx = 0;
+
 	e = FcPatternFindElt (font, os->objects[o]);
 	if (e)
 	{
-	    for (v = e->values; FcValueListPtrU(v); 
-		 v = FcValueListPtrU(v)->next)
+	    for (v = e->values, idx = 0; FcValueListPtrU(v); 
+		 v = FcValueListPtrU(v)->next, ++idx)
 	    {
 		if (!FcPatternAdd (bucket->pattern, 
 				   os->objects[o], 
-				   FcValueCanonicalize(&FcValueListPtrU(v)->value), FcTrue))
+				   FcValueCanonicalize(&FcValueListPtrU(v)->value), defidx != idx))
 		    goto bail2;
 	    }
 	}

--=-=-=
Content-Type: text/plain; charset=iso-2022-jp


-- 
Mike FABIAN   <mfabian at suse.de>   http://www.suse.de/~mfabian
睡眠不足はいい仕事の敵だ。

--=-=-=--




More information about the Fontconfig mailing list