/*
 * Copyright © 2000 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of the author(s) not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  The authors make no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include "fcint.h"
#include "fcftint.h"

/* Objects MT-safe for readonly access. */

FcPattern *
FcPatternCreate (void)
{
    FcPattern	*p;

    p = (FcPattern *) malloc (sizeof (FcPattern));
    if (!p)
	return 0;
    memset (p, 0, sizeof (FcPattern));
    p->num = 0;
    p->size = 0;
    p->elts_offset = FcPtrToOffset (p, NULL);
    FcRefInit (&p->ref, 1);
    return p;
}

void
FcValueDestroy (FcValue v)
{
    switch ((int) v.type) {
    case FcTypeString:
	FcFree (v.u.s);
	break;
    case FcTypeMatrix:
	FcMatrixFree ((FcMatrix *) v.u.m);
	break;
    case FcTypeCharSet:
	FcCharSetDestroy ((FcCharSet *) v.u.c);
	break;
    case FcTypeLangSet:
	FcLangSetDestroy ((FcLangSet *) v.u.l);
	break;
    case FcTypeRange:
	FcRangeDestroy ((FcRange *) v.u.r);
	break;
    default:
	break;
    }
}

FcValue
FcValueCanonicalize (const FcValue *v)
{
    FcValue new;

    switch ((int) v->type)
    {
    case FcTypeString:
	new.u.s = FcValueString(v);
	new.type = FcTypeString;
	break;
    case FcTypeCharSet:
	new.u.c = FcValueCharSet(v);
	new.type = FcTypeCharSet;
	break;
    case FcTypeLangSet:
	new.u.l = FcValueLangSet(v);
	new.type = FcTypeLangSet;
	break;
    case FcTypeRange:
	new.u.r = FcValueRange(v);
	new.type = FcTypeRange;
	break;
    default:
	new = *v;
	break;
    }
    return new;
}

FcValue
FcValueSave (FcValue v)
{
    switch ((int) v.type) {
    case FcTypeString:
	v.u.s = FcStrdup (v.u.s);
	if (!v.u.s)
	    v.type = FcTypeVoid;
	break;
    case FcTypeMatrix:
	v.u.m = FcMatrixCopy (v.u.m);
	if (!v.u.m)
	    v.type = FcTypeVoid;
	break;
    case FcTypeCharSet:
	v.u.c = FcCharSetCopy ((FcCharSet *) v.u.c);
	if (!v.u.c)
	    v.type = FcTypeVoid;
	break;
    case FcTypeLangSet:
	v.u.l = FcLangSetCopy (v.u.l);
	if (!v.u.l)
	    v.type = FcTypeVoid;
	break;
    case FcTypeRange:
	v.u.r = FcRangeCopy (v.u.r);
	if (!v.u.r)
	    v.type = FcTypeVoid;
	break;
    default:
	break;
    }
    return v;
}

FcValueListPtr
FcValueListCreate (void)
{
    return calloc (1, sizeof (FcValueList));
}

void
FcValueListDestroy (FcValueListPtr l)
{
    FcValueListPtr next;
    for (; l; l = next)
    {
	switch ((int) l->value.type) {
	case FcTypeString:
	    FcFree (l->value.u.s);
	    break;
	case FcTypeMatrix:
	    FcMatrixFree ((FcMatrix *)l->value.u.m);
	    break;
	case FcTypeCharSet:
	    FcCharSetDestroy
		((FcCharSet *) (l->value.u.c));
	    break;
	case FcTypeLangSet:
	    FcLangSetDestroy
		((FcLangSet *) (l->value.u.l));
	    break;
	case FcTypeRange:
	    FcRangeDestroy ((FcRange *) (l->value.u.r));
	    break;
	default:
	    break;
	}
	next = FcValueListNext(l);
	free(l);
    }
}

FcValueListPtr
FcValueListPrepend (FcValueListPtr vallist,
		    FcValue        value,
		    FcValueBinding binding)
{
    FcValueListPtr new;

    if (value.type == FcTypeVoid)
	return vallist;
    new = FcValueListCreate ();
    if (!new)
	return vallist;

    new->value = FcValueSave (value);
    new->binding = binding;
    new->next = vallist;

    return new;
}

FcValueListPtr
FcValueListAppend (FcValueListPtr vallist,
		   FcValue        value,
		   FcValueBinding binding)
{
    FcValueListPtr new, last;

    if (value.type == FcTypeVoid)
	return vallist;
    new = FcValueListCreate ();
    if (!new)
	return vallist;

    new->value = FcValueSave (value);
    new->binding = binding;
    new->next = NULL;

    if (vallist)
    {
	for (last = vallist; FcValueListNext (last); last = FcValueListNext (last));

	last->next = new;
    }
    else
	vallist = new;

    return vallist;
}

