aboutsummaryrefslogtreecommitdiff
path: root/fontconfig
diff options
context:
space:
mode:
Diffstat (limited to 'fontconfig')
-rw-r--r--fontconfig/src/fcint.h22
-rw-r--r--fontconfig/src/fcmatch.c63
-rw-r--r--fontconfig/src/fcpat.c146
3 files changed, 210 insertions, 21 deletions
diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h
index c07857502..e9f315f6b 100644
--- a/fontconfig/src/fcint.h
+++ b/fontconfig/src/fcint.h
@@ -923,9 +923,25 @@ FcObjectFini (void);
FcPrivate FcValue
FcValueCanonicalize (const FcValue *v);
+FcPrivate FcValueListPtr
+FcValueListCreate (void);
+
FcPrivate void
FcValueListDestroy (FcValueListPtr l);
+FcPrivate FcValueListPtr
+FcValueListPrepend (FcValueListPtr vallist,
+ FcValue value,
+ FcValueBinding binding);
+
+FcPrivate FcValueListPtr
+FcValueListAppend (FcValueListPtr vallist,
+ FcValue value,
+ FcValueBinding binding);
+
+FcPrivate FcValueListPtr
+FcValueListDuplicate(FcValueListPtr orig);
+
FcPrivate FcPatternElt *
FcPatternObjectFindElt (const FcPattern *p, FcObject object);
@@ -933,6 +949,12 @@ FcPrivate FcPatternElt *
FcPatternObjectInsertElt (FcPattern *p, FcObject object);
FcPrivate FcBool
+FcPatternObjectListAdd (FcPattern *p,
+ FcObject object,
+ FcValueListPtr list,
+ FcBool append);
+
+FcPrivate FcBool
FcPatternObjectAddWithBinding (FcPattern *p,
FcObject object,
FcValue value,
diff --git a/fontconfig/src/fcmatch.c b/fontconfig/src/fcmatch.c
index 623538bd3..970339201 100644
--- a/fontconfig/src/fcmatch.c
+++ b/fontconfig/src/fcmatch.c
@@ -432,7 +432,7 @@ FcFontRenderPrepare (FcConfig *config,
FcPattern *new;
int i;
FcPatternElt *fe, *pe, *fel, *pel;
- FcValue v, vl;
+ FcValue v;
FcResult result;
assert (pat != NULL);
@@ -440,7 +440,7 @@ FcFontRenderPrepare (FcConfig *config,
new = FcPatternCreate ();
if (!new)
- return 0;
+ return NULL;
for (i = 0; i < font->num; i++)
{
fe = &FcPatternElts(font)[i];
@@ -478,47 +478,74 @@ FcFontRenderPrepare (FcConfig *config,
FcPatternEltValues(fe), &v, NULL, NULL, &result))
{
FcPatternDestroy (new);
- return 0;
+ return NULL;
}
if (fel && pel)
{
int n = 1, j;
+ FcValueListPtr l1, l2, ln = NULL, ll = NULL;
match = FcObjectToMatcher (pel->object, FcTrue);
if (!FcCompareValueList (pel->object, match,
FcPatternEltValues (pel),
- FcPatternEltValues (fel), &vl, NULL, &n, &result))
+ FcPatternEltValues (fel), NULL, NULL, &n, &result))
{
FcPatternDestroy (new);
return NULL;
}
- else
- {
- FcValueListPtr l;
- for (j = 0, l = FcPatternEltValues (fe);
- j < n && l != NULL;
- j++, l = FcValueListNext (l));
- if (l)
- v = FcValueCanonicalize (&l->value);
+ for (j = 0, l1 = FcPatternEltValues (fe), l2 = FcPatternEltValues (fel);
+ l1 != NULL || l2 != NULL;
+ j++, l1 = l1 ? FcValueListNext (l1) : NULL, l2 = l2 ? FcValueListNext (l2) : NULL)
+ {
+ if (j == n)
+ {
+ if (l1)
+ ln = FcValueListPrepend (ln,
+ FcValueCanonicalize (&l1->value),
+ FcValueBindingStrong);
+ if (l2)
+ ll = FcValueListPrepend (ll,
+ FcValueCanonicalize (&l2->value),
+ FcValueBindingStrong);
+ }
else
- v = FcValueCanonicalize (&FcPatternEltValues (fe)->value);
+ {
+ if (l1)
+ ln = FcValueListAppend (ln,
+ FcValueCanonicalize (&l1->value),
+ FcValueBindingStrong);
+ if (l2)
+ ll = FcValueListAppend (ll,
+ FcValueCanonicalize (&l2->value),
+ FcValueBindingStrong);
+ }
}
+ FcPatternObjectListAdd (new, fe->object, ln, FcFalse);
+ FcPatternObjectListAdd (new, fel->object, ll, FcFalse);
+
+ continue;
}
else if (fel)
{
- vl = FcValueCanonicalize (&FcPatternEltValues (fel)->value);
+ FcValueListPtr l1, l2;
+
+ copy_lang:
+ l1 = FcValueListDuplicate (FcPatternEltValues (fe));
+ l2 = FcValueListDuplicate (FcPatternEltValues (fel));
+ FcPatternObjectListAdd (new, fe->object, l1, FcFalse);
+ FcPatternObjectListAdd (new, fel->object, l2, FcFalse);
+
+ continue;
}
}
else
{
- v = FcValueCanonicalize(&FcPatternEltValues (fe)->value);
if (fel)
- vl = FcValueCanonicalize (&FcPatternEltValues (fel)->value);
+ goto copy_lang;
+ v = FcValueCanonicalize(&FcPatternEltValues (fe)->value);
}
FcPatternObjectAdd (new, fe->object, v, FcFalse);
- if (fel)
- FcPatternObjectAdd (new, fel->object, vl, FcFalse);
}
for (i = 0; i < pat->num; i++)
{
diff --git a/fontconfig/src/fcpat.c b/fontconfig/src/fcpat.c
index ebd6e57e2..62e47ca7e 100644
--- a/fontconfig/src/fcpat.c
+++ b/fontconfig/src/fcpat.c
@@ -120,6 +120,20 @@ FcValueSave (FcValue v)
return v;
}
+FcValueListPtr
+FcValueListCreate (void)
+{
+ FcValueListPtr ret;
+
+ ret = calloc (1, sizeof (FcValueList));
+ if (ret)
+ {
+ FcMemAlloc(FC_MEM_VALLIST, sizeof (FcValueList));
+ }
+
+ return ret;
+}
+
void
FcValueListDestroy (FcValueListPtr l)
{
@@ -151,6 +165,81 @@ FcValueListDestroy (FcValueListPtr l)
}
}
+FcValueListPtr
+FcValueListPrepend (FcValueListPtr vallist,
+ FcValue value,
+ FcValueBinding binding)
+{
+ FcValueListPtr new;
+
+ if (value.type == FcTypeVoid)
+ return vallist;
+ new = FcValueListCreate ();
+ if (!new)
+ return vallist;
+
+ new->value = FcValueSave (value);
+ new->binding = binding;
+ new->next = vallist;
+
+ return new;
+}
+
+FcValueListPtr
+FcValueListAppend (FcValueListPtr vallist,
+ FcValue value,
+ FcValueBinding binding)
+{
+ FcValueListPtr new, last;
+
+ if (value.type == FcTypeVoid)
+ return vallist;
+ new = FcValueListCreate ();
+ if (!new)
+ return vallist;
+
+ new->value = FcValueSave (value);
+ new->binding = binding;
+ new->next = NULL;
+
+ if (vallist)
+ {
+ for (last = vallist; FcValueListNext (last); last = FcValueListNext (last));
+
+ last->next = new;
+ }
+ else
+ vallist = new;
+
+ return vallist;
+}
+
+FcValueListPtr
+FcValueListDuplicate(FcValueListPtr orig)
+{
+ FcValueListPtr new = NULL, l, t = NULL;
+ FcValue v;
+
+ for (l = orig; l != NULL; l = FcValueListNext (l))
+ {
+ if (!new)
+ {
+ t = new = FcValueListCreate();
+ }
+ else
+ {
+ t->next = FcValueListCreate();
+ t = FcValueListNext (t);
+ }
+ v = FcValueCanonicalize (&l->value);
+ t->value = FcValueSave (v);
+ t->binding = l->binding;
+ t->next = NULL;
+ }
+
+ return new;
+}
+
FcBool
FcValueEqual (FcValue va, FcValue vb)
{
@@ -461,6 +550,59 @@ FcPatternEqualSubset (const FcPattern *pai, const FcPattern *pbi, const FcObject
}
FcBool
+FcPatternObjectListAdd (FcPattern *p,
+ FcObject object,
+ FcValueListPtr list,
+ FcBool append)
+{
+ FcPatternElt *e;
+ FcValueListPtr l, *prev;
+
+ if (p->ref == FC_REF_CONSTANT)
+ goto bail0;
+
+ /*
+ * Make sure the stored type is valid for built-in objects
+ */
+ for (l = list; l != NULL; l = FcValueListNext (l))
+ {
+ if (!FcObjectValidType (object, l->value.type))
+ {
+ if (FcDebug() & FC_DBG_OBJTYPES)
+ {
+ printf ("FcPattern object %s does not accept value ",
+ FcObjectName (object));
+ FcValuePrint (l->value);
+ }
+ goto bail0;
+ }
+ }
+
+ e = FcPatternObjectInsertElt (p, object);
+ if (!e)
+ goto bail0;
+
+ if (append)
+ {
+ for (prev = &e->values; *prev; prev = &(*prev)->next)
+ ;
+ *prev = list;
+ }
+ else
+ {
+ for (prev = &list; *prev; prev = &(*prev)->next)
+ ;
+ *prev = e->values;
+ e->values = list;
+ }
+
+ return FcTrue;
+
+bail0:
+ return FcFalse;
+}
+
+FcBool
FcPatternObjectAddWithBinding (FcPattern *p,
FcObject object,
FcValue value,
@@ -473,12 +615,10 @@ FcPatternObjectAddWithBinding (FcPattern *p,
if (p->ref == FC_REF_CONSTANT)
goto bail0;
- new = malloc (sizeof (FcValueList));
+ new = FcValueListCreate ();
if (!new)
goto bail0;
- memset(new, 0, sizeof (FcValueList));
- FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
value = FcValueSave (value);
if (value.type == FcTypeVoid)
goto bail1;