5 # include <X11/Xft/Xft.h>
13 #include <X11/Xlocale.h>
16 static char *makeFontSetOfSize(char *fontset
, int size
);
20 /* XLFD pattern matching */
22 getElementFromXLFD(const char *xlfd
, int index
)
26 if (*p
== '-' && --index
== 0) {
27 const char *end
= strchr(p
+ 1, '-');
30 if (end
== 0) end
= p
+ strlen(p
);
33 memcpy(buf
, p
+ 1, len
);
43 /* XLFD pattern matching */
45 generalizeXLFD(const char *xlfd
)
49 char *weight
= getElementFromXLFD(xlfd
, 3);
50 char *slant
= getElementFromXLFD(xlfd
, 4);
51 char *pxlsz
= getElementFromXLFD(xlfd
, 7);
53 #define Xstrlen(A) ((A)?strlen(A):0)
54 len
= Xstrlen(xlfd
)+Xstrlen(weight
)+Xstrlen(slant
)+Xstrlen(pxlsz
)*2+60;
57 buf
= wmalloc(len
+ 1);
58 snprintf(buf
, len
+ 1, "%s,-*-*-%s-%s-*-*-%s-*-*-*-*-*-*-*,"
59 "-*-*-*-*-*-*-%s-*-*-*-*-*-*-*,*",
60 xlfd
, weight
, slant
, pxlsz
, pxlsz
);
69 /* XLFD pattern matching */
71 W_CreateFontSetWithGuess(Display
*dpy
, char *xlfd
, char ***missing
,
72 int *nmissing
, char **def_string
)
74 XFontSet fs
= XCreateFontSet(dpy
, xlfd
, missing
, nmissing
, def_string
);
76 if (fs
!= NULL
&& *nmissing
== 0) return fs
;
78 /* for non-iso8859-1 language and iso8859-1 specification
79 (this fontset is only for pattern analysis) */
81 if (*nmissing
!= 0) XFreeStringList(*missing
);
82 setlocale(LC_CTYPE
, "C");
83 fs
= XCreateFontSet(dpy
, xlfd
, missing
, nmissing
, def_string
);
84 setlocale(LC_CTYPE
, "");
87 /* make XLFD font name for pattern analysis */
89 XFontStruct
**fontstructs
;
91 if (XFontsOfFontSet(fs
, &fontstructs
, &fontnames
) > 0)
95 xlfd
= generalizeXLFD(xlfd
);
97 if (*nmissing
!= 0) XFreeStringList(*missing
);
98 if (fs
!= NULL
) XFreeFontSet(dpy
, fs
);
100 fs
= XCreateFontSet(dpy
, xlfd
, missing
, nmissing
, def_string
);
108 WMCreateFontSet(WMScreen
*scrPtr
, char *fontName
)
111 Display
*display
= scrPtr
->display
;
115 XFontSetExtents
*extents
;
117 font
= WMHashGet(scrPtr
->fontSetCache
, fontName
);
123 font
= malloc(sizeof(WMFont
));
126 memset(font
, 0, sizeof(WMFont
));
128 font
->notFontSet
= 0;
129 font
->antialiased
= 0;
131 font
->screen
= scrPtr
;
133 font
->font
.set
= W_CreateFontSetWithGuess(display
, fontName
, &missing
,
134 &nmissing
, &defaultString
);
135 if (nmissing
> 0 && font
->font
.set
) {
138 wwarning(_("the following character sets are missing in %s:"),
140 for (i
= 0; i
< nmissing
; i
++) {
141 wwarning(missing
[i
]);
143 XFreeStringList(missing
);
145 wwarning(_("the string \"%s\" will be used in place of any characters from those sets."),
148 if (!font
->font
.set
) {
153 extents
= XExtentsOfFontSet(font
->font
.set
);
155 font
->height
= extents
->max_logical_extent
.height
;
156 font
->y
= font
->height
- (font
->height
+ extents
->max_logical_extent
.y
);
160 font
->name
= wstrdup(fontName
);
162 assert(WMHashInsert(scrPtr
->fontSetCache
, font
->name
, font
)==NULL
);
170 WMCreateNormalFont(WMScreen
*scrPtr
, char *fontName
)
173 Display
*display
= scrPtr
->display
;
176 if ((ptr
= strchr(fontName
, ','))) {
177 fname
= wmalloc(ptr
- fontName
+ 1);
178 strncpy(fname
, fontName
, ptr
- fontName
);
179 fname
[ptr
- fontName
] = 0;
181 fname
= wstrdup(fontName
);
184 font
= WMHashGet(scrPtr
->fontCache
, fname
);
191 font
= malloc(sizeof(WMFont
));
196 memset(font
, 0, sizeof(WMFont
));
198 font
->notFontSet
= 1;
199 font
->antialiased
= 0;
201 font
->screen
= scrPtr
;
203 font
->font
.normal
= XLoadQueryFont(display
, fname
);
204 if (!font
->font
.normal
) {
209 font
->height
= font
->font
.normal
->ascent
+font
->font
.normal
->descent
;
210 font
->y
= font
->font
.normal
->ascent
;
216 assert(WMHashInsert(scrPtr
->fontCache
, font
->name
, font
)==NULL
);
223 WMCreateAAFont(WMScreen
*scrPtr
, char *fontName
)
227 Display
*display
= scrPtr
->display
;
230 if ((ptr
= strchr(fontName
, ','))) {
231 fname
= wmalloc(ptr
- fontName
+ 1);
232 strncpy(fname
, fontName
, ptr
- fontName
);
233 fname
[ptr
- fontName
] = 0;
235 fname
= wstrdup(fontName
);
238 font
= WMHashGet(scrPtr
->fontCache
, fname
);
245 font
= malloc(sizeof(WMFont
));
250 memset(font
, 0, sizeof(WMFont
));
252 font
->notFontSet
= 1;
253 font
->antialiased
= 1;
255 font
->screen
= scrPtr
;
258 font
->font
.normal
= XLoadQueryFont(display
, fname
);
259 if (!font
->font
.normal
) {
264 XFreeFont(display
, font
->font
.normal
);
266 font
->font
.xft
= XftFontOpenXlfd(display
, scrPtr
->screen
, fname
);
267 if (!font
->font
.xft
) {
272 font
->height
= font
->font
.xft
->ascent
+font
->font
.xft
->descent
;
273 font
->y
= font
->font
.xft
->ascent
;
279 assert(WMHashInsert(scrPtr
->fontCache
, font
->name
, font
)==NULL
);
289 WMCreateNonAAFont(WMScreen
*scrPtr
, char *fontName
)
291 if (scrPtr
->useMultiByte
) {
292 return WMCreateFontSet(scrPtr
, fontName
);
294 return WMCreateNormalFont(scrPtr
, fontName
);
300 WMCreateFont(WMScreen
*scrPtr
, char *fontName
)
302 if (scrPtr
->useMultiByte
) {
303 return WMCreateFontSet(scrPtr
, fontName
);
304 } else if (scrPtr
->antialiasedText
) {
305 WMFont
*font
= WMCreateAAFont(scrPtr
, fontName
);
306 return font
? font
: WMCreateNormalFont(scrPtr
, fontName
);
308 return WMCreateNormalFont(scrPtr
, fontName
);
314 WMRetainFont(WMFont
*font
)
316 wassertrv(font
!=NULL
, NULL
);
325 WMReleaseFont(WMFont
*font
)
327 wassertr(font
!=NULL
);
330 if (font
->refCount
< 1) {
331 if (font
->notFontSet
) {
332 if (font
->antialiased
) {
334 XftFontClose(font
->screen
->display
, font
->font
.xft
);
339 XFreeFont(font
->screen
->display
, font
->font
.normal
);
342 XFreeFontSet(font
->screen
->display
, font
->font
.set
);
345 if (font
->notFontSet
) {
346 WMHashRemove(font
->screen
->fontCache
, font
->name
);
348 WMHashRemove(font
->screen
->fontSetCache
, font
->name
);
358 WMIsAAFont(WMFont
*font
)
360 return font
->antialiased
;
365 WMFontHeight(WMFont
*font
)
367 wassertrv(font
!=NULL
, 0);
374 WMDefaultSystemFont(WMScreen
*scrPtr
)
376 return WMRetainFont(scrPtr
->normalFont
);
381 WMDefaultBoldSystemFont(WMScreen
*scrPtr
)
383 return WMRetainFont(scrPtr
->boldFont
);
388 makeSystemFontOfSize(WMScreen
*scrPtr
, int size
, Bool bold
)
391 char *fontSpec
, *aaFontSpec
;
393 #define WConf WINGsConfiguration
395 fontSpec
= makeFontSetOfSize(WConf
.boldSystemFont
, size
);
396 aaFontSpec
= makeFontSetOfSize(WConf
.antialiasedBoldSystemFont
, size
);
398 fontSpec
= makeFontSetOfSize(WConf
.systemFont
, size
);
399 aaFontSpec
= makeFontSetOfSize(WConf
.antialiasedSystemFont
, size
);
403 if (scrPtr
->useMultiByte
) {
404 font
= WMCreateFontSet(scrPtr
, fontSpec
);
405 } else if (scrPtr
->antialiasedText
) {
406 font
= WMCreateAAFont(scrPtr
, aaFontSpec
);
408 font
= WMCreateNormalFont(scrPtr
, fontSpec
);
412 if (scrPtr
->useMultiByte
) {
413 wwarning(_("could not load font set %s. Trying fixed."), fontSpec
);
414 font
= WMCreateFontSet(scrPtr
, "fixed");
416 font
= WMCreateFontSet(scrPtr
, "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*");
418 } else if (scrPtr
->antialiasedText
) {
419 wwarning(_("could not load font %s. Trying arial."), aaFontSpec
);
421 font
= WMCreateAAFont(scrPtr
, "-*-arial-bold-r-normal-*-12-*-*-*-*-*-*-*");
423 font
= WMCreateAAFont(scrPtr
, "-*-arial-medium-r-normal-*-12-*-*-*-*-*-*-*");
426 wwarning(_("could not load antialiased fonts. Reverting to normal fonts."));
427 font
= WMCreateNormalFont(scrPtr
, fontSpec
);
429 wwarning(_("could not load font %s. Trying fixed."), fontSpec
);
430 font
= WMCreateNormalFont(scrPtr
, "fixed");
434 wwarning(_("could not load font %s. Trying fixed."), fontSpec
);
435 font
= WMCreateNormalFont(scrPtr
, "fixed");
438 wwarning(_("could not load fixed font!"));
452 WMSystemFontOfSize(WMScreen
*scrPtr
, int size
)
454 return makeSystemFontOfSize(scrPtr
, size
, False
);
459 WMBoldSystemFontOfSize(WMScreen
*scrPtr
, int size
)
461 return makeSystemFontOfSize(scrPtr
, size
, True
);
466 WMGetFontFontSet(WMFont
*font
)
468 wassertrv(font
!=NULL
, NULL
);
470 if (font
->notFontSet
)
473 return font
->font
.set
;
478 WMWidthOfString(WMFont
*font
, char *text
, int length
)
480 wassertrv(font
!=NULL
, 0);
481 wassertrv(text
!=NULL
, 0);
483 if (font
->notFontSet
) {
484 if (font
->antialiased
) {
488 XftTextExtents8(font
->screen
->display
, font
->font
.xft
,
489 (XftChar8
*)text
, length
, &extents
);
490 return extents
.xOff
; /* don't ask :P */
495 return XTextWidth(font
->font
.normal
, text
, length
);
501 XmbTextExtents(font
->font
.set
, text
, length
, &AIXsucks
, &rect
);
510 WMDrawString(WMScreen
*scr
, Drawable d
, WMColor
*color
, WMFont
*font
,
511 int x
, int y
, char *text
, int length
)
513 wassertr(font
!=NULL
);
515 if (font
->notFontSet
) {
516 if (font
->antialiased
) {
520 xftcolor
.color
.red
= color
->color
.red
;
521 xftcolor
.color
.green
= color
->color
.green
;
522 xftcolor
.color
.blue
= color
->color
.blue
;
523 xftcolor
.color
.alpha
= color
->alpha
;;
524 xftcolor
.pixel
= W_PIXEL(color
);
526 XftDrawChange(scr
->xftdraw
, d
);
528 XftDrawString8(scr
->xftdraw
, &xftcolor
, font
->font
.xft
,
529 x
, y
+ font
->y
, text
, length
);
534 XSetFont(scr
->display
, scr
->drawStringGC
, font
->font
.normal
->fid
);
535 XSetForeground(scr
->display
, scr
->drawStringGC
, W_PIXEL(color
));
536 XDrawString(scr
->display
, d
, scr
->drawStringGC
, x
, y
+ font
->y
,
540 XSetForeground(scr
->display
, scr
->drawStringGC
, W_PIXEL(color
));
541 XmbDrawString(scr
->display
, d
, font
->font
.set
, scr
->drawStringGC
,
542 x
, y
+ font
->y
, text
, length
);
548 WMDrawImageString(WMScreen
*scr
, Drawable d
, WMColor
*color
, WMColor
*background
,
549 WMFont
*font
, int x
, int y
, char *text
, int length
)
551 wassertr(font
!= NULL
);
553 if (font
->notFontSet
) {
554 if (font
->antialiased
) {
559 textColor
.color
.red
= color
->color
.red
;
560 textColor
.color
.green
= color
->color
.green
;
561 textColor
.color
.blue
= color
->color
.blue
;
562 textColor
.color
.alpha
= color
->alpha
;;
563 textColor
.pixel
= W_PIXEL(color
);
565 bgColor
.color
.red
= background
->color
.red
;
566 bgColor
.color
.green
= background
->color
.green
;
567 bgColor
.color
.blue
= background
->color
.blue
;
568 bgColor
.color
.alpha
= background
->alpha
;;
569 bgColor
.pixel
= W_PIXEL(background
);
572 XftDrawChange(scr
->xftdraw
, d
);
574 XftDrawRect(scr
->xftdraw
, &bgColor
, x
, y
,
575 WMWidthOfString(font
, text
, length
), font
->height
);
577 XftDrawString8(scr
->xftdraw
, &textColor
, font
->font
.xft
,
578 x
, y
+ font
->y
, text
, length
);
583 XSetForeground(scr
->display
, scr
->drawImStringGC
, W_PIXEL(color
));
584 XSetBackground(scr
->display
, scr
->drawImStringGC
, W_PIXEL(background
));
585 XSetFont(scr
->display
, scr
->drawImStringGC
, font
->font
.normal
->fid
);
586 XDrawImageString(scr
->display
, d
, scr
->drawImStringGC
,
587 x
, y
+ font
->y
, text
, length
);
590 XSetForeground(scr
->display
, scr
->drawImStringGC
, W_PIXEL(color
));
591 XSetBackground(scr
->display
, scr
->drawImStringGC
, W_PIXEL(background
));
592 XmbDrawImageString(scr
->display
, d
, font
->font
.set
, scr
->drawImStringGC
,
593 x
, y
+ font
->y
, text
, length
);
601 makeFontSetOfSize(char *fontset
, int size
)
613 ptr
= strchr(fontset
, ',');
615 int count
= ptr
-fontset
;
618 wwarning(_("font description %s is too large."), fontset
);
620 memcpy(font
, fontset
, count
);
631 tmp
= wmalloc(end
+ strlen(f
) + 8);
633 sprintf(tmp
, "%s,", newfs
);
634 sprintf(tmp
+ end
+ 1, f
, size
);
636 sprintf(tmp
+ end
, f
, size
);
651 changeFontProp(char *fname
, char *newprop
, int which
)
653 char before
[128], prop
[128], after
[128];
667 else if (part
==which
+1)
677 snprintf(fname
, 255, "%s-%s%s", before
, newprop
, after
);
682 WMNormalizeFont(WMScreen
*scr
, WMFont
*font
)
684 WMFont
*newfont
=NULL
;
690 snprintf(fname
, 255, "%s", font
->name
);
691 changeFontProp(fname
, "medium", 2);
692 changeFontProp(fname
, "r", 3);
693 newfont
= WMCreateNormalFont(scr
, fname
);
703 WMStrengthenFont(WMScreen
*scr
, WMFont
*font
)
705 WMFont
*newfont
=NULL
;
711 snprintf(fname
, 255, "%s", font
->name
);
712 changeFontProp(fname
, "bold", 2);
713 newfont
= WMCreateNormalFont(scr
, fname
);
723 WMUnstrengthenFont(WMScreen
*scr
, WMFont
*font
)
725 WMFont
*newfont
=NULL
;
731 snprintf(fname
, 255, "%s", font
->name
);
732 changeFontProp(fname
, "medium", 2);
733 newfont
= WMCreateNormalFont(scr
, fname
);
743 WMEmphasizeFont(WMScreen
*scr
, WMFont
*font
)
745 WMFont
*newfont
=NULL
;
751 snprintf(fname
, 255, "%s", font
->name
);
752 changeFontProp(fname
, "o", 3);
753 newfont
= WMCreateNormalFont(scr
, fname
);
763 WMUnemphasizeFont(WMScreen
*scr
, WMFont
*font
)
765 WMFont
*newfont
=NULL
;
771 snprintf(fname
, 255, "%s", font
->name
);
772 changeFontProp(fname
, "r", 3);
773 newfont
= WMCreateNormalFont(scr
, fname
);
783 WMGetFontOfSize(WMScreen
*scr
, WMFont
*font
, int size
)
785 if(!scr
|| !font
|| size
<1)