FcValueListPtr
FcValueListDuplicate(FcValueListPtr orig)
{
    FcValueListPtr new = NULL, l, t = NULL;
    FcValue v;

    for (l = orig; l != NULL; l = FcValueListNext (l))
    {
	if (!new)
	{
	    t = new = FcValueListCreate();
	}
	else
	{
	    t->next = FcValueListCreate();
	    t = FcValueListNext (t);
	}
	v = FcValueCanonicalize (&l->value);
	t->value = FcValueSave (v);
	t->binding = l->binding;
	t->next = NULL;
    }

    return new;
}

FcBool
FcValueEqual (FcValue va, FcValue vb)
{
    if (va.type != vb.type)
    {
	if (va.type == FcTypeInteger)
	{
	    va.type = FcTypeDouble;
	    va.u.d = va.u.i;
	}
	if (vb.type == FcTypeInteger)
	{
	    vb.type = FcTypeDouble;
	    vb.u.d = vb.u.i;
	}
	if (va.type != vb.type)
	    return FcFalse;
    }
    switch (va.type) {
    case FcTypeUnknown:
	return FcFalse;	/* don't know how to compare this object */
    case FcTypeVoid:
	return FcTrue;
    case FcTypeInteger:
	return va.u.i == vb.u.i;
    case FcTypeDouble:
	return va.u.d == vb.u.d;
    case FcTypeString:
	return FcStrCmpIgnoreCase (va.u.s, vb.u.s) == 0;
    case FcTypeBool:
	return va.u.b == vb.u.b;
    case FcTypeMatrix:
	return FcMatrixEqual (va.u.m, vb.u.m);
    case FcTypeCharSet:
	return FcCharSetEqual (va.u.c, vb.u.c);
    case FcTypeFTFace:
	return va.u.f == vb.u.f;
    case FcTypeLangSet:
	return FcLangSetEqual (va.u.l, vb.u.l);
    case FcTypeRange:
	return FcRangeIsInRange (va.u.r, vb.u.r);
    }
    return FcFalse;
}

static FcChar32
FcDoubleHash (double d)
{
    if (d < 0)
	d = -d;
    if (d > 0xffffffff)
	d = 0xffffffff;
    return (FcChar32) d;
}

FcChar32
FcStringHash (const FcChar8 *s)
{
    FcChar8	c;
    FcChar32	h = 0;

    if (s)
	while ((c = *s++))
	    h = ((h << 1) | (h >> 31)) ^ c;
    return h;
}

static FcChar32
FcValueHash (const FcValue *v)
{
    switch (v->type) {
    case FcTypeUnknown:
    case FcTypeVoid:
	return 0;
    case FcTypeInteger:
	return (FcChar32) v->u.i;
    case FcTypeDouble:
	return FcDoubleHash (v->u.d);
    case FcTypeString:
	return FcStringHash (FcValueString(v));
    case FcTypeBool:
	return (FcChar32) v->u.b;
    case FcTypeMatrix:
	return (FcDoubleHash (v->u.m->xx) ^
		FcDoubleHash (v->u.m->xy) ^
		FcDoubleHash (v->u.m->yx) ^
		FcDoubleHash (v->u.m->yy));
    case FcTypeCharSet:
	return (FcChar32) FcValueCharSet(v)->num;
    case FcTypeFTFace:
	return FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->family_name) ^
	       FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->style_name);
    case FcTypeLangSet:
	return FcLangSetHash (FcValueLangSet(v));
    case FcTypeRange:
	return FcRangeHash (v->u.r);
    }
    return 0;
}

static FcBool
FcValueListEqual (FcValueListPtr la, FcValueListPtr lb)
{
    if (la == lb)
	return FcTrue;

    while (la && lb)
    {
	if (!FcValueEqual (la->value, lb->value))
	    return FcFalse;
	la = FcValueListNext(la);
	lb = FcValueListNext(lb);
    }
    if (la || lb)
	return FcFalse;
    return FcTrue;
}

static FcChar32
FcValueListHash (FcValueListPtr l)
{
    FcChar32	hash = 0;

    for (; l; l = FcValueListNext(l))
    {
	hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (&l->value);
    }
    return hash;
}

static void *
FcPatternGetCacheObject (FcPattern *p)
{
  /* We use a value to find the cache, instead of the FcPattern object
   * because the pattern itself may be a cache allocation if we rewrote the path,
   * so the p may not be in the cached region. */
  return FcPatternEltValues(&FcPatternElts (p)[0]);
}

