source: fontconfig_os2/trunk/src/fcpat.c@ 1172

Last change on this file since 1172 was 1172, checked in by Silvan Scherrer, 9 years ago

fontconfig: update to 2.11.94 small change

File size: 20.9 KB
Line 
1/*
2 * Copyright ž 2000 Keith Packard
3 *
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.
13 *
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.
21 *
22 * Contributors:
23 * Doodle <doodle@netlabs.org>
24 * Peter Weilbacher <mozilla@weilbacher.org>
25 * KO Myung-Hun <komh78@gmail.com>
26 * Alex Taylor <alex@altsan.org>
27 * Rich Walsh <rich@e-vertise.com>
28 * Silvan Scherrer <silvan.scherrer@aroa.ch>
29 *
30 */
31
32#include "fcint.h"
33
34FcPattern *
35FcPatternCreate (void)
36{
37 FcPattern *p;
38
39 p = (FcPattern *) malloc (sizeof (FcPattern));
40 if (!p)
41 return 0;
42 memset (p, 0, sizeof (FcPattern));
43 p->num = 0;
44 p->size = 0;
45 p->elts_offset = FcPtrToOffset (p, NULL);
46 FcRefInit (&p->ref, 1);
47 return p;
48}
49
50void
51FcValueDestroy (FcValue v)
52{
53 switch ((int) v.type) {
54 case FcTypeString:
55 FcFree (v.u.s);
56 break;
57 case FcTypeMatrix:
58 FcMatrixFree ((FcMatrix *) v.u.m);
59 break;
60 case FcTypeCharSet:
61 FcCharSetDestroy ((FcCharSet *) v.u.c);
62 break;
63 case FcTypeLangSet:
64 FcLangSetDestroy ((FcLangSet *) v.u.l);
65 break;
66 case FcTypeRange:
67 FcRangeDestroy ((FcRange *) v.u.r);
68 break;
69 default:
70 break;
71 }
72}
73
74FcValue
75FcValueCanonicalize (const FcValue *v)
76{
77 FcValue new;
78
79 switch ((int) v->type)
80 {
81 case FcTypeString:
82 new.u.s = FcValueString(v);
83 new.type = FcTypeString;
84 break;
85 case FcTypeCharSet:
86 new.u.c = FcValueCharSet(v);
87 new.type = FcTypeCharSet;
88 break;
89 case FcTypeLangSet:
90 new.u.l = FcValueLangSet(v);
91 new.type = FcTypeLangSet;
92 break;
93 case FcTypeRange:
94 new.u.r = FcValueRange(v);
95 new.type = FcTypeRange;
96 break;
97 default:
98 new = *v;
99 break;
100 }
101 return new;
102}
103
104FcValue
105FcValueSave (FcValue v)
106{
107 switch ((int) v.type) {
108 case FcTypeString:
109 v.u.s = FcStrdup (v.u.s);
110 if (!v.u.s)
111 v.type = FcTypeVoid;
112 break;
113 case FcTypeMatrix:
114 v.u.m = FcMatrixCopy (v.u.m);
115 if (!v.u.m)
116 v.type = FcTypeVoid;
117 break;
118 case FcTypeCharSet:
119 v.u.c = FcCharSetCopy ((FcCharSet *) v.u.c);
120 if (!v.u.c)
121 v.type = FcTypeVoid;
122 break;
123 case FcTypeLangSet:
124 v.u.l = FcLangSetCopy (v.u.l);
125 if (!v.u.l)
126 v.type = FcTypeVoid;
127 break;
128 case FcTypeRange:
129 v.u.r = FcRangeCopy (v.u.r);
130 if (!v.u.r)
131 v.type = FcTypeVoid;
132 break;
133 default:
134 break;
135 }
136 return v;
137}
138
139FcValueListPtr
140FcValueListCreate (void)
141{
142 return calloc (1, sizeof (FcValueList));
143}
144
145void
146FcValueListDestroy (FcValueListPtr l)
147{
148 FcValueListPtr next;
149 for (; l; l = next)
150 {
151 switch ((int) l->value.type) {
152 case FcTypeString:
153 FcFree (l->value.u.s);
154 break;
155 case FcTypeMatrix:
156 FcMatrixFree ((FcMatrix *)l->value.u.m);
157 break;
158 case FcTypeCharSet:
159 FcCharSetDestroy
160 ((FcCharSet *) (l->value.u.c));
161 break;
162 case FcTypeLangSet:
163 FcLangSetDestroy
164 ((FcLangSet *) (l->value.u.l));
165 break;
166 case FcTypeRange:
167 FcRangeDestroy ((FcRange *) (l->value.u.r));
168 break;
169 default:
170 break;
171 }
172 next = FcValueListNext(l);
173 free(l);
174 }
175}
176
177FcValueListPtr
178FcValueListPrepend (FcValueListPtr vallist,
179 FcValue value,
180 FcValueBinding binding)
181{
182 FcValueListPtr new;
183
184 if (value.type == FcTypeVoid)
185 return vallist;
186 new = FcValueListCreate ();
187 if (!new)
188 return vallist;
189
190 new->value = FcValueSave (value);
191 new->binding = binding;
192 new->next = vallist;
193
194 return new;
195}
196
197FcValueListPtr
198FcValueListAppend (FcValueListPtr vallist,
199 FcValue value,
200 FcValueBinding binding)
201{
202 FcValueListPtr new, last;
203
204 if (value.type == FcTypeVoid)
205 return vallist;
206 new = FcValueListCreate ();
207 if (!new)
208 return vallist;
209
210 new->value = FcValueSave (value);
211 new->binding = binding;
212 new->next = NULL;
213
214 if (vallist)
215 {
216 for (last = vallist; FcValueListNext (last); last = FcValueListNext (last));
217
218 last->next = new;
219 }
220 else
221 vallist = new;
222
223 return vallist;
224}
225
226FcValueListPtr
227FcValueListDuplicate(FcValueListPtr orig)
228{
229 FcValueListPtr new = NULL, l, t = NULL;
230 FcValue v;
231
232 for (l = orig; l != NULL; l = FcValueListNext (l))
233 {
234 if (!new)
235 {
236 t = new = FcValueListCreate();
237 }
238 else
239 {
240 t->next = FcValueListCreate();
241 t = FcValueListNext (t);
242 }
243 v = FcValueCanonicalize (&l->value);
244 t->value = FcValueSave (v);
245 t->binding = l->binding;
246 t->next = NULL;
247 }
248
249 return new;
250}
251
252FcBool
253FcValueEqual (FcValue va, FcValue vb)
254{
255 if (va.type != vb.type)
256 {
257 if (va.type == FcTypeInteger)
258 {
259 va.type = FcTypeDouble;
260 va.u.d = va.u.i;
261 }
262 if (vb.type == FcTypeInteger)
263 {
264 vb.type = FcTypeDouble;
265 vb.u.d = vb.u.i;
266 }
267 if (va.type != vb.type)
268 return FcFalse;
269 }
270 switch (va.type) {
271 case FcTypeUnknown:
272 return FcFalse; /* don't know how to compare this object */
273 case FcTypeVoid:
274 return FcTrue;
275 case FcTypeInteger:
276 return va.u.i == vb.u.i;
277 case FcTypeDouble:
278 return va.u.d == vb.u.d;
279 case FcTypeString:
280 return FcStrCmpIgnoreCase (va.u.s, vb.u.s) == 0;
281 case FcTypeBool:
282 return va.u.b == vb.u.b;
283 case FcTypeMatrix:
284 return FcMatrixEqual (va.u.m, vb.u.m);
285 case FcTypeCharSet:
286 return FcCharSetEqual (va.u.c, vb.u.c);
287 case FcTypeFTFace:
288 return va.u.f == vb.u.f;
289 case FcTypeLangSet:
290 return FcLangSetEqual (va.u.l, vb.u.l);
291 case FcTypeRange:
292 return FcRangeIsInRange (va.u.r, vb.u.r);
293 }
294 return FcFalse;
295}
296
297static FcChar32
298FcDoubleHash (double d)
299{
300 if (d < 0)
301 d = -d;
302 if (d > 0xffffffff)
303 d = 0xffffffff;
304 return (FcChar32) d;
305}
306
307FcChar32
308FcStringHash (const FcChar8 *s)
309{
310 FcChar8 c;
311 FcChar32 h = 0;
312
313 if (s)
314 while ((c = *s++))
315 h = ((h << 1) | (h >> 31)) ^ c;
316 return h;
317}
318
319static FcChar32
320FcValueHash (const FcValue *v)
321{
322 switch (v->type) {
323 case FcTypeUnknown:
324 case FcTypeVoid:
325 return 0;
326 case FcTypeInteger:
327 return (FcChar32) v->u.i;
328 case FcTypeDouble:
329 return FcDoubleHash (v->u.d);
330 case FcTypeString:
331 return FcStringHash (FcValueString(v));
332 case FcTypeBool:
333 return (FcChar32) v->u.b;
334 case FcTypeMatrix:
335 return (FcDoubleHash (v->u.m->xx) ^
336 FcDoubleHash (v->u.m->xy) ^
337 FcDoubleHash (v->u.m->yx) ^
338 FcDoubleHash (v->u.m->yy));
339 case FcTypeCharSet:
340 return (FcChar32) FcValueCharSet(v)->num;
341 case FcTypeFTFace:
342 return FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->family_name) ^
343 FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->style_name);
344 case FcTypeLangSet:
345 return FcLangSetHash (FcValueLangSet(v));
346 case FcTypeRange:
347 return FcRangeHash (v->u.r);
348 }
349 return 0;
350}
351
352static FcBool
353FcValueListEqual (FcValueListPtr la, FcValueListPtr lb)
354{
355 if (la == lb)
356 return FcTrue;
357
358 while (la && lb)
359 {
360 if (!FcValueEqual (la->value, lb->value))
361 return FcFalse;
362 la = FcValueListNext(la);
363 lb = FcValueListNext(lb);
364 }
365 if (la || lb)
366 return FcFalse;
367 return FcTrue;
368}
369
370static FcChar32
371FcValueListHash (FcValueListPtr l)
372{
373 FcChar32 hash = 0;
374
375 for (; l; l = FcValueListNext(l))
376 {
377 hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (&l->value);
378 }
379 return hash;
380}
381
382void
383FcPatternDestroy (FcPattern *p)
384{
385 int i;
386 FcPatternElt *elts;
387
388 if (!p)
389 return;
390
391 if (FcRefIsConst (&p->ref))
392 {
393 // FcCacheObjectDereference (p);
394 FcRefDec (&p->ref);
395 return;
396 }
397
398 if (FcRefDec (&p->ref) != 1)
399 return;
400
401 elts = FcPatternElts (p);
402 for (i = 0; i < p->num; i++)
403 FcValueListDestroy (FcPatternEltValues(&elts[i]));
404
405 free (elts);
406 free (p);
407}
408
409static int
410FcPatternObjectPosition (const FcPattern *p, FcObject object)
411{
412 int low, high, mid, c;
413 FcPatternElt *elts = FcPatternElts(p);
414
415 low = 0;
416 high = p->num - 1;
417 c = 1;
418 mid = 0;
419 while (low <= high)
420 {
421 mid = (low + high) >> 1;
422 c = elts[mid].object - object;
423 if (c == 0)
424 return mid;
425 if (c < 0)
426 low = mid + 1;
427 else
428 high = mid - 1;
429 }
430 if (c < 0)
431 mid++;
432 return -(mid + 1);
433}
434
435FcPatternElt *
436FcPatternObjectFindElt (const FcPattern *p, FcObject object)
437{
438 int i = FcPatternObjectPosition (p, object);
439 if (i < 0)
440 return 0;
441 return &FcPatternElts(p)[i];
442}
443
444FcPatternElt *
445FcPatternObjectInsertElt (FcPattern *p, FcObject object)
446{
447 int i;
448 FcPatternElt *e;
449
450 i = FcPatternObjectPosition (p, object);
451 if (i < 0)
452 {
453 i = -i - 1;
454
455 /* reallocate array */
456 if (p->num + 1 >= p->size)
457 {
458 int s = p->size + 16;
459 if (p->size)
460 {
461 FcPatternElt *e0 = FcPatternElts(p);
462 e = (FcPatternElt *) realloc (e0, s * sizeof (FcPatternElt));
463 if (!e) /* maybe it was mmapped */
464 {
465 e = malloc(s * sizeof (FcPatternElt));
466 if (e)
467 memcpy(e, e0, p->num * sizeof (FcPatternElt));
468 }
469 }
470 else
471 e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt));
472 if (!e)
473 return FcFalse;
474 p->elts_offset = FcPtrToOffset (p, e);
475 while (p->size < s)
476 {
477 e[p->size].object = 0;
478 e[p->size].values = NULL;
479 p->size++;
480 }
481 }
482
483 e = FcPatternElts(p);
484 /* move elts up */
485 memmove (e + i + 1,
486 e + i,
487 sizeof (FcPatternElt) *
488 (p->num - i));
489
490 /* bump count */
491 p->num++;
492
493 e[i].object = object;
494 e[i].values = NULL;
495 }
496
497 return FcPatternElts(p) + i;
498}
499
500FcBool
501FcPatternEqual (const FcPattern *pa, const FcPattern *pb)
502{
503 int i;
504 FcPatternElt *pae, *pbe;
505
506 if (pa == pb)
507 return FcTrue;
508
509 if (pa->num != pb->num)
510 return FcFalse;
511 pae = FcPatternElts(pa);
512 pbe = FcPatternElts(pb);
513 for (i = 0; i < pa->num; i++)
514 {
515 if (pae[i].object != pbe[i].object)
516 return FcFalse;
517 if (!FcValueListEqual (FcPatternEltValues(&pae[i]),
518 FcPatternEltValues(&pbe[i])))
519 return FcFalse;
520 }
521 return FcTrue;
522}
523
524FcChar32
525FcPatternHash (const FcPattern *p)
526{
527 int i;
528 FcChar32 h = 0;
529 FcPatternElt *pe = FcPatternElts(p);
530
531 for (i = 0; i < p->num; i++)
532 {
533 h = (((h << 1) | (h >> 31)) ^
534 pe[i].object ^
535 FcValueListHash (FcPatternEltValues(&pe[i])));
536 }
537 return h;
538}
539
540FcBool
541FcPatternObjectListAdd (FcPattern *p,
542 FcObject object,
543 FcValueListPtr list,
544 FcBool append)
545{
546 FcPatternElt *e;
547 FcValueListPtr l, *prev;
548
549 if (FcRefIsConst (&p->ref))
550 goto bail0;
551
552 /*
553 * Make sure the stored type is valid for built-in objects
554 */
555 for (l = list; l != NULL; l = FcValueListNext (l))
556 {
557 if (!FcObjectValidType (object, l->value.type))
558 {
559 fprintf (stderr,
560 "Fontconfig warning: FcPattern object %s does not accept value", FcObjectName (object));
561 FcValuePrintFile (stderr, l->value);
562 fprintf (stderr, "\n");
563 goto bail0;
564 }
565 }
566
567 e = FcPatternObjectInsertElt (p, object);
568 if (!e)
569 goto bail0;
570
571 if (append)
572 {
573 for (prev = &e->values; *prev; prev = &(*prev)->next)
574 ;
575 *prev = list;
576 }
577 else
578 {
579 for (prev = &list; *prev; prev = &(*prev)->next)
580 ;
581 *prev = e->values;
582 e->values = list;
583 }
584
585 return FcTrue;
586
587bail0:
588 return FcFalse;
589}
590
591FcBool
592FcPatternObjectAddWithBinding (FcPattern *p,
593 FcObject object,
594 FcValue value,
595 FcValueBinding binding,
596 FcBool append)
597{
598 FcPatternElt *e;
599 FcValueListPtr new, *prev;
600
601 if (FcRefIsConst (&p->ref))
602 goto bail0;
603
604 new = FcValueListCreate ();
605 if (!new)
606 goto bail0;
607
608 value = FcValueSave (value);
609 if (value.type == FcTypeVoid)
610 goto bail1;
611
612 /*
613 * Make sure the stored type is valid for built-in objects
614 */
615 if (!FcObjectValidType (object, value.type))
616 {
617 fprintf (stderr,
618 "Fontconfig warning: FcPattern object %s does not accept value",
619 FcObjectName (object));
620 FcValuePrintFile (stderr, value);
621 fprintf (stderr, "\n");
622 goto bail1;
623 }
624
625 new->value = value;
626 new->binding = binding;
627 new->next = NULL;
628
629 e = FcPatternObjectInsertElt (p, object);
630 if (!e)
631 goto bail2;
632
633 if (append)
634 {
635 for (prev = &e->values; *prev; prev = &(*prev)->next)
636 ;
637 *prev = new;
638 }
639 else
640 {
641 new->next = e->values;
642 e->values = new;
643 }
644
645 return FcTrue;
646
647bail2:
648 FcValueDestroy (value);
649bail1:
650 free (new);
651bail0:
652 return FcFalse;
653}
654
655FcBool
656FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append)
657{
658 return FcPatternObjectAddWithBinding (p, object,
659 value, FcValueBindingStrong, append);
660}
661
662FcBool
663FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append)
664{
665 return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
666 value, FcValueBindingStrong, append);
667}
668
669FcBool
670FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append)
671{
672 return FcPatternObjectAddWithBinding (p, FcObjectFromName (object),
673 value, FcValueBindingWeak, append);
674}
675
676FcBool
677FcPatternObjectDel (FcPattern *p, FcObject object)
678{
679 FcPatternElt *e;
680
681 e = FcPatternObjectFindElt (p, object);
682 if (!e)
683 return FcFalse;
684
685 /* destroy value */
686 FcValueListDestroy (e->values);
687
688 /* shuffle existing ones down */
689 memmove (e, e+1,
690 (FcPatternElts(p) + p->num - (e + 1)) *
691 sizeof (FcPatternElt));
692 p->num--;
693 e = FcPatternElts(p) + p->num;
694 e->object = 0;
695 e->values = NULL;
696 return FcTrue;
697}
698
699FcBool
700FcPatternDel (FcPattern *p, const char *object)
701{
702 return FcPatternObjectDel (p, FcObjectFromName (object));
703}
704
705FcBool
706FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i)
707{
708 FcValue v;
709
710 v.type = FcTypeInteger;
711 v.u.i = i;
712 return FcPatternObjectAdd (p, object, v, FcTrue);
713}
714
715FcBool
716FcPatternAddInteger (FcPattern *p, const char *object, int i)
717{
718 return FcPatternObjectAddInteger (p, FcObjectFromName (object), i);
719}
720
721FcBool
722FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d)
723{
724 FcValue v;
725
726 v.type = FcTypeDouble;
727 v.u.d = d;
728 return FcPatternObjectAdd (p, object, v, FcTrue);
729}
730
731
732FcBool
733FcPatternAddDouble (FcPattern *p, const char *object, double d)
734{
735 return FcPatternObjectAddDouble (p, FcObjectFromName (object), d);
736}
737
738FcBool
739FcPatternObjectAddString (FcPattern *p, FcObject object, const FcChar8 *s)
740{
741 FcValue v;
742
743 if (!s)
744 {
745 v.type = FcTypeVoid;
746 v.u.s = 0;
747 return FcPatternObjectAdd (p, object, v, FcTrue);
748 }
749
750 v.type = FcTypeString;
751 v.u.s = s;
752 return FcPatternObjectAdd (p, object, v, FcTrue);
753}
754
755FcBool
756FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
757{
758 return FcPatternObjectAddString (p, FcObjectFromName (object), s);
759}
760
761FcBool
762FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s)
763{
764 FcValue v;
765
766 v.type = FcTypeMatrix;
767 v.u.m = s;
768 return FcPatternAdd (p, object, v, FcTrue);
769}
770
771
772FcBool
773FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b)
774{
775 FcValue v;
776
777 v.type = FcTypeBool;
778 v.u.b = b;
779 return FcPatternObjectAdd (p, object, v, FcTrue);
780}
781
782FcBool
783FcPatternAddBool (FcPattern *p, const char *object, FcBool b)
784{
785 return FcPatternObjectAddBool (p, FcObjectFromName (object), b);
786}
787
788FcBool
789FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c)
790{
791 FcValue v;
792
793 v.type = FcTypeCharSet;
794 v.u.c = (FcCharSet *)c;
795 return FcPatternAdd (p, object, v, FcTrue);
796}
797
798FcBool
799FcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f)
800{
801 FcValue v;
802
803 v.type = FcTypeFTFace;
804 v.u.f = (void *) f;
805 return FcPatternAdd (p, object, v, FcTrue);
806}
807
808FcBool
809FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls)
810{
811 FcValue v;
812
813 v.type = FcTypeLangSet;
814 v.u.l = (FcLangSet *)ls;
815 return FcPatternAdd (p, object, v, FcTrue);
816}
817
818FcResult
819FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v)
820{
821 FcPatternElt *e;
822 FcValueListPtr l;
823
824 if (!p)
825 return FcResultNoMatch;
826 e = FcPatternObjectFindElt (p, object);
827 if (!e)
828 return FcResultNoMatch;
829 for (l = FcPatternEltValues(e); l; l = FcValueListNext(l))
830 {
831 if (!id)
832 {
833 *v = FcValueCanonicalize(&l->value);
834 return FcResultMatch;
835 }
836 id--;
837 }
838 return FcResultNoId;
839}
840
841FcResult
842FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v)
843{
844 return FcPatternObjectGet (p, FcObjectFromName (object), id, v);
845}
846
847FcResult
848FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int id, int *i)
849{
850 FcValue v;
851 FcResult r;
852
853 r = FcPatternObjectGet (p, object, id, &v);
854 if (r != FcResultMatch)
855 return r;
856 switch ((int) v.type) {
857 case FcTypeDouble:
858 *i = (int) v.u.d;
859 break;
860 case FcTypeInteger:
861 *i = v.u.i;
862 break;
863 default:
864 return FcResultTypeMismatch;
865 }
866 return FcResultMatch;
867}
868
869FcResult
870FcPatternGetInteger (const FcPattern *p, const char *object, int id, int *i)
871{
872 return FcPatternObjectGetInteger (p, FcObjectFromName (object), id, i);
873}
874
875
876FcResult
877FcPatternObjectGetDouble (const FcPattern *p, FcObject object, int id, double *d)
878{
879 FcValue v;
880 FcResult r;
881
882 r = FcPatternObjectGet (p, object, id, &v);
883 if (r != FcResultMatch)
884 return r;
885 switch ((int) v.type) {
886 case FcTypeDouble:
887 *d = v.u.d;
888 break;
889 case FcTypeInteger:
890 *d = (double) v.u.i;
891 break;
892 default:
893 return FcResultTypeMismatch;
894 }
895 return FcResultMatch;
896}
897
898FcResult
899FcPatternGetDouble (const FcPattern *p, const char *object, int id, double *d)
900{
901 return FcPatternObjectGetDouble (p, FcObjectFromName (object), id, d);
902}
903
904FcResult
905FcPatternObjectGetString (const FcPattern *p, FcObject object, int id, FcChar8 ** s)
906{
907 FcValue v;
908 FcResult r;
909
910 r = FcPatternObjectGet (p, object, id, &v);
911 if (r != FcResultMatch)
912 return r;
913 if (v.type != FcTypeString)
914 return FcResultTypeMismatch;
915
916 *s = (FcChar8 *) v.u.s;
917 return FcResultMatch;
918}
919
920FcResult
921FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s)
922{
923 return FcPatternObjectGetString (p, FcObjectFromName (object), id, s);
924}
925
926FcResult
927FcPatternGetMatrix(const FcPattern *p, const char *object, int id, FcMatrix **m)
928{
929 FcValue v;
930 FcResult r;
931
932 r = FcPatternGet (p, object, id, &v);
933 if (r != FcResultMatch)
934 return r;
935 if (v.type != FcTypeMatrix)
936 return FcResultTypeMismatch;
937 *m = (FcMatrix *)v.u.m;
938 return FcResultMatch;
939}
940
941FcResult
942FcPatternGetBool(const FcPattern *p, const char *object, int id, FcBool *b)
943{
944 FcValue v;
945 FcResult r;
946
947 r = FcPatternGet (p, object, id, &v);
948 if (r != FcResultMatch)
949 return r;
950 if (v.type != FcTypeBool)
951 return FcResultTypeMismatch;
952 *b = v.u.b;
953 return FcResultMatch;
954}
955
956FcResult
957FcPatternGetCharSet(const FcPattern *p, const char *object, int id, FcCharSet **c)
958{
959 FcValue v;
960 FcResult r;
961
962 r = FcPatternGet (p, object, id, &v);
963 if (r != FcResultMatch)
964 return r;
965 if (v.type != FcTypeCharSet)
966 return FcResultTypeMismatch;
967 *c = (FcCharSet *)v.u.c;
968 return FcResultMatch;
969}
970
971FcResult
972FcPatternGetFTFace(const FcPattern *p, const char *object, int id, FT_Face *f)
973{
974 FcValue v;
975 FcResult r;
976
977 r = FcPatternGet (p, object, id, &v);
978 if (r != FcResultMatch)
979 return r;
980 if (v.type != FcTypeFTFace)
981 return FcResultTypeMismatch;
982 *f = (FT_Face) v.u.f;
983 return FcResultMatch;
984}
985
986FcResult
987FcPatternGetLangSet(const FcPattern *p, const char *object, int id, FcLangSet **ls)
988{
989 FcValue v;
990 FcResult r;
991
992 r = FcPatternGet (p, object, id, &v);
993 if (r != FcResultMatch)
994 return r;
995 if (v.type != FcTypeLangSet)
996 return FcResultTypeMismatch;
997 *ls = (FcLangSet *)v.u.l;
998 return FcResultMatch;
999}
1000
1001FcPattern *
1002FcPatternDuplicate (const FcPattern *orig)
1003{
1004 FcPattern *new;
1005 FcPatternElt *e;
1006 int i;
1007 FcValueListPtr l;
1008
1009 new = FcPatternCreate ();
1010 if (!new)
1011 goto bail0;
1012
1013 e = FcPatternElts(orig);
1014
1015 for (i = 0; i < orig->num; i++)
1016 {
1017 for (l = FcPatternEltValues(e + i); l; l = FcValueListNext(l))
1018 {
1019 if (!FcPatternObjectAddWithBinding (new, e[i].object,
1020 FcValueCanonicalize(&l->value),
1021 l->binding,
1022 FcTrue))
1023 goto bail1;
1024
1025 }
1026 }
1027
1028 return new;
1029
1030bail1:
1031 FcPatternDestroy (new);
1032bail0:
1033 return 0;
1034}
1035
1036void
1037FcPatternReference (FcPattern *p)
1038{
1039 if (!p)
1040 return;
1041
1042 if (!FcRefIsConst (&p->ref))
1043 FcRefInc (&p->ref);
1044 else
1045 FcRefInc (&p->ref);
1046 // FcCacheObjectReference (p);
1047}
1048
1049FcPattern *
1050FcPatternBuild (FcPattern *p, ...)
1051{
1052 va_list va;
1053
1054 // according to fontconfig FcInit() it's not needed in a app, so make sure its called
1055 if (!pConfig)
1056 FcInit();
1057
1058 va_start (va, p);
1059 FcPatternVapBuild (p, p, va);
1060 va_end (va);
1061 return p;
1062}
Note: See TracBrowser for help on using the repository browser.