FILE *f;
int ncountry = 0;
int i = 0;
- FcCharLeaf **leaves, **sleaves;
+ FcCharLeaf **leaves;
int total_leaves = 0;
int l, sl, tl;
int c;
*/
for (i = 0; sets[i]; i++)
{
- sleaves = sets[i]->leaves;
for (sl = 0; sl < sets[i]->num; sl++)
{
for (l = 0; l < tl; l++)
- if (leaves[l] == sleaves[sl])
+ if (leaves[l] == FcCharSetGetLeaf(sets[i], sl))
break;
if (l == tl)
- leaves[tl++] = sleaves[sl];
+ leaves[tl++] = FcCharSetGetLeaf(sets[i], sl);
}
}
if (n % 8 == 0)
printf (" ");
for (l = 0; l < tl; l++)
- if (leaves[l] == sets[i]->leaves[n])
+ if (leaves[l] == FcCharSetGetLeaf(sets[i], n))
break;
if (l == tl)
fatal (names[i], 0, "can't find leaf");
{
if (n % 8 == 0)
printf (" ");
- printf (" 0x%04x,", sets[i]->numbers[n]);
+ printf (" 0x%04x,", FcCharSetGetNumbers(sets[i])[n]);
if (n % 8 == 7)
printf ("\n");
}
if (j < 0)
j = i;
printf (" { (FcChar8 *) \"%s\",\n"
- " { FC_REF_CONSTANT, %d, "
- "(FcCharLeaf **) leaves_%s, "
- "(FcChar16 *) numbers_%s } },\n",
+ " { FC_REF_CONSTANT, %d, FcStorageDynamic, "
+ "{ { (FcCharLeaf **) leaves_%s, "
+ "(FcChar16 *) numbers_%s } } } },\n",
langs[i],
sets[j]->num, names[j], names[j]);
}
__v__.u.d = va_arg (va, double); \
break; \
case FcTypeString: \
- __v__.u.s = va_arg (va, FcChar8 *); \
+ __v__.u.si = va_arg (va, FcObjectPtr); \
break; \
case FcTypeBool: \
__v__.u.b = va_arg (va, FcBool); \
break; \
case FcTypeMatrix: \
- __v__.u.m = va_arg (va, FcMatrix *); \
+ __v__.u.mi = va_arg (va, FcMatrixPtr); \
break; \
case FcTypeCharSet: \
- __v__.u.c = va_arg (va, FcCharSet *); \
+ __v__.u.ci = va_arg (va, FcCharSetPtr); \
break; \
case FcTypeFTFace: \
__v__.u.f = va_arg (va, FT_Face); \
break; \
case FcTypeLangSet: \
- __v__.u.l = va_arg (va, FcLangSet *); \
+ __v__.u.li = va_arg (va, FcLangSetPtr); \
break; \
} \
if (!FcPatternAdd (__p__, __o__, __v__, FcTrue)) \
FcResultOutOfMemory
} FcResult;
+typedef enum _FcStorage {
+ FcStorageStatic, FcStorageDynamic
+} FcStorage;
+
typedef struct _FcPattern FcPattern;
typedef struct _FcLangSet FcLangSet;
+typedef struct _FcMatrixPtr {
+ FcStorage storage;
+ union {
+ int stat;
+ FcMatrix *dyn;
+ } u;
+} FcMatrixPtr;
+
+typedef struct _FcCharSetPtr {
+ FcStorage storage;
+ union {
+ int stat;
+ FcCharSet *dyn;
+ } u;
+} FcCharSetPtr;
+
+typedef struct _FcLangSetPtr {
+ FcStorage storage;
+ union {
+ int stat;
+ FcLangSet *dyn;
+ } u;
+} FcLangSetPtr;
+
+typedef struct _FcObjectPtr {
+ FcStorage storage;
+ union {
+ int stat;
+ const FcChar8 * dyn;
+ } u;
+ FcChar32 hash;
+} FcObjectPtr;
+
typedef struct _FcValue {
FcType type;
union {
- const FcChar8 *s;
+ FcObjectPtr si;
int i;
FcBool b;
double d;
- const FcMatrix *m;
- const FcCharSet *c;
+ FcMatrixPtr mi;
+ FcCharSetPtr ci;
void *f;
const FcPattern *p;
- const FcLangSet *l;
+ FcLangSetPtr li;
} u;
} FcValue;
typedef struct _FcObjectSet {
int nobject;
int sobject;
- const char **objects;
+ FcObjectPtr *objects;
} FcObjectSet;
typedef enum _FcMatchKind {
void
FcMatrixShear (FcMatrix *m, double sh, double sv);
+FcMatrix *
+FcMatrixPtrU (FcMatrixPtr mi);
+
/* fcname.c */
FcBool
bail0:
return FcFalse;
}
+
+void
+FcCacheClearStatic()
+{
+ FcFontSetClearStatic();
+ FcPatternClearStatic();
+ FcValueListClearStatic();
+ FcObjectClearStatic();
+ FcMatrixClearStatic();
+ FcCharSetClearStatic();
+ FcLangSetClearStatic();
+}
+
+FcBool
+FcCachePrepareSerialize (FcConfig * config)
+{
+ int i;
+ for (i = FcSetSystem; i <= FcSetApplication; i++)
+ if (config->fonts[i] && !FcFontSetPrepareSerialize(config->fonts[i]))
+ return FcFalse;
+ return FcTrue;
+}
+
+FcBool
+FcCacheSerialize (FcConfig * config)
+{
+ int i;
+ for (i = FcSetSystem; i <= FcSetApplication; i++)
+ if (config->fonts[i] && !FcFontSetSerialize(config->fonts[i]))
+ return FcFalse;
+ return FcTrue;
+}
}
else if (v.type == FcTypeVoid && u.type == FcTypeMatrix)
{
- v.u.m = &FcIdentityMatrix;
+ v.u.mi = FcIdentityMatrix;
v.type = FcTypeMatrix;
}
else if (v.type == FcTypeString && u.type == FcTypeLangSet)
{
- v.u.l = FcLangSetPromote (v.u.s);
+ v.u.li = FcLangSetPtrCreateDynamic(FcLangSetPromote
+ (FcObjectPtrU(v.u.si)));
v.type = FcTypeLangSet;
}
return v;
switch (op) {
case FcOpEqual:
case FcOpListing:
- ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0;
+ ret = FcStrCmpIgnoreCase (FcObjectPtrU(left.u.si),
+ FcObjectPtrU(right.u.si)) == 0;
break;
case FcOpContains:
- ret = FcStrStrIgnoreCase (left.u.s, right.u.s) != 0;
+ ret = FcStrStrIgnoreCase (FcObjectPtrU(left.u.si),
+ FcObjectPtrU(right.u.si)) != 0;
break;
case FcOpNotEqual:
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0;
break;
case FcOpNotContains:
- ret = FcStrStrIgnoreCase (left.u.s, right.u.s) == 0;
+ ret = FcStrCmpIgnoreCase (FcObjectPtrU(left.u.si),
+ FcObjectPtrU(right.u.si)) == 0;
break;
default:
break;
case FcOpEqual:
case FcOpContains:
case FcOpListing:
- ret = FcMatrixEqual (left.u.m, right.u.m);
+ ret = FcMatrixEqual (FcMatrixPtrU(left.u.mi), FcMatrixPtrU(right.u.mi));
break;
case FcOpNotEqual:
case FcOpNotContains:
- ret = !FcMatrixEqual (left.u.m, right.u.m);
+ ret = !FcMatrixEqual (FcMatrixPtrU(left.u.mi), FcMatrixPtrU(right.u.mi));
break;
default:
break;
case FcOpContains:
case FcOpListing:
/* left contains right if right is a subset of left */
- ret = FcCharSetIsSubset (right.u.c, left.u.c);
+ ret = FcCharSetIsSubset (FcCharSetPtrU(right.u.ci), FcCharSetPtrU(left.u.ci));
break;
case FcOpNotContains:
/* left contains right if right is a subset of left */
- ret = !FcCharSetIsSubset (right.u.c, left.u.c);
+ ret = !FcCharSetIsSubset (FcCharSetPtrU(right.u.ci), FcCharSetPtrU(left.u.ci));
break;
case FcOpEqual:
- ret = FcCharSetEqual (left.u.c, right.u.c);
+ ret = FcCharSetEqual (FcCharSetPtrU(left.u.ci), FcCharSetPtrU(right.u.ci));
break;
case FcOpNotEqual:
- ret = !FcCharSetEqual (left.u.c, right.u.c);
+ ret = !FcCharSetEqual (FcCharSetPtrU(left.u.ci), FcCharSetPtrU(right.u.ci));
break;
default:
break;
switch (op) {
case FcOpContains:
case FcOpListing:
- ret = FcLangSetContains (left.u.l, right.u.l);
+ ret = FcLangSetContains (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
break;
case FcOpNotContains:
- ret = !FcLangSetContains (left.u.l, right.u.l);
+ ret = !FcLangSetContains (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
break;
case FcOpEqual:
- ret = FcLangSetEqual (left.u.l, right.u.l);
+ ret = FcLangSetEqual (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
break;
case FcOpNotEqual:
- ret = !FcLangSetEqual (left.u.l, right.u.l);
+ ret = !FcLangSetEqual (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
break;
default:
break;
break;
case FcOpString:
v.type = FcTypeString;
- v.u.s = e->u.sval;
+ v.u.si = FcObjectPtrCreateDynamic(e->u.sval);
v = FcValueSave (v);
break;
case FcOpMatrix:
v.type = FcTypeMatrix;
- v.u.m = e->u.mval;
+ v.u.mi = FcMatrixPtrCreateDynamic(e->u.mval);
v = FcValueSave (v);
break;
case FcOpCharSet:
v.type = FcTypeCharSet;
- v.u.c = e->u.cval;
+ v.u.ci = FcCharSetPtrCreateDynamic(e->u.cval);
v = FcValueSave (v);
break;
case FcOpBool:
switch (e->op) {
case FcOpPlus:
v.type = FcTypeString;
- v.u.s = FcStrPlus (vl.u.s, vr.u.s);
- if (!v.u.s)
+ v.u.si = FcObjectPtrCreateDynamic
+ (FcStrPlus (FcObjectPtrU(vl.u.si),
+ FcObjectPtrU(vr.u.si)));
+
+ if (!FcObjectPtrU(v.u.si))
v.type = FcTypeVoid;
break;
default:
if (m)
{
FcMemAlloc (FC_MEM_MATRIX, sizeof (FcMatrix));
- FcMatrixMultiply (m, vl.u.m, vr.u.m);
- v.u.m = m;
+ FcMatrixMultiply (m, FcMatrixPtrU(vl.u.mi),
+ FcMatrixPtrU(vr.u.mi));
+ v.u.mi = FcMatrixPtrCreateDynamic(m);
}
else
{
e = 0;
}
- for (v = values; v; v = v->next)
+ for (v = values; v; v = FcValueListPtrU(v->next))
{
/* Compare the pattern value to the match expression value */
if (FcConfigCompareValue (v->value, t->op, value))
FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding)
{
FcValueList *l;
+ FcValueListPtr lp;
if (!e)
return 0;
if (e->op == FcOpComma)
{
l->value = FcConfigEvaluate (p, e->u.tree.left);
- l->next = FcConfigValues (p, e->u.tree.right, binding);
+ l->next = FcValueListPtrCreateDynamic(FcConfigValues (p, e->u.tree.right, binding));
}
else
{
l->value = FcConfigEvaluate (p, e);
- l->next = 0;
+ l->next = FcValueListPtrCreateDynamic(0);
}
l->binding = binding;
- while (l && l->value.type == FcTypeVoid)
+ lp = FcValueListPtrCreateDynamic(l);
+ while (FcValueListPtrU(lp) && FcValueListPtrU(lp)->value.type == FcTypeVoid)
{
- FcValueList *next = l->next;
-
- FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
- free (l);
- l = next;
+ FcValueListPtr next = FcValueListPtrU(lp)->next;
+
+ if (lp.storage == FcStorageDynamic)
+ {
+ FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
+ free (l);
+ }
+ lp = next;
}
return l;
}
static FcBool
-FcConfigAdd (FcValueList **head,
+FcConfigAdd (FcValueListPtr *head,
FcValueList *position,
FcBool append,
FcValueList *new)
{
- FcValueList **prev, *last, *v;
+ FcValueListPtr *prev, last, v;
FcValueBinding sameBinding;
if (position)
sameBinding = position->binding;
else
sameBinding = FcValueBindingWeak;
- for (v = new; v; v = v->next)
- if (v->binding == FcValueBindingSame)
- v->binding = sameBinding;
+ for (v = FcValueListPtrCreateDynamic(new); FcValueListPtrU(v);
+ v = FcValueListPtrU(v)->next)
+ if (FcValueListPtrU(v)->binding == FcValueBindingSame)
+ FcValueListPtrU(v)->binding = sameBinding;
if (append)
{
if (position)
prev = &position->next;
else
- for (prev = head; *prev; prev = &(*prev)->next)
+ for (prev = head; FcValueListPtrU(*prev);
+ prev = &(FcValueListPtrU(*prev)->next))
;
}
else
{
if (position)
{
- for (prev = head; *prev; prev = &(*prev)->next)
+ for (prev = head; FcValueListPtrU(*prev);
+ prev = &(FcValueListPtrU(*prev)->next))
{
- if (*prev == position)
+ if (FcValueListPtrU(*prev) == position)
break;
}
}
if (FcDebug () & FC_DBG_EDIT)
{
- if (!*prev)
+ if (!FcValueListPtrU(*prev))
printf ("position not on list\n");
}
}
if (new)
{
- last = new;
- while (last->next)
- last = last->next;
+ last = FcValueListPtrCreateDynamic(new);
+ while (FcValueListPtrU(FcValueListPtrU(last)->next))
+ last = FcValueListPtrU(last)->next;
- last->next = *prev;
- *prev = new;
+ FcValueListPtrU(last)->next = *prev;
+ *prev = FcValueListPtrCreateDynamic(new);
}
if (FcDebug () & FC_DBG_EDIT)
}
static void
-FcConfigDel (FcValueList **head,
+FcConfigDel (FcValueListPtr *head,
FcValueList *position)
{
- FcValueList **prev;
+ FcValueListPtr *prev;
- for (prev = head; *prev; prev = &(*prev)->next)
+ for (prev = head; FcValueListPtrU(*prev);
+ prev = &(FcValueListPtrU(*prev)->next))
{
- if (*prev == position)
+ if (FcValueListPtrU(*prev) == position)
{
*prev = position->next;
- position->next = 0;
- FcValueListDestroy (position);
+ position->next = FcValueListPtrCreateDynamic(0);
+ FcValueListDestroy (FcValueListPtrCreateDynamic(position));
break;
}
}
FcPatternElt *e = FcPatternFindElt (p, object);
if (!e)
return;
- while (e->values)
- FcConfigDel (&e->values, e->values);
+ while (FcValueListPtrU(e->values))
+ FcConfigDel (&e->values, FcValueListPtrU(e->values));
}
static void
FcPatternElt *e = FcPatternFindElt (p, object);
if (!e)
return;
- if (!e->values)
+ if (!FcValueListPtrU(e->values))
FcPatternDel (p, object);
}
* Check to see if there is a match, mark the location
* to apply match-relative edits
*/
- st[i].value = FcConfigMatchValueList (m, t, st[i].elt->values);
+ st[i].value = FcConfigMatchValueList (m, t, FcValueListPtrU(st[i].elt->values));
if (!st[i].value)
break;
- if (t->qual == FcQualFirst && st[i].value != st[i].elt->values)
+ if (t->qual == FcQualFirst && st[i].value != FcValueListPtrU(st[i].elt->values))
break;
- if (t->qual == FcQualNotFirst && st[i].value == st[i].elt->values)
+ if (t->qual == FcQualNotFirst && st[i].value == FcValueListPtrU(st[i].elt->values))
break;
}
if (t)
if (t)
{
FcValueList *thisValue = st[i].value;
- FcValueList *nextValue = thisValue ? thisValue->next : 0;
+ FcValueList *nextValue = thisValue ? FcValueListPtrU(thisValue->next) : 0;
/*
* Append the new list of values after the current value
int i;
for (i = 0; i < globs->num; i++)
- if (FcConfigGlobMatch (globs->strs[i], string))
+ if (FcConfigGlobMatch (FcStrSetGet(globs, i), string))
return FcTrue;
return FcFalse;
}
/* #define CHATTY */
+static FcCharSet * charsets = 0;
+static FcChar16 * numbers = 0;
+static int charset_ptr, charset_count;
+static int charset_numbers_ptr, charset_numbers_count;
+static FcCharLeaf * leaves = 0;
+static int charset_leaf_ptr, charset_leaf_count;
+static int * leaf_idx = 0;
+static int charset_leaf_idx_ptr, charset_leaf_idx_count;
+
+void
+FcCharSetClearStatic()
+{
+ charsets = 0;
+ numbers = 0;
+ charset_ptr = 0; charset_count = 0;
+ leaves = 0;
+ charset_leaf_ptr = 0; charset_leaf_count = 0;
+ leaf_idx = 0;
+ charset_leaf_idx_ptr = 0; charset_leaf_idx_count = 0;
+}
+
FcCharSet *
FcCharSetCreate (void)
{
FcMemAlloc (FC_MEM_CHARSET, sizeof (FcCharSet));
fcs->ref = 1;
fcs->num = 0;
- fcs->leaves = 0;
- fcs->numbers = 0;
+ fcs->storage = FcStorageDynamic;
+ fcs->u.dyn.leaves = 0;
+ fcs->u.dyn.numbers = 0;
return fcs;
}
return FcCharSetCreate ();
}
+void
+FcCharSetPtrDestroy (FcCharSetPtr fcs)
+{
+ FcCharSetDestroy (FcCharSetPtrU(fcs));
+ if (fcs.storage == FcStorageDynamic &&
+ FcCharSetPtrU(fcs)->ref != FC_REF_CONSTANT)
+ {
+ free (fcs.u.dyn);
+ FcMemFree (FC_MEM_CHARSET, sizeof(FcCharSet));
+ }
+}
void
FcCharSetDestroy (FcCharSet *fcs)
return;
if (--fcs->ref > 0)
return;
- for (i = 0; i < fcs->num; i++)
- {
- FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
- free (fcs->leaves[i]);
- }
- if (fcs->leaves)
+ if (fcs->storage == FcStorageDynamic)
{
- FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *));
- free (fcs->leaves);
- }
- if (fcs->numbers)
- {
- FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
- free (fcs->numbers);
+ for (i = 0; i < fcs->num; i++)
+ {
+ FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
+ free (fcs->u.dyn.leaves[i]);
+ }
+ if (fcs->u.dyn.leaves)
+ {
+ FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *));
+ free (fcs->u.dyn.leaves);
+ }
+ if (fcs->u.dyn.numbers)
+ {
+ FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
+ free (fcs->u.dyn.numbers);
+ }
}
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
free (fcs);
static int
FcCharSetFindLeafPos (const FcCharSet *fcs, FcChar32 ucs4)
{
- FcChar16 *numbers = fcs->numbers;
+ FcChar16 *numbers = FcCharSetGetNumbers(fcs);
FcChar16 page;
int low = 0;
int high = fcs->num - 1;
{
int pos = FcCharSetFindLeafPos (fcs, ucs4);
if (pos >= 0)
- return fcs->leaves[pos];
+ return FcCharSetGetLeaf(fcs, pos);
return 0;
}
ucs4 >>= 8;
if (ucs4 >= 0x10000)
return FcFalse;
- if (!fcs->leaves)
- leaves = malloc (sizeof (FcCharLeaf *));
- else
- leaves = realloc (fcs->leaves, (fcs->num + 1) * sizeof (FcCharLeaf *));
- if (!leaves)
- return FcFalse;
- if (fcs->num)
- FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *));
- FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcCharLeaf *));
- fcs->leaves = leaves;
- if (!fcs->numbers)
- numbers = malloc (sizeof (FcChar16));
+ if (fcs->storage == FcStorageStatic)
+ {
+ int i;
+
+ leaves = malloc ((fcs->num + 1) * sizeof (FcCharLeaf *));
+ if (!leaves)
+ return FcFalse;
+ FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcCharLeaf *));
+ numbers = malloc ((fcs->num + 1) * sizeof (FcChar16));
+ if (!numbers)
+ return FcFalse;
+ FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
+
+ for (i = 0; i < fcs->num; i++)
+ leaves[i] = FcCharSetGetLeaf(fcs, i);
+ memcpy (numbers, FcCharSetGetNumbers(fcs),
+ fcs->num * sizeof (FcChar16));
+ fcs->storage = FcStorageDynamic;
+ }
else
- numbers = realloc (fcs->numbers, (fcs->num + 1) * sizeof (FcChar16));
- if (!numbers)
- return FcFalse;
- if (fcs->num)
- FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
- FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
- fcs->numbers = numbers;
+ {
+ if (!fcs->u.dyn.leaves)
+ leaves = malloc (sizeof (FcCharLeaf *));
+ else
+ leaves = realloc (fcs->u.dyn.leaves, (fcs->num + 1) * sizeof (FcCharLeaf *));
+ if (!leaves)
+ return FcFalse;
+ if (fcs->num)
+ FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *));
+ FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcCharLeaf *));
+ fcs->u.dyn.leaves = leaves;
+ if (!fcs->u.dyn.numbers)
+ numbers = malloc (sizeof (FcChar16));
+ else
+ numbers = realloc (fcs->u.dyn.numbers, (fcs->num + 1) * sizeof (FcChar16));
+ if (!numbers)
+ return FcFalse;
+ if (fcs->num)
+ FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
+ FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
+ fcs->u.dyn.numbers = numbers;
+ }
- memmove (fcs->leaves + pos + 1, fcs->leaves + pos,
+ memmove (fcs->u.dyn.leaves + pos + 1, fcs->u.dyn.leaves + pos,
(fcs->num - pos) * sizeof (FcCharLeaf *));
- memmove (fcs->numbers + pos + 1, fcs->numbers + pos,
+ memmove (fcs->u.dyn.numbers + pos + 1, fcs->u.dyn.numbers + pos,
(fcs->num - pos) * sizeof (FcChar16));
- fcs->numbers[pos] = (FcChar16) ucs4;
- fcs->leaves[pos] = leaf;
+ fcs->u.dyn.numbers[pos] = (FcChar16) ucs4;
+ fcs->u.dyn.leaves[pos] = leaf;
fcs->num++;
return FcTrue;
}
pos = FcCharSetFindLeafPos (fcs, ucs4);
if (pos >= 0)
- return fcs->leaves[pos];
+ return FcCharSetGetLeaf(fcs, pos);
leaf = calloc (1, sizeof (FcCharLeaf));
if (!leaf)
if (pos >= 0)
{
FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
- free (fcs->leaves[pos]);
- fcs->leaves[pos] = leaf;
+ if (fcs->storage == FcStorageDynamic)
+ {
+ free (fcs->u.dyn.leaves[pos]);
+ fcs->u.dyn.leaves[pos] = leaf;
+ }
+ else
+ {
+ leaves[leaf_idx[fcs->u.stat.leafidx_offset]+pos] = *leaf;
+ }
return FcTrue;
}
pos = -pos - 1;
iter->leaf = 0;
return;
}
- iter->ucs4 = (FcChar32) fcs->numbers[pos] << 8;
+ iter->ucs4 = (FcChar32) FcCharSetGetNumbers(fcs)[pos] << 8;
}
- iter->leaf = fcs->leaves[pos];
+ iter->leaf = FcCharSetGetLeaf(fcs, pos);
iter->pos = pos;
#ifdef CHATTY
printf ("set %08x: %08x\n", iter->ucs4, (FcChar32) iter->leaf);
}
else
{
- iter->ucs4 = (FcChar32) fcs->numbers[pos] << 8;
- iter->leaf = fcs->leaves[pos];
+ iter->ucs4 = (FcChar32) FcCharSetGetNumbers(fcs)[pos] << 8;
+ iter->leaf = FcCharSetGetLeaf(fcs, pos);
iter->pos = pos;
}
}
ai = 0;
while (ai < a->num && bi < b->num)
{
- an = a->numbers[ai];
- bn = b->numbers[bi];
+ an = FcCharSetGetNumbers(a)[ai];
+ bn = FcCharSetGetNumbers(b)[bi];
/*
* Check matching pages
*/
if (an == bn)
{
- FcChar32 *am = a->leaves[ai]->map;
- FcChar32 *bm = b->leaves[bi]->map;
+ FcChar32 *am = FcCharSetGetLeaf(a, ai)->map;
+ FcChar32 *bm = FcCharSetGetLeaf(b, bi)->map;
if (am != bm)
{
while (low <= high)
{
int mid = (low + high) >> 1;
- bn = b->numbers[mid];
+ bn = FcCharSetGetNumbers(b)[mid];
if (bn == an)
{
high = mid;
high = mid - 1;
}
bi = high;
- while (bi < b->num && b->numbers[bi] < an)
+ while (bi < b->num && FcCharSetGetNumbers(b)[bi] < an)
bi++;
}
}
FcCharSetHash (FcCharSet *fcs)
{
FcChar32 hash = 0;
- FcChar32 *p;
int i;
/* hash in leaves */
- p = (FcChar32 *) fcs->leaves;
for (i = 0; i < fcs->num * sizeof (FcCharLeaf *) / sizeof (FcChar32); i++)
- hash = ((hash << 1) | (hash >> 31)) ^ *p++;
+ hash = ((hash << 1) | (hash >> 31)) ^ (FcChar32)(FcCharSetGetLeaf(fcs, i)->map);
/* hash in numbers */
for (i = 0; i < fcs->num; i++)
- hash = ((hash << 1) | (hash >> 31)) ^ fcs->numbers[i];
+ hash = ((hash << 1) | (hash >> 31)) ^ *FcCharSetGetNumbers(fcs);
return hash;
}
{
if (ent->hash == hash &&
ent->set.num == fcs->num &&
- !memcmp (ent->set.leaves, fcs->leaves,
- fcs->num * sizeof (FcCharLeaf *)) &&
- !memcmp (ent->set.numbers, fcs->numbers,
+ !memcmp (FcCharSetGetNumbers(&ent->set),
+ FcCharSetGetNumbers(fcs),
fcs->num * sizeof (FcChar16)))
{
- return &ent->set;
+ FcBool ok = FcTrue;
+ int i;
+
+ for (i = 0; i < fcs->num; i++)
+ if (FcCharSetGetLeaf(&ent->set, i) != FcCharSetGetLeaf(fcs, i))
+ ok = FcFalse;
+ if (ok)
+ return &ent->set;
}
}
ent->set.ref = FC_REF_CONSTANT;
ent->set.num = fcs->num;
- if (fcs->num)
+ ent->set.storage = fcs->storage;
+ if (fcs->storage == FcStorageDynamic)
{
- ent->set.leaves = (FcCharLeaf **) (ent + 1);
- ent->set.numbers = (FcChar16 *) (ent->set.leaves + fcs->num);
- memcpy (ent->set.leaves, fcs->leaves, fcs->num * sizeof (FcCharLeaf *));
- memcpy (ent->set.numbers, fcs->numbers, fcs->num * sizeof (FcChar16));
+ if (fcs->num)
+ {
+ ent->set.u.dyn.leaves = (FcCharLeaf **) (ent + 1);
+ ent->set.u.dyn.numbers = (FcChar16 *) (ent->set.u.dyn.leaves + fcs->num);
+ memcpy (ent->set.u.dyn.leaves, fcs->u.dyn.leaves, fcs->num * sizeof (FcCharLeaf *));
+ memcpy (ent->set.u.dyn.numbers, fcs->u.dyn.numbers, fcs->num * sizeof (FcChar16));
+ }
+ else
+ {
+ ent->set.u.dyn.leaves = 0;
+ ent->set.u.dyn.numbers = 0;
+ }
}
else
{
- ent->set.leaves = 0;
- ent->set.numbers = 0;
+ ent->set.u.stat.leafidx_offset = fcs->u.stat.leafidx_offset;
+ ent->set.u.stat.numbers_offset = fcs->u.stat.numbers_offset;
}
ent->hash = hash;
goto bail0;
for (i = 0; i < fcs->num; i++)
{
- l = FcCharSetFreezeLeaf (fcs->leaves[i]);
+ l = FcCharSetFreezeLeaf (FcCharSetGetLeaf(fcs, i));
if (!l)
goto bail1;
- if (!FcCharSetInsertLeaf (b, fcs->numbers[i] << 8, l))
+ if (!FcCharSetInsertLeaf (b, FcCharSetGetNumbers(fcs)[i] << 8, l))
goto bail1;
}
n = FcCharSetFreezeBase (b);
bail1:
- if (b->leaves)
- {
- FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcCharLeaf *));
- free (b->leaves);
- }
- if (b->numbers)
+ if (b->storage == FcStorageDynamic)
{
- FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcChar16));
- free (b->numbers);
+ if (b->u.dyn.leaves)
+ {
+ FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcCharLeaf *));
+ free (b->u.dyn.leaves);
+ }
+ if (b->u.dyn.numbers)
+ {
+ FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcChar16));
+ free (b->u.dyn.numbers);
+ }
}
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
free (b);
#endif
n = FcCharSetFreezeBase (c);
bail1:
- if (c->leaves)
- {
- FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcCharLeaf *));
- free (c->leaves);
- }
- if (c->numbers)
+ if (c->storage == FcStorageDynamic)
{
- FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcChar16));
- free (c->numbers);
+ if (c->u.dyn.leaves)
+ {
+ FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcCharLeaf *));
+ free (c->u.dyn.leaves);
+ }
+ if (c->u.dyn.numbers)
+ {
+ FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcChar16));
+ free (c->u.dyn.numbers);
+ }
+ FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
}
- FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
free (c);
bail0:
return n;
return FcTrue;
}
+
+
+FcCharSet *
+FcCharSetPtrU (FcCharSetPtr ci)
+{
+ switch (ci.storage)
+ {
+ case FcStorageDynamic:
+ return ci.u.dyn;
+ case FcStorageStatic:
+ return &charsets[ci.u.stat];
+ default:
+ return 0;
+ }
+}
+
+FcCharSetPtr
+FcCharSetPtrCreateDynamic(FcCharSet *c)
+{
+ FcCharSetPtr new;
+
+ new.storage = FcStorageDynamic;
+ new.u.dyn = c;
+ return new;
+}
+
+FcBool
+FcCharSetPrepareSerialize(FcCharSet *c)
+{
+ /* note the redundancy */
+ charset_count++;
+ charset_leaf_idx_count++;
+ charset_leaf_count += c->num;
+ charset_numbers_count += c->num;
+ return FcTrue;
+}
+
+FcCharSetPtr
+FcCharSetSerialize(FcCharSet *c)
+{
+ int i;
+ FcCharSetPtr newp;
+ FcCharSet new;
+
+ if (!charsets)
+ {
+ charsets = malloc(sizeof(FcCharSet) * charset_count);
+ if (!charsets) goto bail;
+ numbers = malloc(sizeof(FcChar16) * charset_numbers_count);
+ if (!numbers) goto bail1;
+ leaves = malloc(sizeof(FcCharLeaf) * charset_leaf_count);
+ if (!leaves) goto bail2;
+ leaf_idx = malloc(sizeof(int)*charset_leaf_idx_count);
+ if (!leaf_idx) goto bail3;
+ }
+
+ new.ref = c->ref;
+ new.storage = FcStorageStatic;
+ new.u.stat.leafidx_offset = charset_leaf_ptr;
+ new.u.stat.numbers_offset = charset_numbers_ptr;
+
+ newp.storage = FcStorageStatic;
+ newp.u.stat = charset_ptr;
+ charsets[charset_ptr++] = new;
+
+ leaf_idx[charset_leaf_idx_ptr++] = charset_leaf_ptr;
+ for (i = 0; i < c->num; i++)
+ {
+ memcpy (&leaves[charset_leaf_ptr++],
+ c->u.dyn.leaves[i], sizeof(FcCharLeaf));
+ numbers[charset_numbers_ptr++] = c->u.dyn.numbers[i];
+ }
+
+ return newp;
+
+ bail3:
+ free (leaves);
+ bail2:
+ free (numbers);
+ bail1:
+ free (charsets);
+ bail:
+ return FcCharSetPtrCreateDynamic(0);
+}
+
+FcCharLeaf *
+FcCharSetGetLeaf(const FcCharSet *c, int i)
+{
+ switch (c->storage)
+ {
+ case FcStorageDynamic:
+ return c->u.dyn.leaves[i];
+ case FcStorageStatic:
+ return &leaves[leaf_idx[c->u.stat.leafidx_offset]+i];
+ default:
+ return 0;
+ }
+}
+
+FcChar16 *
+FcCharSetGetNumbers(const FcCharSet *c)
+{
+ switch (c->storage)
+ {
+ case FcStorageDynamic:
+ return c->u.dyn.numbers;
+ case FcStorageStatic:
+ return &numbers[c->u.stat.numbers_offset];
+ default:
+ return 0;
+ }
+}
+
printf (" %g(f)", v.u.d);
break;
case FcTypeString:
- printf (" \"%s\"", v.u.s);
+ printf (" \"%s\"", FcObjectPtrU(v.u.si));
break;
case FcTypeBool:
printf (" %s", v.u.b ? "FcTrue" : "FcFalse");
break;
case FcTypeMatrix:
- printf (" (%f %f; %f %f)", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
+ {
+ FcMatrix *m = FcMatrixPtrU(v.u.mi);
+
+ printf (" (%f %f; %f %f)", m->xx, m->xy, m->yx, m->yy);
break;
+ }
case FcTypeCharSet: /* XXX */
printf (" set");
break;
case FcTypeLangSet:
printf (" ");
- FcLangSetPrint (v.u.l);
+ FcLangSetPrint (FcLangSetPtrU(v.u.li));
break;
case FcTypeFTFace:
printf (" face");
}
void
-FcValueListPrint (const FcValueList *l)
+FcValueListPrint (FcValueListPtr l)
{
- for (; l; l = l->next)
+ for (; FcValueListPtrU(l); l = FcValueListPtrU(l)->next)
{
- FcValuePrint (l->value);
- switch (l->binding) {
+ FcValuePrint (FcValueListPtrU(l)->value);
+ switch (FcValueListPtrU(l)->binding) {
case FcValueBindingWeak:
printf ("(w)");
break;
FcStrBufInit (&buf, init_buf, sizeof (init_buf));
if (FcNameUnparseLangSet (&buf, ls) && FcStrBufChar (&buf,'\0'))
- printf ("%s", buf.buf);
+ printf ("%s", buf.buf);
else
- printf ("langset (alloc error)");
+ printf ("langset (alloc error)");
FcStrBufDestroy (&buf);
}
printf ("Pattern %d of %d\n", p->num, p->size);
for (i = 0; i < p->num; i++)
{
- e = &p->elts[i];
- printf ("\t%s:", e->object);
+ e = FcPatternEltU(p->elts) + i;
+ printf ("\t%s:", FcObjectPtrU(e->object));
FcValueListPrint (e->values);
printf ("\n");
}
s->fonts[s->nfont++] = font;
return FcTrue;
}
+
+FcBool
+FcFontSetPrepareSerialize (FcFontSet *s)
+{
+ int i;
+
+ for (i = 0; i < s->nfont; i++)
+ if (!FcPatternPrepareSerialize(s->fonts[i]))
+ return FcFalse;
+
+ return FcTrue;
+}
+
+FcBool
+FcFontSetSerialize (FcFontSet * s)
+{
+ int i;
+ FcPattern * p;
+
+ for (i = 0; i < s->nfont; i++)
+ {
+ p = FcPatternSerialize (s->fonts[i]);
+ if (!p) return FcFalse;
+ FcPatternDestroy (s->fonts[i]);
+
+ s->fonts[i] = p;
+ }
+
+ return FcTrue;
+}
+
+void
+FcFontSetClearStatic (void)
+{
+ FcPatternClearStatic();
+}
#include <config.h>
#endif
+/* unused */
typedef struct _FcSymbolic {
const char *name;
int value;
FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
} FcValueBinding;
+typedef struct _FcStrSetPtr {
+ FcStorage storage;
+ union {
+ int stat;
+ struct _FcStrSet *dyn;
+ } u;
+} FcStrSetPtr;
+
+typedef struct _FcValueListPtr {
+ FcStorage storage;
+ union {
+ int stat;
+ struct _FcValueList *dyn;
+ } u;
+} FcValueListPtr;
+
typedef struct _FcValueList {
- struct _FcValueList *next;
+ FcValueListPtr next;
+
FcValue value;
FcValueBinding binding;
} FcValueList;
+typedef struct _FcPatternEltPtr {
+ FcStorage storage;
+ union {
+ int stat;
+ struct _FcPatternElt *dyn;
+ } u;
+} FcPatternEltPtr;
+
typedef struct _FcPatternElt {
- const char *object;
- FcValueList *values;
+ FcObjectPtr object;
+ FcValueListPtr values;
} FcPatternElt;
-
struct _FcPattern {
int num;
int size;
- FcPatternElt *elts;
+ FcPatternEltPtr elts;
int ref;
};
struct _FcCharSet {
int ref; /* reference count */
int num; /* size of leaves and numbers arrays */
- FcCharLeaf **leaves;
- FcChar16 *numbers;
+ FcStorage storage;
+ union {
+ struct {
+ FcCharLeaf **leaves;
+ FcChar16 *numbers;
+ } dyn;
+ struct {
+ int leafidx_offset;
+ int numbers_offset;
+ } stat;
+ } u;
};
struct _FcStrSet {
int ref; /* reference count */
int num;
int size;
- FcChar8 **strs;
+ FcStorage storage;
+ union {
+ FcChar8 **strs;
+ int stridx_offset;
+ } u;
};
struct _FcStrList {
FcCharLeaf *
FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4);
+void
+FcCharSetPtrDestroy (FcCharSetPtr fcs);
+
+void
+FcCharSetClearStatic(void);
+
+FcBool
+FcCharSetPrepareSerialize(FcCharSet *c);
+
+FcCharSetPtr
+FcCharSetSerialize(FcCharSet *c);
+
+FcCharSetPtr
+FcCharSetPtrCreateDynamic(FcCharSet *c);
+
+FcCharLeaf *
+FcCharSetGetLeaf(const FcCharSet *c, int i);
+
+FcChar16 *
+FcCharSetGetNumbers(const FcCharSet *c);
+
/* fcdbg.c */
void
-FcValueListPrint (const FcValueList *l);
+FcValueListPrint (const FcValueListPtr l);
void
FcLangSetPrint (const FcLangSet *ls);
int
FcDebug (void);
+FcCharSet *
+FcCharSetPtrU (FcCharSetPtr mi);
+
/* fcdir.c */
FcBool
FcFreeTypeGetPrivateMap (FT_Encoding encoding);
/* fcfs.c */
+
+void
+FcFontSetClearStatic (void);
+
+FcBool
+FcFontSetPrepareSerialize (FcFontSet * s);
+
+FcBool
+FcFontSetSerialize (FcFontSet * s);
+
/* fcgram.y */
int
FcConfigparse (void);
FcBool
FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls);
+void
+FcLangSetClearStatic (void);
+
+FcBool
+FcLangSetPrepareSerialize (FcLangSet *l);
+
+FcLangSetPtr
+FcLangSetSerialize (FcLangSet *l);
+
+FcLangSet *
+FcLangSetPtrU (FcLangSetPtr li);
+
+FcLangSetPtr
+FcLangSetPtrCreateDynamic (FcLangSet *l);
+
+void
+FcLangSetPtrDestroy (FcLangSetPtr li);
+
/* fclist.c */
FcBool
/* fcmatch.c */
+/* fcmmap.c */
+
+void
+FcCacheClearStatic(void);
+
+FcBool
+FcCachePrepareSerialize(FcConfig * config);
+
+FcBool
+FcCacheSerialize (FcConfig * config);
+
+
/* fcname.c */
FcBool
/* fcpat.c */
void
-FcValueListDestroy (FcValueList *l);
-
+FcValueListDestroy (FcValueListPtr l);
+
FcPatternElt *
FcPatternFindElt (const FcPattern *p, const char *object);
FcBool
FcPatternAppend (FcPattern *p, FcPattern *s);
-const char *
+void
+FcObjectClearStatic(void);
+
+FcObjectPtr
FcObjectStaticName (const char *name);
+FcBool
+FcObjectPrepareSerialize (FcObjectPtr si);
+
+const char *
+FcObjectPtrU (FcObjectPtr p);
+
+int
+FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b);
+
+FcObjectPtr
+FcObjectPtrCreateDynamic (const char * s);
+
+void
+FcObjectPtrDestroy (FcObjectPtr p);
+
+FcBool
+FcPatternPrepareSerialize (FcPattern *p);
+
+void
+FcValueListClearStatic (void);
+
+void
+FcPatternClearStatic (void);
+
+FcValueList *
+FcValueListPtrU(FcValueListPtr p);
+
+FcPatternElt *
+FcPatternEltU (FcPatternEltPtr pei);
+
+FcValueListPtr
+FcValueListPtrCreateDynamic(FcValueList * p);
+
+FcBool
+FcValueListPrepareSerialize (FcValueList *p);
+
+FcValueListPtr
+FcValueListSerialize(FcValueList *pi);
+
+FcPattern *
+FcPatternSerialize (FcPattern * p);
+
/* fcrender.c */
/* fcmatrix.c */
-extern const FcMatrix FcIdentityMatrix;
+extern const FcMatrixPtr FcIdentityMatrix;
void
FcMatrixFree (FcMatrix *mat);
+void
+FcMatrixPtrDestroy (FcMatrixPtr mi);
+
+FcBool
+FcMatrixPrepareSerialize(FcMatrix *m);
+
+FcMatrixPtr
+FcMatrixSerialize(FcMatrix *m);
+
+FcMatrix *
+FcMatrixPtrU (FcMatrixPtr mi);
+
+FcMatrixPtr
+FcMatrixPtrCreateDynamic (FcMatrix *m);
+
+void
+FcMatrixClearStatic (void);
+
/* fcstr.c */
+FcStrSet *
+FcStrSetPtrU (const FcStrSetPtr set);
+
+FcStrSetPtr
+FcStrSetPtrCreateDynamic (const FcStrSet * set);
+
+void
+FcStrSetClearStatic (void);
+
+FcBool
+FcStrSetPrepareSerialize (const FcStrSet *set);
+
+void
+FcStrSetSort (FcStrSet * set);
+
+FcChar8 *
+FcStrSetGet (const FcStrSet *set, int i);
+
FcChar8 *
FcStrPlus (const FcChar8 *s1, const FcChar8 *s2);
FcBool
FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
+FcStrSetPtr
+FcStrSetSerialize (FcStrSet *set);
+
int
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
* PERFORMANCE OF THIS SOFTWARE.
*/
+#include <fcntl.h>
+#include <sys/mman.h>
#include "fcint.h"
typedef struct {
struct _FcLangSet {
FcChar32 map[NUM_LANG_SET_MAP];
- FcStrSet *extra;
+ FcStrSetPtr extra;
};
#define FcLangSetBitSet(ls, id) ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f)))
FcFreeTypeLangSet (const FcCharSet *charset,
const FcChar8 *exclusiveLang)
{
- int i;
+ int i, j;
FcChar32 missing;
const FcCharSet *exclusiveCharset = 0;
FcLangSet *ls;
* not support other Han languages
*/
if (exclusiveCharset &&
- FcFreeTypeIsExclusiveLang (fcLangCharSets[i].lang) &&
- fcLangCharSets[i].charset.leaves != exclusiveCharset->leaves)
+ FcFreeTypeIsExclusiveLang (fcLangCharSets[i].lang))
{
- continue;
+ if (fcLangCharSets[i].charset.num != exclusiveCharset->num)
+ continue;
+
+ for (j = 0; j < fcLangCharSets[i].charset.num; j++)
+ if (FcCharSetGetLeaf(&fcLangCharSets[i].charset, j) !=
+ FcCharSetGetLeaf(exclusiveCharset, j))
+ continue;
}
missing = FcCharSetSubtractCount (&fcLangCharSets[i].charset, charset);
if (FcDebug() & FC_DBG_SCANV)
return 0;
FcMemAlloc (FC_MEM_LANGSET, sizeof (FcLangSet));
memset (ls->map, '\0', sizeof (ls->map));
- ls->extra = 0;
+ ls->extra = FcStrSetPtrCreateDynamic(0);
return ls;
}
+void
+FcLangSetPtrDestroy (FcLangSetPtr li)
+{
+ if (li.storage == FcStorageDynamic)
+ FcLangSetDestroy(FcLangSetPtrU(li));
+}
+
void
FcLangSetDestroy (FcLangSet *ls)
{
- if (ls->extra)
- FcStrSetDestroy (ls->extra);
+ if (FcStrSetPtrU(ls->extra))
+ FcStrSetDestroy (FcStrSetPtrU(ls->extra));
FcMemFree (FC_MEM_LANGSET, sizeof (FcLangSet));
free (ls);
}
if (!new)
goto bail0;
memcpy (new->map, ls->map, sizeof (new->map));
- if (ls->extra)
+ if (FcStrSetPtrU(ls->extra))
{
FcStrList *list;
FcChar8 *extra;
- new->extra = FcStrSetCreate ();
- if (!new->extra)
+ new->extra = FcStrSetPtrCreateDynamic(FcStrSetCreate ());
+ if (!FcStrSetPtrU(new->extra))
goto bail1;
- list = FcStrListCreate (ls->extra);
+ list = FcStrListCreate (FcStrSetPtrU(ls->extra));
if (!list)
goto bail1;
while ((extra = FcStrListNext (list)))
- if (!FcStrSetAdd (new->extra, extra))
+ if (!FcStrSetAdd (FcStrSetPtrU(new->extra), extra))
{
FcStrListDone (list);
goto bail1;
FcLangSetBitSet (ls, id);
return FcTrue;
}
- if (!ls->extra)
+ if (!FcStrSetPtrU(ls->extra))
{
- ls->extra = FcStrSetCreate ();
- if (!ls->extra)
+ ls->extra = FcStrSetPtrCreateDynamic(FcStrSetCreate ());
+ if (!FcStrSetPtrU(ls->extra))
return FcFalse;
}
- return FcStrSetAdd (ls->extra, lang);
+ return FcStrSetAdd (FcStrSetPtrU(ls->extra), lang);
}
FcLangResult
if (FcLangSetBitGet (ls, i) && r < best)
best = r;
}
- if (ls->extra)
+ if (FcStrSetPtrU(ls->extra))
{
- FcStrList *list = FcStrListCreate (ls->extra);
+ FcStrList *list = FcStrListCreate (FcStrSetPtrU(ls->extra));
FcChar8 *extra;
FcLangResult r;
best = FcLangDifferentCountry;
break;
}
- if (lsa->extra)
+ if (FcStrSetPtrU(lsa->extra))
{
- r = FcLangSetCompareStrSet (lsb, lsa->extra);
+ r = FcLangSetCompareStrSet (lsb, FcStrSetPtrU(lsa->extra));
if (r < best)
best = r;
}
- if (best > FcLangEqual && lsb->extra)
+ if (best > FcLangEqual && FcStrSetPtrU(lsb->extra))
{
- r = FcLangSetCompareStrSet (lsa, lsb->extra);
+ r = FcLangSetCompareStrSet (lsa, FcStrSetPtrU(lsb->extra));
if (r < best)
best = r;
}
int id;
memset (ls.map, '\0', sizeof (ls.map));
- ls.extra = 0;
+ ls.extra = FcStrSetPtrCreateDynamic(0);
id = FcLangSetIndex (lang);
if (id > 0)
{
}
else
{
- ls.extra = &strs;
+ ls.extra = FcStrSetPtrCreateDynamic(&strs);
strs.num = 1;
strs.size = 1;
- strs.strs = &str;
+ strs.storage = FcStorageDynamic;
+ strs.u.strs = &str;
strs.ref = 1;
str = (FcChar8 *) lang;
}
for (i = 0; i < NUM_LANG_SET_MAP; i++)
h ^= ls->map[i];
- if (ls->extra)
- h ^= ls->extra->num;
+ if (FcStrSetPtrU(ls->extra))
+ h ^= FcStrSetPtrU(ls->extra)->num;
return h;
}
}
}
}
- if (ls->extra)
+ if (FcStrSetPtrU(ls->extra))
{
- FcStrList *list = FcStrListCreate (ls->extra);
+ FcStrList *list = FcStrListCreate (FcStrSetPtrU(ls->extra));
FcChar8 *extra;
if (!list)
if (lsa->map[i] != lsb->map[i])
return FcFalse;
}
- if (!lsa->extra && !lsb->extra)
+ if (!FcStrSetPtrU(lsa->extra) && !FcStrSetPtrU(lsb->extra))
return FcTrue;
- if (lsa->extra && lsb->extra)
- return FcStrSetEqual (lsa->extra, lsb->extra);
+ if (FcStrSetPtrU(lsa->extra) && FcStrSetPtrU(lsb->extra))
+ return FcStrSetEqual (FcStrSetPtrU(lsa->extra), FcStrSetPtrU(lsb->extra));
return FcFalse;
}
FcLangContains (fcLangCharSets[i].lang, lang))
return FcTrue;
}
- if (ls->extra)
+ if (FcStrSetPtrU(ls->extra))
{
- FcStrList *list = FcStrListCreate (ls->extra);
+ FcStrList *list = FcStrListCreate (FcStrSetPtrU(ls->extra));
FcChar8 *extra;
if (list)
}
}
}
- if (lsb->extra)
+ if (FcStrSetPtrU(lsb->extra))
{
- FcStrList *list = FcStrListCreate (lsb->extra);
+ FcStrList *list = FcStrListCreate (FcStrSetPtrU(lsb->extra));
FcChar8 *extra;
if (list)
}
return FcTrue;
}
+
+static FcLangSet * langsets = 0;
+static int langset_ptr = 0, langset_count = 0;
+
+FcLangSet *
+FcLangSetPtrU (FcLangSetPtr li)
+{
+ switch (li.storage)
+ {
+ case FcStorageDynamic:
+ return li.u.dyn;
+ case FcStorageStatic:
+ return &langsets[li.u.stat];
+ default:
+ return 0;
+
+ }
+}
+
+FcLangSetPtr
+FcLangSetPtrCreateDynamic (FcLangSet *li)
+{
+ FcLangSetPtr new;
+ new.storage = FcStorageDynamic;
+ new.u.dyn = li;
+ return new;
+}
+
+void
+FcLangSetClearStatic (void)
+{
+ FcStrSetClearStatic();
+ langset_ptr = 0;
+ langset_count = 0;
+}
+
+/* should only write one copy of any particular FcLangSet */
+FcBool
+FcLangSetPrepareSerialize (FcLangSet *l)
+{
+ langset_count++;
+ if (l && FcStrSetPtrU(l->extra))
+ return FcStrSetPrepareSerialize (FcStrSetPtrU(l->extra));
+ return FcTrue;
+}
+
+FcLangSetPtr
+FcLangSetSerialize(FcLangSet *l)
+{
+ FcLangSetPtr new;
+ int p = langset_ptr;
+
+ if (!l) return FcLangSetPtrCreateDynamic(0);
+
+ if (!langsets)
+ {
+ FcLangSet* t;
+ t = (FcLangSet *)malloc(langset_count * sizeof(FcLangSet));
+ if (!t)
+ return FcLangSetPtrCreateDynamic(0);
+ langsets = t;
+ langset_ptr = 0;
+ }
+
+ langsets[langset_ptr] = *l;
+ if (FcStrSetPtrU(l->extra))
+ langsets[langset_ptr].extra =
+ FcStrSetSerialize(FcStrSetPtrU(l->extra));
+ else
+ langsets[langset_ptr].extra = FcStrSetPtrCreateDynamic(0);
+ langset_ptr++;
+ new.storage = FcStorageStatic;
+ new.u.stat = p;
+ return new;
+}
*/
#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
#include "fcint.h"
FcObjectSet *
FcObjectSetAdd (FcObjectSet *os, const char *object)
{
int s;
- const char **objects;
+ FcObjectPtr *objects;
+ FcObjectPtr obj;
int high, low, mid, c;
if (os->nobject == os->sobject)
{
s = os->sobject + 4;
if (os->objects)
- objects = (const char **) realloc ((void *) os->objects,
- s * sizeof (const char *));
+ objects = (FcObjectPtr *) realloc ((void *) os->objects,
+ s * sizeof (FcObjectPtr));
else
- objects = (const char **) malloc (s * sizeof (const char *));
+ objects = (FcObjectPtr *) malloc (s * sizeof (FcObjectPtr));
if (!objects)
return FcFalse;
if (os->sobject)
low = 0;
mid = 0;
c = 1;
- object = FcObjectStaticName (object);
+ obj = FcObjectStaticName (object);
while (low <= high)
{
mid = (low + high) >> 1;
- c = os->objects[mid] - object;
+ c = FcObjectPtrCompare(os->objects[mid], obj);
if (c == 0)
return FcTrue;
if (c < 0)
if (c < 0)
mid++;
memmove (os->objects + mid + 1, os->objects + mid,
- (os->nobject - mid) * sizeof (const char *));
- os->objects[mid] = object;
+ (os->nobject - mid) * sizeof (FcObjectPtr));
+ os->objects[mid] = obj;
os->nobject++;
return FcTrue;
}
* Font must have a containing value for every value in the pattern
*/
static FcBool
-FcListValueListMatchAny (FcValueList *patOrig, /* pattern */
- FcValueList *fntOrig) /* font */
+FcListValueListMatchAny (FcValueListPtr patOrig, /* pattern */
+ FcValueListPtr fntOrig) /* font */
{
- FcValueList *pat, *fnt;
+ FcValueListPtr pat, fnt;
- for (pat = patOrig; pat; pat = pat->next)
+ for (pat = patOrig; FcValueListPtrU(pat);
+ pat = FcValueListPtrU(pat)->next)
{
- for (fnt = fntOrig; fnt; fnt = fnt->next)
+ for (fnt = fntOrig; FcValueListPtrU(fnt);
+ fnt = FcValueListPtrU(fnt)->next)
{
/*
* make sure the font 'contains' the pattern.
* (OpListing is OpContains except for strings
* where it requires an exact match)
*/
- if (FcConfigCompareValue (fnt->value,
+ if (FcConfigCompareValue (FcValueListPtrU(fnt)->value,
FcOpListing,
- pat->value))
+ FcValueListPtrU(pat)->value))
break;
}
- if (!fnt)
+ if (!FcValueListPtrU(fnt))
return FcFalse;
}
return FcTrue;
}
static FcBool
-FcListValueListEqual (FcValueList *v1orig,
- FcValueList *v2orig)
+FcListValueListEqual (FcValueListPtr v1orig,
+ FcValueListPtr v2orig)
{
- FcValueList *v1, *v2;
+ FcValueListPtr v1, v2;
- for (v1 = v1orig; v1; v1 = v1->next)
+ for (v1 = v1orig; FcValueListPtrU(v1);
+ v1 = FcValueListPtrU(v1)->next)
{
- for (v2 = v2orig; v2; v2 = v2->next)
- if (FcValueEqual (v1->value, v2->value))
+ for (v2 = v2orig; FcValueListPtrU(v2);
+ v2 = FcValueListPtrU(v2)->next)
+ if (FcValueEqual (FcValueListPtrU(v1)->value,
+ FcValueListPtrU(v2)->value))
break;
- if (!v2)
+ if (!FcValueListPtrU(v2))
return FcFalse;
}
- for (v2 = v2orig; v2; v2 = v2->next)
+ for (v2 = v2orig; FcValueListPtrU(v2);
+ v2 = FcValueListPtrU(v2)->next)
{
- for (v1 = v1orig; v1; v1 = v1->next)
- if (FcValueEqual (v1->value, v2->value))
+ for (v1 = v1orig; FcValueListPtrU(v1);
+ v1 = FcValueListPtrU(v1)->next)
+ if (FcValueEqual (FcValueListPtrU(v1)->value,
+ FcValueListPtrU(v2)->value))
break;
- if (!v1)
+ if (!FcValueListPtrU(v1))
return FcFalse;
}
return FcTrue;
for (i = 0; i < os->nobject; i++)
{
- e1 = FcPatternFindElt (p1, os->objects[i]);
- e2 = FcPatternFindElt (p2, os->objects[i]);
+ e1 = FcPatternFindElt (p1, FcObjectPtrU(os->objects[i]));
+ e2 = FcPatternFindElt (p2, FcObjectPtrU(os->objects[i]));
if (!e1 && !e2)
continue;
if (!e1 || !e2)
for (i = 0; i < p->num; i++)
{
- e = FcPatternFindElt (font, p->elts[i].object);
+ e = FcPatternFindElt (font,
+ FcObjectPtrU((FcPatternEltU(p->elts)+i)->object));
if (!e)
return FcFalse;
- if (!FcListValueListMatchAny (p->elts[i].values, /* pat elts */
+ if (!FcListValueListMatchAny ((FcPatternEltU(p->elts)+i)->values, /* pat elts */
e->values)) /* font elts */
return FcFalse;
}
case FcTypeDouble:
return (FcChar32) (int) v.u.d;
case FcTypeString:
- return FcStrHashIgnoreCase (v.u.s);
+ return FcStrHashIgnoreCase (FcObjectPtrU(v.u.si));
case FcTypeBool:
return (FcChar32) v.u.b;
case FcTypeMatrix:
- return FcListMatrixHash (v.u.m);
+ return FcListMatrixHash (FcMatrixPtrU(v.u.mi));
case FcTypeCharSet:
- return FcCharSetCount (v.u.c);
+ return FcCharSetCount (FcCharSetPtrU(v.u.ci));
case FcTypeFTFace:
return (long) v.u.f;
case FcTypeLangSet:
- return FcLangSetHash (v.u.l);
+ return FcLangSetHash (FcLangSetPtrU(v.u.li));
}
return 0;
}
static FcChar32
-FcListValueListHash (FcValueList *list)
+FcListValueListHash (FcValueListPtr list)
{
FcChar32 h = 0;
- while (list)
+ while (FcValueListPtrU(list))
{
- h = h ^ FcListValueHash (list->value);
- list = list->next;
+ h = h ^ FcListValueHash (FcValueListPtrU(list)->value);
+ list = FcValueListPtrU(list)->next;
}
return h;
}
for (n = 0; n < os->nobject; n++)
{
- e = FcPatternFindElt (font, os->objects[n]);
+ e = FcPatternFindElt (font, FcObjectPtrU(os->objects[n]));
if (e)
h = h ^ FcListValueListHash (e->values);
}
{
int o;
FcPatternElt *e;
- FcValueList *v;
+ FcValueListPtr v;
FcChar32 hash;
FcListBucket **prev, *bucket;
for (o = 0; o < os->nobject; o++)
{
- e = FcPatternFindElt (font, os->objects[o]);
+ e = FcPatternFindElt (font, FcObjectPtrU(os->objects[o]));
if (e)
{
- for (v = e->values; v; v = v->next)
+ for (v = e->values; FcValueListPtrU(v);
+ v = FcValueListPtrU(v)->next)
{
if (!FcPatternAdd (bucket->pattern,
- os->objects[o],
- v->value, FcTrue))
+ FcObjectPtrU(os->objects[o]),
+ FcValueListPtrU(v)->value, FcTrue))
goto bail2;
}
}
{
if (value2.type != FcTypeString || value1.type != FcTypeString)
return -1.0;
- return (double) FcStrCmpIgnoreCase (value1.u.s, value2.u.s) != 0;
+ return (double) FcStrCmpIgnoreCase
+ (FcObjectPtrU(value1.u.si), FcObjectPtrU(value2.u.si)) != 0;
}
static double
{
if (value2.type != FcTypeString || value1.type != FcTypeString)
return -1.0;
- return (double) FcStrCmpIgnoreBlanksAndCase (value1.u.s, value2.u.s) != 0;
+ return (double) FcStrCmpIgnoreBlanksAndCase
+ (FcObjectPtrU(value1.u.si), FcObjectPtrU(value2.u.si)) != 0;
}
static double
case FcTypeLangSet:
switch (value2.type) {
case FcTypeLangSet:
- result = FcLangSetCompare (value1.u.l, value2.u.l);
+ result = FcLangSetCompare (FcLangSetPtrU(value1.u.li),
+ FcLangSetPtrU(value2.u.li));
break;
case FcTypeString:
- result = FcLangSetHasLang (value1.u.l, value2.u.s);
+ result = FcLangSetHasLang (FcLangSetPtrU(value1.u.li),
+ FcObjectPtrU(value2.u.si));
break;
default:
return -1.0;
case FcTypeString:
switch (value2.type) {
case FcTypeLangSet:
- result = FcLangSetHasLang (value2.u.l, value1.u.s);
+ result = FcLangSetHasLang (FcLangSetPtrU(value2.u.li),
+ FcObjectPtrU(value1.u.si));
break;
case FcTypeString:
- result = FcLangCompare (value1.u.s, value2.u.s);
+ result = FcLangCompare (FcObjectPtrU(value1.u.si),
+ FcObjectPtrU(value2.u.si));
break;
default:
return -1.0;
{
if (value2.type != FcTypeCharSet || value1.type != FcTypeCharSet)
return -1.0;
- return (double) FcCharSetSubtractCount (value1.u.c, value2.u.c);
+ return (double) FcCharSetSubtractCount (FcCharSetPtrU(value1.u.ci),
+ FcCharSetPtrU(value2.u.ci));
}
static double
static FcBool
FcCompareValueList (const char *object,
- FcValueList *v1orig, /* pattern */
- FcValueList *v2orig, /* target */
+ FcValueListPtr v1orig, /* pattern */
+ FcValueListPtr v2orig, /* target */
FcValue *bestValue,
double *value,
FcResult *result)
{
- FcValueList *v1, *v2;
+ FcValueListPtr v1, v2;
double v, best, bestStrong, bestWeak;
int i;
int j;
(FcChar8 *) object) != 0)
{
if (bestValue)
- *bestValue = v2orig->value;
+ *bestValue = FcValueListPtrU(v2orig)->value;
return FcTrue;
}
#if 0
bestStrong = 1e99;
bestWeak = 1e99;
j = 0;
- for (v1 = v1orig; v1; v1 = v1->next)
+ for (v1 = v1orig; FcValueListPtrU(v1);
+ v1 = FcValueListPtrU(v1)->next)
{
- for (v2 = v2orig; v2; v2 = v2->next)
+ for (v2 = v2orig; FcValueListPtrU(v2);
+ v2 = FcValueListPtrU(v2)->next)
{
v = (*_FcMatchers[i].compare) (_FcMatchers[i].object,
- v1->value,
- v2->value);
+ FcValueListPtrU(v1)->value,
+ FcValueListPtrU(v2)->value);
if (v < 0)
{
*result = FcResultTypeMismatch;
if (v < best)
{
if (bestValue)
- *bestValue = v2->value;
+ *bestValue = FcValueListPtrU(v2)->value;
best = v;
}
- if (v1->binding == FcValueBindingStrong)
+ if (FcValueListPtrU(v1)->binding == FcValueBindingStrong)
{
if (v < bestStrong)
bestStrong = v;
i2 = 0;
while (i1 < pat->num && i2 < fnt->num)
{
- i = pat->elts[i1].object - fnt->elts[i2].object;
+ i = FcObjectPtrCompare((FcPatternEltU(pat->elts)+i1)->object,
+ (FcPatternEltU(fnt->elts)+i2)->object);
if (i > 0)
i2++;
else if (i < 0)
i1++;
else
{
- if (!FcCompareValueList (pat->elts[i1].object,
- pat->elts[i1].values,
- fnt->elts[i2].values,
+ if (!FcCompareValueList (FcObjectPtrU((FcPatternEltU(pat->elts)+i1)->object),
+ (FcPatternEltU(pat->elts)+i1)->values,
+ (FcPatternEltU(fnt->elts)+i2)->values,
0,
value,
result))
return 0;
for (i = 0; i < font->num; i++)
{
- fe = &font->elts[i];
- pe = FcPatternFindElt (pat, fe->object);
+ fe = FcPatternEltU(font->elts)+i;
+ pe = FcPatternFindElt (pat, FcObjectPtrU(fe->object));
if (pe)
{
- if (!FcCompareValueList (pe->object, pe->values,
+ if (!FcCompareValueList (FcObjectPtrU(pe->object), pe->values,
fe->values, &v, 0, &result))
{
FcPatternDestroy (new);
}
}
else
- v = fe->values->value;
- FcPatternAdd (new, fe->object, v, FcFalse);
+ v = FcValueListPtrU(fe->values)->value;
+ FcPatternAdd (new, FcObjectPtrU(fe->object), v, FcFalse);
}
for (i = 0; i < pat->num; i++)
{
- pe = &pat->elts[i];
- fe = FcPatternFindElt (font, pe->object);
+ pe = FcPatternEltU(pat->elts)+i;
+ fe = FcPatternFindElt (font, FcObjectPtrU(pe->object));
if (!fe)
- FcPatternAdd (new, pe->object, pe->values->value, FcTrue);
+ FcPatternAdd (new, FcObjectPtrU(pe->object),
+ FcValueListPtrU(pe->values)->value, FcTrue);
}
FcConfigSubstituteWithPat (config, new, pat, FcMatchFont);
return new;
#include <ctype.h>
#include "fcint.h"
-const FcMatrix FcIdentityMatrix = { 1, 0, 0, 1 };
+FcMatrix _id = { 1, 0, 0, 1 };
+const FcMatrixPtr FcIdentityMatrix = {
+ .storage = FcStorageDynamic,
+ .u.dyn = &_id
+};
FcMatrix *
FcMatrixCopy (const FcMatrix *mat)
return r;
}
+void
+FcMatrixPtrDestroy (FcMatrixPtr mi)
+{
+ if (mi.storage == FcStorageDynamic)
+ FcMatrixFree (mi.u.dyn);
+}
+
void
FcMatrixFree (FcMatrix *mat)
{
- if (mat != &FcIdentityMatrix)
+ if (mat != FcMatrixPtrU(FcIdentityMatrix))
{
FcMemFree (FC_MEM_MATRIX, sizeof (FcMatrix));
free (mat);
r.yy = 1;
FcMatrixMultiply (m, &r, m);
}
+
+static FcMatrix * matrices = 0;
+static int matrix_ptr = 0, matrix_count = 0;
+
+void
+FcMatrixClearStatic (void)
+{
+ matrices = 0;
+ matrix_ptr = 0;
+ matrix_count = 0;
+}
+
+FcMatrix *
+FcMatrixPtrU (FcMatrixPtr mi)
+{
+ switch (mi.storage)
+ {
+ case FcStorageDynamic:
+ return mi.u.dyn;
+ case FcStorageStatic:
+ return &matrices[mi.u.stat];
+ default:
+ return 0;
+
+ }
+}
+
+FcMatrixPtr
+FcMatrixPtrCreateDynamic (FcMatrix *mi)
+{
+ FcMatrixPtr new;
+ new.storage = FcStorageDynamic;
+ new.u.dyn = mi;
+ return new;
+}
+
+FcBool
+FcMatrixPrepareSerialize(FcMatrix *m)
+{
+ matrix_count++;
+ return FcTrue;
+}
+
+FcMatrixPtr
+FcMatrixSerialize(FcMatrix *m)
+{
+ FcMatrixPtr new;
+
+ if (matrix_count == matrix_ptr)
+ return FcMatrixPtrCreateDynamic(0);
+
+ new.storage = FcStorageStatic;
+ new.u.stat = matrix_ptr++;
+ return new;
+}
+
v.u.i = atoi ((char *) string);
break;
case FcTypeString:
- v.u.s = string;
+ v.u.si = FcObjectPtrCreateDynamic(string);
break;
case FcTypeBool:
if (!FcNameBool (string, &v.u.b))
v.u.d = strtod ((char *) string, 0);
break;
case FcTypeMatrix:
- v.u.m = m;
+ v.u.mi = FcMatrixPtrCreateDynamic(m);
sscanf ((char *) string, "%lg %lg %lg %lg", &m->xx, &m->xy, &m->yx, &m->yy);
break;
case FcTypeCharSet:
- v.u.c = FcNameParseCharSet (string);
+ v.u.ci = FcCharSetPtrCreateDynamic(FcNameParseCharSet (string));
break;
case FcTypeLangSet:
- v.u.l = FcNameParseLangSet (string);
+ v.u.li = FcLangSetPtrCreateDynamic(FcNameParseLangSet (string));
break;
default:
break;
{
switch (v.type) {
case FcTypeCharSet:
- FcCharSetDestroy ((FcCharSet *) v.u.c);
+ FcCharSetDestroy ((FcCharSet *) FcCharSetPtrU(v.u.ci));
break;
case FcTypeLangSet:
- FcLangSetDestroy ((FcLangSet *) v.u.l);
+ FcLangSetDestroy ((FcLangSet *) FcLangSetPtrU(v.u.li));
break;
default:
break;
}
switch (v.type) {
case FcTypeCharSet:
- FcCharSetDestroy ((FcCharSet *) v.u.c);
+ FcCharSetDestroy ((FcCharSet *) FcCharSetPtrU(v.u.ci));
break;
case FcTypeLangSet:
- FcLangSetDestroy ((FcLangSet *) v.u.l);
+ FcLangSetDestroy ((FcLangSet *) FcLangSetPtrU(v.u.li));
break;
default:
break;
sprintf ((char *) temp, "%g", v.u.d);
return FcNameUnparseString (buf, temp, 0);
case FcTypeString:
- return FcNameUnparseString (buf, v.u.s, escape);
+ return FcNameUnparseString (buf, FcObjectPtrU(v.u.si), escape);
case FcTypeBool:
return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0);
case FcTypeMatrix:
+ {
+ FcMatrix * m = FcMatrixPtrU(v.u.mi);
sprintf ((char *) temp, "%g %g %g %g",
- v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
+ m->xx, m->xy, m->yx, m->yy);
return FcNameUnparseString (buf, temp, 0);
+ }
case FcTypeCharSet:
- return FcNameUnparseCharSet (buf, v.u.c);
+ return FcNameUnparseCharSet (buf, FcCharSetPtrU(v.u.ci));
case FcTypeLangSet:
- return FcNameUnparseLangSet (buf, v.u.l);
+ return FcNameUnparseLangSet (buf, FcLangSetPtrU(v.u.li));
case FcTypeFTFace:
return FcTrue;
}
static FcBool
FcNameUnparseValueList (FcStrBuf *buf,
- FcValueList *v,
+ FcValueListPtr v,
FcChar8 *escape)
{
- while (v)
+ while (FcValueListPtrU(v))
{
- if (!FcNameUnparseValue (buf, v->value, escape))
+ if (!FcNameUnparseValue (buf, FcValueListPtrU(v)->value, escape))
return FcFalse;
- if ((v = v->next))
+ if (FcValueListPtrU(v = FcValueListPtrU(v)->next))
if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0))
return FcFalse;
}
#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <sys/mman.h>
#include "fcint.h"
+static FcPattern * fcpatterns = NULL;
+static int fcpattern_ptr, fcpattern_count;
+static FcPatternElt * fcpatternelts = NULL;
+static int fcpatternelt_ptr, fcpatternelt_count;
+static FcValueList * fcvaluelists = NULL;
+static int fcvaluelist_ptr, fcvaluelist_count;
+
+static char * object_content;
+static int object_content_count;
+static int object_content_ptr;
+
+static FcBool
+FcPatternEltIsDynamic (FcPatternEltPtr pei);
+
+static FcPatternEltPtr
+FcPatternEltPtrCreateDynamic (FcPatternElt * e);
+
FcPattern *
FcPatternCreate (void)
{
FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern));
p->num = 0;
p->size = 0;
- p->elts = 0;
+ p->elts = FcPatternEltPtrCreateDynamic(0);
p->ref = 1;
return p;
}
{
switch (v.type) {
case FcTypeString:
- FcStrFree ((FcChar8 *) v.u.s);
+ FcObjectPtrDestroy (v.u.si);
break;
case FcTypeMatrix:
- FcMatrixFree ((FcMatrix *) v.u.m);
+ FcMatrixPtrDestroy (v.u.mi);
break;
case FcTypeCharSet:
- FcCharSetDestroy ((FcCharSet *) v.u.c);
+ FcCharSetPtrDestroy (v.u.ci);
break;
case FcTypeLangSet:
- FcLangSetDestroy ((FcLangSet *) v.u.l);
+ FcLangSetPtrDestroy (v.u.li);
break;
default:
break;
{
switch (v.type) {
case FcTypeString:
- v.u.s = FcStrCopy (v.u.s);
- if (!v.u.s)
+ v.u.si = FcObjectPtrCreateDynamic(FcStrCopy (FcObjectPtrU(v.u.si)));
+ if (!FcObjectPtrU(v.u.si))
v.type = FcTypeVoid;
break;
case FcTypeMatrix:
- v.u.m = FcMatrixCopy (v.u.m);
- if (!v.u.m)
+ v.u.mi = FcMatrixPtrCreateDynamic
+ (FcMatrixCopy (FcMatrixPtrU(v.u.mi)));
+ if (!FcMatrixPtrU(v.u.mi))
v.type = FcTypeVoid;
break;
case FcTypeCharSet:
- v.u.c = FcCharSetCopy ((FcCharSet *) v.u.c);
- if (!v.u.c)
+ v.u.ci = FcCharSetPtrCreateDynamic
+ (FcCharSetCopy (FcCharSetPtrU(v.u.ci)));
+ if (!FcCharSetPtrU(v.u.ci))
v.type = FcTypeVoid;
break;
case FcTypeLangSet:
- v.u.l = FcLangSetCopy (v.u.l);
- if (!v.u.l)
+ v.u.li = FcLangSetPtrCreateDynamic
+ (FcLangSetCopy (FcLangSetPtrU(v.u.li)));
+ if (!FcLangSetPtrU(v.u.li))
v.type = FcTypeVoid;
break;
default:
}
void
-FcValueListDestroy (FcValueList *l)
+FcValueListDestroy (FcValueListPtr l)
{
- FcValueList *next;
- for (; l; l = next)
+ FcValueListPtr next;
+ for (; FcValueListPtrU(l); l = next)
{
- switch (l->value.type) {
+ switch (FcValueListPtrU(l)->value.type) {
case FcTypeString:
- FcStrFree ((FcChar8 *) l->value.u.s);
+ FcObjectPtrDestroy (FcValueListPtrU(l)->value.u.si);
break;
case FcTypeMatrix:
- FcMatrixFree ((FcMatrix *) l->value.u.m);
+ FcMatrixPtrDestroy (FcValueListPtrU(l)->value.u.mi);
break;
case FcTypeCharSet:
- FcCharSetDestroy ((FcCharSet *) l->value.u.c);
+ FcCharSetDestroy
+ (FcCharSetPtrU (FcValueListPtrU(l)->value.u.ci));
break;
case FcTypeLangSet:
- FcLangSetDestroy ((FcLangSet *) l->value.u.l);
+ FcLangSetDestroy
+ (FcLangSetPtrU (FcValueListPtrU(l)->value.u.li));
break;
default:
break;
}
- next = l->next;
+ next = FcValueListPtrU(l)->next;
+
FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
- free (l);
+ if (l.storage == FcStorageDynamic)
+ free(l.u.dyn);
}
}
case FcTypeDouble:
return va.u.d == vb.u.d;
case FcTypeString:
- return FcStrCmpIgnoreCase (va.u.s, vb.u.s) == 0;
+ return FcStrCmpIgnoreCase (FcObjectPtrU(va.u.si),
+ FcObjectPtrU(vb.u.si)) == 0;
case FcTypeBool:
return va.u.b == vb.u.b;
case FcTypeMatrix:
- return FcMatrixEqual (va.u.m, vb.u.m);
+ return FcMatrixEqual (FcMatrixPtrU(va.u.mi),
+ FcMatrixPtrU(vb.u.mi));
case FcTypeCharSet:
- return FcCharSetEqual (va.u.c, vb.u.c);
+ return FcCharSetEqual (FcCharSetPtrU(va.u.ci),
+ FcCharSetPtrU(vb.u.ci));
case FcTypeFTFace:
return va.u.f == vb.u.f;
case FcTypeLangSet:
- return FcLangSetEqual (va.u.l, vb.u.l);
+ return FcLangSetEqual (FcLangSetPtrU(va.u.li),
+ FcLangSetPtrU(vb.u.li));
}
return FcFalse;
}
case FcTypeDouble:
return FcDoubleHash (v.u.d);
case FcTypeString:
- return FcStringHash (v.u.s);
+ return FcStringHash (FcObjectPtrU(v.u.si));
case FcTypeBool:
return (FcChar32) v.u.b;
case FcTypeMatrix:
- return (FcDoubleHash (v.u.m->xx) ^
- FcDoubleHash (v.u.m->xy) ^
- FcDoubleHash (v.u.m->yx) ^
- FcDoubleHash (v.u.m->yy));
+ {
+ FcMatrix * m = FcMatrixPtrU(v.u.mi);
+ return (FcDoubleHash (m->xx) ^
+ FcDoubleHash (m->xy) ^
+ FcDoubleHash (m->yx) ^
+ FcDoubleHash (m->yy));
+ }
case FcTypeCharSet:
- return (FcChar32) v.u.c->num;
+ return (FcChar32) (FcCharSetPtrU(v.u.ci))->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 (v.u.l);
+ return FcLangSetHash (FcLangSetPtrU(v.u.li));
}
return FcFalse;
}
static FcBool
-FcValueListEqual (FcValueList *la, FcValueList *lb)
+FcValueListEqual (FcValueListPtr la, FcValueListPtr lb)
{
- if (la == lb)
+ if (FcValueListPtrU(la) == FcValueListPtrU(lb))
return FcTrue;
- while (la && lb)
+ while (FcValueListPtrU(la) && FcValueListPtrU(lb))
{
- if (!FcValueEqual (la->value, lb->value))
+ if (!FcValueEqual (FcValueListPtrU(la)->value,
+ FcValueListPtrU(lb)->value))
return FcFalse;
- la = la->next;
- lb = lb->next;
+ la = FcValueListPtrU(la)->next;
+ lb = FcValueListPtrU(lb)->next;
}
- if (la || lb)
+ if (FcValueListPtrU(la) || FcValueListPtrU(lb))
return FcFalse;
return FcTrue;
}
static FcChar32
-FcValueListHash (FcValueList *l)
+FcValueListHash (FcValueListPtr l)
{
FcChar32 hash = 0;
- while (l)
+ while (FcValueListPtrU(l))
{
- hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (l->value);
- l = l->next;
+ hash = ((hash << 1) | (hash >> 31)) ^
+ FcValueHash (FcValueListPtrU(l)->value);
+ l = FcValueListPtrU(l)->next;
}
return hash;
}
return;
for (i = 0; i < p->num; i++)
- FcValueListDestroy (p->elts[i].values);
+ FcValueListDestroy ((FcPatternEltU(p->elts)+i)->values);
p->num = 0;
- if (p->elts)
+ if (FcPatternEltU(p->elts) && FcPatternEltIsDynamic(p->elts))
{
FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
- free (p->elts);
- p->elts = 0;
+ free (FcPatternEltU(p->elts));
+ p->elts = FcPatternEltPtrCreateDynamic(0);
}
p->size = 0;
FcMemFree (FC_MEM_PATTERN, sizeof (FcPattern));
struct _FcValueListEnt {
FcValueListEnt *next;
- FcValueList *list;
+ FcValueListPtr list;
FcChar32 hash, pad;
};
}
static FcValueListEnt *
-FcValueListEntCreate (FcValueList *h)
+FcValueListEntCreate (FcValueListPtr h)
{
FcValueListAlign *ea;
FcValueListEnt *e;
- FcValueList *l, *new;
+ FcValueListPtr l;
+ FcValueList *new;
int n;
int size;
n = 0;
- for (l = h; l; l = l->next)
+ for (l = h; FcValueListPtrU(l); l = FcValueListPtrU(l)->next)
n++;
size = sizeof (FcValueListAlign) + n * sizeof (FcValueList);
- FcValueListFrozenCount[h->value.type]++;
- FcValueListFrozenBytes[h->value.type] += size;
- ea = malloc (size);
+ FcValueListFrozenCount[FcValueListPtrU(h)->value.type]++;
+ FcValueListFrozenBytes[FcValueListPtrU(h)->value.type] += size;
+ // this leaks for some reason
+ ea = malloc (sizeof (FcValueListAlign));
if (!ea)
return 0;
+ new = malloc (n * sizeof (FcValueList));
+ if (!new)
+ return 0;
+ memset(new, 0, n * sizeof (FcValueList));
FcMemAlloc (FC_MEM_VALLIST, size);
e = &ea->ent;
- e->list = (FcValueList *) (ea + 1);
- new = e->list;
- for (l = h; l; l = l->next, new++)
+ e->list = (FcValueListPtr) FcValueListPtrCreateDynamic(new);
+ for (l = h; FcValueListPtrU(l);
+ l = FcValueListPtrU(l)->next, new++)
{
- if (l->value.type == FcTypeString)
+ if (FcValueListPtrU(l)->value.type == FcTypeString)
{
new->value.type = FcTypeString;
- new->value.u.s = FcObjectStaticName (l->value.u.s);
+ new->value.u.si = FcObjectStaticName
+ (FcObjectPtrU(FcValueListPtrU(l)->value.u.si));
}
else
{
- new->value = FcValueSave (l->value);
+ new->value = FcValueSave (FcValueListPtrU(l)->value);
+ }
+ new->binding = FcValueListPtrU(l)->binding;
+ if (FcValueListPtrU(FcValueListPtrU(l)->next))
+ {
+ new->next = FcValueListPtrCreateDynamic(new + 1);
}
- new->binding = l->binding;
- if (l->next)
- new->next = new + 1;
else
- new->next = 0;
+ {
+ new->next = FcValueListPtrCreateDynamic(0);
+ }
}
return e;
}
static void
FcValueListEntDestroy (FcValueListEnt *e)
{
- FcValueList *l;
+ FcValueListPtr l;
- FcValueListFrozenCount[e->list->value.type]--;
+ FcValueListFrozenCount[FcValueListPtrU(e->list)->value.type]--;
/* XXX: We should perform these two operations with "size" as
computed in FcValueListEntCreate, but we don't have access to
FcMemFree (FC_MEM_VALLIST, size);
*/
- for (l = e->list; l; l = l->next)
+ for (l = e->list; FcValueListPtrU(l);
+ l = FcValueListPtrU(l)->next)
{
- if (l->value.type != FcTypeString)
- FcValueDestroy (l->value);
+ if (FcValueListPtrU(l)->value.type != FcTypeString)
+ FcValueDestroy (FcValueListPtrU(l)->value);
}
/* XXX: Are we being too chummy with the implementation here to
free(e) when it was actually the enclosing FcValueListAlign
static FcValueListEnt *FcValueListHashTable[FC_VALUE_LIST_HASH_SIZE];
-static FcValueList *
-FcValueListFreeze (FcValueList *l)
+static FcValueListPtr
+FcValueListFreeze (FcValueListPtr l)
{
FcChar32 hash = FcValueListHash (l);
FcValueListEnt **bucket = &FcValueListHashTable[hash % FC_VALUE_LIST_HASH_SIZE];
ent = FcValueListEntCreate (l);
if (!ent)
- return 0;
+ return FcValueListPtrCreateDynamic(0);
FcValueListUsed++;
ent->hash = hash;
int i;
for (i = 0; i < b->num; i++)
- hash = ((hash << 1) | (hash >> 31)) ^ ((long) b->elts[i].values);
+ hash = ((hash << 1) | (hash >> 31)) ^
+ (long) (FcValueListPtrU((FcPatternEltU(b->elts)+i)->values));
return hash;
}
struct _FcPatternEnt {
FcPatternEnt *next;
FcChar32 hash;
- FcPattern pattern;
+ FcPattern *pattern;
};
static int FcPatternTotal;
static FcPattern *
FcPatternBaseFreeze (FcPattern *b)
{
+ FcPattern *ep;
+ FcPatternElt *epp;
FcChar32 hash = FcPatternBaseHash (b);
FcPatternEnt **bucket = &FcPatternHashTable[hash % FC_VALUE_LIST_HASH_SIZE];
FcPatternEnt *ent;
int i;
- int size;
FcPatternTotal++;
for (ent = *bucket; ent; ent = ent->next)
{
- if (ent->hash == hash && b->num == ent->pattern.num)
- {
+ if (ent->hash == hash && b->num == ent->pattern->num)
+ {
for (i = 0; i < b->num; i++)
{
- if (b->elts[i].object != ent->pattern.elts[i].object)
+ if (FcObjectPtrCompare((FcPatternEltU(b->elts)+i)->object,
+ (FcPatternEltU(ent->pattern->elts)+i)->object) != 0)
break;
- if (b->elts[i].values != ent->pattern.elts[i].values)
+ if (FcValueListPtrU((FcPatternEltU(b->elts)+i)->values) !=
+ FcValueListPtrU((FcPatternEltU(ent->pattern->elts)+i)->values))
break;
}
if (i == b->num)
- return &ent->pattern;
+ return ent->pattern;
}
}
/*
* Compute size of pattern + elts
*/
- size = sizeof (FcPatternEnt) + b->num*sizeof (FcPatternElt);
- ent = malloc (size);
+ ent = malloc (sizeof (FcPatternEnt));
if (!ent)
return 0;
- FcMemAlloc (FC_MEM_PATTERN, size);
+ FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPatternEnt));
FcPatternUsed++;
- ent->pattern.elts = (FcPatternElt *) (ent + 1);
- ent->pattern.num = b->num;
- ent->pattern.size = b->num;
- ent->pattern.ref = FC_REF_CONSTANT;
+ ep = FcPatternCreate();
+ if (!ep)
+ return 0;
+ ent->pattern = ep;
+ epp = malloc(b->num * sizeof (FcPatternElt));
+ if (!epp)
+ goto bail;
+ ep->elts = FcPatternEltPtrCreateDynamic(epp);
+
+ FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt)*(b->num));
+
+ ep->num = b->num;
+ ep->size = b->num;
+ ep->ref = FC_REF_CONSTANT;
for (i = 0; i < b->num; i++)
{
- ent->pattern.elts[i].values = b->elts[i].values;
- ent->pattern.elts[i].object = b->elts[i].object;
+ (FcPatternEltU(ep->elts)+i)->values =
+ (FcPatternEltU(b->elts)+i)->values;
+ (FcPatternEltU(ep->elts)+i)->object =
+ (FcPatternEltU(b->elts)+i)->object;
}
ent->hash = hash;
ent->next = *bucket;
*bucket = ent;
- return &ent->pattern;
+ return ent->pattern;
+ bail:
+ free(ent);
+ FcMemFree (FC_MEM_PATTERN, sizeof (FcPatternEnt));
+ FcPatternUsed--;
+ return 0;
}
static void
FcPatternFreeze (FcPattern *p)
{
FcPattern *b, *n = 0;
- int size;
+ FcPatternElt *e;
int i;
if (p->ref == FC_REF_CONSTANT)
return p;
- size = sizeof (FcPattern) + p->num * sizeof (FcPatternElt);
- b = (FcPattern *) malloc (size);
+ b = FcPatternCreate();
if (!b)
- return 0;
- FcMemAlloc (FC_MEM_PATTERN, size);
+ return 0;
+
b->num = p->num;
b->size = b->num;
b->ref = 1;
- b->elts = (FcPatternElt *) (b + 1);
+
+ e = malloc(b->num * sizeof (FcPatternElt));
+ if (!e)
+ return 0;
+ b->elts = FcPatternEltPtrCreateDynamic(e);
+ FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt)*(b->num));
+
/*
* Freeze object lists
*/
for (i = 0; i < p->num; i++)
{
- b->elts[i].object = p->elts[i].object;
- b->elts[i].values = FcValueListFreeze (p->elts[i].values);
- if (!b->elts[i].values)
+ (FcPatternEltU(b->elts)+i)->object =
+ (FcPatternEltU(p->elts)+i)->object;
+ (FcPatternEltU(b->elts)+i)->values =
+ FcValueListFreeze((FcPatternEltU(p->elts)+i)->values);
+ if (!FcValueListPtrU((FcPatternEltU(p->elts)+i)->values))
goto bail;
}
/*
printf ("Patterns: total %9d used %9d\n", FcPatternTotal, FcPatternUsed);
}
#endif
-bail:
- free (b);
+ bail:
+ free(FcPatternEltU(b->elts));
+ b->elts = FcPatternEltPtrCreateDynamic(0);
+ FcMemFree (FC_MEM_PATELT, sizeof (FcPatternElt)*(b->num));
+ b->num = -1;
#ifdef DEBUG
assert (FcPatternEqual (n, p));
#endif
FcPatternPosition (const FcPattern *p, const char *object)
{
int low, high, mid, c;
+ FcObjectPtr obj;
- object = FcObjectStaticName(object);
+ obj = FcObjectStaticName(object);
low = 0;
high = p->num - 1;
c = 1;
while (low <= high)
{
mid = (low + high) >> 1;
- c = p->elts[mid].object - object;
+ c = FcObjectPtrCompare((FcPatternEltU(p->elts)+mid)->object, obj);
if (c == 0)
return mid;
if (c < 0)
int i = FcPatternPosition (p, object);
if (i < 0)
return 0;
- return &p->elts[i];
+ return FcPatternEltU(p->elts)+i;
}
FcPatternElt *
{
i = -i - 1;
- /* grow array */
+ /* reallocate array */
if (p->num + 1 >= p->size)
{
int s = p->size + 16;
- if (p->elts)
- e = (FcPatternElt *) realloc (p->elts, s * sizeof (FcPatternElt));
+ if (FcPatternEltU(p->elts))
+ {
+ FcPatternElt *e0 = FcPatternEltU(p->elts);
+ 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 = e;
+ p->elts = FcPatternEltPtrCreateDynamic(e);
if (p->size)
FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
FcMemAlloc (FC_MEM_PATELT, s * sizeof (FcPatternElt));
while (p->size < s)
{
- p->elts[p->size].object = 0;
- p->elts[p->size].values = 0;
+ (FcPatternEltU(p->elts)+p->size)->object = FcObjectPtrCreateDynamic(0);
+ (FcPatternEltU(p->elts)+p->size)->values =
+ FcValueListPtrCreateDynamic(0);
p->size++;
}
}
/* move elts up */
- memmove (p->elts + i + 1,
- p->elts + i,
+ memmove (FcPatternEltU(p->elts) + i + 1,
+ FcPatternEltU(p->elts) + i,
sizeof (FcPatternElt) *
(p->num - i));
/* bump count */
p->num++;
- p->elts[i].object = FcObjectStaticName (object);
- p->elts[i].values = 0;
+ (FcPatternEltU(p->elts)+i)->object = FcObjectStaticName (object);
+ (FcPatternEltU(p->elts)+i)->values = FcValueListPtrCreateDynamic(0);
}
- return &p->elts[i];
+ return FcPatternEltU(p->elts)+i;
}
FcBool
return FcFalse;
for (i = 0; i < pa->num; i++)
{
- if (pa->elts[i].object != pb->elts[i].object)
+ if (FcObjectPtrCompare((FcPatternEltU(pa->elts)+i)->object,
+ (FcPatternEltU(pb->elts)+i)->object) != 0)
return FcFalse;
- if (!FcValueListEqual (pa->elts[i].values, pb->elts[i].values))
+ if (!FcValueListEqual ((FcPatternEltU(pa->elts)+i)->values,
+ (FcPatternEltU(pb->elts)+i)->values))
return FcFalse;
}
return FcTrue;
for (i = 0; i < p->num; i++)
{
h = (((h << 1) | (h >> 31)) ^
- FcStringHash ((const FcChar8 *) p->elts[i].object) ^
- FcValueListHash (p->elts[i].values));
+ FcStringHash ((const FcChar8 *) FcObjectPtrU(((FcPatternEltU(p->elts)+i)->object))) ^
+ FcValueListHash ((FcPatternEltU(p->elts)+i)->values));
}
return h;
}
FcBool
-FcPatternEqualSubset (const FcPattern *pa, const FcPattern *pb, const FcObjectSet *os)
+FcPatternEqualSubset (const FcPattern *pai, const FcPattern *pbi, const FcObjectSet *os)
{
FcPatternElt *ea, *eb;
int i;
for (i = 0; i < os->nobject; i++)
{
- ea = FcPatternFindElt (pa, os->objects[i]);
- eb = FcPatternFindElt (pb, os->objects[i]);
+ ea = FcPatternFindElt (pai, FcObjectPtrU(os->objects[i]));
+ eb = FcPatternFindElt (pbi, FcObjectPtrU(os->objects[i]));
if (ea)
{
if (!eb)
FcBool append)
{
FcPatternElt *e;
- FcValueList *new, **prev;
+ FcValueListPtr new, *prev;
+ FcValueList * newp;
if (p->ref == FC_REF_CONSTANT)
goto bail0;
- new = (FcValueList *) malloc (sizeof (FcValueList));
- if (!new)
+ newp = malloc (sizeof (FcValueList));
+ if (!newp)
goto bail0;
+ memset(newp, 0, sizeof (FcValueList));
+ new = FcValueListPtrCreateDynamic(newp);
FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
/* dup string */
value = FcValueSave (value);
if (value.type == FcTypeVoid)
goto bail1;
- new->value = value;
- new->binding = binding;
- new->next = 0;
+ FcValueListPtrU(new)->value = value;
+ FcValueListPtrU(new)->binding = binding;
+ FcValueListPtrU(new)->next = FcValueListPtrCreateDynamic(0);
e = FcPatternInsertElt (p, object);
if (!e)
if (append)
{
- for (prev = &e->values; *prev; prev = &(*prev)->next);
+ for (prev = &e->values; FcValueListPtrU(*prev); prev = &FcValueListPtrU(*prev)->next)
+ ;
*prev = new;
}
else
{
- new->next = e->values;
+ FcValueListPtrU(new)->next = e->values;
e->values = new;
}
bail2:
switch (value.type) {
case FcTypeString:
- FcStrFree ((FcChar8 *) value.u.s);
+ FcStrFree ((FcChar8 *) FcObjectPtrU(value.u.si));
break;
case FcTypeMatrix:
- FcMatrixFree ((FcMatrix *) value.u.m);
+ FcMatrixFree (FcMatrixPtrU(value.u.mi));
break;
case FcTypeCharSet:
- FcCharSetDestroy ((FcCharSet *) value.u.c);
+ FcCharSetDestroy (FcCharSetPtrU(value.u.ci));
break;
case FcTypeLangSet:
- FcLangSetDestroy ((FcLangSet *) value.u.l);
+ FcLangSetDestroy (FcLangSetPtrU(value.u.li));
break;
default:
break;
}
bail1:
FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
- free (new);
+ free (FcValueListPtrU(new));
bail0:
return FcFalse;
}
FcPatternDel (FcPattern *p, const char *object)
{
FcPatternElt *e;
- int i;
e = FcPatternFindElt (p, object);
if (!e)
return FcFalse;
- i = e - p->elts;
-
/* destroy value */
FcValueListDestroy (e->values);
/* shuffle existing ones down */
- memmove (e, e+1, (p->elts + p->num - (e + 1)) * sizeof (FcPatternElt));
+ memmove (e, e+1,
+ (FcPatternEltU(p->elts) + p->num - (e + 1)) *
+ sizeof (FcPatternElt));
p->num--;
- p->elts[p->num].object = 0;
- p->elts[p->num].values = 0;
+ (FcPatternEltU(p->elts)+p->num)->object = FcObjectPtrCreateDynamic(0);
+ (FcPatternEltU(p->elts)+p->num)->values = FcValueListPtrCreateDynamic(0);
return FcTrue;
}
FcBool
FcPatternRemove (FcPattern *p, const char *object, int id)
{
- FcPatternElt *e;
- FcValueList **prev, *l;
+ FcPatternElt *e;
+ FcValueListPtr *prev, l;
e = FcPatternFindElt (p, object);
if (!e)
return FcFalse;
- for (prev = &e->values; (l = *prev); prev = &l->next)
+ for (prev = &e->values;
+ FcValueListPtrU(l = *prev);
+ prev = &FcValueListPtrU(l)->next)
{
if (!id)
{
- *prev = l->next;
- l->next = 0;
+ *prev = FcValueListPtrU(l)->next;
+ FcValueListPtrU(l)->next = FcValueListPtrCreateDynamic(0);
FcValueListDestroy (l);
- if (!e->values)
+ if (!FcValueListPtrU(e->values))
FcPatternDel (p, object);
return FcTrue;
}
FcValue v;
v.type = FcTypeString;
- v.u.s = s;
+ v.u.si = FcObjectPtrCreateDynamic(s);
return FcPatternAdd (p, object, v, FcTrue);
}
FcValue v;
v.type = FcTypeMatrix;
- v.u.m = (FcMatrix *) s;
+ v.u.mi = FcMatrixPtrCreateDynamic((FcMatrix *) s);
return FcPatternAdd (p, object, v, FcTrue);
}
FcValue v;
v.type = FcTypeCharSet;
- v.u.c = (FcCharSet *) c;
+ v.u.ci = FcCharSetPtrCreateDynamic((FcCharSet *)c);
return FcPatternAdd (p, object, v, FcTrue);
}
FcValue v;
v.type = FcTypeLangSet;
- v.u.l = (FcLangSet *) ls;
+ v.u.li = FcLangSetPtrCreateDynamic((FcLangSet *)ls);
return FcPatternAdd (p, object, v, FcTrue);
}
FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v)
{
FcPatternElt *e;
- FcValueList *l;
+ FcValueListPtr l;
e = FcPatternFindElt (p, object);
if (!e)
return FcResultNoMatch;
- for (l = e->values; l; l = l->next)
+ for (l = e->values; FcValueListPtrU(l); l = FcValueListPtrU(l)->next)
{
if (!id)
{
- *v = l->value;
+ *v = FcValueListPtrU(l)->value;
return FcResultMatch;
}
id--;
return r;
if (v.type != FcTypeString)
return FcResultTypeMismatch;
- *s = (FcChar8 *) v.u.s;
+ *s = (FcChar8 *) FcObjectPtrU(v.u.si);
return FcResultMatch;
}
return r;
if (v.type != FcTypeMatrix)
return FcResultTypeMismatch;
- *m = (FcMatrix *) v.u.m;
+ *m = FcMatrixPtrU(v.u.mi);
return FcResultMatch;
}
return r;
if (v.type != FcTypeCharSet)
return FcResultTypeMismatch;
- *c = (FcCharSet *) v.u.c;
+ *c = FcCharSetPtrU(v.u.ci);
return FcResultMatch;
}
return r;
if (v.type != FcTypeLangSet)
return FcResultTypeMismatch;
- *ls = (FcLangSet *) v.u.l;
+ *ls = FcLangSetPtrU(v.u.li);
return FcResultMatch;
}
FcPatternDuplicate (const FcPattern *orig)
{
FcPattern *new;
+ FcPatternElt *e;
int i;
- FcValueList *l;
+ FcValueListPtr l;
new = FcPatternCreate ();
if (!new)
goto bail0;
+ e = FcPatternEltU(orig->elts);
+
for (i = 0; i < orig->num; i++)
{
- for (l = orig->elts[i].values; l; l = l->next)
- if (!FcPatternAdd (new, orig->elts[i].object, l->value, FcTrue))
+ for (l = (e + i)->values;
+ FcValueListPtrU(l);
+ l = FcValueListPtrU(l)->next)
+ if (!FcPatternAdd (new, FcObjectPtrU((e + i)->object),
+ FcValueListPtrU(l)->value, FcTrue))
goto bail1;
}
{
int i;
FcPatternElt *e;
- FcValueList *v;
+ FcValueListPtr v;
for (i = 0; i < s->num; i++)
{
- e = &s->elts[i];
- for (v = e->values; v; v = v->next)
+ e = FcPatternEltU(s->elts)+i;
+ for (v = e->values; FcValueListPtrU(v);
+ v = FcValueListPtrU(v)->next)
{
- if (!FcPatternAddWithBinding (p, e->object,
- v->value, v->binding, FcTrue))
+ if (!FcPatternAddWithBinding (p, FcObjectPtrU(e->object),
+ FcValueListPtrU(v)->value,
+ FcValueListPtrU(v)->binding, FcTrue))
return FcFalse;
}
}
return FcTrue;
}
-const char *
+#define OBJECT_HASH_SIZE 31
+struct objectBucket {
+ struct objectBucket *next;
+ FcChar32 hash;
+};
+static struct objectBucket **buckets = 0;
+
+FcObjectPtr
FcObjectStaticName (const char *name)
{
-#define OBJECT_HASH_SIZE 31
- static struct objectBucket {
- struct objectBucket *next;
- FcChar32 hash;
- } *buckets[OBJECT_HASH_SIZE];
FcChar32 hash = FcStringHash ((const FcChar8 *) name);
struct objectBucket **p;
struct objectBucket *b;
+ const char * nn;
int size;
+ FcObjectPtr new;
+
+ if (!buckets)
+ {
+ buckets = malloc(sizeof (struct objectBucket *)*OBJECT_HASH_SIZE);
+ memset (buckets, 0, sizeof (struct objectBucket *)*OBJECT_HASH_SIZE);
+ }
for (p = &buckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
- if (b->hash == hash && !strcmp (name, (char *) (b + 1)))
- return (char *) (b + 1);
- size = sizeof (struct objectBucket) + strlen (name) + 1;
+ if (b->hash == hash && !strcmp (name, FcObjectPtrU(*((FcObjectPtr *) (b + 1)))))
+ return *((FcObjectPtr *) (b + 1));
+ size = sizeof (struct objectBucket) + sizeof (FcObjectPtr) + 1;
b = malloc (size);
FcMemAlloc (FC_MEM_STATICSTR, size);
if (!b)
- return NULL;
+ return FcObjectPtrCreateDynamic(0);
b->next = 0;
b->hash = hash;
- strcpy ((char *) (b + 1), name);
+ nn = malloc(strlen(name)+1);
+ if (!nn)
+ goto bail;
+ strcpy ((char *)nn, name);
+ new = FcObjectPtrCreateDynamic ((char *) nn);
+ *((FcObjectPtr *)(b+1)) = new;
*p = b;
- return (char *) (b + 1);
+ return new;
+
+ bail:
+ free(b);
+ return FcObjectPtrCreateDynamic(0);
+}
+
+FcPatternElt *
+FcPatternEltU (FcPatternEltPtr pei)
+{
+ switch (pei.storage)
+ {
+ case FcStorageStatic:
+ if (pei.u.stat == 0) return 0;
+ return &fcpatternelts[pei.u.stat];
+ case FcStorageDynamic:
+ return pei.u.dyn;
+ default:
+ return 0;
+ }
+}
+
+static FcPatternEltPtr
+FcPatternEltPtrCreateDynamic (FcPatternElt * e)
+{
+ FcPatternEltPtr new;
+ new.storage = FcStorageDynamic;
+ new.u.dyn = e;
+ return new;
+}
+
+static FcPatternEltPtr
+FcPatternEltPtrCreateStatic (int i)
+{
+ FcPatternEltPtr new;
+ new.storage = FcStorageStatic;
+ new.u.stat = i;
+ return new;
+}
+
+static FcBool
+FcPatternEltIsDynamic (FcPatternEltPtr pei)
+{
+ return pei.storage == FcStorageDynamic;
+}
+
+struct objectTree {
+ struct objectTree * left, * right;
+ char * s;
+};
+
+FcObjectPtr
+FcObjectPtrCreateDynamic (const char * s)
+{
+ FcObjectPtr new;
+ new.storage = FcStorageDynamic;
+ new.u.dyn = s;
+ if (s)
+ new.hash = FcStringHash(s);
+ else
+ new.hash = 0;
+ return new;
+}
+
+void
+FcObjectPtrDestroy (FcObjectPtr p)
+{
+ if (p.storage == FcStorageDynamic)
+ FcStrFree ((char *)p.u.dyn);
+}
+
+const char *
+FcObjectPtrU (FcObjectPtr si)
+{
+ switch (si.storage)
+ {
+ case FcStorageStatic:
+ if (si.u.stat == 0) return 0;
+ return &object_content[si.u.stat];
+ case FcStorageDynamic:
+ return si.u.dyn;
+ default:
+ return 0;
+ }
+}
+
+int
+FcObjectPtrCompare (const FcObjectPtr a, const FcObjectPtr b)
+{
+ int r = a.hash - b.hash;
+
+ if (r == 0)
+ return strcmp (FcObjectPtrU(a), FcObjectPtrU(b));
+ return r;
+}
+
+void
+FcObjectClearStatic(void)
+{
+ object_content = 0;
+ object_content_count = 0;
+ object_content_ptr = 0;
+}
+
+static FcObjectPtr
+FcObjectSerialize (FcObjectPtr si)
+{
+ struct objectBucket **p;
+ struct objectBucket *b;
+
+ if (!object_content)
+ {
+ object_content = malloc(object_content_count * sizeof(char));
+ if (!object_content)
+ return FcObjectPtrCreateDynamic(0);
+ }
+
+ if (!buckets)
+ return FcObjectPtrCreateDynamic(0);
+
+ for (p = &buckets[si.hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
+ if (b->hash == si.hash && !strcmp (FcObjectPtrU(si), FcObjectPtrU(*((FcObjectPtr *) (b + 1)))))
+ {
+ FcObjectPtr *op = (FcObjectPtr *) (b + 1);
+ if (op->storage == FcStorageStatic)
+ return *op;
+
+ if (object_content_ptr >= object_content_count)
+ return FcObjectPtrCreateDynamic(0);
+
+ strcpy (object_content+object_content_ptr,
+ FcObjectPtrU(si));
+
+ op->storage = FcStorageStatic;
+ op->u.stat = object_content_ptr;
+
+ object_content_ptr += strlen(FcObjectPtrU(si))+1;
+
+ return *op;
+ }
+
+ return FcObjectPtrCreateDynamic(0);
+}
+
+FcBool
+FcObjectPrepareSerialize (FcObjectPtr si)
+{
+ object_content_count += strlen(FcObjectPtrU(si)) + 1;
+ return FcTrue;
+}
+
+void
+FcPatternClearStatic (void)
+{
+ fcpatterns = 0;
+ fcpattern_ptr = 0;
+ fcpattern_count = 0;
+
+ fcpatternelts = 0;
+ fcpatternelt_ptr = 0;
+ fcpatternelt_count = 0;
+}
+
+void
+FcValueListClearStatic (void)
+{
+ fcvaluelists = 0;
+ fcvaluelist_ptr = 0;
+ fcvaluelist_count = 0;
+}
+
+FcBool
+FcPatternPrepareSerialize (FcPattern * p)
+{
+ int i;
+
+ fcpattern_count++;
+ fcpatternelt_count += p->num;
+
+ for (i = 0; i < p->num; i++)
+ {
+ FcObjectPrepareSerialize
+ ((FcPatternEltU(p->elts)+i)->object);
+ if (!FcValueListPrepareSerialize
+ (FcValueListPtrU(((FcPatternEltU(p->elts)+i)->values))))
+ return FcFalse;
+ }
+
+ return FcTrue;
+}
+
+FcBool
+FcValueListPrepareSerialize (FcValueList *p)
+{
+ FcValueList *vl;
+
+ for (vl = p;
+ vl;
+ vl = FcValueListPtrU(vl->next))
+ {
+ FcValue v = vl->value;
+
+ switch (v.type)
+ {
+ case FcTypeMatrix:
+ FcMatrixPrepareSerialize(FcMatrixPtrU(v.u.mi));
+ break;
+ case FcTypeCharSet:
+ FcCharSetPrepareSerialize(FcCharSetPtrU(v.u.ci));
+ break;
+ case FcTypeLangSet:
+ FcLangSetPrepareSerialize(FcLangSetPtrU(v.u.li));
+ break;
+ case FcTypeString:
+ FcObjectPrepareSerialize(v.u.si);
+ default:
+ break;
+ }
+ fcvaluelist_count++;
+ }
+
+ return FcTrue;
+}
+
+FcPattern *
+FcPatternSerialize (FcPattern *old)
+{
+ FcPattern *p;
+ FcPatternElt *e, *nep;
+ FcValueList * nv;
+ FcValueListPtr v, nv_head, nvp;
+ int i, elts;
+
+ if (!fcpatterns)
+ {
+ p = malloc (sizeof (FcPattern) * fcpattern_count);
+ if (!p)
+ goto bail;
+
+ FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern) * fcpattern_count);
+ fcpatterns = p;
+ fcpattern_ptr = 0;
+
+ e = malloc (sizeof (FcPatternElt) * fcpatternelt_count);
+ if (!e)
+ goto bail1;
+
+ FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt) * fcpatternelt_count);
+ fcpatternelts = e;
+ fcpatternelt_ptr = 0;
+ }
+
+ p = FcPatternCreate();
+ elts = fcpatternelt_ptr;
+ nep = &fcpatternelts[elts];
+ if (!nep)
+ return FcFalse;
+ fcpatternelt_ptr += old->num;
+
+ for (e = FcPatternEltU(old->elts), i=0; i < old->num; i++, e++)
+ {
+ v = e->values;
+ nvp = nv_head = FcValueListSerialize(FcValueListPtrU(v));
+ if (!FcValueListPtrU(nv_head))
+ goto bail2;
+ nv = FcValueListPtrU(nvp);
+
+ for (;
+ FcValueListPtrU(v);
+ v = FcValueListPtrU(v)->next,
+ nv = FcValueListPtrU(nv->next))
+ {
+
+ if (FcValueListPtrU(FcValueListPtrU(v)->next))
+ {
+ nvp = FcValueListSerialize
+ (FcValueListPtrU(FcValueListPtrU(v)->next));
+ nv->next = nvp;
+ }
+ }
+
+ nep[i].values = nv_head;
+ nep[i].object = FcObjectSerialize
+ (FcObjectStaticName(FcObjectPtrU(e->object)));
+ }
+
+ p->elts = FcPatternEltPtrCreateStatic(elts);
+ p->size = old->num;
+ p->ref = FC_REF_CONSTANT;
+ return p;
+
+ bail2:
+ free (fcpatternelts);
+ bail1:
+ free (fcpatterns);
+ bail:
+ return 0;
+ }
+
+FcValueListPtr
+FcValueListSerialize(FcValueList *pi)
+{
+ FcValueListPtr new;
+ FcValue * v;
+ FcValueList * vl;
+
+ if (!fcvaluelists)
+ {
+ vl = malloc (sizeof (FcValueList) * fcvaluelist_count);
+ if (!vl)
+ return FcValueListPtrCreateDynamic(0);
+
+ FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList) * fcvaluelist_count);
+ fcvaluelists = vl;
+ fcvaluelist_ptr = 0;
+ }
+
+ fcvaluelists[fcvaluelist_ptr] = *pi;
+ new.storage = FcStorageStatic;
+ new.u.stat = fcvaluelist_ptr++;
+ v = &fcvaluelists[new.u.stat].value;
+ switch (v->type)
+ {
+ case FcTypeString:
+ if (FcObjectPtrU(v->u.si))
+ {
+ FcObjectPtr si =
+ FcObjectSerialize(FcObjectStaticName(FcObjectPtrU(v->u.si)));
+ if (!FcObjectPtrU(v->u.si))
+ return FcValueListPtrCreateDynamic(pi);
+ v->u.si = si;
+ }
+ break;
+ case FcTypeMatrix:
+ if (FcMatrixPtrU(v->u.mi))
+ {
+ FcMatrixPtr mi = FcMatrixSerialize(FcMatrixPtrU(v->u.mi));
+
+ if (!FcMatrixPtrU(mi))
+ return FcValueListPtrCreateDynamic(pi);
+ v->u.mi = mi;
+ }
+ break;
+ case FcTypeCharSet:
+ if (FcCharSetPtrU(v->u.ci))
+ {
+ FcCharSetPtr ci = FcCharSetSerialize(FcCharSetPtrU(v->u.ci));
+ if (!FcCharSetPtrU(v->u.ci))
+ return FcValueListPtrCreateDynamic(pi);
+ v->u.ci = ci;
+ }
+ break;
+ case FcTypeLangSet:
+ if (FcLangSetPtrU(v->u.li))
+ {
+ FcLangSetPtr li = FcLangSetSerialize(FcLangSetPtrU(v->u.li));
+ if (!FcLangSetPtrU(v->u.li))
+ return FcValueListPtrCreateDynamic(pi);
+ v->u.li = li;
+ }
+ break;
+ default:
+ break;
+ }
+ return new;
+}
+
+FcValueList *
+FcValueListPtrU (FcValueListPtr pi)
+{
+ switch (pi.storage)
+ {
+ case FcStorageStatic:
+ if (pi.u.stat == 0) return 0;
+ return &fcvaluelists[pi.u.stat];
+ case FcStorageDynamic:
+ return pi.u.dyn;
+ default:
+ return 0;
+ }
+}
+
+FcValueListPtr
+FcValueListPtrCreateDynamic(FcValueList * p)
+{
+ FcValueListPtr r;
+
+ r.storage = FcStorageDynamic;
+ r.u.dyn = p;
+ return r;
}
set->ref = 1;
set->num = 0;
set->size = 0;
- set->strs = 0;
+ set->storage = FcStorageDynamic;
+ set->u.strs = 0;
return set;
}
+static FcChar8 * strset_buf = 0;
+static int strset_buf_ptr = 0, strset_buf_count = 0;
+static int * strset_idx = 0;
+static int strset_idx_ptr = 0, strset_idx_count = 0;
+static FcStrSet * strsets = 0;
+static int strset_ptr = 0, strset_count = 0;
+
+void FcStrSetClearStatic()
+{
+ strset_buf = 0; strset_buf_ptr = 0; strset_buf_count = 0;
+ strset_idx = 0; strset_idx_ptr = 0; strset_idx_count = 0;
+ strsets = 0; strset_ptr = 0; strset_count = 0;
+}
+
+FcChar8 *
+FcStrSetGet (const FcStrSet *set, int i)
+{
+ int index;
+ switch (set->storage)
+ {
+ case FcStorageStatic:
+ index = strset_idx[set->u.stridx_offset];
+ if (index == -1)
+ return 0;
+ return &strset_buf[index];
+ case FcStorageDynamic:
+ return set->u.strs[i];
+ default:
+ return 0;
+ }
+}
+
+FcStrSet *
+FcStrSetPtrU (const FcStrSetPtr set)
+{
+ switch (set.storage)
+ {
+ case FcStorageStatic:
+ return &strsets[set.u.stat];
+ case FcStorageDynamic:
+ return (FcStrSet *)set.u.dyn;
+ default:
+ return 0;
+ }
+}
+
+FcStrSetPtr
+FcStrSetPtrCreateDynamic (const FcStrSet * set)
+{
+ FcStrSetPtr new;
+
+ new.storage = FcStorageDynamic;
+ new.u.dyn = (FcStrSet *)set;
+ return new;
+}
+
static FcBool
_FcStrSetAppend (FcStrSet *set, FcChar8 *s)
{
FcStrFree (s);
return FcTrue;
}
- if (set->num == set->size)
+ if (set->num == set->size || set->storage == FcStorageStatic)
{
FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *));
return FcFalse;
FcMemAlloc (FC_MEM_STRSET, (set->size + 2) * sizeof (FcChar8 *));
set->size = set->size + 1;
- if (set->num)
- memcpy (strs, set->strs, set->num * sizeof (FcChar8 *));
- if (set->strs)
- free (set->strs);
- set->strs = strs;
- }
- set->strs[set->num++] = s;
- set->strs[set->num] = 0;
+ if (set->storage == FcStorageDynamic)
+ {
+ if (set->num)
+ memcpy (strs, set->u.strs, set->num * sizeof (FcChar8 *));
+ if (set->u.strs)
+ free (set->u.strs);
+ }
+ else
+ {
+ if (set->num)
+ memcpy (strs, strset_idx+set->u.stridx_offset,
+ set->num * sizeof (FcChar8 *));
+ set->storage = FcStorageDynamic;
+ }
+ set->u.strs = strs;
+ }
+ set->u.strs[set->num++] = s;
+ set->u.strs[set->num] = 0;
return FcTrue;
}
int i;
for (i = 0; i < set->num; i++)
- if (!FcStrCmp (set->strs[i], s))
+ if (!FcStrCmp (FcStrSetGet(set, i), s))
return FcTrue;
return FcFalse;
}
if (sa->num != sb->num)
return FcFalse;
for (i = 0; i < sa->num; i++)
- if (!FcStrSetMember (sb, sa->strs[i]))
+ if (!FcStrSetMember (sb, FcStrSetGet(sa, i)))
return FcFalse;
return FcTrue;
}
int i;
for (i = 0; i < set->num; i++)
- if (!FcStrCmp (set->strs[i], s))
+ if (!FcStrCmp (FcStrSetGet(set, i), s))
{
- FcStrFree (set->strs[i]);
+ if (set->storage == FcStorageDynamic)
+ FcStrFree (set->u.strs[i]);
/*
* copy remaining string pointers and trailing
* NULL
*/
- memmove (&set->strs[i], &set->strs[i+1],
+ memmove (FcStrSetGet(set, i), FcStrSetGet(set, i+1),
(set->num - i) * sizeof (FcChar8 *));
set->num--;
return FcTrue;
{
int i;
- for (i = 0; i < set->num; i++)
- FcStrFree (set->strs[i]);
- FcMemFree (FC_MEM_STRSET, (set->size) * sizeof (FcChar8 *));
- if (set->strs)
- free (set->strs);
- FcMemFree (FC_MEM_STRSET, sizeof (FcStrSet));
+ if (set->storage == FcStorageDynamic)
+ {
+ for (i = 0; i < set->num; i++)
+ FcStrFree (set->u.strs[i]);
+ FcMemFree (FC_MEM_STRSET, (set->size) * sizeof (FcChar8 *));
+ if (set->u.strs)
+ free (set->u.strs);
+ FcMemFree (FC_MEM_STRSET, sizeof (FcStrSet));
+ }
free (set);
}
}
+static int _FcStrSetSort_helper (const void * a, const void * b)
+{
+ return FcStrCmp (&strset_buf[(int)a],
+ &strset_buf[(int)b]);
+}
+
+void
+FcStrSetSort (FcStrSet * set)
+{
+ switch (set->storage)
+ {
+ case FcStorageDynamic:
+ qsort (set->u.strs, set->num, sizeof (FcChar8 *),
+ (int (*)(const void *, const void *)) FcStrCmp);
+ break;
+ case FcStorageStatic:
+ qsort (strset_idx+set->u.stridx_offset, set->num, sizeof (int),
+ _FcStrSetSort_helper);
+ break;
+ default:
+ break;
+ }
+}
+
+FcBool
+FcStrSetPrepareSerialize (const FcStrSet *set)
+{
+ int i;
+
+ if (!set)
+ return FcTrue;
+
+ strset_count ++;
+ strset_idx_count += set->num;
+ for (i = 0; i < set->num; i++)
+ {
+ if (FcStrSetGet(set, i))
+ strset_buf_count += strlen(FcStrSetGet(set, i));
+ }
+
+ return FcTrue;
+}
+
+FcStrSetPtr
+FcStrSetSerialize (FcStrSet *set)
+{
+ FcStrSet * new;
+ FcStrSetPtr newp;
+ int i;
+
+ if (!strsets)
+ {
+ strsets = malloc (strset_count * sizeof(FcStrSet));
+ if (!strsets) goto bail1;
+ strset_idx = malloc (strset_idx_count * sizeof(int));
+ if (!strset_idx) goto bail2;
+ strset_buf = malloc (strset_buf_count * sizeof (FcChar8));
+ if (!strset_buf) goto bail3;
+ }
+
+ if (!set)
+ return FcStrSetPtrCreateDynamic(0);
+
+ newp.storage = FcStorageStatic;
+ newp.u.stat = strset_ptr;
+
+ new = &strsets[strset_ptr++];
+ new->ref = set->ref;
+ new->num = set->num;
+ new->size = set->num;
+ new->storage = FcStorageStatic;
+ new->u.stridx_offset = strset_idx_ptr;
+ for (i = 0; i < set->num; i++)
+ {
+ FcChar8 * s = FcStrSetGet(set, i);
+
+ if (s)
+ {
+ memcpy(strset_buf+strset_buf_ptr, s,
+ strlen((char *)s));
+ strset_idx[strset_idx_ptr++] = strset_buf_ptr;
+ strset_buf_ptr += strlen((char *)s)+1;
+ }
+ else
+ strset_idx[strset_idx_ptr++] = -1;
+ }
+
+ if (strset_ptr > strset_count || strset_idx_ptr > strset_idx_count)
+ return FcStrSetPtrCreateDynamic(0);
+
+ // problem with multiple ptrs to the same LangSet.
+ // should hash LangSets or something.
+ // FcStrSetDestroy (set);
+
+ return newp;
+
+ bail3:
+ free (strset_idx);
+ bail2:
+ free (strsets);
+ bail1:
+ return FcStrSetPtrCreateDynamic(0);
+}
+
FcStrList *
FcStrListCreate (FcStrSet *set)
{
{
if (list->n >= list->set->num)
return 0;
- return list->set->strs[list->n++];
+ return FcStrSetGet(list->set, list->n++);
}
void
switch (vstack->tag) {
case FcVStackString:
- value.u.s = FcStrCopy (vstack->u.string);
- if (value.u.s)
+ value.u.si = FcObjectPtrCreateDynamic(FcStrCopy (vstack->u.string));
+ if (FcObjectPtrU(value.u.si))
value.type = FcTypeString;
break;
case FcVStackConstant:
value.type = FcTypeInteger;
break;
case FcVStackMatrix:
- value.u.m = FcMatrixCopy (vstack->u.matrix);
- if (value.u.m)
+ value.u.mi = FcMatrixPtrCreateDynamic(FcMatrixCopy (vstack->u.matrix));
+ if (FcMatrixPtrU(value.u.mi))
value.type = FcTypeMatrix;
break;
case FcVStackBool:
if (ret)
{
int i;
- qsort (files->strs, files->num, sizeof (FcChar8 *),
- (int (*)(const void *, const void *)) FcStrCmp);
+ FcStrSetSort (files);
for (i = 0; ret && i < files->num; i++)
- ret = FcConfigParseAndLoad (config, files->strs[i], complain);
+ ret = FcConfigParseAndLoad (config, FcStrSetGet(files, i), complain);
}
bail3:
FcStrSetDestroy (files);