]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcname.c
Bug 44826 - <alias> must contain only a single <family>
[fontconfig.git] / src / fcname.c
index ed09597d94a5265a092f7f3b6d536393740a2cd0..d77eff6f7518d2785d8c634aae13525229f0796f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $RCSId: xc/lib/fontconfig/src/fcname.c,v 1.15 2002/09/26 00:17:28 keithp Exp $
+ * fontconfig/src/fcname.c
  *
  * Copyright © 2000 Keith Packard
  *
@@ -7,34 +7,35 @@
  * 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 Keith Packard not be used in
+ * documentation, and that the name of the author(s) not be used in
  * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
+ * specific, written prior permission.  The authors make no
  * representations about the suitability of this software for any purpose.  It
  * is provided "as is" without express or implied warranty.
  *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include "fcint.h"
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
-#include "fcint.h"
 
-/* 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
- * otherwise be 0. */
+/*
+ * Please do not change this list, it is used to initialize the object
+ * list in this order to match the FC_foo_OBJECT constants. Those
+ * constants are written into cache files.
+ */
+
 static const FcObjectType _FcBaseObjectTypes[] = {
-    { "__DUMMY__",      FcTypeVoid, }, 
-    { FC_FAMILY,       FcTypeString, },
+    { FC_FAMILY,       FcTypeString, },    /* 1 */
     { FC_FAMILYLANG,   FcTypeString, },
     { FC_STYLE,                FcTypeString, },
     { FC_STYLELANG,    FcTypeString, },
@@ -48,14 +49,12 @@ static const FcObjectType _FcBaseObjectTypes[] = {
     { 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 +64,6 @@ static const FcObjectType _FcBaseObjectTypes[] = {
     { FC_RGBA,         FcTypeInteger, },
     { FC_SCALE,                FcTypeDouble, },
     { FC_MINSPACE,     FcTypeBool, },
-/*    { FC_RENDER,     FcTypeBool, },*/
     { FC_CHAR_WIDTH,   FcTypeInteger },
     { FC_CHAR_HEIGHT,  FcTypeInteger },
     { FC_MATRIX,       FcTypeMatrix },
@@ -76,335 +74,322 @@ static const FcObjectType _FcBaseObjectTypes[] = {
     { FC_FONTFORMAT,   FcTypeString },
     { FC_EMBOLDEN,     FcTypeBool },
     { FC_EMBEDDED_BITMAP,   FcTypeBool },
+    { FC_DECORATIVE,   FcTypeBool },
+    { FC_LCD_FILTER,   FcTypeInteger }, /* 41 */
 };
 
 #define NUM_OBJECT_TYPES    (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0])
 
-static FcObjectType * _FcUserObjectNames = 0;
-static int user_obj_alloc = 0;
-static int next_basic_offset = NUM_OBJECT_TYPES;
-
 typedef struct _FcObjectTypeList    FcObjectTypeList;
 
 struct _FcObjectTypeList {
     const FcObjectTypeList  *next;
     const FcObjectType     *types;
     int                            ntypes;
-    int                            basic_offset;
 };
 
 static const FcObjectTypeList _FcBaseObjectTypesList = {
     0,
     _FcBaseObjectTypes,
     NUM_OBJECT_TYPES,
-    0
 };
 
 static const FcObjectTypeList  *_FcObjectTypes = &_FcBaseObjectTypesList;
 
-FcBool
-FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes)
-{
-    FcObjectTypeList   *l;
+#define OBJECT_HASH_SIZE    31
 
-    l = (FcObjectTypeList *) malloc (sizeof (FcObjectTypeList));
-    if (!l)
-       return FcFalse;
-    FcMemAlloc (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList));
-    l->types = types;
-    l->ntypes = ntypes;
-    l->next = _FcObjectTypes;
-    l->basic_offset = next_basic_offset;
-    next_basic_offset += ntypes;
-    _FcObjectTypes = l;
-    return FcTrue;
-}
+typedef struct _FcObjectBucket {
+    struct _FcObjectBucket  *next;
+    FcChar32               hash;
+    FcObject               id;
+} FcObjectBucket;
 
-static FcBool
-FcNameUnregisterObjectTypesFree (const FcObjectType *types, int ntypes, 
-                                FcBool do_free)
-{
-    const FcObjectTypeList     *l, **prev;
+static FcObjectBucket  *FcObjectBuckets[OBJECT_HASH_SIZE];
+
+static FcObjectType    *FcObjects = (FcObjectType *) _FcBaseObjectTypes;
+static int             FcObjectsNumber = NUM_OBJECT_TYPES;
+static int             FcObjectsSize = 0;
+static FcBool          FcObjectsInited;
 
-    for (prev = &_FcObjectTypes; 
-        (l = *prev); 
-        prev = (const FcObjectTypeList **) &(l->next))
+static FcObjectType *
+FcObjectInsert (const char *name, FcType type)
+{
+    FcObjectType    *o;
+    if (FcObjectsNumber >= FcObjectsSize)
     {
-       if (l->types == types && l->ntypes == ntypes)
+       int             newsize = FcObjectsNumber * 2;
+       FcObjectType    *newobjects;
+       
+       if (FcObjectsSize)
+           newobjects = realloc (FcObjects, newsize * sizeof (FcObjectType));
+       else
        {
-           *prev = l->next;
-           if (do_free) {
-               FcMemFree (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList));
-               free ((void *) l);
-           }
-           return FcTrue;
+           newobjects = malloc (newsize * sizeof (FcObjectType));
+           if (newobjects)
+               memcpy (newobjects, FcObjects,
+                       FcObjectsNumber * sizeof (FcObjectType));
        }
+       if (!newobjects)
+           return NULL;
+       FcObjects = newobjects;
+       FcObjectsSize = newsize;
     }
-    return FcFalse;
+    o = &FcObjects[FcObjectsNumber];
+    o->object = name;
+    o->type = type;
+    ++FcObjectsNumber;
+    return o;
 }
 
-FcBool
-FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
+static FcObject
+FcObjectId (FcObjectType *o)
 {
-    return FcNameUnregisterObjectTypesFree (types, ntypes, FcTrue);
+    return o - FcObjects + 1;
 }
 
-const FcObjectType *
-FcNameGetObjectType (const char *object)
+static FcObjectType *
+FcObjectFindByName (const char *object, FcBool insert)
 {
-    int                            i;
-    const FcObjectTypeList  *l;
-    const FcObjectType     *t;
-    
-    for (l = _FcObjectTypes; l; l = l->next)
+    FcChar32       hash = FcStringHash ((const FcChar8 *) object);
+    FcObjectBucket  **p;
+    FcObjectBucket  *b;
+    FcObjectType    *o;
+
+    if (!FcObjectsInited)
+       FcObjectInit ();
+    for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
     {
-        if (l == (FcObjectTypeList*)_FcUserObjectNames)
-            continue;
+       o = FcObjects + b->id - 1;
+        if (b->hash == hash && !strcmp (object, (o->object)))
+            return o;
+    }
+    if (!insert)
+       return NULL;
+    /*
+     * Hook it into the hash chain
+     */
+    b = malloc (sizeof(FcObjectBucket));
+    if (!b)
+       return NULL;
+    object = (const char *) FcStrCopy ((FcChar8 *) object);
+    if (!object) {
+       free (b);
+       return NULL;
+    }
+    o = FcObjectInsert (object, -1);
+    b->next = NULL;
+    b->hash = hash;
+    b->id = FcObjectId (o);
+    *p = b;
+    return o;
+}
 
-       for (i = 0; i < l->ntypes; i++)
+static FcObjectType *
+FcObjectFindById (FcObject object)
+{
+    if (1 <= object && object <= FcObjectsNumber)
+       return FcObjects + object - 1;
+    return NULL;
+}
+
+static FcBool
+FcObjectHashInsert (const FcObjectType *object, FcBool copy)
+{
+    FcChar32       hash = FcStringHash ((const FcChar8 *) object->object);
+    FcObjectBucket  **p;
+    FcObjectBucket  *b;
+    FcObjectType    *o;
+
+    if (!FcObjectsInited)
+       FcObjectInit ();
+    for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
+    {
+       o = FcObjects + b->id - 1;
+        if (b->hash == hash && !strcmp (object->object, o->object))
+            return FcFalse;
+    }
+    /*
+     * Hook it into the hash chain
+     */
+    b = malloc (sizeof(FcObjectBucket));
+    if (!b)
+       return FcFalse;
+    if (copy)
+    {
+       o = FcObjectInsert (object->object, object->type);
+       if (!o)
        {
-           t = &l->types[i];
-           if (!strcmp (object, t->object))
-               return t;
+           free (b);
+           return FcFalse;
        }
     }
-    return 0;
+    else
+       o = (FcObjectType *) object;
+    b->next = NULL;
+    b->hash = hash;
+    b->id = FcObjectId (o);
+    *p = b;
+    return FcTrue;
 }
 
-#define OBJECT_HASH_SIZE    31
-struct objectBucket {
-    struct objectBucket        *next;
-    FcChar32           hash;
-    int                        id;
-};
-static struct objectBucket *FcObjectBuckets[OBJECT_HASH_SIZE];
-
-/* 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
-FcObjectToPtrLookup (const char * object)
+static void
+FcObjectHashRemove (const FcObjectType *object, FcBool cleanobj)
 {
-    FcObjectPtr                    i = 0, n;
-    const FcObjectTypeList  *l;
-    FcObjectType           *t = _FcUserObjectNames;
-    FcBool                 replace;
-
-    for (l = _FcObjectTypes; l; l = l->next)
+    FcChar32       hash = FcStringHash ((const FcChar8 *) object->object);
+    FcObjectBucket  **p;
+    FcObjectBucket  *b;
+    FcObjectType    *o;
+
+    if (!FcObjectsInited)
+       FcObjectInit ();
+    for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
     {
-       for (i = 0; i < l->ntypes; i++)
+       o = FcObjects + b->id - 1;
+        if (b->hash == hash && !strcmp (object->object, o->object))
        {
-           t = (FcObjectType *)&l->types[i];
-           if (!strcmp (object, t->object))
+           *p = b->next;
+           free (b);
+           if (cleanobj)
            {
-               if (l->types == _FcUserObjectNames)
-                    return -i;
-               else
-                   return l->basic_offset + i;
+               /* Clean up object array */
+               o->object = NULL;
+               o->type = -1;
+               while (FcObjects[FcObjectsNumber-1].object == NULL)
+                   --FcObjectsNumber;
            }
+            break;
        }
     }
