12c393a42Smrg/* 2a6844aabSmrg * fontconfig/src/fcname.c 32c393a42Smrg * 42c393a42Smrg * Copyright © 2000 Keith Packard 52c393a42Smrg * 62c393a42Smrg * Permission to use, copy, modify, distribute, and sell this software and its 72c393a42Smrg * documentation for any purpose is hereby granted without fee, provided that 82c393a42Smrg * the above copyright notice appear in all copies and that both that 92c393a42Smrg * copyright notice and this permission notice appear in supporting 10898dab68Smrg * documentation, and that the name of the author(s) not be used in 112c393a42Smrg * advertising or publicity pertaining to distribution of the software without 12898dab68Smrg * specific, written prior permission. The authors make no 132c393a42Smrg * representations about the suitability of this software for any purpose. It 142c393a42Smrg * is provided "as is" without express or implied warranty. 152c393a42Smrg * 16a6844aabSmrg * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 172c393a42Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18a6844aabSmrg * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR 192c393a42Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 202c393a42Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 212c393a42Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 222c393a42Smrg * PERFORMANCE OF THIS SOFTWARE. 232c393a42Smrg */ 242c393a42Smrg 252c393a42Smrg#include "fcint.h" 262c393a42Smrg#include <ctype.h> 272c393a42Smrg#include <stdlib.h> 282c393a42Smrg#include <string.h> 292c393a42Smrg#include <stdio.h> 302c393a42Smrg 315e61939bSmrgstatic const FcObjectType FcObjects[] = { 325e61939bSmrg#define FC_OBJECT(NAME, Type, Cmp) { FC_##NAME, Type }, 335e61939bSmrg#include "fcobjs.h" 345e61939bSmrg#undef FC_OBJECT 352c393a42Smrg}; 362c393a42Smrg 375e61939bSmrg#define NUM_OBJECT_TYPES ((int) (sizeof FcObjects / sizeof FcObjects[0])) 382c393a42Smrg 395e61939bSmrgstatic const FcObjectType * 402c393a42SmrgFcObjectFindById (FcObject object) 412c393a42Smrg{ 425e61939bSmrg if (1 <= object && object <= NUM_OBJECT_TYPES) 435e61939bSmrg return &FcObjects[object - 1]; 445e61939bSmrg return FcObjectLookupOtherTypeById (object); 452c393a42Smrg} 462c393a42Smrg 472c393a42SmrgFcBool 482c393a42SmrgFcNameRegisterObjectTypes (const FcObjectType *types, int ntypes) 492c393a42Smrg{ 505e61939bSmrg /* Deprecated. */ 515e61939bSmrg return FcFalse; 522c393a42Smrg} 532c393a42Smrg 542c393a42SmrgFcBool 552c393a42SmrgFcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes) 562c393a42Smrg{ 575e61939bSmrg /* Deprecated. */ 585e61939bSmrg return FcFalse; 592c393a42Smrg} 602c393a42Smrg 612c393a42Smrgconst FcObjectType * 622c393a42SmrgFcNameGetObjectType (const char *object) 632c393a42Smrg{ 645e61939bSmrg int id = FcObjectLookupBuiltinIdByName (object); 655e61939bSmrg 665e61939bSmrg if (!id) 675e61939bSmrg return FcObjectLookupOtherTypeByName (object); 685e61939bSmrg 695e61939bSmrg return &FcObjects[id - 1]; 702c393a42Smrg} 712c393a42Smrg 722c393a42SmrgFcBool 732c393a42SmrgFcObjectValidType (FcObject object, FcType type) 742c393a42Smrg{ 755e61939bSmrg const FcObjectType *t = FcObjectFindById (object); 762c393a42Smrg 772c393a42Smrg if (t) { 785e61939bSmrg switch ((int) t->type) { 79d91dd368Smrg case FcTypeUnknown: 80d91dd368Smrg return FcTrue; 812c393a42Smrg case FcTypeDouble: 822c393a42Smrg case FcTypeInteger: 832c393a42Smrg if (type == FcTypeDouble || type == FcTypeInteger) 842c393a42Smrg return FcTrue; 852c393a42Smrg break; 862c393a42Smrg case FcTypeLangSet: 872c393a42Smrg if (type == FcTypeLangSet || type == FcTypeString) 882c393a42Smrg return FcTrue; 892c393a42Smrg break; 9018bd4a06Smrg case FcTypeRange: 9118bd4a06Smrg if (type == FcTypeRange || 9218bd4a06Smrg type == FcTypeDouble || 9318bd4a06Smrg type == FcTypeInteger) 9418bd4a06Smrg return FcTrue; 9518bd4a06Smrg break; 962c393a42Smrg default: 97d91dd368Smrg if (type == t->type) 982c393a42Smrg return FcTrue; 992c393a42Smrg break; 1002c393a42Smrg } 1012c393a42Smrg return FcFalse; 1022c393a42Smrg } 1032c393a42Smrg return FcTrue; 1042c393a42Smrg} 1052c393a42Smrg 1062c393a42SmrgFcObject 1072c393a42SmrgFcObjectFromName (const char * name) 1082c393a42Smrg{ 1095e61939bSmrg return FcObjectLookupIdByName (name); 1102c393a42Smrg} 1112c393a42Smrg 112a6844aabSmrgFcObjectSet * 113a6844aabSmrgFcObjectGetSet (void) 114a6844aabSmrg{ 115a6844aabSmrg int i; 116a6844aabSmrg FcObjectSet *os = NULL; 117a6844aabSmrg 118a6844aabSmrg 119a6844aabSmrg os = FcObjectSetCreate (); 1205e61939bSmrg for (i = 0; i < NUM_OBJECT_TYPES; i++) 121a6844aabSmrg FcObjectSetAdd (os, FcObjects[i].object); 122a6844aabSmrg 123a6844aabSmrg return os; 124a6844aabSmrg} 125a6844aabSmrg 1262c393a42Smrgconst char * 1272c393a42SmrgFcObjectName (FcObject object) 1282c393a42Smrg{ 1295e61939bSmrg const FcObjectType *o = FcObjectFindById (object); 1302c393a42Smrg 1312c393a42Smrg if (o) 1322c393a42Smrg return o->object; 1335e61939bSmrg 1345e61939bSmrg return FcObjectLookupOtherNameById (object); 1352c393a42Smrg} 1362c393a42Smrg 1372c393a42Smrgstatic const FcConstant _FcBaseConstants[] = { 1382c393a42Smrg { (FcChar8 *) "thin", "weight", FC_WEIGHT_THIN, }, 1392c393a42Smrg { (FcChar8 *) "extralight", "weight", FC_WEIGHT_EXTRALIGHT, }, 1402c393a42Smrg { (FcChar8 *) "ultralight", "weight", FC_WEIGHT_EXTRALIGHT, }, 14118bd4a06Smrg { (FcChar8 *) "demilight", "weight", FC_WEIGHT_DEMILIGHT, }, 14218bd4a06Smrg { (FcChar8 *) "semilight", "weight", FC_WEIGHT_DEMILIGHT, }, 1432c393a42Smrg { (FcChar8 *) "light", "weight", FC_WEIGHT_LIGHT, }, 1442c393a42Smrg { (FcChar8 *) "book", "weight", FC_WEIGHT_BOOK, }, 1452c393a42Smrg { (FcChar8 *) "regular", "weight", FC_WEIGHT_REGULAR, }, 14646bb3e47Smrg { (FcChar8 *) "normal", "weight", FC_WEIGHT_NORMAL, }, 1472c393a42Smrg { (FcChar8 *) "medium", "weight", FC_WEIGHT_MEDIUM, }, 1482c393a42Smrg { (FcChar8 *) "demibold", "weight", FC_WEIGHT_DEMIBOLD, }, 1492c393a42Smrg { (FcChar8 *) "semibold", "weight", FC_WEIGHT_DEMIBOLD, }, 1502c393a42Smrg { (FcChar8 *) "bold", "weight", FC_WEIGHT_BOLD, }, 1512c393a42Smrg { (FcChar8 *) "extrabold", "weight", FC_WEIGHT_EXTRABOLD, }, 1522c393a42Smrg { (FcChar8 *) "ultrabold", "weight", FC_WEIGHT_EXTRABOLD, }, 1532c393a42Smrg { (FcChar8 *) "black", "weight", FC_WEIGHT_BLACK, }, 1542c393a42Smrg { (FcChar8 *) "heavy", "weight", FC_WEIGHT_HEAVY, }, 15546bb3e47Smrg { (FcChar8 *) "extrablack", "weight", FC_WEIGHT_EXTRABLACK, }, 15646bb3e47Smrg { (FcChar8 *) "ultrablack", "weight", FC_WEIGHT_ULTRABLACK, }, 1572c393a42Smrg 1582c393a42Smrg { (FcChar8 *) "roman", "slant", FC_SLANT_ROMAN, }, 1592c393a42Smrg { (FcChar8 *) "italic", "slant", FC_SLANT_ITALIC, }, 1602c393a42Smrg { (FcChar8 *) "oblique", "slant", FC_SLANT_OBLIQUE, }, 1612c393a42Smrg 1622c393a42Smrg { (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED }, 1632c393a42Smrg { (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED }, 1642c393a42Smrg { (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED }, 1655e61939bSmrg { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED }, 1662c393a42Smrg { (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL }, 1672c393a42Smrg { (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED }, 1682c393a42Smrg { (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED }, 1692c393a42Smrg { (FcChar8 *) "extraexpanded", "width", FC_WIDTH_EXTRAEXPANDED }, 1702c393a42Smrg { (FcChar8 *) "ultraexpanded", "width", FC_WIDTH_ULTRAEXPANDED }, 171898dab68Smrg 1722c393a42Smrg { (FcChar8 *) "proportional", "spacing", FC_PROPORTIONAL, }, 1732c393a42Smrg { (FcChar8 *) "dual", "spacing", FC_DUAL, }, 1742c393a42Smrg { (FcChar8 *) "mono", "spacing", FC_MONO, }, 1752c393a42Smrg { (FcChar8 *) "charcell", "spacing", FC_CHARCELL, }, 1762c393a42Smrg 1772c393a42Smrg { (FcChar8 *) "unknown", "rgba", FC_RGBA_UNKNOWN }, 1782c393a42Smrg { (FcChar8 *) "rgb", "rgba", FC_RGBA_RGB, }, 1792c393a42Smrg { (FcChar8 *) "bgr", "rgba", FC_RGBA_BGR, }, 1802c393a42Smrg { (FcChar8 *) "vrgb", "rgba", FC_RGBA_VRGB }, 1812c393a42Smrg { (FcChar8 *) "vbgr", "rgba", FC_RGBA_VBGR }, 1822c393a42Smrg { (FcChar8 *) "none", "rgba", FC_RGBA_NONE }, 1832c393a42Smrg 1842c393a42Smrg { (FcChar8 *) "hintnone", "hintstyle", FC_HINT_NONE }, 1852c393a42Smrg { (FcChar8 *) "hintslight", "hintstyle", FC_HINT_SLIGHT }, 1862c393a42Smrg { (FcChar8 *) "hintmedium", "hintstyle", FC_HINT_MEDIUM }, 1872c393a42Smrg { (FcChar8 *) "hintfull", "hintstyle", FC_HINT_FULL }, 1882c393a42Smrg 1892c393a42Smrg { (FcChar8 *) "antialias", "antialias", FcTrue }, 1902c393a42Smrg { (FcChar8 *) "hinting", "hinting", FcTrue }, 1912c393a42Smrg { (FcChar8 *) "verticallayout", "verticallayout", FcTrue }, 1922c393a42Smrg { (FcChar8 *) "autohint", "autohint", FcTrue }, 193898dab68Smrg { (FcChar8 *) "globaladvance", "globaladvance", FcTrue }, /* deprecated */ 1942c393a42Smrg { (FcChar8 *) "outline", "outline", FcTrue }, 1952c393a42Smrg { (FcChar8 *) "scalable", "scalable", FcTrue }, 1962c393a42Smrg { (FcChar8 *) "minspace", "minspace", FcTrue }, 1972c393a42Smrg { (FcChar8 *) "embolden", "embolden", FcTrue }, 1982c393a42Smrg { (FcChar8 *) "embeddedbitmap", "embeddedbitmap", FcTrue }, 1992c393a42Smrg { (FcChar8 *) "decorative", "decorative", FcTrue }, 2002c393a42Smrg { (FcChar8 *) "lcdnone", "lcdfilter", FC_LCD_NONE }, 2012c393a42Smrg { (FcChar8 *) "lcddefault", "lcdfilter", FC_LCD_DEFAULT }, 2022c393a42Smrg { (FcChar8 *) "lcdlight", "lcdfilter", FC_LCD_LIGHT }, 2032c393a42Smrg { (FcChar8 *) "lcdlegacy", "lcdfilter", FC_LCD_LEGACY }, 2042c393a42Smrg}; 2052c393a42Smrg 2062c393a42Smrg#define NUM_FC_CONSTANTS (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0]) 2072c393a42Smrg 2082c393a42SmrgFcBool 2092c393a42SmrgFcNameRegisterConstants (const FcConstant *consts, int nconsts) 2102c393a42Smrg{ 2115e61939bSmrg /* Deprecated. */ 2125e61939bSmrg return FcFalse; 2132c393a42Smrg} 2142c393a42Smrg 2152c393a42SmrgFcBool 2162c393a42SmrgFcNameUnregisterConstants (const FcConstant *consts, int nconsts) 2172c393a42Smrg{ 2185e61939bSmrg /* Deprecated. */ 2192c393a42Smrg return FcFalse; 2202c393a42Smrg} 2212c393a42Smrg 2222c393a42Smrgconst FcConstant * 223898dab68SmrgFcNameGetConstant (const FcChar8 *string) 2242c393a42Smrg{ 2255e61939bSmrg unsigned int i; 2265e61939bSmrg 2275e61939bSmrg for (i = 0; i < NUM_FC_CONSTANTS; i++) 2285e61939bSmrg if (!FcStrCmpIgnoreCase (string, _FcBaseConstants[i].name)) 2295e61939bSmrg return &_FcBaseConstants[i]; 2302c393a42Smrg 2312c393a42Smrg return 0; 2322c393a42Smrg} 2332c393a42Smrg 23446bb3e47Smrgconst FcConstant * 23546bb3e47SmrgFcNameGetConstantFor (const FcChar8 *string, const char *object) 23646bb3e47Smrg{ 23746bb3e47Smrg unsigned int i; 23846bb3e47Smrg 23946bb3e47Smrg for (i = 0; i < NUM_FC_CONSTANTS; i++) 24046bb3e47Smrg if (!FcStrCmpIgnoreCase (string, _FcBaseConstants[i].name) && 24146bb3e47Smrg !FcStrCmpIgnoreCase ((const FcChar8 *)object, (const FcChar8 *)_FcBaseConstants[i].object)) 24246bb3e47Smrg return &_FcBaseConstants[i]; 24346bb3e47Smrg 24446bb3e47Smrg return 0; 24546bb3e47Smrg} 24646bb3e47Smrg 2472c393a42SmrgFcBool 248898dab68SmrgFcNameConstant (const FcChar8 *string, int *result) 2492c393a42Smrg{ 2502c393a42Smrg const FcConstant *c; 2512c393a42Smrg 2522c393a42Smrg if ((c = FcNameGetConstant(string))) 2532c393a42Smrg { 2542c393a42Smrg *result = c->value; 2552c393a42Smrg return FcTrue; 2562c393a42Smrg } 2572c393a42Smrg return FcFalse; 2582c393a42Smrg} 2592c393a42Smrg 2607872e0a1SmrgFcBool 2617872e0a1SmrgFcNameConstantWithObjectCheck (const FcChar8 *string, const char *object, int *result) 2627872e0a1Smrg{ 2637872e0a1Smrg const FcConstant *c; 2647872e0a1Smrg 26546bb3e47Smrg if ((c = FcNameGetConstantFor(string, object))) 26646bb3e47Smrg { 26746bb3e47Smrg *result = c->value; 26846bb3e47Smrg return FcTrue; 26946bb3e47Smrg } 27046bb3e47Smrg else if ((c = FcNameGetConstant(string))) 2717872e0a1Smrg { 2727872e0a1Smrg if (strcmp (c->object, object) != 0) 2737872e0a1Smrg { 2747872e0a1Smrg fprintf (stderr, "Fontconfig error: Unexpected constant name `%s' used for object `%s': should be `%s'\n", string, object, c->object); 2757872e0a1Smrg return FcFalse; 2767872e0a1Smrg } 27746bb3e47Smrg /* Unlikely to reach out */ 2787872e0a1Smrg *result = c->value; 2797872e0a1Smrg return FcTrue; 2807872e0a1Smrg } 2817872e0a1Smrg return FcFalse; 2827872e0a1Smrg} 2837872e0a1Smrg 2842c393a42SmrgFcBool 2852c393a42SmrgFcNameBool (const FcChar8 *v, FcBool *result) 2862c393a42Smrg{ 2872c393a42Smrg char c0, c1; 2882c393a42Smrg 2892c393a42Smrg c0 = *v; 2902c393a42Smrg c0 = FcToLower (c0); 2912c393a42Smrg if (c0 == 't' || c0 == 'y' || c0 == '1') 2922c393a42Smrg { 2932c393a42Smrg *result = FcTrue; 2942c393a42Smrg return FcTrue; 2952c393a42Smrg } 2962c393a42Smrg if (c0 == 'f' || c0 == 'n' || c0 == '0') 2972c393a42Smrg { 2982c393a42Smrg *result = FcFalse; 2992c393a42Smrg return FcTrue; 3002c393a42Smrg } 3011887081fSmrg if (c0 == 'd' || c0 == 'x' || c0 == '2') 3021887081fSmrg { 3031887081fSmrg *result = FcDontCare; 3041887081fSmrg return FcTrue; 3051887081fSmrg } 3062c393a42Smrg if (c0 == 'o') 3072c393a42Smrg { 3082c393a42Smrg c1 = v[1]; 3092c393a42Smrg c1 = FcToLower (c1); 3102c393a42Smrg if (c1 == 'n') 3112c393a42Smrg { 3122c393a42Smrg *result = FcTrue; 3132c393a42Smrg return FcTrue; 3142c393a42Smrg } 3152c393a42Smrg if (c1 == 'f') 3162c393a42Smrg { 3172c393a42Smrg *result = FcFalse; 3182c393a42Smrg return FcTrue; 3192c393a42Smrg } 3201887081fSmrg if (c1 == 'r') 3211887081fSmrg { 3221887081fSmrg *result = FcDontCare; 3231887081fSmrg return FcTrue; 3241887081fSmrg } 3252c393a42Smrg } 3262c393a42Smrg return FcFalse; 3272c393a42Smrg} 3282c393a42Smrg 3292c393a42Smrgstatic FcValue 3307872e0a1SmrgFcNameConvert (FcType type, const char *object, FcChar8 *string) 3312c393a42Smrg{ 3322c393a42Smrg FcValue v; 333898dab68Smrg FcMatrix m; 33418bd4a06Smrg double b, e; 33518bd4a06Smrg char *p; 3362c393a42Smrg 3372c393a42Smrg v.type = type; 3385e61939bSmrg switch ((int) v.type) { 3392c393a42Smrg case FcTypeInteger: 3407872e0a1Smrg if (!FcNameConstantWithObjectCheck (string, object, &v.u.i)) 3412c393a42Smrg v.u.i = atoi ((char *) string); 3422c393a42Smrg break; 3432c393a42Smrg case FcTypeString: 3445e61939bSmrg v.u.s = FcStrdup (string); 3452c393a42Smrg if (!v.u.s) 3462c393a42Smrg v.type = FcTypeVoid; 3472c393a42Smrg break; 3482c393a42Smrg case FcTypeBool: 3492c393a42Smrg if (!FcNameBool (string, &v.u.b)) 3502c393a42Smrg v.u.b = FcFalse; 3512c393a42Smrg break; 3522c393a42Smrg case FcTypeDouble: 3532c393a42Smrg v.u.d = strtod ((char *) string, 0); 3542c393a42Smrg break; 3552c393a42Smrg case FcTypeMatrix: 3565e61939bSmrg FcMatrixInit (&m); 357898dab68Smrg sscanf ((char *) string, "%lg %lg %lg %lg", &m.xx, &m.xy, &m.yx, &m.yy); 358898dab68Smrg v.u.m = FcMatrixCopy (&m); 3592c393a42Smrg break; 3602c393a42Smrg case FcTypeCharSet: 3612c393a42Smrg v.u.c = FcNameParseCharSet (string); 3622c393a42Smrg if (!v.u.c) 3632c393a42Smrg v.type = FcTypeVoid; 3642c393a42Smrg break; 3652c393a42Smrg case FcTypeLangSet: 3662c393a42Smrg v.u.l = FcNameParseLangSet (string); 3672c393a42Smrg if (!v.u.l) 3682c393a42Smrg v.type = FcTypeVoid; 3692c393a42Smrg break; 37018bd4a06Smrg case FcTypeRange: 3711887081fSmrg if (sscanf ((char *) string, "[%lg %lg]", &b, &e) != 2) 37218bd4a06Smrg { 3731887081fSmrg char *sc, *ec; 3741887081fSmrg size_t len = strlen ((const char *) string); 3751887081fSmrg int si, ei; 3761887081fSmrg 3771887081fSmrg sc = malloc (len + 1); 3781887081fSmrg ec = malloc (len + 1); 3791887081fSmrg if (sc && ec && sscanf ((char *) string, "[%s %[^]]]", sc, ec) == 2) 38018bd4a06Smrg { 3817872e0a1Smrg if (FcNameConstantWithObjectCheck ((const FcChar8 *) sc, object, &si) && 3827872e0a1Smrg FcNameConstantWithObjectCheck ((const FcChar8 *) ec, object, &ei)) 3831887081fSmrg v.u.r = FcRangeCreateDouble (si, ei); 3841887081fSmrg else 3851887081fSmrg goto bail1; 38618bd4a06Smrg } 3871887081fSmrg else 3881887081fSmrg { 3891887081fSmrg bail1: 3901887081fSmrg v.type = FcTypeDouble; 3917872e0a1Smrg if (FcNameConstantWithObjectCheck (string, object, &si)) 3921887081fSmrg { 3931887081fSmrg v.u.d = (double) si; 3941887081fSmrg } else { 3951887081fSmrg v.u.d = strtod ((char *) string, &p); 3961887081fSmrg if (p != NULL && p[0] != 0) 3971887081fSmrg v.type = FcTypeVoid; 3981887081fSmrg } 3991887081fSmrg } 4001887081fSmrg if (sc) 4011887081fSmrg free (sc); 4021887081fSmrg if (ec) 4031887081fSmrg free (ec); 40418bd4a06Smrg } 40518bd4a06Smrg else 40618bd4a06Smrg v.u.r = FcRangeCreateDouble (b, e); 40718bd4a06Smrg break; 4082c393a42Smrg default: 4092c393a42Smrg break; 4102c393a42Smrg } 4112c393a42Smrg return v; 4122c393a42Smrg} 4132c393a42Smrg 4142c393a42Smrgstatic const FcChar8 * 4152c393a42SmrgFcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last) 4162c393a42Smrg{ 4172c393a42Smrg FcChar8 c; 418898dab68Smrg 419d91dd368Smrg while ((c = *cur)) 420d91dd368Smrg { 421d91dd368Smrg if (!isspace (c)) 422d91dd368Smrg break; 423d91dd368Smrg ++cur; 424d91dd368Smrg } 4252c393a42Smrg while ((c = *cur)) 4262c393a42Smrg { 4272c393a42Smrg if (c == '\\') 4282c393a42Smrg { 4292c393a42Smrg ++cur; 4302c393a42Smrg if (!(c = *cur)) 4312c393a42Smrg break; 4322c393a42Smrg } 4332c393a42Smrg else if (strchr (delim, c)) 4342c393a42Smrg break; 4352c393a42Smrg ++cur; 4362c393a42Smrg *save++ = c; 4372c393a42Smrg } 4382c393a42Smrg *save = 0; 4392c393a42Smrg *last = *cur; 4402c393a42Smrg if (*cur) 4412c393a42Smrg cur++; 4422c393a42Smrg return cur; 4432c393a42Smrg} 4442c393a42Smrg 4452c393a42SmrgFcPattern * 4462c393a42SmrgFcNameParse (const FcChar8 *name) 4472c393a42Smrg{ 4482c393a42Smrg FcChar8 *save; 4492c393a42Smrg FcPattern *pat; 4502c393a42Smrg double d; 4512c393a42Smrg FcChar8 *e; 4522c393a42Smrg FcChar8 delim; 4532c393a42Smrg FcValue v; 4542c393a42Smrg const FcObjectType *t; 4552c393a42Smrg const FcConstant *c; 4562c393a42Smrg 4572c393a42Smrg /* freed below */ 4582c393a42Smrg save = malloc (strlen ((char *) name) + 1); 4592c393a42Smrg if (!save) 4602c393a42Smrg goto bail0; 4612c393a42Smrg pat = FcPatternCreate (); 4622c393a42Smrg if (!pat) 4632c393a42Smrg goto bail1; 4642c393a42Smrg 4652c393a42Smrg for (;;) 4662c393a42Smrg { 4672c393a42Smrg name = FcNameFindNext (name, "-,:", save, &delim); 4682c393a42Smrg if (save[0]) 4692c393a42Smrg { 4707872e0a1Smrg if (!FcPatternObjectAddString (pat, FC_FAMILY_OBJECT, save)) 4712c393a42Smrg goto bail2; 4722c393a42Smrg } 4732c393a42Smrg if (delim != ',') 4742c393a42Smrg break; 4752c393a42Smrg } 4762c393a42Smrg if (delim == '-') 4772c393a42Smrg { 4782c393a42Smrg for (;;) 4792c393a42Smrg { 4802c393a42Smrg name = FcNameFindNext (name, "-,:", save, &delim); 4812c393a42Smrg d = strtod ((char *) save, (char **) &e); 4822c393a42Smrg if (e != save) 4832c393a42Smrg { 4847872e0a1Smrg if (!FcPatternObjectAddDouble (pat, FC_SIZE_OBJECT, d)) 4852c393a42Smrg goto bail2; 4862c393a42Smrg } 4872c393a42Smrg if (delim != ',') 4882c393a42Smrg break; 4892c393a42Smrg } 4902c393a42Smrg } 4912c393a42Smrg while (delim == ':') 4922c393a42Smrg { 4932c393a42Smrg name = FcNameFindNext (name, "=_:", save, &delim); 4942c393a42Smrg if (save[0]) 4952c393a42Smrg { 4962c393a42Smrg if (delim == '=' || delim == '_') 4972c393a42Smrg { 4982c393a42Smrg t = FcNameGetObjectType ((char *) save); 4992c393a42Smrg for (;;) 5002c393a42Smrg { 5012c393a42Smrg name = FcNameFindNext (name, ":,", save, &delim); 5022c393a42Smrg if (t) 5032c393a42Smrg { 5047872e0a1Smrg v = FcNameConvert (t->type, t->object, save); 5052c393a42Smrg if (!FcPatternAdd (pat, t->object, v, FcTrue)) 5062c393a42Smrg { 507898dab68Smrg FcValueDestroy (v); 5082c393a42Smrg goto bail2; 5092c393a42Smrg } 510898dab68Smrg FcValueDestroy (v); 5112c393a42Smrg } 5122c393a42Smrg if (delim != ',') 5132c393a42Smrg break; 5142c393a42Smrg } 5152c393a42Smrg } 5162c393a42Smrg else 5172c393a42Smrg { 5182c393a42Smrg if ((c = FcNameGetConstant (save))) 5192c393a42Smrg { 5202c393a42Smrg t = FcNameGetObjectType ((char *) c->object); 521b2a52337Smrg if (t == NULL) 522b2a52337Smrg goto bail2; 5235e61939bSmrg switch ((int) t->type) { 5242c393a42Smrg case FcTypeInteger: 5252c393a42Smrg case FcTypeDouble: 5262c393a42Smrg if (!FcPatternAddInteger (pat, c->object, c->value)) 5272c393a42Smrg goto bail2; 5282c393a42Smrg break; 5292c393a42Smrg case FcTypeBool: 5302c393a42Smrg if (!FcPatternAddBool (pat, c->object, c->value)) 5312c393a42Smrg goto bail2; 5322c393a42Smrg break; 5331887081fSmrg case FcTypeRange: 5341887081fSmrg if (!FcPatternAddInteger (pat, c->object, c->value)) 5351887081fSmrg goto bail2; 5361887081fSmrg break; 5372c393a42Smrg default: 5382c393a42Smrg break; 5392c393a42Smrg } 5402c393a42Smrg } 5412c393a42Smrg } 5422c393a42Smrg } 5432c393a42Smrg } 5442c393a42Smrg 5452c393a42Smrg free (save); 5462c393a42Smrg return pat; 5472c393a42Smrg 5482c393a42Smrgbail2: 5492c393a42Smrg FcPatternDestroy (pat); 5502c393a42Smrgbail1: 5512c393a42Smrg free (save); 5522c393a42Smrgbail0: 5532c393a42Smrg return 0; 5542c393a42Smrg} 5552c393a42Smrgstatic FcBool 556898dab68SmrgFcNameUnparseString (FcStrBuf *buf, 5572c393a42Smrg const FcChar8 *string, 5582c393a42Smrg const FcChar8 *escape) 5592c393a42Smrg{ 5602c393a42Smrg FcChar8 c; 5612c393a42Smrg while ((c = *string++)) 5622c393a42Smrg { 5632c393a42Smrg if (escape && strchr ((char *) escape, (char) c)) 5642c393a42Smrg { 5652c393a42Smrg if (!FcStrBufChar (buf, escape[0])) 5662c393a42Smrg return FcFalse; 5672c393a42Smrg } 5682c393a42Smrg if (!FcStrBufChar (buf, c)) 5692c393a42Smrg return FcFalse; 5702c393a42Smrg } 5712c393a42Smrg return FcTrue; 5722c393a42Smrg} 5732c393a42Smrg 574a6844aabSmrgFcBool 5752c393a42SmrgFcNameUnparseValue (FcStrBuf *buf, 5762c393a42Smrg FcValue *v0, 5772c393a42Smrg FcChar8 *escape) 5782c393a42Smrg{ 5792c393a42Smrg FcChar8 temp[1024]; 5802c393a42Smrg FcValue v = FcValueCanonicalize(v0); 581898dab68Smrg 5822c393a42Smrg switch (v.type) { 583d91dd368Smrg case FcTypeUnknown: 5842c393a42Smrg case FcTypeVoid: 5852c393a42Smrg return FcTrue; 5862c393a42Smrg case FcTypeInteger: 5872c393a42Smrg sprintf ((char *) temp, "%d", v.u.i); 5882c393a42Smrg return FcNameUnparseString (buf, temp, 0); 5892c393a42Smrg case FcTypeDouble: 5902c393a42Smrg sprintf ((char *) temp, "%g", v.u.d); 5912c393a42Smrg return FcNameUnparseString (buf, temp, 0); 5922c393a42Smrg case FcTypeString: 5932c393a42Smrg return FcNameUnparseString (buf, v.u.s, escape); 5942c393a42Smrg case FcTypeBool: 5951887081fSmrg return FcNameUnparseString (buf, 5961887081fSmrg v.u.b == FcTrue ? (FcChar8 *) "True" : 5971887081fSmrg v.u.b == FcFalse ? (FcChar8 *) "False" : 5981887081fSmrg (FcChar8 *) "DontCare", 0); 5992c393a42Smrg case FcTypeMatrix: 600898dab68Smrg sprintf ((char *) temp, "%g %g %g %g", 6012c393a42Smrg v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); 6022c393a42Smrg return FcNameUnparseString (buf, temp, 0); 6032c393a42Smrg case FcTypeCharSet: 6042c393a42Smrg return FcNameUnparseCharSet (buf, v.u.c); 6052c393a42Smrg case FcTypeLangSet: 6062c393a42Smrg return FcNameUnparseLangSet (buf, v.u.l); 6072c393a42Smrg case FcTypeFTFace: 6082c393a42Smrg return FcTrue; 60918bd4a06Smrg case FcTypeRange: 6101887081fSmrg sprintf ((char *) temp, "[%g %g]", v.u.r->begin, v.u.r->end); 61118bd4a06Smrg return FcNameUnparseString (buf, temp, 0); 6122c393a42Smrg } 6132c393a42Smrg return FcFalse; 6142c393a42Smrg} 6152c393a42Smrg 616a6844aabSmrgFcBool 6172c393a42SmrgFcNameUnparseValueList (FcStrBuf *buf, 6182c393a42Smrg FcValueListPtr v, 6192c393a42Smrg FcChar8 *escape) 6202c393a42Smrg{ 6212c393a42Smrg while (v) 6222c393a42Smrg { 6232c393a42Smrg if (!FcNameUnparseValue (buf, &v->value, escape)) 6242c393a42Smrg return FcFalse; 6252c393a42Smrg if ((v = FcValueListNext(v)) != NULL) 6262c393a42Smrg if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0)) 6272c393a42Smrg return FcFalse; 6282c393a42Smrg } 6292c393a42Smrg return FcTrue; 6302c393a42Smrg} 6312c393a42Smrg 6322c393a42Smrg#define FC_ESCAPE_FIXED "\\-:," 6332c393a42Smrg#define FC_ESCAPE_VARIABLE "\\=_:," 6342c393a42Smrg 6352c393a42SmrgFcChar8 * 6362c393a42SmrgFcNameUnparse (FcPattern *pat) 6372c393a42Smrg{ 6382c393a42Smrg return FcNameUnparseEscaped (pat, FcTrue); 6392c393a42Smrg} 6402c393a42Smrg 6412c393a42SmrgFcChar8 * 6422c393a42SmrgFcNameUnparseEscaped (FcPattern *pat, FcBool escape) 6432c393a42Smrg{ 64418bd4a06Smrg FcStrBuf buf, buf2; 64518bd4a06Smrg FcChar8 buf_static[8192], buf2_static[256]; 6462c393a42Smrg int i; 6472c393a42Smrg FcPatternElt *e; 6482c393a42Smrg 6492c393a42Smrg FcStrBufInit (&buf, buf_static, sizeof (buf_static)); 65018bd4a06Smrg FcStrBufInit (&buf2, buf2_static, sizeof (buf2_static)); 6512c393a42Smrg e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT); 6522c393a42Smrg if (e) 6532c393a42Smrg { 6542c393a42Smrg if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) 6552c393a42Smrg goto bail0; 6562c393a42Smrg } 6572c393a42Smrg e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT); 6582c393a42Smrg if (e) 6592c393a42Smrg { 66018bd4a06Smrg FcChar8 *p; 66118bd4a06Smrg 66218bd4a06Smrg if (!FcNameUnparseString (&buf2, (FcChar8 *) "-", 0)) 6632c393a42Smrg goto bail0; 66418bd4a06Smrg if (!FcNameUnparseValueList (&buf2, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) 6652c393a42Smrg goto bail0; 66618bd4a06Smrg p = FcStrBufDoneStatic (&buf2); 66718bd4a06Smrg FcStrBufDestroy (&buf2); 66818bd4a06Smrg if (strlen ((const char *)p) > 1) 66918bd4a06Smrg if (!FcStrBufString (&buf, p)) 67018bd4a06Smrg goto bail0; 6712c393a42Smrg } 6725e61939bSmrg for (i = 0; i < NUM_OBJECT_TYPES; i++) 6732c393a42Smrg { 6745e61939bSmrg FcObject id = i + 1; 6755e61939bSmrg const FcObjectType *o; 6765e61939bSmrg o = &FcObjects[i]; 6775e61939bSmrg if (!strcmp (o->object, FC_FAMILY) || 6785e61939bSmrg !strcmp (o->object, FC_SIZE)) 6795e61939bSmrg continue; 68046bb3e47Smrg 6815e61939bSmrg e = FcPatternObjectFindElt (pat, id); 6825e61939bSmrg if (e) 6832c393a42Smrg { 6845e61939bSmrg if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0)) 6855e61939bSmrg goto bail0; 6865e61939bSmrg if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) 6875e61939bSmrg goto bail0; 6885e61939bSmrg if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0)) 6895e61939bSmrg goto bail0; 6905e61939bSmrg if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? 6915e61939bSmrg (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) 6925e61939bSmrg goto bail0; 6932c393a42Smrg } 6942c393a42Smrg } 6952c393a42Smrg return FcStrBufDone (&buf); 6962c393a42Smrgbail0: 6972c393a42Smrg FcStrBufDestroy (&buf); 6982c393a42Smrg return 0; 6992c393a42Smrg} 7002c393a42Smrg#define __fcname__ 7012c393a42Smrg#include "fcaliastail.h" 7022c393a42Smrg#undef __fcname__ 703