/*
 * $RCSId: xc/lib/fontconfig/src/fcname.c,v 1.15 2002/09/26 00:17:28 keithp Exp $
 *
 * Copyright © 2000 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Keith Packard not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Keith Packard makes 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,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL KEITH PACKARD 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>

/* 
 * Please do not change this list, it is used to initialize the object
 * list in this order to match the FC_foo_OBJECT constants. Those 
 * constants are written into cache files.
 */

static const FcObjectType _FcBaseObjectTypes[] = {
    { FC_FAMILY,	FcTypeString, },    /* 1 */
    { FC_FAMILYLANG,	FcTypeString, },
    { FC_STYLE,		FcTypeString, },
    { FC_STYLELANG,	FcTypeString, },
    { FC_FULLNAME,	FcTypeString, },
    { FC_FULLNAMELANG,	FcTypeString, },
    { FC_SLANT,		FcTypeInteger, },
    { FC_WEIGHT,	FcTypeInteger, },
    { FC_WIDTH,		FcTypeInteger, },
    { FC_SIZE,		FcTypeDouble, },
    { FC_ASPECT,	FcTypeDouble, },
    { FC_PIXEL_SIZE,	FcTypeDouble, },
    { FC_SPACING,	FcTypeInteger, },
    { FC_FOUNDRY,	FcTypeString, },
    { FC_ANTIALIAS,	FcTypeBool, },
    { FC_HINT_STYLE,    FcTypeInteger, },
    { FC_HINTING,	FcTypeBool, },
    { FC_VERTICAL_LAYOUT,   FcTypeBool, },
    { FC_AUTOHINT,	FcTypeBool, },
    { FC_GLOBAL_ADVANCE,    FcTypeBool, },
    { FC_FILE,		FcTypeString, },
    { FC_INDEX,		FcTypeInteger, },
    { FC_RASTERIZER,	FcTypeString, },
    { FC_OUTLINE,	FcTypeBool, },
    { FC_SCALABLE,	FcTypeBool, },
    { FC_DPI,		FcTypeDouble },
    { FC_RGBA,		FcTypeInteger, },
    { FC_SCALE,		FcTypeDouble, },
    { FC_MINSPACE,	FcTypeBool, },
    { FC_CHAR_WIDTH,	FcTypeInteger },
    { FC_CHAR_HEIGHT,	FcTypeInteger },
    { FC_MATRIX,	FcTypeMatrix },
    { FC_CHARSET,	FcTypeCharSet },
    { FC_LANG,		FcTypeLangSet },
    { FC_FONTVERSION,	FcTypeInteger },
    { FC_CAPABILITY,	FcTypeString },
    { FC_FONTFORMAT,	FcTypeString },
    { FC_EMBOLDEN,	FcTypeBool },
    { FC_EMBEDDED_BITMAP,   FcTypeBool },
    { FC_DECORATIVE,	FcTypeBool }, /* 40 */
};

#define NUM_OBJECT_TYPES    (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0])

typedef struct _FcObjectTypeList    FcObjectTypeList;

struct _FcObjectTypeList {
    const FcObjectTypeList  *next;
    const FcObjectType	    *types;
    int			    ntypes;
};

static const FcObjectTypeList _FcBaseObjectTypesList = {
    0,
    _FcBaseObjectTypes,
    NUM_OBJECT_TYPES,
};

static const FcObjectTypeList	*_FcObjectTypes = &_FcBaseObjectTypesList;

#define OBJECT_HASH_SIZE    31

typedef struct _FcObjectBucket {
    struct _FcObjectBucket  *next;
    FcChar32		    hash;
    FcObject		    id;
} FcObjectBucket;

static FcObjectBucket	*FcObjectBuckets[OBJECT_HASH_SIZE];

static FcObjectType	*FcObjects = (FcObjectType *) _FcBaseObjectTypes;
static int		FcObjectsNumber = NUM_OBJECT_TYPES;
static int		FcObjectsSize = 0;
static FcBool		FcObjectsInited;