+}
 
-    /* We didn't match.  Look for the application's FcObjectTypeList
-     * and replace it in-place. */
-    for (l = _FcObjectTypes; l; l = l->next)
-    {
-       if (l->types == _FcUserObjectNames)
-           break;
-    }
-
-    replace = l && l->types == _FcUserObjectNames;
-    if (!_FcUserObjectNames || 
-        (replace && user_obj_alloc <= l->ntypes))
-    {
-       int nt = user_obj_alloc + 4;
-        FcObjectType * tt = realloc (_FcUserObjectNames, 
-                                   nt * sizeof (FcObjectType));
-        if (!tt)
-            return 0;
-       _FcUserObjectNames = tt;
-       user_obj_alloc = nt;
-    }
-
-    if (replace)
-    {
-       n = l->ntypes;
-       FcNameUnregisterObjectTypesFree (l->types, l->ntypes, FcFalse);
-    }
-    else
-       n = 0;
-
-    FcNameRegisterObjectTypes (_FcUserObjectNames, n+1);
+FcBool
+FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes)
+{
+    int        i;
 
-    if (!_FcUserObjectNames)
-       return 0;
+    for (i = 0; i < ntypes; i++)
+       if (!FcObjectHashInsert (&types[i], FcTrue))
+           return FcFalse;
+    return FcTrue;
+}
 