FcPattern *
FcPatternCacheRewriteFile (const FcPattern *p,
                           FcCache *cache,
                           const FcChar8 *relocated_font_file)
{
    FcPatternElt *elts = FcPatternElts (p);
    size_t i,j;
    FcChar8 *data;
    FcPattern *new_p;
    FcPatternElt *new_elts;
    FcValueList *new_value_list;
    size_t new_path_len = strlen ((char *)relocated_font_file);
    FcChar8 *new_path;

    /* Allocate space for the patter, the PatternElt headers and
     * the FC_FILE FcValueList and path that will be freed with the
     * cache */
    data = FcCacheAllocate (cache,
			    sizeof (FcPattern) +
			    p->num * sizeof (FcPatternElt) +
			    sizeof (FcValueList) +
			    new_path_len + 1);

    new_p = (FcPattern *)data;
    data += sizeof (FcPattern);
    new_elts = (FcPatternElt *)(data);
    data += p->num * sizeof (FcPatternElt);
    new_value_list = (FcValueList *)data;
    data += sizeof (FcValueList);
    new_path = data;

    *new_p = *p;
    new_p->elts_offset = FcPtrToOffset (new_p, new_elts);

    /* Copy all but the FILE values from the cache */
    for (i = 0, j = 0; i < p->num; i++)
    {
	FcPatternElt *elt = &elts[i];
	new_elts[j].object = elt->object;
	if (elt->object != FC_FILE_OBJECT)
	    new_elts[j++].values = FcPatternEltValues(elt);
	else
	    new_elts[j++].values = new_value_list;
    }

    new_value_list->next = NULL;
    new_value_list->value.type = FcTypeString;
    new_value_list->value.u.s = new_path;
    new_value_list->binding = FcValueBindingWeak;

    /* Add rewritten path at the end */
    strcpy ((char *)new_path, (char *)relocated_font_file);

    return new_p;
}

void
FcPatternDestroy (FcPattern *p)
{
    int		    i;
    FcPatternElt    *elts;

    if (!p)
	return;

    if (FcRefIsConst (&p->ref))
    {
	FcCacheObjectDereference (FcPatternGetCacheObject(p));
	return;
    }

    if (FcRefDec (&p->ref) != 1)
	return;

    elts = FcPatternElts (p);
    for (i = 0; i < FcPatternObjectCount (p); i++)
	FcValueListDestroy (FcPatternEltValues(&elts[i]));

    free (elts);
    free (p);
}

int
FcPatternObjectCount (const FcPattern *pat)
{
    if (pat)
	return pat->num;

    return 0;
}


static int
FcPatternObjectPosition (const FcPattern *p, FcObject object)
{
    int	    low, high, mid, c;
    FcPatternElt    *elts = FcPatternElts(p);

    low = 0;
    high = FcPatternObjectCount (p) - 1;
    c = 1;
    mid = 0;
    while (low <= high)
    {
	mid = (low + high) >> 1;
	c = elts[mid].object - object;
	if (c == 0)
	    return mid;
	if (c < 0)
	    low = mid + 1;
	else
	    high = mid - 1;
    }
    if (c < 0)
	mid++;
    return -(mid + 1);
}

int
FcPatternPosition (const FcPattern *p, const char *object)
{
    return FcPatternObjectPosition (p, FcObjectFromName (object));
}

FcPatternElt *
FcPatternObjectFindElt (const FcPattern *p, FcObject object)
{
    int	    i = FcPatternObjectPosition (p, object);
    if (i < 0)
	return 0;
    return &FcPatternElts(p)[i];
}

FcPatternElt *
FcPatternObjectInsertElt (FcPattern *p, FcObject object)
{
    int		    i;
    FcPatternElt   *e;

    i = FcPatternObjectPosition (p, object);
    if (i < 0)
    {
	i = -i - 1;

	/* reallocate array */
	if (FcPatternObjectCount (p) + 1 >= p->size)
	{
	    int s = p->size + 16;
	    if (p->size)
	    {
		FcPatternElt *e0 = FcPatternElts(p);
		e = (FcPatternElt *) realloc (e0, s * sizeof (FcPatternElt));
		if (!e) /* maybe it was mmapped */
		{
		    e = malloc(s * sizeof (FcPatternElt));
		    if (e)
			memcpy(e, e0, FcPatternObjectCount (p) * sizeof (FcPatternElt));
		}
	    }
	    else
		e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt));
	    if (!e)
		return FcFalse;
	    p->elts_offset = FcPtrToOffset (p, e);
	    while (p->size < s)
	    {
		e[p->size].object = 0;
		e[p->size].values = NULL;
		p->size++;
	    }
	}
	
	e = FcPatternElts(p);
	/* move elts up */
	memmove (e + i + 1,
		 e + i,
		 sizeof (FcPatternElt) *
		 (FcPatternObjectCount (p) - i));
		
	/* bump count */
	p->num++;
	
	e[i].object = object;
	e[i].values = NULL;
    }

    return FcPatternElts(p) + i;
}

