fcname.c revision a6844aab
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 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 * 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 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 330a6844aabSmrgFcObjectSet * 331a6844aabSmrgFcObjectGetSet (void) 332a6844aabSmrg{ 333a6844aabSmrg int i; 334a6844aabSmrg FcObjectSet *os = NULL; 335a6844aabSmrg 336a6844aabSmrg 337a6844aabSmrg os = FcObjectSetCreate (); 338a6844aabSmrg for (i = 0; i < FcObjectsNumber; i++) 339a6844aabSmrg FcObjectSetAdd (os, FcObjects[i].object); 340a6844aabSmrg 341a6844aabSmrg return os; 342a6844aabSmrg} 343a6844aabSmrg 3442c393a42SmrgFcBool 3452c393a42SmrgFcObjectInit (void) 3462c393a42Smrg{ 3472c393a42Smrg int i; 3482c393a42Smrg 3492c393a42Smrg if (FcObjectsInited) 3502c393a42Smrg return FcTrue; 3512c393a42Smrg 3522c393a42Smrg FcObjectsInited = FcTrue; 3532c393a42Smrg for (i = 0; i < NUM_OBJECT_TYPES; i++) 3542c393a42Smrg if (!FcObjectHashInsert (&_FcBaseObjectTypes[i], FcFalse)) 3552c393a42Smrg return FcFalse; 3562c393a42Smrg return FcTrue; 3572c393a42Smrg} 3582c393a42Smrg 3592c393a42Smrgvoid 3602c393a42SmrgFcObjectFini (void) 3612c393a42Smrg{ 3622c393a42Smrg int i; 3632c393a42Smrg FcObjectBucket *b, *next; 3642c393a42Smrg 3652c393a42Smrg for (i = 0; i < OBJECT_HASH_SIZE; i++) 3662c393a42Smrg { 3672c393a42Smrg for (b = FcObjectBuckets[i]; b; b = next) 3682c393a42Smrg { 3692c393a42Smrg next = b->next; 3702c393a42Smrg free (b); 3712c393a42Smrg } 3722c393a42Smrg FcObjectBuckets[i] = 0; 3732c393a42Smrg } 3742c393a42Smrg for (i = 0; i < FcObjectsNumber; i++) 3752c393a42Smrg if (FcObjects[i].type == -1) 3762c393a42Smrg free ((void*) FcObjects[i].object); 3772c393a42Smrg if (FcObjects != _FcBaseObjectTypes) 3782c393a42Smrg free (FcObjects); 3792c393a42Smrg FcObjects = (FcObjectType *) _FcBaseObjectTypes; 3802c393a42Smrg FcObjectsNumber = NUM_OBJECT_TYPES; 3812c393a42Smrg FcObjectsSize = 0; 3822c393a42Smrg FcObjectsInited = FcFalse; 3832c393a42Smrg} 3842c393a42Smrg 3852c393a42Smrgconst char * 3862c393a42SmrgFcObjectName (FcObject object) 3872c393a42Smrg{ 3882c393a42Smrg FcObjectType *o = FcObjectFindById (object); 3892c393a42Smrg 3902c393a42Smrg if (o) 3912c393a42Smrg return o->object; 3922c393a42Smrg return NULL; 3932c393a42Smrg} 3942c393a42Smrg 3952c393a42Smrgstatic const FcConstant _FcBaseConstants[] = { 3962c393a42Smrg { (FcChar8 *) "thin", "weight", FC_WEIGHT_THIN, }, 3972c393a42Smrg { (FcChar8 *) "extralight", "weight", FC_WEIGHT_EXTRALIGHT, }, 3982c393a42Smrg { (FcChar8 *) "ultralight", "weight", FC_WEIGHT_EXTRALIGHT, }, 3992c393a42Smrg { (FcChar8 *) "light", "weight", FC_WEIGHT_LIGHT, }, 4002c393a42Smrg { (FcChar8 *) "book", "weight", FC_WEIGHT_BOOK, }, 4012c393a42Smrg { (FcChar8 *) "regular", "weight", FC_WEIGHT_REGULAR, }, 4022c393a42Smrg { (FcChar8 *) "medium", "weight", FC_WEIGHT_MEDIUM, }, 4032c393a42Smrg { (FcChar8 *) "demibold", "weight", FC_WEIGHT_DEMIBOLD, }, 4042c393a42Smrg { (FcChar8 *) "semibold", "weight", FC_WEIGHT_DEMIBOLD, }, 4052c393a42Smrg { (FcChar8 *) "bold", "weight", FC_WEIGHT_BOLD, }, 4062c393a42Smrg { (FcChar8 *) "extrabold", "weight", FC_WEIGHT_EXTRABOLD, }, 4072c393a42Smrg { (FcChar8 *) "ultrabold", "weight", FC_WEIGHT_EXTRABOLD, }, 4082c393a42Smrg { (FcChar8 *) "black", "weight", FC_WEIGHT_BLACK, }, 4092c393a42Smrg { (FcChar8 *) "heavy", "weight", FC_WEIGHT_HEAVY, }, 4102c393a42Smrg 4112c393a42Smrg { (FcChar8 *) "roman", "slant", FC_SLANT_ROMAN, }, 4122c393a42Smrg { (FcChar8 *) "italic", "slant", FC_SLANT_ITALIC, }, 4132c393a42Smrg { (FcChar8 *) "oblique", "slant", FC_SLANT_OBLIQUE, }, 4142c393a42Smrg 4152c393a42Smrg { (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED }, 4162c393a42Smrg { (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED }, 4172c393a42Smrg { (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED }, 4182c393a42Smrg { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED }, 4192c393a42Smrg { (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL }, 4202c393a42Smrg { (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED }, 4212c393a42Smrg { (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED }, 4222c393a42Smrg { (FcChar8 *) "extraexpanded", "width", FC_WIDTH_EXTRAEXPANDED }, 4232c393a42Smrg { (FcChar8 *) "ultraexpanded", "width", FC_WIDTH_ULTRAEXPANDED }, 4242c393a42Smrg 4252c393a42Smrg { (FcChar8 *) "proportional", "spacing", FC_PROPORTIONAL, }, 4262c393a42Smrg { (FcChar8 *) "dual", "spacing", FC_DUAL, }, 4272c393a42Smrg { (FcChar8 *) "mono", "spacing", FC_MONO, }, 4282c393a42Smrg { (FcChar8 *) "charcell", "spacing", FC_CHARCELL, }, 4292c393a42Smrg 4302c393a42Smrg { (FcChar8 *) "unknown", "rgba", FC_RGBA_UNKNOWN }, 4312c393a42Smrg { (FcChar8 *) "rgb", "rgba", FC_RGBA_RGB, }, 4322c393a42Smrg { (FcChar8 *) "bgr", "rgba", FC_RGBA_BGR, }, 4332c393a42Smrg { (FcChar8 *) "vrgb", "rgba", FC_RGBA_VRGB }, 4342c393a42Smrg { (FcChar8 *) "vbgr", "rgba", FC_RGBA_VBGR }, 4352c393a42Smrg { (FcChar8 *) "none", "rgba", FC_RGBA_NONE }, 4362c393a42Smrg 4372c393a42Smrg { (FcChar8 *) "hintnone", "hintstyle", FC_HINT_NONE }, 4382c393a42Smrg { (FcChar8 *) "hintslight", "hintstyle", FC_HINT_SLIGHT }, 4392c393a42Smrg { (FcChar8 *) "hintmedium", "hintstyle", FC_HINT_MEDIUM }, 4402c393a42Smrg { (FcChar8 *) "hintfull", "hintstyle", FC_HINT_FULL }, 4412c393a42Smrg 4422c393a42Smrg { (FcChar8 *) "antialias", "antialias", FcTrue }, 4432c393a42Smrg { (FcChar8 *) "hinting", "hinting", FcTrue }, 4442c393a42Smrg { (FcChar8 *) "verticallayout", "verticallayout", FcTrue }, 4452c393a42Smrg { (FcChar8 *) "autohint", "autohint", FcTrue }, 4462c393a42Smrg { (FcChar8 *) "globaladvance", "globaladvance", FcTrue }, 4472c393a42Smrg { (FcChar8 *) "outline", "outline", FcTrue }, 4482c393a42Smrg { (FcChar8 *) "scalable", "scalable", FcTrue }, 4492c393a42Smrg { (FcChar8 *) "minspace", "minspace", FcTrue }, 4502c393a42Smrg { (FcChar8 *) "embolden", "embolden", FcTrue }, 4512c393a42Smrg { (FcChar8 *) "embeddedbitmap", "embeddedbitmap", FcTrue }, 4522c393a42Smrg { (FcChar8 *) "decorative", "decorative", FcTrue }, 4532c393a42Smrg { (FcChar8 *) "lcdnone", "lcdfilter", FC_LCD_NONE }, 4542c393a42Smrg { (FcChar8 *) "lcddefault", "lcdfilter", FC_LCD_DEFAULT }, 4552c393a42Smrg { (FcChar8 *) "lcdlight", "lcdfilter", FC_LCD_LIGHT }, 4562c393a42Smrg { (FcChar8 *) "lcdlegacy", "lcdfilter", FC_LCD_LEGACY }, 4572c393a42Smrg}; 4582c393a42Smrg 4592c393a42Smrg#define NUM_FC_CONSTANTS (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0]) 4602c393a42Smrg 4612c393a42Smrgtypedef struct _FcConstantList FcConstantList; 4622c393a42Smrg 4632c393a42Smrgstruct _FcConstantList { 4642c393a42Smrg const FcConstantList *next; 4652c393a42Smrg const FcConstant *consts; 4662c393a42Smrg int nconsts; 4672c393a42Smrg}; 4682c393a42Smrg 4692c393a42Smrgstatic const FcConstantList _FcBaseConstantList = { 4702c393a42Smrg 0, 4712c393a42Smrg _FcBaseConstants, 4722c393a42Smrg NUM_FC_CONSTANTS 4732c393a42Smrg}; 4742c393a42Smrg 4752c393a42Smrgstatic const FcConstantList *_FcConstants = &_FcBaseConstantList; 4762c393a42Smrg 4772c393a42SmrgFcBool 4782c393a42SmrgFcNameRegisterConstants (const FcConstant *consts, int nconsts) 4792c393a42Smrg{ 4802c393a42Smrg FcConstantList *l; 4812c393a42Smrg 4822c393a42Smrg l = (FcConstantList *) malloc (sizeof (FcConstantList)); 4832c393a42Smrg if (!l) 4842c393a42Smrg return FcFalse; 4852c393a42Smrg FcMemAlloc (FC_MEM_CONSTANT, sizeof (FcConstantList)); 4862c393a42Smrg l->consts = consts; 4872c393a42Smrg l->nconsts = nconsts; 4882c393a42Smrg l->next = _FcConstants; 4892c393a42Smrg _FcConstants = l; 4902c393a42Smrg return FcTrue; 4912c393a42Smrg} 4922c393a42Smrg 4932c393a42SmrgFcBool 4942c393a42SmrgFcNameUnregisterConstants (const FcConstant *consts, int nconsts) 4952c393a42Smrg{ 4962c393a42Smrg const FcConstantList *l, **prev; 4972c393a42Smrg 4982c393a42Smrg for (prev = &_FcConstants; 4992c393a42Smrg (l = *prev); 5002c393a42Smrg prev = (const FcConstantList **) &(l->next)) 5012c393a42Smrg { 5022c393a42Smrg if (l->consts == consts && l->nconsts == nconsts) 5032c393a42Smrg { 5042c393a42Smrg *prev = l->next; 5052c393a42Smrg FcMemFree (FC_MEM_CONSTANT, sizeof (FcConstantList)); 5062c393a42Smrg free ((void *) l); 5072c393a42Smrg return FcTrue; 5082c393a42Smrg } 5092c393a42Smrg } 5102c393a42Smrg return FcFalse; 5112c393a42Smrg} 5122c393a42Smrg 5132c393a42Smrgconst FcConstant * 5142c393a42SmrgFcNameGetConstant (FcChar8 *string) 5152c393a42Smrg{ 5162c393a42Smrg const FcConstantList *l; 5172c393a42Smrg int i; 5182c393a42Smrg 5192c393a42Smrg for (l = _FcConstants; l; l = l->next) 5202c393a42Smrg { 5212c393a42Smrg for (i = 0; i < l->nconsts; i++) 5222c393a42Smrg if (!FcStrCmpIgnoreCase (string, l->consts[i].name)) 5232c393a42Smrg return &l->consts[i]; 5242c393a42Smrg } 5252c393a42Smrg return 0; 5262c393a42Smrg} 5272c393a42Smrg 5282c393a42SmrgFcBool 5292c393a42SmrgFcNameConstant (FcChar8 *string, int *result) 5302c393a42Smrg{ 5312c393a42Smrg const FcConstant *c; 5322c393a42Smrg 5332c393a42Smrg if ((c = FcNameGetConstant(string))) 5342c393a42Smrg { 5352c393a42Smrg *result = c->value; 5362c393a42Smrg return FcTrue; 5372c393a42Smrg } 5382c393a42Smrg return FcFalse; 5392c393a42Smrg} 5402c393a42Smrg 5412c393a42SmrgFcBool 5422c393a42SmrgFcNameBool (const FcChar8 *v, FcBool *result) 5432c393a42Smrg{ 5442c393a42Smrg char c0, c1; 5452c393a42Smrg 5462c393a42Smrg c0 = *v; 5472c393a42Smrg c0 = FcToLower (c0); 5482c393a42Smrg if (c0 == 't' || c0 == 'y' || c0 == '1') 5492c393a42Smrg { 5502c393a42Smrg *result = FcTrue; 5512c393a42Smrg return FcTrue; 5522c393a42Smrg } 5532c393a42Smrg if (c0 == 'f' || c0 == 'n' || c0 == '0') 5542c393a42Smrg { 5552c393a42Smrg *result = FcFalse; 5562c393a42Smrg return FcTrue; 5572c393a42Smrg } 5582c393a42Smrg if (c0 == 'o') 5592c393a42Smrg { 5602c393a42Smrg c1 = v[1]; 5612c393a42Smrg c1 = FcToLower (c1); 5622c393a42Smrg if (c1 == 'n') 5632c393a42Smrg { 5642c393a42Smrg *result = FcTrue; 5652c393a42Smrg return FcTrue; 5662c393a42Smrg } 5672c393a42Smrg if (c1 == 'f') 5682c393a42Smrg { 5692c393a42Smrg *result = FcFalse; 5702c393a42Smrg return FcTrue; 5712c393a42Smrg } 5722c393a42Smrg } 5732c393a42Smrg return FcFalse; 5742c393a42Smrg} 5752c393a42Smrg 5762c393a42Smrgstatic FcValue 5772c393a42SmrgFcNameConvert (FcType type, FcChar8 *string, FcMatrix *m) 5782c393a42Smrg{ 5792c393a42Smrg FcValue v; 5802c393a42Smrg 5812c393a42Smrg v.type = type; 5822c393a42Smrg switch (v.type) { 5832c393a42Smrg case FcTypeInteger: 5842c393a42Smrg if (!FcNameConstant (string, &v.u.i)) 5852c393a42Smrg v.u.i = atoi ((char *) string); 5862c393a42Smrg break; 5872c393a42Smrg case FcTypeString: 5882c393a42Smrg v.u.s = FcStrStaticName(string); 5892c393a42Smrg if (!v.u.s) 5902c393a42Smrg v.type = FcTypeVoid; 5912c393a42Smrg break; 5922c393a42Smrg case FcTypeBool: 5932c393a42Smrg if (!FcNameBool (string, &v.u.b)) 5942c393a42Smrg v.u.b = FcFalse; 5952c393a42Smrg break; 5962c393a42Smrg case FcTypeDouble: 5972c393a42Smrg v.u.d = strtod ((char *) string, 0); 5982c393a42Smrg break; 5992c393a42Smrg case FcTypeMatrix: 6002c393a42Smrg v.u.m = m; 6012c393a42Smrg sscanf ((char *) string, "%lg %lg %lg %lg", &m->xx, &m->xy, &m->yx, &m->yy); 6022c393a42Smrg break; 6032c393a42Smrg case FcTypeCharSet: 6042c393a42Smrg v.u.c = FcNameParseCharSet (string); 6052c393a42Smrg if (!v.u.c) 6062c393a42Smrg v.type = FcTypeVoid; 6072c393a42Smrg break; 6082c393a42Smrg case FcTypeLangSet: 6092c393a42Smrg v.u.l = FcNameParseLangSet (string); 6102c393a42Smrg if (!v.u.l) 6112c393a42Smrg v.type = FcTypeVoid; 6122c393a42Smrg break; 6132c393a42Smrg default: 6142c393a42Smrg break; 6152c393a42Smrg } 6162c393a42Smrg return v; 6172c393a42Smrg} 6182c393a42Smrg 6192c393a42Smrgstatic const FcChar8 * 6202c393a42SmrgFcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last) 6212c393a42Smrg{ 6222c393a42Smrg FcChar8 c; 6232c393a42Smrg 6242c393a42Smrg while ((c = *cur)) 6252c393a42Smrg { 6262c393a42Smrg if (c == '\\') 6272c393a42Smrg { 6282c393a42Smrg ++cur; 6292c393a42Smrg if (!(c = *cur)) 6302c393a42Smrg break; 6312c393a42Smrg } 6322c393a42Smrg else if (strchr (delim, c)) 6332c393a42Smrg break; 6342c393a42Smrg ++cur; 6352c393a42Smrg *save++ = c; 6362c393a42Smrg } 6372c393a42Smrg *save = 0; 6382c393a42Smrg *last = *cur; 6392c393a42Smrg if (*cur) 6402c393a42Smrg cur++; 6412c393a42Smrg return cur; 6422c393a42Smrg} 6432c393a42Smrg 6442c393a42SmrgFcPattern * 6452c393a42SmrgFcNameParse (const FcChar8 *name) 6462c393a42Smrg{ 6472c393a42Smrg FcChar8 *save; 6482c393a42Smrg FcPattern *pat; 6492c393a42Smrg double d; 6502c393a42Smrg FcChar8 *e; 6512c393a42Smrg FcChar8 delim; 6522c393a42Smrg FcValue v; 6532c393a42Smrg FcMatrix m; 6542c393a42Smrg const FcObjectType *t; 6552c393a42Smrg const FcConstant *c; 6562c393a42Smrg 6572c393a42Smrg /* freed below */ 6582c393a42Smrg save = malloc (strlen ((char *) name) + 1); 6592c393a42Smrg if (!save) 6602c393a42Smrg goto bail0; 6612c393a42Smrg pat = FcPatternCreate (); 6622c393a42Smrg if (!pat) 6632c393a42Smrg goto bail1; 6642c393a42Smrg 6652c393a42Smrg for (;;) 6662c393a42Smrg { 6672c393a42Smrg name = FcNameFindNext (name, "-,:", save, &delim); 6682c393a42Smrg if (save[0]) 6692c393a42Smrg { 6702c393a42Smrg if (!FcPatternAddString (pat, FC_FAMILY, save)) 6712c393a42Smrg goto bail2; 6722c393a42Smrg } 6732c393a42Smrg if (delim != ',') 6742c393a42Smrg break; 6752c393a42Smrg } 6762c393a42Smrg if (delim == '-') 6772c393a42Smrg { 6782c393a42Smrg for (;;) 6792c393a42Smrg { 6802c393a42Smrg name = FcNameFindNext (name, "-,:", save, &delim); 6812c393a42Smrg d = strtod ((char *) save, (char **) &e); 6822c393a42Smrg if (e != save) 6832c393a42Smrg { 6842c393a42Smrg if (!FcPatternAddDouble (pat, FC_SIZE, d)) 6852c393a42Smrg goto bail2; 6862c393a42Smrg } 6872c393a42Smrg if (delim != ',') 6882c393a42Smrg break; 6892c393a42Smrg } 6902c393a42Smrg } 6912c393a42Smrg while (delim == ':') 6922c393a42Smrg { 6932c393a42Smrg name = FcNameFindNext (name, "=_:", save, &delim); 6942c393a42Smrg if (save[0]) 6952c393a42Smrg { 6962c393a42Smrg if (delim == '=' || delim == '_') 6972c393a42Smrg { 6982c393a42Smrg t = FcNameGetObjectType ((char *) save); 6992c393a42Smrg for (;;) 7002c393a42Smrg { 7012c393a42Smrg name = FcNameFindNext (name, ":,", save, &delim); 7022c393a42Smrg if (t) 7032c393a42Smrg { 7042c393a42Smrg v = FcNameConvert (t->type, save, &m); 7052c393a42Smrg if (!FcPatternAdd (pat, t->object, v, FcTrue)) 7062c393a42Smrg { 7072c393a42Smrg switch (v.type) { 7082c393a42Smrg case FcTypeCharSet: 7092c393a42Smrg FcCharSetDestroy ((FcCharSet *) v.u.c); 7102c393a42Smrg break; 7112c393a42Smrg case FcTypeLangSet: 7122c393a42Smrg FcLangSetDestroy ((FcLangSet *) v.u.l); 7132c393a42Smrg break; 7142c393a42Smrg default: 7152c393a42Smrg break; 7162c393a42Smrg } 7172c393a42Smrg goto bail2; 7182c393a42Smrg } 7192c393a42Smrg switch (v.type) { 7202c393a42Smrg case FcTypeCharSet: 7212c393a42Smrg FcCharSetDestroy ((FcCharSet *) v.u.c); 7222c393a42Smrg break; 7232c393a42Smrg case FcTypeLangSet: 7242c393a42Smrg FcLangSetDestroy ((FcLangSet *) v.u.l); 7252c393a42Smrg break; 7262c393a42Smrg default: 7272c393a42Smrg break; 7282c393a42Smrg } 7292c393a42Smrg } 7302c393a42Smrg if (delim != ',') 7312c393a42Smrg break; 7322c393a42Smrg } 7332c393a42Smrg } 7342c393a42Smrg else 7352c393a42Smrg { 7362c393a42Smrg if ((c = FcNameGetConstant (save))) 7372c393a42Smrg { 7382c393a42Smrg t = FcNameGetObjectType ((char *) c->object); 7392c393a42Smrg switch (t->type) { 7402c393a42Smrg case FcTypeInteger: 7412c393a42Smrg case FcTypeDouble: 7422c393a42Smrg if (!FcPatternAddInteger (pat, c->object, c->value)) 7432c393a42Smrg goto bail2; 7442c393a42Smrg break; 7452c393a42Smrg case FcTypeBool: 7462c393a42Smrg if (!FcPatternAddBool (pat, c->object, c->value)) 7472c393a42Smrg goto bail2; 7482c393a42Smrg break; 7492c393a42Smrg default: 7502c393a42Smrg break; 7512c393a42Smrg } 7522c393a42Smrg } 7532c393a42Smrg } 7542c393a42Smrg } 7552c393a42Smrg } 7562c393a42Smrg 7572c393a42Smrg free (save); 7582c393a42Smrg return pat; 7592c393a42Smrg 7602c393a42Smrgbail2: 7612c393a42Smrg FcPatternDestroy (pat); 7622c393a42Smrgbail1: 7632c393a42Smrg free (save); 7642c393a42Smrgbail0: 7652c393a42Smrg return 0; 7662c393a42Smrg} 7672c393a42Smrgstatic FcBool 7682c393a42SmrgFcNameUnparseString (FcStrBuf *buf, 7692c393a42Smrg const FcChar8 *string, 7702c393a42Smrg const FcChar8 *escape) 7712c393a42Smrg{ 7722c393a42Smrg FcChar8 c; 7732c393a42Smrg while ((c = *string++)) 7742c393a42Smrg { 7752c393a42Smrg if (escape && strchr ((char *) escape, (char) c)) 7762c393a42Smrg { 7772c393a42Smrg if (!FcStrBufChar (buf, escape[0])) 7782c393a42Smrg return FcFalse; 7792c393a42Smrg } 7802c393a42Smrg if (!FcStrBufChar (buf, c)) 7812c393a42Smrg return FcFalse; 7822c393a42Smrg } 7832c393a42Smrg return FcTrue; 7842c393a42Smrg} 7852c393a42Smrg 786a6844aabSmrgFcBool 7872c393a42SmrgFcNameUnparseValue (FcStrBuf *buf, 7882c393a42Smrg FcValue *v0, 7892c393a42Smrg FcChar8 *escape) 7902c393a42Smrg{ 7912c393a42Smrg FcChar8 temp[1024]; 7922c393a42Smrg FcValue v = FcValueCanonicalize(v0); 7932c393a42Smrg 7942c393a42Smrg switch (v.type) { 7952c393a42Smrg case FcTypeVoid: 7962c393a42Smrg return FcTrue; 7972c393a42Smrg case FcTypeInteger: 7982c393a42Smrg sprintf ((char *) temp, "%d", v.u.i); 7992c393a42Smrg return FcNameUnparseString (buf, temp, 0); 8002c393a42Smrg case FcTypeDouble: 8012c393a42Smrg sprintf ((char *) temp, "%g", v.u.d); 8022c393a42Smrg return FcNameUnparseString (buf, temp, 0); 8032c393a42Smrg case FcTypeString: 8042c393a42Smrg return FcNameUnparseString (buf, v.u.s, escape); 8052c393a42Smrg case FcTypeBool: 8062c393a42Smrg return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0); 8072c393a42Smrg case FcTypeMatrix: 8082c393a42Smrg sprintf ((char *) temp, "%g %g %g %g", 8092c393a42Smrg v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); 8102c393a42Smrg return FcNameUnparseString (buf, temp, 0); 8112c393a42Smrg case FcTypeCharSet: 8122c393a42Smrg return FcNameUnparseCharSet (buf, v.u.c); 8132c393a42Smrg case FcTypeLangSet: 8142c393a42Smrg return FcNameUnparseLangSet (buf, v.u.l); 8152c393a42Smrg case FcTypeFTFace: 8162c393a42Smrg return FcTrue; 8172c393a42Smrg } 8182c393a42Smrg return FcFalse; 8192c393a42Smrg} 8202c393a42Smrg 821a6844aabSmrgFcBool 8222c393a42SmrgFcNameUnparseValueList (FcStrBuf *buf, 8232c393a42Smrg FcValueListPtr v, 8242c393a42Smrg FcChar8 *escape) 8252c393a42Smrg{ 8262c393a42Smrg while (v) 8272c393a42Smrg { 8282c393a42Smrg if (!FcNameUnparseValue (buf, &v->value, escape)) 8292c393a42Smrg return FcFalse; 8302c393a42Smrg if ((v = FcValueListNext(v)) != NULL) 8312c393a42Smrg if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0)) 8322c393a42Smrg return FcFalse; 8332c393a42Smrg } 8342c393a42Smrg return FcTrue; 8352c393a42Smrg} 8362c393a42Smrg 8372c393a42Smrg#define FC_ESCAPE_FIXED "\\-:," 8382c393a42Smrg#define FC_ESCAPE_VARIABLE "\\=_:," 8392c393a42Smrg 8402c393a42SmrgFcChar8 * 8412c393a42SmrgFcNameUnparse (FcPattern *pat) 8422c393a42Smrg{ 8432c393a42Smrg return FcNameUnparseEscaped (pat, FcTrue); 8442c393a42Smrg} 8452c393a42Smrg 8462c393a42SmrgFcChar8 * 8472c393a42SmrgFcNameUnparseEscaped (FcPattern *pat, FcBool escape) 8482c393a42Smrg{ 8492c393a42Smrg FcStrBuf buf; 8502c393a42Smrg FcChar8 buf_static[8192]; 8512c393a42Smrg int i; 8522c393a42Smrg FcPatternElt *e; 8532c393a42Smrg const FcObjectTypeList *l; 8542c393a42Smrg const FcObjectType *o; 8552c393a42Smrg 8562c393a42Smrg FcStrBufInit (&buf, buf_static, sizeof (buf_static)); 8572c393a42Smrg e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT); 8582c393a42Smrg if (e) 8592c393a42Smrg { 8602c393a42Smrg if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) 8612c393a42Smrg goto bail0; 8622c393a42Smrg } 8632c393a42Smrg e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT); 8642c393a42Smrg if (e) 8652c393a42Smrg { 8662c393a42Smrg if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0)) 8672c393a42Smrg goto bail0; 8682c393a42Smrg if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) 8692c393a42Smrg goto bail0; 8702c393a42Smrg } 8712c393a42Smrg for (l = _FcObjectTypes; l; l = l->next) 8722c393a42Smrg { 8732c393a42Smrg for (i = 0; i < l->ntypes; i++) 8742c393a42Smrg { 8752c393a42Smrg o = &l->types[i]; 8762c393a42Smrg if (!strcmp (o->object, FC_FAMILY) || 8772c393a42Smrg !strcmp (o->object, FC_SIZE) || 8782c393a42Smrg !strcmp (o->object, FC_FILE)) 8792c393a42Smrg continue; 8802c393a42Smrg 8812c393a42Smrg e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object)); 8822c393a42Smrg if (e) 8832c393a42Smrg { 8842c393a42Smrg if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0)) 8852c393a42Smrg goto bail0; 8862c393a42Smrg if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) 8872c393a42Smrg goto bail0; 8882c393a42Smrg if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0)) 8892c393a42Smrg goto bail0; 8902c393a42Smrg if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? 8912c393a42Smrg (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) 8922c393a42Smrg goto bail0; 8932c393a42Smrg } 8942c393a42Smrg } 8952c393a42Smrg } 8962c393a42Smrg return FcStrBufDone (&buf); 8972c393a42Smrgbail0: 8982c393a42Smrg FcStrBufDestroy (&buf); 8992c393a42Smrg return 0; 9002c393a42Smrg} 9012c393a42Smrg#define __fcname__ 9022c393a42Smrg#include "fcaliastail.h" 9032c393a42Smrg#undef __fcname__ 904