static FcObjectType *
FcObjectInsert (const char *name, FcType type)
{
    FcObjectType    *o;
    if (FcObjectsNumber >= FcObjectsSize)
    {
	int		newsize = FcObjectsNumber * 2;
	FcObjectType	*newobjects;
	
	if (FcObjectsSize)
	    newobjects = realloc (FcObjects, newsize * sizeof (FcObjectType));
	else
	{
	    newobjects = malloc (newsize * sizeof (FcObjectType));
	    if (newobjects)
		memcpy (newobjects, FcObjects,
			FcObjectsNumber * sizeof (FcObjectType));
	}
	if (!newobjects)
	    return NULL;
	FcObjects = newobjects;
	FcObjectsSize = newsize;
    }
    o = &FcObjects[FcObjectsNumber];
    o->object = name;
    o->type = type;
    ++FcObjectsNumber;
    return o;
}

static FcObject
FcObjectId (FcObjectType *o)
{
    return o - FcObjects + 1;
}

static FcObjectType *
FcObjectFindByName (const char *object, FcBool insert)
{
    FcChar32	    hash = FcStringHash ((const FcChar8 *) object);
    FcObjectBucket  **p;
    FcObjectBucket  *b;
    FcObjectType    *o;

    if (!FcObjectsInited)
	FcObjectInit ();
    for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
    {
	o = FcObjects + b->id - 1;
        if (b->hash == hash && !strcmp (object, (o->object)))
            return o;
    }
    if (!insert)
	return NULL;
    /*
     * Hook it into the hash chain
     */
    b = malloc (sizeof(FcObjectBucket));
    if (!b) 
	return NULL;
    object = (const char *) FcStrCopy ((FcChar8 *) object);
    if (!object) {
	free (b);
	return NULL;
    }
    o = FcObjectInsert (object, -1);
    b->next = NULL;
    b->hash = hash;
    b->id = FcObjectId (o);
    *p = b;
    return o;
}

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)
	{
	    free (b);
	    return FcFalse;
	}
    }
    else
	o = (FcObjectType *) object;
    b->next = NULL;
    b->hash = hash;
    b->id = FcObjectId (o);
    *p = b;
    return FcTrue;
}

static void
FcObjectHashRemove (const FcObjectType *object, FcBool cleanobj)
{
    FcChar32	    hash = FcStringHash ((const FcChar8 *) object->object);
    FcObjectBucket  **p;
    FcObjectBucket  *b;
    FcObjectType    *o;

    if (!FcObjectsInited)
	FcObjectInit ();
    for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
    {
	o = FcObjects + b->id - 1;
        if (b->hash == hash && !strcmp (object->object, o->object))
	{
	    *p = b->next;
	    free (b);
	    if (cleanobj)
	    {
		/* Clean up object array */
		o->object = NULL;
		o->type = -1;
		while (FcObjects[FcObjectsNumber-1].object == NULL)
		    --FcObjectsNumber;
	    }
            break;
	}
    }
}

FcBool
FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes)
{
    int	i;

    for (i = 0; i < ntypes; i++)
	if (!FcObjectHashInsert (&types[i], FcTrue))
	    return FcFalse;
    return FcTrue;
}

FcBool
FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
{
    int	i;

    for (i = 0; i < ntypes; i++)
	FcObjectHashRemove (&types[i], FcTrue);
    return FcTrue;
}

const FcObjectType *
FcNameGetObjectType (const char *object)
{
    return FcObjectFindByName (object, FcFalse);
}

FcBool
FcObjectValidType (FcObject object, FcType type)
{
    FcObjectType    *t = FcObjectFindById (object);

    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;
	}
	return FcFalse;
    }
    return FcTrue;
}

FcObject
FcObjectFromName (const char * name)
{
    FcObjectType    *o = FcObjectFindByName (name, FcTrue);

    if (o)
	return FcObjectId (o);
    return 0;
}

FcBool
FcObjectInit (void)
{
    int	i;

    if (FcObjectsInited)
	return FcTrue;

    FcObjectsInited = FcTrue;
    for (i = 0; i < NUM_OBJECT_TYPES; i++)
	if (!FcObjectHashInsert (&_FcBaseObjectTypes[i], FcFalse))
	    return FcFalse;
    return FcTrue;
}

void
FcObjectFini (void)
{
    int		    i;
    FcObjectBucket  *b, *next;

    for (i = 0; i < OBJECT_HASH_SIZE; i++)
    {
	for (b = FcObjectBuckets[i]; b; b = next)
	{
	    next = b->next;
	    free (b);
	}
	FcObjectBuckets[i] = 0;
    }
    for (i = 0; i < FcObjectsNumber; i++)
	if (FcObjects[i].type == -1)
	    free ((void*) FcObjects[i].object);
    if (FcObjects != _FcBaseObjectTypes)
	free (FcObjects);
    FcObjects = (FcObjectType *) _FcBaseObjectTypes;
    FcObjectsNumber = NUM_OBJECT_TYPES;
    FcObjectsSize = 0;
    FcObjectsInited = FcFalse;
}

