Mercurial > kinput2.yaz
comparison lib/fontbank.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 | 5a32b68b627d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:92745d501b9a |
---|---|
1 #ifndef lint | |
2 static char *rcsid = "$Id: fontbank.c,v 1.4 1994/05/17 10:52:15 ishisone Rel $"; | |
3 #endif | |
4 /* | |
5 * Copyright (c) 1991, 1994 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 | |
21 #include <X11/Xos.h> | |
22 #include <X11/Intrinsic.h> | |
23 #include "CachedFont.h" | |
24 #include "KIFontSet.h" | |
25 #include "FontBank.h" | |
26 | |
27 #define DEBUG_VAR debug_fontbank | |
28 #include "DebugPrint.h" | |
29 | |
30 #define FC_HASH_SIZE 8 | |
31 | |
32 typedef struct _font_cache_ { | |
33 int sum; | |
34 char *name; | |
35 XFontStruct **fonts; | |
36 int num_fonts; | |
37 struct _font_cache_ *next; | |
38 } FontCache; | |
39 | |
40 typedef struct _fb_info_ { | |
41 char *language; | |
42 KICharSet *charsets; | |
43 int num_charsets; | |
44 } FBInfo; | |
45 | |
46 typedef struct _fb_rec_ { | |
47 Display *dpy; | |
48 struct _fb_rec_ *next; | |
49 FBInfo *info; | |
50 int reference_count; | |
51 FontCache *hash[FC_HASH_SIZE]; | |
52 } FBRec; | |
53 | |
54 static FontBank fontBankList = NULL; | |
55 | |
56 /* | |
57 * Language information: | |
58 * The FBInfo structure holds information about the character sets | |
59 * required for a specific language. Currently, this infomation | |
60 * is provided only for Japanese. | |
61 */ | |
62 | |
63 static KICharSetSpec asciiCharSets[] = { | |
64 { "iso8859-1", NULL }, /* preferable */ | |
65 { "jisx0201.1976-0", NULL }, /* alternative */ | |
66 { "iso8859-*", NULL }, /* alternative */ | |
67 }; | |
68 static KICharSetSpec kanaCharSets[] = { | |
69 { "jisx0201.1976-0", NULL }, | |
70 }; | |
71 static KICharSetSpec kanjiCharSets[] = { | |
72 { "jisx0208.1983-0", NULL }, | |
73 { "jisx0208.1983-1", NULL }, | |
74 { "jisx0208.1990-0", NULL }, | |
75 { "jisx0208.1990-1", NULL }, | |
76 { "jisx0208.1976-0", NULL }, | |
77 { "jisx0208.1976-1", NULL }, | |
78 }; | |
79 static KICharSet jpCharSets[3] = { | |
80 { asciiCharSets, XtNumber(asciiCharSets) }, | |
81 { kanaCharSets, XtNumber(kanaCharSets) }, | |
82 { kanjiCharSets, XtNumber(kanjiCharSets) }, | |
83 }; | |
84 | |
85 static FBInfo fontBankInfo[] = { | |
86 { "ja_JP", jpCharSets, XtNumber(jpCharSets) }, | |
87 { NULL } | |
88 }; | |
89 | |
90 static int | |
91 getsum(s) | |
92 char *s; | |
93 { | |
94 unsigned char *p = (unsigned char *)s; | |
95 int sum = 0; | |
96 | |
97 while (*p != '\0') sum += *p++; | |
98 return sum; | |
99 } | |
100 | |
101 static FBInfo * | |
102 getInfo(lang) | |
103 char *lang; | |
104 { | |
105 FBInfo *fip; | |
106 | |
107 for (fip = fontBankInfo; fip->language != NULL; fip++) { | |
108 if (!strcmp(fip->language, lang)) return fip; | |
109 } | |
110 DPRINT(("fonbank: language %s not supported\n", lang)); | |
111 return NULL; | |
112 } | |
113 | |
114 static XFontStruct ** | |
115 lookupCacheFonts(bank, fontset, num_fontsp) | |
116 FontBank bank; | |
117 char *fontset; | |
118 int *num_fontsp; | |
119 { | |
120 FontCache *fc; | |
121 int i; | |
122 int sum; | |
123 | |
124 sum = getsum(fontset); | |
125 fc = bank->hash[sum % FC_HASH_SIZE]; | |
126 | |
127 /* lookup cache */ | |
128 while (fc != NULL) { | |
129 if (fc->sum == sum && !strcmp(fc->name, fontset)) { | |
130 /* found */ | |
131 *num_fontsp = fc->num_fonts; | |
132 for (i = 0; i < *num_fontsp; i++) { | |
133 (void)CachedLoadFontByFontStruct(bank->dpy, fc->fonts[i]); | |
134 } | |
135 return fc->fonts; | |
136 } | |
137 fc = fc->next; | |
138 } | |
139 *num_fontsp = 0; | |
140 return NULL; | |
141 } | |
142 | |
143 static void | |
144 cacheFonts(bank, fontset, fonts, num_fonts) | |
145 FontBank bank; | |
146 char *fontset; | |
147 XFontStruct **fonts; | |
148 int num_fonts; | |
149 { | |
150 FontCache *fc; | |
151 int sum; | |
152 | |
153 fc = XtNew(FontCache); | |
154 fontset = XtNewString(fontset); | |
155 sum = getsum(fontset); | |
156 | |
157 fc->sum = sum; | |
158 fc->name = fontset; | |
159 fc->fonts = fonts; | |
160 fc->num_fonts = num_fonts; | |
161 fc->next = bank->hash[sum % FC_HASH_SIZE]; | |
162 bank->hash[sum % FC_HASH_SIZE] = fc; | |
163 } | |
164 | |
165 static XFontStruct ** | |
166 extractFonts(dpy, fontset, charsets, ncharsets, nfontsp) | |
167 Display *dpy; | |
168 char *fontset; | |
169 KICharSet *charsets; | |
170 int ncharsets; | |
171 int *nfontsp; | |
172 { | |
173 KICharSetFont *kifonts; | |
174 KICharSetFont buf[10]; | |
175 XFontStruct **fonts, **fp; | |
176 | |
177 if (ncharsets > 10) { | |
178 kifonts = (KICharSetFont *)XtMalloc(ncharsets * sizeof(KICharSetFont)); | |
179 } else { | |
180 kifonts = buf; | |
181 } | |
182 *nfontsp = ExtractFontsFromFontSet(dpy, fontset, charsets, | |
183 kifonts, ncharsets); | |
184 fonts = NULL; | |
185 if (*nfontsp > 0) { | |
186 int i; | |
187 | |
188 fonts = (XFontStruct **)XtMalloc(*nfontsp * sizeof(XFontStruct *)); | |
189 for (i = 0, fp = fonts; i < ncharsets; i++) { | |
190 if (kifonts[i].font != NULL) *fp++ = kifonts[i].font; | |
191 } | |
192 } | |
193 if (kifonts != buf) XtFree((char *)kifonts); | |
194 return fonts; | |
195 } | |
196 | |
197 static void | |
198 freeCache(bank) | |
199 FontBank bank; | |
200 { | |
201 FontCache *fc; | |
202 int i; | |
203 | |
204 for (i = 0; i < FC_HASH_SIZE; i++) { | |
205 fc = bank->hash[i]; | |
206 while (fc != NULL) { | |
207 FontCache *next = fc->next; | |
208 | |
209 XtFree(fc->name); | |
210 XtFree((char *)fc->fonts); | |
211 XtFree((char *)fc); | |
212 fc = next; | |
213 } | |
214 } | |
215 } | |
216 | |
217 | |
218 /* | |
219 * Public functions | |
220 */ | |
221 | |
222 FontBank | |
223 FontBankCreate(dpy, language) | |
224 Display *dpy; | |
225 char *language; | |
226 { | |
227 FontBank fb; | |
228 FBInfo *info; | |
229 int i; | |
230 | |
231 TRACE(("FontBankCreate(language:%s)\n", language)); | |
232 | |
233 if ((info = getInfo(language)) == NULL) return NULL; | |
234 | |
235 for (fb = fontBankList; fb != NULL; fb = fb->next) { | |
236 if (fb->dpy == dpy && fb->info == info) { | |
237 TRACE(("\tfontbank for %s already exists\n", language)); | |
238 fb->reference_count++; | |
239 return fb; | |
240 } | |
241 } | |
242 | |
243 TRACE(("\tcreate fontbank for %s...\n", language)); | |
244 fb = XtNew(FBRec); | |
245 fb->dpy = dpy; | |
246 fb->info = info; | |
247 fb->reference_count = 1; | |
248 for (i = 0; i < FC_HASH_SIZE; i++) { | |
249 fb->hash[i] = NULL; | |
250 } | |
251 fb->next = fontBankList; | |
252 fontBankList = fb; | |
253 return fb; | |
254 } | |
255 | |
256 void | |
257 FontBankDestroy(bank) | |
258 FontBank bank; | |
259 { | |
260 TRACE(("FontBankDestroy()\n")); | |
261 | |
262 if (--(bank->reference_count) <= 0) { | |
263 FontBank fb, fb0; | |
264 | |
265 TRACE(("\tfreeing fontbank...\n")); | |
266 fb = fontBankList; | |
267 fb0 = NULL; | |
268 while (fb != NULL) { | |
269 if (fb == bank) { | |
270 if (fb0 == NULL) { | |
271 fontBankList = fb->next; | |
272 } else { | |
273 fb0->next = fb->next; | |
274 } | |
275 freeCache(fb); | |
276 XtFree((char *)fb); | |
277 return; | |
278 } | |
279 fb0 = fb; | |
280 fb = fb->next; | |
281 } | |
282 } | |
283 } | |
284 | |
285 XFontStruct ** | |
286 FontBankGet(bank, fontset, num_fontsp) | |
287 FontBank bank; | |
288 char *fontset; | |
289 int *num_fontsp; | |
290 { | |
291 XFontStruct **fpp; | |
292 | |
293 TRACE(("FontBankGet(fontset:%s)\n", fontset)); | |
294 | |
295 if ((fpp = lookupCacheFonts(bank, fontset, num_fontsp)) != NULL) { | |
296 TRACE(("\tfontset found in fontbank (numfonts=%d)\n", | |
297 *num_fontsp)); | |
298 return fpp; | |
299 } | |
300 | |
301 fpp = extractFonts(bank->dpy, fontset, bank->info->charsets, | |
302 bank->info->num_charsets, num_fontsp); | |
303 | |
304 /* enter cache */ | |
305 TRACE(("\tcaching fontset (numfonts=%d)\n", *num_fontsp)); | |
306 cacheFonts(bank, fontset, fpp, *num_fontsp); | |
307 return fpp; | |
308 } | |
309 | |
310 void | |
311 FontBankFreeFonts(bank, fonts, num_fonts) | |
312 FontBank bank; | |
313 XFontStruct **fonts; | |
314 int num_fonts; | |
315 { | |
316 int i; | |
317 | |
318 TRACE(("FontBankFreeFonts()\n")); | |
319 | |
320 for (i = 0; i < num_fonts; i++) { | |
321 CachedFreeFont(bank->dpy, fonts[i]); | |
322 } | |
323 } |