Coverage Report

Created: 2025-07-23 08:13

/src/fontconfig/src/fcname.c
Line
Count
Source (jump to first uncovered line)
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
5.68M
#define NUM_OBJECT_TYPES ((int)(sizeof FcObjects / sizeof FcObjects[0]))
39
40
static const FcObjectType *
41
FcObjectFindById (FcObject object)
42
5.68M
{
43
5.68M
    if (1 <= object && object <= NUM_OBJECT_TYPES)
44
5.68M
  return &FcObjects[object - 1];
45
0
    return FcObjectLookupOtherTypeById (object);
46
5.68M
}
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
5.68M
{
76
5.68M
    const FcObjectType *t = FcObjectFindById (object);
77
78
5.68M
    if (t) {
79
5.68M
  switch ((int)t->type) {
80
0
  case FcTypeUnknown:
81
0
      return FcTrue;
82
586k
  case FcTypeDouble:
83
1.38M
  case FcTypeInteger:
84
1.38M
      if (type == FcTypeDouble || type == FcTypeInteger)
85
1.38M
    return FcTrue;
86
0
      break;
87
388k
  case FcTypeLangSet:
88
388k
      if (type == FcTypeLangSet || type == FcTypeString)
89
388k
    return FcTrue;
90
0
      break;
91
586k
  case FcTypeRange:
92
586k
      if (type == FcTypeRange ||
93
586k
          type == FcTypeDouble ||
94
586k
          type == FcTypeInteger)
95
586k
    return FcTrue;
96
0
      break;
97
3.32M
  default:
98
3.32M
      if (type == t->type)
99
3.32M
    return FcTrue;
100
0
      break;
101
5.68M
  }
102
0
  return FcFalse;
103
5.68M
    }
104
0
    return FcTrue;
105
5.68M
}
106
107
FcObject
108
FcObjectFromName (const char *name)
109
18.0M
{
110
18.0M
    return FcObjectLookupIdByName (name);
111
18.0M
}
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
static const FcConstant _FcBaseConstants[] = {
140
    { (FC8) "thin",           "weight",         FC_WEIGHT_THIN          },
141
    { (FC8) "extralight",     "weight",         FC_WEIGHT_EXTRALIGHT    },
142
    { (FC8) "ultralight",     "weight",         FC_WEIGHT_EXTRALIGHT    },
143
    { (FC8) "demilight",      "weight",         FC_WEIGHT_DEMILIGHT     },
144
    { (FC8) "semilight",      "weight",         FC_WEIGHT_DEMILIGHT     },
145
    { (FC8) "light",          "weight",         FC_WEIGHT_LIGHT         },
146
    { (FC8) "book",           "weight",         FC_WEIGHT_BOOK          },
147
    { (FC8) "regular",        "weight",         FC_WEIGHT_REGULAR       },
148
    { (FC8) "normal",         "weight",         FC_WEIGHT_NORMAL        },
149
    { (FC8) "medium",         "weight",         FC_WEIGHT_MEDIUM        },
150
    { (FC8) "demibold",       "weight",         FC_WEIGHT_DEMIBOLD      },
151
    { (FC8) "semibold",       "weight",         FC_WEIGHT_DEMIBOLD      },
152
    { (FC8) "bold",           "weight",         FC_WEIGHT_BOLD          },
153
    { (FC8) "extrabold",      "weight",         FC_WEIGHT_EXTRABOLD     },
154
    { (FC8) "ultrabold",      "weight",         FC_WEIGHT_EXTRABOLD     },
155
    { (FC8) "black",          "weight",         FC_WEIGHT_BLACK         },
156
    { (FC8) "heavy",          "weight",         FC_WEIGHT_HEAVY         },
157
    { (FC8) "extrablack",     "weight",         FC_WEIGHT_EXTRABLACK    },
158
    { (FC8) "ultrablack",     "weight",         FC_WEIGHT_ULTRABLACK    },
159
160
    { (FC8) "roman",          "slant",          FC_SLANT_ROMAN          },
161
    { (FC8) "italic",         "slant",          FC_SLANT_ITALIC         },
162
    { (FC8) "oblique",        "slant",          FC_SLANT_OBLIQUE        },
163
164
    { (FC8) "ultracondensed", "width",          FC_WIDTH_ULTRACONDENSED },
165
    { (FC8) "extracondensed", "width",          FC_WIDTH_EXTRACONDENSED },
166
    { (FC8) "condensed",      "width",          FC_WIDTH_CONDENSED      },
167
    { (FC8) "semicondensed",  "width",          FC_WIDTH_SEMICONDENSED  },
168
    { (FC8) "normal",         "width",          FC_WIDTH_NORMAL         },
169
    { (FC8) "semiexpanded",   "width",          FC_WIDTH_SEMIEXPANDED   },
170
    { (FC8) "expanded",       "width",          FC_WIDTH_EXPANDED       },
171
    { (FC8) "extraexpanded",  "width",          FC_WIDTH_EXTRAEXPANDED  },
172
    { (FC8) "ultraexpanded",  "width",          FC_WIDTH_ULTRAEXPANDED  },
173
174
    { (FC8) "proportional",   "spacing",        FC_PROPORTIONAL         },
175
    { (FC8) "dual",           "spacing",        FC_DUAL                 },
176
    { (FC8) "mono",           "spacing",        FC_MONO                 },
177
    { (FC8) "charcell",       "spacing",        FC_CHARCELL             },
178
179
    { (FC8) "unknown",        "rgba",           FC_RGBA_UNKNOWN         },
180
    { (FC8) "rgb",            "rgba",           FC_RGBA_RGB             },
181
    { (FC8) "bgr",            "rgba",           FC_RGBA_BGR             },
182
    { (FC8) "vrgb",           "rgba",           FC_RGBA_VRGB            },
183
    { (FC8) "vbgr",           "rgba",           FC_RGBA_VBGR            },
184
    { (FC8) "none",           "rgba",           FC_RGBA_NONE            },
185
186
    { (FC8) "hintnone",       "hintstyle",      FC_HINT_NONE            },
187
    { (FC8) "hintslight",     "hintstyle",      FC_HINT_SLIGHT          },
188
    { (FC8) "hintmedium",     "hintstyle",      FC_HINT_MEDIUM          },
189
    { (FC8) "hintfull",       "hintstyle",      FC_HINT_FULL            },
190
191
    { (FC8) "antialias",      "antialias",      FcTrue                  },
192
    { (FC8) "hinting",        "hinting",        FcTrue                  },
193
    { (FC8) "verticallayout", "verticallayout", FcTrue                  },
194
    { (FC8) "autohint",       "autohint",       FcTrue                  },
195
    { (FC8) "globaladvance",  "globaladvance",  FcTrue                  }, /* deprecated */
196
    { (FC8) "outline",        "outline",        FcTrue                  },
197
    { (FC8) "scalable",       "scalable",       FcTrue                  },
198
    { (FC8) "minspace",       "minspace",       FcTrue                  },
199
    { (FC8) "embolden",       "embolden",       FcTrue                  },
200
    { (FC8) "embeddedbitmap", "embeddedbitmap", FcTrue                  },
201
    { (FC8) "decorative",     "decorative",     FcTrue                  },
202
    { (FC8) "lcdnone",        "lcdfilter",      FC_LCD_NONE             },
203
    { (FC8) "lcddefault",     "lcdfilter",      FC_LCD_DEFAULT          },
204
    { (FC8) "lcdlight",       "lcdfilter",      FC_LCD_LIGHT            },
205
    { (FC8) "lcdlegacy",      "lcdfilter",      FC_LCD_LEGACY           },
206
};
207
208
0
#define NUM_FC_CONSTANTS (sizeof _FcBaseConstants / sizeof _FcBaseConstants[0])
209
210
FcBool
211
FcNameRegisterConstants (const FcConstant *consts, int nconsts)
212
0
{
213
    /* Deprecated. */
214
0
    return FcFalse;
215
0
}
216
217
FcBool
218
FcNameUnregisterConstants (const FcConstant *consts, int nconsts)
219
0
{
220
    /* Deprecated. */
221
0
    return FcFalse;
222
0
}
223
224
const FcConstant *
225
FcNameGetConstant (const FcChar8 *string)
226
0
{
227
0
    unsigned int i;
228
229
0
    for (i = 0; i < NUM_FC_CONSTANTS; i++)
230
0
  if (!FcStrCmpIgnoreCase (string, _FcBaseConstants[i].name))
231
0
      return &_FcBaseConstants[i];
232
233
0
    return 0;
234
0
}
235
236
const FcConstant *
237
FcNameGetConstantFor (const FcChar8 *string, const char *object)
238
0
{
239
0
    unsigned int i;
240
241
0
    for (i = 0; i < NUM_FC_CONSTANTS; i++)
242
0
  if (!FcStrCmpIgnoreCase (string, _FcBaseConstants[i].name) &&
243
0
      !FcStrCmpIgnoreCase ((const FcChar8 *)object, (const FcChar8 *)_FcBaseConstants[i].object))
244
0
      return &_FcBaseConstants[i];
245
246
0
    return 0;
247
0
}
248
249
FcBool
250
FcNameConstant (const FcChar8 *string, int *result)
251
0
{
252
0
    const FcConstant *c;
253
254
0
    if ((c = FcNameGetConstant (string))) {
255
0
  *result = c->value;
256
0
  return FcTrue;
257
0
    }
258
0
    return FcFalse;
259
0
}
260
261
FcBool
262
FcNameConstantWithObjectCheck (const FcChar8 *string, const char *object, int *result)
263
0
{
264
0
    const FcConstant *c;
265
266
0
    if ((c = FcNameGetConstantFor (string, object))) {
267
0
  *result = c->value;
268
0
  return FcTrue;
269
0
    } else if ((c = FcNameGetConstant (string))) {
270
0
  if (strcmp (c->object, object) != 0) {
271
0
      fprintf (stderr, "Fontconfig error: Unexpected constant name `%s' used for object `%s': should be `%s'\n", string, object, c->object);
272
0
      return FcFalse;
273
0
  }
274
  /* Unlikely to reach out */
275
0
  *result = c->value;
276
0
  return FcTrue;
277
0
    }
278
0
    return FcFalse;
279
0
}
280
281
FcBool
282
FcNameBool (const FcChar8 *v, FcBool *result)
283
33
{
284
33
    char c0, c1;
285
286
33
    c0 = *v;
287
33
    c0 = FcToLower (c0);
288
33
    if (c0 == 't' || c0 == 'y' || c0 == '1') {
289
33
  *result = FcTrue;
290
33
  return FcTrue;
291
33
    }
292
0
    if (c0 == 'f' || c0 == 'n' || c0 == '0') {
293
0
  *result = FcFalse;
294
0
  return FcTrue;
295
0
    }
296
0
    if (c0 == 'd' || c0 == 'x' || c0 == '2') {
297
0
  *result = FcDontCare;
298
0
  return FcTrue;
299
0
    }
300
0
    if (c0 == 'o') {
301
0
  c1 = v[1];
302
0
  c1 = FcToLower (c1);
303
0
  if (c1 == 'n') {
304
0
      *result = FcTrue;
305
0
      return FcTrue;
306
0
  }
307
0
  if (c1 == 'f') {
308
0
      *result = FcFalse;
309
0
      return FcTrue;
310
0
  }
311
0
  if (c1 == 'r') {
312
0
      *result = FcDontCare;
313
0
      return FcTrue;
314
0
  }
315
0
    }
316
0
    return FcFalse;
317
0
}
318
319
static FcValue
320
FcNameConvert (FcType type, const char *object, FcChar8 *string)
321
0
{
322
0
    FcValue  v;
323
0
    FcMatrix m;
324
0
    double   b, e;
325
0
    char    *p;
326
327
0
    v.type = type;
328
0
    switch ((int)v.type) {
329
0
    case FcTypeInteger:
330
0
  if (!FcNameConstantWithObjectCheck (string, object, &v.u.i))
331
0
      v.u.i = atoi ((char *)string);
332
0
  break;
333
0
    case FcTypeString:
334
0
  v.u.s = FcStrdup (string);
335
0
  if (!v.u.s)
336
0
      v.type = FcTypeVoid;
337
0
  break;
338
0
    case FcTypeBool:
339
0
  if (!FcNameBool (string, &v.u.b))
340
0
      v.u.b = FcFalse;
341
0
  break;
342
0
    case FcTypeDouble:
343
0
  v.u.d = strtod ((char *)string, 0);
344
0
  break;
345
0
    case FcTypeMatrix:
346
0
  FcMatrixInit (&m);
347
0
  sscanf ((char *)string, "%lg %lg %lg %lg", &m.xx, &m.xy, &m.yx, &m.yy);
348
0
  v.u.m = FcMatrixCopy (&m);
349
0
  break;
350
0
    case FcTypeCharSet:
351
0
  v.u.c = FcNameParseCharSet (string);
352
0
  if (!v.u.c)
353
0
      v.type = FcTypeVoid;
354
0
  break;
355
0
    case FcTypeLangSet:
356
0
  v.u.l = FcNameParseLangSet (string);
357
0
  if (!v.u.l)
358
0
      v.type = FcTypeVoid;
359
0
  break;
360
0
    case FcTypeRange:
361
0
  if (sscanf ((char *)string, "[%lg %lg]", &b, &e) != 2) {
362
0
      char  *sc, *ec;
363
0
      size_t len = strlen ((const char *)string);
364
0
      int    si, ei;
365
366
0
      sc = malloc (len + 1);
367
0
      ec = malloc (len + 1);
368
0
      if (sc && ec && sscanf ((char *)string, "[%s %[^]]]", sc, ec) == 2) {
369
0
    if (FcNameConstantWithObjectCheck ((const FcChar8 *)sc, object, &si) &&
370
0
        FcNameConstantWithObjectCheck ((const FcChar8 *)ec, object, &ei))
371
0
        v.u.r = FcRangeCreateDouble (si, ei);
372
0
    else
373
0
        goto bail1;
374
0
      } else {
375
0
      bail1:
376
0
    v.type = FcTypeDouble;
377
0
    if (FcNameConstantWithObjectCheck (string, object, &si)) {
378
0
        v.u.d = (double)si;
379
0
    } else {
380
0
        v.u.d = strtod ((char *)string, &p);
381
0
        if (p != NULL && p[0] != 0)
382
0
      v.type = FcTypeVoid;
383
0
    }
384
0
      }
385
0
      if (sc)
386
0
    free (sc);
387
0
      if (ec)
388
0
    free (ec);
389
0
  } else
390
0
      v.u.r = FcRangeCreateDouble (b, e);
391
0
  break;
392
0
    default:
393
  /* No valid type to convert */
394
0
  v.type = FcTypeVoid;
395
0
  break;
396
0
    }
397
0
    return v;
398
0
}
399
400
static const FcChar8 *
401
FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last)
402
0
{
403
0
    FcChar8 c;
404
405
0
    while ((c = *cur)) {
406
0
  if (!isspace (c))
407
0
      break;
408
0
  ++cur;
409
0
    }
410
0
    while ((c = *cur)) {
411
0
  if (c == '\\') {
412
0
      ++cur;
413
0
      if (!(c = *cur))
414
0
    break;
415
0
  } else if (strchr (delim, c))
416
0
      break;
417
0
  ++cur;
418
0
  *save++ = c;
419
0
    }
420
0
    *save = 0;
421
0
    *last = *cur;
422
0
    if (*cur)
423
0
  cur++;
424
0
    return cur;
425
0
}
426
427
FcPattern *
428
FcNameParse (const FcChar8 *name)
429
0
{
430
0
    FcChar8            *save;
431
0
    FcPattern          *pat;
432
0
    double              d;
433
0
    FcChar8            *e;
434
0
    FcChar8             delim;
435
0
    FcValue             v;
436
0
    const FcObjectType *t;
437
0
    const FcConstant   *c;
438
439
    /* freed below */
440
0
    save = malloc (strlen ((char *)name) + 1);
441
0
    if (!save)
442
0
  goto bail0;
443
0
    pat = FcPatternCreate();
444
0
    if (!pat)
445
0
  goto bail1;
446
447
0
    for (;;) {
448
0
  name = FcNameFindNext (name, "-,:", save, &delim);
449
0
  if (save[0]) {
450
0
      if (!FcPatternObjectAddString (pat, FC_FAMILY_OBJECT, save))
451
0
    goto bail2;
452
0
  }
453
0
  if (delim != ',')
454
0
      break;
455
0
    }
456
0
    if (delim == '-') {
457
0
  for (;;) {
458
0
      name = FcNameFindNext (name, "-,:", save, &delim);
459
0
      d = strtod ((char *)save, (char **)&e);
460
0
      if (e != save) {
461
0
    if (!FcPatternObjectAddDouble (pat, FC_SIZE_OBJECT, d))
462
0
        goto bail2;
463
0
      }
464
0
      if (delim != ',')
465
0
    break;
466
0
  }
467
0
    }
468
0
    while (delim == ':') {
469
0
  name = FcNameFindNext (name, "=_:", save, &delim);
470
0
  if (save[0]) {
471
0
      if (delim == '=' || delim == '_') {
472
0
    t = FcNameGetObjectType ((char *)save);
473
0
    for (;;) {
474
0
        name = FcNameFindNext (name, ":,", save, &delim);
475
0
        if (t) {
476
0
      v = FcNameConvert (t->type, t->object, save);
477
0
      if (!FcPatternAdd (pat, t->object, v, FcTrue)) {
478
0
          FcValueDestroy (v);
479
0
          goto bail2;
480
0
      }
481
0
      FcValueDestroy (v);
482
0
        }
483
0
        if (delim != ',')
484
0
      break;
485
0
    }
486
0
      } else {
487
0
    if ((c = FcNameGetConstant (save))) {
488
0
        t = FcNameGetObjectType ((char *)c->object);
489
0
        if (t == NULL)
490
0
      goto bail2;
491
0
        switch ((int)t->type) {
492
0
        case FcTypeInteger:
493
0
        case FcTypeDouble:
494
0
      if (!FcPatternAddInteger (pat, c->object, c->value))
495
0
          goto bail2;
496
0
      break;
497
0
        case FcTypeBool:
498
0
      if (!FcPatternAddBool (pat, c->object, c->value))
499
0
          goto bail2;
500
0
      break;
501
0
        case FcTypeRange:
502
0
      if (!FcPatternAddInteger (pat, c->object, c->value))
503
0
          goto bail2;
504
0
      break;
505
0
        default:
506
0
      break;
507
0
        }
508
0
    }
509
0
      }
510
0
  }
511
0
    }
512
513
0
    free (save);
514
0
    return pat;
515
516
0
bail2:
517
0
    FcPatternDestroy (pat);
518
0
bail1:
519
0
    free (save);
520
0
bail0:
521
0
    return 0;
522
0
}
523
static FcBool
524
FcNameUnparseString (FcStrBuf      *buf,
525
                     const FcChar8 *string,
526
                     const FcChar8 *escape)
