8 #include <X11/Xlocale.h>
10 static char *makeFontSetOfSize(char *fontset
, int size
);
14 /* XLFD pattern matching */
16 xlfd_get_element (const char *xlfd
, int index
)
20 if (*p
== '-' && --index
== 0) {
21 const char *end
= strchr(p
+ 1, '-');
24 if (end
== 0) end
= p
+ strlen(p
);
27 memcpy(buf
, p
+ 1, len
);
36 /* XLFD pattern matching */
38 generalize_xlfd (const char *xlfd
)
42 char *weight
= xlfd_get_element(xlfd
, 3);
43 char *slant
= xlfd_get_element(xlfd
, 4);
44 char *pxlsz
= xlfd_get_element(xlfd
, 7);
46 #define Xstrlen(A) ((A)?strlen(A):0)
47 len
= Xstrlen(xlfd
)+Xstrlen(weight
)+Xstrlen(slant
)+Xstrlen(pxlsz
)*2+60;
50 buf
= wmalloc(len
+ 1);
51 snprintf(buf
, len
+ 1, "%s,-*-*-%s-%s-*-*-%s-*-*-*-*-*-*-*,"
52 "-*-*-*-*-*-*-%s-*-*-*-*-*-*-*,*",
53 xlfd
, weight
, slant
, pxlsz
, pxlsz
);
62 /* XLFD pattern matching */
64 W_CreateFontSetWithGuess(Display
*dpy
, char *xlfd
, char ***missing
,
65 int *nmissing
, char **def_string
)
67 XFontSet fs
= XCreateFontSet(dpy
, xlfd
, missing
, nmissing
, def_string
);
69 if (fs
!= NULL
&& *nmissing
== 0) return fs
;
71 /* for non-iso8859-1 language and iso8859-1 specification
72 (this fontset is only for pattern analysis) */
74 if (*nmissing
!= 0) XFreeStringList(*missing
);
75 setlocale(LC_CTYPE
, "C");
76 fs
= XCreateFontSet(dpy
, xlfd
, missing
, nmissing
, def_string
);
77 setlocale(LC_CTYPE
, "");
80 /* make XLFD font name for pattern analysis */
82 XFontStruct
**fontstructs
;
84 if (XFontsOfFontSet(fs
, &fontstructs
, &fontnames
) > 0)
88 xlfd
= generalize_xlfd (xlfd
);
90 if (*nmissing
!= 0) XFreeStringList(*missing
);
91 if (fs
!= NULL
) XFreeFontSet(dpy
, fs
);
93 fs
= XCreateFontSet(dpy
, xlfd
, missing
, nmissing
, def_string
);
100 WMCreateFontSet(WMScreen
*scrPtr
, char *fontName
)
103 Display
*display
= scrPtr
->display
;
107 XFontSetExtents
*extents
;
109 font
= WMHashGet(scrPtr
->fontSetCache
, fontName
);
115 font
= malloc(sizeof(WMFont
));
118 memset(font
, 0, sizeof(WMFont
));
120 font
->notFontSet
= 0;
122 font
->screen
= scrPtr
;
124 font
->font
.set
= W_CreateFontSetWithGuess(display
, fontName
, &missing
,
125 &nmissing
, &defaultString
);
126 if (nmissing
> 0 && font
->font
.set
) {
129 wwarning(_("the following character sets are missing in %s:"),
131 for (i
= 0; i
< nmissing
; i
++) {
132 wwarning(missing
[i
]);
134 XFreeStringList(missing
);
136 wwarning(_("the string \"%s\" will be used in place of any characters from those sets."),
139 if (!font
->font
.set
) {
144 extents
= XExtentsOfFontSet(font
->font
.set
);
146 font
->height
= extents
->max_logical_extent
.height
;
147 font
->y
= font
->height
- (font
->height
+ extents
->max_logical_extent
.y
);
151 font
->name
= wstrdup(fontName
);
153 assert(WMHashInsert(scrPtr
->fontSetCache
, font
->name
, font
)==NULL
);
161 WMCreateNormalFont(WMScreen
*scrPtr
, char *fontName
)
164 Display
*display
= scrPtr
->display
;
167 if ((ptr
= strchr(fontName
, ','))) {
168 fname
= wmalloc(ptr
- fontName
+ 1);
169 strncpy(fname
, fontName
, ptr
- fontName
);
170 fname
[ptr
- fontName
] = 0;
172 fname
= wstrdup(fontName
);
175 font
= WMHashGet(scrPtr
->fontCache
, fname
);
182 font
= malloc(sizeof(WMFont
));
187 memset(font
, 0, sizeof(WMFont
));
189 font
->notFontSet
= 1;
191 font
->screen
= scrPtr
;
193 font
->font
.normal
= XLoadQueryFont(display
, fname
);
194 if (!font
->font
.normal
) {
200 font
->height
= font
->font
.normal
->ascent
+font
->font
.normal
->descent
;
201 font
->y
= font
->font
.normal
->ascent
;
207 assert(WMHashInsert(scrPtr
->fontCache
, font
->name
, font
)==NULL
);
215 WMCreateFont(WMScreen
*scrPtr
, char *fontName
)
217 if (scrPtr
->useMultiByte
)
218 return WMCreateFontSet(scrPtr
, fontName
);
220 return WMCreateNormalFont(scrPtr
, fontName
);
226 WMRetainFont(WMFont
*font
)
228 wassertrv(font
!=NULL
, NULL
);
237 WMReleaseFont(WMFont
*font
)
239 wassertr(font
!=NULL
);
242 if (font
->refCount
< 1) {
243 if (font
->notFontSet
)
244 XFreeFont(font
->screen
->display
, font
->font
.normal
);
246 XFreeFontSet(font
->screen
->display
, font
->font
.set
);
249 if (font
->notFontSet
) {
250 WMHashRemove(font
->screen
->fontCache
, font
->name
);
252 WMHashRemove(font
->screen
->fontSetCache
, font
->name
);
263 WMFontHeight(WMFont
*font
)
265 wassertrv(font
!=NULL
, 0);
272 WMDefaultSystemFont(WMScreen
*scrPtr
)
274 return WMRetainFont(scrPtr
->normalFont
);
279 WMDefaultBoldSystemFont(WMScreen
*scrPtr
)
281 return WMRetainFont(scrPtr
->boldFont
);
286 WMSystemFontOfSize(WMScreen
*scrPtr
, int size
)
291 fontSpec
= makeFontSetOfSize(WINGsConfiguration
.systemFont
, size
);
293 if (scrPtr
->useMultiByte
)
294 font
= WMCreateFontSet(scrPtr
, fontSpec
);
296 font
= WMCreateNormalFont(scrPtr
, fontSpec
);
299 if (scrPtr
->useMultiByte
) {
300 wwarning(_("could not load font set %s. Trying fixed."), fontSpec
);
301 font
= WMCreateFontSet(scrPtr
, "fixed");
303 font
= WMCreateFontSet(scrPtr
, "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*");
306 wwarning(_("could not load font %s. Trying fixed."), fontSpec
);
307 font
= WMCreateNormalFont(scrPtr
, "fixed");
310 wwarning(_("could not load fixed font!"));
322 WMBoldSystemFontOfSize(WMScreen
*scrPtr
, int size
)
327 fontSpec
= makeFontSetOfSize(WINGsConfiguration
.boldSystemFont
, size
);
329 if (scrPtr
->useMultiByte
)
330 font
= WMCreateFontSet(scrPtr
, fontSpec
);
332 font
= WMCreateNormalFont(scrPtr
, fontSpec
);
335 if (scrPtr
->useMultiByte
) {
336 wwarning(_("could not load font set %s. Trying fixed."), fontSpec
);
337 font
= WMCreateFontSet(scrPtr
, "fixed");
339 font
= WMCreateFontSet(scrPtr
, "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*");
342 wwarning(_("could not load font %s. Trying fixed."), fontSpec
);
343 font
= WMCreateNormalFont(scrPtr
, "fixed");
346 wwarning(_("could not load fixed font!"));
358 WMGetFontFontSet(WMFont
*font
)
360 wassertrv(font
!=NULL
, NULL
);
362 if (font
->notFontSet
)
365 return font
->font
.set
;
370 WMWidthOfString(WMFont
*font
, char *text
, int length
)
372 wassertrv(font
!=NULL
, 0);
373 wassertrv(text
!=NULL
, 0);
375 if (font
->notFontSet
)
376 return XTextWidth(font
->font
.normal
, text
, length
);
381 XmbTextExtents(font
->font
.set
, text
, length
, &AIXsucks
, &rect
);
390 WMDrawString(WMScreen
*scr
, Drawable d
, WMColor
*color
, WMFont
*font
,
391 int x
, int y
, char *text
, int length
)
393 wassertr(font
!=NULL
);
395 XSetForeground(scr
->display
, scr
->drawStringGC
, W_PIXEL(color
));
396 if (font
->notFontSet
) {
397 XSetFont(scr
->display
, scr
->drawStringGC
, font
->font
.normal
->fid
);
398 XDrawString(scr
->display
, d
, scr
->drawStringGC
, x
, y
+ font
->y
, text
,
401 XmbDrawString(scr
->display
, d
, font
->font
.set
, scr
->drawStringGC
,
402 x
, y
+ font
->y
, text
, length
);
408 WMDrawImageString(WMScreen
*scr
, Drawable d
, WMColor
*color
, WMColor
*background
,
409 WMFont
*font
, int x
, int y
, char *text
, int length
)
411 wassertr(font
!= NULL
);
413 XSetForeground(scr
->display
, scr
->drawImStringGC
, W_PIXEL(color
));
414 XSetBackground(scr
->display
, scr
->drawImStringGC
, W_PIXEL(background
));
415 if (font
->notFontSet
) {
416 XSetFont(scr
->display
, scr
->drawImStringGC
, font
->font
.normal
->fid
);
417 XDrawImageString(scr
->display
, d
, scr
->drawImStringGC
, x
, y
+ font
->y
,
420 XmbDrawImageString(scr
->display
, d
, font
->font
.set
, scr
->drawImStringGC
,
421 x
, y
+ font
->y
, text
, length
);
429 makeFontSetOfSize(char *fontset
, int size
)
441 ptr
= strchr(fontset
, ',');
443 int count
= ptr
-fontset
;
446 wwarning(_("font description %s is too large."), fontset
);
448 memcpy(font
, fontset
, count
);
459 tmp
= wmalloc(end
+ strlen(f
) + 8);
461 sprintf(tmp
, "%s,", newfs
);
462 sprintf(tmp
+ end
+ 1, f
, size
);
464 sprintf(tmp
+ end
, f
, size
);
479 changeFontProp(char *fname
, char *newprop
, int which
)
481 char before
[128], prop
[128], after
[128];
495 else if(part
==which
+1)
505 snprintf(fname
, 255, "%s-%s%s", before
, newprop
, after
);
510 WMNormalizeFont(WMScreen
*scr
, WMFont
*font
)
512 WMFont
*newfont
=NULL
;
518 snprintf(fname
, 255, font
->name
);
519 changeFontProp(fname
, "medium", 2);
520 changeFontProp(fname
, "r", 3);
521 newfont
= WMCreateNormalFont(scr
, fname
);
531 WMStrengthenFont(WMScreen
*scr
, WMFont
*font
)
533 WMFont
*newfont
=NULL
;
539 snprintf(fname
, 255, font
->name
);
540 changeFontProp(fname
, "bold", 2);
541 newfont
= WMCreateNormalFont(scr
, fname
);
551 WMUnstrengthenFont(WMScreen
*scr
, WMFont
*font
)
553 WMFont
*newfont
=NULL
;
559 snprintf(fname
, 255, font
->name
);
560 changeFontProp(fname
, "medium", 2);
561 newfont
= WMCreateNormalFont(scr
, fname
);
571 WMEmphasizeFont(WMScreen
*scr
, WMFont
*font
)
573 WMFont
*newfont
=NULL
;
579 snprintf(fname
, 255, font
->name
);
580 changeFontProp(fname
, "o", 3);
581 newfont
= WMCreateNormalFont(scr
, fname
);
591 WMUnemphasizeFont(WMScreen
*scr
, WMFont
*font
)
593 WMFont
*newfont
=NULL
;
599 snprintf(fname
, 255, font
->name
);
600 changeFontProp(fname
, "r", 3);
601 newfont
= WMCreateNormalFont(scr
, fname
);
611 WMGetFontOfSize(WMScreen
*scr
, WMFont
*font
, int size
)
613 if(!scr
|| !font
|| size
<1)