2 * Copyright © 2000 Keith Packard
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the author(s) not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. The authors make no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
14 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
26 /* Objects MT-safe for readonly access. */
29 FcPatternCreate (void)
33 p = (FcPattern *) malloc (sizeof (FcPattern));
36 memset (p, 0, sizeof (FcPattern));
39 p->elts_offset = FcPtrToOffset (p, NULL);
40 FcRefInit (&p->ref, 1);
45 FcValueDestroy (FcValue v)
47 switch ((int) v.type) {
52 FcMatrixFree ((FcMatrix *) v.u.m);
55 FcCharSetDestroy ((FcCharSet *) v.u.c);
58 FcLangSetDestroy ((FcLangSet *) v.u.l);
61 FcRangeDestroy ((FcRange *) v.u.r);
69 FcValueCanonicalize (const FcValue *v)
73 switch ((int) v->type)
76 new.u.s = FcValueString(v);
77 new.type = FcTypeString;
80 new.u.c = FcValueCharSet(v);
81 new.type = FcTypeCharSet;
84 new.u.l = FcValueLangSet(v);
85 new.type = FcTypeLangSet;
88 new.u.r = FcValueRange(v);
89 new.type = FcTypeRange;
99 FcValueSave (FcValue v)
101 switch ((int) v.type) {
103 v.u.s = FcStrdup (v.u.s);
108 v.u.m = FcMatrixCopy (v.u.m);
113 v.u.c = FcCharSetCopy ((FcCharSet *) v.u.c);
118 v.u.l = FcLangSetCopy (v.u.l);
123 v.u.r = FcRangeCopy (v.u.r);
134 FcValueListCreate (void)
136 return calloc (1, sizeof (FcValueList));
140 FcValueListDestroy (FcValueListPtr l)
145 FcValueDestroy (l->value);
146 next = FcValueListNext(l);
152 FcValueListPrepend (FcValueListPtr vallist,
154 FcValueBinding binding)
158 if (value.type == FcTypeVoid)
160 new = FcValueListCreate ();
164 new->value = FcValueSave (value);
165 new->binding = binding;
172 FcValueListAppend (FcValueListPtr vallist,
174 FcValueBinding binding)
176 FcValueListPtr new, last;
178 if (value.type == FcTypeVoid)
180 new = FcValueListCreate ();
184 new->value = FcValueSave (value);
185 new->binding = binding;
190 for (last = vallist; FcValueListNext (last); last = FcValueListNext (last));
201 FcValueListDuplicate(FcValueListPtr orig)
203 FcValueListPtr new = NULL, l, t = NULL;
206 for (l = orig; l != NULL; l = FcValueListNext (l))
210 t = new = FcValueListCreate();
214 t->next = FcValueListCreate();
215 t = FcValueListNext (t);
217 v = FcValueCanonicalize (&l->value);
218 t->value = FcValueSave (v);
219 t->binding = l->binding;
227 FcValueEqual (FcValue va, FcValue vb)
229 if (va.type != vb.type)
231 if (va.type == FcTypeInteger)
233 va.type = FcTypeDouble;
236 if (vb.type == FcTypeInteger)
238 vb.type = FcTypeDouble;
241 if (va.type != vb.type)
246 return FcFalse; /* don't know how to compare this object */
250 return va.u.i == vb.u.i;
252 return va.u.d == vb.u.d;
254 return FcStrCmpIgnoreCase (va.u.s, vb.u.s) == 0;
256 return va.u.b == vb.u.b;
258 return FcMatrixEqual (va.u.m, vb.u.m);
260 return FcCharSetEqual (va.u.c, vb.u.c);
262 return va.u.f == vb.u.f;
264 return FcLangSetEqual (va.u.l, vb.u.l);
266 return FcRangeIsInRange (va.u.r, vb.u.r);
272 FcDoubleHash (double d)
282 FcStringHash (const FcChar8 *s)
289 h = ((h << 1) | (h >> 31)) ^ c;
294 FcValueHash (const FcValue *v)
301 return (FcChar32) v->u.i;
303 return FcDoubleHash (v->u.d);
305 return FcStringHash (FcValueString(v));
307 return (FcChar32) v->u.b;
309 return (FcDoubleHash (v->u.m->xx) ^
310 FcDoubleHash (v->u.m->xy) ^
311 FcDoubleHash (v->u.m->yx) ^
312 FcDoubleHash (v->u.m->yy));
314 return (FcChar32) FcValueCharSet(v)->num;
316 return FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->family_name) ^
317 FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->style_name);
319 return FcLangSetHash (FcValueLangSet(v));
321 return FcRangeHash (FcValueRange (v));
327 FcValueListEqual (FcValueListPtr la, FcValueListPtr lb)
334 if (!FcValueEqual (la->value, lb->value))
336 la = FcValueListNext(la);
337 lb = FcValueListNext(lb);
345 FcValueListHash (FcValueListPtr l)
349 for (; l; l = FcValueListNext(l))
351 hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (&l->value);
357 FcPatternGetCacheObject (FcPattern *p)
359 /* We use a value to find the cache, instead of the FcPattern object
360 * because the pattern itself may be a cache allocation if we rewrote the path,
361 * so the p may not be in the cached region. */
362 return FcPatternEltValues(&FcPatternElts (p)[0]);
366 FcPatternCacheRewriteFile (const FcPattern *p,
368 const FcChar8 *relocated_font_file)
370 FcPatternElt *elts = FcPatternElts (p);
374 FcPatternElt *new_elts;
375 FcValueList *new_value_list;
376 size_t new_path_len = strlen ((char *)relocated_font_file);
379 /* Allocate space for the patter, the PatternElt headers and
380 * the FC_FILE FcValueList and path that will be freed with the
382 data = FcCacheAllocate (cache,
384 p->num * sizeof (FcPatternElt) +
385 sizeof (FcValueList) +
388 new_p = (FcPattern *)data;
389 data += sizeof (FcPattern);
390 new_elts = (FcPatternElt *)(data);
391 data += p->num * sizeof (FcPatternElt);
392 new_value_list = (FcValueList *)data;
393 data += sizeof (FcValueList);
397 new_p->elts_offset = FcPtrToOffset (new_p, new_elts);
399 /* Copy all but the FILE values from the cache */
400 for (i = 0, j = 0; i < p->num; i++)
402 FcPatternElt *elt = &elts[i];
403 new_elts[j].object = elt->object;
404 if (elt->object != FC_FILE_OBJECT)
405 new_elts[j++].values = FcPatternEltValues(elt);
407 new_elts[j++].values = new_value_list;
410 new_value_list->next = NULL;
411 new_value_list->value.type = FcTypeString;
412 new_value_list->value.u.s = new_path;
413 new_value_list->binding = FcValueBindingWeak;
415 /* Add rewritten path at the end */
416 strcpy ((char *)new_path, (char *)relocated_font_file);
422 FcPatternDestroy (FcPattern *p)
430 if (FcRefIsConst (&p->ref))
432 FcCacheObjectDereference (FcPatternGetCacheObject(p));
436 if (FcRefDec (&p->ref) != 1)
439 elts = FcPatternElts (p);
440 for (i = 0; i < FcPatternObjectCount (p); i++)
441 FcValueListDestroy (FcPatternEltValues(&elts[i]));
448 FcPatternObjectCount (const FcPattern *pat)
458 FcPatternObjectPosition (const FcPattern *p, FcObject object)
460 int low, high, mid, c;
461 FcPatternElt *elts = FcPatternElts(p);
464 high = FcPatternObjectCount (p) - 1;
469 mid = (low + high) >> 1;
470 c = elts[mid].object - object;
484 FcPatternPosition (const FcPattern *p, const char *object)
486 return FcPatternObjectPosition (p, FcObjectFromName (object));
490 FcPatternObjectFindElt (const FcPattern *p, FcObject object)
492 int i = FcPatternObjectPosition (p, object);
495 return &FcPatternElts(p)[i];
499 FcPatternObjectInsertElt (FcPattern *p, FcObject object)
504 i = FcPatternObjectPosition (p, object);
509 /* reallocate array */
510 if (FcPatternObjectCount (p) + 1 >= p->size)
512 int s = p->size + 16;
515 FcPatternElt *e0 = FcPatternElts(p);
516 e = (FcPatternElt *) realloc (e0, s * sizeof (FcPatternElt));
517 if (!e) /* maybe it was mmapped */
519 e = malloc(s * sizeof (FcPatternElt));
521 memcpy(e, e0, FcPatternObjectCount (p) * sizeof (FcPatternElt));
525 e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt));
528 p->elts_offset = FcPtrToOffset (p, e);
531 e[p->size].object = 0;
532 e[p->size].values = NULL;
537 e = FcPatternElts(p);
541 sizeof (FcPatternElt) *
542 (FcPatternObjectCount (p) - i));
547 e[i].object = object;
551 return FcPatternElts(p) + i;
555 FcPatternEqual (const FcPattern *pa, const FcPattern *pb)
557 FcPatternIter ia, ib;
562 if (FcPatternObjectCount (pa) != FcPatternObjectCount (pb))
564 FcPatternIterStart (pa, &ia);
565 FcPatternIterStart (pb, &ib);
569 if (!FcPatternIterEqual (pa, &ia, pb, &ib))
571 ra = FcPatternIterNext (pa, &ia);
572 rb = FcPatternIterNext (pb, &ib);
581 FcPatternHash (const FcPattern *p)
585 FcPatternElt *pe = FcPatternElts(p);
587 for (i = 0; i < FcPatternObjectCount (p); i++)
589 h = (((h << 1) | (h >> 31)) ^
591 FcValueListHash (FcPatternEltValues(&pe[i])));
597 FcPatternEqualSubset (const FcPattern *pai, const FcPattern *pbi, const FcObjectSet *os)
599 FcPatternElt *ea, *eb;
602 for (i = 0; i < os->nobject; i++)
604 FcObject object = FcObjectFromName (os->objects[i]);
605 ea = FcPatternObjectFindElt (pai, object);
606 eb = FcPatternObjectFindElt (pbi, object);
611 if (!FcValueListEqual (FcPatternEltValues(ea), FcPatternEltValues(eb)))
624 FcPatternObjectListAdd (FcPattern *p,
630 FcValueListPtr l, *prev;
632 if (FcRefIsConst (&p->ref))
636 * Make sure the stored type is valid for built-in objects
638 for (l = list; l != NULL; l = FcValueListNext (l))
640 if (!FcObjectValidType (object, l->value.type))
643 "Fontconfig warning: FcPattern object %s does not accept value", FcObjectName (object));
644 FcValuePrintFile (stderr, l->value);
645 fprintf (stderr, "\n");
650 e = FcPatternObjectInsertElt (p, object);
656 for (prev = &e->values; *prev; prev = &(*prev)->next)
662 for (prev = &list; *prev; prev = &(*prev)->next)
675 FcPatternObjectAddWithBinding (FcPattern *p,
678 FcValueBinding binding,
682 FcValueListPtr new, *prev;
684 if (FcRefIsConst (&p->ref))
687 new = FcValueListCreate ();
691 new->value = FcValueSave (value);
692 new->binding = binding;
695 if (new->value.type == FcTypeVoid)
699 * Make sure the stored type is valid for built-in objects
701 if (!FcObjectValidType (object, new->value.type))
704 "Fontconfig warning: FcPattern object %s does not accept value",
705 FcObjectName (object));
706 FcValuePrintFile (stderr, new->value);
707 fprintf (stderr, "\n");
711 e = FcPatternObjectInsertElt (p, object);
717 for (prev = &e->values; *prev; prev = &(*prev)->next)
723 new->next = e->values;
730 FcValueListDestroy (new);
736 FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append)
738 return FcPatternObjectAddWithBinding (p, object,
739 value, FcValueBindingStrong, append);
743 FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append)
745 return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
746 value, FcValueBindingStrong, append);
750 FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append)
752 return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
753 value, FcValueBindingWeak, append);
757 FcPatternObjectDel (FcPattern *p, FcObject object)
761 e = FcPatternObjectFindElt (p, object);
766 FcValueListDestroy (e->values);
768 /* shuffle existing ones down */
770 (FcPatternElts(p) + FcPatternObjectCount (p) - (e + 1)) *
771 sizeof (FcPatternElt));
773 e = FcPatternElts(p) + FcPatternObjectCount (p);
780 FcPatternDel (FcPattern *p, const char *object)
782 return FcPatternObjectDel (p, FcObjectFromName (object));
786 FcPatternRemove (FcPattern *p, const char *object, int id)
789 FcValueListPtr *prev, l;
791 e = FcPatternObjectFindElt (p, FcObjectFromName (object));
794 for (prev = &e->values; (l = *prev); prev = &l->next)
800 FcValueListDestroy (l);
802 FcPatternDel (p, object);
811 FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i)
815 v.type = FcTypeInteger;
817 return FcPatternObjectAdd (p, object, v, FcTrue);
821 FcPatternAddInteger (FcPattern *p, const char *object, int i)
823 return FcPatternObjectAddInteger (p, FcObjectFromName (object), i);
827 FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d)
831 v.type = FcTypeDouble;
833 return FcPatternObjectAdd (p, object, v, FcTrue);
838 FcPatternAddDouble (FcPattern *p, const char *object, double d)
840 return FcPatternObjectAddDouble (p, FcObjectFromName (object), d);
844 FcPatternObjectAddString (FcPattern *p, FcObject object, const FcChar8 *s)
852 return FcPatternObjectAdd (p, object, v, FcTrue);
855 v.type = FcTypeString;
857 return FcPatternObjectAdd (p, object, v, FcTrue);
861 FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
863 return FcPatternObjectAddString (p, FcObjectFromName (object), s);
867 FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s)
871 v.type = FcTypeMatrix;
873 return FcPatternAdd (p, object, v, FcTrue);
878 FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b)
884 return FcPatternObjectAdd (p, object, v, FcTrue);
888 FcPatternAddBool (FcPattern *p, const char *object, FcBool b)
890 return FcPatternObjectAddBool (p, FcObjectFromName (object), b);
894 FcPatternObjectAddCharSet (FcPattern *p, FcObject object, const FcCharSet *c)
898 v.type = FcTypeCharSet;
899 v.u.c = (FcCharSet *)c;
900 return FcPatternObjectAdd (p, object, v, FcTrue);
904 FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c)
906 return FcPatternObjectAddCharSet (p, FcObjectFromName (object), c);
910 FcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f)
914 v.type = FcTypeFTFace;
916 return FcPatternAdd (p, object, v, FcTrue);
920 FcPatternObjectAddLangSet (FcPattern *p, FcObject object, const FcLangSet *ls)
924 v.type = FcTypeLangSet;
925 v.u.l = (FcLangSet *)ls;
926 return FcPatternObjectAdd (p, object, v, FcTrue);
930 FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls)
932 return FcPatternObjectAddLangSet (p, FcObjectFromName (object), ls);
936 FcPatternObjectAddRange (FcPattern *p, FcObject object, const FcRange *r)
940 v.type = FcTypeRange;
941 v.u.r = (FcRange *)r;
942 return FcPatternObjectAdd (p, object, v, FcTrue);
946 FcPatternAddRange (FcPattern *p, const char *object, const FcRange *r)
948 return FcPatternObjectAddRange (p, FcObjectFromName (object), r);
952 FcPatternObjectGetWithBinding (const FcPattern *p, FcObject object, int id, FcValue *v, FcValueBinding *b)
958 return FcResultNoMatch;
959 e = FcPatternObjectFindElt (p, object);
961 return FcResultNoMatch;
962 for (l = FcPatternEltValues(e); l; l = FcValueListNext(l))
966 *v = FcValueCanonicalize(&l->value);
969 return FcResultMatch;
977 FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v)
979 return FcPatternObjectGetWithBinding (p, object, id, v, NULL);
983 FcPatternGetWithBinding (const FcPattern *p, const char *object, int id, FcValue *v, FcValueBinding *b)
985 return FcPatternObjectGetWithBinding (p, FcObjectFromName (object), id, v, b);
989 FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v)
991 return FcPatternObjectGetWithBinding (p, FcObjectFromName (object), id, v, NULL);
995 FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int id, int *i)
1000 r = FcPatternObjectGet (p, object, id, &v);
1001 if (r != FcResultMatch)
1003 switch ((int) v.type) {
1011 return FcResultTypeMismatch;
1013 return FcResultMatch;
1017 FcPatternGetInteger (const FcPattern *p, const char *object, int id, int *i)
1019 return FcPatternObjectGetInteger (p, FcObjectFromName (object), id, i);
1024 FcPatternObjectGetDouble (const FcPattern *p, FcObject object, int id, double *d)
1029 r = FcPatternObjectGet (p, object, id, &v);
1030 if (r != FcResultMatch)
1032 switch ((int) v.type) {
1037 *d = (double) v.u.i;
1040 return FcResultTypeMismatch;
1042 return FcResultMatch;
1046 FcPatternGetDouble (const FcPattern *p, const char *object, int id, double *d)
1048 return FcPatternObjectGetDouble (p, FcObjectFromName (object), id, d);
1052 FcPatternObjectGetString (const FcPattern *p, FcObject object, int id, FcChar8 ** s)
1057 r = FcPatternObjectGet (p, object, id, &v);
1058 if (r != FcResultMatch)
1060 if (v.type != FcTypeString)
1061 return FcResultTypeMismatch;
1063 *s = (FcChar8 *) v.u.s;
1064 return FcResultMatch;
1068 FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s)
1070 return FcPatternObjectGetString (p, FcObjectFromName (object), id, s);
1074 FcPatternGetMatrix(const FcPattern *p, const char *object, int id, FcMatrix **m)
1079 r = FcPatternGet (p, object, id, &v);
1080 if (r != FcResultMatch)
1082 if (v.type != FcTypeMatrix)
1083 return FcResultTypeMismatch;
1084 *m = (FcMatrix *)v.u.m;
1085 return FcResultMatch;
1090 FcPatternObjectGetBool (const FcPattern *p, FcObject object, int id, FcBool *b)
1095 r = FcPatternObjectGet (p, object, id, &v);
1096 if (r != FcResultMatch)
1098 if (v.type != FcTypeBool)
1099 return FcResultTypeMismatch;
1101 return FcResultMatch;
1105 FcPatternGetBool(const FcPattern *p, const char *object, int id, FcBool *b)
1107 return FcPatternObjectGetBool (p, FcObjectFromName (object), id, b);
1111 FcPatternGetCharSet(const FcPattern *p, const char *object, int id, FcCharSet **c)
1116 r = FcPatternGet (p, object, id, &v);
1117 if (r != FcResultMatch)
1119 if (v.type != FcTypeCharSet)
1120 return FcResultTypeMismatch;
1121 *c = (FcCharSet *)v.u.c;
1122 return FcResultMatch;
1126 FcPatternGetFTFace(const FcPattern *p, const char *object, int id, FT_Face *f)
1131 r = FcPatternGet (p, object, id, &v);
1132 if (r != FcResultMatch)
1134 if (v.type != FcTypeFTFace)
1135 return FcResultTypeMismatch;
1136 *f = (FT_Face) v.u.f;
1137 return FcResultMatch;
1141 FcPatternGetLangSet(const FcPattern *p, const char *object, int id, FcLangSet **ls)
1146 r = FcPatternGet (p, object, id, &v);
1147 if (r != FcResultMatch)
1149 if (v.type != FcTypeLangSet)
1150 return FcResultTypeMismatch;
1151 *ls = (FcLangSet *)v.u.l;
1152 return FcResultMatch;
1156 FcPatternObjectGetRange (const FcPattern *p, FcObject object, int id, FcRange **r)
1161 res = FcPatternObjectGet (p, object, id, &v);
1162 if (res != FcResultMatch)
1164 switch ((int)v.type) {
1166 *r = (FcRange *)v.u.r;
1169 return FcResultTypeMismatch;
1171 return FcResultMatch;
1175 FcPatternGetRange (const FcPattern *p, const char *object, int id, FcRange **r)
1177 return FcPatternObjectGetRange (p, FcObjectFromName (object), id, r);
1181 FcPatternDuplicate (const FcPattern *orig)
1190 new = FcPatternCreate ();
1194 FcPatternIterStart (orig, &iter);
1197 for (l = FcPatternIterGetValues (orig, &iter); l; l = FcValueListNext (l))
1199 if (!FcPatternObjectAddWithBinding (new, FcPatternIterGetObjectId (orig, &iter),
1200 FcValueCanonicalize(&l->value),
1205 } while (FcPatternIterNext (orig, &iter));
1210 FcPatternDestroy (new);
1216 FcPatternReference (FcPattern *p)
1218 if (!FcRefIsConst (&p->ref))
1221 FcCacheObjectReference (FcPatternGetCacheObject(p));
1225 FcPatternVaBuild (FcPattern *p, va_list va)
1229 FcPatternVapBuild (ret, p, va);
1234 FcPatternBuild (FcPattern *p, ...)
1239 FcPatternVapBuild (p, p, va);
1245 * Add all of the elements in 's' to 'p'
1248 FcPatternAppend (FcPattern *p, FcPattern *s)
1253 FcPatternIterStart (s, &iter);
1256 for (v = FcPatternIterGetValues (s, &iter); v; v = FcValueListNext (v))
1258 if (!FcPatternObjectAddWithBinding (p, FcPatternIterGetObjectId (s, &iter),
1259 FcValueCanonicalize(&v->value),
1260 v->binding, FcTrue))
1263 } while (FcPatternIterNext (s, &iter));
1269 FcPatternFilter (FcPattern *p, const FcObjectSet *os)
1277 return FcPatternDuplicate (p);
1279 ret = FcPatternCreate ();
1283 for (i = 0; i < os->nobject; i++)
1285 FcObject object = FcObjectFromName (os->objects[i]);
1286 e = FcPatternObjectFindElt (p, object);
1289 for (v = FcPatternEltValues(e); v; v = FcValueListNext(v))
1291 if (!FcPatternObjectAddWithBinding (ret, e->object,
1292 FcValueCanonicalize(&v->value),
1293 v->binding, FcTrue))
1301 FcPatternDestroy (ret);
1305 typedef struct _FcPatternPrivateIter {
1308 } FcPatternPrivateIter;
1311 FcPatternIterSet (const FcPattern *pat, FcPatternPrivateIter *iter)
1313 iter->elt = FcPatternObjectCount (pat) > 0 && iter->pos < FcPatternObjectCount (pat) ? &FcPatternElts (pat)[iter->pos] : NULL;
1317 FcPatternIterStart (const FcPattern *pat, FcPatternIter *iter)
1319 FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
1322 FcPatternIterSet (pat, priv);
1326 FcPatternIterNext (const FcPattern *pat, FcPatternIter *iter)
1328 FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
1331 if (priv->pos >= FcPatternObjectCount (pat))
1333 FcPatternIterSet (pat, priv);
1339 FcPatternIterEqual (const FcPattern *p1, FcPatternIter *i1,
1340 const FcPattern *p2, FcPatternIter *i2)
1342 FcBool b1 = FcPatternIterIsValid (p1, i1);
1343 FcBool b2 = FcPatternIterIsValid (p2, i2);
1349 if (FcPatternIterGetObjectId (p1, i1) != FcPatternIterGetObjectId (p2, i2))
1352 return FcValueListEqual (FcPatternIterGetValues (p1, i1),
1353 FcPatternIterGetValues (p2, i2));
1357 FcPatternFindObjectIter (const FcPattern *pat, FcPatternIter *iter, FcObject object)
1359 FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
1360 int i = FcPatternObjectPosition (pat, object);
1367 FcPatternIterSet (pat, priv);
1373 FcPatternFindIter (const FcPattern *pat, FcPatternIter *iter, const char *object)
1375 return FcPatternFindObjectIter (pat, iter, FcObjectFromName (object));
1379 FcPatternIterIsValid (const FcPattern *pat, FcPatternIter *iter)
1381 FcPatternPrivateIter *priv = (FcPatternPrivateIter *)iter;
1383 if (priv && priv->elt)
1390 FcPatternIterGetObjectId (const FcPattern *pat, FcPatternIter *iter)
1392 FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
1394 if (priv && priv->elt)
1395 return priv->elt->object;
1401 FcPatternIterGetObject (const FcPattern *pat, FcPatternIter *iter)
1403 return FcObjectName (FcPatternIterGetObjectId (pat, iter));
1407 FcPatternIterGetValues (const FcPattern *pat, FcPatternIter *iter)
1409 FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
1411 if (priv && priv->elt)
1412 return FcPatternEltValues (priv->elt);
1418 FcPatternIterValueCount (const FcPattern *pat, FcPatternIter *iter)
1423 for (l = FcPatternIterGetValues (pat, iter); l; l = FcValueListNext (l))
1430 FcPatternIterGetValue (const FcPattern *pat, FcPatternIter *iter, int id, FcValue *v, FcValueBinding *b)
1434 for (l = FcPatternIterGetValues (pat, iter); l; l = FcValueListNext (l))
1438 *v = FcValueCanonicalize (&l->value);
1441 return FcResultMatch;
1445 return FcResultNoId;
1449 FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat)
1452 FcPatternElt *elts = FcPatternElts(pat);
1454 if (!FcSerializeAlloc (serialize, pat, sizeof (FcPattern)))
1456 if (!FcSerializeAlloc (serialize, elts, FcPatternObjectCount (pat) * sizeof (FcPatternElt)))
1458 for (i = 0; i < FcPatternObjectCount (pat); i++)
1459 if (!FcValueListSerializeAlloc (serialize, FcPatternEltValues(elts+i)))
1465 FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat)
1467 FcPattern *pat_serialized;
1468 FcPatternElt *elts = FcPatternElts (pat);
1469 FcPatternElt *elts_serialized;
1470 FcValueList *values_serialized;
1473 pat_serialized = FcSerializePtr (serialize, pat);
1474 if (!pat_serialized)
1476 *pat_serialized = *pat;
1477 pat_serialized->size = FcPatternObjectCount (pat);
1478 FcRefSetConst (&pat_serialized->ref);
1480 elts_serialized = FcSerializePtr (serialize, elts);
1481 if (!elts_serialized)
1484 pat_serialized->elts_offset = FcPtrToOffset (pat_serialized,
1487 for (i = 0; i < FcPatternObjectCount (pat); i++)
1489 values_serialized = FcValueListSerialize (serialize, FcPatternEltValues (elts+i));
1490 if (!values_serialized)
1492 elts_serialized[i].object = elts[i].object;
1493 elts_serialized[i].values = FcPtrToEncodedOffset (&elts_serialized[i],
1497 if (FcDebug() & FC_DBG_CACHEV) {
1498 printf ("Raw pattern:\n");
1499 FcPatternPrint (pat);
1500 printf ("Serialized pattern:\n");
1501 FcPatternPrint (pat_serialized);
1504 return pat_serialized;
1508 FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *vl)
1512 if (!FcSerializeAlloc (serialize, vl, sizeof (FcValueList)))
1514 switch ((int) vl->value.type) {
1516 if (!FcStrSerializeAlloc (serialize, vl->value.u.s))
1520 if (!FcCharSetSerializeAlloc (serialize, vl->value.u.c))
1524 if (!FcLangSetSerializeAlloc (serialize, vl->value.u.l))
1528 if (!FcRangeSerializeAlloc (serialize, vl->value.u.r))
1540 FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl)
1542 FcValueList *vl_serialized;
1543 FcChar8 *s_serialized;
1544 FcCharSet *c_serialized;
1545 FcLangSet *l_serialized;
1546 FcRange *r_serialized;
1547 FcValueList *head_serialized = NULL;
1548 FcValueList *prev_serialized = NULL;
1552 vl_serialized = FcSerializePtr (serialize, vl);
1556 if (prev_serialized)
1557 prev_serialized->next = FcPtrToEncodedOffset (prev_serialized,
1561 head_serialized = vl_serialized;
1563 vl_serialized->next = NULL;
1564 vl_serialized->value.type = vl->value.type;
1565 switch ((int) vl->value.type) {
1567 vl_serialized->value.u.i = vl->value.u.i;
1570 vl_serialized->value.u.d = vl->value.u.d;
1573 s_serialized = FcStrSerialize (serialize, vl->value.u.s);
1576 vl_serialized->value.u.s = FcPtrToEncodedOffset (&vl_serialized->value,
1581 vl_serialized->value.u.b = vl->value.u.b;
1587 c_serialized = FcCharSetSerialize (serialize, vl->value.u.c);
1590 vl_serialized->value.u.c = FcPtrToEncodedOffset (&vl_serialized->value,
1598 l_serialized = FcLangSetSerialize (serialize, vl->value.u.l);
1601 vl_serialized->value.u.l = FcPtrToEncodedOffset (&vl_serialized->value,
1606 r_serialized = FcRangeSerialize (serialize, vl->value.u.r);
1609 vl_serialized->value.u.r = FcPtrToEncodedOffset (&vl_serialized->value,
1616 prev_serialized = vl_serialized;
1619 return head_serialized;
1623 #include "fcaliastail.h"
1624 #include "fcftaliastail.h"