-    _FcUserObjectNames[n].object = object;
-    _FcUserObjectNames[n].type = FcTypeVoid;
+FcBool
+FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
+{
+    int        i;
 
-    return -n;
+    for (i = 0; i < ntypes; i++)
+       FcObjectHashRemove (&types[i], FcTrue);
+    return FcTrue;
 }
 
-FcObjectPtr
-FcObjectToPtr (const char * name)
+const FcObjectType *
+FcNameGetObjectType (const char *object)
 {
-    FcChar32            hash = FcStringHash ((const FcChar8 *) name);
-    struct objectBucket **p;
-    struct objectBucket *b;
-    int                 size;
-
-    for (p = &FcObjectBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)
-)
-        if (b->hash == hash && !strcmp (name, (char *) (b + 1)))
-            return b->id;
-    size = sizeof (struct objectBucket) + strlen (name) + 1;
-    /* workaround glibc bug which reads strlen in groups of 4 */
-    b = malloc (size + sizeof (int));
-    FcMemAlloc (FC_MEM_STATICSTR, size + sizeof(int));
-    if (!b)
-        return 0;
-    b->next = 0;
-    b->hash = hash;
-    b->id = FcObjectToPtrLookup (name);
-    strcpy ((char *) (b + 1), name);
-    *p = b;
-    return b->id;
+    return FcObjectFindByName (object, FcFalse);
 }
 
