diff options
Diffstat (limited to 'fontconfig/src/fcname.c')
-rw-r--r-- | fontconfig/src/fcname.c | 1806 |
1 files changed, 903 insertions, 903 deletions
diff --git a/fontconfig/src/fcname.c b/fontconfig/src/fcname.c index 86c10b65e..1d2536c9c 100644 --- a/fontconfig/src/fcname.c +++ b/fontconfig/src/fcname.c @@ -1,903 +1,903 @@ -/* - * fontconfig/src/fcname.c - * - * Copyright © 2000 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of the author(s) not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. The authors make no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#include "fcint.h" -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -/* - * Please do not change this list, it is used to initialize the object - * list in this order to match the FC_foo_OBJECT constants. Those - * constants are written into cache files. - */ - -static const FcObjectType _FcBaseObjectTypes[] = { - { FC_FAMILY, FcTypeString, }, /* 1 */ - { FC_FAMILYLANG, FcTypeString, }, - { FC_STYLE, FcTypeString, }, - { FC_STYLELANG, FcTypeString, }, - { FC_FULLNAME, FcTypeString, }, - { FC_FULLNAMELANG, FcTypeString, }, - { FC_SLANT, FcTypeInteger, }, - { FC_WEIGHT, FcTypeInteger, }, - { FC_WIDTH, FcTypeInteger, }, - { FC_SIZE, FcTypeDouble, }, - { FC_ASPECT, FcTypeDouble, }, - { FC_PIXEL_SIZE, FcTypeDouble, }, - { FC_SPACING, FcTypeInteger, }, - { FC_FOUNDRY, FcTypeString, }, - { FC_ANTIALIAS, FcTypeBool, }, - { FC_HINT_STYLE, FcTypeInteger, }, - { FC_HINTING, FcTypeBool, }, - { FC_VERTICAL_LAYOUT, FcTypeBool, }, - { FC_AUTOHINT, FcTypeBool, }, - { FC_GLOBAL_ADVANCE, FcTypeBool, }, - { FC_FILE, FcTypeString, }, - { FC_INDEX, FcTypeInteger, }, - { FC_RASTERIZER, FcTypeString, }, - { FC_OUTLINE, FcTypeBool, }, - { FC_SCALABLE, FcTypeBool, }, - { FC_DPI, FcTypeDouble }, - { FC_RGBA, FcTypeInteger, }, - { FC_SCALE, FcTypeDouble, }, - { FC_MINSPACE, FcTypeBool, }, - { FC_CHAR_WIDTH, FcTypeInteger }, - { FC_CHAR_HEIGHT, FcTypeInteger }, - { FC_MATRIX, FcTypeMatrix }, - { FC_CHARSET, FcTypeCharSet }, - { FC_LANG, FcTypeLangSet }, - { FC_FONTVERSION, FcTypeInteger }, - { FC_CAPABILITY, FcTypeString }, - { FC_FONTFORMAT, FcTypeString }, - { FC_EMBOLDEN, FcTypeBool }, - { FC_EMBEDDED_BITMAP, FcTypeBool }, - { FC_DECORATIVE, FcTypeBool }, - { FC_LCD_FILTER, FcTypeInteger }, /* 41 */ -}; - -#define NUM_OBJECT_TYPES (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0]) - -typedef struct _FcObjectTypeList FcObjectTypeList; - -struct _FcObjectTypeList { - const FcObjectTypeList *next; - const FcObjectType *types; - int ntypes; -}; - -static const FcObjectTypeList _FcBaseObjectTypesList = { - 0, - _FcBaseObjectTypes, - NUM_OBJECT_TYPES, -}; - -static const FcObjectTypeList *_FcObjectTypes = &_FcBaseObjectTypesList; - -#define OBJECT_HASH_SIZE 31 - -typedef struct _FcObjectBucket { - struct _FcObjectBucket *next; - FcChar32 hash; - FcObject id; -} FcObjectBucket; - -static FcObjectBucket *FcObjectBuckets[OBJECT_HASH_SIZE]; - -static FcObjectType *FcObjects = (FcObjectType *) _FcBaseObjectTypes; -static int FcObjectsNumber = NUM_OBJECT_TYPES; -static int FcObjectsSize = 0; -static FcBool FcObjectsInited; - -static FcObjectType * -FcObjectInsert (const char *name, FcType type) -{ - FcObjectType *o; - if (FcObjectsNumber >= FcObjectsSize) - { - int newsize = FcObjectsNumber * 2; - FcObjectType *newobjects; - - if (FcObjectsSize) - newobjects = realloc (FcObjects, newsize * sizeof (FcObjectType)); - else - { - newobjects = malloc (newsize * sizeof (FcObjectType)); - if (newobjects) - memcpy (newobjects, FcObjects, - FcObjectsNumber * sizeof (FcObjectType)); - } - if (!newobjects) - return NULL; - FcObjects = newobjects; - FcObjectsSize = newsize; - } - o = &FcObjects[FcObjectsNumber]; - o->object = name; - o->type = type; - ++FcObjectsNumber; - return o; -} - -static FcObject -FcObjectId (FcObjectType *o) -{ - return o - FcObjects + 1; -} - -static FcObjectType * -FcObjectFindByName (const char *object, FcBool insert) -{ - FcChar32 hash = FcStringHash ((const FcChar8 *) object); - FcObjectBucket **p; - FcObjectBucket *b; - FcObjectType *o; - - if (!FcObjectsInited) - FcObjectInit (); - for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) - { - o = FcObjects + b->id - 1; - if (b->hash == hash && !strcmp (object, (o->object))) - return o; - } - if (!insert) - return NULL; - /* - * Hook it into the hash chain - */ - b = malloc (sizeof(FcObjectBucket)); - if (!b) - return NULL; - object = (const char *) FcStrCopy ((FcChar8 *) object); - if (!object) { - free (b); - return NULL; - } - o = FcObjectInsert (object, -1); - b->next = NULL; - b->hash = hash; - b->id = FcObjectId (o); - *p = b; - return o; -} - -static FcObjectType * -FcObjectFindById (FcObject object) -{ - if (1 <= object && object <= FcObjectsNumber) - return FcObjects + object - 1; - return NULL; -} - -static FcBool -FcObjectHashInsert (const FcObjectType *object, FcBool copy) -{ - FcChar32 hash = FcStringHash ((const FcChar8 *) object->object); - FcObjectBucket **p; - FcObjectBucket *b; - FcObjectType *o; - - if (!FcObjectsInited) - FcObjectInit (); - for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) - { - o = FcObjects + b->id - 1; - if (b->hash == hash && !strcmp (object->object, o->object)) - return FcFalse; - } - /* - * Hook it into the hash chain - */ - b = malloc (sizeof(FcObjectBucket)); - if (!b) - return FcFalse; - if (copy) - { - o = FcObjectInsert (object->object, object->type); - if (!o) - { - free (b); - return FcFalse; - } - } - else - o = (FcObjectType *) object; - b->next = NULL; - b->hash = hash; - b->id = FcObjectId (o); - *p = b; - return FcTrue; -} - -static void -FcObjectHashRemove (const FcObjectType *object, FcBool cleanobj) -{ - FcChar32 hash = FcStringHash ((const FcChar8 *) object->object); - FcObjectBucket **p; - FcObjectBucket *b; - FcObjectType *o; - - if (!FcObjectsInited) - FcObjectInit (); - for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) - { - o = FcObjects + b->id - 1; - if (b->hash == hash && !strcmp (object->object, o->object)) - { - *p = b->next; - free (b); - if (cleanobj) - { - /* Clean up object array */ - o->object = NULL; - o->type = -1; - while (FcObjects[FcObjectsNumber-1].object == NULL) - --FcObjectsNumber; - } - break; - } - } -} - -FcBool -FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes) -{ - int i; - - for (i = 0; i < ntypes; i++) - if (!FcObjectHashInsert (&types[i], FcTrue)) - return FcFalse; - return FcTrue; -} - -FcBool -FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes) -{ - int i; - - for (i = 0; i < ntypes; i++) - FcObjectHashRemove (&types[i], FcTrue); - return FcTrue; -} - -const FcObjectType * -FcNameGetObjectType (const char *object) -{ - return FcObjectFindByName (object, FcFalse); -} - -FcBool -FcObjectValidType (FcObject object, FcType type) -{ - FcObjectType *t = FcObjectFindById (object); - - if (t) { - switch (t->type) { - case -1: - return FcTrue; - case FcTypeDouble: - case FcTypeInteger: - if (type == FcTypeDouble || type == FcTypeInteger) - return FcTrue; - break; - case FcTypeLangSet: - if (type == FcTypeLangSet || type == FcTypeString) - return FcTrue; - break; - default: - if (type == t->type) - return FcTrue; - break; - } - return FcFalse; - } - return FcTrue; -} - -FcObject -FcObjectFromName (const char * name) -{ - FcObjectType *o = FcObjectFindByName (name, FcTrue); - - if (o) - return FcObjectId (o); - return 0; -} - -FcObjectSet * -FcObjectGetSet (void) -{ - int i; - FcObjectSet *os = NULL; - - - os = FcObjectSetCreate (); - for (i = 0; i < FcObjectsNumber; i++) - FcObjectSetAdd (os, FcObjects[i].object); - - return os; -} - -FcBool -FcObjectInit (void) -{ - int i; - - if (FcObjectsInited) - return FcTrue; - - FcObjectsInited = FcTrue; - for (i = 0; i < NUM_OBJECT_TYPES; i++) - if (!FcObjectHashInsert (&_FcBaseObjectTypes[i], FcFalse)) - return FcFalse; - return FcTrue; -} - -void -FcObjectFini (void) -{ - int i; - FcObjectBucket *b, *next; - - for (i = 0; i < OBJECT_HASH_SIZE; i++) - { - for (b = FcObjectBuckets[i]; b; b = next) - { - next = b->next; - free (b); - } - FcObjectBuckets[i] = 0; - } - for (i = 0; i < FcObjectsNumber; i++) - if (FcObjects[i].type == -1) - free ((void*) FcObjects[i].object); - if (FcObjects != _FcBaseObjectTypes) - free (FcObjects); - FcObjects = (FcObjectType *) _FcBaseObjectTypes; - FcObjectsNumber = NUM_OBJECT_TYPES; - FcObjectsSize = 0; - FcObjectsInited = FcFalse; -} - -const char * -FcObjectName (FcObject object) -{ - FcObjectType *o = FcObjectFindById (object); - - if (o) - return o->object; - return NULL; -} - -static const FcConstant _FcBaseConstants[] = { - { (FcChar8 *) "thin", "weight", FC_WEIGHT_THIN, }, - { (FcChar8 *) "extralight", "weight", FC_WEIGHT_EXTRALIGHT, }, - { (FcChar8 *) "ultralight", "weight", FC_WEIGHT_EXTRALIGHT, }, - { (FcChar8 *) "light", "weight", FC_WEIGHT_LIGHT, }, - { (FcChar8 *) "book", "weight", FC_WEIGHT_BOOK, }, - { (FcChar8 *) "regular", "weight", FC_WEIGHT_REGULAR, }, - { (FcChar8 *) "medium", "weight", FC_WEIGHT_MEDIUM, }, - { (FcChar8 *) "demibold", "weight", FC_WEIGHT_DEMIBOLD, }, - { (FcChar8 *) "semibold", "weight", FC_WEIGHT_DEMIBOLD, }, - { (FcChar8 *) "bold", "weight", FC_WEIGHT_BOLD, }, - { (FcChar8 *) "extrabold", "weight", FC_WEIGHT_EXTRABOLD, }, - { (FcChar8 *) "ultrabold", "weight", FC_WEIGHT_EXTRABOLD, }, - { (FcChar8 *) "black", "weight", FC_WEIGHT_BLACK, }, - { (FcChar8 *) "heavy", "weight", FC_WEIGHT_HEAVY, }, - - { (FcChar8 *) "roman", "slant", FC_SLANT_ROMAN, }, - { (FcChar8 *) "italic", "slant", FC_SLANT_ITALIC, }, - { (FcChar8 *) "oblique", "slant", FC_SLANT_OBLIQUE, }, - - { (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED }, - { (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED }, - { (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED }, - { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED }, - { (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL }, - { (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED }, - { (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED }, - { (FcChar8 *) "extraexpanded", "width", FC_WIDTH_EXTRAEXPANDED }, - { (FcChar8 *) "ultraexpanded", "width", FC_WIDTH_ULTRAEXPANDED }, - - { (FcChar8 *) "proportional", "spacing", FC_PROPORTIONAL, }, - { (FcChar8 *) "dual", "spacing", FC_DUAL, }, - { (FcChar8 *) "mono", "spacing", FC_MONO, }, - { (FcChar8 *) "charcell", "spacing", FC_CHARCELL, }, - - { (FcChar8 *) "unknown", "rgba", FC_RGBA_UNKNOWN }, - { (FcChar8 *) "rgb", "rgba", FC_RGBA_RGB, }, - { (FcChar8 *) "bgr", "rgba", FC_RGBA_BGR, }, - { (FcChar8 *) "vrgb", "rgba", FC_RGBA_VRGB }, - { (FcChar8 *) "vbgr", "rgba", FC_RGBA_VBGR }, - { (FcChar8 *) "none", "rgba", FC_RGBA_NONE }, - - { (FcChar8 *) "hintnone", "hintstyle", FC_HINT_NONE }, - { (FcChar8 *) "hintslight", "hintstyle", FC_HINT_SLIGHT }, - { (FcChar8 *) "hintmedium", "hintstyle", FC_HINT_MEDIUM }, - { (FcChar8 *) "hintfull", "hintstyle", FC_HINT_FULL }, - - { (FcChar8 *) "antialias", "antialias", FcTrue }, - { (FcChar8 *) "hinting", "hinting", FcTrue }, - { (FcChar8 *) "verticallayout", "verticallayout", FcTrue }, - { (FcChar8 *) "autohint", "autohint", FcTrue }, - { (FcChar8 *) "globaladvance", "globaladvance", FcTrue }, - { (FcChar8 *) "outline", "outline", FcTrue }, - { (FcChar8 *) "scalable", "scalable", FcTrue }, - { (FcChar8 *) "minspace", "minspace", FcTrue }, - { (FcChar8 *) "embolden", "embolden", FcTrue }, - { (FcChar8 *) "embeddedbitmap", "embeddedbitmap", FcTrue }, - { (FcChar8 *) "decorative", "decorative", FcTrue }, - { (FcChar8 *) "lcdnone", "lcdfilter", FC_LCD_NONE }, - { (FcChar8 *) "lcddefault", "lcdfilter", FC_LCD_DEFAULT }, - { (FcChar8 *) "lcdlight", "lcdfilter", FC_LCD_LIGHT }, - { (FcChar8 *) "lcdlegacy", "lcdfilter", FC_LCD_LEGACY }, -}; - -#define NUM_FC_CONSTANTS (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0]) - -typedef struct _FcConstantList FcConstantList; - -struct _FcConstantList { - const FcConstantList *next; - const FcConstant *consts; - int nconsts; -}; - -static const FcConstantList _FcBaseConstantList = { - 0, - _FcBaseConstants, - NUM_FC_CONSTANTS -}; - -static const FcConstantList *_FcConstants = &_FcBaseConstantList; - -FcBool -FcNameRegisterConstants (const FcConstant *consts, int nconsts) -{ - FcConstantList *l; - - l = (FcConstantList *) malloc (sizeof (FcConstantList)); - if (!l) - return FcFalse; - FcMemAlloc (FC_MEM_CONSTANT, sizeof (FcConstantList)); - l->consts = consts; - l->nconsts = nconsts; - l->next = _FcConstants; - _FcConstants = l; - return FcTrue; -} - -FcBool -FcNameUnregisterConstants (const FcConstant *consts, int nconsts) -{ - const FcConstantList *l, **prev; - - for (prev = &_FcConstants; - (l = *prev); - prev = (const FcConstantList **) &(l->next)) - { - if (l->consts == consts && l->nconsts == nconsts) - { - *prev = l->next; - FcMemFree (FC_MEM_CONSTANT, sizeof (FcConstantList)); - free ((void *) l); - return FcTrue; - } - } - return FcFalse; -} - -const FcConstant * -FcNameGetConstant (FcChar8 *string) -{ - const FcConstantList *l; - int i; - - for (l = _FcConstants; l; l = l->next) - { - for (i = 0; i < l->nconsts; i++) - if (!FcStrCmpIgnoreCase (string, l->consts[i].name)) - return &l->consts[i]; - } - return 0; -} - -FcBool -FcNameConstant (FcChar8 *string, int *result) -{ - const FcConstant *c; - - if ((c = FcNameGetConstant(string))) - { - *result = c->value; - return FcTrue; - } - return FcFalse; -} - -FcBool -FcNameBool (const FcChar8 *v, FcBool *result) -{ - char c0, c1; - - c0 = *v; - c0 = FcToLower (c0); - if (c0 == 't' || c0 == 'y' || c0 == '1') - { - *result = FcTrue; - return FcTrue; - } - if (c0 == 'f' || c0 == 'n' || c0 == '0') - { - *result = FcFalse; - return FcTrue; - } - if (c0 == 'o') - { - c1 = v[1]; - c1 = FcToLower (c1); - if (c1 == 'n') - { - *result = FcTrue; - return FcTrue; - } - if (c1 == 'f') - { - *result = FcFalse; - return FcTrue; - } - } - return FcFalse; -} - -static FcValue -FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m) -{ - FcValue v; - - v.type = type; - switch (v.type) { - case FcTypeInteger: - if (!FcNameConstant (string, &v.u.i)) - v.u.i = atoi ((char *) string); - break; - case FcTypeString: - v.u.s = FcStrStaticName(string); - if (!v.u.s) - v.type = FcTypeVoid; - break; - case FcTypeBool: - if (!FcNameBool (string, &v.u.b)) - v.u.b = FcFalse; - break; - case FcTypeDouble: - v.u.d = strtod ((char *) string, 0); - break; - case FcTypeMatrix: - v.u.m = m; - sscanf ((char *) string, "%lg %lg %lg %lg", &m->xx, &m->xy, &m->yx, &m->yy); - break; - case FcTypeCharSet: - v.u.c = FcNameParseCharSet (string); - if (!v.u.c) - v.type = FcTypeVoid; - break; - case FcTypeLangSet: - v.u.l = FcNameParseLangSet (string); - if (!v.u.l) - v.type = FcTypeVoid; - break; - default: - break; - } - return v; -} - -static const FcChar8 * -FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last) -{ - FcChar8 c; - - while ((c = *cur)) - { - if (c == '\\') - { - ++cur; - if (!(c = *cur)) - break; - } - else if (strchr (delim, c)) - break; - ++cur; - *save++ = c; - } - *save = 0; - *last = *cur; - if (*cur) - cur++; - return cur; -} - -FcPattern * -FcNameParse (const FcChar8 *name) -{ - FcChar8 *save; - FcPattern *pat; - double d; - FcChar8 *e; - FcChar8 delim; - FcValue v; - FcMatrix m; - const FcObjectType *t; - const FcConstant *c; - - /* freed below */ - save = malloc (strlen ((char *) name) + 1); - if (!save) - goto bail0; - pat = FcPatternCreate (); - if (!pat) - goto bail1; - - for (;;) - { - name = FcNameFindNext (name, "-,:", save, &delim); - if (save[0]) - { - if (!FcPatternAddString (pat, FC_FAMILY, save)) - goto bail2; - } - if (delim != ',') - break; - } - if (delim == '-') - { - for (;;) - { - name = FcNameFindNext (name, "-,:", save, &delim); - d = strtod ((char *) save, (char **) &e); - if (e != save) - { - if (!FcPatternAddDouble (pat, FC_SIZE, d)) - goto bail2; - } - if (delim != ',') - break; - } - } - while (delim == ':') - { - name = FcNameFindNext (name, "=_:", save, &delim); - if (save[0]) - { - if (delim == '=' || delim == '_') - { - t = FcNameGetObjectType ((char *) save); - for (;;) - { - name = FcNameFindNext (name, ":,", save, &delim); - if (t) - { - v = FcNameConvert (t->type, save, &m); - if (!FcPatternAdd (pat, t->object, v, FcTrue)) - { - switch (v.type) { - case FcTypeCharSet: - FcCharSetDestroy ((FcCharSet *) v.u.c); - break; - case FcTypeLangSet: - FcLangSetDestroy ((FcLangSet *) v.u.l); - break; - default: - break; - } - goto bail2; - } - switch (v.type) { - case FcTypeCharSet: - FcCharSetDestroy ((FcCharSet *) v.u.c); - break; - case FcTypeLangSet: - FcLangSetDestroy ((FcLangSet *) v.u.l); - break; - default: - break; - } - } - if (delim != ',') - break; - } - } - else - { - if ((c = FcNameGetConstant (save))) - { - t = FcNameGetObjectType ((char *) c->object); - switch (t->type) { - case FcTypeInteger: - case FcTypeDouble: - if (!FcPatternAddInteger (pat, c->object, c->value)) - goto bail2; - break; - case FcTypeBool: - if (!FcPatternAddBool (pat, c->object, c->value)) - goto bail2; - break; - default: - break; - } - } - } - } - } - - free (save); - return pat; - -bail2: - FcPatternDestroy (pat); -bail1: - free (save); -bail0: - return 0; -} -static FcBool -FcNameUnparseString (FcStrBuf *buf, - const FcChar8 *string, - const FcChar8 *escape) -{ - FcChar8 c; - while ((c = *string++)) - { - if (escape && strchr ((char *) escape, (char) c)) - { - if (!FcStrBufChar (buf, escape[0])) - return FcFalse; - } - if (!FcStrBufChar (buf, c)) - return FcFalse; - } - return FcTrue; -} - -FcBool -FcNameUnparseValue (FcStrBuf *buf, - FcValue *v0, - FcChar8 *escape) -{ - FcChar8 temp[1024]; - FcValue v = FcValueCanonicalize(v0); - - switch (v.type) { - case FcTypeVoid: - return FcTrue; - case FcTypeInteger: - sprintf ((char *) temp, "%d", v.u.i); - return FcNameUnparseString (buf, temp, 0); - case FcTypeDouble: - sprintf ((char *) temp, "%g", v.u.d); - return FcNameUnparseString (buf, temp, 0); - case FcTypeString: - return FcNameUnparseString (buf, v.u.s, escape); - case FcTypeBool: - return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0); - case FcTypeMatrix: - sprintf ((char *) temp, "%g %g %g %g", - v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); - return FcNameUnparseString (buf, temp, 0); - case FcTypeCharSet: - return FcNameUnparseCharSet (buf, v.u.c); - case FcTypeLangSet: - return FcNameUnparseLangSet (buf, v.u.l); - case FcTypeFTFace: - return FcTrue; - } - return FcFalse; -} - -FcBool -FcNameUnparseValueList (FcStrBuf *buf, - FcValueListPtr v, - FcChar8 *escape) -{ - while (v) - { - if (!FcNameUnparseValue (buf, &v->value, escape)) - return FcFalse; - if ((v = FcValueListNext(v)) != NULL) - if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0)) - return FcFalse; - } - return FcTrue; -} - -#define FC_ESCAPE_FIXED "\\-:," -#define FC_ESCAPE_VARIABLE "\\=_:," - -FcChar8 * -FcNameUnparse (FcPattern *pat) -{ - return FcNameUnparseEscaped (pat, FcTrue); -} - -FcChar8 * -FcNameUnparseEscaped (FcPattern *pat, FcBool escape) -{ - FcStrBuf buf; - FcChar8 buf_static[8192]; - int i; - FcPatternElt *e; - const FcObjectTypeList *l; - const FcObjectType *o; - - FcStrBufInit (&buf, buf_static, sizeof (buf_static)); - e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT); - if (e) - { - if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) - goto bail0; - } - e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT); - if (e) - { - if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0)) - goto bail0; - if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) - goto bail0; - } - for (l = _FcObjectTypes; l; l = l->next) - { - for (i = 0; i < l->ntypes; i++) - { - o = &l->types[i]; - if (!strcmp (o->object, FC_FAMILY) || - !strcmp (o->object, FC_SIZE) || - !strcmp (o->object, FC_FILE)) - continue; - - e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object)); - if (e) - { - if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0)) - goto bail0; - if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) - goto bail0; - if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0)) - goto bail0; - if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? - (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) - goto bail0; - } - } - } - return FcStrBufDone (&buf); -bail0: - FcStrBufDestroy (&buf); - return 0; -} -#define __fcname__ -#include "fcaliastail.h" -#undef __fcname__ +/*
+ * fontconfig/src/fcname.c
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fcint.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+/*
+ * Please do not change this list, it is used to initialize the object
+ * list in this order to match the FC_foo_OBJECT constants. Those
+ * constants are written into cache files.
+ */
+
+static const FcObjectType _FcBaseObjectTypes[] = {
+ { FC_FAMILY, FcTypeString, }, /* 1 */
+ { FC_FAMILYLANG, FcTypeString, },
+ { FC_STYLE, FcTypeString, },
+ { FC_STYLELANG, FcTypeString, },
+ { FC_FULLNAME, FcTypeString, },
+ { FC_FULLNAMELANG, FcTypeString, },
+ { FC_SLANT, FcTypeInteger, },
+ { FC_WEIGHT, FcTypeInteger, },
+ { FC_WIDTH, FcTypeInteger, },
+ { FC_SIZE, FcTypeDouble, },
+ { FC_ASPECT, FcTypeDouble, },
+ { FC_PIXEL_SIZE, FcTypeDouble, },
+ { FC_SPACING, FcTypeInteger, },
+ { FC_FOUNDRY, FcTypeString, },
+ { FC_ANTIALIAS, FcTypeBool, },
+ { FC_HINT_STYLE, FcTypeInteger, },
+ { FC_HINTING, FcTypeBool, },
+ { FC_VERTICAL_LAYOUT, FcTypeBool, },
+ { FC_AUTOHINT, FcTypeBool, },
+ { FC_GLOBAL_ADVANCE, FcTypeBool, },
+ { FC_FILE, FcTypeString, },
+ { FC_INDEX, FcTypeInteger, },
+ { FC_RASTERIZER, FcTypeString, },
+ { FC_OUTLINE, FcTypeBool, },
+ { FC_SCALABLE, FcTypeBool, },
+ { FC_DPI, FcTypeDouble },
+ { FC_RGBA, FcTypeInteger, },
+ { FC_SCALE, FcTypeDouble, },
+ { FC_MINSPACE, FcTypeBool, },
+ { FC_CHAR_WIDTH, FcTypeInteger },
+ { FC_CHAR_HEIGHT, FcTypeInteger },
+ { FC_MATRIX, FcTypeMatrix },
+ { FC_CHARSET, FcTypeCharSet },
+ { FC_LANG, FcTypeLangSet },
+ { FC_FONTVERSION, FcTypeInteger },
+ { FC_CAPABILITY, FcTypeString },
+ { FC_FONTFORMAT, FcTypeString },
+ { FC_EMBOLDEN, FcTypeBool },
+ { FC_EMBEDDED_BITMAP, FcTypeBool },
+ { FC_DECORATIVE, FcTypeBool },
+ { FC_LCD_FILTER, FcTypeInteger }, /* 41 */
+};
+
+#define NUM_OBJECT_TYPES (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0])
+
+typedef struct _FcObjectTypeList FcObjectTypeList;
+
+struct _FcObjectTypeList {
+ const FcObjectTypeList *next;
+ const FcObjectType *types;
+ int ntypes;
+};
+
+static const FcObjectTypeList _FcBaseObjectTypesList = {
+ 0,
+ _FcBaseObjectTypes,
+ NUM_OBJECT_TYPES,
+};
+
+static const FcObjectTypeList *_FcObjectTypes = &_FcBaseObjectTypesList;
+
+#define OBJECT_HASH_SIZE 31
+
+typedef struct _FcObjectBucket {
+ struct _FcObjectBucket *next;
+ FcChar32 hash;
+ FcObject id;
+} FcObjectBucket;
+
+static FcObjectBucket *FcObjectBuckets[OBJECT_HASH_SIZE];
+
+static FcObjectType *FcObjects = (FcObjectType *) _FcBaseObjectTypes;
+static int FcObjectsNumber = NUM_OBJECT_TYPES;
+static int FcObjectsSize = 0;
+static FcBool FcObjectsInited;
+
+static FcObjectType *
+FcObjectInsert (const char *name, FcType type)
+{
+ FcObjectType *o;
+ if (FcObjectsNumber >= FcObjectsSize)
+ {
+ int newsize = FcObjectsNumber * 2;
+ FcObjectType *newobjects;
+
+ if (FcObjectsSize)
+ newobjects = realloc (FcObjects, newsize * sizeof (FcObjectType));
+ else
+ {
+ newobjects = malloc (newsize * sizeof (FcObjectType));
+ if (newobjects)
+ memcpy (newobjects, FcObjects,
+ FcObjectsNumber * sizeof (FcObjectType));
+ }
+ if (!newobjects)
+ return NULL;
+ FcObjects = newobjects;
+ FcObjectsSize = newsize;
+ }
+ o = &FcObjects[FcObjectsNumber];
+ o->object = name;
+ o->type = type;
+ ++FcObjectsNumber;
+ return o;
+}
+
+static FcObject
+FcObjectId (FcObjectType *o)
+{
+ return o - FcObjects + 1;
+}
+
+static FcObjectType *
+FcObjectFindByName (const char *object, FcBool insert)
+{
+ FcChar32 hash = FcStringHash ((const FcChar8 *) object);
+ FcObjectBucket **p;
+ FcObjectBucket *b;
+ FcObjectType *o;
+
+ if (!FcObjectsInited)
+ FcObjectInit ();
+ for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
+ {
+ o = FcObjects + b->id - 1;
+ if (b->hash == hash && !strcmp (object, (o->object)))
+ return o;
+ }
+ if (!insert)
+ return NULL;
+ /*
+ * Hook it into the hash chain
+ */
+ b = malloc (sizeof(FcObjectBucket));
+ if (!b)
+ return NULL;
+ object = (const char *) FcStrCopy ((FcChar8 *) object);
+ if (!object) {
+ free (b);
+ return NULL;
+ }
+ o = FcObjectInsert (object, -1);
+ b->next = NULL;
+ b->hash = hash;
+ b->id = FcObjectId (o);
+ *p = b;
+ return o;
+}
+
+static FcObjectType *
+FcObjectFindById (FcObject object)
+{
+ if (1 <= object && object <= FcObjectsNumber)
+ return FcObjects + object - 1;
+ return NULL;
+}
+
+static FcBool
+FcObjectHashInsert (const FcObjectType *object, FcBool copy)
+{
+ FcChar32 hash = FcStringHash ((const FcChar8 *) object->object);
+ FcObjectBucket **p;
+ FcObjectBucket *b;
+ FcObjectType *o;
+
+ if (!FcObjectsInited)
+ FcObjectInit ();
+ for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
+ {
+ o = FcObjects + b->id - 1;
+ if (b->hash == hash && !strcmp (object->object, o->object))
+ return FcFalse;
+ }
+ /*
+ * Hook it into the hash chain
+ */
+ b = malloc (sizeof(FcObjectBucket));
+ if (!b)
+ return FcFalse;
+ if (copy)
+ {
+ o = FcObjectInsert (object->object, object->type);
+ if (!o)
+ {
+ free (b);
+ return FcFalse;
+ }
+ }
+ else
+ o = (FcObjectType *) object;
+ b->next = NULL;
+ b->hash = hash;
+ b->id = FcObjectId (o);
+ *p = b;
+ return FcTrue;
+}
+
+static void
+FcObjectHashRemove (const FcObjectType *object, FcBool cleanobj)
+{
+ FcChar32 hash = FcStringHash ((const FcChar8 *) object->object);
+ FcObjectBucket **p;
+ FcObjectBucket *b;
+ FcObjectType *o;
+
+ if (!FcObjectsInited)
+ FcObjectInit ();
+ for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
+ {
+ o = FcObjects + b->id - 1;
+ if (b->hash == hash && !strcmp (object->object, o->object))
+ {
+ *p = b->next;
+ free (b);
+ if (cleanobj)
+ {
+ /* Clean up object array */
+ o->object = NULL;
+ o->type = -1;
+ while (FcObjects[FcObjectsNumber-1].object == NULL)
+ --FcObjectsNumber;
+ }
+ break;
+ }
+ }
+}
+
+FcBool
+FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes)
+{
+ int i;
+
+ for (i = 0; i < ntypes; i++)
+ if (!FcObjectHashInsert (&types[i], FcTrue))
+ return FcFalse;
+ return FcTrue;
+}
+
+FcBool
+FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
+{
+ int i;
+
+ for (i = 0; i < ntypes; i++)
+ FcObjectHashRemove (&types[i], FcTrue);
+ return FcTrue;
+}
+
+const FcObjectType *
+FcNameGetObjectType (const char *object)
+{
+ return FcObjectFindByName (object, FcFalse);
+}
+
+FcBool
+FcObjectValidType (FcObject object, FcType type)
+{
+ FcObjectType *t = FcObjectFindById (object);
+
+ if (t) {
+ switch (t->type) {
+ case -1:
+ return FcTrue;
+ case FcTypeDouble:
+ case FcTypeInteger:
+ if (type == FcTypeDouble || type == FcTypeInteger)
+ return FcTrue;
+ break;
+ case FcTypeLangSet:
+ if (type == FcTypeLangSet || type == FcTypeString)
+ return FcTrue;
+ break;
+ default:
+ if (type == t->type)
+ return FcTrue;
+ break;
+ }
+ return FcFalse;
+ }
+ return FcTrue;
+}
+
+FcObject
+FcObjectFromName (const char * name)
+{
+ FcObjectType *o = FcObjectFindByName (name, FcTrue);
+
+ if (o)
+ return FcObjectId (o);
+ return 0;
+}
+
+FcObjectSet *
+FcObjectGetSet (void)
+{
+ int i;
+ FcObjectSet *os = NULL;
+
+
+ os = FcObjectSetCreate ();
+ for (i = 0; i < FcObjectsNumber; i++)
+ FcObjectSetAdd (os, FcObjects[i].object);
+
+ return os;
+}
+
+FcBool
+FcObjectInit (void)
+{
+ int i;
+
+ if (FcObjectsInited)
+ return FcTrue;
+
+ FcObjectsInited = FcTrue;
+ for (i = 0; i < NUM_OBJECT_TYPES; i++)
+ if (!FcObjectHashInsert (&_FcBaseObjectTypes[i], FcFalse))
+ return FcFalse;
+ return FcTrue;
+}
+
+void
+FcObjectFini (void)
+{
+ int i;
+ FcObjectBucket *b, *next;
+
+ for (i = 0; i < OBJECT_HASH_SIZE; i++)
+ {
+ for (b = FcObjectBuckets[i]; b; b = next)
+ {
+ next = b->next;
+ free (b);
+ }
+ FcObjectBuckets[i] = 0;
+ }
+ for (i = 0; i < FcObjectsNumber; i++)
+ if (FcObjects[i].type == -1)
+ free ((void*) FcObjects[i].object);
+ if (FcObjects != _FcBaseObjectTypes)
+ free (FcObjects);
+ FcObjects = (FcObjectType *) _FcBaseObjectTypes;
+ FcObjectsNumber = NUM_OBJECT_TYPES;
+ FcObjectsSize = 0;
+ FcObjectsInited = FcFalse;
+}
+
+const char *
+FcObjectName (FcObject object)
+{
+ FcObjectType *o = FcObjectFindById (object);
+
+ if (o)
+ return o->object;
+ return NULL;
+}
+
+static const FcConstant _FcBaseConstants[] = {
+ { (FcChar8 *) "thin", "weight", FC_WEIGHT_THIN, },
+ { (FcChar8 *) "extralight", "weight", FC_WEIGHT_EXTRALIGHT, },
+ { (FcChar8 *) "ultralight", "weight", FC_WEIGHT_EXTRALIGHT, },
+ { (FcChar8 *) "light", "weight", FC_WEIGHT_LIGHT, },
+ { (FcChar8 *) "book", "weight", FC_WEIGHT_BOOK, },
+ { (FcChar8 *) "regular", "weight", FC_WEIGHT_REGULAR, },
+ { (FcChar8 *) "medium", "weight", FC_WEIGHT_MEDIUM, },
+ { (FcChar8 *) "demibold", "weight", FC_WEIGHT_DEMIBOLD, },
+ { (FcChar8 *) "semibold", "weight", FC_WEIGHT_DEMIBOLD, },
+ { (FcChar8 *) "bold", "weight", FC_WEIGHT_BOLD, },
+ { (FcChar8 *) "extrabold", "weight", FC_WEIGHT_EXTRABOLD, },
+ { (FcChar8 *) "ultrabold", "weight", FC_WEIGHT_EXTRABOLD, },
+ { (FcChar8 *) "black", "weight", FC_WEIGHT_BLACK, },
+ { (FcChar8 *) "heavy", "weight", FC_WEIGHT_HEAVY, },
+
+ { (FcChar8 *) "roman", "slant", FC_SLANT_ROMAN, },
+ { (FcChar8 *) "italic", "slant", FC_SLANT_ITALIC, },
+ { (FcChar8 *) "oblique", "slant", FC_SLANT_OBLIQUE, },
+
+ { (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED },
+ { (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED },
+ { (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED },
+ { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED },
+ { (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL },
+ { (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED },
+ { (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED },
+ { (FcChar8 *) "extraexpanded", "width", FC_WIDTH_EXTRAEXPANDED },
+ { (FcChar8 *) "ultraexpanded", "width", FC_WIDTH_ULTRAEXPANDED },
+
+ { (FcChar8 *) "proportional", "spacing", FC_PROPORTIONAL, },
+ { (FcChar8 *) "dual", "spacing", FC_DUAL, },
+ { (FcChar8 *) "mono", "spacing", FC_MONO, },
+ { (FcChar8 *) "charcell", "spacing", FC_CHARCELL, },
+
+ { (FcChar8 *) "unknown", "rgba", FC_RGBA_UNKNOWN },
+ { (FcChar8 *) "rgb", "rgba", FC_RGBA_RGB, },
+ { (FcChar8 *) "bgr", "rgba", FC_RGBA_BGR, },
+ { (FcChar8 *) "vrgb", "rgba", FC_RGBA_VRGB },
+ { (FcChar8 *) "vbgr", "rgba", FC_RGBA_VBGR },
+ { (FcChar8 *) "none", "rgba", FC_RGBA_NONE },
+
+ { (FcChar8 *) "hintnone", "hintstyle", FC_HINT_NONE },
+ { (FcChar8 *) "hintslight", "hintstyle", FC_HINT_SLIGHT },
+ { (FcChar8 *) "hintmedium", "hintstyle", FC_HINT_MEDIUM },
+ { (FcChar8 *) "hintfull", "hintstyle", FC_HINT_FULL },
+
+ { (FcChar8 *) "antialias", "antialias", FcTrue },
+ { (FcChar8 *) "hinting", "hinting", FcTrue },
+ { (FcChar8 *) "verticallayout", "verticallayout", FcTrue },
+ { (FcChar8 *) "autohint", "autohint", FcTrue },
+ { (FcChar8 *) "globaladvance", "globaladvance", FcTrue },
+ { (FcChar8 *) "outline", "outline", FcTrue },
+ { (FcChar8 *) "scalable", "scalable", FcTrue },
+ { (FcChar8 *) "minspace", "minspace", FcTrue },
+ { (FcChar8 *) "embolden", "embolden", FcTrue },
+ { (FcChar8 *) "embeddedbitmap", "embeddedbitmap", FcTrue },
+ { (FcChar8 *) "decorative", "decorative", FcTrue },
+ { (FcChar8 *) "lcdnone", "lcdfilter", FC_LCD_NONE },
+ { (FcChar8 *) "lcddefault", "lcdfilter", FC_LCD_DEFAULT },
+ { (FcChar8 *) "lcdlight", "lcdfilter", FC_LCD_LIGHT },
+ { (FcChar8 *) "lcdlegacy", "lcdfilter", FC_LCD_LEGACY },
+};
+
+#define NUM_FC_CONSTANTS (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0])
+
+typedef struct _FcConstantList FcConstantList;
+
+struct _FcConstantList {
+ const FcConstantList *next;
+ const FcConstant *consts;
+ int nconsts;
+};
+
+static const FcConstantList _FcBaseConstantList = {
+ 0,
+ _FcBaseConstants,
+ NUM_FC_CONSTANTS
+};
+
+static const FcConstantList *_FcConstants = &_FcBaseConstantList;
+
+FcBool
+FcNameRegisterConstants (const FcConstant *consts, int nconsts)
+{
+ FcConstantList *l;
+
+ l = (FcConstantList *) malloc (sizeof (FcConstantList));
+ if (!l)
+ return FcFalse;
+ FcMemAlloc (FC_MEM_CONSTANT, sizeof (FcConstantList));
+ l->consts = consts;
+ l->nconsts = nconsts;
+ l->next = _FcConstants;
+ _FcConstants = l;
+ return FcTrue;
+}
+
+FcBool
+FcNameUnregisterConstants (const FcConstant *consts, int nconsts)
+{
+ const FcConstantList *l, **prev;
+
+ for (prev = &_FcConstants;
+ (l = *prev);
+ prev = (const FcConstantList **) &(l->next))
+ {
+ if (l->consts == consts && l->nconsts == nconsts)
+ {
+ *prev = l->next;
+ FcMemFree (FC_MEM_CONSTANT, sizeof (FcConstantList));
+ free ((void *) l);
+ return FcTrue;
+ }
+ }
+ return FcFalse;
+}
+
+const FcConstant *
+FcNameGetConstant (FcChar8 *string)
+{
+ const FcConstantList *l;
+ int i;
+
+ for (l = _FcConstants; l; l = l->next)
+ {
+ for (i = 0; i < l->nconsts; i++)
+ if (!FcStrCmpIgnoreCase (string, l->consts[i].name))
+ return &l->consts[i];
+ }
+ return 0;
+}
+
+FcBool
+FcNameConstant (FcChar8 *string, int *result)
+{
+ const FcConstant *c;
+
+ if ((c = FcNameGetConstant(string)))
+ {
+ *result = c->value;
+ return FcTrue;
+ }
+ return FcFalse;
+}
+
+FcBool
+FcNameBool (const FcChar8 *v, FcBool *result)
+{
+ char c0, c1;
+
+ c0 = *v;
+ c0 = FcToLower (c0);
+ if (c0 == 't' || c0 == 'y' || c0 == '1')
+ {
+ *result = FcTrue;
+ return FcTrue;
+ }
+ if (c0 == 'f' || c0 == 'n' || c0 == '0')
+ {
+ *result = FcFalse;
+ return FcTrue;
+ }
+ if (c0 == 'o')
+ {
+ c1 = v[1];
+ c1 = FcToLower (c1);
+ if (c1 == 'n')
+ {
+ *result = FcTrue;
+ return FcTrue;
+ }
+ if (c1 == 'f')
+ {
+ *result = FcFalse;
+ return FcTrue;
+ }
+ }
+ return FcFalse;
+}
+
+static FcValue
+FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m)
+{
+ FcValue v;
+
+ v.type = type;
+ switch (v.type) {
+ case FcTypeInteger:
+ if (!FcNameConstant (string, &v.u.i))
+ v.u.i = atoi ((char *) string);
+ break;
+ case FcTypeString:
+ v.u.s = FcStrStaticName(string);
+ if (!v.u.s)
+ v.type = FcTypeVoid;
+ break;
+ case FcTypeBool:
+ if (!FcNameBool (string, &v.u.b))
+ v.u.b = FcFalse;
+ break;
+ case FcTypeDouble:
+ v.u.d = strtod ((char *) string, 0);
+ break;
+ case FcTypeMatrix:
+ v.u.m = m;
+ sscanf ((char *) string, "%lg %lg %lg %lg", &m->xx, &m->xy, &m->yx, &m->yy);
+ break;
+ case FcTypeCharSet:
+ v.u.c = FcNameParseCharSet (string);
+ if (!v.u.c)
+ v.type = FcTypeVoid;
+ break;
+ case FcTypeLangSet:
+ v.u.l = FcNameParseLangSet (string);
+ if (!v.u.l)
+ v.type = FcTypeVoid;
+ break;
+ default:
+ break;
+ }
+ return v;
+}
+
+static const FcChar8 *
+FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last)
+{
+ FcChar8 c;
+
+ while ((c = *cur))
+ {
+ if (c == '\\')
+ {
+ ++cur;
+ if (!(c = *cur))
+ break;
+ }
+ else if (strchr (delim, c))
+ break;
+ ++cur;
+ *save++ = c;
+ }
+ *save = 0;
+ *last = *cur;
+ if (*cur)
+ cur++;
+ return cur;
+}
+
+FcPattern *
+FcNameParse (const FcChar8 *name)
+{
+ FcChar8 *save;
+ FcPattern *pat;
+ double d;
+ FcChar8 *e;
+ FcChar8 delim;
+ FcValue v;
+ FcMatrix m;
+ const FcObjectType *t;
+ const FcConstant *c;
+
+ /* freed below */
+ save = malloc (strlen ((char *) name) + 1);
+ if (!save)
+ goto bail0;
+ pat = FcPatternCreate ();
+ if (!pat)
+ goto bail1;
+
+ for (;;)
+ {
+ name = FcNameFindNext (name, "-,:", save, &delim);
+ if (save[0])
+ {
+ if (!FcPatternAddString (pat, FC_FAMILY, save))
+ goto bail2;
+ }
+ if (delim != ',')
+ break;
+ }
+ if (delim == '-')
+ {
+ for (;;)
+ {
+ name = FcNameFindNext (name, "-,:", save, &delim);
+ d = strtod ((char *) save, (char **) &e);
+ if (e != save)
+ {
+ if (!FcPatternAddDouble (pat, FC_SIZE, d))
+ goto bail2;
+ }
+ if (delim != ',')
+ break;
+ }
+ }
+ while (delim == ':')
+ {
+ name = FcNameFindNext (name, "=_:", save, &delim);
+ if (save[0])
+ {
+ if (delim == '=' || delim == '_')
+ {
+ t = FcNameGetObjectType ((char *) save);
+ for (;;)
+ {
+ name = FcNameFindNext (name, ":,", save, &delim);
+ if (t)
+ {
+ v = FcNameConvert (t->type, save, &m);
+ if (!FcPatternAdd (pat, t->object, v, FcTrue))
+ {
+ switch (v.type) {
+ case FcTypeCharSet:
+ FcCharSetDestroy ((FcCharSet *) v.u.c);
+ break;
+ case FcTypeLangSet:
+ FcLangSetDestroy ((FcLangSet *) v.u.l);
+ break;
+ default:
+ break;
+ }
+ goto bail2;
+ }
+ switch (v.type) {
+ case FcTypeCharSet:
+ FcCharSetDestroy ((FcCharSet *) v.u.c);
+ break;
+ case FcTypeLangSet:
+ FcLangSetDestroy ((FcLangSet *) v.u.l);
+ break;
+ default:
+ break;
+ }
+ }
+ if (delim != ',')
+ break;
+ }
+ }
+ else
+ {
+ if ((c = FcNameGetConstant (save)))
+ {
+ t = FcNameGetObjectType ((char *) c->object);
+ switch (t->type) {
+ case FcTypeInteger:
+ case FcTypeDouble:
+ if (!FcPatternAddInteger (pat, c->object, c->value))
+ goto bail2;
+ break;
+ case FcTypeBool:
+ if (!FcPatternAddBool (pat, c->object, c->value))
+ goto bail2;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ free (save);
+ return pat;
+
+bail2:
+ FcPatternDestroy (pat);
+bail1:
+ free (save);
+bail0:
+ return 0;
+}
+static FcBool
+FcNameUnparseString (FcStrBuf *buf,
+ const FcChar8 *string,
+ const FcChar8 *escape)
+{
+ FcChar8 c;
+ while ((c = *string++))
+ {
+ if (escape && strchr ((char *) escape, (char) c))
+ {
+ if (!FcStrBufChar (buf, escape[0]))
+ return FcFalse;
+ }
+ if (!FcStrBufChar (buf, c))
+ return FcFalse;
+ }
+ return FcTrue;
+}
+
+FcBool
+FcNameUnparseValue (FcStrBuf *buf,
+ FcValue *v0,
+ FcChar8 *escape)
+{
+ FcChar8 temp[1024];
+ FcValue v = FcValueCanonicalize(v0);
+
+ switch (v.type) {
+ case FcTypeVoid:
+ return FcTrue;
+ case FcTypeInteger:
+ sprintf ((char *) temp, "%d", v.u.i);
+ return FcNameUnparseString (buf, temp, 0);
+ case FcTypeDouble:
+ sprintf ((char *) temp, "%g", v.u.d);
+ return FcNameUnparseString (buf, temp, 0);
+ case FcTypeString:
+ return FcNameUnparseString (buf, v.u.s, escape);
+ case FcTypeBool:
+ return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0);
+ case FcTypeMatrix:
+ sprintf ((char *) temp, "%g %g %g %g",
+ v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
+ return FcNameUnparseString (buf, temp, 0);
+ case FcTypeCharSet:
+ return FcNameUnparseCharSet (buf, v.u.c);
+ case FcTypeLangSet:
+ return FcNameUnparseLangSet (buf, v.u.l);
+ case FcTypeFTFace:
+ return FcTrue;
+ }
+ return FcFalse;
+}
+
+FcBool
+FcNameUnparseValueList (FcStrBuf *buf,
+ FcValueListPtr v,
+ FcChar8 *escape)
+{
+ while (v)
+ {
+ if (!FcNameUnparseValue (buf, &v->value, escape))
+ return FcFalse;
+ if ((v = FcValueListNext(v)) != NULL)
+ if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0))
+ return FcFalse;
+ }
+ return FcTrue;
+}
+
+#define FC_ESCAPE_FIXED "\\-:,"
+#define FC_ESCAPE_VARIABLE "\\=_:,"
+
+FcChar8 *
+FcNameUnparse (FcPattern *pat)
+{
+ return FcNameUnparseEscaped (pat, FcTrue);
+}
+
+FcChar8 *
+FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
+{
+ FcStrBuf buf;
+ FcChar8 buf_static[8192];
+ int i;
+ FcPatternElt *e;
+ const FcObjectTypeList *l;
+ const FcObjectType *o;
+
+ FcStrBufInit (&buf, buf_static, sizeof (buf_static));
+ e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT);
+ if (e)
+ {
+ if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
+ goto bail0;
+ }
+ e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT);
+ if (e)
+ {
+ if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0))
+ goto bail0;
+ if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
+ goto bail0;
+ }
+ for (l = _FcObjectTypes; l; l = l->next)
+ {
+ for (i = 0; i < l->ntypes; i++)
+ {
+ o = &l->types[i];
+ if (!strcmp (o->object, FC_FAMILY) ||
+ !strcmp (o->object, FC_SIZE) ||
+ !strcmp (o->object, FC_FILE))
+ continue;
+
+ e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object));
+ if (e)
+ {
+ if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0))
+ goto bail0;
+ if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0))
+ goto bail0;
+ if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0))
+ goto bail0;
+ if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ?
+ (FcChar8 *) FC_ESCAPE_VARIABLE : 0))
+ goto bail0;
+ }
+ }
+ }
+ return FcStrBufDone (&buf);
+bail0:
+ FcStrBufDestroy (&buf);
+ return 0;
+}
+#define __fcname__
+#include "fcaliastail.h"
+#undef __fcname__
|