use macros for property names
[wmaker-crm.git] / WINGs / wfont.c
blob8cc16450d11db76718ef40d3ffb751caad83ffa7
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, FC_PIXEL_SIZE);
93 FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)size);
94 } else if (size==0 && !hasProperty(pattern, "size") &&
95 !hasProperty(pattern, FC_PIXEL_SIZE)) {
96 FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)DEFAULT_SIZE);
99 if (fallback && !hasPropertyWithStringValue(pattern, FC_FAMILY, fallback)) {
100 FcPatternAddString(pattern, FC_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 if (fname[0] == '-') {
140 // Backward compat thing. Remove in a later version
141 font->font = XftFontOpenXlfd(display, scrPtr->screen, fname);
142 } else {
143 font->font = XftFontOpenName(display, scrPtr->screen, fname);
145 if (!font->font) {
146 wfree(font);
147 wfree(fname);
148 return NULL;
150 font->height = font->font->ascent+font->font->descent;
151 font->y = font->font->ascent;
153 font->refCount = 1;
155 font->name = fname;
157 assert(WMHashInsert(scrPtr->fontCache, font->name, font)==NULL);
159 return font;
163 WMFont*
164 WMRetainFont(WMFont *font)
166 wassertrv(font!=NULL, NULL);
168 font->refCount++;
170 return font;
174 void
175 WMReleaseFont(WMFont *font)
177 wassertr(font!=NULL);
179 font->refCount--;
180 if (font->refCount < 1) {
181 XftFontClose(font->screen->display, font->font);
182 if (font->name) {
183 WMHashRemove(font->screen->fontCache, font->name);
184 wfree(font->name);
186 wfree(font);
191 Bool
192 WMIsAntialiasingEnabled(WMScreen *scrPtr)
194 return scrPtr->antialiasedText;
198 unsigned int
199 WMFontHeight(WMFont *font)
201 wassertrv(font!=NULL, 0);
203 return font->height;
207 char*
208 WMGetFontName(WMFont *font)
210 wassertrv(font!=NULL, NULL);
212 return font->name;
216 WMFont*
217 WMDefaultSystemFont(WMScreen *scrPtr)
219 return WMRetainFont(scrPtr->normalFont);
223 WMFont*
224 WMDefaultBoldSystemFont(WMScreen *scrPtr)
226 return WMRetainFont(scrPtr->boldFont);
230 WMFont*
231 WMSystemFontOfSize(WMScreen *scrPtr, int size)
233 WMFont *font;
234 char *fontSpec;
236 fontSpec = makeFontOfSize(WINGsConfiguration.systemFont, size, "sans");
238 font = WMCreateFont(scrPtr, fontSpec);
240 if (!font) {
241 wwarning(_("could not load font %s."), fontSpec);
244 wfree(fontSpec);
246 return font;
250 WMFont*
251 WMBoldSystemFontOfSize(WMScreen *scrPtr, int size)
253 WMFont *font;
254 char *fontSpec;
256 fontSpec = makeFontOfSize(WINGsConfiguration.boldSystemFont, size, "sans");
258 font = WMCreateFont(scrPtr, fontSpec);
260 if (!font) {
261 wwarning(_("could not load font %s."), fontSpec);
264 wfree(fontSpec);
266 return font;
271 WMWidthOfString(WMFont *font, char *text, int length)
273 XGlyphInfo extents;
275 wassertrv(font!=NULL && text!=NULL, 0);
277 XftTextExtentsUtf8(font->screen->display, font->font,
278 (XftChar8 *)text, length, &extents);
280 return extents.xOff; /* don't ask :P */
285 void
286 WMDrawString(WMScreen *scr, Drawable d, WMColor *color, WMFont *font,
287 int x, int y, char *text, int length)
289 XftColor xftcolor;
291 wassertr(font!=NULL);
293 xftcolor.color.red = color->color.red;
294 xftcolor.color.green = color->color.green;
295 xftcolor.color.blue = color->color.blue;
296 xftcolor.color.alpha = color->alpha;;
297 xftcolor.pixel = W_PIXEL(color);
299 XftDrawChange(scr->xftdraw, d);
301 XftDrawStringUtf8(scr->xftdraw, &xftcolor, font->font,
302 x, y + font->y, (XftChar8*)text, length);
306 void
307 WMDrawImageString(WMScreen *scr, Drawable d, WMColor *color, WMColor *background,
308 WMFont *font, int x, int y, char *text, int length)
310 XftColor textColor;
311 XftColor bgColor;
313 wassertr(font!=NULL);
315 textColor.color.red = color->color.red;
316 textColor.color.green = color->color.green;
317 textColor.color.blue = color->color.blue;
318 textColor.color.alpha = color->alpha;;
319 textColor.pixel = W_PIXEL(color);
321 bgColor.color.red = background->color.red;
322 bgColor.color.green = background->color.green;
323 bgColor.color.blue = background->color.blue;
324 bgColor.color.alpha = background->alpha;;
325 bgColor.pixel = W_PIXEL(background);
327 XftDrawChange(scr->xftdraw, d);
329 XftDrawRect(scr->xftdraw, &bgColor, x, y,
330 WMWidthOfString(font, text, length),
331 font->height);
333 XftDrawStringUtf8(scr->xftdraw, &textColor, font->font,
334 x, y + font->y, (XftChar8*)text, length);
338 WMFont*
339 WMCopyFontWithStyle(WMScreen *scrPtr, WMFont *font, WMFontStyle style)
341 FcPattern *pattern;
342 WMFont *copy;
343 char *name;
345 if (!font)
346 return NULL;
348 pattern = FcNameParse(WMGetFontName(font));
349 switch (style) {
350 case WFSNormal:
351 FcPatternDel(pattern, FC_WEIGHT);
352 FcPatternDel(pattern, FC_SLANT);
353 FcPatternAddString(pattern, FC_WEIGHT, "regular");
354 FcPatternAddString(pattern, FC_WEIGHT, "medium");
355 FcPatternAddString(pattern, FC_SLANT, "roman");
356 break;
357 case WFSBold:
358 FcPatternDel(pattern, FC_WEIGHT);
359 FcPatternAddString(pattern, FC_WEIGHT, "bold");
360 break;
361 case WFSEmphasized:
362 FcPatternDel(pattern, FC_SLANT);
363 FcPatternAddString(pattern, FC_SLANT, "italic");
364 FcPatternAddString(pattern, FC_SLANT, "oblique");
365 break;
366 case WFSBoldEmphasized:
367 FcPatternDel(pattern, FC_WEIGHT);
368 FcPatternDel(pattern, FC_SLANT);
369 FcPatternAddString(pattern, FC_WEIGHT, "bold");
370 FcPatternAddString(pattern, FC_SLANT, "italic");
371 FcPatternAddString(pattern, FC_SLANT, "oblique");
372 break;
375 name = FcNameUnparse(pattern);
376 copy = WMCreateFont(scrPtr, name);
377 FcPatternDestroy(pattern);
378 wfree(name);
380 return copy;
384 #endif /* XFT */