diff options
Diffstat (limited to 'fontconfig')
-rw-r--r-- | fontconfig/configure.in | 89 | ||||
-rw-r--r-- | fontconfig/doc/fontconfig-devel.sgml | 3 | ||||
-rw-r--r-- | fontconfig/doc/fontconfig-user.sgml | 20 | ||||
-rw-r--r-- | fontconfig/fontconfig/fontconfig.h | 1 | ||||
-rw-r--r-- | fontconfig/src/fccache.c | 77 | ||||
-rw-r--r-- | fontconfig/src/fcdefault.c | 37 | ||||
-rw-r--r-- | fontconfig/src/fcint.h | 3 | ||||
-rw-r--r-- | fontconfig/src/fclist.c | 47 | ||||
-rw-r--r-- | fontconfig/src/fcmatch.c | 113 | ||||
-rw-r--r-- | fontconfig/src/fcname.c | 1 |
10 files changed, 329 insertions, 62 deletions
diff --git a/fontconfig/configure.in b/fontconfig/configure.in index 62bc25e4a..b77c52a29 100644 --- a/fontconfig/configure.in +++ b/fontconfig/configure.in @@ -123,7 +123,7 @@ dnl ========================================================================== # Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC -AC_CHECK_HEADERS([fcntl.h regex.h stdlib.h string.h unistd.h]) +AC_CHECK_HEADERS([fcntl.h regex.h stdlib.h string.h unistd.h sys/vfs.h sys/statfs.h sys/param.h sys/mount.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -133,9 +133,29 @@ AC_TYPE_PID_T # Checks for library functions. AC_FUNC_VPRINTF AC_FUNC_MMAP -AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr strtol getopt getopt_long sysconf ftruncate chsize rand random lrand48 random_r rand_r regcomp regerror regexec regfree posix_fadvise]) +AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr strtol getopt getopt_long sysconf ftruncate chsize rand random lrand48 random_r rand_r regcomp regerror regexec regfree posix_fadvise fstatvfs fstatfs]) # +if test "x$ac_cv_func_fstatvfs" = "xyes"; then + AC_CHECK_MEMBERS([struct statvfs.f_basetype, struct statvfs.f_fstypename],,, + [#include <sys/statvfs.h>]) +fi +if test "x$ac_cv_func_fstatfs" = "xyes"; then + AC_CHECK_MEMBERS([struct statfs.f_flags, struct statfs.f_fstypename],,, [ +#ifdef HAVE_SYS_VFS_H +#include <sys/vfs.h> +#endif +#ifdef HAVE_SYS_STATFS_H +#include <sys/statfs.h> +#endif +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif +#ifdef HAVE_SYS_MOUNT_H +#include <sys/mount.h> +#endif]) +fi +# # regex # if test "x$ac_cv_func_regcomp" = "xyes" -a "x$ac_cv_func_regerror" = "xyes" -a "x$ac_cv_func_regexec" = "xyes" -a "x$ac_cv_func_regfree"; then @@ -145,6 +165,10 @@ fi # # Checks for iconv # +AC_ARG_ENABLE(iconv, + [AC_HELP_STRING([--enable-iconv], + [Use iconv to support non-Unicode SFNT name])], + ,enable_iconv=no) AC_ARG_WITH(libiconv, [AC_HELP_STRING([--with-libiconv=DIR], [Use libiconv in DIR])], @@ -186,38 +210,39 @@ if test "x$libiconv_cflags" != "x"; then fi use_iconv=0 -AC_MSG_CHECKING([for a usable iconv]) -if test "x$libiconv_cflags" != "x" -o "x$libiconv_libs" != "x"; then - iconvsaved_CFLAGS="$CFLAGS" - iconvsaved_LIBS="$LIBS" - CFLAGS="$CFLAGS $libiconv_cflags" - LIBS="$LIBS $libiconv_libs" - - AC_TRY_LINK([#include <iconv.h>], - [iconv_open ("from", "to");], - [iconv_type="libiconv" - use_iconv=1], - [use_iconv=0]) - - CFLAGS="$iconvsaved_CFLAGS" - LIBS="$iconvsaved_LIBS" - ICONV_CFLAGS="$libiconv_cflags" - ICONV_LIBS="$libiconv_libs" -fi -if test "x$use_iconv" = "x0"; then - AC_TRY_LINK([#include <iconv.h>], - [iconv_open ("from", "to");], - [iconv_type="libc" - use_iconv=1], - [iconv_type="not found" - use_iconv=0]) -fi +if test "x$enable_iconv" != "xno"; then + AC_MSG_CHECKING([for a usable iconv]) + if test "x$libiconv_cflags" != "x" -o "x$libiconv_libs" != "x"; then + iconvsaved_CFLAGS="$CFLAGS" + iconvsaved_LIBS="$LIBS" + CFLAGS="$CFLAGS $libiconv_cflags" + LIBS="$LIBS $libiconv_libs" + + AC_TRY_LINK([#include <iconv.h>], + [iconv_open ("from", "to");], + [iconv_type="libiconv" + use_iconv=1], + [use_iconv=0]) + + CFLAGS="$iconvsaved_CFLAGS" + LIBS="$iconvsaved_LIBS" + ICONV_CFLAGS="$libiconv_cflags" + ICONV_LIBS="$libiconv_libs" + fi + if test "x$use_iconv" = "x0"; then + AC_TRY_LINK([#include <iconv.h>], + [iconv_open ("from", "to");], + [iconv_type="libc" + use_iconv=1], + [iconv_type="not found" + use_iconv=0]) + fi -AC_MSG_RESULT([$iconv_type]) -AC_SUBST(ICONV_CFLAGS) -AC_SUBST(ICONV_LIBS) + AC_MSG_RESULT([$iconv_type]) + AC_SUBST(ICONV_CFLAGS) + AC_SUBST(ICONV_LIBS) +fi AC_DEFINE_UNQUOTED(USE_ICONV,$use_iconv,[Use iconv.]) - # # Checks for FreeType # diff --git a/fontconfig/doc/fontconfig-devel.sgml b/fontconfig/doc/fontconfig-devel.sgml index 87339511c..ab390925d 100644 --- a/fontconfig/doc/fontconfig-devel.sgml +++ b/fontconfig/doc/fontconfig-devel.sgml @@ -190,6 +190,9 @@ convenience for the application's rendering mechanism. the font embolden FC_EMBOLDEN Bool Rasterizer should synthetically embolden the font + namelang FC_NAMELANG String Language name to be used for the + default value of familylang, + stylelang and fullnamelang </programlisting> </sect2> </sect1> diff --git a/fontconfig/doc/fontconfig-user.sgml b/fontconfig/doc/fontconfig-user.sgml index 14fdc79aa..86f2b3299 100644 --- a/fontconfig/doc/fontconfig-user.sgml +++ b/fontconfig/doc/fontconfig-user.sgml @@ -224,7 +224,7 @@ values as the font name is read. </para> </refsect2> </refsect1> -<refsect1><title>Debugging Applications</title> +<refsect1 id="debug"><title>Debugging Applications</title> <para> To help diagnose font and applications problems, fontconfig is built with a large amount of internal debugging left enabled. It is controlled by means @@ -692,6 +692,24 @@ is the conventional repository of font information that isn't found in the per-directory caches. This file is automatically maintained by fontconfig. </para> </refsect1> +<refsect1><title>Environment variables</title> + <para> +<emphasis>FONTCONFIG_FILE</emphasis> +is used to override the default configuration file. + </para> + <para> +<emphasis>FONTCONFIG_PATH</emphasis> +is used to override the default configuration directory. + </para> + <para> +<emphasis>FC_DEBUG</emphasis> +is used to output the detailed debugging messages. see <link linkend="debug">Debugging Applications</link> section for more details. + </para> + <para> +<emphasis>FONTCONFIG_USE_MMAP</emphasis> +is used to control the use of mmap(2) for the cache files if available. this take a boolean value. fontconfig will checks if the cache files are stored on the filesystem that is safe to use mmap(2). explicitly setting this environment variable will causes skipping this check and enforce to use or not use mmap(2) anyway. + </para> +</refsect1> <refsect1><title>See Also</title> <para> fc-cat(1), fc-cache(1), fc-list(1), fc-match(1), fc-query(1) diff --git a/fontconfig/fontconfig/fontconfig.h b/fontconfig/fontconfig/fontconfig.h index e4d57088d..2671da78d 100644 --- a/fontconfig/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig/fontconfig.h @@ -111,6 +111,7 @@ typedef int FcBool; #define FC_EMBEDDED_BITMAP "embeddedbitmap" /* Bool - true to enable embedded bitmaps */ #define FC_DECORATIVE "decorative" /* Bool - true if style is a decorative variant */ #define FC_LCD_FILTER "lcdfilter" /* Int */ +#define FC_NAMELANG "namelang" /* String RFC 3866 langs */ #define FC_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION #define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION diff --git a/fontconfig/src/fccache.c b/fontconfig/src/fccache.c index fbe2d5c01..882dd3eb5 100644 --- a/fontconfig/src/fccache.c +++ b/fontconfig/src/fccache.c @@ -37,6 +37,21 @@ # include <unistd.h> # include <sys/mman.h> #endif +#ifdef HAVE_SYS_VFS_H +#include <sys/vfs.h> +#endif +#ifdef HAVE_SYS_STATFS_H +#include <sys/statfs.h> +#endif +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif +#ifdef HAVE_SYS_MOUNT_H +#include <sys/mount.h> +#endif +#ifdef HAVE_MNTENT_H +#include <mntent.h> +#endif #ifndef O_BINARY #define O_BINARY 0 @@ -144,6 +159,64 @@ FcStat (const FcChar8 *file, struct stat *statb) #endif +static FcBool +FcCacheIsMmapSafe (int fd) +{ + FcBool retval = FcTrue; + static FcBool is_initialized = FcFalse; + static FcBool is_env_available = FcFalse; + static FcBool use_mmap = FcFalse; + + if (!is_initialized) + { + const char *env; + + env = getenv ("FONTCONFIG_USE_MMAP"); + if (env) + { + if (FcNameBool ((const FcChar8 *)env, &use_mmap)) + is_env_available = FcTrue; + } + is_initialized = FcTrue; + } + if (is_env_available) + return use_mmap; +#if defined(HAVE_FSTATVFS) && (defined(HAVE_STRUCT_STATVFS_F_BASETYPE) || defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME)) + struct statvfs buf; + + if (fstatvfs (fd, &buf) == 0) + { + const char *p; +#if defined(HAVE_STRUCT_STATVFS_F_BASETYPE) + p = buf.f_basetype; +#elif defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME) + p = buf.f_fstypename; +#endif + + if (strcmp (p, "nfs") == 0) + retval = FcFalse; + } +#elif defined(HAVE_FSTATFS) && (defined(HAVE_STRUCT_STATFS_F_FLAGS) || defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) || defined(__linux__)) + struct statfs buf; + + if (fstatfs (fd, &buf) == 0) + { +# if defined(HAVE_STRUCT_STATFS_F_FLAGS) && defined(MNT_LOCAL) + if (!(buf.f_flags & MNT_LOCAL)) +# elif defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) + if (strcmp (buf.f_fstypename, "nfs") == 0) +# elif defined(__linux__) + if (buf.f_type == 0x6969) /* nfs */ +# else +# error "BUG: No way to figure out with fstatfs()" +# endif + retval = FcFalse; + } +#endif + + return retval; +} + static const char bin2hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', @@ -602,10 +675,10 @@ FcDirCacheMapFd (int fd, struct stat *fd_stat, struct stat *dir_stat) } /* - * Lage cache files are mmap'ed, smaller cache files are read. This + * Large cache files are mmap'ed, smaller cache files are read. This * balances the system cost of mmap against per-process memory usage. */ - if (fd_stat->st_size >= FC_CACHE_MIN_MMAP) + if (FcCacheIsMmapSafe (fd) && fd_stat->st_size >= FC_CACHE_MIN_MMAP) { #if defined(HAVE_MMAP) || defined(__CYGWIN__) cache = mmap (0, fd_stat->st_size, PROT_READ, MAP_SHARED, fd, 0); diff --git a/fontconfig/src/fcdefault.c b/fontconfig/src/fcdefault.c index a9165facd..170a8a4d8 100644 --- a/fontconfig/src/fcdefault.c +++ b/fontconfig/src/fcdefault.c @@ -119,7 +119,7 @@ FcGetDefaultLang (void) void FcDefaultSubstitute (FcPattern *pattern) { - FcValue v; + FcValue v, namelang, v2; int i; if (FcPatternObjectGet (pattern, FC_WEIGHT_OBJECT, 0, &v) == FcResultNoMatch ) @@ -175,6 +175,41 @@ FcDefaultSubstitute (FcPattern *pattern) { FcPatternObjectAddInteger (pattern, FC_HINT_STYLE_OBJECT, FC_HINT_FULL); } + if (FcPatternObjectGet (pattern, FC_NAMELANG_OBJECT, 0, &v) == FcResultNoMatch) + { + FcPatternObjectAddString (pattern, FC_NAMELANG_OBJECT, FcGetDefaultLang ()); + } + /* shouldn't be failed. */ + FcPatternObjectGet (pattern, FC_NAMELANG_OBJECT, 0, &namelang); + /* Add a fallback to ensure the english name when the requested language + * isn't available. this would helps for the fonts that have non-English + * name at the beginning. + */ + /* Set "en-us" instead of "en" to avoid giving higher score to "en". + * This is a hack for the case that the orth is not like ll-cc, because, + * if no namelang isn't explicitly set, it will has something like ll-cc + * according to current locale. which may causes FcLangDifferentTerritory + * at FcLangCompare(). thus, the English name is selected so that + * exact matched "en" has higher score than ll-cc. + */ + v2.type = FcTypeString; + v2.u.s = FcSharedStr ((FcChar8 *)"en-us"); + if (FcPatternObjectGet (pattern, FC_FAMILYLANG_OBJECT, 0, &v) == FcResultNoMatch) + { + FcPatternObjectAdd (pattern, FC_FAMILYLANG_OBJECT, namelang, FcTrue); + FcPatternObjectAddWithBinding (pattern, FC_FAMILYLANG_OBJECT, v2, FcValueBindingWeak, FcTrue); + } + if (FcPatternObjectGet (pattern, FC_STYLELANG_OBJECT, 0, &v) == FcResultNoMatch) + { + FcPatternObjectAdd (pattern, FC_STYLELANG_OBJECT, namelang, FcTrue); + FcPatternObjectAddWithBinding (pattern, FC_STYLELANG_OBJECT, v2, FcValueBindingWeak, FcTrue); + } + if (FcPatternObjectGet (pattern, FC_FULLNAMELANG_OBJECT, 0, &v) == FcResultNoMatch) + { + FcPatternObjectAdd (pattern, FC_FULLNAMELANG_OBJECT, namelang, FcTrue); + FcPatternObjectAddWithBinding (pattern, FC_FULLNAMELANG_OBJECT, v2, FcValueBindingWeak, FcTrue); + } + FcSharedStrFree (v2.u.s); } #define __fcdefault__ #include "fcaliastail.h" diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h index bada32550..fb4a64b9d 100644 --- a/fontconfig/src/fcint.h +++ b/fontconfig/src/fcint.h @@ -858,7 +858,8 @@ FcListPatternMatchAny (const FcPattern *p, #define FC_EMBEDDED_BITMAP_OBJECT 39 #define FC_DECORATIVE_OBJECT 40 #define FC_LCD_FILTER_OBJECT 41 -#define FC_MAX_BASE_OBJECT FC_LCD_FILTER_OBJECT +#define FC_NAMELANG_OBJECT 42 +#define FC_MAX_BASE_OBJECT FC_NAMELANG_OBJECT FcPrivate FcBool FcNameBool (const FcChar8 *v, FcBool *result); diff --git a/fontconfig/src/fclist.c b/fontconfig/src/fclist.c index 88025e900..331352cd8 100644 --- a/fontconfig/src/fclist.c +++ b/fontconfig/src/fclist.c @@ -221,7 +221,18 @@ FcListPatternMatchAny (const FcPattern *p, for (i = 0; i < p->num; i++) { FcPatternElt *pe = &FcPatternElts(p)[i]; - FcPatternElt *fe = FcPatternObjectFindElt (font, pe->object); + FcPatternElt *fe; + + if (pe->object == FC_NAMELANG_OBJECT) + { + /* "namelang" object is the alias object to change "familylang", + * "stylelang" and "fullnamelang" object alltogether. it won't be + * available on the font pattern. so checking its availability + * causes no results. we should ignore it here. + */ + continue; + } + fe = FcPatternObjectFindElt (font, pe->object); if (!fe) return FcFalse; if (!FcListValueListMatchAny (FcPatternEltValues(pe), /* pat elts */ @@ -340,13 +351,13 @@ FcListHashTableCleanup (FcListHashTable *table) } static int -FcGetDefaultObjectLangIndex (FcPattern *font, FcObject object) +FcGetDefaultObjectLangIndex (FcPattern *font, FcObject object, const FcChar8 *lang) { - FcChar8 *lang = FcGetDefaultLang (); FcPatternElt *e = FcPatternObjectFindElt (font, object); FcValueListPtr v; FcValue value; int idx = -1; + int defidx = -1; int i; if (e) @@ -363,17 +374,27 @@ FcGetDefaultObjectLangIndex (FcPattern *font, FcObject object) if (res == FcLangDifferentCountry && idx < 0) idx = i; + if (defidx < 0) + { + /* workaround for fonts that has non-English value + * at the head of values. + */ + res = FcLangCompare (value.u.s, (FcChar8 *)"en"); + if (res == FcLangEqual) + defidx = i; + } } } } - return (idx > 0) ? idx : 0; + return (idx > 0) ? idx : (defidx > 0) ? defidx : 0; } static FcBool FcListAppend (FcListHashTable *table, FcPattern *font, - FcObjectSet *os) + FcObjectSet *os, + const FcChar8 *lang) { int o; FcPatternElt *e; @@ -409,19 +430,19 @@ FcListAppend (FcListHashTable *table, if (!strcmp (os->objects[o], FC_FAMILY) || !strcmp (os->objects[o], FC_FAMILYLANG)) { if (familyidx < 0) - familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG_OBJECT); + familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG_OBJECT, lang); defidx = familyidx; } else if (!strcmp (os->objects[o], FC_FULLNAME) || !strcmp (os->objects[o], FC_FULLNAMELANG)) { if (fullnameidx < 0) - fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG_OBJECT); + fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG_OBJECT, lang); defidx = fullnameidx; } else if (!strcmp (os->objects[o], FC_STYLE) || !strcmp (os->objects[o], FC_STYLELANG)) { if (styleidx < 0) - styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG_OBJECT); + styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG_OBJECT, lang); defidx = styleidx; } else @@ -499,8 +520,16 @@ FcFontSetList (FcConfig *config, for (f = 0; f < s->nfont; f++) if (FcListPatternMatchAny (p, /* pattern */ s->fonts[f])) /* font */ - if (!FcListAppend (&table, s->fonts[f], os)) + { + FcChar8 *lang; + + if (FcPatternObjectGetString (p, FC_NAMELANG_OBJECT, 0, &lang) != FcResultMatch) + { + lang = FcGetDefaultLang (); + } + if (!FcListAppend (&table, s->fonts[f], os, lang)) goto bail1; + } } #if 0 { diff --git a/fontconfig/src/fcmatch.c b/fontconfig/src/fcmatch.c index 655e62cf5..623538bd3 100644 --- a/fontconfig/src/fcmatch.c +++ b/fontconfig/src/fcmatch.c @@ -240,7 +240,8 @@ static const FcMatcher _FcMatchers [] = { #define NUM_MATCH_VALUES 17 static const FcMatcher* -FcObjectToMatcher (FcObject object) +FcObjectToMatcher (FcObject object, + FcBool include_lang) { int i; @@ -278,6 +279,16 @@ FcObjectToMatcher (FcObject object) i = MATCH_OUTLINE; break; case FC_DECORATIVE_OBJECT: i = MATCH_DECORATIVE; break; + default: + if (include_lang) + { + switch (object) { + case FC_FAMILYLANG_OBJECT: + case FC_STYLELANG_OBJECT: + case FC_FULLNAMELANG_OBJECT: + i = MATCH_LANG; break; + } + } } if (i < 0) @@ -287,22 +298,25 @@ FcObjectToMatcher (FcObject object) } static FcBool -FcCompareValueList (FcObject object, - FcValueListPtr v1orig, /* pattern */ - FcValueListPtr v2orig, /* target */ - FcValue *bestValue, - double *value, - FcResult *result) +FcCompareValueList (FcObject object, + const FcMatcher *match, + FcValueListPtr v1orig, /* pattern */ + FcValueListPtr v2orig, /* target */ + FcValue *bestValue, + double *value, + int *n, + FcResult *result) { FcValueListPtr v1, v2; double v, best, bestStrong, bestWeak; - int j; - const FcMatcher *match = FcObjectToMatcher(object); + int j, k, pos = 0; if (!match) { if (bestValue) *bestValue = FcValueCanonicalize(&v2orig->value); + if (n) + *n = 0; return FcTrue; } @@ -312,7 +326,7 @@ FcCompareValueList (FcObject object, j = 1; for (v1 = v1orig; v1; v1 = FcValueListNext(v1)) { - for (v2 = v2orig; v2; v2 = FcValueListNext(v2)) + for (v2 = v2orig, k = 0; v2; v2 = FcValueListNext(v2), k++) { v = (match->compare) (&v1->value, &v2->value); if (v < 0) @@ -326,6 +340,7 @@ FcCompareValueList (FcObject object, if (bestValue) *bestValue = FcValueCanonicalize(&v2->value); best = v; + pos = k; } if (v1->binding == FcValueBindingStrong) { @@ -360,6 +375,9 @@ FcCompareValueList (FcObject object, value[strong] += bestStrong; } } + if (n) + *n = pos; + return FcTrue; } @@ -393,10 +411,11 @@ FcCompare (FcPattern *pat, i1++; else { - if (!FcCompareValueList (elt_i1->object, + const FcMatcher *match = FcObjectToMatcher (elt_i1->object, FcFalse); + if (!FcCompareValueList (elt_i1->object, match, FcPatternEltValues(elt_i1), FcPatternEltValues(elt_i2), - 0, value, result)) + NULL, value, NULL, result)) return FcFalse; i1++; i2++; @@ -412,8 +431,8 @@ FcFontRenderPrepare (FcConfig *config, { FcPattern *new; int i; - FcPatternElt *fe, *pe; - FcValue v; + FcPatternElt *fe, *pe, *fel, *pel; + FcValue v, vl; FcResult result; assert (pat != NULL); @@ -425,19 +444,81 @@ FcFontRenderPrepare (FcConfig *config, for (i = 0; i < font->num; i++) { fe = &FcPatternElts(font)[i]; + if (fe->object == FC_FAMILYLANG_OBJECT || + fe->object == FC_STYLELANG_OBJECT || + fe->object == FC_FULLNAMELANG_OBJECT) + { + /* ignore those objects. we need to deal with them + * another way */ + continue; + } + if (fe->object == FC_FAMILY_OBJECT || + fe->object == FC_STYLE_OBJECT || + fe->object == FC_FULLNAME_OBJECT) + { + FC_ASSERT_STATIC ((FC_FAMILY_OBJECT + 1) == FC_FAMILYLANG_OBJECT); + FC_ASSERT_STATIC ((FC_STYLE_OBJECT + 1) == FC_STYLELANG_OBJECT); + FC_ASSERT_STATIC ((FC_FULLNAME_OBJECT + 1) == FC_FULLNAMELANG_OBJECT); + + fel = FcPatternObjectFindElt (font, fe->object + 1); + pel = FcPatternObjectFindElt (pat, fe->object + 1); + } + else + { + fel = NULL; + pel = NULL; + } pe = FcPatternObjectFindElt (pat, fe->object); if (pe) { - if (!FcCompareValueList (pe->object, FcPatternEltValues(pe), - FcPatternEltValues(fe), &v, 0, &result)) + const FcMatcher *match = FcObjectToMatcher (pe->object, FcFalse); + + if (!FcCompareValueList (pe->object, match, + FcPatternEltValues(pe), + FcPatternEltValues(fe), &v, NULL, NULL, &result)) { FcPatternDestroy (new); return 0; } + if (fel && pel) + { + int n = 1, j; + + match = FcObjectToMatcher (pel->object, FcTrue); + if (!FcCompareValueList (pel->object, match, + FcPatternEltValues (pel), + FcPatternEltValues (fel), &vl, NULL, &n, &result)) + { + FcPatternDestroy (new); + return NULL; + } + else + { + FcValueListPtr l; + + for (j = 0, l = FcPatternEltValues (fe); + j < n && l != NULL; + j++, l = FcValueListNext (l)); + if (l) + v = FcValueCanonicalize (&l->value); + else + v = FcValueCanonicalize (&FcPatternEltValues (fe)->value); + } + } + else if (fel) + { + vl = FcValueCanonicalize (&FcPatternEltValues (fel)->value); + } } else + { v = FcValueCanonicalize(&FcPatternEltValues (fe)->value); + if (fel) + vl = FcValueCanonicalize (&FcPatternEltValues (fel)->value); + } FcPatternObjectAdd (new, fe->object, v, FcFalse); + if (fel) + FcPatternObjectAdd (new, fel->object, vl, FcFalse); } for (i = 0; i < pat->num; i++) { diff --git a/fontconfig/src/fcname.c b/fontconfig/src/fcname.c index d0b1ca84c..d51307bec 100644 --- a/fontconfig/src/fcname.c +++ b/fontconfig/src/fcname.c @@ -76,6 +76,7 @@ static const FcObjectType _FcBaseObjectTypes[] = { { FC_EMBEDDED_BITMAP, FcTypeBool }, { FC_DECORATIVE, FcTypeBool }, { FC_LCD_FILTER, FcTypeInteger }, /* 41 */ + { FC_NAMELANG, FcTypeString }, /* 42 */ }; #define NUM_OBJECT_TYPES (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0]) |