diff options
author | Akira TAGOH <akira@tagoh.org> | 2018-05-11 20:48:30 +0900 |
---|---|---|
committer | Akira TAGOH <akira@tagoh.org> | 2018-05-11 20:48:30 +0900 |
commit | 307639cff143341cb10273db1a19264ba28b247e (patch) | |
tree | 9f081f59572d71640cb65aa7f71a60739d10d1bc /src/fcpat.c | |
parent | 454923709a1a1e480554c400e053aea9a1ba951a (diff) | |
download | fontconfig-307639cff143341cb10273db1a19264ba28b247e.tar.gz |
Bug 43367 - RFE: iterator to peek objects in FcPattern
Add various APIs to obtain things in FcPattern through the iterator
https://bugs.freedesktop.org/show_bug.cgi?id=43367
Diffstat (limited to 'src/fcpat.c')
-rw-r--r-- | src/fcpat.c | 233 |
1 files changed, 192 insertions, 41 deletions
diff --git a/src/fcpat.c b/src/fcpat.c index e624aea..eb534c3 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -392,13 +392,23 @@ FcPatternDestroy (FcPattern *p) return; elts = FcPatternElts (p); - for (i = 0; i < p->num; i++) + for (i = 0; i < FcPatternObjectCount (p); i++) FcValueListDestroy (FcPatternEltValues(&elts[i])); free (elts); free (p); } +int +FcPatternObjectCount (const FcPattern *pat) +{ + if (pat) + return pat->num; + + return 0; +} + + static int FcPatternObjectPosition (const FcPattern *p, FcObject object) { @@ -406,7 +416,7 @@ FcPatternObjectPosition (const FcPattern *p, FcObject object) FcPatternElt *elts = FcPatternElts(p); low = 0; - high = p->num - 1; + high = FcPatternObjectCount (p) - 1; c = 1; mid = 0; while (low <= high) @@ -452,7 +462,7 @@ FcPatternObjectInsertElt (FcPattern *p, FcObject object) i = -i - 1; /* reallocate array */ - if (p->num + 1 >= p->size) + if (FcPatternObjectCount (p) + 1 >= p->size) { int s = p->size + 16; if (p->size) @@ -463,7 +473,7 @@ FcPatternObjectInsertElt (FcPattern *p, FcObject object) { e = malloc(s * sizeof (FcPatternElt)); if (e) - memcpy(e, e0, p->num * sizeof (FcPatternElt)); + memcpy(e, e0, FcPatternObjectCount (p) * sizeof (FcPatternElt)); } } else @@ -484,7 +494,7 @@ FcPatternObjectInsertElt (FcPattern *p, FcObject object) memmove (e + i + 1, e + i, sizeof (FcPatternElt) * - (p->num - i)); + (FcPatternObjectCount (p) - i)); /* bump count */ p->num++; @@ -499,24 +509,26 @@ FcPatternObjectInsertElt (FcPattern *p, FcObject object) FcBool FcPatternEqual (const FcPattern *pa, const FcPattern *pb) { - int i; - FcPatternElt *pae, *pbe; + FcPatternIter ia, ib; if (pa == pb) return FcTrue; - if (pa->num != pb->num) + if (FcPatternObjectCount (pa) != FcPatternObjectCount (pb)) return FcFalse; - pae = FcPatternElts(pa); - pbe = FcPatternElts(pb); - for (i = 0; i < pa->num; i++) - { - if (pae[i].object != pbe[i].object) - return FcFalse; - if (!FcValueListEqual (FcPatternEltValues(&pae[i]), - FcPatternEltValues(&pbe[i]))) + FcPatternIterStart (pa, &ia); + FcPatternIterStart (pb, &ib); + do { + FcBool ra, rb; + + if (!FcPatternIterEqual (pa, &ia, pb, &ib)) return FcFalse; - } + ra = FcPatternIterNext (pa, &ia); + rb = FcPatternIterNext (pb, &ib); + if (!ra && !rb) + break; + } while (1); + return FcTrue; } @@ -527,7 +539,7 @@ FcPatternHash (const FcPattern *p) FcChar32 h = 0; FcPatternElt *pe = FcPatternElts(p); - for (i = 0; i < p->num; i++) + for (i = 0; i < FcPatternObjectCount (p); i++) { h = (((h << 1) | (h >> 31)) ^ pe[i].object ^ @@ -713,10 +725,10 @@ FcPatternObjectDel (FcPattern *p, FcObject object) /* shuffle existing ones down */ memmove (e, e+1, - (FcPatternElts(p) + p->num - (e + 1)) * + (FcPatternElts(p) + FcPatternObjectCount (p) - (e + 1)) * sizeof (FcPatternElt)); p->num--; - e = FcPatternElts(p) + p->num; + e = FcPatternElts(p) + FcPatternObjectCount (p); e->object = 0; e->values = NULL; return FcTrue; @@ -1115,8 +1127,7 @@ FcPattern * FcPatternDuplicate (const FcPattern *orig) { FcPattern *new; - FcPatternElt *e; - int i; + FcPatternIter iter; FcValueListPtr l; if (!orig) @@ -1126,20 +1137,18 @@ FcPatternDuplicate (const FcPattern *orig) if (!new) goto bail0; - e = FcPatternElts(orig); - - for (i = 0; i < orig->num; i++) + FcPatternIterStart (orig, &iter); + do { - for (l = FcPatternEltValues(e + i); l; l = FcValueListNext(l)) + for (l = FcPatternIterGetValues (orig, &iter); l; l = FcValueListNext (l)) { - if (!FcPatternObjectAddWithBinding (new, e[i].object, + if (!FcPatternObjectAddWithBinding (new, FcPatternIterGetObjectId (orig, &iter), FcValueCanonicalize(&l->value), l->binding, FcTrue)) goto bail1; - } - } + } while (FcPatternIterNext (orig, &iter)); return new; @@ -1184,21 +1193,21 @@ FcPatternBuild (FcPattern *p, ...) FcBool FcPatternAppend (FcPattern *p, FcPattern *s) { - int i; - FcPatternElt *e; - FcValueListPtr v; + FcPatternIter iter; + FcValueListPtr v; - for (i = 0; i < s->num; i++) + FcPatternIterStart (s, &iter); + do { - e = FcPatternElts(s)+i; - for (v = FcPatternEltValues(e); v; v = FcValueListNext(v)) + for (v = FcPatternIterGetValues (s, &iter); v; v = FcValueListNext (v)) { - if (!FcPatternObjectAddWithBinding (p, e->object, + if (!FcPatternObjectAddWithBinding (p, FcPatternIterGetObjectId (s, &iter), FcValueCanonicalize(&v->value), v->binding, FcTrue)) return FcFalse; } - } + } while (FcPatternIterNext (s, &iter)); + return FcTrue; } @@ -1239,6 +1248,148 @@ bail0: return NULL; } +typedef struct _FcPatternPrivateIter { + FcPatternElt *elt; + int pos; +} FcPatternPrivateIter; + +static void +FcPatternIterSet (const FcPattern *pat, FcPatternPrivateIter *iter) +{ + iter->elt = FcPatternObjectCount (pat) > 0 && iter->pos < FcPatternObjectCount (pat) ? &FcPatternElts (pat)[iter->pos] : NULL; +} + +void +FcPatternIterStart (const FcPattern *pat, FcPatternIter *iter) +{ + FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter; + + priv->pos = 0; + FcPatternIterSet (pat, priv); +} + +FcBool +FcPatternIterNext (const FcPattern *pat, FcPatternIter *iter) +{ + FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter; + + priv->pos++; + if (priv->pos >= FcPatternObjectCount (pat)) + return FcFalse; + FcPatternIterSet (pat, priv); + + return FcTrue; +} + +FcBool +FcPatternIterEqual (const FcPattern *p1, FcPatternIter *i1, + const FcPattern *p2, FcPatternIter *i2) +{ + FcBool b1 = FcPatternIterIsValid (p1, i1); + FcBool b2 = FcPatternIterIsValid (p2, i2); + + if (!i1 && !i2) + return FcTrue; + if (!b1 || !b2) + return FcFalse; + if (FcPatternIterGetObjectId (p1, i1) != FcPatternIterGetObjectId (p2, i2)) + return FcFalse; + + return FcValueListEqual (FcPatternIterGetValues (p1, i1), + FcPatternIterGetValues (p2, i2)); +} + +FcBool +FcPatternFindObjectIter (const FcPattern *pat, FcPatternIter *iter, FcObject object) +{ + FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter; + int i = FcPatternObjectPosition (pat, object); + + priv->elt = NULL; + if (i < 0) + return FcFalse; + + priv->pos = i; + FcPatternIterSet (pat, priv); + + return FcTrue; +} + +FcBool +FcPatternFindIter (const FcPattern *pat, FcPatternIter *iter, const char *object) +{ + return FcPatternFindObjectIter (pat, iter, FcObjectFromName (object)); +} + +FcBool +FcPatternIterIsValid (const FcPattern *pat, FcPatternIter *iter) +{ + FcPatternPrivateIter *priv = (FcPatternPrivateIter *)iter; + + if (priv && priv->elt) + return FcTrue; + + return FcFalse; +} + +FcObject +FcPatternIterGetObjectId (const FcPattern *pat, FcPatternIter *iter) +{ + FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter; + + if (priv && priv->elt) + return priv->elt->object; + + return 0; +} + +const char * +FcPatternIterGetObject (const FcPattern *pat, FcPatternIter *iter) +{ + return FcObjectName (FcPatternIterGetObjectId (pat, iter)); +} + +FcValueListPtr +FcPatternIterGetValues (const FcPattern *pat, FcPatternIter *iter) +{ + FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter; + + if (priv && priv->elt) + return FcPatternEltValues (priv->elt); + + return NULL; +} + +int +FcPatternIterValueCount (const FcPattern *pat, FcPatternIter *iter) +{ + int count = 0; + FcValueListPtr l; + + for (l = FcPatternIterGetValues (pat, iter); l; l = FcValueListNext (l)) + count++; + + return count; +} + +FcResult +FcPatternIterGetValue (const FcPattern *pat, FcPatternIter *iter, int id, FcValue *v, FcValueBinding *b) +{ + FcValueListPtr l; + + for (l = FcPatternIterGetValues (pat, iter); l; l = FcValueListNext (l)) + { + if (id == 0) + { + *v = FcValueCanonicalize (&l->value); + if (b) + *b = l->binding; + return FcResultMatch; + } + id--; + } + return FcResultNoId; +} FcBool FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat) @@ -1248,9 +1399,9 @@ FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat) if (!FcSerializeAlloc (serialize, pat, sizeof (FcPattern))) return FcFalse; - if (!FcSerializeAlloc (serialize, elts, pat->num * sizeof (FcPatternElt))) + if (!FcSerializeAlloc (serialize, elts, FcPatternObjectCount (pat) * sizeof (FcPatternElt))) return FcFalse; - for (i = 0; i < pat->num; i++) + for (i = 0; i < FcPatternObjectCount (pat); i++) if (!FcValueListSerializeAlloc (serialize, FcPatternEltValues(elts+i))) return FcFalse; return FcTrue; @@ -1269,7 +1420,7 @@ FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat) if (!pat_serialized) return NULL; *pat_serialized = *pat; - pat_serialized->size = pat->num; + pat_serialized->size = FcPatternObjectCount (pat); FcRefSetConst (&pat_serialized->ref); elts_serialized = FcSerializePtr (serialize, elts); @@ -1279,7 +1430,7 @@ FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat) pat_serialized->elts_offset = FcPtrToOffset (pat_serialized, elts_serialized); - for (i = 0; i < pat->num; i++) + for (i = 0; i < FcPatternObjectCount (pat); i++) { values_serialized = FcValueListSerialize (serialize, FcPatternEltValues (elts+i)); if (!values_serialized) |