Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / wfont_wchar.c
Commit [+]AuthorDateLineData
9aca0d5f dan2004-10-12 01:34:32 +00001
2#include "wconfig.h"
3
4#ifdef XFT
5
6#include <X11/Xft/Xft.h>
7#include <fontconfig/fontconfig.h>
8
9#if defined(HAVE_MBSNRTOWCS)
10# define __USE_GNU
11#endif
12
13#ifdef HAVE_WCHAR_H
14# include <wchar.h>
15#endif
16
17#include <stdlib.h>
18
19#include "WINGsP.h"
20
21#include <wraster.h>
22#include <assert.h>
23#include <X11/Xlocale.h>
24
9aca0d5f dan2004-10-12 01:34:32 +000025// && defined(HAVE_MBSTATE_T___COUNT)
26// in configure.ac use AC_CHECK_MEMBER(struct mbstate_t.__count,
27// have=1, have=0, [#include <wchar.h>])
28#if defined(HAVE_MBSNRTOWCS)
29
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020030static size_t wmbsnrtowcs(wchar_t * dest, const char **src, size_t nbytes, size_t len)
9aca0d5f dan2004-10-12 01:34:32 +000031{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020032 mbstate_t ps;
33 size_t n;
9aca0d5f dan2004-10-12 01:34:32 +000034
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020035 memset(&ps, 0, sizeof(mbstate_t));
36 n = mbsnrtowcs(dest, src, nbytes, len, &ps);
37 if (n != (size_t) - 1 && *src) {
38 *src -= ps.__count;
39 }
9aca0d5f dan2004-10-12 01:34:32 +000040
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020041 return n;
9aca0d5f dan2004-10-12 01:34:32 +000042}
43
44#elif defined(HAVE_MBRTOWC)
45
46// This is 8 times slower than the version above.
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020047static size_t wmbsnrtowcs(wchar_t * dest, const char **src, size_t nbytes, size_t len)
9aca0d5f dan2004-10-12 01:34:32 +000048{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020049 mbstate_t ps;
50 const char *ptr;
51 size_t n;
52 int nb;
53
54 if (nbytes == 0)
55 return 0;
56
57 memset(&ps, 0, sizeof(mbstate_t));
58
59 if (dest == NULL) {
60 for (ptr = *src, n = 0; nbytes > 0; n++) {
61 nb = mbrtowc(NULL, ptr, nbytes, &ps);
62 if (nb == -1) {
63 return ((size_t) - 1);
64 } else if (nb == 0 || nb == -2) {
65 return n;
66 }
67 ptr += nb;
68 nbytes -= nb;
69 }
70 }
71
72 for (ptr = *src, n = 0; n < len && nbytes > 0; n++, dest++) {
73 nb = mbrtowc(dest, ptr, nbytes, &ps);
74 if (nb == -2) {
75 *src = ptr;
76 return n;
77 } else if (nb == -1) {
78 *src = ptr;
79 return ((size_t) - 1);
80 } else if (nb == 0) {
81 *src = NULL;
82 return n;
83 }
84 ptr += nb;
85 nbytes -= nb;
86 }
87
88 *src = ptr;
89 return n;
9aca0d5f dan2004-10-12 01:34:32 +000090}
91
92#else
93
94// Not only 8 times slower than the version based on mbsnrtowcs
95// but also this version is not thread safe nor reentrant
96
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020097static size_t wmbsnrtowcs(wchar_t * dest, const char **src, size_t nbytes, size_t len)
9aca0d5f dan2004-10-12 01:34:32 +000098{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020099 const char *ptr;
100 size_t n;
101 int nb;
102
103 if (nbytes == 0)
104 return 0;
105
106 mbtowc(NULL, NULL, 0); /* reset shift state */
107
108 if (dest == NULL) {
109 for (ptr = *src, n = 0; nbytes > 0; n++) {
110 nb = mbtowc(NULL, ptr, nbytes);
111 if (nb == -1) {
112 mbtowc(NULL, NULL, 0);
113 nb = mbtowc(NULL, ptr, strlen(ptr));
114 return (nb == -1 ? (size_t) - 1 : n);
115 } else if (nb == 0) {
116 return n;
117 }
118 ptr += nb;
119 nbytes -= nb;
120 }
121 }
122
123 for (ptr = *src, n = 0; n < len && nbytes > 0; n++, dest++) {
124 nb = mbtowc(dest, ptr, nbytes);
125 if (nb == -1) {
126 mbtowc(NULL, NULL, 0);
127 nb = mbtowc(NULL, ptr, strlen(ptr));
128 *src = ptr;
129 return (nb == -1 ? (size_t) - 1 : n);
130 } else if (nb == 0) {
131 *src = NULL;
132 return n;
133 }
134 ptr += nb;
135 nbytes -= nb;
136 }
137
138 *src = ptr;
139 return n;
9aca0d5f dan2004-10-12 01:34:32 +0000140}
141
142#endif
143
9aca0d5f dan2004-10-12 01:34:32 +0000144#define DEFAULT_SIZE 12
145
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200146static char *fixXLFD(char *xlfd, int size)
9aca0d5f dan2004-10-12 01:34:32 +0000147{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200148 char *fname, *ptr;
9aca0d5f dan2004-10-12 01:34:32 +0000149
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200150 fname = wmalloc(strlen(xlfd) + 20);
151 if (strstr(xlfd, "%d") != NULL)
152 sprintf(fname, xlfd, size ? size : DEFAULT_SIZE);
153 else
154 strcpy(fname, xlfd);
9aca0d5f dan2004-10-12 01:34:32 +0000155
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200156 if ((ptr = strchr(fname, ','))) {
157 *ptr = 0;
158 }
9aca0d5f dan2004-10-12 01:34:32 +0000159
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200160 return fname;
9aca0d5f dan2004-10-12 01:34:32 +0000161}
162
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200163static Bool hasProperty(FcPattern * pattern, const char *property)
9aca0d5f dan2004-10-12 01:34:32 +0000164{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200165 FcValue val;
9aca0d5f dan2004-10-12 01:34:32 +0000166
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200167 if (FcPatternGet(pattern, property, 0, &val) == FcResultMatch) {
168 return True;
169 }
9aca0d5f dan2004-10-12 01:34:32 +0000170
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200171 return False;
9aca0d5f dan2004-10-12 01:34:32 +0000172}
173
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200174static Bool hasPropertyWithStringValue(FcPattern * pattern, const char *object, char *value)
9aca0d5f dan2004-10-12 01:34:32 +0000175{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200176 FcChar8 *str;
177 int id;
9aca0d5f dan2004-10-12 01:34:32 +0000178
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200179 if (!value || value[0] == 0)
180 return True;
9aca0d5f dan2004-10-12 01:34:32 +0000181
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200182 id = 0;
183 while (FcPatternGetString(pattern, object, id, &str) == FcResultMatch) {
184 if (strcasecmp(value, (char *)str) == 0) {
185 return True;
186 }
187 id++;
188 }
9aca0d5f dan2004-10-12 01:34:32 +0000189
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200190 return False;
9aca0d5f dan2004-10-12 01:34:32 +0000191}
192
9aca0d5f dan2004-10-12 01:34:32 +0000193// also handle an xlfd with %d for size?
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200194static char *makeFontOfSize(char *font, int size, char *fallback)
9aca0d5f dan2004-10-12 01:34:32 +0000195{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200196 FcPattern *pattern;
197 char *result;
198
199 if (font[0] == '-') {
200 char *fname;
201
202 fname = fixXLFD(font, size);
203 pattern = XftXlfdParse(fname, False, False);
204 wfree(fname);
205 } else {
206 pattern = FcNameParse(font);
207 }
208
209 //FcPatternPrint(pattern);
210 if (size > 0) {
211 FcPatternDel(pattern, "pixelsize");
212 FcPatternAddDouble(pattern, "pixelsize", (double)size);
213 } else if (size == 0 && !hasProperty(pattern, "size") && !hasProperty(pattern, "pixelsize")) {
214 FcPatternAddDouble(pattern, "pixelsize", (double)DEFAULT_SIZE);
215 }
216
217 if (fallback && !hasPropertyWithStringValue(pattern, "family", fallback)) {
218 FcPatternAddString(pattern, "family", fallback);
219 }
220
221 result = FcNameUnparse(pattern);
222 FcPatternDestroy(pattern);
223
224 return result;
9aca0d5f dan2004-10-12 01:34:32 +0000225}
226
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200227WMFont *WMCreateFont(WMScreen * scrPtr, char *fontName)
9aca0d5f dan2004-10-12 01:34:32 +0000228{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200229 WMFont *font;
230 Display *display = scrPtr->display;
231 char *fname, *ptr;
232
233 /* This is for back-compat (to allow reading of old xlfd descriptions) */
234 if (fontName[0] == '-' && (ptr = strchr(fontName, ','))) {
235 // warn for deprecation
236 fname = wmalloc(ptr - fontName + 1);
237 strncpy(fname, fontName, ptr - fontName);
238 fname[ptr - fontName] = 0;
239 } else {
240 fname = wstrdup(fontName);
241 }
242
243 font = WMHashGet(scrPtr->fontCache, fname);
244 if (font) {
245 WMRetainFont(font);
246 wfree(fname);
247 return font;
248 }
249
250 font = wmalloc(sizeof(WMFont));
251 memset(font, 0, sizeof(WMFont));
252
253 font->screen = scrPtr;
254
255 // remove
256 printf("WMCreateFont: %s\n", fname);
257
258 if (fname[0] == '-') {
259 // Backward compat thing. Remove in a later version
260 font->font = XftFontOpenXlfd(display, scrPtr->screen, fname);
261 } else {
262 font->font = XftFontOpenName(display, scrPtr->screen, fname);
263 }
264 if (!font->font) {
265 wfree(font);
266 wfree(fname);
267 return NULL;
268 }
269 font->height = font->font->ascent + font->font->descent;
270 font->y = font->font->ascent;
271
272 font->refCount = 1;
273
274 font->name = fname;
275
276 assert(WMHashInsert(scrPtr->fontCache, font->name, font) == NULL);
277
278 return font;
9aca0d5f dan2004-10-12 01:34:32 +0000279}
280
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200281WMFont *WMRetainFont(WMFont * font)
9aca0d5f dan2004-10-12 01:34:32 +0000282{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200283 wassertrv(font != NULL, NULL);
9aca0d5f dan2004-10-12 01:34:32 +0000284
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200285 font->refCount++;
9aca0d5f dan2004-10-12 01:34:32 +0000286
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200287 return font;
9aca0d5f dan2004-10-12 01:34:32 +0000288}
289
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200290void WMReleaseFont(WMFont * font)
9aca0d5f dan2004-10-12 01:34:32 +0000291{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200292 wassertr(font != NULL);
293
294 font->refCount--;
295 if (font->refCount < 1) {
296 XftFontClose(font->screen->display, font->font);
297 if (font->name) {
298 WMHashRemove(font->screen->fontCache, font->name);
299 wfree(font->name);
300 }
301 wfree(font);
302 }
9aca0d5f dan2004-10-12 01:34:32 +0000303}
304
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200305Bool WMIsAntialiasingEnabled(WMScreen * scrPtr)
9aca0d5f dan2004-10-12 01:34:32 +0000306{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200307 return scrPtr->antialiasedText;
9aca0d5f dan2004-10-12 01:34:32 +0000308}
309
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200310unsigned int WMFontHeight(WMFont * font)
9aca0d5f dan2004-10-12 01:34:32 +0000311{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200312 wassertrv(font != NULL, 0);
9aca0d5f dan2004-10-12 01:34:32 +0000313
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200314 return font->height;
9aca0d5f dan2004-10-12 01:34:32 +0000315}
316
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200317char *WMGetFontName(WMFont * font)
9aca0d5f dan2004-10-12 01:34:32 +0000318{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200319 wassertrv(font != NULL, NULL);
9aca0d5f dan2004-10-12 01:34:32 +0000320
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200321 return font->name;
9aca0d5f dan2004-10-12 01:34:32 +0000322}
323
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200324WMFont *WMDefaultSystemFont(WMScreen * scrPtr)
9aca0d5f dan2004-10-12 01:34:32 +0000325{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200326 return WMRetainFont(scrPtr->normalFont);
9aca0d5f dan2004-10-12 01:34:32 +0000327}
328
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200329WMFont *WMDefaultBoldSystemFont(WMScreen * scrPtr)
9aca0d5f dan2004-10-12 01:34:32 +0000330{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200331 return WMRetainFont(scrPtr->boldFont);
9aca0d5f dan2004-10-12 01:34:32 +0000332}
333
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200334WMFont *WMSystemFontOfSize(WMScreen * scrPtr, int size)
9aca0d5f dan2004-10-12 01:34:32 +0000335{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200336 WMFont *font;
337 char *fontSpec;
9aca0d5f dan2004-10-12 01:34:32 +0000338
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200339 fontSpec = makeFontOfSize(WINGsConfiguration.systemFont, size, "sans");
9aca0d5f dan2004-10-12 01:34:32 +0000340
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200341 font = WMCreateFont(scrPtr, fontSpec);
9aca0d5f dan2004-10-12 01:34:32 +0000342
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200343 if (!font) {
344 wwarning(_("could not load font %s."), fontSpec);
345 }
9aca0d5f dan2004-10-12 01:34:32 +0000346
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200347 wfree(fontSpec);
9aca0d5f dan2004-10-12 01:34:32 +0000348
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200349 return font;
9aca0d5f dan2004-10-12 01:34:32 +0000350}
351
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200352WMFont *WMBoldSystemFontOfSize(WMScreen * scrPtr, int size)
9aca0d5f dan2004-10-12 01:34:32 +0000353{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200354 WMFont *font;
355 char *fontSpec;
9aca0d5f dan2004-10-12 01:34:32 +0000356
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200357 fontSpec = makeFontOfSize(WINGsConfiguration.boldSystemFont, size, "sans");
9aca0d5f dan2004-10-12 01:34:32 +0000358
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200359 font = WMCreateFont(scrPtr, fontSpec);
9aca0d5f dan2004-10-12 01:34:32 +0000360
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200361 if (!font) {
362 wwarning(_("could not load font %s."), fontSpec);
363 }
9aca0d5f dan2004-10-12 01:34:32 +0000364
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200365 wfree(fontSpec);
9aca0d5f dan2004-10-12 01:34:32 +0000366
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200367 return font;
9aca0d5f dan2004-10-12 01:34:32 +0000368}
369
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200370int WMWidthOfString(WMFont * font, char *text, int length)
9aca0d5f dan2004-10-12 01:34:32 +0000371{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200372 XGlyphInfo extents;
373
374 wassertrv(font != NULL, 0);
375 wassertrv(text != NULL, 0);
376
377 if (font->screen->useWideChar) {
378 wchar_t *wtext;
379 const char *mtext;
380 int len;
381
382 wtext = (wchar_t *) wmalloc(sizeof(wchar_t) * (length + 1));
383 mtext = text;
384 len = wmbsnrtowcs(wtext, &mtext, length, length);
385 if (len > 0) {
386 wtext[len] = L'\0'; /* not really necessary here */
387 XftTextExtents32(font->screen->display, font->font, (XftChar32 *) wtext, len, &extents);
388 } else {
389 if (len == -1) {
390 wwarning(_("Conversion to widechar failed (possible "
391 "invalid multibyte sequence): '%s':(pos %d)\n"),
392 text, mtext - text + 1);
393 }
394 extents.xOff = 0;
395 }
396 wfree(wtext);
397 } else if (font->screen->useMultiByte) {
398 XftTextExtentsUtf8(font->screen->display, font->font, (XftChar8 *) text, length, &extents);
399 } else {
400 XftTextExtents8(font->screen->display, font->font, (XftChar8 *) text, length, &extents);
401 }
402
403 return extents.xOff; /* don't ask :P */
9aca0d5f dan2004-10-12 01:34:32 +0000404}
405
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200406void WMDrawString(WMScreen * scr, Drawable d, WMColor * color, WMFont * font, int x, int y, char *text, int length)
9aca0d5f dan2004-10-12 01:34:32 +0000407{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200408 XftColor xftcolor;
409
410 wassertr(font != NULL);
411
412 xftcolor.color.red = color->color.red;
413 xftcolor.color.green = color->color.green;
414 xftcolor.color.blue = color->color.blue;
415 xftcolor.color.alpha = color->alpha;;
416 xftcolor.pixel = W_PIXEL(color);
417
418 XftDrawChange(scr->xftdraw, d);
419
420 if (font->screen->useWideChar) {
421 wchar_t *wtext;
422 const char *mtext;
423 int len;
424
425 wtext = (wchar_t *) wmalloc(sizeof(wchar_t) * (length + 1));
426 mtext = text;
427 len = wmbsnrtowcs(wtext, &mtext, length, length);
428 if (len > 0) {
429 XftDrawString32(scr->xftdraw, &xftcolor, font->font,
430 x, y + font->y, (XftChar32 *) wtext, len);
431 } else if (len == -1) {
432 wwarning(_("Conversion to widechar failed (possible invalid "
433 "multibyte sequence): '%s':(pos %d)\n"), text, mtext - text + 1);
434 /* we can draw normal text, or we can draw as much widechar
435 * text as was already converted until the error. go figure */
436 /*XftDrawString8(scr->xftdraw, &xftcolor, font->font,
437 x, y + font->y, (XftChar8*)text, length); */
438 }
439 wfree(wtext);
440 } else if (font->screen->useMultiByte) {
441 XftDrawStringUtf8(scr->xftdraw, &xftcolor, font->font, x, y + font->y, (XftChar8 *) text, length);
442 } else {
443 XftDrawString8(scr->xftdraw, &xftcolor, font->font, x, y + font->y, (XftChar8 *) text, length);
444 }
9aca0d5f dan2004-10-12 01:34:32 +0000445}
446
9aca0d5f dan2004-10-12 01:34:32 +0000447void
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200448WMDrawImageString(WMScreen * scr, Drawable d, WMColor * color, WMColor * background,
449 WMFont * font, int x, int y, char *text, int length)
9aca0d5f dan2004-10-12 01:34:32 +0000450{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200451 XftColor textColor;
452 XftColor bgColor;
453
454 wassertr(font != NULL);
455
456 textColor.color.red = color->color.red;
457 textColor.color.green = color->color.green;
458 textColor.color.blue = color->color.blue;
459 textColor.color.alpha = color->alpha;;
460 textColor.pixel = W_PIXEL(color);
461
462 bgColor.color.red = background->color.red;
463 bgColor.color.green = background->color.green;
464 bgColor.color.blue = background->color.blue;
465 bgColor.color.alpha = background->alpha;;
466 bgColor.pixel = W_PIXEL(background);
467
468 XftDrawChange(scr->xftdraw, d);
469
470 XftDrawRect(scr->xftdraw, &bgColor, x, y, WMWidthOfString(font, text, length), font->height);
471
472 if (font->screen->useWideChar) {
473 wchar_t *wtext;
474 const char *mtext;
475 int len;
476
477 mtext = text;
478 wtext = (wchar_t *) wmalloc(sizeof(wchar_t) * (length + 1));
479 len = wmbsnrtowcs(wtext, &mtext, length, length);
480 if (len > 0) {
481 XftDrawString32(scr->xftdraw, &textColor, font->font,
482 x, y + font->y, (XftChar32 *) wtext, len);
483 } else if (len == -1) {
484 wwarning(_("Conversion to widechar failed (possible invalid "
485 "multibyte sequence): '%s':(pos %d)\n"), text, mtext - text + 1);
486 /* we can draw normal text, or we can draw as much widechar
487 * text as was already converted until the error. go figure */
488 /*XftDrawString8(scr->xftdraw, &textColor, font->font,
489 x, y + font->y, (XftChar8*)text, length); */
490 }
491 wfree(wtext);
492 } else if (font->screen->useMultiByte) {
493 XftDrawStringUtf8(scr->xftdraw, &textColor, font->font, x, y + font->y, (XftChar8 *) text, length);
494 } else {
495 XftDrawString8(scr->xftdraw, &textColor, font->font, x, y + font->y, (XftChar8 *) text, length);
496 }
9aca0d5f dan2004-10-12 01:34:32 +0000497}
498
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200499WMFont *WMCopyFontWithStyle(WMScreen * scrPtr, WMFont * font, WMFontStyle style)
9aca0d5f dan2004-10-12 01:34:32 +0000500{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200501 FcPattern *pattern;
502 WMFont *copy;
503 char *name;
504
505 if (!font)
506 return NULL;
507
508 pattern = FcNameParse(WMGetFontName(font));
509 switch (style) {
510 case WFSNormal:
511 FcPatternDel(pattern, "weight");
512 FcPatternDel(pattern, "slant");
513 FcPatternAddString(pattern, "weight", "regular");
514 FcPatternAddString(pattern, "weight", "medium");
515 FcPatternAddString(pattern, "slant", "roman");
516 break;
517 case WFSBold:
518 FcPatternDel(pattern, "weight");
519 FcPatternAddString(pattern, "weight", "bold");
520 break;
521 case WFSEmphasized:
522 FcPatternDel(pattern, "slant");
523 FcPatternAddString(pattern, "slant", "italic");
524 FcPatternAddString(pattern, "slant", "oblique");
525 break;
526 case WFSBoldEmphasized:
527 FcPatternDel(pattern, "weight");
528 FcPatternDel(pattern, "slant");
529 FcPatternAddString(pattern, "weight", "bold");
530 FcPatternAddString(pattern, "slant", "italic");
531 FcPatternAddString(pattern, "slant", "oblique");
532 break;
533 }
534
535 name = FcNameUnparse(pattern);
536 copy = WMCreateFont(scrPtr, name);
537 FcPatternDestroy(pattern);
538 wfree(name);
539
540 return copy;
9aca0d5f dan2004-10-12 01:34:32 +0000541}
542
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200543#endif /* XFT */