fontconfig/src/fcpat.c

1649 lines
35 KiB
C
Raw Normal View History

2002-02-15 00:34:13 +01:00
/*
2004-12-07 02:14:46 +01:00
* Copyright © 2000 Keith Packard
2002-02-15 00:34:13 +01:00
*
* 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
2002-02-15 00:34:13 +01:00
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. The authors make no
2002-02-15 00:34:13 +01:00
* 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,
2002-02-15 00:34:13 +01:00
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
2002-02-15 00:34:13 +01:00
* 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. */
2002-02-15 00:34:13 +01:00
FcPattern *
FcPatternCreate (void)
{
FcPattern *p;
p = (FcPattern *) malloc (sizeof (FcPattern));
if (!p)
return 0;
memset (p, 0, sizeof (FcPattern));
2002-02-15 00:34:13 +01:00
p->num = 0;
p->size = 0;
p->elts_offset = FcPtrToOffset (p, NULL);
FcRefInit (&p->ref, 1);
2002-02-15 00:34:13 +01:00
return p;
}
void
FcValueDestroy (FcValue v)
{
2012-12-30 04:11:09 +01:00
switch ((int) v.type) {
2002-02-15 00:34:13 +01:00
case FcTypeString:
2013-01-02 09:06:15 +01:00
FcFree (v.u.s);
2002-02-15 00:34:13 +01:00
break;
case FcTypeMatrix:
FcMatrixFree ((FcMatrix *) v.u.m);
2002-02-15 00:34:13 +01:00
break;
case FcTypeCharSet:
FcCharSetDestroy ((FcCharSet *) v.u.c);
2002-02-15 00:34:13 +01:00
break;
case FcTypeLangSet:
FcLangSetDestroy ((FcLangSet *) v.u.l);
break;
case FcTypeRange:
FcRangeDestroy ((FcRange *) v.u.r);
break;
2002-02-15 00:34:13 +01:00
default:
break;
}
}
FcValue
FcValueCanonicalize (const FcValue *v)
{
FcValue new;
2012-12-30 04:11:09 +01:00
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;
}
2002-02-15 00:34:13 +01:00
FcValue
FcValueSave (FcValue v)
{
2012-12-30 04:11:09 +01:00
switch ((int) v.type) {
2002-02-15 00:34:13 +01:00
case FcTypeString:
2013-01-02 09:06:15 +01:00
v.u.s = FcStrdup (v.u.s);
if (!v.u.s)
2002-02-15 00:34:13 +01:00
v.type = FcTypeVoid;
break;
case FcTypeMatrix:
v.u.m = FcMatrixCopy (v.u.m);
if (!v.u.m)
2002-02-15 00:34:13 +01:00
v.type = FcTypeVoid;
break;
case FcTypeCharSet:
v.u.c = FcCharSetCopy ((FcCharSet *) v.u.c);
if (!v.u.c)
2002-02-15 00:34:13 +01:00
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;
2002-02-15 00:34:13 +01:00
default:
break;
}
return v;
}
FcValueListPtr
FcValueListCreate (void)
{
return calloc (1, sizeof (FcValueList));
}
2002-02-15 00:34:13 +01:00
void
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcValueListDestroy (FcValueListPtr l)
2002-02-15 00:34:13 +01:00
{
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcValueListPtr next;
for (; l; l = next)
2002-02-15 00:34:13 +01:00
{
2012-12-30 04:11:09 +01:00
switch ((int) l->value.type) {
2002-02-15 00:34:13 +01:00
case FcTypeString:
2013-01-02 09:06:15 +01:00
FcFree (l->value.u.s);
2002-02-15 00:34:13 +01:00
break;
case FcTypeMatrix:
FcMatrixFree ((FcMatrix *)l->value.u.m);
2002-02-15 00:34:13 +01:00
break;
case FcTypeCharSet:
2010-04-12 18:18:50 +02:00
FcCharSetDestroy
((FcCharSet *) (l->value.u.c));
2002-02-15 00:34:13 +01:00
break;
case FcTypeLangSet:
2010-04-12 18:18:50 +02:00
FcLangSetDestroy
((FcLangSet *) (l->value.u.l));
break;
case FcTypeRange:
FcRangeDestroy ((FcRange *) (l->value.u.r));
break;
2002-02-15 00:34:13 +01:00
default:
break;
}
next = FcValueListNext(l);
free(l);
2002-02-15 00:34:13 +01:00
}
}
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;
2010-04-12 18:18:50 +02:00
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:
2010-04-12 18:18:50 +02:00
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 (FcValueRange (v));
}
return 0;
}
static FcBool
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
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
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcValueListHash (FcValueListPtr l)
{
FcChar32 hash = 0;
2010-04-12 18:18:50 +02:00
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;
}
2002-02-15 00:34:13 +01:00
void
FcPatternDestroy (FcPattern *p)
{
int i;
FcPatternElt *elts;
2010-04-12 18:18:50 +02:00
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]));
2002-02-15 00:34:13 +01:00
free (elts);
2002-02-15 00:34:13 +01:00
free (p);
}
int
FcPatternObjectCount (const FcPattern *pat)
{
if (pat)
return pat->num;
return 0;
}
static int
FcPatternObjectPosition (const FcPattern *p, FcObject object)
2002-02-15 00:34:13 +01:00
{
int low, high, mid, c;
FcPatternElt *elts = FcPatternElts(p);
low = 0;
high = FcPatternObjectCount (p) - 1;
c = 1;
mid = 0;
while (low <= high)
2002-02-15 00:34:13 +01:00
{
mid = (low + high) >> 1;
c = elts[mid].object - object;
if (c == 0)
return mid;
if (c < 0)
low = mid + 1;
else
high = mid - 1;
2002-02-15 00:34:13 +01:00
}
if (c < 0)
mid++;
return -(mid + 1);
}
2002-02-15 00:34:13 +01:00
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];
}
2002-02-15 00:34:13 +01:00
FcPatternElt *
FcPatternObjectInsertElt (FcPattern *p, FcObject object)
{
int i;
FcPatternElt *e;
2010-04-12 18:18:50 +02:00
i = FcPatternObjectPosition (p, object);
if (i < 0)
2002-02-15 00:34:13 +01:00
{
i = -i - 1;
2010-04-12 18:18:50 +02:00
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
/* reallocate array */
if (FcPatternObjectCount (p) + 1 >= p->size)
2002-02-15 00:34:13 +01:00
{
int s = p->size + 16;
if (p->size)
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
{
FcPatternElt *e0 = FcPatternElts(p);
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
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));
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
}
}
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++;
}
2002-02-15 00:34:13 +01:00
}
e = FcPatternElts(p);
/* move elts up */
memmove (e + i + 1,
e + i,
sizeof (FcPatternElt) *
(FcPatternObjectCount (p) - i));
2010-04-12 18:18:50 +02:00
/* bump count */
p->num++;
e[i].object = object;
e[i].values = NULL;
2002-02-15 00:34:13 +01:00
}
2010-04-12 18:18:50 +02:00
return FcPatternElts(p) + i;
2002-02-15 00:34:13 +01:00
}
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++)
{
2010-04-12 18:18:50 +02:00
h = (((h << 1) | (h >> 31)) ^
pe[i].object ^
FcValueListHash (FcPatternEltValues(&pe[i])));
}
return h;
}
FcBool
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcPatternEqualSubset (const FcPattern *pai, const FcPattern *pbi, const FcObjectSet *os)
{
FcPatternElt *ea, *eb;
int i;
2010-04-12 18:18:50 +02:00
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;
}
2002-02-15 00:34:13 +01:00
FcBool
FcPatternObjectAddWithBinding (FcPattern *p,
FcObject object,
FcValue value,
FcValueBinding binding,
FcBool append)
2002-02-15 00:34:13 +01:00
{
FcPatternElt *e;
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcValueListPtr new, *prev;
2002-02-15 00:34:13 +01:00
if (FcRefIsConst (&p->ref))
goto bail0;
new = FcValueListCreate ();
if (!new)
2002-02-15 00:34:13 +01:00
goto bail0;
2009-06-05 22:49:07 +02:00
value = FcValueSave (value);
2002-02-15 00:34:13 +01:00
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;
2010-04-12 18:18:50 +02:00
e = FcPatternObjectInsertElt (p, object);
2002-02-15 00:34:13 +01:00
if (!e)
goto bail2;
2010-04-12 18:18:50 +02:00
2002-02-15 00:34:13 +01:00
if (append)
{
for (prev = &e->values; *prev; prev = &(*prev)->next)
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
;
2002-02-15 00:34:13 +01:00
*prev = new;
}
else
{
new->next = e->values;
2002-02-15 00:34:13 +01:00
e->values = new;
}
2010-04-12 18:18:50 +02:00
2002-02-15 00:34:13 +01:00
return FcTrue;
2010-04-12 18:18:50 +02:00
bail2:
FcValueDestroy (value);
2002-02-15 00:34:13 +01:00
bail1:
free (new);
2002-02-15 00:34:13 +01:00
bail0:
return FcFalse;
}
FcBool
FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append)
{
return FcPatternObjectAddWithBinding (p, object,
value, FcValueBindingStrong, append);
}
2002-07-07 01:47:44 +02:00
FcBool
FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append)
{
return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
value, FcValueBindingStrong, append);
2002-07-07 01:47:44 +02:00
}
FcBool
FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append)
{
return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
value, FcValueBindingWeak, append);
2002-07-07 01:47:44 +02:00
}
2002-02-15 00:34:13 +01:00
FcBool
FcPatternObjectDel (FcPattern *p, FcObject object)
2002-02-15 00:34:13 +01:00
{
FcPatternElt *e;
e = FcPatternObjectFindElt (p, object);
2002-02-15 00:34:13 +01:00
if (!e)
return FcFalse;
/* destroy value */
FcValueListDestroy (e->values);
2010-04-12 18:18:50 +02:00
2002-02-15 00:34:13 +01:00
/* shuffle existing ones down */
2010-04-12 18:18:50 +02:00
memmove (e, e+1,
(FcPatternElts(p) + FcPatternObjectCount (p) - (e + 1)) *
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
sizeof (FcPatternElt));
2002-02-15 00:34:13 +01:00
p->num--;
e = FcPatternElts(p) + FcPatternObjectCount (p);
e->object = 0;
e->values = NULL;
2002-02-15 00:34:13 +01:00
return FcTrue;
}
FcBool
FcPatternDel (FcPattern *p, const char *object)
{
return FcPatternObjectDel (p, FcObjectFromName (object));
}
2010-04-12 18:18:50 +02:00
FcBool
FcPatternRemove (FcPattern *p, const char *object, int id)
{
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
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;
}
2002-02-15 00:34:13 +01:00
FcBool
FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i)
2002-02-15 00:34:13 +01:00
{
FcValue v;
v.type = FcTypeInteger;
v.u.i = i;
return FcPatternObjectAdd (p, object, v, FcTrue);
2002-02-15 00:34:13 +01:00
}
FcBool
FcPatternAddInteger (FcPattern *p, const char *object, int i)
{
return FcPatternObjectAddInteger (p, FcObjectFromName (object), i);
}
FcBool
FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d)
2002-02-15 00:34:13 +01:00
{
FcValue v;
v.type = FcTypeDouble;
v.u.d = d;
return FcPatternObjectAdd (p, object, v, FcTrue);
2002-02-15 00:34:13 +01:00
}
FcBool
FcPatternAddDouble (FcPattern *p, const char *object, double d)
{
return FcPatternObjectAddDouble (p, FcObjectFromName (object), d);
}
FcBool
FcPatternObjectAddString (FcPattern *p, FcObject object, const FcChar8 *s)
2002-02-15 00:34:13 +01:00
{
FcValue v;
if (!s)
{
v.type = FcTypeVoid;
v.u.s = 0;
return FcPatternObjectAdd (p, object, v, FcTrue);
}
2002-02-15 00:34:13 +01:00
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);
2002-02-15 00:34:13 +01:00
}
FcBool
FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s)
{
FcValue v;
v.type = FcTypeMatrix;
v.u.m = s;
2002-02-15 00:34:13 +01:00
return FcPatternAdd (p, object, v, FcTrue);
}
FcBool
FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b)
2002-02-15 00:34:13 +01:00
{
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);
2002-02-15 00:34:13 +01:00
}
FcBool
FcPatternObjectAddCharSet (FcPattern *p, FcObject object, const FcCharSet *c)
2002-02-15 00:34:13 +01:00
{
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);
2002-02-15 00:34:13 +01:00
}
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);
}
2002-02-15 00:34:13 +01:00
FcResult
FcPatternObjectGetWithBinding (const FcPattern *p, FcObject object, int id, FcValue *v, FcValueBinding *b)
2002-02-15 00:34:13 +01:00
{
FcPatternElt *e;
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcValueListPtr l;
2002-02-15 00:34:13 +01:00
if (!p)
return FcResultNoMatch;
e = FcPatternObjectFindElt (p, object);
2002-02-15 00:34:13 +01:00
if (!e)
return FcResultNoMatch;
for (l = FcPatternEltValues(e); l; l = FcValueListNext(l))
2002-02-15 00:34:13 +01:00
{
if (!id)
{
*v = FcValueCanonicalize(&l->value);
if (b)
*b = l->binding;
2002-02-15 00:34:13 +01:00
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);
}
2002-02-15 00:34:13 +01:00
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)
2002-02-15 00:34:13 +01:00
{
FcValue v;
FcResult r;
r = FcPatternObjectGet (p, object, id, &v);
2002-02-15 00:34:13 +01:00
if (r != FcResultMatch)
return r;
2012-12-30 04:11:09 +01:00
switch ((int) v.type) {
2002-02-15 00:34:13 +01:00
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);
}
2010-04-12 18:18:50 +02:00
FcResult
FcPatternObjectGetDouble (const FcPattern *p, FcObject object, int id, double *d)
2002-02-15 00:34:13 +01:00
{
FcValue v;
FcResult r;
r = FcPatternObjectGet (p, object, id, &v);
2002-02-15 00:34:13 +01:00
if (r != FcResultMatch)
return r;
2012-12-30 04:11:09 +01:00
switch ((int) v.type) {
2002-02-15 00:34:13 +01:00
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)
2002-02-15 00:34:13 +01:00
{
FcValue v;
FcResult r;
r = FcPatternObjectGet (p, object, id, &v);
2002-02-15 00:34:13 +01:00
if (r != FcResultMatch)
return r;
if (v.type != FcTypeString)
return FcResultTypeMismatch;
*s = (FcChar8 *) v.u.s;
2002-02-15 00:34:13 +01:00
return FcResultMatch;
}
FcResult
FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s)
{
return FcPatternObjectGetString (p, FcObjectFromName (object), id, s);
}
2010-04-12 18:18:50 +02:00
2002-02-15 00:34:13 +01:00
FcResult
FcPatternGetMatrix(const FcPattern *p, const char *object, int id, FcMatrix **m)
2002-02-15 00:34:13 +01:00
{
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;
2002-02-15 00:34:13 +01:00
return FcResultMatch;
}
FcResult
FcPatternObjectGetBool (const FcPattern *p, FcObject object, int id, FcBool *b)
2002-02-15 00:34:13 +01:00
{
FcValue v;
FcResult r;
r = FcPatternObjectGet (p, object, id, &v);
2002-02-15 00:34:13 +01:00
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);
}
2002-02-15 00:34:13 +01:00
FcResult
FcPatternGetCharSet(const FcPattern *p, const char *object, int id, FcCharSet **c)
2002-02-15 00:34:13 +01:00
{
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;
2002-02-15 00:34:13 +01:00
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);
}
2002-02-15 00:34:13 +01:00
FcPattern *
FcPatternDuplicate (const FcPattern *orig)
2002-02-15 00:34:13 +01:00
{
FcPattern *new;
FcPatternIter iter;
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcValueListPtr l;
2002-02-15 00:34:13 +01:00
if (!orig)
return NULL;
2002-02-15 00:34:13 +01:00
new = FcPatternCreate ();
if (!new)
goto bail0;
FcPatternIterStart (orig, &iter);
do
2002-02-15 00:34:13 +01:00
{
for (l = FcPatternIterGetValues (orig, &iter); l; l = FcValueListNext (l))
{
if (!FcPatternObjectAddWithBinding (new, FcPatternIterGetObjectId (orig, &iter),
FcValueCanonicalize(&l->value),
l->binding,
FcTrue))
2002-02-15 00:34:13 +01:00
goto bail1;
}
} while (FcPatternIterNext (orig, &iter));
2002-02-15 00:34:13 +01:00
return new;
bail1:
FcPatternDestroy (new);
bail0:
return 0;
}
void
FcPatternReference (FcPattern *p)
{
if (!FcRefIsConst (&p->ref))
FcRefInc (&p->ref);
else
FcCacheObjectReference (FcPatternGetCacheObject(p));
}
2002-02-15 00:34:13 +01:00
FcPattern *
FcPatternVaBuild (FcPattern *p, va_list va)
2002-02-15 00:34:13 +01:00
{
FcPattern *ret;
2010-04-12 18:18:50 +02:00
FcPatternVapBuild (ret, p, va);
2002-02-15 00:34:13 +01:00
return ret;
}
FcPattern *
FcPatternBuild (FcPattern *p, ...)
2002-02-15 00:34:13 +01:00
{
va_list va;
2010-04-12 18:18:50 +02:00
va_start (va, p);
FcPatternVapBuild (p, p, va);
2002-02-15 00:34:13 +01:00
va_end (va);
return p;
2002-02-15 00:34:13 +01:00
}
/*
* Add all of the elements in 's' to 'p'
*/
FcBool
FcPatternAppend (FcPattern *p, FcPattern *s)
{
FcPatternIter iter;
FcValueListPtr v;
2010-04-12 18:18:50 +02:00
FcPatternIterStart (s, &iter);
do
{
for (v = FcPatternIterGetValues (s, &iter); v; v = FcValueListNext (v))
{
if (!FcPatternObjectAddWithBinding (p, FcPatternIterGetObjectId (s, &iter),
2010-04-12 18:18:50 +02:00
FcValueCanonicalize(&v->value),
v->binding, FcTrue))
return FcFalse;
}
} while (FcPatternIterNext (s, &iter));
return FcTrue;
}
2008-08-13 08:50:35 +02:00
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;
}
}
}
2009-01-16 01:12:27 +01:00
return ret;
2008-08-13 08:50:35 +02:00
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);
2010-04-12 18:18:50 +02:00
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;
}
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcPattern *
FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat)
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
{
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);
2010-04-12 18:18:50 +02:00
elts_serialized = FcSerializePtr (serialize, elts);
if (!elts_serialized)
return NULL;
2010-04-12 18:18:50 +02:00
pat_serialized->elts_offset = FcPtrToOffset (pat_serialized,
elts_serialized);
for (i = 0; i < FcPatternObjectCount (pat); i++)
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
{
values_serialized = FcValueListSerialize (serialize, FcPatternEltValues (elts+i));
if (!values_serialized)
return NULL;
elts_serialized[i].object = elts[i].object;
2010-04-12 18:18:50 +02:00
elts_serialized[i].values = FcPtrToEncodedOffset (&elts_serialized[i],
values_serialized,
FcValueList);
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
}
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;
2012-12-30 04:11:09 +01:00
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;
2010-04-12 18:18:50 +02:00
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;
2012-12-30 04:11:09 +01:00
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;
2005-07-15 20:49:12 +02:00
}
#define __fcpat__
#include "fcaliastail.h"
#include "fcftaliastail.h"
#undef __fcpat__