12c393a42Smrg/* 22c393a42Smrg * Copyright © 2000 Keith Packard 32c393a42Smrg * 42c393a42Smrg * Permission to use, copy, modify, distribute, and sell this software and its 52c393a42Smrg * documentation for any purpose is hereby granted without fee, provided that 62c393a42Smrg * the above copyright notice appear in all copies and that both that 72c393a42Smrg * copyright notice and this permission notice appear in supporting 8ca08ab68Smrg * documentation, and that the name of the author(s) not be used in 92c393a42Smrg * advertising or publicity pertaining to distribution of the software without 10ca08ab68Smrg * specific, written prior permission. The authors make no 112c393a42Smrg * representations about the suitability of this software for any purpose. It 122c393a42Smrg * is provided "as is" without express or implied warranty. 132c393a42Smrg * 14a6844aabSmrg * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 152c393a42Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16a6844aabSmrg * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR 172c393a42Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 182c393a42Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 192c393a42Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 202c393a42Smrg * PERFORMANCE OF THIS SOFTWARE. 212c393a42Smrg */ 222c393a42Smrg 232c393a42Smrg#include "fcint.h" 242c393a42Smrg#include "fcftint.h" 25c9710b42Smrg 26c9710b42Smrg/* Objects MT-safe for readonly access. */ 272c393a42Smrg 282c393a42SmrgFcPattern * 292c393a42SmrgFcPatternCreate (void) 302c393a42Smrg{ 312c393a42Smrg FcPattern *p; 322c393a42Smrg 332c393a42Smrg p = (FcPattern *) malloc (sizeof (FcPattern)); 342c393a42Smrg if (!p) 352c393a42Smrg return 0; 36b09479dcSmrg memset (p, 0, sizeof (FcPattern)); 372c393a42Smrg p->num = 0; 382c393a42Smrg p->size = 0; 392c393a42Smrg p->elts_offset = FcPtrToOffset (p, NULL); 40c9710b42Smrg FcRefInit (&p->ref, 1); 412c393a42Smrg return p; 422c393a42Smrg} 432c393a42Smrg 442c393a42Smrgvoid 452c393a42SmrgFcValueDestroy (FcValue v) 462c393a42Smrg{ 47c9710b42Smrg switch ((int) v.type) { 482c393a42Smrg case FcTypeString: 49c9710b42Smrg FcFree (v.u.s); 502c393a42Smrg break; 512c393a42Smrg case FcTypeMatrix: 522c393a42Smrg FcMatrixFree ((FcMatrix *) v.u.m); 532c393a42Smrg break; 542c393a42Smrg case FcTypeCharSet: 552c393a42Smrg FcCharSetDestroy ((FcCharSet *) v.u.c); 562c393a42Smrg break; 572c393a42Smrg case FcTypeLangSet: 582c393a42Smrg FcLangSetDestroy ((FcLangSet *) v.u.l); 592c393a42Smrg break; 60953daebaSmrg case FcTypeRange: 61953daebaSmrg FcRangeDestroy ((FcRange *) v.u.r); 62953daebaSmrg break; 632c393a42Smrg default: 642c393a42Smrg break; 652c393a42Smrg } 662c393a42Smrg} 672c393a42Smrg 682c393a42SmrgFcValue 692c393a42SmrgFcValueCanonicalize (const FcValue *v) 702c393a42Smrg{ 712c393a42Smrg FcValue new; 722c393a42Smrg 73c9710b42Smrg switch ((int) v->type) 742c393a42Smrg { 752c393a42Smrg case FcTypeString: 76a6844aabSmrg new.u.s = FcValueString(v); 772c393a42Smrg new.type = FcTypeString; 782c393a42Smrg break; 792c393a42Smrg case FcTypeCharSet: 80a6844aabSmrg new.u.c = FcValueCharSet(v); 812c393a42Smrg new.type = FcTypeCharSet; 822c393a42Smrg break; 832c393a42Smrg case FcTypeLangSet: 84a6844aabSmrg new.u.l = FcValueLangSet(v); 852c393a42Smrg new.type = FcTypeLangSet; 862c393a42Smrg break; 87953daebaSmrg case FcTypeRange: 88953daebaSmrg new.u.r = FcValueRange(v); 89953daebaSmrg new.type = FcTypeRange; 90953daebaSmrg break; 912c393a42Smrg default: 922c393a42Smrg new = *v; 932c393a42Smrg break; 942c393a42Smrg } 952c393a42Smrg return new; 962c393a42Smrg} 972c393a42Smrg 982c393a42SmrgFcValue 992c393a42SmrgFcValueSave (FcValue v) 1002c393a42Smrg{ 101c9710b42Smrg switch ((int) v.type) { 1022c393a42Smrg case FcTypeString: 103c9710b42Smrg v.u.s = FcStrdup (v.u.s); 1042c393a42Smrg if (!v.u.s) 1052c393a42Smrg v.type = FcTypeVoid; 1062c393a42Smrg break; 1072c393a42Smrg case FcTypeMatrix: 1082c393a42Smrg v.u.m = FcMatrixCopy (v.u.m); 1092c393a42Smrg if (!v.u.m) 1102c393a42Smrg v.type = FcTypeVoid; 1112c393a42Smrg break; 1122c393a42Smrg case FcTypeCharSet: 1132c393a42Smrg v.u.c = FcCharSetCopy ((FcCharSet *) v.u.c); 1142c393a42Smrg if (!v.u.c) 1152c393a42Smrg v.type = FcTypeVoid; 1162c393a42Smrg break; 1172c393a42Smrg case FcTypeLangSet: 1182c393a42Smrg v.u.l = FcLangSetCopy (v.u.l); 1192c393a42Smrg if (!v.u.l) 1202c393a42Smrg v.type = FcTypeVoid; 1212c393a42Smrg break; 122953daebaSmrg case FcTypeRange: 123953daebaSmrg v.u.r = FcRangeCopy (v.u.r); 124953daebaSmrg if (!v.u.r) 125953daebaSmrg v.type = FcTypeVoid; 126953daebaSmrg break; 1272c393a42Smrg default: 1282c393a42Smrg break; 1292c393a42Smrg } 1302c393a42Smrg return v; 1312c393a42Smrg} 1322c393a42Smrg 133ca08ab68SmrgFcValueListPtr 134ca08ab68SmrgFcValueListCreate (void) 135ca08ab68Smrg{ 136c9710b42Smrg return calloc (1, sizeof (FcValueList)); 137ca08ab68Smrg} 138ca08ab68Smrg 1392c393a42Smrgvoid 1402c393a42SmrgFcValueListDestroy (FcValueListPtr l) 1412c393a42Smrg{ 1422c393a42Smrg FcValueListPtr next; 1432c393a42Smrg for (; l; l = next) 1442c393a42Smrg { 145a4e54154Smrg FcValueDestroy (l->value); 1462c393a42Smrg next = FcValueListNext(l); 1472c393a42Smrg free(l); 1482c393a42Smrg } 1492c393a42Smrg} 1502c393a42Smrg 151ca08ab68SmrgFcValueListPtr 152ca08ab68SmrgFcValueListPrepend (FcValueListPtr vallist, 153ca08ab68Smrg FcValue value, 154ca08ab68Smrg FcValueBinding binding) 155ca08ab68Smrg{ 156ca08ab68Smrg FcValueListPtr new; 157ca08ab68Smrg 158ca08ab68Smrg if (value.type == FcTypeVoid) 159ca08ab68Smrg return vallist; 160ca08ab68Smrg new = FcValueListCreate (); 161ca08ab68Smrg if (!new) 162ca08ab68Smrg return vallist; 163ca08ab68Smrg 164ca08ab68Smrg new->value = FcValueSave (value); 165ca08ab68Smrg new->binding = binding; 166ca08ab68Smrg new->next = vallist; 167ca08ab68Smrg 168ca08ab68Smrg return new; 169ca08ab68Smrg} 170ca08ab68Smrg 171ca08ab68SmrgFcValueListPtr 172ca08ab68SmrgFcValueListAppend (FcValueListPtr vallist, 173ca08ab68Smrg FcValue value, 174ca08ab68Smrg FcValueBinding binding) 175ca08ab68Smrg{ 176ca08ab68Smrg FcValueListPtr new, last; 177ca08ab68Smrg 178ca08ab68Smrg if (value.type == FcTypeVoid) 179ca08ab68Smrg return vallist; 180ca08ab68Smrg new = FcValueListCreate (); 181ca08ab68Smrg if (!new) 182ca08ab68Smrg return vallist; 183ca08ab68Smrg 184ca08ab68Smrg new->value = FcValueSave (value); 185ca08ab68Smrg new->binding = binding; 186ca08ab68Smrg new->next = NULL; 187ca08ab68Smrg 188ca08ab68Smrg if (vallist) 189ca08ab68Smrg { 190ca08ab68Smrg for (last = vallist; FcValueListNext (last); last = FcValueListNext (last)); 191ca08ab68Smrg 192ca08ab68Smrg last->next = new; 193ca08ab68Smrg } 194ca08ab68Smrg else 195ca08ab68Smrg vallist = new; 196ca08ab68Smrg 197ca08ab68Smrg return vallist; 198ca08ab68Smrg} 199ca08ab68Smrg 200ca08ab68SmrgFcValueListPtr 201ca08ab68SmrgFcValueListDuplicate(FcValueListPtr orig) 202ca08ab68Smrg{ 203ca08ab68Smrg FcValueListPtr new = NULL, l, t = NULL; 204ca08ab68Smrg FcValue v; 205ca08ab68Smrg 206ca08ab68Smrg for (l = orig; l != NULL; l = FcValueListNext (l)) 207ca08ab68Smrg { 208ca08ab68Smrg if (!new) 209ca08ab68Smrg { 210ca08ab68Smrg t = new = FcValueListCreate(); 211ca08ab68Smrg } 212ca08ab68Smrg else 213ca08ab68Smrg { 214ca08ab68Smrg t->next = FcValueListCreate(); 215ca08ab68Smrg t = FcValueListNext (t); 216ca08ab68Smrg } 217ca08ab68Smrg v = FcValueCanonicalize (&l->value); 218ca08ab68Smrg t->value = FcValueSave (v); 219ca08ab68Smrg t->binding = l->binding; 220ca08ab68Smrg t->next = NULL; 221ca08ab68Smrg } 222ca08ab68Smrg 223ca08ab68Smrg return new; 224ca08ab68Smrg} 225ca08ab68Smrg 2262c393a42SmrgFcBool 2272c393a42SmrgFcValueEqual (FcValue va, FcValue vb) 2282c393a42Smrg{ 2292c393a42Smrg if (va.type != vb.type) 2302c393a42Smrg { 2312c393a42Smrg if (va.type == FcTypeInteger) 2322c393a42Smrg { 2332c393a42Smrg va.type = FcTypeDouble; 2342c393a42Smrg va.u.d = va.u.i; 2352c393a42Smrg } 2362c393a42Smrg if (vb.type == FcTypeInteger) 2372c393a42Smrg { 2382c393a42Smrg vb.type = FcTypeDouble; 2392c393a42Smrg vb.u.d = vb.u.i; 2402c393a42Smrg } 2412c393a42Smrg if (va.type != vb.type) 2422c393a42Smrg return FcFalse; 2432c393a42Smrg } 2442c393a42Smrg switch (va.type) { 2456fc018e4Smrg case FcTypeUnknown: 2466fc018e4Smrg return FcFalse; /* don't know how to compare this object */ 2472c393a42Smrg case FcTypeVoid: 2482c393a42Smrg return FcTrue; 2492c393a42Smrg case FcTypeInteger: 2502c393a42Smrg return va.u.i == vb.u.i; 2512c393a42Smrg case FcTypeDouble: 2522c393a42Smrg return va.u.d == vb.u.d; 2532c393a42Smrg case FcTypeString: 2542c393a42Smrg return FcStrCmpIgnoreCase (va.u.s, vb.u.s) == 0; 2552c393a42Smrg case FcTypeBool: 2562c393a42Smrg return va.u.b == vb.u.b; 2572c393a42Smrg case FcTypeMatrix: 2582c393a42Smrg return FcMatrixEqual (va.u.m, vb.u.m); 2592c393a42Smrg case FcTypeCharSet: 2602c393a42Smrg return FcCharSetEqual (va.u.c, vb.u.c); 2612c393a42Smrg case FcTypeFTFace: 2622c393a42Smrg return va.u.f == vb.u.f; 2632c393a42Smrg case FcTypeLangSet: 2642c393a42Smrg return FcLangSetEqual (va.u.l, vb.u.l); 265953daebaSmrg case FcTypeRange: 266953daebaSmrg return FcRangeIsInRange (va.u.r, vb.u.r); 2672c393a42Smrg } 2682c393a42Smrg return FcFalse; 2692c393a42Smrg} 2702c393a42Smrg 2712c393a42Smrgstatic FcChar32 2722c393a42SmrgFcDoubleHash (double d) 2732c393a42Smrg{ 2742c393a42Smrg if (d < 0) 2752c393a42Smrg d = -d; 2762c393a42Smrg if (d > 0xffffffff) 2772c393a42Smrg d = 0xffffffff; 2782c393a42Smrg return (FcChar32) d; 2792c393a42Smrg} 2802c393a42Smrg 2812c393a42SmrgFcChar32 2822c393a42SmrgFcStringHash (const FcChar8 *s) 2832c393a42Smrg{ 2842c393a42Smrg FcChar8 c; 2852c393a42Smrg FcChar32 h = 0; 286ca08ab68Smrg 2872c393a42Smrg if (s) 2882c393a42Smrg while ((c = *s++)) 2892c393a42Smrg h = ((h << 1) | (h >> 31)) ^ c; 2902c393a42Smrg return h; 2912c393a42Smrg} 2922c393a42Smrg 2932c393a42Smrgstatic FcChar32 2942c393a42SmrgFcValueHash (const FcValue *v) 2952c393a42Smrg{ 296a6844aabSmrg switch (v->type) { 2976fc018e4Smrg case FcTypeUnknown: 2982c393a42Smrg case FcTypeVoid: 2992c393a42Smrg return 0; 3002c393a42Smrg case FcTypeInteger: 3012c393a42Smrg return (FcChar32) v->u.i; 3022c393a42Smrg case FcTypeDouble: 3032c393a42Smrg return FcDoubleHash (v->u.d); 3042c393a42Smrg case FcTypeString: 305a6844aabSmrg return FcStringHash (FcValueString(v)); 3062c393a42Smrg case FcTypeBool: 3072c393a42Smrg return (FcChar32) v->u.b; 3082c393a42Smrg case FcTypeMatrix: 309ca08ab68Smrg return (FcDoubleHash (v->u.m->xx) ^ 310ca08ab68Smrg FcDoubleHash (v->u.m->xy) ^ 311ca08ab68Smrg FcDoubleHash (v->u.m->yx) ^ 3122c393a42Smrg FcDoubleHash (v->u.m->yy)); 3132c393a42Smrg case FcTypeCharSet: 314a6844aabSmrg return (FcChar32) FcValueCharSet(v)->num; 3152c393a42Smrg case FcTypeFTFace: 3162c393a42Smrg return FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->family_name) ^ 3172c393a42Smrg FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->style_name); 3182c393a42Smrg case FcTypeLangSet: 319a6844aabSmrg return FcLangSetHash (FcValueLangSet(v)); 320953daebaSmrg case FcTypeRange: 321a4e54154Smrg return FcRangeHash (FcValueRange (v)); 3222c393a42Smrg } 3236fc018e4Smrg return 0; 3242c393a42Smrg} 3252c393a42Smrg 3262c393a42Smrgstatic FcBool 3272c393a42SmrgFcValueListEqual (FcValueListPtr la, FcValueListPtr lb) 3282c393a42Smrg{ 3292c393a42Smrg if (la == lb) 3302c393a42Smrg return FcTrue; 3312c393a42Smrg 3322c393a42Smrg while (la && lb) 3332c393a42Smrg { 3342c393a42Smrg if (!FcValueEqual (la->value, lb->value)) 3352c393a42Smrg return FcFalse; 3362c393a42Smrg la = FcValueListNext(la); 3372c393a42Smrg lb = FcValueListNext(lb); 3382c393a42Smrg } 3392c393a42Smrg if (la || lb) 3402c393a42Smrg return FcFalse; 3412c393a42Smrg return FcTrue; 3422c393a42Smrg} 3432c393a42Smrg 3442c393a42Smrgstatic FcChar32 3452c393a42SmrgFcValueListHash (FcValueListPtr l) 3462c393a42Smrg{ 3472c393a42Smrg FcChar32 hash = 0; 348ca08ab68Smrg 3492c393a42Smrg for (; l; l = FcValueListNext(l)) 3502c393a42Smrg { 3512c393a42Smrg hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (&l->value); 3522c393a42Smrg } 3532c393a42Smrg return hash; 3542c393a42Smrg} 3552c393a42Smrg 356a32e9e42Smrgstatic void * 357a32e9e42SmrgFcPatternGetCacheObject (FcPattern *p) 358a32e9e42Smrg{ 359a32e9e42Smrg /* We use a value to find the cache, instead of the FcPattern object 360a32e9e42Smrg * because the pattern itself may be a cache allocation if we rewrote the path, 361a32e9e42Smrg * so the p may not be in the cached region. */ 362a32e9e42Smrg return FcPatternEltValues(&FcPatternElts (p)[0]); 363a32e9e42Smrg} 364a32e9e42Smrg 365a32e9e42SmrgFcPattern * 366a32e9e42SmrgFcPatternCacheRewriteFile (const FcPattern *p, 367a32e9e42Smrg FcCache *cache, 368a32e9e42Smrg const FcChar8 *relocated_font_file) 369a32e9e42Smrg{ 370a32e9e42Smrg FcPatternElt *elts = FcPatternElts (p); 371a32e9e42Smrg size_t i,j; 372a32e9e42Smrg FcChar8 *data; 373a32e9e42Smrg FcPattern *new_p; 374a32e9e42Smrg FcPatternElt *new_elts; 375a32e9e42Smrg FcValueList *new_value_list; 376a32e9e42Smrg size_t new_path_len = strlen ((char *)relocated_font_file); 377a32e9e42Smrg FcChar8 *new_path; 378a32e9e42Smrg 379a32e9e42Smrg /* Allocate space for the patter, the PatternElt headers and 380a32e9e42Smrg * the FC_FILE FcValueList and path that will be freed with the 381a32e9e42Smrg * cache */ 382a32e9e42Smrg data = FcCacheAllocate (cache, 383a32e9e42Smrg sizeof (FcPattern) + 384a32e9e42Smrg p->num * sizeof (FcPatternElt) + 385a32e9e42Smrg sizeof (FcValueList) + 386a32e9e42Smrg new_path_len + 1); 387a32e9e42Smrg 388a32e9e42Smrg new_p = (FcPattern *)data; 389a32e9e42Smrg data += sizeof (FcPattern); 390a32e9e42Smrg new_elts = (FcPatternElt *)(data); 391a32e9e42Smrg data += p->num * sizeof (FcPatternElt); 392a32e9e42Smrg new_value_list = (FcValueList *)data; 393a32e9e42Smrg data += sizeof (FcValueList); 394a32e9e42Smrg new_path = data; 395a32e9e42Smrg 396a32e9e42Smrg *new_p = *p; 397a32e9e42Smrg new_p->elts_offset = FcPtrToOffset (new_p, new_elts); 398a32e9e42Smrg 399a32e9e42Smrg /* Copy all but the FILE values from the cache */ 400a32e9e42Smrg for (i = 0, j = 0; i < p->num; i++) 401a32e9e42Smrg { 402a32e9e42Smrg FcPatternElt *elt = &elts[i]; 403a32e9e42Smrg new_elts[j].object = elt->object; 404a32e9e42Smrg if (elt->object != FC_FILE_OBJECT) 405a32e9e42Smrg new_elts[j++].values = FcPatternEltValues(elt); 406a32e9e42Smrg else 407a32e9e42Smrg new_elts[j++].values = new_value_list; 408a32e9e42Smrg } 409a32e9e42Smrg 410a32e9e42Smrg new_value_list->next = NULL; 411a32e9e42Smrg new_value_list->value.type = FcTypeString; 412a32e9e42Smrg new_value_list->value.u.s = new_path; 413a32e9e42Smrg new_value_list->binding = FcValueBindingWeak; 414a32e9e42Smrg 415a32e9e42Smrg /* Add rewritten path at the end */ 416a32e9e42Smrg strcpy ((char *)new_path, (char *)relocated_font_file); 417a32e9e42Smrg 418a32e9e42Smrg return new_p; 419a32e9e42Smrg} 420a32e9e42Smrg 4212c393a42Smrgvoid 4222c393a42SmrgFcPatternDestroy (FcPattern *p) 4232c393a42Smrg{ 4242c393a42Smrg int i; 4252c393a42Smrg FcPatternElt *elts; 426ca08ab68Smrg 427c9710b42Smrg if (!p) 428c9710b42Smrg return; 429c9710b42Smrg 430c9710b42Smrg if (FcRefIsConst (&p->ref)) 4312c393a42Smrg { 432a32e9e42Smrg FcCacheObjectDereference (FcPatternGetCacheObject(p)); 4332c393a42Smrg return; 4342c393a42Smrg } 435a32e9e42Smrg 436c9710b42Smrg if (FcRefDec (&p->ref) != 1) 4372c393a42Smrg return; 4382c393a42Smrg 4392c393a42Smrg elts = FcPatternElts (p); 440a32e9e42Smrg for (i = 0; i < FcPatternObjectCount (p); i++) 4412c393a42Smrg FcValueListDestroy (FcPatternEltValues(&elts[i])); 4422c393a42Smrg 4432c393a42Smrg free (elts); 4442c393a42Smrg free (p); 4452c393a42Smrg} 4462c393a42Smrg 447a32e9e42Smrgint 448a32e9e42SmrgFcPatternObjectCount (const FcPattern *pat) 449a32e9e42Smrg{ 450a32e9e42Smrg if (pat) 451a32e9e42Smrg return pat->num; 452a32e9e42Smrg 453a32e9e42Smrg return 0; 454a32e9e42Smrg} 455a32e9e42Smrg 456a32e9e42Smrg 4572c393a42Smrgstatic int 4582c393a42SmrgFcPatternObjectPosition (const FcPattern *p, FcObject object) 4592c393a42Smrg{ 4602c393a42Smrg int low, high, mid, c; 4612c393a42Smrg FcPatternElt *elts = FcPatternElts(p); 4622c393a42Smrg 4632c393a42Smrg low = 0; 464a32e9e42Smrg high = FcPatternObjectCount (p) - 1; 4652c393a42Smrg c = 1; 4662c393a42Smrg mid = 0; 4672c393a42Smrg while (low <= high) 4682c393a42Smrg { 4692c393a42Smrg mid = (low + high) >> 1; 4702c393a42Smrg c = elts[mid].object - object; 4712c393a42Smrg if (c == 0) 4722c393a42Smrg return mid; 4732c393a42Smrg if (c < 0) 4742c393a42Smrg low = mid + 1; 4752c393a42Smrg else 4762c393a42Smrg high = mid - 1; 4772c393a42Smrg } 4782c393a42Smrg if (c < 0) 4792c393a42Smrg mid++; 4802c393a42Smrg return -(mid + 1); 4812c393a42Smrg} 4822c393a42Smrg 483953daebaSmrgint 484953daebaSmrgFcPatternPosition (const FcPattern *p, const char *object) 485953daebaSmrg{ 486953daebaSmrg return FcPatternObjectPosition (p, FcObjectFromName (object)); 487953daebaSmrg} 488953daebaSmrg 4892c393a42SmrgFcPatternElt * 4902c393a42SmrgFcPatternObjectFindElt (const FcPattern *p, FcObject object) 4912c393a42Smrg{ 4922c393a42Smrg int i = FcPatternObjectPosition (p, object); 4932c393a42Smrg if (i < 0) 4942c393a42Smrg return 0; 4952c393a42Smrg return &FcPatternElts(p)[i]; 4962c393a42Smrg} 4972c393a42Smrg 4982c393a42SmrgFcPatternElt * 4992c393a42SmrgFcPatternObjectInsertElt (FcPattern *p, FcObject object) 5002c393a42Smrg{ 5012c393a42Smrg int i; 5022c393a42Smrg FcPatternElt *e; 503ca08ab68Smrg 5042c393a42Smrg i = FcPatternObjectPosition (p, object); 5052c393a42Smrg if (i < 0) 5062c393a42Smrg { 5072c393a42Smrg i = -i - 1; 508ca08ab68Smrg 5092c393a42Smrg /* reallocate array */ 510a32e9e42Smrg if (FcPatternObjectCount (p) + 1 >= p->size) 5112c393a42Smrg { 5122c393a42Smrg int s = p->size + 16; 5132c393a42Smrg if (p->size) 5142c393a42Smrg { 5152c393a42Smrg FcPatternElt *e0 = FcPatternElts(p); 5162c393a42Smrg e = (FcPatternElt *) realloc (e0, s * sizeof (FcPatternElt)); 5172c393a42Smrg if (!e) /* maybe it was mmapped */ 5182c393a42Smrg { 5192c393a42Smrg e = malloc(s * sizeof (FcPatternElt)); 5202c393a42Smrg if (e) 521a32e9e42Smrg memcpy(e, e0, FcPatternObjectCount (p) * sizeof (FcPatternElt)); 5222c393a42Smrg } 5232c393a42Smrg } 5242c393a42Smrg else 5252c393a42Smrg e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt)); 5262c393a42Smrg if (!e) 5272c393a42Smrg return FcFalse; 5282c393a42Smrg p->elts_offset = FcPtrToOffset (p, e); 5292c393a42Smrg while (p->size < s) 5302c393a42Smrg { 5312c393a42Smrg e[p->size].object = 0; 5322c393a42Smrg e[p->size].values = NULL; 5332c393a42Smrg p->size++; 5342c393a42Smrg } 5352c393a42Smrg } 5361cc69409Smrg 5372c393a42Smrg e = FcPatternElts(p); 5382c393a42Smrg /* move elts up */ 5392c393a42Smrg memmove (e + i + 1, 5402c393a42Smrg e + i, 5412c393a42Smrg sizeof (FcPatternElt) * 542a32e9e42Smrg (FcPatternObjectCount (p) - i)); 5431cc69409Smrg 5442c393a42Smrg /* bump count */ 5452c393a42Smrg p->num++; 5461cc69409Smrg 5472c393a42Smrg e[i].object = object; 5482c393a42Smrg e[i].values = NULL; 5492c393a42Smrg } 550ca08ab68Smrg 5512c393a42Smrg return FcPatternElts(p) + i; 5522c393a42Smrg} 5532c393a42Smrg 5542c393a42SmrgFcBool 5552c393a42SmrgFcPatternEqual (const FcPattern *pa, const FcPattern *pb) 5562c393a42Smrg{ 557a32e9e42Smrg FcPatternIter ia, ib; 5582c393a42Smrg 5592c393a42Smrg if (pa == pb) 5602c393a42Smrg return FcTrue; 5612c393a42Smrg 562a32e9e42Smrg if (FcPatternObjectCount (pa) != FcPatternObjectCount (pb)) 5632c393a42Smrg return FcFalse; 564a32e9e42Smrg FcPatternIterStart (pa, &ia); 565a32e9e42Smrg FcPatternIterStart (pb, &ib); 566a32e9e42Smrg do { 567a32e9e42Smrg FcBool ra, rb; 568a32e9e42Smrg 569a32e9e42Smrg if (!FcPatternIterEqual (pa, &ia, pb, &ib)) 5702c393a42Smrg return FcFalse; 571a32e9e42Smrg ra = FcPatternIterNext (pa, &ia); 572a32e9e42Smrg rb = FcPatternIterNext (pb, &ib); 573a32e9e42Smrg if (!ra && !rb) 574a32e9e42Smrg break; 575a32e9e42Smrg } while (1); 576a32e9e42Smrg 5772c393a42Smrg return FcTrue; 5782c393a42Smrg} 5792c393a42Smrg 5802c393a42SmrgFcChar32 5812c393a42SmrgFcPatternHash (const FcPattern *p) 5822c393a42Smrg{ 5832c393a42Smrg int i; 5842c393a42Smrg FcChar32 h = 0; 5852c393a42Smrg FcPatternElt *pe = FcPatternElts(p); 5862c393a42Smrg 587a32e9e42Smrg for (i = 0; i < FcPatternObjectCount (p); i++) 5882c393a42Smrg { 589ca08ab68Smrg h = (((h << 1) | (h >> 31)) ^ 5902c393a42Smrg pe[i].object ^ 5912c393a42Smrg FcValueListHash (FcPatternEltValues(&pe[i]))); 5922c393a42Smrg } 5932c393a42Smrg return h; 5942c393a42Smrg} 5952c393a42Smrg 5962c393a42SmrgFcBool 5972c393a42SmrgFcPatternEqualSubset (const FcPattern *pai, const FcPattern *pbi, const FcObjectSet *os) 5982c393a42Smrg{ 5992c393a42Smrg FcPatternElt *ea, *eb; 6002c393a42Smrg int i; 601ca08ab68Smrg 6022c393a42Smrg for (i = 0; i < os->nobject; i++) 6032c393a42Smrg { 6042c393a42Smrg FcObject object = FcObjectFromName (os->objects[i]); 6052c393a42Smrg ea = FcPatternObjectFindElt (pai, object); 6062c393a42Smrg eb = FcPatternObjectFindElt (pbi, object); 6072c393a42Smrg if (ea) 6082c393a42Smrg { 6092c393a42Smrg if (!eb) 6102c393a42Smrg return FcFalse; 6112c393a42Smrg if (!FcValueListEqual (FcPatternEltValues(ea), FcPatternEltValues(eb))) 6122c393a42Smrg return FcFalse; 6132c393a42Smrg } 6142c393a42Smrg else 6152c393a42Smrg { 6162c393a42Smrg if (eb) 6172c393a42Smrg return FcFalse; 6182c393a42Smrg } 6192c393a42Smrg } 6202c393a42Smrg return FcTrue; 6212c393a42Smrg} 6222c393a42Smrg 623ca08ab68SmrgFcBool 624ca08ab68SmrgFcPatternObjectListAdd (FcPattern *p, 625ca08ab68Smrg FcObject object, 626ca08ab68Smrg FcValueListPtr list, 627ca08ab68Smrg FcBool append) 628ca08ab68Smrg{ 629ca08ab68Smrg FcPatternElt *e; 630ca08ab68Smrg FcValueListPtr l, *prev; 631ca08ab68Smrg 632c9710b42Smrg if (FcRefIsConst (&p->ref)) 633ca08ab68Smrg goto bail0; 634ca08ab68Smrg 635ca08ab68Smrg /* 636ca08ab68Smrg * Make sure the stored type is valid for built-in objects 637ca08ab68Smrg */ 638ca08ab68Smrg for (l = list; l != NULL; l = FcValueListNext (l)) 639ca08ab68Smrg { 640ca08ab68Smrg if (!FcObjectValidType (object, l->value.type)) 641ca08ab68Smrg { 642c9710b42Smrg fprintf (stderr, 643c9710b42Smrg "Fontconfig warning: FcPattern object %s does not accept value", FcObjectName (object)); 644c9710b42Smrg FcValuePrintFile (stderr, l->value); 645c9710b42Smrg fprintf (stderr, "\n"); 646ca08ab68Smrg goto bail0; 647ca08ab68Smrg } 648ca08ab68Smrg } 649ca08ab68Smrg 650ca08ab68Smrg e = FcPatternObjectInsertElt (p, object); 651ca08ab68Smrg if (!e) 652ca08ab68Smrg goto bail0; 653ca08ab68Smrg 654ca08ab68Smrg if (append) 655ca08ab68Smrg { 656ca08ab68Smrg for (prev = &e->values; *prev; prev = &(*prev)->next) 657ca08ab68Smrg ; 658ca08ab68Smrg *prev = list; 659ca08ab68Smrg } 660ca08ab68Smrg else 661ca08ab68Smrg { 662ca08ab68Smrg for (prev = &list; *prev; prev = &(*prev)->next) 663ca08ab68Smrg ; 664ca08ab68Smrg *prev = e->values; 665ca08ab68Smrg e->values = list; 666ca08ab68Smrg } 667ca08ab68Smrg 668ca08ab68Smrg return FcTrue; 669ca08ab68Smrg 670ca08ab68Smrgbail0: 671ca08ab68Smrg return FcFalse; 672ca08ab68Smrg} 673ca08ab68Smrg 6742c393a42SmrgFcBool 6752c393a42SmrgFcPatternObjectAddWithBinding (FcPattern *p, 6762c393a42Smrg FcObject object, 6772c393a42Smrg FcValue value, 6782c393a42Smrg FcValueBinding binding, 6792c393a42Smrg FcBool append) 6802c393a42Smrg{ 6812c393a42Smrg FcPatternElt *e; 6822c393a42Smrg FcValueListPtr new, *prev; 6832c393a42Smrg 684c9710b42Smrg if (FcRefIsConst (&p->ref)) 6852c393a42Smrg goto bail0; 6862c393a42Smrg 687ca08ab68Smrg new = FcValueListCreate (); 6882c393a42Smrg if (!new) 6892c393a42Smrg goto bail0; 6902c393a42Smrg 691a4e54154Smrg new->value = FcValueSave (value); 692a4e54154Smrg new->binding = binding; 693a4e54154Smrg new->next = NULL; 694a4e54154Smrg 695a4e54154Smrg if (new->value.type == FcTypeVoid) 6962c393a42Smrg goto bail1; 6972c393a42Smrg 6982c393a42Smrg /* 6992c393a42Smrg * Make sure the stored type is valid for built-in objects 7002c393a42Smrg */ 701a4e54154Smrg if (!FcObjectValidType (object, new->value.type)) 7022c393a42Smrg { 703c9710b42Smrg fprintf (stderr, 704c9710b42Smrg "Fontconfig warning: FcPattern object %s does not accept value", 705c9710b42Smrg FcObjectName (object)); 706a4e54154Smrg FcValuePrintFile (stderr, new->value); 707c9710b42Smrg fprintf (stderr, "\n"); 7082c393a42Smrg goto bail1; 7092c393a42Smrg } 7102c393a42Smrg 7112c393a42Smrg e = FcPatternObjectInsertElt (p, object); 7122c393a42Smrg if (!e) 713a4e54154Smrg goto bail1; 714ca08ab68Smrg 7152c393a42Smrg if (append) 7162c393a42Smrg { 7172c393a42Smrg for (prev = &e->values; *prev; prev = &(*prev)->next) 7182c393a42Smrg ; 7192c393a42Smrg *prev = new; 7202c393a42Smrg } 7212c393a42Smrg else 7222c393a42Smrg { 7232c393a42Smrg new->next = e->values; 7242c393a42Smrg e->values = new; 7252c393a42Smrg } 726ca08ab68Smrg 7272c393a42Smrg return FcTrue; 7282c393a42Smrg 7292c393a42Smrgbail1: 730a4e54154Smrg FcValueListDestroy (new); 7312c393a42Smrgbail0: 7322c393a42Smrg return FcFalse; 7332c393a42Smrg} 7342c393a42Smrg 7352c393a42SmrgFcBool 7362c393a42SmrgFcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append) 7372c393a42Smrg{ 7382c393a42Smrg return FcPatternObjectAddWithBinding (p, object, 7392c393a42Smrg value, FcValueBindingStrong, append); 7402c393a42Smrg} 7412c393a42Smrg 7422c393a42SmrgFcBool 7432c393a42SmrgFcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append) 7442c393a42Smrg{ 7452c393a42Smrg return FcPatternObjectAddWithBinding (p, FcObjectFromName (object), 7462c393a42Smrg value, FcValueBindingStrong, append); 7472c393a42Smrg} 7482c393a42Smrg 7492c393a42SmrgFcBool 7502c393a42SmrgFcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append) 7512c393a42Smrg{ 7522c393a42Smrg return FcPatternObjectAddWithBinding (p, FcObjectFromName (object), 7532c393a42Smrg value, FcValueBindingWeak, append); 7542c393a42Smrg} 7552c393a42Smrg 7562c393a42SmrgFcBool 7572c393a42SmrgFcPatternObjectDel (FcPattern *p, FcObject object) 7582c393a42Smrg{ 7592c393a42Smrg FcPatternElt *e; 7602c393a42Smrg 7612c393a42Smrg e = FcPatternObjectFindElt (p, object); 7622c393a42Smrg if (!e) 7632c393a42Smrg return FcFalse; 7642c393a42Smrg 7652c393a42Smrg /* destroy value */ 7662c393a42Smrg FcValueListDestroy (e->values); 767ca08ab68Smrg 7682c393a42Smrg /* shuffle existing ones down */ 769ca08ab68Smrg memmove (e, e+1, 770a32e9e42Smrg (FcPatternElts(p) + FcPatternObjectCount (p) - (e + 1)) * 7712c393a42Smrg sizeof (FcPatternElt)); 7722c393a42Smrg p->num--; 773a32e9e42Smrg e = FcPatternElts(p) + FcPatternObjectCount (p); 7742c393a42Smrg e->object = 0; 7752c393a42Smrg e->values = NULL; 7762c393a42Smrg return FcTrue; 7772c393a42Smrg} 7782c393a42Smrg 7792c393a42SmrgFcBool 7802c393a42SmrgFcPatternDel (FcPattern *p, const char *object) 7812c393a42Smrg{ 7822c393a42Smrg return FcPatternObjectDel (p, FcObjectFromName (object)); 7832c393a42Smrg} 784ca08ab68Smrg 7852c393a42SmrgFcBool 7862c393a42SmrgFcPatternRemove (FcPattern *p, const char *object, int id) 7872c393a42Smrg{ 7882c393a42Smrg FcPatternElt *e; 7892c393a42Smrg FcValueListPtr *prev, l; 7902c393a42Smrg 7912c393a42Smrg e = FcPatternObjectFindElt (p, FcObjectFromName (object)); 7922c393a42Smrg if (!e) 7932c393a42Smrg return FcFalse; 7942c393a42Smrg for (prev = &e->values; (l = *prev); prev = &l->next) 7952c393a42Smrg { 7962c393a42Smrg if (!id) 7972c393a42Smrg { 7982c393a42Smrg *prev = l->next; 7992c393a42Smrg l->next = NULL; 8002c393a42Smrg FcValueListDestroy (l); 8012c393a42Smrg if (!e->values) 8022c393a42Smrg FcPatternDel (p, object); 8032c393a42Smrg return FcTrue; 8042c393a42Smrg } 8052c393a42Smrg id--; 8062c393a42Smrg } 8072c393a42Smrg return FcFalse; 8082c393a42Smrg} 8092c393a42Smrg 8102c393a42SmrgFcBool 8112c393a42SmrgFcPatternObjectAddInteger (FcPattern *p, FcObject object, int i) 8122c393a42Smrg{ 8132c393a42Smrg FcValue v; 8142c393a42Smrg 8152c393a42Smrg v.type = FcTypeInteger; 8162c393a42Smrg v.u.i = i; 8172c393a42Smrg return FcPatternObjectAdd (p, object, v, FcTrue); 8182c393a42Smrg} 8192c393a42Smrg 8202c393a42SmrgFcBool 8212c393a42SmrgFcPatternAddInteger (FcPattern *p, const char *object, int i) 8222c393a42Smrg{ 8232c393a42Smrg return FcPatternObjectAddInteger (p, FcObjectFromName (object), i); 8242c393a42Smrg} 8252c393a42Smrg 8262c393a42SmrgFcBool 8272c393a42SmrgFcPatternObjectAddDouble (FcPattern *p, FcObject object, double d) 8282c393a42Smrg{ 8292c393a42Smrg FcValue v; 8302c393a42Smrg 8312c393a42Smrg v.type = FcTypeDouble; 8322c393a42Smrg v.u.d = d; 8332c393a42Smrg return FcPatternObjectAdd (p, object, v, FcTrue); 8342c393a42Smrg} 8352c393a42Smrg 8362c393a42Smrg 8372c393a42SmrgFcBool 8382c393a42SmrgFcPatternAddDouble (FcPattern *p, const char *object, double d) 8392c393a42Smrg{ 8402c393a42Smrg return FcPatternObjectAddDouble (p, FcObjectFromName (object), d); 8412c393a42Smrg} 8422c393a42Smrg 8432c393a42SmrgFcBool 8442c393a42SmrgFcPatternObjectAddString (FcPattern *p, FcObject object, const FcChar8 *s) 8452c393a42Smrg{ 8462c393a42Smrg FcValue v; 8472c393a42Smrg 8482c393a42Smrg if (!s) 8492c393a42Smrg { 8502c393a42Smrg v.type = FcTypeVoid; 8512c393a42Smrg v.u.s = 0; 8522c393a42Smrg return FcPatternObjectAdd (p, object, v, FcTrue); 8532c393a42Smrg } 8542c393a42Smrg 8552c393a42Smrg v.type = FcTypeString; 856ca08ab68Smrg v.u.s = s; 8572c393a42Smrg return FcPatternObjectAdd (p, object, v, FcTrue); 8582c393a42Smrg} 8592c393a42Smrg 8602c393a42SmrgFcBool 8612c393a42SmrgFcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s) 8622c393a42Smrg{ 8632c393a42Smrg return FcPatternObjectAddString (p, FcObjectFromName (object), s); 8642c393a42Smrg} 8652c393a42Smrg 8662c393a42SmrgFcBool 8672c393a42SmrgFcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s) 8682c393a42Smrg{ 8692c393a42Smrg FcValue v; 8702c393a42Smrg 8712c393a42Smrg v.type = FcTypeMatrix; 8722c393a42Smrg v.u.m = s; 8732c393a42Smrg return FcPatternAdd (p, object, v, FcTrue); 8742c393a42Smrg} 8752c393a42Smrg 8762c393a42Smrg 8772c393a42SmrgFcBool 8782c393a42SmrgFcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b) 8792c393a42Smrg{ 8802c393a42Smrg FcValue v; 8812c393a42Smrg 8822c393a42Smrg v.type = FcTypeBool; 8832c393a42Smrg v.u.b = b; 8842c393a42Smrg return FcPatternObjectAdd (p, object, v, FcTrue); 8852c393a42Smrg} 8862c393a42Smrg 8872c393a42SmrgFcBool 8882c393a42SmrgFcPatternAddBool (FcPattern *p, const char *object, FcBool b) 8892c393a42Smrg{ 8902c393a42Smrg return FcPatternObjectAddBool (p, FcObjectFromName (object), b); 8912c393a42Smrg} 8922c393a42Smrg 8932c393a42SmrgFcBool 894a4e54154SmrgFcPatternObjectAddCharSet (FcPattern *p, FcObject object, const FcCharSet *c) 8952c393a42Smrg{ 8962c393a42Smrg FcValue v; 8972c393a42Smrg 8982c393a42Smrg v.type = FcTypeCharSet; 8992c393a42Smrg v.u.c = (FcCharSet *)c; 900a4e54154Smrg return FcPatternObjectAdd (p, object, v, FcTrue); 901a4e54154Smrg} 902a4e54154Smrg 903a4e54154SmrgFcBool 904a4e54154SmrgFcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c) 905a4e54154Smrg{ 906a4e54154Smrg return FcPatternObjectAddCharSet (p, FcObjectFromName (object), c); 9072c393a42Smrg} 9082c393a42Smrg 9092c393a42SmrgFcBool 9102c393a42SmrgFcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f) 9112c393a42Smrg{ 9122c393a42Smrg FcValue v; 9132c393a42Smrg 9142c393a42Smrg v.type = FcTypeFTFace; 9152c393a42Smrg v.u.f = (void *) f; 9162c393a42Smrg return FcPatternAdd (p, object, v, FcTrue); 9172c393a42Smrg} 9182c393a42Smrg 9192c393a42SmrgFcBool 920a4e54154SmrgFcPatternObjectAddLangSet (FcPattern *p, FcObject object, const FcLangSet *ls) 9212c393a42Smrg{ 9222c393a42Smrg FcValue v; 9232c393a42Smrg 9242c393a42Smrg v.type = FcTypeLangSet; 9252c393a42Smrg v.u.l = (FcLangSet *)ls; 926a4e54154Smrg return FcPatternObjectAdd (p, object, v, FcTrue); 927a4e54154Smrg} 928a4e54154Smrg 929a4e54154SmrgFcBool 930a4e54154SmrgFcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls) 931a4e54154Smrg{ 932a4e54154Smrg return FcPatternObjectAddLangSet (p, FcObjectFromName (object), ls); 9332c393a42Smrg} 9342c393a42Smrg 935953daebaSmrgFcBool 936953daebaSmrgFcPatternObjectAddRange (FcPattern *p, FcObject object, const FcRange *r) 937953daebaSmrg{ 938953daebaSmrg FcValue v; 939953daebaSmrg 940953daebaSmrg v.type = FcTypeRange; 941953daebaSmrg v.u.r = (FcRange *)r; 942953daebaSmrg return FcPatternObjectAdd (p, object, v, FcTrue); 943953daebaSmrg} 944953daebaSmrg 945953daebaSmrgFcBool 946953daebaSmrgFcPatternAddRange (FcPattern *p, const char *object, const FcRange *r) 947953daebaSmrg{ 948953daebaSmrg return FcPatternObjectAddRange (p, FcObjectFromName (object), r); 949953daebaSmrg} 950953daebaSmrg 9512c393a42SmrgFcResult 952a32e9e42SmrgFcPatternObjectGetWithBinding (const FcPattern *p, FcObject object, int id, FcValue *v, FcValueBinding *b) 9532c393a42Smrg{ 9542c393a42Smrg FcPatternElt *e; 9552c393a42Smrg FcValueListPtr l; 9562c393a42Smrg 957c9710b42Smrg if (!p) 958c9710b42Smrg return FcResultNoMatch; 9592c393a42Smrg e = FcPatternObjectFindElt (p, object); 9602c393a42Smrg if (!e) 9612c393a42Smrg return FcResultNoMatch; 9622c393a42Smrg for (l = FcPatternEltValues(e); l; l = FcValueListNext(l)) 9632c393a42Smrg { 9642c393a42Smrg if (!id) 9652c393a42Smrg { 9662c393a42Smrg *v = FcValueCanonicalize(&l->value); 967a32e9e42Smrg if (b) 968a32e9e42Smrg *b = l->binding; 9692c393a42Smrg return FcResultMatch; 9702c393a42Smrg } 9712c393a42Smrg id--; 9722c393a42Smrg } 9732c393a42Smrg return FcResultNoId; 9742c393a42Smrg} 9752c393a42Smrg 976a32e9e42SmrgFcResult 977a32e9e42SmrgFcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v) 978a32e9e42Smrg{ 979a32e9e42Smrg return FcPatternObjectGetWithBinding (p, object, id, v, NULL); 980a32e9e42Smrg} 981a32e9e42Smrg 982a32e9e42SmrgFcResult 983a32e9e42SmrgFcPatternGetWithBinding (const FcPattern *p, const char *object, int id, FcValue *v, FcValueBinding *b) 984a32e9e42Smrg{ 985a32e9e42Smrg return FcPatternObjectGetWithBinding (p, FcObjectFromName (object), id, v, b); 986a32e9e42Smrg} 987a32e9e42Smrg 9882c393a42SmrgFcResult 9892c393a42SmrgFcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v) 9902c393a42Smrg{ 991a32e9e42Smrg return FcPatternObjectGetWithBinding (p, FcObjectFromName (object), id, v, NULL); 9922c393a42Smrg} 9932c393a42Smrg 9942c393a42SmrgFcResult 9952c393a42SmrgFcPatternObjectGetInteger (const FcPattern *p, FcObject object, int id, int *i) 9962c393a42Smrg{ 9972c393a42Smrg FcValue v; 9982c393a42Smrg FcResult r; 9992c393a42Smrg 10002c393a42Smrg r = FcPatternObjectGet (p, object, id, &v); 10012c393a42Smrg if (r != FcResultMatch) 10022c393a42Smrg return r; 1003c9710b42Smrg switch ((int) v.type) { 10042c393a42Smrg case FcTypeDouble: 10052c393a42Smrg *i = (int) v.u.d; 10062c393a42Smrg break; 10072c393a42Smrg case FcTypeInteger: 10082c393a42Smrg *i = v.u.i; 10092c393a42Smrg break; 10102c393a42Smrg default: 10112c393a42Smrg return FcResultTypeMismatch; 10122c393a42Smrg } 10132c393a42Smrg return FcResultMatch; 10142c393a42Smrg} 10152c393a42Smrg 10162c393a42SmrgFcResult 10172c393a42SmrgFcPatternGetInteger (const FcPattern *p, const char *object, int id, int *i) 10182c393a42Smrg{ 10192c393a42Smrg return FcPatternObjectGetInteger (p, FcObjectFromName (object), id, i); 10202c393a42Smrg} 1021ca08ab68Smrg 1022ca08ab68Smrg 10232c393a42SmrgFcResult 10242c393a42SmrgFcPatternObjectGetDouble (const FcPattern *p, FcObject object, int id, double *d) 10252c393a42Smrg{ 10262c393a42Smrg FcValue v; 10272c393a42Smrg FcResult r; 10282c393a42Smrg 10292c393a42Smrg r = FcPatternObjectGet (p, object, id, &v); 10302c393a42Smrg if (r != FcResultMatch) 10312c393a42Smrg return r; 1032c9710b42Smrg switch ((int) v.type) { 10332c393a42Smrg case FcTypeDouble: 10342c393a42Smrg *d = v.u.d; 10352c393a42Smrg break; 10362c393a42Smrg case FcTypeInteger: 10372c393a42Smrg *d = (double) v.u.i; 10382c393a42Smrg break; 10392c393a42Smrg default: 10402c393a42Smrg return FcResultTypeMismatch; 10412c393a42Smrg } 10422c393a42Smrg return FcResultMatch; 10432c393a42Smrg} 10442c393a42Smrg 10452c393a42SmrgFcResult 10462c393a42SmrgFcPatternGetDouble (const FcPattern *p, const char *object, int id, double *d) 10472c393a42Smrg{ 10482c393a42Smrg return FcPatternObjectGetDouble (p, FcObjectFromName (object), id, d); 10492c393a42Smrg} 10502c393a42Smrg 10512c393a42SmrgFcResult 10522c393a42SmrgFcPatternObjectGetString (const FcPattern *p, FcObject object, int id, FcChar8 ** s) 10532c393a42Smrg{ 10542c393a42Smrg FcValue v; 10552c393a42Smrg FcResult r; 10562c393a42Smrg 10572c393a42Smrg r = FcPatternObjectGet (p, object, id, &v); 10582c393a42Smrg if (r != FcResultMatch) 10592c393a42Smrg return r; 10602c393a42Smrg if (v.type != FcTypeString) 10612c393a42Smrg return FcResultTypeMismatch; 10622c393a42Smrg 10632c393a42Smrg *s = (FcChar8 *) v.u.s; 10642c393a42Smrg return FcResultMatch; 10652c393a42Smrg} 10662c393a42Smrg 10672c393a42SmrgFcResult 10682c393a42SmrgFcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s) 10692c393a42Smrg{ 10702c393a42Smrg return FcPatternObjectGetString (p, FcObjectFromName (object), id, s); 10712c393a42Smrg} 1072ca08ab68Smrg 10732c393a42SmrgFcResult 10742c393a42SmrgFcPatternGetMatrix(const FcPattern *p, const char *object, int id, FcMatrix **m) 10752c393a42Smrg{ 10762c393a42Smrg FcValue v; 10772c393a42Smrg FcResult r; 10782c393a42Smrg 10792c393a42Smrg r = FcPatternGet (p, object, id, &v); 10802c393a42Smrg if (r != FcResultMatch) 10812c393a42Smrg return r; 10822c393a42Smrg if (v.type != FcTypeMatrix) 10832c393a42Smrg return FcResultTypeMismatch; 10842c393a42Smrg *m = (FcMatrix *)v.u.m; 10852c393a42Smrg return FcResultMatch; 10862c393a42Smrg} 10872c393a42Smrg 10882c393a42Smrg 10892c393a42SmrgFcResult 1090a32e9e42SmrgFcPatternObjectGetBool (const FcPattern *p, FcObject object, int id, FcBool *b) 10912c393a42Smrg{ 10922c393a42Smrg FcValue v; 10932c393a42Smrg FcResult r; 10942c393a42Smrg 1095a32e9e42Smrg r = FcPatternObjectGet (p, object, id, &v); 10962c393a42Smrg if (r != FcResultMatch) 10972c393a42Smrg return r; 10982c393a42Smrg if (v.type != FcTypeBool) 10992c393a42Smrg return FcResultTypeMismatch; 11002c393a42Smrg *b = v.u.b; 11012c393a42Smrg return FcResultMatch; 11022c393a42Smrg} 11032c393a42Smrg 1104a32e9e42SmrgFcResult 1105a32e9e42SmrgFcPatternGetBool(const FcPattern *p, const char *object, int id, FcBool *b) 1106a32e9e42Smrg{ 1107a32e9e42Smrg return FcPatternObjectGetBool (p, FcObjectFromName (object), id, b); 1108a32e9e42Smrg} 1109a32e9e42Smrg 11102c393a42SmrgFcResult 11112c393a42SmrgFcPatternGetCharSet(const FcPattern *p, const char *object, int id, FcCharSet **c) 11122c393a42Smrg{ 11132c393a42Smrg FcValue v; 11142c393a42Smrg FcResult r; 11152c393a42Smrg 11162c393a42Smrg r = FcPatternGet (p, object, id, &v); 11172c393a42Smrg if (r != FcResultMatch) 11182c393a42Smrg return r; 11192c393a42Smrg if (v.type != FcTypeCharSet) 11202c393a42Smrg return FcResultTypeMismatch; 11212c393a42Smrg *c = (FcCharSet *)v.u.c; 11222c393a42Smrg return FcResultMatch; 11232c393a42Smrg} 11242c393a42Smrg 11252c393a42SmrgFcResult 11262c393a42SmrgFcPatternGetFTFace(const FcPattern *p, const char *object, int id, FT_Face *f) 11272c393a42Smrg{ 11282c393a42Smrg FcValue v; 11292c393a42Smrg FcResult r; 11302c393a42Smrg 11312c393a42Smrg r = FcPatternGet (p, object, id, &v); 11322c393a42Smrg if (r != FcResultMatch) 11332c393a42Smrg return r; 11342c393a42Smrg if (v.type != FcTypeFTFace) 11352c393a42Smrg return FcResultTypeMismatch; 11362c393a42Smrg *f = (FT_Face) v.u.f; 11372c393a42Smrg return FcResultMatch; 11382c393a42Smrg} 11392c393a42Smrg 11402c393a42SmrgFcResult 11412c393a42SmrgFcPatternGetLangSet(const FcPattern *p, const char *object, int id, FcLangSet **ls) 11422c393a42Smrg{ 11432c393a42Smrg FcValue v; 11442c393a42Smrg FcResult r; 11452c393a42Smrg 11462c393a42Smrg r = FcPatternGet (p, object, id, &v); 11472c393a42Smrg if (r != FcResultMatch) 11482c393a42Smrg return r; 11492c393a42Smrg if (v.type != FcTypeLangSet) 11502c393a42Smrg return FcResultTypeMismatch; 11512c393a42Smrg *ls = (FcLangSet *)v.u.l; 11522c393a42Smrg return FcResultMatch; 11532c393a42Smrg} 11542c393a42Smrg 1155953daebaSmrgFcResult 1156953daebaSmrgFcPatternObjectGetRange (const FcPattern *p, FcObject object, int id, FcRange **r) 1157953daebaSmrg{ 1158953daebaSmrg FcValue v; 1159953daebaSmrg FcResult res; 1160953daebaSmrg 1161953daebaSmrg res = FcPatternObjectGet (p, object, id, &v); 1162953daebaSmrg if (res != FcResultMatch) 1163953daebaSmrg return res; 1164953daebaSmrg switch ((int)v.type) { 1165953daebaSmrg case FcTypeRange: 1166953daebaSmrg *r = (FcRange *)v.u.r; 1167953daebaSmrg break; 1168953daebaSmrg default: 1169953daebaSmrg return FcResultTypeMismatch; 1170953daebaSmrg } 1171953daebaSmrg return FcResultMatch; 1172953daebaSmrg} 1173953daebaSmrg 1174953daebaSmrgFcResult 1175953daebaSmrgFcPatternGetRange (const FcPattern *p, const char *object, int id, FcRange **r) 1176953daebaSmrg{ 1177953daebaSmrg return FcPatternObjectGetRange (p, FcObjectFromName (object), id, r); 1178953daebaSmrg} 1179953daebaSmrg 11802c393a42SmrgFcPattern * 11812c393a42SmrgFcPatternDuplicate (const FcPattern *orig) 11822c393a42Smrg{ 11832c393a42Smrg FcPattern *new; 1184a32e9e42Smrg FcPatternIter iter; 11852c393a42Smrg FcValueListPtr l; 11862c393a42Smrg 1187a32e9e42Smrg if (!orig) 1188a32e9e42Smrg return NULL; 1189a32e9e42Smrg 11902c393a42Smrg new = FcPatternCreate (); 11912c393a42Smrg if (!new) 11922c393a42Smrg goto bail0; 11932c393a42Smrg 1194a32e9e42Smrg FcPatternIterStart (orig, &iter); 1195a32e9e42Smrg do 11962c393a42Smrg { 1197a32e9e42Smrg for (l = FcPatternIterGetValues (orig, &iter); l; l = FcValueListNext (l)) 11982c393a42Smrg { 1199a32e9e42Smrg if (!FcPatternObjectAddWithBinding (new, FcPatternIterGetObjectId (orig, &iter), 12002c393a42Smrg FcValueCanonicalize(&l->value), 12012c393a42Smrg l->binding, 12022c393a42Smrg FcTrue)) 12032c393a42Smrg goto bail1; 12042c393a42Smrg } 1205a32e9e42Smrg } while (FcPatternIterNext (orig, &iter)); 12062c393a42Smrg 12072c393a42Smrg return new; 12082c393a42Smrg 12092c393a42Smrgbail1: 12102c393a42Smrg FcPatternDestroy (new); 12112c393a42Smrgbail0: 12122c393a42Smrg return 0; 12132c393a42Smrg} 12142c393a42Smrg 12152c393a42Smrgvoid 12162c393a42SmrgFcPatternReference (FcPattern *p) 12172c393a42Smrg{ 1218c9710b42Smrg if (!FcRefIsConst (&p->ref)) 1219c9710b42Smrg FcRefInc (&p->ref); 12202c393a42Smrg else 1221a32e9e42Smrg FcCacheObjectReference (FcPatternGetCacheObject(p)); 12222c393a42Smrg} 12232c393a42Smrg 12242c393a42SmrgFcPattern * 1225a6844aabSmrgFcPatternVaBuild (FcPattern *p, va_list va) 12262c393a42Smrg{ 12272c393a42Smrg FcPattern *ret; 1228ca08ab68Smrg 1229a6844aabSmrg FcPatternVapBuild (ret, p, va); 12302c393a42Smrg return ret; 12312c393a42Smrg} 12322c393a42Smrg 12332c393a42SmrgFcPattern * 1234a6844aabSmrgFcPatternBuild (FcPattern *p, ...) 12352c393a42Smrg{ 12362c393a42Smrg va_list va; 1237ca08ab68Smrg 1238a6844aabSmrg va_start (va, p); 1239a6844aabSmrg FcPatternVapBuild (p, p, va); 12402c393a42Smrg va_end (va); 1241a6844aabSmrg return p; 12422c393a42Smrg} 12432c393a42Smrg 12442c393a42Smrg/* 12452c393a42Smrg * Add all of the elements in 's' to 'p' 12462c393a42Smrg */ 12472c393a42SmrgFcBool 12482c393a42SmrgFcPatternAppend (FcPattern *p, FcPattern *s) 12492c393a42Smrg{ 1250a32e9e42Smrg FcPatternIter iter; 1251a32e9e42Smrg FcValueListPtr v; 1252ca08ab68Smrg 1253a32e9e42Smrg FcPatternIterStart (s, &iter); 1254a32e9e42Smrg do 12552c393a42Smrg { 1256a32e9e42Smrg for (v = FcPatternIterGetValues (s, &iter); v; v = FcValueListNext (v)) 12572c393a42Smrg { 1258a32e9e42Smrg if (!FcPatternObjectAddWithBinding (p, FcPatternIterGetObjectId (s, &iter), 1259ca08ab68Smrg FcValueCanonicalize(&v->value), 12602c393a42Smrg v->binding, FcTrue)) 12612c393a42Smrg return FcFalse; 12622c393a42Smrg } 1263a32e9e42Smrg } while (FcPatternIterNext (s, &iter)); 1264a32e9e42Smrg 12652c393a42Smrg return FcTrue; 12662c393a42Smrg} 12672c393a42Smrg 1268a6844aabSmrgFcPattern * 1269a6844aabSmrgFcPatternFilter (FcPattern *p, const FcObjectSet *os) 1270a6844aabSmrg{ 1271a6844aabSmrg int i; 1272a6844aabSmrg FcPattern *ret; 1273a6844aabSmrg FcPatternElt *e; 1274a6844aabSmrg FcValueListPtr v; 1275a6844aabSmrg 1276a6844aabSmrg if (!os) 1277a6844aabSmrg return FcPatternDuplicate (p); 1278a6844aabSmrg 1279a6844aabSmrg ret = FcPatternCreate (); 1280a6844aabSmrg if (!ret) 1281a6844aabSmrg return NULL; 1282a6844aabSmrg 1283a6844aabSmrg for (i = 0; i < os->nobject; i++) 1284a6844aabSmrg { 1285a6844aabSmrg FcObject object = FcObjectFromName (os->objects[i]); 1286a6844aabSmrg e = FcPatternObjectFindElt (p, object); 1287a6844aabSmrg if (e) 1288a6844aabSmrg { 1289a6844aabSmrg for (v = FcPatternEltValues(e); v; v = FcValueListNext(v)) 1290a6844aabSmrg { 1291a6844aabSmrg if (!FcPatternObjectAddWithBinding (ret, e->object, 1292a6844aabSmrg FcValueCanonicalize(&v->value), 1293a6844aabSmrg v->binding, FcTrue)) 1294a6844aabSmrg goto bail0; 1295a6844aabSmrg } 1296a6844aabSmrg } 1297a6844aabSmrg } 1298a6844aabSmrg return ret; 1299a6844aabSmrg 1300a6844aabSmrgbail0: 1301a6844aabSmrg FcPatternDestroy (ret); 1302a6844aabSmrg return NULL; 1303a6844aabSmrg} 1304a6844aabSmrg 1305a32e9e42Smrgtypedef struct _FcPatternPrivateIter { 1306a32e9e42Smrg FcPatternElt *elt; 1307a32e9e42Smrg int pos; 1308a32e9e42Smrg} FcPatternPrivateIter; 1309a32e9e42Smrg 1310a32e9e42Smrgstatic void 1311a32e9e42SmrgFcPatternIterSet (const FcPattern *pat, FcPatternPrivateIter *iter) 1312a32e9e42Smrg{ 1313a32e9e42Smrg iter->elt = FcPatternObjectCount (pat) > 0 && iter->pos < FcPatternObjectCount (pat) ? &FcPatternElts (pat)[iter->pos] : NULL; 1314a32e9e42Smrg} 1315a32e9e42Smrg 1316a32e9e42Smrgvoid 1317a32e9e42SmrgFcPatternIterStart (const FcPattern *pat, FcPatternIter *iter) 1318a32e9e42Smrg{ 1319a32e9e42Smrg FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter; 1320a32e9e42Smrg 1321a32e9e42Smrg priv->pos = 0; 1322a32e9e42Smrg FcPatternIterSet (pat, priv); 1323a32e9e42Smrg} 1324a32e9e42Smrg 1325a32e9e42SmrgFcBool 1326a32e9e42SmrgFcPatternIterNext (const FcPattern *pat, FcPatternIter *iter) 1327a32e9e42Smrg{ 1328a32e9e42Smrg FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter; 1329a32e9e42Smrg 1330a32e9e42Smrg priv->pos++; 1331a32e9e42Smrg if (priv->pos >= FcPatternObjectCount (pat)) 1332a32e9e42Smrg return FcFalse; 1333a32e9e42Smrg FcPatternIterSet (pat, priv); 1334a32e9e42Smrg 1335a32e9e42Smrg return FcTrue; 1336a32e9e42Smrg} 1337a32e9e42Smrg 1338a32e9e42SmrgFcBool 1339a32e9e42SmrgFcPatternIterEqual (const FcPattern *p1, FcPatternIter *i1, 1340a32e9e42Smrg const FcPattern *p2, FcPatternIter *i2) 1341a32e9e42Smrg{ 1342a32e9e42Smrg FcBool b1 = FcPatternIterIsValid (p1, i1); 1343a32e9e42Smrg FcBool b2 = FcPatternIterIsValid (p2, i2); 1344a32e9e42Smrg 1345a32e9e42Smrg if (!i1 && !i2) 1346a32e9e42Smrg return FcTrue; 1347a32e9e42Smrg if (!b1 || !b2) 1348a32e9e42Smrg return FcFalse; 1349a32e9e42Smrg if (FcPatternIterGetObjectId (p1, i1) != FcPatternIterGetObjectId (p2, i2)) 1350a32e9e42Smrg return FcFalse; 1351a32e9e42Smrg 1352a32e9e42Smrg return FcValueListEqual (FcPatternIterGetValues (p1, i1), 1353a32e9e42Smrg FcPatternIterGetValues (p2, i2)); 1354a32e9e42Smrg} 1355a32e9e42Smrg 1356a32e9e42SmrgFcBool 1357a32e9e42SmrgFcPatternFindObjectIter (const FcPattern *pat, FcPatternIter *iter, FcObject object) 1358a32e9e42Smrg{ 1359a32e9e42Smrg FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter; 1360a32e9e42Smrg int i = FcPatternObjectPosition (pat, object); 1361a32e9e42Smrg 1362a32e9e42Smrg priv->elt = NULL; 1363a32e9e42Smrg if (i < 0) 1364a32e9e42Smrg return FcFalse; 1365a32e9e42Smrg 1366a32e9e42Smrg priv->pos = i; 1367a32e9e42Smrg FcPatternIterSet (pat, priv); 1368a32e9e42Smrg 1369a32e9e42Smrg return FcTrue; 1370a32e9e42Smrg} 1371a32e9e42Smrg 1372a32e9e42SmrgFcBool 1373a32e9e42SmrgFcPatternFindIter (const FcPattern *pat, FcPatternIter *iter, const char *object) 1374a32e9e42Smrg{ 1375a32e9e42Smrg return FcPatternFindObjectIter (pat, iter, FcObjectFromName (object)); 1376a32e9e42Smrg} 1377a32e9e42Smrg 1378a32e9e42SmrgFcBool 1379a32e9e42SmrgFcPatternIterIsValid (const FcPattern *pat, FcPatternIter *iter) 1380a32e9e42Smrg{ 1381a32e9e42Smrg FcPatternPrivateIter *priv = (FcPatternPrivateIter *)iter; 1382a32e9e42Smrg 1383a32e9e42Smrg if (priv && priv->elt) 1384a32e9e42Smrg return FcTrue; 1385a32e9e42Smrg 1386a32e9e42Smrg return FcFalse; 1387a32e9e42Smrg} 1388a32e9e42Smrg 1389a32e9e42SmrgFcObject 1390a32e9e42SmrgFcPatternIterGetObjectId (const FcPattern *pat, FcPatternIter *iter) 1391a32e9e42Smrg{ 1392a32e9e42Smrg FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter; 1393a32e9e42Smrg 1394a32e9e42Smrg if (priv && priv->elt) 1395a32e9e42Smrg return priv->elt->object; 1396a32e9e42Smrg 1397a32e9e42Smrg return 0; 1398a32e9e42Smrg} 1399a32e9e42Smrg 1400a32e9e42Smrgconst char * 1401a32e9e42SmrgFcPatternIterGetObject (const FcPattern *pat, FcPatternIter *iter) 1402a32e9e42Smrg{ 1403a32e9e42Smrg return FcObjectName (FcPatternIterGetObjectId (pat, iter)); 1404a32e9e42Smrg} 1405a32e9e42Smrg 1406a32e9e42SmrgFcValueListPtr 1407a32e9e42SmrgFcPatternIterGetValues (const FcPattern *pat, FcPatternIter *iter) 1408a32e9e42Smrg{ 1409a32e9e42Smrg FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter; 1410a32e9e42Smrg 1411a32e9e42Smrg if (priv && priv->elt) 1412a32e9e42Smrg return FcPatternEltValues (priv->elt); 1413a32e9e42Smrg 1414a32e9e42Smrg return NULL; 1415a32e9e42Smrg} 1416a32e9e42Smrg 1417a32e9e42Smrgint 1418a32e9e42SmrgFcPatternIterValueCount (const FcPattern *pat, FcPatternIter *iter) 1419a32e9e42Smrg{ 1420a32e9e42Smrg int count = 0; 1421a32e9e42Smrg FcValueListPtr l; 1422a32e9e42Smrg 1423a32e9e42Smrg for (l = FcPatternIterGetValues (pat, iter); l; l = FcValueListNext (l)) 1424a32e9e42Smrg count++; 1425a32e9e42Smrg 1426a32e9e42Smrg return count; 1427a32e9e42Smrg} 1428a32e9e42Smrg 1429a32e9e42SmrgFcResult 1430a32e9e42SmrgFcPatternIterGetValue (const FcPattern *pat, FcPatternIter *iter, int id, FcValue *v, FcValueBinding *b) 1431a32e9e42Smrg{ 1432a32e9e42Smrg FcValueListPtr l; 1433a32e9e42Smrg 1434a32e9e42Smrg for (l = FcPatternIterGetValues (pat, iter); l; l = FcValueListNext (l)) 1435a32e9e42Smrg { 1436a32e9e42Smrg if (id == 0) 1437a32e9e42Smrg { 1438a32e9e42Smrg *v = FcValueCanonicalize (&l->value); 1439a32e9e42Smrg if (b) 1440a32e9e42Smrg *b = l->binding; 1441a32e9e42Smrg return FcResultMatch; 1442a32e9e42Smrg } 1443a32e9e42Smrg id--; 1444a32e9e42Smrg } 1445a32e9e42Smrg return FcResultNoId; 1446a32e9e42Smrg} 14472c393a42Smrg 14482c393a42SmrgFcBool 14492c393a42SmrgFcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat) 14502c393a42Smrg{ 14512c393a42Smrg int i; 14522c393a42Smrg FcPatternElt *elts = FcPatternElts(pat); 1453ca08ab68Smrg 14542c393a42Smrg if (!FcSerializeAlloc (serialize, pat, sizeof (FcPattern))) 14552c393a42Smrg return FcFalse; 1456a32e9e42Smrg if (!FcSerializeAlloc (serialize, elts, FcPatternObjectCount (pat) * sizeof (FcPatternElt))) 14572c393a42Smrg return FcFalse; 1458a32e9e42Smrg for (i = 0; i < FcPatternObjectCount (pat); i++) 14592c393a42Smrg if (!FcValueListSerializeAlloc (serialize, FcPatternEltValues(elts+i))) 14602c393a42Smrg return FcFalse; 14612c393a42Smrg return FcTrue; 14622c393a42Smrg} 14632c393a42Smrg 14642c393a42SmrgFcPattern * 14652c393a42SmrgFcPatternSerialize (FcSerialize *serialize, const FcPattern *pat) 14662c393a42Smrg{ 14672c393a42Smrg FcPattern *pat_serialized; 14682c393a42Smrg FcPatternElt *elts = FcPatternElts (pat); 14692c393a42Smrg FcPatternElt *elts_serialized; 14702c393a42Smrg FcValueList *values_serialized; 14712c393a42Smrg int i; 14722c393a42Smrg 14732c393a42Smrg pat_serialized = FcSerializePtr (serialize, pat); 14742c393a42Smrg if (!pat_serialized) 14752c393a42Smrg return NULL; 14762c393a42Smrg *pat_serialized = *pat; 1477a32e9e42Smrg pat_serialized->size = FcPatternObjectCount (pat); 1478c9710b42Smrg FcRefSetConst (&pat_serialized->ref); 1479ca08ab68Smrg 14802c393a42Smrg elts_serialized = FcSerializePtr (serialize, elts); 14812c393a42Smrg if (!elts_serialized) 14822c393a42Smrg return NULL; 1483ca08ab68Smrg 14842c393a42Smrg pat_serialized->elts_offset = FcPtrToOffset (pat_serialized, 14852c393a42Smrg elts_serialized); 14862c393a42Smrg 1487a32e9e42Smrg for (i = 0; i < FcPatternObjectCount (pat); i++) 14882c393a42Smrg { 14892c393a42Smrg values_serialized = FcValueListSerialize (serialize, FcPatternEltValues (elts+i)); 14902c393a42Smrg if (!values_serialized) 14912c393a42Smrg return NULL; 14922c393a42Smrg elts_serialized[i].object = elts[i].object; 1493ca08ab68Smrg elts_serialized[i].values = FcPtrToEncodedOffset (&elts_serialized[i], 14942c393a42Smrg values_serialized, 14952c393a42Smrg FcValueList); 14962c393a42Smrg } 14972c393a42Smrg if (FcDebug() & FC_DBG_CACHEV) { 14982c393a42Smrg printf ("Raw pattern:\n"); 14992c393a42Smrg FcPatternPrint (pat); 15002c393a42Smrg printf ("Serialized pattern:\n"); 15012c393a42Smrg FcPatternPrint (pat_serialized); 15022c393a42Smrg printf ("\n"); 15032c393a42Smrg } 15042c393a42Smrg return pat_serialized; 15052c393a42Smrg} 15062c393a42Smrg 15072c393a42SmrgFcBool 15082c393a42SmrgFcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *vl) 15092c393a42Smrg{ 15102c393a42Smrg while (vl) 15112c393a42Smrg { 15122c393a42Smrg if (!FcSerializeAlloc (serialize, vl, sizeof (FcValueList))) 15132c393a42Smrg return FcFalse; 1514c9710b42Smrg switch ((int) vl->value.type) { 15152c393a42Smrg case FcTypeString: 15162c393a42Smrg if (!FcStrSerializeAlloc (serialize, vl->value.u.s)) 15172c393a42Smrg return FcFalse; 15182c393a42Smrg break; 15192c393a42Smrg case FcTypeCharSet: 15202c393a42Smrg if (!FcCharSetSerializeAlloc (serialize, vl->value.u.c)) 15212c393a42Smrg return FcFalse; 15222c393a42Smrg break; 15232c393a42Smrg case FcTypeLangSet: 15242c393a42Smrg if (!FcLangSetSerializeAlloc (serialize, vl->value.u.l)) 15252c393a42Smrg return FcFalse; 15262c393a42Smrg break; 1527953daebaSmrg case FcTypeRange: 1528953daebaSmrg if (!FcRangeSerializeAlloc (serialize, vl->value.u.r)) 1529953daebaSmrg return FcFalse; 1530953daebaSmrg break; 15312c393a42Smrg default: 15322c393a42Smrg break; 15332c393a42Smrg } 15342c393a42Smrg vl = vl->next; 15352c393a42Smrg } 15362c393a42Smrg return FcTrue; 15372c393a42Smrg} 15382c393a42Smrg 15392c393a42SmrgFcValueList * 15402c393a42SmrgFcValueListSerialize (FcSerialize *serialize, const FcValueList *vl) 15412c393a42Smrg{ 15422c393a42Smrg FcValueList *vl_serialized; 15432c393a42Smrg FcChar8 *s_serialized; 15442c393a42Smrg FcCharSet *c_serialized; 15452c393a42Smrg FcLangSet *l_serialized; 1546953daebaSmrg FcRange *r_serialized; 15472c393a42Smrg FcValueList *head_serialized = NULL; 15482c393a42Smrg FcValueList *prev_serialized = NULL; 15492c393a42Smrg 15502c393a42Smrg while (vl) 15512c393a42Smrg { 15522c393a42Smrg vl_serialized = FcSerializePtr (serialize, vl); 15532c393a42Smrg if (!vl_serialized) 15542c393a42Smrg return NULL; 1555ca08ab68Smrg 15562c393a42Smrg if (prev_serialized) 15572c393a42Smrg prev_serialized->next = FcPtrToEncodedOffset (prev_serialized, 15582c393a42Smrg vl_serialized, 15592c393a42Smrg FcValueList); 15602c393a42Smrg else 15612c393a42Smrg head_serialized = vl_serialized; 15621cc69409Smrg 15632c393a42Smrg vl_serialized->next = NULL; 15642c393a42Smrg vl_serialized->value.type = vl->value.type; 1565c9710b42Smrg switch ((int) vl->value.type) { 15662c393a42Smrg case FcTypeInteger: 15672c393a42Smrg vl_serialized->value.u.i = vl->value.u.i; 15682c393a42Smrg break; 15692c393a42Smrg case FcTypeDouble: 15702c393a42Smrg vl_serialized->value.u.d = vl->value.u.d; 15712c393a42Smrg break; 15722c393a42Smrg case FcTypeString: 15732c393a42Smrg s_serialized = FcStrSerialize (serialize, vl->value.u.s); 15742c393a42Smrg if (!s_serialized) 15752c393a42Smrg return NULL; 15762c393a42Smrg vl_serialized->value.u.s = FcPtrToEncodedOffset (&vl_serialized->value, 15772c393a42Smrg s_serialized, 15782c393a42Smrg FcChar8); 15792c393a42Smrg break; 15802c393a42Smrg case FcTypeBool: 15812c393a42Smrg vl_serialized->value.u.b = vl->value.u.b; 15822c393a42Smrg break; 15832c393a42Smrg case FcTypeMatrix: 15842c393a42Smrg /* can't happen */ 15852c393a42Smrg break; 15862c393a42Smrg case FcTypeCharSet: 15872c393a42Smrg c_serialized = FcCharSetSerialize (serialize, vl->value.u.c); 15882c393a42Smrg if (!c_serialized) 15892c393a42Smrg return NULL; 15902c393a42Smrg vl_serialized->value.u.c = FcPtrToEncodedOffset (&vl_serialized->value, 15912c393a42Smrg c_serialized, 15922c393a42Smrg FcCharSet); 15932c393a42Smrg break; 15942c393a42Smrg case FcTypeFTFace: 15952c393a42Smrg /* can't happen */ 15962c393a42Smrg break; 15972c393a42Smrg case FcTypeLangSet: 15982c393a42Smrg l_serialized = FcLangSetSerialize (serialize, vl->value.u.l); 15992c393a42Smrg if (!l_serialized) 16002c393a42Smrg return NULL; 16012c393a42Smrg vl_serialized->value.u.l = FcPtrToEncodedOffset (&vl_serialized->value, 16022c393a42Smrg l_serialized, 16032c393a42Smrg FcLangSet); 16042c393a42Smrg break; 1605953daebaSmrg case FcTypeRange: 1606953daebaSmrg r_serialized = FcRangeSerialize (serialize, vl->value.u.r); 1607953daebaSmrg if (!r_serialized) 1608953daebaSmrg return NULL; 1609953daebaSmrg vl_serialized->value.u.r = FcPtrToEncodedOffset (&vl_serialized->value, 1610953daebaSmrg r_serialized, 1611953daebaSmrg FcRange); 1612953daebaSmrg break; 16132c393a42Smrg default: 16142c393a42Smrg break; 16152c393a42Smrg } 16162c393a42Smrg prev_serialized = vl_serialized; 16172c393a42Smrg vl = vl->next; 16182c393a42Smrg } 16192c393a42Smrg return head_serialized; 16202c393a42Smrg} 1621b09479dcSmrg 16222c393a42Smrg#define __fcpat__ 16232c393a42Smrg#include "fcaliastail.h" 16242c393a42Smrg#include "fcftaliastail.h" 16252c393a42Smrg#undef __fcpat__ 1626