/src/fontconfig/src/fcname.c
Line | Count | Source |
1 | | /* |
2 | | * fontconfig/src/fcname.c |
3 | | * |
4 | | * Copyright © 2000 Keith Packard |
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 the author(s) not be used in |
11 | | * advertising or publicity pertaining to distribution of the software without |
12 | | * specific, written prior permission. The authors make 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 | | * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
17 | | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO |
18 | | * EVENT SHALL THE AUTHOR(S) 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 "fcint.h" |
26 | | |
27 | | #include <ctype.h> |
28 | | #include <stdio.h> |
29 | | #include <stdlib.h> |
30 | | #include <string.h> |
31 | | |
32 | | static const FcObjectType FcObjects[] = { |
33 | | #define FC_OBJECT(NAME, Type, Cmp) { FC_##NAME, Type }, |
34 | | #include "fcobjs.h" |
35 | | #undef FC_OBJECT |
36 | | }; |
37 | | |
38 | 4.32M | #define NUM_OBJECT_TYPES ((int)(sizeof FcObjects / sizeof FcObjects[0])) |
39 | | |
40 | | static const FcObjectType * |
41 | | FcObjectFindById (FcObject object) |
42 | 4.32M | { |
43 | 4.32M | if (1 <= object && object <= NUM_OBJECT_TYPES) |
44 | 4.32M | return &FcObjects[object - 1]; |
45 | 0 | return FcObjectLookupOtherTypeById (object); |
46 | 4.32M | } |
47 | | |
48 | | FcBool |
49 | | FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes) |
50 | 0 | { |
51 | | /* Deprecated. */ |
52 | 0 | return FcFalse; |
53 | 0 | } |
54 | | |
55 | | FcBool |
56 | | FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes) |
57 | 0 | { |
58 | | /* Deprecated. */ |
59 | 0 | return FcFalse; |
60 | 0 | } |
61 | | |
62 | | const FcObjectType * |
63 | | FcNameGetObjectType (const char *object) |
64 | 0 | { |
65 | 0 | int id = FcObjectLookupBuiltinIdByName (object); |
66 | |
|
67 | 0 | if (!id) |
68 | 0 | return FcObjectLookupOtherTypeByName (object); |
69 | | |
70 | 0 | return &FcObjects[id - 1]; |
71 | 0 | } |
72 | | |
73 | | FcBool |
74 | | FcObjectValidType (FcObject object, FcType type) |
75 | 4.32M | { |
76 | 4.32M | const FcObjectType *t = FcObjectFindById (object); |
77 | | |
78 | 4.32M | if (t) { |
79 | 4.32M | switch ((int)t->type) { |
80 | 0 | case FcTypeUnknown: |
81 | 0 | return FcTrue; |
82 | 446k | case FcTypeDouble: |
83 | 1.04M | case FcTypeInteger: |
84 | 1.04M | if (type == FcTypeDouble || type == FcTypeInteger) |
85 | 1.04M | return FcTrue; |
86 | 0 | break; |
87 | 297k | case FcTypeLangSet: |
88 | 297k | if (type == FcTypeLangSet || type == FcTypeString) |
89 | 297k | return FcTrue; |
90 | 0 | break; |
91 | 446k | case FcTypeRange: |
92 | 446k | if (type == FcTypeRange || |
93 | 446k | type == FcTypeDouble || |
94 | 297k | type == FcTypeInteger) |
95 | 446k | return FcTrue; |
96 | 0 | break; |
97 | 2.53M | default: |
98 | 2.53M | if (type == t->type) |
99 | 2.53M | return FcTrue; |
100 | 0 | break; |
101 | 4.32M | } |
102 | 0 | return FcFalse; |
103 | 4.32M | } |
104 | 0 | return FcTrue; |
105 | 4.32M | } |
106 | | |
107 | | FcObject |
108 | | FcObjectFromName (const char *name) |
109 | 14.4M | { |
110 | 14.4M | return FcObjectLookupIdByName (name); |
111 | 14.4M | } |
112 | | |
113 | | FcObjectSet * |
114 | | FcObjectGetSet (void) |
115 | 0 | { |
116 | 0 | int i; |
117 | 0 | FcObjectSet *os = NULL; |
118 | |
|
119 | 0 | os = FcObjectSetCreate(); |
120 | 0 | for (i = 0; i < NUM_OBJECT_TYPES; i++) |
121 | 0 | FcObjectSetAdd (os, FcObjects[i].object); |
122 | |
|
123 | 0 | return os; |
124 | 0 | } |
125 | | |
126 | | const char * |
127 | | FcObjectName (FcObject object) |
128 | 0 | { |
129 | 0 | const FcObjectType *o = FcObjectFindById (object); |
130 | |
|
131 | 0 | if (o) |
132 | 0 | return o->object; |
133 | | |
134 | 0 | return FcObjectLookupOtherNameById (object); |
135 | 0 | } |
136 | | |
137 | | typedef FcChar8 *FC8; |
138 | | |
139 | | #include "fcconst.h" |
140 | | |
141 | | FcBool |
142 | | FcNameRegisterConstants (const FcConstant *consts, int nconsts) |
143 | 0 | { |
144 | | /* Deprecated. */ |
145 | 0 | return FcFalse; |
146 | 0 | } |
147 | | |
148 | | FcBool |
149 | | FcNameUnregisterConstants (const FcConstant *consts, int nconsts) |
150 | 0 | { |
151 | | /* Deprecated. */ |
152 | 0 | return FcFalse; |
153 | 0 | } |
154 | | |
155 | | static int |
156 | | FcNameFindConstant (const FcChar8 *string) |
157 | 0 | { |
158 | 0 | int min, max; |
159 | 0 | int last = NUM_FC_CONST_SYMBOLS - 1; |
160 | 0 | FcChar8 c = FcToLower (string[0]); |
161 | 0 | FcChar8 b = FcToLower (_FcBaseConstantSymbols[0].name[0]); |
162 | 0 | FcChar8 e = FcToLower (_FcBaseConstantSymbols[last - 1].name[0]); |
163 | |
|
164 | 0 | if (c < b || c > e) |
165 | 0 | return -1; /* not found */ |
166 | 0 | for (min = 0, max = last; min <= max;) { |
167 | 0 | int mid = (min + max) / 2; |
168 | 0 | int ret; |
169 | |
|
170 | 0 | ret = FcStrCmpIgnoreCase (_FcBaseConstantSymbols[mid].name, string); |
171 | 0 | if (ret > 0) |
172 | 0 | max = mid - 1; |
173 | 0 | else if (ret < 0) |
174 | 0 | min = mid + 1; |
175 | 0 | else |
176 | 0 | return mid; |
177 | 0 | } |
178 | 0 | return -1; |
179 | 0 | } |
180 | | |
181 | | const FcConstant * |
182 | | FcNameGetConstant (const FcChar8 *string) |
183 | 0 | { |
184 | 0 | int pos = FcNameFindConstant (string); |
185 | |
|
186 | 0 | if (pos >= 0) { |
187 | 0 | const FcConstSymbolMap *sym = &_FcBaseConstantSymbols[pos]; |
188 | |
|
189 | 0 | if (sym->values[1].object != FC_INVALID_OBJECT) { |
190 | 0 | fprintf (stderr, "Fontconfig error: the ambiguous constant name: %s: Use :<property name>=<keyword> instead of :<keyword>\n", string); |
191 | 0 | return NULL; |
192 | 0 | } else { |
193 | 0 | return &_FcBaseConstantObjects[sym->values[0].idx_obj].values[sym->values[0].idx_variant]; |
194 | 0 | } |
195 | 0 | } |
196 | 0 | return NULL; |
197 | 0 | } |
198 | | |
199 | | static const FcConstant * |
200 | | FcNameGetConstantForObject (const FcChar8 *string, FcObject object) |
201 | 0 | { |
202 | 0 | int i; |
203 | |
|
204 | 0 | if (object > FC_MAX_BASE_OBJECT) |
205 | 0 | return NULL; |
206 | 0 | for (i = 0; _FcBaseConstantObjects[object].values[i].name != NULL; i++) { |
207 | 0 | FcChar8 c = FcToLower (string[0]); |
208 | 0 | FcChar8 b = FcToLower (_FcBaseConstantObjects[object].values[i].name[0]); |
209 | 0 | int ret; |
210 | |
|
211 | 0 | if (c < b) |
212 | 0 | return NULL; |
213 | 0 | ret = FcStrCmpIgnoreCase (_FcBaseConstantObjects[object].values[i].name, string); |
214 | 0 | if (ret > 0) |
215 | 0 | return NULL; |
216 | 0 | else if (ret == 0) { |
217 | 0 | return &_FcBaseConstantObjects[object].values[i]; |
218 | 0 | } |
219 | 0 | } |
220 | 0 | return NULL; |
221 | 0 | } |
222 | | |
223 | | const FcConstant * |
224 | | FcNameGetConstantFor (const FcChar8 *string, const char *object) |
225 | 0 | { |
226 | 0 | FcObject o = FcObjectFromName (object); |
227 | |
|
228 | 0 | return FcNameGetConstantForObject (string, o); |
229 | 0 | } |
230 | | |
231 | | FcBool |
232 | | FcNameConstant (const FcChar8 *string, int *result) |
233 | 0 | { |
234 | 0 | const FcConstant *c; |
235 | |
|
236 | 0 | if ((c = FcNameGetConstant (string))) { |
237 | 0 | *result = c->value; |
238 | 0 | return FcTrue; |
239 | 0 | } |
240 | 0 | return FcFalse; |
241 | 0 | } |
242 | | |
243 | | FcBool |
244 | | FcNameConstantWithObjectCheck (const FcChar8 *string, FcObject object, int *result) |
245 | 0 | { |
246 | 0 | const FcConstant *c; |
247 | |
|
248 | 0 | c = FcNameGetConstantForObject (string, object); |
249 | 0 | if (c) { |
250 | 0 | *result = c->value; |
251 | 0 | return FcTrue; |
252 | 0 | } |
253 | 0 | return FcFalse; |
254 | 0 | } |
255 | | |
256 | | const FcChar8 * |
257 | | FcNameGetConstantNameFromObject (FcObject object, int value) |
258 | 0 | { |
259 | 0 | int i; |
260 | |
|
261 | 0 | if (object > FC_MAX_BASE_OBJECT) |
262 | 0 | return NULL; |
263 | 0 | for (i = 0; _FcBaseConstantObjects[object].values[i].name != NULL; i++) { |
264 | 0 | if (_FcBaseConstantObjects[object].values[i].value == value) { |
265 | 0 | return _FcBaseConstantObjects[object].values[i].name; |
266 | 0 | } |
267 | 0 | } |
268 | 0 | return NULL; |
269 | 0 | } |
270 | | |
271 | | const FcChar8 * |
272 | | FcNameGetConstantNameFrom (const char *object, int value) |
273 | 0 | { |
274 | 0 | return FcNameGetConstantNameFromObject (FcObjectFromName ((const char *)object), value); |
275 | 0 | } |
276 | | |
277 | | FcBool |
278 | | FcNameBool (const FcChar8 *v, FcBool *result) |
279 | 33 | { |
280 | 33 | char c0, c1; |
281 | | |
282 | 33 | c0 = *v; |
283 | 33 | c0 = FcToLower (c0); |
284 | 33 | if (c0 == 't' || c0 == 'y' || c0 == '1') { |
285 | 33 | *result = FcTrue; |
286 | 33 | return FcTrue; |
287 | 33 | } |
288 | 0 | if (c0 == 'f' || c0 == 'n' || c0 == '0') { |
289 | 0 | *result = FcFalse; |
290 | 0 | return FcTrue; |
291 | 0 | } |
292 | 0 | if (c0 == 'd' || c0 == 'x' || c0 == '2') { |
293 | 0 | *result = FcDontCare; |
294 | 0 | return FcTrue; |
295 | 0 | } |
296 | 0 | if (c0 == 'o') { |
297 | 0 | c1 = v[1]; |
298 | 0 | c1 = FcToLower (c1); |
299 | 0 | if (c1 == 'n') { |
300 | 0 | *result = FcTrue; |
301 | 0 | return FcTrue; |
302 | 0 | } |
303 | 0 | if (c1 == 'f') { |
304 | 0 | *result = FcFalse; |
305 | 0 | return FcTrue; |
306 | 0 | } |
307 | 0 | if (c1 == 'r') { |
308 | 0 | *result = FcDontCare; |
309 | 0 | return FcTrue; |
310 | 0 | } |
311 | 0 | } |
312 | 0 | return FcFalse; |
313 | 0 | } |
314 | | |
315 | | static FcValue |
316 | | FcNameConvert (FcType type, const char *object, FcChar8 *string) |
317 | 0 | { |
318 | 0 | FcValue v; |
319 | 0 | FcMatrix m; |
320 | 0 | double b, e; |
321 | 0 | char *p; |
322 | 0 | FcObject o = FcObjectFromName (object); |
323 | |
|
324 | 0 | v.type = type; |
325 | 0 | switch ((int)v.type) { |
326 | 0 | case FcTypeInteger: |
327 | 0 | if (!FcNameConstantWithObjectCheck (string, o, &v.u.i)) |
328 | 0 | v.u.i = atoi ((char *)string); |
329 | 0 | break; |
330 | 0 | case FcTypeString: |
331 | 0 | v.u.s = FcStrCopy (string); |
332 | 0 | if (!v.u.s) |
333 | 0 | v.type = FcTypeVoid; |
334 | 0 | break; |
335 | 0 | case FcTypeBool: |
336 | 0 | if (!FcNameBool (string, &v.u.b)) |
337 | 0 | v.u.b = FcFalse; |
338 | 0 | break; |
339 | 0 | case FcTypeDouble: |
340 | 0 | v.u.d = FcStrtod ((char *)string, 0); |
341 | 0 | break; |
342 | 0 | case FcTypeMatrix: |
343 | 0 | FcMatrixInit (&m); |
344 | 0 | sscanf ((char *)string, "%lg %lg %lg %lg", &m.xx, &m.xy, &m.yx, &m.yy); |
345 | 0 | v.u.m = FcMatrixCopy (&m); |
346 | 0 | break; |
347 | 0 | case FcTypeCharSet: |
348 | 0 | v.u.c = FcNameParseCharSet (string); |
349 | 0 | if (!v.u.c) |
350 | 0 | v.type = FcTypeVoid; |
351 | 0 | break; |
352 | 0 | case FcTypeLangSet: |
353 | 0 | v.u.l = FcNameParseLangSet (string); |
354 | 0 | if (!v.u.l) |
355 | 0 | v.type = FcTypeVoid; |
356 | 0 | break; |
357 | 0 | case FcTypeRange: |
358 | 0 | if (sscanf ((char *)string, "[%lg %lg]", &b, &e) != 2) { |
359 | 0 | char *sc, *ec; |
360 | 0 | size_t len = strlen ((const char *)string); |
361 | 0 | int si, ei; |
362 | |
|
363 | 0 | sc = malloc (len + 1); |
364 | 0 | ec = malloc (len + 1); |
365 | 0 | if (sc && ec && sscanf ((char *)string, "[%s %[^]]]", sc, ec) == 2) { |
366 | 0 | if (FcNameConstantWithObjectCheck ((const FcChar8 *)sc, o, &si) && |
367 | 0 | FcNameConstantWithObjectCheck ((const FcChar8 *)ec, o, &ei)) |
368 | 0 | v.u.r = FcRangeCreateDouble (si, ei); |
369 | 0 | else |
370 | 0 | goto bail1; |
371 | 0 | } else { |
372 | 0 | bail1: |
373 | 0 | v.type = FcTypeDouble; |
374 | 0 | if (FcNameConstantWithObjectCheck (string, o, &si)) { |
375 | 0 | v.u.d = (double)si; |
376 | 0 | } else { |
377 | 0 | v.u.d = FcStrtod ((char *)string, &p); |
378 | 0 | if (p != NULL && p[0] != 0) |
379 | 0 | v.type = FcTypeVoid; |
380 | 0 | } |
381 | 0 | } |
382 | 0 | if (sc) |
383 | 0 | free (sc); |
384 | 0 | if (ec) |
385 | 0 | free (ec); |
386 | 0 | } else |
387 | 0 | v.u.r = FcRangeCreateDouble (b, e); |
388 | 0 | break; |
389 | 0 | default: |
390 | | /* No valid type to convert */ |
391 | 0 | v.type = FcTypeVoid; |
392 | 0 | break; |
393 | 0 | } |
394 | 0 | return v; |
395 | 0 | } |
396 | | |
397 | | static const FcChar8 * |
398 | | FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last) |
399 | 0 | { |
400 | 0 | FcChar8 c; |
401 | |
|
402 | 0 | while ((c = *cur)) { |
403 | 0 | if (!isspace (c)) |
404 | 0 | break; |
405 | 0 | ++cur; |
406 | 0 | } |
407 | 0 | while ((c = *cur)) { |
408 | 0 | if (c == '\\') { |
409 | 0 | ++cur; |
410 | 0 | if (!(c = *cur)) |
411 | 0 | break; |
412 | 0 | } else if (strchr (delim, c)) |
413 | 0 | break; |
414 | 0 | ++cur; |
415 | 0 | *save++ = c; |
416 | 0 | } |
417 | 0 | *save = 0; |
418 | 0 | *last = *cur; |
419 | 0 | if (*cur) |
420 | 0 | cur++; |
421 | 0 | return cur; |
422 | 0 | } |
423 | | |
424 | | FcPattern * |
425 | | FcNameParse (const FcChar8 *name) |
426 | 0 | { |
427 | 0 | FcChar8 *save; |
428 | 0 | FcPattern *pat; |
429 | 0 | double d; |
430 | 0 | FcChar8 *e; |
431 | 0 | FcChar8 delim; |
432 | 0 | FcValue v; |
433 | 0 | const FcObjectType *t; |
434 | 0 | const FcConstant *c; |
435 | | |
436 | | /* freed below */ |
437 | 0 | save = malloc (strlen ((char *)name) + 1); |
438 | 0 | if (!save) |
439 | 0 | goto bail0; |
440 | 0 | pat = FcPatternCreate(); |
441 | 0 | if (!pat) |
442 | 0 | goto bail1; |
443 | | |
444 | 0 | for (;;) { |
445 | 0 | name = FcNameFindNext (name, "-,:", save, &delim); |
446 | 0 | if (save[0]) { |
447 | 0 | if (!FcPatternObjectAddString (pat, FC_FAMILY_OBJECT, save)) |
448 | 0 | goto bail2; |
449 | 0 | } |
450 | 0 | if (delim != ',') |
451 | 0 | break; |
452 | 0 | } |
453 | 0 | if (delim == '-') { |
454 | 0 | for (;;) { |
455 | 0 | name = FcNameFindNext (name, "-,:", save, &delim); |
456 | 0 | d = FcStrtod ((char *)save, (char **)&e); |
457 | 0 | if (e != save) { |
458 | 0 | if (!FcPatternObjectAddDouble (pat, FC_SIZE_OBJECT, d)) |
459 | 0 | goto bail2; |
460 | 0 | } |
461 | 0 | if (delim != ',') |
462 | 0 | break; |
463 | 0 | } |
464 | 0 | } |
465 | 0 | while (delim == ':') { |
466 | 0 | name = FcNameFindNext (name, "=_:", save, &delim); |
467 | 0 | if (save[0]) { |
468 | 0 | if (delim == '=' || delim == '_') { |
469 | 0 | t = FcNameGetObjectType ((char *)save); |
470 | 0 | for (;;) { |
471 | 0 | name = FcNameFindNext (name, ":,", save, &delim); |
472 | 0 | if (t) { |
473 | 0 | v = FcNameConvert (t->type, t->object, save); |
474 | 0 | if (!FcPatternAdd (pat, t->object, v, FcTrue)) { |
475 | 0 | FcValueDestroy (v); |
476 | 0 | goto bail2; |
477 | 0 | } |
478 | 0 | FcValueDestroy (v); |
479 | 0 | } |
480 | 0 | if (delim != ',') |
481 | 0 | break; |
482 | 0 | } |
483 | 0 | } else { |
484 | 0 | if ((c = FcNameGetConstant (save))) { |
485 | 0 | t = FcNameGetObjectType ((char *)c->object); |
486 | 0 | if (t == NULL) |
487 | 0 | goto bail2; |
488 | 0 | switch ((int)t->type) { |
489 | 0 | case FcTypeInteger: |
490 | 0 | case FcTypeDouble: |
491 | 0 | if (!FcPatternAddInteger (pat, c->object, c->value)) |
492 | 0 | goto bail2; |
493 | 0 | break; |
494 | 0 | case FcTypeBool: |
495 | 0 | if (!FcPatternAddBool (pat, c->object, c->value)) |
496 | 0 | goto bail2; |
497 | 0 | break; |
498 | 0 | case FcTypeRange: |
499 | 0 | if (!FcPatternAddInteger (pat, c->object, c->value)) |
500 | 0 | goto bail2; |
501 | 0 | break; |
502 | 0 | default: |
503 | 0 | break; |
504 | 0 | } |
505 | 0 | } |
506 | 0 | } |
507 | 0 | } |
508 | 0 | } |
509 | | |
510 | 0 | free (save); |
511 | 0 | return pat; |
512 | | |
513 | 0 | bail2: |
514 | 0 | FcPatternDestroy (pat); |
515 | 0 | bail1: |
516 | 0 | free (save); |
517 | 0 | bail0: |
518 | 0 | return 0; |
519 | 0 | } |
520 | | static FcBool |
521 | | FcNameUnparseString (FcStrBuf *buf, |
522 | | const FcChar8 *string, |
523 | | const FcChar8 *escape) |
524 | 0 | { |
525 | 0 | FcChar8 c; |
526 | 0 | while ((c = *string++)) { |
527 | 0 | if (escape && strchr ((char *)escape, (char)c)) { |
528 | 0 | if (!FcStrBufChar (buf, escape[0])) |
529 | 0 | return FcFalse; |
530 | 0 | } |
531 | 0 | if (!FcStrBufChar (buf, c)) |
532 | 0 | return FcFalse; |
533 | 0 | } |
534 | 0 | return FcTrue; |
535 | 0 | } |
536 | | |
537 | | FcBool |
538 | | FcNameUnparseValue (FcStrBuf *buf, |
539 | | FcValue *v0, |
540 | | FcChar8 *escape) |
541 | 0 | { |
542 | 0 | const FcChar8 *s; |
543 | 0 | FcChar8 *p = NULL; |
544 | 0 | FcValue v = FcValueCanonicalize (v0); |
545 | 0 | FcBool ret; |
546 | |
|
547 | 0 | switch (v.type) { |
548 | 0 | case FcTypeUnknown: |
549 | 0 | case FcTypeVoid: |
550 | 0 | return FcTrue; |
551 | 0 | case FcTypeInteger: |
552 | 0 | p = FcStrDupFormat ("%d", v.u.i); |
553 | 0 | s = (const FcChar8 *)p; |
554 | 0 | break; |
555 | 0 | case FcTypeDouble: |
556 | 0 | p = FcStrDupFormat ("%g", v.u.d); |
557 | 0 | s = (const FcChar8 *)p; |
558 | 0 | break; |
559 | 0 | case FcTypeString: |
560 | 0 | s = v.u.s; |
561 | 0 | break; |
562 | 0 | case FcTypeBool: |
563 | 0 | return FcNameUnparseString (buf, |
564 | 0 | v.u.b == FcTrue ? (FcChar8 *)"True" : v.u.b == FcFalse ? (FcChar8 *)"False" |
565 | 0 | : (FcChar8 *)"DontCare", |
566 | 0 | 0); |
567 | 0 | case FcTypeMatrix: |
568 | 0 | p = FcStrDupFormat ("%g %g %g %g", |
569 | 0 | v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); |
570 | 0 | s = (const FcChar8 *)p; |
571 | 0 | break; |
572 | 0 | case FcTypeCharSet: |
573 | 0 | return FcNameUnparseCharSet (buf, v.u.c); |
574 | 0 | case FcTypeLangSet: |
575 | 0 | return FcNameUnparseLangSet (buf, v.u.l); |
576 | 0 | case FcTypeFTFace: |
577 | 0 | return FcTrue; |
578 | 0 | case FcTypeRange: |
579 | 0 | p = FcStrDupFormat ("[%g %g]", v.u.r->begin, v.u.r->end); |
580 | 0 | s = (const FcChar8 *)p; |
581 | 0 | break; |
582 | 0 | default: |
583 | 0 | return FcFalse; |
584 | 0 | } |
585 | 0 | ret = FcNameUnparseString (buf, s, 0); |
586 | 0 | if (p) |
587 | 0 | FcStrFree (p); |
588 | 0 | return ret; |
589 | 0 | } |
590 | | |
591 | | FcBool |
592 | | FcNameUnparseValueList (FcStrBuf *buf, |
593 | | FcValueListPtr v, |
594 | | FcChar8 *escape) |
595 | 0 | { |
596 | 0 | while (v) { |
597 | 0 | if (!FcNameUnparseValue (buf, &v->value, escape)) |
598 | 0 | return FcFalse; |
599 | 0 | if ((v = FcValueListNext (v)) != NULL) |
600 | 0 | if (!FcNameUnparseString (buf, (FcChar8 *)",", 0)) |
601 | 0 | return FcFalse; |
602 | 0 | } |
603 | 0 | return FcTrue; |
604 | 0 | } |
605 | | |
606 | 0 | #define FC_ESCAPE_FIXED "\\-:," |
607 | 0 | #define FC_ESCAPE_VARIABLE "\\=_:," |
608 | | |
609 | | FcChar8 * |
610 | | FcNameUnparse (FcPattern *pat) |
611 | 0 | { |
612 | 0 | return FcNameUnparseEscaped (pat, FcTrue); |
613 | 0 | } |
614 | | |
615 | | FcChar8 * |
616 | | FcNameUnparseEscaped (FcPattern *pat, FcBool escape) |
617 | 0 | { |
618 | 0 | FcStrBuf buf, buf2; |
619 | 0 | FcChar8 buf_static[8192], buf2_static[256]; |
620 | 0 | int i; |
621 | 0 | FcPatternElt *e; |
622 | |
|
623 | 0 | FcStrBufInit (&buf, buf_static, sizeof (buf_static)); |
624 | 0 | FcStrBufInit (&buf2, buf2_static, sizeof (buf2_static)); |
625 | 0 | e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT); |
626 | 0 | if (e) { |
627 | 0 | if (!FcNameUnparseValueList (&buf, FcPatternEltValues (e), escape ? (FcChar8 *)FC_ESCAPE_FIXED : 0)) |
628 | 0 | goto bail0; |
629 | 0 | } |
630 | 0 | e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT); |
631 | 0 | if (e) { |
632 | 0 | FcChar8 *p; |
633 | |
|
634 | 0 | if (!FcNameUnparseString (&buf2, (FcChar8 *)"-", 0)) |
635 | 0 | goto bail0; |
636 | 0 | if (!FcNameUnparseValueList (&buf2, FcPatternEltValues (e), escape ? (FcChar8 *)FC_ESCAPE_FIXED : 0)) |
637 | 0 | goto bail0; |
638 | 0 | p = FcStrBufDoneStatic (&buf2); |
639 | 0 | FcStrBufDestroy (&buf2); |
640 | 0 | if (strlen ((const char *)p) > 1) |
641 | 0 | if (!FcStrBufString (&buf, p)) |
642 | 0 | goto bail0; |
643 | 0 | } |
644 | 0 | for (i = 0; i < NUM_OBJECT_TYPES; i++) { |
645 | 0 | FcObject id = i + 1; |
646 | 0 | const FcObjectType *o; |
647 | 0 | o = &FcObjects[i]; |
648 | 0 | if (!strcmp (o->object, FC_FAMILY) || |
649 | 0 | !strcmp (o->object, FC_SIZE)) |
650 | 0 | continue; |
651 | | |
652 | 0 | e = FcPatternObjectFindElt (pat, id); |
653 | 0 | if (e) { |
654 | 0 | if (!FcNameUnparseString (&buf, (FcChar8 *)":", 0)) |
655 | 0 | goto bail0; |
656 | 0 | if (!FcNameUnparseString (&buf, (FcChar8 *)o->object, escape ? (FcChar8 *)FC_ESCAPE_VARIABLE : 0)) |
657 | 0 | goto bail0; |
658 | 0 | if (!FcNameUnparseString (&buf, (FcChar8 *)"=", 0)) |
659 | 0 | goto bail0; |
660 | 0 | if (!FcNameUnparseValueList (&buf, FcPatternEltValues (e), escape ? (FcChar8 *)FC_ESCAPE_VARIABLE : 0)) |
661 | 0 | goto bail0; |
662 | 0 | } |
663 | 0 | } |
664 | 0 | return FcStrBufDone (&buf); |
665 | 0 | bail0: |
666 | 0 | FcStrBufDestroy (&buf); |
667 | 0 | return 0; |
668 | 0 | } |
669 | | #define __fcname__ |
670 | | #include "fcaliastail.h" |
671 | | #undef __fcname__ |