comparison lib/cachedfont.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: cachedfont.c,v 1.13 1994/05/17 10:51:54 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
21 #include <X11/Intrinsic.h>
22 #include <X11/Xatom.h>
23 #include <X11/Xmu/CharSet.h>
24 #include "CachedAtom.h"
25 #include "CachedFont.h"
26 #include "AsyncErr.h"
27
28 #define DEBUG_VAR debug_cachedfont
29 #include "DebugPrint.h"
30
31 typedef struct _fontrec_ {
32 Display *dpy;
33 String *names; /* full name or aliases... (in lower case) */
34 Cardinal num_names;
35 Atom fontprop; /* 'FONT' property value */
36 XFontStruct *font;
37 int refcnt;
38 struct _fontrec_ *next;
39 } FontRec;
40
41 static FontRec *FRP = NULL;
42
43 static FontRec *
44 LookupByAtom(dpy, atom)
45 Display *dpy;
46 Atom atom;
47 {
48 register FontRec *frp;
49
50 for (frp = FRP; frp != NULL; frp = frp->next) {
51 if (frp->dpy == dpy && frp->fontprop == atom) return frp;
52 }
53 return NULL;
54 }
55
56 static FontRec *
57 LookupByName(dpy, name)
58 Display *dpy;
59 String name;
60 {
61 register FontRec *frp;
62 register String *names;
63 register Cardinal i;
64
65 for (frp = FRP; frp != NULL; frp = frp->next) {
66 if (frp->dpy != dpy) continue;
67
68 for (i = frp->num_names, names = frp->names; i > 0; i--, names++) {
69 if (!strcmp(*names, name)) return frp;
70 }
71 }
72 return NULL;
73 }
74
75 static void
76 AddName(frp, name)
77 register FontRec *frp;
78 String name;
79 {
80 String dup = XtNewString(name);
81
82 if (frp->num_names++ == 0) {
83 frp->names = (String *)XtMalloc(sizeof(String));
84 } else {
85 frp->names = (String *)XtRealloc((char *)frp->names,
86 sizeof(String) * frp->num_names);
87 }
88 frp->names[frp->num_names - 1] = dup;
89 }
90
91 static void
92 LoadFont(frp)
93 register FontRec *frp;
94 {
95 if (frp->font->fid == None) {
96 frp->font->fid = XLoadFont(frp->dpy, frp->names[0]);
97 frp->refcnt = 0; /* reset */
98 }
99 }
100
101 static XFontStruct *
102 AddFont(dpy, name)
103 Display *dpy;
104 char *name;
105 {
106 FontRec *frp;
107 XFontStruct *font;
108 Atom fontprop;
109
110 font = XLoadQueryFont(dpy, name);
111 if (font == NULL) return NULL;
112
113 if (!XGetFontProperty(font, XA_FONT, (unsigned long *)&fontprop)) {
114 /* well, make it by myself */
115 DPRINT(("AddFont(): %s doesn't have FONT property\n", name));
116 fontprop = CachedInternAtom(dpy, name, False);
117 }
118
119 if ((frp = LookupByAtom(dpy, fontprop)) != NULL) {
120 /* already loaded. use it */
121 TRACE(("\tfound in the cache (alias name?)\n"));
122 AddName(frp, name);
123 frp->refcnt++;
124 if (frp->font->fid == None) {
125 frp->font->fid = font->fid;
126 XFreeFontInfo((char **)NULL, font, 1);
127 } else {
128 XFreeFont(dpy, font);
129 }
130 return frp->font;
131 }
132
133 TRACE(("\tnot found in the cache\n"));
134 frp = XtNew(FontRec);
135 frp->dpy = dpy;
136 frp->num_names = 0;
137 AddName(frp, name);
138 frp->fontprop = fontprop;
139 frp->font = font;
140 frp->refcnt = 1;
141 frp->next = FRP;
142 FRP = frp;
143
144 return frp->font;
145 }
146
147
148 /*
149 * Public functions
150 */
151
152 XFontStruct *
153 CachedLoadQueryFontByName(dpy, name)
154 Display *dpy;
155 String name;
156 {
157 FontRec *frp;
158 XFontStruct *font;
159 char buf[256];
160 char *loweredname = buf;
161 int len = strlen(name) + 1;
162
163 if (len > sizeof(buf)) loweredname = XtMalloc(len);
164
165 XmuCopyISOLatin1Lowered(loweredname, name);
166
167 TRACE(("CachedLoadQueryFontByName(name=%s)\n", name));
168 if ((frp = LookupByName(dpy, loweredname)) != NULL) {
169 TRACE(("\tfound in the cache\n"));
170 LoadFont(frp);
171 frp->refcnt++;
172 if (loweredname != buf) XtFree(loweredname);
173 return frp->font;
174 }
175
176 font = AddFont(dpy, loweredname);
177 if (loweredname != buf) XtFree(loweredname);
178 return font;
179 }
180
181 XFontStruct *
182 CachedLoadQueryFontByProp(dpy, atom)
183 Display *dpy;
184 Atom atom;
185 {
186 FontRec *frp;
187 XFontStruct *font;
188 String name;
189 XAEHandle h;
190
191 TRACE(("CachedLoadQueryFontByProp(atom=%ld)\n", atom));
192 if ((frp = LookupByAtom(dpy, atom)) != NULL) {
193 TRACE(("\tfound in the cache\n"));
194 LoadFont(frp);
195 frp->refcnt++;
196 return frp->font;
197 }
198
199 /* get fontname */
200 /* make it safe... */
201 h = XAESetIgnoreErrors(dpy);
202 name = CachedGetAtomName(dpy, atom);
203 XAEUnset(h);
204
205 TRACE(("\tnot found. got font name: %s\n", name ? name : "<null>"));
206
207 if (name == NULL) {
208 font = NULL;
209 } else {
210 char buf[256];
211 char *loweredname = buf;
212 int len = strlen(name) + 1;
213
214 if (len > sizeof(buf)) loweredname = XtMalloc(len);
215 XmuCopyISOLatin1Lowered(loweredname, name);
216 font = AddFont(dpy, loweredname);
217 if (loweredname != buf) XtFree(loweredname);
218 }
219 return font;
220 }
221
222 /* ARGSUSED */
223 XFontStruct *
224 CachedLoadFontByFontStruct(dpy, font)
225 Display *dpy;
226 XFontStruct *font;
227 {
228 register FontRec *frp;
229
230 TRACE(("CachedLoadFontByFontStruct(fid=%08lx)\n", font->fid));
231 for (frp = FRP; frp != NULL; frp = frp->next) {
232 if (frp->font == font) {
233 if (frp->refcnt++ == 0) {
234 /* load it */
235 TRACE(("\trefcnt == 0. loading %s again...\n", frp->names[0]));
236 frp->font->fid = XLoadFont(frp->dpy, frp->names[0]);
237 }
238 return font;
239 }
240 }
241
242 /* not found */
243 TRACE(("\tfont not found in the cache\n"));
244 return NULL;
245 }
246
247 /* ARGSUSED */
248 void
249 CachedFreeFont(dpy, font)
250 Display *dpy;
251 XFontStruct *font;
252 {
253 register FontRec *frp;
254
255 TRACE(("CachedFreeFont(fid=%08lx)\n", font->fid));
256 for (frp = FRP; frp != NULL; frp = frp->next) {
257 if (frp->font == font) {
258 if (--frp->refcnt == 0) {
259 /* unload it, but not free its structure for later use */
260 TRACE(("\trefcnt == 0. unloading...\n"));
261 XUnloadFont(frp->dpy, frp->font->fid);
262 frp->font->fid = None;
263 }
264 return;
265 }
266 }
267
268 /* not found. free anyway... */
269 TRACE(("\tfont not found in the cache. free anyway...\n"));
270 XFreeFont(dpy, font);
271 }