FcBool
FcPatternEqual (const FcPattern *pa, const FcPattern *pb)
{
    FcPatternIter ia, ib;

    if (pa == pb)
	return FcTrue;

    if (FcPatternObjectCount (pa) != FcPatternObjectCount (pb))
	return FcFalse;
    FcPatternIterStart (pa, &ia);
    FcPatternIterStart (pb, &ib);
    do {
	FcBool ra, rb;

	if (!FcPatternIterEqual (pa, &ia, pb, &ib))
	    return FcFalse;
	ra = FcPatternIterNext (pa, &ia);
	rb = FcPatternIterNext (pb, &ib);
	if (!ra && !rb)
	    break;
    } while (1);

    return FcTrue;
}

FcChar32
FcPatternHash (const FcPattern *p)
{
    int		i;
    FcChar32	h = 0;
    FcPatternElt    *pe = FcPatternElts(p);

    for (i = 0; i < FcPatternObjectCount (p); i++)
    {
	h = (((h << 1) | (h >> 31)) ^
	     pe[i].object ^
	     FcValueListHash (FcPatternEltValues(&pe[i])));
    }
    return h;
}

FcBool
FcPatternEqualSubset (const FcPattern *pai, const FcPattern *pbi, const FcObjectSet *os)
{
    FcPatternElt    *ea, *eb;
    int		    i;

    for (i = 0; i < os->nobject; i++)
    {
	FcObject    object = FcObjectFromName (os->objects[i]);
	ea = FcPatternObjectFindElt (pai, object);
	eb = FcPatternObjectFindElt (pbi, object);
	if (ea)
	{
	    if (!eb)
		return FcFalse;
	    if (!FcValueListEqual (FcPatternEltValues(ea), FcPatternEltValues(eb)))
		return FcFalse;
	}
	else
	{
	    if (eb)
		return FcFalse;
	}
    }
    return FcTrue;
}

FcBool
FcPatternObjectListAdd (FcPattern	*p,
			FcObject	object,
			FcValueListPtr	list,
			FcBool		append)
{
    FcPatternElt   *e;
    FcValueListPtr l, *prev;

    if (FcRefIsConst (&p->ref))
	goto bail0;

    /*
     * Make sure the stored type is valid for built-in objects
     */
    for (l = list; l != NULL; l = FcValueListNext (l))
    {
	if (!FcObjectValidType (object, l->value.type))
	{
	    fprintf (stderr,
		     "Fontconfig warning: FcPattern object %s does not accept value", FcObjectName (object));
	    FcValuePrintFile (stderr, l->value);
	    fprintf (stderr, "\n");
	    goto bail0;
	}
    }

    e = FcPatternObjectInsertElt (p, object);
    if (!e)
	goto bail0;

    if (append)
    {
	for (prev = &e->values; *prev; prev = &(*prev)->next)
	    ;
	*prev = list;
    }
    else
    {
	for (prev = &list; *prev; prev = &(*prev)->next)
	    ;
	*prev = e->values;
	e->values = list;
    }

    return FcTrue;

bail0:
    return FcFalse;
}

FcBool
FcPatternObjectAddWithBinding  (FcPattern	*p,
				FcObject	object,
				FcValue		value,
				FcValueBinding  binding,
				FcBool		append)
{
    FcPatternElt   *e;
    FcValueListPtr new, *prev;

    if (FcRefIsConst (&p->ref))
	goto bail0;

    new = FcValueListCreate ();
    if (!new)
	goto bail0;

    value = FcValueSave (value);
    if (value.type == FcTypeVoid)
	goto bail1;

    /*
     * Make sure the stored type is valid for built-in objects
     */
    if (!FcObjectValidType (object, value.type))
    {
	fprintf (stderr,
		 "Fontconfig warning: FcPattern object %s does not accept value",
		 FcObjectName (object));
	FcValuePrintFile (stderr, value);
	fprintf (stderr, "\n");
	goto bail1;
    }

    new->value = value;
    new->binding = binding;
    new->next = NULL;

    e = FcPatternObjectInsertElt (p, object);
    if (!e)
	goto bail2;

    if (append)
    {
	for (prev = &e->values; *prev; prev = &(*prev)->next)
	    ;
	*prev = new;
    }
    else
    {
	new->next = e->values;
	e->values = new;
    }

    return FcTrue;

bail2:
    FcValueDestroy (value);
bail1:
    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 FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
					  value, FcValueBindingStrong, append);
}

FcBool
FcPatternAddWeak  (FcPattern *p, const char *object, FcValue value, FcBool append)
{
    return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
					  value, FcValueBindingWeak, append);
}