const char *
FcObjectName (FcObject object)
{
    FcObjectType    *o = FcObjectFindById (object);

    if (o)
	return o->object;
    return NULL;
}

static const FcConstant _FcBaseConstants[] = {
    { (FcChar8 *) "thin",	    "weight",   FC_WEIGHT_THIN, },
    { (FcChar8 *) "extralight",	    "weight",   FC_WEIGHT_EXTRALIGHT, },
    { (FcChar8 *) "ultralight",	    "weight",   FC_WEIGHT_EXTRALIGHT, },
    { (FcChar8 *) "light",	    "weight",   FC_WEIGHT_LIGHT, },
    { (FcChar8 *) "book",	    "weight",	FC_WEIGHT_BOOK, },
    { (FcChar8 *) "regular",	    "weight",   FC_WEIGHT_REGULAR, },
    { (FcChar8 *) "medium",	    "weight",   FC_WEIGHT_MEDIUM, },
    { (FcChar8 *) "demibold",	    "weight",   FC_WEIGHT_DEMIBOLD, },
    { (FcChar8 *) "semibold",	    "weight",   FC_WEIGHT_DEMIBOLD, },
    { (FcChar8 *) "bold",	    "weight",   FC_WEIGHT_BOLD, },
    { (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, },
    { (FcChar8 *) "oblique",	    "slant",    FC_SLANT_OBLIQUE, },

    { (FcChar8 *) "ultracondensed", "width",	FC_WIDTH_ULTRACONDENSED },
    { (FcChar8 *) "extracondensed", "width",	FC_WIDTH_EXTRACONDENSED },
    { (FcChar8 *) "condensed",	    "width",	FC_WIDTH_CONDENSED },
    { (FcChar8 *) "semicondensed", "width",	FC_WIDTH_SEMICONDENSED },
    { (FcChar8 *) "normal",	    "width",	FC_WIDTH_NORMAL },
    { (FcChar8 *) "semiexpanded",   "width",	FC_WIDTH_SEMIEXPANDED },
    { (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, },
    { (FcChar8 *) "charcell",	    "spacing",  FC_CHARCELL, },

    { (FcChar8 *) "unknown",	    "rgba",	    FC_RGBA_UNKNOWN },
    { (FcChar8 *) "rgb",	    "rgba",	    FC_RGBA_RGB, },
    { (FcChar8 *) "bgr",	    "rgba",	    FC_RGBA_BGR, },
    { (FcChar8 *) "vrgb",	    "rgba",	    FC_RGBA_VRGB },
    { (FcChar8 *) "vbgr",	    "rgba",	    FC_RGBA_VBGR },
    { (FcChar8 *) "none",	    "rgba",	    FC_RGBA_NONE },

    { (FcChar8 *) "hintnone",	    "hintstyle",   FC_HINT_NONE },
    { (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 },
};

#define NUM_FC_CONSTANTS   (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0])

typedef struct _FcConstantList FcConstantList;

struct _FcConstantList {
    const FcConstantList    *next;
    const FcConstant	    *consts;
    int			    nconsts;
};

static const FcConstantList _FcBaseConstantList = {
    0,
    _FcBaseConstants,
    NUM_FC_CONSTANTS
};

static const FcConstantList	*_FcConstants = &_FcBaseConstantList;

FcBool
FcNameRegisterConstants (const FcConstant *consts, int nconsts)
{
    FcConstantList	*l;

    l = (FcConstantList *) malloc (sizeof (FcConstantList));
    if (!l)
	return FcFalse;
    FcMemAlloc (FC_MEM_CONSTANT, sizeof (FcConstantList));
    l->consts = consts;
    l->nconsts = nconsts;
    l->next = _FcConstants;
    _FcConstants = l;
    return FcTrue;
}

FcBool
FcNameUnregisterConstants (const FcConstant *consts, int nconsts)
{
    const FcConstantList	*l, **prev;

    for (prev = &_FcConstants; 
	 (l = *prev); 
	 prev = (const FcConstantList **) &(l->next))
    {
	if (l->consts == consts && l->nconsts == nconsts)
	{
	    *prev = l->next;
	    FcMemFree (FC_MEM_CONSTANT, sizeof (FcConstantList));
	    free ((void *) l);
	    return FcTrue;
	}
    }
    return FcFalse;
}

const FcConstant *
FcNameGetConstant (FcChar8 *string)
{
    const FcConstantList    *l;
    int			    i;

    for (l = _FcConstants; l; l = l->next)
    {
	for (i = 0; i < l->nconsts; i++)
	    if (!FcStrCmpIgnoreCase (string, l->consts[i].name))
		return &l->consts[i];
    }
    return 0;
}

FcBool
FcNameConstant (FcChar8 *string, int *result)
{
    const FcConstant	*c;

    if ((c = FcNameGetConstant(string)))
    {
	*result = c->value;
	return FcTrue;
    }
    return FcFalse;
}

FcBool
FcNameBool (const FcChar8 *v, FcBool *result)
{
    char    c0, c1;

    c0 = *v;
    c0 = FcToLower (c0);
    if (c0 == 't' || c0 == 'y' || c0 == '1')
    {
	*result = FcTrue;
	return FcTrue;
    }
    if (c0 == 'f' || c0 == 'n' || c0 == '0')
    {
	*result = FcFalse;
	return FcTrue;
    }
    if (c0 == 'o')
    {
	c1 = v[1];
	c1 = FcToLower (c1);
	if (c1 == 'n')
	{
	    *result = FcTrue;
	    return FcTrue;
	}
	if (c1 == 'f')
	{
	    *result = FcFalse;
	    return FcTrue;
	}
    }
    return FcFalse;
}

static FcValue
FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m)
{
    FcValue	v;

    v.type = type;
    switch (v.type) {
    case FcTypeInteger:
	if (!FcNameConstant (string, &v.u.i))
	    v.u.i = atoi ((char *) string);
	break;
    case FcTypeString:
	v.u.s = FcStrStaticName(string);
	if (!v.u.s)
	    v.type = FcTypeVoid;
	break;
    case FcTypeBool:
	if (!FcNameBool (string, &v.u.b))
	    v.u.b = FcFalse;
	break;
    case FcTypeDouble:
	v.u.d = strtod ((char *) string, 0);
	break;
    case FcTypeMatrix:
	v.u.m = m;
	sscanf ((char *) string, "%lg %lg %lg %lg", &m->xx, &m->xy, &m->yx, &m->yy);
	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;
    }
    return v;
}

static const FcChar8 *
FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last)
{
    FcChar8    c;
    
    while ((c = *cur))
    {
	if (c == '\\')
	{
	    ++cur;
	    if (!(c = *cur))
		break;
	}
	else if (strchr (delim, c))
	    break;
	++cur;
	*save++ = c;
    }
    *save = 0;
    *last = *cur;
    if (*cur)
	cur++;
    return cur;
}

FcPattern *
FcNameParse (const FcChar8 *name)
{
    FcChar8		*save;
    FcPattern		*pat;
    double		d;
    FcChar8		*e;
    FcChar8		delim;
    FcValue		v;
    FcMatrix		m;
    const FcObjectType	*t;
    const FcConstant	*c;

    /* freed below */
    save = malloc (strlen ((char *) name) + 1);
    if (!save)
	goto bail0;
    pat = FcPatternCreate ();
    if (!pat)
	goto bail1;

    for (;;)
    {
	name = FcNameFindNext (name, "-,:", save, &delim);
	if (save[0])
	{
	    if (!FcPatternAddString (pat, FC_FAMILY, save))
		goto bail2;
	}
	if (delim != ',')
	    break;
    }
    if (delim == '-')
    {
	for (;;)
	{
	    name = FcNameFindNext (name, "-,:", save, &delim);
	    d = strtod ((char *) save, (char **) &e);
	    if (e != save)
	    {
		if (!FcPatternAddDouble (pat, FC_SIZE, d))
		    goto bail2;
	    }
	    if (delim != ',')
		break;
	}
    }
    while (delim == ':')
    {
	name = FcNameFindNext (name, "=_:", save, &delim);
	if (save[0])
	{
	    if (delim == '=' || delim == '_')
	    {
		t = FcNameGetObjectType ((char *) save);
		for (;;)
		{
		    name = FcNameFindNext (name, ":,", save, &delim);
		    if (t)
		    {
			v = FcNameConvert (t->type, save, &m);
			if (!FcPatternAdd (pat, t->object, v, FcTrue))
			{
			    switch (v.type) {
			    case FcTypeCharSet:
				FcCharSetDestroy ((FcCharSet *) v.u.c);
				break;
			    case FcTypeLangSet:
				FcLangSetDestroy ((FcLangSet *) v.u.l);
				break;
			    default:
				break;
			    }
			    goto bail2;
			}
			switch (v.type) {
			case FcTypeCharSet:
			    FcCharSetDestroy ((FcCharSet *) v.u.c);
			    break;
			case FcTypeLangSet:
			    FcLangSetDestroy ((FcLangSet *) v.u.l);
			    break;
			default:
			    break;
			}
		    }
		    if (delim != ',')
			break;
		}
	    }
	    else
	    {
		if ((c = FcNameGetConstant (save)))
		{
		    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;
		    }
		}
	    }
	}
    }

    free (save);
    return pat;

bail2:
    FcPatternDestroy (pat);
bail1:
    free (save);
bail0:
    return 0;
}
static FcBool
FcNameUnparseString (FcStrBuf	    *buf, 
		     const FcChar8  *string,
		     const FcChar8  *escape)
{
    FcChar8 c;
    while ((c = *string++))
    {
	if (escape && strchr ((char *) escape, (char) c))
	{
	    if (!FcStrBufChar (buf, escape[0]))
		return FcFalse;
	}
	if (!FcStrBufChar (buf, c))
	    return FcFalse;
    }
    return FcTrue;
}

