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 switch ((int) l->value.type) {
147 FcFree (l->value.u.s);
150 FcMatrixFree ((FcMatrix *)l->value.u.m);
154 ((FcCharSet *) (l->value.u.c));
158 ((FcLangSet *) (l->value.u.l));
161 FcRangeDestroy ((FcRange *) (l->value.u.r));
166 next = FcValueListNext(l);
172 FcValueListPrepend (FcValueListPtr vallist,
174 FcValueBinding binding)
178 if (value.type == FcTypeVoid)
180 new = FcValueListCreate ();
184 new->value = FcValueSave (value);
185 new->binding = binding;
192 FcValueListAppend (FcValueListPtr vallist,
194 FcValueBinding binding)
196 FcValueListPtr new, last;
198 if (value.type == FcTypeVoid)
200 new = FcValueListCreate ();
204 new->value = FcValueSave (value);
205 new->binding = binding;
210 for (last = vallist; FcValueListNext (last); last = FcValueListNext (last));
221 FcValueListDuplicate(FcValueListPtr orig)
223 FcValueListPtr new = NULL, l, t = NULL;
226 for (l = orig; l != NULL; l = FcValueListNext (l))
230 t = new = FcValueListCreate();
234 t->next = FcValueListCreate();
235 t = FcValueListNext (t);
237 v = FcValueCanonicalize (&l->value);
238 t->value = FcValueSave (v);
239 t->binding = l->binding;
247 FcValueEqual (FcValue va, FcValue vb)
249 if (va.type != vb.type)
251 if (va.type == FcTypeInteger)
253 va.type = FcTypeDouble;
256 if (vb.type == FcTypeInteger)
258 vb.type = FcTypeDouble;
261 if (va.type != vb.type)
266 return FcFalse; /* don't know how to compare this object */
270 return va.u.i == vb.u.i;
272 return va.u.d == vb.u.d;
274 return FcStrCmpIgnoreCase (va.u.s, vb.u.s) == 0;
276 return va.u.b == vb.u.b;
278 return FcMatrixEqual (va.u.m, vb.u.m);
280 return FcCharSetEqual (va.u.c, vb.u.c);
282 return va.u.f == vb.u.f;
284 return FcLangSetEqual (va.u.l, vb.u.l);
286 return FcRangeIsInRange (va.u.r, vb.u.r);
292 FcDoubleHash (double d)
302 FcStringHash (const FcChar8 *s)
309 h = ((h << 1) | (h >> 31)) ^ c;
314 FcValueHash (const FcValue *v)
321 return (FcChar32) v->u.i;
323 return FcDoubleHash (v->u.d);
325 return FcStringHash (FcValueString(v));
327 return (FcChar32) v->u.b;
329 return (FcDoubleHash (v->u.m->xx) ^
330 FcDoubleHash (v->u.m->xy) ^
331 FcDoubleHash (v->u.m->yx) ^
332 FcDoubleHash (v->u.m->yy));
334 return (FcChar32) FcValueCharSet(v)->num;
336 return FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->family_name) ^
337 FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->style_name);
339 return FcLangSetHash (FcValueLangSet(v));
341 return FcRangeHash (v->u.r);
347 FcValueListEqual (FcValueListPtr la, FcValueListPtr lb)
354 if (!FcValueEqual (la->value, lb->value))
356 la = FcValueListNext(la);
357 lb = FcValueListNext(lb);
365 FcValueListHash (FcValueListPtr l)
369 for (; l; l = FcValueListNext(l))
371 hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (&l->value);
377 FcPatternGetCacheObject (FcPattern *p)
379 /* We use a value to find the cache, instead of the FcPattern object
380 * because the pattern itself may be a cache allocation if we rewrote the path,
381 * so the p may not be in the cached region. */
382 return FcPatternEltValues(&FcPatternElts (p)[0]);
386 FcPatternCacheRewriteFile (const FcPattern *p,
388 const FcChar8 *relocated_font_file)
390 FcPatternElt *elts = FcPatternElts (p);
394 FcPatternElt *new_elts;
395 FcValueList *new_value_list;
396 size_t new_path_len = strlen ((char *)relocated_font_file);
399 /* Allocate space for the patter, the PatternElt headers and
400 * the FC_FILE FcValueList and path that will be freed with the
402 data = FcCacheAllocate (cache,
404 p->num * sizeof (FcPatternElt) +
405 sizeof (FcValueList) +
408 new_p = (FcPattern *)data;
409 data += sizeof (FcPattern);
410 new_elts = (FcPatternElt *)(data);
411 data += p->num * sizeof (FcPatternElt);
412 new_value_list = (FcValueList *)data;
413 data += sizeof (FcValueList);
417 new_p->elts_offset = FcPtrToOffset (new_p, new_elts);
419 /* Copy all but the FILE values from the cache */
420 for (i = 0, j = 0; i < p->num; i++)
422 FcPatternElt *elt = &elts[i];
423 new_elts[j].object = elt->object;
424 if (elt->object != FC_FILE_OBJECT)
425 new_elts[j++].values = FcPatternEltValues(elt);
427 new_elts[j++].values = new_value_list;
430 new_value_list->next = NULL;
431 new_value_list->value.type = FcTypeString;
432 new_value_list->value.u.s = new_path;
433 new_value_list->binding = FcValueBindingWeak;
435 /* Add rewritten path at the end */
436 strcpy ((char *)new_path, (char *)relocated_font_file);
442 FcPatternDestroy (FcPattern *p)
450 if (FcRefIsConst (&p->ref))
452 FcCacheObjectDereference (FcPatternGetCacheObject(p));
456 if (FcRefDec (&p->ref) != 1)
459 elts = FcPatternElts (p);
460 for (i = 0; i < FcPatternObjectCount (p); i++)
461 FcValueListDestroy (FcPatternEltValues(&elts[i]));
468 FcPatternObjectCount (const FcPattern *pat)
478 FcPatternObjectPosition (const FcPattern *p, FcObject object)
480 int low, high, mid, c;
481 FcPatternElt *elts = FcPatternElts(p);
484 high = FcPatternObjectCount (p) - 1;
489 mid = (low + high) >> 1;
490 c = elts[mid].object - object;
504 FcPatternPosition (const FcPattern *p, const char *object)
506 return FcPatternObjectPosition (p, FcObjectFromName (object));
510 FcPatternObjectFindElt (const FcPattern *p, FcObject object)
512 int i = FcPatternObjectPosition (p, object);
515 return &FcPatternElts(p)[i];
519 FcPatternObjectInsertElt (FcPattern *p, FcObject object)
524 i = FcPatternObjectPosition (p, object);
529 /* reallocate array */
530 if (FcPatternObjectCount (p) + 1 >= p->size)
532 int s = p->size + 16;
535 FcPatternElt *e0 = FcPatternElts(p);
536 e = (FcPatternElt *) realloc (e0, s * sizeof (FcPatternElt));
537 if (!e) /* maybe it was mmapped */
539 e = malloc(s * sizeof (FcPatternElt));
541 memcpy(e, e0, FcPatternObjectCount (p) * sizeof (FcPatternElt));
545 e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt));
548 p->elts_offset = FcPtrToOffset (p, e);
551 e[p->size].object = 0;
552 e[p->size].values = NULL;
557 e = FcPatternElts(p);
561 sizeof (FcPatternElt) *
562 (FcPatternObjectCount (p) - i));
567 e[i].object = object;
571 return FcPatternElts(p) + i;
575 FcPatternEqual (const FcPattern *pa, const FcPattern *pb)
577 FcPatternIter ia, ib;
582 if (FcPatternObjectCount (pa) != FcPatternObjectCount (pb))
584 FcPatternIterStart (pa, &ia);
585 FcPatternIterStart (pb, &ib);
589 if (!FcPatternIterEqual (pa, &ia, pb, &ib))
591 ra = FcPatternIterNext (pa, &ia);
592 rb = FcPatternIterNext (pb, &ib);
601 FcPatternHash (const FcPattern *p)
605 FcPatternElt *pe = FcPatternElts(p);
607 for (i = 0; i < FcPatternObjectCount (p); i++)
609 h = (((h << 1) | (h >> 31)) ^
611 FcValueListHash (FcPatternEltValues(&pe[i])));
617 FcPatternEqualSubset (const FcPattern *pai, const FcPattern *pbi, const FcObjectSet *os)
619 FcPatternElt *ea, *eb;
622 for (i = 0; i < os->nobject; i++)
624 FcObject object = FcObjectFromName (os->objects[i]);
625 ea = FcPatternObjectFindElt (pai, object);
626 eb = FcPatternObjectFindElt (pbi, object);
631 if (!FcValueListEqual (FcPatternEltValues(ea), FcPatternEltValues(eb)))
644 FcPatternObjectListAdd (FcPattern *p,
650 FcValueListPtr l, *prev;
652 if (FcRefIsConst (&p->ref))
656 * Make sure the stored type is valid for built-in objects
658 for (l = list; l != NULL; l = FcValueListNext (l))
660 if (!FcObjectValidType (object, l->value.type))
663 "Fontconfig warning: FcPattern object %s does not accept value", FcObjectName (object));
664 FcValuePrintFile (stderr, l->value);
665 fprintf (stderr, "\n");
670 e = FcPatternObjectInsertElt (p, object);
676 for (prev = &e->values; *prev; prev = &(*prev)->next)
682 for (prev = &list; *prev; prev = &(*prev)->next)
695 FcPatternObjectAddWithBinding (FcPattern *p,
698 FcValueBinding binding,
702 FcValueListPtr new, *prev;
704 if (FcRefIsConst (&p->ref))
707 new = FcValueListCreate ();
711 value = FcValueSave (value);
712 if (value.type == FcTypeVoid)
716 * Make sure the stored type is valid for built-in objects
718 if (!FcObjectValidType (object, value.type))
721 "Fontconfig warning: FcPattern object %s does not accept value",
722 FcObjectName (object));
723 FcValuePrintFile (stderr, value);
724 fprintf (stderr, "\n");
729 new->binding = binding;
732 e = FcPatternObjectInsertElt (p, object);
738 for (prev = &e->values; *prev; prev = &(*prev)->next)
744 new->next = e->values;
751 FcValueDestroy (value);
759 FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append)
761 return FcPatternObjectAddWithBinding (p, object,
762 value, FcValueBindingStrong, append);
766 FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append)
768 return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
769 value, FcValueBindingStrong, append);
773 FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append)
775 return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
776 value, FcValueBindingWeak, append);
780 FcPatternObjectDel (FcPattern *p, FcObject object)
784 e = FcPatternObjectFindElt (p, object);
789 FcValueListDestroy (e->values);
791 /* shuffle existing ones down */
793 (FcPatternElts(p) + FcPatternObjectCount (p) - (e + 1)) *
794 sizeof (FcPatternElt));
796 e = FcPatternElts(p) + FcPatternObjectCount (p);
803 FcPatternDel (FcPattern *p, const char *object)
805 return FcPatternObjectDel (p, FcObjectFromName (object));
809 FcPatternRemove (FcPattern *p, const char *object, int id)
812 FcValueListPtr *prev, l;
814 e = FcPatternObjectFindElt (p, FcObjectFromName (object));
817 for (prev = &e->values; (l = *prev); prev = &l->next)
823 FcValueListDestroy (l);
825 FcPatternDel (p, object);
834 FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i)
838 v.type = FcTypeInteger;
840 return FcPatternObjectAdd (p, object, v, FcTrue);
844 FcPatternAddInteger (FcPattern *p, const char *object, int i)
846 return FcPatternObjectAddInteger (p, FcObjectFromName (object), i);
850 FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d)
854 v.type = FcTypeDouble;
856 return FcPatternObjectAdd (p, object, v, FcTrue);
861 FcPatternAddDouble (FcPattern *p, const char *object, double d)
863 return FcPatternObjectAddDouble (p, FcObjectFromName (object), d);
867 FcPatternObjectAddString (FcPattern *p, FcObject object, const FcChar8 *s)
875 return FcPatternObjectAdd (p, object, v, FcTrue);
878 v.type = FcTypeString;
880 return FcPatternObjectAdd (p, object, v, FcTrue);
884 FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
886 return FcPatternObjectAddString (p, FcObjectFromName (object), s);
890 FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s)
894 v.type = FcTypeMatrix;
896 return FcPatternAdd (p, object, v, FcTrue);
901 FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b)
907 return FcPatternObjectAdd (p, object, v, FcTrue);
911 FcPatternAddBool (FcPattern *p, const char *object, FcBool b)
913 return FcPatternObjectAddBool (p, FcObjectFromName (object), b);
917 FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c)
921 v.type = FcTypeCharSet;
922 v.u.c = (FcCharSet *)c;
923 return FcPatternAdd (p, object, v, FcTrue);
927 FcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f)
931 v.type = FcTypeFTFace;
933 return FcPatternAdd (p, object, v, FcTrue);
937 FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls)
941 v.type = FcTypeLangSet;
942 v.u.l = (FcLangSet *)ls;
943 return FcPatternAdd (p, object, v, FcTrue);
947 FcPatternObjectAddRange (FcPattern *p, FcObject object, const FcRange *r)
951 v.type = FcTypeRange;
952 v.u.r = (FcRange *)r;
953 return FcPatternObjectAdd (p, object, v, FcTrue);
957 FcPatternAddRange (FcPattern *p, const char *object, const FcRange *r)
959 return FcPatternObjectAddRange (p, FcObjectFromName (object), r);
963 FcPatternObjectGetWithBinding (const FcPattern *p, FcObject object, int id, FcValue *v, FcValueBinding *b)
969 return FcResultNoMatch;
970 e = FcPatternObjectFindElt (p, object);
972 return FcResultNoMatch;
973 for (l = FcPatternEltValues(e); l; l = FcValueListNext(l))
977 *v = FcValueCanonicalize(&l->value);
980 return FcResultMatch;
988 FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v)
990 return FcPatternObjectGetWithBinding (p, object, id, v, NULL);
994 FcPatternGetWithBinding (const FcPattern *p, const char *object, int id, FcValue *v, FcValueBinding *b)
996 return FcPatternObjectGetWithBinding (p, FcObjectFromName (object), id, v, b);
1000 FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v)
1002 return FcPatternObjectGetWithBinding (p, FcObjectFromName (object), id, v, NULL);
1006 FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int id, int *i)
1011 r = FcPatternObjectGet (p, object, id, &v);
1012 if (r != FcResultMatch)
1014 switch ((int) v.type) {
1022 return FcResultTypeMismatch;
1024 return FcResultMatch;
1028 FcPatternGetInteger (const FcPattern *p, const char *object, int id, int *i)
1030 return FcPatternObjectGetInteger (p, FcObjectFromName (object), id, i);
1035 FcPatternObjectGetDouble (const FcPattern *p, FcObject object, int id, double *d)
1040 r = FcPatternObjectGet (p, object, id, &v);
1041 if (r != FcResultMatch)
1043 switch ((int) v.type) {
1048 *d = (double) v.u.i;
1051 return FcResultTypeMismatch;
1053 return FcResultMatch;
1057 FcPatternGetDouble (const FcPattern *p, const char *object, int id, double *d)
1059 return FcPatternObjectGetDouble (p, FcObjectFromName (object), id, d);
1063 FcPatternObjectGetString (const FcPattern *p, FcObject object, int id, FcChar8 ** s)
1068 r = FcPatternObjectGet (p, object, id, &v);
1069 if (r != FcResultMatch)
1071 if (v.type != FcTypeString)
1072 return FcResultTypeMismatch;
1074 *s = (FcChar8 *) v.u.s;
1075 return FcResultMatch;
1079 FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s)
1081 return FcPatternObjectGetString (p, FcObjectFromName (object), id, s);
1085 FcPatternGetMatrix(const FcPattern *p, const char *object, int id, FcMatrix **m)
1090 r = FcPatternGet (p, object, id, &v);
1091 if (r != FcResultMatch)
1093 if (v.type != FcTypeMatrix)
1094 return FcResultTypeMismatch;
1095 *m = (FcMatrix *)v.u.m;
1096 return FcResultMatch;
1101 FcPatternObjectGetBool (const FcPattern *p, FcObject object, int id, FcBool *b)
1106 r = FcPatternObjectGet (p, object, id, &v);
1107 if (r != FcResultMatch)
1109 if (v.type != FcTypeBool)
1110 return FcResultTypeMismatch;
1112 return FcResultMatch;
1116 FcPatternGetBool(const FcPattern *p, const char *object, int id, FcBool *b)
1118 return FcPatternObjectGetBool (p, FcObjectFromName (object), id, b);
1122 FcPatternGetCharSet(const FcPattern *p, const char *object, int id, FcCharSet **c)
1127 r = FcPatternGet (p, object, id, &v);
1128 if (r != FcResultMatch)
1130 if (v.type != FcTypeCharSet)
1131 return FcResultTypeMismatch;
1132 *c = (FcCharSet *)v.u.c;
1133 return FcResultMatch;
1137 FcPatternGetFTFace(const FcPattern *p, const char *object, int id, FT_Face *f)
1142 r = FcPatternGet (p, object, id, &v);
1143 if (r != FcResultMatch)
1145 if (v.type != FcTypeFTFace)
1146 return FcResultTypeMismatch;
1147 *f = (FT_Face) v.u.f;
1148 return FcResultMatch;
1152 FcPatternGetLangSet(const FcPattern *p, const char *object, int id, FcLangSet **ls)
1157 r = FcPatternGet (p, object, id, &v);
1158 if (r != FcResultMatch)
1160 if (v.type != FcTypeLangSet)
1161 return FcResultTypeMismatch;
1162 *ls = (FcLangSet *)v.u.l;
1163 return FcResultMatch;
1167 FcPatternObjectGetRange (const FcPattern *p, FcObject object, int id, FcRange **r)
1172 res = FcPatternObjectGet (p, object, id, &v);
1173 if (res != FcResultMatch)
1175 switch ((int)v.type) {
1177 *r = (FcRange *)v.u.r;
1180 return FcResultTypeMismatch;
1182 return FcResultMatch;
1186 FcPatternGetRange (const FcPattern *p, const char *object, int id, FcRange **r)
1188 return FcPatternObjectGetRange (p, FcObjectFromName (object), id, r);
1192 FcPatternDuplicate (const FcPattern *orig)
1201 new = FcPatternCreate ();
1205 FcPatternIterStart (orig, &iter);
1208 for (l = FcPatternIterGetValues (orig, &iter); l; l = FcValueListNext (l))
1210 if (!FcPatternObjectAddWithBinding (new, FcPatternIterGetObjectId (orig, &iter),
1211 FcValueCanonicalize(&l->value),
1216 } while (FcPatternIterNext (orig, &iter));
1221 FcPatternDestroy (new);
1227 FcPatternReference (FcPattern *p)
1229 if (!FcRefIsConst (&p->ref))
1232 FcCacheObjectReference (FcPatternGetCacheObject(p));
1236 FcPatternVaBuild (FcPattern *p, va_list va)
1240 FcPatternVapBuild (ret, p, va);
1245 FcPatternBuild (FcPattern *p, ...)
1250 FcPatternVapBuild (p, p, va);
1256 * Add all of the elements in 's' to 'p'
1259 FcPatternAppend (FcPattern *p, FcPattern *s)
1264 FcPatternIterStart (s, &iter);
1267 for (v = FcPatternIterGetValues (s, &iter); v; v = FcValueListNext (v))
1269 if (!FcPatternObjectAddWithBinding (p, FcPatternIterGetObjectId (s, &iter),
1270 FcValueCanonicalize(&v->value),
1271 v->binding, FcTrue))
1274 } while (FcPatternIterNext (s, &iter));
1280 FcPatternFilter (FcPattern *p, const FcObjectSet *os)
1288 return FcPatternDuplicate (p);
1290 ret = FcPatternCreate ();
1294 for (i = 0; i < os->nobject; i++)
1296 FcObject object = FcObjectFromName (os->objects[i]);
1297 e = FcPatternObjectFindElt (p, object);
1300 for (v = FcPatternEltValues(e); v; v = FcValueListNext(v))
1302 if (!FcPatternObjectAddWithBinding (ret, e->object,
1303 FcValueCanonicalize(&v->value),
1304 v->binding, FcTrue))
1312 FcPatternDestroy (ret);
1316 typedef struct _FcPatternPrivateIter {
1319 } FcPatternPrivateIter;
1322 FcPatternIterSet (const FcPattern *pat, FcPatternPrivateIter *iter)
1324 iter->elt = FcPatternObjectCount (pat) > 0 && iter->pos < FcPatternObjectCount (pat) ? &FcPatternElts (pat)[iter->pos] : NULL;
1328 FcPatternIterStart (const FcPattern *pat, FcPatternIter *iter)
1330 FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
1333 FcPatternIterSet (pat, priv);
1337 FcPatternIterNext (const FcPattern *pat, FcPatternIter *iter)
1339 FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
1342 if (priv->pos >= FcPatternObjectCount (pat))
1344 FcPatternIterSet (pat, priv);
1350 FcPatternIterEqual (const FcPattern *p1, FcPatternIter *i1,
1351 const FcPattern *p2, FcPatternIter *i2)
1353 FcBool b1 = FcPatternIterIsValid (p1, i1);
1354 FcBool b2 = FcPatternIterIsValid (p2, i2);
1360 if (FcPatternIterGetObjectId (p1, i1) != FcPatternIterGetObjectId (p2, i2))
1363 return FcValueListEqual (FcPatternIterGetValues (p1, i1),
1364 FcPatternIterGetValues (p2, i2));
1368 FcPatternFindObjectIter (const FcPattern *pat, FcPatternIter *iter, FcObject object)
1370 FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
1371 int i = FcPatternObjectPosition (pat, object);
1378 FcPatternIterSet (pat, priv);
1384 FcPatternFindIter (const FcPattern *pat, FcPatternIter *iter, const char *object)
1386 return FcPatternFindObjectIter (pat, iter, FcObjectFromName (object));
1390 FcPatternIterIsValid (const FcPattern *pat, FcPatternIter *iter)
1392 FcPatternPrivateIter *priv = (FcPatternPrivateIter *)iter;
1394 if (priv && priv->elt)
1401 FcPatternIterGetObjectId (const FcPattern *pat, FcPatternIter *iter)
1403 FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
1405 if (priv && priv->elt)
1406 return priv->elt->object;
1412 FcPatternIterGetObject (const FcPattern *pat, FcPatternIter *iter)
1414 return FcObjectName (FcPatternIterGetObjectId (pat, iter));
1418 FcPatternIterGetValues (const FcPattern *pat, FcPatternIter *iter)
1420 FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
1422 if (priv && priv->elt)
1423 return FcPatternEltValues (priv->elt);
1429 FcPatternIterValueCount (const FcPattern *pat, FcPatternIter *iter)
1434 for (l = FcPatternIterGetValues (pat, iter); l; l = FcValueListNext (l))
1441 FcPatternIterGetValue (const FcPattern *pat, FcPatternIter *iter, int id, FcValue *v, FcValueBinding *b)
1445 for (l = FcPatternIterGetValues (pat, iter); l; l = FcValueListNext (l))
1449 *v = FcValueCanonicalize (&l->value);
1452 return FcResultMatch;
1456 return FcResultNoId;
1460 FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat)
1463 FcPatternElt *elts = FcPatternElts(pat);
1465 if (!FcSerializeAlloc (serialize, pat, sizeof (FcPattern)))
1467 if (!FcSerializeAlloc (serialize, elts, FcPatternObjectCount (pat) * sizeof (FcPatternElt)))
1469 for (i = 0; i < FcPatternObjectCount (pat); i++)
1470 if (!FcValueListSerializeAlloc (serialize, FcPatternEltValues(elts+i)))
1476 FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat)
1478 FcPattern *pat_serialized;
1479 FcPatternElt *elts = FcPatternElts (pat);
1480 FcPatternElt *elts_serialized;
1481 FcValueList *values_serialized;
1484 pat_serialized = FcSerializePtr (serialize, pat);
1485 if (!pat_serialized)
1487 *pat_serialized = *pat;
1488 pat_serialized->size = FcPatternObjectCount (pat);
1489 FcRefSetConst (&pat_serialized->ref);
1491 elts_serialized = FcSerializePtr (serialize, elts);
1492 if (!elts_serialized)
1495 pat_serialized->elts_offset = FcPtrToOffset (pat_serialized,
1498 for (i = 0; i < FcPatternObjectCount (pat); i++)
1500 values_serialized = FcValueListSerialize (serialize, FcPatternEltValues (elts+i));
1501 if (!values_serialized)
1503 elts_serialized[i].object = elts[i].object;
1504 elts_serialized[i].values = FcPtrToEncodedOffset (&elts_serialized[i],
1508 if (FcDebug() & FC_DBG_CACHEV) {
1509 printf ("Raw pattern:\n");
1510 FcPatternPrint (pat);
1511 printf ("Serialized pattern:\n");
1512 FcPatternPrint (pat_serialized);
1515 return pat_serialized;
1519 FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *vl)
1523 if (!FcSerializeAlloc (serialize, vl, sizeof (FcValueList)))
1525 switch ((int) vl->value.type) {
1527 if (!FcStrSerializeAlloc (serialize, vl->value.u.s))
1531 if (!FcCharSetSerializeAlloc (serialize, vl->value.u.c))
1535 if (!FcLangSetSerializeAlloc (serialize, vl->value.u.l))
1539 if (!FcRangeSerializeAlloc (serialize, vl->value.u.r))
1551 FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl)
1553 FcValueList *vl_serialized;
1554 FcChar8 *s_serialized;
1555 FcCharSet *c_serialized;
1556 FcLangSet *l_serialized;
1557 FcRange *r_serialized;
1558 FcValueList *head_serialized = NULL;
1559 FcValueList *prev_serialized = NULL;
1563 vl_serialized = FcSerializePtr (serialize, vl);
1567 if (prev_serialized)
1568 prev_serialized->next = FcPtrToEncodedOffset (prev_serialized,
1572 head_serialized = vl_serialized;
1574 vl_serialized->next = NULL;
1575 vl_serialized->value.type = vl->value.type;
1576 switch ((int) vl->value.type) {
1578 vl_serialized->value.u.i = vl->value.u.i;
1581 vl_serialized->value.u.d = vl->value.u.d;
1584 s_serialized = FcStrSerialize (serialize, vl->value.u.s);
1587 vl_serialized->value.u.s = FcPtrToEncodedOffset (&vl_serialized->value,
1592 vl_serialized->value.u.b = vl->value.u.b;
1598 c_serialized = FcCharSetSerialize (serialize, vl->value.u.c);
1601 vl_serialized->value.u.c = FcPtrToEncodedOffset (&vl_serialized->value,
1609 l_serialized = FcLangSetSerialize (serialize, vl->value.u.l);
1612 vl_serialized->value.u.l = FcPtrToEncodedOffset (&vl_serialized->value,
1617 r_serialized = FcRangeSerialize (serialize, vl->value.u.r);
1620 vl_serialized->value.u.r = FcPtrToEncodedOffset (&vl_serialized->value,
1627 prev_serialized = vl_serialized;
1630 return head_serialized;
1634 #include "fcaliastail.h"
1635 #include "fcftaliastail.h"