FcBool
FcPatternObjectDel (FcPattern *p, FcObject object)
{
    FcPatternElt   *e;

    e = FcPatternObjectFindElt (p, object);
    if (!e)
	return FcFalse;

    /* destroy value */
    FcValueListDestroy (e->values);

    /* shuffle existing ones down */
    memmove (e, e+1,
	     (FcPatternElts(p) + FcPatternObjectCount (p) - (e + 1)) *
	     sizeof (FcPatternElt));
    p->num--;
    e = FcPatternElts(p) + FcPatternObjectCount (p);
    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 = FcPatternObjectFindElt (p, FcObjectFromName (object));
    if (!e)
	return FcFalse;
    for (prev = &e->values; (l = *prev); prev = &l->next)
    {
	if (!id)
	{
	    *prev = l->next;
	    l->next = NULL;
	    FcValueListDestroy (l);
	    if (!e->values)
		FcPatternDel (p, object);
	    return FcTrue;
	}
	id--;
    }
    return FcFalse;
}

FcBool
FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i)
{
    FcValue	v;

    v.type = FcTypeInteger;
    v.u.i = i;
    return FcPatternObjectAdd (p, object, v, FcTrue);
}

FcBool
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 FcPatternObjectAdd (p, object, v, FcTrue);
}


FcBool
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;

    if (!s)
    {
	v.type = FcTypeVoid;
	v.u.s = 0;
	return FcPatternObjectAdd (p, object, v, FcTrue);
    }

    v.type = FcTypeString;
    v.u.s = s;
    return FcPatternObjectAdd (p, object, v, FcTrue);
}

FcBool
FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
{
    return FcPatternObjectAddString (p, FcObjectFromName (object), s);
}

FcBool
FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s)
{
    FcValue	v;

    v.type = FcTypeMatrix;
    v.u.m = s;
    return FcPatternAdd (p, object, v, FcTrue);
}


FcBool
FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b)
{
    FcValue	v;

    v.type = FcTypeBool;
    v.u.b = b;
    return FcPatternObjectAdd (p, object, v, FcTrue);
}

FcBool
FcPatternAddBool (FcPattern *p, const char *object, FcBool b)
{
    return FcPatternObjectAddBool (p, FcObjectFromName (object), b);
}

FcBool
FcPatternObjectAddCharSet (FcPattern *p, FcObject object, const FcCharSet *c)
{
    FcValue	v;

    v.type = FcTypeCharSet;
    v.u.c = (FcCharSet *)c;
    return FcPatternObjectAdd (p, object, v, FcTrue);
}

FcBool
FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c)
{
    return FcPatternObjectAddCharSet (p, FcObjectFromName (object), c);
}

FcBool
FcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f)
{
    FcValue	v;

    v.type = FcTypeFTFace;
    v.u.f = (void *) f;
    return FcPatternAdd (p, object, v, FcTrue);
}

FcBool
FcPatternObjectAddLangSet (FcPattern *p, FcObject object, const FcLangSet *ls)
{
    FcValue	v;

    v.type = FcTypeLangSet;
    v.u.l = (FcLangSet *)ls;
    return FcPatternObjectAdd (p, object, v, FcTrue);
}

FcBool
FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls)
{
    return FcPatternObjectAddLangSet (p, FcObjectFromName (object), ls);
}

FcBool
FcPatternObjectAddRange (FcPattern *p, FcObject object, const FcRange *r)
{
    FcValue v;

    v.type = FcTypeRange;
    v.u.r = (FcRange *)r;
    return FcPatternObjectAdd (p, object, v, FcTrue);
}

FcBool
FcPatternAddRange (FcPattern *p, const char *object, const FcRange *r)
{
    return FcPatternObjectAddRange (p, FcObjectFromName (object), r);
}

FcResult
FcPatternObjectGetWithBinding (const FcPattern *p, FcObject object, int id, FcValue *v, FcValueBinding *b)
{
    FcPatternElt   *e;
    FcValueListPtr l;

    if (!p)
	return FcResultNoMatch;
    e = FcPatternObjectFindElt (p, object);
    if (!e)
	return FcResultNoMatch;
    for (l = FcPatternEltValues(e); l; l = FcValueListNext(l))
    {
	if (!id)
	{
	    *v = FcValueCanonicalize(&l->value);
	    if (b)
		*b = l->binding;
	    return FcResultMatch;
	}
	id--;
    }
    return FcResultNoId;
}

FcResult
FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v)
{
    return FcPatternObjectGetWithBinding (p, object, id, v, NULL);
}

FcResult
FcPatternGetWithBinding (const FcPattern *p, const char *object, int id, FcValue *v, FcValueBinding *b)
{
    return FcPatternObjectGetWithBinding (p, FcObjectFromName (object), id, v, b);
}

