fontconfig/src/fcpat.c

1254 lines
26 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"
2002-02-15 00:34:13 +01:00
#include <stdlib.h>
#include <string.h>
#include <assert.h>
2002-02-15 00:34:13 +01:00
FcPattern *
FcPatternCreate (void)
{
FcPattern *p;
p = (FcPattern *) malloc (sizeof (FcPattern));
if (!p)
return 0;
FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern));
p->num = 0;
p->size = 0;
p->elts_offset = FcPtrToOffset (p, NULL);
p->ref = 1;
2002-02-15 00:34:13 +01:00
return p;
}
void
FcValueDestroy (FcValue v)
{
switch (v.type) {
case FcTypeString:
if (!FcSharedStrFree (v.u.s))
FcStrFree ((FcChar8 *) 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;
2002-02-15 00:34:13 +01:00
default:
break;
}
}
FcValue
FcValueCanonicalize (const FcValue *v)
{
FcValue new;
switch (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;
default:
new = *v;
break;
}
return new;
}
2002-02-15 00:34:13 +01:00
FcValue
FcValueSave (FcValue v)
{
switch (v.type) {
case FcTypeString:
v.u.s = FcSharedStr (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;
2002-02-15 00:34:13 +01:00
default:
break;
}
return v;
}
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
{
switch (l->value.type) {
2002-02-15 00:34:13 +01:00
case FcTypeString:
if (!FcSharedStrFree ((FcChar8 *)l->value.u.s))
FcStrFree ((FcChar8 *)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;
2002-02-15 00:34:13 +01:00
default:
break;
}
next = FcValueListNext(l);
2002-02-15 00:34:13 +01:00
FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
free(l);
2002-02-15 00:34:13 +01:00
}
}
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 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);
}
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 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));
}
return FcFalse;
}
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;
}
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->ref == FC_REF_CONSTANT)
{
FcCacheObjectDereference (p);
return;
}
if (--p->ref > 0)
return;
elts = FcPatternElts (p);
2002-02-15 00:34:13 +01:00
for (i = 0; i < p->num; i++)
FcValueListDestroy (FcPatternEltValues(&elts[i]));
2002-02-15 00:34:13 +01:00
FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
free (elts);
2002-02-15 00:34:13 +01:00
FcMemFree (FC_MEM_PATTERN, sizeof (FcPattern));
free (p);
}
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 = p->num - 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
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 (p->num + 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, p->num * sizeof (FcPatternElt));
}
}
else
e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt));
if (!e)
return FcFalse;
p->elts_offset = FcPtrToOffset (p, e);
if (p->size)
FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
FcMemAlloc (FC_MEM_PATELT, s * sizeof (FcPatternElt));
while (p->size < s)
{
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) *
(p->num - 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)
{
int i;
FcPatternElt *pae, *pbe;
if (pa == pb)
return FcTrue;
if (pa->num != pb->num)
return FcFalse;
pae = FcPatternElts(pa);
pbe = FcPatternElts(pb);
for (i = 0; i < pa->num; i++)
{
if (pae[i].object != pbe[i].object)
return FcFalse;
if (!FcValueListEqual (FcPatternEltValues(&pae[i]),
FcPatternEltValues(&pbe[i])))
return FcFalse;
}
return FcTrue;
}
FcChar32
FcPatternHash (const FcPattern *p)
{
int i;
FcChar32 h = 0;
FcPatternElt *pe = FcPatternElts(p);
for (i = 0; i < p->num; 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;
}
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 (p->ref == FC_REF_CONSTANT)
goto bail0;
new = malloc (sizeof (FcValueList));
if (!new)
2002-02-15 00:34:13 +01:00
goto bail0;
memset(new, 0, sizeof (FcValueList));
2002-02-15 00:34:13 +01:00
FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
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))
{
if (FcDebug() & FC_DBG_OBJTYPES)
{
printf ("FcPattern object %s does not accept value ",
FcObjectName (object));
FcValuePrint (value);
}
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:
FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
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) + p->num - (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) + p->num;
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
FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c)
{
FcValue v;
v.type = FcTypeCharSet;
v.u.c = (FcCharSet *)c;
2002-02-15 00:34:13 +01:00
return FcPatternAdd (p, object, v, FcTrue);
}
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
FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls)
{
FcValue v;
v.type = FcTypeLangSet;
v.u.l = (FcLangSet *)ls;
return FcPatternAdd (p, object, v, FcTrue);
}
2002-02-15 00:34:13 +01:00
FcResult
FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v)
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
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);
2002-02-15 00:34:13 +01:00
return FcResultMatch;
}
id--;
}
return FcResultNoId;
}
FcResult
FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v)
{
return FcPatternObjectGet (p, FcObjectFromName (object), id, v);
}
FcResult
FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int id, int *i)
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;
switch (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);
}
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;
switch (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)
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
FcPatternGetBool(const FcPattern *p, const char *object, int id, FcBool *b)
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 != FcTypeBool)
return FcResultTypeMismatch;
*b = v.u.b;
return FcResultMatch;
}
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;
}
2002-02-15 00:34:13 +01:00
FcPattern *
FcPatternDuplicate (const FcPattern *orig)
2002-02-15 00:34:13 +01:00
{
FcPattern *new;
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;
2002-02-15 00:34:13 +01:00
int 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
FcValueListPtr l;
2002-02-15 00:34:13 +01:00
new = FcPatternCreate ();
if (!new)
goto bail0;
e = FcPatternElts(orig);
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
for (i = 0; i < orig->num; i++)
{
for (l = FcPatternEltValues(e + i); l; l = FcValueListNext(l))
{
if (!FcPatternObjectAddWithBinding (new, e[i].object,
FcValueCanonicalize(&l->value),
l->binding,
FcTrue))
2002-02-15 00:34:13 +01:00
goto bail1;
2010-04-12 18:18:50 +02:00
}
2002-02-15 00:34:13 +01:00
}
return new;
bail1:
FcPatternDestroy (new);
bail0:
return 0;
}
void
FcPatternReference (FcPattern *p)
{
if (p->ref != FC_REF_CONSTANT)
p->ref++;
else
FcCacheObjectReference (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)
{
int i;
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 v;
2010-04-12 18:18:50 +02:00
for (i = 0; i < s->num; i++)
{
e = FcPatternElts(s)+i;
for (v = FcPatternEltValues(e); v; v = FcValueListNext(v))
{
if (!FcPatternObjectAddWithBinding (p, e->object,
2010-04-12 18:18:50 +02:00
FcValueCanonicalize(&v->value),
v->binding, FcTrue))
return FcFalse;
}
}
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;
}
#define OBJECT_HASH_SIZE 251
static struct objectBucket {
struct objectBucket *next;
FcChar32 hash;
int ref_count;
} *FcObjectBuckets[OBJECT_HASH_SIZE];
FcBool
FcSharedStrFree (const FcChar8 *name)
{
FcChar32 hash = FcStringHash (name);
struct objectBucket **p;
struct objectBucket *b;
int size;
for (p = &FcObjectBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
if (b->hash == hash && ((char *)name == (char *) (b + 1)))
{
b->ref_count--;
if (!b->ref_count)
{
*p = b->next;
size = sizeof (struct objectBucket) + strlen ((char *)name) + 1;
size = (size + 3) & ~3;
FcMemFree (FC_MEM_SHAREDSTR, size);
free (b);
}
return FcTrue;
}
return FcFalse;
}
const FcChar8 *
FcSharedStr (const FcChar8 *name)
{
FcChar32 hash = FcStringHash (name);
struct objectBucket **p;
struct objectBucket *b;
int size;
for (p = &FcObjectBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
if (b->hash == hash && !strcmp ((char *)name, (char *) (b + 1)))
{
b->ref_count++;
return (FcChar8 *) (b + 1);
}
size = sizeof (struct objectBucket) + strlen ((char *)name) + 1;
/*
* workaround valgrind warning because glibc takes advantage of how it knows memory is
* allocated to implement strlen by reading in groups of 4
*/
size = (size + 3) & ~3;
b = malloc (size);
FcMemAlloc (FC_MEM_SHAREDSTR, size);
if (!b)
return NULL;
b->next = 0;
b->hash = hash;
b->ref_count = 1;
strcpy ((char *) (b + 1), (char *)name);
*p = b;
return (FcChar8 *) (b + 1);
}
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, pat->num * sizeof (FcPatternElt)))
return FcFalse;
for (i = 0; i < pat->num; 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 = pat->num;
pat_serialized->ref = FC_REF_CONSTANT;
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 < pat->num; 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;
switch (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;
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;
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;
switch (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;
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__