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