static FcBool
FcNameUnparseValue (FcStrBuf	*buf,
		    FcValue	*v0,
		    FcChar8	*escape)
{
    FcChar8	temp[1024];
    FcValue v = FcValueCanonicalize(v0);
    
    switch (v.type) {
    case FcTypeVoid:
	return FcTrue;
    case FcTypeInteger:
	sprintf ((char *) temp, "%d", v.u.i);
	return FcNameUnparseString (buf, temp, 0);
    case FcTypeDouble:
	sprintf ((char *) temp, "%g", v.u.d);
	return FcNameUnparseString (buf, temp, 0);
    case FcTypeString:
	return FcNameUnparseString (buf, v.u.s, escape);
    case FcTypeBool:
	return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0);
    case FcTypeMatrix:
	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:
	return FcNameUnparseCharSet (buf, v.u.c);
    case FcTypeLangSet:
	return FcNameUnparseLangSet (buf, v.u.l);
    case FcTypeFTFace:
	return FcTrue;
    }
    return FcFalse;
}

static FcBool
FcNameUnparseValueList (FcStrBuf	*buf,
			FcValueListPtr	v,
			FcChar8		*escape)
{
    while (v)
    {
	if (!FcNameUnparseValue (buf, &v->value, escape))
	    return FcFalse;
	if ((v = FcValueListNext(v)) != NULL)
	    if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0))
		return FcFalse;
    }
    return FcTrue;
}