-void
-FcObjectStaticNameFini (void)
+FcBool
+FcObjectValidType (FcObject object, FcType type)
 {
-    int i, size;
-    struct objectBucket *b, *next;
-    char *name;
+    FcObjectType    *t = FcObjectFindById (object);
 
-    for (i = 0; i < OBJECT_HASH_SIZE; i++)
-    {
-       for (b = FcObjectBuckets[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);
+    if (t) {
+       switch (t->type) {
+       case -1:
+           return FcTrue;
+       case FcTypeDouble:
+       case FcTypeInteger:
+           if (type == FcTypeDouble || type == FcTypeInteger)
+               return FcTrue;
+           break;
+       case FcTypeLangSet:
+           if (type == FcTypeLangSet || type == FcTypeString)
+               return FcTrue;
+           break;
+       default:
+           if (type == t->type)
+               return FcTrue;
+           break;
        }
-       FcObjectBuckets[i] = 0;
+       return FcFalse;
     }
+    return FcTrue;
 }
 
-const char *
-FcObjectPtrU (FcObjectPtr si)
+FcObject
+FcObjectFromName (const char * name)
 {
-    const FcObjectTypeList  *l;
-    int i, j;
-
-    if (si > 0)
-    {
-        if (si < biggest_known_ntypes)
-            return biggest_known_types[si].object;
-
-        j = 0;
-        for (l = _FcObjectTypes; l; l = l->next)
-            for (i = 0; i < l->ntypes; i++, j++)
-                if (j == si)
-                    return l->types[i].object;
-    }
+    FcObjectType    *o = FcObjectFindByName (name, FcTrue);
 
-    return _FcUserObjectNames[-si].object;
+    if (o)
+       return FcObjectId (o);
+    return 0;
 }
 
-int
-FcObjectNeededBytes ()
+FcObjectSet *
+FcObjectGetSet (void)
 {
-    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                i;
+    FcObjectSet        *os = NULL;
 
-int
-FcObjectNeededBytesAlign (void)
-{
-    return fc_alignof (int) + fc_alignof (char);
+
+    os = FcObjectSetCreate ();
+    for (i = 0; i < FcObjectsNumber; i++)
+       FcObjectSetAdd (os, FcObjects[i].object);
+
+    return os;
 }
 
-void *
-FcObjectDistributeBytes (FcCache * metadata, void * block_ptr)
+FcBool
+FcObjectInit (void)
 {
-    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;
+    int        i;
+
+    if (FcObjectsInited)
+       return FcTrue;
+
+    FcObjectsInited = FcTrue;
+    for (i = 0; i < NUM_OBJECT_TYPES; i++)
+       if (!FcObjectHashInsert (&_FcBaseObjectTypes[i], FcFalse))
+           return FcFalse;
+    return FcTrue;
 }
 
 void
-FcObjectSerialize (void)
+FcObjectFini (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;
-    }
-}
+    int                    i;
+    FcObjectBucket  *b, *next;
 
-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)
+    for (i = 0; i < OBJECT_HASH_SIZE; i++)
     {
-       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++)
+       for (b = FcObjectBuckets[i]; b; b = next)
        {
-           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;
+           next = b->next;
+           free (b);
        }
+       FcObjectBuckets[i] = 0;
+    }
+    for (i = 0; i < FcObjectsNumber; i++)
+       if (FcObjects[i].type == -1)
+           free ((void*) FcObjects[i].object);
+    if (FcObjects != _FcBaseObjectTypes)
+       free (FcObjects);
+    FcObjects = (FcObjectType *) _FcBaseObjectTypes;
+    FcObjectsNumber = NUM_OBJECT_TYPES;
+    FcObjectsSize = 0;
+    FcObjectsInited = FcFalse;
+}
 
