7 #include <X11/Xlocale.h>
9 static char *makeFontSetOfSize(char *fontset
, int size
);
13 /* XLFD pattern matching */
15 xlfd_get_element (const char *xlfd
, int index
)
19 if (*p
== '-' && --index
== 0) {
20 const char *end
= strchr(p
+ 1, '-');
23 if (end
== 0) end
= p
+ strlen(p
);
26 memcpy(buf
, p
+ 1, len
);
35 /* XLFD pattern matching */
37 generalize_xlfd (const char *xlfd
)
41 char *weight
= xlfd_get_element(xlfd
, 3);
42 char *slant
= xlfd_get_element(xlfd
, 4);
43 char *pxlsz
= xlfd_get_element(xlfd
, 7);
45 len
= snprintf(NULL
, 0, "%s,-*-*-%s-%s-*-*-%s-*-*-*-*-*-*-*,"
46 "-*-*-*-*-*-*-%s-*-*-*-*-*-*-*,*",
47 xlfd
, weight
, slant
, pxlsz
, pxlsz
);
48 buf
= wmalloc(len
+ 1);
49 snprintf(buf
, len
+ 1, "%s,-*-*-%s-%s-*-*-%s-*-*-*-*-*-*-*,"
50 "-*-*-*-*-*-*-%s-*-*-*-*-*-*-*,*",
51 xlfd
, weight
, slant
, pxlsz
, pxlsz
);
60 /* XLFD pattern matching */
62 W_CreateFontSetWithGuess(Display
*dpy
, char *xlfd
, char ***missing
,
63 int *nmissing
, char **def_string
)
65 XFontSet fs
= XCreateFontSet(dpy
, xlfd
, missing
, nmissing
, def_string
);
67 if (fs
!= NULL
&& *nmissing
== 0) return fs
;
69 /* for non-iso8859-1 language and iso8859-1 specification
70 (this fontset is only for pattern analysis) */
72 char *old_locale
= setlocale(LC_CTYPE
, NULL
);
73 if (*nmissing
!= 0) XFreeStringList(*missing
);
74 setlocale(LC_CTYPE
, "C");
75 fs
= XCreateFontSet(dpy
, xlfd
, missing
, nmissing
, def_string
);
76 setlocale(LC_CTYPE
, old_locale
);
79 /* make XLFD font name for pattern analysis */
81 XFontStruct
**fontstructs
;
83 if (XFontsOfFontSet(fs
, &fontstructs
, &fontnames
) > 0)
87 xlfd
= generalize_xlfd (xlfd
);
89 if (*nmissing
!= 0) XFreeStringList(*missing
);
90 if (fs
!= 0) XFreeFontSet(dpy
, fs
);
92 fs
= XCreateFontSet(dpy
, xlfd
, missing
, nmissing
, def_string
);
99 WMCreateFontSet(WMScreen
*scrPtr
, char *fontName
)
102 Display
*display
= scrPtr
->display
;
106 XFontSetExtents
*extents
;
108 font
= WMHashGet(scrPtr
->fontCache
, fontName
);
114 font
= malloc(sizeof(WMFont
));
117 memset(font
, 0, sizeof(WMFont
));
119 font
->notFontSet
= 0;
121 font
->screen
= scrPtr
;
123 font
->font
.set
= W_CreateFontSetWithGuess(display
, fontName
, &missing
,
124 &nmissing
, &defaultString
);
125 if (nmissing
> 0 && font
->font
.set
) {
128 wwarning("the following character sets are missing in %s:",
130 for (i
= 0; i
< nmissing
; i
++) {
131 wwarning(missing
[i
]);
133 XFreeStringList(missing
);
135 wwarning("the string \"%s\" will be used in place of any characters from those sets.",
138 if (!font
->font
.set
) {
143 extents
= XExtentsOfFontSet(font
->font
.set
);
145 font
->height
= extents
->max_logical_extent
.height
;
146 font
->y
= font
->height
- (font
->height
+ extents
->max_logical_extent
.y
);
150 font
->name
= wstrdup(fontName
);
152 assert(WMHashInsert(scrPtr
->fontCache
, font
->name
, font
)==NULL
);
160 WMCreateNormalFont(WMScreen
*scrPtr
, char *fontName
)
163 Display
*display
= scrPtr
->display
;
166 if ((ptr
= strchr(fontName
, ','))) {
167 fname
= wmalloc(ptr
- fontName
+ 1);
168 strncpy(fname
, fontName
, ptr
- fontName
);
169 fname
[ptr
- fontName
] = 0;
171 fname
= wstrdup(fontName
);
174 font
= WMHashGet(scrPtr
->fontCache
, fname
);
181 font
= malloc(sizeof(WMFont
));
186 memset(font
, 0, sizeof(WMFont
));
188 font
->notFontSet
= 1;
190 font
->screen
= scrPtr
;
192 font
->font
.normal
= XLoadQueryFont(display
, fname
);
193 if (!font
->font
.normal
) {
198 font
->height
= font
->font
.normal
->ascent
+font
->font
.normal
->descent
;
199 font
->y
= font
->font
.normal
->ascent
;
205 assert(WMHashInsert(scrPtr
->fontCache
, font
->name
, font
)==NULL
);
213 WMCreateFont(WMScreen
*scrPtr
, char *fontName
)
215 if (scrPtr
->useMultiByte
)
216 return WMCreateFontSet(scrPtr
, fontName
);
218 return WMCreateNormalFont(scrPtr
, fontName
);
224 WMRetainFont(WMFont
*font
)
226 wassertrv(font
!=NULL
, NULL
);
235 WMReleaseFont(WMFont
*font
)
237 wassertr(font
!=NULL
);
240 if (font
->refCount
< 1) {
241 if (font
->notFontSet
)
242 XFreeFont(font
->screen
->display
, font
->font
.normal
);
244 XFreeFontSet(font
->screen
->display
, font
->font
.set
);
247 WMHashRemove(font
->screen
->fontCache
, font
->name
);
257 WMFontHeight(WMFont
*font
)
259 wassertrv(font
!=NULL
, 0);
267 WMSystemFontOfSize(WMScreen
*scrPtr
, int size
)
272 fontSpec
= makeFontSetOfSize(WINGsConfiguration
.systemFont
, size
);
274 if (scrPtr
->useMultiByte
)
275 font
= WMCreateFontSet(scrPtr
, fontSpec
);
277 font
= WMCreateNormalFont(scrPtr
, fontSpec
);
280 if (scrPtr
->useMultiByte
) {
281 wwarning("could not load font set %s. Trying fixed.", fontSpec
);
282 font
= WMCreateFontSet(scrPtr
, "fixed");
284 font
= WMCreateFontSet(scrPtr
, "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*");
287 wwarning("could not load font %s. Trying fixed.", fontSpec
);
288 font
= WMCreateNormalFont(scrPtr
, "fixed");
291 wwarning("could not load fixed font!");
303 WMBoldSystemFontOfSize(WMScreen
*scrPtr
, int size
)
308 fontSpec
= makeFontSetOfSize(WINGsConfiguration
.boldSystemFont
, size
);
310 if (scrPtr
->useMultiByte
)
311 font
= WMCreateFontSet(scrPtr
, fontSpec
);
313 font
= WMCreateNormalFont(scrPtr
, fontSpec
);
316 if (scrPtr
->useMultiByte
) {
317 wwarning("could not load font set %s. Trying fixed.", fontSpec
);
318 font
= WMCreateFontSet(scrPtr
, "fixed");
320 font
= WMCreateFontSet(scrPtr
, "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*");
323 wwarning("could not load font %s. Trying fixed.", fontSpec
);
324 font
= WMCreateNormalFont(scrPtr
, "fixed");
327 wwarning("could not load fixed font!");
339 WMGetFontFontSet(WMFont
*font
)
341 wassertrv(font
!=NULL
, NULL
);
343 if (font
->notFontSet
)
346 return font
->font
.set
;
351 WMWidthOfString(WMFont
*font
, char *text
, int length
)
353 wassertrv(font
!=NULL
, 0);
354 wassertrv(text
!=NULL
, 0);
356 if (font
->notFontSet
)
357 return XTextWidth(font
->font
.normal
, text
, length
);
362 XmbTextExtents(font
->font
.set
, text
, length
, &AIXsucks
, &rect
);
371 WMDrawString(WMScreen
*scr
, Drawable d
, GC gc
, WMFont
*font
, int x
, int y
,
372 char *text
, int length
)
374 wassertr(font
!=NULL
);
376 if (font
->notFontSet
) {
377 XSetFont(scr
->display
, gc
, font
->font
.normal
->fid
);
378 XDrawString(scr
->display
, d
, gc
, x
, y
+ font
->y
, text
, length
);
380 XmbDrawString(scr
->display
, d
, font
->font
.set
, gc
, x
, y
+ font
->y
,
387 WMDrawImageString(WMScreen
*scr
, Drawable d
, GC gc
, WMFont
*font
, int x
, int y
,
388 char *text
, int length
)
390 wassertr(font
!= NULL
);
392 if (font
->notFontSet
) {
393 XSetFont(scr
->display
, gc
, font
->font
.normal
->fid
);
394 XDrawImageString(scr
->display
, d
, gc
, x
, y
+ font
->y
, text
, length
);
396 XmbDrawImageString(scr
->display
, d
, font
->font
.set
, gc
, x
, y
+ font
->y
,
405 makeFontSetOfSize(char *fontset
, int size
)
417 ptr
= strchr(fontset
, ',');
419 int count
= ptr
-fontset
;
422 wwarning("font description %s is too large.", fontset
);
424 memcpy(font
, fontset
, count
);
435 tmp
= wmalloc(end
+ strlen(f
) + 8);
437 sprintf(tmp
, "%s,", newfs
);
438 sprintf(tmp
+ end
+ 1, f
, size
);
440 sprintf(tmp
+ end
, f
, size
);
455 changeFontProp(char *fname
, char *newprop
, int which
)
457 char before
[128], prop
[128], after
[128];
469 if(part
==which
) bptr
= prop
;
470 else if(part
==which
+1) bptr
= after
;
477 snprintf(fname
, 255, "%s-%s%s", before
, newprop
, after
);
482 WMNormalizeFont(WMScreen
*scr
, WMFont
*font
)
484 WMFont
*newfont
=NULL
;
490 snprintf(fname
, 255, font
->name
);
491 changeFontProp(fname
, "medium", 2);
492 changeFontProp(fname
, "r", 3);
493 newfont
= WMCreateNormalFont(scr
, fname
);
503 WMStrengthenFont(WMScreen
*scr
, WMFont
*font
)
505 WMFont
*newfont
=NULL
;
511 snprintf(fname
, 255, font
->name
);
512 changeFontProp(fname
, "bold", 2);
513 newfont
= WMCreateNormalFont(scr
, fname
);
523 WMUnstrengthenFont(WMScreen
*scr
, WMFont
*font
)
525 WMFont
*newfont
=NULL
;
531 snprintf(fname
, 255, font
->name
);
532 changeFontProp(fname
, "medium", 2);
533 newfont
= WMCreateNormalFont(scr
, fname
);
543 WMEmphasizeFont(WMScreen
*scr
, WMFont
*font
)
545 WMFont
*newfont
=NULL
;
551 snprintf(fname
, 255, font
->name
);
552 changeFontProp(fname
, "o", 3);
553 newfont
= WMCreateNormalFont(scr
, fname
);
563 WMUnemphasizeFont(WMScreen
*scr
, WMFont
*font
)
565 WMFont
*newfont
=NULL
;
571 snprintf(fname
, 255, font
->name
);
572 changeFontProp(fname
, "r", 3);
573 newfont
= WMCreateNormalFont(scr
, fname
);
582 WMGetFontOfSize(WMScreen
*scr
, WMFont
*font
, int size
)
584 if(!scr
|| !font
|| size
<1)