diff --git a/src/fcint.h b/src/fcint.h index c078575..e9f315f 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -923,15 +923,37 @@ 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); 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, diff --git a/src/fcmatch.c b/src/fcmatch.c index 623538b..9703392 100644 --- a/src/fcmatch.c +++ b/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/src/fcpat.c b/src/fcpat.c index ebd6e57..62e47ca 100644 --- a/src/fcpat.c +++ b/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) { @@ -460,6 +549,59 @@ FcPatternEqualSubset (const FcPattern *pai, const FcPattern *pbi, const FcObject return FcTrue; } +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, @@ -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;