-       FcNameUnregisterObjectTypesFree (biggest_known_types, biggest_known_ntypes, FcFalse);
-       if (allocated_biggest_known_types)
-       {
-           free ((FcObjectTypeList *)biggest_known_types);
-       }
-       else
-           allocated_biggest_known_types = FcTrue;
+const char *
+FcObjectName (FcObject object)
+{
+    FcObjectType    *o = FcObjectFindById (object);
 
-       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;
+    if (o)
+       return o->object;
+    return NULL;
 }
 
 static const FcConstant _FcBaseConstants[] = {
@@ -421,6 +406,7 @@ static const FcConstant _FcBaseConstants[] = {
     { (FcChar8 *) "extrabold",     "weight",   FC_WEIGHT_EXTRABOLD, },
     { (FcChar8 *) "ultrabold",     "weight",   FC_WEIGHT_EXTRABOLD, },
     { (FcChar8 *) "black",         "weight",   FC_WEIGHT_BLACK, },
+    { (FcChar8 *) "heavy",         "weight",   FC_WEIGHT_HEAVY, },
 
     { (FcChar8 *) "roman",         "slant",    FC_SLANT_ROMAN, },
     { (FcChar8 *) "italic",        "slant",    FC_SLANT_ITALIC, },
@@ -435,7 +421,7 @@ static const FcConstant _FcBaseConstants[] = {
     { (FcChar8 *) "expanded",      "width",    FC_WIDTH_EXPANDED },
     { (FcChar8 *) "extraexpanded",  "width",   FC_WIDTH_EXTRAEXPANDED },
     { (FcChar8 *) "ultraexpanded",  "width",   FC_WIDTH_ULTRAEXPANDED },
-    
+
     { (FcChar8 *) "proportional",   "spacing",  FC_PROPORTIONAL, },
     { (FcChar8 *) "dual",          "spacing",  FC_DUAL, },
     { (FcChar8 *) "mono",          "spacing",  FC_MONO, },
@@ -452,6 +438,22 @@ static const FcConstant _FcBaseConstants[] = {
     { (FcChar8 *) "hintslight",            "hintstyle",   FC_HINT_SLIGHT },
     { (FcChar8 *) "hintmedium",            "hintstyle",   FC_HINT_MEDIUM },
     { (FcChar8 *) "hintfull",      "hintstyle",   FC_HINT_FULL },
+
+    { (FcChar8 *) "antialias",     "antialias",    FcTrue },
+    { (FcChar8 *) "hinting",       "hinting",      FcTrue },
+    { (FcChar8 *) "verticallayout", "verticallayout",  FcTrue },
+    { (FcChar8 *) "autohint",      "autohint",     FcTrue },
+    { (FcChar8 *) "globaladvance",  "globaladvance",   FcTrue },
+    { (FcChar8 *) "outline",       "outline",      FcTrue },
+    { (FcChar8 *) "scalable",      "scalable",     FcTrue },
+    { (FcChar8 *) "minspace",      "minspace",     FcTrue },
+    { (FcChar8 *) "embolden",      "embolden",     FcTrue },
+    { (FcChar8 *) "embeddedbitmap", "embeddedbitmap",  FcTrue },
+    { (FcChar8 *) "decorative",            "decorative",   FcTrue },
+    { (FcChar8 *) "lcdnone",       "lcdfilter",    FC_LCD_NONE },
+    { (FcChar8 *) "lcddefault",            "lcdfilter",    FC_LCD_DEFAULT },
+    { (FcChar8 *) "lcdlight",      "lcdfilter",    FC_LCD_LIGHT },
+    { (FcChar8 *) "lcdlegacy",     "lcdfilter",    FC_LCD_LEGACY },
 };
 
 #define NUM_FC_CONSTANTS   (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0])
@@ -493,8 +495,8 @@ FcNameUnregisterConstants (const FcConstant *consts, int nconsts)
 {
     const FcConstantList       *l, **prev;
 
-    for (prev = &_FcConstants; 
-        (l = *prev); 
+    for (prev = &_FcConstants;
+        (l = *prev);
         prev = (const FcConstantList **) &(l->next))
     {
        if (l->consts == consts && l->nconsts == nconsts)
@@ -584,6 +586,8 @@ FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m)
        break;
     case FcTypeString:
        v.u.s = FcStrStaticName(string);
+       if (!v.u.s)
+           v.type = FcTypeVoid;
        break;
     case FcTypeBool:
        if (!FcNameBool (string, &v.u.b))
@@ -598,9 +602,13 @@ FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m)
        break;
     case FcTypeCharSet:
        v.u.c = FcNameParseCharSet (string);
+       if (!v.u.c)
+           v.type = FcTypeVoid;
        break;
     case FcTypeLangSet:
        v.u.l = FcNameParseLangSet (string);
+       if (!v.u.l)
+           v.type = FcTypeVoid;
        break;
     default:
        break;
@@ -612,7 +620,7 @@ static const FcChar8 *
 FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last)
 {
     FcChar8    c;
-    
+
     while ((c = *cur))
     {
        if (c == '\\')
@@ -691,7 +699,7 @@ FcNameParse (const FcChar8 *name)
                for (;;)
                {
                    name = FcNameFindNext (name, ":,", save, &delim);
-                   if (t && strcmp (t->object, _FcBaseObjectTypes[0].object))
+                   if (t)
                    {
                        v = FcNameConvert (t->type, save, &m);
                        if (!FcPatternAdd (pat, t->object, v, FcTrue))
@@ -727,8 +735,20 @@ FcNameParse (const FcChar8 *name)
            {
                if ((c = FcNameGetConstant (save)))
                {
-                   if (!FcPatternAddInteger (pat, c->object, c->value))
-                       goto bail2;
+                   t = FcNameGetObjectType ((char *) c->object);
+                   switch (t->type) {
+                   case FcTypeInteger:
+                   case FcTypeDouble:
+                       if (!FcPatternAddInteger (pat, c->object, c->value))
+                           goto bail2;
+                       break;
+                   case FcTypeBool:
+                       if (!FcPatternAddBool (pat, c->object, c->value))
+                           goto bail2;
+                       break;
+                   default:
+                       break;
+                   }
                }
            }
        }
@@ -745,7 +765,7 @@ bail0:
     return 0;
 }
 static FcBool
-FcNameUnparseString (FcStrBuf      *buf, 
+FcNameUnparseString (FcStrBuf      *buf,
                     const FcChar8  *string,
                     const FcChar8  *escape)
 {
@@ -763,14 +783,14 @@ FcNameUnparseString (FcStrBuf         *buf,
     return FcTrue;
 }
 
-static FcBool
+FcBool
 FcNameUnparseValue (FcStrBuf   *buf,
                    FcValue     *v0,
                    FcChar8     *escape)
 {
     FcChar8    temp[1024];
     FcValue v = FcValueCanonicalize(v0);
-    
+
     switch (v.type) {
     case FcTypeVoid:
        return FcTrue;
@@ -785,7 +805,7 @@ FcNameUnparseValue (FcStrBuf        *buf,
     case FcTypeBool:
        return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0);
     case FcTypeMatrix:
-       sprintf ((char *) temp, "%g %g %g %g", 
+       sprintf ((char *) temp, "%g %g %g %g",
                 v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
        return FcNameUnparseString (buf, temp, 0);
     case FcTypeCharSet:
@@ -798,16 +818,16 @@ FcNameUnparseValue (FcStrBuf      *buf,
     return FcFalse;
 }
 
-static FcBool
+FcBool
 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 +854,18 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
     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)
@@ -853,12 +873,11 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
        for (i = 0; i < l->ntypes; i++)
        {
            o = &l->types[i];
-           if (!strcmp (o->object, FC_FAMILY) || 
-               !strcmp (o->object, FC_SIZE) ||
-               !strcmp (o->object, FC_FILE))
+           if (!strcmp (o->object, FC_FAMILY) ||
+               !strcmp (o->object, FC_SIZE))
                continue;
-           
-           e = FcPatternFindElt (pat, o->object);
+       
+           e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object));
            if (e)
            {
                if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0))
@@ -867,7 +886,7 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
                    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;
            }
@@ -878,3 +897,6 @@ bail0:
     FcStrBufDestroy (&buf);
     return 0;
 }
+#define __fcname__
+#include "fcaliastail.h"
+#undef __fcname__