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 }