4 #include <X11/Xft/Xft.h>
5 #include <fontconfig/fontconfig.h>
13 #include <X11/Xlocale.h>
16 #define DEFAULT_FONT "sans serif:pixelsize=12"
18 #define DEFAULT_SIZE WINGsConfiguration.defaultFontSize
22 xlfdToFcPattern(char *xlfd
, int size
)
27 fname
= wmalloc(strlen(xlfd
) + 20);
28 if (strstr(xlfd
, "%d")!=NULL
)
29 sprintf(fname
, xlfd
, size
? size
: DEFAULT_SIZE
);
33 if ((ptr
= strchr(fname
, ','))) {
37 pattern
= XftXlfdParse(fname
, False
, False
);
41 wwarning(_("invalid font: %s. Trying '%s'"), xlfd
, DEFAULT_FONT
);
42 pattern
= FcNameParse(DEFAULT_FONT
);
50 xlfdToFcName(char *xlfd
, int size
)
55 pattern
= xlfdToFcPattern(xlfd
, size
);
56 fname
= FcNameUnparse(pattern
);
57 FcPatternDestroy(pattern
);
64 hasProperty(FcPattern
*pattern
, const char *property
)
68 if (FcPatternGet(pattern
, property
, 0, &val
)==FcResultMatch
) {
77 hasPropertyWithStringValue(FcPattern
*pattern
, const char *object
, char *value
)
82 if (!value
|| value
[0]==0)
86 while (FcPatternGetString(pattern
, object
, id
, &str
)==FcResultMatch
) {
87 if (strcasecmp(value
, (char*)str
) == 0) {
98 makeFontOfSize(char *font
, int size
, char *fallback
)
104 pattern
= xlfdToFcPattern(font
, size
);
106 pattern
= FcNameParse(font
);
109 /*FcPatternPrint(pattern);*/
112 FcPatternDel(pattern
, FC_PIXEL_SIZE
);
113 FcPatternAddDouble(pattern
, FC_PIXEL_SIZE
, (double)size
);
114 } else if (size
==0 && !hasProperty(pattern
, "size") &&
115 !hasProperty(pattern
, FC_PIXEL_SIZE
)) {
116 FcPatternAddDouble(pattern
, FC_PIXEL_SIZE
, (double)DEFAULT_SIZE
);
119 if (fallback
&& !hasPropertyWithStringValue(pattern
, FC_FAMILY
, fallback
)) {
120 FcPatternAddString(pattern
, FC_FAMILY
, fallback
);
123 /*FcPatternPrint(pattern);*/
125 result
= FcNameUnparse(pattern
);
126 FcPatternDestroy(pattern
);
133 WMCreateFont(WMScreen
*scrPtr
, char *fontName
)
135 Display
*display
= scrPtr
->display
;
139 if (fontName
[0]=='-'){
140 fname
= xlfdToFcName(fontName
, 0);
142 fname
= wstrdup(fontName
);
145 if (!WINGsConfiguration
.antialiasedText
&& !strstr(fname
, ":antialias=")) {
146 fname
= wstrappend(fname
, ":antialias=false");
149 font
= WMHashGet(scrPtr
->fontCache
, fname
);
156 font
= wmalloc(sizeof(WMFont
));
157 memset(font
, 0, sizeof(WMFont
));
159 font
->screen
= scrPtr
;
161 font
->font
= XftFontOpenName(display
, scrPtr
->screen
, fname
);
167 font
->height
= font
->font
->ascent
+font
->font
->descent
;
168 font
->y
= font
->font
->ascent
;
174 assert(WMHashInsert(scrPtr
->fontCache
, font
->name
, font
)==NULL
);
181 WMRetainFont(WMFont
*font
)
183 wassertrv(font
!=NULL
, NULL
);
192 WMReleaseFont(WMFont
*font
)
194 wassertr(font
!=NULL
);
197 if (font
->refCount
< 1) {
198 XftFontClose(font
->screen
->display
, font
->font
);
200 WMHashRemove(font
->screen
->fontCache
, font
->name
);
209 WMIsAntialiasingEnabled(WMScreen
*scrPtr
)
211 return scrPtr
->antialiasedText
;
216 WMFontHeight(WMFont
*font
)
218 wassertrv(font
!=NULL
, 0);
225 WMGetFontName(WMFont
*font
)
227 wassertrv(font
!=NULL
, NULL
);
234 WMDefaultSystemFont(WMScreen
*scrPtr
)
236 return WMRetainFont(scrPtr
->normalFont
);
241 WMDefaultBoldSystemFont(WMScreen
*scrPtr
)
243 return WMRetainFont(scrPtr
->boldFont
);
248 WMSystemFontOfSize(WMScreen
*scrPtr
, int size
)
253 fontSpec
= makeFontOfSize(WINGsConfiguration
.systemFont
, size
, NULL
);
255 font
= WMCreateFont(scrPtr
, fontSpec
);
258 wwarning(_("could not load font: %s."), fontSpec
);
268 WMBoldSystemFontOfSize(WMScreen
*scrPtr
, int size
)
273 fontSpec
= makeFontOfSize(WINGsConfiguration
.boldSystemFont
, size
, NULL
);
275 font
= WMCreateFont(scrPtr
, fontSpec
);
278 wwarning(_("could not load font: %s."), fontSpec
);
288 WMWidthOfString(WMFont
*font
, char *text
, int length
)
292 wassertrv(font
!=NULL
&& text
!=NULL
, 0);
294 XftTextExtentsUtf8(font
->screen
->display
, font
->font
,
295 (XftChar8
*)text
, length
, &extents
);
297 return extents
.xOff
; /* don't ask :P */
303 WMDrawString(WMScreen
*scr
, Drawable d
, WMColor
*color
, WMFont
*font
,
304 int x
, int y
, char *text
, int length
)
308 wassertr(font
!=NULL
);
310 xftcolor
.color
.red
= color
->color
.red
;
311 xftcolor
.color
.green
= color
->color
.green
;
312 xftcolor
.color
.blue
= color
->color
.blue
;
313 xftcolor
.color
.alpha
= color
->alpha
;;
314 xftcolor
.pixel
= W_PIXEL(color
);
316 XftDrawChange(scr
->xftdraw
, d
);
318 XftDrawStringUtf8(scr
->xftdraw
, &xftcolor
, font
->font
,
319 x
, y
+ font
->y
, (XftChar8
*)text
, length
);
324 WMDrawImageString(WMScreen
*scr
, Drawable d
, WMColor
*color
, WMColor
*background
,
325 WMFont
*font
, int x
, int y
, char *text
, int length
)
330 wassertr(font
!=NULL
);
332 textColor
.color
.red
= color
->color
.red
;
333 textColor
.color
.green
= color
->color
.green
;
334 textColor
.color
.blue
= color
->color
.blue
;
335 textColor
.color
.alpha
= color
->alpha
;;
336 textColor
.pixel
= W_PIXEL(color
);
338 bgColor
.color
.red
= background
->color
.red
;
339 bgColor
.color
.green
= background
->color
.green
;
340 bgColor
.color
.blue
= background
->color
.blue
;
341 bgColor
.color
.alpha
= background
->alpha
;;
342 bgColor
.pixel
= W_PIXEL(background
);
344 XftDrawChange(scr
->xftdraw
, d
);
346 XftDrawRect(scr
->xftdraw
, &bgColor
, x
, y
,
347 WMWidthOfString(font
, text
, length
),
350 XftDrawStringUtf8(scr
->xftdraw
, &textColor
, font
->font
,
351 x
, y
+ font
->y
, (XftChar8
*)text
, length
);
356 WMCopyFontWithStyle(WMScreen
*scrPtr
, WMFont
*font
, WMFontStyle style
)
365 /* It's enough to add italic to slant, even if the font has no italic
366 * variant, but only oblique. This is because fontconfig will actually
367 * return the closest match font to what we requested which is the
368 * oblique font. Same goes for using bold for weight.
370 pattern
= FcNameParse(WMGetFontName(font
));
373 FcPatternDel(pattern
, FC_WEIGHT
);
374 FcPatternDel(pattern
, FC_SLANT
);
377 FcPatternDel(pattern
, FC_WEIGHT
);
378 FcPatternAddString(pattern
, FC_WEIGHT
, "bold");
381 FcPatternDel(pattern
, FC_SLANT
);
382 FcPatternAddString(pattern
, FC_SLANT
, "italic");
385 FcPatternDel(pattern
, FC_WEIGHT
);
386 FcPatternDel(pattern
, FC_SLANT
);
387 FcPatternAddString(pattern
, FC_WEIGHT
, "bold");
388 FcPatternAddString(pattern
, FC_SLANT
, "italic");
392 name
= FcNameUnparse(pattern
);
393 copy
= WMCreateFont(scrPtr
, name
);
394 FcPatternDestroy(pattern
);