aboutsummaryrefslogtreecommitdiff
path: root/fontconfig/src
diff options
context:
space:
mode:
Diffstat (limited to 'fontconfig/src')
-rw-r--r--fontconfig/src/Makefile.am42
-rw-r--r--fontconfig/src/fcarch.c11
-rw-r--r--fontconfig/src/fcatomic.c7
-rw-r--r--fontconfig/src/fcatomic.h121
-rw-r--r--fontconfig/src/fcblanks.c8
-rw-r--r--fontconfig/src/fccache.c154
-rw-r--r--fontconfig/src/fccfg.c285
-rw-r--r--fontconfig/src/fccharset.c64
-rw-r--r--fontconfig/src/fcdbg.c75
-rw-r--r--fontconfig/src/fcdefault.c91
-rw-r--r--fontconfig/src/fcdir.c6
-rw-r--r--fontconfig/src/fcformat.c15
-rw-r--r--fontconfig/src/fcfreetype.c12
-rw-r--r--fontconfig/src/fcfs.c8
-rw-r--r--fontconfig/src/fcinit.c134
-rw-r--r--fontconfig/src/fcint.h209
-rw-r--r--fontconfig/src/fclang.c66
-rw-r--r--fontconfig/src/fclist.c16
-rw-r--r--fontconfig/src/fcmatch.c27
-rw-r--r--fontconfig/src/fcmatrix.c4
-rw-r--r--fontconfig/src/fcmutex.h127
-rw-r--r--fontconfig/src/fcname.c426
-rw-r--r--fontconfig/src/fcobjs.c139
-rw-r--r--fontconfig/src/fcobjs.h44
-rw-r--r--fontconfig/src/fcobjshash.gperf.h26
-rw-r--r--fontconfig/src/fcpat.c150
-rw-r--r--fontconfig/src/fcserialize.c1
-rw-r--r--fontconfig/src/fcstat.c9
-rw-r--r--fontconfig/src/fcstr.c65
-rw-r--r--fontconfig/src/fcwindows.h44
-rw-r--r--fontconfig/src/fcxml.c280
-rw-r--r--fontconfig/src/ftglue.c3
32 files changed, 1411 insertions, 1258 deletions
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 <config.h>
#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 <time.h>
#ifdef _WIN32
+#include <direct.h>
#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 <chris@chris-wilson.co.uk>
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef _FCATOMIC_H_
+#define _FCATOMIC_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#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 <libkern/OSAtomic.h>
+
+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 <dirent.h>
#include <sys/types.h>
-#if defined (_WIN32) && (defined (PIC) || defined (DLL_EXPORT))
-#define STRICT
-#include <windows.h>
-#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: <name> tag has target=\"font\" in a <match target=\"pattern\">.\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,17 +1731,18 @@ FcConfigSubstitute (FcConfig *config,
#if defined (_WIN32)
-# define WIN32_LEAN_AND_MEAN
-# define WIN32_EXTRA_LEAN
-# include <windows.h>
-
-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,
LPVOID lpvReserved)
{
FcChar8 *p;
@@ -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 <stdlib.h>
static void
-_FcValuePrint (const FcValue v)
+_FcValuePrintFile (FILE *f, const FcValue v)
{
switch (v.type) {
case FcTypeVoid:
- printf ("<void>");
+ fprintf (f, "<void>");
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 <string.h>
+/* 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 <stdlib.h>
+#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 <stdio.h>
#include <string.h>
#include <ctype.h>
+#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <stddef.h>
@@ -44,18 +45,15 @@
#include <fontconfig/fontconfig.h>
#include <fontconfig/fcprivate.h>
#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 <windows.h>
+# 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 <string.h>
#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 <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
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 <chris@chris-wilson.co.uk>
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef _FCMUTEX_H_
+#define _FCMUTEX_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#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 <pthread.h>
+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 <sched.h>
+# 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 <sched.h>
+# 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 <string.h>
#include <stdio.h>
-/*
- * 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 <string.h>
+
+/* 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 <fontconfig/fontconfig.h>
+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 <stdlib.h>
-#include <string.h>
-#include <assert.h>
+
+/* 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 <windows.h>
-
#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 <regex.h>
#endif
-#ifdef _WIN32
-#include <windows.h>
-#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 <config.h>
+#endif
+
+#ifdef _WIN32
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0500
+# endif
+# define WIN32_LEAN_AND_MEAN
+# define WIN32_EXTRA_LEAN
+# define STRICT
+# include <windows.h>
+#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;
}
@@ -833,6 +870,18 @@ FcVStackPushLangSet (FcConfigParse *parse, FcLangSet *langset)
}
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)
{
FcVStack *vstack = FcVStackCreateAndPush (parse);
@@ -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__