10 #include <X11/Xlocale.h>
12 #include <X11/Xft/Xft.h>
13 #include <fontconfig/fontconfig.h>
15 #define DEFAULT_FONT "sans serif:pixelsize=12"
17 #define DEFAULT_SIZE WINGsConfiguration.defaultFontSize
19 static FcPattern
*xlfdToFcPattern(char *xlfd
)
24 /* Just skip old font names that contain %d in them.
25 * We don't support that anymore. */
26 if (strchr(xlfd
, '%') != NULL
)
27 return FcNameParse((FcChar8
*) DEFAULT_FONT
);
29 fname
= wstrdup(xlfd
);
30 if ((ptr
= strchr(fname
, ','))) {
33 pattern
= XftXlfdParse(fname
, False
, False
);
37 wwarning(_("invalid font: %s. Trying '%s'"), xlfd
, DEFAULT_FONT
);
38 pattern
= FcNameParse((FcChar8
*) DEFAULT_FONT
);
44 static char *xlfdToFcName(char *xlfd
)
49 pattern
= xlfdToFcPattern(xlfd
);
50 fname
= (char *)FcNameUnparse(pattern
);
51 FcPatternDestroy(pattern
);
56 static Bool
hasProperty(FcPattern
* pattern
, const char *property
)
60 if (FcPatternGet(pattern
, property
, 0, &val
) == FcResultMatch
) {
67 static Bool
hasPropertyWithStringValue(FcPattern
* pattern
, const char *object
, char *value
)
72 if (!value
|| value
[0] == 0)
76 while (FcPatternGetString(pattern
, object
, id
, &str
) == FcResultMatch
) {
77 if (strcasecmp(value
, (char *)str
) == 0) {
86 static char *makeFontOfSize(char *font
, int size
, char *fallback
)
92 pattern
= xlfdToFcPattern(font
);
94 pattern
= FcNameParse((FcChar8
*) font
);
97 /*FcPatternPrint(pattern); */
100 FcPatternDel(pattern
, FC_PIXEL_SIZE
);
101 FcPatternAddDouble(pattern
, FC_PIXEL_SIZE
, (double)size
);
102 } else if (size
== 0 && !hasProperty(pattern
, "size") && !hasProperty(pattern
, FC_PIXEL_SIZE
)) {
103 FcPatternAddDouble(pattern
, FC_PIXEL_SIZE
, (double)DEFAULT_SIZE
);
106 if (fallback
&& !hasPropertyWithStringValue(pattern
, FC_FAMILY
, fallback
)) {
107 FcPatternAddString(pattern
, FC_FAMILY
, (FcChar8
*) fallback
);
110 /*FcPatternPrint(pattern); */
112 result
= (char *)FcNameUnparse(pattern
);
113 FcPatternDestroy(pattern
);
118 WMFont
*WMCreateFont(WMScreen
* scrPtr
, char *fontName
)
120 Display
*display
= scrPtr
->display
;
124 if (fontName
[0] == '-') {
125 fname
= xlfdToFcName(fontName
);
127 fname
= wstrdup(fontName
);
130 if (!WINGsConfiguration
.antialiasedText
&& !strstr(fname
, ":antialias=")) {
131 fname
= wstrappend(fname
, ":antialias=false");
134 font
= WMHashGet(scrPtr
->fontCache
, fname
);
141 font
= wmalloc(sizeof(WMFont
));
143 font
->screen
= scrPtr
;
145 font
->font
= XftFontOpenName(display
, scrPtr
->screen
, fname
);
147 printf("Font named %s doesn't exist.\n", fname
);
148 printf("Please check your system configuration.\n");
149 printf("Will try default font %s.\n", DEFAULT_FONT
);
150 font
->font
= XftFontOpenName(display
, scrPtr
->screen
, DEFAULT_FONT
);
152 printf("Unrecoverable font error! I must die!\n");
157 printf("Default font loading succeded.\n");
160 font
->height
= font
->font
->ascent
+ font
->font
->descent
;
161 font
->y
= font
->font
->ascent
;
167 assert(WMHashInsert(scrPtr
->fontCache
, font
->name
, font
) == NULL
);
172 WMFont
*WMRetainFont(WMFont
* font
)
174 wassertrv(font
!= NULL
, NULL
);
181 void WMReleaseFont(WMFont
* font
)
183 wassertr(font
!= NULL
);
186 if (font
->refCount
< 1) {
187 XftFontClose(font
->screen
->display
, font
->font
);
189 WMHashRemove(font
->screen
->fontCache
, font
->name
);
196 Bool
WMIsAntialiasingEnabled(WMScreen
* scrPtr
)
198 return scrPtr
->antialiasedText
;
201 unsigned int WMFontHeight(WMFont
* font
)
203 wassertrv(font
!= NULL
, 0);
208 char *WMGetFontName(WMFont
* font
)
210 wassertrv(font
!= NULL
, NULL
);
215 WMFont
*WMDefaultSystemFont(WMScreen
* scrPtr
)
217 return WMRetainFont(scrPtr
->normalFont
);
220 WMFont
*WMDefaultBoldSystemFont(WMScreen
* scrPtr
)
222 return WMRetainFont(scrPtr
->boldFont
);
225 WMFont
*WMSystemFontOfSize(WMScreen
* scrPtr
, int size
)
230 fontSpec
= makeFontOfSize(WINGsConfiguration
.systemFont
, size
, NULL
);
232 font
= WMCreateFont(scrPtr
, fontSpec
);
235 wwarning(_("could not load font: %s."), fontSpec
);
243 WMFont
*WMBoldSystemFontOfSize(WMScreen
* scrPtr
, int size
)
248 fontSpec
= makeFontOfSize(WINGsConfiguration
.boldSystemFont
, size
, NULL
);
250 font
= WMCreateFont(scrPtr
, fontSpec
);
253 wwarning(_("could not load font: %s."), fontSpec
);
261 int WMWidthOfString(WMFont
* font
, char *text
, int length
)
265 wassertrv(font
!= NULL
&& text
!= NULL
, 0);
267 XftTextExtentsUtf8(font
->screen
->display
, font
->font
, (XftChar8
*) text
, length
, &extents
);
269 return extents
.xOff
; /* don't ask :P */
272 void WMDrawString(WMScreen
* scr
, Drawable d
, WMColor
* color
, WMFont
* font
, int x
, int y
, char *text
, int length
)
276 wassertr(font
!= NULL
);
278 xftcolor
.color
.red
= color
->color
.red
;
279 xftcolor
.color
.green
= color
->color
.green
;
280 xftcolor
.color
.blue
= color
->color
.blue
;
281 xftcolor
.color
.alpha
= color
->alpha
;;
282 xftcolor
.pixel
= W_PIXEL(color
);
284 XftDrawChange(scr
->xftdraw
, d
);
286 XftDrawStringUtf8(scr
->xftdraw
, &xftcolor
, font
->font
, x
, y
+ font
->y
, (XftChar8
*) text
, length
);
290 WMDrawImageString(WMScreen
* scr
, Drawable d
, WMColor
* color
, WMColor
* background
,
291 WMFont
* font
, int x
, int y
, char *text
, int length
)
296 wassertr(font
!= NULL
);
298 textColor
.color
.red
= color
->color
.red
;
299 textColor
.color
.green
= color
->color
.green
;
300 textColor
.color
.blue
= color
->color
.blue
;
301 textColor
.color
.alpha
= color
->alpha
;;
302 textColor
.pixel
= W_PIXEL(color
);
304 bgColor
.color
.red
= background
->color
.red
;
305 bgColor
.color
.green
= background
->color
.green
;
306 bgColor
.color
.blue
= background
->color
.blue
;
307 bgColor
.color
.alpha
= background
->alpha
;;
308 bgColor
.pixel
= W_PIXEL(background
);
310 XftDrawChange(scr
->xftdraw
, d
);
312 XftDrawRect(scr
->xftdraw
, &bgColor
, x
, y
, WMWidthOfString(font
, text
, length
), font
->height
);
314 XftDrawStringUtf8(scr
->xftdraw
, &textColor
, font
->font
, x
, y
+ font
->y
, (XftChar8
*) text
, length
);
317 WMFont
*WMCopyFontWithStyle(WMScreen
* scrPtr
, WMFont
* font
, WMFontStyle style
)
326 /* It's enough to add italic to slant, even if the font has no italic
327 * variant, but only oblique. This is because fontconfig will actually
328 * return the closest match font to what we requested which is the
329 * oblique font. Same goes for using bold for weight.
331 pattern
= FcNameParse((FcChar8
*) WMGetFontName(font
));
334 FcPatternDel(pattern
, FC_WEIGHT
);
335 FcPatternDel(pattern
, FC_SLANT
);
338 FcPatternDel(pattern
, FC_WEIGHT
);
339 FcPatternAddString(pattern
, FC_WEIGHT
, (FcChar8
*) "bold");
342 FcPatternDel(pattern
, FC_SLANT
);
343 FcPatternAddString(pattern
, FC_SLANT
, (FcChar8
*) "italic");
346 FcPatternDel(pattern
, FC_WEIGHT
);
347 FcPatternDel(pattern
, FC_SLANT
);
348 FcPatternAddString(pattern
, FC_WEIGHT
, (FcChar8
*) "bold");
349 FcPatternAddString(pattern
, FC_SLANT
, (FcChar8
*) "italic");
353 name
= (char *)FcNameUnparse(pattern
);
354 copy
= WMCreateFont(scrPtr
, name
);
355 FcPatternDestroy(pattern
);