10 #include <X11/Xlocale.h>
12 #include <X11/Xft/Xft.h>
13 #include <fontconfig/fontconfig.h>
16 #define DEFAULT_FONT "sans serif:pixelsize=12"
18 #define DEFAULT_SIZE WINGsConfiguration.defaultFontSize
22 xlfdToFcPattern(char *xlfd
)
27 /* Just skip old font names that contain %d in them.
28 * We don't support that anymore. */
29 if (strchr(xlfd
, '%')!=NULL
)
30 return FcNameParse((FcChar8
*)DEFAULT_FONT
);
33 if ((ptr
= strchr(fname
, ','))) {
36 pattern
= XftXlfdParse(fname
, False
, False
);
40 wwarning(_("invalid font: %s. Trying '%s'"), xlfd
, DEFAULT_FONT
);
41 pattern
= FcNameParse((FcChar8
*)DEFAULT_FONT
);
49 xlfdToFcName(char *xlfd
)
54 pattern
= xlfdToFcPattern(xlfd
);
55 fname
= (char*)FcNameUnparse(pattern
);
56 FcPatternDestroy(pattern
);
63 hasProperty(FcPattern
*pattern
, const char *property
)
67 if (FcPatternGet(pattern
, property
, 0, &val
)==FcResultMatch
) {
76 hasPropertyWithStringValue(FcPattern
*pattern
, const char *object
, char *value
)
81 if (!value
|| value
[0]==0)
85 while (FcPatternGetString(pattern
, object
, id
, &str
)==FcResultMatch
) {
86 if (strcasecmp(value
, (char*)str
) == 0) {
97 makeFontOfSize(char *font
, int size
, char *fallback
)
103 pattern
= xlfdToFcPattern(font
);
105 pattern
= FcNameParse((FcChar8
*)font
);
108 /*FcPatternPrint(pattern);*/
111 FcPatternDel(pattern
, FC_PIXEL_SIZE
);
112 FcPatternAddDouble(pattern
, FC_PIXEL_SIZE
, (double)size
);
113 } else if (size
==0 && !hasProperty(pattern
, "size") &&
114 !hasProperty(pattern
, FC_PIXEL_SIZE
)) {
115 FcPatternAddDouble(pattern
, FC_PIXEL_SIZE
, (double)DEFAULT_SIZE
);
118 if (fallback
&& !hasPropertyWithStringValue(pattern
, FC_FAMILY
, fallback
)) {
119 FcPatternAddString(pattern
, FC_FAMILY
, (FcChar8
*)fallback
);
122 /*FcPatternPrint(pattern);*/
124 result
= (char*)FcNameUnparse(pattern
);
125 FcPatternDestroy(pattern
);
132 WMCreateFont(WMScreen
*scrPtr
, char *fontName
)
134 Display
*display
= scrPtr
->display
;
138 if (fontName
[0]=='-'){
139 fname
= xlfdToFcName(fontName
);
141 fname
= wstrdup(fontName
);
144 if (!WINGsConfiguration
.antialiasedText
&& !strstr(fname
, ":antialias=")) {
145 fname
= wstrappend(fname
, ":antialias=false");
148 font
= WMHashGet(scrPtr
->fontCache
, fname
);
155 font
= wmalloc(sizeof(WMFont
));
156 memset(font
, 0, sizeof(WMFont
));
158 font
->screen
= scrPtr
;
160 font
->font
= XftFontOpenName(display
, scrPtr
->screen
, fname
);
162 printf("Font named %s doesn't exist.\n", fname
);
163 printf("Please check your system configuration.\n");
164 printf("Will try default font %s.\n", DEFAULT_FONT
);
165 font
->font
= XftFontOpenName(display
, scrPtr
->screen
, DEFAULT_FONT
);
167 printf("Unrecoverable font error! I must die!\n");
172 printf("Default font loading succeded.\n");
175 font
->height
= font
->font
->ascent
+font
->font
->descent
;
176 font
->y
= font
->font
->ascent
;
182 assert(WMHashInsert(scrPtr
->fontCache
, font
->name
, font
)==NULL
);
189 WMRetainFont(WMFont
*font
)
191 wassertrv(font
!=NULL
, NULL
);
200 WMReleaseFont(WMFont
*font
)
202 wassertr(font
!=NULL
);
205 if (font
->refCount
< 1) {
206 XftFontClose(font
->screen
->display
, font
->font
);
208 WMHashRemove(font
->screen
->fontCache
, font
->name
);
217 WMIsAntialiasingEnabled(WMScreen
*scrPtr
)
219 return scrPtr
->antialiasedText
;
224 WMFontHeight(WMFont
*font
)
226 wassertrv(font
!=NULL
, 0);
233 WMGetFontName(WMFont
*font
)
235 wassertrv(font
!=NULL
, NULL
);
242 WMDefaultSystemFont(WMScreen
*scrPtr
)
244 return WMRetainFont(scrPtr
->normalFont
);
249 WMDefaultBoldSystemFont(WMScreen
*scrPtr
)
251 return WMRetainFont(scrPtr
->boldFont
);
256 WMSystemFontOfSize(WMScreen
*scrPtr
, int size
)
261 fontSpec
= makeFontOfSize(WINGsConfiguration
.systemFont
, size
, NULL
);
263 font
= WMCreateFont(scrPtr
, fontSpec
);
266 wwarning(_("could not load font: %s."), fontSpec
);
276 WMBoldSystemFontOfSize(WMScreen
*scrPtr
, int size
)
281 fontSpec
= makeFontOfSize(WINGsConfiguration
.boldSystemFont
, size
, NULL
);
283 font
= WMCreateFont(scrPtr
, fontSpec
);
286 wwarning(_("could not load font: %s."), fontSpec
);
296 WMWidthOfString(WMFont
*font
, char *text
, int length
)
300 wassertrv(font
!=NULL
&& text
!=NULL
, 0);
302 XftTextExtentsUtf8(font
->screen
->display
, font
->font
,
303 (XftChar8
*)text
, length
, &extents
);
305 return extents
.xOff
; /* don't ask :P */
311 WMDrawString(WMScreen
*scr
, Drawable d
, WMColor
*color
, WMFont
*font
,
312 int x
, int y
, char *text
, int length
)
316 wassertr(font
!=NULL
);
318 xftcolor
.color
.red
= color
->color
.red
;
319 xftcolor
.color
.green
= color
->color
.green
;
320 xftcolor
.color
.blue
= color
->color
.blue
;
321 xftcolor
.color
.alpha
= color
->alpha
;;
322 xftcolor
.pixel
= W_PIXEL(color
);
324 XftDrawChange(scr
->xftdraw
, d
);
326 XftDrawStringUtf8(scr
->xftdraw
, &xftcolor
, font
->font
,
327 x
, y
+ font
->y
, (XftChar8
*)text
, length
);
332 WMDrawImageString(WMScreen
*scr
, Drawable d
, WMColor
*color
, WMColor
*background
,
333 WMFont
*font
, int x
, int y
, char *text
, int length
)
338 wassertr(font
!=NULL
);
340 textColor
.color
.red
= color
->color
.red
;
341 textColor
.color
.green
= color
->color
.green
;
342 textColor
.color
.blue
= color
->color
.blue
;
343 textColor
.color
.alpha
= color
->alpha
;;
344 textColor
.pixel
= W_PIXEL(color
);
346 bgColor
.color
.red
= background
->color
.red
;
347 bgColor
.color
.green
= background
->color
.green
;
348 bgColor
.color
.blue
= background
->color
.blue
;
349 bgColor
.color
.alpha
= background
->alpha
;;
350 bgColor
.pixel
= W_PIXEL(background
);
352 XftDrawChange(scr
->xftdraw
, d
);
354 XftDrawRect(scr
->xftdraw
, &bgColor
, x
, y
,
355 WMWidthOfString(font
, text
, length
),
358 XftDrawStringUtf8(scr
->xftdraw
, &textColor
, font
->font
,
359 x
, y
+ font
->y
, (XftChar8
*)text
, length
);
364 WMCopyFontWithStyle(WMScreen
*scrPtr
, WMFont
*font
, WMFontStyle style
)
373 /* It's enough to add italic to slant, even if the font has no italic
374 * variant, but only oblique. This is because fontconfig will actually
375 * return the closest match font to what we requested which is the
376 * oblique font. Same goes for using bold for weight.
378 pattern
= FcNameParse((FcChar8
*)WMGetFontName(font
));
381 FcPatternDel(pattern
, FC_WEIGHT
);
382 FcPatternDel(pattern
, FC_SLANT
);
385 FcPatternDel(pattern
, FC_WEIGHT
);
386 FcPatternAddString(pattern
, FC_WEIGHT
, (FcChar8
*)"bold");
389 FcPatternDel(pattern
, FC_SLANT
);
390 FcPatternAddString(pattern
, FC_SLANT
, (FcChar8
*)"italic");
393 FcPatternDel(pattern
, FC_WEIGHT
);
394 FcPatternDel(pattern
, FC_SLANT
);
395 FcPatternAddString(pattern
, FC_WEIGHT
, (FcChar8
*)"bold");
396 FcPatternAddString(pattern
, FC_SLANT
, (FcChar8
*)"italic");
400 name
= (char*)FcNameUnparse(pattern
);
401 copy
= WMCreateFont(scrPtr
, name
);
402 FcPatternDestroy(pattern
);