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));
142 memset(font, 0, sizeof(WMFont));
144 font->screen = scrPtr;
146 font->font = XftFontOpenName(display, scrPtr->screen, fname);
148 printf("Font named %s doesn't exist.\n", fname);
149 printf("Please check your system configuration.\n");
150 printf("Will try default font %s.\n", DEFAULT_FONT);
151 font->font = XftFontOpenName(display, scrPtr->screen, DEFAULT_FONT);
153 printf("Unrecoverable font error! I must die!\n");
158 printf("Default font loading succeded.\n");
161 font->height = font->font->ascent + font->font->descent;
162 font->y = font->font->ascent;
168 assert(WMHashInsert(scrPtr->fontCache, font->name, font) == NULL);
173 WMFont *WMRetainFont(WMFont * font)
175 wassertrv(font != NULL, NULL);
182 void WMReleaseFont(WMFont * font)
184 wassertr(font != NULL);
187 if (font->refCount < 1) {
188 XftFontClose(font->screen->display, font->font);
190 WMHashRemove(font->screen->fontCache, font->name);
197 Bool WMIsAntialiasingEnabled(WMScreen * scrPtr)
199 return scrPtr->antialiasedText;
202 unsigned int WMFontHeight(WMFont * font)
204 wassertrv(font != NULL, 0);
209 char *WMGetFontName(WMFont * font)
211 wassertrv(font != NULL, NULL);
216 WMFont *WMDefaultSystemFont(WMScreen * scrPtr)
218 return WMRetainFont(scrPtr->normalFont);
221 WMFont *WMDefaultBoldSystemFont(WMScreen * scrPtr)
223 return WMRetainFont(scrPtr->boldFont);
226 WMFont *WMSystemFontOfSize(WMScreen * scrPtr, int size)
231 fontSpec = makeFontOfSize(WINGsConfiguration.systemFont, size, NULL);
233 font = WMCreateFont(scrPtr, fontSpec);
236 wwarning(_("could not load font: %s."), fontSpec);
244 WMFont *WMBoldSystemFontOfSize(WMScreen * scrPtr, int size)
249 fontSpec = makeFontOfSize(WINGsConfiguration.boldSystemFont, size, NULL);
251 font = WMCreateFont(scrPtr, fontSpec);
254 wwarning(_("could not load font: %s."), fontSpec);
262 int WMWidthOfString(WMFont * font, char *text, int length)
266 wassertrv(font != NULL && text != NULL, 0);
268 XftTextExtentsUtf8(font->screen->display, font->font, (XftChar8 *) text, length, &extents);
270 return extents.xOff; /* don't ask :P */
273 void WMDrawString(WMScreen * scr, Drawable d, WMColor * color, WMFont * font, int x, int y, char *text, int length)
277 wassertr(font != NULL);
279 xftcolor.color.red = color->color.red;
280 xftcolor.color.green = color->color.green;
281 xftcolor.color.blue = color->color.blue;
282 xftcolor.color.alpha = color->alpha;;
283 xftcolor.pixel = W_PIXEL(color);
285 XftDrawChange(scr->xftdraw, d);
287 XftDrawStringUtf8(scr->xftdraw, &xftcolor, font->font, x, y + font->y, (XftChar8 *) text, length);
291 WMDrawImageString(WMScreen * scr, Drawable d, WMColor * color, WMColor * background,
292 WMFont * font, int x, int y, char *text, int length)
297 wassertr(font != NULL);
299 textColor.color.red = color->color.red;
300 textColor.color.green = color->color.green;
301 textColor.color.blue = color->color.blue;
302 textColor.color.alpha = color->alpha;;
303 textColor.pixel = W_PIXEL(color);
305 bgColor.color.red = background->color.red;
306 bgColor.color.green = background->color.green;
307 bgColor.color.blue = background->color.blue;
308 bgColor.color.alpha = background->alpha;;
309 bgColor.pixel = W_PIXEL(background);
311 XftDrawChange(scr->xftdraw, d);
313 XftDrawRect(scr->xftdraw, &bgColor, x, y, WMWidthOfString(font, text, length), font->height);
315 XftDrawStringUtf8(scr->xftdraw, &textColor, font->font, x, y + font->y, (XftChar8 *) text, length);
318 WMFont *WMCopyFontWithStyle(WMScreen * scrPtr, WMFont * font, WMFontStyle style)
327 /* It's enough to add italic to slant, even if the font has no italic
328 * variant, but only oblique. This is because fontconfig will actually
329 * return the closest match font to what we requested which is the
330 * oblique font. Same goes for using bold for weight.
332 pattern = FcNameParse((FcChar8 *) WMGetFontName(font));
335 FcPatternDel(pattern, FC_WEIGHT);
336 FcPatternDel(pattern, FC_SLANT);
339 FcPatternDel(pattern, FC_WEIGHT);
340 FcPatternAddString(pattern, FC_WEIGHT, (FcChar8 *) "bold");
343 FcPatternDel(pattern, FC_SLANT);
344 FcPatternAddString(pattern, FC_SLANT, (FcChar8 *) "italic");
347 FcPatternDel(pattern, FC_WEIGHT);
348 FcPatternDel(pattern, FC_SLANT);
349 FcPatternAddString(pattern, FC_WEIGHT, (FcChar8 *) "bold");
350 FcPatternAddString(pattern, FC_SLANT, (FcChar8 *) "italic");
354 name = (char *)FcNameUnparse(pattern);
355 copy = WMCreateFont(scrPtr, name);
356 FcPatternDestroy(pattern);