upload tizen2.0 source
[framework/uifw/xorg/lib/libxft.git] / src / xftxlfd.c
1 /*
2  * Copyright © 2000 Keith Packard
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of Keith Packard not be used in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific, written prior permission.  Keith Packard makes no
11  * representations about the suitability of this software for any purpose.  It
12  * is provided "as is" without express or implied warranty.
13  *
14  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #include "xftint.h"
24
25 static XftSymbolic XftXlfdWeights[] = {
26     {   "light",    FC_WEIGHT_LIGHT     },
27     {   "medium",   FC_WEIGHT_MEDIUM    },
28     {   "regular",  FC_WEIGHT_MEDIUM    },
29     {   "demibold", FC_WEIGHT_DEMIBOLD },
30     {   "bold",     FC_WEIGHT_BOLD      },
31     {   "black",    FC_WEIGHT_BLACK     },
32 };
33
34 #define NUM_XLFD_WEIGHTS    (sizeof XftXlfdWeights/sizeof XftXlfdWeights[0])
35
36 static XftSymbolic XftXlfdSlants[] = {
37     {   "r",        FC_SLANT_ROMAN      },
38     {   "i",        FC_SLANT_ITALIC     },
39     {   "o",        FC_SLANT_OBLIQUE    },
40 };
41
42 #define NUM_XLFD_SLANTS    (sizeof XftXlfdSlants/sizeof XftXlfdSlants[0])
43
44 /*
45  * Cut out one XLFD field, placing it in 'save' and return
46  * the start of 'save'
47  */
48 static char *
49 XftSplitStr (const char *field, char *save)
50 {
51     char    *s = save;
52     char    c;
53
54     while (*field)
55     {
56         if (*field == '-')
57             break;
58         c = *field++;
59         *save++ = c;
60     }
61     *save = 0;
62     return s;
63 }
64
65 /*
66  * convert one XLFD numeric field.  Return -1 if the field is '*'
67  */
68
69 static const char *
70 XftGetInt(const char *ptr, int *val)
71 {
72     if (*ptr == '*') {
73         *val = -1;
74         ptr++;
75     } else
76         for (*val = 0; *ptr >= '0' && *ptr <= '9';)
77             *val = *val * 10 + *ptr++ - '0';
78     if (*ptr == '-')
79         return ptr;
80     return (char *) 0;
81 }
82
83 _X_EXPORT FcPattern *
84 XftXlfdParse (const char *xlfd_orig, FcBool ignore_scalable, FcBool complete)
85 {
86     FcPattern   *pat;
87     const char  *xlfd = xlfd_orig;
88     const char  *foundry;
89     const char  *family;
90     const char  *weight_name;
91     const char  *slant;
92     const char  *registry;
93     const char  *encoding;
94     char        *save;
95     int         pixel;
96     int         point;
97     int         resx;
98     int         resy;
99     int         slant_value, weight_value;
100     double      dpixel;
101
102     if (*xlfd != '-')
103         return NULL;
104     if (!(xlfd = strchr (foundry = ++xlfd, '-'))) return NULL;
105     if (!(xlfd = strchr (family = ++xlfd, '-'))) return NULL;
106     if (!(xlfd = strchr (weight_name = ++xlfd, '-'))) return NULL;
107     if (!(xlfd = strchr (slant = ++xlfd, '-'))) return NULL;
108     if (!(xlfd = strchr (/* setwidth_name = */ ++xlfd, '-'))) return NULL;
109     if (!(xlfd = strchr (/* add_style_name = */ ++xlfd, '-'))) return NULL;
110     if (!(xlfd = XftGetInt (++xlfd, &pixel))) return NULL;
111     if (!(xlfd = XftGetInt (++xlfd, &point))) return NULL;
112     if (!(xlfd = XftGetInt (++xlfd, &resx))) return NULL;
113     if (!(xlfd = XftGetInt (++xlfd, &resy))) return NULL;
114     if (!(xlfd = strchr (/* spacing = */ ++xlfd, '-'))) return NULL;
115     if (!(xlfd = strchr (/* average_width = */ ++xlfd, '-'))) return NULL;
116     if (!(xlfd = strchr (registry = ++xlfd, '-'))) return NULL;
117     /* make sure no fields follow this one */
118     if ((xlfd = strchr (encoding = ++xlfd, '-'))) return NULL;
119
120     if (!pixel)
121         return NULL;
122
123     pat = FcPatternCreate ();
124     if (!pat)
125         return NULL;
126
127     save = (char *) malloc (strlen (foundry) + 1);
128
129     if (!save) {
130         FcPatternDestroy (pat);
131         return NULL;
132     }
133
134     if (!FcPatternAddString (pat, XFT_XLFD, (FcChar8 *) xlfd_orig)) goto bail;
135
136     XftSplitStr (foundry, save);
137     if (save[0] && strcmp (save, "*") != 0)
138         if (!FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) save)) goto bail;
139
140     XftSplitStr (family, save);
141     if (save[0] && strcmp (save, "*") != 0)
142         if (!FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) save)) goto bail;
143
144     weight_value = _XftMatchSymbolic (XftXlfdWeights, NUM_XLFD_WEIGHTS,
145                                       XftSplitStr (weight_name, save),
146                                       FC_WEIGHT_MEDIUM);
147     if (!FcPatternAddInteger (pat, FC_WEIGHT, weight_value))
148         goto bail;
149
150     slant_value = _XftMatchSymbolic (XftXlfdSlants, NUM_XLFD_SLANTS,
151                                      XftSplitStr (slant, save),
152                                      FC_SLANT_ROMAN);
153     if (!FcPatternAddInteger (pat, FC_SLANT, slant_value))
154         goto bail;
155
156     dpixel = (double) pixel;
157
158     if (point > 0)
159     {
160         if (!FcPatternAddDouble (pat, FC_SIZE, ((double) point) / 10.0)) goto bail;
161         if (pixel <= 0 && resy > 0)
162         {
163             dpixel = (double) point * (double) resy / 720.0;
164         }
165     }
166
167     if (dpixel > 0)
168         if (!FcPatternAddDouble (pat, FC_PIXEL_SIZE, dpixel)) goto bail;
169
170     free (save);
171     return pat;
172
173 bail:
174     free (save);
175     FcPatternDestroy (pat);
176     return NULL;
177 }