Line data Source code
1 : /* Copyright (C) 2000-2012 by George Williams */
2 : /*
3 : * Redistribution and use in source and binary forms, with or without
4 : * modification, are permitted provided that the following conditions are met:
5 :
6 : * Redistributions of source code must retain the above copyright notice, this
7 : * list of conditions and the following disclaimer.
8 :
9 : * Redistributions in binary form must reproduce the above copyright notice,
10 : * this list of conditions and the following disclaimer in the documentation
11 : * and/or other materials provided with the distribution.
12 :
13 : * The name of the author may not be used to endorse or promote products
14 : * derived from this software without specific prior written permission.
15 :
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 : #include "fontP.h"
28 : #include "utype.h"
29 : #include "ustring.h"
30 :
31 : struct fontabbrev _gdraw_fontabbrev[] = {
32 : { "times", ft_serif, 0, 0, 0, 0, NULL },
33 : { "Helvetica", ft_sans, 0, 0, 0, 0, NULL },
34 : { "Courier", ft_mono, 0, 0, 0, 0, NULL },
35 :
36 : { "sans-serif", ft_sans, 0, 0, true, 0, NULL },
37 : { "serif", ft_serif, 0, 0, true, 0, NULL },
38 : { "cursive", ft_cursive, 0, 0, true, 0, NULL },
39 : { "monospace", ft_mono, 0, 0, true, 0, NULL },
40 : { "fantasy", ft_sans, 0, 0, true, 0, NULL },
41 :
42 : { "Albertus", ft_serif, 0, 0, 0, 0, NULL },
43 : { "Arial", ft_sans, 0, 0, 0, 0, NULL },
44 : { "Avant Garde", ft_sans, 0, 0, 0, 0, NULL },
45 : { "Bembo", ft_serif, 0, 0, 0, 0, NULL },
46 : { "Bodoni", ft_serif, 0, 0, 0, 0, NULL },
47 : { "Book Antiqua", ft_serif, 0, 0, 0, 0, NULL },
48 : { "Book Rounded", ft_serif, 0, 0, 0, 0, NULL },
49 : { "Bookman", ft_serif, 0, 0, 0, 0, NULL },
50 : { "Caslon", ft_serif, 0, 0, 0, 0, NULL },
51 : { "Century Sch", ft_serif, 0, 0, 0, 0, NULL }, /* New century Schoolbook */
52 : { "charter", ft_serif, 0, 0, 0, 0, NULL },
53 : { "Charcoal", ft_mono, 0, true, 0, 0, NULL },
54 : { "Cheltenham", ft_serif, 0, 0, 0, 0, NULL },
55 : { "ChelthmITC", ft_serif, 0, 0, 0, 0, NULL },
56 : { "Chicago", ft_mono, 0, true, 0, 0, NULL },
57 : { "Clarendon", ft_mono, 0, 0, 0, 0, NULL },
58 : { "Coronel", ft_cursive, 0, 0, 0, 0, NULL },
59 : { "Eurostyle", ft_sans, 0, 0, 0, 0, NULL },
60 : { "Fixed", ft_mono, 0, 0, 0, 0, NULL },
61 : { "Footlight", ft_serif, 0, 0, 0, 0, NULL },
62 : { "Futura", ft_sans, 0, 0, 0, 0, NULL },
63 : { "Galliard", ft_serif, 0, 0, 0, 0, NULL },
64 : { "Garamond", ft_serif, 0, 0, 0, 0, NULL },
65 : { "Geneva", ft_sans, 0, 0, 0, 0, NULL },
66 : { "Gill Sans", ft_sans, 0, 0, 0, 0, NULL },
67 : { "Gothic", ft_sans, 0, 0, 0, 0, NULL },
68 : { "Goudy", ft_serif, 0, 0, 0, 0, NULL },
69 : { "Grotesque", ft_serif, 0, 0, 0, 0, NULL },
70 : { "Impact Bold", ft_sans, 0, true, 0, 0, NULL },
71 : { "lucidatypewriter", ft_mono, 0, 0, 0, 0, NULL },
72 : { "lucidabright", ft_serif, 0, 0, 0, 0, NULL },
73 : { "lucida", ft_sans, 0, 0, 0, 0, NULL },
74 : { "Marigold", ft_cursive, 0, 0, 0, 0, NULL },
75 : { "Melior", ft_serif, 0, 0, 0, 0, NULL },
76 : { "Monaco", ft_mono, 0, 0, 0, 0, NULL },
77 : { "MS Linedraw", ft_serif, 0, 0, 0, 0, NULL },
78 : { "MS Sans Serif", ft_sans, 0, 0, 0, 0, NULL },
79 : { "MS Serif", ft_serif, 0, 0, 0, 0, NULL },
80 : { "New York", ft_serif, 0, 0, 0, 0, NULL },
81 : { "Omega", ft_sans, 0, 0, 0, 0, NULL },
82 : { "Optima", ft_sans, 0, 0, 0, 0, NULL },
83 : { "Palatino", ft_serif, 0, 0, 0, 0, NULL },
84 : { "Roman", ft_serif, 0, 0, 0, 0, NULL },
85 : { "script", ft_cursive, 0, 0, 0, 0, NULL },
86 : { "terminal", ft_mono, 0, 0, 0, 0, NULL },
87 : { "Univers", ft_sans, 0, 0, 0, 0, NULL },
88 : { "Wide Latin", ft_serif, 0, 0, 0, 0, NULL },
89 : { "Zapf Chancery", ft_cursive, 0, 0, 0, 0, NULL },
90 :
91 : FONTABBREV_EMPTY
92 : };
93 :
94 0 : int _GDraw_ClassifyFontName(unichar_t *fontname, int *italic, int *bold) {
95 : int i;
96 :
97 0 : *italic = *bold = 0;
98 :
99 0 : for ( i=0; _gdraw_fontabbrev[i].abbrev!=NULL; ++i )
100 0 : if ( uc_strstrmatch(fontname,_gdraw_fontabbrev[i].abbrev)!=NULL ) {
101 0 : *italic = _gdraw_fontabbrev[i].italic;
102 0 : *bold = _gdraw_fontabbrev[i].bold;
103 0 : return( _gdraw_fontabbrev[i].ft);
104 : }
105 0 : return( ft_unknown );
106 : }
107 :
108 0 : static int IsUserMap(unichar_t *setname) {
109 : extern unichar_t **usercharset_names;
110 : int i;
111 :
112 0 : if ( usercharset_names!=NULL ) {
113 0 : for ( i=0; usercharset_names[i]!=NULL; ++i )
114 0 : if ( u_strstrmatch(setname,usercharset_names[i])!=NULL )
115 0 : return( true );
116 : }
117 0 : return( false );
118 : }
119 :
120 0 : enum charset _GDraw_ParseMapping(unichar_t *setname) {
121 : unichar_t *pt;
122 : int val;
123 :
124 0 : if ( uc_strstrmatch(setname,"iso")!=NULL && uc_strstrmatch(setname,"10646")!=NULL )
125 0 : return( em_unicode );
126 0 : else if ( uc_strstrmatch(setname,"UnicodePlane")!=NULL ) {
127 0 : pt = u_strchr(setname,'-');
128 0 : if ( pt==NULL )
129 0 : return( em_uplane0+1 );
130 0 : return( em_uplane0+u_strtol(pt+1,NULL,10) );
131 0 : } else if ( uc_strstrmatch(setname,"unicode")!=NULL )
132 0 : return( em_unicode );
133 :
134 0 : if ( uc_strstrmatch(setname,"iso")!=NULL && uc_strstrmatch(setname,"8859")!=NULL ) {
135 0 : pt = uc_strstrmatch(setname,"8859");
136 0 : pt += 4;
137 0 : if ( *pt=='-' ) ++pt;
138 0 : if ( !isdigit(*pt) )
139 : /* Bad */;
140 0 : else if ( !isdigit(pt[1]) )
141 0 : return( em_iso8859_1+*pt-'1' );
142 : else {
143 0 : val = (pt[0]-'0')*10 + pt[1]-'0';
144 0 : switch ( val ) {
145 : case 10: case 11:
146 0 : return( em_iso8859_10+val-10 );
147 : case 13: case 14: case 15:
148 0 : return( em_iso8859_13+val-13 );
149 : }
150 : }
151 : }
152 :
153 0 : if ( uc_strstrmatch(setname,"latin10")!=NULL )
154 0 : return( em_iso8859_16 );
155 0 : if ( uc_strstrmatch(setname,"latin1")!=NULL )
156 0 : return( em_iso8859_1 );
157 0 : else if ( uc_strstrmatch(setname,"latin2")!=NULL )
158 0 : return( em_iso8859_2 );
159 0 : else if ( uc_strstrmatch(setname,"latin3")!=NULL )
160 0 : return( em_iso8859_3 );
161 0 : else if ( uc_strstrmatch(setname,"latin4")!=NULL )
162 0 : return( em_iso8859_4 );
163 0 : else if ( uc_strstrmatch(setname,"latin5")!=NULL )
164 0 : return( em_iso8859_9 );
165 0 : else if ( uc_strstrmatch(setname,"latin6")!=NULL )
166 0 : return( em_iso8859_10 );
167 0 : else if ( uc_strstrmatch(setname,"latin7")!=NULL )
168 0 : return( em_iso8859_13 );
169 0 : else if ( uc_strstrmatch(setname,"latin8")!=NULL )
170 0 : return( em_iso8859_14 );
171 0 : else if ( uc_strstrmatch(setname,"latin0")!=NULL || uc_strstrmatch(setname,"latin9")!=NULL )
172 0 : return( em_iso8859_15 );
173 :
174 0 : if ( uc_strstrmatch(setname,"koi8")!=NULL )
175 0 : return( em_koi8_r );
176 :
177 0 : if ( uc_strstrmatch(setname,"cyrillic")!=NULL )
178 0 : return( em_iso8859_5 ); /* This is grasping at straws */
179 0 : else if ( uc_strstrmatch(setname,"greek")!=NULL )
180 0 : return( em_iso8859_7 ); /* This is grasping at straws */
181 0 : else if ( uc_strstrmatch(setname,"arabic")!=NULL )
182 0 : return( em_iso8859_6 ); /* This is grasping at straws */
183 0 : else if ( uc_strstrmatch(setname,"hebrew")!=NULL )
184 0 : return( em_iso8859_8 ); /* This is grasping at straws */
185 0 : else if ( uc_strstrmatch(setname,"thai")!=NULL || uc_strstrmatch(setname,"tis")!=NULL )
186 0 : return( em_iso8859_11 );
187 :
188 0 : if ( uc_strstrmatch(setname,"jis")!=NULL ) {
189 0 : if ( uc_strstrmatch(setname,"201")!=NULL )
190 0 : return( em_jis201 );
191 0 : if ( uc_strstrmatch(setname,"208")!=NULL )
192 0 : return( em_jis208 );
193 0 : if ( uc_strstrmatch(setname,"212")!=NULL )
194 0 : return( em_jis212 );
195 0 : if ( uc_strstrmatch(setname,"213")!=NULL ) /* I don't support 213 */
196 0 : return( em_none );
197 :
198 0 : return( em_jis208 );
199 : }
200 :
201 0 : if ( uc_strstrmatch(setname,"ksc")!=NULL && uc_strstrmatch(setname,"5601")!=NULL )
202 0 : return( em_ksc5601 ); /* Seem to be several versions of 5601, we want 94x94 */
203 :
204 0 : if ( uc_strstrmatch(setname,"gb")!=NULL && uc_strstrmatch(setname,"2312")!=NULL )
205 0 : return( em_gb2312 );
206 0 : if ( uc_strstrmatch(setname,"big5")!=NULL )
207 0 : return( em_big5 );
208 :
209 0 : if ( uc_strstrmatch(setname,"mac")!=NULL )
210 0 : return( em_mac );
211 0 : if ( uc_strstrmatch(setname,"win")!=NULL )
212 0 : return( em_win );
213 :
214 0 : if ( IsUserMap(setname))
215 0 : return( em_user );
216 :
217 : /* !!! Encodings used for postscript japanese fonts, which I don't understand */
218 : /* if ( uc_strstrmatch(setname,"RJSJ")!=NULL ) */
219 : /* return( em_sjis ); */
220 : /* if ( uc_strstrmatch(setname,"EUC")!=NULL ) */
221 : /* return( em_euc ); */
222 :
223 0 : return( em_none );
224 : }
225 :
226 : struct keyword { char *name; int val; };
227 : static struct keyword weights[] = {
228 : { "extra_light", 100 },
229 : { "extra-light", 100 },
230 : { "extralight", 100 },
231 : { "light", 200 },
232 : { "demi_light", 300 },
233 : { "demi-light", 300 },
234 : { "demilight", 300 },
235 : { "book", 400 },
236 : { "regular", 400 },
237 : { "roman", 400 },
238 : { "normal", 400 },
239 : { "medium", 500 },
240 : { "demi_bold", 600 },
241 : { "demi-bold", 600 },
242 : { "demibold", 600 },
243 : { "demi", 600 },
244 : { "bold", 700 },
245 : { "demi_black", 800 },
246 : { "demi-black", 800 },
247 : { "demiblack", 800 },
248 : { "extra_bold", 800 },
249 : { "extra-bold", 800 },
250 : { "extrabold", 800 },
251 : { "heavy", 800 },
252 : { "black", 900 },
253 : { "extrablack", 950 },
254 : { "extra-black", 950 },
255 : { "extra_black", 950 },
256 : { "nord", 950 },
257 : { NULL, 0 }
258 : };
259 :
260 0 : static struct keyword *KeyFind(unichar_t *name,struct keyword *words) {
261 0 : while ( words->name!=NULL ) {
262 0 : if ( uc_strmatch(name,words->name)==0 )
263 0 : return( words );
264 0 : ++words;
265 : }
266 0 : return( NULL );
267 : }
268 :
269 0 : static struct keyword *KeyInside(unichar_t *name,struct keyword *words) {
270 0 : while ( words->name!=NULL ) {
271 0 : if ( uc_strstrmatch(name,words->name)!=NULL )
272 0 : return( words );
273 0 : ++words;
274 : }
275 0 : return( NULL );
276 : }
277 :
278 0 : int _GDraw_FontFigureWeights(unichar_t *weight_str) {
279 : struct keyword *val;
280 :
281 0 : if (( val=KeyFind(weight_str,weights))!=NULL )
282 0 : return( val->val );
283 0 : else if (( val=KeyInside(weight_str,weights))!=NULL )
284 0 : return( val->val );
285 : else
286 0 : return( 400 ); /* Assume normal */
287 : }
288 :
289 0 : struct font_name *_GDraw_HashFontFamily(FState *fonts,unichar_t *name, int prop) {
290 : struct font_name *fn;
291 : int ch;
292 : int b,i;
293 :
294 0 : ch = *name;
295 0 : if ( isupper(ch)) ch = tolower(ch);
296 0 : if ( ch<'a' ) ch = 'q'; else if ( ch>'z' ) ch='z';
297 0 : ch -= 'a';
298 :
299 0 : fn = fonts->font_names[ch];
300 0 : while ( fn!=NULL ) {
301 0 : if ( u_strmatch(name,fn->family_name)==0 )
302 0 : break;
303 0 : fn = fn->next;
304 : }
305 0 : if ( fn==NULL ) {
306 0 : fn = calloc(1,sizeof(struct font_name));
307 0 : fn->family_name = u_copy(name);
308 0 : fn->ft = _GDraw_ClassifyFontName(fn->family_name,&b,&i);
309 0 : if ( !prop && fn->ft==ft_unknown )
310 0 : fn->ft = ft_mono;
311 0 : fn->next = fonts->font_names[ch];
312 0 : fonts->font_names[ch] = fn;
313 : }
314 0 : return( fn );
315 : }
316 :
317 0 : void _GDraw_FreeFD(struct font_data *fd) {
318 0 : free(fd->charmap_name);
319 0 : free(fd->localname);
320 0 : free(fd->fontfile);
321 0 : free(fd->metricsfile);
322 0 : free(fd);
323 0 : }
324 :
|