fcname.c revision 2c393a42
12c393a42Smrg/* 22c393a42Smrg * $RCSId: xc/lib/fontconfig/src/fcname.c,v 1.15 2002/09/26 00:17:28 keithp Exp $ 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 102c393a42Smrg * documentation, and that the name of Keith Packard not be used in 112c393a42Smrg * advertising or publicity pertaining to distribution of the software without 122c393a42Smrg * specific, written prior permission. Keith Packard makes no 132c393a42Smrg * representations about the suitability of this software for any purpose. It 142c393a42Smrg * is provided "as is" without express or implied warranty. 152c393a42Smrg * 162c393a42Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 172c393a42Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 182c393a42Smrg * EVENT SHALL KEITH PACKARD 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 312c393a42Smrg/* 322c393a42Smrg * Please do not change this list, it is used to initialize the object 332c393a42Smrg * list in this order to match the FC_foo_OBJECT constants. Those 342c393a42Smrg * constants are written into cache files. 352c393a42Smrg */ 362c393a42Smrg 372c393a42Smrgstatic const FcObjectType _FcBaseObjectTypes[] = { 382c393a42Smrg { FC_FAMILY, FcTypeString, }, /* 1 */ 392c393a42Smrg { FC_FAMILYLANG, FcTypeString, }, 402c393a42Smrg { FC_STYLE, FcTypeString, }, 412c393a42Smrg { FC_STYLELANG, FcTypeString, }, 422c393a42Smrg { FC_FULLNAME, FcTypeString, }, 432c393a42Smrg { FC_FULLNAMELANG, FcTypeString, }, 442c393a42Smrg { FC_SLANT, FcTypeInteger, }, 452c393a42Smrg { FC_WEIGHT, FcTypeInteger, }, 462c393a42Smrg { FC_WIDTH, FcTypeInteger, }, 472c393a42Smrg { FC_SIZE, FcTypeDouble, }, 482c393a42Smrg { FC_ASPECT, FcTypeDouble, }, 492c393a42Smrg { FC_PIXEL_SIZE, FcTypeDouble, }, 502c393a42Smrg { FC_SPACING, FcTypeInteger, }, 512c393a42Smrg { FC_FOUNDRY, FcTypeString, }, 522c393a42Smrg { FC_ANTIALIAS, FcTypeBool, }, 532c393a42Smrg { FC_HINT_STYLE, FcTypeInteger, }, 542c393a42Smrg { FC_HINTING, FcTypeBool, }, 552c393a42Smrg { FC_VERTICAL_LAYOUT, FcTypeBool, }, 562c393a42Smrg { FC_AUTOHINT, FcTypeBool, }, 572c393a42Smrg { FC_GLOBAL_ADVANCE, FcTypeBool, }, 582c393a42Smrg { FC_FILE, FcTypeString, }, 592c393a42Smrg { FC_INDEX, FcTypeInteger, }, 602c393a42Smrg { FC_RASTERIZER, FcTypeString, }, 612c393a42Smrg { FC_OUTLINE, FcTypeBool, }, 622c393a42Smrg { FC_SCALABLE, FcTypeBool, }, 632c393a42Smrg { FC_DPI, FcTypeDouble }, 642c393a42Smrg { FC_RGBA, FcTypeInteger, }, 652c393a42Smrg { FC_SCALE, FcTypeDouble, }, 662c393a42Smrg { FC_MINSPACE, FcTypeBool, }, 672c393a42Smrg { FC_CHAR_WIDTH, FcTypeInteger }, 682c393a42Smrg { FC_CHAR_HEIGHT, FcTypeInteger }, 692c393a42Smrg { FC_MATRIX, FcTypeMatrix }, 702c393a42Smrg { FC_CHARSET, FcTypeCharSet }, 712c393a42Smrg { FC_LANG, FcTypeLangSet }, 722c393a42Smrg { FC_FONTVERSION, FcTypeInteger }, 732c393a42Smrg { FC_CAPABILITY, FcTypeString }, 742c393a42Smrg { FC_FONTFORMAT, FcTypeString }, 752c393a42Smrg { FC_EMBOLDEN, FcTypeBool }, 762c393a42Smrg { FC_EMBEDDED_BITMAP, FcTypeBool }, 772c393a42Smrg { FC_DECORATIVE, FcTypeBool }, 782c393a42Smrg { FC_LCD_FILTER, FcTypeInteger }, /* 41 */ 792c393a42Smrg}; 802c393a42Smrg 812c393a42Smrg#define NUM_OBJECT_TYPES (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0]) 822c393a42Smrg 832c393a42Smrgtypedef struct _FcObjectTypeList FcObjectTypeList; 842c393a42Smrg 852c393a42Smrgstruct _FcObjectTypeList { 862c393a42Smrg const FcObjectTypeList *next; 872c393a42Smrg const FcObjectType *types; 882c393a42Smrg int ntypes; 892c393a42Smrg}; 902c393a42Smrg 912c393a42Smrgstatic const FcObjectTypeList _FcBaseObjectTypesList = { 922c393a42Smrg 0, 932c393a42Smrg _FcBaseObjectTypes, 942c393a42Smrg NUM_OBJECT_TYPES, 952c393a42Smrg}; 962c393a42Smrg 972c393a42Smrgstatic const FcObjectTypeList *_FcObjectTypes = &_FcBaseObjectTypesList; 982c393a42Smrg 992c393a42Smrg#define OBJECT_HASH_SIZE 31 1002c393a42Smrg 1012c393a42Smrgtypedef struct _FcObjectBucket { 1022c393a42Smrg struct _FcObjectBucket *next; 1032c393a42Smrg FcChar32 hash; 1042c393a42Smrg FcObject id; 1052c393a42Smrg} FcObjectBucket; 1062c393a42Smrg 1072c393a42Smrgstatic FcObjectBucket *FcObjectBuckets[OBJECT_HASH_SIZE]; 1082c393a42Smrg 1092c393a42Smrgstatic FcObjectType *FcObjects = (FcObjectType *) _FcBaseObjectTypes; 1102c393a42Smrgstatic int FcObjectsNumber = NUM_OBJECT_TYPES; 1112c393a42Smrgstatic int FcObjectsSize = 0; 1122c393a42Smrgstatic FcBool FcObjectsInited; 1132c393a42Smrg 1142c393a42Smrgstatic FcObjectType * 1152c393a42SmrgFcObjectInsert (const char *name, FcType type) 1162c393a42Smrg{ 1172c393a42Smrg FcObjectType *o; 1182c393a42Smrg if (FcObjectsNumber >= FcObjectsSize) 1192c393a42Smrg { 1202c393a42Smrg int newsize = FcObjectsNumber * 2; 1212c393a42Smrg FcObjectType *newobjects; 1222c393a42Smrg 1232c393a42Smrg if (FcObjectsSize) 1242c393a42Smrg newobjects = realloc (FcObjects, newsize * sizeof (FcObjectType)); 1252c393a42Smrg else 1262c393a42Smrg { 1272c393a42Smrg newobjects = malloc (newsize * sizeof (FcObjectType)); 1282c393a42Smrg if (newobjects) 1292c393a42Smrg memcpy (newobjects, FcObjects, 1302c393a42Smrg FcObjectsNumber * sizeof (FcObjectType)); 1312c393a42Smrg } 1322c393a42Smrg if (!newobjects) 1332c393a42Smrg return NULL; 1342c393a42Smrg FcObjects = newobjects; 1352c393a42Smrg FcObjectsSize = newsize; 1362c393a42Smrg } 1372c393a42Smrg o = &FcObjects[FcObjectsNumber]; 1382c393a42Smrg o->object = name; 1392c393a42Smrg o->type = type; 1402c393a42Smrg ++FcObjectsNumber; 1412c393a42Smrg return o; 1422c393a42Smrg} 1432c393a42Smrg 1442c393a42Smrgstatic FcObject 1452c393a42SmrgFcObjectId (FcObjectType *o) 1462c393a42Smrg{ 1472c393a42Smrg return o - FcObjects + 1; 1482c393a42Smrg} 1492c393a42Smrg 1502c393a42Smrgstatic FcObjectType * 1512c393a42SmrgFcObjectFindByName (const char *object, FcBool insert) 1522c393a42Smrg{ 1532c393a42Smrg FcChar32 hash = FcStringHash ((const FcChar8 *) object); 1542c393a42Smrg FcObjectBucket **p; 1552c393a42Smrg FcObjectBucket *b; 1562c393a42Smrg FcObjectType *o; 1572c393a42Smrg 1582c393a42Smrg if (!FcObjectsInited) 1592c393a42Smrg FcObjectInit (); 1602c393a42Smrg for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) 1612c393a42Smrg { 1622c393a42Smrg o = FcObjects + b->id - 1; 1632c393a42Smrg if (b->hash == hash && !strcmp (object, (o->object))) 1642c393a42Smrg return o; 1652c393a42Smrg } 1662c393a42Smrg if (!insert) 1672c393a42Smrg return NULL; 1682c393a42Smrg /* 1692c393a42Smrg * Hook it into the hash chain 1702c393a42Smrg */ 1712c393a42Smrg b = malloc (sizeof(FcObjectBucket)); 1722c393a42Smrg if (!b) 1732c393a42Smrg return NULL; 1742c393a42Smrg object = (const char *) FcStrCopy ((FcChar8 *) object); 1752c393a42Smrg if (!object) { 1762c393a42Smrg free (b); 1772c393a42Smrg return NULL; 1782c393a42Smrg } 1792c393a42Smrg o = FcObjectInsert (object, -1); 1802c393a42Smrg b->next = NULL; 1812c393a42Smrg b->hash = hash; 1822c393a42Smrg b->id = FcObjectId (o); 1832c393a42Smrg *p = b; 1842c393a42Smrg return o; 1852c393a42Smrg} 1862c393a42Smrg 1872c393a42Smrgstatic FcObjectType * 1882c393a42SmrgFcObjectFindById (FcObject object) 1892c393a42Smrg{ 1902c393a42Smrg if (1 <= object && object <= FcObjectsNumber) 1912c393a42Smrg return FcObjects + object - 1; 1922c393a42Smrg return NULL; 1932c393a42Smrg} 1942c393a42Smrg 1952c393a42Smrgstatic FcBool 1962c393a42SmrgFcObjectHashInsert (const FcObjectType *object, FcBool copy) 1972c393a42Smrg{ 1982c393a42Smrg FcChar32 hash = FcStringHash ((const FcChar8 *) object->object); 1992c393a42Smrg FcObjectBucket **p; 2002c393a42Smrg FcObjectBucket *b; 2012c393a42Smrg FcObjectType *o; 2022c393a42Smrg 2032c393a42Smrg if (!FcObjectsInited) 2042c393a42Smrg FcObjectInit (); 2052c393a42Smrg for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) 2062c393a42Smrg { 2072c393a42Smrg o = FcObjects + b->id - 1; 2082c393a42Smrg if (b->hash == hash && !strcmp (object->object, o->object)) 2092c393a42Smrg return FcFalse; 2102c393a42Smrg } 2112c393a42Smrg /* 2122c393a42Smrg * Hook it into the hash chain 2132c393a42Smrg */ 2142c393a42Smrg b = malloc (sizeof(FcObjectBucket)); 2152c393a42Smrg if (!b) 2162c393a42Smrg return FcFalse; 2172c393a42Smrg if (copy) 2182c393a42Smrg { 2192c393a42Smrg o = FcObjectInsert (object->object, object->type); 2202c393a42Smrg if (!o) 2212c393a42Smrg { 2222c393a42Smrg free (b); 2232c393a42Smrg return FcFalse; 2242c393a42Smrg } 2252c393a42Smrg } 2262c393a42Smrg else 2272c393a42Smrg o = (FcObjectType *) object; 2282c393a42Smrg b->next = NULL; 2292c393a42Smrg b->hash = hash; 2302c393a42Smrg b->id = FcObjectId (o); 2312c393a42Smrg *p = b; 2322c393a42Smrg return FcTrue; 2332c393a42Smrg} 2342c393a42Smrg 2352c393a42Smrgstatic void 2362c393a42SmrgFcObjectHashRemove (const FcObjectType *object, FcBool cleanobj) 2372c393a42Smrg{ 2382c393a42Smrg FcChar32 hash = FcStringHash ((const FcChar8 *) object->object); 2392c393a42Smrg FcObjectBucket **p; 2402c393a42Smrg FcObjectBucket *b; 2412c393a42Smrg FcObjectType *o; 2422c393a42Smrg 2432c393a42Smrg if (!FcObjectsInited) 2442c393a42Smrg FcObjectInit (); 2452c393a42Smrg for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) 2462c393a42Smrg { 2472c393a42Smrg o = FcObjects + b->id - 1; 2482c393a42Smrg if (b->hash == hash && !strcmp (object->object, o->object)) 2492c393a42Smrg { 2502c393a42Smrg *p = b->next; 2512c393a42Smrg free (b); 2522c393a42Smrg if (cleanobj) 2532c393a42Smrg { 2542c393a42Smrg /* Clean up object array */ 2552c393a42Smrg o->object = NULL; 2562c393a42Smrg o->type = -1; 2572c393a42Smrg while (FcObjects[FcObjectsNumber-1].object == NULL) 2582c393a42Smrg --FcObjectsNumber; 2592c393a42Smrg } 2602c393a42Smrg break; 2612c393a42Smrg } 2622c393a42Smrg } 2632c393a42Smrg} 2642c393a42Smrg 2652c393a42SmrgFcBool 2662c393a42SmrgFcNameRegisterObjectTypes (const FcObjectType *types, int ntypes) 2672c393a42Smrg{ 2682c393a42Smrg int i; 2692c393a42Smrg 2702c393a42Smrg for (i = 0; i < ntypes; i++) 2712c393a42Smrg if (!FcObjectHashInsert (&types[i], FcTrue)) 2722c393a42Smrg return FcFalse; 2732c393a42Smrg return FcTrue; 2742c393a42Smrg} 2752c393a42Smrg 2762c393a42SmrgFcBool 2772c393a42SmrgFcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes) 2782c393a42Smrg{ 2792c393a42Smrg int i; 2802c393a42Smrg 2812c393a42Smrg for (i = 0; i < ntypes; i++) 2822c393a42Smrg FcObjectHashRemove (&types[i], FcTrue); 2832c393a42Smrg return FcTrue; 2842c393a42Smrg} 2852c393a42Smrg 2862c393a42Smrgconst FcObjectType * 2872c393a42SmrgFcNameGetObjectType (const char *object) 2882c393a42Smrg{ 2892c393a42Smrg return FcObjectFindByName (object, FcFalse); 2902c393a42Smrg} 2912c393a42Smrg 2922c393a42SmrgFcBool 2932c393a42SmrgFcObjectValidType (FcObject object, FcType type) 2942c393a42Smrg{ 2952c393a42Smrg FcObjectType *t = FcObjectFindById (object); 2962c393a42Smrg 2972c393a42Smrg if (t) { 2982c393a42Smrg switch (t->type) { 2992c393a42Smrg case -1: 3002c393a42Smrg return FcTrue; 3012c393a42Smrg case FcTypeDouble: 3022c393a42Smrg case FcTypeInteger: 3032c393a42Smrg if (type == FcTypeDouble || type == FcTypeInteger) 3042c393a42Smrg return FcTrue; 3052c393a42Smrg break; 3062c393a42Smrg case FcTypeLangSet: 3072c393a42Smrg if (type == FcTypeLangSet || type == FcTypeString) 3082c393a42Smrg return FcTrue; 3092c393a42Smrg break; 3102c393a42Smrg default: 3112c393a42Smrg if (type == t->type) 3122c393a42Smrg return FcTrue; 3132c393a42Smrg break; 3142c393a42Smrg } 3152c393a42Smrg return FcFalse; 3162c393a42Smrg } 3172c393a42Smrg return FcTrue; 3182c393a42Smrg} 3192c393a42Smrg 3202c393a42SmrgFcObject 3212c393a42SmrgFcObjectFromName (const char * name) 3222c393a42Smrg{ 3232c393a42Smrg FcObjectType *o = FcObjectFindByName (name, FcTrue); 3242c393a42Smrg 3252c393a42Smrg if (o) 3262c393a42Smrg return FcObjectId (o); 3272c393a42Smrg return 0; 3282c393a42Smrg} 3292c393a42Smrg 3302c393a42SmrgFcBool 3312c393a42SmrgFcObjectInit (void) 3322c393a42Smrg{ 3332c393a42Smrg int i; 3342c393a42Smrg 3352c393a42Smrg if (FcObjectsInited) 3362c393a42Smrg return FcTrue; 3372c393a42Smrg 3382c393a42Smrg FcObjectsInited = FcTrue; 3392c393a42Smrg for (i = 0; i < NUM_OBJECT_TYPES; i++) 3402c393a42Smrg if (!FcObjectHashInsert (&_FcBaseObjectTypes[i], FcFalse)) 3412c393a42Smrg return FcFalse; 3422c393a42Smrg return FcTrue; 3432c393a42Smrg} 3442c393a42Smrg 3452c393a42Smrgvoid 3462c393a42SmrgFcObjectFini (void) 3472c393a42Smrg{ 3482c393a42Smrg int i; 3492c393a42Smrg FcObjectBucket *b, *next; 3502c393a42Smrg 3512c393a42Smrg for (i = 0; i < OBJECT_HASH_SIZE; i++) 3522c393a42Smrg { 3532c393a42Smrg for (b = FcObjectBuckets[i]; b; b = next) 3542c393a42Smrg { 3552c393a42Smrg next = b->next; 3562c393a42Smrg free (b); 3572c393a42Smrg } 3582c393a42Smrg FcObjectBuckets[i] = 0; 3592c393a42Smrg } 3602c393a42Smrg for (i = 0; i < FcObjectsNumber; i++) 3612c393a42Smrg if (FcObjects[i].type == -1) 3622c393a42Smrg free ((void*) FcObjects[i].object); 3632c393a42Smrg if (FcObjects != _FcBaseObjectTypes) 3642c393a42Smrg free (FcObjects); 3652c393a42Smrg FcObjects = (FcObjectType *) _FcBaseObjectTypes; 3662c393a42Smrg FcObjectsNumber = NUM_OBJECT_TYPES; 3672c393a42Smrg FcObjectsSize = 0; 3682c393a42Smrg FcObjectsInited = FcFalse; 3692c393a42Smrg} 3702c393a42Smrg 3712c393a42Smrgconst char * 3722c393a42SmrgFcObjectName (FcObject object) 3732c393a42Smrg{ 3742c393a42Smrg FcObjectType *o = FcObjectFindById (object); 3752c393a42Smrg 3762c393a42Smrg if (o) 3772c393a42Smrg return o->object; 3782c393a42Smrg return NULL; 3792c393a42Smrg} 3802c393a42Smrg 3812c393a42Smrgstatic const FcConstant _FcBaseConstants[] = { 3822c393a42Smrg { (FcChar8 *) "thin", "weight", FC_WEIGHT_THIN, }, 3832c393a42Smrg { (FcChar8 *) "extralight", "weight", FC_WEIGHT_EXTRALIGHT, }, 3842c393a42Smrg { (FcChar8 *) "ultralight", "weight", FC_WEIGHT_EXTRALIGHT, }, 3852c393a42Smrg { (FcChar8 *) "light", "weight", FC_WEIGHT_LIGHT, }, 3862c393a42Smrg { (FcChar8 *) "book", "weight", FC_WEIGHT_BOOK, }, 3872c393a42Smrg { (FcChar8 *) "regular", "weight", FC_WEIGHT_REGULAR, }, 3882c393a42Smrg { (FcChar8 *) "medium", "weight", FC_WEIGHT_MEDIUM, }, 3892c393a42Smrg { (FcChar8 *) "demibold", "weight", FC_WEIGHT_DEMIBOLD, }, 3902c393a42Smrg { (FcChar8 *) "semibold", "weight", FC_WEIGHT_DEMIBOLD, }, 3912c393a42Smrg { (FcChar8 *) "bold", "weight", FC_WEIGHT_BOLD, }, 3922c393a42Smrg { (FcChar8 *) "extrabold", "weight", FC_WEIGHT_EXTRABOLD, }, 3932c393a42Smrg { (FcChar8 *) "ultrabold", "weight", FC_WEIGHT_EXTRABOLD, }, 3942c393a42Smrg { (FcChar8 *) "black", "weight", FC_WEIGHT_BLACK, }, 3952c393a42Smrg { (FcChar8 *) "heavy", "weight", FC_WEIGHT_HEAVY, }, 3962c393a42Smrg 3972c393a42Smrg { (FcChar8 *) "roman", "slant", FC_SLANT_ROMAN, }, 3982c393a42Smrg { (FcChar8 *) "italic", "slant", FC_SLANT_ITALIC, }, 3992c393a42Smrg { (FcChar8 *) "oblique", "slant", FC_SLANT_OBLIQUE, }, 4002c393a42Smrg 4012c393a42Smrg { (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED }, 4022c393a42Smrg { (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED }, 4032c393a42Smrg { (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED }, 4042c393a42Smrg { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED }, 4052c393a42Smrg { (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL }, 4062c393a42Smrg { (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED }, 4072c393a42Smrg { (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED }, 4082c393a42Smrg { (FcChar8 *) "extraexpanded", "width", FC_WIDTH_EXTRAEXPANDED }, 4092c393a42Smrg { (FcChar8 *) "ultraexpanded", "width", FC_WIDTH_ULTRAEXPANDED }, 4102c393a42Smrg 4112c393a42Smrg { (FcChar8 *) "proportional", "spacing", FC_PROPORTIONAL, }, 4122c393a42Smrg { (FcChar8 *) "dual", "spacing", FC_DUAL, }, 4132c393a42Smrg { (FcChar8 *) "mono", "spacing", FC_MONO, }, 4142c393a42Smrg { (FcChar8 *) "charcell", "spacing", FC_CHARCELL, }, 4152c393a42Smrg 4162c393a42Smrg { (FcChar8 *) "unknown", "rgba", FC_RGBA_UNKNOWN }, 4172c393a42Smrg { (FcChar8 *) "rgb", "rgba", FC_RGBA_RGB, }, 4182c393a42Smrg { (FcChar8 *) "bgr", "rgba", FC_RGBA_BGR, }, 4192c393a42Smrg { (FcChar8 *) "vrgb", "rgba", FC_RGBA_VRGB }, 4202c393a42Smrg { (FcChar8 *) "vbgr", "rgba", FC_RGBA_VBGR }, 4212c393a42Smrg { (FcChar8 *) "none", "rgba", FC_RGBA_NONE }, 4222c393a42Smrg 4232c393a42Smrg { (FcChar8 *) "hintnone", "hintstyle", FC_HINT_NONE }, 4242c393a42Smrg { (FcChar8 *) "hintslight", "hintstyle", FC_HINT_SLIGHT }, 4252c393a42Smrg { (FcChar8 *) "hintmedium", "hintstyle", FC_HINT_MEDIUM }, 4262c393a42Smrg { (FcChar8 *) "hintfull", "hintstyle", FC_HINT_FULL }, 4272c393a42Smrg 4282c393a42Smrg { (FcChar8 *) "antialias", "antialias", FcTrue }, 4292c393a42Smrg { (FcChar8 *) "hinting", "hinting", FcTrue }, 4302c393a42Smrg { (FcChar8 *) "verticallayout", "verticallayout", FcTrue }, 4312c393a42Smrg { (FcChar8 *) "autohint", "autohint", FcTrue }, 4322c393a42Smrg { (FcChar8 *) "globaladvance", "globaladvance", FcTrue }, 4332c393a42Smrg { (FcChar8 *) "outline", "outline", FcTrue }, 4342c393a42Smrg { (FcChar8 *) "scalable", "scalable", FcTrue }, 4352c393a42Smrg { (FcChar8 *) "minspace", "minspace", FcTrue }, 4362c393a42Smrg { (FcChar8 *) "embolden", "embolden", FcTrue }, 4372c393a42Smrg { (FcChar8 *) "embeddedbitmap", "embeddedbitmap", FcTrue }, 4382c393a42Smrg { (FcChar8 *) "decorative", "decorative", FcTrue }, 4392c393a42Smrg { (FcChar8 *) "lcdnone", "lcdfilter", FC_LCD_NONE }, 4402c393a42Smrg { (FcChar8 *) "lcddefault", "lcdfilter", FC_LCD_DEFAULT }, 4412c393a42Smrg { (FcChar8 *) "lcdlight", "lcdfilter", FC_LCD_LIGHT }, 4422c393a42Smrg { (FcChar8 *) "lcdlegacy", "lcdfilter", FC_LCD_LEGACY }, 4432c393a42Smrg}; 4442c393a42Smrg 4452c393a42Smrg#define NUM_FC_CONSTANTS (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0]) 4462c393a42Smrg 4472c393a42Smrgtypedef struct _FcConstantList FcConstantList; 4482c393a42Smrg 4492c393a42Smrgstruct _FcConstantList { 4502c393a42Smrg const FcConstantList *next; 4512c393a42Smrg const FcConstant *consts; 4522c393a42Smrg int nconsts; 4532c393a42Smrg}; 4542c393a42Smrg 4552c393a42Smrgstatic const FcConstantList _FcBaseConstantList = { 4562c393a42Smrg 0, 4572c393a42Smrg _FcBaseConstants, 4582c393a42Smrg NUM_FC_CONSTANTS 4592c393a42Smrg}; 4602c393a42Smrg 4612c393a42Smrgstatic const FcConstantList *_FcConstants = &_FcBaseConstantList; 4622c393a42Smrg 4632c393a42SmrgFcBool 4642c393a42SmrgFcNameRegisterConstants (const FcConstant *consts, int nconsts) 4652c393a42Smrg{ 4662c393a42Smrg FcConstantList *l; 4672c393a42Smrg 4682c393a42Smrg l = (FcConstantList *) malloc (sizeof (FcConstantList)); 4692c393a42Smrg if (!l) 4702c393a42Smrg return FcFalse; 4712c393a42Smrg FcMemAlloc (FC_MEM_CONSTANT, sizeof (FcConstantList)); 4722c393a42Smrg l->consts = consts; 4732c393a42Smrg l->nconsts = nconsts; 4742c393a42Smrg l->next = _FcConstants; 4752c393a42Smrg _FcConstants = l; 4762c393a42Smrg return FcTrue; 4772c393a42Smrg} 4782c393a42Smrg 4792c393a42SmrgFcBool 4802c393a42SmrgFcNameUnregisterConstants (const FcConstant *consts, int nconsts) 4812c393a42Smrg{ 4822c393a42Smrg const FcConstantList *l, **prev; 4832c393a42Smrg 4842c393a42Smrg for (prev = &_FcConstants; 4852c393a42Smrg (l = *prev); 4862c393a42Smrg prev = (const FcConstantList **) &(l->next)) 4872c393a42Smrg { 4882c393a42Smrg if (l->consts == consts && l->nconsts == nconsts) 4892c393a42Smrg { 4902c393a42Smrg *prev = l->next; 4912c393a42Smrg FcMemFree (FC_MEM_CONSTANT, sizeof (FcConstantList)); 4922c393a42Smrg free ((void *) l); 4932c393a42Smrg return FcTrue; 4942c393a42Smrg } 4952c393a42Smrg } 4962c393a42Smrg return FcFalse; 4972c393a42Smrg} 4982c393a42Smrg 4992c393a42Smrgconst FcConstant * 5002c393a42SmrgFcNameGetConstant (FcChar8 *string) 5012c393a42Smrg{ 5022c393a42Smrg const FcConstantList *l; 5032c393a42Smrg int i; 5042c393a42Smrg 5052c393a42Smrg for (l = _FcConstants; l; l = l->next) 5062c393a42Smrg { 5072c393a42Smrg for (i = 0; i < l->nconsts; i++) 5082c393a42Smrg if (!FcStrCmpIgnoreCase (string, l->consts[i].name)) 5092c393a42Smrg return &l->consts[i]; 5102c393a42Smrg } 5112c393a42Smrg return 0; 5122c393a42Smrg} 5132c393a42Smrg 5142c393a42SmrgFcBool 5152c393a42SmrgFcNameConstant (FcChar8 *string, int *result) 5162c393a42Smrg{ 5172c393a42Smrg const FcConstant *c; 5182c393a42Smrg 5192c393a42Smrg if ((c = FcNameGetConstant(string))) 5202c393a42Smrg { 5212c393a42Smrg *result = c->value; 5222c393a42Smrg return FcTrue; 5232c393a42Smrg } 5242c393a42Smrg return FcFalse; 5252c393a42Smrg} 5262c393a42Smrg 5272c393a42SmrgFcBool 5282c393a42SmrgFcNameBool (const FcChar8 *v, FcBool *result) 5292c393a42Smrg{ 5302c393a42Smrg char c0, c1; 5312c393a42Smrg 5322c393a42Smrg c0 = *v; 5332c393a42Smrg c0 = FcToLower (c0); 5342c393a42Smrg if (c0 == 't' || c0 == 'y' || c0 == '1') 5352c393a42Smrg { 5362c393a42Smrg *result = FcTrue; 5372c393a42Smrg return FcTrue; 5382c393a42Smrg } 5392c393a42Smrg if (c0 == 'f' || c0 == 'n' || c0 == '0') 5402c393a42Smrg { 5412c393a42Smrg *result = FcFalse; 5422c393a42Smrg return FcTrue; 5432c393a42Smrg } 5442c393a42Smrg if (c0 == 'o') 5452c393a42Smrg { 5462c393a42Smrg c1 = v[1]; 5472c393a42Smrg c1 = FcToLower (c1); 5482c393a42Smrg if (c1 == 'n') 5492c393a42Smrg { 5502c393a42Smrg *result = FcTrue; 5512c393a42Smrg return FcTrue; 5522c393a42Smrg } 5532c393a42Smrg if (c1 == 'f') 5542c393a42Smrg { 5552c393a42Smrg *result = FcFalse; 5562c393a42Smrg return FcTrue; 5572c393a42Smrg } 5582c393a42Smrg } 5592c393a42Smrg return FcFalse; 5602c393a42Smrg} 5612c393a42Smrg 5622c393a42Smrgstatic FcValue 5632c393a42SmrgFcNameConvert (FcType type, FcChar8 *string, FcMatrix *m) 5642c393a42Smrg{ 5652c393a42Smrg FcValue v; 5662c393a42Smrg 5672c393a42Smrg v.type = type; 5682c393a42Smrg switch (v.type) { 5692c393a42Smrg case FcTypeInteger: 5702c393a42Smrg if (!FcNameConstant (string, &v.u.i)) 5712c393a42Smrg v.u.i = atoi ((char *) string); 5722c393a42Smrg break; 5732c393a42Smrg case FcTypeString: 5742c393a42Smrg v.u.s = FcStrStaticName(string); 5752c393a42Smrg if (!v.u.s) 5762c393a42Smrg v.type = FcTypeVoid; 5772c393a42Smrg break; 5782c393a42Smrg case FcTypeBool: 5792c393a42Smrg if (!FcNameBool (string, &v.u.b)) 5802c393a42Smrg v.u.b = FcFalse; 5812c393a42Smrg break; 5822c393a42Smrg case FcTypeDouble: 5832c393a42Smrg v.u.d = strtod ((char *) string, 0); 5842c393a42Smrg break; 5852c393a42Smrg case FcTypeMatrix: 5862c393a42Smrg v.u.m = m; 5872c393a42Smrg sscanf ((char *) string, "%lg %lg %lg %lg", &m->xx, &m->xy, &m->yx, &m->yy); 5882c393a42Smrg break; 5892c393a42Smrg case FcTypeCharSet: 5902c393a42Smrg v.u.c = FcNameParseCharSet (string); 5912c393a42Smrg if (!v.u.c) 5922c393a42Smrg v.type = FcTypeVoid; 5932c393a42Smrg break; 5942c393a42Smrg case FcTypeLangSet: 5952c393a42Smrg v.u.l = FcNameParseLangSet (string); 5962c393a42Smrg if (!v.u.l) 5972c393a42Smrg v.type = FcTypeVoid; 5982c393a42Smrg break; 5992c393a42Smrg default: 6002c393a42Smrg break; 6012c393a42Smrg } 6022c393a42Smrg return v; 6032c393a42Smrg} 6042c393a42Smrg 6052c393a42Smrgstatic const FcChar8 * 6062c393a42SmrgFcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last) 6072c393a42Smrg{ 6082c393a42Smrg FcChar8 c; 6092c393a42Smrg 6102c393a42Smrg while ((c = *cur)) 6112c393a42Smrg { 6122c393a42Smrg if (c == '\\') 6132c393a42Smrg { 6142c393a42Smrg ++cur; 6152c393a42Smrg if (!(c = *cur)) 6162c393a42Smrg break; 6172c393a42Smrg } 6182c393a42Smrg else if (strchr (delim, c)) 6192c393a42Smrg break; 6202c393a42Smrg ++cur; 6212c393a42Smrg *save++ = c; 6222c393a42Smrg } 6232c393a42Smrg *save = 0; 6242c393a42Smrg *last = *cur; 6252c393a42Smrg if (*cur) 6262c393a42Smrg cur++; 6272c393a42Smrg return cur; 6282c393a42Smrg} 6292c393a42Smrg 6302c393a42SmrgFcPattern * 6312c393a42SmrgFcNameParse (const FcChar8 *name) 6322c393a42Smrg{ 6332c393a42Smrg FcChar8 *save; 6342c393a42Smrg FcPattern *pat; 6352c393a42Smrg double d; 6362c393a42Smrg FcChar8 *e; 6372c393a42Smrg FcChar8 delim; 6382c393a42Smrg FcValue v; 6392c393a42Smrg FcMatrix m; 6402c393a42Smrg const FcObjectType *t; 6412c393a42Smrg const FcConstant *c; 6422c393a42Smrg 6432c393a42Smrg /* freed below */ 6442c393a42Smrg save = malloc (strlen ((char *) name) + 1); 6452c393a42Smrg if (!save) 6462c393a42Smrg goto bail0; 6472c393a42Smrg pat = FcPatternCreate (); 6482c393a42Smrg if (!pat) 6492c393a42Smrg goto bail1; 6502c393a42Smrg 6512c393a42Smrg for (;;) 6522c393a42Smrg { 6532c393a42Smrg name = FcNameFindNext (name, "-,:", save, &delim); 6542c393a42Smrg if (save[0]) 6552c393a42Smrg { 6562c393a42Smrg if (!FcPatternAddString (pat, FC_FAMILY, save)) 6572c393a42Smrg goto bail2; 6582c393a42Smrg } 6592c393a42Smrg if (delim != ',') 6602c393a42Smrg break; 6612c393a42Smrg } 6622c393a42Smrg if (delim == '-') 6632c393a42Smrg { 6642c393a42Smrg for (;;) 6652c393a42Smrg { 6662c393a42Smrg name = FcNameFindNext (name, "-,:", save, &delim); 6672c393a42Smrg d = strtod ((char *) save, (char **) &e); 6682c393a42Smrg if (e != save) 6692c393a42Smrg { 6702c393a42Smrg if (!FcPatternAddDouble (pat, FC_SIZE, d)) 6712c393a42Smrg goto bail2; 6722c393a42Smrg } 6732c393a42Smrg if (delim != ',') 6742c393a42Smrg break; 6752c393a42Smrg } 6762c393a42Smrg } 6772c393a42Smrg while (delim == ':') 6782c393a42Smrg { 6792c393a42Smrg name = FcNameFindNext (name, "=_:", save, &delim); 6802c393a42Smrg if (save[0]) 6812c393a42Smrg { 6822c393a42Smrg if (delim == '=' || delim == '_') 6832c393a42Smrg { 6842c393a42Smrg t = FcNameGetObjectType ((char *) save); 6852c393a42Smrg for (;;) 6862c393a42Smrg { 6872c393a42Smrg name = FcNameFindNext (name, ":,", save, &delim); 6882c393a42Smrg if (t) 6892c393a42Smrg { 6902c393a42Smrg v = FcNameConvert (t->type, save, &m); 6912c393a42Smrg if (!FcPatternAdd (pat, t->object, v, FcTrue)) 6922c393a42Smrg { 6932c393a42Smrg switch (v.type) { 6942c393a42Smrg case FcTypeCharSet: 6952c393a42Smrg FcCharSetDestroy ((FcCharSet *) v.u.c); 6962c393a42Smrg break; 6972c393a42Smrg case FcTypeLangSet: 6982c393a42Smrg FcLangSetDestroy ((FcLangSet *) v.u.l); 6992c393a42Smrg break; 7002c393a42Smrg default: 7012c393a42Smrg break; 7022c393a42Smrg } 7032c393a42Smrg goto bail2; 7042c393a42Smrg } 7052c393a42Smrg switch (v.type) { 7062c393a42Smrg case FcTypeCharSet: 7072c393a42Smrg FcCharSetDestroy ((FcCharSet *) v.u.c); 7082c393a42Smrg break; 7092c393a42Smrg case FcTypeLangSet: 7102c393a42Smrg FcLangSetDestroy ((FcLangSet *) v.u.l); 7112c393a42Smrg break; 7122c393a42Smrg default: 7132c393a42Smrg break; 7142c393a42Smrg } 7152c393a42Smrg } 7162c393a42Smrg if (delim != ',') 7172c393a42Smrg break; 7182c393a42Smrg } 7192c393a42Smrg } 7202c393a42Smrg else 7212c393a42Smrg { 7222c393a42Smrg if ((c = FcNameGetConstant (save))) 7232c393a42Smrg { 7242c393a42Smrg t = FcNameGetObjectType ((char *) c->object); 7252c393a42Smrg switch (t->type) { 7262c393a42Smrg case FcTypeInteger: 7272c393a42Smrg case FcTypeDouble: 7282c393a42Smrg if (!FcPatternAddInteger (pat, c->object, c->value)) 7292c393a42Smrg goto bail2; 7302c393a42Smrg break; 7312c393a42Smrg case FcTypeBool: 7322c393a42Smrg if (!FcPatternAddBool (pat, c->object, c->value)) 7332c393a42Smrg goto bail2; 7342c393a42Smrg break; 7352c393a42Smrg default: 7362c393a42Smrg break; 7372c393a42Smrg } 7382c393a42Smrg } 7392c393a42Smrg } 7402c393a42Smrg } 7412c393a42Smrg } 7422c393a42Smrg 7432c393a42Smrg free (save); 7442c393a42Smrg return pat; 7452c393a42Smrg 7462c393a42Smrgbail2: 7472c393a42Smrg FcPatternDestroy (pat); 7482c393a42Smrgbail1: 7492c393a42Smrg free (save); 7502c393a42Smrgbail0: 7512c393a42Smrg return 0; 7522c393a42Smrg} 7532c393a42Smrgstatic FcBool 7542c393a42SmrgFcNameUnparseString (FcStrBuf *buf, 7552c393a42Smrg const FcChar8 *string, 7562c393a42Smrg const FcChar8 *escape) 7572c393a42Smrg{ 7582c393a42Smrg FcChar8 c; 7592c393a42Smrg while ((c = *string++)) 7602c393a42Smrg { 7612c393a42Smrg if (escape && strchr ((char *) escape, (char) c)) 7622c393a42Smrg { 7632c393a42Smrg if (!FcStrBufChar (buf, escape[0])) 7642c393a42Smrg return FcFalse; 7652c393a42Smrg } 7662c393a42Smrg if (!FcStrBufChar (buf, c)) 7672c393a42Smrg return FcFalse; 7682c393a42Smrg } 7692c393a42Smrg return FcTrue; 7702c393a42Smrg} 7712c393a42Smrg 7722c393a42Smrgstatic FcBool 7732c393a42SmrgFcNameUnparseValue (FcStrBuf *buf, 7742c393a42Smrg FcValue *v0, 7752c393a42Smrg FcChar8 *escape) 7762c393a42Smrg{ 7772c393a42Smrg FcChar8 temp[1024]; 7782c393a42Smrg FcValue v = FcValueCanonicalize(v0); 7792c393a42Smrg 7802c393a42Smrg switch (v.type) { 7812c393a42Smrg case FcTypeVoid: 7822c393a42Smrg return FcTrue; 7832c393a42Smrg case FcTypeInteger: 7842c393a42Smrg sprintf ((char *) temp, "%d", v.u.i); 7852c393a42Smrg return FcNameUnparseString (buf, temp, 0); 7862c393a42Smrg case FcTypeDouble: 7872c393a42Smrg sprintf ((char *) temp, "%g", v.u.d); 7882c393a42Smrg return FcNameUnparseString (buf, temp, 0); 7892c393a42Smrg case FcTypeString: 7902c393a42Smrg return FcNameUnparseString (buf, v.u.s, escape); 7912c393a42Smrg case FcTypeBool: 7922c393a42Smrg return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0); 7932c393a42Smrg case FcTypeMatrix: 7942c393a42Smrg sprintf ((char *) temp, "%g %g %g %g", 7952c393a42Smrg v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); 7962c393a42Smrg return FcNameUnparseString (buf, temp, 0); 7972c393a42Smrg case FcTypeCharSet: 7982c393a42Smrg return FcNameUnparseCharSet (buf, v.u.c); 7992c393a42Smrg case FcTypeLangSet: 8002c393a42Smrg return FcNameUnparseLangSet (buf, v.u.l); 8012c393a42Smrg case FcTypeFTFace: 8022c393a42Smrg return FcTrue; 8032c393a42Smrg } 8042c393a42Smrg return FcFalse; 8052c393a42Smrg} 8062c393a42Smrg 8072c393a42Smrgstatic FcBool 8082c393a42SmrgFcNameUnparseValueList (FcStrBuf *buf, 8092c393a42Smrg FcValueListPtr v, 8102c393a42Smrg FcChar8 *escape) 8112c393a42Smrg{ 8122c393a42Smrg while (v) 8132c393a42Smrg { 8142c393a42Smrg if (!FcNameUnparseValue (buf, &v->value, escape)) 8152c393a42Smrg return FcFalse; 8162c393a42Smrg if ((v = FcValueListNext(v)) != NULL) 8172c393a42Smrg if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0)) 8182c393a42Smrg return FcFalse; 8192c393a42Smrg } 8202c393a42Smrg return FcTrue; 8212c393a42Smrg} 8222c393a42Smrg 8232c393a42Smrg#define FC_ESCAPE_FIXED "\\-:," 8242c393a42Smrg#define FC_ESCAPE_VARIABLE "\\=_:," 8252c393a42Smrg 8262c393a42SmrgFcChar8 * 8272c393a42SmrgFcNameUnparse (FcPattern *pat) 8282c393a42Smrg{ 8292c393a42Smrg return FcNameUnparseEscaped (pat, FcTrue); 8302c393a42Smrg} 8312c393a42Smrg 8322c393a42SmrgFcChar8 * 8332c393a42SmrgFcNameUnparseEscaped (FcPattern *pat, FcBool escape) 8342c393a42Smrg{ 8352c393a42Smrg FcStrBuf buf; 8362c393a42Smrg FcChar8 buf_static[8192]; 8372c393a42Smrg int i; 8382c393a42Smrg FcPatternElt *e; 8392c393a42Smrg const FcObjectTypeList *l; 8402c393a42Smrg const FcObjectType *o; 8412c393a42Smrg 8422c393a42Smrg FcStrBufInit (&buf, buf_static, sizeof (buf_static)); 8432c393a42Smrg e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT); 8442c393a42Smrg if (e) 8452c393a42Smrg { 8462c393a42Smrg if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) 8472c393a42Smrg goto bail0; 8482c393a42Smrg } 8492c393a42Smrg e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT); 8502c393a42Smrg if (e) 8512c393a42Smrg { 8522c393a42Smrg if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0)) 8532c393a42Smrg goto bail0; 8542c393a42Smrg if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) 8552c393a42Smrg goto bail0; 8562c393a42Smrg } 8572c393a42Smrg for (l = _FcObjectTypes; l; l = l->next) 8582c393a42Smrg { 8592c393a42Smrg for (i = 0; i < l->ntypes; i++) 8602c393a42Smrg { 8612c393a42Smrg o = &l->types[i]; 8622c393a42Smrg if (!strcmp (o->object, FC_FAMILY) || 8632c393a42Smrg !strcmp (o->object, FC_SIZE) || 8642c393a42Smrg !strcmp (o->object, FC_FILE)) 8652c393a42Smrg continue; 8662c393a42Smrg 8672c393a42Smrg e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object)); 8682c393a42Smrg if (e) 8692c393a42Smrg { 8702c393a42Smrg if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0)) 8712c393a42Smrg goto bail0; 8722c393a42Smrg if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) 8732c393a42Smrg goto bail0; 8742c393a42Smrg if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0)) 8752c393a42Smrg goto bail0; 8762c393a42Smrg if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? 8772c393a42Smrg (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) 8782c393a42Smrg goto bail0; 8792c393a42Smrg } 8802c393a42Smrg } 8812c393a42Smrg } 8822c393a42Smrg return FcStrBufDone (&buf); 8832c393a42Smrgbail0: 8842c393a42Smrg FcStrBufDestroy (&buf); 8852c393a42Smrg return 0; 8862c393a42Smrg} 8872c393a42Smrg#define __fcname__ 8882c393a42Smrg#include "fcaliastail.h" 8892c393a42Smrg#undef __fcname__ 890