From 3f553aaceddc9b09363c73d9bea40eaea8164fc4 Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 7 Jan 2013 11:56:06 +0100 Subject: pixman xkbcomp libX11 libXau mesa fontconfig xserver xkeyboard-config git update 7 jan 2013 fontconfig: 17eda89ed2e24a3fc5f68538dd7fd9ada8efb087 xserver: bd91b05b631f13afd1f7a9d6cbc4f0c5408b523a xkeyboard-config: 4779e2745094ebe0c06364b4099d7067ae750d07 libX11: cd25cab4b5b957641183ce72dd1ae0424aff1663 libXau: e04364efccbb3bb4cfc5f4cb491ffa1faaaacbdb mesa: afec10df373f342f058aab66c622237964a4a147 pixman: 35cc965514ca6e665c18411fcf66db826d559c2a xkbcomp: e4f767913338052527538d429931e8abd8c3fb88 --- fontconfig/src/Makefile.am | 42 +++- fontconfig/src/fcarch.c | 11 +- fontconfig/src/fcatomic.c | 7 +- fontconfig/src/fcatomic.h | 121 +++++++++++ fontconfig/src/fcblanks.c | 8 - fontconfig/src/fccache.c | 154 ++++++++++---- fontconfig/src/fccfg.c | 285 +++++++++++++++---------- fontconfig/src/fccharset.c | 64 ++---- fontconfig/src/fcdbg.c | 75 ++++--- fontconfig/src/fcdefault.c | 91 +++++--- fontconfig/src/fcdir.c | 6 +- fontconfig/src/fcformat.c | 15 +- fontconfig/src/fcfreetype.c | 12 +- fontconfig/src/fcfs.c | 8 - fontconfig/src/fcinit.c | 134 ++---------- fontconfig/src/fcint.h | 209 ++++++++----------- fontconfig/src/fclang.c | 66 +++--- fontconfig/src/fclist.c | 16 +- fontconfig/src/fcmatch.c | 27 +-- fontconfig/src/fcmatrix.c | 4 - fontconfig/src/fcmutex.h | 127 ++++++++++++ fontconfig/src/fcname.c | 426 ++++++-------------------------------- fontconfig/src/fcobjs.c | 139 +++++++++++++ fontconfig/src/fcobjs.h | 44 ++++ fontconfig/src/fcobjshash.gperf.h | 26 +++ fontconfig/src/fcpat.c | 150 +++----------- fontconfig/src/fcserialize.c | 1 - fontconfig/src/fcstat.c | 9 +- fontconfig/src/fcstr.c | 65 ++---- fontconfig/src/fcwindows.h | 44 ++++ fontconfig/src/fcxml.c | 280 +++++++++++++++---------- fontconfig/src/ftglue.c | 3 +- 32 files changed, 1411 insertions(+), 1258 deletions(-) create mode 100644 fontconfig/src/fcatomic.h create mode 100644 fontconfig/src/fcmutex.h create mode 100644 fontconfig/src/fcobjs.c create mode 100644 fontconfig/src/fcobjs.h create mode 100644 fontconfig/src/fcobjshash.gperf.h create mode 100644 fontconfig/src/fcwindows.h (limited to 'fontconfig/src') diff --git a/fontconfig/src/Makefile.am b/fontconfig/src/Makefile.am index dc082b7df..617713fe7 100644 --- a/fontconfig/src/Makefile.am +++ b/fontconfig/src/Makefile.am @@ -21,6 +21,8 @@ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. +EXTRA_DIST = + if OS_WIN32 export_symbols = -export-symbols fontconfig.def @@ -78,7 +80,7 @@ INCLUDES = \ -DFC_CACHEDIR='"$(FC_CACHEDIR)"' \ -DFONTCONFIG_PATH='"$(BASECONFIGDIR)"' -EXTRA_DIST = makealias +EXTRA_DIST += makealias noinst_HEADERS=fcint.h fcftint.h fcdeprecate.h fcstdint.h @@ -88,7 +90,9 @@ BUILT_SOURCES = $(ALIAS_FILES) \ ../fc-case/fccase.h \ ../fc-glyphname/fcglyphname.h \ ../fc-lang/fclang.h \ - stamp-fcstdint + stamp-fcstdint \ + fcobjshash.h \ + fcobjshash.gperf noinst_PROGRAMS = fcarch @@ -99,9 +103,30 @@ noinst_PROGRAMS = fcarch ../fc-lang/fclang.h: cd ../fc-lang && $(MAKE) $(AM_MAKEFLAGS) fclang.h +fcobjshash.gperf: fcobjshash.gperf.h fcobjs.h + $(AM_V_GEN) $(CPP) -I$(top_srcdir) $< | \ + $(SED) 's/^ *//;s/ *, */,/' | \ + $(GREP) '^[^#]' | \ + awk ' \ + /CUT_OUT_BEGIN/ { no_write=1; next; }; \ + /CUT_OUT_END/ { no_write=0; next; }; \ + { if (!no_write) print; next; }; \ + ' - > $@.tmp && \ + mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) + +fcobjshash.h: fcobjshash.gperf + $(AM_V_GEN) $(top_srcdir)/missing --run gperf -m 100 $< > $@.tmp && \ + mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) + +EXTRA_DIST += \ + fcobjshash.gperf.h \ + fcobjshash.gperf \ + fcobjshash.h + libfontconfig_la_SOURCES = \ fcarch.h \ fcatomic.c \ + fcatomic.h \ fcblanks.c \ fccache.c \ fccfg.c \ @@ -117,11 +142,16 @@ libfontconfig_la_SOURCES = \ fclist.c \ fcmatch.c \ fcmatrix.c \ + fcmutex.h \ fcname.c \ + fcobjs.c \ + fcobjs.h \ + fcobjshash.h \ fcpat.c \ fcserialize.c \ fcstat.c \ fcstr.c \ + fcwindows.h \ fcxml.c \ ftglue.h \ ftglue.c @@ -164,15 +194,17 @@ stamp-fcstdint: $(top_builddir)/config.status $(SHELL) ./config.status src/fcstdint.h @touch $@ -CLEANFILES = $(ALIAS_FILES) +CLEANFILES = $(ALIAS_FILES) fontconfig.def DISTCLEANFILES = stamp-fcstdint fcstdint.h fontconfig.def: $(PUBLIC_FILES) $(PUBLIC_FT_FILES) echo Generating $@ (echo EXPORTS; \ (cat $(PUBLIC_FILES) $(PUBLIC_FT_FILES) || echo 'FcERROR ()' ) | \ - grep '^Fc[^ ]* *(' | sed -e 's/ *(.*$$//' -e 's/^/ /' | \ + $(GREP) '^Fc[^ ]* *(' | $(SED) -e 's/ *(.*$$//' -e 's/^/ /' | \ sort; \ echo LIBRARY libfontconfig-@LIBT_CURRENT_MINUS_AGE@.dll; \ echo VERSION @LIBT_CURRENT@.@LIBT_REVISION@) >$@ - @ ! grep -q FcERROR $@ || ($(RM) $@; false) + @ ! $(GREP) -q FcERROR $@ || ($(RM) $@; false) + +-include $(top_srcdir)/git.mk diff --git a/fontconfig/src/fcarch.c b/fontconfig/src/fcarch.c index 44548fc1b..35734c021 100644 --- a/fontconfig/src/fcarch.c +++ b/fontconfig/src/fcarch.c @@ -27,14 +27,7 @@ #include #endif -/* If architecture is hardcoded, skip the assert tests */ - -#ifndef FC_ARCHITECTURE - -/* Make sure the cache structure is consistent with what we expect */ - #include "fcint.h" - #include "fcarch.h" FC_ASSERT_STATIC (1 == sizeof (char)); @@ -62,11 +55,9 @@ FC_ASSERT_STATIC (0x08 + 2*SIZEOF_VOID_P == sizeof (FcPattern)); FC_ASSERT_STATIC (0x08 + 2*SIZEOF_VOID_P == sizeof (FcCharSet)); FC_ASSERT_STATIC (0x08 + 6*SIZEOF_VOID_P == sizeof (FcCache)); -#endif - int -main (int argc, char **argv) +main (int argc FC_UNUSED, char **argv FC_UNUSED) { printf ("%s\n", FC_ARCHITECTURE); return 0; diff --git a/fontconfig/src/fcatomic.c b/fontconfig/src/fcatomic.c index 350744abb..cb5b7a5e6 100644 --- a/fontconfig/src/fcatomic.c +++ b/fontconfig/src/fcatomic.c @@ -56,6 +56,7 @@ #include #ifdef _WIN32 +#include #define mkdir(path,mode) _mkdir(path) #endif @@ -78,7 +79,6 @@ FcAtomicCreate (const FcChar8 *file) FcAtomic *atomic = malloc (total_len); if (!atomic) return 0; - FcMemAlloc (FC_MEM_ATOMIC, total_len); atomic->file = (FcChar8 *) (atomic + 1); strcpy ((char *) atomic->file, (char *) file); @@ -223,11 +223,6 @@ FcAtomicUnlock (FcAtomic *atomic) void FcAtomicDestroy (FcAtomic *atomic) { - FcMemFree (FC_MEM_ATOMIC, sizeof (FcAtomic) + - strlen ((char *) atomic->file) * 4 + 4 + - sizeof (NEW_NAME) + sizeof (LCK_NAME) + - sizeof (TMP_NAME)); - free (atomic); } #define __fcatomic__ diff --git a/fontconfig/src/fcatomic.h b/fontconfig/src/fcatomic.h new file mode 100644 index 000000000..72ae37280 --- /dev/null +++ b/fontconfig/src/fcatomic.h @@ -0,0 +1,121 @@ +/* + * Mutex operations. Originally copied from HarfBuzz. + * + * Copyright © 2007 Chris Wilson + * Copyright © 2009,2010 Red Hat, Inc. + * Copyright © 2011,2012,2013 Google, Inc. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Contributor(s): + * Chris Wilson + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#ifndef _FCATOMIC_H_ +#define _FCATOMIC_H_ + +#ifdef HAVE_CONFIG_H +#include +#endif + + +/* atomic_int */ + +/* We need external help for these */ + +#if 0 + + +#elif !defined(FC_NO_MT) && defined(_MSC_VER) || defined(__MINGW32__) + +#include "fcwindows.h" + +/* mingw32 does not have MemoryBarrier. + * MemoryBarrier may be defined as a macro or a function. + * Just make a failsafe version for ourselves. */ +#ifdef MemoryBarrier +#define HBMemoryBarrier MemoryBarrier +#else +static inline void HBMemoryBarrier (void) { + long dummy = 0; + InterlockedExchange (&dummy, 1); +} +#endif + +typedef LONG fc_atomic_int_t; +#define fc_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) + +#define fc_atomic_ptr_get(P) (HBMemoryBarrier (), (void *) *(P)) +#define fc_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) + + +#elif !defined(FC_NO_MT) && defined(__APPLE__) + +#include + +typedef int fc_atomic_int_t; +#define fc_atomic_int_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V)) + +#define fc_atomic_ptr_get(P) (OSMemoryBarrier (), (void *) *(P)) +#define fc_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P)) + + +#elif !defined(FC_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) + +typedef int fc_atomic_int_t; +#define fc_atomic_int_add(AI, V) __sync_fetch_and_add (&(AI), (V)) + +#define fc_atomic_ptr_get(P) (void *) (__sync_synchronize (), *(P)) +#define fc_atomic_ptr_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) + + +#elif !defined(FC_NO_MT) + +#define FC_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */ +typedef volatile int fc_atomic_int_t; +#define fc_atomic_int_add(AI, V) (((AI) += (V)) - (V)) + +#define fc_atomic_ptr_get(P) ((void *) *(P)) +#define fc_atomic_ptr_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), FcTrue) : FcFalse) + + +#else /* FC_NO_MT */ + +typedef int fc_atomic_int_t; +#define fc_atomic_int_add(AI, V) (((AI) += (V)) - (V)) + +#define fc_atomic_ptr_get(P) ((void *) *(P)) +#define fc_atomic_ptr_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), FcTrue) : FcFalse) + +#endif + +/* reference count */ +#define FC_REF_CONSTANT_VALUE ((fc_atomic_int_t) -1) +#define FC_REF_CONSTANT {FC_REF_CONSTANT_VALUE} +typedef struct _FcRef { fc_atomic_int_t count; } FcRef; +static inline void FcRefInit (FcRef *r, int v) { r->count = v; } +static inline int FcRefInc (FcRef *r) { return fc_atomic_int_add (r->count, +1); } +static inline int FcRefDec (FcRef *r) { return fc_atomic_int_add (r->count, -1); } +static inline int FcRefAdd (FcRef *r, int v) { return fc_atomic_int_add (r->count, v); } +static inline void FcRefSetConst (FcRef *r) { r->count = FC_REF_CONSTANT_VALUE; } +static inline FcBool FcRefIsConst (const FcRef *r) { return r->count == FC_REF_CONSTANT_VALUE; } + +#endif /* _FCATOMIC_H_ */ diff --git a/fontconfig/src/fcblanks.c b/fontconfig/src/fcblanks.c index a80a1344f..46698bcda 100644 --- a/fontconfig/src/fcblanks.c +++ b/fontconfig/src/fcblanks.c @@ -32,7 +32,6 @@ FcBlanksCreate (void) b = malloc (sizeof (FcBlanks)); if (!b) return 0; - FcMemAlloc (FC_MEM_BLANKS, sizeof (FcBlanks)); b->nblank = 0; b->sblank = 0; b->blanks = 0; @@ -43,11 +42,7 @@ void FcBlanksDestroy (FcBlanks *b) { if (b->blanks) - { - FcMemFree (FC_MEM_BLANKS, b->sblank * sizeof (FcChar32)); free (b->blanks); - } - FcMemFree (FC_MEM_BLANKS, sizeof (FcBlanks)); free (b); } @@ -70,9 +65,6 @@ FcBlanksAdd (FcBlanks *b, FcChar32 ucs4) c = (FcChar32 *) malloc (sblank * sizeof (FcChar32)); if (!c) return FcFalse; - if (b->sblank) - FcMemFree (FC_MEM_BLANKS, b->sblank * sizeof (FcChar32)); - FcMemAlloc (FC_MEM_BLANKS, sblank * sizeof (FcChar32)); b->sblank = sblank; b->blanks = c; } diff --git a/fontconfig/src/fccache.c b/fontconfig/src/fccache.c index 81985df59..2f1104f25 100644 --- a/fontconfig/src/fccache.c +++ b/fontconfig/src/fccache.c @@ -59,26 +59,32 @@ static void MD5Transform(FcChar32 buf[4], FcChar32 in[16]); static FcBool FcCacheIsMmapSafe (int fd) { - static FcBool is_initialized = FcFalse; - static FcBool is_env_available = FcFalse; - static FcBool use_mmap = FcFalse; + enum { + MMAP_NOT_INITIALIZED = 0, + MMAP_USE, + MMAP_DONT_USE, + MMAP_CHECK_FS, + } status; + static void *static_status; - if (!is_initialized) - { - const char *env; + status = (intptr_t) fc_atomic_ptr_get (&static_status); - env = getenv ("FONTCONFIG_USE_MMAP"); - if (env) - { - if (FcNameBool ((const FcChar8 *)env, &use_mmap)) - is_env_available = FcTrue; - } - is_initialized = FcTrue; + if (status == MMAP_NOT_INITIALIZED) + { + const char *env = getenv ("FONTCONFIG_USE_MMAP"); + FcBool use; + if (env && FcNameBool ((const FcChar8 *) env, &use)) + status = use ? MMAP_USE : MMAP_DONT_USE; + else + status = MMAP_CHECK_FS; + (void) fc_atomic_ptr_cmpexch (&static_status, NULL, (void *) status); } - if (is_env_available) - return use_mmap; - return FcIsFsMmapSafe (fd); + if (status == MMAP_CHECK_FS) + return FcIsFsMmapSafe (fd); + else + return status == MMAP_USE; + } static const char bin2hex[] = { '0', '1', '2', '3', @@ -227,7 +233,7 @@ typedef struct _FcCacheSkip FcCacheSkip; struct _FcCacheSkip { FcCache *cache; - int ref; + FcRef ref; intptr_t size; dev_t cache_dev; ino_t cache_ino; @@ -242,6 +248,7 @@ struct _FcCacheSkip { #define FC_CACHE_MAX_LEVEL 16 +/* Protected by cache_lock below */ static FcCacheSkip *fcCacheChains[FC_CACHE_MAX_LEVEL]; static int fcCacheMaxLevel; @@ -301,6 +308,50 @@ FcRandom(void) return result; } + +static FcMutex *cache_lock; + +static void +lock_cache (void) +{ + FcMutex *lock; +retry: + lock = fc_atomic_ptr_get (&cache_lock); + if (!lock) { + lock = (FcMutex *) malloc (sizeof (FcMutex)); + FcMutexInit (lock); + if (!fc_atomic_ptr_cmpexch (&cache_lock, NULL, lock)) { + FcMutexFinish (lock); + goto retry; + } + + FcMutexLock (lock); + /* Initialize random state */ + FcRandom (); + return; + } + FcMutexLock (lock); +} + +static void +unlock_cache (void) +{ + FcMutexUnlock (cache_lock); +} + +static void +free_lock (void) +{ + FcMutex *lock; + lock = fc_atomic_ptr_get (&cache_lock); + if (lock && fc_atomic_ptr_cmpexch (&cache_lock, lock, NULL)) { + FcMutexFinish (lock); + free (lock); + } +} + + + /* * Generate a random level number, distributed * so that each level is 1/4 as likely as the one before @@ -333,6 +384,8 @@ FcCacheInsert (FcCache *cache, struct stat *cache_stat) FcCacheSkip *s, **next; int i, level; + lock_cache (); + /* * Find links along each chain */ @@ -362,7 +415,7 @@ FcCacheInsert (FcCache *cache, struct stat *cache_stat) s->cache = cache; s->size = cache->size; - s->ref = 1; + FcRefInit (&s->ref, 1); if (cache_stat) { s->cache_dev = cache_stat->st_dev; @@ -384,11 +437,13 @@ FcCacheInsert (FcCache *cache, struct stat *cache_stat) s->next[i] = *update[i]; *update[i] = s; } + + unlock_cache (); return FcTrue; } static FcCacheSkip * -FcCacheFindByAddr (void *object) +FcCacheFindByAddrUnlocked (void *object) { int i; FcCacheSkip **next = fcCacheChains; @@ -409,8 +464,18 @@ FcCacheFindByAddr (void *object) return NULL; } +static FcCacheSkip * +FcCacheFindByAddr (void *object) +{ + FcCacheSkip *ret; + lock_cache (); + ret = FcCacheFindByAddrUnlocked (object); + unlock_cache (); + return ret; +} + static void -FcCacheRemove (FcCache *cache) +FcCacheRemoveUnlocked (FcCache *cache) { FcCacheSkip **update[FC_CACHE_MAX_LEVEL]; FcCacheSkip *s, **next; @@ -440,20 +505,25 @@ FcCacheFindByStat (struct stat *cache_stat) { FcCacheSkip *s; + lock_cache (); for (s = fcCacheChains[0]; s; s = s->next[0]) if (s->cache_dev == cache_stat->st_dev && s->cache_ino == cache_stat->st_ino && s->cache_mtime == cache_stat->st_mtime) { - s->ref++; + FcRefInc (&s->ref); + unlock_cache (); return s->cache; } + unlock_cache (); return NULL; } static void -FcDirCacheDispose (FcCache *cache) +FcDirCacheDisposeUnlocked (FcCache *cache) { + FcCacheRemoveUnlocked (cache); + switch (cache->magic) { case FC_CACHE_MAGIC_ALLOC: free (cache); @@ -466,7 +536,6 @@ FcDirCacheDispose (FcCache *cache) #endif break; } - FcCacheRemove (cache); } void @@ -475,20 +544,22 @@ FcCacheObjectReference (void *object) FcCacheSkip *skip = FcCacheFindByAddr (object); if (skip) - skip->ref++; + FcRefInc (&skip->ref); } void FcCacheObjectDereference (void *object) { - FcCacheSkip *skip = FcCacheFindByAddr (object); + FcCacheSkip *skip; + lock_cache (); + skip = FcCacheFindByAddrUnlocked (object); if (skip) { - skip->ref--; - if (skip->ref <= 0) - FcDirCacheDispose (skip->cache); + if (FcRefDec (&skip->ref) <= 1) + FcDirCacheDisposeUnlocked (skip->cache); } + unlock_cache (); } void @@ -499,6 +570,8 @@ FcCacheFini (void) for (i = 0; i < FC_CACHE_MAX_LEVEL; i++) assert (fcCacheChains[i] == NULL); assert (fcCacheMaxLevel == 0); + + free_lock (); } static FcBool @@ -527,7 +600,7 @@ FcDirCacheMapFd (int fd, struct stat *fd_stat, struct stat *dir_stat) FcCache *cache; FcBool allocated = FcFalse; - if (fd_stat->st_size < sizeof (FcCache)) + if (fd_stat->st_size < (int) sizeof (FcCache)) return NULL; cache = FcCacheFindByStat (fd_stat); if (cache) @@ -582,7 +655,7 @@ FcDirCacheMapFd (int fd, struct stat *fd_stat, struct stat *dir_stat) } if (cache->magic != FC_CACHE_MAGIC_MMAP || cache->version < FC_CACHE_CONTENT_VERSION || - cache->size != fd_stat->st_size || + cache->size != (intptr_t) fd_stat->st_size || !FcCacheTimeValid (cache, dir_stat) || !FcCacheInsert (cache, fd_stat)) { @@ -612,7 +685,7 @@ FcDirCacheReference (FcCache *cache, int nref) FcCacheSkip *skip = FcCacheFindByAddr (cache); if (skip) - skip->ref += nref; + FcRefAdd (&skip->ref, nref); } void @@ -666,7 +739,7 @@ FcDirCacheLoadFile (const FcChar8 *cache_file, struct stat *file_stat) * the magic number and the size field */ static FcBool -FcDirCacheValidateHelper (int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure) +FcDirCacheValidateHelper (int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure FC_UNUSED) { FcBool ret = FcTrue; FcCache c; @@ -842,7 +915,7 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) FcChar8 *test_dir; FcCacheSkip *skip; struct stat cache_stat; - int magic; + unsigned int magic; int written; /* @@ -936,13 +1009,16 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) * new cache file is not read again. If it's large, we don't do that * such that we reload it, using mmap, which is shared across processes. */ - if (cache->size < FC_CACHE_MIN_MMAP && - (skip = FcCacheFindByAddr (cache)) && - FcStat (cache_hashed, &cache_stat)) + if (cache->size < FC_CACHE_MIN_MMAP && FcStat (cache_hashed, &cache_stat)) { - skip->cache_dev = cache_stat.st_dev; - skip->cache_ino = cache_stat.st_ino; - skip->cache_mtime = cache_stat.st_mtime; + lock_cache (); + if ((skip = FcCacheFindByAddrUnlocked (cache))) + { + skip->cache_dev = cache_stat.st_dev; + skip->cache_ino = cache_stat.st_ino; + skip->cache_mtime = cache_stat.st_mtime; + } + unlock_cache (); } FcStrFree (cache_hashed); diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c index f94f0e051..877a4f57e 100644 --- a/fontconfig/src/fccfg.c +++ b/fontconfig/src/fccfg.c @@ -22,21 +22,50 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* Objects MT-safe for readonly access. */ + #include "fcint.h" #include #include -#if defined (_WIN32) && (defined (PIC) || defined (DLL_EXPORT)) -#define STRICT -#include -#undef STRICT -#endif - #if defined (_WIN32) && !defined (R_OK) #define R_OK 4 #endif -FcConfig *_fcConfig; +static FcConfig *_fcConfig; /* MT-safe */ + +static FcConfig * +FcConfigEnsure (void) +{ + FcConfig *config; +retry: + config = fc_atomic_ptr_get (&_fcConfig); + if (!config) + { + config = FcInitLoadConfigAndFonts (); + + if (!fc_atomic_ptr_cmpexch (&_fcConfig, NULL, config)) { + FcConfigDestroy (config); + goto retry; + } + } + return config; +} + +FcBool +FcConfigInit (void) +{ + return FcConfigEnsure () ? FcTrue : FcFalse; +} + +void +FcConfigFini (void) +{ + FcConfig *cfg = fc_atomic_ptr_get (&_fcConfig); + if (cfg && fc_atomic_ptr_cmpexch (&_fcConfig, cfg, NULL)) + FcConfigDestroy (cfg); +} + FcConfig * FcConfigCreate (void) @@ -47,7 +76,6 @@ FcConfigCreate (void) config = malloc (sizeof (FcConfig)); if (!config) goto bail0; - FcMemAlloc (FC_MEM_CONFIG, sizeof (FcConfig)); config->configDirs = FcStrSetCreate (); if (!config->configDirs) @@ -95,7 +123,7 @@ FcConfigCreate (void) config->expr_pool = NULL; - config->ref = 1; + FcRefInit (&config->ref, 1); return config; @@ -115,7 +143,6 @@ bail2: FcStrSetDestroy (config->configDirs); bail1: free (config); - FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig)); bail0: return 0; } @@ -166,7 +193,7 @@ FcConfigUptoDate (FcConfig *config) (font_time.set && (font_time.time - now) > 0)) { fprintf (stderr, - "Fontconfig warning: Directory/file mtime in the future. New fonts may not be detected\n"); + "Fontconfig warning: Directory/file mtime in the future. New fonts may not be detected.\n"); config->rescanTime = now; return FcTrue; } @@ -190,7 +217,6 @@ FcSubstDestroy (FcSubst *s) if (s->edit) FcEditDestroy (s->edit); free (s); - FcMemFree (FC_MEM_SUBST, sizeof (FcSubst)); s = n; } } @@ -205,7 +231,6 @@ FcConfigAllocExpr (FcConfig *config) new_page = malloc (sizeof (FcExprPage)); if (!new_page) return 0; - FcMemAlloc (FC_MEM_EXPR, sizeof (FcExprPage)); new_page->next_page = config->expr_pool; new_page->next = new_page->exprs; @@ -225,7 +250,7 @@ FcConfigReference (FcConfig *config) return 0; } - config->ref++; + FcRefInc (&config->ref); return config; } @@ -236,11 +261,10 @@ FcConfigDestroy (FcConfig *config) FcSetName set; FcExprPage *page; - if (--config->ref > 0) + if (FcRefDec (&config->ref) != 1) return; - if (config == _fcConfig) - _fcConfig = 0; + (void) fc_atomic_ptr_cmpexch (&_fcConfig, config, NULL); FcStrSetDestroy (config->configDirs); FcStrSetDestroy (config->fontDirs); @@ -265,13 +289,11 @@ FcConfigDestroy (FcConfig *config) while (page) { FcExprPage *next = page->next_page; - FcMemFree (FC_MEM_EXPR, sizeof (FcExprPage)); free (page); page = next; } free (config); - FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig)); } /* @@ -395,26 +417,31 @@ FcConfigBuildFonts (FcConfig *config) FcBool FcConfigSetCurrent (FcConfig *config) { - if (config == _fcConfig) + FcConfig *cfg; + +retry: + cfg = fc_atomic_ptr_get (&_fcConfig); + + if (config == cfg) return FcTrue; if (!config->fonts[FcSetSystem]) if (!FcConfigBuildFonts (config)) return FcFalse; - if (_fcConfig) - FcConfigDestroy (_fcConfig); - _fcConfig = config; + if (!fc_atomic_ptr_cmpexch (&_fcConfig, cfg, config)) + goto retry; + + if (cfg) + FcConfigDestroy (cfg); + return FcTrue; } FcConfig * FcConfigGetCurrent (void) { - if (!_fcConfig) - if (!FcInit ()) - return 0; - return _fcConfig; + return FcConfigEnsure (); } FcBool @@ -510,7 +537,7 @@ FcConfigGetConfigFiles (FcConfig *config) } FcChar8 * -FcConfigGetCache (FcConfig *config) +FcConfigGetCache (FcConfig *config FC_UNUSED) { return NULL; } @@ -640,7 +667,6 @@ FcConfigAddEdit (FcConfig *config, subst = (FcSubst *) malloc (sizeof (FcSubst)); if (!subst) return FcFalse; - FcMemAlloc (FC_MEM_SUBST, sizeof (FcSubst)); for (; *prev; prev = &(*prev)->next); *prev = subst; subst->next = 0; @@ -669,7 +695,7 @@ typedef struct _FcSubState { } FcSubState; static FcValue -FcConfigPromote (FcValue v, FcValue u) +FcConfigPromote (FcValue v, FcValue u, FcValuePromotionBuffer *buf) { if (v.type == FcTypeInteger) { @@ -681,9 +707,9 @@ FcConfigPromote (FcValue v, FcValue u) v.u.m = &FcIdentityMatrix; v.type = FcTypeMatrix; } - else if (v.type == FcTypeString && u.type == FcTypeLangSet) + else if (buf && v.type == FcTypeString && u.type == FcTypeLangSet) { - v.u.l = FcLangSetPromote (v.u.s); + v.u.l = FcLangSetPromote (v.u.s, buf); v.type = FcTypeLangSet; } return v; @@ -699,16 +725,17 @@ FcConfigCompareValue (const FcValue *left_o, FcBool ret = FcFalse; FcOp op = FC_OP_GET_OP (op_); int flags = FC_OP_GET_FLAGS (op_); + FcValuePromotionBuffer buf1, buf2; - left = FcConfigPromote (left, right); - right = FcConfigPromote (right, left); + left = FcConfigPromote (left, right, &buf1); + right = FcConfigPromote (right, left, &buf2); if (left.type == right.type) { switch (left.type) { case FcTypeInteger: break; /* FcConfigPromote prevents this from happening */ case FcTypeDouble: - switch (op) { + switch ((int) op) { case FcOpEqual: case FcOpContains: case FcOpListing: @@ -735,7 +762,7 @@ FcConfigCompareValue (const FcValue *left_o, } break; case FcTypeBool: - switch (op) { + switch ((int) op) { case FcOpEqual: case FcOpContains: case FcOpListing: @@ -750,7 +777,7 @@ FcConfigCompareValue (const FcValue *left_o, } break; case FcTypeString: - switch (op) { + switch ((int) op) { case FcOpEqual: case FcOpListing: if (flags & FcOpFlagIgnoreBlanks) @@ -775,7 +802,7 @@ FcConfigCompareValue (const FcValue *left_o, } break; case FcTypeMatrix: - switch (op) { + switch ((int) op) { case FcOpEqual: case FcOpContains: case FcOpListing: @@ -790,7 +817,7 @@ FcConfigCompareValue (const FcValue *left_o, } break; case FcTypeCharSet: - switch (op) { + switch ((int) op) { case FcOpContains: case FcOpListing: /* left contains right if right is a subset of left */ @@ -811,7 +838,7 @@ FcConfigCompareValue (const FcValue *left_o, } break; case FcTypeLangSet: - switch (op) { + switch ((int) op) { case FcOpContains: case FcOpListing: ret = FcLangSetContains (left.u.l, right.u.l); @@ -830,7 +857,7 @@ FcConfigCompareValue (const FcValue *left_o, } break; case FcTypeVoid: - switch (op) { + switch ((int) op) { case FcOpEqual: case FcOpContains: case FcOpListing: @@ -841,7 +868,7 @@ FcConfigCompareValue (const FcValue *left_o, } break; case FcTypeFTFace: - switch (op) { + switch ((int) op) { case FcOpEqual: case FcOpContains: case FcOpListing: @@ -874,15 +901,14 @@ FcConfigCompareValue (const FcValue *left_o, #define FcDoubleTrunc(d) ((d) >= 0 ? _FcDoubleFloor (d) : -_FcDoubleFloor (-(d))) static FcValue -FcConfigEvaluate (FcPattern *p, FcExpr *e) +FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e) { FcValue v, vl, vr; - FcResult r; FcMatrix *m; FcChar8 *str; FcOp op = FC_OP_GET_OP (e->op); - switch (op) { + switch ((int) op) { case FcOpInteger: v.type = FcTypeInteger; v.u.i = e->u.ival; @@ -897,9 +923,27 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) v = FcValueSave (v); break; case FcOpMatrix: - v.type = FcTypeMatrix; - v.u.m = e->u.mval; - v = FcValueSave (v); + { + FcMatrix m; + FcValue xx, xy, yx, yy; + v.type = FcTypeMatrix; + xx = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->xx), v, NULL); + xy = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->xy), v, NULL); + yx = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->yx), v, NULL); + yy = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->yy), v, NULL); + if (xx.type == FcTypeDouble && xy.type == FcTypeDouble && + yx.type == FcTypeDouble && yy.type == FcTypeDouble) + { + m.xx = xx.u.d; + m.xy = xy.u.d; + m.yx = yx.u.d; + m.yy = yy.u.d; + v.u.m = &m; + } + else + v.type = FcTypeVoid; + v = FcValueSave (v); + } break; case FcOpCharSet: v.type = FcTypeCharSet; @@ -916,9 +960,22 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) v.u.b = e->u.bval; break; case FcOpField: - r = FcPatternObjectGet (p, e->u.object, 0, &v); - if (r != FcResultMatch) + if (kind == FcMatchFont && e->u.name.kind == FcMatchPattern) + { + if (FcResultMatch != FcPatternObjectGet (p_pat, e->u.name.object, 0, &v)) + v.type = FcTypeVoid; + } + else if (kind == FcMatchPattern && e->u.name.kind == FcMatchFont) + { + fprintf (stderr, + "Fontconfig warning: tag has target=\"font\" in a .\n"); v.type = FcTypeVoid; + } + else + { + if (FcResultMatch != FcPatternObjectGet (p, e->u.name.object, 0, &v)) + v.type = FcTypeVoid; + } v = FcValueSave (v); break; case FcOpConst: @@ -928,13 +985,13 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) v.type = FcTypeVoid; break; case FcOpQuest: - vl = FcConfigEvaluate (p, e->u.tree.left); + vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left); if (vl.type == FcTypeBool) { if (vl.u.b) - v = FcConfigEvaluate (p, e->u.tree.right->u.tree.left); + v = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right->u.tree.left); else - v = FcConfigEvaluate (p, e->u.tree.right->u.tree.right); + v = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right->u.tree.right); } else v.type = FcTypeVoid; @@ -949,8 +1006,8 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) case FcOpContains: case FcOpNotContains: case FcOpListing: - vl = FcConfigEvaluate (p, e->u.tree.left); - vr = FcConfigEvaluate (p, e->u.tree.right); + vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left); + vr = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right); v.type = FcTypeBool; v.u.b = FcConfigCompareValue (&vl, e->op, &vr); FcValueDestroy (vl); @@ -962,15 +1019,15 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) case FcOpMinus: case FcOpTimes: case FcOpDivide: - vl = FcConfigEvaluate (p, e->u.tree.left); - vr = FcConfigEvaluate (p, e->u.tree.right); - vl = FcConfigPromote (vl, vr); - vr = FcConfigPromote (vr, vl); + vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left); + vr = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right); + vl = FcConfigPromote (vl, vr, NULL); + vr = FcConfigPromote (vr, vl, NULL); if (vl.type == vr.type) { - switch (vl.type) { + switch ((int) vl.type) { case FcTypeDouble: - switch (op) { + switch ((int) op) { case FcOpPlus: v.type = FcTypeDouble; v.u.d = vl.u.d + vr.u.d; @@ -999,7 +1056,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) } break; case FcTypeBool: - switch (op) { + switch ((int) op) { case FcOpOr: v.type = FcTypeBool; v.u.b = vl.u.b || vr.u.b; @@ -1014,11 +1071,11 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) } break; case FcTypeString: - switch (op) { + switch ((int) op) { case FcOpPlus: v.type = FcTypeString; str = FcStrPlus (vl.u.s, vr.u.s); - v.u.s = FcSharedStr (str); + v.u.s = FcStrdup (str); FcStrFree (str); if (!v.u.s) @@ -1030,13 +1087,12 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) } break; case FcTypeMatrix: - switch (op) { + switch ((int) op) { case FcOpTimes: v.type = FcTypeMatrix; m = malloc (sizeof (FcMatrix)); if (m) { - FcMemAlloc (FC_MEM_MATRIX, sizeof (FcMatrix)); FcMatrixMultiply (m, vl.u.m, vr.u.m); v.u.m = m; } @@ -1051,7 +1107,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) } break; case FcTypeCharSet: - switch (op) { + switch ((int) op) { case FcOpPlus: v.type = FcTypeCharSet; v.u.c = FcCharSetUnion (vl.u.c, vr.u.c); @@ -1070,7 +1126,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) } break; case FcTypeLangSet: - switch (op) { + switch ((int) op) { case FcOpPlus: v.type = FcTypeLangSet; v.u.l = FcLangSetUnion (vl.u.l, vr.u.l); @@ -1099,8 +1155,8 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) FcValueDestroy (vr); break; case FcOpNot: - vl = FcConfigEvaluate (p, e->u.tree.left); - switch (vl.type) { + vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left); + switch ((int) vl.type) { case FcTypeBool: v.type = FcTypeBool; v.u.b = !vl.u.b; @@ -1112,8 +1168,8 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) FcValueDestroy (vl); break; case FcOpFloor: - vl = FcConfigEvaluate (p, e->u.tree.left); - switch (vl.type) { + vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left); + switch ((int) vl.type) { case FcTypeInteger: v = vl; break; @@ -1128,8 +1184,8 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) FcValueDestroy (vl); break; case FcOpCeil: - vl = FcConfigEvaluate (p, e->u.tree.left); - switch (vl.type) { + vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left); + switch ((int) vl.type) { case FcTypeInteger: v = vl; break; @@ -1144,8 +1200,8 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) FcValueDestroy (vl); break; case FcOpRound: - vl = FcConfigEvaluate (p, e->u.tree.left); - switch (vl.type) { + vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left); + switch ((int) vl.type) { case FcTypeInteger: v = vl; break; @@ -1160,8 +1216,8 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) FcValueDestroy (vl); break; case FcOpTrunc: - vl = FcConfigEvaluate (p, e->u.tree.left); - switch (vl.type) { + vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left); + switch ((int) vl.type) { case FcTypeInteger: v = vl; break; @@ -1184,6 +1240,8 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) static FcValueList * FcConfigMatchValueList (FcPattern *p, + FcPattern *p_pat, + FcMatchKind kind, FcTest *t, FcValueList *values) { @@ -1197,12 +1255,12 @@ FcConfigMatchValueList (FcPattern *p, /* Compute the value of the match expression */ if (FC_OP_GET_OP (e->op) == FcOpComma) { - value = FcConfigEvaluate (p, e->u.tree.left); + value = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left); e = e->u.tree.right; } else { - value = FcConfigEvaluate (p, e); + value = FcConfigEvaluate (p, p_pat, kind, e); e = 0; } @@ -1229,7 +1287,7 @@ FcConfigMatchValueList (FcPattern *p, } static FcValueList * -FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding) +FcConfigValues (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e, FcValueBinding binding) { FcValueList *l; @@ -1238,15 +1296,14 @@ FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding) l = (FcValueList *) malloc (sizeof (FcValueList)); if (!l) return 0; - FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList)); if (FC_OP_GET_OP (e->op) == FcOpComma) { - l->value = FcConfigEvaluate (p, e->u.tree.left); - l->next = FcConfigValues (p, e->u.tree.right, binding); + l->value = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left); + l->next = FcConfigValues (p, p_pat, kind, e->u.tree.right, binding); } else { - l->value = FcConfigEvaluate (p, e); + l->value = FcConfigEvaluate (p, p_pat, kind, e); l->next = NULL; } l->binding = binding; @@ -1254,7 +1311,6 @@ FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding) { FcValueList *next = FcValueListNext(l); - FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList)); free (l); l = next; } @@ -1266,11 +1322,33 @@ static FcBool FcConfigAdd (FcValueListPtr *head, FcValueList *position, FcBool append, - FcValueList *new) + FcValueList *new, + FcObject object) { - FcValueListPtr *prev, last, v; + FcValueListPtr *prev, l, last, v; FcValueBinding sameBinding; + /* + * Make sure the stored type is valid for built-in objects + */ + for (l = new; l != NULL; l = FcValueListNext (l)) + { + if (!FcObjectValidType (object, l->value.type)) + { + fprintf (stderr, + "Fontconfig warning: FcPattern object %s does not accept value", FcObjectName (object)); + FcValuePrintFile (stderr, l->value); + fprintf (stderr, "\n"); + + if (FcDebug () & FC_DBG_EDIT) + { + printf ("Not adding\n"); + } + + return FcFalse; + } + } + if (position) sameBinding = position->binding; else @@ -1365,7 +1443,7 @@ FcConfigPatternAdd (FcPattern *p, if (!e) return; - FcConfigAdd (&e->values, 0, append, list); + FcConfigAdd (&e->values, 0, append, list, object); } } @@ -1449,7 +1527,6 @@ FcConfigSubstituteWithPat (FcConfig *config, st = (FcSubState *) malloc (config->maxObjects * sizeof (FcSubState)); if (!st && config->maxObjects) return FcFalse; - FcMemAlloc (FC_MEM_SUBSTATE, config->maxObjects * sizeof (FcSubState)); if (FcDebug () & FC_DBG_EDIT) { @@ -1496,7 +1573,7 @@ FcConfigSubstituteWithPat (FcConfig *config, * Check to see if there is a match, mark the location * to apply match-relative edits */ - st[i].value = FcConfigMatchValueList (m, t, st[i].elt->values); + st[i].value = FcConfigMatchValueList (m, p_pat, kind, t, st[i].elt->values); if (!st[i].value) break; if (t->qual == FcQualFirst && st[i].value != st[i].elt->values) @@ -1520,7 +1597,7 @@ FcConfigSubstituteWithPat (FcConfig *config, /* * Evaluate the list of expressions */ - l = FcConfigValues (p, e->expr, e->binding); + l = FcConfigValues (p, p_pat,kind, e->expr, e->binding); /* * Locate any test associated with this field, skipping * tests associated with the pattern when substituting in @@ -1558,7 +1635,7 @@ FcConfigSubstituteWithPat (FcConfig *config, /* * Append the new list of values after the current value */ - FcConfigAdd (&st[i].elt->values, thisValue, FcTrue, l); + FcConfigAdd (&st[i].elt->values, thisValue, FcTrue, l, e->object); /* * Delete the marked value */ @@ -1600,7 +1677,7 @@ FcConfigSubstituteWithPat (FcConfig *config, case FcOpPrepend: if (t) { - FcConfigAdd (&st[i].elt->values, st[i].value, FcFalse, l); + FcConfigAdd (&st[i].elt->values, st[i].value, FcFalse, l, e->object); break; } /* fall through ... */ @@ -1610,7 +1687,7 @@ FcConfigSubstituteWithPat (FcConfig *config, case FcOpAppend: if (t) { - FcConfigAdd (&st[i].elt->values, st[i].value, FcTrue, l); + FcConfigAdd (&st[i].elt->values, st[i].value, FcTrue, l, e->object); break; } /* fall through ... */ @@ -1635,7 +1712,6 @@ FcConfigSubstituteWithPat (FcConfig *config, FcPatternPrint (p); } } - FcMemFree (FC_MEM_SUBSTATE, config->maxObjects * sizeof (FcSubState)); free (st); if (FcDebug () & FC_DBG_EDIT) { @@ -1655,14 +1731,15 @@ FcConfigSubstitute (FcConfig *config, #if defined (_WIN32) -# define WIN32_LEAN_AND_MEAN -# define WIN32_EXTRA_LEAN -# include - -static FcChar8 fontconfig_path[1000] = ""; +static FcChar8 fontconfig_path[1000] = ""; /* MT-dontcare */ # if (defined (PIC) || defined (DLL_EXPORT)) +BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved); + BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, @@ -1748,7 +1825,6 @@ FcConfigFileExists (const FcChar8 *dir, const FcChar8 *file) #endif strcat ((char *) path, (char *) file); - FcMemAlloc (FC_MEM_STRING, osize); if (access ((char *) path, R_OK) == 0) return path; @@ -1838,7 +1914,7 @@ FcConfigFreePath (FcChar8 **path) free (path); } -static FcBool _FcConfigHomeEnabled = FcTrue; +static FcBool _FcConfigHomeEnabled = FcTrue; /* MT-goodenough */ FcChar8 * FcConfigHome (void) @@ -1873,7 +1949,6 @@ FcConfigXdgCacheHome (void) ret = malloc (len + 7 + 1); if (ret) { - FcMemAlloc (FC_MEM_STRING, len + 7 + 1); memcpy (ret, home, len); memcpy (&ret[len], FC_DIR_SEPARATOR_S ".cache", 7); ret[len + 7] = 0; @@ -1899,7 +1974,6 @@ FcConfigXdgConfigHome (void) ret = malloc (len + 8 + 1); if (ret) { - FcMemAlloc (FC_MEM_STRING, len + 8 + 1); memcpy (ret, home, len); memcpy (&ret[len], FC_DIR_SEPARATOR_S ".config", 8); ret[len + 8] = 0; @@ -1925,7 +1999,6 @@ FcConfigXdgDataHome (void) ret = malloc (len + 13 + 1); if (ret) { - FcMemAlloc (FC_MEM_STRING, len + 13 + 1); memcpy (ret, home, len); memcpy (&ret[len], FC_DIR_SEPARATOR_S ".local" FC_DIR_SEPARATOR_S "share", 13); ret[len + 13] = 0; diff --git a/fontconfig/src/fccharset.c b/fontconfig/src/fccharset.c index 8c1d85819..c9f928cd4 100644 --- a/fontconfig/src/fccharset.c +++ b/fontconfig/src/fccharset.c @@ -35,8 +35,7 @@ FcCharSetCreate (void) fcs = (FcCharSet *) malloc (sizeof (FcCharSet)); if (!fcs) return 0; - FcMemAlloc (FC_MEM_CHARSET, sizeof (FcCharSet)); - fcs->ref = 1; + FcRefInit (&fcs->ref, 1); fcs->num = 0; fcs->leaves_offset = 0; fcs->numbers_offset = 0; @@ -56,27 +55,20 @@ FcCharSetDestroy (FcCharSet *fcs) if (fcs) { - if (fcs->ref == FC_REF_CONSTANT) + if (FcRefIsConst (&fcs->ref)) { FcCacheObjectDereference (fcs); return; } - if (--fcs->ref > 0) + if (FcRefDec (&fcs->ref) != 1) return; for (i = 0; i < fcs->num; i++) - { - FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf)); free (FcCharSetLeaf (fcs, i)); - } if (fcs->num) { - /* the numbers here are estimates */ - FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t)); free (FcCharSetLeaves (fcs)); - FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16)); free (FcCharSetNumbers (fcs)); } - FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet)); free (fcs); } } @@ -157,24 +149,16 @@ FcCharSetPutLeaf (FcCharSet *fcs, unsigned int alloced = 8; leaves = malloc (alloced * sizeof (*leaves)); numbers = malloc (alloced * sizeof (*numbers)); - FcMemAlloc (FC_MEM_CHARSET, alloced * sizeof (*leaves)); - FcMemAlloc (FC_MEM_CHARSET, alloced * sizeof (*numbers)); } else { unsigned int alloced = fcs->num; intptr_t *new_leaves, distance; - FcMemFree (FC_MEM_CHARSET, alloced * sizeof (*leaves)); - FcMemFree (FC_MEM_CHARSET, alloced * sizeof (*numbers)); - alloced *= 2; new_leaves = realloc (leaves, alloced * sizeof (*leaves)); numbers = realloc (numbers, alloced * sizeof (*numbers)); - FcMemAlloc (FC_MEM_CHARSET, alloced * sizeof (*leaves)); - FcMemAlloc (FC_MEM_CHARSET, alloced * sizeof (*numbers)); - distance = (intptr_t) new_leaves - (intptr_t) leaves; if (new_leaves && distance) { @@ -227,7 +211,6 @@ FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4) free (leaf); return 0; } - FcMemAlloc (FC_MEM_CHARLEAF, sizeof (FcCharLeaf)); return leaf; } @@ -239,7 +222,6 @@ FcCharSetInsertLeaf (FcCharSet *fcs, FcChar32 ucs4, FcCharLeaf *leaf) pos = FcCharSetFindLeafPos (fcs, ucs4); if (pos >= 0) { - FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf)); free (FcCharSetLeaf (fcs, pos)); FcCharSetLeaves(fcs)[pos] = FcPtrToOffset (FcCharSetLeaves(fcs), leaf); @@ -255,7 +237,7 @@ FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4) FcCharLeaf *leaf; FcChar32 *b; - if (fcs == NULL || fcs->ref == FC_REF_CONSTANT) + if (fcs == NULL || FcRefIsConst (&fcs->ref)) return FcFalse; leaf = FcCharSetFindLeafCreate (fcs, ucs4); if (!leaf) @@ -271,7 +253,7 @@ FcCharSetDelChar (FcCharSet *fcs, FcChar32 ucs4) FcCharLeaf *leaf; FcChar32 *b; - if (fcs == NULL || fcs->ref == FC_REF_CONSTANT) + if (fcs == NULL || FcRefIsConst (&fcs->ref)) return FcFalse; leaf = FcCharSetFindLeaf (fcs, ucs4); if (!leaf) @@ -347,8 +329,8 @@ FcCharSetCopy (FcCharSet *src) { if (src) { - if (src->ref != FC_REF_CONSTANT) - src->ref++; + if (!FcRefIsConst (&src->ref)) + FcRefInc (&src->ref); else FcCacheObjectReference (src); } @@ -506,7 +488,7 @@ FcCharSetMerge (FcCharSet *a, const FcCharSet *b, FcBool *changed) if (!a || !b) return FcFalse; - if (a->ref == FC_REF_CONSTANT) { + if (FcRefIsConst (&a->ref)) { if (changed) *changed = FcFalse; return FcFalse; @@ -971,15 +953,12 @@ FcNameParseCharSet (FcChar8 *string) bail1: if (c->num) { - FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcCharLeaf *)); free (FcCharSetLeaves (c)); } if (c->num) { - FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcChar16)); free (FcCharSetNumbers (c)); } - FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet)); free (c); bail0: return NULL; @@ -1116,7 +1095,6 @@ FcCharLeafEntCreate (FcCharSetFreezer *freezer) freezer->current_block = freezer->leaf_blocks[freezer->leaf_block_count-1] = malloc (FC_CHAR_LEAF_BLOCK * sizeof (FcCharLeafEnt)); if (!freezer->current_block) return 0; - FcMemAlloc (FC_MEM_CHARLEAF, FC_CHAR_LEAF_BLOCK * sizeof (FcCharLeafEnt)); freezer->leaf_remain = FC_CHAR_LEAF_BLOCK; } freezer->leaf_remain--; @@ -1190,7 +1168,7 @@ FcCharSetFreezeOrig (FcCharSetFreezer *freezer, const FcCharSet *orig, const FcC } static FcCharSet * -FcCharSetFreezeBase (FcCharSetFreezer *freezer, FcCharSet *fcs, const FcCharSet *orig) +FcCharSetFreezeBase (FcCharSetFreezer *freezer, FcCharSet *fcs) { FcChar32 hash = FcCharSetHash (fcs); FcCharSetEnt **bucket = &freezer->set_hash_table[hash % FC_CHAR_SET_HASH_SIZE]; @@ -1223,11 +1201,10 @@ FcCharSetFreezeBase (FcCharSetFreezer *freezer, FcCharSet *fcs, const FcCharSet ent = malloc (size); if (!ent) return 0; - FcMemAlloc (FC_MEM_CHARSET, size); freezer->charsets_allocated++; - ent->set.ref = FC_REF_CONSTANT; + FcRefSetConst (&ent->set.ref); ent->set.num = fcs->num; if (fcs->num) { @@ -1289,7 +1266,7 @@ FcCharSetFreeze (FcCharSetFreezer *freezer, const FcCharSet *fcs) if (!FcCharSetInsertLeaf (b, FcCharSetNumbers(fcs)[i] << 8, l)) goto bail1; } - n = FcCharSetFreezeBase (freezer, b, fcs); + n = FcCharSetFreezeBase (freezer, b); if (!FcCharSetFreezeOrig (freezer, fcs, n)) { n = NULL; @@ -1299,16 +1276,9 @@ FcCharSetFreeze (FcCharSetFreezer *freezer, const FcCharSet *fcs) freezer->leaves_seen += fcs->num; bail1: if (b->num) - { - FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcCharLeaf *)); free (FcCharSetLeaves (b)); - } if (b->num) - { - FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcChar16)); free (FcCharSetNumbers (b)); - } - FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet)); free (b); bail0: return n; @@ -1340,9 +1310,6 @@ FcCharSetFreezerDestroy (FcCharSetFreezer *freezer) for (ent = freezer->set_hash_table[i]; ent; ent = next) { next = ent->next; - FcMemFree (FC_MEM_CHARSET, (sizeof (FcCharSetEnt) + - ent->set.num * sizeof (FcCharLeaf *) + - ent->set.num * sizeof (FcChar16))); free (ent); } } @@ -1358,10 +1325,7 @@ FcCharSetFreezerDestroy (FcCharSetFreezer *freezer) } for (i = 0; i < freezer->leaf_block_count; i++) - { free (freezer->leaf_blocks[i]); - FcMemFree (FC_MEM_CHARLEAF, FC_CHAR_LEAF_BLOCK * sizeof (FcCharLeafEnt)); - } free (freezer->leaf_blocks); free (freezer); @@ -1374,7 +1338,7 @@ FcCharSetSerializeAlloc (FcSerialize *serialize, const FcCharSet *cs) FcChar16 *numbers; int i; - if (cs->ref != FC_REF_CONSTANT) + if (!FcRefIsConst (&cs->ref)) { if (!serialize->cs_freezer) { @@ -1413,7 +1377,7 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs) FcCharLeaf *leaf, *leaf_serialized; int i; - if (cs->ref != FC_REF_CONSTANT && serialize->cs_freezer) + if (!FcRefIsConst (&cs->ref) && serialize->cs_freezer) { cs = FcCharSetFindFrozen (serialize->cs_freezer, cs); if (!cs) @@ -1424,7 +1388,7 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs) if (!cs_serialized) return NULL; - cs_serialized->ref = FC_REF_CONSTANT; + FcRefSetConst (&cs_serialized->ref); cs_serialized->num = cs->num; if (cs->num) diff --git a/fontconfig/src/fcdbg.c b/fontconfig/src/fcdbg.c index a1ed2b2dd..270d79179 100644 --- a/fontconfig/src/fcdbg.c +++ b/fontconfig/src/fcdbg.c @@ -27,44 +27,52 @@ #include static void -_FcValuePrint (const FcValue v) +_FcValuePrintFile (FILE *f, const FcValue v) { switch (v.type) { case FcTypeVoid: - printf (""); + fprintf (f, ""); break; case FcTypeInteger: - printf ("%d(i)", v.u.i); + fprintf (f, "%d(i)", v.u.i); break; case FcTypeDouble: - printf ("%g(f)", v.u.d); + fprintf (f, "%g(f)", v.u.d); break; case FcTypeString: - printf ("\"%s\"", v.u.s); + fprintf (f, "\"%s\"", v.u.s); break; case FcTypeBool: - printf ("%s", v.u.b ? "FcTrue" : "FcFalse"); + fprintf (f, "%s", v.u.b ? "True" : "False"); break; case FcTypeMatrix: - printf ("(%f %f; %f %f)", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); + fprintf (f, "[%g %g; %g %g]", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); break; case FcTypeCharSet: /* XXX */ - FcCharSetPrint (v.u.c); + if (f == stdout) + FcCharSetPrint (v.u.c); break; case FcTypeLangSet: FcLangSetPrint (v.u.l); break; case FcTypeFTFace: - printf ("face"); + fprintf (f, "face"); break; } } +void +FcValuePrintFile (FILE *f, const FcValue v) +{ + fprintf (f, " "); + _FcValuePrintFile (f, v); +} + void FcValuePrint (const FcValue v) { printf (" "); - _FcValuePrint (v); + _FcValuePrintFile (stdout, v); } void @@ -74,7 +82,7 @@ FcValuePrintWithPosition (const FcValue v, FcBool show_pos_mark) printf (" [insert here] "); else printf (" "); - _FcValuePrint (v); + _FcValuePrintFile (stdout, v); } static void @@ -249,11 +257,17 @@ FcExprPrint (const FcExpr *expr) case FcOpInteger: printf ("%d", expr->u.ival); break; case FcOpDouble: printf ("%g", expr->u.dval); break; case FcOpString: printf ("\"%s\"", expr->u.sval); break; - case FcOpMatrix: printf ("[%g %g %g %g]", - expr->u.mval->xx, - expr->u.mval->xy, - expr->u.mval->yx, - expr->u.mval->yy); break; + case FcOpMatrix: + printf ("["); + FcExprPrint (expr->u.mexpr->xx); + printf (" "); + FcExprPrint (expr->u.mexpr->xy); + printf ("; "); + FcExprPrint (expr->u.mexpr->yx); + printf (" "); + FcExprPrint (expr->u.mexpr->yy); + printf ("]"); + break; case FcOpRange: break; case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break; case FcOpCharSet: printf ("charset\n"); break; @@ -263,7 +277,16 @@ FcExprPrint (const FcExpr *expr) printf ("\n"); break; case FcOpNil: printf ("nil\n"); break; - case FcOpField: printf ("%s", FcObjectName(expr->u.object)); break; + case FcOpField: printf ("%s ", FcObjectName(expr->u.name.object)); + switch ((int) expr->u.name.kind) { + case FcMatchPattern: + printf ("(pattern) "); + break; + case FcMatchFont: + printf ("(font) "); + break; + } + break; case FcOpConst: printf ("%s", expr->u.constant); break; case FcOpQuest: FcExprPrint (expr->u.tree.left); @@ -432,15 +455,17 @@ int FcDebugVal; void FcInitDebug (void) { - char *e; + if (!FcDebugVal) { + char *e; - e = getenv ("FC_DEBUG"); - if (e) - { - printf ("FC_DEBUG=%s\n", e); - FcDebugVal = atoi (e); - if (FcDebugVal < 0) - FcDebugVal = 0; + e = getenv ("FC_DEBUG"); + if (e) + { + printf ("FC_DEBUG=%s\n", e); + FcDebugVal = atoi (e); + if (FcDebugVal < 0) + FcDebugVal = 0; + } } } #define __fcdbg__ diff --git a/fontconfig/src/fcdefault.c b/fontconfig/src/fcdefault.c index 8ad1b1e90..6937994b7 100644 --- a/fontconfig/src/fcdefault.c +++ b/fontconfig/src/fcdefault.c @@ -25,6 +25,8 @@ #include "fcint.h" #include +/* MT-safe */ + static const struct { FcObject field; FcBool value; @@ -32,7 +34,6 @@ static const struct { { FC_HINTING_OBJECT, FcTrue }, /* !FT_LOAD_NO_HINTING */ { FC_VERTICAL_LAYOUT_OBJECT, FcFalse }, /* FC_LOAD_VERTICAL_LAYOUT */ { FC_AUTOHINT_OBJECT, FcFalse }, /* FC_LOAD_FORCE_AUTOHINT */ - /* XXX: FC_GLOBAL_ADVANCE is deprecated */ { FC_GLOBAL_ADVANCE_OBJECT, FcTrue }, /* !FC_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ { FC_EMBEDDED_BITMAP_OBJECT, FcTrue }, /* !FC_LOAD_NO_BITMAP */ { FC_DECORATIVE_OBJECT, FcFalse }, @@ -40,45 +41,85 @@ static const struct { #define NUM_FC_BOOL_DEFAULTS (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0]) +FcStrSet *default_langs; + FcStrSet * FcGetDefaultLangs (void) { - FcStrSet *result = FcStrSetCreate (); - char *langs; - - langs = getenv ("FC_LANG"); - if (!langs || !langs[0]) - langs = getenv ("LC_ALL"); - if (!langs || !langs[0]) - langs = getenv ("LC_CTYPE"); - if (!langs || !langs[0]) - langs = getenv ("LANG"); - if (langs && langs[0]) + FcStrSet *result; +retry: + result = (FcStrSet *) fc_atomic_ptr_get (&default_langs); + if (!result) { - if (!FcStrSetAddLangs (result, langs)) + char *langs; + + result = FcStrSetCreate (); + + langs = getenv ("FC_LANG"); + if (!langs || !langs[0]) + langs = getenv ("LC_ALL"); + if (!langs || !langs[0]) + langs = getenv ("LC_CTYPE"); + if (!langs || !langs[0]) + langs = getenv ("LANG"); + if (langs && langs[0]) + { + if (!FcStrSetAddLangs (result, langs)) + FcStrSetAdd (result, (const FcChar8 *) "en"); + } + else FcStrSetAdd (result, (const FcChar8 *) "en"); + + FcRefSetConst (&result->ref); + if (!fc_atomic_ptr_cmpexch (&default_langs, NULL, result)) { + FcRefInit (&result->ref, 1); + FcStrSetDestroy (result); + goto retry; + } } - else - FcStrSetAdd (result, (const FcChar8 *) "en"); return result; } +static FcChar8 *default_lang; /* MT-safe */ + FcChar8 * FcGetDefaultLang (void) { - static FcChar8 lang_local[128] = {0}; - FcStrSet *langs; - - if (!lang_local[0]) + FcChar8 *lang; +retry: + lang = fc_atomic_ptr_get (&default_lang); + if (!lang) { - langs = FcGetDefaultLangs (); - strncpy ((char *)lang_local, (const char *)langs->strs[0], 127); - lang_local[127] = 0; + FcStrSet *langs = FcGetDefaultLangs (); + lang = FcStrdup (langs->strs[0]); FcStrSetDestroy (langs); + + if (!fc_atomic_ptr_cmpexch (&default_lang, NULL, lang)) { + free (lang); + goto retry; + } } - return lang_local; + return lang; +} + +void +FcDefaultFini (void) +{ + FcChar8 *lang; + FcStrSet *langs; + + lang = fc_atomic_ptr_get (&default_lang); + if (lang && fc_atomic_ptr_cmpexch (&default_lang, lang, NULL)) { + free (lang); + } + + langs = fc_atomic_ptr_get (&default_langs); + if (langs && fc_atomic_ptr_cmpexch (&default_langs, langs, NULL)) { + FcRefInit (&langs->ref, 1); + FcStrSetDestroy (langs); + } } void @@ -154,7 +195,7 @@ FcDefaultSubstitute (FcPattern *pattern) * exact matched "en" has higher score than ll-cc. */ v2.type = FcTypeString; - v2.u.s = FcSharedStr ((FcChar8 *)"en-us"); + v2.u.s = FcStrdup ("en-us"); if (FcPatternObjectGet (pattern, FC_FAMILYLANG_OBJECT, 0, &v) == FcResultNoMatch) { FcPatternObjectAdd (pattern, FC_FAMILYLANG_OBJECT, namelang, FcTrue); @@ -170,7 +211,7 @@ FcDefaultSubstitute (FcPattern *pattern) FcPatternObjectAdd (pattern, FC_FULLNAMELANG_OBJECT, namelang, FcTrue); FcPatternObjectAddWithBinding (pattern, FC_FULLNAMELANG_OBJECT, v2, FcValueBindingWeak, FcTrue); } - FcSharedStrFree (v2.u.s); + FcFree (v2.u.s); } #define __fcdefault__ #include "fcaliastail.h" diff --git a/fontconfig/src/fcdir.c b/fontconfig/src/fcdir.c index 6869ea179..dc580bb6f 100644 --- a/fontconfig/src/fcdir.c +++ b/fontconfig/src/fcdir.c @@ -126,10 +126,10 @@ FcFileScanConfig (FcFontSet *set, FcBool FcFileScan (FcFontSet *set, FcStrSet *dirs, - FcFileCache *cache, /* XXX unused */ + FcFileCache *cache FC_UNUSED, FcBlanks *blanks, const FcChar8 *file, - FcBool force) + FcBool force FC_UNUSED) { return FcFileScanConfig (set, dirs, blanks, file, FcConfigGetCurrent ()); } @@ -316,7 +316,7 @@ FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config) } FcBool -FcDirSave (FcFontSet *set, FcStrSet * dirs, const FcChar8 *dir) +FcDirSave (FcFontSet *set FC_UNUSED, FcStrSet * dirs FC_UNUSED, const FcChar8 *dir FC_UNUSED) { return FcFalse; /* XXX deprecated */ } diff --git a/fontconfig/src/fcformat.c b/fontconfig/src/fcformat.c index 8eef7bb29..59f8681df 100644 --- a/fontconfig/src/fcformat.c +++ b/fontconfig/src/fcformat.c @@ -358,7 +358,7 @@ skip_percent (FcFormatContext *c) /* skip an optional width specifier */ if (strtol ((const char *) c->format, (char **) &c->format, 10)) - /* don't care */; + {/* don't care */} if (!expect_char (c, '{')) return FcFalse; @@ -790,7 +790,7 @@ interpret_simple (FcFormatContext *c, } static FcBool -cescape (FcFormatContext *c, +cescape (FcFormatContext *c FC_UNUSED, const FcChar8 *str, FcStrBuf *buf) { @@ -811,7 +811,7 @@ cescape (FcFormatContext *c, } static FcBool -shescape (FcFormatContext *c, +shescape (FcFormatContext *c FC_UNUSED, const FcChar8 *str, FcStrBuf *buf) { @@ -829,7 +829,7 @@ shescape (FcFormatContext *c, } static FcBool -xmlescape (FcFormatContext *c, +xmlescape (FcFormatContext *c FC_UNUSED, const FcChar8 *str, FcStrBuf *buf) { @@ -1193,12 +1193,19 @@ FcPatternFormat (FcPattern *pat, { FcStrBuf buf; FcChar8 buf_static[8192 - 1024]; + FcPattern *alloced = NULL; FcBool ret; + if (!pat) + alloced = pat = FcPatternCreate (); + FcStrBufInit (&buf, buf_static, sizeof (buf_static)); ret = FcPatternFormatToBuf (pat, format, &buf); + if (alloced) + FcPatternDestroy (alloced); + if (ret) return FcStrBufDone (&buf); else diff --git a/fontconfig/src/fcfreetype.c b/fontconfig/src/fcfreetype.c index fb2b0f2f9..9ac2fa901 100644 --- a/fontconfig/src/fcfreetype.c +++ b/fontconfig/src/fcfreetype.c @@ -1005,7 +1005,6 @@ static const FcStringConst slantConsts[] = { #define NUM_SLANT_CONSTS (int) (sizeof (slantConsts) / sizeof (slantConsts[0])) -#define FcIsSlant(s) FcStringIsConst(s,slantConsts,NUM_SLANT_CONSTS) #define FcContainsSlant(s) FcStringContainsConst (s,slantConsts,NUM_SLANT_CONSTS) static const FcStringConst decorativeConsts[] = { @@ -1019,7 +1018,6 @@ static const FcStringConst decorativeConsts[] = { #define NUM_DECORATIVE_CONSTS (int) (sizeof (decorativeConsts) / sizeof (decorativeConsts[0])) -#define FcIsDecorative(s) FcStringIsConst(s,decorativeConsts,NUM_DECORATIVE_CONSTS) #define FcContainsDecorative(s) FcStringContainsConst (s,decorativeConsts,NUM_DECORATIVE_CONSTS) static double @@ -1119,8 +1117,8 @@ FcFreeTypeQueryFace (const FT_Face face, int nstyle_lang = 0; int nfullname = 0; int nfullname_lang = 0; - int p, platform; - int n, nameid; + unsigned int p, n; + int platform, nameid; FcChar8 *style = 0; int st; @@ -1201,7 +1199,7 @@ FcFreeTypeQueryFace (const FT_Face face, } else { - int sp; + unsigned int sp; for (sp = 0; sp < NUM_PLATFORM_ORDER; sp++) if (sname.platform_id == platform_order[sp]) @@ -2262,7 +2260,7 @@ FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4, *advance = slot->metrics.horiAdvance; - switch (slot->format) { + switch ((int) slot->format) { case ft_glyph_format_bitmap: /* * Bitmaps are assumed to be reasonable; if @@ -2598,7 +2596,7 @@ addtag(FcChar8 *complex_, FT_ULong tag) if (*complex_ != '\0') strcat ((char *) complex_, " "); - strcat ((char *) complex_, "otlayout:"); + strcat ((char *) complex_, OTLAYOUT_HEAD); strcat ((char *) complex_, (char *) tagstring); } diff --git a/fontconfig/src/fcfs.c b/fontconfig/src/fcfs.c index 6625687c1..941abba8f 100644 --- a/fontconfig/src/fcfs.c +++ b/fontconfig/src/fcfs.c @@ -33,7 +33,6 @@ FcFontSetCreate (void) s = (FcFontSet *) malloc (sizeof (FcFontSet)); if (!s) return 0; - FcMemAlloc (FC_MEM_FONTSET, sizeof (FcFontSet)); s->nfont = 0; s->sfont = 0; s->fonts = 0; @@ -48,11 +47,7 @@ FcFontSetDestroy (FcFontSet *s) for (i = 0; i < s->nfont; i++) FcPatternDestroy (s->fonts[i]); if (s->fonts) - { - FcMemFree (FC_MEM_FONTPTR, s->sfont * sizeof (FcPattern *)); free (s->fonts); - } - FcMemFree (FC_MEM_FONTSET, sizeof (FcFontSet)); free (s); } @@ -71,9 +66,6 @@ FcFontSetAdd (FcFontSet *s, FcPattern *font) f = (FcPattern **) malloc (sfont * sizeof (FcPattern *)); if (!f) return FcFalse; - if (s->sfont) - FcMemFree (FC_MEM_FONTPTR, s->sfont * sizeof (FcPattern *)); - FcMemAlloc (FC_MEM_FONTPTR, sfont * sizeof (FcPattern *)); s->sfont = sfont; s->fonts = f; } diff --git a/fontconfig/src/fcinit.c b/fontconfig/src/fcinit.c index 606483d8d..2360764fc 100644 --- a/fontconfig/src/fcinit.c +++ b/fontconfig/src/fcinit.c @@ -25,6 +25,16 @@ #include "fcint.h" #include +#if defined(FC_ATOMIC_INT_NIL) +#pragma message("Could not find any system to define atomic_int macros, library may NOT be thread-safe.") +#endif +#if defined(FC_MUTEX_IMPL_NIL) +#pragma message("Could not find any system to define mutex macros, library may NOT be thread-safe.") +#endif +#if defined(FC_ATOMIC_INT_NIL) || defined(FC_MUTEX_IMPL_NIL) +#pragma message("To suppress these warnings, define FC_NO_MT.") +#endif + static FcConfig * FcInitFallbackConfig (void) { @@ -88,8 +98,6 @@ FcInitLoadConfig (void) if (!p) goto bail; prefix = p; - FcMemFree (FC_MEM_STRING, plen + 1); - FcMemAlloc (FC_MEM_STRING, plen + 12); memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11); prefix[plen + 11] = 0; fprintf (stderr, @@ -137,17 +145,7 @@ FcInitLoadConfigAndFonts (void) FcBool FcInit (void) { - FcConfig *config; - - if (_fcConfig) - return FcTrue; - config = FcInitLoadConfigAndFonts (); - if (!config) - return FcFalse; - FcConfigSetCurrent (config); - if (FcDebug() & FC_DBG_MEMORY) - FcMemReport (); - return FcTrue; + return FcConfigInit (); } /* @@ -156,13 +154,9 @@ FcInit (void) void FcFini (void) { - if (_fcConfig) - FcConfigDestroy (_fcConfig); - - FcObjectFini (); + FcConfigFini (); FcCacheFini (); - if (FcDebug() & FC_DBG_MEMORY) - FcMemReport (); + FcDefaultFini (); } /* @@ -176,8 +170,7 @@ FcInitReinitialize (void) config = FcInitLoadConfigAndFonts (); if (!config) return FcFalse; - FcConfigSetCurrent (config); - return FcTrue; + return FcConfigSetCurrent (config); } FcBool @@ -205,105 +198,6 @@ FcInitBringUptoDate (void) return FcInitReinitialize (); } -static struct { - char name[16]; - int alloc_count; - int alloc_mem; - int free_count; - int free_mem; -} FcInUse[FC_MEM_NUM] = { - { "charset" }, - { "charleaf" }, - { "fontset" }, - { "fontptr" }, - { "objectset" }, - { "objectptr" }, - { "matrix" }, - { "pattern" }, - { "patelt" }, - { "vallist" }, - { "substate" }, - { "string" }, - { "listbuck" }, - { "strset" }, - { "strlist" }, - { "config" }, - { "langset" }, - { "atomic" }, - { "blanks" }, - { "cache" }, - { "strbuf" }, - { "subst" }, - { "objecttype" }, - { "constant" }, - { "test" }, - { "expr" }, - { "vstack" }, - { "attr" }, - { "pstack" }, - { "sharedstr" }, -}; - -static int FcAllocCount, FcAllocMem; -static int FcFreeCount, FcFreeMem; - -static int FcMemNotice = 1*1024*1024; - -static int FcAllocNotify, FcFreeNotify; - -void -FcMemReport (void) -{ - int i; - printf ("Fc Memory Usage:\n"); - printf ("\t Which Alloc Free Active\n"); - printf ("\t count bytes count bytes count bytes\n"); - for (i = 0; i < FC_MEM_NUM; i++) - printf ("%16.16s%8d%8d%8d%8d%8d%8d\n", - FcInUse[i].name, - FcInUse[i].alloc_count, FcInUse[i].alloc_mem, - FcInUse[i].free_count, FcInUse[i].free_mem, - FcInUse[i].alloc_count - FcInUse[i].free_count, - FcInUse[i].alloc_mem - FcInUse[i].free_mem); - printf ("%16.16s%8d%8d%8d%8d%8d%8d\n", - "Total", - FcAllocCount, FcAllocMem, - FcFreeCount, FcFreeMem, - FcAllocCount - FcFreeCount, - FcAllocMem - FcFreeMem); - FcAllocNotify = 0; - FcFreeNotify = 0; -} - -void -FcMemAlloc (int kind, int size) -{ - if (FcDebug() & FC_DBG_MEMORY) - { - FcInUse[kind].alloc_count++; - FcInUse[kind].alloc_mem += size; - FcAllocCount++; - FcAllocMem += size; - FcAllocNotify += size; - if (FcAllocNotify > FcMemNotice) - FcMemReport (); - } -} - -void -FcMemFree (int kind, int size) -{ - if (FcDebug() & FC_DBG_MEMORY) - { - FcInUse[kind].free_count++; - FcInUse[kind].free_mem += size; - FcFreeCount++; - FcFreeMem += size; - FcFreeNotify += size; - if (FcFreeNotify > FcMemNotice) - FcMemReport (); - } -} #define __fcinit__ #include "fcaliastail.h" #undef __fcinit__ diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h index 87c7b9a9f..38bd9bb73 100644 --- a/fontconfig/src/fcint.h +++ b/fontconfig/src/fcint.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -44,18 +45,15 @@ #include #include #include "fcdeprecate.h" +#include "fcmutex.h" +#include "fcatomic.h" #ifndef FC_CONFIG_PATH #define FC_CONFIG_PATH "fonts.conf" #endif #ifdef _WIN32 -# ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0500 -# endif -# define WIN32_LEAN_AND_MEAN -# define STRICT -# include +# include "fcwindows.h" typedef UINT (WINAPI *pfnGetSystemWindowsDirectory)(LPSTR, UINT); typedef HRESULT (WINAPI *pfnSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR); extern pfnGetSystemWindowsDirectory pGetSystemWindowsDirectory; @@ -69,6 +67,12 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA; # define FC_DIR_SEPARATOR_S "/" #endif +#if __GNUC__ >= 4 +#define FC_UNUSED __attribute__((unused)) +#else +#define FC_UNUSED +#endif + #define FC_DBG_MATCH 1 #define FC_DBG_MATCHV 2 #define FC_DBG_EDIT 4 @@ -78,43 +82,8 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA; #define FC_DBG_PARSE 64 #define FC_DBG_SCAN 128 #define FC_DBG_SCANV 256 -#define FC_DBG_MEMORY 512 #define FC_DBG_CONFIG 1024 #define FC_DBG_LANGSET 2048 -#define FC_DBG_OBJTYPES 4096 - -#define FC_MEM_CHARSET 0 -#define FC_MEM_CHARLEAF 1 -#define FC_MEM_FONTSET 2 -#define FC_MEM_FONTPTR 3 -#define FC_MEM_OBJECTSET 4 -#define FC_MEM_OBJECTPTR 5 -#define FC_MEM_MATRIX 6 -#define FC_MEM_PATTERN 7 -#define FC_MEM_PATELT 8 -#define FC_MEM_VALLIST 9 -#define FC_MEM_SUBSTATE 10 -#define FC_MEM_STRING 11 -#define FC_MEM_LISTBUCK 12 -#define FC_MEM_STRSET 13 -#define FC_MEM_STRLIST 14 -#define FC_MEM_CONFIG 15 -#define FC_MEM_LANGSET 16 -#define FC_MEM_ATOMIC 17 -#define FC_MEM_BLANKS 18 -#define FC_MEM_CACHE 19 -#define FC_MEM_STRBUF 20 -#define FC_MEM_SUBST 21 -#define FC_MEM_OBJECTTYPE 22 -#define FC_MEM_CONSTANT 23 -#define FC_MEM_TEST 24 -#define FC_MEM_EXPR 25 -#define FC_MEM_VSTACK 26 -#define FC_MEM_ATTR 27 -#define FC_MEM_PSTACK 28 -#define FC_MEM_SHAREDSTR 29 - -#define FC_MEM_NUM 30 #define _FC_ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] #define _FC_ASSERT_STATIC0(_line, _cond) _FC_ASSERT_STATIC1 (_line, (_cond)) @@ -135,10 +104,15 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA; #define FcPrivate #endif +FC_ASSERT_STATIC (sizeof (FcRef) == sizeof (int)); + typedef enum _FcValueBinding { FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame } FcValueBinding; +#define FcStrdup(s) ((FcChar8 *) strdup ((const char *) (s))) +#define FcFree(s) (free ((FcChar8 *) (s))) + /* * Serialized data structures use only offsets instead of pointers * A low bit of 1 indicates an offset. @@ -215,7 +189,7 @@ struct _FcPattern { int num; int size; intptr_t elts_offset; - int ref; + FcRef ref; }; #define FcPatternElts(p) FcOffsetMember(p,elts_offset,FcPatternElt) @@ -251,17 +225,28 @@ typedef enum _FcOpFlags { #define FC_OP_GET_FLAGS(_x_) (((_x_) & 0xffff0000) >> 16) #define FC_OP(_x_,_f_) (FC_OP_GET_OP (_x_) | ((_f_) << 16)) +typedef struct _FcExprMatrix { + struct _FcExpr *xx, *xy, *yx, *yy; +} FcExprMatrix; + +typedef struct _FcExprName { + FcObject object; + FcMatchKind kind; +} FcExprName; + + typedef struct _FcExpr { FcOp op; union { int ival; double dval; const FcChar8 *sval; - FcMatrix *mval; + FcExprMatrix *mexpr; FcBool bval; FcCharSet *cval; FcLangSet *lval; - FcObject object; + + FcExprName name; const FcChar8 *constant; struct { struct _FcExpr *left, *right; @@ -311,10 +296,8 @@ typedef struct _FcCharLeaf { FcChar32 map[256/32]; } FcCharLeaf; -#define FC_REF_CONSTANT -1 - struct _FcCharSet { - int ref; /* reference count */ + FcRef ref; /* reference count */ int num; /* size of leaves and numbers arrays */ intptr_t leaves_offset; intptr_t numbers_offset; @@ -327,7 +310,7 @@ struct _FcCharSet { #define FcCharSetNumbers(c) FcOffsetMember(c,numbers_offset,FcChar16) struct _FcStrSet { - int ref; /* reference count */ + FcRef ref; /* reference count */ int num; int size; FcChar8 **strs; @@ -348,7 +331,7 @@ typedef struct _FcStrBuf { } FcStrBuf; struct _FcCache { - int magic; /* FC_CACHE_MAGIC_MMAP or FC_CACHE_ALLOC */ + unsigned int magic; /* FC_CACHE_MAGIC_MMAP or FC_CACHE_ALLOC */ int version; /* FC_CACHE_CONTENT_VERSION */ intptr_t size; /* size of file */ intptr_t dir; /* offset to dir name */ @@ -441,7 +424,7 @@ typedef struct _FcCaseFold { #define FC_CACHE_MAGIC_MMAP 0xFC02FC04 #define FC_CACHE_MAGIC_ALLOC 0xFC02FC05 -#define FC_CACHE_CONTENT_VERSION 3 /* also check FC_CACHE_VERSION */ +#define FC_CACHE_CONTENT_VERSION 3 struct _FcAtomic { FcChar8 *file; /* original file name */ @@ -515,13 +498,11 @@ struct _FcConfig { time_t rescanTime; /* last time information was scanned */ int rescanInterval; /* interval between scans */ - int ref; /* reference count */ + FcRef ref; /* reference count */ FcExprPage *expr_pool; /* pool of FcExpr's */ }; -extern FcPrivate FcConfig *_fcConfig; - typedef struct _FcFileTime { time_t time; FcBool set; @@ -543,6 +524,17 @@ struct _FcStatFS { FcBool is_mtime_broken; }; +typedef struct _FcValuePromotionBuffer FcValuePromotionBuffer; + +struct _FcValuePromotionBuffer { + union { + double d; + int i; + long l; + char c[256]; /* Enlarge as needed */ + } u; +}; + /* fcblanks.c */ /* fccache.c */ @@ -573,6 +565,12 @@ FcDirCacheReference (FcCache *cache, int nref); /* fccfg.c */ +FcPrivate FcBool +FcConfigInit (void); + +FcPrivate void +FcConfigFini (void); + FcPrivate FcChar8 * FcConfigXdgCacheHome (void); @@ -720,6 +718,10 @@ FcPrivate FcChar16 * FcCharSetGetNumbers(const FcCharSet *c); /* fcdbg.c */ + +FcPrivate void +FcValuePrintFile (FILE *f, const FcValue v); + FcPrivate void FcValuePrintWithPosition (const FcValue v, FcBool show_pos_mark); @@ -761,6 +763,9 @@ FcInitDebug (void); FcPrivate FcChar8 * FcGetDefaultLang (void); +FcPrivate void +FcDefaultFini (void); + /* fcdir.c */ FcPrivate FcBool @@ -800,17 +805,6 @@ FcTestDestroy (FcTest *test); FcPrivate void FcEditDestroy (FcEdit *e); -/* fcinit.c */ - -FcPrivate void -FcMemReport (void); - -FcPrivate void -FcMemAlloc (int kind, int size); - -FcPrivate void -FcMemFree (int kind, int size); - /* fclang.c */ FcPrivate FcLangSet * FcFreeTypeLangSet (const FcCharSet *charset, @@ -823,7 +817,7 @@ FcPrivate FcLangResult FcLangCompare (const FcChar8 *s1, const FcChar8 *s2); FcPrivate FcLangSet * -FcLangSetPromote (const FcChar8 *lang); +FcLangSetPromote (const FcChar8 *lang, FcValuePromotionBuffer *buf); FcPrivate FcLangSet * FcNameParseLangSet (const FcChar8 *string); @@ -844,54 +838,14 @@ FcListPatternMatchAny (const FcPattern *p, /* fcname.c */ -/* - * NOTE -- this ordering is part of the cache file format. - * It must also match the ordering in fcname.c - */ - -#define FC_FAMILY_OBJECT 1 -#define FC_FAMILYLANG_OBJECT 2 -#define FC_STYLE_OBJECT 3 -#define FC_STYLELANG_OBJECT 4 -#define FC_FULLNAME_OBJECT 5 -#define FC_FULLNAMELANG_OBJECT 6 -#define FC_SLANT_OBJECT 7 -#define FC_WEIGHT_OBJECT 8 -#define FC_WIDTH_OBJECT 9 -#define FC_SIZE_OBJECT 10 -#define FC_ASPECT_OBJECT 11 -#define FC_PIXEL_SIZE_OBJECT 12 -#define FC_SPACING_OBJECT 13 -#define FC_FOUNDRY_OBJECT 14 -#define FC_ANTIALIAS_OBJECT 15 -#define FC_HINT_STYLE_OBJECT 16 -#define FC_HINTING_OBJECT 17 -#define FC_VERTICAL_LAYOUT_OBJECT 18 -#define FC_AUTOHINT_OBJECT 19 -#define FC_GLOBAL_ADVANCE_OBJECT 20 /* deprecated */ -#define FC_FILE_OBJECT 21 -#define FC_INDEX_OBJECT 22 -#define FC_RASTERIZER_OBJECT 23 -#define FC_OUTLINE_OBJECT 24 -#define FC_SCALABLE_OBJECT 25 -#define FC_DPI_OBJECT 26 -#define FC_RGBA_OBJECT 27 -#define FC_SCALE_OBJECT 28 -#define FC_MINSPACE_OBJECT 29 -#define FC_CHAR_WIDTH_OBJECT 30 -#define FC_CHAR_HEIGHT_OBJECT 31 -#define FC_MATRIX_OBJECT 32 -#define FC_CHARSET_OBJECT 33 -#define FC_LANG_OBJECT 34 -#define FC_FONTVERSION_OBJECT 35 -#define FC_CAPABILITY_OBJECT 36 -#define FC_FONTFORMAT_OBJECT 37 -#define FC_EMBOLDEN_OBJECT 38 -#define FC_EMBEDDED_BITMAP_OBJECT 39 -#define FC_DECORATIVE_OBJECT 40 -#define FC_LCD_FILTER_OBJECT 41 -#define FC_NAMELANG_OBJECT 42 -#define FC_MAX_BASE_OBJECT FC_NAMELANG_OBJECT +enum { + FC_INVALID_OBJECT = 0, +#define FC_OBJECT(NAME, Type) FC_##NAME##_OBJECT, +#include "fcobjs.h" +#undef FC_OBJECT + FC_ONE_AFTER_MAX_BASE_OBJECT +#define FC_MAX_BASE_OBJECT (FC_ONE_AFTER_MAX_BASE_OBJECT - 1) +}; FcPrivate FcBool FcNameBool (const FcChar8 *v, FcBool *result); @@ -908,12 +862,6 @@ FcObjectName (FcObject object); FcPrivate FcObjectSet * FcObjectGetSet (void); -FcPrivate FcBool -FcObjectInit (void); - -FcPrivate void -FcObjectFini (void); - #define FcObjectCompare(a, b) ((int) a - (int) b) /* fcpat.c */ @@ -1019,12 +967,6 @@ FcPatternObjectGetLangSet (const FcPattern *p, FcObject object, int n, FcLangSet FcPrivate FcBool FcPatternAppend (FcPattern *p, FcPattern *s); -FcPrivate const FcChar8 * -FcSharedStr (const FcChar8 *name); - -FcPrivate FcBool -FcSharedStrFree (const FcChar8 *name); - FcPrivate FcChar32 FcStringHash (const FcChar8 *s); @@ -1127,4 +1069,21 @@ FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str); FcPrivate FcChar8 * FcStrSerialize (FcSerialize *serialize, const FcChar8 *str); +/* fcobjs.c */ + +FcPrivate FcObject +FcObjectLookupIdByName (const char *str); + +FcPrivate FcObject +FcObjectLookupBuiltinIdByName (const char *str); + +FcPrivate const char * +FcObjectLookupOtherNameById (FcObject id); + +FcPrivate const FcObjectType * +FcObjectLookupOtherTypeById (FcObject id); + +FcPrivate const FcObjectType * +FcObjectLookupOtherTypeByName (const char *str); + #endif /* _FC_INT_H_ */ diff --git a/fontconfig/src/fclang.c b/fontconfig/src/fclang.c index 65d22a932..8e9b094b2 100644 --- a/fontconfig/src/fclang.c +++ b/fontconfig/src/fclang.c @@ -22,10 +22,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include #include "fcint.h" #include "fcftint.h" +/* Objects MT-safe for readonly access. */ + typedef struct { const FcChar8 lang[8]; const FcCharSet charset; @@ -51,7 +52,7 @@ static void FcLangSetBitSet (FcLangSet *ls, unsigned int id) { - int bucket; + unsigned int bucket; id = fcLangCharSetIndices[id]; bucket = id >> 5; @@ -65,7 +66,7 @@ static FcBool FcLangSetBitGet (const FcLangSet *ls, unsigned int id) { - int bucket; + unsigned int bucket; id = fcLangCharSetIndices[id]; bucket = id >> 5; @@ -79,7 +80,7 @@ static void FcLangSetBitReset (FcLangSet *ls, unsigned int id) { - int bucket; + unsigned int bucket; id = fcLangCharSetIndices[id]; bucket = id >> 5; @@ -182,7 +183,7 @@ FcLangNormalize (const FcChar8 *lang) { FcChar8 *result = NULL, *s, *orig; char *territory, *encoding, *modifier; - size_t llen, tlen = 0, mlen = 0, ssize; + size_t llen, tlen = 0, mlen = 0; if (!lang || !*lang) return NULL; @@ -197,10 +198,6 @@ FcLangNormalize (const FcChar8 *lang) s = FcStrCopy (lang); if (!s) goto bail; - /* store the original length of 's' here to let FcMemFree know - * the correct size since we breaks 's' from now on. - */ - ssize = strlen ((const char *)s) + 1; /* from the comments in glibc: * @@ -289,8 +286,6 @@ FcLangNormalize (const FcChar8 *lang) /* we'll miss the opportunity to reduce the correct size * of the allocated memory for the string after that. */ - FcMemFree (FC_MEM_STRING, ssize); - FcMemAlloc (FC_MEM_STRING, strlen((const char *)s) + 1); s = NULL; goto bail1; } @@ -307,8 +302,6 @@ FcLangNormalize (const FcChar8 *lang) /* we'll miss the opportunity to reduce the correct size * of the allocated memory for the string after that. */ - FcMemFree (FC_MEM_STRING, ssize); - FcMemAlloc (FC_MEM_STRING, strlen((const char *)s) + 1); s = NULL; goto bail1; } @@ -329,8 +322,6 @@ FcLangNormalize (const FcChar8 *lang) /* we'll miss the opportunity to reduce the correct size * of the allocated memory for the string after that. */ - FcMemFree (FC_MEM_STRING, ssize); - FcMemAlloc (FC_MEM_STRING, strlen((const char *)s) + 1); s = NULL; } bail1: @@ -338,10 +329,7 @@ FcLangNormalize (const FcChar8 *lang) FcStrFree (orig); bail0: if (s) - { free (s); - FcMemFree (FC_MEM_STRING, ssize); - } bail: if (FcDebug () & FC_DBG_LANGSET) { @@ -465,7 +453,6 @@ FcLangSetCreate (void) ls = malloc (sizeof (FcLangSet)); if (!ls) return 0; - FcMemAlloc (FC_MEM_LANGSET, sizeof (FcLangSet)); memset (ls->map, '\0', sizeof (ls->map)); ls->map_size = NUM_LANG_SET_MAP; ls->extra = 0; @@ -477,7 +464,6 @@ FcLangSetDestroy (FcLangSet *ls) { if (ls->extra) FcStrSetDestroy (ls->extra); - FcMemFree (FC_MEM_LANGSET, sizeof (FcLangSet)); free (ls); } @@ -717,34 +703,38 @@ FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb) /* * Used in computing values -- mustn't allocate any storage - * XXX Not thread-safe */ FcLangSet * -FcLangSetPromote (const FcChar8 *lang) +FcLangSetPromote (const FcChar8 *lang, FcValuePromotionBuffer *vbuf) { - static FcLangSet ls; - static FcStrSet strs; - static FcChar8 *str; - int id; - - memset (ls.map, '\0', sizeof (ls.map)); - ls.map_size = NUM_LANG_SET_MAP; - ls.extra = 0; + int id; + typedef struct { + FcLangSet ls; + FcStrSet strs; + FcChar8 *str; + } FcLangSetPromotionBuffer; + FcLangSetPromotionBuffer *buf = (FcLangSetPromotionBuffer *) vbuf; + + FC_ASSERT_STATIC (sizeof (FcLangSetPromotionBuffer) <= sizeof (FcValuePromotionBuffer)); + + memset (buf->ls.map, '\0', sizeof (buf->ls.map)); + buf->ls.map_size = NUM_LANG_SET_MAP; + buf->ls.extra = 0; id = FcLangSetIndex (lang); if (id > 0) { - FcLangSetBitSet (&ls, id); + FcLangSetBitSet (&buf->ls, id); } else { - ls.extra = &strs; - strs.num = 1; - strs.size = 1; - strs.strs = &str; - strs.ref = 1; - str = (FcChar8 *) lang; + buf->ls.extra = &buf->strs; + buf->strs.num = 1; + buf->strs.size = 1; + buf->strs.strs = &buf->str; + FcRefInit (&buf->strs.ref, 1); + buf->str = (FcChar8 *) lang; } - return &ls; + return &buf->ls; } FcChar32 diff --git a/fontconfig/src/fclist.c b/fontconfig/src/fclist.c index 56f04329e..b7ae899cd 100644 --- a/fontconfig/src/fclist.c +++ b/fontconfig/src/fclist.c @@ -33,7 +33,6 @@ FcObjectSetCreate (void) os = (FcObjectSet *) malloc (sizeof (FcObjectSet)); if (!os) return 0; - FcMemAlloc (FC_MEM_OBJECTSET, sizeof (FcObjectSet)); os->nobject = 0; os->sobject = 0; os->objects = 0; @@ -57,9 +56,6 @@ FcObjectSetAdd (FcObjectSet *os, const char *object) objects = (const char **) malloc (s * sizeof (const char *)); if (!objects) return FcFalse; - if (os->sobject) - FcMemFree (FC_MEM_OBJECTPTR, os->sobject * sizeof (const char *)); - FcMemAlloc (FC_MEM_OBJECTPTR, s * sizeof (const char *)); os->objects = objects; os->sobject = s; } @@ -67,14 +63,14 @@ FcObjectSetAdd (FcObjectSet *os, const char *object) low = 0; mid = 0; c = 1; - object = (char *)FcSharedStr ((FcChar8 *)object); + object = strdup (object); while (low <= high) { mid = (low + high) >> 1; c = os->objects[mid] - object; if (c == 0) { - FcSharedStrFree ((FcChar8 *)object); + FcFree (object); return FcTrue; } if (c < 0) @@ -99,12 +95,10 @@ FcObjectSetDestroy (FcObjectSet *os) if (os->objects) { for (i = 0; i < os->nobject; i++) - FcSharedStrFree ((FcChar8 *)os->objects[i]); + FcFree (os->objects[i]); - FcMemFree (FC_MEM_OBJECTPTR, os->sobject * sizeof (const char *)); free ((void *) os->objects); } - FcMemFree (FC_MEM_OBJECTSET, sizeof (FcObjectSet)); free (os); } @@ -342,7 +336,6 @@ FcListHashTableCleanup (FcListHashTable *table) { next = bucket->next; FcPatternDestroy (bucket->pattern); - FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket)); free (bucket); } table->buckets[i] = 0; @@ -418,7 +411,6 @@ FcListAppend (FcListHashTable *table, bucket = (FcListBucket *) malloc (sizeof (FcListBucket)); if (!bucket) goto bail0; - FcMemAlloc (FC_MEM_LISTBUCK, sizeof (FcListBucket)); bucket->next = 0; bucket->hash = hash; bucket->pattern = FcPatternCreate (); @@ -469,7 +461,6 @@ FcListAppend (FcListHashTable *table, bail2: FcPatternDestroy (bucket->pattern); bail1: - FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket)); free (bucket); bail0: return FcFalse; @@ -569,7 +560,6 @@ FcFontSetList (FcConfig *config, if (!FcFontSetAdd (ret, bucket->pattern)) goto bail2; table.buckets[i] = bucket->next; - FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket)); free (bucket); } diff --git a/fontconfig/src/fcmatch.c b/fontconfig/src/fcmatch.c index 970339201..6778967b9 100644 --- a/fontconfig/src/fcmatch.c +++ b/fontconfig/src/fcmatch.c @@ -23,17 +23,13 @@ */ #include "fcint.h" -#include -#include -#include -#include static double FcCompareNumber (FcValue *value1, FcValue *value2) { double v1, v2, v; - switch (value1->type) { + switch ((int) value1->type) { case FcTypeInteger: v1 = (double) value1->u.i; break; @@ -43,7 +39,7 @@ FcCompareNumber (FcValue *value1, FcValue *value2) default: return -1.0; } - switch (value2->type) { + switch ((int) value2->type) { case FcTypeInteger: v2 = (double) value2->u.i; break; @@ -86,9 +82,9 @@ FcCompareLang (FcValue *v1, FcValue *v2) FcLangResult result; FcValue value1 = FcValueCanonicalize(v1), value2 = FcValueCanonicalize(v2); - switch (value1.type) { + switch ((int) value1.type) { case FcTypeLangSet: - switch (value2.type) { + switch ((int) value2.type) { case FcTypeLangSet: result = FcLangSetCompare (value1.u.l, value2.u.l); break; @@ -101,7 +97,7 @@ FcCompareLang (FcValue *v1, FcValue *v2) } break; case FcTypeString: - switch (value2.type) { + switch ((int) value2.type) { case FcTypeLangSet: result = FcLangSetHasLang (value2.u.l, value1.u.s); break; @@ -146,7 +142,7 @@ FcCompareSize (FcValue *value1, FcValue *value2) { double v1, v2, v; - switch (value1->type) { + switch ((int) value1->type) { case FcTypeInteger: v1 = value1->u.i; break; @@ -156,7 +152,7 @@ FcCompareSize (FcValue *value1, FcValue *value2) default: return -1; } - switch (value2->type) { + switch ((int) value2->type) { case FcTypeInteger: v2 = value2->u.i; break; @@ -563,8 +559,7 @@ FcFontRenderPrepare (FcConfig *config, } static FcPattern * -FcFontSetMatchInternal (FcConfig *config, - FcFontSet **sets, +FcFontSetMatchInternal (FcFontSet **sets, int nsets, FcPattern *p, FcResult *result) @@ -658,7 +653,7 @@ FcFontSetMatch (FcConfig *config, if (!config) return 0; } - best = FcFontSetMatchInternal (config, sets, nsets, p, result); + best = FcFontSetMatchInternal (sets, nsets, p, result); if (best) return FcFontRenderPrepare (config, p, best); else @@ -691,7 +686,7 @@ FcFontMatch (FcConfig *config, if (config->fonts[FcSetApplication]) sets[nsets++] = config->fonts[FcSetApplication]; - best = FcFontSetMatchInternal (config, sets, nsets, p, result); + best = FcFontSetMatchInternal (sets, nsets, p, result); if (best) return FcFontRenderPrepare (config, p, best); else @@ -794,7 +789,7 @@ FcFontSetSortDestroy (FcFontSet *fs) } FcFontSet * -FcFontSetSort (FcConfig *config, +FcFontSetSort (FcConfig *config FC_UNUSED, FcFontSet **sets, int nsets, FcPattern *p, diff --git a/fontconfig/src/fcmatrix.c b/fontconfig/src/fcmatrix.c index f0c613918..a6fbca2a0 100644 --- a/fontconfig/src/fcmatrix.c +++ b/fontconfig/src/fcmatrix.c @@ -38,7 +38,6 @@ FcMatrixCopy (const FcMatrix *mat) r = (FcMatrix *) malloc (sizeof (*r) ); if (!r) return 0; - FcMemAlloc (FC_MEM_MATRIX, sizeof (FcMatrix)); *r = *mat; return r; } @@ -47,10 +46,7 @@ void FcMatrixFree (FcMatrix *mat) { if (mat != &FcIdentityMatrix) - { - FcMemFree (FC_MEM_MATRIX, sizeof (FcMatrix)); free (mat); - } } FcBool diff --git a/fontconfig/src/fcmutex.h b/fontconfig/src/fcmutex.h new file mode 100644 index 000000000..556a05efc --- /dev/null +++ b/fontconfig/src/fcmutex.h @@ -0,0 +1,127 @@ +/* + * Atomic int and pointer operations. Originally copied from HarfBuzz. + * + * Copyright © 2007 Chris Wilson + * Copyright © 2009,2010 Red Hat, Inc. + * Copyright © 2011,2012,2013 Google, Inc. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Contributor(s): + * Chris Wilson + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#ifndef _FCMUTEX_H_ +#define _FCMUTEX_H_ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define FC_STMT_START do +#define FC_STMT_END while (0) + +/* mutex */ + +/* We need external help for these */ + +#if 0 + + +#elif !defined(FC_NO_MT) && defined(_MSC_VER) || defined(__MINGW32__) + +#include "fcwindows.h" +typedef CRITICAL_SECTION fc_mutex_impl_t; +#define FC_MUTEX_IMPL_INIT { NULL, 0, 0, NULL, NULL, 0 } +#define fc_mutex_impl_init(M) InitializeCriticalSection (M) +#define fc_mutex_impl_lock(M) EnterCriticalSection (M) +#define fc_mutex_impl_unlock(M) LeaveCriticalSection (M) +#define fc_mutex_impl_finish(M) DeleteCriticalSection (M) + + +#elif !defined(FC_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__)) + +#include +typedef pthread_mutex_t fc_mutex_impl_t; +#define FC_MUTEX_IMPL_INIT PTHREAD_MUTEX_INITIALIZER +#define fc_mutex_impl_init(M) pthread_mutex_init (M, NULL) +#define fc_mutex_impl_lock(M) pthread_mutex_lock (M) +#define fc_mutex_impl_unlock(M) pthread_mutex_unlock (M) +#define fc_mutex_impl_finish(M) pthread_mutex_destroy (M) + + +#elif !defined(FC_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD) +# include +# define FC_SCHED_YIELD() sched_yield () +#else +# define FC_SCHED_YIELD() FC_STMT_START {} FC_STMT_END +#endif + +/* This actually is not a totally awful implementation. */ +typedef volatile int fc_mutex_impl_t; +#define FC_MUTEX_IMPL_INIT 0 +#define fc_mutex_impl_init(M) *(M) = 0 +#define fc_mutex_impl_lock(M) FC_STMT_START { while (__sync_lock_test_and_set((M), 1)) FC_SCHED_YIELD (); } FC_STMT_END +#define fc_mutex_impl_unlock(M) __sync_lock_release (M) +#define fc_mutex_impl_finish(M) FC_STMT_START {} FC_STMT_END + + +#elif !defined(FC_NO_MT) + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD) +# include +# define FC_SCHED_YIELD() sched_yield () +#else +# define FC_SCHED_YIELD() FC_STMT_START {} FC_STMT_END +#endif + +#define FC_MUTEX_INT_NIL 1 /* Warn that fallback implementation is in use. */ +typedef volatile int fc_mutex_impl_t; +#define FC_MUTEX_IMPL_INIT 0 +#define fc_mutex_impl_init(M) *(M) = 0 +#define fc_mutex_impl_lock(M) FC_STMT_START { while (*(M)) FC_SCHED_YIELD (); (*(M))++; } FC_STMT_END +#define fc_mutex_impl_unlock(M) (*(M))--; +#define fc_mutex_impl_finish(M) FC_STMT_START {} FC_STMT_END + + +#else /* FC_NO_MT */ + +typedef int fc_mutex_impl_t; +#define FC_MUTEX_IMPL_INIT 0 +#define fc_mutex_impl_init(M) FC_STMT_START {} FC_STMT_END +#define fc_mutex_impl_lock(M) FC_STMT_START {} FC_STMT_END +#define fc_mutex_impl_unlock(M) FC_STMT_START {} FC_STMT_END +#define fc_mutex_impl_finish(M) FC_STMT_START {} FC_STMT_END + +#endif + + +#define FC_MUTEX_INIT {FC_MUTEX_IMPL_INIT} +typedef fc_mutex_impl_t FcMutex; +static inline void FcMutexInit (FcMutex *m) { fc_mutex_impl_init (m); } +static inline void FcMutexLock (FcMutex *m) { fc_mutex_impl_lock (m); } +static inline void FcMutexUnlock (FcMutex *m) { fc_mutex_impl_unlock (m); } +static inline void FcMutexFinish (FcMutex *m) { fc_mutex_impl_finish (m); } + + +#endif /* _FCMUTEX_H_ */ diff --git a/fontconfig/src/fcname.c b/fontconfig/src/fcname.c index 6a1fc12e8..2418189f9 100644 --- a/fontconfig/src/fcname.c +++ b/fontconfig/src/fcname.c @@ -28,275 +28,54 @@ #include #include -/* - * Please do not change this list, it is used to initialize the object - * list in this order to match the FC_foo_OBJECT constants. Those - * constants are written into cache files. - */ - -static const FcObjectType _FcBaseObjectTypes[] = { - { FC_FAMILY, FcTypeString, }, /* 1 */ - { FC_FAMILYLANG, FcTypeString, }, - { FC_STYLE, FcTypeString, }, - { FC_STYLELANG, FcTypeString, }, - { FC_FULLNAME, FcTypeString, }, - { FC_FULLNAMELANG, FcTypeString, }, - { FC_SLANT, FcTypeInteger, }, - { FC_WEIGHT, FcTypeInteger, }, - { FC_WIDTH, FcTypeInteger, }, - { FC_SIZE, FcTypeDouble, }, - { FC_ASPECT, FcTypeDouble, }, - { FC_PIXEL_SIZE, FcTypeDouble, }, - { FC_SPACING, FcTypeInteger, }, - { FC_FOUNDRY, FcTypeString, }, - { FC_ANTIALIAS, FcTypeBool, }, - { FC_HINT_STYLE, FcTypeInteger, }, - { FC_HINTING, FcTypeBool, }, - { FC_VERTICAL_LAYOUT, FcTypeBool, }, - { FC_AUTOHINT, FcTypeBool, }, - { FC_GLOBAL_ADVANCE, FcTypeBool, }, /* deprecated */ - { FC_FILE, FcTypeString, }, - { FC_INDEX, FcTypeInteger, }, - { FC_RASTERIZER, FcTypeString, }, - { FC_OUTLINE, FcTypeBool, }, - { FC_SCALABLE, FcTypeBool, }, - { FC_DPI, FcTypeDouble }, - { FC_RGBA, FcTypeInteger, }, - { FC_SCALE, FcTypeDouble, }, - { FC_MINSPACE, FcTypeBool, }, - { FC_CHAR_WIDTH, FcTypeInteger }, - { FC_CHAR_HEIGHT, FcTypeInteger }, - { FC_MATRIX, FcTypeMatrix }, - { FC_CHARSET, FcTypeCharSet }, - { FC_LANG, FcTypeLangSet }, - { FC_FONTVERSION, FcTypeInteger }, - { FC_CAPABILITY, FcTypeString }, - { FC_FONTFORMAT, FcTypeString }, - { FC_EMBOLDEN, FcTypeBool }, - { 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]) - -typedef struct _FcObjectTypeList FcObjectTypeList; - -struct _FcObjectTypeList { - const FcObjectTypeList *next; - const FcObjectType *types; - int ntypes; +static const FcObjectType FcObjects[] = { +#define FC_OBJECT(NAME, Type) { FC_##NAME, Type }, +#include "fcobjs.h" +#undef FC_OBJECT }; -static const FcObjectTypeList _FcBaseObjectTypesList = { - 0, - _FcBaseObjectTypes, - NUM_OBJECT_TYPES, -}; - -static const FcObjectTypeList *_FcObjectTypes = &_FcBaseObjectTypesList; - -#define OBJECT_HASH_SIZE 31 - -typedef struct _FcObjectBucket { - struct _FcObjectBucket *next; - FcChar32 hash; - FcObject id; -} FcObjectBucket; - -static FcObjectBucket *FcObjectBuckets[OBJECT_HASH_SIZE]; - -static FcObjectType *FcObjects = (FcObjectType *) _FcBaseObjectTypes; -static int FcObjectsNumber = NUM_OBJECT_TYPES; -static int FcObjectsSize = 0; -static FcBool FcObjectsInited; - -static FcObjectType * -FcObjectInsert (const char *name, FcType type) -{ - FcObjectType *o; - if (FcObjectsNumber >= FcObjectsSize) - { - int newsize = FcObjectsNumber * 2; - FcObjectType *newobjects; - - if (FcObjectsSize) - newobjects = realloc (FcObjects, newsize * sizeof (FcObjectType)); - else - { - newobjects = malloc (newsize * sizeof (FcObjectType)); - if (newobjects) - memcpy (newobjects, FcObjects, - FcObjectsNumber * sizeof (FcObjectType)); - } - if (!newobjects) - return NULL; - FcObjects = newobjects; - FcObjectsSize = newsize; - } - o = &FcObjects[FcObjectsNumber]; - o->object = name; - o->type = type; - ++FcObjectsNumber; - return o; -} - -static FcObject -FcObjectId (FcObjectType *o) -{ - return o - FcObjects + 1; -} - -static FcObjectType * -FcObjectFindByName (const char *object, FcBool insert) -{ - FcChar32 hash = FcStringHash ((const FcChar8 *) object); - FcObjectBucket **p; - FcObjectBucket *b; - FcObjectType *o; - - if (!FcObjectsInited) - FcObjectInit (); - for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) - { - o = FcObjects + b->id - 1; - if (b->hash == hash && !strcmp (object, (o->object))) - return o; - } - if (!insert) - return NULL; - /* - * Hook it into the hash chain - */ - b = malloc (sizeof(FcObjectBucket)); - if (!b) - return NULL; - object = (const char *) FcStrCopy ((FcChar8 *) object); - if (!object) { - free (b); - return NULL; - } - o = FcObjectInsert (object, -1); - b->next = NULL; - b->hash = hash; - b->id = FcObjectId (o); - *p = b; - return o; -} +#define NUM_OBJECT_TYPES ((int) (sizeof FcObjects / sizeof FcObjects[0])) -static FcObjectType * +static const FcObjectType * FcObjectFindById (FcObject object) { - if (1 <= object && object <= FcObjectsNumber) - return FcObjects + object - 1; - return NULL; -} - -static FcBool -FcObjectHashInsert (const FcObjectType *object, FcBool copy) -{ - FcChar32 hash = FcStringHash ((const FcChar8 *) object->object); - FcObjectBucket **p; - FcObjectBucket *b; - FcObjectType *o; - - if (!FcObjectsInited) - FcObjectInit (); - for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) - { - o = FcObjects + b->id - 1; - if (b->hash == hash && !strcmp (object->object, o->object)) - return FcFalse; - } - /* - * Hook it into the hash chain - */ - b = malloc (sizeof(FcObjectBucket)); - if (!b) - return FcFalse; - if (copy) - { - o = FcObjectInsert (object->object, object->type); - if (!o) - { - free (b); - return FcFalse; - } - } - else - o = (FcObjectType *) object; - b->next = NULL; - b->hash = hash; - b->id = FcObjectId (o); - *p = b; - return FcTrue; -} - -static void -FcObjectHashRemove (const FcObjectType *object, FcBool cleanobj) -{ - FcChar32 hash = FcStringHash ((const FcChar8 *) object->object); - FcObjectBucket **p; - FcObjectBucket *b; - FcObjectType *o; - - if (!FcObjectsInited) - FcObjectInit (); - for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) - { - o = FcObjects + b->id - 1; - if (b->hash == hash && !strcmp (object->object, o->object)) - { - *p = b->next; - free (b); - if (cleanobj) - { - /* Clean up object array */ - o->object = NULL; - o->type = -1; - while (FcObjects[FcObjectsNumber-1].object == NULL) - --FcObjectsNumber; - } - break; - } - } + if (1 <= object && object <= NUM_OBJECT_TYPES) + return &FcObjects[object - 1]; + return FcObjectLookupOtherTypeById (object); } FcBool FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes) { - int i; - - for (i = 0; i < ntypes; i++) - if (!FcObjectHashInsert (&types[i], FcTrue)) - return FcFalse; - return FcTrue; + /* Deprecated. */ + return FcFalse; } FcBool FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes) { - int i; - - for (i = 0; i < ntypes; i++) - FcObjectHashRemove (&types[i], FcTrue); - return FcTrue; + /* Deprecated. */ + return FcFalse; } const FcObjectType * FcNameGetObjectType (const char *object) { - return FcObjectFindByName (object, FcFalse); + int id = FcObjectLookupBuiltinIdByName (object); + + if (!id) + return FcObjectLookupOtherTypeByName (object); + + return &FcObjects[id - 1]; } FcBool FcObjectValidType (FcObject object, FcType type) { - FcObjectType *t = FcObjectFindById (object); + const FcObjectType *t = FcObjectFindById (object); if (t) { - switch (t->type) { + switch ((int) t->type) { case FcTypeDouble: case FcTypeInteger: if (type == FcTypeDouble || type == FcTypeInteger) @@ -307,7 +86,7 @@ FcObjectValidType (FcObject object, FcType type) return FcTrue; break; default: - if (t->type == -1 || type == t->type) + if (t->type == (unsigned int) -1 || type == t->type) return FcTrue; break; } @@ -319,11 +98,7 @@ FcObjectValidType (FcObject object, FcType type) FcObject FcObjectFromName (const char * name) { - FcObjectType *o = FcObjectFindByName (name, FcTrue); - - if (o) - return FcObjectId (o); - return 0; + return FcObjectLookupIdByName (name); } FcObjectSet * @@ -334,61 +109,21 @@ FcObjectGetSet (void) os = FcObjectSetCreate (); - for (i = 0; i < FcObjectsNumber; i++) + for (i = 0; i < NUM_OBJECT_TYPES; i++) FcObjectSetAdd (os, FcObjects[i].object); return os; } -FcBool -FcObjectInit (void) -{ - int i; - - if (FcObjectsInited) - return FcTrue; - - FcObjectsInited = FcTrue; - for (i = 0; i < NUM_OBJECT_TYPES; i++) - if (!FcObjectHashInsert (&_FcBaseObjectTypes[i], FcFalse)) - return FcFalse; - return FcTrue; -} - -void -FcObjectFini (void) -{ - int i; - FcObjectBucket *b, *next; - - for (i = 0; i < OBJECT_HASH_SIZE; i++) - { - for (b = FcObjectBuckets[i]; b; b = next) - { - next = b->next; - free (b); - } - FcObjectBuckets[i] = 0; - } - for (i = 0; i < FcObjectsNumber; i++) - if (FcObjects[i].type == -1) - free ((void*) FcObjects[i].object); - if (FcObjects != _FcBaseObjectTypes) - free (FcObjects); - FcObjects = (FcObjectType *) _FcBaseObjectTypes; - FcObjectsNumber = NUM_OBJECT_TYPES; - FcObjectsSize = 0; - FcObjectsInited = FcFalse; -} - const char * FcObjectName (FcObject object) { - FcObjectType *o = FcObjectFindById (object); + const FcObjectType *o = FcObjectFindById (object); if (o) return o->object; - return NULL; + + return FcObjectLookupOtherNameById (object); } static const FcConstant _FcBaseConstants[] = { @@ -414,7 +149,7 @@ static const FcConstant _FcBaseConstants[] = { { (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED }, { (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED }, { (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED }, - { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED }, + { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED }, { (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL }, { (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED }, { (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED }, @@ -457,70 +192,29 @@ static const FcConstant _FcBaseConstants[] = { #define NUM_FC_CONSTANTS (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0]) -typedef struct _FcConstantList FcConstantList; - -struct _FcConstantList { - const FcConstantList *next; - const FcConstant *consts; - int nconsts; -}; - -static const FcConstantList _FcBaseConstantList = { - 0, - _FcBaseConstants, - NUM_FC_CONSTANTS -}; - -static const FcConstantList *_FcConstants = &_FcBaseConstantList; - FcBool FcNameRegisterConstants (const FcConstant *consts, int nconsts) { - FcConstantList *l; - - l = (FcConstantList *) malloc (sizeof (FcConstantList)); - if (!l) - return FcFalse; - FcMemAlloc (FC_MEM_CONSTANT, sizeof (FcConstantList)); - l->consts = consts; - l->nconsts = nconsts; - l->next = _FcConstants; - _FcConstants = l; - return FcTrue; + /* Deprecated. */ + return FcFalse; } FcBool FcNameUnregisterConstants (const FcConstant *consts, int nconsts) { - const FcConstantList *l, **prev; - - for (prev = &_FcConstants; - (l = *prev); - prev = (const FcConstantList **) &(l->next)) - { - if (l->consts == consts && l->nconsts == nconsts) - { - *prev = l->next; - FcMemFree (FC_MEM_CONSTANT, sizeof (FcConstantList)); - free ((void *) l); - return FcTrue; - } - } + /* Deprecated. */ return FcFalse; } const FcConstant * FcNameGetConstant (const FcChar8 *string) { - const FcConstantList *l; - int i; + unsigned int i; + + for (i = 0; i < NUM_FC_CONSTANTS; i++) + if (!FcStrCmpIgnoreCase (string, _FcBaseConstants[i].name)) + return &_FcBaseConstants[i]; - for (l = _FcConstants; l; l = l->next) - { - for (i = 0; i < l->nconsts; i++) - if (!FcStrCmpIgnoreCase (string, l->consts[i].name)) - return &l->consts[i]; - } return 0; } @@ -579,13 +273,13 @@ FcNameConvert (FcType type, FcChar8 *string) FcMatrix m; v.type = type; - switch (v.type) { + switch ((int) v.type) { case FcTypeInteger: if (!FcNameConstant (string, &v.u.i)) v.u.i = atoi ((char *) string); break; case FcTypeString: - v.u.s = FcSharedStr (string); + v.u.s = FcStrdup (string); if (!v.u.s) v.type = FcTypeVoid; break; @@ -597,6 +291,7 @@ FcNameConvert (FcType type, FcChar8 *string) v.u.d = strtod ((char *) string, 0); break; case FcTypeMatrix: + FcMatrixInit (&m); sscanf ((char *) string, "%lg %lg %lg %lg", &m.xx, &m.xy, &m.yx, &m.yy); v.u.m = FcMatrixCopy (&m); break; @@ -717,7 +412,7 @@ FcNameParse (const FcChar8 *name) if ((c = FcNameGetConstant (save))) { t = FcNameGetObjectType ((char *) c->object); - switch (t->type) { + switch ((int) t->type) { case FcTypeInteger: case FcTypeDouble: if (!FcPatternAddInteger (pat, c->object, c->value)) @@ -831,8 +526,6 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape) FcChar8 buf_static[8192]; int i; FcPatternElt *e; - const FcObjectTypeList *l; - const FcObjectType *o; FcStrBufInit (&buf, buf_static, sizeof (buf_static)); e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT); @@ -849,28 +542,27 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape) if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) goto bail0; } - for (l = _FcObjectTypes; l; l = l->next) + for (i = 0; i < NUM_OBJECT_TYPES; i++) { - for (i = 0; i < l->ntypes; i++) + FcObject id = i + 1; + const FcObjectType *o; + o = &FcObjects[i]; + if (!strcmp (o->object, FC_FAMILY) || + !strcmp (o->object, FC_SIZE)) + continue; + + e = FcPatternObjectFindElt (pat, id); + if (e) { - o = &l->types[i]; - if (!strcmp (o->object, FC_FAMILY) || - !strcmp (o->object, FC_SIZE)) - continue; - - e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object)); - if (e) - { - if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0)) - goto bail0; - if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) - goto bail0; - if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0)) - goto bail0; - if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? - (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) - goto bail0; - } + if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0)) + goto bail0; + if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) + goto bail0; + if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0)) + goto bail0; + if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? + (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) + goto bail0; } } return FcStrBufDone (&buf); diff --git a/fontconfig/src/fcobjs.c b/fontconfig/src/fcobjs.c new file mode 100644 index 000000000..146ca70d0 --- /dev/null +++ b/fontconfig/src/fcobjs.c @@ -0,0 +1,139 @@ +/* + * fontconfig/src/fclist.c + * + * Copyright © 2000 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "fcint.h" + +static unsigned int +FcObjectTypeHash (register const char *str, register unsigned int len); + +static const struct FcObjectTypeInfo * +FcObjectTypeLookup (register const char *str, register unsigned int len); + +#include "fcobjshash.h" + +#include + +/* The 1000 is to leave some room for future added internal objects, such + * that caches from newer fontconfig can still be used with older fontconfig + * without getting confused. */ +static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + 1000; +struct FcObjectOtherTypeInfo { + struct FcObjectOtherTypeInfo *next; + FcObjectType object; + FcObject id; +} *other_types; + +static FcObjectType * +_FcObjectLookupOtherTypeByName (const char *str, FcObject *id) +{ + struct FcObjectOtherTypeInfo *ots, *ot; + +retry: + ots = fc_atomic_ptr_get (&other_types); + + for (ot = ots; ot; ot = ot->next) + if (0 == strcmp (ot->object.object, str)) + break; + + if (!ot) + { + ot = malloc (sizeof (*ot)); + if (!ot) + return NULL; + + ot->object.object = (const char *) FcStrdup (str); + ot->object.type = -1; + ot->id = fc_atomic_int_add (next_id, +1); + ot->next = ots; + + if (!fc_atomic_ptr_cmpexch (&other_types, ots, ot)) { + free (ot); + goto retry; + } + } + + if (id) + *id = ot->id; + + return &ot->object; +} + +FcObject +FcObjectLookupBuiltinIdByName (const char *str) +{ + const struct FcObjectTypeInfo *o = FcObjectTypeLookup (str, strlen (str)); + + if (o) + return o->id; + + return 0; +} + +FcObject +FcObjectLookupIdByName (const char *str) +{ + const struct FcObjectTypeInfo *o = FcObjectTypeLookup (str, strlen (str)); + FcObject id; + if (o) + return o->id; + + if (_FcObjectLookupOtherTypeByName (str, &id)) + return id; + + return 0; +} + +const char * +FcObjectLookupOtherNameById (FcObject id) +{ + struct FcObjectOtherTypeInfo *ot; + + for (ot = fc_atomic_ptr_get (&other_types); ot; ot = ot->next) + if (ot->id == id) + return ot->object.object; + + return NULL; +} + +const FcObjectType * +FcObjectLookupOtherTypeByName (const char *str) +{ + return _FcObjectLookupOtherTypeByName (str, NULL); +} + +FcPrivate const FcObjectType * +FcObjectLookupOtherTypeById (FcObject id) +{ + struct FcObjectOtherTypeInfo *ot; + + for (ot = fc_atomic_ptr_get (&other_types); ot; ot = ot->next) + if (ot->id == id) + return &ot->object; + + return NULL; +} + + +#include "fcaliastail.h" +#undef __fcobjs__ diff --git a/fontconfig/src/fcobjs.h b/fontconfig/src/fcobjs.h new file mode 100644 index 000000000..1e9067e21 --- /dev/null +++ b/fontconfig/src/fcobjs.h @@ -0,0 +1,44 @@ +/* DON'T REORDER! The order is part of the cache signature. */ +FC_OBJECT (FAMILY, FcTypeString) +FC_OBJECT (FAMILYLANG, FcTypeString) +FC_OBJECT (STYLE, FcTypeString) +FC_OBJECT (STYLELANG, FcTypeString) +FC_OBJECT (FULLNAME, FcTypeString) +FC_OBJECT (FULLNAMELANG, FcTypeString) +FC_OBJECT (SLANT, FcTypeInteger) +FC_OBJECT (WEIGHT, FcTypeInteger) +FC_OBJECT (WIDTH, FcTypeInteger) +FC_OBJECT (SIZE, FcTypeDouble) +FC_OBJECT (ASPECT, FcTypeDouble) +FC_OBJECT (PIXEL_SIZE, FcTypeDouble) +FC_OBJECT (SPACING, FcTypeInteger) +FC_OBJECT (FOUNDRY, FcTypeString) +FC_OBJECT (ANTIALIAS, FcTypeBool) +FC_OBJECT (HINT_STYLE, FcTypeInteger) +FC_OBJECT (HINTING, FcTypeBool) +FC_OBJECT (VERTICAL_LAYOUT, FcTypeBool) +FC_OBJECT (AUTOHINT, FcTypeBool) +FC_OBJECT (GLOBAL_ADVANCE, FcTypeBool) /* deprecated */ +FC_OBJECT (FILE, FcTypeString) +FC_OBJECT (INDEX, FcTypeInteger) +FC_OBJECT (RASTERIZER, FcTypeString) +FC_OBJECT (OUTLINE, FcTypeBool) +FC_OBJECT (SCALABLE, FcTypeBool) +FC_OBJECT (DPI, FcTypeDouble) +FC_OBJECT (RGBA, FcTypeInteger) +FC_OBJECT (SCALE, FcTypeDouble) +FC_OBJECT (MINSPACE, FcTypeBool) +FC_OBJECT (CHAR_WIDTH, FcTypeInteger) +FC_OBJECT (CHAR_HEIGHT, FcTypeInteger) +FC_OBJECT (MATRIX, FcTypeMatrix) +FC_OBJECT (CHARSET, FcTypeCharSet) +FC_OBJECT (LANG, FcTypeLangSet) +FC_OBJECT (FONTVERSION, FcTypeInteger) +FC_OBJECT (CAPABILITY, FcTypeString) +FC_OBJECT (FONTFORMAT, FcTypeString) +FC_OBJECT (EMBOLDEN, FcTypeBool) +FC_OBJECT (EMBEDDED_BITMAP, FcTypeBool) +FC_OBJECT (DECORATIVE, FcTypeBool) +FC_OBJECT (LCD_FILTER, FcTypeInteger) +FC_OBJECT (NAMELANG, FcTypeString) +/* ^-------------- Add new objects here. */ diff --git a/fontconfig/src/fcobjshash.gperf.h b/fontconfig/src/fcobjshash.gperf.h new file mode 100644 index 000000000..dafac1bc2 --- /dev/null +++ b/fontconfig/src/fcobjshash.gperf.h @@ -0,0 +1,26 @@ +%{ +CUT_OUT_BEGIN +#include +CUT_OUT_END +%} +%struct-type +%language=ANSI-C +%includes +%enum +%readonly-tables +%define slot-name name +%define hash-function-name FcObjectTypeHash +%define lookup-function-name FcObjectTypeLookup + +%pic +%define string-pool-name FcObjectTypeNamePool + +struct FcObjectTypeInfo { + int name; + int id; +}; + +%% +#define FC_OBJECT(NAME, Type) FC_##NAME, FC_##NAME##_OBJECT +#include "fcobjs.h" +#undef FC_OBJECT diff --git a/fontconfig/src/fcpat.c b/fontconfig/src/fcpat.c index 62e47ca7e..b3b155d4d 100644 --- a/fontconfig/src/fcpat.c +++ b/fontconfig/src/fcpat.c @@ -22,9 +22,8 @@ #include "fcint.h" #include "fcftint.h" -#include -#include -#include + +/* Objects MT-safe for readonly access. */ FcPattern * FcPatternCreate (void) @@ -34,21 +33,19 @@ FcPatternCreate (void) p = (FcPattern *) malloc (sizeof (FcPattern)); if (!p) return 0; - FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern)); p->num = 0; p->size = 0; p->elts_offset = FcPtrToOffset (p, NULL); - p->ref = 1; + FcRefInit (&p->ref, 1); return p; } void FcValueDestroy (FcValue v) { - switch (v.type) { + switch ((int) v.type) { case FcTypeString: - if (!FcSharedStrFree (v.u.s)) - FcStrFree ((FcChar8 *) v.u.s); + FcFree (v.u.s); break; case FcTypeMatrix: FcMatrixFree ((FcMatrix *) v.u.m); @@ -69,7 +66,7 @@ FcValueCanonicalize (const FcValue *v) { FcValue new; - switch (v->type) + switch ((int) v->type) { case FcTypeString: new.u.s = FcValueString(v); @@ -93,9 +90,9 @@ FcValueCanonicalize (const FcValue *v) FcValue FcValueSave (FcValue v) { - switch (v.type) { + switch ((int) v.type) { case FcTypeString: - v.u.s = FcSharedStr (v.u.s); + v.u.s = FcStrdup (v.u.s); if (!v.u.s) v.type = FcTypeVoid; break; @@ -123,15 +120,7 @@ FcValueSave (FcValue v) FcValueListPtr FcValueListCreate (void) { - FcValueListPtr ret; - - ret = calloc (1, sizeof (FcValueList)); - if (ret) - { - FcMemAlloc(FC_MEM_VALLIST, sizeof (FcValueList)); - } - - return ret; + return calloc (1, sizeof (FcValueList)); } void @@ -140,10 +129,9 @@ FcValueListDestroy (FcValueListPtr l) FcValueListPtr next; for (; l; l = next) { - switch (l->value.type) { + switch ((int) l->value.type) { case FcTypeString: - if (!FcSharedStrFree ((FcChar8 *)l->value.u.s)) - FcStrFree ((FcChar8 *)l->value.u.s); + FcFree (l->value.u.s); break; case FcTypeMatrix: FcMatrixFree ((FcMatrix *)l->value.u.m); @@ -160,7 +148,6 @@ FcValueListDestroy (FcValueListPtr l) break; } next = FcValueListNext(l); - FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList)); free(l); } } @@ -369,22 +356,23 @@ FcPatternDestroy (FcPattern *p) int i; FcPatternElt *elts; - if (p->ref == FC_REF_CONSTANT) + if (!p) + return; + + if (FcRefIsConst (&p->ref)) { FcCacheObjectDereference (p); return; } - if (--p->ref > 0) + if (FcRefDec (&p->ref) != 1) return; elts = FcPatternElts (p); for (i = 0; i < p->num; i++) FcValueListDestroy (FcPatternEltValues(&elts[i])); - FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt)); free (elts); - FcMemFree (FC_MEM_PATTERN, sizeof (FcPattern)); free (p); } @@ -454,9 +442,6 @@ FcPatternObjectInsertElt (FcPattern *p, FcObject object) if (!e) return FcFalse; p->elts_offset = FcPtrToOffset (p, e); - if (p->size) - FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt)); - FcMemAlloc (FC_MEM_PATELT, s * sizeof (FcPatternElt)); while (p->size < s) { e[p->size].object = 0; @@ -558,7 +543,7 @@ FcPatternObjectListAdd (FcPattern *p, FcPatternElt *e; FcValueListPtr l, *prev; - if (p->ref == FC_REF_CONSTANT) + if (FcRefIsConst (&p->ref)) goto bail0; /* @@ -568,12 +553,10 @@ FcPatternObjectListAdd (FcPattern *p, { if (!FcObjectValidType (object, l->value.type)) { - if (FcDebug() & FC_DBG_OBJTYPES) - { - printf ("FcPattern object %s does not accept value ", - FcObjectName (object)); - FcValuePrint (l->value); - } + fprintf (stderr, + "Fontconfig warning: FcPattern object %s does not accept value", FcObjectName (object)); + FcValuePrintFile (stderr, l->value); + fprintf (stderr, "\n"); goto bail0; } } @@ -612,7 +595,7 @@ FcPatternObjectAddWithBinding (FcPattern *p, FcPatternElt *e; FcValueListPtr new, *prev; - if (p->ref == FC_REF_CONSTANT) + if (FcRefIsConst (&p->ref)) goto bail0; new = FcValueListCreate (); @@ -628,12 +611,11 @@ FcPatternObjectAddWithBinding (FcPattern *p, */ if (!FcObjectValidType (object, value.type)) { - if (FcDebug() & FC_DBG_OBJTYPES) - { - printf ("FcPattern object %s does not accept value ", - FcObjectName (object)); - FcValuePrint (value); - } + fprintf (stderr, + "Fontconfig warning: FcPattern object %s does not accept value", + FcObjectName (object)); + FcValuePrintFile (stderr, value); + fprintf (stderr, "\n"); goto bail1; } @@ -662,7 +644,6 @@ FcPatternObjectAddWithBinding (FcPattern *p, bail2: FcValueDestroy (value); bail1: - FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList)); free (new); bail0: return FcFalse; @@ -892,7 +873,7 @@ FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int id, int *i) r = FcPatternObjectGet (p, object, id, &v); if (r != FcResultMatch) return r; - switch (v.type) { + switch ((int) v.type) { case FcTypeDouble: *i = (int) v.u.d; break; @@ -921,7 +902,7 @@ FcPatternObjectGetDouble (const FcPattern *p, FcObject object, int id, double *d r = FcPatternObjectGet (p, object, id, &v); if (r != FcResultMatch) return r; - switch (v.type) { + switch ((int) v.type) { case FcTypeDouble: *d = v.u.d; break; @@ -1076,8 +1057,8 @@ bail0: void FcPatternReference (FcPattern *p) { - if (p->ref != FC_REF_CONSTANT) - p->ref++; + if (!FcRefIsConst (&p->ref)) + FcRefInc (&p->ref); else FcCacheObjectReference (p); } @@ -1163,69 +1144,6 @@ bail0: return NULL; } -#define OBJECT_HASH_SIZE 251 -static struct objectBucket { - struct objectBucket *next; - FcChar32 hash; - int ref_count; -} *FcObjectBuckets[OBJECT_HASH_SIZE]; - -FcBool -FcSharedStrFree (const FcChar8 *name) -{ - FcChar32 hash = FcStringHash (name); - struct objectBucket **p; - struct objectBucket *b; - int size; - - for (p = &FcObjectBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) - if (b->hash == hash && ((char *)name == (char *) (b + 1))) - { - b->ref_count--; - if (!b->ref_count) - { - *p = b->next; - size = sizeof (struct objectBucket) + strlen ((char *)name) + 1; - size = (size + 3) & ~3; - FcMemFree (FC_MEM_SHAREDSTR, size); - free (b); - } - return FcTrue; - } - return FcFalse; -} - -const FcChar8 * -FcSharedStr (const FcChar8 *name) -{ - FcChar32 hash = FcStringHash (name); - struct objectBucket **p; - struct objectBucket *b; - int size; - - for (p = &FcObjectBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) - if (b->hash == hash && !strcmp ((char *)name, (char *) (b + 1))) - { - b->ref_count++; - return (FcChar8 *) (b + 1); - } - size = sizeof (struct objectBucket) + strlen ((char *)name) + 1; - /* - * workaround valgrind warning because glibc takes advantage of how it knows memory is - * allocated to implement strlen by reading in groups of 4 - */ - size = (size + 3) & ~3; - b = malloc (size); - FcMemAlloc (FC_MEM_SHAREDSTR, size); - if (!b) - return NULL; - b->next = 0; - b->hash = hash; - b->ref_count = 1; - strcpy ((char *) (b + 1), (char *)name); - *p = b; - return (FcChar8 *) (b + 1); -} FcBool FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat) @@ -1257,7 +1175,7 @@ FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat) return NULL; *pat_serialized = *pat; pat_serialized->size = pat->num; - pat_serialized->ref = FC_REF_CONSTANT; + FcRefSetConst (&pat_serialized->ref); elts_serialized = FcSerializePtr (serialize, elts); if (!elts_serialized) @@ -1293,7 +1211,7 @@ FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *vl) { if (!FcSerializeAlloc (serialize, vl, sizeof (FcValueList))) return FcFalse; - switch (vl->value.type) { + switch ((int) vl->value.type) { case FcTypeString: if (!FcStrSerializeAlloc (serialize, vl->value.u.s)) return FcFalse; @@ -1339,7 +1257,7 @@ FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl) vl_serialized->next = NULL; vl_serialized->value.type = vl->value.type; - switch (vl->value.type) { + switch ((int) vl->value.type) { case FcTypeInteger: vl_serialized->value.u.i = vl->value.u.i; break; diff --git a/fontconfig/src/fcserialize.c b/fontconfig/src/fcserialize.c index e5ec90bde..d2f221df8 100644 --- a/fontconfig/src/fcserialize.c +++ b/fontconfig/src/fcserialize.c @@ -151,6 +151,5 @@ FcStrSerialize (FcSerialize *serialize, const FcChar8 *str) strcpy ((char *) str_serialize, (const char *) str); return str_serialize; } -#define __fcserialize__ #include "fcaliastail.h" #undef __fcserialize__ diff --git a/fontconfig/src/fcstat.c b/fontconfig/src/fcstat.c index d4431e00e..9763c21a4 100644 --- a/fontconfig/src/fcstat.c +++ b/fontconfig/src/fcstat.c @@ -44,9 +44,6 @@ #endif #ifdef _WIN32 - -#include - #ifdef __GNUC__ typedef long long INT64; #define EPOCH_OFFSET 11644473600ll @@ -268,11 +265,11 @@ FcFStatFs (int fd, FcStatFS *statb) int ret = -1; FcBool flag = FcFalse; - memset (statb, 0, sizeof (FcStatFS)); - #if defined(HAVE_FSTATVFS) && (defined(HAVE_STRUCT_STATVFS_F_BASETYPE) || defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME)) struct statvfs buf; + memset (statb, 0, sizeof (FcStatFS)); + if ((ret = fstatvfs (fd, &buf)) == 0) { # if defined(HAVE_STRUCT_STATVFS_F_BASETYPE) @@ -284,6 +281,8 @@ FcFStatFs (int fd, FcStatFS *statb) #elif defined(HAVE_FSTATFS) && (defined(HAVE_STRUCT_STATFS_F_FLAGS) || defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) || defined(__linux__)) struct statfs buf; + memset (statb, 0, sizeof (FcStatFS)); + if ((ret = fstatfs (fd, &buf)) == 0) { # if defined(HAVE_STRUCT_STATFS_F_FLAGS) && defined(MNT_LOCAL) diff --git a/fontconfig/src/fcstr.c b/fontconfig/src/fcstr.c index cc1465cc9..cdab38397 100644 --- a/fontconfig/src/fcstr.c +++ b/fontconfig/src/fcstr.c @@ -29,24 +29,13 @@ #ifdef HAVE_REGEX_H #include #endif -#ifdef _WIN32 -#include -#endif + +/* Objects MT-safe for readonly access. */ FcChar8 * FcStrCopy (const FcChar8 *s) { - int len; - FcChar8 *r; - if (!s) - return 0; - len = strlen ((char *) s) + 1; - r = (FcChar8 *) malloc (len); - if (!r) - return 0; - FcMemAlloc (FC_MEM_STRING, len); - memcpy (r, s, len); - return r; + return FcStrdup (s); } FcChar8 * @@ -59,7 +48,6 @@ FcStrPlus (const FcChar8 *s1, const FcChar8 *s2) if (!s) return 0; - FcMemAlloc (FC_MEM_STRING, l); memcpy (s, s1, s1l); memcpy (s + s1l, s2, s2l + 1); return s; @@ -68,7 +56,6 @@ FcStrPlus (const FcChar8 *s1, const FcChar8 *s2) void FcStrFree (FcChar8 *s) { - FcMemFree (FC_MEM_STRING, strlen ((char *) s) + 1); free (s); } @@ -78,8 +65,6 @@ FcStrFree (FcChar8 *s) #define FcCaseFoldUpperCount(cf) \ ((cf)->method == FC_CASE_FOLD_FULL ? 1 : (cf)->count) -#define FC_STR_CANON_BUF_LEN 1024 - typedef struct _FcCaseWalker { const FcChar8 *read; const FcChar8 *src; @@ -206,7 +191,6 @@ FcStrDowncase (const FcChar8 *s) d = dst = malloc (len + 1); if (!d) return 0; - FcMemAlloc (FC_MEM_STRING, len + 1); FcStrCaseWalkerInit (s, &w); while ((*d++ = FcStrCaseWalkerNext (&w))); return dst; @@ -782,7 +766,6 @@ FcStrBufDestroy (FcStrBuf *buf) { if (buf->allocated) { - FcMemFree (FC_MEM_STRBUF, buf->size); free (buf->buf); FcStrBufInit (buf, 0, 0); } @@ -799,7 +782,6 @@ FcStrBufDone (FcStrBuf *buf) ret = malloc (buf->len + 1); if (ret) { - FcMemAlloc (FC_MEM_STRING, buf->len + 1); memcpy (ret, buf->buf, buf->len); ret[buf->len] = '\0'; } @@ -832,7 +814,6 @@ FcStrBufChar (FcStrBuf *buf, FcChar8 c) if (buf->allocated) { size = buf->size * 2; - FcMemFree (FC_MEM_STRBUF, buf->size); new = realloc (buf->buf, size); } else @@ -850,7 +831,6 @@ FcStrBufChar (FcStrBuf *buf, FcChar8 c) buf->failed = FcTrue; return FcFalse; } - FcMemAlloc (FC_MEM_STRBUF, size); buf->size = size; buf->buf = new; } @@ -941,7 +921,6 @@ FcStrDirname (const FcChar8 *file) dir = malloc ((slash - file) + 1); if (!dir) return 0; - FcMemAlloc (FC_MEM_STRING, (slash - file) + 1); strncpy ((char *) dir, (const char *) file, slash - file); dir[slash - file] = '\0'; return dir; @@ -970,7 +949,6 @@ FcStrCanonAbsoluteFilename (const FcChar8 *s) file = malloc (size); if (!file) return NULL; - FcMemAlloc (FC_MEM_STRING, size); slash = NULL; f = file; #ifdef _WIN32 @@ -1090,8 +1068,7 @@ FcStrSetCreate (void) FcStrSet *set = malloc (sizeof (FcStrSet)); if (!set) return 0; - FcMemAlloc (FC_MEM_STRSET, sizeof (FcStrSet)); - set->ref = 1; + FcRefInit (&set->ref, 1); set->num = 0; set->size = 0; set->strs = 0; @@ -1112,14 +1089,10 @@ _FcStrSetAppend (FcStrSet *set, FcChar8 *s) if (!strs) return FcFalse; - FcMemAlloc (FC_MEM_STRSET, (set->size + 2) * sizeof (FcChar8 *)); if (set->num) memcpy (strs, set->strs, set->num * sizeof (FcChar8 *)); if (set->strs) - { - FcMemFree (FC_MEM_STRSET, (set->size + 1) * sizeof (FcChar8 *)); free (set->strs); - } set->size = set->size + 1; set->strs = strs; } @@ -1247,20 +1220,20 @@ FcStrSetDel (FcStrSet *set, const FcChar8 *s) void FcStrSetDestroy (FcStrSet *set) { - if (--set->ref == 0) - { - int i; + int i; - for (i = 0; i < set->num; i++) - FcStrFree (set->strs[i]); - if (set->strs) - { - FcMemFree (FC_MEM_STRSET, (set->size + 1) * sizeof (FcChar8 *)); - free (set->strs); - } - FcMemFree (FC_MEM_STRSET, sizeof (FcStrSet)); - free (set); - } + /* We rely on this in FcGetDefaultLangs for caching. */ + if (FcRefIsConst (&set->ref)) + return; + + if (FcRefDec (&set->ref) != 1) + return; + + for (i = 0; i < set->num; i++) + FcStrFree (set->strs[i]); + if (set->strs) + free (set->strs); + free (set); } FcStrList * @@ -1271,9 +1244,8 @@ FcStrListCreate (FcStrSet *set) list = malloc (sizeof (FcStrList)); if (!list) return 0; - FcMemAlloc (FC_MEM_STRLIST, sizeof (FcStrList)); list->set = set; - set->ref++; + FcRefInc (&set->ref); list->n = 0; return list; } @@ -1290,7 +1262,6 @@ void FcStrListDone (FcStrList *list) { FcStrSetDestroy (list->set); - FcMemFree (FC_MEM_STRLIST, sizeof (FcStrList)); free (list); } diff --git a/fontconfig/src/fcwindows.h b/fontconfig/src/fcwindows.h new file mode 100644 index 000000000..02489d9dc --- /dev/null +++ b/fontconfig/src/fcwindows.h @@ -0,0 +1,44 @@ +/* + * fontconfig/src/fcwindows.h + * + * Copyright © 2013 Google, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef _FCWINDOWS_H_ +#define _FCWINDOWS_H_ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef _WIN32 +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0500 +# endif +# define WIN32_LEAN_AND_MEAN +# define WIN32_EXTRA_LEAN +# define STRICT +# include +#endif + +#endif /* _FCWINDOWS_H_ */ diff --git a/fontconfig/src/fcxml.c b/fontconfig/src/fcxml.c index c9d41df8e..b234e4301 100644 --- a/fontconfig/src/fcxml.c +++ b/fontconfig/src/fcxml.c @@ -65,7 +65,6 @@ FcTestDestroy (FcTest *test) if (test->next) FcTestDestroy (test->next); FcExprDestroy (test->expr); - FcMemFree (FC_MEM_TEST, sizeof (FcTest)); free (test); } @@ -100,19 +99,53 @@ FcExprCreateString (FcConfig *config, const FcChar8 *s) if (e) { e->op = FcOpString; - e->u.sval = FcSharedStr (s); + e->u.sval = FcStrdup (s); } return e; } +static FcExprMatrix * +FcExprMatrixCopyShallow (const FcExprMatrix *matrix) +{ + FcExprMatrix *m = malloc (sizeof (FcExprMatrix)); + if (m) + { + *m = *matrix; + } + return m; +} + +static void +FcExprMatrixFreeShallow (FcExprMatrix *m) +{ + if (!m) + return; + + free (m); +} + +static void +FcExprMatrixFree (FcExprMatrix *m) +{ + if (!m) + return; + + FcExprDestroy (m->xx); + FcExprDestroy (m->xy); + FcExprDestroy (m->yx); + FcExprDestroy (m->yy); + + free (m); +} + static FcExpr * -FcExprCreateMatrix (FcConfig *config, const FcMatrix *m) +FcExprCreateMatrix (FcConfig *config, const FcExprMatrix *matrix) { FcExpr *e = FcConfigAllocExpr (config); if (e) { e->op = FcOpMatrix; - e->u.mval = FcMatrixCopy (m); + e->u.mexpr = FcExprMatrixCopyShallow (matrix); } return e; } @@ -154,13 +187,13 @@ FcExprCreateLangSet (FcConfig *config, FcLangSet *langset) } static FcExpr * -FcExprCreateField (FcConfig *config, const char *field) +FcExprCreateName (FcConfig *config, FcExprName name) { FcExpr *e = FcConfigAllocExpr (config); if (e) { e->op = FcOpField; - e->u.object = FcObjectFromName (field); + e->u.name = name; } return e; } @@ -172,7 +205,7 @@ FcExprCreateConst (FcConfig *config, const FcChar8 *constant) if (e) { e->op = FcOpConst; - e->u.constant = FcSharedStr (constant); + e->u.constant = FcStrdup (constant); } return e; } @@ -201,10 +234,10 @@ FcExprDestroy (FcExpr *e) case FcOpDouble: break; case FcOpString: - FcSharedStrFree (e->u.sval); + FcFree (e->u.sval); break; case FcOpMatrix: - FcMatrixFree (e->u.mval); + FcExprMatrixFree (e->u.mexpr); break; case FcOpRange: break; @@ -219,7 +252,7 @@ FcExprDestroy (FcExpr *e) case FcOpField: break; case FcOpConst: - FcSharedStrFree (e->u.constant); + FcFree (e->u.constant); break; case FcOpAssign: case FcOpAssignReplace: @@ -420,9 +453,9 @@ typedef enum _FcVStackTag { FcVStackString, FcVStackFamily, - FcVStackField, FcVStackConstant, FcVStackGlob, + FcVStackName, FcVStackPattern, FcVStackPrefer, @@ -451,11 +484,12 @@ typedef struct _FcVStack { int integer; double _double; - FcMatrix *matrix; + FcExprMatrix *matrix; FcRange range; FcBool bool_; FcCharSet *charset; FcLangSet *langset; + FcExprName name; FcTest *test; FcQual qual; @@ -474,9 +508,9 @@ typedef struct _FcConfigParse { const FcChar8 *name; FcConfig *config; XML_Parser parser; - int pstack_static_used; + unsigned int pstack_static_used; FcPStack pstack_static[8]; - int vstack_static_used; + unsigned int vstack_static_used; FcVStack vstack_static[64]; } FcConfigParse; @@ -516,6 +550,10 @@ FcConfigMessage (FcConfigParse *parse, FcConfigSeverity severe, const char *fmt, } +static FcExpr * +FcPopExpr (FcConfigParse *parse); + + static const char * FcTypeName (FcType type) { @@ -556,6 +594,10 @@ FcTypecheckValue (FcConfigParse *parse, FcType value, FcType type) return; if (type == (FcType) -1) return; + /* It's perfectly fine to use user-define elements in expressions, + * so don't warn in that case. */ + if (value == (FcType) -1) + return; FcConfigMessage (parse, FcSevereWarning, "saw %s, expected %s", FcTypeName (value), FcTypeName (type)); } @@ -594,7 +636,7 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type) case FcOpNil: break; case FcOpField: - o = FcNameGetObjectType (FcObjectName (expr->u.object)); + o = FcNameGetObjectType (FcObjectName (expr->u.name.object)); if (o) FcTypecheckValue (parse, o->type, type); break; @@ -670,7 +712,6 @@ FcTestCreate (FcConfigParse *parse, { const FcObjectType *o; - FcMemAlloc (FC_MEM_TEST, sizeof (FcTest)); test->next = 0; test->kind = kind; test->qual = qual; @@ -721,7 +762,6 @@ FcVStackCreateAndPush (FcConfigParse *parse) new = malloc (sizeof (FcVStack)); if (!new) return 0; - FcMemAlloc (FC_MEM_VSTACK, sizeof (FcVStack)); } new->tag = FcVStackNone; new->prev = 0; @@ -767,16 +807,13 @@ FcVStackPushDouble (FcConfigParse *parse, double _double) } static FcBool -FcVStackPushMatrix (FcConfigParse *parse, FcMatrix *matrix) +FcVStackPushMatrix (FcConfigParse *parse, FcExprMatrix *matrix) { FcVStack *vstack; - matrix = FcMatrixCopy (matrix); - if (!matrix) - return FcFalse; vstack = FcVStackCreateAndPush (parse); if (!vstack) return FcFalse; - vstack->u.matrix = matrix; + vstack->u.matrix = FcExprMatrixCopyShallow (matrix); vstack->tag = FcVStackMatrix; return FcTrue; } @@ -832,6 +869,18 @@ FcVStackPushLangSet (FcConfigParse *parse, FcLangSet *langset) return FcTrue; } +static FcBool +FcVStackPushName (FcConfigParse *parse, FcMatchKind kind, FcObject object) +{ + FcVStack *vstack = FcVStackCreateAndPush (parse); + if (!vstack) + return FcFalse; + vstack->u.name.object = object; + vstack->u.name.kind = kind; + vstack->tag = FcVStackName; + return FcTrue; +} + static FcBool FcVStackPushTest (FcConfigParse *parse, FcTest *test) { @@ -906,10 +955,11 @@ FcVStackPopAndDestroy (FcConfigParse *parse) switch (vstack->tag) { case FcVStackNone: break; + case FcVStackName: + break; case FcVStackFamily: break; case FcVStackString: - case FcVStackField: case FcVStackConstant: case FcVStackGlob: FcStrFree (vstack->u.string); @@ -921,7 +971,7 @@ FcVStackPopAndDestroy (FcConfigParse *parse) case FcVStackDouble: break; case FcVStackMatrix: - FcMatrixFree (vstack->u.matrix); + FcExprMatrixFreeShallow (vstack->u.matrix); break; case FcVStackRange: case FcVStackBool: @@ -949,10 +999,7 @@ FcVStackPopAndDestroy (FcConfigParse *parse) if (vstack == &parse->vstack_static[parse->vstack_static_used - 1]) parse->vstack_static_used--; else - { - FcMemFree (FC_MEM_VSTACK, sizeof (FcVStack)); free (vstack); - } } static void @@ -1001,7 +1048,6 @@ FcConfigSaveAttr (const XML_Char **attr, FcChar8 **buf, int size_bytes) FcConfigMessage (0, FcSevereError, "out of memory"); return 0; } - FcMemAlloc (FC_MEM_ATTR, 1); /* size is too expensive */ } s = (FcChar8 *) (new + (i + 1)); for (i = 0; attr[i]; i++) @@ -1026,7 +1072,6 @@ FcPStackPush (FcConfigParse *parse, FcElement element, const XML_Char **attr) new = malloc (sizeof (FcPStack)); if (!new) return FcFalse; - FcMemAlloc (FC_MEM_PSTACK, sizeof (FcPStack)); } new->prev = parse->pstack; @@ -1047,28 +1092,38 @@ FcPStackPop (FcConfigParse *parse) FcConfigMessage (parse, FcSevereError, "mismatching element"); return FcFalse; } + + if (parse->pstack->attr) + { + /* Warn about unused attrs. */ + FcChar8 **attrs = parse->pstack->attr; + while (*attrs) + { + if (attrs[0][0]) + { + FcConfigMessage (parse, FcSevereError, "invalid attribute '%s'", attrs[0]); + } + attrs += 2; + } + } + FcVStackClear (parse); old = parse->pstack; parse->pstack = old->prev; FcStrBufDestroy (&old->str); + if (old->attr && old->attr != old->attr_buf_static) - { - FcMemFree (FC_MEM_ATTR, 1); /* size is to expensive */ free (old->attr); - } if (old == &parse->pstack_static[parse->pstack_static_used - 1]) parse->pstack_static_used--; else - { - FcMemFree (FC_MEM_PSTACK, sizeof (FcPStack)); free (old); - } return FcTrue; } static FcBool -FcConfigInit (FcConfigParse *parse, const FcChar8 *name, FcConfig *config, XML_Parser parser) +FcConfigParseInit (FcConfigParse *parse, const FcChar8 *name, FcConfig *config, XML_Parser parser) { parse->pstack = 0; parse->pstack_static_used = 0; @@ -1102,7 +1157,10 @@ FcConfigGetAttribute (FcConfigParse *parse, const char *attr) while (*attrs) { if (!strcmp ((char *) *attrs, attr)) + { + attrs[0][0] = '\0'; /* Mark as used. */ return attrs[1]; + } attrs += 2; } return 0; @@ -1140,7 +1198,7 @@ FcParseBlank (FcConfigParse *parse) if (!parse->config->blanks) goto bail; } - switch (v->tag) { + switch ((int) v->tag) { case FcVStackInteger: if (!FcBlanksAdd (parse->config->blanks, v->u.integer)) goto bail; @@ -1301,48 +1359,67 @@ FcParseString (FcConfigParse *parse, FcVStackTag tag) } static void -FcParseMatrix (FcConfigParse *parse) +FcParseName (FcConfigParse *parse) { - FcVStack *vstack; - enum { m_done, m_xx, m_xy, m_yx, m_yy } matrix_state = m_yy; - FcMatrix m; + const FcChar8 *kind_string; + FcMatchKind kind; + FcChar8 *s; + FcObject object; - while ((vstack = FcVStackPeek (parse))) + kind_string = FcConfigGetAttribute (parse, "target"); + if (!kind_string) + kind = FcMatchDefault; + else { - double v; - switch (vstack->tag) { - case FcVStackInteger: - v = vstack->u.integer; - break; - case FcVStackDouble: - v = vstack->u._double; - break; - default: - FcConfigMessage (parse, FcSevereError, "non-double matrix element"); - v = 1.0; - break; - } - switch (matrix_state) { - case m_xx: m.xx = v; break; - case m_xy: m.xy = v; break; - case m_yx: m.yx = v; break; - case m_yy: m.yy = v; break; - default: break; + if (!strcmp ((char *) kind_string, "pattern")) + kind = FcMatchPattern; + else if (!strcmp ((char *) kind_string, "font")) + kind = FcMatchFont; + else if (!strcmp ((char *) kind_string, "default")) + kind = FcMatchDefault; + else + { + FcConfigMessage (parse, FcSevereWarning, "invalid name target \"%s\"", kind_string); + return; } - FcVStackPopAndDestroy (parse); - matrix_state--; } - if (matrix_state != m_done) - FcConfigMessage (parse, FcSevereError, "wrong number of matrix elements"); + + if (!parse->pstack) + return; + s = FcStrBufDone (&parse->pstack->str); + if (!s) + { + FcConfigMessage (parse, FcSevereError, "out of memory"); + return; + } + object = FcObjectFromName ((const char *) s); + + FcVStackPushName (parse, kind, object); + + FcStrFree (s); +} + +static void +FcParseMatrix (FcConfigParse *parse) +{ + FcExprMatrix m; + + m.yy = FcPopExpr (parse); + m.yx = FcPopExpr (parse); + m.xy = FcPopExpr (parse); + m.xx = FcPopExpr (parse); + + if (FcPopExpr (parse)) + FcConfigMessage (parse, FcSevereError, "wrong number of matrix elements"); else - FcVStackPushMatrix (parse, &m); + FcVStackPushMatrix (parse, &m); } static void FcParseRange (FcConfigParse *parse) { FcVStack *vstack; - FcRange r; + FcRange r = {0, 0}; FcChar32 n; int count = 1; @@ -1353,7 +1430,7 @@ FcParseRange (FcConfigParse *parse) FcConfigMessage (parse, FcSevereError, "too many elements in range"); return; } - switch (vstack->tag) { + switch ((int) vstack->tag) { case FcVStackInteger: n = vstack->u.integer; break; @@ -1420,7 +1497,7 @@ FcParseCharSet (FcConfigParse *parse) while ((vstack = FcVStackPeek (parse))) { - switch (vstack->tag) { + switch ((int) vstack->tag) { case FcVStackInteger: if (!FcCharSetAddChar (charset, vstack->u.integer)) { @@ -1464,7 +1541,7 @@ FcParseLangSet (FcConfigParse *parse) while ((vstack = FcVStackPeek (parse))) { - switch (vstack->tag) { + switch ((int) vstack->tag) { case FcVStackString: if (!FcLangSetAdd (langset, vstack->u.string)) { @@ -1587,7 +1664,7 @@ FcParseAlias (FcConfigParse *parse) return; while ((vstack = FcVStackPeek (parse))) { - switch (vstack->tag) { + switch ((int) vstack->tag) { case FcVStackFamily: if (family) { @@ -1716,15 +1793,15 @@ FcPopExpr (FcConfigParse *parse) FcExpr *expr = 0; if (!vstack) return 0; - switch (vstack->tag) { + switch ((int) vstack->tag) { case FcVStackNone: break; case FcVStackString: case FcVStackFamily: expr = FcExprCreateString (parse->config, vstack->u.string); break; - case FcVStackField: - expr = FcExprCreateField (parse->config, (char *) vstack->u.string); + case FcVStackName: + expr = FcExprCreateName (parse->config, vstack->u.name); break; case FcVStackConstant: expr = FcExprCreateConst (parse->config, vstack->u.string); @@ -1876,8 +1953,6 @@ FcParseDir (FcConfigParse *parse) goto bail; } prefix = p; - FcMemFree (FC_MEM_STRING, plen + 1); - FcMemAlloc (FC_MEM_STRING, plen + 1 + dlen + 1); prefix[plen] = FC_DIR_SEPARATOR; memcpy (&prefix[plen + 1], data, dlen); prefix[plen + 1 + dlen] = 0; @@ -1886,7 +1961,7 @@ FcParseDir (FcConfigParse *parse) #ifdef _WIN32 if (strcmp ((const char *) data, "CUSTOMFONTDIR") == 0) { - char *p; + FcChar8 *p; data = buffer; if (!GetModuleFileName (NULL, (LPCH) buffer, sizeof (buffer) - 20)) { @@ -1901,11 +1976,11 @@ FcParseDir (FcConfigParse *parse) */ p = _mbsrchr (data, '\\'); if (p) *p = '\0'; - strcat (data, "\\fonts"); + strcat ((char *) data, "\\fonts"); } else if (strcmp ((const char *) data, "APPSHAREFONTDIR") == 0) { - char *p; + FcChar8 *p; data = buffer; if (!GetModuleFileName (NULL, (LPCH) buffer, sizeof (buffer) - 20)) { @@ -1914,7 +1989,7 @@ FcParseDir (FcConfigParse *parse) } p = _mbsrchr (data, '\\'); if (p) *p = '\0'; - strcat (data, "\\..\\share\\fonts"); + strcat ((char *) data, "\\..\\share\\fonts"); } else if (strcmp ((const char *) data, "WINDOWSFONTDIR") == 0) { @@ -1927,8 +2002,8 @@ FcParseDir (FcConfigParse *parse) goto bail; } if (data [strlen ((const char *) data) - 1] != '\\') - strcat (data, "\\"); - strcat (data, "fonts"); + strcat ((char *) data, "\\"); + strcat ((char *) data, "fonts"); } #endif if (strlen ((char *) data) == 0) @@ -1973,8 +2048,6 @@ FcParseCacheDir (FcConfigParse *parse) goto bail; } prefix = p; - FcMemFree (FC_MEM_STRING, plen + 1); - FcMemAlloc (FC_MEM_STRING, plen + 1 + dlen + 1); prefix[plen] = FC_DIR_SEPARATOR; memcpy (&prefix[plen + 1], data, dlen); prefix[plen + 1 + dlen] = 0; @@ -1992,7 +2065,6 @@ FcParseCacheDir (FcConfigParse *parse) FcConfigMessage (parse, FcSevereError, "out of memory"); goto bail; } - FcMemAlloc (FC_MEM_STRING, 1000); rc = GetTempPath (800, (LPSTR) data); if (rc == 0 || rc > 800) { @@ -2000,8 +2072,8 @@ FcParseCacheDir (FcConfigParse *parse) goto bail; } if (data [strlen ((const char *) data) - 1] != '\\') - strcat (data, "\\"); - strcat (data, "fontconfig\\cache"); + strcat ((char *) data, "\\"); + strcat ((char *) data, "fontconfig\\cache"); } else if (strcmp ((const char *) data, "LOCAL_APPDATA_FONTCONFIG_CACHE") == 0) { @@ -2022,7 +2094,6 @@ FcParseCacheDir (FcConfigParse *parse) FcConfigMessage (parse, FcSevereError, "out of memory"); goto bail; } - FcMemAlloc (FC_MEM_STRING, len); strncpy((char *) data, szFPath, len); } #endif @@ -2076,8 +2147,6 @@ FcParseInclude (FcConfigParse *parse) goto bail; } prefix = p; - FcMemFree (FC_MEM_STRING, plen + 1); - FcMemAlloc (FC_MEM_STRING, plen + 1 + dlen + 1); prefix[plen] = FC_DIR_SEPARATOR; memcpy (&prefix[plen + 1], s, dlen); prefix[plen + 1 + dlen] = 0; @@ -2334,7 +2403,7 @@ FcParseMatch (FcConfigParse *parse) } while ((vstack = FcVStackPeek (parse))) { - switch (vstack->tag) { + switch ((int) vstack->tag) { case FcVStackTest: vstack->u.test->next = test; test = vstack->u.test; @@ -2368,7 +2437,7 @@ FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element) while ((vstack = FcVStackPeek (parse))) { - switch (vstack->tag) { + switch ((int) vstack->tag) { case FcVStackGlob: if (!FcConfigGlobAdd (parse->config, vstack->u.string, @@ -2407,9 +2476,9 @@ FcPopValue (FcConfigParse *parse) if (!vstack) return value; - switch (vstack->tag) { + switch ((int) vstack->tag) { case FcVStackString: - value.u.s = FcSharedStr (vstack->u.string); + value.u.s = FcStrdup (vstack->u.string); if (value.u.s) value.type = FcTypeString; break; @@ -2423,12 +2492,7 @@ FcPopValue (FcConfigParse *parse) break; case FcVStackDouble: value.u.d = vstack->u._double; - value.type = FcTypeInteger; - break; - case FcVStackMatrix: - value.u.m = FcMatrixCopy (vstack->u.matrix); - if (value.u.m) - value.type = FcTypeMatrix; + value.type = FcTypeDouble; break; case FcVStackBool: value.u.b = vstack->u.bool_; @@ -2506,7 +2570,7 @@ FcParsePattern (FcConfigParse *parse) while ((vstack = FcVStackPeek (parse))) { - switch (vstack->tag) { + switch ((int) vstack->tag) { case FcVStackPattern: if (!FcPatternAppend (pattern, vstack->u.pattern)) { @@ -2526,7 +2590,7 @@ FcParsePattern (FcConfigParse *parse) } static void -FcEndElement(void *userData, const XML_Char *name) +FcEndElement(void *userData, const XML_Char *name FC_UNUSED) { FcConfigParse *parse = userData; FcChar8 *data; @@ -2633,7 +2697,7 @@ FcEndElement(void *userData, const XML_Char *name) FcParsePatelt (parse); break; case FcElementName: - FcParseString (parse, FcVStackField); + FcParseName (parse); break; case FcElementConst: FcParseString (parse, FcVStackConstant); @@ -2718,9 +2782,9 @@ FcCharacterData (void *userData, const XML_Char *s, int len) static void FcStartDoctypeDecl (void *userData, const XML_Char *doctypeName, - const XML_Char *sysid, - const XML_Char *pubid, - int has_internal_subset) + const XML_Char *sysid FC_UNUSED, + const XML_Char *pubid FC_UNUSED, + int has_internal_subset FC_UNUSED) { FcConfigParse *parse = userData; @@ -2751,7 +2815,7 @@ FcExternalSubsetDecl (void *userData, #else /* ENABLE_LIBXML2 */ static void -FcEndDoctypeDecl (void *userData) +FcEndDoctypeDecl (void *userData FC_UNUSED) { } @@ -2939,7 +3003,7 @@ FcConfigParseAndLoad (FcConfig *config, if (!p) goto bail1; - if (!FcConfigInit (&parse, name, config, p)) + if (!FcConfigParseInit (&parse, name, config, p)) goto bail2; #ifndef ENABLE_LIBXML2 diff --git a/fontconfig/src/ftglue.c b/fontconfig/src/ftglue.c index 7c643d0ff..0e02bd2df 100644 --- a/fontconfig/src/ftglue.c +++ b/fontconfig/src/ftglue.c @@ -87,7 +87,7 @@ ftglue_stream_seek( FT_Stream stream, if ( stream->read( stream, pos, 0, 0 ) ) error = FT_Err_Invalid_Stream_Operation; } - else if ( pos > stream->size ) + else if ( pos < 0 || (FT_ULong) pos > stream->size ) error = FT_Err_Invalid_Stream_Operation; if ( !error ) @@ -257,6 +257,5 @@ Exit: } #undef QALLOC -#define __ftglue__ #include "fcaliastail.h" #undef __ftglue__ -- cgit v1.2.3