FcResult
FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v)
{
    return FcPatternObjectGetWithBinding (p, FcObjectFromName (object), id, v, NULL);
}

FcResult
FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int id, int *i)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternObjectGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    switch ((int) v.type) {
    case FcTypeDouble:
	*i = (int) v.u.d;
	break;
    case FcTypeInteger:
	*i = v.u.i;
	break;
    default:
        return FcResultTypeMismatch;
    }
    return FcResultMatch;
}

FcResult
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 = FcPatternObjectGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    switch ((int) v.type) {
    case FcTypeDouble:
	*d = v.u.d;
	break;
    case FcTypeInteger:
	*d = (double) v.u.i;
	break;
    default:
        return FcResultTypeMismatch;
    }
    return FcResultMatch;
}

FcResult
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 = FcPatternObjectGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    if (v.type != FcTypeString)
        return FcResultTypeMismatch;

    *s = (FcChar8 *) v.u.s;
    return FcResultMatch;
}

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;
    FcResult	r;

    r = FcPatternGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    if (v.type != FcTypeMatrix)
        return FcResultTypeMismatch;
    *m = (FcMatrix *)v.u.m;
    return FcResultMatch;
}


FcResult
FcPatternObjectGetBool (const FcPattern *p, FcObject object, int id, FcBool *b)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternObjectGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    if (v.type != FcTypeBool)
        return FcResultTypeMismatch;
    *b = v.u.b;
    return FcResultMatch;
}

FcResult
FcPatternGetBool(const FcPattern *p, const char *object, int id, FcBool *b)
{
    return FcPatternObjectGetBool (p, FcObjectFromName (object), id, b);
}

FcResult
FcPatternGetCharSet(const FcPattern *p, const char *object, int id, FcCharSet **c)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    if (v.type != FcTypeCharSet)
        return FcResultTypeMismatch;
    *c = (FcCharSet *)v.u.c;
    return FcResultMatch;
}

FcResult
FcPatternGetFTFace(const FcPattern *p, const char *object, int id, FT_Face *f)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    if (v.type != FcTypeFTFace)
	return FcResultTypeMismatch;
    *f = (FT_Face) v.u.f;
    return FcResultMatch;
}

FcResult
FcPatternGetLangSet(const FcPattern *p, const char *object, int id, FcLangSet **ls)
{
    FcValue	v;
    FcResult	r;

    r = FcPatternGet (p, object, id, &v);
    if (r != FcResultMatch)
	return r;
    if (v.type != FcTypeLangSet)
        return FcResultTypeMismatch;
    *ls = (FcLangSet *)v.u.l;
    return FcResultMatch;
}

FcResult
FcPatternObjectGetRange (const FcPattern *p, FcObject object, int id, FcRange **r)
{
    FcValue	v;
    FcResult	res;

    res = FcPatternObjectGet (p, object, id, &v);
    if (res != FcResultMatch)
	return res;
    switch ((int)v.type) {
    case FcTypeRange:
	*r = (FcRange *)v.u.r;
	break;
    default:
	return FcResultTypeMismatch;
    }
    return FcResultMatch;
}

FcResult
FcPatternGetRange (const FcPattern *p, const char *object, int id, FcRange **r)
{
    return FcPatternObjectGetRange (p, FcObjectFromName (object), id, r);
}

FcPattern *
FcPatternDuplicate (const FcPattern *orig)
{
    FcPattern	    *new;
    FcPatternIter   iter;
    FcValueListPtr  l;

    if (!orig)
	return NULL;

    new = FcPatternCreate ();
    if (!new)
	goto bail0;

    FcPatternIterStart (orig, &iter);
    do
    {
	for (l = FcPatternIterGetValues (orig, &iter); l; l = FcValueListNext (l))
	{
	    if (!FcPatternObjectAddWithBinding (new, FcPatternIterGetObjectId (orig, &iter),
						FcValueCanonicalize(&l->value),
						l->binding,
						FcTrue))
		goto bail1;
	}
    } while (FcPatternIterNext (orig, &iter));

    return new;

bail1:
    FcPatternDestroy (new);
bail0:
    return 0;
}

void
FcPatternReference (FcPattern *p)
{
    if (!FcRefIsConst (&p->ref))
	FcRefInc (&p->ref);
    else
	FcCacheObjectReference (FcPatternGetCacheObject(p));
}

FcPattern *
FcPatternVaBuild (FcPattern *p, va_list va)
{
    FcPattern	*ret;

    FcPatternVapBuild (ret, p, va);
    return ret;
}

