2 * fontconfig/src/fcname.c
4 * Copyright © 2000 Keith Packard
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of the author(s) not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. The authors make no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
16 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
31 static const FcObjectType FcObjects[] = {
32 #define FC_OBJECT(NAME, Type) { FC_##NAME, Type },
37 #define NUM_OBJECT_TYPES ((int) (sizeof FcObjects / sizeof FcObjects[0]))
39 static const FcObjectType *
40 FcObjectFindById (FcObject object)
42 if (1 <= object && object <= NUM_OBJECT_TYPES)
43 return &FcObjects[object - 1];
44 return FcObjectLookupOtherTypeById (object);
48 FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes)
55 FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
62 FcNameGetObjectType (const char *object)
64 int id = FcObjectLookupBuiltinIdByName (object);
67 return FcObjectLookupOtherTypeByName (object);
69 return &FcObjects[id - 1];
73 FcObjectValidType (FcObject object, FcType type)
75 const FcObjectType *t = FcObjectFindById (object);
78 switch ((int) t->type) {
81 if (type == FcTypeDouble || type == FcTypeInteger)
85 if (type == FcTypeLangSet || type == FcTypeString)
89 if (t->type == (unsigned int) -1 || type == t->type)
99 FcObjectFromName (const char * name)
101 return FcObjectLookupIdByName (name);
105 FcObjectGetSet (void)
108 FcObjectSet *os = NULL;
111 os = FcObjectSetCreate ();
112 for (i = 0; i < NUM_OBJECT_TYPES; i++)
113 FcObjectSetAdd (os, FcObjects[i].object);
119 FcObjectName (FcObject object)
121 const FcObjectType *o = FcObjectFindById (object);
126 return FcObjectLookupOtherNameById (object);
129 static const FcConstant _FcBaseConstants[] = {
130 { (FcChar8 *) "thin", "weight", FC_WEIGHT_THIN, },
131 { (FcChar8 *) "extralight", "weight", FC_WEIGHT_EXTRALIGHT, },
132 { (FcChar8 *) "ultralight", "weight", FC_WEIGHT_EXTRALIGHT, },
133 { (FcChar8 *) "light", "weight", FC_WEIGHT_LIGHT, },
134 { (FcChar8 *) "book", "weight", FC_WEIGHT_BOOK, },
135 { (FcChar8 *) "regular", "weight", FC_WEIGHT_REGULAR, },
136 { (FcChar8 *) "medium", "weight", FC_WEIGHT_MEDIUM, },
137 { (FcChar8 *) "demibold", "weight", FC_WEIGHT_DEMIBOLD, },
138 { (FcChar8 *) "semibold", "weight", FC_WEIGHT_DEMIBOLD, },
139 { (FcChar8 *) "bold", "weight", FC_WEIGHT_BOLD, },
140 { (FcChar8 *) "extrabold", "weight", FC_WEIGHT_EXTRABOLD, },
141 { (FcChar8 *) "ultrabold", "weight", FC_WEIGHT_EXTRABOLD, },
142 { (FcChar8 *) "black", "weight", FC_WEIGHT_BLACK, },
143 { (FcChar8 *) "heavy", "weight", FC_WEIGHT_HEAVY, },
145 { (FcChar8 *) "roman", "slant", FC_SLANT_ROMAN, },
146 { (FcChar8 *) "italic", "slant", FC_SLANT_ITALIC, },
147 { (FcChar8 *) "oblique", "slant", FC_SLANT_OBLIQUE, },
149 { (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED },
150 { (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED },
151 { (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED },
152 { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED },
153 { (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL },
154 { (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED },
155 { (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED },
156 { (FcChar8 *) "extraexpanded", "width", FC_WIDTH_EXTRAEXPANDED },
157 { (FcChar8 *) "ultraexpanded", "width", FC_WIDTH_ULTRAEXPANDED },
159 { (FcChar8 *) "proportional", "spacing", FC_PROPORTIONAL, },
160 { (FcChar8 *) "dual", "spacing", FC_DUAL, },
161 { (FcChar8 *) "mono", "spacing", FC_MONO, },
162 { (FcChar8 *) "charcell", "spacing", FC_CHARCELL, },
164 { (FcChar8 *) "unknown", "rgba", FC_RGBA_UNKNOWN },
165 { (FcChar8 *) "rgb", "rgba", FC_RGBA_RGB, },
166 { (FcChar8 *) "bgr", "rgba", FC_RGBA_BGR, },
167 { (FcChar8 *) "vrgb", "rgba", FC_RGBA_VRGB },
168 { (FcChar8 *) "vbgr", "rgba", FC_RGBA_VBGR },
169 { (FcChar8 *) "none", "rgba", FC_RGBA_NONE },
171 { (FcChar8 *) "hintnone", "hintstyle", FC_HINT_NONE },
172 { (FcChar8 *) "hintslight", "hintstyle", FC_HINT_SLIGHT },
173 { (FcChar8 *) "hintmedium", "hintstyle", FC_HINT_MEDIUM },
174 { (FcChar8 *) "hintfull", "hintstyle", FC_HINT_FULL },
176 { (FcChar8 *) "antialias", "antialias", FcTrue },
177 { (FcChar8 *) "hinting", "hinting", FcTrue },
178 { (FcChar8 *) "verticallayout", "verticallayout", FcTrue },
179 { (FcChar8 *) "autohint", "autohint", FcTrue },
180 { (FcChar8 *) "globaladvance", "globaladvance", FcTrue }, /* deprecated */
181 { (FcChar8 *) "outline", "outline", FcTrue },
182 { (FcChar8 *) "scalable", "scalable", FcTrue },
183 { (FcChar8 *) "minspace", "minspace", FcTrue },
184 { (FcChar8 *) "embolden", "embolden", FcTrue },
185 { (FcChar8 *) "embeddedbitmap", "embeddedbitmap", FcTrue },
186 { (FcChar8 *) "decorative", "decorative", FcTrue },
187 { (FcChar8 *) "lcdnone", "lcdfilter", FC_LCD_NONE },
188 { (FcChar8 *) "lcddefault", "lcdfilter", FC_LCD_DEFAULT },
189 { (FcChar8 *) "lcdlight", "lcdfilter", FC_LCD_LIGHT },
190 { (FcChar8 *) "lcdlegacy", "lcdfilter", FC_LCD_LEGACY },
193 #define NUM_FC_CONSTANTS (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0])
196 FcNameRegisterConstants (const FcConstant *consts, int nconsts)
203 FcNameUnregisterConstants (const FcConstant *consts, int nconsts)
210 FcNameGetConstant (const FcChar8 *string)
214 for (i = 0; i < NUM_FC_CONSTANTS; i++)
215 if (!FcStrCmpIgnoreCase (string, _FcBaseConstants[i].name))
216 return &_FcBaseConstants[i];
222 FcNameConstant (const FcChar8 *string, int *result)
226 if ((c = FcNameGetConstant(string)))
235 FcNameBool (const FcChar8 *v, FcBool *result)
241 if (c0 == 't' || c0 == 'y' || c0 == '1')
246 if (c0 == 'f' || c0 == 'n' || c0 == '0')
270 FcNameConvert (FcType type, FcChar8 *string)
276 switch ((int) v.type) {
278 if (!FcNameConstant (string, &v.u.i))
279 v.u.i = atoi ((char *) string);
282 v.u.s = FcSharedStr (string);
287 if (!FcNameBool (string, &v.u.b))
291 v.u.d = strtod ((char *) string, 0);
295 sscanf ((char *) string, "%lg %lg %lg %lg", &m.xx, &m.xy, &m.yx, &m.yy);
296 v.u.m = FcMatrixCopy (&m);
299 v.u.c = FcNameParseCharSet (string);
304 v.u.l = FcNameParseLangSet (string);
314 static const FcChar8 *
315 FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last)
327 else if (strchr (delim, c))
340 FcNameParse (const FcChar8 *name)
348 const FcObjectType *t;
352 save = malloc (strlen ((char *) name) + 1);
355 pat = FcPatternCreate ();
361 name = FcNameFindNext (name, "-,:", save, &delim);
364 if (!FcPatternAddString (pat, FC_FAMILY, save))
374 name = FcNameFindNext (name, "-,:", save, &delim);
375 d = strtod ((char *) save, (char **) &e);
378 if (!FcPatternAddDouble (pat, FC_SIZE, d))
387 name = FcNameFindNext (name, "=_:", save, &delim);
390 if (delim == '=' || delim == '_')
392 t = FcNameGetObjectType ((char *) save);
395 name = FcNameFindNext (name, ":,", save, &delim);
398 v = FcNameConvert (t->type, save);
399 if (!FcPatternAdd (pat, t->object, v, FcTrue))
412 if ((c = FcNameGetConstant (save)))
414 t = FcNameGetObjectType ((char *) c->object);
415 switch ((int) t->type) {
418 if (!FcPatternAddInteger (pat, c->object, c->value))
422 if (!FcPatternAddBool (pat, c->object, c->value))
437 FcPatternDestroy (pat);
444 FcNameUnparseString (FcStrBuf *buf,
445 const FcChar8 *string,
446 const FcChar8 *escape)
449 while ((c = *string++))
451 if (escape && strchr ((char *) escape, (char) c))
453 if (!FcStrBufChar (buf, escape[0]))
456 if (!FcStrBufChar (buf, c))
463 FcNameUnparseValue (FcStrBuf *buf,
468 FcValue v = FcValueCanonicalize(v0);
474 sprintf ((char *) temp, "%d", v.u.i);
475 return FcNameUnparseString (buf, temp, 0);
477 sprintf ((char *) temp, "%g", v.u.d);
478 return FcNameUnparseString (buf, temp, 0);
480 return FcNameUnparseString (buf, v.u.s, escape);
482 return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0);
484 sprintf ((char *) temp, "%g %g %g %g",
485 v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
486 return FcNameUnparseString (buf, temp, 0);
488 return FcNameUnparseCharSet (buf, v.u.c);
490 return FcNameUnparseLangSet (buf, v.u.l);
498 FcNameUnparseValueList (FcStrBuf *buf,
504 if (!FcNameUnparseValue (buf, &v->value, escape))
506 if ((v = FcValueListNext(v)) != NULL)
507 if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0))
513 #define FC_ESCAPE_FIXED "\\-:,"
514 #define FC_ESCAPE_VARIABLE "\\=_:,"
517 FcNameUnparse (FcPattern *pat)
519 return FcNameUnparseEscaped (pat, FcTrue);
523 FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
526 FcChar8 buf_static[8192];
530 FcStrBufInit (&buf, buf_static, sizeof (buf_static));
531 e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT);
534 if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
537 e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT);
540 if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0))
542 if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
545 for (i = 0; i < NUM_OBJECT_TYPES; i++)
548 const FcObjectType *o;
550 if (!strcmp (o->object, FC_FAMILY) ||
551 !strcmp (o->object, FC_SIZE))
554 e = FcPatternObjectFindElt (pat, id);
557 if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0))
559 if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0))
561 if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0))
563 if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ?
564 (FcChar8 *) FC_ESCAPE_VARIABLE : 0))
568 return FcStrBufDone (&buf);
570 FcStrBufDestroy (&buf);
574 #include "fcaliastail.h"