- Check whether libXft is at least version 2.1.2 else refuse to compile.
[wmaker-crm.git] / WINGs / wfont.c
blob89742f8deb5c12f17363cb49eca43145ad397607
2 #include "wconfig.h"
4 #ifdef XFT
6 #include <X11/Xft/Xft.h>
7 #include <fontconfig/fontconfig.h>
9 #include <stdlib.h>
11 #include "WINGsP.h"
13 #include <wraster.h>
14 #include <assert.h>
15 #include <X11/Xlocale.h>
18 #define DEFAULT_SIZE WINGsConfiguration.defaultFontSize
20 static char*
21 fixXLFD(char *xlfd, int size)
23 char *fname, *ptr;
25 fname = wmalloc(strlen(xlfd) + 20);
26 if (strstr(xlfd, "%d")!=NULL)
27 sprintf(fname, xlfd, size ? size : DEFAULT_SIZE);
28 else
29 strcpy(fname, xlfd);
31 if ((ptr = strchr(fname, ','))) {
32 *ptr = 0;
35 return fname;
39 static Bool
40 hasProperty(FcPattern *pattern, const char *property)
42 FcValue val;
44 if (FcPatternGet(pattern, property, 0, &val)==FcResultMatch) {
45 return True;
48 return False;
52 static Bool
53 hasPropertyWithStringValue(FcPattern *pattern, const char *object, char *value)
55 FcChar8 *str;
56 int id;
58 if (!value || value[0]==0)
59 return True;
61 id = 0;
62 while (FcPatternGetString(pattern, object, id, &str)==FcResultMatch) {
63 if (strcasecmp(value, (char*)str) == 0) {
64 return True;
66 id++;
69 return False;
73 // also handle an xlfd with %d for size?
74 static char*
75 makeFontOfSize(char *font, int size, char *fallback)
77 FcPattern *pattern;
78 char *result;
80 if (font[0]=='-') {
81 char *fname;
83 fname = fixXLFD(font, size);
84 pattern = XftXlfdParse(fname, False, False);
85 wfree(fname);
86 } else {
87 pattern = FcNameParse(font);
90 //FcPatternPrint(pattern);
91 if (size > 0) {
92 FcPatternDel(pattern, "pixelsize");
93 FcPatternAddDouble(pattern, "pixelsize", (double)size);
94 } else if (size==0 && !hasProperty(pattern, "size") &&
95 !hasProperty(pattern, "pixelsize")) {
96 FcPatternAddDouble(pattern, "pixelsize", (double)DEFAULT_SIZE);
99 if (fallback && !hasPropertyWithStringValue(pattern, "family", fallback)) {
100 FcPatternAddString(pattern, "family", fallback);
103 result = FcNameUnparse(pattern);
104 FcPatternDestroy(pattern);
106 return result;
110 WMFont*
111 WMCreateFont(WMScreen *scrPtr, char *fontName)
113 WMFont *font;
114 Display *display = scrPtr->display;
115 char *fname, *ptr;
117 /* This is for back-compat (to allow reading of old xlfd descriptions) */
118 if (fontName[0]=='-' && (ptr = strchr(fontName, ','))) {
119 // warn for deprecation
120 fname = wmalloc(ptr - fontName + 1);
121 strncpy(fname, fontName, ptr - fontName);
122 fname[ptr - fontName] = 0;
123 } else {
124 fname = wstrdup(fontName);
127 font = WMHashGet(scrPtr->fontCache, fname);
128 if (font) {
129 WMRetainFont(font);
130 wfree(fname);
131 return font;
134 font = wmalloc(sizeof(WMFont));
135 memset(font, 0, sizeof(WMFont));
137 font->screen = scrPtr;
139 // remove
140 printf("WMCreateFont: %s\n", fname);
142 if (fname[0] == '-') {
143 // Backward compat thing. Remove in a later version
144 font->font = XftFontOpenXlfd(display, scrPtr->screen, fname);
145 } else {
146 font->font = XftFontOpenName(display, scrPtr->screen, fname);
148 if (!font->font) {
149 wfree(font);
150 wfree(fname);
151 return NULL;
153 font->height = font->font->ascent+font->font->descent;
154 font->y = font->font->ascent;
156 font->refCount = 1;
158 font->name = fname;
160 assert(WMHashInsert(scrPtr->fontCache, font->name, font)==NULL);
162 return font;
166 WMFont*
167 WMRetainFont(WMFont *font)
169 wassertrv(font!=NULL, NULL);
171 font->refCount++;
173 return font;
177 void
178 WMReleaseFont(WMFont *font)
180 wassertr(font!=NULL);
182 font->refCount--;
183 if (font->refCount < 1) {
184 XftFontClose(font->screen->display, font->font);
185 if (font->name) {
186 WMHashRemove(font->screen->fontCache, font->name);
187 wfree(font->name);
189 wfree(font);
194 Bool
195 WMIsAntialiasingEnabled(WMScreen *scrPtr)
197 return scrPtr->antialiasedText;
201 unsigned int
202 WMFontHeight(WMFont *font)
204 wassertrv(font!=NULL, 0);
206 return font->height;
210 char*
211 WMGetFontName(WMFont *font)
213 wassertrv(font!=NULL, NULL);
215 return font->name;
219 WMFont*
220 WMDefaultSystemFont(WMScreen *scrPtr)
222 return WMRetainFont(scrPtr->normalFont);
226 WMFont*
227 WMDefaultBoldSystemFont(WMScreen *scrPtr)
229 return WMRetainFont(scrPtr->boldFont);
233 WMFont*
234 WMSystemFontOfSize(WMScreen *scrPtr, int size)
236 WMFont *font;
237 char *fontSpec;
239 fontSpec = makeFontOfSize(WINGsConfiguration.systemFont, size, "sans");
241 font = WMCreateFont(scrPtr, fontSpec);
243 if (!font) {
244 wwarning(_("could not load font %s."), fontSpec);
247 wfree(fontSpec);
249 return font;
253 WMFont*
254 WMBoldSystemFontOfSize(WMScreen *scrPtr, int size)
256 WMFont *font;
257 char *fontSpec;
259 fontSpec = makeFontOfSize(WINGsConfiguration.boldSystemFont, size, "sans");
261 font = WMCreateFont(scrPtr, fontSpec);
263 if (!font) {
264 wwarning(_("could not load font %s."), fontSpec);
267 wfree(fontSpec);
269 return font;
274 WMWidthOfString(WMFont *font, char *text, int length)
276 XGlyphInfo extents;
278 wassertrv(font!=NULL && text!=NULL, 0);
280 XftTextExtentsUtf8(font->screen->display, font->font,
281 (XftChar8 *)text, length, &extents);
283 return extents.xOff; /* don't ask :P */
288 void
289 WMDrawString(WMScreen *scr, Drawable d, WMColor *color, WMFont *font,
290 int x, int y, char *text, int length)
292 XftColor xftcolor;
294 wassertr(font!=NULL);
296 xftcolor.color.red = color->color.red;
297 xftcolor.color.green = color->color.green;
298 xftcolor.color.blue = color->color.blue;
299 xftcolor.color.alpha = color->alpha;;
300 xftcolor.pixel = W_PIXEL(color);
302 XftDrawChange(scr->xftdraw, d);
304 XftDrawStringUtf8(scr->xftdraw, &xftcolor, font->font,
305 x, y + font->y, (XftChar8*)text, length);
309 void
310 WMDrawImageString(WMScreen *scr, Drawable d, WMColor *color, WMColor *background,
311 WMFont *font, int x, int y, char *text, int length)
313 XftColor textColor;
314 XftColor bgColor;
316 wassertr(font!=NULL);
318 textColor.color.red = color->color.red;
319 textColor.color.green = color->color.green;
320 textColor.color.blue = color->color.blue;
321 textColor.color.alpha = color->alpha;;
322 textColor.pixel = W_PIXEL(color);
324 bgColor.color.red = background->color.red;
325 bgColor.color.green = background->color.green;
326 bgColor.color.blue = background->color.blue;
327 bgColor.color.alpha = background->alpha;;
328 bgColor.pixel = W_PIXEL(background);
330 XftDrawChange(scr->xftdraw, d);
332 XftDrawRect(scr->xftdraw, &bgColor, x, y,
333 WMWidthOfString(font, text, length),
334 font->height);
336 XftDrawStringUtf8(scr->xftdraw, &textColor, font->font,
337 x, y + font->y, (XftChar8*)text, length);
341 WMFont*
342 WMCopyFontWithStyle(WMScreen *scrPtr, WMFont *font, WMFontStyle style)
344 FcPattern *pattern;
345 WMFont *copy;
346 char *name;
348 if (!font)
349 return NULL;
351 pattern = FcNameParse(WMGetFontName(font));
352 switch (style) {
353 case WFSNormal:
354 FcPatternDel(pattern, "weight");
355 FcPatternDel(pattern, "slant");
356 FcPatternAddString(pattern, "weight", "regular");
357 FcPatternAddString(pattern, "weight", "medium");
358 FcPatternAddString(pattern, "slant", "roman");
359 break;
360 case WFSBold:
361 FcPatternDel(pattern, "weight");
362 FcPatternAddString(pattern, "weight", "bold");
363 break;
364 case WFSEmphasized:
365 FcPatternDel(pattern, "slant");
366 FcPatternAddString(pattern, "slant", "italic");
367 FcPatternAddString(pattern, "slant", "oblique");
368 break;
369 case WFSBoldEmphasized:
370 FcPatternDel(pattern, "weight");
371 FcPatternDel(pattern, "slant");
372 FcPatternAddString(pattern, "weight", "bold");
373 FcPatternAddString(pattern, "slant", "italic");
374 FcPatternAddString(pattern, "slant", "oblique");
375 break;
378 name = FcNameUnparse(pattern);
379 copy = WMCreateFont(scrPtr, name);
380 FcPatternDestroy(pattern);
381 wfree(name);
383 return copy;
387 #endif /* XFT */