527
0
{
528
0
    FcChar8 c;
529
0
    while ((c = *string++)) {
530
0
  if (escape && strchr ((char *)escape, (char)c)) {
531
0
      if (!FcStrBufChar (buf, escape[0]))
532
0
    return FcFalse;
533
0
  }
534
0
  if (!FcStrBufChar (buf, c))
535
0
      return FcFalse;
536
0
    }
537
0
    return FcTrue;
538
0
}
539
540
FcBool
541
FcNameUnparseValue (FcStrBuf *buf,
542
                    FcValue  *v0,
543
                    FcChar8  *escape)
544
0
{
545
0
    FcChar8 temp[1024];
546
0
    FcValue v = FcValueCanonicalize (v0);
547
548
0
    switch (v.type) {
549
0
    case FcTypeUnknown:
550
0
    case FcTypeVoid:
551
0
  return FcTrue;
552
0
    case FcTypeInteger:
553
0
  sprintf ((char *)temp, "%d", v.u.i);
554
0
  return FcNameUnparseString (buf, temp, 0);
555
0
    case FcTypeDouble:
556
0
  sprintf ((char *)temp, "%g", v.u.d);
557
0
  return FcNameUnparseString (buf, temp, 0);
558
0
    case FcTypeString:
559
0
  return FcNameUnparseString (buf, v.u.s, escape);
560
0
    case FcTypeBool:
561
0
  return FcNameUnparseString (buf,
562
0
                              v.u.b == FcTrue ? (FcChar8 *)"True" : v.u.b == FcFalse ? (FcChar8 *)"False"
563
0
                                                                                     : (FcChar8 *)"DontCare",
564
0
                              0);
565
0
    case FcTypeMatrix:
566
0
  sprintf ((char *)temp, "%g %g %g %g",
567
0
           v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
568
0
  return FcNameUnparseString (buf, temp, 0);
569
0
    case FcTypeCharSet:
570
0
  return FcNameUnparseCharSet (buf, v.u.c);
571
0
    case FcTypeLangSet:
572
0
  return FcNameUnparseLangSet (buf, v.u.l);
573
0
    case FcTypeFTFace:
574
0
  return FcTrue;
575
0
    case FcTypeRange:
576
0
  sprintf ((char *)temp, "[%g %g]", v.u.r->begin, v.u.r->end);
577
0
  return FcNameUnparseString (buf, temp, 0);
578
0
    }
579
0
    return FcFalse;
580
0
}
581
582
FcBool
583
FcNameUnparseValueList (FcStrBuf      *buf,
584
                        FcValueListPtr v,
585
                        FcChar8       *escape)
586
0
{
587
0
    while (v) {
588
0
  if (!FcNameUnparseValue (buf, &v->value, escape))
589
0
      return FcFalse;
590
0
  if ((v = FcValueListNext (v)) != NULL)
591
0
      if (!FcNameUnparseString (buf, (FcChar8 *)",", 0))
592
0
    return FcFalse;
593
0
    }
594
0
    return FcTrue;
595
0
}
596
597
0
#define FC_ESCAPE_FIXED    "\\-:,"
598
0
#define FC_ESCAPE_VARIABLE "\\=_:,"
599
600
FcChar8 *
601
FcNameUnparse (FcPattern *pat)
602
0
{
603
0
    return FcNameUnparseEscaped (pat, FcTrue);
604
0
}
605
606
FcChar8 *
607
FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
608
0
{
609
0
    FcStrBuf      buf, buf2;
610
0
    FcChar8       buf_static[8192], buf2_static[256];
611
0
    int           i;
612
0
    FcPatternElt *e;
613
614
0
    FcStrBufInit (&buf, buf_static, sizeof (buf_static));
615
0
    FcStrBufInit (&buf2, buf2_static, sizeof (buf2_static));
616
0
    e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT);
617
0
    if (e) {
618
0
  if (!FcNameUnparseValueList (&buf, FcPatternEltValues (e), escape ? (FcChar8 *)FC_ESCAPE_FIXED : 0))
619
0
      goto bail0;
620
0
    }
621
0
    e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT);
