source: trunk/poppler/fontconfig-2.3.2-os2/src/fcname.c @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 16 years ago

First import

File size: 15.2 KB
Line 
1/*
2 * $RCSId: xc/lib/fontconfig/src/fcname.c,v 1.15 2002/09/26 00:17:28 keithp Exp $
3 *
4 * Copyright © 2000 Keith Packard
5 *
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 Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission.  Keith Packard makes no
13 * representations about the suitability of this software for any purpose.  It
14 * is provided "as is" without express or implied warranty.
15 *
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD 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.
23 */
24
25#include <ctype.h>
26#include <stdlib.h>
27#include <string.h>
28#include <stdio.h>
29#include "fcint.h"
30
31static const FcObjectType _FcBaseObjectTypes[] = {
32    { FC_FAMILY,        FcTypeString, },
33    { FC_FAMILYLANG,    FcTypeString, },
34    { FC_STYLE,         FcTypeString, },
35    { FC_STYLELANG,     FcTypeString, },
36    { FC_FULLNAME,      FcTypeString, },
37    { FC_FULLNAMELANG,  FcTypeString, },
38    { FC_SLANT,         FcTypeInteger, },
39    { FC_WEIGHT,        FcTypeInteger, },
40    { FC_WIDTH,         FcTypeInteger, },
41    { FC_SIZE,          FcTypeDouble, },
42    { FC_ASPECT,        FcTypeDouble, },
43    { FC_PIXEL_SIZE,    FcTypeDouble, },
44    { FC_SPACING,       FcTypeInteger, },
45    { FC_FOUNDRY,       FcTypeString, },
46/*    { FC_CORE,                FcTypeBool, }, */
47    { FC_ANTIALIAS,     FcTypeBool, },
48    { FC_HINT_STYLE,    FcTypeInteger, },
49    { FC_HINTING,       FcTypeBool, },
50    { FC_VERTICAL_LAYOUT,   FcTypeBool, },
51    { FC_AUTOHINT,      FcTypeBool, },
52    { FC_GLOBAL_ADVANCE,    FcTypeBool, },
53/*    { FC_XLFD,                FcTypeString, }, */
54    { FC_FILE,          FcTypeString, },
55    { FC_INDEX,         FcTypeInteger, },
56    { FC_RASTERIZER,    FcTypeString, },
57    { FC_OUTLINE,       FcTypeBool, },
58    { FC_SCALABLE,      FcTypeBool, },
59    { FC_DPI,           FcTypeDouble },
60    { FC_RGBA,          FcTypeInteger, },
61    { FC_SCALE,         FcTypeDouble, },
62/*    { FC_RENDER,      FcTypeBool, },*/
63    { FC_MINSPACE,      FcTypeBool, },
64    { FC_CHAR_WIDTH,    FcTypeInteger },
65    { FC_CHAR_HEIGHT,   FcTypeInteger },
66    { FC_MATRIX,        FcTypeMatrix },
67    { FC_CHARSET,       FcTypeCharSet },
68    { FC_LANG,          FcTypeLangSet },
69    { FC_FONTVERSION,   FcTypeInteger },
70    { FC_CAPABILITY,    FcTypeString },
71    { FC_FONTFORMAT,    FcTypeString },
72    { FC_EMBOLDEN,      FcTypeBool },
73};
74
75#define NUM_OBJECT_TYPES    (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0])
76
77typedef struct _FcObjectTypeList    FcObjectTypeList;
78
79struct _FcObjectTypeList {
80    const FcObjectTypeList  *next;
81    const FcObjectType      *types;
82    int                     ntypes;
83};
84
85static const FcObjectTypeList _FcBaseObjectTypesList = {
86    0,
87    _FcBaseObjectTypes,
88    NUM_OBJECT_TYPES
89};
90
91static const FcObjectTypeList   *_FcObjectTypes = &_FcBaseObjectTypesList;
92
93FcBool
94FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes)
95{
96    FcObjectTypeList    *l;
97
98    l = (FcObjectTypeList *) malloc (sizeof (FcObjectTypeList));
99    if (!l)
100        return FcFalse;
101    FcMemAlloc (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList));
102    l->types = types;
103    l->ntypes = ntypes;
104    l->next = _FcObjectTypes;
105    _FcObjectTypes = l;
106    return FcTrue;
107}
108
109FcBool
110FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
111{
112    const FcObjectTypeList      *l, **prev;
113
114    for (prev = &_FcObjectTypes; 
115         (l = *prev); 
116         prev = (const FcObjectTypeList **) &(l->next))
117    {
118        if (l->types == types && l->ntypes == ntypes)
119        {
120            *prev = l->next;
121            FcMemFree (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList));
122            free ((void *) l);
123            return FcTrue;
124        }
125    }
126    return FcFalse;
127}
128
129const FcObjectType *
130FcNameGetObjectType (const char *object)
131{
132    int                     i;
133    const FcObjectTypeList  *l;
134    const FcObjectType      *t;
135   
136    for (l = _FcObjectTypes; l; l = l->next)
137    {
138        for (i = 0; i < l->ntypes; i++)
139        {
140            t = &l->types[i];
141            if (!strcmp (object, t->object))
142                return t;
143        }
144    }
145    return 0;
146}
147
148static const FcConstant _FcBaseConstants[] = {
149    { (FcChar8 *) "thin",           "weight",   FC_WEIGHT_THIN, },
150    { (FcChar8 *) "extralight",     "weight",   FC_WEIGHT_EXTRALIGHT, },
151    { (FcChar8 *) "ultralight",     "weight",   FC_WEIGHT_EXTRALIGHT, },
152    { (FcChar8 *) "light",          "weight",   FC_WEIGHT_LIGHT, },
153    { (FcChar8 *) "book",           "weight",   FC_WEIGHT_BOOK, },
154    { (FcChar8 *) "regular",        "weight",   FC_WEIGHT_REGULAR, },
155    { (FcChar8 *) "medium",         "weight",   FC_WEIGHT_MEDIUM, },
156    { (FcChar8 *) "demibold",       "weight",   FC_WEIGHT_DEMIBOLD, },
157    { (FcChar8 *) "semibold",       "weight",   FC_WEIGHT_DEMIBOLD, },
158    { (FcChar8 *) "bold",           "weight",   FC_WEIGHT_BOLD, },
159    { (FcChar8 *) "extrabold",      "weight",   FC_WEIGHT_EXTRABOLD, },
160    { (FcChar8 *) "ultrabold",      "weight",   FC_WEIGHT_EXTRABOLD, },
161    { (FcChar8 *) "black",          "weight",   FC_WEIGHT_BLACK, },
162
163    { (FcChar8 *) "roman",          "slant",    FC_SLANT_ROMAN, },
164    { (FcChar8 *) "italic",         "slant",    FC_SLANT_ITALIC, },
165    { (FcChar8 *) "oblique",        "slant",    FC_SLANT_OBLIQUE, },
166
167    { (FcChar8 *) "ultracondensed", "width",    FC_WIDTH_ULTRACONDENSED },
168    { (FcChar8 *) "extracondensed", "width",    FC_WIDTH_EXTRACONDENSED },
169    { (FcChar8 *) "condensed",      "width",    FC_WIDTH_CONDENSED },
170    { (FcChar8 *) "semicondensed", "width",     FC_WIDTH_SEMICONDENSED },
171    { (FcChar8 *) "normal",         "width",    FC_WIDTH_NORMAL },
172    { (FcChar8 *) "semiexpanded",   "width",    FC_WIDTH_SEMIEXPANDED },
173    { (FcChar8 *) "expanded",       "width",    FC_WIDTH_EXPANDED },
174    { (FcChar8 *) "extraexpanded",  "width",    FC_WIDTH_EXTRAEXPANDED },
175    { (FcChar8 *) "ultraexpanded",  "width",    FC_WIDTH_ULTRAEXPANDED },
176   
177    { (FcChar8 *) "proportional",   "spacing",  FC_PROPORTIONAL, },
178    { (FcChar8 *) "dual",           "spacing",  FC_DUAL, },
179    { (FcChar8 *) "mono",           "spacing",  FC_MONO, },
180    { (FcChar8 *) "charcell",       "spacing",  FC_CHARCELL, },
181
182    { (FcChar8 *) "unknown",        "rgba",         FC_RGBA_UNKNOWN },
183    { (FcChar8 *) "rgb",            "rgba",         FC_RGBA_RGB, },
184    { (FcChar8 *) "bgr",            "rgba",         FC_RGBA_BGR, },
185    { (FcChar8 *) "vrgb",           "rgba",         FC_RGBA_VRGB },
186    { (FcChar8 *) "vbgr",           "rgba",         FC_RGBA_VBGR },
187    { (FcChar8 *) "none",           "rgba",         FC_RGBA_NONE },
188
189    { (FcChar8 *) "hintnone",       "hintstyle",   FC_HINT_NONE },
190    { (FcChar8 *) "hintslight",     "hintstyle",   FC_HINT_SLIGHT },
191    { (FcChar8 *) "hintmedium",     "hintstyle",   FC_HINT_MEDIUM },
192    { (FcChar8 *) "hintfull",       "hintstyle",   FC_HINT_FULL },
193};
194
195#define NUM_FC_CONSTANTS   (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0])
196
197typedef struct _FcConstantList FcConstantList;
198
199struct _FcConstantList {
200    const FcConstantList    *next;
201    const FcConstant        *consts;
202    int                     nconsts;
203};
204
205static const FcConstantList _FcBaseConstantList = {
206    0,
207    _FcBaseConstants,
208    NUM_FC_CONSTANTS
209};
210
211static const FcConstantList     *_FcConstants = &_FcBaseConstantList;
212
213FcBool
214FcNameRegisterConstants (const FcConstant *consts, int nconsts)
215{
216    FcConstantList      *l;
217
218    l = (FcConstantList *) malloc (sizeof (FcConstantList));
219    if (!l)
220        return FcFalse;
221    FcMemAlloc (FC_MEM_CONSTANT, sizeof (FcConstantList));
222    l->consts = consts;
223    l->nconsts = nconsts;
224    l->next = _FcConstants;
225    _FcConstants = l;
226    return FcTrue;
227}
228
229FcBool
230FcNameUnregisterConstants (const FcConstant *consts, int nconsts)
231{
232    const FcConstantList        *l, **prev;
233
234    for (prev = &_FcConstants; 
235         (l = *prev); 
236         prev = (const FcConstantList **) &(l->next))
237    {
238        if (l->consts == consts && l->nconsts == nconsts)
239        {
240            *prev = l->next;
241            FcMemFree (FC_MEM_CONSTANT, sizeof (FcConstantList));
242            free ((void *) l);
243            return FcTrue;
244        }
245    }
246    return FcFalse;
247}
248
249const FcConstant *
250FcNameGetConstant (FcChar8 *string)
251{
252    const FcConstantList    *l;
253    int                     i;
254
255    for (l = _FcConstants; l; l = l->next)
256    {
257        for (i = 0; i < l->nconsts; i++)
258            if (!FcStrCmpIgnoreCase (string, l->consts[i].name))
259                return &l->consts[i];
260    }
261    return 0;
262}
263
264FcBool
265FcNameConstant (FcChar8 *string, int *result)
266{
267    const FcConstant    *c;
268
269    if ((c = FcNameGetConstant(string)))
270    {
271        *result = c->value;
272        return FcTrue;
273    }
274    return FcFalse;
275}
276
277FcBool
278FcNameBool (const FcChar8 *v, FcBool *result)
279{
280    char    c0, c1;
281
282    c0 = *v;
283    c0 = FcToLower (c0);
284    if (c0 == 't' || c0 == 'y' || c0 == '1')
285    {
286        *result = FcTrue;
287        return FcTrue;
288    }
289    if (c0 == 'f' || c0 == 'n' || c0 == '0')
290    {
291        *result = FcFalse;
292        return FcTrue;
293    }
294    if (c0 == 'o')
295    {
296        c1 = v[1];
297        c1 = FcToLower (c1);
298        if (c1 == 'n')
299        {
300            *result = FcTrue;
301            return FcTrue;
302        }
303        if (c1 == 'f')
304        {
305            *result = FcFalse;
306            return FcTrue;
307        }
308    }
309    return FcFalse;
310}
311
312static FcValue
313FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m)
314{
315    FcValue     v;
316
317    v.type = type;
318    switch (v.type) {
319    case FcTypeInteger:
320        if (!FcNameConstant (string, &v.u.i))
321            v.u.i = atoi ((char *) string);
322        break;
323    case FcTypeString:
324        v.u.s = string;
325        break;
326    case FcTypeBool:
327        if (!FcNameBool (string, &v.u.b))
328            v.u.b = FcFalse;
329        break;
330    case FcTypeDouble:
331        v.u.d = strtod ((char *) string, 0);
332        break;
333    case FcTypeMatrix:
334        v.u.m = m;
335        sscanf ((char *) string, "%lg %lg %lg %lg", &m->xx, &m->xy, &m->yx, &m->yy);
336        break;
337    case FcTypeCharSet:
338        v.u.c = FcNameParseCharSet (string);
339        break;
340    case FcTypeLangSet:
341        v.u.l = FcNameParseLangSet (string);
342        break;
343    default:
344        break;
345    }
346    return v;
347}
348
349static const FcChar8 *
350FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last)
351{
352    FcChar8    c;
353   
354    while ((c = *cur))
355    {
356        if (c == '\\')
357        {
358            ++cur;
359            if (!(c = *cur))
360                break;
361        }
362        else if (strchr (delim, c))
363            break;
364        ++cur;
365        *save++ = c;
366    }
367    *save = 0;
368    *last = *cur;
369    if (*cur)
370        cur++;
371    return cur;
372}
373
374FcPattern *
375FcNameParse (const FcChar8 *name)
376{
377    FcChar8             *save;
378    FcPattern           *pat;
379    double              d;
380    FcChar8             *e;
381    FcChar8             delim;
382    FcValue             v;
383    FcMatrix            m;
384    const FcObjectType  *t;
385    const FcConstant    *c;
386
387    /* freed below */
388    save = malloc (strlen ((char *) name) + 1);
389    if (!save)
390        goto bail0;
391    pat = FcPatternCreate ();
392    if (!pat)
393        goto bail1;
394
395    for (;;)
396    {
397        name = FcNameFindNext (name, "-,:", save, &delim);
398        if (save[0])
399        {
400            if (!FcPatternAddString (pat, FC_FAMILY, save))
401                goto bail2;
402        }
403        if (delim != ',')
404            break;
405    }
406    if (delim == '-')
407    {
408        for (;;)
409        {
410            name = FcNameFindNext (name, "-,:", save, &delim);
411            d = strtod ((char *) save, (char **) &e);
412            if (e != save)
413            {
414                if (!FcPatternAddDouble (pat, FC_SIZE, d))
415                    goto bail2;
416            }
417            if (delim != ',')
418                break;
419        }
420    }
421    while (delim == ':')
422    {
423        name = FcNameFindNext (name, "=_:", save, &delim);
424        if (save[0])
425        {
426            if (delim == '=' || delim == '_')
427            {
428                t = FcNameGetObjectType ((char *) save);
429                for (;;)
430                {
431                    name = FcNameFindNext (name, ":,", save, &delim);
432                    if (t)
433                    {
434                        v = FcNameConvert (t->type, save, &m);
435                        if (!FcPatternAdd (pat, t->object, v, FcTrue))
436                        {
437                            switch (v.type) {
438                            case FcTypeCharSet:
439                                FcCharSetDestroy ((FcCharSet *) v.u.c);
440                                break;
441                            case FcTypeLangSet:
442                                FcLangSetDestroy ((FcLangSet *) v.u.l);
443                                break;
444                            default:
445                                break;
446                            }
447                            goto bail2;
448                        }
449                        switch (v.type) {
450                        case FcTypeCharSet:
451                            FcCharSetDestroy ((FcCharSet *) v.u.c);
452                            break;
453                        case FcTypeLangSet:
454                            FcLangSetDestroy ((FcLangSet *) v.u.l);
455                            break;
456                        default:
457                            break;
458                        }
459                    }
460                    if (delim != ',')
461                        break;
462                }
463            }
464            else
465            {
466                if ((c = FcNameGetConstant (save)))
467                {
468                    if (!FcPatternAddInteger (pat, c->object, c->value))
469                        goto bail2;
470                }
471            }
472        }
473    }
474
475    free (save);
476    return pat;
477
478bail2:
479    FcPatternDestroy (pat);
480bail1:
481    free (save);
482bail0:
483    return 0;
484}
485static FcBool
486FcNameUnparseString (FcStrBuf       *buf, 
487                     const FcChar8  *string,
488                     const FcChar8  *escape)
489{
490    FcChar8 c;
491    while ((c = *string++))
492    {
493        if (escape && strchr ((char *) escape, (char) c))
494        {
495            if (!FcStrBufChar (buf, escape[0]))
496                return FcFalse;
497        }
498        if (!FcStrBufChar (buf, c))
499            return FcFalse;
500    }
501    return FcTrue;
502}
503
504static FcBool
505FcNameUnparseValue (FcStrBuf    *buf,
506                    FcValue     v,
507                    FcChar8     *escape)
508{
509    FcChar8     temp[1024];
510   
511    switch (v.type) {
512    case FcTypeVoid:
513        return FcTrue;
514    case FcTypeInteger:
515        sprintf ((char *) temp, "%d", v.u.i);
516        return FcNameUnparseString (buf, temp, 0);
517    case FcTypeDouble:
518        sprintf ((char *) temp, "%g", v.u.d);
519        return FcNameUnparseString (buf, temp, 0);
520    case FcTypeString:
521        return FcNameUnparseString (buf, v.u.s, escape);
522    case FcTypeBool:
523        return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0);
524    case FcTypeMatrix:
525        sprintf ((char *) temp, "%g %g %g %g", 
526                 v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
527        return FcNameUnparseString (buf, temp, 0);
528    case FcTypeCharSet:
529        return FcNameUnparseCharSet (buf, v.u.c);
530    case FcTypeLangSet:
531        return FcNameUnparseLangSet (buf, v.u.l);
532    case FcTypeFTFace:
533        return FcTrue;
534    }
535    return FcFalse;
536}
537
538static FcBool
539FcNameUnparseValueList (FcStrBuf        *buf,
540                        FcValueList     *v,
541                        FcChar8         *escape)
542{
543    while (v)
544    {
545        if (!FcNameUnparseValue (buf, v->value, escape))
546            return FcFalse;
547        if ((v = v->next))
548            if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0))
549                return FcFalse;
550    }
551    return FcTrue;
552}
553
554#define FC_ESCAPE_FIXED    "\\-:,"
555#define FC_ESCAPE_VARIABLE "\\=_:,"
556
557FcChar8 *
558FcNameUnparse (FcPattern *pat)
559{
560    FcStrBuf                buf;
561    FcChar8                 buf_static[8192];
562    int                     i;
563    FcPatternElt            *e;
564    const FcObjectTypeList  *l;
565    const FcObjectType      *o;
566
567    FcStrBufInit (&buf, buf_static, sizeof (buf_static));
568    e = FcPatternFindElt (pat, FC_FAMILY);
569    if (e)
570    {
571        if (!FcNameUnparseValueList (&buf, e->values, (FcChar8 *) FC_ESCAPE_FIXED))
572            goto bail0;
573    }
574    e = FcPatternFindElt (pat, FC_SIZE);
575    if (e)
576    {
577        if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0))
578            goto bail0;
579        if (!FcNameUnparseValueList (&buf, e->values, (FcChar8 *) FC_ESCAPE_FIXED))
580            goto bail0;
581    }
582    for (l = _FcObjectTypes; l; l = l->next)
583    {
584        for (i = 0; i < l->ntypes; i++)
585        {
586            o = &l->types[i];
587            if (!strcmp (o->object, FC_FAMILY) || 
588                !strcmp (o->object, FC_SIZE) ||
589                !strcmp (o->object, FC_FILE))
590                continue;
591           
592            e = FcPatternFindElt (pat, o->object);
593            if (e)
594            {
595                if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0))
596                    goto bail0;
597                if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, (FcChar8 *) FC_ESCAPE_VARIABLE))
598                    goto bail0;
599                if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0))
600                    goto bail0;
601                if (!FcNameUnparseValueList (&buf, e->values, 
602                                             (FcChar8 *) FC_ESCAPE_VARIABLE))
603                    goto bail0;
604            }
605        }
606    }
607    return FcStrBufDone (&buf);
608bail0:
609    FcStrBufDestroy (&buf);
610    return 0;
611}
Note: See TracBrowser for help on using the repository browser.