Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / wfont_wchar.c
dissimilarity index 92%
index cfc6f03..85c75a1 100644 (file)
-
-#include "wconfig.h"
-
-#ifdef XFT
-
-#include <X11/Xft/Xft.h>
-#include <fontconfig/fontconfig.h>
-
-#if defined(HAVE_MBSNRTOWCS)
-# define __USE_GNU
-#endif
-
-#ifdef HAVE_WCHAR_H
-# include <wchar.h>
-#endif
-
-#include <stdlib.h>
-
-#include "WINGsP.h"
-
-#include <wraster.h>
-#include <assert.h>
-#include <X11/Xlocale.h>
-
-
-// && defined(HAVE_MBSTATE_T___COUNT)
-// in configure.ac use AC_CHECK_MEMBER(struct mbstate_t.__count,
-//                                     have=1, have=0, [#include <wchar.h>])
-#if defined(HAVE_MBSNRTOWCS)
-
-static size_t
-wmbsnrtowcs(wchar_t *dest, const char **src, size_t nbytes, size_t len)
-{
-    mbstate_t ps;
-    size_t n;
-
-    memset(&ps, 0, sizeof(mbstate_t));
-    n = mbsnrtowcs(dest, src, nbytes, len, &ps);
-    if (n!=(size_t)-1 && *src) {
-        *src -= ps.__count;
-    }
-
-    return n;
-}
-
-#elif defined(HAVE_MBRTOWC)
-
-// This is 8 times slower than the version above.
-static size_t
-wmbsnrtowcs(wchar_t *dest, const char **src, size_t nbytes, size_t len)
-{
-    mbstate_t ps;
-    const char *ptr;
-    size_t n;
-    int nb;
-
-    if (nbytes==0)
-        return 0;
-
-    memset(&ps, 0, sizeof(mbstate_t));
-
-    if (dest == NULL) {
-        for (ptr=*src, n=0; nbytes>0; n++) {
-            nb = mbrtowc(NULL, ptr, nbytes, &ps);
-            if (nb == -1) {
-                return ((size_t)-1);
-            } else if (nb==0 || nb==-2) {
-                return n;
-            }
-            ptr += nb;
-            nbytes -= nb;
-        }
-    }
-
-    for (ptr=*src, n=0; n<len && nbytes>0; n++, dest++) {
-        nb = mbrtowc(dest, ptr, nbytes, &ps);
-        if (nb == -2) {
-            *src = ptr;
-            return n;
-        } else if (nb == -1) {
-            *src = ptr;
-            return ((size_t)-1);
-        } else if (nb == 0) {
-            *src = NULL;
-            return n;
-        }
-        ptr += nb;
-        nbytes -= nb;
-    }
-
-    *src = ptr;
-    return n;
-}
-
-#else
-
-// Not only 8 times slower than the version based on mbsnrtowcs
-// but also this version is not thread safe nor reentrant
-
-static size_t
-wmbsnrtowcs(wchar_t *dest, const char **src, size_t nbytes, size_t len)
-{
-    const char *ptr;
-    size_t n;
-    int nb;
-
-    if (nbytes==0)
-        return 0;
-
-    mbtowc(NULL, NULL, 0); /* reset shift state */
-
-    if (dest == NULL) {
-        for (ptr=*src, n=0; nbytes>0; n++) {
-            nb = mbtowc(NULL, ptr, nbytes);
-            if (nb == -1) {
-                mbtowc(NULL, NULL, 0);
-                nb = mbtowc(NULL, ptr, strlen(ptr));
-                return (nb == -1 ? (size_t)-1 : n);
-            } else if (nb==0) {
-                return n;
-            }
-            ptr += nb;
-            nbytes -= nb;
-        }
-    }
-
-    for (ptr=*src, n=0; n<len && nbytes>0; n++, dest++) {
-        nb = mbtowc(dest, ptr, nbytes);
-        if (nb == -1) {
-            mbtowc(NULL, NULL, 0);
-            nb = mbtowc(NULL, ptr, strlen(ptr));
-            *src = ptr;
-            return (nb == -1 ? (size_t)-1 : n);
-        } else if (nb == 0) {
-            *src = NULL;
-            return n;
-        }
-        ptr += nb;
-        nbytes -= nb;
-    }
-
-    *src = ptr;
-    return n;
-}
-
-#endif
-
-
-#define DEFAULT_SIZE 12
-
-static char*
-fixXLFD(char *xlfd, int size)
-{
-    char *fname, *ptr;
-
-    fname = wmalloc(strlen(xlfd) + 20);
-    if (strstr(xlfd, "%d")!=NULL)
-        sprintf(fname, xlfd, size ? size : DEFAULT_SIZE);
-    else
-        strcpy(fname, xlfd);
-
-    if ((ptr = strchr(fname, ','))) {
-        *ptr = 0;
-    }
-
-    return fname;
-}
-
-
-static Bool
-hasProperty(FcPattern *pattern, const char *property)
-{
-    FcValue val;
-
-    if (FcPatternGet(pattern, property, 0, &val)==FcResultMatch) {
-        return True;
-    }
-
-    return False;
-}
-
-
-static Bool
-hasPropertyWithStringValue(FcPattern *pattern, const char *object, char *value)
-{
-    FcChar8 *str;
-    int id;
-
-    if (!value || value[0]==0)
-        return True;
-
-    id = 0;
-    while (FcPatternGetString(pattern, object, id, &str)==FcResultMatch) {
-        if (strcasecmp(value, (char*)str) == 0) {
-            return True;
-        }
-        id++;
-    }
-
-    return False;
-}
-
-
-// also handle an xlfd with %d for size?
-static char*
-makeFontOfSize(char *font, int size, char *fallback)
-{
-    FcPattern *pattern;
-    char *result;
-
-    if (font[0]=='-') {
-        char *fname;
-
-        fname = fixXLFD(font, size);
-        pattern = XftXlfdParse(fname, False, False);
-        wfree(fname);
-    } else {
-        pattern = FcNameParse(font);
-    }
-
-    //FcPatternPrint(pattern);
-    if (size > 0) {
-        FcPatternDel(pattern, "pixelsize");
-        FcPatternAddDouble(pattern, "pixelsize", (double)size);
-    } else if (size==0 && !hasProperty(pattern, "size") &&
-               !hasProperty(pattern, "pixelsize")) {
-        FcPatternAddDouble(pattern, "pixelsize", (double)DEFAULT_SIZE);
-    }
-
-    if (fallback && !hasPropertyWithStringValue(pattern, "family", fallback)) {
-        FcPatternAddString(pattern, "family", fallback);
-    }
-
-    result = FcNameUnparse(pattern);
-    FcPatternDestroy(pattern);
-
-    return result;
-}
-
-
-WMFont*
-WMCreateFont(WMScreen *scrPtr, char *fontName)
-{
-    WMFont *font;
-    Display *display = scrPtr->display;
-    char *fname, *ptr;
-
-    /* This is for back-compat (to allow reading of old xlfd descriptions) */
-    if (fontName[0]=='-' && (ptr = strchr(fontName, ','))) {
-        // warn for deprecation
-        fname = wmalloc(ptr - fontName + 1);
-        strncpy(fname, fontName, ptr - fontName);
-        fname[ptr - fontName] = 0;
-    } else {
-        fname = wstrdup(fontName);
-    }
-
-    font = WMHashGet(scrPtr->fontCache, fname);
-    if (font) {
-        WMRetainFont(font);
-        wfree(fname);
-        return font;
-    }
-
-    font = wmalloc(sizeof(WMFont));
-    memset(font, 0, sizeof(WMFont));
-
-    font->screen = scrPtr;
-
-    // remove
-    printf("WMCreateFont: %s\n", fname);
-
-    if (fname[0] == '-') {
-        // Backward compat thing. Remove in a later version
-        font->font = XftFontOpenXlfd(display, scrPtr->screen, fname);
-    } else {
-        font->font = XftFontOpenName(display, scrPtr->screen, fname);
-    }
-    if (!font->font) {
-        wfree(font);
-        wfree(fname);
-        return NULL;
-    }
-    font->height = font->font->ascent+font->font->descent;
-    font->y = font->font->ascent;
-
-    font->refCount = 1;
-
-    font->name = fname;
-
-    assert(WMHashInsert(scrPtr->fontCache, font->name, font)==NULL);
-
-    return font;
-}
-
-
-WMFont*
-WMRetainFont(WMFont *font)
-{
-    wassertrv(font!=NULL, NULL);
-
-    font->refCount++;
-
-    return font;
-}
-
-
-void
-WMReleaseFont(WMFont *font)
-{
-    wassertr(font!=NULL);
-
-    font->refCount--;
-    if (font->refCount < 1) {
-        XftFontClose(font->screen->display, font->font);
-        if (font->name) {
-            WMHashRemove(font->screen->fontCache, font->name);
-            wfree(font->name);
-        }
-        wfree(font);
-    }
-}
-
-
-Bool
-WMIsAntialiasingEnabled(WMScreen *scrPtr)
-{
-    return scrPtr->antialiasedText;
-}
-
-
-unsigned int
-WMFontHeight(WMFont *font)
-{
-    wassertrv(font!=NULL, 0);
-
-    return font->height;
-}
-
-
-char*
-WMGetFontName(WMFont *font)
-{
-    wassertrv(font!=NULL, NULL);
-
-    return font->name;
-}
-
-
-WMFont*
-WMDefaultSystemFont(WMScreen *scrPtr)
-{
-    return WMRetainFont(scrPtr->normalFont);
-}
-
-
-WMFont*
-WMDefaultBoldSystemFont(WMScreen *scrPtr)
-{
-    return WMRetainFont(scrPtr->boldFont);
-}
-
-
-WMFont*
-WMSystemFontOfSize(WMScreen *scrPtr, int size)
-{
-    WMFont *font;
-    char *fontSpec;
-
-    fontSpec = makeFontOfSize(WINGsConfiguration.systemFont, size, "sans");
-
-    font = WMCreateFont(scrPtr, fontSpec);
-
-    if (!font) {
-        wwarning(_("could not load font %s."), fontSpec);
-    }
-
-    wfree(fontSpec);
-
-    return font;
-}
-
-
-WMFont*
-WMBoldSystemFontOfSize(WMScreen *scrPtr, int size)
-{
-    WMFont *font;
-    char *fontSpec;
-
-    fontSpec = makeFontOfSize(WINGsConfiguration.boldSystemFont, size, "sans");
-
-    font = WMCreateFont(scrPtr, fontSpec);
-
-    if (!font) {
-        wwarning(_("could not load font %s."), fontSpec);
-    }
-
-    wfree(fontSpec);
-
-    return font;
-}
-
-
-int
-WMWidthOfString(WMFont *font, char *text, int length)
-{
-    XGlyphInfo extents;
-
-    wassertrv(font!=NULL, 0);
-    wassertrv(text!=NULL, 0);
-
-    if (font->screen->useWideChar) {
-        wchar_t *wtext;
-        const char *mtext;
-        int len;
-
-        wtext = (wchar_t *)wmalloc(sizeof(wchar_t)*(length+1));
-        mtext = text;
-        len = wmbsnrtowcs(wtext, &mtext, length, length);
-        if (len>0) {
-            wtext[len] = L'\0'; /* not really necessary here */
-            XftTextExtents32(font->screen->display, font->font,
-                             (XftChar32 *)wtext, len, &extents);
-        } else {
-            if (len==-1) {
-                wwarning(_("Conversion to widechar failed (possible "
-                           "invalid multibyte sequence): '%s':(pos %d)\n"),
-                         text, mtext-text+1);
-            }
-            extents.xOff = 0;
-        }
-        wfree(wtext);
-    } else if (font->screen->useMultiByte) {
-        XftTextExtentsUtf8(font->screen->display, font->font,
-                           (XftChar8 *)text, length, &extents);
-    } else {
-        XftTextExtents8(font->screen->display, font->font,
-                        (XftChar8 *)text, length, &extents);
-    }
-
-    return extents.xOff; /* don't ask :P */
-}
-
-
-
-void
-WMDrawString(WMScreen *scr, Drawable d, WMColor *color, WMFont *font,
-             int x, int y, char *text, int length)
-{
-    XftColor xftcolor;
-
-    wassertr(font!=NULL);
-
-    xftcolor.color.red = color->color.red;
-    xftcolor.color.green = color->color.green;
-    xftcolor.color.blue = color->color.blue;
-    xftcolor.color.alpha = color->alpha;;
-    xftcolor.pixel = W_PIXEL(color);
-
-    XftDrawChange(scr->xftdraw, d);
-
-    if (font->screen->useWideChar) {
-        wchar_t *wtext;
-        const char *mtext;
-        int len;
-
-        wtext = (wchar_t *)wmalloc(sizeof(wchar_t)*(length+1));
-        mtext = text;
-        len = wmbsnrtowcs(wtext, &mtext, length, length);
-        if (len>0) {
-            XftDrawString32(scr->xftdraw, &xftcolor, font->font,
-                            x, y + font->y, (XftChar32*)wtext, len);
-        } else if (len==-1) {
-            wwarning(_("Conversion to widechar failed (possible invalid "
-                       "multibyte sequence): '%s':(pos %d)\n"),
-                     text, mtext-text+1);
-            /* we can draw normal text, or we can draw as much widechar
-             * text as was already converted until the error. go figure */
-            /*XftDrawString8(scr->xftdraw, &xftcolor, font->font,
-             x, y + font->y, (XftChar8*)text, length);*/
-        }
-        wfree(wtext);
-    } else if (font->screen->useMultiByte) {
-        XftDrawStringUtf8(scr->xftdraw, &xftcolor, font->font,
-                          x, y + font->y, (XftChar8*)text, length);
-    } else {
-        XftDrawString8(scr->xftdraw, &xftcolor, font->font,
-                       x, y + font->y, (XftChar8*)text, length);
-    }
-}
-
-
-void
-WMDrawImageString(WMScreen *scr, Drawable d, WMColor *color, WMColor *background,
-                  WMFont *font, int x, int y, char *text, int length)
-{
-    XftColor textColor;
-    XftColor bgColor;
-
-    wassertr(font!=NULL);
-
-    textColor.color.red = color->color.red;
-    textColor.color.green = color->color.green;
-    textColor.color.blue = color->color.blue;
-    textColor.color.alpha = color->alpha;;
-    textColor.pixel = W_PIXEL(color);
-
-    bgColor.color.red = background->color.red;
-    bgColor.color.green = background->color.green;
-    bgColor.color.blue = background->color.blue;
-    bgColor.color.alpha = background->alpha;;
-    bgColor.pixel = W_PIXEL(background);
-
-    XftDrawChange(scr->xftdraw, d);
-
-    XftDrawRect(scr->xftdraw, &bgColor, x, y,
-                WMWidthOfString(font, text, length),
-                font->height);
-
-    if (font->screen->useWideChar) {
-        wchar_t *wtext;
-        const char *mtext;
-        int len;
-
-        mtext = text;
-        wtext = (wchar_t *)wmalloc(sizeof(wchar_t)*(length+1));
-        len = wmbsnrtowcs(wtext, &mtext, length, length);
-        if (len>0) {
-            XftDrawString32(scr->xftdraw, &textColor, font->font,
-                            x, y + font->y, (XftChar32*)wtext, len);
-        } else if (len==-1) {
-            wwarning(_("Conversion to widechar failed (possible invalid "
-                       "multibyte sequence): '%s':(pos %d)\n"),
-                     text, mtext-text+1);
-            /* we can draw normal text, or we can draw as much widechar
-             * text as was already converted until the error. go figure */
-            /*XftDrawString8(scr->xftdraw, &textColor, font->font,
-             x, y + font->y, (XftChar8*)text, length);*/
-        }
-        wfree(wtext);
-    } else if (font->screen->useMultiByte) {
-        XftDrawStringUtf8(scr->xftdraw, &textColor, font->font,
-                          x, y + font->y, (XftChar8*)text, length);
-    } else {
-        XftDrawString8(scr->xftdraw, &textColor, font->font,
-                       x, y + font->y, (XftChar8*)text, length);
-    }
-}
-
-
-WMFont*
-WMCopyFontWithStyle(WMScreen *scrPtr, WMFont *font, WMFontStyle style)
-{
-    FcPattern *pattern;
-    WMFont *copy;
-    char *name;
-
-    if (!font)
-        return NULL;
-
-    pattern = FcNameParse(WMGetFontName(font));
-    switch (style) {
-    case WFSNormal:
-        FcPatternDel(pattern, "weight");
-        FcPatternDel(pattern, "slant");
-        FcPatternAddString(pattern, "weight", "regular");
-        FcPatternAddString(pattern, "weight", "medium");
-        FcPatternAddString(pattern, "slant", "roman");
-        break;
-    case WFSBold:
-        FcPatternDel(pattern, "weight");
-        FcPatternAddString(pattern, "weight", "bold");
-        break;
-    case WFSEmphasized:
-        FcPatternDel(pattern, "slant");
-        FcPatternAddString(pattern, "slant", "italic");
-        FcPatternAddString(pattern, "slant", "oblique");
-        break;
-    case WFSBoldEmphasized:
-        FcPatternDel(pattern, "weight");
-        FcPatternDel(pattern, "slant");
-        FcPatternAddString(pattern, "weight", "bold");
-        FcPatternAddString(pattern, "slant", "italic");
-        FcPatternAddString(pattern, "slant", "oblique");
-        break;
-    }
-
-    name = FcNameUnparse(pattern);
-    copy = WMCreateFont(scrPtr, name);
-    FcPatternDestroy(pattern);
-    wfree(name);
-
-    return copy;
-}
-
-
-#endif /* XFT */
-
-
+
+#include "wconfig.h"
+
+#ifdef XFT
+
+#include <X11/Xft/Xft.h>
+#include <fontconfig/fontconfig.h>
+
+#if defined(HAVE_MBSNRTOWCS)
+# define __USE_GNU
+#endif
+
+#ifdef HAVE_WCHAR_H
+# include <wchar.h>
+#endif
+
+#include <stdlib.h>
+
+#include "WINGsP.h"
+
+#include <wraster.h>
+#include <assert.h>
+#include <X11/Xlocale.h>
+
+// && defined(HAVE_MBSTATE_T___COUNT)
+// in configure.ac use AC_CHECK_MEMBER(struct mbstate_t.__count,
+//                                     have=1, have=0, [#include <wchar.h>])
+#if defined(HAVE_MBSNRTOWCS)
+
+static size_t wmbsnrtowcs(wchar_t * dest, const char **src, size_t nbytes, size_t len)
+{
+       mbstate_t ps;
+       size_t n;
+
+       memset(&ps, 0, sizeof(mbstate_t));
+       n = mbsnrtowcs(dest, src, nbytes, len, &ps);
+       if (n != (size_t) - 1 && *src) {
+               *src -= ps.__count;
+       }
+
+       return n;
+}
+
+#elif defined(HAVE_MBRTOWC)
+
+// This is 8 times slower than the version above.
+static size_t wmbsnrtowcs(wchar_t * dest, const char **src, size_t nbytes, size_t len)
+{
+       mbstate_t ps;
+       const char *ptr;
+       size_t n;
+       int nb;
+
+       if (nbytes == 0)
+               return 0;
+
+       memset(&ps, 0, sizeof(mbstate_t));
+
+       if (dest == NULL) {
+               for (ptr = *src, n = 0; nbytes > 0; n++) {
+                       nb = mbrtowc(NULL, ptr, nbytes, &ps);
+                       if (nb == -1) {
+                               return ((size_t) - 1);
+                       } else if (nb == 0 || nb == -2) {
+                               return n;
+                       }
+                       ptr += nb;
+                       nbytes -= nb;
+               }
+       }
+
+       for (ptr = *src, n = 0; n < len && nbytes > 0; n++, dest++) {
+               nb = mbrtowc(dest, ptr, nbytes, &ps);
+               if (nb == -2) {
+                       *src = ptr;
+                       return n;
+               } else if (nb == -1) {
+                       *src = ptr;
+                       return ((size_t) - 1);
+               } else if (nb == 0) {
+                       *src = NULL;
+                       return n;
+               }
+               ptr += nb;
+               nbytes -= nb;
+       }
+
+       *src = ptr;
+       return n;
+}
+
+#else
+
+// Not only 8 times slower than the version based on mbsnrtowcs
+// but also this version is not thread safe nor reentrant
+
+static size_t wmbsnrtowcs(wchar_t * dest, const char **src, size_t nbytes, size_t len)
+{
+       const char *ptr;
+       size_t n;
+       int nb;
+
+       if (nbytes == 0)
+               return 0;
+
+       mbtowc(NULL, NULL, 0);  /* reset shift state */
+
+       if (dest == NULL) {
+               for (ptr = *src, n = 0; nbytes > 0; n++) {
+                       nb = mbtowc(NULL, ptr, nbytes);
+                       if (nb == -1) {
+                               mbtowc(NULL, NULL, 0);
+                               nb = mbtowc(NULL, ptr, strlen(ptr));
+                               return (nb == -1 ? (size_t) - 1 : n);
+                       } else if (nb == 0) {
+                               return n;
+                       }
+                       ptr += nb;
+                       nbytes -= nb;
+               }
+       }
+
+       for (ptr = *src, n = 0; n < len && nbytes > 0; n++, dest++) {
+               nb = mbtowc(dest, ptr, nbytes);
+               if (nb == -1) {
+                       mbtowc(NULL, NULL, 0);
+                       nb = mbtowc(NULL, ptr, strlen(ptr));
+                       *src = ptr;
+                       return (nb == -1 ? (size_t) - 1 : n);
+               } else if (nb == 0) {
+                       *src = NULL;
+                       return n;
+               }
+               ptr += nb;
+               nbytes -= nb;
+       }
+
+       *src = ptr;
+       return n;
+}
+
+#endif
+
+#define DEFAULT_SIZE 12
+
+static char *fixXLFD(char *xlfd, int size)
+{
+       char *fname, *ptr;
+
+       fname = wmalloc(strlen(xlfd) + 20);
+       if (strstr(xlfd, "%d") != NULL)
+               sprintf(fname, xlfd, size ? size : DEFAULT_SIZE);
+       else
+               strcpy(fname, xlfd);
+
+       if ((ptr = strchr(fname, ','))) {
+               *ptr = 0;
+       }
+
+       return fname;
+}
+
+static Bool hasProperty(FcPattern * pattern, const char *property)
+{
+       FcValue val;
+
+       if (FcPatternGet(pattern, property, 0, &val) == FcResultMatch) {
+               return True;
+       }
+
+       return False;
+}
+
+static Bool hasPropertyWithStringValue(FcPattern * pattern, const char *object, char *value)
+{
+       FcChar8 *str;
+       int id;
+
+       if (!value || value[0] == 0)
+               return True;
+
+       id = 0;
+       while (FcPatternGetString(pattern, object, id, &str) == FcResultMatch) {
+               if (strcasecmp(value, (char *)str) == 0) {
+                       return True;
+               }
+               id++;
+       }
+
+       return False;
+}
+
+// also handle an xlfd with %d for size?
+static char *makeFontOfSize(char *font, int size, char *fallback)
+{
+       FcPattern *pattern;
+       char *result;
+
+       if (font[0] == '-') {
+               char *fname;
+
+               fname = fixXLFD(font, size);
+               pattern = XftXlfdParse(fname, False, False);
+               wfree(fname);
+       } else {
+               pattern = FcNameParse(font);
+       }
+
+       //FcPatternPrint(pattern);
+       if (size > 0) {
+               FcPatternDel(pattern, "pixelsize");
+               FcPatternAddDouble(pattern, "pixelsize", (double)size);
+       } else if (size == 0 && !hasProperty(pattern, "size") && !hasProperty(pattern, "pixelsize")) {
+               FcPatternAddDouble(pattern, "pixelsize", (double)DEFAULT_SIZE);
+       }
+
+       if (fallback && !hasPropertyWithStringValue(pattern, "family", fallback)) {
+               FcPatternAddString(pattern, "family", fallback);
+       }
+
+       result = FcNameUnparse(pattern);
+       FcPatternDestroy(pattern);
+
+       return result;
+}
+
+WMFont *WMCreateFont(WMScreen * scrPtr, char *fontName)
+{
+       WMFont *font;
+       Display *display = scrPtr->display;
+       char *fname, *ptr;
+
+       /* This is for back-compat (to allow reading of old xlfd descriptions) */
+       if (fontName[0] == '-' && (ptr = strchr(fontName, ','))) {
+               // warn for deprecation
+               fname = wmalloc(ptr - fontName + 1);
+               strncpy(fname, fontName, ptr - fontName);
+               fname[ptr - fontName] = 0;
+       } else {
+               fname = wstrdup(fontName);
+       }
+
+       font = WMHashGet(scrPtr->fontCache, fname);
+       if (font) {
+               WMRetainFont(font);
+               wfree(fname);
+               return font;
+       }
+
+       font = wmalloc(sizeof(WMFont));
+       memset(font, 0, sizeof(WMFont));
+
+       font->screen = scrPtr;
+
+       // remove
+       printf("WMCreateFont: %s\n", fname);
+
+       if (fname[0] == '-') {
+               // Backward compat thing. Remove in a later version
+               font->font = XftFontOpenXlfd(display, scrPtr->screen, fname);
+       } else {
+               font->font = XftFontOpenName(display, scrPtr->screen, fname);
+       }
+       if (!font->font) {
+               wfree(font);
+               wfree(fname);
+               return NULL;
+       }
+       font->height = font->font->ascent + font->font->descent;
+       font->y = font->font->ascent;
+
+       font->refCount = 1;
+
+       font->name = fname;
+
+       assert(WMHashInsert(scrPtr->fontCache, font->name, font) == NULL);
+
+       return font;
+}
+
+WMFont *WMRetainFont(WMFont * font)
+{
+       wassertrv(font != NULL, NULL);
+
+       font->refCount++;
+
+       return font;
+}
+
+void WMReleaseFont(WMFont * font)
+{
+       wassertr(font != NULL);
+
+       font->refCount--;
+       if (font->refCount < 1) {
+               XftFontClose(font->screen->display, font->font);
+               if (font->name) {
+                       WMHashRemove(font->screen->fontCache, font->name);
+                       wfree(font->name);
+               }
+               wfree(font);
+       }
+}
+
+Bool WMIsAntialiasingEnabled(WMScreen * scrPtr)
+{
+       return scrPtr->antialiasedText;
+}
+
+unsigned int WMFontHeight(WMFont * font)
+{
+       wassertrv(font != NULL, 0);
+
+       return font->height;
+}
+
+char *WMGetFontName(WMFont * font)
+{
+       wassertrv(font != NULL, NULL);
+
+       return font->name;
+}
+
+WMFont *WMDefaultSystemFont(WMScreen * scrPtr)
+{
+       return WMRetainFont(scrPtr->normalFont);
+}
+
+WMFont *WMDefaultBoldSystemFont(WMScreen * scrPtr)
+{
+       return WMRetainFont(scrPtr->boldFont);
+}
+
+WMFont *WMSystemFontOfSize(WMScreen * scrPtr, int size)
+{
+       WMFont *font;
+       char *fontSpec;
+
+       fontSpec = makeFontOfSize(WINGsConfiguration.systemFont, size, "sans");
+
+       font = WMCreateFont(scrPtr, fontSpec);
+
+       if (!font) {
+               wwarning(_("could not load font %s."), fontSpec);
+       }
+
+       wfree(fontSpec);
+
+       return font;
+}
+
+WMFont *WMBoldSystemFontOfSize(WMScreen * scrPtr, int size)
+{
+       WMFont *font;
+       char *fontSpec;
+
+       fontSpec = makeFontOfSize(WINGsConfiguration.boldSystemFont, size, "sans");
+
+       font = WMCreateFont(scrPtr, fontSpec);
+
+       if (!font) {
+               wwarning(_("could not load font %s."), fontSpec);
+       }
+
+       wfree(fontSpec);
+
+       return font;
+}
+
+int WMWidthOfString(WMFont * font, char *text, int length)
+{
+       XGlyphInfo extents;
+
+       wassertrv(font != NULL, 0);
+       wassertrv(text != NULL, 0);
+
+       if (font->screen->useWideChar) {
+               wchar_t *wtext;
+               const char *mtext;
+               int len;
+
+               wtext = (wchar_t *) wmalloc(sizeof(wchar_t) * (length + 1));
+               mtext = text;
+               len = wmbsnrtowcs(wtext, &mtext, length, length);
+               if (len > 0) {
+                       wtext[len] = L'\0';     /* not really necessary here */
+                       XftTextExtents32(font->screen->display, font->font, (XftChar32 *) wtext, len, &extents);
+               } else {
+                       if (len == -1) {
+                               wwarning(_("Conversion to widechar failed (possible "
+                                          "invalid multibyte sequence): '%s':(pos %d)\n"),
+                                        text, mtext - text + 1);
+                       }
+                       extents.xOff = 0;
+               }
+               wfree(wtext);
+       } else if (font->screen->useMultiByte) {
+               XftTextExtentsUtf8(font->screen->display, font->font, (XftChar8 *) text, length, &extents);
+       } else {
+               XftTextExtents8(font->screen->display, font->font, (XftChar8 *) text, length, &extents);
+       }
+
+       return extents.xOff;    /* don't ask :P */
+}
+
+void WMDrawString(WMScreen * scr, Drawable d, WMColor * color, WMFont * font, int x, int y, char *text, int length)
+{
+       XftColor xftcolor;
+
+       wassertr(font != NULL);
+
+       xftcolor.color.red = color->color.red;
+       xftcolor.color.green = color->color.green;
+       xftcolor.color.blue = color->color.blue;
+       xftcolor.color.alpha = color->alpha;;
+       xftcolor.pixel = W_PIXEL(color);
+
+       XftDrawChange(scr->xftdraw, d);
+
+       if (font->screen->useWideChar) {
+               wchar_t *wtext;
+               const char *mtext;
+               int len;
+
+               wtext = (wchar_t *) wmalloc(sizeof(wchar_t) * (length + 1));
+               mtext = text;
+               len = wmbsnrtowcs(wtext, &mtext, length, length);
+               if (len > 0) {
+                       XftDrawString32(scr->xftdraw, &xftcolor, font->font,
+                                       x, y + font->y, (XftChar32 *) wtext, len);
+               } else if (len == -1) {
+                       wwarning(_("Conversion to widechar failed (possible invalid "
+                                  "multibyte sequence): '%s':(pos %d)\n"), text, mtext - text + 1);
+                       /* we can draw normal text, or we can draw as much widechar
+                        * text as was already converted until the error. go figure */
+                       /*XftDrawString8(scr->xftdraw, &xftcolor, font->font,
+                          x, y + font->y, (XftChar8*)text, length); */
+               }
+               wfree(wtext);
+       } else if (font->screen->useMultiByte) {
+               XftDrawStringUtf8(scr->xftdraw, &xftcolor, font->font, x, y + font->y, (XftChar8 *) text, length);
+       } else {
+               XftDrawString8(scr->xftdraw, &xftcolor, font->font, x, y + font->y, (XftChar8 *) text, length);
+       }
+}
+
+void
+WMDrawImageString(WMScreen * scr, Drawable d, WMColor * color, WMColor * background,
+                 WMFont * font, int x, int y, char *text, int length)
+{
+       XftColor textColor;
+       XftColor bgColor;
+
+       wassertr(font != NULL);
+
+       textColor.color.red = color->color.red;
+       textColor.color.green = color->color.green;
+       textColor.color.blue = color->color.blue;
+       textColor.color.alpha = color->alpha;;
+       textColor.pixel = W_PIXEL(color);
+
+       bgColor.color.red = background->color.red;
+       bgColor.color.green = background->color.green;
+       bgColor.color.blue = background->color.blue;
+       bgColor.color.alpha = background->alpha;;
+       bgColor.pixel = W_PIXEL(background);
+
+       XftDrawChange(scr->xftdraw, d);
+
+       XftDrawRect(scr->xftdraw, &bgColor, x, y, WMWidthOfString(font, text, length), font->height);
+
+       if (font->screen->useWideChar) {
+               wchar_t *wtext;
+               const char *mtext;
+               int len;
+
+               mtext = text;
+               wtext = (wchar_t *) wmalloc(sizeof(wchar_t) * (length + 1));
+               len = wmbsnrtowcs(wtext, &mtext, length, length);
+               if (len > 0) {
+                       XftDrawString32(scr->xftdraw, &textColor, font->font,
+                                       x, y + font->y, (XftChar32 *) wtext, len);
+               } else if (len == -1) {
+                       wwarning(_("Conversion to widechar failed (possible invalid "
+                                  "multibyte sequence): '%s':(pos %d)\n"), text, mtext - text + 1);
+                       /* we can draw normal text, or we can draw as much widechar
+                        * text as was already converted until the error. go figure */
+                       /*XftDrawString8(scr->xftdraw, &textColor, font->font,
+                          x, y + font->y, (XftChar8*)text, length); */
+               }
+               wfree(wtext);
+       } else if (font->screen->useMultiByte) {
+               XftDrawStringUtf8(scr->xftdraw, &textColor, font->font, x, y + font->y, (XftChar8 *) text, length);
+       } else {
+               XftDrawString8(scr->xftdraw, &textColor, font->font, x, y + font->y, (XftChar8 *) text, length);
+       }
+}
+
+WMFont *WMCopyFontWithStyle(WMScreen * scrPtr, WMFont * font, WMFontStyle style)
+{
+       FcPattern *pattern;
+       WMFont *copy;
+       char *name;
+
+       if (!font)
+               return NULL;
+
+       pattern = FcNameParse(WMGetFontName(font));
+       switch (style) {
+       case WFSNormal:
+               FcPatternDel(pattern, "weight");
+               FcPatternDel(pattern, "slant");
+               FcPatternAddString(pattern, "weight", "regular");
+               FcPatternAddString(pattern, "weight", "medium");
+               FcPatternAddString(pattern, "slant", "roman");
+               break;
+       case WFSBold:
+               FcPatternDel(pattern, "weight");
+               FcPatternAddString(pattern, "weight", "bold");
+               break;
+       case WFSEmphasized:
+               FcPatternDel(pattern, "slant");
+               FcPatternAddString(pattern, "slant", "italic");
+               FcPatternAddString(pattern, "slant", "oblique");
+               break;
+       case WFSBoldEmphasized:
+               FcPatternDel(pattern, "weight");
+               FcPatternDel(pattern, "slant");
+               FcPatternAddString(pattern, "weight", "bold");
+               FcPatternAddString(pattern, "slant", "italic");
+               FcPatternAddString(pattern, "slant", "oblique");
+               break;
+       }
+
+       name = FcNameUnparse(pattern);
+       copy = WMCreateFont(scrPtr, name);
+       FcPatternDestroy(pattern);
+       wfree(name);
+
+       return copy;
+}
+
+#endif                         /* XFT */