diff options
Diffstat (limited to 'fontconfig')
-rw-r--r-- | fontconfig/README | 40 | ||||
-rw-r--r-- | fontconfig/configure.ac | 2 | ||||
-rw-r--r-- | fontconfig/doc/fontconfig-devel.sgml | 1 | ||||
-rw-r--r-- | fontconfig/doc/fontconfig-user.sgml | 6 | ||||
-rw-r--r-- | fontconfig/fontconfig/fontconfig.h | 10 | ||||
-rw-r--r-- | fontconfig/src/fccache.c | 6 | ||||
-rw-r--r-- | fontconfig/src/fcdbg.c | 88 | ||||
-rw-r--r-- | fontconfig/src/fcdefault.c | 1 | ||||
-rw-r--r-- | fontconfig/src/fcfreetype.c | 80 | ||||
-rw-r--r-- | fontconfig/src/fcinit.c | 28 | ||||
-rw-r--r-- | fontconfig/src/fcint.h | 41 | ||||
-rw-r--r-- | fontconfig/src/fcmatch.c | 44 | ||||
-rw-r--r-- | fontconfig/src/fcname.c | 20 | ||||
-rw-r--r-- | fontconfig/src/fcobjs.c | 31 | ||||
-rw-r--r-- | fontconfig/src/fcobjs.h | 1 | ||||
-rw-r--r-- | fontconfig/src/fcpat.c | 6 | ||||
-rw-r--r-- | fontconfig/src/fcrange.c | 109 | ||||
-rw-r--r-- | fontconfig/src/fcxml.c | 63 |
18 files changed, 385 insertions, 192 deletions
diff --git a/fontconfig/README b/fontconfig/README index 4a4dc307b..8f04b9b3c 100644 --- a/fontconfig/README +++ b/fontconfig/README @@ -1,12 +1,48 @@ Fontconfig Font configuration and customization library - Version 2.11.93 (2.12 RC3) - 2015-03-09 + Version 2.11.94 (2.12 RC4) + 2015-06-02 Check INSTALL for compilation and installation instructions. Report bugs to https://bugs.freedesktop.org in the fontconfig module. +2.11.94 (2.12 RC4) + +Akira TAGOH (16): + Remove the dead code + Bug 89617 - FcConfigAppFontAddFile() returns false on any font file + Fix unknown attribute in Win32 + Fix SIGFPE + Fix a typo for the latest cache version + Fix a typo in fontconfig-user.sgml + Drop unmaintained code + Observe blanks to compute correct languages in fc-query/fc-scan + Add missing description for usage + Make FC_SCALE deprecated + Bug 90148 - Don't warn if cachedir isn't specified + Fix memory leaks after FcFini() + Fix a typo + Fix a crash + Detect the overflow for the object ID + Revert the previous change + +Behdad Esfahbod (11): + Fix bitmap scaling + Add su[pport for symbol fonts + Write ranges using a [start finish) format + Only set FC_SIZE for scalable fonts if OS/2 version 5 is present + Add bitmap-only font size as Double, not Range + Accept Integer for FC_SIZE + Don't set FC_SIZE for bitmap fonts + Fix compiler warnings + Simplify FcRange + Reduce number of places that cache version is specified to 1 + Bump cache version number to 6, because of recent FcRange changes + +Руслан Ижбулатов (1): + W32: Support cache paths relative to the root directory + 2.11.93 (2.12 RC3) Akira TAGOH (18): diff --git a/fontconfig/configure.ac b/fontconfig/configure.ac index bb9880487..e888f2c9e 100644 --- a/fontconfig/configure.ac +++ b/fontconfig/configure.ac @@ -33,7 +33,7 @@ dnl This is the package version number, not the shared library dnl version. This same version number must appear in fontconfig/fontconfig.h dnl Yes, it is a pain to synchronize version numbers. Unfortunately, it's dnl not possible to extract the version number here from fontconfig.h -AC_INIT([fontconfig], [2.11.93], [https://bugs.freedesktop.org/enter_bug.cgi?product=fontconfig]) +AC_INIT([fontconfig], [2.11.94], [https://bugs.freedesktop.org/enter_bug.cgi?product=fontconfig]) AM_INIT_AUTOMAKE([1.11 parallel-tests dist-bzip2]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) diff --git a/fontconfig/doc/fontconfig-devel.sgml b/fontconfig/doc/fontconfig-devel.sgml index 17402c7bc..d0ec8a579 100644 --- a/fontconfig/doc/fontconfig-devel.sgml +++ b/fontconfig/doc/fontconfig-devel.sgml @@ -177,6 +177,7 @@ convenience for the application's rendering mechanism. scalable FC_SCALABLE Bool Whether glyphs can be scaled scale FC_SCALE Double Scale factor for point->pixel conversions (deprecated) + symbol FC_SYMBOL Bool Whether font uses MS symbol-font encoding color FC_COLOR Bool Whether any glyphs have color dpi FC_DPI Double Target dots per inch rgba FC_RGBA Int unknown, rgb, bgr, vrgb, diff --git a/fontconfig/doc/fontconfig-user.sgml b/fontconfig/doc/fontconfig-user.sgml index e7cdb2e77..8f49f78ed 100644 --- a/fontconfig/doc/fontconfig-user.sgml +++ b/fontconfig/doc/fontconfig-user.sgml @@ -258,7 +258,7 @@ debugging messages. MEMORY 512 Monitor fontconfig memory usage CONFIG 1024 Monitor which config files are loaded LANGSET 2048 Dump char sets used to construct lang values - OBJTYPES 4096 Display message when value typechecks fail + MATCH2 4096 Display font-matching transformation in patterns </programlisting> <para> Add the value of the desired debug levels together and assign that (in @@ -787,6 +787,10 @@ is used to override the default configuration directory. is used to output the detailed debugging messages. see <link linkend="debug">Debugging Applications</link> section for more details. </para> <para> +<emphasis>FC_DBG_MATCH_FILTER</emphasis> +is used to filter out the patterns. this takes a comma-separated list of object names and effects only when FC_DEBUG has MATCH2. 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> diff --git a/fontconfig/fontconfig/fontconfig.h b/fontconfig/fontconfig/fontconfig.h index 58b6b5137..a570b2f5c 100644 --- a/fontconfig/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig/fontconfig.h @@ -52,7 +52,7 @@ typedef int FcBool; #define FC_MAJOR 2 #define FC_MINOR 11 -#define FC_REVISION 93 +#define FC_REVISION 94 #define FC_VERSION ((FC_MAJOR * 10000) + (FC_MINOR * 100) + (FC_REVISION)) @@ -66,7 +66,10 @@ typedef int FcBool; * it means multiple copies of the font information. */ -#define FC_CACHE_VERSION "5" +#define FC_CACHE_VERSION_NUMBER 6 +#define _FC_STRINGIFY_(s) #s +#define _FC_STRINGIFY(s) _FC_STRINGIFY_(s) +#define FC_CACHE_VERSION _FC_STRINGIFY(FC_CACHE_VERSION_NUMBER) #define FcTrue 1 #define FcFalse 0 @@ -96,6 +99,7 @@ typedef int FcBool; #define FC_SCALABLE "scalable" /* Bool */ #define FC_COLOR "color" /* Bool */ #define FC_SCALE "scale" /* double (deprecated) */ +#define FC_SYMBOL "symbol" /* Bool */ #define FC_DPI "dpi" /* double */ #define FC_RGBA "rgba" /* Int */ #define FC_MINSPACE "minspace" /* Bool use minimum line spacing */ @@ -216,7 +220,7 @@ typedef struct _FcMatrix { typedef struct _FcCharSet FcCharSet; typedef struct _FcObjectType { - const char *object; + char *object; FcType type; } FcObjectType; diff --git a/fontconfig/src/fccache.c b/fontconfig/src/fccache.c index 25538bd70..fc3ed410a 100644 --- a/fontconfig/src/fccache.c +++ b/fontconfig/src/fccache.c @@ -655,7 +655,7 @@ FcDirCacheMapFd (FcConfig *config, int fd, struct stat *fd_stat, struct stat *di allocated = FcTrue; } if (cache->magic != FC_CACHE_MAGIC_MMAP || - cache->version < FC_CACHE_CONTENT_VERSION || + cache->version < FC_CACHE_VERSION_NUMBER || cache->size != (intptr_t) fd_stat->st_size || !FcCacheTimeValid (config, cache, dir_stat) || !FcCacheDirsValid (config, cache) || @@ -751,7 +751,7 @@ FcDirCacheValidateHelper (FcConfig *config, int fd, struct stat *fd_stat, struct ret = FcFalse; else if (c.magic != FC_CACHE_MAGIC_MMAP) ret = FcFalse; - else if (c.version < FC_CACHE_CONTENT_VERSION) + else if (c.version < FC_CACHE_VERSION_NUMBER) ret = FcFalse; else if (fd_stat->st_size != c.size) ret = FcFalse; @@ -828,7 +828,7 @@ FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcSt serialize->linear = cache; cache->magic = FC_CACHE_MAGIC_ALLOC; - cache->version = FC_CACHE_CONTENT_VERSION; + cache->version = FC_CACHE_VERSION_NUMBER; cache->size = serialize->size; cache->checksum = (int) dir_stat->st_mtime; diff --git a/fontconfig/src/fcdbg.c b/fontconfig/src/fcdbg.c index ef038f017..c2853fff3 100644 --- a/fontconfig/src/fcdbg.c +++ b/fontconfig/src/fcdbg.c @@ -29,8 +29,6 @@ static void _FcValuePrintFile (FILE *f, const FcValue v) { - FcRange r; - switch (v.type) { case FcTypeUnknown: fprintf (f, "<unknown>"); @@ -64,8 +62,7 @@ _FcValuePrintFile (FILE *f, const FcValue v) fprintf (f, "face"); break; case FcTypeRange: - r = FcRangeCanonicalize (v.u.r); - fprintf (f, "(%g, %g)", r.u.d.begin, r.u.d.end); + fprintf (f, "[%g %g)", v.u.r->begin, v.u.r->end); break; } } @@ -214,6 +211,84 @@ FcPatternPrint (const FcPattern *p) } void +FcPatternPrint2 (FcPattern *pp1, + FcPattern *pp2, + const FcObjectSet *os) +{ + int i, j, k, pos; + FcPatternElt *e1, *e2; + FcPattern *p1, *p2; + + if (os) + { + p1 = FcPatternFilter (pp1, os); + p2 = FcPatternFilter (pp2, os); + } + else + { + p1 = pp1; + p2 = pp2; + } + printf ("Pattern has %d elts (size %d), %d elts (size %d)\n", + p1->num, p1->size, p2->num, p2->size); + for (i = 0, j = 0; i < p1->num; i++) + { + e1 = &FcPatternElts(p1)[i]; + e2 = &FcPatternElts(p2)[j]; + if (!e2 || e1->object != e2->object) + { + pos = FcPatternPosition (p2, FcObjectName (e1->object)); + if (pos >= 0) + { + for (k = j; k < pos; k++) + { + e2 = &FcPatternElts(p2)[k]; + printf ("\t%s: (None) -> ", FcObjectName (e2->object)); + FcValueListPrint (FcPatternEltValues (e2)); + printf ("\n"); + } + j = pos; + goto cont; + } + else + { + printf ("\t%s:", FcObjectName (e1->object)); + FcValueListPrint (FcPatternEltValues (e1)); + printf (" -> (None)\n"); + } + } + else + { + cont: + printf ("\t%s:", FcObjectName (e1->object)); + FcValueListPrint (FcPatternEltValues (e1)); + printf (" -> "); + e2 = &FcPatternElts(p2)[j]; + FcValueListPrint (FcPatternEltValues (e2)); + printf ("\n"); + j++; + } + } + if (j < p2->num) + { + for (k = j; k < p2->num; k++) + { + e2 = &FcPatternElts(p2)[k]; + if (FcObjectName (e2->object)) + { + printf ("\t%s: (None) -> ", FcObjectName (e2->object)); + FcValueListPrint (FcPatternEltValues (e2)); + printf ("\n"); + } + } + } + if (p1 != pp1) + FcPatternDestroy (p1); + if (p2 != pp2) + FcPatternDestroy (p2); +} + +void FcOpPrint (FcOp op_) { FcOp op = FC_OP_GET_OP (op_); @@ -267,8 +342,6 @@ FcOpPrint (FcOp op_) void FcExprPrint (const FcExpr *expr) { - FcRange r; - if (!expr) printf ("none"); else switch (FC_OP_GET_OP (expr->op)) { case FcOpInteger: printf ("%d", expr->u.ival); break; @@ -286,8 +359,7 @@ FcExprPrint (const FcExpr *expr) printf ("]"); break; case FcOpRange: - r = FcRangeCanonicalize (expr->u.rval); - printf ("(%g, %g)", r.u.d.begin, r.u.d.end); + printf ("(%g, %g)", expr->u.rval->begin, expr->u.rval->end); break; case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break; case FcOpCharSet: printf ("charset\n"); break; diff --git a/fontconfig/src/fcdefault.c b/fontconfig/src/fcdefault.c index 7c16f4841..4643e46dc 100644 --- a/fontconfig/src/fcdefault.c +++ b/fontconfig/src/fcdefault.c @@ -38,6 +38,7 @@ static const struct { { FC_GLOBAL_ADVANCE_OBJECT, FcTrue }, /* !FC_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ { FC_EMBEDDED_BITMAP_OBJECT, FcTrue }, /* !FC_LOAD_NO_BITMAP */ { FC_DECORATIVE_OBJECT, FcFalse }, + { FC_SYMBOL_OBJECT, FcFalse }, }; #define NUM_FC_BOOL_DEFAULTS (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0]) diff --git a/fontconfig/src/fcfreetype.c b/fontconfig/src/fcfreetype.c index afbd9ac1e..809ff2992 100644 --- a/fontconfig/src/fcfreetype.c +++ b/fontconfig/src/fcfreetype.c @@ -1199,7 +1199,8 @@ FcFreeTypeQueryFace (const FT_Face face, const char *tmp; FcRange *r = NULL; - double lower_size = 0.0L, upper_size = DBL_MAX; + + FcBool symbol = FcFalse; FcInitDebug (); /* We might be called with no initizalization whatsoever. */ @@ -1615,13 +1616,12 @@ FcFreeTypeQueryFace (const FT_Face face, #if defined (HAVE_TT_OS2_USUPPEROPTICALPOINTSIZE) && defined (HAVE_TT_OS2_USLOWEROPTICALPOINTSIZE) if (os2 && os2->version >= 0x0005 && os2->version != 0xffff) { + double lower_size, upper_size; + /* usLowerPointSize and usUpperPointSize is actually twips */ lower_size = os2->usLowerOpticalPointSize / 20.0L; upper_size = os2->usUpperOpticalPointSize / 20.0L; - } -#endif - if (os2) - { + r = FcRangeCreateDouble (lower_size, upper_size); if (!FcPatternAddRange (pat, FC_SIZE, r)) { @@ -1630,20 +1630,7 @@ FcFreeTypeQueryFace (const FT_Face face, } FcRangeDestroy (r); } - else - { - for (i = 0; i < face->num_fixed_sizes; i++) - { - double d = FcGetPixelSize (face, i); - r = FcRangeCreateDouble (d, d); - if (!FcPatternAddRange (pat, FC_SIZE, r)) - { - FcRangeDestroy (r); - goto bail1; - } - FcRangeDestroy (r); - } - } +#endif /* * Type 1: Check for FontInfo dictionary information @@ -1803,6 +1790,11 @@ FcFreeTypeQueryFace (const FT_Face face, if (!cs) goto bail1; + /* The FcFreeTypeCharSetAndSpacing() chose the encoding; test it for symbol. */ + symbol = face->charmap && face->charmap->encoding == FT_ENCODING_MS_SYMBOL; + if (!FcPatternAddBool (pat, FC_SYMBOL, symbol)) + goto bail1; + #if HAVE_FT_GET_BDF_PROPERTY /* For PCF fonts, override the computed spacing with the one from the property */ @@ -1835,9 +1827,18 @@ FcFreeTypeQueryFace (const FT_Face face, if (!FcPatternAddCharSet (pat, FC_CHARSET, cs)) goto bail2; - ls = FcFreeTypeLangSet (cs, exclusiveLang); - if (!ls) - goto bail2; + if (!symbol) + { + ls = FcFreeTypeLangSet (cs, exclusiveLang); + if (!ls) + goto bail2; + } + else + { + /* Symbol fonts don't cover any language, even though they + * claim to support Latin1 range. */ + ls = FcLangSetCreate (); + } if (!FcPatternAddLangSet (pat, FC_LANG, ls)) { @@ -2093,6 +2094,22 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4) glyphindex = FT_Get_Char_Index (face, (FT_ULong) ucs4); if (glyphindex) return glyphindex; + if (ucs4 < 0x100 && face->charmap && + face->charmap->encoding == FT_ENCODING_MS_SYMBOL) + { + /* For symbol-encoded OpenType fonts, we duplicate the + * U+F000..F0FF range at U+0000..U+00FF. That's what + * Windows seems to do, and that's hinted about at: + * http://www.microsoft.com/typography/otspec/recom.htm + * under "Non-Standard (Symbol) Fonts". + * + * See thread with subject "Webdings and other MS symbol + * fonts don't display" on mailing list from May 2015. + */ + glyphindex = FT_Get_Char_Index (face, (FT_ULong) ucs4 + 0xF000); + if (glyphindex) + return glyphindex; + } } #if HAVE_FT_HAS_PS_GLYPH_NAMES /* @@ -2253,6 +2270,23 @@ FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing } ucs4 = FT_Get_Next_Char (face, ucs4, &glyph); } + if (fcFontEncodings[o] == FT_ENCODING_MS_SYMBOL) + { + /* For symbol-encoded OpenType fonts, we duplicate the + * U+F000..F0FF range at U+0000..U+00FF. That's what + * Windows seems to do, and that's hinted about at: + * http://www.microsoft.com/typography/otspec/recom.htm + * under "Non-Standard (Symbol) Fonts". + * + * See thread with subject "Webdings and other MS symbol + * fonts don't display" on mailing list from May 2015. + */ + for (ucs4 = 0xF000; ucs4 < 0xF100; ucs4++) + { + if (FcCharSetHasChar (fcs, ucs4)) + FcCharSetAddChar (fcs, ucs4 - 0xF000); + } + } #ifdef CHECK for (ucs4 = 0; ucs4 < 0x10000; ucs4++) { @@ -2267,6 +2301,8 @@ FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing } #endif } + + break; } #if HAVE_FT_HAS_PS_GLYPH_NAMES /* diff --git a/fontconfig/src/fcinit.c b/fontconfig/src/fcinit.c index 6134ed40d..5e7c2f156 100644 --- a/fontconfig/src/fcinit.c +++ b/fontconfig/src/fcinit.c @@ -91,12 +91,23 @@ FcInitLoadOwnConfig (FcConfig *config) { FcChar8 *prefix, *p; size_t plen; + FcBool have_own = FcFalse; + char *env_file, *env_path; - fprintf (stderr, - "Fontconfig warning: no <cachedir> elements found. Check configuration.\n"); - fprintf (stderr, - "Fontconfig warning: adding <cachedir>%s</cachedir>\n", - FC_CACHEDIR); + env_file = getenv ("FONTCONFIG_FILE"); + env_path = getenv ("FONTCONFIG_PATH"); + if ((env_file != NULL && env_file[0] != 0) || + (env_path != NULL && env_path[0] != 0)) + have_own = FcTrue; + + if (!have_own) + { + fprintf (stderr, + "Fontconfig warning: no <cachedir> elements found. Check configuration.\n"); + fprintf (stderr, + "Fontconfig warning: adding <cachedir>%s</cachedir>\n", + FC_CACHEDIR); + } prefix = FcConfigXdgCacheHome (); if (!prefix) goto bail; @@ -107,8 +118,9 @@ FcInitLoadOwnConfig (FcConfig *config) prefix = p; memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11); prefix[plen + 11] = 0; - fprintf (stderr, - "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n"); + if (!have_own) + fprintf (stderr, + "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n"); if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) || !FcConfigAddCacheDir (config, (FcChar8 *) prefix)) @@ -180,6 +192,8 @@ FcFini (void) FcConfigFini (); FcCacheFini (); FcDefaultFini (); + FcObjectFini (); + FcConfigPathFini (); } /* diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h index 80205c950..15e22fdbc 100644 --- a/fontconfig/src/fcint.h +++ b/fontconfig/src/fcint.h @@ -87,6 +87,7 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA; #define FC_DBG_SCANV 256 #define FC_DBG_CONFIG 1024 #define FC_DBG_LANGSET 2048 +#define FC_DBG_MATCH2 4096 #define _FC_ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] FC_UNUSED #define _FC_ASSERT_STATIC0(_line, _cond) _FC_ASSERT_STATIC1 (_line, (_cond)) @@ -96,11 +97,6 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA; #define FC_MAX(a,b) ((a) > (b) ? (a) : (b)) #define FC_ABS(a) ((a) < 0 ? -(a) : (a)) -#define FcDoubleIsZero(a) (fabs ((a)) <= DBL_EPSILON) -#define FcDoubleCmpEQ(a,b) (fabs ((a) - (b)) <= DBL_EPSILON) -#define FcDoubleCmpGE(a,b) (FcDoubleCmpEQ (a, b) || (a) > (b)) -#define FcDoubleCmpLE(a,b) (FcDoubleCmpEQ (a, b) || (a) < (b)) - /* slim_internal.h */ #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun) #define FcPrivate __attribute__((__visibility__("hidden"))) @@ -252,21 +248,9 @@ typedef struct _FcExprName { FcMatchKind kind; } FcExprName; -typedef struct _FcRangeInt { - FcChar32 begin; - FcChar32 end; -} FcRangeInt; -typedef struct _FcRangeDouble { +struct _FcRange { double begin; double end; -} FcRangeDouble; -struct _FcRange { - FcBool is_double; - FcBool is_inclusive; - union { - FcRangeInt i; - FcRangeDouble d; - } u; }; @@ -378,7 +362,7 @@ typedef struct _FcStrBuf { struct _FcCache { unsigned int magic; /* FC_CACHE_MAGIC_MMAP or FC_CACHE_ALLOC */ - int version; /* FC_CACHE_CONTENT_VERSION */ + int version; /* FC_CACHE_VERSION_NUMBER */ intptr_t size; /* size of file */ intptr_t dir; /* offset to dir name */ intptr_t dirs; /* offset to subdirs */ @@ -470,7 +454,6 @@ typedef struct _FcCaseFold { #define FC_CACHE_MAGIC_MMAP 0xFC02FC04 #define FC_CACHE_MAGIC_ALLOC 0xFC02FC05 -#define FC_CACHE_CONTENT_VERSION 5 struct _FcAtomic { FcChar8 *file; /* original file name */ @@ -811,6 +794,9 @@ FcSubstPrint (const FcSubst *subst); FcPrivate void FcCharSetPrint (const FcCharSet *c); +FcPrivate void +FcPatternPrint2 (FcPattern *p1, FcPattern *p2, const FcObjectSet *os); + extern FcPrivate int FcDebugVal; #define FcDebug() (FcDebugVal) @@ -881,6 +867,9 @@ FcInitLoadOwnConfigAndFonts (FcConfig *config); /* fcxml.c */ FcPrivate void +FcConfigPathFini (void); + +FcPrivate void FcTestDestroy (FcTest *test); FcPrivate void @@ -1054,6 +1043,9 @@ FcPatternObjectGetRange (const FcPattern *p, FcObject object, int id, FcRange ** FcPrivate FcBool FcPatternAppend (FcPattern *p, FcPattern *s); +FcPrivate int +FcPatternPosition (const FcPattern *p, const char *object); + FcPrivate FcChar32 FcStringHash (const FcChar8 *s); @@ -1080,16 +1072,10 @@ FcMatrixFree (FcMatrix *mat); /* fcrange.c */ -FcPrivate FcRange -FcRangeCanonicalize (const FcRange *range); - FcPrivate FcRange * FcRangePromote (double v, FcValuePromotionBuffer *vbuf); FcPrivate FcBool -FcRangeIsZero (const FcRange *r); - -FcPrivate FcBool FcRangeIsInRange (const FcRange *a, const FcRange *b); FcPrivate FcBool @@ -1192,6 +1178,9 @@ FcStrSerialize (FcSerialize *serialize, const FcChar8 *str); /* fcobjs.c */ +FcPrivate void +FcObjectFini (void); + FcPrivate FcObject FcObjectLookupIdByName (const char *str); diff --git a/fontconfig/src/fcmatch.c b/fontconfig/src/fcmatch.c index 46d08bcc7..40efbd3f6 100644 --- a/fontconfig/src/fcmatch.c +++ b/fontconfig/src/fcmatch.c @@ -220,7 +220,7 @@ FcCompareSizeRange (FcValue *v1, FcValue *v2) if (FcRangeIsInRange (r1, r2)) ret = 0.0; else - ret = FC_MIN (fabs (r1->u.d.end - r2->u.d.begin), fabs (r1->u.d.begin - r2->u.d.end)); + ret = FC_MIN (fabs (r1->end - r2->begin), fabs (r1->begin - r2->end)); bail: if (r1) @@ -292,6 +292,7 @@ typedef enum _FcMatcherPriority { PRI1(LANG), PRI_FAMILY_WEAK, PRI_POSTSCRIPT_NAME_WEAK, + PRI1(SYMBOL), PRI1(SPACING), PRI1(SIZE), PRI1(PIXEL_SIZE), @@ -688,6 +689,47 @@ FcFontSetMatchInternal (FcFontSet **sets, printf ("\n"); FcPatternPrint (best); } + if (FcDebug () & FC_DBG_MATCH2) + { + char *env = getenv ("FC_DBG_MATCH_FILTER"); + FcObjectSet *os = NULL; + + if (env) + { + char *ss, *s; + char *p; + FcBool f = FcTrue; + + ss = s = strdup (env); + os = FcObjectSetCreate (); + while (f) + { + size_t len; + char *x; + + if (!(p = strchr (s, ','))) + { + f = FcFalse; + len = strlen (s) + 1; + } + else + { + len = (p - s) + 1; + } + x = malloc (sizeof (char) * len); + strncpy (x, s, len - 1); + x[len - 1] = 0; + if (FcObjectFromName (x) > 0) + FcObjectSetAdd (os, x); + s = p + 1; + free (x); + } + free (ss); + } + FcPatternPrint2 (p, best, os); + if (os) + FcObjectSetDestroy (os); + } /* assuming that 'result' is initialized with FcResultNoMatch * outside this function */ if (best) diff --git a/fontconfig/src/fcname.c b/fontconfig/src/fcname.c index 1d8fe757c..8be36c70c 100644 --- a/fontconfig/src/fcname.c +++ b/fontconfig/src/fcname.c @@ -88,7 +88,9 @@ FcObjectValidType (FcObject object, FcType type) return FcTrue; break; case FcTypeRange: - if (type == FcTypeRange || type == FcTypeDouble) + if (type == FcTypeRange || + type == FcTypeDouble || + type == FcTypeInteger) return FcTrue; break; default: @@ -316,7 +318,7 @@ FcNameConvert (FcType type, FcChar8 *string) v.type = FcTypeVoid; break; case FcTypeRange: - if (sscanf ((char *) string, "(%lg %lg)", &b, &e) != 2) + if (sscanf ((char *) string, "[%lg %lg)", &b, &e) != 2) { v.u.d = strtod ((char *) string, &p); if (p != NULL && p[0] != 0) @@ -498,7 +500,6 @@ FcNameUnparseValue (FcStrBuf *buf, { FcChar8 temp[1024]; FcValue v = FcValueCanonicalize(v0); - FcRange r; switch (v.type) { case FcTypeUnknown: @@ -525,17 +526,8 @@ FcNameUnparseValue (FcStrBuf *buf, case FcTypeFTFace: return FcTrue; case FcTypeRange: - r = FcRangeCanonicalize (v.u.r); - if (!FcDoubleIsZero (r.u.d.begin) || !FcDoubleIsZero (r.u.d.end)) - { - if (FcDoubleCmpEQ (r.u.d.begin, r.u.d.end)) - sprintf ((char *) temp, "%g", r.u.d.begin); - else - sprintf ((char *) temp, "(%g %g)", r.u.d.begin, r.u.d.end); - return FcNameUnparseString (buf, temp, 0); - } - else - return FcTrue; + sprintf ((char *) temp, "[%g %g)", v.u.r->begin, v.u.r->end); + return FcNameUnparseString (buf, temp, 0); } return FcFalse; } diff --git a/fontconfig/src/fcobjs.c b/fontconfig/src/fcobjs.c index bad9824d4..16ff31c47 100644 --- a/fontconfig/src/fcobjs.c +++ b/fontconfig/src/fcobjs.c @@ -44,6 +44,28 @@ struct FcObjectOtherTypeInfo { FcObject id; } *other_types; +void +FcObjectFini (void) +{ + struct FcObjectOtherTypeInfo *ots, *ot; + +retry: + ots = fc_atomic_ptr_get (&other_types); + if (!ots) + return; + if (!fc_atomic_ptr_cmpexch (&other_types, ots, NULL)) + goto retry; + + while (ots) + { + ot = ots->next; + if (ots->object.object) + free (ots->object.object); + free (ots); + ots = ot; + } +} + static FcObjectType * _FcObjectLookupOtherTypeByName (const char *str, FcObject *id) { @@ -62,12 +84,19 @@ retry: if (!ot) return NULL; - ot->object.object = (const char *) FcStrdup (str); + ot->object.object = (char *) FcStrdup (str); ot->object.type = FcTypeUnknown; ot->id = fc_atomic_int_add (next_id, +1); + if (ot->id < (FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX)) + { + fprintf (stderr, "Fontconfig error: No object ID to assign\n"); + abort (); + } ot->next = ots; if (!fc_atomic_ptr_cmpexch (&other_types, ots, ot)) { + if (ot->object.object) + free (ot->object.object); free (ot); goto retry; } diff --git a/fontconfig/src/fcobjs.h b/fontconfig/src/fcobjs.h index 573fa610d..1fc4f656b 100644 --- a/fontconfig/src/fcobjs.h +++ b/fontconfig/src/fcobjs.h @@ -69,4 +69,5 @@ FC_OBJECT (PRGNAME, FcTypeString, NULL) FC_OBJECT (HASH, FcTypeString, NULL) /* deprecated */ FC_OBJECT (POSTSCRIPT_NAME, FcTypeString, FcComparePostScript) FC_OBJECT (COLOR, FcTypeBool, FcCompareBool) +FC_OBJECT (SYMBOL, FcTypeBool, FcCompareBool) /* ^-------------- Add new objects here. */ diff --git a/fontconfig/src/fcpat.c b/fontconfig/src/fcpat.c index 7e7d54a4e..3ef1ed212 100644 --- a/fontconfig/src/fcpat.c +++ b/fontconfig/src/fcpat.c @@ -425,6 +425,12 @@ FcPatternObjectPosition (const FcPattern *p, FcObject object) return -(mid + 1); } +int +FcPatternPosition (const FcPattern *p, const char *object) +{ + return FcPatternObjectPosition (p, FcObjectFromName (object)); +} + FcPatternElt * FcPatternObjectFindElt (const FcPattern *p, FcObject object) { diff --git a/fontconfig/src/fcrange.c b/fontconfig/src/fcrange.c index 9b1b67b82..f70226c55 100644 --- a/fontconfig/src/fcrange.c +++ b/fontconfig/src/fcrange.c @@ -32,10 +32,8 @@ FcRangeCreateDouble (double begin, double end) if (ret) { - ret->is_double = FcTrue; - ret->is_inclusive = FcDoubleCmpEQ (begin, end); - ret->u.d.begin = begin; - ret->u.d.end = end; + ret->begin = begin; + ret->end = end; } return ret; @@ -48,10 +46,8 @@ FcRangeCreateInteger (FcChar32 begin, FcChar32 end) if (ret) { - ret->is_double = FcFalse; - ret->is_inclusive = (begin == end); - ret->u.i.begin = begin; - ret->u.i.end = end; + ret->begin = begin; + ret->end = end; } return ret; @@ -66,14 +62,7 @@ FcRangeDestroy (FcRange *range) FcRange * FcRangeCopy (const FcRange *range) { - FcRange *ret; - - if (range->is_double) - ret = FcRangeCreateDouble (range->u.d.begin, range->u.d.end); - else - ret = FcRangeCreateInteger (range->u.i.begin, range->u.i.end); - - return ret; + return FcRangeCreateDouble (range->begin, range->end); } FcBool @@ -81,41 +70,14 @@ FcRangeGetDouble(const FcRange *range, double *begin, double *end) { if (!range) return FcFalse; - if (range->is_double) - { - if (begin) - *begin = range->u.d.begin; - if (end) - *end = range->u.d.end; - } - else - { - if (begin) - *begin = (double)range->u.i.begin; - if (end) - *end = (double)range->u.i.end; - } + if (begin) + *begin = range->begin; + if (end) + *end = range->end; return FcTrue; } -FcRange -FcRangeCanonicalize (const FcRange *range) -{ - FcRange new; - - if (range->is_double) - new = *range; - else - { - new.is_double = FcTrue; - new.is_inclusive = range->is_inclusive; - new.u.d.begin = (double)range->u.i.begin; - new.u.d.end = (double)range->u.i.end; - } - return new; -} - FcRange * FcRangePromote (double v, FcValuePromotionBuffer *vbuf) { @@ -125,50 +87,24 @@ FcRangePromote (double v, FcValuePromotionBuffer *vbuf) FcRangePromotionBuffer *buf = (FcRangePromotionBuffer *) vbuf; FC_ASSERT_STATIC (sizeof (FcRangePromotionBuffer) <= sizeof (FcValuePromotionBuffer)); - buf->r.is_double = FcTrue; - buf->r.is_inclusive = FcTrue; - buf->r.u.d.begin = v; - buf->r.u.d.end = v; + buf->r.begin = v; + buf->r.end = v; return &buf->r; } FcBool -FcRangeIsZero (const FcRange *r) -{ - FcRange c; - - if (!r) - return FcFalse; - c = FcRangeCanonicalize (r); - - return FcDoubleIsZero (c.u.d.begin) && FcDoubleIsZero (c.u.d.end); -} - -FcBool FcRangeIsInRange (const FcRange *a, const FcRange *b) { - FcRange ca, cb; - FcBool f; - if (!a || !b) return FcFalse; - ca = FcRangeCanonicalize (a); - cb = FcRangeCanonicalize (b); - if (ca.is_inclusive & cb.is_inclusive) - f = ca.u.d.end <= cb.u.d.end; - else - f = ca.u.d.end < cb.u.d.end; - - return FcDoubleCmpGE (ca.u.d.begin, cb.u.d.begin) && f; + return a->begin >= b->begin && a->end <= b->end; } FcBool FcRangeCompare (FcOp op, const FcRange *a, const FcRange *b) { - FcRange ca, cb; - switch ((int) op) { case FcOpEqual: case FcOpContains: @@ -178,21 +114,13 @@ FcRangeCompare (FcOp op, const FcRange *a, const FcRange *b) case FcOpNotContains: return !FcRangeIsInRange (a, b); case FcOpLess: - ca = FcRangeCanonicalize (a); - cb = FcRangeCanonicalize (b); - return ca.u.d.begin < cb.u.d.begin; + return a->begin < b->begin; case FcOpLessEqual: - ca = FcRangeCanonicalize (a); - cb = FcRangeCanonicalize (b); - return FcDoubleCmpLE (ca.u.d.begin, cb.u.d.begin); + return a->begin <= b->begin; case FcOpMore: - ca = FcRangeCanonicalize (a); - cb = FcRangeCanonicalize (b); - return ca.u.d.end > cb.u.d.end; + return a->end > b->end; case FcOpMoreEqual: - ca = FcRangeCanonicalize (a); - cb = FcRangeCanonicalize (b); - return FcDoubleCmpGE (ca.u.d.end, cb.u.d.end); + return a->end >= b->end; default: break; } @@ -202,9 +130,8 @@ FcRangeCompare (FcOp op, const FcRange *a, const FcRange *b) FcChar32 FcRangeHash (const FcRange *r) { - FcRange c = FcRangeCanonicalize (r); - int b = (int) (c.u.d.begin * 100); - int e = FcDoubleCmpEQ (c.u.d.end, DBL_MAX) ? INT_MAX : (int) (c.u.d.end * 100); + int b = (int) (r->begin * 100); + int e = (int) (r->end * 100); return b ^ (b << 1) ^ (e << 9); } diff --git a/fontconfig/src/fcxml.c b/fontconfig/src/fcxml.c index 9a6f08d27..bad6b8193 100644 --- a/fontconfig/src/fcxml.c +++ b/fontconfig/src/fcxml.c @@ -57,6 +57,9 @@ extern FcChar8 fontconfig_instprefix[]; #endif +static FcChar8 *__fc_userdir = NULL; +static FcChar8 *__fc_userconf = NULL; + static void FcExprDestroy (FcExpr *e); @@ -79,6 +82,7 @@ FcRuleDestroy (FcRule *rule) case FcRuleEdit: FcEditDestroy (rule->u.edit); break; + case FcRuleUnknown: default: break; } @@ -609,6 +613,7 @@ FcTypeName (FcType type) return "langset"; case FcTypeRange: return "range"; + case FcTypeUnknown: default: return "unknown"; } @@ -806,6 +811,7 @@ FcRuleCreate (FcRuleType type, case FcRuleEdit: r->u.edit = (FcEdit *) p; break; + case FcRuleUnknown: default: free (r); r = NULL; @@ -1255,7 +1261,6 @@ FcParseBlank (FcConfigParse *parse) { int n = FcVStackElements (parse); FcChar32 i, begin, end; - FcRange r; while (n-- > 0) { @@ -1272,9 +1277,8 @@ FcParseBlank (FcConfigParse *parse) goto bail; break; case FcVStackRange: - r = FcRangeCanonicalize (v->u.range); - begin = (FcChar32)r.u.d.begin; - end = (FcChar32)r.u.d.end; + begin = (FcChar32) v->u.range->begin; + end = (FcChar32) v->u.range->end; if (begin <= end) { for (i = begin; i <= end; i++) @@ -1587,7 +1591,6 @@ FcParseCharSet (FcConfigParse *parse) FcVStack *vstack; FcCharSet *charset = FcCharSetCreate (); FcChar32 i, begin, end; - FcRange r; int n = 0; while ((vstack = FcVStackPeek (parse))) @@ -1602,9 +1605,8 @@ FcParseCharSet (FcConfigParse *parse) n++; break; case FcVStackRange: - r = FcRangeCanonicalize (vstack->u.range); - begin = (FcChar32)r.u.d.begin; - end = (FcChar32)r.u.d.end; + begin = (FcChar32) vstack->u.range->begin; + end = (FcChar32) vstack->u.range->end; if (begin <= end) { @@ -2262,6 +2264,24 @@ FcParseCacheDir (FcConfigParse *parse) FcStrFree (data); } +void +FcConfigPathFini (void) +{ + FcChar8 *s; + +retry_dir: + s = fc_atomic_ptr_get (&__fc_userdir); + if (!fc_atomic_ptr_cmpexch (&__fc_userdir, s, NULL)) + goto retry_dir; + free (s); + +retry_conf: + s = fc_atomic_ptr_get (&__fc_userconf); + if (!fc_atomic_ptr_cmpexch (&__fc_userconf, s, NULL)) + goto retry_conf; + free (s); +} + static void FcParseInclude (FcConfigParse *parse) { @@ -2272,8 +2292,7 @@ FcParseInclude (FcConfigParse *parse) FcBool deprecated = FcFalse; #endif FcChar8 *prefix = NULL, *p; - static FcChar8 *userdir = NULL; - static FcChar8 *userconf = NULL; + FcChar8 *userdir = NULL, *userconf = NULL; s = FcStrBufDoneStatic (&parse->pstack->str); if (!s) @@ -2303,6 +2322,7 @@ FcParseInclude (FcConfigParse *parse) { size_t plen = strlen ((const char *)prefix); size_t dlen = strlen ((const char *)s); + FcChar8 *u; p = realloc (prefix, plen + 1 + dlen + 1); if (!p) @@ -2318,14 +2338,32 @@ FcParseInclude (FcConfigParse *parse) if (FcFileIsDir (s)) { userdir: + userdir = fc_atomic_ptr_get (&__fc_userdir); if (!userdir) - userdir = FcStrdup (s); + { + u = FcStrdup (s); + if (!fc_atomic_ptr_cmpexch (&__fc_userdir, userdir, u)) + { + free (u); + goto userdir; + } + userdir = u; + } } else if (FcFileIsFile (s)) { userconf: + userconf = fc_atomic_ptr_get (&__fc_userconf); if (!userconf) - userconf = FcStrdup (s); + { + u = FcStrdup (s); + if (!fc_atomic_ptr_cmpexch (&__fc_userconf, userconf, u)) + { + free (u); + goto userconf; + } + userconf = u; + } } else { @@ -2349,6 +2387,7 @@ FcParseInclude (FcConfigParse *parse) filename = FcConfigFilename(s); if (deprecated == FcTrue && filename != NULL && + userdir != NULL && !FcFileIsLink (filename)) { if (FcFileIsDir (filename)) |