#define FC_ESCAPE_FIXED    "\\-:,"
#define FC_ESCAPE_VARIABLE "\\=_:,"

FcChar8 *
FcNameUnparse (FcPattern *pat)
{
    return FcNameUnparseEscaped (pat, FcTrue);
}

FcChar8 *
FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
{
    FcStrBuf		    buf;
    FcChar8		    buf_static[8192];
    int			    i;
    FcPatternElt	    *e;
    const FcObjectTypeList  *l;
    const FcObjectType	    *o;

    FcStrBufInit (&buf, buf_static, sizeof (buf_static));
    e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT);
    if (e)
    {
        if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
	    goto bail0;
    }
    e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT);
    if (e)
    {
	if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0))
	    goto bail0;
	if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
	    goto bail0;
    }
    for (l = _FcObjectTypes; l; l = l->next)
    {
	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))
		continue;
	    
	    e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object));
	    if (e)
	    {
		if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0))
		    goto bail0;
		if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0))
		    goto bail0;
		if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0))
		    goto bail0;
		if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? 
					     (FcChar8 *) FC_ESCAPE_VARIABLE : 0))
		    goto bail0;
	    }
	}
    }
    return FcStrBufDone (&buf);
bail0:
    FcStrBufDestroy (&buf);
    return 0;
}
