[Fontconfig] fontconfig: Branch 'fc-2_4-keithp' - 2 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Aug 30 04:24:48 PDT 2006


 fc-arch/fc-arch.c       |   14 
 fc-arch/fcarch.tmpl.h   |    7 
 fc-lang/fc-lang.c       |  186 ++++----
 fontconfig/fontconfig.h |    3 
 src/Makefile.am         |    1 
 src/fccache.c           |  581 ++++++++++-----------------
 src/fccfg.c             |  102 ++--
 src/fccharset.c         |  493 +++++++---------------
 src/fcdbg.c             |   43 +-
 src/fcdefault.c         |   64 +-
 src/fcfs.c              |  133 +-----
 src/fcint.h             |  481 +++++++++++++---------
 src/fclang.c            |  120 +----
 src/fclist.c            |   86 +---
 src/fcmatch.c           |  179 +++-----
 src/fcname.c            |  142 +-----
 src/fcpat.c             | 1029 ++++++++++++++----------------------------------
 src/fcserialize.c       |  159 +++++++
 src/fcstr.c             |    1 
 src/fcxml.c             |   15 
 20 files changed, 1563 insertions(+), 2276 deletions(-)

New commits:
diff-tree e3096d90fd3e0ba8b62d2c6df4cfb24f08a0766c (from 7ce196733129b0e664c1bdc20f973f15167292f7)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Wed Aug 30 04:24:03 2006 -0700

    Fix build problems caused by cache rework.
    
    Pagesize no longer matters in architecture decisions, the entire cache file
    is mmaped into the library. However, lots of intptr_t values are in use now,
    so that value is important.
    
    fc-lang now requires fcserialize.c, which has been added to the repository.

diff --git a/fc-arch/fc-arch.c b/fc-arch/fc-arch.c
index 0179034..2fa6b18 100644
--- a/fc-arch/fc-arch.c
+++ b/fc-arch/fc-arch.c
@@ -26,9 +26,6 @@
 
 #define ENDIAN_TEST 0x12345678
 #define MACHINE_SIGNATURE_SIZE (9*21 + 1)
-#define MACHINE_ARCH_SIZE   32
-/* for when we don't have sysconf: */
-#define FC_HARDCODED_PAGESIZE 8192 
 
 static char *
 FcCacheMachineSignature (void)
@@ -44,11 +41,12 @@ FcCacheMachineSignature (void)
 	     (unsigned int)sizeof (char),
 	     (unsigned int)sizeof (char *),
 	     (unsigned int)sizeof (int),
+	     (unsigned int)sizeof (intptr_t),
 	     (unsigned int)sizeof (FcPattern),
 	     (unsigned int)sizeof (FcPatternEltPtr),
 	     (unsigned int)sizeof (struct  FcPatternElt *),
 	     (unsigned int)sizeof (FcPatternElt),
-	     (unsigned int)sizeof (FcObjectPtr),
+	     (unsigned int)sizeof (FcObject),
 	     (unsigned int)sizeof (FcValueListPtr),
 	     (unsigned int)sizeof (FcValue),
 	     (unsigned int)sizeof (FcValueBinding),
@@ -59,13 +57,7 @@ FcCacheMachineSignature (void)
 	     (unsigned int)sizeof (FcChar16),
 	     (unsigned int)sizeof (FcCharLeaf),
 	     (unsigned int)sizeof (FcChar32),
-	     (unsigned int)sizeof (FcCache),
-#if defined (HAVE_SYSCONF)
-	     (unsigned int)sysconf(_SC_PAGESIZE)
-#else
-	     (unsigned int)FC_HARDCODED_PAGESIZE
-#endif
-	     );
+	     (unsigned int)sizeof (FcCache));
 
     return buf;
 }
diff --git a/fc-arch/fcarch.tmpl.h b/fc-arch/fcarch.tmpl.h
index 4cf483f..b0712e5 100644
--- a/fc-arch/fcarch.tmpl.h
+++ b/fc-arch/fcarch.tmpl.h
@@ -28,8 +28,8 @@
 @@@ name. Architecture names are used to construct file names, so
 @@@ use something reasonable and don't include any spaces
 @@@
-@@@ name    endian   char     char*    int      Pattern  EltPtr   Elt *    Elt      ObjPtr   VLPtr    Value    Binding  VL *     CharSet  Leaf**   Char16 * Char16   Leaf     Char32   Cache    PageSize
-x86	    78563412_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_0000000c_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000
+@@@ name    endian   char     char*    int      intptr_t Pattern  EltPtr   Elt *    Elt      ObjPtr   VLPtr    Value    Binding  VL *     CharSet  Leaf**   Char16 * Char16   Leaf     Char32   Cache
+x86	    78563412_00000001_00000004_00000004_00000004_00000010_00000004_00000004_00000008_00000004_00000004_0000000c_00000004_00000004_00000010_00000004_00000004_00000002_00000020_00000004_00000018
 x86-64	    78563412_00000001_00000008_00000004_00000020_00000010_00000008_00000018_00000004_00000010_00000010_00000004_00000008_00000020_00000008_00000008_00000002_00000020_00000004_00000040_00001000
 ppc-4k	    12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000
 ppc-64k     12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00010000
diff --git a/fc-lang/fc-lang.c b/fc-lang/fc-lang.c
index 631411d..324a0b2 100644
--- a/fc-lang/fc-lang.c
+++ b/fc-lang/fc-lang.c
@@ -25,6 +25,7 @@
 #include "fcint.h"
 #include "fccharset.c"
 #include "fcstr.c"
+#include "fcserialize.c"
 
 /*
  * fc-lang
diff --git a/src/fcserialize.c b/src/fcserialize.c
new file mode 100644
index 0000000..5a4b4af
--- /dev/null
+++ b/src/fcserialize.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright © 2006 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 copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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"
+
+typedef union _FcAlign {
+    double	d;
+    int		i;
+    intptr_t	ip;
+    off_t	o;
+    FcBool	b;
+    void	*p;
+} FcAlign;
+
+intptr_t
+FcAlignSize (intptr_t size)
+{
+    intptr_t	rem = size % sizeof (FcAlign);
+    if (rem)
+	size += sizeof (FcAlign) - rem;
+    return size;
+}
+
+/*
+ * Serialization helper object -- allocate space in the
+ * yet-to-be-created linear array for a serialized font set
+ */
+
+FcSerialize *
+FcSerializeCreate (void)
+{
+    FcSerialize	*serialize;
+
+    serialize = malloc (sizeof (FcSerialize));
+    if (!serialize)
+	return NULL;
+    serialize->size = 0;
+    serialize->linear = NULL;
+    memset (serialize->buckets, '\0', sizeof (serialize->buckets));
+    return serialize;
+}
+
+void
+FcSerializeDestroy (FcSerialize *serialize)
+{
+    uintptr_t	bucket;
+
+    for (bucket = 0; bucket < FC_SERIALIZE_HASH_SIZE; bucket++)
+    {
+	FcSerializeBucket   *buck, *next;
+
+	for (buck = serialize->buckets[bucket]; buck; buck = next) {
+	    next = buck->next;
+	    free (buck);
+	}
+    }
+    free (serialize);
+}
+
+/*
+ * Allocate space for an object in the serialized array. Keep track
+ * of where the object is placed and only allocate one copy of each object
+ */
+
+FcBool
+FcSerializeAlloc (FcSerialize *serialize, const void *object, int size)
+{
+    uintptr_t	bucket = ((uintptr_t) object) % FC_SERIALIZE_HASH_SIZE;
+    FcSerializeBucket  *buck;
+
+    for (buck = serialize->buckets[bucket]; buck; buck = buck->next)
+	if (buck->object == object)
+	    return FcTrue;
+    buck = malloc (sizeof (FcSerializeBucket));
+    if (!buck)
+	return FcFalse;
+    buck->object = object;
+    buck->offset = serialize->size;
+    buck->next = serialize->buckets[bucket];
+    serialize->buckets[bucket] = buck;
+    serialize->size += FcAlignSize (size);
+    return FcTrue;
+}
+
+/*
+ * Reserve space in the serialization array
+ */
+intptr_t
+FcSerializeReserve (FcSerialize *serialize, int size)
+{
+    intptr_t	offset = serialize->size;
+    serialize->size += FcAlignSize (size);
+    return offset;
+}
+
+/*
+ * Given an object, return the offset in the serialized array where
+ * the serialized copy of the object is stored
+ */
+intptr_t
+FcSerializeOffset (FcSerialize *serialize, const void *object)
+{
+    uintptr_t	bucket = ((uintptr_t) object) % FC_SERIALIZE_HASH_SIZE;
+    FcSerializeBucket  *buck;
+
+    for (buck = serialize->buckets[bucket]; buck; buck = buck->next)
+	if (buck->object == object)
+	    return buck->offset;
+    return 0;
+}
+
+/*
+ * Given a cache and an object, return a pointer to where
+ * the serialized copy of the object is stored
+ */
+void *
+FcSerializePtr (FcSerialize *serialize, const void *object)
+{
+    intptr_t	offset = FcSerializeOffset (serialize, object);
+
+    if (!offset)
+	return NULL;
+    return (void *) ((char *) serialize->linear + offset);
+}
+
+FcBool
+FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str)
+{
+    return FcSerializeAlloc (serialize, str, strlen ((const char *) str) + 1);
+}
+
+FcChar8 *
+FcStrSerialize (FcSerialize *serialize, const FcChar8 *str)
+{
+    FcChar8 *str_serialize = FcSerializePtr (serialize, str);
+    if (!str_serialize)
+	return NULL;
+    strcpy ((char *) str_serialize, (const char *) str);
+    return str_serialize;
+}
diff-tree 7ce196733129b0e664c1bdc20f973f15167292f7 (from 2a9179d8895c1cc90d02917f7bb6fac30ffb6a62)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Wed Aug 30 04:16:22 2006 -0700

    Rework cache files to use offsets for all data structures.
    
    Replace all of the bank/id pairs with simple offsets, recode several
    data structures to always use offsets inside the library to avoid
    conditional paths. Exposed data structures use pointers to hold offsets,
    setting the low bit to distinguish between offset and pointer.
    
    Use offset-based data structures for lang charset encodings; eliminates
    separate data structure format for that file.
    
    Much testing will be needed; offsets are likely not detected everywhere in
    the library yet.

diff --git a/fc-arch/fcarch.tmpl.h b/fc-arch/fcarch.tmpl.h
index 6e89ad9..4cf483f 100644
--- a/fc-arch/fcarch.tmpl.h
+++ b/fc-arch/fcarch.tmpl.h
@@ -31,4 +31,5 @@
 @@@ name    endian   char     char*    int      Pattern  EltPtr   Elt *    Elt      ObjPtr   VLPtr    Value    Binding  VL *     CharSet  Leaf**   Char16 * Char16   Leaf     Char32   Cache    PageSize
 x86	    78563412_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_0000000c_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000
 x86-64	    78563412_00000001_00000008_00000004_00000020_00000010_00000008_00000018_00000004_00000010_00000010_00000004_00000008_00000020_00000008_00000008_00000002_00000020_00000004_00000040_00001000
-ppc	    12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000
+ppc-4k	    12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000
+ppc-64k     12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00010000
diff --git a/fc-lang/fc-lang.c b/fc-lang/fc-lang.c
index b72893b..631411d 100644
--- a/fc-lang/fc-lang.c
+++ b/fc-lang/fc-lang.c
@@ -37,10 +37,6 @@
  * functions are also needed in slightly modified form
  */
 
-const FcChar16 langBankNumbers[1]; /* place holders so that externs resolve */
-const FcCharLeaf	langBankLeaves[1];
-const int langBankLeafIdx[1];
-
 void
 FcMemAlloc (int kind, int size)
 {
@@ -51,18 +47,6 @@ FcMemFree (int kind, int size)
 {
 }
 
-int* _fcBankId = 0;
-int* _fcBankIdx = 0;
-FcValueList ** _fcValueLists = 0;
-FcPatternElt ** _fcPatternElts = 0;
-int FcDebugVal = 0;
-
-int
-FcCacheBankToIndexMTF (int bank)
-{
-    return -1;
-}
-
 FcChar8 *
 FcConfigHome (void)
 {
@@ -239,19 +223,18 @@ main (int argc, char **argv)
     static char		*files[MAX_LANG];
     static FcCharSet	*sets[MAX_LANG];
     static int		duplicate[MAX_LANG];
-    static int		offsets[MAX_LANG];
     static int		country[MAX_LANG];
     static char		*names[MAX_LANG];
     static char		*langs[MAX_LANG];
+    static int		off[MAX_LANG];
     FILE	*f;
-    int         offset = 0;
     int		ncountry = 0;
     int		i = 0;
+    int		nsets = 0;
     int		argi;
     FcCharLeaf	**leaves;
     int		total_leaves = 0;
-    int		offset_count = 0;
-    int		l, sl, tl;
+    int		l, sl, tl, tn;
     static char		line[1024];
     static FcChar32	map[MAX_LANG_SET_MAP];
     int		num_lang_set_map;
@@ -290,6 +273,7 @@ main (int argc, char **argv)
 	i++;
 	fclose (f);
     }
+    nsets = i;
     sets[i] = 0;
     leaves = malloc (total_leaves * sizeof (FcCharLeaf *));
     tl = 0;
@@ -301,10 +285,10 @@ main (int argc, char **argv)
 	for (sl = 0; sl < sets[i]->num; sl++)
 	{
 	    for (l = 0; l < tl; l++)
-		if (leaves[l] == FcCharSetGetLeaf(sets[i], sl))
+		if (leaves[l] == FcCharSetLeaf(sets[i], sl))
 		    break;
 	    if (l == tl)
-		leaves[tl++] = FcCharSetGetLeaf(sets[i], sl);
+		leaves[tl++] = FcCharSetLeaf(sets[i], sl);
 	}
     }
 
@@ -321,22 +305,6 @@ main (int argc, char **argv)
     
     printf ("/* total size: %d unique leaves: %d */\n\n",
 	    total_leaves, tl);
-    /*
-     * Dump leaves
-     */
-    printf ("const FcCharLeaf	langBankLeaves[%d] = {\n", tl);
-    for (l = 0; l < tl; l++)
-    {
-	printf ("    { { /* %d */", l);
-	for (i = 0; i < 256/32; i++)
-	{
-	    if (i % 4 == 0)
-		printf ("\n   ");
-	    printf (" 0x%08x,", leaves[l]->map[i]);
-	}
-	printf ("\n    } },\n");
-    }
-    printf ("};\n\n");
 
     /*
      * Find duplicate charsets
@@ -355,111 +323,121 @@ main (int argc, char **argv)
 	    }
     }
 
+    tn = 0;
+    for (i = 0; sets[i]; i++) {
+	if (duplicate[i] >= 0)
+	    continue;
+	off[i] = tn;
+	tn += sets[i]->num;
+    }
+
+    printf ("#define LEAF0       (%d * sizeof (FcLangCharSet))\n", nsets);
+    printf ("#define OFF0        (LEAF0 + %d * sizeof (FcCharLeaf))\n", tl);
+    printf ("#define NUM0        (OFF0 + %d * sizeof (intptr_t))\n", tn);
+    printf ("#define SET(n)      (n * sizeof (FcLangCharSet) + offsetof (FcLangCharSet, charset))\n");
+    printf ("#define OFF(s,o)    (OFF0 + o * sizeof (intptr_t) - SET(s))\n");
+    printf ("#define NUM(s,n)    (NUM0 + n * sizeof (FcChar16) - SET(s))\n");
+    printf ("#define LEAF(o,l)   (LEAF0 + l * sizeof (FcCharLeaf) - (OFF0 + o * sizeof (intptr_t)))\n");
+    printf ("#define fcLangCharSets (fcLangData.langCharSets)\n");
+    printf ("\n");
+    
+    printf ("static const struct {\n"
+	    "    FcLangCharSet  langCharSets[%d];\n"
+	    "    FcCharLeaf     leaves[%d];\n"
+	    "    intptr_t       leaf_offsets[%d];\n"
+	    "    FcChar16       numbers[%d];\n"
+	    "} fcLangData = {\n",
+	    nsets, tl, tn, tn);
+	
     /*
-     * Find ranges for each letter for faster searching
+     * Dump sets
      */
-    setRangeChar = 'a';
+
+    printf ("{\n");
     for (i = 0; sets[i]; i++)
     {
-	char	c = names[i][0];
-	
-	while (setRangeChar <= c && c <= 'z')
-	    setRangeStart[setRangeChar++ - 'a'] = i;
+	int	j = duplicate[i];
+
+	if (j < 0)
+	    j = i;
+
+	printf ("    { (FcChar8 *) \"%s\", "
+		" { FC_REF_CONSTANT, %d, OFF(%d,%d), NUM(%d,%d) } }, /* %d */\n",
+		langs[i],
+		sets[j]->num, i, off[j], i, off[j], i);
     }
-    for (setRangeChar = 'a'; setRangeChar < 'z'; setRangeChar++)
-	setRangeEnd[setRangeChar - 'a'] = setRangeStart[setRangeChar+1-'a'] - 1;
-    setRangeEnd[setRangeChar - 'a'] = i - 1;
+    printf ("},\n");
     
     /*
-     * Dump arrays
+     * Dump leaves
      */
-    for (i = 0; sets[i]; i++)
+    printf ("{\n");
+    for (l = 0; l < tl; l++)
     {
-	int n;
-	
-	if (duplicate[i] >= 0)
-	    continue;
-
-	for (n = 0; n < sets[i]->num; n++)
+	printf ("    { { /* %d */", l);
+	for (i = 0; i < 256/32; i++)
 	{
-	    for (l = 0; l < tl; l++)
-		if (leaves[l] == FcCharSetGetLeaf(sets[i], n))
-		    break;
-	    if (l == tl)
-		fatal (names[i], 0, "can't find leaf");
-	    offset_count++;
+	    if (i % 4 == 0)
+		printf ("\n   ");
+	    printf (" 0x%08x,", leaves[l]->map[i]);
 	}
-	offsets[i] = offset;
-	offset += sets[i]->num;
+	printf ("\n    } },\n");
     }
+    printf ("},\n");
 
-    printf ("const int langBankLeafIdx[%d] = {\n",
-	    offset_count);
+    /*
+     * Dump leaves
+     */
+    printf ("{\n");
     for (i = 0; sets[i]; i++)
     {
 	int n;
 	
 	if (duplicate[i] >= 0)
 	    continue;
+	printf ("    /* %s */\n", names[i]);
 	for (n = 0; n < sets[i]->num; n++)
 	{
-	    if (n % 8 == 0)
+	    if (n % 4 == 0)
 		printf ("   ");
 	    for (l = 0; l < tl; l++)
-		if (leaves[l] == FcCharSetGetLeaf(sets[i], n))
+		if (leaves[l] == FcCharSetLeaf(sets[i], n))
 		    break;
 	    if (l == tl)
 		fatal (names[i], 0, "can't find leaf");
-	    printf (" %3d,", l);
-	    if (n % 8 == 7)
+	    printf (" LEAF(%3d,%3d),", off[i], l);
+	    if (n % 4 == 3)
 		printf ("\n");
 	}
-	if (n % 8 != 0)
+	if (n % 4 != 0)
 	    printf ("\n");
     }
-    printf ("};\n\n");
-
-    printf ("const FcChar16 langBankNumbers[%d] = {\n",
-	    offset_count);
+    printf ("},\n");
+	
 
+    printf ("{\n");
     for (i = 0; sets[i]; i++)
     {
 	int n;
-
+	
 	if (duplicate[i] >= 0)
 	    continue;
+	printf ("    /* %s */\n", names[i]);
 	for (n = 0; n < sets[i]->num; n++)
 	{
 	    if (n % 8 == 0)
 		printf ("   ");
-	    printf (" 0x%04x,", FcCharSetGetNumbers(sets[i])[n]);
+	    printf (" 0x%04x,", FcCharSetNumbers (sets[i])[n]);
 	    if (n % 8 == 7)
 		printf ("\n");
 	}
 	if (n % 8 != 0)
 	    printf ("\n");
     }
-    printf ("};\n\n");
+    printf ("}\n");
     
-    /*
-     * Dump sets
-     */
-
-    printf ("const FcLangCharSet  fcLangCharSets[] = {\n");
-    for (i = 0; sets[i]; i++)
-    {
-	int	j = duplicate[i];
-
-	if (j < 0)
-	    j = i;
-
-	printf ("    { (FcChar8 *) \"%s\",\n"
-		"      { FC_REF_CONSTANT, %d, FC_BANK_LANGS, "
-		"{ { %d, %d } } } }, /* %d */\n",
-		langs[i],
-		sets[j]->num, offsets[j], offsets[j], j);
-    }
     printf ("};\n\n");
+    
     printf ("#define NUM_LANG_CHAR_SET	%d\n", i);
     num_lang_set_map = (i + 31) / 32;
     printf ("#define NUM_LANG_SET_MAP	%d\n", num_lang_set_map);
@@ -507,6 +485,23 @@ main (int argc, char **argv)
     
 
     /*
+     * Find ranges for each letter for faster searching
+     */
+    setRangeChar = 'a';
+    memset(setRangeStart, '\0', sizeof (setRangeStart));
+    memset(setRangeEnd, '\0', sizeof (setRangeEnd));
+    for (i = 0; sets[i]; i++)
+    {
+	char	c = names[i][0];
+	
+	while (setRangeChar <= c && c <= 'z')
+	    setRangeStart[setRangeChar++ - 'a'] = i;
+    }
+    for (setRangeChar = 'a'; setRangeChar < 'z'; setRangeChar++)
+	setRangeEnd[setRangeChar - 'a'] = setRangeStart[setRangeChar+1-'a'] - 1;
+    setRangeEnd[setRangeChar - 'a'] = i - 1;
+    
+    /*
      * Dump sets start/finish for the fastpath
      */
     printf ("static const FcLangCharSetRange  fcLangCharSetRanges[] = {\n");
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index 8ef2f7c..410da1e 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -212,17 +212,14 @@ typedef struct _FcValue {
     FcType	type;
     union {
 	const FcChar8  *s;
-	int             s_off;
 	int		i;
 	FcBool		b;
 	double		d;
 	const FcMatrix  *m;
 	const FcCharSet *c;
-	int		c_off;
 	void		*f;
 	const FcPattern	*p;
 	const FcLangSet *l;
-	int		l_off; /* this is a difference of char *s */
     } u;
 } FcValue;
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 5d144bc..586594c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -95,6 +95,7 @@ libfontconfig_la_SOURCES = \
 	fcmatrix.c \
 	fcname.c \
 	fcpat.c \
+	fcserialize.c \
 	fcstr.c \
 	fcxml.c \
 	ftglue.h \
diff --git a/src/fccache.c b/src/fccache.c
index a677253..c1c58fb 100644
--- a/src/fccache.c
+++ b/src/fccache.c
@@ -1,6 +1,4 @@
 /*
- * $RCSId: xc/lib/fontconfig/src/fccache.c,v 1.12 2002/08/22 07:36:44 keithp Exp $
- *
  * Copyright © 2000 Keith Packard
  * Copyright © 2005 Patrick Lam
  *
@@ -37,29 +35,12 @@
 #  include <windows.h>
 #endif
 
-#define ENDIAN_TEST 0x12345678
-#define MACHINE_SIGNATURE_SIZE (9 + 5*20 + 1)
-/* for when we don't have sysconf: */
-#define FC_HARDCODED_PAGESIZE 8192 
-
 #ifndef O_BINARY
 #define O_BINARY 0
 #endif
 
