]> git.wh0rd.org Git - fontconfig.git/blob - src/fcpat.c
Make autoconf use correct options to build solaris shared libraries
[fontconfig.git] / src / fcpat.c
1 /*
2  * $XFree86: xc/lib/fontconfig/src/fcpat.c,v 1.6 2002/05/31 23:21:25 keithp Exp $
3  *
4  * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of Keith Packard not be used in
11  * advertising or publicity pertaining to distribution of the software without
12  * specific, written prior permission.  Keith Packard makes no
13  * representations about the suitability of this software for any purpose.  It
14  * is provided "as is" without express or implied warranty.
15  *
16  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22  * PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include "fcint.h"
28
29 FcPattern *
30 FcPatternCreate (void)
31 {
32     FcPattern   *p;
33
34     p = (FcPattern *) malloc (sizeof (FcPattern));
35     if (!p)
36         return 0;
37     FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern));
38     p->num = 0;
39     p->size = 0;
40     p->elts = 0;
41     return p;
42 }
43
44 void
45 FcValueDestroy (FcValue v)
46 {
47     switch (v.type) {
48     case FcTypeString:
49         FcStrFree ((FcChar8 *) v.u.s);
50         break;
51     case FcTypeMatrix:
52         FcMatrixFree ((FcMatrix *) v.u.m);
53         break;
54     case FcTypeCharSet:
55         FcCharSetDestroy ((FcCharSet *) v.u.c);
56         break;
57     default:
58         break;
59     }
60 }
61
62 FcValue
63 FcValueSave (FcValue v)
64 {
65     switch (v.type) {
66     case FcTypeString:
67         v.u.s = FcStrCopy (v.u.s);
68         if (!v.u.s)
69             v.type = FcTypeVoid;
70         break;
71     case FcTypeMatrix:
72         v.u.m = FcMatrixCopy (v.u.m);
73         if (!v.u.m)
74             v.type = FcTypeVoid;
75         break;
76     case FcTypeCharSet:
77         v.u.c = FcCharSetCopy ((FcCharSet *) v.u.c);
78         if (!v.u.c)
79             v.type = FcTypeVoid;
80         break;
81     default:
82         break;
83     }
84     return v;
85 }
86
87 void
88 FcValueListDestroy (FcValueList *l)
89 {
90     FcValueList    *next;
91     for (; l; l = next)
92     {
93         switch (l->value.type) {
94         case FcTypeString:
95             FcStrFree ((FcChar8 *) l->value.u.s);
96             break;
97         case FcTypeMatrix:
98             FcMatrixFree ((FcMatrix *) l->value.u.m);
99             break;
100         case FcTypeCharSet:
101             FcCharSetDestroy ((FcCharSet *) l->value.u.c);
102             break;
103         default:
104             break;
105         }
106         next = l->next;
107         FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
108         free (l);
109     }
110 }
111
112 FcBool
113 FcValueEqual (FcValue va, FcValue vb)
114 {
115     if (va.type != vb.type)
116     {
117         if (va.type == FcTypeInteger)
118         {
119             va.type = FcTypeDouble;
120             va.u.d = va.u.i;
121         }
122         if (vb.type == FcTypeInteger)
123         {
124             vb.type = FcTypeDouble;
125             vb.u.d = vb.u.i;
126         }
127         if (va.type != vb.type)
128             return FcFalse;
129     }
130     switch (va.type) {
131     case FcTypeVoid:
132         return FcTrue;
133     case FcTypeInteger:
134         return va.u.i == vb.u.i;
135     case FcTypeDouble:
136         return va.u.d == vb.u.d;
137     case FcTypeString:
138         return FcStrCmpIgnoreCase (va.u.s, vb.u.s) == 0;
139     case FcTypeBool:
140         return va.u.b == vb.u.b;
141     case FcTypeMatrix:
142         return FcMatrixEqual (va.u.m, vb.u.m);
143     case FcTypeCharSet:
144         return FcCharSetEqual (va.u.c, vb.u.c);
145     case FcTypeFTFace:
146         return va.u.f == vb.u.f;
147     }
148     return FcFalse;
149 }
150
151 static FcBool
152 FcValueListEqual (FcValueList *la, FcValueList *lb)
153 {
154     while (la && lb)
155     {
156         if (!FcValueEqual (la->value, lb->value))
157             return FcFalse;
158         la = la->next;
159         lb = lb->next;
160     }
161     if (la || lb)
162         return FcFalse;
163     return FcTrue;
164 }
165
166 void
167 FcPatternDestroy (FcPattern *p)
168 {
169     int             i;
170     
171     for (i = 0; i < p->num; i++)
172         FcValueListDestroy (p->elts[i].values);
173
174     p->num = 0;
175     if (p->elts)
176     {
177         FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
178         free (p->elts);
179         p->elts = 0;
180     }
181     p->size = 0;
182     FcMemFree (FC_MEM_PATTERN, sizeof (FcPattern));
183     free (p);
184 }
185
186 static int
187 FcPatternPosition (const FcPattern *p, const char *object)
188 {
189     int     low, high, mid, c;
190
191     low = 0;
192     high = p->num - 1;
193     c = 1;
194     mid = 0;
195     while (low <= high)
196     {
197         mid = (low + high) >> 1;
198         c = strcmp (p->elts[mid].object, object);
199         if (c == 0)
200             return mid;
201         if (c < 0)
202             low = mid + 1;
203         else
204             high = mid - 1;
205     }
206     if (c < 0)
207         mid++;
208     return -(mid + 1);
209 }
210
211 FcPatternElt *
212 FcPatternFindElt (const FcPattern *p, const char *object)
213 {
214     int     i = FcPatternPosition (p, object);
215     if (i < 0)
216         return 0;
217     return &p->elts[i];
218 }
219
220 FcPatternElt *
221 FcPatternInsertElt (FcPattern *p, const char *object)
222 {
223     int             i;
224     FcPatternElt   *e;
225     
226     i = FcPatternPosition (p, object);
227     if (i < 0)
228     {
229         i = -i - 1;
230     
231         /* grow array */
232         if (p->num + 1 >= p->size)
233         {
234             int s = p->size + 16;
235             if (p->elts)
236                 e = (FcPatternElt *) realloc (p->elts, s * sizeof (FcPatternElt));
237             else
238                 e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt));
239             if (!e)
240                 return FcFalse;
241             p->elts = e;
242             if (p->size)
243                 FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
244             FcMemAlloc (FC_MEM_PATELT, s * sizeof (FcPatternElt));
245             while (p->size < s)
246             {
247                 p->elts[p->size].object = 0;
248                 p->elts[p->size].values = 0;
249                 p->size++;
250             }
251         }
252         
253         /* move elts up */
254         memmove (p->elts + i + 1,
255                  p->elts + i,
256                  sizeof (FcPatternElt) *
257                  (p->num - i));
258                  
259         /* bump count */
260         p->num++;
261         
262         p->elts[i].object = object;
263         p->elts[i].values = 0;
264     }
265     
266     return &p->elts[i];
267 }
268
269 FcBool
270 FcPatternEqual (const FcPattern *pa, const FcPattern *pb)
271 {
272     int i;
273
274     if (pa->num != pb->num)
275         return FcFalse;
276     for (i = 0; i < pa->num; i++)
277     {
278         if (strcmp (pa->elts[i].object, pb->elts[i].object) != 0)
279             return FcFalse;
280         if (!FcValueListEqual (pa->elts[i].values, pb->elts[i].values))
281             return FcFalse;
282     }
283     return FcTrue;
284 }
285
286 FcBool
287 FcPatternEqualSubset (const FcPattern *pa, const FcPattern *pb, const FcObjectSet *os)
288 {
289     FcPatternElt    *ea, *eb;
290     int             i;
291     
292     for (i = 0; i < os->nobject; i++)
293     {
294         ea = FcPatternFindElt (pa, os->objects[i]);
295         eb = FcPatternFindElt (pb, os->objects[i]);
296         if (ea)
297         {
298             if (!eb)
299                 return FcFalse;
300             if (!FcValueListEqual (ea->values, eb->values))
301                 return FcFalse;
302         }
303         else
304         {
305             if (eb)
306                 return FcFalse;
307         }
308     }
309     return FcTrue;
310 }
311
312 FcBool
313 FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append)
314 {
315     FcPatternElt   *e;
316     FcValueList    *new, **prev;
317
318     new = (FcValueList *) malloc (sizeof (FcValueList));
319     if (!new)
320         goto bail0;
321
322     FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
323     /* dup string */
324     value = FcValueSave (value);
325     if (value.type == FcTypeVoid)
326         goto bail1;
327
328     new->value = value;
329     new->next = 0;
330     
331     e = FcPatternInsertElt (p, object);
332     if (!e)
333         goto bail2;
334     
335     if (append)
336     {
337         for (prev = &e->values; *prev; prev = &(*prev)->next);
338         *prev = new;
339     }
340     else
341     {
342         new->next = e->values;
343         e->values = new;
344     }
345     
346     return FcTrue;
347
348 bail2:    
349     switch (value.type) {
350     case FcTypeString:
351         FcStrFree ((FcChar8 *) value.u.s);
352         break;
353     case FcTypeMatrix:
354         FcMatrixFree ((FcMatrix *) value.u.m);
355         break;
356     case FcTypeCharSet:
357         FcCharSetDestroy ((FcCharSet *) value.u.c);
358         break;
359     default:
360         break;
361     }
362 bail1:
363     FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
364     free (new);
365 bail0:
366     return FcFalse;
367 }
368
369 FcBool
370 FcPatternDel (FcPattern *p, const char *object)
371 {
372     FcPatternElt   *e;
373     int             i;
374
375     e = FcPatternFindElt (p, object);
376     if (!e)
377         return FcFalse;
378
379     i = e - p->elts;
380     
381     /* destroy value */
382     FcValueListDestroy (e->values);
383     
384     /* shuffle existing ones down */
385     memmove (e, e+1, (p->elts + p->num - (e + 1)) * sizeof (FcPatternElt));
386     p->num--;
387     p->elts[p->num].object = 0;
388     p->elts[p->num].values = 0;
389     return FcTrue;
390 }
391
392 FcBool
393 FcPatternAddInteger (FcPattern *p, const char *object, int i)
394 {
395     FcValue     v;
396
397     v.type = FcTypeInteger;
398     v.u.i = i;
399     return FcPatternAdd (p, object, v, FcTrue);
400 }
401
402 FcBool
403 FcPatternAddDouble (FcPattern *p, const char *object, double d)
404 {
405     FcValue     v;
406
407     v.type = FcTypeDouble;
408     v.u.d = d;
409     return FcPatternAdd (p, object, v, FcTrue);
410 }
411
412
413 FcBool
414 FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
415 {
416     FcValue     v;
417
418     v.type = FcTypeString;
419     v.u.s = s;
420     return FcPatternAdd (p, object, v, FcTrue);
421 }
422
423 FcBool
424 FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s)
425 {
426     FcValue     v;
427
428     v.type = FcTypeMatrix;
429     v.u.m = (FcMatrix *) s;
430     return FcPatternAdd (p, object, v, FcTrue);
431 }
432
433
434 FcBool
435 FcPatternAddBool (FcPattern *p, const char *object, FcBool b)
436 {
437     FcValue     v;
438
439     v.type = FcTypeBool;
440     v.u.b = b;
441     return FcPatternAdd (p, object, v, FcTrue);
442 }
443
444 FcBool
445 FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c)
446 {
447     FcValue     v;
448
449     v.type = FcTypeCharSet;
450     v.u.c = (FcCharSet *) c;
451     return FcPatternAdd (p, object, v, FcTrue);
452 }
453
454 FcBool
455 FcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f)
456 {
457     FcValue     v;
458
459     v.type = FcTypeFTFace;
460     v.u.f = (void *) f;
461     return FcPatternAdd (p, object, v, FcTrue);
462 }
463
464 FcResult
465 FcPatternGet (FcPattern *p, const char *object, int id, FcValue *v)
466 {
467     FcPatternElt   *e;
468     FcValueList    *l;
469
470     e = FcPatternFindElt (p, object);
471     if (!e)
472         return FcResultNoMatch;
473     for (l = e->values; l; l = l->next)
474     {
475         if (!id)
476         {
477             *v = l->value;
478             return FcResultMatch;
479         }
480         id--;
481     }
482     return FcResultNoId;
483 }
484
485 FcResult
486 FcPatternGetInteger (FcPattern *p, const char *object, int id, int *i)
487 {
488     FcValue     v;
489     FcResult    r;
490
491     r = FcPatternGet (p, object, id, &v);
492     if (r != FcResultMatch)
493         return r;
494     switch (v.type) {
495     case FcTypeDouble:
496         *i = (int) v.u.d;
497         break;
498     case FcTypeInteger:
499         *i = v.u.i;
500         break;
501     default:
502         return FcResultTypeMismatch;
503     }
504     return FcResultMatch;
505 }
506
507 FcResult
508 FcPatternGetDouble (FcPattern *p, const char *object, int id, double *d)
509 {
510     FcValue     v;
511     FcResult    r;
512
513     r = FcPatternGet (p, object, id, &v);
514     if (r != FcResultMatch)
515         return r;
516     switch (v.type) {
517     case FcTypeDouble:
518         *d = v.u.d;
519         break;
520     case FcTypeInteger:
521         *d = (double) v.u.i;
522         break;
523     default:
524         return FcResultTypeMismatch;
525     }
526     return FcResultMatch;
527 }
528
529 FcResult
530 FcPatternGetString (FcPattern *p, const char *object, int id, FcChar8 ** s)
531 {
532     FcValue     v;
533     FcResult    r;
534
535     r = FcPatternGet (p, object, id, &v);
536     if (r != FcResultMatch)
537         return r;
538     if (v.type != FcTypeString)
539         return FcResultTypeMismatch;
540     *s = (FcChar8 *) v.u.s;
541     return FcResultMatch;
542 }
543
544 FcResult
545 FcPatternGetMatrix (FcPattern *p, const char *object, int id, FcMatrix **m)
546 {
547     FcValue     v;
548     FcResult    r;
549
550     r = FcPatternGet (p, object, id, &v);
551     if (r != FcResultMatch)
552         return r;
553     if (v.type != FcTypeMatrix)
554         return FcResultTypeMismatch;
555     *m = (FcMatrix *) v.u.m;
556     return FcResultMatch;
557 }
558
559
560 FcResult
561 FcPatternGetBool (FcPattern *p, const char *object, int id, FcBool *b)
562 {
563     FcValue     v;
564     FcResult    r;
565
566     r = FcPatternGet (p, object, id, &v);
567     if (r != FcResultMatch)
568         return r;
569     if (v.type != FcTypeBool)
570         return FcResultTypeMismatch;
571     *b = v.u.b;
572     return FcResultMatch;
573 }
574
575 FcResult
576 FcPatternGetCharSet (FcPattern *p, const char *object, int id, FcCharSet **c)
577 {
578     FcValue     v;
579     FcResult    r;
580
581     r = FcPatternGet (p, object, id, &v);
582     if (r != FcResultMatch)
583         return r;
584     if (v.type != FcTypeCharSet)
585         return FcResultTypeMismatch;
586     *c = (FcCharSet *) v.u.c;
587     return FcResultMatch;
588 }
589
590 FcResult
591 FcPatternGetFTFace (FcPattern *p, const char *object, int id, FT_Face *f)
592 {
593     FcValue     v;
594     FcResult    r;
595
596     r = FcPatternGet (p, object, id, &v);
597     if (r != FcResultMatch)
598         return r;
599     if (v.type != FcTypeFTFace)
600         return FcResultTypeMismatch;
601     *f = (FT_Face) v.u.f;
602     return FcResultMatch;
603 }
604
605 FcPattern *
606 FcPatternDuplicate (FcPattern *orig)
607 {
608     FcPattern       *new;
609     int             i;
610     FcValueList    *l;
611
612     new = FcPatternCreate ();
613     if (!new)
614         goto bail0;
615
616     for (i = 0; i < orig->num; i++)
617     {
618         for (l = orig->elts[i].values; l; l = l->next)
619             if (!FcPatternAdd (new, orig->elts[i].object, l->value, FcTrue))
620                 goto bail1;
621     }
622
623     return new;
624
625 bail1:
626     FcPatternDestroy (new);
627 bail0:
628     return 0;
629 }
630
631 FcPattern *
632 FcPatternVaBuild (FcPattern *orig, va_list va)
633 {
634     FcPattern   *ret;
635     
636     FcPatternVapBuild (ret, orig, va);
637     return ret;
638 }
639
640 FcPattern *
641 FcPatternBuild (FcPattern *orig, ...)
642 {
643     va_list     va;
644     
645     va_start (va, orig);
646     FcPatternVapBuild (orig, orig, va);
647     va_end (va);
648     return orig;
649 }