set charset to utf-8
[wmaker-crm.git] / WINGs / wfont.c
blob0201735b37b46aa10e3e23d474a9ae21d10bc35d
2 #include "wconfig.h"
4 #include <X11/Xft/Xft.h>
5 #include <fontconfig/fontconfig.h>
7 #include <stdlib.h>
9 #include "WINGsP.h"
11 #include <wraster.h>
12 #include <assert.h>
13 #include <X11/Xlocale.h>
16 #define DEFAULT_SIZE WINGsConfiguration.defaultFontSize
18 static char*
19 fixXLFD(char *xlfd, int size)
21 char *fname, *ptr;
23 fname = wmalloc(strlen(xlfd) + 20);
24 if (strstr(xlfd, "%d")!=NULL)
25 sprintf(fname, xlfd, size ? size : DEFAULT_SIZE);
26 else
27 strcpy(fname, xlfd);
29 if ((ptr = strchr(fname, ','))) {
30 *ptr = 0;
33 return fname;
37 static Bool
38 hasProperty(FcPattern *pattern, const char *property)
40 FcValue val;
42 if (FcPatternGet(pattern, property, 0, &val)==FcResultMatch) {
43 return True;
46 return False;
50 static Bool
51 hasPropertyWithStringValue(FcPattern *pattern, const char *object, char *value)
53 FcChar8 *str;
54 int id;
56 if (!value || value[0]==0)
57 return True;
59 id = 0;
60 while (FcPatternGetString(pattern, object, id, &str)==FcResultMatch) {
61 if (strcasecmp(value, (char*)str) == 0) {
62 return True;
64 id++;
67 return False;
71 // also handle an xlfd with %d for size?
72 static char*
73 makeFontOfSize(char *font, int size, char *fallback)
75 FcPattern *pattern;
76 char *result;
78 if (font[0]=='-') {
79 char *fname;
81 fname = fixXLFD(font, size);
82 pattern = XftXlfdParse(fname, False, False);
83 wfree(fname);
84 } else {
85 pattern = FcNameParse(font);
88 //FcPatternPrint(pattern);
89 if (size > 0) {
90 FcPatternDel(pattern, FC_PIXEL_SIZE);
91 FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)size);
92 } else if (size==0 && !hasProperty(pattern, "size") &&
93 !hasProperty(pattern, FC_PIXEL_SIZE)) {
94 FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)DEFAULT_SIZE);
97 if (fallback && !hasPropertyWithStringValue(pattern, FC_FAMILY, fallback)) {
98 FcPatternAddString(pattern, FC_FAMILY, fallback);
101 result = FcNameUnparse(pattern);
102 FcPatternDestroy(pattern);
104 return result;
108 WMFont*
109 WMCreateFont(WMScreen *scrPtr, char *fontName)
111 WMFont *font;
112 Display *display = scrPtr->display;
113 char *fname, *ptr;
115 /* This is for back-compat (to allow reading of old xlfd descriptions) */
116 if (fontName[0]=='-' && (ptr = strchr(fontName, ','))) {
117 // warn for deprecation
118 fname = wmalloc(ptr - fontName + 1);
119 strncpy(fname, fontName, ptr - fontName);
120 fname[ptr - fontName] = 0;
121 } else {
122 fname = wstrdup(fontName);
125 font = WMHashGet(scrPtr->fontCache, fname);
126 if (font) {
127 WMRetainFont(font);
128 wfree(fname);
129 return font;
132 font = wmalloc(sizeof(WMFont));
133 memset(font, 0, sizeof(WMFont));
135 font->screen = scrPtr;
137 if (fname[0] == '-') {
138 // Backward compat thing. Remove in a later version
139 font->font = XftFontOpenXlfd(display, scrPtr->screen, fname);
140 } else {
141 font->font = XftFontOpenName(display, scrPtr->screen, fname);
143 if (!font->font) {
144 wfree(font);
145 wfree(fname);
146 return NULL;
148 font->height = font->font->ascent+font->font->descent;
149 font->y = font->font->ascent;
151 font->refCount = 1;
153 font->name = fname;
155 assert(WMHashInsert(scrPtr->fontCache, font->name, font)==NULL);
157 return font;
161 WMFont*
162 WMRetainFont(WMFont *font)
164 wassertrv(font!=NULL, NULL);
166 font->refCount++;
168 return font;
172 void
173 WMReleaseFont(WMFont *font)
175 wassertr(font!=NULL);
177 font->refCount--;
178 if (font->refCount < 1) {
179 XftFontClose(font->screen->display, font->font);
180 if (font->name) {
181 WMHashRemove(font->screen->fontCache, font->name);
182 wfree(font->name);
184 wfree(font);
189 Bool
190 WMIsAntialiasingEnabled(WMScreen *scrPtr)
192 return scrPtr->antialiasedText;
196 unsigned int
197 WMFontHeight(WMFont *font)
199 wassertrv(font!=NULL, 0);
201 return font->height;
205 char*
206 WMGetFontName(WMFont *font)
208 wassertrv(font!=NULL, NULL);
210 return font->name;
214 WMFont*
215 WMDefaultSystemFont(WMScreen *scrPtr)
217 return WMRetainFont(scrPtr->normalFont);
221 WMFont*
222 WMDefaultBoldSystemFont(WMScreen *scrPtr)
224 return WMRetainFont(scrPtr->boldFont);
228 WMFont*
229 WMSystemFontOfSize(WMScreen *scrPtr, int size)
231 WMFont *font;
232 char *fontSpec;
234 fontSpec = makeFontOfSize(WINGsConfiguration.systemFont, size, "sans");
236 font = WMCreateFont(scrPtr, fontSpec);
238 if (!font) {
239 wwarning(_("could not load font %s."), fontSpec);
242 wfree(fontSpec);
244 return font;
248 WMFont*
249 WMBoldSystemFontOfSize(WMScreen *scrPtr, int size)
251 WMFont *font;
252 char *fontSpec;
254 fontSpec = makeFontOfSize(WINGsConfiguration.boldSystemFont, size, "sans");
256 font = WMCreateFont(scrPtr, fontSpec);
258 if (!font) {
259 wwarning(_("could not load font %s."), fontSpec);
262 wfree(fontSpec);
264 return font;
269 WMWidthOfString(WMFont *font, char *text, int length)
271 XGlyphInfo extents;
273 wassertrv(font!=NULL && text!=NULL, 0);
275 XftTextExtentsUtf8(font->screen->display, font->font,
276 (XftChar8 *)text, length, &extents);
278 return extents.xOff; /* don't ask :P */
283 void
284 WMDrawString(WMScreen *scr, Drawable d, WMColor *color, WMFont *font,
285 int x, int y, char *text, int length)
287 XftColor xftcolor;
289 wassertr(font!=NULL);
291 xftcolor.color.red = color->color.red;
292 xftcolor.color.green = color->color.green;
293 xftcolor.color.blue = color->color.blue;
294 xftcolor.color.alpha = color->alpha;;
295 xftcolor.pixel = W_PIXEL(color);
297 XftDrawChange(scr->xftdraw, d);
299 XftDrawStringUtf8(scr->xftdraw, &xftcolor, font->font,
300 x, y + font->y, (XftChar8*)text, length);
304 void
305 WMDrawImageString(WMScreen *scr, Drawable d, WMColor *color, WMColor *background,
306 WMFont *font, int x, int y, char *text, int length)
308 XftColor textColor;
309 XftColor bgColor;
311 wassertr(font!=NULL);
313 textColor.color.red = color->color.red;
314 textColor.color.green = color->color.green;
315 textColor.color.blue = color->color.blue;
316 textColor.color.alpha = color->alpha;;
317 textColor.pixel = W_PIXEL(color);
319 bgColor.color.red = background->color.red;
320 bgColor.color.green = background->color.green;
321 bgColor.color.blue = background->color.blue;
322 bgColor.color.alpha = background->alpha;;
323 bgColor.pixel = W_PIXEL(background);
325 XftDrawChange(scr->xftdraw, d);
327 XftDrawRect(scr->xftdraw, &bgColor, x, y,
328 WMWidthOfString(font, text, length),
329 font->height);
331 XftDrawStringUtf8(scr->xftdraw, &textColor, font->font,
332 x, y + font->y, (XftChar8*)text, length);
336 WMFont*
337 WMCopyFontWithStyle(WMScreen *scrPtr, WMFont *font, WMFontStyle style)
339 FcPattern *pattern;
340 WMFont *copy;
341 char *name;
343 if (!font)
344 return NULL;
346 pattern = FcNameParse(WMGetFontName(font));
347 switch (style) {
348 case WFSNormal:
349 FcPatternDel(pattern, FC_WEIGHT);
350 FcPatternDel(pattern, FC_SLANT);
351 FcPatternAddString(pattern, FC_WEIGHT, "regular");
352 FcPatternAddString(pattern, FC_WEIGHT, "medium");
353 FcPatternAddString(pattern, FC_SLANT, "roman");
354 break;
355 case WFSBold:
356 FcPatternDel(pattern, FC_WEIGHT);
357 FcPatternAddString(pattern, FC_WEIGHT, "bold");
358 break;
359 case WFSEmphasized:
360 FcPatternDel(pattern, FC_SLANT);
361 FcPatternAddString(pattern, FC_SLANT, "italic");
362 FcPatternAddString(pattern, FC_SLANT, "oblique");
363 break;
364 case WFSBoldEmphasized:
365 FcPatternDel(pattern, FC_WEIGHT);
366 FcPatternDel(pattern, FC_SLANT);
367 FcPatternAddString(pattern, FC_WEIGHT, "bold");
368 FcPatternAddString(pattern, FC_SLANT, "italic");
369 FcPatternAddString(pattern, FC_SLANT, "oblique");
370 break;
373 name = FcNameUnparse(pattern);
374 copy = WMCreateFont(scrPtr, name);
375 FcPatternDestroy(pattern);
376 wfree(name);
378 return copy;