-static FILE *
-FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, FcChar8 **cache_path);
-
-static void *
-FcDirCacheProduce (FcFontSet *set, FcCache * metadata);
-
-static off_t
-FcCacheNextOffset(off_t w);
-
-static FcBool
-FcCacheHaveBank (int bank);
-
-static void
-FcCacheAddBankDir (int bank, const char * dir);
+static int
+FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, off_t *size);
 
 struct MD5Context {
         FcChar32 buf[4];
@@ -74,67 +55,17 @@ static void MD5Transform(FcChar32 buf[4]
 
 #define FC_DBG_CACHE_REF    1024
 
-static char *
-FcCacheReadString (FILE *file, char *dest, int len)
-{
-    int	    c;
-    char    *d = dest;
-
-    if (len == 0)
-	return 0;
-
-    while ((c = getc (file)) != EOF && len > 0) {
-	*d++ = c;
-	if (c == '\0')
-	    return dest;
-	len--;
-    }
-    return 0;
-}
-
-static FcBool
-FcCacheWriteString (int fd, const char *chars)
-{
-    if (write (fd, chars, strlen(chars)+1) != strlen(chars)+1)
-	return FcFalse;
-    return FcTrue;
-}
-
-/* 
- * Find the next presumably-mmapable offset after the supplied file
- * position.
- */
-static off_t
-FcCacheNextOffset(off_t w)
-{
-    static long pagesize = -1;
-
-    if (w == -1)
-        return w;
-
-    if (pagesize == -1)
-#if defined (HAVE_SYSCONF)
-	pagesize = sysconf(_SC_PAGESIZE);
-#else
-	pagesize = FC_HARDCODED_PAGESIZE;
-#endif
-    if (w % pagesize == 0) 
-	return w;
-    else
-	return ((w / pagesize)+1)*pagesize;
-}
-
 /* Does not check that the cache has the appropriate arch section. */
 FcBool
 FcDirCacheValid (const FcChar8 *dir, FcConfig *config)
 {
-    FILE *file;
+    int fd;
 
-    file = FcDirCacheOpen (config, dir, NULL);
+    fd = FcDirCacheOpen (config, dir, NULL);
 
-    if (file == NULL)
+    if (fd < 0)
 	return FcFalse;
-    fclose (file);
+    close (fd);
 
     return FcTrue;
 }
@@ -282,218 +213,281 @@ FcCacheRead (FcConfig *config)
  * This searches the list of cache dirs for the relevant cache file,
  * returning the first one found.
  */
-static FILE *
-FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, FcChar8 **cache_path)
+static int
+FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, off_t *size)
 {
-    FILE	*file = NULL;
-    FcChar8	*cache_hashed = NULL;
+    int		fd = -1;
     FcChar8	cache_base[CACHEBASE_LEN];
     FcStrList	*list;
     FcChar8	*cache_dir;
     struct stat file_stat, dir_stat;
 
     if (stat ((char *) dir, &dir_stat) < 0)
-        return NULL;
+        return -1;
 
     FcDirCacheBasename (dir, cache_base);
 
     list = FcStrListCreate (config->cacheDirs);
     if (!list)
-        return NULL;
+        return -1;
 	
     while ((cache_dir = FcStrListNext (list)))
     {
-        cache_hashed = FcStrPlus (cache_dir, cache_base);
+        FcChar8	*cache_hashed = FcStrPlus (cache_dir, cache_base);
         if (!cache_hashed)
 	    break;
-        file = fopen((char *) cache_hashed, "rb");
-        if (file != NULL) {
-	    if (fstat (fileno (file), &file_stat) >= 0 &&
+        fd = open((char *) cache_hashed, O_RDONLY | O_BINARY);
+	FcStrFree (cache_hashed);
+        if (fd >= 0) {
+	    if (fstat (fd, &file_stat) >= 0 &&
 		dir_stat.st_mtime <= file_stat.st_mtime)
 	    {
+		if (size)
+		    *size = file_stat.st_size;
 		break;
 	    }
-	    fclose (file);
-	    file = NULL;
+	    close (fd);
+	    fd = -1;
 	}
-	FcStrFree (cache_hashed);
-	cache_hashed = NULL;
     }
     FcStrListDone (list);
-
-    if (file == NULL)
-	return NULL;
     
-    if (cache_path)
-	*cache_path = cache_hashed;
-    else
-	FcStrFree (cache_hashed);
+    return fd;
+}
 
-    return file;
+#if 0
+static void
+FcDirCacheUnmap (FcCache *cache)
+{
+    if (cache->magic == FC_CACHE_MAGIC_COPY)
+    {
+	free (cache);
+	return;
+    }
+#if defined(HAVE_MMAP) || defined(__CYGWIN__)
+    munmap (cache, cache->size);
+#elif defined(_WIN32)
+    UnmapViewOfFile (cache);
+#endif
 }
+#endif
 
 /* read serialized state from the cache file */
-FcBool
-FcDirCacheConsume (FILE *file, FcFontSet *set, FcStrSet *dirs,
-		   const FcChar8 *dir, char *dirname)
+static FcCache *
+FcDirCacheMap (int fd, off_t size)
 {
-    FcCache	metadata;
-    void	*current_dir_block;
-    char	subdir_name[FC_MAX_FILE_LEN + 1 + 12 + 1];
-    int		i;
-
-    if (fread(&metadata, sizeof(FcCache), 1, file) != 1)
-	goto bail;
-    if (metadata.magic != FC_CACHE_MAGIC)
-        goto bail;
-
-    /* skip directory name; it's just for fc-cat */
-    if (!FcCacheReadString (file, subdir_name, sizeof (subdir_name)))
-	goto bail;
-    
-    if (dirname)
-	strcpy (dirname, subdir_name);
+    FcCache	*cache;
+    FcBool	allocated = FcFalse;
 
-    for (i = 0; i < metadata.subdirs; i++) {
-	if (!FcCacheReadString (file, subdir_name, sizeof (subdir_name)))
-	    goto bail;
-	FcStrSetAdd (dirs, (FcChar8 *)subdir_name);
-    }
-
-    if (metadata.count)
-    {
-	int	fd = fileno (file);
+    if (size < sizeof (FcCache))
+	return NULL;
 #if defined(HAVE_MMAP) || defined(__CYGWIN__)
-	current_dir_block = mmap (0, metadata.count, 
-				  PROT_READ, MAP_SHARED, fd, metadata.pos);
-	if (current_dir_block == MAP_FAILED)
-	    goto bail;
+    cache = mmap (0, size, PROT_READ, MAP_SHARED, fd, 0);
 #elif defined(_WIN32)
-	{
-	    HANDLE hFileMap;
-
-	    hFileMap = CreateFileMapping((HANDLE) _get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL);
-	    if (hFileMap == NULL)
-		goto bail;
+    {
+	HANDLE hFileMap;
 
-	    current_dir_block = MapViewOfFile (hFileMap, FILE_MAP_READ, 0, metadata.pos, metadata.count);
-	    if (current_dir_block == NULL)
-	    {
-		CloseHandle (hFileMap);
-		goto bail;
-	    }
+	cache = NULL;
+	hFileMap = CreateFileMapping((HANDLE) _get_osfhandle(fd), NULL,
+				     PAGE_READONLY, 0, 0, NULL);
+	if (hFileMap != NULL)
+	{
+	    cache = MapViewOfFile (hFileMap, FILE_MAP_READ, 0, 0, size);
+	    CloseHandle (hFileMap);
 	}
-#else
-	if (lseek (fd, metatdata.pos, SEEK_SET) == -1)
-	    goto bail;
-
-	current_dir_block = malloc (metadata.count);
-	if (!current_dir_block)
-	    goto bail;
+    }
+#endif
+    if (!cache)
+    {
+	cache = malloc (size);
+	if (!cache)
+	    return NULL;
 
-	/* could also use CreateMappedViewOfFile under MinGW... */
-	if (read (fd, current_dir_block, metadata.count) != metadata.count)
+	if (read (fd, cache, size) != size)
 	{
-	    free (current_dir_block);
-	    goto bail;
+	    free (cache);
+	    return NULL;
 	}
+	allocated = FcTrue;
+    } 
+    if (cache->magic != FC_CACHE_MAGIC ||
+	cache->size != size)
+    {
+	if (allocated)
+	    free (cache);
+	else
+	{
+#if defined(HAVE_MMAP) || defined(__CYGWIN__)
+	    munmap (cache, size);
+#elif defined(_WIN32)
+	    UnmapViewOfFile (cache);
 #endif
-	FcCacheAddBankDir (metadata.bank, (char *) dir);
-	if (!FcFontSetUnserialize (&metadata, set, current_dir_block))
-	    goto bail;
+	}
+	return NULL;
     }
 
-    return FcTrue;
-
- bail:
-    return FcFalse;
+    /* Mark allocated caches so they're freed rather than unmapped */
+    if (allocated)
+	cache->magic = FC_CACHE_MAGIC_COPY;
+	
+    return cache;
 }
 
 FcBool
 FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, 
 		const FcChar8 *dir, FcConfig *config)
 {
-    FILE    *file;
-
-    file = FcDirCacheOpen (config, dir, NULL);
-    if (file == NULL)
-	goto bail;
+    int		fd;
+    FcCache	*cache;
+    off_t	size;
+    int		i;
+    FcFontSet	*cache_set;
+    intptr_t	*cache_dirs;
+    FcPattern   **cache_fonts;
 
-    if (!FcDirCacheConsume (file, set, dirs, dir, NULL))
-	goto bail1;
+    fd = FcDirCacheOpen (config, dir, &size);
+    if (fd < 0)
+	return FcFalse;
 
+    cache = FcDirCacheMap (fd, size);
+    
+    if (!cache)
+    {
+	if (FcDebug() & FC_DBG_CACHE)
+	    printf ("FcDirCacheRead failed to map cache for %s\n", dir);
+	close (fd);
+	return FcFalse;
+    }
+    
+    cache_set = FcCacheSet (cache);
+    cache_fonts = FcFontSetFonts(cache_set);
+    if (FcDebug() & FC_DBG_CACHE)
+        printf ("FcDirCacheRead mapped cache for %s (%d fonts %d subdirs)\n",
+		dir, cache_set->nfont, cache->dirs_count);
+    for (i = 0; i < cache_set->nfont; i++)
+    {
+	FcPattern   *font = FcEncodedOffsetToPtr (cache_set,
+						  cache_fonts[i],
+						  FcPattern);
+	if (FcDebug() & FC_DBG_CACHEV) {
+	    printf ("Mapped font %d\n", i);
+	    FcPatternPrint (font);
+	}
+	FcFontSetAdd (set, font);
+    }
+    
+    cache_dirs = FcCacheDirs (cache);
+    for (i = 0; i < cache->dirs_count; i++) 
+	FcStrSetAdd (dirs, FcOffsetToPtr (cache_dirs,
+					  cache_dirs[i],
+					  FcChar8));
+	 
     if (config)
 	FcConfigAddFontDir (config, (FcChar8 *)dir);
     
-    fclose (file);
+    close (fd);
     return FcTrue;
-
-bail1:
-    fclose (file);
-bail:
-    return FcFalse;
 }
     
+/*
+ * Cache file is:
+ *
+ * FcCache
+ * dir name
+ * subdirs
+ * FcFontSet
+ */
 
-static void *
-FcDirCacheProduce (FcFontSet *set, FcCache *metadata)
+static FcCache *
+FcDirCacheProduce (FcFontSet *set, const FcChar8 *dir, FcStrSet *dirs)
 {
-    void * current_dir_block, * final_dir_block;
-    static unsigned int rand_state = 0;
-    int bank, needed_bytes_no_align;
-
-#if defined (HAVE_RAND_R)
-    if (!rand_state) 
-	rand_state = time(0L);
-    bank = rand_r(&rand_state);
+    FcSerialize	*serialize = FcSerializeCreate ();
+    FcCache *cache;
+    int i;
+    intptr_t	cache_offset;
+    intptr_t	dirs_offset;
+    FcChar8	*dir_serialize;
+    intptr_t	*dirs_serialize;
+    FcFontSet	*set_serialize;
+    
+    if (!serialize)
+	return NULL;
+    /*
+     * Space for cache structure
+     */
+    cache_offset = FcSerializeReserve (serialize, sizeof (FcCache));
+    /*
+     * Directory name
+     */
+    if (!FcStrSerializeAlloc (serialize, dir))
+	goto bail1;
+    /*
+     * Subdirs
+     */
+    dirs_offset = FcSerializeAlloc (serialize, dirs, dirs->num * sizeof (FcChar8 *));
+    for (i = 0; i < dirs->num; i++)
+	if (!FcStrSerializeAlloc (serialize, dirs->strs[i]))
+	    goto bail1;
 
-    while (FcCacheHaveBank(bank))
-	bank = rand_r(&rand_state);
-#else
-    if (!rand_state)
-    {
-        rand_state = 1;
-        srand (time (0L));
-    }
-    bank = rand();
+    /*
+     * Patterns
+     */
+    if (!FcFontSetSerializeAlloc (serialize, set))
+	goto bail1;
+    
+    /* Serialize layout complete. Now allocate space and fill it */
+    cache = malloc (serialize->size);
+    if (!cache)
+	goto bail1;
+    /* shut up valgrind */
+    memset (cache, 0, serialize->size);
 
-    while (FcCacheHaveBank(bank))
-        bank = rand();
-#endif
+    serialize->linear = cache;
 
-    memset (metadata, 0, sizeof(FcCache));
-    FcFontSetNewBank();
-    needed_bytes_no_align = FcFontSetNeededBytes (set);
-    metadata->count = needed_bytes_no_align + 
-	FcFontSetNeededBytesAlign ();
-    metadata->magic = FC_CACHE_MAGIC;
-    metadata->bank = bank;
+    cache->magic = FC_CACHE_MAGIC;
+    cache->size = serialize->size;
 
-    if (!needed_bytes_no_align) /* not a failure, no fonts to write */
+    /*
+     * Serialize directory name
+     */
+    dir_serialize = FcStrSerialize (serialize, dir);
+    if (!dir_serialize)
+	goto bail2;
+    cache->dir = FcPtrToOffset (cache, dir_serialize);
+    
+    /*
+     * Serialize sub dirs
+     */
+    dirs_serialize = FcSerializePtr (serialize, dirs);
+    if (!dirs_serialize)
+	goto bail2;
+    cache->dirs = FcPtrToOffset (cache, dirs_serialize);
+    cache->dirs_count = dirs->num;
+    for (i = 0; i < dirs->num; i++) 
     {
-	/* no, you don't really need to write any bytes at all. */
-	metadata->count = 0;
-	return 0;
+	FcChar8	*d_serialize = FcStrSerialize (serialize, dirs->strs[i]);
+	if (!d_serialize)
+	    goto bail2;
+	dirs_serialize[i] = FcPtrToOffset (dirs_serialize, d_serialize);
     }
+    
+    /*
+     * Serialize font set
+     */
+    set_serialize = FcFontSetSerialize (serialize, set);
+    if (!set_serialize)
+	goto bail2;
+    cache->set = FcPtrToOffset (cache, set_serialize);
 
-    current_dir_block = malloc (metadata->count);
-    if (!current_dir_block)
-	goto bail;
-    /* shut up valgrind */
-    memset (current_dir_block, 0, metadata->count);
-    final_dir_block = FcFontSetDistributeBytes (metadata, current_dir_block);
-
-    if ((void *)((char *)current_dir_block+metadata->count) < final_dir_block)
-	goto bail;
-			      
-    if (!FcFontSetSerialize (bank, set))
-	goto bail;
-
-    return current_dir_block;
+    FcSerializeDestroy (serialize);
+    
+    return cache;
 
- bail:
-    free (current_dir_block);
-    return 0;
+bail2:
+    free (cache);
+bail1:
+    FcSerializeDestroy (serialize);
+    return NULL;
 }
 
 static FcBool
@@ -524,14 +518,12 @@ FcDirCacheWrite (FcFontSet *set, FcStrSe
 {
     FcChar8	    cache_base[CACHEBASE_LEN];
     FcChar8	    *cache_hashed;
-    int 	    fd, i;
+    int 	    fd;
     FcAtomic 	    *atomic;
-    FcCache 	    metadata;
-    void 	    *current_dir_block = 0;
+    FcCache	    *cache;
     FcStrList	    *list;
     FcChar8	    *cache_dir = NULL;
     FcChar8	    *test_dir;
-    off_t	    header_len;
 
     /*
      * Write it to the first directory in the list which is writable
@@ -563,14 +555,15 @@ FcDirCacheWrite (FcFontSet *set, FcStrSe
     FcStrListDone (list);
     if (!cache_dir)
 	return FcFalse;
+
     FcDirCacheBasename (dir, cache_base);
     cache_hashed = FcStrPlus (cache_dir, cache_base);
     if (!cache_hashed)
         return FcFalse;
 
-    current_dir_block = FcDirCacheProduce (set, &metadata);
+    cache = FcDirCacheProduce (set, dir, dirs);
 
-    if (metadata.count && !current_dir_block)
+    if (!cache)
 	goto bail1;
 
     if (FcDebug () & FC_DBG_CACHE)
@@ -579,54 +572,24 @@ FcDirCacheWrite (FcFontSet *set, FcStrSe
 
     atomic = FcAtomicCreate ((FcChar8 *)cache_hashed);
     if (!atomic)
-	goto bail1;
+	goto bail2;
 
     if (!FcAtomicLock (atomic))
-	goto bail2;
+	goto bail3;
 
     fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT | O_BINARY, 0666);
     if (fd == -1)
-	goto bail3;
-    
-    /*
-     * Compute file header length -- the FcCache followed by the subdir names
-     */
-    header_len = sizeof (FcCache);
-    header_len += strlen ((char *) dir) + 1;
-    for (i = 0; i < dirs->size; i++)
-	header_len += strlen ((char *)dirs->strs[i]) + 1;
+	goto bail4;
     
-    metadata.pos = FcCacheNextOffset (lseek (fd, 0, SEEK_CUR) + header_len);
-    metadata.subdirs = dirs->size;
-    
-    /*
-     * Write out the header
-     */
-    if (write (fd, &metadata, sizeof(FcCache)) != sizeof(FcCache)) 
+    if (write (fd, cache, cache->size) != cache->size)
     {
-	perror("write metadata");
+	perror ("write cache");
 	goto bail5;
     }
-    
-    FcCacheWriteString (fd, (char *) dir);
-    
-    for (i = 0; i < dirs->size; i++)
-        FcCacheWriteString (fd, (char *)dirs->strs[i]);
-
-    if (metadata.count)
-    {
-	if (lseek (fd, metadata.pos, SEEK_SET) != metadata.pos)
-	    perror("lseek");
-	else if (write (fd, current_dir_block, metadata.count) !=
-		 metadata.count)
-	    perror("write current_dir_block");
-	free (current_dir_block);
-        current_dir_block = 0;
-    }
 
     close(fd);
     if (!FcAtomicReplaceOrig(atomic))
-        goto bail3;
+        goto bail4;
     FcStrFree ((FcChar8 *)cache_hashed);
     FcAtomicUnlock (atomic);
     FcAtomicDestroy (atomic);
@@ -634,99 +597,17 @@ FcDirCacheWrite (FcFontSet *set, FcStrSe
 
  bail5:
     close (fd);
- bail3:
+ bail4:
     FcAtomicUnlock (atomic);
- bail2:
+ bail3:
     FcAtomicDestroy (atomic);
+ bail2:
+    free (cache);
  bail1:
     FcStrFree ((FcChar8 *)cache_hashed);
-    if (current_dir_block)
-        free (current_dir_block);
-    return FcFalse;
-}
-
-static int banks_ptr = 0, banks_alloc = 0;
-int * _fcBankId = 0, * _fcBankIdx = 0;
-static const char ** bankDirs = 0;
-
-static FcBool
-FcCacheHaveBank (int bank)
-{
-    int i;
-
-    if (bank < FC_BANK_FIRST)
-	return FcTrue;
-
-    for (i = 0; i < banks_ptr; i++)
-	if (_fcBankId[i] == bank)
-	    return FcTrue;
-
     return FcFalse;
 }
 
-int
-FcCacheBankToIndexMTF (int bank)
-{
-    int i, j;
-
-    for (i = 0; i < banks_ptr; i++)
-	if (_fcBankId[_fcBankIdx[i]] == bank)
-	{
-	    int t = _fcBankIdx[i];
-
-	    for (j = i; j > 0; j--)
-		_fcBankIdx[j] = _fcBankIdx[j-1];
-	    _fcBankIdx[0] = t;
-	    return t;
-	}
-
-    if (banks_ptr >= banks_alloc)
-    {
-	int * b, * bidx;
-	const char ** bds;
-
-	b = realloc (_fcBankId, (banks_alloc + 4) * sizeof(int));
-	if (!b)
-	    return -1;
-	_fcBankId = b;
-
-	bidx = realloc (_fcBankIdx, (banks_alloc + 4) * sizeof(int));
-	if (!bidx)
-	    return -1;
-	_fcBankIdx = bidx;
-
-	bds = realloc (bankDirs, (banks_alloc + 4) * sizeof (char *));
-	if (!bds)
-	    return -1;
-	bankDirs = bds;
-
-	banks_alloc += 4;
-    }
-
-    i = banks_ptr++;
-    _fcBankId[i] = bank;
-    _fcBankIdx[i] = i;
-    return i;
-}
-
-static void
-FcCacheAddBankDir (int bank, const char * dir)
-{
-    int bi = FcCacheBankToIndexMTF (bank);
-
-    if (bi < 0)
-	return;
-
-    bankDirs[bi] = (const char *)FcStrCopy ((FcChar8 *)dir);
-}
-
-const char *
-FcCacheFindBankDir (int bank)
-{
-    int bi = FcCacheBankToIndex (bank);
-    return bankDirs[bi];
-}
-
 /*
  * This code implements the MD5 message-digest algorithm.
  * The algorithm is due to Ron Rivest.	This code was
diff --git a/src/fccfg.c b/src/fccfg.c
index 586c656..4377ce6 100644
--- a/src/fccfg.c
+++ b/src/fccfg.c
@@ -310,11 +310,12 @@ FcConfigBuildFonts (FcConfig *config)
 	for (i = 0; i < cached_fonts->nfont; i++)
 	{
 	    FcChar8 	*cfn; 
-	    FcPatternGetString (cached_fonts->fonts[i], FC_FILE, 0, &cfn);
+	    FcPattern	*font = cached_fonts->fonts[i];
+	    FcPatternObjectGetString (font, FC_FILE_OBJECT, 0, &cfn);
 
-	    if (FcConfigAcceptFont (config, cached_fonts->fonts[i]) &&
+	    if (FcConfigAcceptFont (config, font) &&
                 (cfn && FcConfigAcceptFilename (config, cfn)))
-		FcFontSetAdd (fonts, cached_fonts->fonts[i]);
+		FcFontSetAdd (fonts, font);
 
 	    cached_fonts->fonts[i] = 0; /* prevent free in FcFontSetDestroy */
 	}
@@ -841,7 +842,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *
 	v.u.b = e->u.bval;
 	break;
     case FcOpField:
-	r = FcPatternGet (p, e->u.field, 0, &v);
+	r = FcPatternObjectGet (p, e->u.object, 0, &v);
 	if (r != FcResultMatch)
 	    v.type = FcTypeVoid;
 	v = FcValueSave (v);
@@ -1093,7 +1094,7 @@ FcConfigMatchValueList (FcPattern	*p,
 	    e = 0;
 	}
 
-	for (v = values; v; v = FcValueListPtrU(v->next))
+	for (v = values; v; v = FcValueListNext(v))
 	{
 	    /* Compare the pattern value to the match expression value */
 	    if (FcConfigCompareValue (&v->value, t->op, &value))
@@ -1129,17 +1130,17 @@ FcConfigValues (FcPattern *p, FcExpr *e,
     if (e->op == FcOpComma)
     {
 	l->value = FcConfigEvaluate (p, e->u.tree.left);
-	l->next  = FcValueListPtrCreateDynamic(FcConfigValues (p, e->u.tree.right, binding));
+	l->next = FcConfigValues (p, e->u.tree.right, binding);
     }
     else
     {
 	l->value = FcConfigEvaluate (p, e);
-	l->next  = FcValueListPtrCreateDynamic(0);
+	l->next = NULL;
     }
     l->binding = binding;
     if (l->value.type == FcTypeVoid)
     {
-	FcValueList  *next = FcValueListPtrU(l->next);
+	FcValueList  *next = FcValueListNext(l);
 
 	FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
 	free (l);
@@ -1162,27 +1163,26 @@ FcConfigAdd (FcValueListPtr *head,
 	sameBinding = position->binding;
     else
 	sameBinding = FcValueBindingWeak;
-    for (v = FcValueListPtrCreateDynamic(new); FcValueListPtrU(v); 
-	 v = FcValueListPtrU(v)->next)
-	if (FcValueListPtrU(v)->binding == FcValueBindingSame)
-	    FcValueListPtrU(v)->binding = sameBinding;
+    for (v = new; v != NULL; v = FcValueListNext(v))
+	if (v->binding == FcValueBindingSame)
+	    v->binding = sameBinding;
     if (append)
     {
 	if (position)
 	    prev = &position->next;
 	else
-	    for (prev = head; FcValueListPtrU(*prev); 
-		 prev = &(FcValueListPtrU(*prev)->next))
+	    for (prev = head; *prev != NULL; 
+		 prev = &(*prev)->next)
 		;
     }
     else
     {
 	if (position)
 	{
-	    for (prev = head; FcValueListPtrU(*prev); 
-		 prev = &(FcValueListPtrU(*prev)->next))
+	    for (prev = head; *prev != NULL; 
+		 prev = &(*prev)->next)
 	    {
-		if (FcValueListPtrU(*prev) == position)
+		if (*prev == position)
 		    break;
 	    }
 	}
@@ -1191,7 +1191,7 @@ FcConfigAdd (FcValueListPtr *head,
 
 	if (FcDebug () & FC_DBG_EDIT)
 	{
-	    if (!FcValueListPtrU(*prev))
+	    if (*prev == NULL)
 		printf ("position not on list\n");
 	}
     }
@@ -1205,12 +1205,12 @@ FcConfigAdd (FcValueListPtr *head,
     
     if (new)
     {
-	last = FcValueListPtrCreateDynamic(new);
-	while (FcValueListPtrU(FcValueListPtrU(last)->next))
-	    last = FcValueListPtrU(last)->next;
+	last = new;
+	while (last->next != NULL)
+	    last = last->next;
     
-	FcValueListPtrU(last)->next = *prev;
-	*prev = FcValueListPtrCreateDynamic(new);
+	last->next = *prev;
+	*prev = new;
     }
     
     if (FcDebug () & FC_DBG_EDIT)
@@ -1229,14 +1229,13 @@ FcConfigDel (FcValueListPtr *head,
 {
     FcValueListPtr *prev;
 
-    for (prev = head; FcValueListPtrU(*prev); 
-	 prev = &(FcValueListPtrU(*prev)->next))
+    for (prev = head; *prev != NULL; prev = &(*prev)->next)
     {
-	if (FcValueListPtrU(*prev) == position)
+	if (*prev == position)
 	{
 	    *prev = position->next;
-	    position->next = FcValueListPtrCreateDynamic(0);
-	    FcValueListDestroy (FcValueListPtrCreateDynamic(position));
+	    position->next = NULL;
+	    FcValueListDestroy (position);
 	    break;
 	}
     }
@@ -1244,13 +1243,13 @@ FcConfigDel (FcValueListPtr *head,
 
 static void
 FcConfigPatternAdd (FcPattern	*p,
-		    const char	*object,
+		    FcObject	object,
 		    FcValueList	*list,
 		    FcBool	append)
 {
     if (list)
     {
-	FcPatternElt    *e = FcPatternInsertElt (p, object);
+	FcPatternElt    *e = FcPatternObjectInsertElt (p, object);
     
 	if (!e)
 	    return;
@@ -1263,24 +1262,24 @@ FcConfigPatternAdd (FcPattern	*p,
  */
 static void
 FcConfigPatternDel (FcPattern	*p,
-		    const char	*object)
+		    FcObject	object)
 {
-    FcPatternElt    *e = FcPatternFindElt (p, object);
+    FcPatternElt    *e = FcPatternObjectFindElt (p, object);
     if (!e)
 	return;
-    while (FcValueListPtrU(e->values))
-	FcConfigDel (&e->values, FcValueListPtrU(e->values));
+    while (e->values != NULL)
+	FcConfigDel (&e->values, e->values);
 }
 
 static void
 FcConfigPatternCanon (FcPattern	    *p,
-		      const char    *object)
+		      FcObject	    object)
 {
-    FcPatternElt    *e = FcPatternFindElt (p, object);
+    FcPatternElt    *e = FcPatternObjectFindElt (p, object);
     if (!e)
 	return;
-    if (!FcValueListPtrU(e->values))
-	FcPatternDel (p, object);
+    if (e->values == NULL)
+	FcPatternObjectDel (p, object);
 }
 
 FcBool
@@ -1337,7 +1336,7 @@ FcConfigSubstituteWithPat (FcConfig    *
 	    else
 		m = p;
 	    if (m)
-		st[i].elt = FcPatternFindElt (m, t->field);
+		st[i].elt = FcPatternObjectFindElt (m, t->object);
 	    else
 		st[i].elt = 0;
 	    /*
@@ -1358,12 +1357,12 @@ FcConfigSubstituteWithPat (FcConfig    *
 	     * Check to see if there is a match, mark the location
 	     * to apply match-relative edits
 	     */
-	    st[i].value = FcConfigMatchValueList (m, t, FcValueListPtrU(st[i].elt->values));
+	    st[i].value = FcConfigMatchValueList (m, t, st[i].elt->values);
 	    if (!st[i].value)
 		break;
-	    if (t->qual == FcQualFirst && st[i].value != FcValueListPtrU(st[i].elt->values))
+	    if (t->qual == FcQualFirst && st[i].value != st[i].elt->values)
 		break;
-	    if (t->qual == FcQualNotFirst && st[i].value == FcValueListPtrU(st[i].elt->values))
+	    if (t->qual == FcQualNotFirst && st[i].value == st[i].elt->values)
 		break;
 	}
 	if (t)
@@ -1391,8 +1390,7 @@ FcConfigSubstituteWithPat (FcConfig    *
 	    for (t = s->test, i = 0; t; t = t->next, i++)
 	    {
 		if ((t->kind == FcMatchFont || kind == FcMatchPattern) &&
-		    !FcStrCmpIgnoreCase ((FcChar8 *) t->field, 
-					 (FcChar8 *) e->field))
+		    t->object == e->object)
 		{
 		    /* 
 		     * KLUDGE - the pattern may have been reallocated or
@@ -1401,7 +1399,7 @@ FcConfigSubstituteWithPat (FcConfig    *
 		     * the element again
 		     */
 		    if (e != s->edit && st[i].elt)
-			st[i].elt = FcPatternFindElt (p, t->field);
+			st[i].elt = FcPatternObjectFindElt (p, t->object);
 		    if (!st[i].elt)
 			t = 0;
 		    break;
@@ -1416,7 +1414,7 @@ FcConfigSubstituteWithPat (FcConfig    *
 		if (t)
 		{
 		    FcValueList	*thisValue = st[i].value;
-		    FcValueList	*nextValue = thisValue ? FcValueListPtrU(thisValue->next) : 0;
+		    FcValueList	*nextValue = thisValue;
 		    
 		    /*
 		     * Append the new list of values after the current value
@@ -1444,8 +1442,8 @@ FcConfigSubstituteWithPat (FcConfig    *
 		 * Delete all of the values and insert
 		 * the new set
 		 */
-		FcConfigPatternDel (p, e->field);
-		FcConfigPatternAdd (p, e->field, l, FcTrue);
+		FcConfigPatternDel (p, e->object);
+		FcConfigPatternAdd (p, e->object, l, FcTrue);
 		/*
 		 * Adjust any pointers into the value list as they no
 		 * longer point to anything valid
@@ -1468,7 +1466,7 @@ FcConfigSubstituteWithPat (FcConfig    *
 		}
 		/* fall through ... */
 	    case FcOpPrependFirst:
-		FcConfigPatternAdd (p, e->field, l, FcFalse);
+		FcConfigPatternAdd (p, e->object, l, FcFalse);
 		break;
 	    case FcOpAppend:
 		if (t)
@@ -1478,10 +1476,10 @@ FcConfigSubstituteWithPat (FcConfig    *
 		}
 		/* fall through ... */
 	    case FcOpAppendLast:
-		FcConfigPatternAdd (p, e->field, l, FcTrue);
+		FcConfigPatternAdd (p, e->object, l, FcTrue);
 		break;
 	    default:
-                FcValueListDestroy (FcValueListPtrCreateDynamic(l));
+                FcValueListDestroy (l);
 		break;
 	    }
 	}
@@ -1490,7 +1488,7 @@ FcConfigSubstituteWithPat (FcConfig    *
 	 * any properties without data
 	 */
 	for (e = s->edit; e; e = e->next)
-	    FcConfigPatternCanon (p, e->field);
+	    FcConfigPatternCanon (p, e->object);
 
 	if (FcDebug () & FC_DBG_EDIT)
 	{
diff --git a/src/fccharset.c b/src/fccharset.c
index e0a0961..d55c611 100644
--- a/src/fccharset.c
+++ b/src/fccharset.c
@@ -29,33 +29,6 @@
 
 /* #define CHATTY */
 
-static FcCharSet ** charsets = 0;
-static FcChar16 ** numbers = 0;
-static int charset_bank_count = 0, charset_ptr, charset_count;
-static int charset_numbers_ptr, charset_numbers_count;
-static FcCharLeaf ** leaves = 0;
-static int charset_leaf_ptr, charset_leaf_count;
-static int ** leaf_idx = 0;
-static int charset_leaf_idx_ptr, charset_leaf_idx_count;
-
-extern const FcChar16 langBankNumbers[];
-extern const FcCharLeaf	langBankLeaves[];
-extern const int langBankLeafIdx[];
-
-static FcBool
-FcCharSetEnsureBank (int bi);
-
-void
-FcLangCharSetPopulate (void)
-{
-    int bi = FcCacheBankToIndexMTF (FC_BANK_LANGS);
-    FcCharSetEnsureBank (bi);
-    charsets[bi] = 0;
-    numbers[bi] = (FcChar16 *)langBankNumbers;
-    leaves[bi] = (FcCharLeaf *)langBankLeaves;
-    leaf_idx[bi] = (int *)langBankLeafIdx;
-}
-
 FcCharSet *
 FcCharSetCreate (void)
 {
@@ -67,9 +40,8 @@ FcCharSetCreate (void)
     FcMemAlloc (FC_MEM_CHARSET, sizeof (FcCharSet));
     fcs->ref = 1;
     fcs->num = 0;
-    fcs->bank = FC_BANK_DYNAMIC;
-    fcs->u.dyn.leaves = 0;
-    fcs->u.dyn.numbers = 0;
+    fcs->leaves_offset = FcPtrToOffset (fcs, NULL);
+    fcs->numbers_offset = FcPtrToOffset (fcs, NULL);
     return fcs;
 }
 
@@ -86,27 +58,25 @@ void
 FcCharSetDestroy (FcCharSet *fcs)
 {
     int i;
+    
     if (fcs->ref == FC_REF_CONSTANT)
 	return;
     if (--fcs->ref > 0)
 	return;
-    if (fcs->bank == FC_BANK_DYNAMIC)
+    for (i = 0; i < fcs->num; i++)
     {
-	for (i = 0; i < fcs->num; i++)
-	{
-	    FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
-	    free (fcs->u.dyn.leaves[i]);
-	}
-	if (fcs->u.dyn.leaves)
-	{
-	    FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *));
-	    free (fcs->u.dyn.leaves);
-	}
-	if (fcs->u.dyn.numbers)
-	{
-	    FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
-	    free (fcs->u.dyn.numbers);
-	}
+	FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
+	free (FcCharSetLeaf (fcs, i));
+    }
+    if (FcCharSetLeaves (fcs))
+    {
+	FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t));
+	free (FcCharSetLeaves (fcs));
+    }
+    if (FcCharSetNumbers (fcs))
+    {
+	FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
+	free (FcCharSetNumbers (fcs));
     }
     FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
     free (fcs);
@@ -121,7 +91,7 @@ FcCharSetDestroy (FcCharSet *fcs)
 static int
 FcCharSetFindLeafPos (const FcCharSet *fcs, FcChar32 ucs4)
 {
-    FcChar16		*numbers = FcCharSetGetNumbers(fcs);
+    FcChar16		*numbers = FcCharSetNumbers(fcs);
     FcChar16		page;
     int			low = 0;
     int			high = fcs->num - 1;
@@ -150,7 +120,7 @@ FcCharSetFindLeaf (const FcCharSet *fcs,
 {
     int	pos = FcCharSetFindLeafPos (fcs, ucs4);
     if (pos >= 0)
-	return FcCharSetGetLeaf(fcs, pos);
+	return FcCharSetLeaf(fcs, pos);
     return 0;
 }
 
@@ -160,68 +130,55 @@ FcCharSetPutLeaf (FcCharSet	*fcs, 
 		  FcCharLeaf	*leaf, 
 		  int		pos)
 {
-    FcCharLeaf	**leaves;
-    FcChar16	*numbers;
+    intptr_t	*leaves = FcCharSetLeaves (fcs);
+    FcChar16	*numbers = FcCharSetNumbers (fcs);
 
     ucs4 >>= 8;
     if (ucs4 >= 0x10000)
 	return FcFalse;
-    if (fcs->bank != FC_BANK_DYNAMIC)
+    if (!leaves)
+	leaves = malloc (sizeof (*leaves));
+    else
     {
-        /* convert to dynamic */
-	int i;
-
-	leaves = malloc ((fcs->num + 1) * sizeof (FcCharLeaf *));
-	if (!leaves)
-	    return FcFalse;
-	FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcCharLeaf *));
-	numbers = malloc ((fcs->num + 1) * sizeof (FcChar16));
-	if (!numbers)
-        {
-	    free (leaves);
-	    return FcFalse;
-        }
-	FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
-
-	for (i = 0; i < fcs->num; i++)
-	    leaves[i] = FcCharSetGetLeaf(fcs, i);
-	memcpy (numbers, FcCharSetGetNumbers(fcs), 
-		fcs->num * sizeof (FcChar16));
+	intptr_t    *new_leaves = realloc (leaves, (fcs->num + 1) * 
+					   sizeof (*leaves));
+	intptr_t    distance = (intptr_t) new_leaves - (intptr_t) leaves;
+	
+	if (new_leaves && distance)
+	{
+	    int i;
 
-	fcs->bank = FC_BANK_DYNAMIC;
-	fcs->u.dyn.leaves = leaves;
-	fcs->u.dyn.numbers = numbers;
+	    for (i = 0; i < fcs->num; i++)
+		new_leaves[i] -= distance;
+	}
+	leaves = new_leaves;
     }
+    if (!leaves)
+	return FcFalse;
+    
+    if (fcs->num)
+	FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t));
+    FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (intptr_t));
+    fcs->leaves_offset = FcPtrToOffset (fcs, leaves);
+    
+    if (!numbers)
+	numbers = malloc (sizeof (FcChar16));
     else
-    {
-	if (!fcs->u.dyn.leaves)
-	    leaves = malloc (sizeof (FcCharLeaf *));
-	else
-	    leaves = realloc (fcs->u.dyn.leaves, (fcs->num + 1) * sizeof (FcCharLeaf *));
-	if (!leaves)
-	    return FcFalse;
-	if (fcs->num)
-	    FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *));
-	FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcCharLeaf *));
-	fcs->u.dyn.leaves = leaves;
-	if (!fcs->u.dyn.numbers)
-	    numbers = malloc (sizeof (FcChar16));
-	else
-	    numbers = realloc (fcs->u.dyn.numbers, (fcs->num + 1) * sizeof (FcChar16));
-	if (!numbers)
-	    return FcFalse;
-	if (fcs->num)
-	    FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
-	FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
-	fcs->u.dyn.numbers = numbers;
-    }
+	numbers = realloc (numbers, (fcs->num + 1) * sizeof (FcChar16));
+    if (!numbers)
+	return FcFalse;
+    
+    if (fcs->num)
+	FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
+    FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
+    fcs->numbers_offset = FcPtrToOffset (fcs, numbers);
     
-    memmove (fcs->u.dyn.leaves + pos + 1, fcs->u.dyn.leaves + pos, 
-	     (fcs->num - pos) * sizeof (FcCharLeaf *));
-    memmove (fcs->u.dyn.numbers + pos + 1, fcs->u.dyn.numbers + pos,
-	     (fcs->num - pos) * sizeof (FcChar16));
-    fcs->u.dyn.numbers[pos] = (FcChar16) ucs4;
-    fcs->u.dyn.leaves[pos] = leaf;
+    memmove (leaves + pos + 1, leaves + pos, 
+	     (fcs->num - pos) * sizeof (*leaves));
+    memmove (numbers + pos + 1, numbers + pos,
+	     (fcs->num - pos) * sizeof (*numbers));
+    numbers[pos] = (FcChar16) ucs4;
+    leaves[pos] = FcPtrToOffset (leaves, leaf);
     fcs->num++;
     return FcTrue;
 }
@@ -239,7 +196,7 @@ FcCharSetFindLeafCreate (FcCharSet *fcs,
 
     pos = FcCharSetFindLeafPos (fcs, ucs4);
     if (pos >= 0)
-	return FcCharSetGetLeaf(fcs, pos);
+	return FcCharSetLeaf(fcs, pos);
     
     leaf = calloc (1, sizeof (FcCharLeaf));
     if (!leaf)
@@ -264,16 +221,9 @@ FcCharSetInsertLeaf (FcCharSet *fcs, FcC
     if (pos >= 0)
     {
 	FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
-	if (fcs->bank == FC_BANK_DYNAMIC)
-	{
-	    free (fcs->u.dyn.leaves[pos]);
-	    fcs->u.dyn.leaves[pos] = leaf;
-	}
-	else
-	{
-	    int bi = FcCacheBankToIndex(fcs->bank);
-	    leaves[bi][leaf_idx[fcs->bank][fcs->u.stat.leafidx_offset]+pos] = *leaf;
-	}
+	free (FcCharSetLeaf (fcs, pos));
+	FcCharSetLeaves(fcs)[pos] = FcPtrToOffset (FcCharSetLeaves(fcs),
+						   leaf);
 	return FcTrue;
     }
     pos = -pos - 1;
@@ -324,9 +274,9 @@ FcCharSetIterSet (const FcCharSet *fcs, 
 	    iter->leaf = 0;
 	    return;
 	}
-        iter->ucs4 = (FcChar32) FcCharSetGetNumbers(fcs)[pos] << 8;
+        iter->ucs4 = (FcChar32) FcCharSetNumbers(fcs)[pos] << 8;
     }
-    iter->leaf = FcCharSetGetLeaf(fcs, pos);
+    iter->leaf = FcCharSetLeaf(fcs, pos);
     iter->pos = pos;
 #ifdef CHATTY
     printf ("set %08x: %08x\n", iter->ucs4, (FcChar32) iter->leaf);
@@ -344,8 +294,8 @@ FcCharSetIterNext (const FcCharSet *fcs,
     }
     else
     {
-	iter->ucs4 = (FcChar32) FcCharSetGetNumbers(fcs)[pos] << 8;
-	iter->leaf = FcCharSetGetLeaf(fcs, pos);
+	iter->ucs4 = (FcChar32) FcCharSetNumbers(fcs)[pos] << 8;
+	iter->leaf = FcCharSetLeaf(fcs, pos);
 	iter->pos = pos;
     }
 }
@@ -662,15 +612,15 @@ FcCharSetIsSubset (const FcCharSet *a, c
     ai = 0;
     while (ai < a->num && bi < b->num)
     {
-	an = FcCharSetGetNumbers(a)[ai];
-	bn = FcCharSetGetNumbers(b)[bi];
+	an = FcCharSetNumbers(a)[ai];
+	bn = FcCharSetNumbers(b)[bi];
 	/*
 	 * Check matching pages
 	 */
 	if (an == bn)
 	{
-	    FcChar32	*am = FcCharSetGetLeaf(a, ai)->map;
-	    FcChar32	*bm = FcCharSetGetLeaf(b, bi)->map;
+	    FcChar32	*am = FcCharSetLeaf(a, ai)->map;
+	    FcChar32	*bm = FcCharSetLeaf(b, bi)->map;
 	    
 	    if (am != bm)
 	    {
@@ -701,7 +651,7 @@ FcCharSetIsSubset (const FcCharSet *a, c
 	    while (low <= high)
 	    {
 		int mid = (low + high) >> 1;
-		bn = FcCharSetGetNumbers(b)[mid];
+		bn = FcCharSetNumbers(b)[mid];
 		if (bn == an)
 		{
 		    high = mid;
@@ -713,7 +663,7 @@ FcCharSetIsSubset (const FcCharSet *a, c
 		    high = mid - 1;
 	    }
 	    bi = high;
-	    while (bi < b->num && FcCharSetGetNumbers(b)[bi] < an)
+	    while (bi < b->num && FcCharSetNumbers(b)[bi] < an)
 		bi++;
 	}
     }
@@ -1021,10 +971,10 @@ FcCharSetHash (FcCharSet *fcs)
 
     /* hash in leaves */
     for (i = 0; i < fcs->num * (int) (sizeof (FcCharLeaf *) / sizeof (FcChar32)); i++)
-	hash = ((hash << 1) | (hash >> 31)) ^ (FcChar32)(FcCharSetGetLeaf(fcs, i)->map);
+	hash = ((hash << 1) | (hash >> 31)) ^ (FcChar32)(FcCharSetLeaf(fcs, i)->map);
     /* hash in numbers */
     for (i = 0; i < fcs->num; i++)
-	hash = ((hash << 1) | (hash >> 31)) ^ *FcCharSetGetNumbers(fcs);
+	hash = ((hash << 1) | (hash >> 31)) ^ *FcCharSetNumbers(fcs);
     return hash;
 }
 
@@ -1041,6 +991,7 @@ FcCharSetFreezeBase (FcCharSet *fcs)
     FcCharSetEnt	**bucket = &FcCharSetHashTable[hash % FC_CHAR_SET_HASH_SIZE];
     FcCharSetEnt	*ent;
     int			size;
+    int			i;
 
     FcCharSetTotal++;
     FcCharSetTotalEnts += fcs->num;
@@ -1048,15 +999,15 @@ FcCharSetFreezeBase (FcCharSet *fcs)
     {
 	if (ent->hash == hash &&
 	    ent->set.num == fcs->num &&
-	    !memcmp (FcCharSetGetNumbers(&ent->set), 
-		     FcCharSetGetNumbers(fcs),
+	    !memcmp (FcCharSetNumbers(&ent->set), 
+		     FcCharSetNumbers(fcs),
 		     fcs->num * sizeof (FcChar16)))
 	{
 	    FcBool ok = FcTrue;
 	    int i;
 
 	    for (i = 0; i < fcs->num; i++)
-		if (FcCharSetGetLeaf(&ent->set, i) != FcCharSetGetLeaf(fcs, i))
+		if (FcCharSetLeaf(&ent->set, i) != FcCharSetLeaf(fcs, i))
 		    ok = FcFalse;
 	    if (ok)
 		return &ent->set;
@@ -1075,26 +1026,26 @@ FcCharSetFreezeBase (FcCharSet *fcs)
     
     ent->set.ref = FC_REF_CONSTANT;
     ent->set.num = fcs->num;
-    ent->set.bank = fcs->bank;
-    if (fcs->bank == FC_BANK_DYNAMIC)
+    if (fcs->num)
     {
-	if (fcs->num)
-	{
-	    ent->set.u.dyn.leaves = (FcCharLeaf **) (ent + 1);
-	    ent->set.u.dyn.numbers = (FcChar16 *) (ent->set.u.dyn.leaves + fcs->num);
-	    memcpy (ent->set.u.dyn.leaves, fcs->u.dyn.leaves, fcs->num * sizeof (FcCharLeaf *));
-	    memcpy (ent->set.u.dyn.numbers, fcs->u.dyn.numbers, fcs->num * sizeof (FcChar16));
-	}
-	else
-	{
-	    ent->set.u.dyn.leaves = 0;
-	    ent->set.u.dyn.numbers = 0;
-	}
+	intptr_t    *ent_leaves;
+
+	ent->set.leaves_offset = sizeof (ent->set);
+	ent->set.numbers_offset = (ent->set.leaves_offset +
+				   fcs->num * sizeof (intptr_t));
+    
+	ent_leaves = FcCharSetLeaves (&ent->set);
+	for (i = 0; i < fcs->num; i++)
+	    ent_leaves[i] = FcPtrToOffset (ent_leaves,
+					   FcCharSetLeaf (fcs, i));
+	memcpy (FcCharSetNumbers (&ent->set), 
+		FcCharSetNumbers (fcs), 
+		fcs->num * sizeof (FcChar16));
     }
     else
     {
-	ent->set.u.stat.leafidx_offset = fcs->u.stat.leafidx_offset;
-	ent->set.u.stat.numbers_offset = fcs->u.stat.numbers_offset;
+	ent->set.leaves_offset = 0;
+	ent->set.numbers_offset = 0;
     }
 
     ent->hash = hash;
@@ -1140,26 +1091,23 @@ FcCharSetFreeze (FcCharSet *fcs)
 	goto bail0;
     for (i = 0; i < fcs->num; i++)
     {
-	l = FcCharSetFreezeLeaf (FcCharSetGetLeaf(fcs, i));
+	l = FcCharSetFreezeLeaf (FcCharSetLeaf(fcs, i));
 	if (!l)
 	    goto bail1;
-	if (!FcCharSetInsertLeaf (b, FcCharSetGetNumbers(fcs)[i] << 8, l))
+	if (!FcCharSetInsertLeaf (b, FcCharSetNumbers(fcs)[i] << 8, l))
 	    goto bail1;
     }
     n = FcCharSetFreezeBase (b);
 bail1:
-    if (b->bank == FC_BANK_DYNAMIC)
+    if (FcCharSetLeaves (b))
     {
-	if (b->u.dyn.leaves)
-	{
-	    FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcCharLeaf *));
-	    free (b->u.dyn.leaves);
-	}
-	if (b->u.dyn.numbers)
-	{
-	    FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcChar16));
-	    free (b->u.dyn.numbers);
-	}
+	FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcCharLeaf *));
+	free (FcCharSetLeaves (b));
+    }
+    if (FcCharSetNumbers (b))
+    {
+	FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcChar16));
+	free (FcCharSetNumbers (b));
     }
     FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
     free (b);
@@ -1225,20 +1173,17 @@ FcNameParseCharSet (FcChar8 *string)
 #endif
     n = FcCharSetFreezeBase (c);
 bail1:
-    if (c->bank == FC_BANK_DYNAMIC)
+    if (FcCharSetLeaves (c))
     {
-	if (c->u.dyn.leaves)
-	{
-	    FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcCharLeaf *));
-	    free (c->u.dyn.leaves);
-	}
-	if (c->u.dyn.numbers)
-	{
-	    FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcChar16));
-	    free (c->u.dyn.numbers);
-	}
-	FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
+	FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcCharLeaf *));
+	free (FcCharSetLeaves (c));
+    }
+    if (FcCharSetNumbers (c))
+    {
+	FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcChar16));
+	free (FcCharSetNumbers (c));
     }
