]> git.wh0rd.org - fontconfig.git/blob - src/fcpat.c
fontconfig library: build fixes and compiler warning fixes
[fontconfig.git] / src / fcpat.c
1 /*
2 * $XFree86: $
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 void
113 FcPatternDestroy (FcPattern *p)
114 {
115 int i;
116
117 for (i = 0; i < p->num; i++)
118 FcValueListDestroy (p->elts[i].values);
119
120 p->num = 0;
121 if (p->elts)
122 {
123 FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
124 free (p->elts);
125 p->elts = 0;
126 }
127 p->size = 0;
128 FcMemFree (FC_MEM_PATTERN, sizeof (FcPattern));
129 free (p);
130 }
131
132 FcPatternElt *
133 FcPatternFind (FcPattern *p, const char *object, FcBool insert)
134 {
135 int i;
136 int s;
137 FcPatternElt *e;
138
139 /* match existing */
140 for (i = 0; i < p->num; i++)
141 {
142 if (!FcStrCmpIgnoreCase ((FcChar8 *) object, (FcChar8 *) p->elts[i].object))
143 return &p->elts[i];
144 }
145
146 if (!insert)
147 return FcFalse;
148
149 /* grow array */
150 if (i == p->size)
151 {
152 s = p->size + 16;
153 if (p->elts)
154 e = (FcPatternElt *) realloc (p->elts, s * sizeof (FcPatternElt));
155 else
156 e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt));
157 if (!e)
158 return FcFalse;
159 p->elts = e;
160 if (p->size)
161 FcMemFree (FC_MEM_PATELT, p->size * sizeof (FcPatternElt));
162 FcMemAlloc (FC_MEM_PATELT, s * sizeof (FcPatternElt));
163 while (p->size < s)
164 {
165 p->elts[p->size].object = 0;
166 p->elts[p->size].values = 0;
167 p->size++;
168 }
169 }
170
171 /* bump count */
172 p->num++;
173
174 p->elts[i].object = object;
175
176 return &p->elts[i];
177 }
178
179 FcBool
180 FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append)
181 {
182 FcPatternElt *e;
183 FcValueList *new, **prev;
184
185 new = (FcValueList *) malloc (sizeof (FcValueList));
186 if (!new)
187 goto bail0;
188
189 FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
190 /* dup string */
191 value = FcValueSave (value);
192 if (value.type == FcTypeVoid)
193 goto bail1;
194
195 new->value = value;
196 new->next = 0;
197
198 e = FcPatternFind (p, object, FcTrue);
199 if (!e)
200 goto bail2;
201
202 if (append)
203 {
204 for (prev = &e->values; *prev; prev = &(*prev)->next);
205 *prev = new;
206 }
207 else
208 {
209 new->next = e->values;
210 e->values = new;
211 }
212
213 return FcTrue;
214
215 bail2:
216 switch (value.type) {
217 case FcTypeString:
218 FcStrFree ((FcChar8 *) value.u.s);
219 break;
220 case FcTypeMatrix:
221 FcMatrixFree ((FcMatrix *) value.u.m);
222 break;
223 case FcTypeCharSet:
224 FcCharSetDestroy ((FcCharSet *) value.u.c);
225 break;
226 default:
227 break;
228 }
229 bail1:
230 FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
231 free (new);
232 bail0:
233 return FcFalse;
234 }
235
236 FcBool
237 FcPatternDel (FcPattern *p, const char *object)
238 {
239 FcPatternElt *e;
240 int i;
241
242 e = FcPatternFind (p, object, FcFalse);
243 if (!e)
244 return FcFalse;
245
246 i = e - p->elts;
247
248 /* destroy value */
249 FcValueListDestroy (e->values);
250
251 /* shuffle existing ones down */
252 memmove (e, e+1, (p->elts + p->num - (e + 1)) * sizeof (FcPatternElt));
253 p->num--;
254 p->elts[p->num].object = 0;
255 p->elts[p->num].values = 0;
256 return FcTrue;
257 }
258
259 FcBool
260 FcPatternAddInteger (FcPattern *p, const char *object, int i)
261 {
262 FcValue v;
263
264 v.type = FcTypeInteger;
265 v.u.i = i;
266 return FcPatternAdd (p, object, v, FcTrue);
267 }
268
269 FcBool
270 FcPatternAddDouble (FcPattern *p, const char *object, double d)
271 {
272 FcValue v;
273
274 v.type = FcTypeDouble;
275 v.u.d = d;
276 return FcPatternAdd (p, object, v, FcTrue);
277 }
278
279
280 FcBool
281 FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
282 {
283 FcValue v;
284
285 v.type = FcTypeString;
286 v.u.s = s;
287 return FcPatternAdd (p, object, v, FcTrue);
288 }
289
290 FcBool
291 FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s)
292 {
293 FcValue v;
294
295 v.type = FcTypeMatrix;
296 v.u.m = (FcMatrix *) s;
297 return FcPatternAdd (p, object, v, FcTrue);
298 }
299
300
301 FcBool
302 FcPatternAddBool (FcPattern *p, const char *object, FcBool b)
303 {
304 FcValue v;
305
306 v.type = FcTypeBool;
307 v.u.b = b;
308 return FcPatternAdd (p, object, v, FcTrue);
309 }
310
311 FcBool
312 FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c)
313 {
314 FcValue v;
315
316 v.type = FcTypeCharSet;
317 v.u.c = (FcCharSet *) c;
318 return FcPatternAdd (p, object, v, FcTrue);
319 }
320
321 FcResult
322 FcPatternGet (FcPattern *p, const char *object, int id, FcValue *v)
323 {
324 FcPatternElt *e;
325 FcValueList *l;
326
327 e = FcPatternFind (p, object, FcFalse);
328 if (!e)
329 return FcResultNoMatch;
330 for (l = e->values; l; l = l->next)
331 {
332 if (!id)
333 {
334 *v = l->value;
335 return FcResultMatch;
336 }
337 id--;
338 }
339 return FcResultNoId;
340 }
341
342 FcResult
343 FcPatternGetInteger (FcPattern *p, const char *object, int id, int *i)
344 {
345 FcValue v;
346 FcResult r;
347
348 r = FcPatternGet (p, object, id, &v);
349 if (r != FcResultMatch)
350 return r;
351 switch (v.type) {
352 case FcTypeDouble:
353 *i = (int) v.u.d;
354 break;
355 case FcTypeInteger:
356 *i = v.u.i;
357 break;
358 default:
359 return FcResultTypeMismatch;
360 }
361 return FcResultMatch;
362 }
363
364 FcResult
365 FcPatternGetDouble (FcPattern *p, const char *object, int id, double *d)
366 {
367 FcValue v;
368 FcResult r;
369
370 r = FcPatternGet (p, object, id, &v);
371 if (r != FcResultMatch)
372 return r;
373 switch (v.type) {
374 case FcTypeDouble:
375 *d = v.u.d;
376 break;
377 case FcTypeInteger:
378 *d = (double) v.u.i;
379 break;
380 default:
381 return FcResultTypeMismatch;
382 }
383 return FcResultMatch;
384 }
385
386 FcResult
387 FcPatternGetString (FcPattern *p, const char *object, int id, FcChar8 const ** s)
388 {
389 FcValue v;
390 FcResult r;
391
392 r = FcPatternGet (p, object, id, &v);
393 if (r != FcResultMatch)
394 return r;
395 if (v.type != FcTypeString)
396 return FcResultTypeMismatch;
397 *s = v.u.s;
398 return FcResultMatch;
399 }
400
401 FcResult
402 FcPatternGetMatrix (FcPattern *p, const char *object, int id, FcMatrix **m)
403 {
404 FcValue v;
405 FcResult r;
406
407 r = FcPatternGet (p, object, id, &v);
408 if (r != FcResultMatch)
409 return r;
410 if (v.type != FcTypeMatrix)
411 return FcResultTypeMismatch;
412 *m = (FcMatrix *) v.u.m;
413 return FcResultMatch;
414 }
415
416
417 FcResult
418 FcPatternGetBool (FcPattern *p, const char *object, int id, FcBool *b)
419 {
420 FcValue v;
421 FcResult r;
422
423 r = FcPatternGet (p, object, id, &v);
424 if (r != FcResultMatch)
425 return r;
426 if (v.type != FcTypeBool)
427 return FcResultTypeMismatch;
428 *b = v.u.b;
429 return FcResultMatch;
430 }
431
432 FcResult
433 FcPatternGetCharSet (FcPattern *p, const char *object, int id, FcCharSet **c)
434 {
435 FcValue v;
436 FcResult r;
437
438 r = FcPatternGet (p, object, id, &v);
439 if (r != FcResultMatch)
440 return r;
441 if (v.type != FcTypeCharSet)
442 return FcResultTypeMismatch;
443 *c = (FcCharSet *) v.u.c;
444 return FcResultMatch;
445 }
446
447 FcPattern *
448 FcPatternDuplicate (FcPattern *orig)
449 {
450 FcPattern *new;
451 int i;
452 FcValueList *l;
453
454 new = FcPatternCreate ();
455 if (!new)
456 goto bail0;
457
458 for (i = 0; i < orig->num; i++)
459 {
460 for (l = orig->elts[i].values; l; l = l->next)
461 if (!FcPatternAdd (new, orig->elts[i].object, l->value, FcTrue))
462 goto bail1;
463 }
464
465 return new;
466
467 bail1:
468 FcPatternDestroy (new);
469 bail0:
470 return 0;
471 }
472
473 FcPattern *
474 FcPatternVaBuild (FcPattern *orig, va_list va)
475 {
476 FcPattern *ret;
477
478 FcPatternVapBuild (ret, orig, va);
479 return ret;
480 }
481
482 FcPattern *
483 FcPatternBuild (FcPattern *orig, ...)
484 {
485 va_list va;
486
487 va_start (va, orig);
488 FcPatternVapBuild (orig, orig, va);
489 va_end (va);
490 return orig;
491 }