2 * $XFree86: xc/lib/fontconfig/src/fcpat.c,v 1.10 2002/06/29 20:31:02 keithp Exp $
4 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
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.
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.
30 FcPatternCreate (void)
34 p = (FcPattern *) malloc (sizeof (FcPattern));
37 FcMemAlloc (FC_MEM_PATTERN, sizeof (FcPattern));
46 FcValueDestroy (FcValue v)
50 FcStrFree ((FcChar8 *) v.u.s);
53 FcMatrixFree ((FcMatrix *) v.u.m);
56 FcCharSetDestroy ((FcCharSet *) v.u.c);
64 FcValueSave (FcValue v)
68 v.u.s = FcStrCopy (v.u.s);
73 v.u.m = FcMatrixCopy (v.u.m);
78 v.u.c = FcCharSetCopy ((FcCharSet *) v.u.c);
89 FcValueListDestroy (FcValueList *l)
94 switch (l->value.type) {
96 FcStrFree ((FcChar8 *) l->value.u.s);
99 FcMatrixFree ((FcMatrix *) l->value.u.m);
102 FcCharSetDestroy ((FcCharSet *) l->value.u.c);
108 FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
114 FcValueEqual (FcValue va, FcValue vb)
116 if (va.type != vb.type)
118 if (va.type == FcTypeInteger)
120 va.type = FcTypeDouble;
123 if (vb.type == FcTypeInteger)
125 vb.type = FcTypeDouble;
128 if (va.type != vb.type)
135 return va.u.i == vb.u.i;
137 return va.u.d == vb.u.d;
139 return FcStrCmpIgnoreCase (va.u.s, vb.u.s) == 0;
141 return va.u.b == vb.u.b;
143 return FcMatrixEqual (va.u.m, vb.u.m);
145 return FcCharSetEqual (va.u.c, vb.u.c);
147 return va.u.f == vb.u.f;
153 FcDoubleHash (double d)
163 FcStringHash (const FcChar8 *s)
170 h = ((h << 1) | (h >> 31)) ^ c;
175 FcValueHash (FcValue v)
181 return (FcChar32) v.u.i;
183 return FcDoubleHash (v.u.d);
185 return FcStringHash (v.u.s);
187 return (FcChar32) v.u.b;
189 return (FcDoubleHash (v.u.m->xx) ^
190 FcDoubleHash (v.u.m->xy) ^
191 FcDoubleHash (v.u.m->yx) ^
192 FcDoubleHash (v.u.m->yy));
194 return (FcChar32) v.u.c->num;
196 return FcStringHash ((const FcChar8 *) ((FT_Face) v.u.f)->family_name) ^
197 FcStringHash ((const FcChar8 *) ((FT_Face) v.u.f)->style_name);
203 FcValueListEqual (FcValueList *la, FcValueList *lb)
207 if (!FcValueEqual (la->value, lb->value))
218 FcValueListHash (FcValueList *l)
224 hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (l->value);
231 FcPatternDestroy (FcPattern *p)
238 for (i = 0; i < p->num; i++)
239 FcValueListDestroy (p->elts[i].values);
244 FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
249 FcMemFree (FC_MEM_PATTERN, sizeof (FcPattern));
254 FcPatternPosition (const FcPattern *p, const char *object)
256 int low, high, mid, c;
264 mid = (low + high) >> 1;
265 c = strcmp (p->elts[mid].object, object);
279 FcPatternFindElt (const FcPattern *p, const char *object)
281 int i = FcPatternPosition (p, object);
288 FcPatternInsertElt (FcPattern *p, const char *object)
293 i = FcPatternPosition (p, object);
299 if (p->num + 1 >= p->size)
301 int s = p->size + 16;
303 e = (FcPatternElt *) realloc (p->elts, s * sizeof (FcPatternElt));
305 e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt));
310 FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
311 FcMemAlloc (FC_MEM_PATELT, s * sizeof (FcPatternElt));
314 p->elts[p->size].object = 0;
315 p->elts[p->size].values = 0;
321 memmove (p->elts + i + 1,
323 sizeof (FcPatternElt) *
329 p->elts[i].object = object;
330 p->elts[i].values = 0;
337 FcPatternEqual (const FcPattern *pa, const FcPattern *pb)
341 if (pa->num != pb->num)
343 for (i = 0; i < pa->num; i++)
345 if (strcmp (pa->elts[i].object, pb->elts[i].object) != 0)
347 if (!FcValueListEqual (pa->elts[i].values, pb->elts[i].values))
354 FcPatternHash (const FcPattern *p)
359 for (i = 0; i < p->num; i++)
361 h = (((h << 1) | (h >> 31)) ^
362 FcStringHash ((const FcChar8 *) p->elts[i].object) ^
363 FcValueListHash (p->elts[i].values));
369 FcPatternEqualSubset (const FcPattern *pa, const FcPattern *pb, const FcObjectSet *os)
371 FcPatternElt *ea, *eb;
374 for (i = 0; i < os->nobject; i++)
376 ea = FcPatternFindElt (pa, os->objects[i]);
377 eb = FcPatternFindElt (pb, os->objects[i]);
382 if (!FcValueListEqual (ea->values, eb->values))
395 FcPatternAddWithBinding (FcPattern *p,
398 FcValueBinding binding,
402 FcValueList *new, **prev;
404 new = (FcValueList *) malloc (sizeof (FcValueList));
408 FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
410 value = FcValueSave (value);
411 if (value.type == FcTypeVoid)
415 new->binding = binding;
418 e = FcPatternInsertElt (p, object);
424 for (prev = &e->values; *prev; prev = &(*prev)->next);
429 new->next = e->values;
436 switch (value.type) {
438 FcStrFree ((FcChar8 *) value.u.s);
441 FcMatrixFree ((FcMatrix *) value.u.m);
444 FcCharSetDestroy ((FcCharSet *) value.u.c);
450 FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
457 FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append)
459 return FcPatternAddWithBinding (p, object, value, FcValueBindingStrong, append);
463 FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append)
465 return FcPatternAddWithBinding (p, object, value, FcValueBindingWeak, append);
469 FcPatternDel (FcPattern *p, const char *object)
474 e = FcPatternFindElt (p, object);
481 FcValueListDestroy (e->values);
483 /* shuffle existing ones down */
484 memmove (e, e+1, (p->elts + p->num - (e + 1)) * sizeof (FcPatternElt));
486 p->elts[p->num].object = 0;
487 p->elts[p->num].values = 0;
492 FcPatternAddInteger (FcPattern *p, const char *object, int i)
496 v.type = FcTypeInteger;
498 return FcPatternAdd (p, object, v, FcTrue);
502 FcPatternAddDouble (FcPattern *p, const char *object, double d)
506 v.type = FcTypeDouble;
508 return FcPatternAdd (p, object, v, FcTrue);
513 FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
517 v.type = FcTypeString;
519 return FcPatternAdd (p, object, v, FcTrue);
523 FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s)
527 v.type = FcTypeMatrix;
528 v.u.m = (FcMatrix *) s;
529 return FcPatternAdd (p, object, v, FcTrue);
534 FcPatternAddBool (FcPattern *p, const char *object, FcBool b)
540 return FcPatternAdd (p, object, v, FcTrue);
544 FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c)
548 v.type = FcTypeCharSet;
549 v.u.c = (FcCharSet *) c;
550 return FcPatternAdd (p, object, v, FcTrue);
554 FcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f)
558 v.type = FcTypeFTFace;
560 return FcPatternAdd (p, object, v, FcTrue);
564 FcPatternGet (FcPattern *p, const char *object, int id, FcValue *v)
569 e = FcPatternFindElt (p, object);
571 return FcResultNoMatch;
572 for (l = e->values; l; l = l->next)
577 return FcResultMatch;
585 FcPatternGetInteger (FcPattern *p, const char *object, int id, int *i)
590 r = FcPatternGet (p, object, id, &v);
591 if (r != FcResultMatch)
601 return FcResultTypeMismatch;
603 return FcResultMatch;
607 FcPatternGetDouble (FcPattern *p, const char *object, int id, double *d)
612 r = FcPatternGet (p, object, id, &v);
613 if (r != FcResultMatch)
623 return FcResultTypeMismatch;
625 return FcResultMatch;
629 FcPatternGetString (FcPattern *p, const char *object, int id, FcChar8 ** s)
634 r = FcPatternGet (p, object, id, &v);
635 if (r != FcResultMatch)
637 if (v.type != FcTypeString)
638 return FcResultTypeMismatch;
639 *s = (FcChar8 *) v.u.s;
640 return FcResultMatch;
644 FcPatternGetMatrix (FcPattern *p, const char *object, int id, FcMatrix **m)
649 r = FcPatternGet (p, object, id, &v);
650 if (r != FcResultMatch)
652 if (v.type != FcTypeMatrix)
653 return FcResultTypeMismatch;
654 *m = (FcMatrix *) v.u.m;
655 return FcResultMatch;
660 FcPatternGetBool (FcPattern *p, const char *object, int id, FcBool *b)
665 r = FcPatternGet (p, object, id, &v);
666 if (r != FcResultMatch)
668 if (v.type != FcTypeBool)
669 return FcResultTypeMismatch;
671 return FcResultMatch;
675 FcPatternGetCharSet (FcPattern *p, const char *object, int id, FcCharSet **c)
680 r = FcPatternGet (p, object, id, &v);
681 if (r != FcResultMatch)
683 if (v.type != FcTypeCharSet)
684 return FcResultTypeMismatch;
685 *c = (FcCharSet *) v.u.c;
686 return FcResultMatch;
690 FcPatternGetFTFace (FcPattern *p, const char *object, int id, FT_Face *f)
695 r = FcPatternGet (p, object, id, &v);
696 if (r != FcResultMatch)
698 if (v.type != FcTypeFTFace)
699 return FcResultTypeMismatch;
700 *f = (FT_Face) v.u.f;
701 return FcResultMatch;
705 FcPatternDuplicate (FcPattern *orig)
711 new = FcPatternCreate ();
715 for (i = 0; i < orig->num; i++)
717 for (l = orig->elts[i].values; l; l = l->next)
718 if (!FcPatternAdd (new, orig->elts[i].object, l->value, FcTrue))
725 FcPatternDestroy (new);
731 FcPatternReference (FcPattern *p)
737 FcPatternVaBuild (FcPattern *orig, va_list va)
741 FcPatternVapBuild (ret, orig, va);
746 FcPatternBuild (FcPattern *orig, ...)
751 FcPatternVapBuild (orig, orig, va);