+    FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
     free (c);
 bail0:
     return n;
@@ -1317,175 +1262,67 @@ FcNameUnparseCharSet (FcStrBuf *buf, con
     return FcTrue;
 }
 
-void
-FcCharSetNewBank(void)
-{
-    charset_count = 0;
-    charset_numbers_count = 0;
-    charset_leaf_count = 0;
-    charset_leaf_idx_count = 0;
-}
-
-int
-FcCharSetNeededBytes (const FcCharSet *c)
-{
-    /* yes, there's redundancy */
-    charset_count++;
-    charset_leaf_idx_count += c->num;
-    charset_leaf_count += c->num;
-    charset_numbers_count += c->num;
-    return sizeof (FcCharSet) + 
-	sizeof (int) * c->num + 	/* leaf_idx */
-	sizeof (FcCharLeaf) * c->num + 	/* leaf */
-	sizeof (FcChar16) * c->num; 	/* number */
-}
-
-int
-FcCharSetNeededBytesAlign (void)
-{
-    return fc_alignof (FcCharSet) + fc_alignof (int) + 
-	fc_alignof (FcCharLeaf) + fc_alignof (FcChar16);
-}
-
-static FcBool
-FcCharSetEnsureBank (int bi)
+FcBool
+FcCharSetSerializeAlloc (FcSerialize *serialize, const FcCharSet *cs)
 {
-    if (!charsets || charset_bank_count <= bi)
-    {
-	int new_count = charset_bank_count + 2;
-	FcCharSet ** cs;
-	FcChar16 ** n;
-	FcCharLeaf ** lvs;
-	int ** lvi;
-	int i;
-	
-	cs = realloc(charsets, sizeof(FcCharSet*) * new_count);
-	if (!cs) return 0;
-	n = realloc(numbers, sizeof(FcChar16*) * new_count);
-	if (!n) return 0;
-	lvs = realloc(leaves, sizeof(FcCharLeaf*) * new_count);
-	if (!lvs) return 0;
-	lvi = realloc(leaf_idx, sizeof(int*) * new_count);
-	if (!lvi) return 0;
-
-	charsets = cs; numbers = n; leaves = lvs; leaf_idx = lvi;
-	for (i = charset_bank_count; i < new_count; i++)
-	{
-	    charsets[i] = 0;
-	    numbers[i] = 0;
-	    leaves[i] = 0;
-	    leaf_idx[i] = 0;
-	}
-	charset_bank_count = new_count;
-    }
+    intptr_t	    *leaves = FcCharSetLeaves (cs);
+    FcChar16	    *numbers = FcCharSetNumbers (cs);
+    int		    i;
+    
+    if (!FcSerializeAlloc (serialize, cs, sizeof (FcCharSet)))
+	return FcFalse;
+    if (!FcSerializeAlloc (serialize, leaves, cs->num * sizeof (intptr_t)))
+	return FcFalse;
+    if (!FcSerializeAlloc (serialize, numbers, cs->num * sizeof (FcChar16)))
+	return FcFalse;
+    for (i = 0; i < cs->num; i++)
+	if (!FcSerializeAlloc (serialize, FcCharSetLeaf(cs, i),
+			       sizeof (FcCharLeaf)))
+	    return FcFalse;
     return FcTrue;
 }
-
-void *
-FcCharSetDistributeBytes (FcCache * metadata, void * block_ptr)
+    
+FcCharSet *
+FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs)
 {
-    int bi = FcCacheBankToIndex(metadata->bank);
-    if (!FcCharSetEnsureBank(bi))
-	return 0;
+    FcCharSet	*cs_serialized = FcSerializePtr (serialize, cs);
+    intptr_t	*leaves, *leaves_serialized;
+    FcChar16	*numbers, *numbers_serialized;
+    FcCharLeaf	*leaf, *leaf_serialized;
+    int		i;
 
-    block_ptr = ALIGN (block_ptr, FcCharSet);
-    charsets[bi] = (FcCharSet *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr + 
-		     (sizeof (FcCharSet) * charset_count));
-    block_ptr = ALIGN (block_ptr, FcChar16);
-    numbers[bi] = (FcChar16 *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr + 
-		     (sizeof(FcChar16) * charset_numbers_count));
-    block_ptr = ALIGN (block_ptr, FcCharLeaf);
-    leaves[bi] = (FcCharLeaf *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr +
-		     (sizeof(FcCharLeaf) * charset_leaf_count));
-    block_ptr = ALIGN (block_ptr, int);
-    leaf_idx[bi] = (int *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr +
-		     (sizeof(int) * charset_leaf_idx_count));
-
-    metadata->charset_count = charset_count;
-    metadata->charset_numbers_count = charset_numbers_count;
-    metadata->charset_leaf_count = charset_leaf_count;
-    metadata->charset_leaf_idx_count = charset_leaf_idx_count;
-    charset_ptr = 0; charset_leaf_ptr = 0;
-    charset_leaf_idx_ptr = 0; charset_numbers_ptr = 0;
-    return block_ptr;
-}
+    if (!cs_serialized)
+	return NULL;
+    
+    cs_serialized->ref = FC_REF_CONSTANT;
+    cs_serialized->num = cs->num;
 
