]> git.wh0rd.org - fontconfig.git/blame - src/fcname.c
#ifdef out old cache stuff, replace with first version of new mmapping
[fontconfig.git] / src / fcname.c
CommitLineData
24330d27 1/*
94421e40 2 * $RCSId: xc/lib/fontconfig/src/fcname.c,v 1.15 2002/09/26 00:17:28 keithp Exp $
24330d27 3 *
46b51147 4 * Copyright © 2000 Keith Packard
24330d27
KP
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 <ctype.h>
26#include <stdlib.h>
27#include <string.h>
28#include <stdio.h>
29#include "fcint.h"
30
31static const FcObjectType _FcBaseObjectTypes[] = {
32 { FC_FAMILY, FcTypeString, },
4f27c1c0 33 { FC_FAMILYLANG, FcTypeString, },
24330d27 34 { FC_STYLE, FcTypeString, },
4f27c1c0
KP
35 { FC_STYLELANG, FcTypeString, },
36 { FC_FULLNAME, FcTypeString, },
37 { FC_FULLNAMELANG, FcTypeString, },
24330d27
KP
38 { FC_SLANT, FcTypeInteger, },
39 { FC_WEIGHT, FcTypeInteger, },
81fa16c3 40 { FC_WIDTH, FcTypeInteger, },
24330d27 41 { FC_SIZE, FcTypeDouble, },
2a41214a 42 { FC_ASPECT, FcTypeDouble, },
24330d27
KP
43 { FC_PIXEL_SIZE, FcTypeDouble, },
44 { FC_SPACING, FcTypeInteger, },
45 { FC_FOUNDRY, FcTypeString, },
46/* { FC_CORE, FcTypeBool, }, */
47 { FC_ANTIALIAS, FcTypeBool, },
f077d662 48 { FC_HINT_STYLE, FcTypeInteger, },
4c003605
KP
49 { FC_HINTING, FcTypeBool, },
50 { FC_VERTICAL_LAYOUT, FcTypeBool, },
51 { FC_AUTOHINT, FcTypeBool, },
52 { FC_GLOBAL_ADVANCE, FcTypeBool, },
24330d27
KP
53/* { FC_XLFD, FcTypeString, }, */
54 { FC_FILE, FcTypeString, },
55 { FC_INDEX, FcTypeInteger, },
56 { FC_RASTERIZER, FcTypeString, },
57 { FC_OUTLINE, FcTypeBool, },
58 { FC_SCALABLE, FcTypeBool, },
4c003605 59 { FC_DPI, FcTypeDouble },
24330d27
KP
60 { FC_RGBA, FcTypeInteger, },
61 { FC_SCALE, FcTypeDouble, },
62/* { FC_RENDER, FcTypeBool, },*/
63 { FC_MINSPACE, FcTypeBool, },
64 { FC_CHAR_WIDTH, FcTypeInteger },
65 { FC_CHAR_HEIGHT, FcTypeInteger },
66 { FC_MATRIX, FcTypeMatrix },
67 { FC_CHARSET, FcTypeCharSet },
d8d73958 68 { FC_LANG, FcTypeLangSet },
a342e87d 69 { FC_FONTVERSION, FcTypeInteger },
dbf68dd5 70 { FC_CAPABILITY, FcTypeString },
537e3d23 71 { FC_FONTFORMAT, FcTypeString },
414f7202 72 { FC_EMBOLDEN, FcTypeBool },
24330d27
KP
73};
74
75#define NUM_OBJECT_TYPES (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0])
76
77typedef struct _FcObjectTypeList FcObjectTypeList;
78
79struct _FcObjectTypeList {
80 const FcObjectTypeList *next;
81 const FcObjectType *types;
82 int ntypes;
83};
84
85static const FcObjectTypeList _FcBaseObjectTypesList = {
86 0,
87 _FcBaseObjectTypes,
88 NUM_OBJECT_TYPES
89};
90
91static const FcObjectTypeList *_FcObjectTypes = &_FcBaseObjectTypesList;
92
93FcBool
94FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes)
95{
96 FcObjectTypeList *l;
97
98 l = (FcObjectTypeList *) malloc (sizeof (FcObjectTypeList));
99 if (!l)
100 return FcFalse;
9dac3c59 101 FcMemAlloc (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList));
24330d27
KP
102 l->types = types;
103 l->ntypes = ntypes;
104 l->next = _FcObjectTypes;
105 _FcObjectTypes = l;
106 return FcTrue;
107}
108
109FcBool
110FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
111{
112 const FcObjectTypeList *l, **prev;
113
114 for (prev = &_FcObjectTypes;
115 (l = *prev);
116 prev = (const FcObjectTypeList **) &(l->next))
117 {
118 if (l->types == types && l->ntypes == ntypes)
119 {
120 *prev = l->next;
9dac3c59 121 FcMemFree (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList));
24330d27
KP
122 free ((void *) l);
123 return FcTrue;
124 }
125 }
126 return FcFalse;
127}
128
129const FcObjectType *
130FcNameGetObjectType (const char *object)
131{
132 int i;
133 const FcObjectTypeList *l;
134 const FcObjectType *t;
135
136 for (l = _FcObjectTypes; l; l = l->next)
137 {
138 for (i = 0; i < l->ntypes; i++)
139 {
140 t = &l->types[i];
bc9469ba 141 if (!strcmp (object, t->object))
24330d27
KP
142 return t;
143 }
144 }
145 return 0;
146}
147
148static const FcConstant _FcBaseConstants[] = {
81fa16c3
KP
149 { (FcChar8 *) "thin", "weight", FC_WEIGHT_THIN, },
150 { (FcChar8 *) "extralight", "weight", FC_WEIGHT_EXTRALIGHT, },
151 { (FcChar8 *) "ultralight", "weight", FC_WEIGHT_EXTRALIGHT, },
ccb3e93b 152 { (FcChar8 *) "light", "weight", FC_WEIGHT_LIGHT, },
1f71c4d8 153 { (FcChar8 *) "book", "weight", FC_WEIGHT_BOOK, },
81fa16c3 154 { (FcChar8 *) "regular", "weight", FC_WEIGHT_REGULAR, },
ccb3e93b
KP
155 { (FcChar8 *) "medium", "weight", FC_WEIGHT_MEDIUM, },
156 { (FcChar8 *) "demibold", "weight", FC_WEIGHT_DEMIBOLD, },
81fa16c3 157 { (FcChar8 *) "semibold", "weight", FC_WEIGHT_DEMIBOLD, },
ccb3e93b 158 { (FcChar8 *) "bold", "weight", FC_WEIGHT_BOLD, },
81fa16c3
KP
159 { (FcChar8 *) "extrabold", "weight", FC_WEIGHT_EXTRABOLD, },
160 { (FcChar8 *) "ultrabold", "weight", FC_WEIGHT_EXTRABOLD, },
ccb3e93b
KP
161 { (FcChar8 *) "black", "weight", FC_WEIGHT_BLACK, },
162
163 { (FcChar8 *) "roman", "slant", FC_SLANT_ROMAN, },
164 { (FcChar8 *) "italic", "slant", FC_SLANT_ITALIC, },
165 { (FcChar8 *) "oblique", "slant", FC_SLANT_OBLIQUE, },
166
81fa16c3
KP
167 { (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED },
168 { (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED },
169 { (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED },
170 { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED },
171 { (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL },
172 { (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED },
173 { (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED },
174 { (FcChar8 *) "extraexpanded", "width", FC_WIDTH_EXTRAEXPANDED },
175 { (FcChar8 *) "ultraexpanded", "width", FC_WIDTH_ULTRAEXPANDED },
176
ccb3e93b 177 { (FcChar8 *) "proportional", "spacing", FC_PROPORTIONAL, },
a05d257f 178 { (FcChar8 *) "dual", "spacing", FC_DUAL, },
ccb3e93b
KP
179 { (FcChar8 *) "mono", "spacing", FC_MONO, },
180 { (FcChar8 *) "charcell", "spacing", FC_CHARCELL, },
181
1852d490 182 { (FcChar8 *) "unknown", "rgba", FC_RGBA_UNKNOWN },
ccb3e93b
KP
183 { (FcChar8 *) "rgb", "rgba", FC_RGBA_RGB, },
184 { (FcChar8 *) "bgr", "rgba", FC_RGBA_BGR, },
185 { (FcChar8 *) "vrgb", "rgba", FC_RGBA_VRGB },
186 { (FcChar8 *) "vbgr", "rgba", FC_RGBA_VBGR },
1852d490 187 { (FcChar8 *) "none", "rgba", FC_RGBA_NONE },
f077d662
OT
188
189 { (FcChar8 *) "hintnone", "hintstyle", FC_HINT_NONE },
190 { (FcChar8 *) "hintslight", "hintstyle", FC_HINT_SLIGHT },
191 { (FcChar8 *) "hintmedium", "hintstyle", FC_HINT_MEDIUM },
192 { (FcChar8 *) "hintfull", "hintstyle", FC_HINT_FULL },
24330d27
KP
193};
194
195#define NUM_FC_CONSTANTS (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0])
196
197typedef struct _FcConstantList FcConstantList;
198
199struct _FcConstantList {
200 const FcConstantList *next;
201 const FcConstant *consts;
202 int nconsts;
203};
204
205static const FcConstantList _FcBaseConstantList = {
206 0,
207 _FcBaseConstants,
208 NUM_FC_CONSTANTS
209};
210
211static const FcConstantList *_FcConstants = &_FcBaseConstantList;
212
213FcBool
214FcNameRegisterConstants (const FcConstant *consts, int nconsts)
215{
216 FcConstantList *l;
217
218 l = (FcConstantList *) malloc (sizeof (FcConstantList));
219 if (!l)
220 return FcFalse;
9dac3c59 221 FcMemAlloc (FC_MEM_CONSTANT, sizeof (FcConstantList));
24330d27
KP
222 l->consts = consts;
223 l->nconsts = nconsts;
224 l->next = _FcConstants;
225 _FcConstants = l;
226 return FcTrue;
227}
228
229FcBool
230FcNameUnregisterConstants (const FcConstant *consts, int nconsts)
231{
232 const FcConstantList *l, **prev;
233
234 for (prev = &_FcConstants;
235 (l = *prev);
236 prev = (const FcConstantList **) &(l->next))
237 {
238 if (l->consts == consts && l->nconsts == nconsts)
239 {
240 *prev = l->next;
9dac3c59 241 FcMemFree (FC_MEM_CONSTANT, sizeof (FcConstantList));
24330d27
KP
242 free ((void *) l);
243 return FcTrue;
244 }
245 }
246 return FcFalse;
247}
248
249const FcConstant *
ccb3e93b 250FcNameGetConstant (FcChar8 *string)
24330d27
KP
251{
252 const FcConstantList *l;
253 int i;
94421e40 254
24330d27
KP
255 for (l = _FcConstants; l; l = l->next)
256 {
257 for (i = 0; i < l->nconsts; i++)
258 if (!FcStrCmpIgnoreCase (string, l->consts[i].name))
259 return &l->consts[i];
260 }
261 return 0;
262}
263
264FcBool
ccb3e93b 265FcNameConstant (FcChar8 *string, int *result)
24330d27
KP
266{
267 const FcConstant *c;
268
269 if ((c = FcNameGetConstant(string)))
270 {
271 *result = c->value;
272 return FcTrue;
273 }
274 return FcFalse;
275}
276
277FcBool
ca60d2b5 278FcNameBool (const FcChar8 *v, FcBool *result)
24330d27
KP
279{
280 char c0, c1;
281
282 c0 = *v;
94421e40 283 c0 = FcToLower (c0);
24330d27
KP
284 if (c0 == 't' || c0 == 'y' || c0 == '1')
285 {
286 *result = FcTrue;
287 return FcTrue;
288 }
289 if (c0 == 'f' || c0 == 'n' || c0 == '0')
290 {
291 *result = FcFalse;
292 return FcTrue;
293 }
294 if (c0 == 'o')
295 {
296 c1 = v[1];
94421e40 297 c1 = FcToLower (c1);
24330d27
KP
298 if (c1 == 'n')
299 {
300 *result = FcTrue;
301 return FcTrue;
302 }
303 if (c1 == 'f')
304 {
305 *result = FcFalse;
306 return FcTrue;
307 }
308 }
309 return FcFalse;
310}
311
312static FcValue
ccb3e93b 313FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m)
24330d27
KP
314{
315 FcValue v;
316
317 v.type = type;
318 switch (v.type) {
319 case FcTypeInteger:
320 if (!FcNameConstant (string, &v.u.i))
ccb3e93b 321 v.u.i = atoi ((char *) string);
24330d27
KP
322 break;
323 case FcTypeString:
0fa680f0 324 v.u.si = FcObjectStaticName(string);
24330d27
KP
325 break;
326 case FcTypeBool:
327 if (!FcNameBool (string, &v.u.b))
328 v.u.b = FcFalse;
329 break;
330 case FcTypeDouble:
ccb3e93b 331 v.u.d = strtod ((char *) string, 0);
24330d27
KP
332 break;
333 case FcTypeMatrix:
cd2ec1a9 334 v.u.mi = FcMatrixPtrCreateDynamic(m);
ccb3e93b 335 sscanf ((char *) string, "%lg %lg %lg %lg", &m->xx, &m->xy, &m->yx, &m->yy);
24330d27
KP
336 break;
337 case FcTypeCharSet:
cd2ec1a9 338 v.u.ci = FcCharSetPtrCreateDynamic(FcNameParseCharSet (string));
24330d27 339 break;
d8d73958 340 case FcTypeLangSet:
cd2ec1a9 341 v.u.li = FcLangSetPtrCreateDynamic(FcNameParseLangSet (string));
d8d73958 342 break;
24330d27
KP
343 default:
344 break;
345 }
346 return v;
347}
348
ccb3e93b
KP
349static const FcChar8 *
350FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last)
24330d27 351{
ccb3e93b 352 FcChar8 c;
24330d27
KP
353
354 while ((c = *cur))
355 {
356 if (c == '\\')
357 {
358 ++cur;
359 if (!(c = *cur))
360 break;
361 }
362 else if (strchr (delim, c))
363 break;
364 ++cur;
365 *save++ = c;
366 }
367 *save = 0;
368 *last = *cur;
369 if (*cur)
370 cur++;
371 return cur;
372}
373
374FcPattern *
ccb3e93b 375FcNameParse (const FcChar8 *name)
24330d27 376{
ccb3e93b 377 FcChar8 *save;
24330d27
KP
378 FcPattern *pat;
379 double d;
ccb3e93b
KP
380 FcChar8 *e;
381 FcChar8 delim;
24330d27
KP
382 FcValue v;
383 FcMatrix m;
384 const FcObjectType *t;
385 const FcConstant *c;
386
9dac3c59 387 /* freed below */
ccb3e93b 388 save = malloc (strlen ((char *) name) + 1);
24330d27
KP
389 if (!save)
390 goto bail0;
391 pat = FcPatternCreate ();
392 if (!pat)
393 goto bail1;
394
395 for (;;)
396 {
397 name = FcNameFindNext (name, "-,:", save, &delim);
398 if (save[0])
399 {
400 if (!FcPatternAddString (pat, FC_FAMILY, save))
401 goto bail2;
402 }
403 if (delim != ',')
404 break;
405 }
406 if (delim == '-')
407 {
408 for (;;)
409 {
410 name = FcNameFindNext (name, "-,:", save, &delim);
ccb3e93b 411 d = strtod ((char *) save, (char **) &e);
24330d27
KP
412 if (e != save)
413 {
414 if (!FcPatternAddDouble (pat, FC_SIZE, d))
415 goto bail2;
416 }
417 if (delim != ',')
418 break;
419 }
420 }
421 while (delim == ':')
422 {
423 name = FcNameFindNext (name, "=_:", save, &delim);
424 if (save[0])
425 {
426 if (delim == '=' || delim == '_')
427 {
ccb3e93b 428 t = FcNameGetObjectType ((char *) save);
24330d27
KP
429 for (;;)
430 {
431 name = FcNameFindNext (name, ":,", save, &delim);
c552f59b 432 if (t)
24330d27
KP
433 {
434 v = FcNameConvert (t->type, save, &m);
435 if (!FcPatternAdd (pat, t->object, v, FcTrue))
436 {
d8d73958
KP
437 switch (v.type) {
438 case FcTypeCharSet:
cd2ec1a9 439 FcCharSetDestroy ((FcCharSet *) FcCharSetPtrU(v.u.ci));
d8d73958
KP
440 break;
441 case FcTypeLangSet:
cd2ec1a9 442 FcLangSetDestroy ((FcLangSet *) FcLangSetPtrU(v.u.li));
d8d73958
KP
443 break;
444 default:
445 break;
446 }
24330d27
KP
447 goto bail2;
448 }
d8d73958
KP
449 switch (v.type) {
450 case FcTypeCharSet:
cd2ec1a9 451 FcCharSetDestroy ((FcCharSet *) FcCharSetPtrU(v.u.ci));
d8d73958
KP
452 break;
453 case FcTypeLangSet:
cd2ec1a9 454 FcLangSetDestroy ((FcLangSet *) FcLangSetPtrU(v.u.li));
d8d73958
KP
455 break;
456 default:
457 break;
458 }
24330d27
KP
459 }
460 if (delim != ',')
461 break;
462 }
463 }
464 else
465 {
466 if ((c = FcNameGetConstant (save)))
467 {
468 if (!FcPatternAddInteger (pat, c->object, c->value))
469 goto bail2;
470 }
471 }
472 }
473 }
474
475 free (save);
476 return pat;
477
478bail2:
479 FcPatternDestroy (pat);
480bail1:
481 free (save);
482bail0:
483 return 0;
484}
24330d27 485static FcBool
c2e7c611 486FcNameUnparseString (FcStrBuf *buf,
24330d27
KP
487 const FcChar8 *string,
488 const FcChar8 *escape)
489{
490 FcChar8 c;
491 while ((c = *string++))
492 {
493 if (escape && strchr ((char *) escape, (char) c))
494 {
c2e7c611 495 if (!FcStrBufChar (buf, escape[0]))
24330d27
KP
496 return FcFalse;
497 }
c2e7c611 498 if (!FcStrBufChar (buf, c))
24330d27
KP
499 return FcFalse;
500 }
501 return FcTrue;
502}
503
504static FcBool
c2e7c611 505FcNameUnparseValue (FcStrBuf *buf,
24330d27
KP
506 FcValue v,
507 FcChar8 *escape)
508{
509 FcChar8 temp[1024];
510
511 switch (v.type) {
512 case FcTypeVoid:
513 return FcTrue;
514 case FcTypeInteger:
515 sprintf ((char *) temp, "%d", v.u.i);
516 return FcNameUnparseString (buf, temp, 0);
517 case FcTypeDouble:
518 sprintf ((char *) temp, "%g", v.u.d);
519 return FcNameUnparseString (buf, temp, 0);
520 case FcTypeString:
cd2ec1a9 521 return FcNameUnparseString (buf, FcObjectPtrU(v.u.si), escape);
24330d27 522 case FcTypeBool:
ccb3e93b 523 return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0);
24330d27 524 case FcTypeMatrix:
cd2ec1a9
PL
525 {
526 FcMatrix * m = FcMatrixPtrU(v.u.mi);
24330d27 527 sprintf ((char *) temp, "%g %g %g %g",
cd2ec1a9 528 m->xx, m->xy, m->yx, m->yy);
24330d27 529 return FcNameUnparseString (buf, temp, 0);
cd2ec1a9 530 }
24330d27 531 case FcTypeCharSet:
cd2ec1a9 532 return FcNameUnparseCharSet (buf, FcCharSetPtrU(v.u.ci));
d8d73958 533 case FcTypeLangSet:
cd2ec1a9 534 return FcNameUnparseLangSet (buf, FcLangSetPtrU(v.u.li));
88c747e2
KP
535 case FcTypeFTFace:
536 return FcTrue;
24330d27
KP
537 }
538 return FcFalse;
539}
540
541static FcBool
c2e7c611 542FcNameUnparseValueList (FcStrBuf *buf,
cd2ec1a9 543 FcValueListPtr v,
ccb3e93b 544 FcChar8 *escape)
24330d27 545{
cd2ec1a9 546 while (FcValueListPtrU(v))
24330d27 547 {
cd2ec1a9 548 if (!FcNameUnparseValue (buf, FcValueListPtrU(v)->value, escape))
24330d27 549 return FcFalse;
cd2ec1a9 550 if (FcValueListPtrU(v = FcValueListPtrU(v)->next))
ccb3e93b 551 if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0))
24330d27
KP
552 return FcFalse;
553 }
554 return FcTrue;
555}
556
557#define FC_ESCAPE_FIXED "\\-:,"
558#define FC_ESCAPE_VARIABLE "\\=_:,"
559
560FcChar8 *
561FcNameUnparse (FcPattern *pat)
562{
c2e7c611 563 FcStrBuf buf;
24330d27
KP
564 FcChar8 buf_static[8192];
565 int i;
566 FcPatternElt *e;
567 const FcObjectTypeList *l;
568 const FcObjectType *o;
569
c2e7c611 570 FcStrBufInit (&buf, buf_static, sizeof (buf_static));
e9be9cd1 571 e = FcPatternFindElt (pat, FC_FAMILY);
24330d27
KP
572 if (e)
573 {
ccb3e93b 574 if (!FcNameUnparseValueList (&buf, e->values, (FcChar8 *) FC_ESCAPE_FIXED))
24330d27
KP
575 goto bail0;
576 }
e9be9cd1 577 e = FcPatternFindElt (pat, FC_SIZE);
24330d27
KP
578 if (e)
579 {
ccb3e93b 580 if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0))
24330d27 581 goto bail0;
ccb3e93b 582 if (!FcNameUnparseValueList (&buf, e->values, (FcChar8 *) FC_ESCAPE_FIXED))
24330d27
KP
583 goto bail0;
584 }
585 for (l = _FcObjectTypes; l; l = l->next)
586 {
587 for (i = 0; i < l->ntypes; i++)
588 {
589 o = &l->types[i];
590 if (!strcmp (o->object, FC_FAMILY) ||
591 !strcmp (o->object, FC_SIZE) ||
592 !strcmp (o->object, FC_FILE))
593 continue;
594
e9be9cd1 595 e = FcPatternFindElt (pat, o->object);
24330d27
KP
596 if (e)
597 {
ccb3e93b 598 if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0))
24330d27 599 goto bail0;
ccb3e93b 600 if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, (FcChar8 *) FC_ESCAPE_VARIABLE))
24330d27 601 goto bail0;
ccb3e93b 602 if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0))
24330d27
KP
603 goto bail0;
604 if (!FcNameUnparseValueList (&buf, e->values,
ccb3e93b 605 (FcChar8 *) FC_ESCAPE_VARIABLE))
24330d27
KP
606 goto bail0;
607 }
608 }
609 }
c2e7c611 610 return FcStrBufDone (&buf);
24330d27 611bail0:
c2e7c611 612 FcStrBufDestroy (&buf);
24330d27
KP
613 return 0;
614}