FcPattern *
FcPatternBuild (FcPattern *p, ...)
{
    va_list	va;

    va_start (va, p);
    FcPatternVapBuild (p, p, va);
    va_end (va);
    return p;
}

/*
 * Add all of the elements in 's' to 'p'
 */
FcBool
FcPatternAppend (FcPattern *p, FcPattern *s)
{
    FcPatternIter  iter;
    FcValueListPtr v;

    FcPatternIterStart (s, &iter);
    do
    {
	for (v = FcPatternIterGetValues (s, &iter); v; v = FcValueListNext (v))
	{
	    if (!FcPatternObjectAddWithBinding (p, FcPatternIterGetObjectId (s, &iter),
						FcValueCanonicalize(&v->value),
						v->binding, FcTrue))
		return FcFalse;
	}
    } while (FcPatternIterNext (s, &iter));

    return FcTrue;
}

FcPattern *
FcPatternFilter (FcPattern *p, const FcObjectSet *os)
{
    int		    i;
    FcPattern	    *ret;
    FcPatternElt    *e;
    FcValueListPtr  v;

    if (!os)
	return FcPatternDuplicate (p);

    ret = FcPatternCreate ();
    if (!ret)
	return NULL;

    for (i = 0; i < os->nobject; i++)
    {
	FcObject object = FcObjectFromName (os->objects[i]);
	e = FcPatternObjectFindElt (p, object);
	if (e)
	{
	    for (v = FcPatternEltValues(e); v; v = FcValueListNext(v))
	    {
		if (!FcPatternObjectAddWithBinding (ret, e->object,
						    FcValueCanonicalize(&v->value),
						    v->binding, FcTrue))
		    goto bail0;
	    }
	}
    }
    return ret;

bail0:
    FcPatternDestroy (ret);
    return NULL;
}

typedef struct _FcPatternPrivateIter {
    FcPatternElt *elt;
    int           pos;
} FcPatternPrivateIter;

static void
FcPatternIterSet (const FcPattern *pat, FcPatternPrivateIter *iter)
{
    iter->elt = FcPatternObjectCount (pat) > 0 && iter->pos < FcPatternObjectCount (pat) ? &FcPatternElts (pat)[iter->pos] : NULL;
}

void
FcPatternIterStart (const FcPattern *pat, FcPatternIter *iter)
{
    FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;

    priv->pos = 0;
    FcPatternIterSet (pat, priv);
}

FcBool
FcPatternIterNext (const FcPattern *pat, FcPatternIter *iter)
{
    FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;

    priv->pos++;
    if (priv->pos >= FcPatternObjectCount (pat))
	return FcFalse;
    FcPatternIterSet (pat, priv);

    return FcTrue;
}

FcBool
FcPatternIterEqual (const FcPattern *p1, FcPatternIter *i1,
		    const FcPattern *p2, FcPatternIter *i2)
{
    FcBool b1 = FcPatternIterIsValid (p1, i1);
    FcBool b2 = FcPatternIterIsValid (p2, i2);

    if (!i1 && !i2)
	return FcTrue;
    if (!b1 || !b2)
	return FcFalse;
    if (FcPatternIterGetObjectId (p1, i1) != FcPatternIterGetObjectId (p2, i2))
	return FcFalse;

    return FcValueListEqual (FcPatternIterGetValues (p1, i1),
			     FcPatternIterGetValues (p2, i2));
}

FcBool
FcPatternFindObjectIter (const FcPattern *pat, FcPatternIter *iter, FcObject object)
{
    FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
    int i = FcPatternObjectPosition (pat, object);

    priv->elt = NULL;
    if (i < 0)
	return FcFalse;

    priv->pos = i;
    FcPatternIterSet (pat, priv);

    return FcTrue;
}

FcBool
FcPatternFindIter (const FcPattern *pat, FcPatternIter *iter, const char *object)
{
    return FcPatternFindObjectIter (pat, iter, FcObjectFromName (object));
}

FcBool
FcPatternIterIsValid (const FcPattern *pat, FcPatternIter *iter)
{
    FcPatternPrivateIter *priv = (FcPatternPrivateIter *)iter;

    if (priv && priv->elt)
	return FcTrue;

    return FcFalse;
}

FcObject
FcPatternIterGetObjectId (const FcPattern *pat, FcPatternIter *iter)
{
    FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;

    if (priv && priv->elt)
	return priv->elt->object;

    return 0;
}

const char *
FcPatternIterGetObject (const FcPattern *pat, FcPatternIter *iter)
{
    return FcObjectName (FcPatternIterGetObjectId (pat, iter));
}

FcValueListPtr
FcPatternIterGetValues (const FcPattern *pat, FcPatternIter *iter)
{
    FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;

    if (priv && priv->elt)
	return FcPatternEltValues (priv->elt);

    return NULL;
}