-FcCharSet *
-FcCharSetSerialize(int bank, FcCharSet *c)
-{
-    int i;
-    FcCharSet new;
-    int bi = FcCacheBankToIndex(bank), cp = charset_ptr;
+    leaves = FcCharSetLeaves (cs);
+    leaves_serialized = FcSerializePtr (serialize, leaves);
+    if (!leaves_serialized)
+	return NULL;
 
-    new.ref = FC_REF_CONSTANT;
-    new.bank = bank;
-    new.u.stat.leafidx_offset = charset_leaf_idx_ptr;
-    new.u.stat.numbers_offset = charset_numbers_ptr;
-    new.num = c->num;
+    cs_serialized->leaves_offset = FcPtrToOffset (cs_serialized,
+						  leaves_serialized);
+    
+    numbers = FcCharSetNumbers (cs);
+    numbers_serialized = FcSerializePtr (serialize, numbers);
+    if (!numbers)
+	return NULL;
 
-    charsets[bi][charset_ptr++] = new;
+    cs_serialized->numbers_offset = FcPtrToOffset (cs_serialized,
+						   numbers_serialized);
 
-    for (i = 0; i < c->num; i++)
+    for (i = 0; i < cs->num; i++)
     {
-	leaf_idx[bi][charset_leaf_idx_ptr++] = charset_leaf_ptr;
-	memcpy (&leaves[bi][charset_leaf_ptr++], 
-		c->u.dyn.leaves[i], sizeof(FcCharLeaf));
-	numbers[bi][charset_numbers_ptr++] = c->u.dyn.numbers[i];
+	leaf = FcCharSetLeaf (cs, i);
+	leaf_serialized = FcSerializePtr (serialize, leaf);
+	if (!leaf_serialized)
+	    return NULL;
+	*leaf_serialized = *leaf;
+	leaves_serialized[i] = FcPtrToOffset (leaves_serialized, leaf);
+	numbers_serialized[i] = numbers[i];
     }
-
-    return &charsets[bi][cp];
-}
-
-void *
-FcCharSetUnserialize (FcCache *metadata, void *block_ptr)
-{
-    int bi = FcCacheBankToIndex(metadata->bank);
-    if (!FcCharSetEnsureBank(bi))
-	return 0;
-
-    block_ptr = ALIGN (block_ptr, FcCharSet);
-    charsets[bi] = (FcCharSet *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr + 
-		     (sizeof (FcCharSet) * metadata->charset_count));
-    block_ptr = ALIGN (block_ptr, FcChar16);
-    numbers[bi] = (FcChar16 *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr + 
-		     (sizeof(FcChar16) * metadata->charset_numbers_count));
-    block_ptr = ALIGN (block_ptr, FcCharLeaf);
-    leaves[bi] = (FcCharLeaf *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr +
-		     (sizeof(FcCharLeaf) * metadata->charset_leaf_count));
-    block_ptr = ALIGN (block_ptr, int);
-    leaf_idx[bi] = (int *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr +
-		     (sizeof(int) * metadata->charset_leaf_idx_count));
-
-    return block_ptr;
-}
-
-FcCharLeaf *
-FcCharSetGetLeaf(const FcCharSet *c, int i)
-{
-    int bi;
-    if (c->bank == FC_BANK_DYNAMIC)
-	return c->u.dyn.leaves[i];
-    bi = FcCacheBankToIndex(c->bank);
-
-    return &leaves[bi][leaf_idx[bi][c->u.stat.leafidx_offset+i]];
-}
-
-FcChar16 *
-FcCharSetGetNumbers(const FcCharSet *c)
-{
-    int bi;
-    if (c->bank == FC_BANK_DYNAMIC)
-	return c->u.dyn.numbers;
-    bi = FcCacheBankToIndex(c->bank);
-
-    return &numbers[bi][c->u.stat.numbers_offset];
+    
+    return cs_serialized;
 }
-
diff --git a/src/fcdbg.c b/src/fcdbg.c
index 9b7e8f7..16b6bfd 100644
--- a/src/fcdbg.c
+++ b/src/fcdbg.c
@@ -49,7 +49,8 @@ FcValuePrint (const FcValue v)
 	printf (" (%f %f; %f %f)", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
 	break;
     case FcTypeCharSet:	/* XXX */
-	printf (" set");
+	printf (" ");
+	FcCharSetPrint (v.u.c);
 	break;
     case FcTypeLangSet:
 	printf (" ");
@@ -64,10 +65,10 @@ FcValuePrint (const FcValue v)
 void
 FcValueListPrint (FcValueListPtr l)
 {
-    for (; FcValueListPtrU(l); l = FcValueListPtrU(l)->next)
+    for (; l != NULL; l = FcValueListNext(l))
     {
-	FcValuePrint (FcValueCanonicalize(&FcValueListPtrU(l)->value));
-	switch (FcValueListPtrU(l)->binding) {
+	FcValuePrint (FcValueCanonicalize(&l->value));
+	switch (l->binding) {
 	case FcValueBindingWeak:
 	    printf ("(w)");
 	    break;
@@ -96,6 +97,22 @@ FcLangSetPrint (const FcLangSet *ls)
 }
 
 void
+FcCharSetPrint (const FcCharSet *c)
+{
+    int	i, j;
+
+    for (i = 0; i < c->num; i++)
+    {
+	FcCharLeaf	*leaf = FcCharSetLeaf(c, i);
+	
+	printf ("%04x:", FcCharSetNumbers(c)[i]);
+	for (j = 0; j < 256/32; j++)
+	    printf (" %08x", leaf->map[j]);
+	printf ("\n");
+    }
+}
+
+void
 FcPatternPrint (const FcPattern *p)
 {
     int		    i;
@@ -109,15 +126,15 @@ FcPatternPrint (const FcPattern *p)
     printf ("Pattern has %d elts (size %d)\n", p->num, p->size);
     for (i = 0; i < p->num; i++)
     {
-	e = FcPatternEltU(p->elts) + i;
-	printf ("\t%s:", FcObjectPtrU(e->object));
+	e = &FcPatternElts(p)[i];
+	printf ("\t%s:", FcObjectName(e->object));
 	/* so that fc-match properly displays file: foo... */
-	if (e->object == FcObjectToPtr(FC_FILE))
+	if (e->object == FC_FILE_OBJECT)
 	{
 	    FcChar8 * s;
-	    FcPatternGetString (p, FC_FILE, 0, &s);
+	    FcPatternObjectGetString (p, FC_FILE_OBJECT, 0, &s);
 	    printf (" \"%s\"", s);
-	    switch (FcValueListPtrU(e->values)->binding) {
+	    switch (FcPatternEltValues(e)->binding) {
 	    case FcValueBindingWeak:
 	        printf ("(w)");
 	        break;
@@ -130,7 +147,7 @@ FcPatternPrint (const FcPattern *p)
 	    }
 	}
 	else
-	    FcValueListPrint (e->values);
+	    FcValueListPrint (FcPatternEltValues(e));
 	printf ("\n");
     }
     printf ("\n");
@@ -197,7 +214,7 @@ FcExprPrint (const FcExpr *expr)
     case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
     case FcOpCharSet: printf ("charset\n"); break;
     case FcOpNil: printf ("nil\n"); break;
-    case FcOpField: printf ("%s", expr->u.field); break;
+    case FcOpField: printf ("%s", FcObjectName(expr->u.object)); break;
     case FcOpConst: printf ("%s", expr->u.constant); break;
     case FcOpQuest:
 	FcExprPrint (expr->u.tree.left);
@@ -307,7 +324,7 @@ FcTestPrint (const FcTest *test)
 	printf ("not_first ");
 	break;
     }
-    printf ("%s ", test->field);
+    printf ("%s ", FcObjectName (test->object));
     FcOpPrint (test->op);
     printf (" ");
     FcExprPrint (test->expr);
@@ -317,7 +334,7 @@ FcTestPrint (const FcTest *test)
 void
 FcEditPrint (const FcEdit *edit)
 {
-    printf ("Edit %s ", edit->field);
+    printf ("Edit %s ", FcObjectName (edit->object));
     FcOpPrint (edit->op);
     printf (" ");
     FcExprPrint (edit->expr);
diff --git a/src/fcdefault.c b/src/fcdefault.c
index 4fd3ed8..b582310 100644
--- a/src/fcdefault.c
+++ b/src/fcdefault.c
@@ -26,14 +26,14 @@
 #include <locale.h>
 
 static const struct {
-    const char	*field;
+    FcObject	field;
     FcBool	value;
 } FcBoolDefaults[] = {
-    { FC_HINTING,	    FcTrue	},  /* !FT_LOAD_NO_HINTING */
-    { FC_VERTICAL_LAYOUT,   FcFalse	},  /* FC_LOAD_VERTICAL_LAYOUT */
-    { FC_AUTOHINT,	    FcFalse	},  /* FC_LOAD_FORCE_AUTOHINT */
-    { FC_GLOBAL_ADVANCE,    FcTrue	},  /* !FC_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */
-    { FC_EMBEDDED_BITMAP,   FcTrue 	},  /* !FC_LOAD_NO_BITMAP */
+    { 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 */
+    { FC_GLOBAL_ADVANCE_OBJECT,    FcTrue	},  /* !FC_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */
+    { FC_EMBEDDED_BITMAP_OBJECT,   FcTrue 	},  /* !FC_LOAD_NO_BITMAP */
 };
 
 #define NUM_FC_BOOL_DEFAULTS	(int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0])
@@ -105,63 +105,63 @@ FcDefaultSubstitute (FcPattern *pattern)
     FcValue v;
     int	    i;
 
-    if (FcPatternGet (pattern, FC_STYLE, 0, &v) == FcResultNoMatch)
+    if (FcPatternObjectGet (pattern, FC_STYLE_OBJECT, 0, &v) == FcResultNoMatch)
     {
-	if (FcPatternGet (pattern, FC_WEIGHT, 0, &v) == FcResultNoMatch )
+	if (FcPatternObjectGet (pattern, FC_WEIGHT_OBJECT, 0, &v) == FcResultNoMatch )
 	{
-	    FcPatternAddInteger (pattern, FC_WEIGHT, FC_WEIGHT_MEDIUM);
+	    FcPatternObjectAddInteger (pattern, FC_WEIGHT_OBJECT, FC_WEIGHT_MEDIUM);
 	}
-	if (FcPatternGet (pattern, FC_SLANT, 0, &v) == FcResultNoMatch)
+	if (FcPatternObjectGet (pattern, FC_SLANT_OBJECT, 0, &v) == FcResultNoMatch)
 	{
-	    FcPatternAddInteger (pattern, FC_SLANT, FC_SLANT_ROMAN);
+	    FcPatternObjectAddInteger (pattern, FC_SLANT_OBJECT, FC_SLANT_ROMAN);
 	}
     }
 
-    if (FcPatternGet (pattern, FC_WIDTH, 0, &v) == FcResultNoMatch)
-	FcPatternAddInteger (pattern, FC_WIDTH, FC_WIDTH_NORMAL);
+    if (FcPatternObjectGet (pattern, FC_WIDTH_OBJECT, 0, &v) == FcResultNoMatch)
+	FcPatternObjectAddInteger (pattern, FC_WIDTH_OBJECT, FC_WIDTH_NORMAL);
 
     for (i = 0; i < NUM_FC_BOOL_DEFAULTS; i++)
-	if (FcPatternGet (pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch)
-	    FcPatternAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value);
+	if (FcPatternObjectGet (pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch)
+	    FcPatternObjectAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value);
     
-    if (FcPatternGet (pattern, FC_PIXEL_SIZE, 0, &v) == FcResultNoMatch)
+    if (FcPatternObjectGet (pattern, FC_PIXEL_SIZE_OBJECT, 0, &v) == FcResultNoMatch)
     {
 	double	dpi, size, scale;
 
-	if (FcPatternGetDouble (pattern, FC_SIZE, 0, &size) != FcResultMatch)
+	if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch)
 	{
 	    size = 12.0;
-	    (void) FcPatternDel (pattern, FC_SIZE);
-	    FcPatternAddDouble (pattern, FC_SIZE, size);
+	    (void) FcPatternObjectDel (pattern, FC_SIZE_OBJECT);
+	    FcPatternObjectAddDouble (pattern, FC_SIZE_OBJECT, size);
 	}
-	if (FcPatternGetDouble (pattern, FC_SCALE, 0, &scale) != FcResultMatch)
+	if (FcPatternObjectGetDouble (pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch)
 	{
 	    scale = 1.0;
-	    (void) FcPatternDel (pattern, FC_SCALE);
-	    FcPatternAddDouble (pattern, FC_SCALE, scale);
+	    (void) FcPatternObjectDel (pattern, FC_SCALE_OBJECT);
+	    FcPatternObjectAddDouble (pattern, FC_SCALE_OBJECT, scale);
 	}
 	size *= scale;
-	if (FcPatternGetDouble (pattern, FC_DPI, 0, &dpi) != FcResultMatch)
+	if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch)
 	{
 	    dpi = 75.0;
-	    (void) FcPatternDel (pattern, FC_DPI);
-	    FcPatternAddDouble (pattern, FC_DPI, dpi);
+	    (void) FcPatternObjectDel (pattern, FC_DPI_OBJECT);
+	    FcPatternObjectAddDouble (pattern, FC_DPI_OBJECT, dpi);
 	}
 	size *= dpi / 72.0;
-	FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
+	FcPatternObjectAddDouble (pattern, FC_PIXEL_SIZE_OBJECT, size);
     }
 
-    if (FcPatternGet (pattern, FC_LANG, 0, &v) == FcResultNoMatch)
+    if (FcPatternObjectGet (pattern, FC_LANG_OBJECT, 0, &v) == FcResultNoMatch)
     {
- 	FcPatternAddString (pattern, FC_LANG, FcGetDefaultLang ());
+ 	FcPatternObjectAddString (pattern, FC_LANG_OBJECT, FcGetDefaultLang ());
     }
-    if (FcPatternGet (pattern, FC_FONTVERSION, 0, &v) == FcResultNoMatch)
+    if (FcPatternObjectGet (pattern, FC_FONTVERSION_OBJECT, 0, &v) == FcResultNoMatch)
     {
-	FcPatternAddInteger (pattern, FC_FONTVERSION, 0x7fffffff);
+	FcPatternObjectAddInteger (pattern, FC_FONTVERSION_OBJECT, 0x7fffffff);
     }
 
-    if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
+    if (FcPatternObjectGet (pattern, FC_HINT_STYLE_OBJECT, 0, &v) == FcResultNoMatch)
     {
-	FcPatternAddInteger (pattern, FC_HINT_STYLE, FC_HINT_FULL);
+	FcPatternObjectAddInteger (pattern, FC_HINT_STYLE_OBJECT, FC_HINT_FULL);
     }
 }
diff --git a/src/fcfs.c b/src/fcfs.c
index fdc15d7..e9b2d07 100644
--- a/src/fcfs.c
+++ b/src/fcfs.c
@@ -81,117 +81,52 @@ FcFontSetAdd (FcFontSet *s, FcPattern *f
     return FcTrue;
 }
 
-static int * fcfs_pat_count;
-
-void
-FcFontSetNewBank (void)
-{
-    FcPatternNewBank();
-}
-
-int
-FcFontSetNeededBytes (FcFontSet *s)
-{
-    int i, c, cum = 0;
-
-    for (i = 0; i < s->nfont; i++)
-    {
-	c = FcPatternNeededBytes(s->fonts[i]);
-	if (c < 0)
-	    return c;
-	cum += c;
-    }
-
-    if (cum > 0)
-	return cum + sizeof(int) + FcObjectNeededBytes();
-    else
-	return 0;
-}
-
-/* Returns an overestimate of the number of bytes that
- * might later get eaten up by padding in the ALIGN macro. */
-int
-FcFontSetNeededBytesAlign (void)
-{
-    return fc_alignof (int) + 
-	FcPatternNeededBytesAlign () + FcObjectNeededBytesAlign ();
-}
-
-void *
-FcFontSetDistributeBytes (FcCache * metadata, void * block_ptr)
-{
-    block_ptr = ALIGN (block_ptr, int);
-    fcfs_pat_count = (int *)block_ptr;
-    block_ptr = (int *)block_ptr + 1;
-    /* we don't consume any bytes for the fontset itself, */
-    /* since we don't allocate it statically. */
-    block_ptr = FcPatternDistributeBytes (metadata, block_ptr);
-
-    /* for good measure, write out the object ids used for */
-    /* this bank to the file. */
-    return FcObjectDistributeBytes (metadata, block_ptr);
-}
-
 FcBool
-FcFontSetSerialize (int bank, FcFontSet * s)
+FcFontSetSerializeAlloc (FcSerialize *serialize, const FcFontSet *s)
 {
     int i;
-    FcPattern * p;
-    *fcfs_pat_count = s->nfont;
-
+    
+    if (!FcSerializeAlloc (serialize, s, sizeof (FcFontSet)))
+	return FcFalse;
+    if (!FcSerializeAlloc (serialize, s->fonts, s->nfont * sizeof (FcPattern *)))
+	return FcFalse;
     for (i = 0; i < s->nfont; i++)
     {
-	p = FcPatternSerialize (bank, s->fonts[i]);
-	if (!p) return FcFalse;
+	if (!FcPatternSerializeAlloc (serialize, s->fonts[i]))
+	    return FcFalse;
     }
-    FcObjectSerialize();
-
     return FcTrue;
 }
 
-FcBool
-FcFontSetUnserialize(FcCache * metadata, FcFontSet * s, void * block_ptr)
+FcFontSet *
+FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s)
 {
-    int nfont;
-    int i, n;
-
-    block_ptr = ALIGN (block_ptr, int);
-    nfont = *(int *)block_ptr;
-    block_ptr = (int *)block_ptr + 1;
+    int		i;
+    FcFontSet	*s_serialize;
+    FcPattern	**fonts_serialize;
+    FcPattern	*p_serialize;
+
+    s_serialize = FcSerializePtr (serialize, s);
+    if (!s_serialize)
+	return NULL;
+    *s_serialize = *s;
+    s_serialize->sfont = s_serialize->nfont;
+    
+    fonts_serialize = FcSerializePtr (serialize, s->fonts);
+    if (!fonts_serialize)
+	return NULL;
+    s_serialize->fonts = FcPtrToEncodedOffset (s_serialize,
+					       fonts_serialize, FcPattern *);
 
-    /* comparing nfont and metadata.count is a bit like comparing
-       apples and oranges. Its just for rejecting totally insane
-       nfont values, and for that its good enough */
-    if (nfont > 0 && nfont < metadata->count / sizeof(void*))
+    for (i = 0; i < s->nfont; i++)
     {
-	FcPattern * p = (FcPattern *)block_ptr;
-
-	if (s->sfont < s->nfont + nfont)
-	{
-	    int sfont = s->nfont + nfont;
-	    FcPattern ** pp;
-	    pp = realloc (s->fonts, sfont * sizeof (FcPattern));
-	    if (!pp)
-		return FcFalse;
-	    s->fonts = pp;
-	    s->sfont = sfont;
-	}
-	n = s->nfont;
-	s->nfont += nfont;
-
-        /* The following line is a bit counterintuitive.  The usual
-         * convention is that FcPatternUnserialize is responsible for
-         * aligning the FcPattern.  However, the FontSet also stores
-         * the FcPatterns in its own array, so we need to align here
-         * too. */
-        p = ALIGN(p, FcPattern);
-	for (i = 0; i < nfont; i++)
-	    s->fonts[n + i] = p+i;
-
-	block_ptr = FcPatternUnserialize (metadata, block_ptr);
-	block_ptr = FcObjectUnserialize (metadata, block_ptr);
-	return block_ptr != 0;
+	p_serialize = FcPatternSerialize (serialize, s->fonts[i]);
+	if (!p_serialize)
+	    return NULL;
+	fonts_serialize[i] = FcPtrToEncodedOffset (s_serialize,
+						   p_serialize,
+						   FcPattern);
     }
 
-    return FcFalse;
+    return s_serialize;
 }
diff --git a/src/fcint.h b/src/fcint.h
index fbbdf77..2f656cb 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -74,6 +74,7 @@
 #define FC_DBG_SCANV	256
 #define FC_DBG_MEMORY	512
 #define FC_DBG_CONFIG	1024
+#define FC_DBG_LANGSET	2048
 
 #define FC_MEM_CHARSET	    0
 #define FC_MEM_CHARLEAF	    1
@@ -116,44 +117,94 @@ typedef enum _FcValueBinding {
     FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
 } FcValueBinding;
 
-typedef struct _FcValueListPtr {
-    int		 	bank;
-    union {
-        int		    stat;
-        struct _FcValueList *dyn;
-    } u;
-} FcValueListPtr;
+/*
+ * Serialized data structures use only offsets instead of pointers
+ * A low bit of 1 indicates an offset.
+ */
+ 
+/* Is the provided pointer actually an offset? */
+#define FcIsEncodedOffset(p)	((((intptr_t) (p)) & 1) != 0)
 
-typedef struct _FcValueList {
-    FcValueListPtr	    next;
+/* Encode offset in a pointer of type t */
+#define FcOffsetEncode(o,t)	((t *) ((o) | 1))
+
+/* Decode a pointer into an offset */
+#define FcOffsetDecode(p)	(((intptr_t) (p)) & ~1)
+
+/* Compute pointer offset */
+#define FcPtrToOffset(b,p)	((intptr_t) (p) - (intptr_t) (b))
+
+/* Given base address, offset and type, return a pointer */
+#define FcOffsetToPtr(b,o,t)	((t *) ((intptr_t) (b) + (o)))
+
+/* Given base address, encoded offset and type, return a pointer */
+#define FcEncodedOffsetToPtr(b,p,t) FcOffsetToPtr(b,FcOffsetDecode(p),t)
 
-    FcValue		    value;
-    FcValueBinding	    binding;
+/* Given base address, pointer and type, return an encoded offset */
+#define FcPtrToEncodedOffset(b,p,t) FcOffsetEncode(FcPtrToOffset(b,p),t)
+
+/* Given a structure, offset member and type, return pointer */
+#define FcOffsetMember(s,m,t)	    FcOffsetToPtr(s,(s)->m,t)
+
+/* Given a structure, encoded offset member and type, return pointer to member */
+#define FcEncodedOffsetMember(s,m,t) FcOffsetToPtr(s,FcOffsetDecode((s)->m), t)
+
+/* Given a structure, member and type, convert the member to a pointer */
+#define FcPointerMember(s,m,t)	(FcIsEncodedOffset((s)->m) ? \
+				 FcEncodedOffsetMember (s,m,t) : \
+				 (s)->m)
+
+/*
+ * Serialized values may hold strings, charsets and langsets as pointers,
+ * unfortunately FcValue is an exposed type so we can't just always use
+ * offsets
+ */
+#define FcValueString(v)	FcPointerMember(v,u.s,FcChar8)
+#define FcValueCharSet(v)	FcPointerMember(v,u.c,const FcCharSet)
+#define FcValueLangSet(v)	FcPointerMember(v,u.l,const FcLangSet)
+
+typedef struct _FcValueList *FcValueListPtr;
+
+typedef struct _FcValueList {
+    struct _FcValueList	*next;
+    FcValue		value;
+    FcValueBinding	binding;
 } FcValueList;
 
-typedef int FcObjectPtr;
+#define FcValueListNext(vl)	FcPointerMember(vl,next,FcValueList)
+			     
+typedef int FcObject;
 
-typedef struct _FcPatternEltPtr {
-    int		 	bank;
-    union {
-        int		    stat;
-        struct _FcPatternElt *dyn;
-    } u;
-} FcPatternEltPtr;
+typedef struct _FcPatternElt *FcPatternEltPtr;
 
+/*
+ * Pattern elts are stuck in a structure connected to the pattern, 
+ * so they get moved around when the pattern is resized. Hence, the
+ * values field must be a pointer/offset instead of just an offset
+ */
 typedef struct _FcPatternElt {
-    FcObjectPtr             object;
-    FcValueListPtr          values;
+    FcObject		object;
+    FcValueList		*values;
 } FcPatternElt;
 
+#define FcPatternEltValues(pe)	FcPointerMember(pe,values,FcValueList)
+
 struct _FcPattern {
     int		    num;
     int		    size;
-    FcPatternEltPtr elts;
+    intptr_t	    elts_offset;
     int		    ref;
-    int		    bank;
 };
 
+#define FcPatternElts(p)	FcOffsetMember(p,elts_offset,FcPatternElt)
+
+#define FcFontSetFonts(fs)	FcPointerMember(fs,fonts,FcPattern *)
+/*
+#define FcFontSetFont(fs,i)	(FcIsEncodedOffset((fs)->fonts) ? \
+				 FcOffsetToPtr(FcFontSetFonts(fs), \
+					       FcFontSetFonts(fs)[i]) : \
+				 fs->fonts[i])*/
+						
 typedef enum _FcOp {
     FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpBool, FcOpCharSet, 
     FcOpNil,
@@ -178,7 +229,7 @@ typedef struct _FcExpr {
 	FcMatrix    *mval;
 	FcBool	    bval;
 	FcCharSet   *cval;
-	char	    *field;
+	FcObject    object;
 	FcChar8	    *constant;
 	struct {
 	    struct _FcExpr *left, *right;
@@ -196,14 +247,14 @@ typedef struct _FcTest {
     struct _FcTest	*next;
     FcMatchKind		kind;
     FcQual		qual;
-    const char		*field;
+    FcObject		object;
     FcOp		op;
     FcExpr		*expr;
 } FcTest;
 
 typedef struct _FcEdit {
     struct _FcEdit *next;
-    const char	    *field;
+    FcObject	    object;
     FcOp	    op;
     FcExpr	    *expr;
     FcValueBinding  binding;
@@ -224,19 +275,16 @@ typedef struct _FcCharLeaf {
 struct _FcCharSet {
     int		    ref;	/* reference count */
     int		    num;	/* size of leaves and numbers arrays */
-    int		    bank;
-    union {
-	struct {
-	    int	    	leafidx_offset;
-	    int	      	numbers_offset;
-	} stat;
-	struct {
-	    FcCharLeaf  **leaves;
-	    FcChar16    *numbers;
-	} dyn;
-    } u;
+    intptr_t	    leaves_offset;
+    intptr_t	    numbers_offset;
 };
 
+#define FcCharSetLeaves(c)	FcOffsetMember(c,leaves_offset,intptr_t)
+#define FcCharSetLeaf(c,i)	(FcOffsetToPtr(FcCharSetLeaves(c), \
+					       FcCharSetLeaves(c)[i], \
+					       FcCharLeaf))
+#define FcCharSetNumbers(c)	FcOffsetMember(c,numbers_offset,FcChar16)
+
 struct _FcStrSet {
     int		    ref;	/* reference count */
     int		    num;
@@ -258,22 +306,36 @@ typedef struct _FcStrBuf {
 } FcStrBuf;
 
 typedef struct _FcCache {
-    int	    magic;              /* FC_CACHE_MAGIC */
-    int	    subdirs;		/* number of subdir strings */
-    off_t   pos;		/* position of data block in file */
-    off_t   count;              /* number of bytes of data in block */
-    int     bank;               /* bank ID */
-    int     pattern_count;      /* number of FcPatterns */
-    int     patternelt_count;   /* number of FcPatternElts */
-    int     valuelist_count;    /* number of FcValueLists */
-    int     str_count;          /* size of strings appearing as FcValues */
-    int	    langset_count;      /* number of FcLangSets */
-    int     charset_count;      /* number of FcCharSets */
-    int     charset_numbers_count; 
-    int     charset_leaf_count;
-    int     charset_leaf_idx_count;
+    int		magic;              /* FC_CACHE_MAGIC */
+    off_t	size;		    /* size of file */
+    intptr_t	dir;		    /* offset to dir name */
+    intptr_t	dirs;		    /* offset to subdirs */
+    int		dirs_count;	    /* number of subdir strings */
+    intptr_t	set;		    /* offset to font set */
 } FcCache;
 
+#define FcCacheDir(c)	FcOffsetMember(c,dir,FcChar8)
+#define FcCacheDirs(c)	FcOffsetMember(c,dirs,intptr_t)
+#define FcCacheSet(c)	FcOffsetMember(c,set,FcFontSet)
+
+/*
+ * Used while constructing a directory cache object
+ */
+
+#define FC_SERIALIZE_HASH_SIZE	8191
+
+typedef struct _FcSerializeBucket {
+    struct _FcSerializeBucket *next;
+    const void	*object;
+    intptr_t	offset;
+} FcSerializeBucket;
+
+typedef struct _FcSerialize {
+    intptr_t		size;
+    void		*linear;
+    FcSerializeBucket	*buckets[FC_SERIALIZE_HASH_SIZE];
+} FcSerialize;
+    
 /*
  * To map adobe glyph names to unicode values, a precomputed hash
  * table is used
@@ -317,15 +379,17 @@ typedef struct _FcCaseFold {
 
 #define FC_MAX_FILE_LEN	    4096
 
-#define FC_STORAGE_STATIC 0x80
-#define fc_value_string(v)  (((v)->type & FC_STORAGE_STATIC) ? ((FcChar8 *) v) + (v)->u.s_off : (v) -> u.s)
-#define fc_value_charset(v)  (((v)->type & FC_STORAGE_STATIC) ? (const FcCharSet *)(((char *) v) + (v)->u.c_off) : (v) -> u.c)
-#define fc_value_langset(v)  (((v)->type & FC_STORAGE_STATIC) ? (const FcLangSet *)(((char *) v) + (v)->u.l_off) : (v) -> u.l)
-#define fc_storage_type(v) ((v)->type & ~FC_STORAGE_STATIC)
+/* XXX remove these when we're ready */
+
+#define fc_value_string(v)	FcValueString(v)
+#define fc_value_charset(v)	FcValueCharSet(v)
+#define fc_value_langset(v)	FcValueLangSet(v)
+#define fc_storage_type(v)	((v)->type)
 
 #define fc_alignof(type) offsetof (struct { char c; type member; }, member)
 
-#define FC_CACHE_MAGIC 0xFC02FC04
+#define FC_CACHE_MAGIC	    0xFC02FC04
+#define FC_CACHE_MAGIC_COPY 0xFC02FC05
 
 struct _FcAtomic {
     FcChar8	*file;		/* original file name */
@@ -428,19 +492,6 @@ FcDirCacheConsume (FILE *file, FcFontSet
     
 FcBool
 FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir, FcConfig *config);
-
-extern int *_fcBankId, *_fcBankIdx;
-int
-FcCacheBankToIndexMTF (int bank);
-
-static inline int
-FcCacheBankToIndex (int bank)
-{
-    return (_fcBankId[*_fcBankIdx] == bank) ? *_fcBankIdx : FcCacheBankToIndexMTF(bank);
-}
-
-const char *
-FcCacheFindBankDir (int bank);
  
 /* fccfg.c */
 
@@ -512,6 +563,33 @@ FcConfigAcceptFont (FcConfig	    *config
 FcFileTime
 FcConfigModifiedTime (FcConfig *config);
 
+intptr_t
+FcAlignSize (intptr_t size);
+    
+FcSerialize *
+FcSerializeCreate (void);
+
+void
+FcSerializeDestroy (FcSerialize *serialize);
+
+FcBool
+FcSerializeAlloc (FcSerialize *serialize, const void *object, int size);
+
+intptr_t
+FcSerializeReserve (FcSerialize *serialize, int size);
+
+intptr_t
+FcSerializeOffset (FcSerialize *serialize, const void *object);
+
+void *
+FcSerializePtr (FcSerialize *serialize, const void *object);
+
+FcBool
+FcLangSetSerializeAlloc (FcSerialize *serialize, const FcLangSet *l);
+
+FcLangSet *
+FcLangSetSerialize(FcSerialize *serialize, const FcLangSet *l);
+
 /* fccharset.c */
 void
 FcLangCharSetPopulate (void);
@@ -531,27 +609,11 @@ FcNameParseCharSet (FcChar8 *string);
 FcCharLeaf *
 FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4);
 
-void
-FcCharSetNewBank (void);
-
-int
-FcCharSetNeededBytes (const FcCharSet *c);
-
-int
-FcCharSetNeededBytesAlign (void);
-
-void *
-FcCharSetDistributeBytes (FcCache * metadata,
-			  void * block_ptr);
+FcBool
+FcCharSetSerializeAlloc(FcSerialize *serialize, const FcCharSet *cs);
 
 FcCharSet *
-FcCharSetSerialize(int bank, FcCharSet *c);
-
-void *
-FcCharSetUnserialize (FcCache * metadata, void *block_ptr);
-
-FcCharLeaf *
-FcCharSetGetLeaf(const FcCharSet *c, int i);
+FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs);
 
 FcChar16 *
 FcCharSetGetNumbers(const FcCharSet *c);
@@ -578,6 +640,9 @@ FcEditPrint (const FcEdit *edit);
 void
 FcSubstPrint (const FcSubst *subst);
 
+void
+FcCharSetPrint (const FcCharSet *c);
+    
 extern int FcDebugVal;
 
 static inline int
@@ -633,24 +698,12 @@ FcFreeTypeGetPrivateMap (FT_Encoding enc
     
 /* fcfs.c */
 
-void
-FcFontSetNewBank (void);
-
-int
-FcFontSetNeededBytes (FcFontSet *s);
-
-int
-FcFontSetNeededBytesAlign (void);
-
-void *
-FcFontSetDistributeBytes (FcCache * metadata, void * block_ptr);
-
 FcBool
-FcFontSetSerialize (int bank, FcFontSet * s);
-
-FcBool
-FcFontSetUnserialize(FcCache * metadata, FcFontSet * s, void * block_ptr);
+FcFontSetSerializeAlloc (FcSerialize *serialize, const FcFontSet *s);
 
+FcFontSet *
+FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s);
+    
 /* fcgram.y */
 int
 FcConfigparse (void);
@@ -731,25 +784,6 @@ FcNameParseLangSet (const FcChar8 *strin
 FcBool
 FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls);
 
-void
-FcLangSetNewBank (void);
-
-int
-FcLangSetNeededBytes (const FcLangSet *l);
-
-int
-FcLangSetNeededBytesAlign (void);
-
-void *
-FcLangSetDistributeBytes (FcCache * metadata,
-			  void * block_ptr);
-
-FcLangSet *
-FcLangSetSerialize (int bank, FcLangSet *l);
-
-void *
-FcLangSetUnserialize (FcCache * metadata, void *block_ptr);
-
 /* fclist.c */
 
 FcBool
@@ -760,36 +794,64 @@ FcListPatternMatchAny (const FcPattern *
 
 /* fcname.c */
 
-FcBool
-FcNameBool (const FcChar8 *v, FcBool *result);
-
-void *
-FcObjectDistributeBytes (FcCache * metadata,
-			 void * block_ptr);
-
-FcObjectPtr
-FcObjectToPtr (const char * si);
+/*
+ * NOTE -- this ordering is part of the cache file format.
+ * It must also match the ordering in fcname.c
+ */
 
-int
-FcObjectNeededBytes (void);
+#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
+#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
 
-int
-FcObjectNeededBytesAlign (void);
+FcBool
+FcNameBool (const FcChar8 *v, FcBool *result);
 
-void *
-FcObjectUnserialize (FcCache * metadata, void *block_ptr);
+FcBool
+FcObjectValidType (FcObject object, FcType type);
 
-void
-FcObjectSerialize (void);
+FcObject
+FcObjectFromName (const char * name);
 
 const char *
-FcObjectPtrU (FcObjectPtr p);
+FcObjectName (FcObject object);
 
-static inline int
-FcObjectPtrCompare (const FcObjectPtr a, const FcObjectPtr b)
-{
-    return a - b;
-}
+#define FcObjectCompare(a, b)	((int) a - (int) b)
 
 void
 FcObjectStaticNameFini (void);
@@ -803,17 +865,74 @@ void
 FcValueListDestroy (FcValueListPtr l);
 
 FcPatternElt *
-FcPatternFindElt (const FcPattern *p, const char *object);
+FcPatternObjectFindElt (const FcPattern *p, FcObject object);
 
 FcPatternElt *
-FcPatternInsertElt (FcPattern *p, const char *object);
+FcPatternObjectInsertElt (FcPattern *p, FcObject object);
+
+FcBool
+FcPatternObjectAddWithBinding  (FcPattern	*p,
+				FcObject	object,
+				FcValue		value,
+				FcValueBinding  binding,
+				FcBool		append);
+
+FcBool
+FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append);
+    
+FcBool
+FcPatternObjectAddWeak (FcPattern *p, FcObject object, FcValue value, FcBool append);
+    
+FcResult
+FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v);
+    
+FcBool
+FcPatternObjectDel (FcPattern *p, FcObject object);
 
 FcBool
-FcPatternAddWithBinding  (FcPattern	    *p,
-			  const char	    *object,
-			  FcValue	    value,
-			  FcValueBinding    binding,
-			  FcBool	    append);
+FcPatternObjectRemove (FcPattern *p, FcObject object, int id);
+
+FcBool
+FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i);
+
+FcBool
+FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d);
+
+FcBool
+FcPatternObjectAddString (FcPattern *p, FcObject object, const FcChar8 *s);
+
+FcBool
+FcPatternObjectAddMatrix (FcPattern *p, FcObject object, const FcMatrix *s);
+
+FcBool
+FcPatternObjectAddCharSet (FcPattern *p, FcObject object, const FcCharSet *c);
+
+FcBool
+FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b);
+
+FcBool
+FcPatternObjectAddLangSet (FcPattern *p, FcObject object, const FcLangSet *ls);
+
+FcResult
+FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int n, int *i);
+
+FcResult
+FcPatternObjectGetDouble (const FcPattern *p, FcObject object, int n, double *d);
+
+FcResult
+FcPatternObjectGetString (const FcPattern *p, FcObject object, int n, FcChar8 ** s);
+
+FcResult
+FcPatternObjectGetMatrix (const FcPattern *p, FcObject object, int n, FcMatrix **s);
+
+FcResult
+FcPatternObjectGetCharSet (const FcPattern *p, FcObject object, int n, FcCharSet **c);
+
+FcResult
+FcPatternObjectGetBool (const FcPattern *p, FcObject object, int n, FcBool *b);
+
+FcResult
+FcPatternObjectGetLangSet (const FcPattern *p, FcObject object, int n, FcLangSet **ls);
 
 void
 FcPatternFini (void);
@@ -827,49 +946,17 @@ FcStrStaticName (const FcChar8 *name);
 FcChar32
 FcStringHash (const FcChar8 *s);
 
-void
-FcPatternNewBank (void);
-
-int
-FcPatternNeededBytes (FcPattern *p);
-
-int
-FcPatternNeededBytesAlign (void);
-
-void *
-FcPatternDistributeBytes (FcCache * metadata, void * block_ptr);
-
-/* please don't access these outside of fcpat.c! only visible so that
- * *PtrU can be inlined. */
-extern FcValueList ** _fcValueLists;
-extern FcPatternElt ** _fcPatternElts;
-
-static inline FcValueList * 
-FcValueListPtrU (FcValueListPtr pi)
-{
-    if (pi.bank == FC_BANK_DYNAMIC)
-        return pi.u.dyn;
-
-    return &_fcValueLists[FcCacheBankToIndex(pi.bank)][pi.u.stat];
-}
-
-static inline FcPatternElt *
-FcPatternEltU (FcPatternEltPtr pei)
-{
-    if (pei.bank == FC_BANK_DYNAMIC)
-	return pei.u.dyn;
-
-    return &_fcPatternElts[FcCacheBankToIndex(pei.bank)][pei.u.stat];
-}
-
-FcValueListPtr
-FcValueListPtrCreateDynamic(FcValueList * p);
+FcBool
+FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat);
 
 FcPattern *
-FcPatternSerialize (int bank, FcPattern * p);
+FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat);
 
-void *
-FcPatternUnserialize (FcCache * metadata, void *block_ptr);
+FcBool
+FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *pat);
+
+FcValueList *
+FcValueListSerialize (FcSerialize *serialize, const FcValueList *pat);
 
 /* fcrender.c */
 
