Mercurial > kinput2.yaz
comparison lib/fontset.c @ 0:92745d501b9a
initial import from kinput2-v3.1
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 04:44:30 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:92745d501b9a |
---|---|
1 #ifndef lint | |
2 static char *rcsid = "$Id: fontset.c,v 1.9 1994/06/02 04:59:23 ishisone Rel $"; | |
3 #endif | |
4 /* | |
5 * Copyright (c) 1991 Software Research Associates, Inc. | |
6 * | |
7 * Permission to use, copy, modify, and distribute this software and its | |
8 * documentation for any purpose and without fee is hereby granted, provided | |
9 * that the above copyright notice appear in all copies and that both that | |
10 * copyright notice and this permission notice appear in supporting | |
11 * documentation, and that the name of Software Research Associates not be | |
12 * used in advertising or publicity pertaining to distribution of the | |
13 * software without specific, written prior permission. Software Research | |
14 * Associates makes no representations about the suitability of this software | |
15 * for any purpose. It is provided "as is" without express or implied | |
16 * warranty. | |
17 * | |
18 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan | |
19 * | |
20 * a FontSet handler for kinput2. | |
21 */ | |
22 | |
23 #include <X11/Intrinsic.h> | |
24 #include <X11/Xatom.h> | |
25 #include <X11/Xmu/CharSet.h> | |
26 #include "CachedAtom.h" | |
27 #include "CachedFont.h" | |
28 #include "KIFontSet.h" | |
29 | |
30 #define DEBUG_VAR debug_fontset | |
31 #include "DebugPrint.h" | |
32 | |
33 typedef struct { | |
34 String name; | |
35 String xlfdname; | |
36 } FSFontName; | |
37 | |
38 static char noname[] = "no"; | |
39 | |
40 static int match(); | |
41 static Cardinal parseFontSet(); | |
42 static Boolean tryCharSet(); | |
43 static XFontStruct *csSuppliedMatchFont(); | |
44 static XFontStruct *exactMatchFont(); | |
45 static XFontStruct *csReplacedMatchFont(); | |
46 static String getXLFDName(); | |
47 | |
48 | |
49 /*- match: returns 1 if the specified string matches the pattern -*/ | |
50 static int | |
51 match(s, p) | |
52 register char *s; /* string */ | |
53 register char *p; /* pattern */ | |
54 { | |
55 register int tmp; | |
56 | |
57 while ((tmp = *p++) != '\0') { | |
58 switch (tmp) { | |
59 case '?': | |
60 if (*s++ == '\0') return 0; | |
61 continue; | |
62 case '*': | |
63 while ((tmp = match(s, p)) == 0) { | |
64 if (*s++ == '\0') return -1; | |
65 } | |
66 return tmp; | |
67 default: | |
68 if (*s++ != tmp) return 0; | |
69 continue; | |
70 } | |
71 } | |
72 return (*s == '\0'); | |
73 } | |
74 | |
75 /*- countCommas: count number of commas in the string -*/ | |
76 static Cardinal | |
77 countCommas(s) | |
78 String s; | |
79 { | |
80 int n = 0; | |
81 | |
82 while (*s != '\0') { | |
83 if (*s++ == ',') n++; | |
84 } | |
85 return n; | |
86 } | |
87 | |
88 /*- parseFontSet: separate each font in a font name list -*/ | |
89 static Cardinal | |
90 parseFontSet(spec, basenames) | |
91 String spec; /* IN */ | |
92 FSFontName *basenames; /* OUT */ | |
93 { | |
94 register char *p, *q; | |
95 Cardinal nnames; | |
96 int c; | |
97 | |
98 nnames = 0; | |
99 p = spec; | |
100 for (;;) { | |
101 /* skip leading blanks */ | |
102 while ((c = *p) != '\0' && (c == ' ' || c == '\t' || c == '\n')) p++; | |
103 if (c == '\0') break; | |
104 | |
105 basenames[nnames++].name = p; | |
106 | |
107 /* find comma or NUL char */ | |
108 for (q = p; (c = *q) != '\0' && c != ','; q++) ; | |
109 | |
110 /* omit trailing blanks */ | |
111 p = q - 1; | |
112 while ((c = *p) == ' ' || c == '\t' || c == '\n') *p-- = '\0'; | |
113 | |
114 if (*q == '\0') break; | |
115 *q = '\0'; | |
116 p = q + 1; | |
117 } | |
118 | |
119 #ifdef DEBUG | |
120 if (DDEBUG_CONDITION(10)) { | |
121 if (nnames == 0) { | |
122 printf("\tparse error\n"); | |
123 } else { | |
124 int i; | |
125 printf("\t%d elements\n", nnames); | |
126 for (i = 0; i < nnames; i++) printf("\t\t%s\n", basenames[i].name); | |
127 } | |
128 } | |
129 #endif | |
130 | |
131 return nnames; | |
132 } | |
133 | |
134 /*- tryCharSet: apply specified function to the fontnames for getting appropriate font for given character set -*/ | |
135 static Boolean | |
136 tryCharSet(dpy, cset, extfont, namelist, numlist, func) | |
137 Display *dpy; | |
138 KICharSet *cset; | |
139 KICharSetFont *extfont; | |
140 FSFontName *namelist; | |
141 Cardinal numlist; | |
142 XFontStruct *(*func)(); | |
143 { | |
144 KICharSetSpec *specs; | |
145 Cardinal i; | |
146 XFontStruct *font; | |
147 | |
148 for (i = 0, specs = cset->specs; i < cset->num_specs; i++, specs++) { | |
149 font = (*func)(dpy, specs->pattern, namelist, numlist); | |
150 if (font != NULL) { | |
151 extfont->charset = specs->pattern; | |
152 extfont->cldata = specs->cldata; | |
153 extfont->font = font; | |
154 return True; | |
155 } | |
156 } | |
157 return False; | |
158 } | |
159 | |
160 static XFontStruct * | |
161 exactMatchFont(dpy, csetstr, namelist, numlist) | |
162 Display *dpy; | |
163 String csetstr; | |
164 FSFontName *namelist; | |
165 Cardinal numlist; | |
166 { | |
167 XFontStruct *font; | |
168 | |
169 while (numlist-- > 0) { | |
170 String name = (namelist++)->name; | |
171 String p; | |
172 int namelen; | |
173 int hyphen; | |
174 | |
175 if (*name != '-' && *name != '+') continue; /* not an XLFD name */ | |
176 | |
177 namelen = strlen(name); | |
178 for (p = name + namelen - 1, hyphen = 0; p > name; p--) { | |
179 if (*p == '-') hyphen++; | |
180 if (hyphen == 2) goto found; | |
181 } | |
182 continue; /* doesn't contain charset part */ | |
183 | |
184 found: | |
185 p++; /* now p points the charset part of the fontname */ | |
186 if (match(p, csetstr) > 0 && | |
187 (font = CachedLoadQueryFontByName(dpy, name)) != NULL) { | |
188 TRACE(("\tmatched in exactMatchFont()\n")); | |
189 TRACE(("\t\tcset=%s, font=%s\n", csetstr, name)); | |
190 return font; | |
191 } | |
192 } | |
193 return NULL; | |
194 } | |
195 | |
196 static XFontStruct * | |
197 csSuppliedMatchFont(dpy, csetstr, namelist, numlist) | |
198 Display *dpy; | |
199 String csetstr; | |
200 FSFontName *namelist; | |
201 Cardinal numlist; | |
202 { | |
203 XFontStruct *font; | |
204 | |
205 while (numlist-- > 0) { | |
206 String name = (namelist++)->name; | |
207 char namebuf[512]; | |
208 | |
209 if (*name != '-' && *name != '+') continue; /* not an XLFD name */ | |
210 | |
211 (void)strcpy(namebuf, name); | |
212 (void)strcat(namebuf, "-"); | |
213 (void)strcat(namebuf, csetstr); | |
214 | |
215 if ((font = CachedLoadQueryFontByName(dpy, namebuf)) != NULL) { | |
216 TRACE(("\tmatched in csSuppliedMatchFont()\n")); | |
217 TRACE(("\t\tcset=%s, font=%s\n", csetstr, namebuf)); | |
218 return font; | |
219 } | |
220 } | |
221 return NULL; | |
222 } | |
223 | |
224 static XFontStruct * | |
225 csReplacedMatchFont(dpy, csetstr, namelist, numlist) | |
226 Display *dpy; | |
227 String csetstr; | |
228 FSFontName *namelist; | |
229 Cardinal numlist; | |
230 { | |
231 XFontStruct *font; | |
232 | |
233 while (numlist-- > 0) { | |
234 String name = namelist->name; | |
235 char namebuf[512]; | |
236 String p; | |
237 int namelen; | |
238 int hyphen; | |
239 | |
240 if (*name != '-' && *name != '+') { /* non XLFD name */ | |
241 if (namelist->xlfdname == NULL || | |
242 (namelist->xlfdname == noname && | |
243 (namelist->xlfdname = getXLFDName(dpy, name)) == NULL)) { | |
244 /* this font doesn't have XLFD name */ | |
245 namelist++; | |
246 continue; | |
247 } | |
248 name = namelist->xlfdname; | |
249 } | |
250 namelist++; | |
251 | |
252 (void)strcpy(namebuf, name); | |
253 namelen = strlen(namebuf); | |
254 | |
255 /* find charset part of the font name */ | |
256 for (p = namebuf + namelen - 1, hyphen = 0; p > namebuf; p--) { | |
257 if (*p == '-') hyphen++; | |
258 if (hyphen == 2) goto found; | |
259 } | |
260 continue; /* doesn't contain charset part */ | |
261 | |
262 found: | |
263 p++; /* now p points the charset part of the fontname */ | |
264 | |
265 /* replace charset part */ | |
266 (void)strcpy(p, csetstr); | |
267 | |
268 if ((font = CachedLoadQueryFontByName(dpy, namebuf)) != NULL) { | |
269 TRACE(("\tmatched in csReplacedMatchFont()\n")); | |
270 TRACE(("\t\tcset=%s, font=%s\n", csetstr, namebuf)); | |
271 return font; | |
272 } | |
273 } | |
274 return NULL; | |
275 } | |
276 | |
277 /*- getXLFDName: obtain XLFD font name from a non XLFD font name -*/ | |
278 static String | |
279 getXLFDName(dpy, nonxlfdname) | |
280 Display *dpy; | |
281 String nonxlfdname; | |
282 { | |
283 XFontStruct *font; | |
284 Atom fontprop; | |
285 String name; | |
286 | |
287 TRACE(("getXLFDName(%s)\n", nonxlfdname)); | |
288 font = CachedLoadQueryFontByName(dpy, nonxlfdname); | |
289 if (font == NULL) { | |
290 DPRINT(("getXLFDName(%s):CachedLoadQueryFontByName() failed\n", | |
291 nonxlfdname)); | |
292 return NULL; | |
293 } | |
294 if (!XGetFontProperty(font, XA_FONT, (unsigned long *)&fontprop)) { | |
295 /* can't get 'FONT' property. so XLFD name cannot be obtained */ | |
296 DPRINT(("getXLFDName(%s): can't get FONT property\n", | |
297 nonxlfdname)); | |
298 CachedFreeFont(dpy, font); | |
299 return NULL; | |
300 } | |
301 | |
302 CachedFreeFont(dpy, font); | |
303 name = CachedGetAtomName(dpy, fontprop); | |
304 TRACE(("\tgot %s\n", name)); | |
305 return (*name == '-' || *name == '+') ? name : NULL; | |
306 } | |
307 | |
308 | |
309 /* | |
310 * public functions | |
311 */ | |
312 | |
313 int | |
314 ExtractFontsFromFontSet(dpy, fontset, charsets, exfonts, numcsets) | |
315 Display *dpy; | |
316 String fontset; | |
317 KICharSet *charsets; | |
318 KICharSetFont *exfonts; | |
319 Cardinal numcsets; | |
320 { | |
321 Cardinal nfonts; | |
322 String fsp; | |
323 char fsbuf[1024]; | |
324 FSFontName *fnp; | |
325 FSFontName fnbuf[20]; | |
326 int nfound; | |
327 int i; | |
328 | |
329 TRACE(("ExtractFontsFromFontSet(fontset=%s)\n", fontset)); | |
330 for (i = 0; i < numcsets; i++) { | |
331 exfonts[i].font = NULL; | |
332 exfonts[i].charset = NULL; | |
333 exfonts[i].cldata = NULL; | |
334 } | |
335 | |
336 if (strlen(fontset) >= sizeof(fsbuf)) { | |
337 fsp = XtMalloc((unsigned int)(strlen(fontset) + 1)); | |
338 } else { | |
339 fsp = fsbuf; | |
340 } | |
341 XmuCopyISOLatin1Lowered(fsp, fontset); | |
342 | |
343 if ((nfonts = countCommas(fsp) + 1) >= XtNumber(fnbuf)) { | |
344 fnp = (FSFontName *)XtMalloc(nfonts * sizeof(FSFontName)); | |
345 } else { | |
346 fnp = fnbuf; | |
347 } | |
348 for (i = 0; i < nfonts; i++) fnp[i].xlfdname = noname; | |
349 | |
350 if ((nfonts = parseFontSet(fsp, fnp)) == 0) { | |
351 if (fsp != fsbuf) XtFree(fsp); | |
352 if (fnp != fnbuf) XtFree((char *)fnp); | |
353 return 0; | |
354 } | |
355 | |
356 nfound = 0; | |
357 for (i = 0; i < numcsets; i++) { | |
358 KICharSet *cp = charsets + i; | |
359 KICharSetFont *fp = exfonts + i; | |
360 | |
361 TRACE(("\tfor charset #%d\n", i)); | |
362 if (tryCharSet(dpy, cp, fp, fnp, nfonts, exactMatchFont) || | |
363 tryCharSet(dpy, cp, fp, fnp, nfonts, csSuppliedMatchFont) || | |
364 tryCharSet(dpy, cp, fp, fnp, nfonts, csReplacedMatchFont)) { | |
365 nfound++; | |
366 } | |
367 } | |
368 if (fsp != fsbuf) XtFree(fsp); | |
369 if (fnp != fnbuf) XtFree((char *)fnp); | |
370 | |
371 return nfound; | |
372 } |