fixed misc bugs
[wmaker-crm.git] / WINGs / wfont.c
blob483eec3f00e60f7efe5bab259c8b47aecc9b0928
2 #include "WINGsP.h"
5 #include <wraster.h>
6 #include <assert.h>
8 static char *makeFontSetOfSize(char *fontset, int size);
11 WMFont*
12 WMCreateFontSet(WMScreen *scrPtr, char *fontName)
14 WMFont *font;
15 Display *display = scrPtr->display;
16 char **missing;
17 int nmissing = 0;
18 char *defaultString;
19 XFontSetExtents *extents;
21 font = WMHashGet(scrPtr->fontCache, fontName);
22 if (font) {
23 WMRetainFont(font);
24 return font;
27 font = malloc(sizeof(WMFont));
28 if (!font)
29 return NULL;
30 memset(font, 0, sizeof(WMFont));
32 font->notFontSet = 0;
34 font->screen = scrPtr;
36 font->font.set = XCreateFontSet(display, fontName, &missing, &nmissing,
37 &defaultString);
38 if (nmissing > 0 && font->font.set) {
39 int i;
41 wwarning("the following character sets are missing in %s:",
42 fontName);
43 for (i = 0; i < nmissing; i++) {
44 wwarning(missing[i]);
46 XFreeStringList(missing);
47 if (defaultString)
48 wwarning("the string \"%s\" will be used in place of any characters from those sets.",
49 defaultString);
51 if (!font->font.set) {
52 wfree(font);
53 return NULL;
56 extents = XExtentsOfFontSet(font->font.set);
58 font->height = extents->max_logical_extent.height;
59 font->y = font->height - (font->height + extents->max_logical_extent.y);
61 font->refCount = 1;
63 font->name = wstrdup(fontName);
65 assert(WMHashInsert(scrPtr->fontCache, font->name, font)==NULL);
67 return font;
72 WMFont*
73 WMCreateNormalFont(WMScreen *scrPtr, char *fontName)
75 WMFont *font;
76 Display *display = scrPtr->display;
77 char *fname, *ptr;
79 if ((ptr = strchr(fontName, ','))) {
80 fname = wmalloc(ptr - fontName + 1);
81 strncpy(fname, fontName, ptr - fontName);
82 fname[ptr - fontName] = 0;
83 } else {
84 fname = wstrdup(fontName);
87 font = WMHashGet(scrPtr->fontCache, fname);
88 if (font) {
89 WMRetainFont(font);
90 wfree(fname);
91 return font;
94 font = malloc(sizeof(WMFont));
95 if (!font) {
96 wfree(fname);
97 return NULL;
99 memset(font, 0, sizeof(WMFont));
101 font->notFontSet = 1;
103 font->screen = scrPtr;
105 font->font.normal = XLoadQueryFont(display, fname);
106 if (!font->font.normal) {
107 wfree(font);
108 return NULL;
111 font->height = font->font.normal->ascent+font->font.normal->descent;
112 font->y = font->font.normal->ascent;
114 font->refCount = 1;
116 font->name = fname;
118 assert(WMHashInsert(scrPtr->fontCache, font->name, font)==NULL);
120 return font;
125 WMFont*
126 WMCreateFont(WMScreen *scrPtr, char *fontName)
128 if (scrPtr->useMultiByte)
129 return WMCreateFontSet(scrPtr, fontName);
130 else
131 return WMCreateNormalFont(scrPtr, fontName);
136 WMFont*
137 WMRetainFont(WMFont *font)
139 wassertrv(font!=NULL, NULL);
141 font->refCount++;
143 return font;
147 void
148 WMReleaseFont(WMFont *font)
150 wassertr(font!=NULL);
152 font->refCount--;
153 if (font->refCount < 1) {
154 if (font->notFontSet)
155 XFreeFont(font->screen->display, font->font.normal);
156 else {
157 XFreeFontSet(font->screen->display, font->font.set);
159 if (font->name) {
160 WMHashRemove(font->screen->fontCache, font->name);
161 wfree(font->name);
163 wfree(font);
169 unsigned int
170 WMFontHeight(WMFont *font)
172 wassertrv(font!=NULL, 0);
174 return font->height;
179 WMFont*
180 WMSystemFontOfSize(WMScreen *scrPtr, int size)
182 WMFont *font;
183 char *fontSpec;
185 fontSpec = makeFontSetOfSize(WINGsConfiguration.systemFont, size);
187 if (scrPtr->useMultiByte)
188 font = WMCreateFontSet(scrPtr, fontSpec);
189 else
190 font = WMCreateNormalFont(scrPtr, fontSpec);
192 if (!font) {
193 if (scrPtr->useMultiByte) {
194 wwarning("could not load font set %s. Trying fixed.", fontSpec);
195 font = WMCreateFontSet(scrPtr, "fixed");
196 if (!font) {
197 font = WMCreateFontSet(scrPtr, "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*");
199 } else {
200 wwarning("could not load font %s. Trying fixed.", fontSpec);
201 font = WMCreateNormalFont(scrPtr, "fixed");
203 if (!font) {
204 wwarning("could not load fixed font!");
205 wfree(fontSpec);
206 return NULL;
209 wfree(fontSpec);
211 return font;
215 WMFont*
216 WMBoldSystemFontOfSize(WMScreen *scrPtr, int size)
218 WMFont *font;
219 char *fontSpec;
221 fontSpec = makeFontSetOfSize(WINGsConfiguration.boldSystemFont, size);
223 if (scrPtr->useMultiByte)
224 font = WMCreateFontSet(scrPtr, fontSpec);
225 else
226 font = WMCreateNormalFont(scrPtr, fontSpec);
228 if (!font) {
229 if (scrPtr->useMultiByte) {
230 wwarning("could not load font set %s. Trying fixed.", fontSpec);
231 font = WMCreateFontSet(scrPtr, "fixed");
232 if (!font) {
233 font = WMCreateFontSet(scrPtr, "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*");
235 } else {
236 wwarning("could not load font %s. Trying fixed.", fontSpec);
237 font = WMCreateNormalFont(scrPtr, "fixed");
239 if (!font) {
240 wwarning("could not load fixed font!");
241 wfree(fontSpec);
242 return NULL;
245 wfree(fontSpec);
247 return font;
251 XFontSet
252 WMGetFontFontSet(WMFont *font)
254 wassertrv(font!=NULL, NULL);
256 if (font->notFontSet)
257 return NULL;
258 else
259 return font->font.set;
264 WMWidthOfString(WMFont *font, char *text, int length)
266 wassertrv(font!=NULL, 0);
267 wassertrv(text!=NULL, 0);
269 if (font->notFontSet)
270 return XTextWidth(font->font.normal, text, length);
271 else {
272 XRectangle rect;
273 XRectangle AIXsucks;
275 XmbTextExtents(font->font.set, text, length, &AIXsucks, &rect);
277 return rect.width;
283 void
284 WMDrawString(WMScreen *scr, Drawable d, GC gc, WMFont *font, int x, int y,
285 char *text, int length)
287 wassertr(font!=NULL);
289 if (font->notFontSet) {
290 XSetFont(scr->display, gc, font->font.normal->fid);
291 XDrawString(scr->display, d, gc, x, y + font->y, text, length);
292 } else {
293 XmbDrawString(scr->display, d, font->font.set, gc, x, y + font->y,
294 text, length);
299 void
300 WMDrawImageString(WMScreen *scr, Drawable d, GC gc, WMFont *font, int x, int y,
301 char *text, int length)
303 wassertr(font != NULL);
305 if (font->notFontSet) {
306 XSetFont(scr->display, gc, font->font.normal->fid);
307 XDrawImageString(scr->display, d, gc, x, y + font->y, text, length);
308 } else {
309 XmbDrawImageString(scr->display, d, font->font.set, gc, x, y + font->y,
310 text, length);
317 static char*
318 makeFontSetOfSize(char *fontset, int size)
320 char font[300], *f;
321 char *newfs = NULL;
322 char *ptr;
324 do {
325 char *tmp;
326 int end;
329 f = fontset;
330 ptr = strchr(fontset, ',');
331 if (ptr) {
332 int count = ptr-fontset;
334 if (count > 255) {
335 wwarning("font description %s is too large.", fontset);
336 } else {
337 memcpy(font, fontset, count);
338 font[count] = 0;
339 f = (char*)font;
343 if (newfs)
344 end = strlen(newfs);
345 else
346 end = 0;
348 tmp = wmalloc(end + strlen(f) + 8);
349 if (end != 0) {
350 sprintf(tmp, "%s,", newfs);
351 sprintf(tmp + end + 1, f, size);
352 } else {
353 sprintf(tmp + end, f, size);
356 if (newfs)
357 wfree(newfs);
358 newfs = tmp;
360 fontset = ptr+1;
361 } while (ptr!=NULL);
363 return newfs;