622
0
    if (e) {
623
0
  FcChar8 *p;
624
625
0
  if (!FcNameUnparseString (&buf2, (FcChar8 *)"-", 0))
626
0
      goto bail0;
627
0
  if (!FcNameUnparseValueList (&buf2, FcPatternEltValues (e), escape ? (FcChar8 *)FC_ESCAPE_FIXED : 0))
628
0
      goto bail0;
629
0
  p = FcStrBufDoneStatic (&buf2);
630
0
  FcStrBufDestroy (&buf2);
631
0
  if (strlen ((const char *)p) > 1)
632
0
      if (!FcStrBufString (&buf, p))
633
0
    goto bail0;
634
0
    }
635
0
    for (i = 0; i < NUM_OBJECT_TYPES; i++) {
636
0
  FcObject            id = i + 1;
637
0
  const FcObjectType *o;
638
0
  o = &FcObjects[i];
639
0
  if (!strcmp (o->object, FC_FAMILY) ||
640
0
      !strcmp (o->object, FC_SIZE))
641
0
      continue;
642
643
0
  e = FcPatternObjectFindElt (pat, id);
644
0
  if (e) {
645
0
      if (!FcNameUnparseString (&buf, (FcChar8 *)":", 0))
646
0
    goto bail0;
647
0
      if (!FcNameUnparseString (&buf, (FcChar8 *)o->object, escape ? (FcChar8 *)FC_ESCAPE_VARIABLE : 0))
648
0
    goto bail0;
649
0
      if (!FcNameUnparseString (&buf, (FcChar8 *)"=", 0))
650
0
    goto bail0;
651
0
      if (!FcNameUnparseValueList (&buf, FcPatternEltValues (e), escape ? (FcChar8 *)FC_ESCAPE_VARIABLE : 0))
652
0
    goto bail0;
653
0
  }
654
0
    }
655
0
    return FcStrBufDone (&buf);
656
0
bail0:
657
0
    FcStrBufDestroy (&buf);
658
0
    return 0;
659
0
}
660
#define __fcname__
661
#include "fcaliastail.h"
662
#undef __fcname__