@@ -929,4 +1016,10 @@ FcStrHashIgnoreCase (const FcChar8 *s);
 FcChar8 *
 FcStrCanonFilename (const FcChar8 *s);
 
+FcBool
+FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str);
+
+FcChar8 *
+FcStrSerialize (FcSerialize *serialize, const FcChar8 *str);
+
 #endif /* _FC_INT_H_ */
diff --git a/src/fclang.c b/src/fclang.c
index 552253d..f8f6f0b 100644
--- a/src/fclang.c
+++ b/src/fclang.c
@@ -44,8 +44,6 @@ struct _FcLangSet {
 #define FcLangSetBitSet(ls, id)	((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f)))
 #define FcLangSetBitGet(ls, id) (((ls)->map[(id)>>5] >> ((id) & 0x1f)) & 1)
 
-static FcBool langsets_populated = FcFalse;
-
 FcLangSet *
 FcFreeTypeLangSet (const FcCharSet  *charset, 
 		   const FcChar8    *exclusiveLang)
@@ -55,19 +53,26 @@ FcFreeTypeLangSet (const FcCharSet  *cha
     const FcCharSet *exclusiveCharset = 0;
     FcLangSet	    *ls;
 
-    if (!langsets_populated)
-    {
-        FcLangCharSetPopulate ();
-        langsets_populated = FcTrue;
-    }
-
     if (exclusiveLang)
 	exclusiveCharset = FcCharSetForLang (exclusiveLang);
     ls = FcLangSetCreate ();
     if (!ls)
 	return 0;
+    if (FcDebug() & FC_DBG_LANGSET) 
+    {
+	printf ("font charset\n");
+	FcCharSetPrint (charset);
+	printf ("\n");
+    }
     for (i = 0; i < NUM_LANG_CHAR_SET; i++)
     {
+	if (FcDebug() & FC_DBG_LANGSET) 
+	{
+	    printf ("%s charset\n", fcLangCharSets[i].lang);
+	    FcCharSetPrint (&fcLangCharSets[i].charset);
+	    printf ("\n");
+	}
+	
 	/*
 	 * Check for Han charsets to make fonts
 	 * which advertise support for a single language
@@ -80,8 +85,8 @@ FcFreeTypeLangSet (const FcCharSet  *cha
 		continue;
 
 	    for (j = 0; j < fcLangCharSets[i].charset.num; j++)
-		if (FcCharSetGetLeaf(&fcLangCharSets[i].charset, j) != 
-		    FcCharSetGetLeaf(exclusiveCharset, j))
+		if (FcCharSetLeaf(&fcLangCharSets[i].charset, j) != 
+		    FcCharSetLeaf(exclusiveCharset, j))
 		    continue;
 	}
 	missing = FcCharSetSubtractCount (&fcLangCharSets[i].charset, charset);
@@ -196,12 +201,6 @@ FcCharSetForLang (const FcChar8 *lang)
     int		i;
     int		country = -1;
 
-    if (!langsets_populated)
-    {
-        FcLangCharSetPopulate ();
-        langsets_populated = FcTrue;
-    }
-
     for (i = 0; i < NUM_LANG_CHAR_SET; i++)
     {
 	switch (FcLangCompare (lang, fcLangCharSets[i].lang)) {
@@ -710,90 +709,21 @@ FcLangSetContains (const FcLangSet *lsa,
     return FcTrue;
 }
 
-static FcLangSet ** langsets = 0;
-static int langset_bank_count = 0, langset_ptr = 0, langset_count = 0;
-
-void
-FcLangSetNewBank (void)
-{
-    langset_count = 0;
-}
-
-/* ideally, should only write one copy of any particular FcLangSet */
-int
-FcLangSetNeededBytes (const FcLangSet *l)
-{
-    langset_count++;
-    return sizeof (FcLangSet);
-}
-
-int
-FcLangSetNeededBytesAlign (void)
-{
-    return fc_alignof (FcLangSet);
-}
-
-static FcBool
-FcLangSetEnsureBank (int bi)
+FcBool
+FcLangSetSerializeAlloc (FcSerialize *serialize, const FcLangSet *l)
 {
-    if (!langsets || bi >= langset_bank_count)
-    {
-	int new_count = langset_bank_count + 2;
-	int i;
-	FcLangSet** tt;
-	tt = realloc(langsets, new_count * sizeof(FcLangSet *));
-	if (!tt)
-	    return FcFalse;
-
-	langsets = tt;
-	for (i = langset_bank_count; i < new_count; i++)
-	    langsets[i] = 0; 
-	langset_bank_count = new_count;
-    }
-
+    if (!FcSerializeAlloc (serialize, l, sizeof (FcLangSet)))
+	return FcFalse;
     return FcTrue;
 }
 
-void *
-FcLangSetDistributeBytes (FcCache * metadata, void * block_ptr)
-{
-    int bi = FcCacheBankToIndex(metadata->bank);
-    if (!FcLangSetEnsureBank(bi))
-	return 0;
-
-    block_ptr = ALIGN(block_ptr, FcLangSet);
-    langsets[bi] = block_ptr;
-    block_ptr = (void *)((char *)block_ptr +
-			 langset_count * sizeof(FcLangSet));
-    langset_ptr = 0;
-    metadata->langset_count = langset_count;
-    return block_ptr;
-}
-
 FcLangSet *
-FcLangSetSerialize(int bank, FcLangSet *l)
-{
-    int p = langset_ptr, bi = FcCacheBankToIndex(bank);
-
-    if (!l) return 0;
-
-    langsets[bi][langset_ptr] = *l;
-    langsets[bi][langset_ptr].extra = 0;
-    langset_ptr++;
-    return &langsets[bi][p];
-}
-
-void *
-FcLangSetUnserialize (FcCache * metadata, void *block_ptr)
+FcLangSetSerialize(FcSerialize *serialize, const FcLangSet *l)
 {
-    int bi = FcCacheBankToIndex(metadata->bank);
-    if (!FcLangSetEnsureBank(bi))
-	return 0;
+    FcLangSet	*l_serialize = FcSerializePtr (serialize, l);
 
-    FcMemAlloc (FC_MEM_LANGSET, metadata->langset_count * sizeof(FcLangSet));
-    block_ptr = ALIGN(block_ptr, FcLangSet);
-    langsets[bi] = (FcLangSet *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr +
-			 metadata->langset_count * sizeof(FcLangSet));
-    return block_ptr;
+    if (!l_serialize)
+	return NULL;
+    *l_serialize = *l;
+    return l_serialize;
 }
diff --git a/src/fclist.c b/src/fclist.c
index 9aef842..c0b7fb0 100644
--- a/src/fclist.c
+++ b/src/fclist.c
@@ -130,23 +130,21 @@ FcListValueListMatchAny (FcValueListPtr 
 {
     FcValueListPtr	 pat, fnt;
 
-    for (pat = patOrig; FcValueListPtrU(pat); 
-	 pat = FcValueListPtrU(pat)->next)
+    for (pat = patOrig; pat != NULL; pat = FcValueListNext(pat))
     {
-	for (fnt = fntOrig; FcValueListPtrU(fnt); 
-	     fnt = FcValueListPtrU(fnt)->next)
+	for (fnt = fntOrig; fnt != NULL; fnt = FcValueListNext(fnt))
 	{
 	    /*
 	     * make sure the font 'contains' the pattern.
 	     * (OpListing is OpContains except for strings
 	     *  where it requires an exact match)
 	     */
-	    if (FcConfigCompareValue (&FcValueListPtrU(fnt)->value,
+	    if (FcConfigCompareValue (&fnt->value,
 				      FcOpListing, 
-				      &FcValueListPtrU(pat)->value)) 
+				      &pat->value)) 
 		break;
 	}
-	if (!FcValueListPtrU(fnt))
+	if (fnt == NULL)
 	    return FcFalse;
     }
     return FcTrue;
@@ -158,26 +156,22 @@ FcListValueListEqual (FcValueListPtr v1o
 {
     FcValueListPtr	    v1, v2;
 
-    for (v1 = v1orig; FcValueListPtrU(v1); 
-	 v1 = FcValueListPtrU(v1)->next)
+    for (v1 = v1orig; v1 != NULL; v1 = FcValueListNext(v1))
     {
-	for (v2 = v2orig; FcValueListPtrU(v2); 
-	     v2 = FcValueListPtrU(v2)->next)
-	    if (FcValueEqual (FcValueCanonicalize(&FcValueListPtrU(v1)->value),
-			      FcValueCanonicalize(&FcValueListPtrU(v2)->value)))
+	for (v2 = v2orig; v2 != NULL; v2 = FcValueListNext(v2))
+	    if (FcValueEqual (FcValueCanonicalize(&(v1)->value),
+			      FcValueCanonicalize(&(v2)->value)))
 		break;
-	if (!FcValueListPtrU(v2))
+	if (v2 == NULL)
 	    return FcFalse;
     }
-    for (v2 = v2orig; FcValueListPtrU(v2); 
-	 v2 = FcValueListPtrU(v2)->next)
+    for (v2 = v2orig; v2 != NULL; v2 = FcValueListNext(v2))
     {
-	for (v1 = v1orig; FcValueListPtrU(v1); 
-	     v1 = FcValueListPtrU(v1)->next)
-	    if (FcValueEqual (FcValueCanonicalize(&FcValueListPtrU(v1)->value),
-			      FcValueCanonicalize(&FcValueListPtrU(v2)->value)))
+	for (v1 = v1orig; v1 != NULL; v1 = FcValueListNext(v1))
+	    if (FcValueEqual (FcValueCanonicalize(&v1->value),
+			      FcValueCanonicalize(&v2->value)))
 		break;
-	if (!FcValueListPtrU(v1))
+	if (v1 == NULL)
 	    return FcFalse;
     }
     return FcTrue;
@@ -193,13 +187,14 @@ FcListPatternEqual (FcPattern	*p1,
 
     for (i = 0; i < os->nobject; i++)
     {
-	e1 = FcPatternFindElt (p1, os->objects[i]);
-	e2 = FcPatternFindElt (p2, os->objects[i]);
+	e1 = FcPatternObjectFindElt (p1, FcObjectFromName (os->objects[i]));
+	e2 = FcPatternObjectFindElt (p2, FcObjectFromName (os->objects[i]));
 	if (!e1 && !e2)
 	    continue;
 	if (!e1 || !e2)
 	    return FcFalse;
-	if (!FcListValueListEqual (e1->values, e2->values))
+	if (!FcListValueListEqual (FcPatternEltValues(e1),
+				   FcPatternEltValues(e2)))
 	    return FcFalse;
     }
     return FcTrue;
@@ -214,16 +209,15 @@ FcListPatternMatchAny (const FcPattern *
 		       const FcPattern *font)
 {
     int		    i;
-    FcPatternElt   *e;
 
     for (i = 0; i < p->num; i++)
     {
-	e = FcPatternFindElt (font, 
-			      FcObjectPtrU((FcPatternEltU(p->elts)+i)->object));
-	if (!e)
+	FcPatternElt	*pe = &FcPatternElts(p)[i];
+	FcPatternElt	*fe = FcPatternObjectFindElt (font, pe->object);
+	if (!fe)
 	    return FcFalse;
-	if (!FcListValueListMatchAny ((FcPatternEltU(p->elts)+i)->values,    /* pat elts */
-				      e->values))	    /* font elts */
+	if (!FcListValueListMatchAny (FcPatternEltValues(pe),    /* pat elts */
+				      FcPatternEltValues(fe)))   /* font elts */
 	    return FcFalse;
     }
     return FcTrue;
@@ -272,10 +266,10 @@ FcListValueListHash (FcValueListPtr list
 {
     FcChar32	h = 0;
     
-    while (FcValueListPtrU(list))
+    while (list != NULL)
     {
-	h = h ^ FcListValueHash (&FcValueListPtrU(list)->value);
-	list = FcValueListPtrU(list)->next;
+	h = h ^ FcListValueHash (&list->value);
+	list = FcValueListNext(list);
     }
     return h;
 }
@@ -290,9 +284,9 @@ FcListPatternHash (FcPattern	*font,
 
     for (n = 0; n < os->nobject; n++)
     {
-	e = FcPatternFindElt (font, os->objects[n]);
+	e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[n]));
 	if (e)
-	    h = h ^ FcListValueListHash (e->values);
+	    h = h ^ FcListValueListHash (FcPatternEltValues(e));
     }
     return h;
 }
@@ -338,10 +332,10 @@ FcListHashTableCleanup (FcListHashTable 
 }
 
 static int
-FcGetDefaultObjectLangIndex (FcPattern *font, const char *object)
+FcGetDefaultObjectLangIndex (FcPattern *font, FcObject object)
 {
     FcChar8	   *lang = FcGetDefaultLang ();
-    FcPatternElt   *e = FcPatternFindElt (font, object);
+    FcPatternElt   *e = FcPatternObjectFindElt (font, object);
     FcValueListPtr  v;
     FcValue         value;
     int             idx = -1;
@@ -349,9 +343,9 @@ FcGetDefaultObjectLangIndex (FcPattern *
 
     if (e)
     {
-	for (v = e->values, i = 0; FcValueListPtrU(v); v = FcValueListPtrU(v)->next, ++i)
+	for (v = FcPatternEltValues(e), i = 0; v; v = FcValueListNext(v), ++i)
 	{
-	    value = FcValueCanonicalize (&FcValueListPtrU (v)->value);
+	    value = FcValueCanonicalize (&v->value);
 
 	    if (value.type == FcTypeString)
 	    {
@@ -404,33 +398,33 @@ FcListAppend (FcListHashTable	*table,
 	if (!strcmp (os->objects[o], FC_FAMILY) || !strcmp (os->objects[o], FC_FAMILYLANG))
 	{
 	    if (familyidx < 0)
-		familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG);
+		familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG_OBJECT);
 	    defidx = familyidx;
 	}
 	else if (!strcmp (os->objects[o], FC_FULLNAME) || !strcmp (os->objects[o], FC_FULLNAMELANG))
 	{
 	    if (fullnameidx < 0)
-		fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG);
+		fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG_OBJECT);
 	    defidx = fullnameidx;
 	}
 	else if (!strcmp (os->objects[o], FC_STYLE) || !strcmp (os->objects[o], FC_STYLELANG))
 	{
 	    if (styleidx < 0)
-		styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG);
+		styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG_OBJECT);
 	    defidx = styleidx;
 	}
 	else
 	    defidx = 0;
 
-	e = FcPatternFindElt (font, os->objects[o]);
+	e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[o]));
 	if (e)
 	{
-	    for (v = e->values, idx = 0; FcValueListPtrU(v); 
-		 v = FcValueListPtrU(v)->next, ++idx)
+	    for (v = FcPatternEltValues(e), idx = 0; v;
+		 v = FcValueListNext(v), ++idx)
 	    {
 		if (!FcPatternAdd (bucket->pattern, 
 				   os->objects[o], 
-				   FcValueCanonicalize(&FcValueListPtrU(v)->value), defidx != idx))
+				   FcValueCanonicalize(&v->value), defidx != idx))
 		    goto bail2;
 	    }
 	}
diff --git a/src/fcmatch.c b/src/fcmatch.c
index 739ef3e..7e3353b 100644
--- a/src/fcmatch.c
+++ b/src/fcmatch.c
@@ -173,8 +173,7 @@ FcCompareSize (FcValue *value1, FcValue 
 }
 
 typedef struct _FcMatcher {
-    const char	    *object;
-    FcObjectPtr	    objectPtr;
+    FcObject	    object;
     double	    (*compare) (FcValue *value1, FcValue *value2);
     int		    strong, weak;
 } FcMatcher;
@@ -185,156 +184,111 @@ typedef struct _FcMatcher {
  * later values
  */
 static FcMatcher _FcMatchers [] = {
-    { FC_FOUNDRY,	0, FcCompareString,	0, 0 },
+    { FC_FOUNDRY_OBJECT,	FcCompareString,	0, 0 },
 #define MATCH_FOUNDRY	    0
 #define MATCH_FOUNDRY_INDEX 0
     
-    { FC_CHARSET,	0, FcCompareCharSet,	1, 1 },
+    { FC_CHARSET_OBJECT,	FcCompareCharSet,	1, 1 },
 #define MATCH_CHARSET	    1
 #define MATCH_CHARSET_INDEX 1
     
-    { FC_FAMILY,    	0, FcCompareFamily,	2, 4 },
+    { FC_FAMILY_OBJECT,    	FcCompareFamily,	2, 4 },
 #define MATCH_FAMILY	    2
 #define MATCH_FAMILY_STRONG_INDEX   2
 #define MATCH_FAMILY_WEAK_INDEX	    4
     
-    { FC_LANG,		0, FcCompareLang,	3, 3 },
+    { FC_LANG_OBJECT,		FcCompareLang,	3, 3 },
 #define MATCH_LANG	    3
 #define MATCH_LANG_INDEX    3
     
-    { FC_SPACING,	0, FcCompareNumber,	5, 5 },
+    { FC_SPACING_OBJECT,	FcCompareNumber,	5, 5 },
 #define MATCH_SPACING	    4
 #define MATCH_SPACING_INDEX 5
     
-    { FC_PIXEL_SIZE,	0, FcCompareSize,	6, 6 },
+    { FC_PIXEL_SIZE_OBJECT,	FcCompareSize,	6, 6 },
 #define MATCH_PIXEL_SIZE    5
 #define MATCH_PIXEL_SIZE_INDEX	6
     
-    { FC_STYLE,		0, FcCompareString,	7, 7 },
+    { FC_STYLE_OBJECT,		FcCompareString,	7, 7 },
 #define MATCH_STYLE	    6
 #define MATCH_STYLE_INDEX   7
     
-    { FC_SLANT,		0, FcCompareNumber,	8, 8 },
+    { FC_SLANT_OBJECT,		FcCompareNumber,	8, 8 },
 #define MATCH_SLANT	    7
 #define MATCH_SLANT_INDEX   8
     
-    { FC_WEIGHT,	0, FcCompareNumber,	9, 9 },
+    { FC_WEIGHT_OBJECT,		FcCompareNumber,	9, 9 },
 #define MATCH_WEIGHT	    8
 #define MATCH_WEIGHT_INDEX  9
     
-    { FC_WIDTH,		0, FcCompareNumber,	10, 10 },
+    { FC_WIDTH_OBJECT,		FcCompareNumber,	10, 10 },
 #define MATCH_WIDTH	    9
 #define MATCH_WIDTH_INDEX   10
     
-    { FC_ANTIALIAS,	0, FcCompareBool,	11, 11 },
+    { FC_ANTIALIAS_OBJECT,	FcCompareBool,	11, 11 },
 #define MATCH_ANTIALIAS	    10
 #define MATCH_ANTIALIAS_INDEX	    11
     
-    { FC_RASTERIZER,	0, FcCompareString,	12, 12 },
+    { FC_RASTERIZER_OBJECT,	FcCompareString,	12, 12 },
 #define MATCH_RASTERIZER    11
 #define MATCH_RASTERIZER_INDEX    12
 
-    { FC_OUTLINE,	0, FcCompareBool,	13, 13 },
+    { FC_OUTLINE_OBJECT,	FcCompareBool,	13, 13 },
 #define MATCH_OUTLINE	    12
 #define MATCH_OUTLINE_INDEX	    13
 
-    { FC_FONTVERSION,	0, FcCompareNumber,	14, 14 },
+    { FC_FONTVERSION_OBJECT,	FcCompareNumber,	14, 14 },
 #define MATCH_FONTVERSION   13
 #define MATCH_FONTVERSION_INDEX   14
 };
 
 #define NUM_MATCH_VALUES    15
 
-static FcBool matchObjectPtrsInit = FcFalse;
-
-static void
-FcMatchObjectPtrsInit (void)
-{
-    _FcMatchers[MATCH_FOUNDRY].objectPtr = FcObjectToPtr(FC_FOUNDRY);
-    _FcMatchers[MATCH_CHARSET].objectPtr = FcObjectToPtr(FC_CHARSET);
-    _FcMatchers[MATCH_FAMILY].objectPtr = FcObjectToPtr(FC_FAMILY);
-    _FcMatchers[MATCH_LANG].objectPtr = FcObjectToPtr(FC_LANG);
-    _FcMatchers[MATCH_SPACING].objectPtr = FcObjectToPtr(FC_SPACING);
-    _FcMatchers[MATCH_PIXEL_SIZE].objectPtr = FcObjectToPtr(FC_PIXEL_SIZE);
-    _FcMatchers[MATCH_STYLE].objectPtr = FcObjectToPtr(FC_STYLE);
-    _FcMatchers[MATCH_SLANT].objectPtr = FcObjectToPtr(FC_SLANT);
-    _FcMatchers[MATCH_WEIGHT].objectPtr = FcObjectToPtr(FC_WEIGHT);
-    _FcMatchers[MATCH_WIDTH].objectPtr = FcObjectToPtr(FC_WIDTH);
-    _FcMatchers[MATCH_ANTIALIAS].objectPtr = FcObjectToPtr(FC_ANTIALIAS);
-    _FcMatchers[MATCH_RASTERIZER].objectPtr = FcObjectToPtr(FC_RASTERIZER);
-    _FcMatchers[MATCH_OUTLINE].objectPtr = FcObjectToPtr(FC_OUTLINE);
-    _FcMatchers[MATCH_FONTVERSION].objectPtr = FcObjectToPtr(FC_FONTVERSION);
-    matchObjectPtrsInit = FcTrue;
-}
-
 static FcMatcher*
-FcObjectPtrToMatcher (FcObjectPtr o)
+FcObjectToMatcher (FcObject object)
 {
     int 	i;
-    const char  *object = FcObjectPtrU(o);
 
     i = -1;
-    switch (object[0]) {
-    case 'f':
-	switch (object[1]) {
-	case 'o':
-	    switch (object[2]) {
-	    case 'u':
-		i = MATCH_FOUNDRY; break;
-	    case 'n':
-		i = MATCH_FONTVERSION; break;
-	    }
-	    break;
-	case 'a':
-	    i = MATCH_FAMILY; break;
-	}
-	break;
-    case 'c':
+    switch (object) {
+    case FC_FOUNDRY_OBJECT:
+	i = MATCH_FOUNDRY; break;
+    case FC_FONTVERSION_OBJECT:
+	i = MATCH_FONTVERSION; break;
+    case FC_FAMILY_OBJECT:
+	i = MATCH_FAMILY; break;
+    case FC_CHARSET_OBJECT:
 	i = MATCH_CHARSET; break;
-    case 'a':
+    case FC_ANTIALIAS_OBJECT:
 	i = MATCH_ANTIALIAS; break;
-    case 'l':
+    case FC_LANG_OBJECT:
 	i = MATCH_LANG; break;
-    case 's':
-	switch (object[1]) {
-	case 'p':
-	    i = MATCH_SPACING; break;
-	case 't':
-	    i = MATCH_STYLE; break;
-	case 'l':
-	    i = MATCH_SLANT; break;
-	}
-	break;
-    case 'p':
+    case FC_SPACING_OBJECT:
+        i = MATCH_SPACING; break;
+    case FC_STYLE_OBJECT:
+        i = MATCH_STYLE; break;
+    case FC_SLANT_OBJECT:
+        i = MATCH_SLANT; break;
+    case FC_PIXEL_SIZE_OBJECT:
 	i = MATCH_PIXEL_SIZE; break;
-    case 'w':
-	switch (object[1]) {
-	case 'i':
-	    i = MATCH_WIDTH; break;
-	case 'e':
-	    i = MATCH_WEIGHT; break;
-	}
-	break;
-    case 'r':
+    case FC_WIDTH_OBJECT:
+        i = MATCH_WIDTH; break;
+    case FC_WEIGHT_OBJECT:
+        i = MATCH_WEIGHT; break;
+    case FC_RASTERIZER_OBJECT:
 	i = MATCH_RASTERIZER; break;
-    case 'o':
+    case FC_OUTLINE_OBJECT:
 	i = MATCH_OUTLINE; break;
     }
 
     if (i < 0)
-	return 0;
-
-    if (!matchObjectPtrsInit)
-        FcMatchObjectPtrsInit();
-
-    if (o != _FcMatchers[i].objectPtr)
-	return 0;
+	return NULL;
 
     return _FcMatchers+i;
 }
 
 static FcBool
-FcCompareValueList (FcObjectPtr o,
+FcCompareValueList (FcObject	 object,
 		    FcValueListPtr v1orig,	/* pattern */
 		    FcValueListPtr v2orig,	/* target */
 		    FcValue	*bestValue,
@@ -342,16 +296,14 @@ FcCompareValueList (FcObjectPtr o,
 		    FcResult	*result)
 {
     FcValueListPtr  v1, v2;
-    FcValueList     *v1_ptrU, *v2_ptrU;
     double    	    v, best, bestStrong, bestWeak;
     int		    j;
-    const char	    *object = FcObjectPtrU(o);
-    FcMatcher       *match = FcObjectPtrToMatcher(o);
+    FcMatcher       *match = FcObjectToMatcher(object);
 
     if (!match)
     {
 	if (bestValue)
-	    *bestValue = FcValueCanonicalize(&FcValueListPtrU(v2orig)->value);
+	    *bestValue = FcValueCanonicalize(&v2orig->value);
 	return FcTrue;
     }
 
@@ -359,13 +311,11 @@ FcCompareValueList (FcObjectPtr o,
     bestStrong = 1e99;
     bestWeak = 1e99;
     j = 0;
-    for (v1 = v1orig, v1_ptrU = FcValueListPtrU(v1); v1_ptrU;
-	 v1 = v1_ptrU->next, v1_ptrU = FcValueListPtrU(v1))
+    for (v1 = v1orig; v1; v1 = FcValueListNext(v1))
     {
-	for (v2 = v2orig, v2_ptrU = FcValueListPtrU(v2); v2_ptrU;
-	     v2 = v2_ptrU->next, v2_ptrU = FcValueListPtrU(v2))
+	for (v2 = v1orig; v2; v2 = FcValueListNext(v2))
 	{
-	    v = (match->compare) (&v1_ptrU->value, &v2_ptrU->value);
+	    v = (match->compare) (&v1->value, &v2->value);
 	    if (v < 0)
 	    {
 		*result = FcResultTypeMismatch;
@@ -375,10 +325,10 @@ FcCompareValueList (FcObjectPtr o,
 	    if (v < best)
 	    {
 		if (bestValue)
-		    *bestValue = FcValueCanonicalize(&v2_ptrU->value);
+		    *bestValue = FcValueCanonicalize(&v2->value);
 		best = v;
 	    }
-	    if (v1_ptrU->binding == FcValueBindingStrong)
+	    if (v1->binding == FcValueBindingStrong)
 	    {
 		if (v < bestStrong)
 		    bestStrong = v;
@@ -393,7 +343,7 @@ FcCompareValueList (FcObjectPtr o,
     }
     if (FcDebug () & FC_DBG_MATCHV)
     {
-	printf (" %s: %g ", object, best);
+	printf (" %s: %g ", FcObjectName (object), best);
 	FcValueListPrint (v1orig);
 	printf (", ");
 	FcValueListPrint (v2orig);
@@ -434,10 +384,10 @@ FcCompare (FcPattern	*pat,
     i2 = 0;
     while (i1 < pat->num && i2 < fnt->num)
     {
-	FcPatternElt *elt_i1 = FcPatternEltU(pat->elts)+i1;
-	FcPatternElt *elt_i2 = FcPatternEltU(fnt->elts)+i2;
+	FcPatternElt *elt_i1 = &FcPatternElts(pat)[i1];
+	FcPatternElt *elt_i2 = &FcPatternElts(fnt)[i2];
 
-	i = FcObjectPtrCompare(elt_i1->object, elt_i2->object);
+	i = FcObjectCompare(elt_i1->object, elt_i2->object);
 	if (i > 0)
 	    i2++;
 	else if (i < 0)
@@ -445,7 +395,8 @@ FcCompare (FcPattern	*pat,
 	else
 	{
 	    if (!FcCompareValueList (elt_i1->object,
-				     elt_i1->values, elt_i2->values,
+				     FcPatternEltValues(elt_i1),
+				     FcPatternEltValues(elt_i2),
 				     0, value, result))
 		return FcFalse;
 	    i1++;
@@ -471,28 +422,30 @@ FcFontRenderPrepare (FcConfig	    *confi
 	return 0;
     for (i = 0; i < font->num; i++)
     {
-	fe = FcPatternEltU(font->elts)+i;
-	pe = FcPatternFindElt (pat, FcObjectPtrU(fe->object));
+	fe = &FcPatternElts(font)[i];
+	pe = FcPatternObjectFindElt (pat, fe->object);
 	if (pe)
 	{
-	    if (!FcCompareValueList (pe->object, pe->values, 
-				     fe->values, &v, 0, &result))
+	    if (!FcCompareValueList (pe->object, FcPatternEltValues(pe), 
+				     FcPatternEltValues(fe), &v, 0, &result))
 	    {
 		FcPatternDestroy (new);
 		return 0;
 	    }
 	}
 	else
-	    v = FcValueCanonicalize(&FcValueListPtrU(fe->values)->value);
-	FcPatternAdd (new, FcObjectPtrU(fe->object), v, FcFalse);
+	    v = FcValueCanonicalize(&FcPatternEltValues (fe)->value);
+	FcPatternObjectAdd (new, fe->object, v, FcFalse);
     }
     for (i = 0; i < pat->num; i++)
     {
-	pe = FcPatternEltU(pat->elts)+i;
-	fe = FcPatternFindElt (font, FcObjectPtrU(pe->object));
+	pe = &FcPatternElts(pat)[i];
+	fe = FcPatternObjectFindElt (font, pe->object);
 	if (!fe)
-	    FcPatternAdd (new, FcObjectPtrU(pe->object), 
-                          FcValueCanonicalize(&FcValueListPtrU(pe->values)->value), FcTrue);
+	{
+	    v = FcValueCanonicalize(&FcPatternEltValues(pe)->value);
+	    FcPatternObjectAdd (new, pe->object, v, FcTrue);
+	}
     }
 
     FcConfigSubstituteWithPat (config, new, pat, FcMatchFont);
diff --git a/src/fcname.c b/src/fcname.c
index a5c8fee..96adc62 100644
--- a/src/fcname.c
+++ b/src/fcname.c
@@ -30,7 +30,7 @@
 
 /* Please do not revoke any of these bindings. */
 /* The __DUMMY__ object enables callers to distinguish the error return
- * of FcObjectToPtrLookup from FC_FAMILY's FcObjectPtr, which would
+ * of FcObjectToPtrLookup from FC_FAMILY's FcObject, which would
  * otherwise be 0. */
 static const FcObjectType _FcBaseObjectTypes[] = {
     { "__DUMMY__",      FcTypeVoid, }, 
@@ -48,14 +48,12 @@ static const FcObjectType _FcBaseObjectT
     { FC_PIXEL_SIZE,	FcTypeDouble, },
     { FC_SPACING,	FcTypeInteger, },
     { FC_FOUNDRY,	FcTypeString, },
-/*    { FC_CORE,		FcTypeBool, }, */
     { FC_ANTIALIAS,	FcTypeBool, },
     { FC_HINT_STYLE,    FcTypeInteger, },
     { FC_HINTING,	FcTypeBool, },
     { FC_VERTICAL_LAYOUT,   FcTypeBool, },
     { FC_AUTOHINT,	FcTypeBool, },
     { FC_GLOBAL_ADVANCE,    FcTypeBool, },
-/*    { FC_XLFD,		FcTypeString, }, */
     { FC_FILE,		FcTypeString, },
     { FC_INDEX,		FcTypeInteger, },
     { FC_RASTERIZER,	FcTypeString, },
@@ -65,7 +63,6 @@ static const FcObjectType _FcBaseObjectT
     { FC_RGBA,		FcTypeInteger, },
     { FC_SCALE,		FcTypeDouble, },
     { FC_MINSPACE,	FcTypeBool, },
-/*    { FC_RENDER,	FcTypeBool, },*/
     { FC_CHAR_WIDTH,	FcTypeInteger },
     { FC_CHAR_HEIGHT,	FcTypeInteger },
     { FC_MATRIX,	FcTypeMatrix },
@@ -182,16 +179,13 @@ static struct objectBucket *FcObjectBuck
 /* Design constraint: biggest_known_ntypes must never change
  * after any call to FcNameRegisterObjectTypes. */
 static const FcObjectType *biggest_known_types = _FcBaseObjectTypes; 
-static FcBool allocated_biggest_known_types;
 static int biggest_known_ntypes = NUM_OBJECT_TYPES;
-static int biggest_known_count = 0;
-static char * biggest_ptr;
 
 
-static FcObjectPtr
+static FcObject
 FcObjectToPtrLookup (const char * object)
 {
-    FcObjectPtr		    i = 0, n;
+    FcObject		    i = 0, n;
     const FcObjectTypeList  *l;
     FcObjectType	    *t = _FcUserObjectNames;
     FcBool		    replace;
@@ -251,8 +245,16 @@ FcObjectToPtrLookup (const char * object
     return -n;
 }
 
-FcObjectPtr
-FcObjectToPtr (const char * name)
+FcBool
+FcObjectValidType (FcObject object, FcType type)
+{
+    if (object < NUM_OBJECT_TYPES && _FcBaseObjectTypes[object].type != type)
+	return FcFalse;
+    return FcTrue;
+}
+
+FcObject
+FcObjectFromName (const char * name)
 {
     FcChar32            hash = FcStringHash ((const FcChar8 *) name);
     struct objectBucket **p;
@@ -299,112 +301,24 @@ FcObjectStaticNameFini (void)
 }
 
 const char *
-FcObjectPtrU (FcObjectPtr si)
+FcObjectName (FcObject object)
 {
     const FcObjectTypeList  *l;
     int i, j;
 
-    if (si > 0)
+    if (object > 0)
     {
-        if (si < biggest_known_ntypes)
-            return biggest_known_types[si].object;
+        if (object < biggest_known_ntypes)
+            return biggest_known_types[object].object;
 
         j = 0;
         for (l = _FcObjectTypes; l; l = l->next)
             for (i = 0; i < l->ntypes; i++, j++)
-                if (j == si)
+                if (j == object)
                     return l->types[i].object;
     }
 
-    return _FcUserObjectNames[-si].object;
-}
-
-int
-FcObjectNeededBytes ()
-{
-    int num = 0, i;
-    for (i = 0; i < biggest_known_ntypes; i++)
-    {
-	const char * t = biggest_known_types[i].object;
-	num = num + strlen(t) + 1;
-    }
-    biggest_known_count = num;
-    return num + sizeof(int);
-}
-
-int
-FcObjectNeededBytesAlign (void)
-{
-    return fc_alignof (int) + fc_alignof (char);
-}
-
-void *
-FcObjectDistributeBytes (FcCache * metadata, void * block_ptr)
-{
-    block_ptr = ALIGN (block_ptr, int);
-    *(int *)block_ptr = biggest_known_ntypes;
-    block_ptr = (int *) block_ptr + 1;
-    block_ptr = ALIGN (block_ptr, char);
-    biggest_ptr = block_ptr;
-    block_ptr = (char *) block_ptr + biggest_known_count;
-    return block_ptr;
-}
-
-void
-FcObjectSerialize (void)
-{
-    int i;
-    for (i = 0; i < biggest_known_ntypes; i++)
-    {
-	const char * t = biggest_known_types[i].object;
-	strcpy (biggest_ptr, t);
-	biggest_ptr = biggest_ptr + strlen(t) + 1;
-    }
-}
-
-void *
-FcObjectUnserialize (FcCache * metadata, void *block_ptr)
-{
-    int new_biggest;
-    block_ptr = ALIGN (block_ptr, int);
-    new_biggest = *(int *)block_ptr;
-    block_ptr = (int *) block_ptr + 1;
-    if (biggest_known_ntypes < new_biggest)
-    {
-	int i;
-	char * bp = (char *)block_ptr;
-	FcObjectType * bn;
-
-	bn = malloc (sizeof (const FcObjectType) * (new_biggest + 1));
-	if (!bn)
-	    return 0;
-
-	for (i = 0; i < new_biggest; i++)
-	{
-	    const FcObjectType * t = FcNameGetObjectType(bp);
-	    if (t)
-		bn[i].type = t->type;
-	    else
-		bn[i].type = FcTypeVoid;
-	    bn[i].object = bp;
-	    bp = bp + strlen(bp) + 1;
-	}
-
-	FcNameUnregisterObjectTypesFree (biggest_known_types, biggest_known_ntypes, FcFalse);
-	if (allocated_biggest_known_types)
-	{
-	    free ((FcObjectTypeList *)biggest_known_types);
-	}
-	else
-	    allocated_biggest_known_types = FcTrue;
-
-	FcNameRegisterObjectTypes (bn, new_biggest);
-	biggest_known_ntypes = new_biggest;
-	biggest_known_types = (const FcObjectType *)bn;
-    }
-    block_ptr = ALIGN (block_ptr, char);
-    block_ptr = (char *) block_ptr + biggest_known_count;
-    return block_ptr;
+    return _FcUserObjectNames[-object].object;
 }
 
 static const FcConstant _FcBaseConstants[] = {
@@ -803,11 +717,11 @@ FcNameUnparseValueList (FcStrBuf	*buf,
 			FcValueListPtr	v,
 			FcChar8		*escape)
 {
-    while (FcValueListPtrU(v))
+    while (v)
     {
-	if (!FcNameUnparseValue (buf, &FcValueListPtrU(v)->value, escape))
+	if (!FcNameUnparseValue (buf, &v->value, escape))
 	    return FcFalse;
-	if (FcValueListPtrU(v = FcValueListPtrU(v)->next))
+	if ((v = FcValueListNext(v)) != NULL)
 	    if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0))
 		return FcFalse;
     }
@@ -834,18 +748,18 @@ FcNameUnparseEscaped (FcPattern *pat, Fc
     const FcObjectType	    *o;
 
     FcStrBufInit (&buf, buf_static, sizeof (buf_static));
-    e = FcPatternFindElt (pat, FC_FAMILY);
+    e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT);
     if (e)
     {
-        if (!FcNameUnparseValueList (&buf, e->values, escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
+        if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
 	    goto bail0;
     }
-    e = FcPatternFindElt (pat, FC_SIZE);
+    e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT);
     if (e)
     {
 	if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0))
 	    goto bail0;
-	if (!FcNameUnparseValueList (&buf, e->values, escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
+	if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
 	    goto bail0;
     }
     for (l = _FcObjectTypes; l; l = l->next)
@@ -858,7 +772,7 @@ FcNameUnparseEscaped (FcPattern *pat, Fc
 		!strcmp (o->object, FC_FILE))
 		continue;
 	    
-	    e = FcPatternFindElt (pat, o->object);
+	    e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object));
 	    if (e)
 	    {
 		if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0))
@@ -867,7 +781,7 @@ FcNameUnparseEscaped (FcPattern *pat, Fc
 		    goto bail0;
 		if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0))
 		    goto bail0;
-		if (!FcNameUnparseValueList (&buf, e->values, escape ? 
+		if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? 
 					     (FcChar8 *) FC_ESCAPE_VARIABLE : 0))
 		    goto bail0;
 	    }
diff --git a/src/fcpat.c b/src/fcpat.c
index da1d490..7432745 100644
--- a/src/fcpat.c
+++ b/src/fcpat.c
@@ -1,6 +1,4 @@
 /*
- * $RCSId: xc/lib/fontconfig/src/fcpat.c,v 1.18 2002/09/18 17:11:46 tsi Exp $
- *
  * Copyright © 2000 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -27,15 +25,6 @@
 #include <string.h>
 #include <assert.h>
 
-static FcPattern ** _fcPatterns = 0;
-static int fcpattern_bank_count = 0, fcpattern_ptr, fcpattern_count;
-FcPatternElt ** _fcPatternElts = 0;
-static int fcpatternelt_ptr, fcpatternelt_count;
-FcValueList ** _fcValueLists = 0;
-static int fcvaluelist_bank_count = 0, fcvaluelist_ptr, fcvaluelist_count;
-
-static FcPatternEltPtr
-FcPatternEltPtrCreateDynamic (FcPatternElt * e);
 static FcBool
 FcStrHashed (const FcChar8 *name);
 
@@ -50,8 +39,7 @@ FcPatternCreate (void)
     FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern));
     p->num = 0;
     p->size = 0;
-    p->elts = FcPatternEltPtrCreateDynamic(0);
-    p->bank = FC_BANK_DYNAMIC;
+    p->elts_offset = FcPtrToOffset (p, NULL);
     p->ref = 1;
     return p;
 }
@@ -81,28 +69,27 @@ FcValueDestroy (FcValue v)
 FcValue
 FcValueCanonicalize (const FcValue *v)
 {
-    if (v->type & FC_STORAGE_STATIC)
-    {
-	FcValue new = *v;
+    FcValue new;
 
-	switch (v->type & ~FC_STORAGE_STATIC)
-	{
-	case FcTypeString:
-	    new.u.s = fc_value_string(v);
-	    new.type = FcTypeString;
-	    break;
-	case FcTypeCharSet:
-	    new.u.c = fc_value_charset(v);
-	    new.type = FcTypeCharSet;
-	    break;
-	case FcTypeLangSet:
-	    new.u.l = fc_value_langset(v);
-	    new.type = FcTypeLangSet;
-	    break;
-	}
-	return new;
+    switch (v->type)
+    {
+    case FcTypeString:
+	new.u.s = fc_value_string(v);
+	new.type = FcTypeString;
+	break;
+    case FcTypeCharSet:
+	new.u.c = fc_value_charset(v);
+	new.type = FcTypeCharSet;
+	break;
+    case FcTypeLangSet:
+	new.u.l = fc_value_langset(v);
+	new.type = FcTypeLangSet;
+	break;
+    default:
+	new = *v;
+	break;
     }
-    return *v;
+    return new;
 }
 
 FcValue
@@ -139,31 +126,30 @@ void
 FcValueListDestroy (FcValueListPtr l)
 {
     FcValueListPtr next;
-    for (; FcValueListPtrU(l); l = next)
+    for (; l; l = next)
     {
-	switch (FcValueListPtrU(l)->value.type) {
+	switch (l->value.type) {
 	case FcTypeString:
-            if (!FcStrHashed ((FcChar8 *)FcValueListPtrU(l)->value.u.s))
-                FcStrFree ((FcChar8 *)FcValueListPtrU(l)->value.u.s);
+            if (!FcStrHashed ((FcChar8 *)l->value.u.s))
+                FcStrFree ((FcChar8 *)l->value.u.s);
 	    break;
 	case FcTypeMatrix:
-	    FcMatrixFree ((FcMatrix *)FcValueListPtrU(l)->value.u.m);
+	    FcMatrixFree ((FcMatrix *)l->value.u.m);
 	    break;
 	case FcTypeCharSet:
 	    FcCharSetDestroy 
-		((FcCharSet *) (FcValueListPtrU(l)->value.u.c));
+		((FcCharSet *) (l->value.u.c));
 	    break;
 	case FcTypeLangSet:
 	    FcLangSetDestroy 
-		((FcLangSet *) (FcValueListPtrU(l)->value.u.l));
+		((FcLangSet *) (l->value.u.l));
 	    break;
 	default:
 	    break;
 	}
-	next = FcValueListPtrU(l)->next;
+	next = FcValueListNext(l);
 	FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
-	if (l.bank == FC_BANK_DYNAMIC)
-	    free(l.u.dyn);
+	free(l);
     }
 }
 
@@ -263,18 +249,17 @@ FcValueHash (const FcValue *v)
 static FcBool
 FcValueListEqual (FcValueListPtr la, FcValueListPtr lb)
 {
-    if (FcValueListPtrU(la) == FcValueListPtrU(lb))
+    if (la == lb)
 	return FcTrue;
 
-    while (FcValueListPtrU(la) && FcValueListPtrU(lb))
+    while (la && lb)
     {
-	if (!FcValueEqual (FcValueListPtrU(la)->value, 
-			   FcValueListPtrU(lb)->value))
+	if (!FcValueEqual (la->value, lb->value))
 	    return FcFalse;
-	la = FcValueListPtrU(la)->next;
-	lb = FcValueListPtrU(lb)->next;
+	la = FcValueListNext(la);
+	lb = FcValueListNext(lb);
     }
-    if (FcValueListPtrU(la) || FcValueListPtrU(lb))
+    if (la || lb)
 	return FcFalse;
     return FcTrue;
 }
@@ -283,12 +268,10 @@ static FcChar32
 FcValueListHash (FcValueListPtr l)
 {
     FcChar32	hash = 0;
-    FcValueList *l_ptrU;
     
-    for (l_ptrU = FcValueListPtrU(l); l_ptrU; 
-	 l_ptrU = FcValueListPtrU(l_ptrU->next))
+    for (; l; l = FcValueListNext(l))
     {
-	hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (&l_ptrU->value);
+	hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (&l->value);
     }
     return hash;
 }
@@ -297,32 +280,27 @@ void
 FcPatternDestroy (FcPattern *p)
 {
     int		    i;
+    FcPatternElt    *elts;
     
     if (p->ref == FC_REF_CONSTANT || --p->ref > 0)
 	return;
 
+    elts = FcPatternElts (p);
     for (i = 0; i < p->num; i++)
-	FcValueListDestroy ((FcPatternEltU(p->elts)+i)->values);
+	FcValueListDestroy (FcPatternEltValues(&elts[i]));
 
-    p->num = 0;
-    if (FcPatternEltU(p->elts) && p->elts.bank == FC_BANK_DYNAMIC)
-    {
-	FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
-	free (FcPatternEltU(p->elts));
-	p->elts = FcPatternEltPtrCreateDynamic(0);
-    }
-    p->size = 0;
+    FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
+    free (elts);
     FcMemFree (FC_MEM_PATTERN, sizeof (FcPattern));
     free (p);
 }
 
 static int
-FcPatternPosition (const FcPattern *p, const char *object)
+FcPatternObjectPosition (const FcPattern *p, FcObject object)
 {
     int	    low, high, mid, c;
-    FcObjectPtr obj;
+    FcPatternElt    *elts = FcPatternElts(p);
 
-    obj = FcObjectToPtr(object);
     low = 0;
     high = p->num - 1;
     c = 1;
@@ -330,7 +308,7 @@ FcPatternPosition (const FcPattern *p, c
     while (low <= high)
     {
 	mid = (low + high) >> 1;
-	c = FcObjectPtrCompare((FcPatternEltU(p->elts)+mid)->object, obj);
+	c = elts[mid].object - object;
 	if (c == 0)
 	    return mid;
 	if (c < 0)
@@ -344,21 +322,21 @@ FcPatternPosition (const FcPattern *p, c
 }
 
 FcPatternElt *
-FcPatternFindElt (const FcPattern *p, const char *object)
+FcPatternObjectFindElt (const FcPattern *p, FcObject object)
 {
-    int	    i = FcPatternPosition (p, object);
+    int	    i = FcPatternObjectPosition (p, object);
     if (i < 0)
 	return 0;
-    return FcPatternEltU(p->elts)+i;
+    return &FcPatternElts(p)[i];
 }
 
 FcPatternElt *
-FcPatternInsertElt (FcPattern *p, const char *object)
+FcPatternObjectInsertElt (FcPattern *p, FcObject object)
 {
     int		    i;
     FcPatternElt   *e;
     
-    i = FcPatternPosition (p, object);
+    i = FcPatternObjectPosition (p, object);
     if (i < 0)
     {
 	i = -i - 1;
@@ -367,9 +345,9 @@ FcPatternInsertElt (FcPattern *p, const 
 	if (p->num + 1 >= p->size)
 	{
 	    int s = p->size + 16;
-	    if (FcPatternEltU(p->elts))
+	    if (p->size)
 	    {
-		FcPatternElt *e0 = FcPatternEltU(p->elts);
+		FcPatternElt *e0 = FcPatternElts(p);
 		e = (FcPatternElt *) realloc (e0, s * sizeof (FcPatternElt));
 		if (!e) /* maybe it was mmapped */
 		{
@@ -382,52 +360,54 @@ FcPatternInsertElt (FcPattern *p, const 
 		e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt));
 	    if (!e)
 		return FcFalse;
-	    p->elts = FcPatternEltPtrCreateDynamic(e);
+	    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)
 	    {
-		(FcPatternEltU(p->elts)+p->size)->object = 0;
-		(FcPatternEltU(p->elts)+p->size)->values = 
-		    FcValueListPtrCreateDynamic(0);
+		e[p->size].object = 0;
+		e[p->size].values = NULL;
 		p->size++;
 	    }
 	}
 	
+	e = FcPatternElts(p);
 	/* move elts up */
-	memmove (FcPatternEltU(p->elts) + i + 1,
-		 FcPatternEltU(p->elts) + i,
+	memmove (e + i + 1,
+		 e + i,
 		 sizeof (FcPatternElt) *
 		 (p->num - i));
 		 
 	/* bump count */
 	p->num++;
 	
-	(FcPatternEltU(p->elts)+i)->object = FcObjectToPtr (object);
-	(FcPatternEltU(p->elts)+i)->values = FcValueListPtrCreateDynamic(0);
+	e[i].object = object;
+	e[i].values = NULL;
     }
     
-    return FcPatternEltU(p->elts)+i;
+    return FcPatternElts(p) + i;
 }
 
 FcBool
 FcPatternEqual (const FcPattern *pa, const FcPattern *pb)
 {
     int	i;
+    FcPatternElt   *pae, *pbe;
 
     if (pa == pb)
 	return FcTrue;
 
     if (pa->num != pb->num)
 	return FcFalse;
+    pae = FcPatternElts(pa);
+    pbe = FcPatternElts(pb);
     for (i = 0; i < pa->num; i++)
     {
-	if (FcObjectPtrCompare((FcPatternEltU(pa->elts)+i)->object,
-			       (FcPatternEltU(pb->elts)+i)->object) != 0)
+	if (pae[i].object != pbe[i].object)
 	    return FcFalse;
-	if (!FcValueListEqual ((FcPatternEltU(pa->elts)+i)->values, 
-			       (FcPatternEltU(pb->elts)+i)->values))
+	if (!FcValueListEqual (FcPatternEltValues(&pae[i]),
+			       FcPatternEltValues(&pbe[i])))
 	    return FcFalse;
     }
     return FcTrue;
@@ -438,12 +418,13 @@ FcPatternHash (const FcPattern *p)
 {
     int		i;
     FcChar32	h = 0;
+    FcPatternElt    *pe = FcPatternElts(p);
 
     for (i = 0; i < p->num; i++)
     {
 	h = (((h << 1) | (h >> 31)) ^ 
-	     FcStringHash ((FcChar8 *)FcObjectPtrU ((FcPatternEltU(p->elts)+i)->object)) ^
-	     FcValueListHash ((FcPatternEltU(p->elts)+i)->values));
+	     pe[i].object ^
+	     FcValueListHash (FcPatternEltValues(&pe[i])));
     }
     return h;
 }
@@ -456,13 +437,14 @@ FcPatternEqualSubset (const FcPattern *p
     
     for (i = 0; i < os->nobject; i++)
     {
-	ea = FcPatternFindElt (pai, os->objects[i]);
-	eb = FcPatternFindElt (pbi, os->objects[i]);
+	FcObject    object = FcObjectFromName (os->objects[i]);
+	ea = FcPatternObjectFindElt (pai, object);
+	eb = FcPatternObjectFindElt (pbi, object);
 	if (ea)
 	{
 	    if (!eb)
 		return FcFalse;
-	    if (!FcValueListEqual (ea->values, eb->values))
+	    if (!FcValueListEqual (FcPatternEltValues(ea), FcPatternEltValues(eb)))
 		return FcFalse;
 	}
 	else
@@ -475,26 +457,23 @@ FcPatternEqualSubset (const FcPattern *p
 }
 
 FcBool
-FcPatternAddWithBinding  (FcPattern	    *p,
-			  const char	    *object,
-			  FcValue	    value,
-			  FcValueBinding    binding,
-			  FcBool	    append)
+FcPatternObjectAddWithBinding  (FcPattern	*p,
+				FcObject	object,
+				FcValue		value,
+				FcValueBinding  binding,
+				FcBool		append)
 {
     FcPatternElt   *e;
     FcValueListPtr new, *prev;
-    FcValueList    *newp;
-    FcObjectPtr    objectPtr;
 
     if (p->ref == FC_REF_CONSTANT)
 	goto bail0;
 
-    newp = malloc (sizeof (FcValueList));
-    if (!newp)
+    new = malloc (sizeof (FcValueList));
+    if (!new)
 	goto bail0;
 
-    memset(newp, 0, sizeof (FcValueList));
-    new = FcValueListPtrCreateDynamic(newp);
+    memset(new, 0, sizeof (FcValueList));
     FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
     /* dup string */
     if (value.type == FcTypeString)
@@ -508,88 +487,70 @@ FcPatternAddWithBinding  (FcPattern	    
     if (value.type == FcTypeVoid)
 	goto bail1;
 
-    /* quick and dirty hack to enable FcCompareFamily/FcCompareString
-     * speedup: only allow strings to be added under the FC_FAMILY,
-     * FC_FOUNDRY, FC_STYLE, FC_RASTERIZER keys.  
-     * and charsets under FC_CHARSET key.
-     * This is slightly semantically different from the old behaviour,
-     * but fonts shouldn't be getting non-strings here anyway.
-     * a better hack would use FcBaseObjectTypes to check all objects. */
-    objectPtr = FcObjectToPtr(object);
-    if ((objectPtr == FcObjectToPtr(FC_FAMILY)
-         || objectPtr == FcObjectToPtr(FC_FOUNDRY)
-         || objectPtr == FcObjectToPtr(FC_STYLE)
-         || objectPtr == FcObjectToPtr(FC_RASTERIZER))
-        && value.type != FcTypeString)
-        goto bail1;
-    if (objectPtr == FcObjectToPtr(FC_CHARSET)
-        && value.type != FcTypeCharSet)
-        goto bail1;
-
-    FcValueListPtrU(new)->value = value;
-    FcValueListPtrU(new)->binding = binding;
-    FcValueListPtrU(new)->next = FcValueListPtrCreateDynamic(0);
+    /*
+     * Make sure the stored type is valid for built-in objects
+     */
+    if (!FcObjectValidType (object, value.type))
+	goto bail1;
+
+    new->value = value;
+    new->binding = binding;
+    new->next = NULL;
     
-    e = FcPatternInsertElt (p, object);
+    e = FcPatternObjectInsertElt (p, object);
     if (!e)
 	goto bail2;
     
     if (append)
     {
-	for (prev = &e->values; FcValueListPtrU(*prev); prev = &FcValueListPtrU(*prev)->next)
+	for (prev = &e->values; *prev; prev = &(*prev)->next)
 	    ;
 	*prev = new;
     }
     else
     {
-	FcValueListPtrU(new)->next = e->values;
+	new->next = e->values;
 	e->values = new;
     }
     
     return FcTrue;
 
 bail2:    
-    switch (value.type) {
-    case FcTypeString:
-	FcStrFree ((FcChar8 *) value.u.s);
-	break;
-    case FcTypeMatrix:
-	FcMatrixFree ((FcMatrix *) value.u.m);
-	break;
-    case FcTypeCharSet:
-	FcCharSetDestroy ((FcCharSet *) value.u.c);
-	break;
-    case FcTypeLangSet:
-	FcLangSetDestroy ((FcLangSet *) value.u.l);
-	break;
-    default:
-	break;
-    }
+    FcValueDestroy (value);
 bail1:
     FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
-    free (FcValueListPtrU(new));
+    free (new);
 bail0:
     return FcFalse;
 }
 
 FcBool
+FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append)
+{
+    return FcPatternObjectAddWithBinding (p, object,
+					  value, FcValueBindingStrong, append);
+}
+
+FcBool
 FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append)
 {
-    return FcPatternAddWithBinding (p, object, value, FcValueBindingStrong, append);
+    return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
+					  value, FcValueBindingStrong, append);
 }
 
 FcBool
 FcPatternAddWeak  (FcPattern *p, const char *object, FcValue value, FcBool append)
 {
-    return FcPatternAddWithBinding (p, object, value, FcValueBindingWeak, append);
+    return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
+					  value, FcValueBindingWeak, append);
 }
 
 FcBool
-FcPatternDel (FcPattern *p, const char *object)
+FcPatternObjectDel (FcPattern *p, FcObject object)
 {
     FcPatternElt   *e;
 
-    e = FcPatternFindElt (p, object);
+    e = FcPatternObjectFindElt (p, object);
     if (!e)
 	return FcFalse;
 
@@ -598,33 +559,38 @@ FcPatternDel (FcPattern *p, const char *
     
     /* shuffle existing ones down */
     memmove (e, e+1, 
-	     (FcPatternEltU(p->elts) + p->num - (e + 1)) * 
+	     (FcPatternElts(p) + p->num - (e + 1)) * 
 	     sizeof (FcPatternElt));
     p->num--;
-    (FcPatternEltU(p->elts)+p->num)->object = 0;
-    (FcPatternEltU(p->elts)+p->num)->values = FcValueListPtrCreateDynamic(0);
+    e = FcPatternElts(p) + p->num;
+    e->object = 0;
+    e->values = NULL;
     return FcTrue;
 }
 
 FcBool
+FcPatternDel (FcPattern *p, const char *object)
+{
+    return FcPatternObjectDel (p, FcObjectFromName (object));
+}
+    
+FcBool
 FcPatternRemove (FcPattern *p, const char *object, int id)
 {
     FcPatternElt    *e;
     FcValueListPtr  *prev, l;
 
-    e = FcPatternFindElt (p, object);
+    e = FcPatternObjectFindElt (p, FcObjectFromName (object));
     if (!e)
 	return FcFalse;
-    for (prev = &e->values; 
-	 FcValueListPtrU(l = *prev); 
-	 prev = &FcValueListPtrU(l)->next)
+    for (prev = &e->values; (l = *prev); prev = &l->next)
     {
 	if (!id)
 	{
-	    *prev = FcValueListPtrU(l)->next;
-	    FcValueListPtrU(l)->next = FcValueListPtrCreateDynamic(0);
+	    *prev = l->next;
+	    l->next = NULL;
 	    FcValueListDestroy (l);
-	    if (!FcValueListPtrU(e->values))
+	    if (!e->values)
 		FcPatternDel (p, object);
 	    return FcTrue;
 	}
@@ -634,28 +600,40 @@ FcPatternRemove (FcPattern *p, const cha
 }
 
 FcBool
-FcPatternAddInteger (FcPattern *p, const char *object, int i)
+FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i)
 {
     FcValue	v;
 
     v.type = FcTypeInteger;
     v.u.i = i;
-    return FcPatternAdd (p, object, v, FcTrue);
+    return FcPatternObjectAdd (p, object, v, FcTrue);
 }
 
 FcBool
-FcPatternAddDouble (FcPattern *p, const char *object, double d)
+FcPatternAddInteger (FcPattern *p, const char *object, int i)
+{
+    return FcPatternObjectAddInteger (p, FcObjectFromName (object), i);
+}
+
+FcBool
+FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d)
 {
     FcValue	v;
 
     v.type = FcTypeDouble;
     v.u.d = d;
-    return FcPatternAdd (p, object, v, FcTrue);
+    return FcPatternObjectAdd (p, object, v, FcTrue);
 }
 
 
 FcBool
-FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
+FcPatternAddDouble (FcPattern *p, const char *object, double d)
+{
+    return FcPatternObjectAddDouble (p, FcObjectFromName (object), d);
+}
+
+FcBool
+FcPatternObjectAddString (FcPattern *p, FcObject object, const FcChar8 *s)
 {
     FcValue	v;
 
@@ -663,12 +641,18 @@ FcPatternAddString (FcPattern *p, const 
     {
 	v.type = FcTypeVoid;
 	v.u.s = 0;
-	return FcPatternAdd (p, object, v, FcTrue);
+	return FcPatternObjectAdd (p, object, v, FcTrue);
     }
 
     v.type = FcTypeString;
     v.u.s = FcStrStaticName(s);
-    return FcPatternAdd (p, object, v, FcTrue);
+    return FcPatternObjectAdd (p, object, v, FcTrue);
+}
+
+FcBool
+FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
+{
+    return FcPatternObjectAddString (p, FcObjectFromName (object), s);
 }
 
 FcBool
@@ -683,13 +667,19 @@ FcPatternAddMatrix (FcPattern *p, const 
 
 
 FcBool
-FcPatternAddBool (FcPattern *p, const char *object, FcBool b)
+FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b)
 {
     FcValue	v;
 
     v.type = FcTypeBool;
     v.u.b = b;
-    return FcPatternAdd (p, object, v, FcTrue);
+    return FcPatternObjectAdd (p, object, v, FcTrue);
+}
+
+FcBool
+FcPatternAddBool (FcPattern *p, const char *object, FcBool b)
+{
+    return FcPatternObjectAddBool (p, FcObjectFromName (object), b);
 }
 
 FcBool
@@ -723,19 +713,19 @@ FcPatternAddLangSet (FcPattern *p, const
 }
 
 FcResult
-FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v)
+FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v)
 {
     FcPatternElt   *e;
     FcValueListPtr l;
 
-    e = FcPatternFindElt (p, object);
+    e = FcPatternObjectFindElt (p, object);
     if (!e)
 	return FcResultNoMatch;
-    for (l = e->values; FcValueListPtrU(l); l = FcValueListPtrU(l)->next)
+    for (l = FcPatternEltValues(e); l; l = FcValueListNext(l))
     {
 	if (!id)
 	{
-	    *v = FcValueCanonicalize(&FcValueListPtrU(l)->value);
+	    *v = FcValueCanonicalize(&l->value);
 	    return FcResultMatch;
 	}
 	id--;
@@ -744,12 +734,18 @@ FcPatternGet (const FcPattern *p, const 
 }
 
 FcResult
-FcPatternGetInteger (const FcPattern *p, const char *object, int id, int *i)
+FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v)
+{
+    return FcPatternObjectGet (p, FcObjectFromName (object), id, v);
+}
+
+FcResult
+FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int id, int *i)
 {
     FcValue	v;
     FcResult	r;
 
-    r = FcPatternGet (p, object, id, &v);
+    r = FcPatternObjectGet (p, object, id, &v);
     if (r != FcResultMatch)
 	return r;
     switch (v.type) {
@@ -766,12 +762,19 @@ FcPatternGetInteger (const FcPattern *p,
 }
 
 FcResult
-FcPatternGetDouble (const FcPattern *p, const char *object, int id, double *d)
+FcPatternGetInteger (const FcPattern *p, const char *object, int id, int *i)
+{
+    return FcPatternObjectGetInteger (p, FcObjectFromName (object), id, i);
+}
+    
+    
+FcResult
+FcPatternObjectGetDouble (const FcPattern *p, FcObject object, int id, double *d)
 {
     FcValue	v;
     FcResult	r;
 
-    r = FcPatternGet (p, object, id, &v);
+    r = FcPatternObjectGet (p, object, id, &v);
     if (r != FcResultMatch)
 	return r;
     switch (v.type) {
@@ -788,12 +791,18 @@ FcPatternGetDouble (const FcPattern *p, 
 }
 
 FcResult
-FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s)
+FcPatternGetDouble (const FcPattern *p, const char *object, int id, double *d)
+{
+    return FcPatternObjectGetDouble (p, FcObjectFromName (object), id, d);
+}
+
+FcResult
+FcPatternObjectGetString (const FcPattern *p, FcObject object, int id, FcChar8 ** s)
 {
     FcValue	v;
     FcResult	r;
 
-    r = FcPatternGet (p, object, id, &v);
+    r = FcPatternObjectGet (p, object, id, &v);
     if (r != FcResultMatch)
 	return r;
     if (v.type != FcTypeString)
@@ -804,6 +813,12 @@ FcPatternGetString (const FcPattern *p, 
 }
 
 FcResult
+FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s)
+{
+    return FcPatternObjectGetString (p, FcObjectFromName (object), id, s);
+}
+    
+FcResult
 FcPatternGetMatrix(const FcPattern *p, const char *object, int id, FcMatrix **m)
 {
     FcValue	v;
@@ -891,16 +906,14 @@ FcPatternDuplicate (const FcPattern *ori
     if (!new)
 	goto bail0;
 
-    e = FcPatternEltU(orig->elts);
+    e = FcPatternElts(orig);
 
     for (i = 0; i < orig->num; i++)
     {
-	for (l = (e + i)->values; 
-	     FcValueListPtrU(l); 
-	     l = FcValueListPtrU(l)->next)
-	    if (!FcPatternAdd (new, FcObjectPtrU((e + i)->object), 
-                               FcValueCanonicalize(&FcValueListPtrU(l)->value),
-			       FcTrue))
+	for (l = FcPatternEltValues(e + i); l; l = FcValueListNext(l))
+	    if (!FcPatternObjectAdd (new, e[i].object,
+				     FcValueCanonicalize(&l->value),
+				     FcTrue))
 		goto bail1;
     }
 
@@ -951,13 +964,12 @@ FcPatternAppend (FcPattern *p, FcPattern
     
     for (i = 0; i < s->num; i++)
     {
-	e = FcPatternEltU(s->elts)+i;
-	for (v = e->values; FcValueListPtrU(v); 
-	     v = FcValueListPtrU(v)->next)
+	e = FcPatternElts(s)+i;
+	for (v = FcPatternEltValues(e); v; v = FcValueListNext(v))
 	{
-	    if (!FcPatternAddWithBinding (p, FcObjectPtrU(e->object),
-					  FcValueCanonicalize(&FcValueListPtrU(v)->value), 
-					  FcValueListPtrU(v)->binding, FcTrue))
+	    if (!FcPatternObjectAddWithBinding (p, e->object,
+						FcValueCanonicalize(&v->value), 
+						v->binding, FcTrue))
 		return FcFalse;
 	}
     }
@@ -1035,561 +1047,140 @@ FcPatternFini (void)
     FcObjectStaticNameFini ();
 }
 
-static FcPatternEltPtr
-FcPatternEltPtrCreateDynamic (FcPatternElt * e)
-{
-    FcPatternEltPtr new;
-    new.bank = FC_BANK_DYNAMIC;
-    new.u.dyn = e;
-    return new;
-}
-
-static FcPatternEltPtr
-FcPatternEltPtrCreateStatic (int bank, int i)
-{
-    FcPatternEltPtr new;
-    new.bank = bank;
-    new.u.stat = i;
-    return new;
-}
-
-static void
-FcStrNewBank (void);
-static int
-FcStrNeededBytes (const FcChar8 * s);
-static int
-FcStrNeededBytesAlign (void);
-static void *
-FcStrDistributeBytes (FcCache * metadata, void * block_ptr);
-static const FcChar8 *
-FcStrSerialize (int bank, const FcChar8 * s);
-static void *
-FcStrUnserialize (FcCache * metadata, void *block_ptr);
-
-static void
-FcValueListNewBank (void);
-static int
-FcValueListNeededBytes (FcValueList * vl);
-static int
-FcValueListNeededBytesAlign (void);
-static void *
-FcValueListDistributeBytes (FcCache * metadata, void *block_ptr);
-static FcValueListPtr
-FcValueListSerialize(int bank, FcValueList *pi);
-static void *
-FcValueListUnserialize (FcCache * metadata, void *block_ptr);
-
-
-void
-FcPatternNewBank (void)
-{
-    fcpattern_count = 0;
-    fcpatternelt_count = 0;
-
-    FcStrNewBank();
-    FcValueListNewBank();
-}
-
-int
-FcPatternNeededBytes (FcPattern * p)
-{
-    int i, cum = 0, c;
-
-    fcpattern_count++;
-    fcpatternelt_count += p->num;
-
-    for (i = 0; i < p->num; i++)
-    {
-	c = FcValueListNeededBytes (FcValueListPtrU
-				    (((FcPatternEltU(p->elts)+i)->values)));
-	if (c < 0)
-	    return c;
-	cum += c;
-    }
-
-    return cum + sizeof (FcPattern) + sizeof(FcPatternElt)*p->num;
-}
-
-int
-FcPatternNeededBytesAlign (void)
-{
-    return fc_alignof (FcPattern) + fc_alignof (FcPatternElt) + 
-	FcValueListNeededBytesAlign ();
-}
-
-static FcBool
-FcPatternEnsureBank (int bi)
+FcBool
+FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat)
 {
-    FcPattern **pp;
-    FcPatternElt **ep;
-    int i;
-
-    if (!_fcPatterns || fcpattern_bank_count <= bi)
-    {
-	int new_count = bi + 4;
-	pp = realloc (_fcPatterns, sizeof (FcPattern *) * new_count);
-	if (!pp)
-	    return 0;
-
-	FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern *) * new_count);
-	_fcPatterns = pp;
-
-	ep = realloc (_fcPatternElts, sizeof (FcPatternElt *) * new_count);
-	if (!ep)
-	    return 0;
-
-	FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt *) * new_count);
-	_fcPatternElts = ep;
-
-	for (i = fcpattern_bank_count; i < new_count; i++)
-	{
-	    _fcPatterns[i] = 0;
-	    _fcPatternElts[i] = 0;
-	}
-
-	fcpattern_bank_count = new_count;
-    }
-
-    FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern) * fcpattern_count);
+    int	i;
+    FcPatternElt    *elts = FcPatternElts(pat);
+    
+    if (!FcSerializeAlloc (serialize, pat, sizeof (FcPattern)))
+	return FcFalse;
+    if (!FcSerializeAlloc (serialize, elts, pat->num * sizeof (FcPatternElt)))
+	return FcFalse;
+    for (i = 0; i < pat->num; i++)
+	if (!FcValueListSerializeAlloc (serialize, FcPatternEltValues(elts+i)))
+	    return FcFalse;
     return FcTrue;
 }
 
-void *
-FcPatternDistributeBytes (FcCache * metadata, void * block_ptr)
-{
-    int bi = FcCacheBankToIndex(metadata->bank);
-
-    if (!FcPatternEnsureBank(bi))
-	return 0;
-
-    fcpattern_ptr = 0;
-    block_ptr = ALIGN(block_ptr, FcPattern);
-    _fcPatterns[bi] = (FcPattern *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr + 
-			 (sizeof (FcPattern) * fcpattern_count));
-    
-    FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt) * fcpatternelt_count);
-    fcpatternelt_ptr = 0;
-    block_ptr = ALIGN(block_ptr, FcPatternElt);
-    _fcPatternElts[bi] = (FcPatternElt *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr + 
-			 (sizeof (FcPatternElt) * fcpatternelt_count));
-
-    metadata->pattern_count = fcpattern_count;
-    metadata->patternelt_count = fcpatternelt_count;
-
-    block_ptr = FcStrDistributeBytes (metadata, block_ptr);
-    block_ptr = FcValueListDistributeBytes (metadata, block_ptr);
-    return block_ptr;
-}
-
 FcPattern *
-FcPatternSerialize (int bank, FcPattern *old)
+FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat)
 {
-    FcPattern *p;
-    FcPatternElt *e, *nep;
-    FcValueList * nv;
-    FcValueListPtr v, nv_head, nvp;
-    int i, elts, bi = FcCacheBankToIndex(bank);
-
-    p = &_fcPatterns[bi][fcpattern_ptr++];
-    p->bank = bank;
-    elts = fcpatternelt_ptr;
-    nep = &_fcPatternElts[bi][elts];
-    if (!nep)
-	return FcFalse;
+    FcPattern	    *pat_serialized;
+    FcPatternElt    *elts = FcPatternElts (pat);
+    FcPatternElt    *elts_serialized;
+    FcValueList	    *values_serialized;
+    int		    i;
 
-    fcpatternelt_ptr += old->num;
+    pat_serialized = FcSerializePtr (serialize, pat);
+    if (!pat_serialized)
+	return NULL;
+    *pat_serialized = *pat;
+    pat_serialized->size = pat->num;
+    pat_serialized->ref = FC_REF_CONSTANT;
+    
+    elts_serialized = FcSerializePtr (serialize, elts);
+    if (!elts_serialized)
+	return NULL;
+    
+    pat_serialized->elts_offset = FcPtrToOffset (pat_serialized,
+						 elts_serialized);
 
-    for (e = FcPatternEltU(old->elts), i=0; i < old->num; i++, e++) 
+    for (i = 0; i < pat->num; i++)
     {
-        v = e->values;
-        nvp = nv_head = FcValueListSerialize(bank, FcValueListPtrU(v));
-        if (!FcValueListPtrU(nv_head))
-            return 0;
-	nv = FcValueListPtrU(nvp);
-	
-        for (;
-             FcValueListPtrU(v);
-             v = FcValueListPtrU(v)->next, 
-		 nv = FcValueListPtrU(nv->next))
-        {
-	    
-	    if (FcValueListPtrU(FcValueListPtrU(v)->next))
-	    {
-                nvp = FcValueListSerialize
-		    (bank, FcValueListPtrU(FcValueListPtrU(v)->next));
-                nv->next = nvp;
-	    }
-        }
-	
-	nep[i].values = nv_head;
-	nep[i].object = e->object;
+	values_serialized = FcValueListSerialize (serialize, FcPatternEltValues (elts+i));
+	if (!values_serialized)
+	    return NULL;
+	elts_serialized[i].object = elts[i].object;
+	elts_serialized[i].values = FcPtrToEncodedOffset (&elts_serialized[i], 
+							  values_serialized,
+							  FcValueList);
     }
-
-    p->elts = old->elts;
-    p->elts = FcPatternEltPtrCreateStatic(bank, elts);
-    p->size = old->num;
-    p->num = old->num;
-    p->ref = FC_REF_CONSTANT;
-    return p;
-}
-
-void *
-FcPatternUnserialize (FcCache * metadata, void *block_ptr)
-{
-    int bi = FcCacheBankToIndex(metadata->bank);
-    if (!FcPatternEnsureBank(bi))
-	return FcFalse;
-
-    FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern) * metadata->pattern_count);
-    block_ptr = ALIGN(block_ptr, FcPattern);
-    _fcPatterns[bi] = (FcPattern *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr + 
-			 (sizeof (FcPattern) * metadata->pattern_count));
-    
-    FcMemAlloc (FC_MEM_PATELT, 
-		sizeof (FcPatternElt) * metadata->patternelt_count);
-    block_ptr = ALIGN(block_ptr, FcPatternElt);
-    _fcPatternElts[bi] = (FcPatternElt *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr + 
-			 (sizeof (FcPatternElt) * metadata->patternelt_count));
-	
-    block_ptr = FcStrUnserialize (metadata, block_ptr);
-    block_ptr = FcValueListUnserialize (metadata, block_ptr);
-
-    return block_ptr;
-}
-
-static void
-FcValueListNewBank (void)
-{
-    fcvaluelist_count = 0;
-
-    FcCharSetNewBank();
-    FcLangSetNewBank();
+    return pat_serialized;
 }
 
-static int
-FcValueListNeededBytes (FcValueList *p)
+FcBool
+FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *vl)
 {
-    FcValueList *vl;
-    int cum = 0;
-
-    for (vl = p;
-	 vl; 
-	 vl = FcValueListPtrU(vl->next))
+    while (vl)
     {
-        /* unserialize just in case */
-        FcValue v = FcValueCanonicalize(&vl->value); 
-
-	switch (v.type)
-	{
+	if (!FcSerializeAlloc (serialize, vl, sizeof (FcValueList)))
+	    return FcFalse;
+	switch (vl->value.type) {
+	case FcTypeString:
+	    if (!FcStrSerializeAlloc (serialize, vl->value.u.s))
+		return FcFalse;
+	    break;
 	case FcTypeCharSet:
-	    cum += FcCharSetNeededBytes(v.u.c);
+	    if (!FcCharSetSerializeAlloc (serialize, vl->value.u.c))
+		return FcFalse;
 	    break;
 	case FcTypeLangSet:
-	    cum += FcLangSetNeededBytes(v.u.l);
+	    if (!FcLangSetSerializeAlloc (serialize, vl->value.u.l))
+		return FcFalse;
 	    break;
-	case FcTypeString:
-	    cum += FcStrNeededBytes(v.u.s);
 	default:
 	    break;
 	}
-	fcvaluelist_count++;
-	cum += sizeof (FcValueList);
-    }
-    
-    return cum;
-}
-
-static int
-FcValueListNeededBytesAlign (void)
-{
-    return FcCharSetNeededBytesAlign() + FcLangSetNeededBytesAlign() + 
-	FcStrNeededBytesAlign() + fc_alignof (FcValueList);
-}
-
-static FcBool
-FcValueListEnsureBank (int bi)
-{
-    FcValueList **pvl;
-
-    if (!_fcValueLists || fcvaluelist_bank_count <= bi)
-    {
-	int new_count = bi + 2, i;
-
-	pvl = realloc (_fcValueLists, sizeof (FcValueList *) * new_count);
-	if (!pvl)
-	    return FcFalse;
-
-	FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList *) * new_count);
-
-	_fcValueLists = pvl;
-	for (i = fcvaluelist_bank_count; i < new_count; i++)
-	    _fcValueLists[i] = 0;
-
-	fcvaluelist_bank_count = new_count;
+	vl = vl->next;
     }
     return FcTrue;
 }
 
-static void *
-FcValueListDistributeBytes (FcCache * metadata, void *block_ptr)
-{
-    int bi = FcCacheBankToIndex(metadata->bank);
-
-    if (!FcValueListEnsureBank(bi))
-	return 0;
-
-    FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList) * fcvaluelist_count);
-    fcvaluelist_ptr = 0;
-    block_ptr = ALIGN(block_ptr, FcValueList);
-    _fcValueLists[bi] = (FcValueList *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr + 
-			 (sizeof (FcValueList) * fcvaluelist_count));
-    metadata->valuelist_count = fcvaluelist_count;
-
-    block_ptr = FcCharSetDistributeBytes(metadata, block_ptr);
-    block_ptr = FcLangSetDistributeBytes(metadata, block_ptr);
-
-    return block_ptr;
-}
-
-static FcValueListPtr
-FcValueListSerialize(int bank, FcValueList *pi)
-{
-    FcValueListPtr new; 
-    FcValue * v;
-    int bi = FcCacheBankToIndex(bank);
-
-    if (!pi)
-    {
-	new.bank = FC_BANK_DYNAMIC;
-	new.u.dyn = 0;
-	return new;
-    }
-
-    _fcValueLists[bi][fcvaluelist_ptr] = *pi;
-    new.bank = bank;
-    new.u.stat = fcvaluelist_ptr++;
-    _fcValueLists[bi][new.u.stat].value = FcValueCanonicalize (&pi->value);
-    v = &_fcValueLists[bi][new.u.stat].value;
-    switch (v->type)
-    {
-    case FcTypeString:
-	if (v->u.s)
-	{
-	    const FcChar8 * s = FcStrSerialize(bank, v->u.s);
-	    if (!s)
-		return FcValueListPtrCreateDynamic(pi);
-	    v->u.s_off = s - (const FcChar8 *)v;
-	    v->type |= FC_STORAGE_STATIC;
-	}
-	break;
-    case FcTypeMatrix:
-	break;
-    case FcTypeCharSet:
-	if (v->u.c)
-	{
-	    FcCharSet * c = FcCharSetSerialize(bank, (FcCharSet *)v->u.c);
-	    if (!c)
-		return FcValueListPtrCreateDynamic(pi);
-	    v->u.c_off = (char *)c - (char *)v;
-	    v->type |= FC_STORAGE_STATIC;
-	}
-	break;
-    case FcTypeLangSet:
-	if (v->u.l)
-	{
-	    FcLangSet * l = FcLangSetSerialize(bank, (FcLangSet *)v->u.l);
-	    if (!l)
-		return FcValueListPtrCreateDynamic(pi);
-	    v->u.l_off = (char *)l - (char *)v;
-	    v->type |= FC_STORAGE_STATIC;
-	}
-	break;
-    default:
-	break;
-    }
-    return new;
-}
-
-static void *
-FcValueListUnserialize (FcCache * metadata, void *block_ptr)
+FcValueList *
+FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl)
 {
-    int bi = FcCacheBankToIndex(metadata->bank);
-
-    if (!FcValueListEnsureBank(bi))
-	return 0;
-
-    FcMemAlloc (FC_MEM_VALLIST, 
-		sizeof (FcValueList) * metadata->valuelist_count);
-    block_ptr = ALIGN(block_ptr, FcValueList);
-    _fcValueLists[bi] = (FcValueList *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr + 
-			 (sizeof (FcValueList) * metadata->valuelist_count));
-
-    block_ptr = FcCharSetUnserialize(metadata, block_ptr);
-    block_ptr = FcLangSetUnserialize(metadata, block_ptr);
-
-    return block_ptr;
-}
-
-FcValueListPtr
-FcValueListPtrCreateDynamic(FcValueList * p)
-{
-    FcValueListPtr r; 
-
-    r.bank = FC_BANK_DYNAMIC; 
-    r.u.dyn = p;
-    return r;
-}
-
-static FcChar8 ** static_strs;
-static int static_str_bank_count = 0, fcstr_ptr, fcstr_count;
-
-static struct objectBucket *FcStrBuckets[OBJECT_HASH_SIZE];
-
-static void
-FcStrNewBank (void)
-{
-    int i, size;
-    struct objectBucket *b, *next;
-    char *name;
-
-    for (i = 0; i < OBJECT_HASH_SIZE; i++)
-    {
-	for (b = FcStrBuckets[i]; b; b = next)
-	{
-	    next = b->next;
-	    name = (char *) (b + 1);
-	    size = sizeof (struct objectBucket) + strlen (name) + 1;
-	    FcMemFree (FC_MEM_STATICSTR, size);
-	    free (b);
+    FcValueList	*vl_serialized;
+    FcChar8	*s_serialized;
+    FcCharSet	*c_serialized;
+    FcLangSet	*l_serialized;
+    FcValueList	*head_serialized = NULL;
+    FcValueList	*prev_serialized = NULL;
+
+    while (vl)
+    {
+	vl_serialized = FcSerializePtr (serialize, vl);
+	if (!vl_serialized)
+	    return NULL;
+    
+	if (prev_serialized)
+	    prev_serialized->next = FcPtrToEncodedOffset (prev_serialized,
+							  vl_serialized,
+							  FcValueList);
+	else
+	    head_serialized = vl_serialized;
+	
+	vl_serialized->next = NULL;
+	vl_serialized->value = vl->value;
+	switch (vl->value.type) {
+	case FcTypeString:
+	    s_serialized = FcStrSerialize (serialize, vl->value.u.s);
+	    if (!s_serialized)
+		return NULL;
+	    vl_serialized->value.u.s = FcPtrToEncodedOffset (&vl_serialized->value,
+							     s_serialized,
+							     FcChar8);
+	    break;
+	case FcTypeCharSet:
+	    c_serialized = FcCharSetSerialize (serialize, vl->value.u.c);
+	    if (!c_serialized)
+		return NULL;
+	    vl_serialized->value.u.c = FcPtrToEncodedOffset (&vl_serialized->value,
+							     c_serialized,
+							     FcCharSet);
+	    break;
+	case FcTypeLangSet:
+	    l_serialized = FcLangSetSerialize (serialize, vl->value.u.l);
+	    if (!l_serialized)
+		return NULL;
+	    vl_serialized->value.u.l = FcPtrToEncodedOffset (&vl_serialized->value,
+							     l_serialized,
+							     FcLangSet);
+	    break;
+	default:
+	    break;
 	}
-	FcStrBuckets[i] = 0;
+	vl = vl->next;
     }
-
-    fcstr_count = 0;
-}
-
-static int
-FcStrNeededBytes (const FcChar8 * s)
-{
-    FcChar32            hash = FcStringHash ((const FcChar8 *) s);
-    struct objectBucket **p;
-    struct objectBucket *b;
-    int                 size;
-    FcChar8 *const null = 0;
-
-    for (p = &FcStrBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
-        if (b->hash == hash && !strcmp ((char *)s, (char *) (b + 1)))
-            return 0;
-    size = sizeof (struct objectBucket) + strlen ((char *)s) + 1 + sizeof(char *);
-    b = malloc (size);
-    FcMemAlloc (FC_MEM_STATICSTR, size);
-    if (!b)
-        return -1;
-    b->next = 0;
-    b->hash = hash;
-    strcpy ((char *) (b + 1), (char *)s);
-
-    /* Yes, the following line is convoluted.  However, it is
-     * incorrect to replace the with a memset, because the C
-     * specification doesn't guarantee that the null pointer is
-     * the same as the zero bit pattern. */
-    /* Misaligned pointers are not guaranteed to work, either! */
-    memcpy (((char *) (b + 1) + strlen((char *)s) + 1), &null, sizeof (null));
-    *p = b;
-
-    fcstr_count += strlen((char *)s) + 1;
-    return strlen((char *)s) + 1;
-}
-
-static int
-FcStrNeededBytesAlign (void)
-{
-    return fc_alignof (char);
-}
-
-static FcBool
-FcStrEnsureBank (int bi)
-{
-    FcChar8 ** ss;
-
-    if (!static_strs || static_str_bank_count <= bi)
-    {
-	int new_count = bi + 4, i;
-	ss = realloc (static_strs, sizeof (const char *) * new_count);
-	if (!ss)
-	    return FcFalse;
-
-	FcMemAlloc (FC_MEM_STRING, sizeof (const char *) * (new_count-static_str_bank_count));
-	static_strs = ss;
-
-	for (i = static_str_bank_count; i < new_count; i++)
-	    static_strs[i] = 0;
-	static_str_bank_count = new_count;
-    }
-    return FcTrue;
-}
-
-static void *
-FcStrDistributeBytes (FcCache * metadata, void * block_ptr)
-{
-    int bi = FcCacheBankToIndex(metadata->bank);
-    if (!FcStrEnsureBank(bi)) 
-	return 0;
-
-    FcMemAlloc (FC_MEM_STRING, sizeof (char) * fcstr_count);
-    block_ptr = ALIGN (block_ptr, FcChar8);
-    static_strs[bi] = (FcChar8 *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr + (sizeof (char) * fcstr_count));
-    metadata->str_count = fcstr_count;
-    fcstr_ptr = 0;
-
-    return block_ptr;
-}
-
-static const FcChar8 *
-FcStrSerialize (int bank, const FcChar8 * s)
-{
-    FcChar32            hash = FcStringHash ((const FcChar8 *) s);
-    struct objectBucket **p;
-    struct objectBucket *b;
-    int bi = FcCacheBankToIndex(bank);
-
-    for (p = &FcStrBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
-        if (b->hash == hash && !strcmp ((char *)s, (char *) (b + 1)))
-	{
-	    FcChar8 * t;
-	    memcpy (&t, ((FcChar8 *)(b + 1)) + strlen ((char *)s) + 1, sizeof (FcChar8 *));
-	    if (!t)
-	    {
-		strcpy((char *)(static_strs[bi] + fcstr_ptr), (char *)s);
-		t = static_strs[bi] + fcstr_ptr;
-		memcpy ((FcChar8 *) (b + 1) + strlen((char *)s) + 1, &t, sizeof (FcChar8 *));
-		fcstr_ptr += strlen((char *)s) + 1;
-		memcpy (&t, ((FcChar8 *)(b + 1)) + strlen ((char *)s) + 1, sizeof (FcChar8 *));
-	    }
-	    return t;
-	}
-    return 0;
-}
-
-static void *
-FcStrUnserialize (FcCache * metadata, void *block_ptr)
-{
-    int bi = FcCacheBankToIndex(metadata->bank);
-    if (!FcStrEnsureBank(bi))
-	return 0;
-
-    FcMemAlloc (FC_MEM_STRING, sizeof (char) * metadata->str_count);
-    block_ptr = ALIGN (block_ptr, FcChar8);
-    static_strs[bi] = (FcChar8 *)block_ptr;
-    block_ptr = (void *)((char *)block_ptr + 
-			 (sizeof (char) * metadata->str_count));
-
-    return block_ptr;
+    return head_serialized;
 }
diff --git a/src/fcstr.c b/src/fcstr.c
index 37bad6b..b83a709 100644
--- a/src/fcstr.c
+++ b/src/fcstr.c
@@ -1052,3 +1052,4 @@ FcStrListDone (FcStrList *list)
     FcMemFree (FC_MEM_STRLIST, sizeof (FcStrList));
     free (list);
 }
+
diff --git a/src/fcxml.c b/src/fcxml.c
index c5c9065..608f834 100644
--- a/src/fcxml.c
+++ b/src/fcxml.c
@@ -65,7 +65,6 @@ FcTestDestroy (FcTest *test)
     if (test->next)
 	FcTestDestroy (test->next);
     FcExprDestroy (test->expr);
-    FcStrFree ((FcChar8 *) test->field);
     FcMemFree (FC_MEM_TEST, sizeof (FcTest));
     free (test);
 }
@@ -162,7 +161,7 @@ FcExprCreateField (const char *field)
     {
 	FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
 	e->op = FcOpField;
-	e->u.field = (char *) FcStrCopy ((FcChar8 *) field);
+	e->u.object = FcObjectFromName (field);
     }
     return e;
 }
@@ -218,7 +217,6 @@ FcExprDestroy (FcExpr *e)
     case FcOpBool:
 	break;
     case FcOpField:
-	FcStrFree ((FcChar8 *) e->u.field);
 	break;
     case FcOpConst:
 	FcStrFree (e->u.constant);
@@ -269,7 +267,6 @@ FcEditDestroy (FcEdit *e)
 {
     if (e->next)
 	FcEditDestroy (e->next);
-    FcStrFree ((FcChar8 *) e->field);
     if (e->expr)
 	FcExprDestroy (e->expr);
     free (e);
@@ -579,7 +576,7 @@ FcTypecheckExpr (FcConfigParse *parse, F
     case FcOpNil:
 	break;
     case FcOpField:
-	o = FcNameGetObjectType (expr->u.field);
+	o = FcNameGetObjectType (FcObjectName (expr->u.object));
 	if (o)
 	    FcTypecheckValue (parse, o->type, type);
 	break;
@@ -659,10 +656,10 @@ FcTestCreate (FcConfigParse *parse,
 	test->next = 0;
 	test->kind = kind;
 	test->qual = qual;
-	test->field = (char *) FcStrCopy (field);
+	test->object = FcObjectFromName ((const char *) field);
 	test->op = compare;
 	test->expr = expr;
-	o = FcNameGetObjectType (test->field);
+	o = FcNameGetObjectType (FcObjectName (test->object));
 	if (o)
 	    FcTypecheckExpr (parse, expr, o->type);
     }
@@ -683,11 +680,11 @@ FcEditCreate (FcConfigParse	*parse,
 	const FcObjectType	*o;
 
 	e->next = 0;
-	e->field = field;   /* already saved in grammar */
+	e->object = FcObjectFromName (field);
 	e->op = op;
 	e->expr = expr;
 	e->binding = binding;
-	o = FcNameGetObjectType (e->field);
+	o = FcNameGetObjectType (FcObjectName (e->object));
 	if (o)
 	    FcTypecheckExpr (parse, expr, o->type);
     }


More information about the Fontconfig mailing list