fcname.c revision 7872e0a1
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, }, 1462c393a42Smrg { (FcChar8 *) "medium", "weight", FC_WEIGHT_MEDIUM, }, 1472c393a42Smrg { (FcChar8 *) "demibold", "weight", FC_WEIGHT_DEMIBOLD, }, 1482c393a42Smrg { (FcChar8 *) "semibold", "weight", FC_WEIGHT_DEMIBOLD, }, 1492c393a42Smrg { (FcChar8 *) "bold", "weight", FC_WEIGHT_BOLD, }, 1502c393a42Smrg { (FcChar8 *) "extrabold", "weight", FC_WEIGHT_EXTRABOLD, }, 1512c393a42Smrg { (FcChar8 *) "ultrabold", "weight", FC_WEIGHT_EXTRABOLD, }, 1522c393a42Smrg { (FcChar8 *) "black", "weight", FC_WEIGHT_BLACK, }, 1532c393a42Smrg { (FcChar8 *) "heavy", "weight", FC_WEIGHT_HEAVY, }, 1542c393a42Smrg 1552c393a42Smrg { (FcChar8 *) "roman", "slant", FC_SLANT_ROMAN, }, 1562c393a42Smrg { (FcChar8 *) "italic", "slant", FC_SLANT_ITALIC, }, 1572c393a42Smrg { (FcChar8 *) "oblique", "slant", FC_SLANT_OBLIQUE, }, 1582c393a42Smrg 1592c393a42Smrg { (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED }, 1602c393a42Smrg { (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED }, 1612c393a42Smrg { (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED }, 1625e61939bSmrg { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED }, 1632c393a42Smrg { (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL }, 1642c393a42Smrg { (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED }, 1652c393a42Smrg { (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED }, 1662c393a42Smrg { (FcChar8 *) "extraexpanded", "width", FC_WIDTH_EXTRAEXPANDED }, 1672c393a42Smrg { (FcChar8 *) "ultraexpanded", "width", FC_WIDTH_ULTRAEXPANDED }, 168898dab68Smrg 1692c393a42Smrg { (FcChar8 *) "proportional", "spacing", FC_PROPORTIONAL, }, 1702c393a42Smrg { (FcChar8 *) "dual", "spacing", FC_DUAL, }, 1712c393a42Smrg { (FcChar8 *) "mono", "spacing", FC_MONO, }, 1722c393a42Smrg { (FcChar8 *) "charcell", "spacing", FC_CHARCELL, }, 1732c393a42Smrg 1742c393a42Smrg { (FcChar8 *) "unknown", "rgba", FC_RGBA_UNKNOWN }, 1752c393a42Smrg { (FcChar8 *) "rgb", "rgba", FC_RGBA_RGB, }, 1762c393a42Smrg { (FcChar8 *) "bgr", "rgba", FC_RGBA_BGR, }, 1772c393a42Smrg { (FcChar8 *) "vrgb", "rgba", FC_RGBA_VRGB }, 1782c393a42Smrg { (FcChar8 *) "vbgr", "rgba", FC_RGBA_VBGR }, 1792c393a42Smrg { (FcChar8 *) "none", "rgba", FC_RGBA_NONE }, 1802c393a42Smrg 1812c393a42Smrg { (FcChar8 *) "hintnone", "hintstyle", FC_HINT_NONE }, 1822c393a42Smrg { (FcChar8 *) "hintslight", "hintstyle", FC_HINT_SLIGHT }, 1832c393a42Smrg { (FcChar8 *) "hintmedium", "hintstyle", FC_HINT_MEDIUM }, 1842c393a42Smrg { (FcChar8 *) "hintfull", "hintstyle", FC_HINT_FULL }, 1852c393a42Smrg 1862c393a42Smrg { (FcChar8 *) "antialias", "antialias", FcTrue }, 1872c393a42Smrg { (FcChar8 *) "hinting", "hinting", FcTrue }, 1882c393a42Smrg { (FcChar8 *) "verticallayout", "verticallayout", FcTrue }, 1892c393a42Smrg { (FcChar8 *) "autohint", "autohint", FcTrue }, 190898dab68Smrg { (FcChar8 *) "globaladvance", "globaladvance", FcTrue }, /* deprecated */ 1912c393a42Smrg { (FcChar8 *) "outline", "outline", FcTrue }, 1922c393a42Smrg { (FcChar8 *) "scalable", "scalable", FcTrue }, 1932c393a42Smrg { (FcChar8 *) "minspace", "minspace", FcTrue }, 1942c393a42Smrg { (FcChar8 *) "embolden", "embolden", FcTrue }, 1952c393a42Smrg { (FcChar8 *) "embeddedbitmap", "embeddedbitmap", FcTrue }, 1962c393a42Smrg { (FcChar8 *) "decorative", "decorative", FcTrue }, 1972c393a42Smrg { (FcChar8 *) "lcdnone", "lcdfilter", FC_LCD_NONE }, 1982c393a42Smrg { (FcChar8 *) "lcddefault", "lcdfilter", FC_LCD_DEFAULT }, 1992c393a42Smrg { (FcChar8 *) "lcdlight", "lcdfilter", FC_LCD_LIGHT }, 2002c393a42Smrg { (FcChar8 *) "lcdlegacy", "lcdfilter", FC_LCD_LEGACY }, 2012c393a42Smrg}; 2022c393a42Smrg 2032c393a42Smrg#define NUM_FC_CONSTANTS (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0]) 2042c393a42Smrg 2052c393a42SmrgFcBool 2062c393a42SmrgFcNameRegisterConstants (const FcConstant *consts, int nconsts) 2072c393a42Smrg{ 2085e61939bSmrg /* Deprecated. */ 2095e61939bSmrg return FcFalse; 2102c393a42Smrg} 2112c393a42Smrg 2122c393a42SmrgFcBool 2132c393a42SmrgFcNameUnregisterConstants (const FcConstant *consts, int nconsts) 2142c393a42Smrg{ 2155e61939bSmrg /* Deprecated. */ 2162c393a42Smrg return FcFalse; 2172c393a42Smrg} 2182c393a42Smrg 2192c393a42Smrgconst FcConstant * 220898dab68SmrgFcNameGetConstant (const FcChar8 *string) 2212c393a42Smrg{ 2225e61939bSmrg unsigned int i; 2235e61939bSmrg 2245e61939bSmrg for (i = 0; i < NUM_FC_CONSTANTS; i++) 2255e61939bSmrg if (!FcStrCmpIgnoreCase (string, _FcBaseConstants[i].name)) 2265e61939bSmrg return &_FcBaseConstants[i]; 2272c393a42Smrg 2282c393a42Smrg return 0; 2292c393a42Smrg} 2302c393a42Smrg 2312c393a42SmrgFcBool 232898dab68SmrgFcNameConstant (const FcChar8 *string, int *result) 2332c393a42Smrg{ 2342c393a42Smrg const FcConstant *c; 2352c393a42Smrg 2362c393a42Smrg if ((c = FcNameGetConstant(string))) 2372c393a42Smrg { 2382c393a42Smrg *result = c->value; 2392c393a42Smrg return FcTrue; 2402c393a42Smrg } 2412c393a42Smrg return FcFalse; 2422c393a42Smrg} 2432c393a42Smrg 2447872e0a1SmrgFcBool 2457872e0a1SmrgFcNameConstantWithObjectCheck (const FcChar8 *string, const char *object, int *result) 2467872e0a1Smrg{ 2477872e0a1Smrg const FcConstant *c; 2487872e0a1Smrg 2497872e0a1Smrg if ((c = FcNameGetConstant(string))) 2507872e0a1Smrg { 2517872e0a1Smrg if (strcmp (c->object, object) != 0) 2527872e0a1Smrg { 2537872e0a1Smrg fprintf (stderr, "Fontconfig error: Unexpected constant name `%s' used for object `%s': should be `%s'\n", string, object, c->object); 2547872e0a1Smrg return FcFalse; 2557872e0a1Smrg } 2567872e0a1Smrg *result = c->value; 2577872e0a1Smrg return FcTrue; 2587872e0a1Smrg } 2597872e0a1Smrg return FcFalse; 2607872e0a1Smrg} 2617872e0a1Smrg 2622c393a42SmrgFcBool 2632c393a42SmrgFcNameBool (const FcChar8 *v, FcBool *result) 2642c393a42Smrg{ 2652c393a42Smrg char c0, c1; 2662c393a42Smrg 2672c393a42Smrg c0 = *v; 2682c393a42Smrg c0 = FcToLower (c0); 2692c393a42Smrg if (c0 == 't' || c0 == 'y' || c0 == '1') 2702c393a42Smrg { 2712c393a42Smrg *result = FcTrue; 2722c393a42Smrg return FcTrue; 2732c393a42Smrg } 2742c393a42Smrg if (c0 == 'f' || c0 == 'n' || c0 == '0') 2752c393a42Smrg { 2762c393a42Smrg *result = FcFalse; 2772c393a42Smrg return FcTrue; 2782c393a42Smrg } 2791887081fSmrg if (c0 == 'd' || c0 == 'x' || c0 == '2') 2801887081fSmrg { 2811887081fSmrg *result = FcDontCare; 2821887081fSmrg return FcTrue; 2831887081fSmrg } 2842c393a42Smrg if (c0 == 'o') 2852c393a42Smrg { 2862c393a42Smrg c1 = v[1]; 2872c393a42Smrg c1 = FcToLower (c1); 2882c393a42Smrg if (c1 == 'n') 2892c393a42Smrg { 2902c393a42Smrg *result = FcTrue; 2912c393a42Smrg return FcTrue; 2922c393a42Smrg } 2932c393a42Smrg if (c1 == 'f') 2942c393a42Smrg { 2952c393a42Smrg *result = FcFalse; 2962c393a42Smrg return FcTrue; 2972c393a42Smrg } 2981887081fSmrg if (c1 == 'r') 2991887081fSmrg { 3001887081fSmrg *result = FcDontCare; 3011887081fSmrg return FcTrue; 3021887081fSmrg } 3032c393a42Smrg } 3042c393a42Smrg return FcFalse; 3052c393a42Smrg} 3062c393a42Smrg 3072c393a42Smrgstatic FcValue 3087872e0a1SmrgFcNameConvert (FcType type, const char *object, FcChar8 *string) 3092c393a42Smrg{ 3102c393a42Smrg FcValue v; 311898dab68Smrg FcMatrix m; 31218bd4a06Smrg double b, e; 31318bd4a06Smrg char *p; 3142c393a42Smrg 3152c393a42Smrg v.type = type; 3165e61939bSmrg switch ((int) v.type) { 3172c393a42Smrg case FcTypeInteger: 3187872e0a1Smrg if (!FcNameConstantWithObjectCheck (string, object, &v.u.i)) 3192c393a42Smrg v.u.i = atoi ((char *) string); 3202c393a42Smrg break; 3212c393a42Smrg case FcTypeString: 3225e61939bSmrg v.u.s = FcStrdup (string); 3232c393a42Smrg if (!v.u.s) 3242c393a42Smrg v.type = FcTypeVoid; 3252c393a42Smrg break; 3262c393a42Smrg case FcTypeBool: 3272c393a42Smrg if (!FcNameBool (string, &v.u.b)) 3282c393a42Smrg v.u.b = FcFalse; 3292c393a42Smrg break; 3302c393a42Smrg case FcTypeDouble: 3312c393a42Smrg v.u.d = strtod ((char *) string, 0); 3322c393a42Smrg break; 3332c393a42Smrg case FcTypeMatrix: 3345e61939bSmrg FcMatrixInit (&m); 335898dab68Smrg sscanf ((char *) string, "%lg %lg %lg %lg", &m.xx, &m.xy, &m.yx, &m.yy); 336898dab68Smrg v.u.m = FcMatrixCopy (&m); 3372c393a42Smrg break; 3382c393a42Smrg case FcTypeCharSet: 3392c393a42Smrg v.u.c = FcNameParseCharSet (string); 3402c393a42Smrg if (!v.u.c) 3412c393a42Smrg v.type = FcTypeVoid; 3422c393a42Smrg break; 3432c393a42Smrg case FcTypeLangSet: 3442c393a42Smrg v.u.l = FcNameParseLangSet (string); 3452c393a42Smrg if (!v.u.l) 3462c393a42Smrg v.type = FcTypeVoid; 3472c393a42Smrg break; 34818bd4a06Smrg case FcTypeRange: 3491887081fSmrg if (sscanf ((char *) string, "[%lg %lg]", &b, &e) != 2) 35018bd4a06Smrg { 3511887081fSmrg char *sc, *ec; 3521887081fSmrg size_t len = strlen ((const char *) string); 3531887081fSmrg int si, ei; 3541887081fSmrg 3551887081fSmrg sc = malloc (len + 1); 3561887081fSmrg ec = malloc (len + 1); 3571887081fSmrg if (sc && ec && sscanf ((char *) string, "[%s %[^]]]", sc, ec) == 2) 35818bd4a06Smrg { 3597872e0a1Smrg if (FcNameConstantWithObjectCheck ((const FcChar8 *) sc, object, &si) && 3607872e0a1Smrg FcNameConstantWithObjectCheck ((const FcChar8 *) ec, object, &ei)) 3611887081fSmrg v.u.r = FcRangeCreateDouble (si, ei); 3621887081fSmrg else 3631887081fSmrg goto bail1; 36418bd4a06Smrg } 3651887081fSmrg else 3661887081fSmrg { 3671887081fSmrg bail1: 3681887081fSmrg v.type = FcTypeDouble; 3697872e0a1Smrg if (FcNameConstantWithObjectCheck (string, object, &si)) 3701887081fSmrg { 3711887081fSmrg v.u.d = (double) si; 3721887081fSmrg } else { 3731887081fSmrg v.u.d = strtod ((char *) string, &p); 3741887081fSmrg if (p != NULL && p[0] != 0) 3751887081fSmrg v.type = FcTypeVoid; 3761887081fSmrg } 3771887081fSmrg } 3781887081fSmrg if (sc) 3791887081fSmrg free (sc); 3801887081fSmrg if (ec) 3811887081fSmrg free (ec); 38218bd4a06Smrg } 38318bd4a06Smrg else 38418bd4a06Smrg v.u.r = FcRangeCreateDouble (b, e); 38518bd4a06Smrg break; 3862c393a42Smrg default: 3872c393a42Smrg break; 3882c393a42Smrg } 3892c393a42Smrg return v; 3902c393a42Smrg} 3912c393a42Smrg 3922c393a42Smrgstatic const FcChar8 * 3932c393a42SmrgFcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last) 3942c393a42Smrg{ 3952c393a42Smrg FcChar8 c; 396898dab68Smrg 397d91dd368Smrg while ((c = *cur)) 398d91dd368Smrg { 399d91dd368Smrg if (!isspace (c)) 400d91dd368Smrg break; 401d91dd368Smrg ++cur; 402d91dd368Smrg } 4032c393a42Smrg while ((c = *cur)) 4042c393a42Smrg { 4052c393a42Smrg if (c == '\\') 4062c393a42Smrg { 4072c393a42Smrg ++cur; 4082c393a42Smrg if (!(c = *cur)) 4092c393a42Smrg break; 4102c393a42Smrg } 4112c393a42Smrg else if (strchr (delim, c)) 4122c393a42Smrg break; 4132c393a42Smrg ++cur; 4142c393a42Smrg *save++ = c; 4152c393a42Smrg } 4162c393a42Smrg *save = 0; 4172c393a42Smrg *last = *cur; 4182c393a42Smrg if (*cur) 4192c393a42Smrg cur++; 4202c393a42Smrg return cur; 4212c393a42Smrg} 4222c393a42Smrg 4232c393a42SmrgFcPattern * 4242c393a42SmrgFcNameParse (const FcChar8 *name) 4252c393a42Smrg{ 4262c393a42Smrg FcChar8 *save; 4272c393a42Smrg FcPattern *pat; 4282c393a42Smrg double d; 4292c393a42Smrg FcChar8 *e; 4302c393a42Smrg FcChar8 delim; 4312c393a42Smrg FcValue v; 4322c393a42Smrg const FcObjectType *t; 4332c393a42Smrg const FcConstant *c; 4342c393a42Smrg 4352c393a42Smrg /* freed below */ 4362c393a42Smrg save = malloc (strlen ((char *) name) + 1); 4372c393a42Smrg if (!save) 4382c393a42Smrg goto bail0; 4392c393a42Smrg pat = FcPatternCreate (); 4402c393a42Smrg if (!pat) 4412c393a42Smrg goto bail1; 4422c393a42Smrg 4432c393a42Smrg for (;;) 4442c393a42Smrg { 4452c393a42Smrg name = FcNameFindNext (name, "-,:", save, &delim); 4462c393a42Smrg if (save[0]) 4472c393a42Smrg { 4487872e0a1Smrg if (!FcPatternObjectAddString (pat, FC_FAMILY_OBJECT, save)) 4492c393a42Smrg goto bail2; 4502c393a42Smrg } 4512c393a42Smrg if (delim != ',') 4522c393a42Smrg break; 4532c393a42Smrg } 4542c393a42Smrg if (delim == '-') 4552c393a42Smrg { 4562c393a42Smrg for (;;) 4572c393a42Smrg { 4582c393a42Smrg name = FcNameFindNext (name, "-,:", save, &delim); 4592c393a42Smrg d = strtod ((char *) save, (char **) &e); 4602c393a42Smrg if (e != save) 4612c393a42Smrg { 4627872e0a1Smrg if (!FcPatternObjectAddDouble (pat, FC_SIZE_OBJECT, d)) 4632c393a42Smrg goto bail2; 4642c393a42Smrg } 4652c393a42Smrg if (delim != ',') 4662c393a42Smrg break; 4672c393a42Smrg } 4682c393a42Smrg } 4692c393a42Smrg while (delim == ':') 4702c393a42Smrg { 4712c393a42Smrg name = FcNameFindNext (name, "=_:", save, &delim); 4722c393a42Smrg if (save[0]) 4732c393a42Smrg { 4742c393a42Smrg if (delim == '=' || delim == '_') 4752c393a42Smrg { 4762c393a42Smrg t = FcNameGetObjectType ((char *) save); 4772c393a42Smrg for (;;) 4782c393a42Smrg { 4792c393a42Smrg name = FcNameFindNext (name, ":,", save, &delim); 4802c393a42Smrg if (t) 4812c393a42Smrg { 4827872e0a1Smrg v = FcNameConvert (t->type, t->object, save); 4832c393a42Smrg if (!FcPatternAdd (pat, t->object, v, FcTrue)) 4842c393a42Smrg { 485898dab68Smrg FcValueDestroy (v); 4862c393a42Smrg goto bail2; 4872c393a42Smrg } 488898dab68Smrg FcValueDestroy (v); 4892c393a42Smrg } 4902c393a42Smrg if (delim != ',') 4912c393a42Smrg break; 4922c393a42Smrg } 4932c393a42Smrg } 4942c393a42Smrg else 4952c393a42Smrg { 4962c393a42Smrg if ((c = FcNameGetConstant (save))) 4972c393a42Smrg { 4982c393a42Smrg t = FcNameGetObjectType ((char *) c->object); 499b2a52337Smrg if (t == NULL) 500b2a52337Smrg goto bail2; 5015e61939bSmrg switch ((int) t->type) { 5022c393a42Smrg case FcTypeInteger: 5032c393a42Smrg case FcTypeDouble: 5042c393a42Smrg if (!FcPatternAddInteger (pat, c->object, c->value)) 5052c393a42Smrg goto bail2; 5062c393a42Smrg break; 5072c393a42Smrg case FcTypeBool: 5082c393a42Smrg if (!FcPatternAddBool (pat, c->object, c->value)) 5092c393a42Smrg goto bail2; 5102c393a42Smrg break; 5111887081fSmrg case FcTypeRange: 5121887081fSmrg if (!FcPatternAddInteger (pat, c->object, c->value)) 5131887081fSmrg goto bail2; 5141887081fSmrg break; 5152c393a42Smrg default: 5162c393a42Smrg break; 5172c393a42Smrg } 5182c393a42Smrg } 5192c393a42Smrg } 5202c393a42Smrg } 5212c393a42Smrg } 5222c393a42Smrg 5232c393a42Smrg free (save); 5242c393a42Smrg return pat; 5252c393a42Smrg 5262c393a42Smrgbail2: 5272c393a42Smrg FcPatternDestroy (pat); 5282c393a42Smrgbail1: 5292c393a42Smrg free (save); 5302c393a42Smrgbail0: 5312c393a42Smrg return 0; 5322c393a42Smrg} 5332c393a42Smrgstatic FcBool 534898dab68SmrgFcNameUnparseString (FcStrBuf *buf, 5352c393a42Smrg const FcChar8 *string, 5362c393a42Smrg const FcChar8 *escape) 5372c393a42Smrg{ 5382c393a42Smrg FcChar8 c; 5392c393a42Smrg while ((c = *string++)) 5402c393a42Smrg { 5412c393a42Smrg if (escape && strchr ((char *) escape, (char) c)) 5422c393a42Smrg { 5432c393a42Smrg if (!FcStrBufChar (buf, escape[0])) 5442c393a42Smrg return FcFalse; 5452c393a42Smrg } 5462c393a42Smrg if (!FcStrBufChar (buf, c)) 5472c393a42Smrg return FcFalse; 5482c393a42Smrg } 5492c393a42Smrg return FcTrue; 5502c393a42Smrg} 5512c393a42Smrg 552a6844aabSmrgFcBool 5532c393a42SmrgFcNameUnparseValue (FcStrBuf *buf, 5542c393a42Smrg FcValue *v0, 5552c393a42Smrg FcChar8 *escape) 5562c393a42Smrg{ 5572c393a42Smrg FcChar8 temp[1024]; 5582c393a42Smrg FcValue v = FcValueCanonicalize(v0); 559898dab68Smrg 5602c393a42Smrg switch (v.type) { 561d91dd368Smrg case FcTypeUnknown: 5622c393a42Smrg case FcTypeVoid: 5632c393a42Smrg return FcTrue; 5642c393a42Smrg case FcTypeInteger: 5652c393a42Smrg sprintf ((char *) temp, "%d", v.u.i); 5662c393a42Smrg return FcNameUnparseString (buf, temp, 0); 5672c393a42Smrg case FcTypeDouble: 5682c393a42Smrg sprintf ((char *) temp, "%g", v.u.d); 5692c393a42Smrg return FcNameUnparseString (buf, temp, 0); 5702c393a42Smrg case FcTypeString: 5712c393a42Smrg return FcNameUnparseString (buf, v.u.s, escape); 5722c393a42Smrg case FcTypeBool: 5731887081fSmrg return FcNameUnparseString (buf, 5741887081fSmrg v.u.b == FcTrue ? (FcChar8 *) "True" : 5751887081fSmrg v.u.b == FcFalse ? (FcChar8 *) "False" : 5761887081fSmrg (FcChar8 *) "DontCare", 0); 5772c393a42Smrg case FcTypeMatrix: 578898dab68Smrg sprintf ((char *) temp, "%g %g %g %g", 5792c393a42Smrg v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); 5802c393a42Smrg return FcNameUnparseString (buf, temp, 0); 5812c393a42Smrg case FcTypeCharSet: 5822c393a42Smrg return FcNameUnparseCharSet (buf, v.u.c); 5832c393a42Smrg case FcTypeLangSet: 5842c393a42Smrg return FcNameUnparseLangSet (buf, v.u.l); 5852c393a42Smrg case FcTypeFTFace: 5862c393a42Smrg return FcTrue; 58718bd4a06Smrg case FcTypeRange: 5881887081fSmrg sprintf ((char *) temp, "[%g %g]", v.u.r->begin, v.u.r->end); 58918bd4a06Smrg return FcNameUnparseString (buf, temp, 0); 5902c393a42Smrg } 5912c393a42Smrg return FcFalse; 5922c393a42Smrg} 5932c393a42Smrg 594a6844aabSmrgFcBool 5952c393a42SmrgFcNameUnparseValueList (FcStrBuf *buf, 5962c393a42Smrg FcValueListPtr v, 5972c393a42Smrg FcChar8 *escape) 5982c393a42Smrg{ 5992c393a42Smrg while (v) 6002c393a42Smrg { 6012c393a42Smrg if (!FcNameUnparseValue (buf, &v->value, escape)) 6022c393a42Smrg return FcFalse; 6032c393a42Smrg if ((v = FcValueListNext(v)) != NULL) 6042c393a42Smrg if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0)) 6052c393a42Smrg return FcFalse; 6062c393a42Smrg } 6072c393a42Smrg return FcTrue; 6082c393a42Smrg} 6092c393a42Smrg 6102c393a42Smrg#define FC_ESCAPE_FIXED "\\-:," 6112c393a42Smrg#define FC_ESCAPE_VARIABLE "\\=_:," 6122c393a42Smrg 6132c393a42SmrgFcChar8 * 6142c393a42SmrgFcNameUnparse (FcPattern *pat) 6152c393a42Smrg{ 6162c393a42Smrg return FcNameUnparseEscaped (pat, FcTrue); 6172c393a42Smrg} 6182c393a42Smrg 6192c393a42SmrgFcChar8 * 6202c393a42SmrgFcNameUnparseEscaped (FcPattern *pat, FcBool escape) 6212c393a42Smrg{ 62218bd4a06Smrg FcStrBuf buf, buf2; 62318bd4a06Smrg FcChar8 buf_static[8192], buf2_static[256]; 6242c393a42Smrg int i; 6252c393a42Smrg FcPatternElt *e; 6262c393a42Smrg 6272c393a42Smrg FcStrBufInit (&buf, buf_static, sizeof (buf_static)); 62818bd4a06Smrg FcStrBufInit (&buf2, buf2_static, sizeof (buf2_static)); 6292c393a42Smrg e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT); 6302c393a42Smrg if (e) 6312c393a42Smrg { 6322c393a42Smrg if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) 6332c393a42Smrg goto bail0; 6342c393a42Smrg } 6352c393a42Smrg e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT); 6362c393a42Smrg if (e) 6372c393a42Smrg { 63818bd4a06Smrg FcChar8 *p; 63918bd4a06Smrg 64018bd4a06Smrg if (!FcNameUnparseString (&buf2, (FcChar8 *) "-", 0)) 6412c393a42Smrg goto bail0; 64218bd4a06Smrg if (!FcNameUnparseValueList (&buf2, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) 6432c393a42Smrg goto bail0; 64418bd4a06Smrg p = FcStrBufDoneStatic (&buf2); 64518bd4a06Smrg FcStrBufDestroy (&buf2); 64618bd4a06Smrg if (strlen ((const char *)p) > 1) 64718bd4a06Smrg if (!FcStrBufString (&buf, p)) 64818bd4a06Smrg goto bail0; 6492c393a42Smrg } 6505e61939bSmrg for (i = 0; i < NUM_OBJECT_TYPES; i++) 6512c393a42Smrg { 6525e61939bSmrg FcObject id = i + 1; 6535e61939bSmrg const FcObjectType *o; 6545e61939bSmrg o = &FcObjects[i]; 6555e61939bSmrg if (!strcmp (o->object, FC_FAMILY) || 6565e61939bSmrg !strcmp (o->object, FC_SIZE)) 6575e61939bSmrg continue; 6585e61939bSmrg 6595e61939bSmrg e = FcPatternObjectFindElt (pat, id); 6605e61939bSmrg if (e) 6612c393a42Smrg { 6625e61939bSmrg if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0)) 6635e61939bSmrg goto bail0; 6645e61939bSmrg if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) 6655e61939bSmrg goto bail0; 6665e61939bSmrg if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0)) 6675e61939bSmrg goto bail0; 6685e61939bSmrg if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? 6695e61939bSmrg (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) 6705e61939bSmrg goto bail0; 6712c393a42Smrg } 6722c393a42Smrg } 6732c393a42Smrg return FcStrBufDone (&buf); 6742c393a42Smrgbail0: 6752c393a42Smrg FcStrBufDestroy (&buf); 6762c393a42Smrg return 0; 6772c393a42Smrg} 6782c393a42Smrg#define __fcname__ 6792c393a42Smrg#include "fcaliastail.h" 6802c393a42Smrg#undef __fcname__ 681