int
FcPatternIterValueCount (const FcPattern *pat, FcPatternIter *iter)
{
    int count = 0;
    FcValueListPtr l;

    for (l = FcPatternIterGetValues (pat, iter); l; l = FcValueListNext (l))
	count++;

    return count;
}

FcResult
FcPatternIterGetValue (const FcPattern *pat, FcPatternIter *iter, int id, FcValue *v, FcValueBinding *b)
{
    FcValueListPtr l;

    for (l = FcPatternIterGetValues (pat, iter); l; l = FcValueListNext (l))
    {
	if (id == 0)
	{
	    *v = FcValueCanonicalize (&l->value);
	    if (b)
		*b = l->binding;
	    return FcResultMatch;
	}
	id--;
    }
    return FcResultNoId;
}

FcBool
FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat)
{
    int	i;
    FcPatternElt    *elts = FcPatternElts(pat);

    if (!FcSerializeAlloc (serialize, pat, sizeof (FcPattern)))
	return FcFalse;
    if (!FcSerializeAlloc (serialize, elts, FcPatternObjectCount (pat) * sizeof (FcPatternElt)))
	return FcFalse;
    for (i = 0; i < FcPatternObjectCount (pat); i++)
	if (!FcValueListSerializeAlloc (serialize, FcPatternEltValues(elts+i)))
	    return FcFalse;
    return FcTrue;
}

FcPattern *
FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat)
{
    FcPattern	    *pat_serialized;
    FcPatternElt    *elts = FcPatternElts (pat);
    FcPatternElt    *elts_serialized;
    FcValueList	    *values_serialized;
    int		    i;

    pat_serialized = FcSerializePtr (serialize, pat);
    if (!pat_serialized)
	return NULL;
    *pat_serialized = *pat;
    pat_serialized->size = FcPatternObjectCount (pat);
    FcRefSetConst (&pat_serialized->ref);

    elts_serialized = FcSerializePtr (serialize, elts);
    if (!elts_serialized)
	return NULL;

    pat_serialized->elts_offset = FcPtrToOffset (pat_serialized,
						 elts_serialized);

    for (i = 0; i < FcPatternObjectCount (pat); i++)
    {
	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);
    }
    if (FcDebug() & FC_DBG_CACHEV) {
	printf ("Raw pattern:\n");
	FcPatternPrint (pat);
	printf ("Serialized pattern:\n");
	FcPatternPrint (pat_serialized);
	printf ("\n");
    }
    return pat_serialized;
}

FcBool
FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *vl)
{
    while (vl)
    {
	if (!FcSerializeAlloc (serialize, vl, sizeof (FcValueList)))
	    return FcFalse;
	switch ((int) vl->value.type) {
	case FcTypeString:
	    if (!FcStrSerializeAlloc (serialize, vl->value.u.s))
		return FcFalse;
	    break;
	case FcTypeCharSet:
	    if (!FcCharSetSerializeAlloc (serialize, vl->value.u.c))
		return FcFalse;
	    break;
	case FcTypeLangSet:
	    if (!FcLangSetSerializeAlloc (serialize, vl->value.u.l))
		return FcFalse;
	    break;
	case FcTypeRange:
	    if (!FcRangeSerializeAlloc (serialize, vl->value.u.r))
		return FcFalse;
	    break;
	default:
	    break;
	}
	vl = vl->next;
    }
    return FcTrue;
}

FcValueList *
FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl)
{
    FcValueList	*vl_serialized;
    FcChar8	*s_serialized;
    FcCharSet	*c_serialized;
    FcLangSet	*l_serialized;
    FcRange	*r_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.type = vl->value.type;
	switch ((int) vl->value.type) {
	case FcTypeInteger:
	    vl_serialized->value.u.i = vl->value.u.i;
	    break;
	case FcTypeDouble:
	    vl_serialized->value.u.d = vl->value.u.d;
	    break;
	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 FcTypeBool:
	    vl_serialized->value.u.b = vl->value.u.b;
	    break;
	case FcTypeMatrix:
	    /* can't happen */
	    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 FcTypeFTFace:
	    /* can't happen */
	    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;
	case FcTypeRange:
	    r_serialized = FcRangeSerialize (serialize, vl->value.u.r);
	    if (!r_serialized)
		return NULL;
	    vl_serialized->value.u.r = FcPtrToEncodedOffset (&vl_serialized->value,
							     r_serialized,
							     FcRange);
	    break;
	default:
	    break;
	}
	prev_serialized = vl_serialized;
	vl = vl->next;
    }
    return head_serialized;
}

#define __fcpat__
#include "fcaliastail.h"
#include "fcftaliastail.h"
#undef __fcpat__
