From dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Mon, 12 Sep 2011 11:27:51 +0200
Subject: Synchronised line endinge with release branch

---
 libXft/configure.ac  |  308 +++---
 libXft/src/xftcore.c | 2766 +++++++++++++++++++++++++-------------------------
 libXft/src/xftdpy.c  | 1104 ++++++++++----------
 libXft/src/xftdraw.c | 1988 ++++++++++++++++++------------------
 4 files changed, 3083 insertions(+), 3083 deletions(-)

(limited to 'libXft')

diff --git a/libXft/configure.ac b/libXft/configure.ac
index b031a0116..9b9f6a74d 100644
--- a/libXft/configure.ac
+++ b/libXft/configure.ac
@@ -1,154 +1,154 @@
-#
-#  Copyright © 2003 Keith Packard, Noah Levitt
-#
-#  Permission to use, copy, modify, distribute, and sell this software and its
-#  documentation for any purpose is hereby granted without fee, provided that
-#  the above copyright notice appear in all copies and that both that
-#  copyright notice and this permission notice appear in supporting
-#  documentation, and that the name of Keith Packard not be used in
-#  advertising or publicity pertaining to distribution of the software without
-#  specific, written prior permission.  Keith Packard makes no
-#  representations about the suitability of this software for any purpose.  It
-#  is provided "as is" without express or implied warranty.
-#
-#  KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-#  EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-#  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-#  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-#  PERFORMANCE OF THIS SOFTWARE.
-#
-
-# Initialize Autoconf
-AC_PREREQ([2.60])
-#
-# This is the package version number, not the shared library
-# version.  This version number will be substituted into Xft.h
-# Please bump the minor library number at each release as well.
-#
-AC_INIT([libXft], [2.2.0],
-        [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXft])
-AC_CONFIG_SRCDIR([Makefile.am])
-AC_CONFIG_HEADERS([config.h])
-
-# Initialize Automake
-AM_INIT_AUTOMAKE([foreign dist-bzip2])
-AM_MAINTAINER_MODE
-
-# Initialize libtool
-AC_PROG_LIBTOOL
-
-# Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS
-m4_ifndef([XORG_MACROS_VERSION],
-          [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])])
-XORG_MACROS_VERSION(1.8)
-XORG_DEFAULT_OPTIONS
-
-# Set library version for Xft.h from package version set in AC_INIT
-# copied from PACKAGE_VERSION_* settings in XORG_VERSION
-AC_CONFIG_HEADERS([include/X11/Xft/Xft.h])
-AC_DEFINE_UNQUOTED([XFT_MAJOR],
-                [`echo $PACKAGE_VERSION | cut -d . -f 1`],
-                [Major version of Xft])
-AC_DEFINE_UNQUOTED([XFT_MINOR],
-                [`echo $PACKAGE_VERSION | cut -d . -f 2 | cut -d - -f 1`],
-                [Minor version of Xft])
-AC_DEFINE_UNQUOTED([XFT_REVISION],
-                [`echo $PACKAGE_VERSION | cut -d . -f 3 | cut -d - -f 1`],
-                [Micro revision of Xft])
-
-XFT_LT_VERSION=`echo $PACKAGE_VERSION | tr '.' ':'`
-AC_SUBST([XFT_LT_VERSION])
-
-#
-# Check for Xrender
-#
-PKG_CHECK_MODULES(XRENDER, xrender >= 0.8.2, [xrender_found_with_pkgconfig=yes], 
-                  [xrender_found_with_pkgconfig=no])
-case "$xrender_found_with_pkgconfig" in
-no)
-	PKG_CHECK_MODULES(XRENDER, xrender >= 0, [old_xrender_found_with_pkgconfig=yes], 
-			  [old_xrender_found_with_pkgconfig=no])
-	case "$old_xrender_found_with_pkgconfig" in
-	yes)
-		XRENDER_LIBS="$XRENDER_LIBS -lXext -lX11"
-		;;
-	*)
-	        # checks for X
-	        AC_PATH_X
-
-	        XRENDER_CFLAGS="-I$x_includes"
-	        XRENDER_LIBS="-L$x_libraries -lXrender -lXext -lX11"
-
-	        saved_CPPFLAGS="$CPPFLAGS"
-	        CPPFLAGS="$CPPFLAGS $XRENDER_CFLAGS"
-	        AC_CHECK_HEADERS([X11/extensions/Xrender.h], [], [AC_MSG_ERROR([Xrender.h not found.])])
-	        CPPFLAGS="$saved_CPPFLAGS"
-
-	        saved_LIBS="$LIBS"
-	        LIBS="$LIBS $XRENDER_LIBS"
-	        AC_CHECK_FUNCS([XRenderFindStandardFormat], [], [AC_MSG_ERROR([libXrender not found or too old.])])
-	        LIBS="$saved_LIBS"
-		;;
-	esac
-        ;;
-esac
-
-# Check freetype configuration
-AC_ARG_WITH(freetype-config, [  --with-freetype-config=PROG   Use FreeType configuration program PROG], freetype_config=$withval, freetype_config=auto)
-	
-if test "$freetype_config" = "auto"; then
-	PKG_CHECK_MODULES(FREETYPE, freetype2, 
-		freetype_config=no, freetype_config=yes)
-fi
-
-if test "$freetype_config" = "yes"; then 
-	AC_PATH_PROG(ft_config,freetype-config,no)
-	if test "$ft_config" = "no"; then
-		AC_MSG_ERROR([You must have freetype installed; see http://www.freetype.org/])
-	fi
-else
-	ft_config="$freetype_config"
-fi
-
-if test "$freetype_config" != "no"; then 	
-	FREETYPE_CFLAGS="`$ft_config --cflags`"
-	FREETYPE_LIBS="`$ft_config --libs`"
-fi
-
-# Check fontconfig configuration
-PKG_CHECK_MODULES(FONTCONFIG, fontconfig >= 2.2)
-
-AC_SUBST(XRENDER_CFLAGS)
-AC_SUBST(XRENDER_LIBS)
-AC_SUBST(FREETYPE_CFLAGS)
-AC_SUBST(FREETYPE_LIBS)
-AC_SUBST(FONTCONFIG_CFLAGS)
-AC_SUBST(FONTCONFIG_LIBS)
-
-fontconfig_save_libs="$LIBS"
-fontconfig_save_cflags="$CFLAGS"
-LIBS="$LIBS $FREETYPE_LIBS"
-CFLAGS="$CFLAGS $FREETYPE_CFLAGS"
-AC_CHECK_FUNCS(FT_Get_Next_Char FT_Get_BDF_Property FT_Get_PS_Font_Info FT_Has_PS_Glyph_Names FT_GlyphSlot_Embolden)
-AC_CHECK_MEMBER(FT_Bitmap_Size.y_ppem,
-		HAVE_FT_BITMAP_SIZE_Y_PPEM=1,
-		HAVE_FT_BITMAP_SIZE_Y_PPEM=0,
-[#include <ft2build.h>
-#include FT_FREETYPE_H])
-AC_DEFINE_UNQUOTED(HAVE_FT_BITMAP_SIZE_Y_PPEM,$HAVE_FT_BITMAP_SIZE_Y_PPEM,
-		   [FT_Bitmap_Size structure includes y_ppem field])
-
-LIBS="$fontconfig_save_libs"
-CFLAGS="$fontconfig_save_cflags"
-
-if test "$VERSION" = "" ; then
-       VERSION=$PACKAGE_VERSION;
-fi
-
-AC_CONFIG_FILES([Makefile
-		xft.pc
-		src/Makefile
-		man/Makefile])
-AC_OUTPUT
+#
+#  Copyright © 2003 Keith Packard, Noah Levitt
+#
+#  Permission to use, copy, modify, distribute, and sell this software and its
+#  documentation for any purpose is hereby granted without fee, provided that
+#  the above copyright notice appear in all copies and that both that
+#  copyright notice and this permission notice appear in supporting
+#  documentation, and that the name of Keith Packard not be used in
+#  advertising or publicity pertaining to distribution of the software without
+#  specific, written prior permission.  Keith Packard makes no
+#  representations about the suitability of this software for any purpose.  It
+#  is provided "as is" without express or implied warranty.
+#
+#  KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+#  EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+#  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+#  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+#  PERFORMANCE OF THIS SOFTWARE.
+#
+
+# Initialize Autoconf
+AC_PREREQ([2.60])
+#
+# This is the package version number, not the shared library
+# version.  This version number will be substituted into Xft.h
+# Please bump the minor library number at each release as well.
+#
+AC_INIT([libXft], [2.2.0],
+        [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXft])
+AC_CONFIG_SRCDIR([Makefile.am])
+AC_CONFIG_HEADERS([config.h])
+
+# Initialize Automake
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AM_MAINTAINER_MODE
+
+# Initialize libtool
+AC_PROG_LIBTOOL
+
+# Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS
+m4_ifndef([XORG_MACROS_VERSION],
+          [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.8)
+XORG_DEFAULT_OPTIONS
+
+# Set library version for Xft.h from package version set in AC_INIT
+# copied from PACKAGE_VERSION_* settings in XORG_VERSION
+AC_CONFIG_HEADERS([include/X11/Xft/Xft.h])
+AC_DEFINE_UNQUOTED([XFT_MAJOR],
+                [`echo $PACKAGE_VERSION | cut -d . -f 1`],
+                [Major version of Xft])
+AC_DEFINE_UNQUOTED([XFT_MINOR],
+                [`echo $PACKAGE_VERSION | cut -d . -f 2 | cut -d - -f 1`],
+                [Minor version of Xft])
+AC_DEFINE_UNQUOTED([XFT_REVISION],
+                [`echo $PACKAGE_VERSION | cut -d . -f 3 | cut -d - -f 1`],
+                [Micro revision of Xft])
+
+XFT_LT_VERSION=`echo $PACKAGE_VERSION | tr '.' ':'`
+AC_SUBST([XFT_LT_VERSION])
+
+#
+# Check for Xrender
+#
+PKG_CHECK_MODULES(XRENDER, xrender >= 0.8.2, [xrender_found_with_pkgconfig=yes], 
+                  [xrender_found_with_pkgconfig=no])
+case "$xrender_found_with_pkgconfig" in
+no)
+	PKG_CHECK_MODULES(XRENDER, xrender >= 0, [old_xrender_found_with_pkgconfig=yes], 
+			  [old_xrender_found_with_pkgconfig=no])
+	case "$old_xrender_found_with_pkgconfig" in
+	yes)
+		XRENDER_LIBS="$XRENDER_LIBS -lXext -lX11"
+		;;
+	*)
+	        # checks for X
+	        AC_PATH_X
+
+	        XRENDER_CFLAGS="-I$x_includes"
+	        XRENDER_LIBS="-L$x_libraries -lXrender -lXext -lX11"
+
+	        saved_CPPFLAGS="$CPPFLAGS"
+	        CPPFLAGS="$CPPFLAGS $XRENDER_CFLAGS"
+	        AC_CHECK_HEADERS([X11/extensions/Xrender.h], [], [AC_MSG_ERROR([Xrender.h not found.])])
+	        CPPFLAGS="$saved_CPPFLAGS"
+
+	        saved_LIBS="$LIBS"
+	        LIBS="$LIBS $XRENDER_LIBS"
+	        AC_CHECK_FUNCS([XRenderFindStandardFormat], [], [AC_MSG_ERROR([libXrender not found or too old.])])
+	        LIBS="$saved_LIBS"
+		;;
+	esac
+        ;;
+esac
+
+# Check freetype configuration
+AC_ARG_WITH(freetype-config, [  --with-freetype-config=PROG   Use FreeType configuration program PROG], freetype_config=$withval, freetype_config=auto)
+	
+if test "$freetype_config" = "auto"; then
+	PKG_CHECK_MODULES(FREETYPE, freetype2, 
+		freetype_config=no, freetype_config=yes)
+fi
+
+if test "$freetype_config" = "yes"; then 
+	AC_PATH_PROG(ft_config,freetype-config,no)
+	if test "$ft_config" = "no"; then
+		AC_MSG_ERROR([You must have freetype installed; see http://www.freetype.org/])
+	fi
+else
+	ft_config="$freetype_config"
+fi
+
+if test "$freetype_config" != "no"; then 	
+	FREETYPE_CFLAGS="`$ft_config --cflags`"
+	FREETYPE_LIBS="`$ft_config --libs`"
+fi
+
+# Check fontconfig configuration
+PKG_CHECK_MODULES(FONTCONFIG, fontconfig >= 2.2)
+
+AC_SUBST(XRENDER_CFLAGS)
+AC_SUBST(XRENDER_LIBS)
+AC_SUBST(FREETYPE_CFLAGS)
+AC_SUBST(FREETYPE_LIBS)
+AC_SUBST(FONTCONFIG_CFLAGS)
+AC_SUBST(FONTCONFIG_LIBS)
+
+fontconfig_save_libs="$LIBS"
+fontconfig_save_cflags="$CFLAGS"
+LIBS="$LIBS $FREETYPE_LIBS"
+CFLAGS="$CFLAGS $FREETYPE_CFLAGS"
+AC_CHECK_FUNCS(FT_Get_Next_Char FT_Get_BDF_Property FT_Get_PS_Font_Info FT_Has_PS_Glyph_Names FT_GlyphSlot_Embolden)
+AC_CHECK_MEMBER(FT_Bitmap_Size.y_ppem,
+		HAVE_FT_BITMAP_SIZE_Y_PPEM=1,
+		HAVE_FT_BITMAP_SIZE_Y_PPEM=0,
+[#include <ft2build.h>
+#include FT_FREETYPE_H])
+AC_DEFINE_UNQUOTED(HAVE_FT_BITMAP_SIZE_Y_PPEM,$HAVE_FT_BITMAP_SIZE_Y_PPEM,
+		   [FT_Bitmap_Size structure includes y_ppem field])
+
+LIBS="$fontconfig_save_libs"
+CFLAGS="$fontconfig_save_cflags"
+
+if test "$VERSION" = "" ; then
+       VERSION=$PACKAGE_VERSION;
+fi
+
+AC_CONFIG_FILES([Makefile
+		xft.pc
+		src/Makefile
+		man/Makefile])
+AC_OUTPUT
diff --git a/libXft/src/xftcore.c b/libXft/src/xftcore.c
index 04fa47640..a0103cf26 100644
--- a/libXft/src/xftcore.c
+++ b/libXft/src/xftcore.c
@@ -1,1383 +1,1383 @@
-/*
- * Copyright © 2000 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "xftint.h"
-
-_X_HIDDEN void
-XftRectCore (XftDraw		*draw,
-	     _Xconst XftColor	*color,
-	     int		x, 
-	     int		y,
-	     unsigned int	width,
-	     unsigned int	height)
-{
-    if (color->color.alpha >= 0x8000)
-    {
-	XSetForeground (draw->dpy, draw->core.gc, color->pixel);
-	XFillRectangle (draw->dpy, draw->drawable, draw->core.gc,
-			x, y, width, height);
-    }
-}
-
-/*
- * Use the core protocol to draw the glyphs
- */
-
-static void
-_XftSharpGlyphMono (XftDraw	*draw,
-		    XftGlyph	*glyph,
-		    int		x,
-		    int		y)
-{
-    unsigned char   *srcLine = glyph->bitmap, *src;
-    unsigned char   bits, bitsMask;
-    int		    width = glyph->metrics.width;
-    int		    stride = ((width + 31) & ~31) >> 3;
-    int		    height = glyph->metrics.height;
-    int		    w;
-    int		    xspan, lenspan;
-
-    x -= glyph->metrics.x;
-    y -= glyph->metrics.y;
-    while (height--)
-    {
-	src = srcLine;
-	srcLine += stride;
-	w = width;
-	
-	bitsMask = 0x80;    /* FreeType is always MSB first */
-	bits = *src++;
-	
-	xspan = x;
-	while (w)
-	{
-	    if (bits & bitsMask)
-	    {
-		lenspan = 0;
-		do
-		{
-		    lenspan++;
-		    if (lenspan == w)
-			break;
-		    bitsMask = bitsMask >> 1;
-		    if (!bitsMask)
-		    {
-			bits = *src++;
-			bitsMask = 0x80;
-		    }
-		} while (bits & bitsMask);
-		XFillRectangle (draw->dpy, draw->drawable, 
-				draw->core.gc, xspan, y, lenspan, 1);
-		xspan += lenspan;
-		w -= lenspan;
-	    }
-	    else
-	    {
-		do
-		{
-		    w--;
-		    xspan++;
-		    if (!w)
-			break;
-		    bitsMask = bitsMask >> 1;
-		    if (!bitsMask)
-		    {
-			bits = *src++;
-			bitsMask = 0x80;
-		    }
-		} while (!(bits & bitsMask));
-	    }
-	}
-	y++;
-    }
-}
-
-/*
- * Draw solid color text from an anti-aliased bitmap.  This is a
- * fallback for cases where a particular drawable has no AA code
- */
-static void
-_XftSharpGlyphGray (XftDraw	*draw,
-		    XftGlyph	*glyph,
-		    int		x,
-		    int		y)
-{
-    unsigned char   *srcLine = glyph->bitmap, *src, bits;
-    int		    width = glyph->metrics.width;
-    int		    stride = ((width + 3) & ~3);
-    int		    height = glyph->metrics.height;
-    int		    w;
-    int		    xspan, lenspan;
-
-    x -= glyph->metrics.x;
-    y -= glyph->metrics.y;
-    while (height--)
-    {
-	src = srcLine;
-	srcLine += stride;
-	w = width;
-	
-	bits = *src++;
-	xspan = x;
-	while (w)
-	{
-	    if (bits >= 0x80)
-	    {
-		lenspan = 0;
-		do
-		{
-		    lenspan++;
-		    if (lenspan == w)
-			break;
-		    bits = *src++;
-		} while (bits >= 0x80);
-		XFillRectangle (draw->dpy, draw->drawable, 
-				draw->core.gc, xspan, y, lenspan, 1);
-		xspan += lenspan;
-		w -= lenspan;
-	    }
-	    else
-	    {
-		do
-		{
-		    w--;
-		    xspan++;
-		    if (!w)
-			break;
-		    bits = *src++;
-		} while (bits < 0x80);
-	    }
-	}
-	y++;
-    }
-}
-
-static void
-_XftSharpGlyphRgba (XftDraw	*draw,
-		    XftGlyph	*glyph,
-		    int		x,
-		    int		y)
-{
-    CARD32	    *srcLine = glyph->bitmap, *src, bits;
-    int		    width = glyph->metrics.width;
-    int		    stride = ((width + 3) & ~3);
-    int		    height = glyph->metrics.height;
-    int		    w;
-    int		    xspan, lenspan;
-
-    x -= glyph->metrics.x;
-    y -= glyph->metrics.y;
-    while (height--)
-    {
-	src = srcLine;
-	srcLine += stride;
-	w = width;
-	
-	bits = *src++;
-	xspan = x;
-	while (w)
-	{
-	    if (bits >= 0x80000000)
-	    {
-		lenspan = 0;
-		do
-		{
-		    lenspan++;
-		    if (lenspan == w)
-			break;
-		    bits = *src++;
-		} while (bits >= 0x80000000);
-		XFillRectangle (draw->dpy, draw->drawable, 
-				draw->core.gc, xspan, y, lenspan, 1);
-		xspan += lenspan;
-		w -= lenspan;
-	    }
-	    else
-	    {
-		do
-		{
-		    w--;
-		    xspan++;
-		    if (!w)
-			break;
-		    bits = *src++;
-		} while (bits < 0x80000000);
-	    }
-	}
-	y++;
-    }
-}
-
-typedef void (*XftSharpGlyph) (XftDraw	*draw,
-			       XftGlyph	*glyph,
-			       int	x,
-			       int	y);
-
-static XftSharpGlyph
-_XftSharpGlyphFind (XftDraw *draw, XftFont *public)
-{
-    XftFontInt *font = (XftFontInt *) public;
-
-    if (!font->info.antialias)
-	return _XftSharpGlyphMono;
-    else switch (font->info.rgba) {
-    case FC_RGBA_RGB:
-    case FC_RGBA_BGR:
-    case FC_RGBA_VRGB:
-    case FC_RGBA_VBGR:
-	return _XftSharpGlyphRgba;
-    default:
-	return _XftSharpGlyphGray;
-    }
-}
-
-/*
- * Draw glyphs to a target that supports anti-aliasing
- */
-
-/*
- * Primitives for converting between RGB values and TrueColor pixels
- */
- 
-static void
-_XftExamineBitfield (unsigned long mask, int *shift, int *len)
-{
-    int	s, l;
-
-    s = 0;
-    while ((mask & 1) == 0)
-    {
-	mask >>= 1;
-	s++;
-    }
-    l = 0;
-    while ((mask & 1) == 1)
-    {
-	mask >>= 1;
-	l++;
-    }
-    *shift = s;
-    *len = l;
-}
-
-static CARD32
-_XftGetField (unsigned long l_pixel, int shift, int len)
-{
-    CARD32  pixel = (CARD32) l_pixel;
-    
-    pixel = pixel & (((1 << (len)) - 1) << shift);
-    pixel = pixel << (32 - (shift + len)) >> 24;
-    while (len < 8)
-    {
-	pixel |= (pixel >> len);
-	len <<= 1;
-    }
-    return pixel;
-}
-
-static unsigned long
-_XftPutField (CARD32 pixel, int shift, int len)
-{
-    unsigned long   l_pixel = (unsigned long) pixel;
-
-    shift = shift - (8 - len);
-    if (len <= 8)
-	l_pixel &= (((1 << len) - 1) << (8 - len));
-    if (shift < 0)
-	l_pixel >>= -shift;
-    else
-	l_pixel <<= shift;
-    return l_pixel;
-}
-
-/*
- * This is used when doing XftCharFontSpec/XftGlyphFontSpec where
- * some of the fonts are bitmaps and some are anti-aliased to handle
- * the bitmap portions
- */
-static void
-_XftSmoothGlyphMono (XImage		*image,
-		     _Xconst XftGlyph	*xftg,
-		     int		x,
-		     int		y,
-		     _Xconst XftColor   *color)
-{
-    unsigned char   *srcLine = xftg->bitmap, *src;
-    unsigned char   bits, bitsMask;
-    int		    width = xftg->metrics.width;
-    int		    stride = ((width + 31) & ~31) >> 3;
-    int		    height = xftg->metrics.height;
-    int		    w;
-    int		    xspan;
-    int		    r_shift, r_len;
-    int		    g_shift, g_len;
-    int		    b_shift, b_len;
-    unsigned long   pixel;
-
-    _XftExamineBitfield (image->red_mask, &r_shift, &r_len);
-    _XftExamineBitfield (image->green_mask, &g_shift, &g_len);
-    _XftExamineBitfield (image->blue_mask, &b_shift, &b_len);
-    pixel = (_XftPutField (color->color.red >> 8, r_shift, r_len) |
-	     _XftPutField (color->color.green >> 8, g_shift, g_len) |
-	     _XftPutField (color->color.blue >> 8, b_shift, b_len));
-    x -= xftg->metrics.x;
-    y -= xftg->metrics.y;
-    while (height--)
-    {
-	src = srcLine;
-	srcLine += stride;
-	w = width;
-	
-	bitsMask = 0x80;    /* FreeType is always MSB first */
-	bits = *src++;
-	
-	xspan = x;
-	while (w--)
-	{
-	    if (bits & bitsMask)
-		XPutPixel (image, xspan, y, pixel);
-    	    bitsMask = bitsMask >> 1;
-    	    if (!bitsMask)
-    	    {
-    		bits = *src++;
-    		bitsMask = 0x80;
-    	    }
-	    xspan++;
-	}
-	y++;
-    }
-}
-
-/*
- * As simple anti-aliasing is likely to be common, there are three
- * optimized versions for the usual true color pixel formats (888, 565, 555).
- * Other formats are handled by the general case
- */
-
-#define cvt8888to0565(s)    ((((s) >> 3) & 0x001f) | \
-			     (((s) >> 5) & 0x07e0) | \
-			     (((s) >> 8) & 0xf800))
-
-#define cvt0565to8888(s)    (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
-			     ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
-			     ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
-
-#define cvt8888to0555(s)    ((((s) >> 3) & 0x001f) | \
-			     (((s) >> 6) & 0x03e0) | \
-			     (((s) >> 7) & 0x7c00))
-
-#define cvt0555to8888(s)    (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
-			     ((((s) << 6) & 0xf800) | (((s) >> 0) & 0x300)) | \
-			     ((((s) << 9) & 0xf80000) | (((s) << 4) & 0x70000)))
-
-
-#define XftIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
-#define XftIntDiv(a,b)	 (((CARD16) (a) * 255) / (b))
-
-#define XftGet8(v,i)   ((CARD16) (CARD8) ((v) >> i))
-
-/*
- * There are two ways of handling alpha -- either as a single unified value or
- * a separate value for each component, hence each macro must have two
- * versions.  The unified alpha version has a 'U' at the end of the name,
- * the component version has a 'C'.  Similarly, functions which deal with
- * this difference will have two versions using the same convention.
- */
-
-#define XftOverU(x,y,i,a,t) ((t) = XftIntMult(XftGet8(y,i),(a),(t)) + XftGet8(x,i),\
-			   (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
-
-#define XftOverC(x,y,i,a,t) ((t) = XftIntMult(XftGet8(y,i),XftGet8(a,i),(t)) + XftGet8(x,i),\
-			    (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
-
-#define XftInU(x,i,a,t) ((CARD32) XftIntMult(XftGet8(x,i),(a),(t)) << (i))
-
-#define XftInC(x,i,a,t) ((CARD32) XftIntMult(XftGet8(x,i),XftGet8(a,i),(t)) << (i))
-
-#define XftGen(x,y,i,ax,ay,t,u,v) ((t) = (XftIntMult(XftGet8(y,i),ay,(u)) + \
-					 XftIntMult(XftGet8(x,i),ax,(v))),\
-				  (CARD32) ((CARD8) ((t) | \
-						     (0 - ((t) >> 8)))) << (i))
-
-#define XftAdd(x,y,i,t)	((t) = XftGet8(x,i) + XftGet8(y,i), \
-			 (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
-
-
-static CARD32
-fbOver24 (CARD32 x, CARD32 y)
-{
-    CARD16  a = ~x >> 24;
-    CARD16  t;
-    CARD32  m,n,o;
-
-    m = XftOverU(x,y,0,a,t);
-    n = XftOverU(x,y,8,a,t);
-    o = XftOverU(x,y,16,a,t);
-    return m|n|o;
-}
-
-static CARD32
-fbIn (CARD32 x, CARD8 y)
-{
-    CARD16  a = y;
-    CARD16  t;
-    CARD32  m,n,o,p;
-
-    m = XftInU(x,0,a,t);
-    n = XftInU(x,8,a,t);
-    o = XftInU(x,16,a,t);
-    p = XftInU(x,24,a,t);
-    return m|n|o|p;
-}
-
-static void
-_XftSmoothGlyphGray8888 (XImage		    *image,
-			 _Xconst XftGlyph   *xftg,
-			 int		    x,
-			 int		    y,
-			 _Xconst XftColor   *color)
-{
-    CARD32	src, srca;
-    CARD32	r, g, b;
-    CARD32	*dstLine, *dst, d;
-    CARD8	*maskLine, *mask, m;
-    int		dstStride, maskStride;
-    int		width, height;
-    int		w;
-
-    srca = color->color.alpha >> 8;
-    
-    /* This handles only RGB and BGR */
-    g = (color->color.green & 0xff00);
-    if (image->red_mask == 0xff0000)
-    {
-	r = (color->color.red & 0xff00) << 8;
-	b = color->color.blue >> 8;
-    }
-    else
-    {
-	r = color->color.red >> 8;
-	b = (color->color.blue & 0xff00) << 8;
-    }
-    src = (srca << 24) | r | g | b;
-    
-    width = xftg->metrics.width;
-    height = xftg->metrics.height;
-    
-    x -= xftg->metrics.x;
-    y -= xftg->metrics.y;
-
-    dstLine = (CARD32 *) (image->data + image->bytes_per_line * y + (x << 2));
-    dstStride = image->bytes_per_line >> 2;
-    maskLine = (unsigned char *) xftg->bitmap;
-    maskStride = (width + 3) & ~3;
-    
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    m = *mask++;
-	    if (m == 0xff)
-	    {
-		if (srca == 0xff)
-		    *dst = src;
-		else
-		    *dst = fbOver24 (src, *dst);
-	    }
-	    else if (m)
-	    {
-		d = fbIn (src, m);
-		*dst = fbOver24 (d, *dst);
-	    }
-	    dst++;
-	}
-    }
-}
-
-static void
-_XftSmoothGlyphGray565 (XImage		    *image,
-			_Xconst XftGlyph    *xftg,
-			int		    x,
-			int		    y,
-			_Xconst XftColor    *color)
-{
-    CARD32	src, srca;
-    CARD32	r, g, b;
-    CARD32	d;
-    CARD16	*dstLine, *dst;
-    CARD8	*maskLine, *mask, m;
-    int		dstStride, maskStride;
-    int		width, height;
-    int		w;
-
-    srca = color->color.alpha >> 8;
-    
-    /* This handles only RGB and BGR */
-    g = (color->color.green & 0xff00);
-    if (image->red_mask == 0xf800)
-    {
-	r = (color->color.red & 0xff00) << 8;
-	b = color->color.blue >> 8;
-    }
-    else
-    {
-	r = color->color.red >> 8;
-	b = (color->color.blue & 0xff00) << 8;
-    }
-    src = (srca << 24) | r | g | b;
-    
-    width = xftg->metrics.width;
-    height = xftg->metrics.height;
-    
-    x -= xftg->metrics.x;
-    y -= xftg->metrics.y;
-
-    dstLine = (CARD16 *) (image->data + image->bytes_per_line * y + (x << 1));
-    dstStride = image->bytes_per_line >> 1;
-    maskLine = (unsigned char *) xftg->bitmap;
-    maskStride = (width + 3) & ~3;
-    
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    m = *mask++;
-	    if (m == 0xff)
-	    {
-		if (srca == 0xff)
-		    d = src;
-		else
-		{
-		    d = *dst;
-		    d = fbOver24 (src, cvt0565to8888(d));
-		}
-		*dst = cvt8888to0565(d);
-	    }
-	    else if (m)
-	    {
-		d = *dst;
-		d = fbOver24 (fbIn(src,m), cvt0565to8888(d));
-		*dst = cvt8888to0565(d);
-	    }
-	    dst++;
-	}
-    }
-}
-
-static void
-_XftSmoothGlyphGray555 (XImage		    *image,
-			_Xconst XftGlyph    *xftg,
-			int		    x,
-			int		    y,
-			_Xconst XftColor    *color)
-{
-    CARD32	src, srca;
-    CARD32	r, g, b;
-    CARD32	d;
-    CARD16	*dstLine, *dst;
-    CARD8	*maskLine, *mask, m;
-    int		dstStride, maskStride;
-    int		width, height;
-    int		w;
-
-    srca = color->color.alpha >> 8;
-    
-    /* This handles only RGB and BGR */
-    g = (color->color.green & 0xff00);
-    if (image->red_mask == 0xf800)
-    {
-	r = (color->color.red & 0xff00) << 8;
-	b = color->color.blue >> 8;
-    }
-    else
-    {
-	r = color->color.red >> 8;
-	b = (color->color.blue & 0xff00) << 8;
-    }
-    src = (srca << 24) | r | g | b;
-    
-    width = xftg->metrics.width;
-    height = xftg->metrics.height;
-    
-    x -= xftg->metrics.x;
-    y -= xftg->metrics.y;
-
-    dstLine = (CARD16 *) (image->data + image->bytes_per_line * y + (x << 1));
-    dstStride = image->bytes_per_line >> 1;
-    maskLine = (unsigned char *) xftg->bitmap;
-    maskStride = (width + 3) & ~3;
-    
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    m = *mask++;
-	    if (m == 0xff)
-	    {
-		if (srca == 0xff)
-		    d = src;
-		else
-		{
-		    d = *dst;
-		    d = fbOver24 (src, cvt0555to8888(d));
-		}
-		*dst = cvt8888to0555(d);
-	    }
-	    else if (m)
-	    {
-		d = *dst;
-		d = fbOver24 (fbIn(src,m), cvt0555to8888(d));
-		*dst = cvt8888to0555(d);
-	    }
-	    dst++;
-	}
-    }
-}
-
-static void
-_XftSmoothGlyphGray (XImage		*image,
-		     _Xconst XftGlyph	*xftg,
-		     int		x,
-		     int		y,
-		     _Xconst XftColor   *color)
-{
-    CARD32	    src, srca;
-    int		    r_shift, r_len;
-    int		    g_shift, g_len;
-    int		    b_shift, b_len;
-    CARD8	    *maskLine, *mask, m;
-    int		    maskStride;
-    CARD32	    d;
-    unsigned long   pixel;
-    int		    width, height;
-    int		    w, tx;
-    
-    srca = color->color.alpha >> 8;
-    src = (srca << 24 |
-	   (color->color.red & 0xff00) << 8 |
-	   (color->color.green & 0xff00) |
-	   (color->color.blue) >> 8);
-    x -= xftg->metrics.x;
-    y -= xftg->metrics.y;
-    width = xftg->metrics.width;
-    height = xftg->metrics.height;
-    
-    maskLine = (unsigned char *) xftg->bitmap;
-    maskStride = (width + 3) & ~3;
-
-    _XftExamineBitfield (image->red_mask, &r_shift, &r_len);
-    _XftExamineBitfield (image->green_mask, &g_shift, &g_len);
-    _XftExamineBitfield (image->blue_mask, &b_shift, &b_len);
-    while (height--)
-    {
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-	tx = x;
-	
-	while (w--)
-	{
-	    m = *mask++;
-	    if (m == 0xff)
-	    {
-		if (srca == 0xff)
-		    d = src;
-		else
-		{
-		    pixel = XGetPixel (image, tx, y);
-		    d = (_XftGetField (pixel, r_shift, r_len) << 16 |
-			 _XftGetField (pixel, g_shift, g_len) << 8 |
-			 _XftGetField (pixel, b_shift, b_len));
-		    d = fbOver24 (src, d);
-		}
-		pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) |
-			 _XftPutField ((d >>  8) & 0xff, g_shift, g_len) |
-			 _XftPutField ((d      ) & 0xff, b_shift, b_len));
-		XPutPixel (image, tx, y, pixel);
-	    }
-	    else if (m)
-	    {
-		pixel = XGetPixel (image, tx, y);
-		d = (_XftGetField (pixel, r_shift, r_len) << 16 |
-		     _XftGetField (pixel, g_shift, g_len) << 8 |
-		     _XftGetField (pixel, b_shift, b_len));
-		d = fbOver24 (fbIn(src,m), d);
-		pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) |
-			 _XftPutField ((d >>  8) & 0xff, g_shift, g_len) |
-			 _XftPutField ((d      ) & 0xff, b_shift, b_len));
-		XPutPixel (image, tx, y, pixel);
-	    }
-	    tx++;
-	}
-	y++;
-    }
-}
-
-static void
-_XftSmoothGlyphRgba (XImage		*image,
-		     _Xconst XftGlyph	*xftg,
-		     int		x,
-		     int		y,
-		     _Xconst XftColor   *color)
-{
-    CARD32	    src, srca;
-    int		    r_shift, r_len;
-    int		    g_shift, g_len;
-    int		    b_shift, b_len;
-    CARD32	    *mask, ma;
-    CARD32	    d;
-    unsigned long   pixel;
-    int		    width, height;
-    int		    w, tx;
-    
-    srca = color->color.alpha >> 8;
-    src = (srca << 24 |
-	   (color->color.red & 0xff00) << 8 |
-	   (color->color.green & 0xff00) |
-	   (color->color.blue) >> 8);
-    x -= xftg->metrics.x;
-    y -= xftg->metrics.y;
-    width = xftg->metrics.width;
-    height = xftg->metrics.height;
-    
-    mask = (CARD32 *) xftg->bitmap;
-
-    _XftExamineBitfield (image->red_mask, &r_shift, &r_len);
-    _XftExamineBitfield (image->green_mask, &g_shift, &g_len);
-    _XftExamineBitfield (image->blue_mask, &b_shift, &b_len);
-    while (height--)
-    {
-	w = width;
-	tx = x;
-	
-	while (w--)
-	{
-	    ma = *mask++;
-	    if (ma == 0xffffffff)
-	    {
-		if (srca == 0xff)
-		    d = src;
-		else
-		{
-		    pixel = XGetPixel (image, tx, y);
-		    d = (_XftGetField (pixel, r_shift, r_len) << 16 |
-			 _XftGetField (pixel, g_shift, g_len) << 8 |
-			 _XftGetField (pixel, b_shift, b_len));
-		    d = fbOver24 (src, d);
-		}
-		pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) |
-			 _XftPutField ((d >>  8) & 0xff, g_shift, g_len) |
-			 _XftPutField ((d      ) & 0xff, b_shift, b_len));
-		XPutPixel (image, tx, y, pixel);
-	    }
-	    else if (ma)
-	    {
-		CARD32	m,n,o;
-		pixel = XGetPixel (image, tx, y);
-		d = (_XftGetField (pixel, r_shift, r_len) << 16 |
-		     _XftGetField (pixel, g_shift, g_len) << 8 |
-		     _XftGetField (pixel, b_shift, b_len));
-#define XftInOverC(src,srca,msk,dst,i,result) { \
-    CARD16  __a = XftGet8(msk,i); \
-    CARD32  __t, __ta; \
-    CARD32  __i; \
-    __t = XftIntMult (XftGet8(src,i), __a,__i); \
-    __ta = (CARD8) ~XftIntMult (srca, __a,__i); \
-    __t = __t + XftIntMult(XftGet8(dst,i),__ta,__i); \
-    __t = (CARD32) (CARD8) (__t | (-(__t >> 8))); \
-    result = __t << (i); \
-}
-		XftInOverC(src,srca,ma,d,0,m);
-		XftInOverC(src,srca,ma,d,8,n);
-		XftInOverC(src,srca,ma,d,16,o);
-		d = m | n | o;
-		pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) |
-			 _XftPutField ((d >>  8) & 0xff, g_shift, g_len) |
-			 _XftPutField ((d      ) & 0xff, b_shift, b_len));
-		XPutPixel (image, tx, y, pixel);
-	    }
-	    tx++;
-	}
-	y++;
-    }
-}
-
-static FcBool
-_XftSmoothGlyphPossible (XftDraw *draw)
-{
-    if (!draw->visual)
-	return FcFalse;
-    if (draw->visual->class != TrueColor)
-	return FcFalse;
-    return FcTrue;
-}
-
-typedef	void (*XftSmoothGlyph) (XImage		    *image, 
-				_Xconst XftGlyph    *xftg,
-				int		    x,
-				int		    y,
-				_Xconst XftColor    *color);
-
-static XftSmoothGlyph
-_XftSmoothGlyphFind (XftDraw *draw, XftFont *public)
-{
-    XftFontInt *font = (XftFontInt *) public;
-
-    if (!font->info.antialias)
-	return _XftSmoothGlyphMono;
-    else switch (font->info.rgba) {
-    case FC_RGBA_RGB:
-    case FC_RGBA_BGR:
-    case FC_RGBA_VRGB:
-    case FC_RGBA_VBGR:
-	return _XftSmoothGlyphRgba;
-    default:
-	switch (XftDrawBitsPerPixel (draw)) {
-	case 32:
-	    if ((draw->visual->red_mask   == 0xff0000 &&
-		 draw->visual->green_mask == 0x00ff00 &&
-		 draw->visual->blue_mask  == 0x0000ff) ||
-		(draw->visual->red_mask   == 0x0000ff &&
-		 draw->visual->green_mask == 0x00ff00 &&
-		 draw->visual->blue_mask  == 0xff0000))
-	    {
-		return _XftSmoothGlyphGray8888;
-	    }
-	    break;
-	case 16:
-	    if ((draw->visual->red_mask   == 0xf800 &&
-		 draw->visual->green_mask == 0x07e0 &&
-		 draw->visual->blue_mask  == 0x001f) ||
-		(draw->visual->red_mask   == 0x001f &&
-		 draw->visual->green_mask == 0x07e0 &&
-		 draw->visual->blue_mask  == 0xf800))
-	    {
-		return _XftSmoothGlyphGray565;
-	    }
-	    if ((draw->visual->red_mask   == 0x7c00 &&
-		 draw->visual->green_mask == 0x03e0 &&
-		 draw->visual->blue_mask  == 0x001f) ||
-		(draw->visual->red_mask   == 0x001f &&
-		 draw->visual->green_mask == 0x03e0 &&
-		 draw->visual->blue_mask  == 0x7c00))
-	    {
-		return _XftSmoothGlyphGray555;
-	    }
-	    break;
-	default:
-	    break;
-	}
-	return _XftSmoothGlyphGray;
-    }
-}
-
-static XftGlyph *
-_XftGlyphDefault (Display *dpy, XftFont   *public)
-{
-    XftFontInt	    *font = (XftFontInt *) public;
-    FT_UInt	    missing[XFT_NMISSING];
-    int		    nmissing;
-    FcBool	    glyphs_loaded = FcFalse;
-
-    if (XftFontCheckGlyph (dpy, public, FcTrue, 0, missing, &nmissing))
-	glyphs_loaded = FcTrue;
-    if (nmissing)
-	XftFontLoadGlyphs (dpy, public, glyphs_loaded, missing, nmissing);
-    return font->glyphs[0];
-}
-
-static int XftGetImageErrorHandler (Display *dpy, XErrorEvent *error_event)
-{
-    return 0;
-}
-
-_X_HIDDEN void
-XftGlyphCore (XftDraw		*draw,
-	      _Xconst XftColor	*color,
-	      XftFont		*public,
-	      int		x,
-	      int		y,
-	      _Xconst FT_UInt	*glyphs,
-	      int		nglyphs)
-{
-    Display	    *dpy = draw->dpy;
-    XftFontInt	    *font = (XftFontInt *) public;
-    XftGlyph	    *xftg;
-    FT_UInt	    glyph;
-    _Xconst FT_UInt *g;
-    FT_UInt	    missing[XFT_NMISSING];
-    FcBool	    glyphs_loaded;
-    int		    nmissing;
-    int		    n;
-    XErrorHandler   prev_error;
-
-    /*
-     * Load missing glyphs
-     */
-    g = glyphs;
-    n = nglyphs;
-    nmissing = 0;
-    glyphs_loaded = FcFalse;
-    while (n--)
-	if (XftFontCheckGlyph (dpy, public, FcTrue, *g++, missing, &nmissing))
-	    glyphs_loaded = FcTrue;
-    if (nmissing)
-	XftFontLoadGlyphs (dpy, public, FcTrue, missing, nmissing);
-    
-    g = glyphs;
-    n = nglyphs;
-    if ((font->info.antialias || color->color.alpha != 0xffff) &&
-	_XftSmoothGlyphPossible (draw))
-    {
-	XGlyphInfo	gi;
-	XImage		*image;
-        unsigned int    depth;
-	int		ox, oy;
-	XftSmoothGlyph	smooth = _XftSmoothGlyphFind (draw, public);
-	
-	XftGlyphExtents (dpy, public, glyphs, nglyphs, &gi);
-	if (!gi.width || !gi.height)
-	    goto bail1;
-	ox = x - gi.x;
-	oy = y - gi.y;
-	/*
-	 * Try to get bits directly from the drawable; if that fails,
-	 * use a temporary pixmap.  When it does fail, assume it
-	 * will probably fail for a while and keep using temporary
-	 * pixmaps for a while to avoid double round trips.
-	 */
-	if (draw->core.use_pixmap == 0)
-	{
-	    prev_error = XSetErrorHandler (XftGetImageErrorHandler);
-	    image = XGetImage (dpy, draw->drawable,
-			       ox, oy,
-			       gi.width, gi.height, AllPlanes,
-			       ZPixmap);
-	    XSetErrorHandler (prev_error);
-	    if (!image)
-		draw->core.use_pixmap = XFT_ASSUME_PIXMAP;
-	}
-	else
-	{
-	    draw->core.use_pixmap--;
-	    image = NULL;
-	}
-	if (!image && (depth = XftDrawDepth (draw)))
-	{
-	    Pixmap	pix;
-	    GC		gc;
-	    XGCValues	gcv;
-
-	    pix = XCreatePixmap (dpy, draw->drawable,
-				 gi.width, gi.height, depth);
-	    gcv.graphics_exposures = False;
-	    gc = XCreateGC (dpy, pix, GCGraphicsExposures, &gcv);
-	    XCopyArea (dpy, draw->drawable, pix, gc, ox, oy,
-		       gi.width, gi.height, 0, 0);
-	    XFreeGC (dpy, gc);
-	    image = XGetImage (dpy, pix, 0, 0, gi.width, gi.height, AllPlanes,
-			       ZPixmap);
-	    XFreePixmap (dpy, pix);
-	}
-	if (!image)
-	    goto bail1;
-	image->red_mask = draw->visual->red_mask;
-	image->green_mask = draw->visual->green_mask;
-	image->blue_mask = draw->visual->blue_mask;
-	if (image->byte_order != XftNativeByteOrder ())
-	    XftSwapImage (image);
-	while (n--)
-	{
-	    glyph = *g++;
-	    if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
-		xftg = _XftGlyphDefault (dpy, public);
-	    if (xftg)
-	    {
-		(*smooth) (image, xftg, x - ox, y - oy, color);
-		x += xftg->metrics.xOff;
-		y += xftg->metrics.yOff;
-	    }
-	}
-	if (image->byte_order != XftNativeByteOrder ())
-	    XftSwapImage (image);
-	XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, ox, oy,
-		   gi.width, gi.height);
-	XDestroyImage (image);
-    }
-    else
-    {
-	XftSharpGlyph	sharp = _XftSharpGlyphFind (draw, public);
-	while (n--)
-	{
-	    glyph = *g++;
-	    if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
-		xftg = _XftGlyphDefault (dpy, public);
-	    if (xftg)
-	    {
-		(*sharp) (draw, xftg, x, y);
-		x += xftg->metrics.xOff;
-		y += xftg->metrics.yOff;
-	    }
-	}
-    }
-bail1:
-    if (glyphs_loaded)
-	_XftFontManageMemory (dpy, public);
-}
-
-#define NUM_LOCAL   1024
-
-_X_HIDDEN void
-XftGlyphSpecCore (XftDraw		*draw,
-		  _Xconst XftColor	*color,
-		  XftFont		*public,
-		  _Xconst XftGlyphSpec	*glyphs,
-		  int			nglyphs)
-{
-    Display	    *dpy = draw->dpy;
-    XftFontInt	    *font = (XftFontInt *) public;
-    XftGlyph	    *xftg;
-    FT_UInt	    missing[XFT_NMISSING];
-    FcBool	    glyphs_loaded;
-    int		    nmissing;
-    int		    i;
-    XErrorHandler   prev_error;
-    int		    x1, y1, x2, y2;
-
-    /*
-     * Load missing glyphs
-     */
-    glyphs_loaded = FcFalse;
-    x1 = y1 = x2 = y2 = 0;
-    for (i = 0; i < nglyphs; i++)
-    {
-	XGlyphInfo	gi;
-	int		g_x1, g_x2, g_y1, g_y2;
-	
-	nmissing = 0;
-	if (XftFontCheckGlyph (dpy, public, FcTrue, glyphs[i].glyph, missing, &nmissing))
-	    glyphs_loaded = FcTrue;
-	if (nmissing)
-	    XftFontLoadGlyphs (dpy, public, FcTrue, missing, nmissing);
-
-	XftGlyphExtents (dpy, public, &glyphs[i].glyph, 1, &gi);
-	g_x1 = glyphs[i].x - gi.x;
-	g_y1 = glyphs[i].y - gi.y;
-	g_x2 = g_x1 + gi.width;
-	g_y2 = g_y1 + gi.height;
-	if (i)
-	{
-	    if (g_x1 < x1)
-		x1 = g_x1;
-	    if (g_y1 < y1)
-		y1 = g_y1;
-	    if (g_x2 > x2)
-		x2 = g_x2;
-	    if (g_y2 > y2)
-		y2 = g_y2;
-	}
-	else
-	{
-	    x1 = g_x1;
-	    y1 = g_y1;
-	    x2 = g_x2;
-	    y2 = g_y2;
-	}
-    }
-    
-    if (x1 == x2 || y1 == y2)
-	goto bail1;
-
-    if ((font->info.antialias || color->color.alpha != 0xffff) &&
-	_XftSmoothGlyphPossible (draw))
-    {
-	XImage		*image;
-        unsigned int    depth;
-	int		width = x2 - x1, height = y2 - y1;
-	XftSmoothGlyph	smooth = _XftSmoothGlyphFind (draw, public);
-
-	/*
-	 * Try to get bits directly from the drawable; if that fails,
-	 * use a temporary pixmap.  When it does fail, assume it
-	 * will probably fail for a while and keep using temporary
-	 * pixmaps for a while to avoid double round trips.
-	 */
-	if (draw->core.use_pixmap == 0)
-	{
-	    prev_error = XSetErrorHandler (XftGetImageErrorHandler);
-	    image = XGetImage (dpy, draw->drawable,
-			       x1, y1,
-			       width, height, AllPlanes,
-			       ZPixmap);
-	    XSetErrorHandler (prev_error);
-	    if (!image)
-		draw->core.use_pixmap = XFT_ASSUME_PIXMAP;
-	}
-	else
-	{
-	    draw->core.use_pixmap--;
-	    image = NULL;
-	}
-	if (!image && (depth = XftDrawDepth (draw)))
-	{
-	    Pixmap	pix;
-	    GC		gc;
-	    XGCValues	gcv;
-
-	    pix = XCreatePixmap (dpy, draw->drawable,
-				 width, height, depth);
-	    gcv.graphics_exposures = False;
-	    gc = XCreateGC (dpy, pix, GCGraphicsExposures, &gcv);
-	    XCopyArea (dpy, draw->drawable, pix, gc, x1, y1,
-		       width, height, 0, 0);
-	    XFreeGC (dpy, gc);
-	    image = XGetImage (dpy, pix, 0, 0, width, height, AllPlanes,
-			       ZPixmap);
-	    XFreePixmap (dpy, pix);
-	}
-	if (!image)
-	    goto bail1;
-	image->red_mask = draw->visual->red_mask;
-	image->green_mask = draw->visual->green_mask;
-	image->blue_mask = draw->visual->blue_mask;
-	if (image->byte_order != XftNativeByteOrder ())
-	    XftSwapImage (image);
-	for (i = 0; i < nglyphs; i++)
-	{
-	    FT_UInt glyph = glyphs[i].glyph;
-	    if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
-		xftg = _XftGlyphDefault (dpy, public);
-	    if (xftg)
-	    {
-		(*smooth) (image, xftg, glyphs[i].x - x1, 
-			   glyphs[i].y - y1, color);
-	    }
-	}
-	if (image->byte_order != XftNativeByteOrder ())
-	    XftSwapImage (image);
-	XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, x1, y1,
-		   width, height);
-	XDestroyImage (image);
-    }
-    else
-    {
-	XftSharpGlyph	sharp = _XftSharpGlyphFind (draw, public);
-	for (i = 0; i < nglyphs; i++)
-	{
-	    FT_UInt glyph = glyphs[i].glyph;
-	    if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
-		xftg = _XftGlyphDefault (dpy, public);
-	    if (xftg)
-		(*sharp) (draw, xftg, glyphs[i].x, glyphs[i].y);
-	}
-    }
-bail1:
-    if (glyphs_loaded)
-	_XftFontManageMemory (dpy, public);
-}
-
-_X_HIDDEN void
-XftGlyphFontSpecCore (XftDraw			*draw,
-		      _Xconst XftColor		*color,
-		      _Xconst XftGlyphFontSpec	*glyphs,
-		      int			nglyphs)
-{
-    Display	    *dpy = draw->dpy;
-    XftGlyph	    *xftg;
-    FT_UInt	    missing[XFT_NMISSING];
-    FcBool	    glyphs_loaded;
-    int		    nmissing;
-    int		    i;
-    XErrorHandler   prev_error;
-    int		    x1, y1, x2, y2;
-
-    /*
-     * Load missing glyphs
-     */
-    glyphs_loaded = FcFalse;
-    x1 = y1 = x2 = y2 = 0;
-    for (i = 0; i < nglyphs; i++)
-    {
-	XftFont		*public = glyphs[i].font;
-	XGlyphInfo	gi;
-	int		g_x1, g_x2, g_y1, g_y2;
-	
-	nmissing = 0;
-	if (XftFontCheckGlyph (dpy, public, FcTrue, glyphs[i].glyph, missing, &nmissing))
-	    glyphs_loaded = FcTrue;
-	if (nmissing)
-	    XftFontLoadGlyphs (dpy, public, FcTrue, missing, nmissing);
-	
-	XftGlyphExtents (dpy, public, &glyphs[i].glyph, 1, &gi);
-	g_x1 = glyphs[i].x - gi.x;
-	g_y1 = glyphs[i].y - gi.y;
-	g_x2 = g_x1 + gi.width;
-	g_y2 = g_y1 + gi.height;
-	if (i)
-	{
-	    if (g_x1 < x1)
-	    {
-		if (g_x1 < 0)
-		{
-		    /* do nothing if the given glyphs are out of range */
-		    short t = glyphs[i-1].font->max_advance_width
-			+ glyphs[i-1].x;
-		    if (t < 0 && glyphs[i-1].x > 0)
-			goto bail1;
-		}
-		x1 = g_x1;
-	    }
-	    if (g_y1 < y1)
-		y1 = g_y1;
-	    if (g_x2 > x2)
-		x2 = g_x2;
-	    if (g_y2 > y2)
-		y2 = g_y2;
-	}
-	else
-	{
-	    x1 = g_x1;
-	    y1 = g_y1;
-	    x2 = g_x2;
-	    y2 = g_y2;
-	}
-    }
-    
-    if (x1 == x2 || y1 == y2)
-	goto bail1;
-
-    for (i = 0; i < nglyphs; i++)
-	if (((XftFontInt *) glyphs[i].font)->info.antialias)
-	    break;
-    
-    if ((i != nglyphs || color->color.alpha != 0xffff) &&
-	_XftSmoothGlyphPossible (draw))
-    {
-	XImage		*image;
-        unsigned int    depth;
-	int		width = x2 - x1, height = y2 - y1;
-
-	/*
-	 * Try to get bits directly from the drawable; if that fails,
-	 * use a temporary pixmap.  When it does fail, assume it
-	 * will probably fail for a while and keep using temporary
-	 * pixmaps for a while to avoid double round trips.
-	 */
-	if (draw->core.use_pixmap == 0)
-	{
-	    prev_error = XSetErrorHandler (XftGetImageErrorHandler);
-	    image = XGetImage (dpy, draw->drawable,
-			       x1, y1,
-			       width, height, AllPlanes,
-			       ZPixmap);
-	    XSetErrorHandler (prev_error);
-	    if (!image)
-		draw->core.use_pixmap = XFT_ASSUME_PIXMAP;
-	}
-	else
-	{
-	    draw->core.use_pixmap--;
-	    image = NULL;
-	}
-	if (!image && (depth = XftDrawDepth (draw)))
-	{
-	    Pixmap	pix;
-	    GC		gc;
-	    XGCValues	gcv;
-
-	    pix = XCreatePixmap (dpy, draw->drawable,
-				 width, height, depth);
-	    gcv.graphics_exposures = False;
-	    gc = XCreateGC (dpy, pix, GCGraphicsExposures, &gcv);
-	    XCopyArea (dpy, draw->drawable, pix, gc, x1, y1,
-		       width, height, 0, 0);
-	    XFreeGC (dpy, gc);
-	    image = XGetImage (dpy, pix, 0, 0, width, height, AllPlanes,
-			       ZPixmap);
-	    XFreePixmap (dpy, pix);
-	}
-	if (!image)
-	    goto bail1;
-	image->red_mask = draw->visual->red_mask;
-	image->green_mask = draw->visual->green_mask;
-	image->blue_mask = draw->visual->blue_mask;
-	if (image->byte_order != XftNativeByteOrder ())
-	    XftSwapImage (image);
-	for (i = 0; i < nglyphs; i++)
-	{
-	    XftFont	    *public = glyphs[i].font;
-	    XftFontInt	    *font = (XftFontInt *) public;
-	    XftSmoothGlyph  smooth = _XftSmoothGlyphFind (draw, public);
-	    FT_UInt	    glyph = glyphs[i].glyph;
-	    
-	    if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
-		xftg = _XftGlyphDefault (dpy, public);
-	    if (xftg)
-	    {
-		(*smooth) (image, xftg, glyphs[i].x - x1, 
-			   glyphs[i].y - y1, color);
-	    }
-	}
-	if (image->byte_order != XftNativeByteOrder ())
-	    XftSwapImage (image);
-	XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, x1, y1,
-		   width, height);
-	XDestroyImage (image);
-    }
-    else
-    {
-	for (i = 0; i < nglyphs; i++)
-	{
-	    XftFont		*public = glyphs[i].font;
-	    XftFontInt		*font = (XftFontInt *) public;
-	    XftSharpGlyph	sharp = _XftSharpGlyphFind (draw, public);
-	    FT_UInt		glyph = glyphs[i].glyph;
-	    
-	    if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
-		xftg = _XftGlyphDefault (dpy, public);
-	    if (xftg)
-		(*sharp) (draw, xftg, glyphs[i].x, glyphs[i].y);
-	}
-    }
-bail1:
-    if (glyphs_loaded)
-	for (i = 0; i < nglyphs; i++)
-	    _XftFontManageMemory (dpy, glyphs[i].font);
-}
+/*
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "xftint.h"
+
+_X_HIDDEN void
+XftRectCore (XftDraw		*draw,
+	     _Xconst XftColor	*color,
+	     int		x, 
+	     int		y,
+	     unsigned int	width,
+	     unsigned int	height)
+{
+    if (color->color.alpha >= 0x8000)
+    {
+	XSetForeground (draw->dpy, draw->core.gc, color->pixel);
+	XFillRectangle (draw->dpy, draw->drawable, draw->core.gc,
+			x, y, width, height);
+    }
+}
+
+/*
+ * Use the core protocol to draw the glyphs
+ */
+
+static void
+_XftSharpGlyphMono (XftDraw	*draw,
+		    XftGlyph	*glyph,
+		    int		x,
+		    int		y)
+{
+    unsigned char   *srcLine = glyph->bitmap, *src;
+    unsigned char   bits, bitsMask;
+    int		    width = glyph->metrics.width;
+    int		    stride = ((width + 31) & ~31) >> 3;
+    int		    height = glyph->metrics.height;
+    int		    w;
+    int		    xspan, lenspan;
+
+    x -= glyph->metrics.x;
+    y -= glyph->metrics.y;
+    while (height--)
+    {
+	src = srcLine;
+	srcLine += stride;
+	w = width;
+	
+	bitsMask = 0x80;    /* FreeType is always MSB first */
+	bits = *src++;
+	
+	xspan = x;
+	while (w)
+	{
+	    if (bits & bitsMask)
+	    {
+		lenspan = 0;
+		do
+		{
+		    lenspan++;
+		    if (lenspan == w)
+			break;
+		    bitsMask = bitsMask >> 1;
+		    if (!bitsMask)
+		    {
+			bits = *src++;
+			bitsMask = 0x80;
+		    }
+		} while (bits & bitsMask);
+		XFillRectangle (draw->dpy, draw->drawable, 
+				draw->core.gc, xspan, y, lenspan, 1);
+		xspan += lenspan;
+		w -= lenspan;
+	    }
+	    else
+	    {
+		do
+		{
+		    w--;
+		    xspan++;
+		    if (!w)
+			break;
+		    bitsMask = bitsMask >> 1;
+		    if (!bitsMask)
+		    {
+			bits = *src++;
+			bitsMask = 0x80;
+		    }
+		} while (!(bits & bitsMask));
+	    }
+	}
+	y++;
+    }
+}
+
+/*
+ * Draw solid color text from an anti-aliased bitmap.  This is a
+ * fallback for cases where a particular drawable has no AA code
+ */
+static void
+_XftSharpGlyphGray (XftDraw	*draw,
+		    XftGlyph	*glyph,
+		    int		x,
+		    int		y)
+{
+    unsigned char   *srcLine = glyph->bitmap, *src, bits;
+    int		    width = glyph->metrics.width;
+    int		    stride = ((width + 3) & ~3);
+    int		    height = glyph->metrics.height;
+    int		    w;
+    int		    xspan, lenspan;
+
+    x -= glyph->metrics.x;
+    y -= glyph->metrics.y;
+    while (height--)
+    {
+	src = srcLine;
+	srcLine += stride;
+	w = width;
+	
+	bits = *src++;
+	xspan = x;
+	while (w)
+	{
+	    if (bits >= 0x80)
+	    {
+		lenspan = 0;
+		do
+		{
+		    lenspan++;
+		    if (lenspan == w)
+			break;
+		    bits = *src++;
+		} while (bits >= 0x80);
+		XFillRectangle (draw->dpy, draw->drawable, 
+				draw->core.gc, xspan, y, lenspan, 1);
+		xspan += lenspan;
+		w -= lenspan;
+	    }
+	    else
+	    {
+		do
+		{
+		    w--;
+		    xspan++;
+		    if (!w)
+			break;
+		    bits = *src++;
+		} while (bits < 0x80);
+	    }
+	}
+	y++;
+    }
+}
+
+static void
+_XftSharpGlyphRgba (XftDraw	*draw,
+		    XftGlyph	*glyph,
+		    int		x,
+		    int		y)
+{
+    CARD32	    *srcLine = glyph->bitmap, *src, bits;
+    int		    width = glyph->metrics.width;
+    int		    stride = ((width + 3) & ~3);
+    int		    height = glyph->metrics.height;
+    int		    w;
+    int		    xspan, lenspan;
+
+    x -= glyph->metrics.x;
+    y -= glyph->metrics.y;
+    while (height--)
+    {
+	src = srcLine;
+	srcLine += stride;
+	w = width;
+	
+	bits = *src++;
+	xspan = x;
+	while (w)
+	{
+	    if (bits >= 0x80000000)
+	    {
+		lenspan = 0;
+		do
+		{
+		    lenspan++;
+		    if (lenspan == w)
+			break;
+		    bits = *src++;
+		} while (bits >= 0x80000000);
+		XFillRectangle (draw->dpy, draw->drawable, 
+				draw->core.gc, xspan, y, lenspan, 1);
+		xspan += lenspan;
+		w -= lenspan;
+	    }
+	    else
+	    {
+		do
+		{
+		    w--;
+		    xspan++;
+		    if (!w)
+			break;
+		    bits = *src++;
+		} while (bits < 0x80000000);
+	    }
+	}
+	y++;
+    }
+}
+
+typedef void (*XftSharpGlyph) (XftDraw	*draw,
+			       XftGlyph	*glyph,
+			       int	x,
+			       int	y);
+
+static XftSharpGlyph
+_XftSharpGlyphFind (XftDraw *draw, XftFont *public)
+{
+    XftFontInt *font = (XftFontInt *) public;
+
+    if (!font->info.antialias)
+	return _XftSharpGlyphMono;
+    else switch (font->info.rgba) {
+    case FC_RGBA_RGB:
+    case FC_RGBA_BGR:
+    case FC_RGBA_VRGB:
+    case FC_RGBA_VBGR:
+	return _XftSharpGlyphRgba;
+    default:
+	return _XftSharpGlyphGray;
+    }
+}
+
+/*
+ * Draw glyphs to a target that supports anti-aliasing
+ */
+
+/*
+ * Primitives for converting between RGB values and TrueColor pixels
+ */
+ 
+static void
+_XftExamineBitfield (unsigned long mask, int *shift, int *len)
+{
+    int	s, l;
+
+    s = 0;
+    while ((mask & 1) == 0)
+    {
+	mask >>= 1;
+	s++;
+    }
+    l = 0;
+    while ((mask & 1) == 1)
+    {
+	mask >>= 1;
+	l++;
+    }
+    *shift = s;
+    *len = l;
+}
+
+static CARD32
+_XftGetField (unsigned long l_pixel, int shift, int len)
+{
+    CARD32  pixel = (CARD32) l_pixel;
+    
+    pixel = pixel & (((1 << (len)) - 1) << shift);
+    pixel = pixel << (32 - (shift + len)) >> 24;
+    while (len < 8)
+    {
+	pixel |= (pixel >> len);
+	len <<= 1;
+    }
+    return pixel;
+}
+
+static unsigned long
+_XftPutField (CARD32 pixel, int shift, int len)
+{
+    unsigned long   l_pixel = (unsigned long) pixel;
+
+    shift = shift - (8 - len);
+    if (len <= 8)
+	l_pixel &= (((1 << len) - 1) << (8 - len));
+    if (shift < 0)
+	l_pixel >>= -shift;
+    else
+	l_pixel <<= shift;
+    return l_pixel;
+}
+
+/*
+ * This is used when doing XftCharFontSpec/XftGlyphFontSpec where
+ * some of the fonts are bitmaps and some are anti-aliased to handle
+ * the bitmap portions
+ */
+static void
+_XftSmoothGlyphMono (XImage		*image,
+		     _Xconst XftGlyph	*xftg,
+		     int		x,
+		     int		y,
+		     _Xconst XftColor   *color)
+{
+    unsigned char   *srcLine = xftg->bitmap, *src;
+    unsigned char   bits, bitsMask;
+    int		    width = xftg->metrics.width;
+    int		    stride = ((width + 31) & ~31) >> 3;
+    int		    height = xftg->metrics.height;
+    int		    w;
+    int		    xspan;
+    int		    r_shift, r_len;
+    int		    g_shift, g_len;
+    int		    b_shift, b_len;
+    unsigned long   pixel;
+
+    _XftExamineBitfield (image->red_mask, &r_shift, &r_len);
+    _XftExamineBitfield (image->green_mask, &g_shift, &g_len);
+    _XftExamineBitfield (image->blue_mask, &b_shift, &b_len);
+    pixel = (_XftPutField (color->color.red >> 8, r_shift, r_len) |
+	     _XftPutField (color->color.green >> 8, g_shift, g_len) |
+	     _XftPutField (color->color.blue >> 8, b_shift, b_len));
+    x -= xftg->metrics.x;
+    y -= xftg->metrics.y;
+    while (height--)
+    {
+	src = srcLine;
+	srcLine += stride;
+	w = width;
+	
+	bitsMask = 0x80;    /* FreeType is always MSB first */
+	bits = *src++;
+	
+	xspan = x;
+	while (w--)
+	{
+	    if (bits & bitsMask)
+		XPutPixel (image, xspan, y, pixel);
+    	    bitsMask = bitsMask >> 1;
+    	    if (!bitsMask)
+    	    {
+    		bits = *src++;
+    		bitsMask = 0x80;
+    	    }
+	    xspan++;
+	}
+	y++;
+    }
+}
+
+/*
+ * As simple anti-aliasing is likely to be common, there are three
+ * optimized versions for the usual true color pixel formats (888, 565, 555).
+ * Other formats are handled by the general case
+ */
+
+#define cvt8888to0565(s)    ((((s) >> 3) & 0x001f) | \
+			     (((s) >> 5) & 0x07e0) | \
+			     (((s) >> 8) & 0xf800))
+
+#define cvt0565to8888(s)    (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
+			     ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
+			     ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
+
+#define cvt8888to0555(s)    ((((s) >> 3) & 0x001f) | \
+			     (((s) >> 6) & 0x03e0) | \
+			     (((s) >> 7) & 0x7c00))
+
+#define cvt0555to8888(s)    (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
+			     ((((s) << 6) & 0xf800) | (((s) >> 0) & 0x300)) | \
+			     ((((s) << 9) & 0xf80000) | (((s) << 4) & 0x70000)))
+
+
+#define XftIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
+#define XftIntDiv(a,b)	 (((CARD16) (a) * 255) / (b))
+
+#define XftGet8(v,i)   ((CARD16) (CARD8) ((v) >> i))
+
+/*
+ * There are two ways of handling alpha -- either as a single unified value or
+ * a separate value for each component, hence each macro must have two
+ * versions.  The unified alpha version has a 'U' at the end of the name,
+ * the component version has a 'C'.  Similarly, functions which deal with
+ * this difference will have two versions using the same convention.
+ */
+
+#define XftOverU(x,y,i,a,t) ((t) = XftIntMult(XftGet8(y,i),(a),(t)) + XftGet8(x,i),\
+			   (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
+
+#define XftOverC(x,y,i,a,t) ((t) = XftIntMult(XftGet8(y,i),XftGet8(a,i),(t)) + XftGet8(x,i),\
+			    (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
+
+#define XftInU(x,i,a,t) ((CARD32) XftIntMult(XftGet8(x,i),(a),(t)) << (i))
+
+#define XftInC(x,i,a,t) ((CARD32) XftIntMult(XftGet8(x,i),XftGet8(a,i),(t)) << (i))
+
+#define XftGen(x,y,i,ax,ay,t,u,v) ((t) = (XftIntMult(XftGet8(y,i),ay,(u)) + \
+					 XftIntMult(XftGet8(x,i),ax,(v))),\
+				  (CARD32) ((CARD8) ((t) | \
+						     (0 - ((t) >> 8)))) << (i))
+
+#define XftAdd(x,y,i,t)	((t) = XftGet8(x,i) + XftGet8(y,i), \
+			 (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
+
+
+static CARD32
+fbOver24 (CARD32 x, CARD32 y)
+{
+    CARD16  a = ~x >> 24;
+    CARD16  t;
+    CARD32  m,n,o;
+
+    m = XftOverU(x,y,0,a,t);
+    n = XftOverU(x,y,8,a,t);
+    o = XftOverU(x,y,16,a,t);
+    return m|n|o;
+}
+
+static CARD32
+fbIn (CARD32 x, CARD8 y)
+{
+    CARD16  a = y;
+    CARD16  t;
+    CARD32  m,n,o,p;
+
+    m = XftInU(x,0,a,t);
+    n = XftInU(x,8,a,t);
+    o = XftInU(x,16,a,t);
+    p = XftInU(x,24,a,t);
+    return m|n|o|p;
+}
+
+static void
+_XftSmoothGlyphGray8888 (XImage		    *image,
+			 _Xconst XftGlyph   *xftg,
+			 int		    x,
+			 int		    y,
+			 _Xconst XftColor   *color)
+{
+    CARD32	src, srca;
+    CARD32	r, g, b;
+    CARD32	*dstLine, *dst, d;
+    CARD8	*maskLine, *mask, m;
+    int		dstStride, maskStride;
+    int		width, height;
+    int		w;
+
+    srca = color->color.alpha >> 8;
+    
+    /* This handles only RGB and BGR */
+    g = (color->color.green & 0xff00);
+    if (image->red_mask == 0xff0000)
+    {
+	r = (color->color.red & 0xff00) << 8;
+	b = color->color.blue >> 8;
+    }
+    else
+    {
+	r = color->color.red >> 8;
+	b = (color->color.blue & 0xff00) << 8;
+    }
+    src = (srca << 24) | r | g | b;
+    
+    width = xftg->metrics.width;
+    height = xftg->metrics.height;
+    
+    x -= xftg->metrics.x;
+    y -= xftg->metrics.y;
+
+    dstLine = (CARD32 *) (image->data + image->bytes_per_line * y + (x << 2));
+    dstStride = image->bytes_per_line >> 2;
+    maskLine = (unsigned char *) xftg->bitmap;
+    maskStride = (width + 3) & ~3;
+    
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	while (w--)
+	{
+	    m = *mask++;
+	    if (m == 0xff)
+	    {
+		if (srca == 0xff)
+		    *dst = src;
+		else
+		    *dst = fbOver24 (src, *dst);
+	    }
+	    else if (m)
+	    {
+		d = fbIn (src, m);
+		*dst = fbOver24 (d, *dst);
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
+_XftSmoothGlyphGray565 (XImage		    *image,
+			_Xconst XftGlyph    *xftg,
+			int		    x,
+			int		    y,
+			_Xconst XftColor    *color)
+{
+    CARD32	src, srca;
+    CARD32	r, g, b;
+    CARD32	d;
+    CARD16	*dstLine, *dst;
+    CARD8	*maskLine, *mask, m;
+    int		dstStride, maskStride;
+    int		width, height;
+    int		w;
+
+    srca = color->color.alpha >> 8;
+    
+    /* This handles only RGB and BGR */
+    g = (color->color.green & 0xff00);
+    if (image->red_mask == 0xf800)
+    {
+	r = (color->color.red & 0xff00) << 8;
+	b = color->color.blue >> 8;
+    }
+    else
+    {
+	r = color->color.red >> 8;
+	b = (color->color.blue & 0xff00) << 8;
+    }
+    src = (srca << 24) | r | g | b;
+    
+    width = xftg->metrics.width;
+    height = xftg->metrics.height;
+    
+    x -= xftg->metrics.x;
+    y -= xftg->metrics.y;
+
+    dstLine = (CARD16 *) (image->data + image->bytes_per_line * y + (x << 1));
+    dstStride = image->bytes_per_line >> 1;
+    maskLine = (unsigned char *) xftg->bitmap;
+    maskStride = (width + 3) & ~3;
+    
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	while (w--)
+	{
+	    m = *mask++;
+	    if (m == 0xff)
+	    {
+		if (srca == 0xff)
+		    d = src;
+		else
+		{
+		    d = *dst;
+		    d = fbOver24 (src, cvt0565to8888(d));
+		}
+		*dst = cvt8888to0565(d);
+	    }
+	    else if (m)
+	    {
+		d = *dst;
+		d = fbOver24 (fbIn(src,m), cvt0565to8888(d));
+		*dst = cvt8888to0565(d);
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
+_XftSmoothGlyphGray555 (XImage		    *image,
+			_Xconst XftGlyph    *xftg,
+			int		    x,
+			int		    y,
+			_Xconst XftColor    *color)
+{
+    CARD32	src, srca;
+    CARD32	r, g, b;
+    CARD32	d;
+    CARD16	*dstLine, *dst;
+    CARD8	*maskLine, *mask, m;
+    int		dstStride, maskStride;
+    int		width, height;
+    int		w;
+
+    srca = color->color.alpha >> 8;
+    
+    /* This handles only RGB and BGR */
+    g = (color->color.green & 0xff00);
+    if (image->red_mask == 0xf800)
+    {
+	r = (color->color.red & 0xff00) << 8;
+	b = color->color.blue >> 8;
+    }
+    else
+    {
+	r = color->color.red >> 8;
+	b = (color->color.blue & 0xff00) << 8;
+    }
+    src = (srca << 24) | r | g | b;
+    
+    width = xftg->metrics.width;
+    height = xftg->metrics.height;
+    
+    x -= xftg->metrics.x;
+    y -= xftg->metrics.y;
+
+    dstLine = (CARD16 *) (image->data + image->bytes_per_line * y + (x << 1));
+    dstStride = image->bytes_per_line >> 1;
+    maskLine = (unsigned char *) xftg->bitmap;
+    maskStride = (width + 3) & ~3;
+    
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	while (w--)
+	{
+	    m = *mask++;
+	    if (m == 0xff)
+	    {
+		if (srca == 0xff)
+		    d = src;
+		else
+		{
+		    d = *dst;
+		    d = fbOver24 (src, cvt0555to8888(d));
+		}
+		*dst = cvt8888to0555(d);
+	    }
+	    else if (m)
+	    {
+		d = *dst;
+		d = fbOver24 (fbIn(src,m), cvt0555to8888(d));
+		*dst = cvt8888to0555(d);
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
+_XftSmoothGlyphGray (XImage		*image,
+		     _Xconst XftGlyph	*xftg,
+		     int		x,
+		     int		y,
+		     _Xconst XftColor   *color)
+{
+    CARD32	    src, srca;
+    int		    r_shift, r_len;
+    int		    g_shift, g_len;
+    int		    b_shift, b_len;
+    CARD8	    *maskLine, *mask, m;
+    int		    maskStride;
+    CARD32	    d;
+    unsigned long   pixel;
+    int		    width, height;
+    int		    w, tx;
+    
+    srca = color->color.alpha >> 8;
+    src = (srca << 24 |
+	   (color->color.red & 0xff00) << 8 |
+	   (color->color.green & 0xff00) |
+	   (color->color.blue) >> 8);
+    x -= xftg->metrics.x;
+    y -= xftg->metrics.y;
+    width = xftg->metrics.width;
+    height = xftg->metrics.height;
+    
+    maskLine = (unsigned char *) xftg->bitmap;
+    maskStride = (width + 3) & ~3;
+
+    _XftExamineBitfield (image->red_mask, &r_shift, &r_len);
+    _XftExamineBitfield (image->green_mask, &g_shift, &g_len);
+    _XftExamineBitfield (image->blue_mask, &b_shift, &b_len);
+    while (height--)
+    {
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+	tx = x;
+	
+	while (w--)
+	{
+	    m = *mask++;
+	    if (m == 0xff)
+	    {
+		if (srca == 0xff)
+		    d = src;
+		else
+		{
+		    pixel = XGetPixel (image, tx, y);
+		    d = (_XftGetField (pixel, r_shift, r_len) << 16 |
+			 _XftGetField (pixel, g_shift, g_len) << 8 |
+			 _XftGetField (pixel, b_shift, b_len));
+		    d = fbOver24 (src, d);
+		}
+		pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) |
+			 _XftPutField ((d >>  8) & 0xff, g_shift, g_len) |
+			 _XftPutField ((d      ) & 0xff, b_shift, b_len));
+		XPutPixel (image, tx, y, pixel);
+	    }
+	    else if (m)
+	    {
+		pixel = XGetPixel (image, tx, y);
+		d = (_XftGetField (pixel, r_shift, r_len) << 16 |
+		     _XftGetField (pixel, g_shift, g_len) << 8 |
+		     _XftGetField (pixel, b_shift, b_len));
+		d = fbOver24 (fbIn(src,m), d);
+		pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) |
+			 _XftPutField ((d >>  8) & 0xff, g_shift, g_len) |
+			 _XftPutField ((d      ) & 0xff, b_shift, b_len));
+		XPutPixel (image, tx, y, pixel);
+	    }
+	    tx++;
+	}
+	y++;
+    }
+}
+
+static void
+_XftSmoothGlyphRgba (XImage		*image,
+		     _Xconst XftGlyph	*xftg,
+		     int		x,
+		     int		y,
+		     _Xconst XftColor   *color)
+{
+    CARD32	    src, srca;
+    int		    r_shift, r_len;
+    int		    g_shift, g_len;
+    int		    b_shift, b_len;
+    CARD32	    *mask, ma;
+    CARD32	    d;
+    unsigned long   pixel;
+    int		    width, height;
+    int		    w, tx;
+    
+    srca = color->color.alpha >> 8;
+    src = (srca << 24 |
+	   (color->color.red & 0xff00) << 8 |
+	   (color->color.green & 0xff00) |
+	   (color->color.blue) >> 8);
+    x -= xftg->metrics.x;
+    y -= xftg->metrics.y;
+    width = xftg->metrics.width;
+    height = xftg->metrics.height;
+    
+    mask = (CARD32 *) xftg->bitmap;
+
+    _XftExamineBitfield (image->red_mask, &r_shift, &r_len);
+    _XftExamineBitfield (image->green_mask, &g_shift, &g_len);
+    _XftExamineBitfield (image->blue_mask, &b_shift, &b_len);
+    while (height--)
+    {
+	w = width;
+	tx = x;
+	
+	while (w--)
+	{
+	    ma = *mask++;
+	    if (ma == 0xffffffff)
+	    {
+		if (srca == 0xff)
+		    d = src;
+		else
+		{
+		    pixel = XGetPixel (image, tx, y);
+		    d = (_XftGetField (pixel, r_shift, r_len) << 16 |
+			 _XftGetField (pixel, g_shift, g_len) << 8 |
+			 _XftGetField (pixel, b_shift, b_len));
+		    d = fbOver24 (src, d);
+		}
+		pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) |
+			 _XftPutField ((d >>  8) & 0xff, g_shift, g_len) |
+			 _XftPutField ((d      ) & 0xff, b_shift, b_len));
+		XPutPixel (image, tx, y, pixel);
+	    }
+	    else if (ma)
+	    {
+		CARD32	m,n,o;
+		pixel = XGetPixel (image, tx, y);
+		d = (_XftGetField (pixel, r_shift, r_len) << 16 |
+		     _XftGetField (pixel, g_shift, g_len) << 8 |
+		     _XftGetField (pixel, b_shift, b_len));
+#define XftInOverC(src,srca,msk,dst,i,result) { \
+    CARD16  __a = XftGet8(msk,i); \
+    CARD32  __t, __ta; \
+    CARD32  __i; \
+    __t = XftIntMult (XftGet8(src,i), __a,__i); \
+    __ta = (CARD8) ~XftIntMult (srca, __a,__i); \
+    __t = __t + XftIntMult(XftGet8(dst,i),__ta,__i); \
+    __t = (CARD32) (CARD8) (__t | (-(__t >> 8))); \
+    result = __t << (i); \
+}
+		XftInOverC(src,srca,ma,d,0,m);
+		XftInOverC(src,srca,ma,d,8,n);
+		XftInOverC(src,srca,ma,d,16,o);
+		d = m | n | o;
+		pixel = (_XftPutField ((d >> 16) & 0xff, r_shift, r_len) |
+			 _XftPutField ((d >>  8) & 0xff, g_shift, g_len) |
+			 _XftPutField ((d      ) & 0xff, b_shift, b_len));
+		XPutPixel (image, tx, y, pixel);
+	    }
+	    tx++;
+	}
+	y++;
+    }
+}
+
+static FcBool
+_XftSmoothGlyphPossible (XftDraw *draw)
+{
+    if (!draw->visual)
+	return FcFalse;
+    if (draw->visual->class != TrueColor)
+	return FcFalse;
+    return FcTrue;
+}
+
+typedef	void (*XftSmoothGlyph) (XImage		    *image, 
+				_Xconst XftGlyph    *xftg,
+				int		    x,
+				int		    y,
+				_Xconst XftColor    *color);
+
+static XftSmoothGlyph
+_XftSmoothGlyphFind (XftDraw *draw, XftFont *public)
+{
+    XftFontInt *font = (XftFontInt *) public;
+
+    if (!font->info.antialias)
+	return _XftSmoothGlyphMono;
+    else switch (font->info.rgba) {
+    case FC_RGBA_RGB:
+    case FC_RGBA_BGR:
+    case FC_RGBA_VRGB:
+    case FC_RGBA_VBGR:
+	return _XftSmoothGlyphRgba;
+    default:
+	switch (XftDrawBitsPerPixel (draw)) {
+	case 32:
+	    if ((draw->visual->red_mask   == 0xff0000 &&
+		 draw->visual->green_mask == 0x00ff00 &&
+		 draw->visual->blue_mask  == 0x0000ff) ||
+		(draw->visual->red_mask   == 0x0000ff &&
+		 draw->visual->green_mask == 0x00ff00 &&
+		 draw->visual->blue_mask  == 0xff0000))
+	    {
+		return _XftSmoothGlyphGray8888;
+	    }
+	    break;
+	case 16:
+	    if ((draw->visual->red_mask   == 0xf800 &&
+		 draw->visual->green_mask == 0x07e0 &&
+		 draw->visual->blue_mask  == 0x001f) ||
+		(draw->visual->red_mask   == 0x001f &&
+		 draw->visual->green_mask == 0x07e0 &&
+		 draw->visual->blue_mask  == 0xf800))
+	    {
+		return _XftSmoothGlyphGray565;
+	    }
+	    if ((draw->visual->red_mask   == 0x7c00 &&
+		 draw->visual->green_mask == 0x03e0 &&
+		 draw->visual->blue_mask  == 0x001f) ||
+		(draw->visual->red_mask   == 0x001f &&
+		 draw->visual->green_mask == 0x03e0 &&
+		 draw->visual->blue_mask  == 0x7c00))
+	    {
+		return _XftSmoothGlyphGray555;
+	    }
+	    break;
+	default:
+	    break;
+	}
+	return _XftSmoothGlyphGray;
+    }
+}
+
+static XftGlyph *
+_XftGlyphDefault (Display *dpy, XftFont   *public)
+{
+    XftFontInt	    *font = (XftFontInt *) public;
+    FT_UInt	    missing[XFT_NMISSING];
+    int		    nmissing;
+    FcBool	    glyphs_loaded = FcFalse;
+
+    if (XftFontCheckGlyph (dpy, public, FcTrue, 0, missing, &nmissing))
+	glyphs_loaded = FcTrue;
+    if (nmissing)
+	XftFontLoadGlyphs (dpy, public, glyphs_loaded, missing, nmissing);
+    return font->glyphs[0];
+}
+
+static int XftGetImageErrorHandler (Display *dpy, XErrorEvent *error_event)
+{
+    return 0;
+}
+
+_X_HIDDEN void
+XftGlyphCore (XftDraw		*draw,
+	      _Xconst XftColor	*color,
+	      XftFont		*public,
+	      int		x,
+	      int		y,
+	      _Xconst FT_UInt	*glyphs,
+	      int		nglyphs)
+{
+    Display	    *dpy = draw->dpy;
+    XftFontInt	    *font = (XftFontInt *) public;
+    XftGlyph	    *xftg;
+    FT_UInt	    glyph;
+    _Xconst FT_UInt *g;
+    FT_UInt	    missing[XFT_NMISSING];
+    FcBool	    glyphs_loaded;
+    int		    nmissing;
+    int		    n;
+    XErrorHandler   prev_error;
+
+    /*
+     * Load missing glyphs
+     */
+    g = glyphs;
+    n = nglyphs;
+    nmissing = 0;
+    glyphs_loaded = FcFalse;
+    while (n--)
+	if (XftFontCheckGlyph (dpy, public, FcTrue, *g++, missing, &nmissing))
+	    glyphs_loaded = FcTrue;
+    if (nmissing)
+	XftFontLoadGlyphs (dpy, public, FcTrue, missing, nmissing);
+    
+    g = glyphs;
+    n = nglyphs;
+    if ((font->info.antialias || color->color.alpha != 0xffff) &&
+	_XftSmoothGlyphPossible (draw))
+    {
+	XGlyphInfo	gi;
+	XImage		*image;
+        unsigned int    depth;
+	int		ox, oy;
+	XftSmoothGlyph	smooth = _XftSmoothGlyphFind (draw, public);
+	
+	XftGlyphExtents (dpy, public, glyphs, nglyphs, &gi);
+	if (!gi.width || !gi.height)
+	    goto bail1;
+	ox = x - gi.x;
+	oy = y - gi.y;
+	/*
+	 * Try to get bits directly from the drawable; if that fails,
+	 * use a temporary pixmap.  When it does fail, assume it
+	 * will probably fail for a while and keep using temporary
+	 * pixmaps for a while to avoid double round trips.
+	 */
+	if (draw->core.use_pixmap == 0)
+	{
+	    prev_error = XSetErrorHandler (XftGetImageErrorHandler);
+	    image = XGetImage (dpy, draw->drawable,
+			       ox, oy,
+			       gi.width, gi.height, AllPlanes,
+			       ZPixmap);
+	    XSetErrorHandler (prev_error);
+	    if (!image)
+		draw->core.use_pixmap = XFT_ASSUME_PIXMAP;
+	}
+	else
+	{
+	    draw->core.use_pixmap--;
+	    image = NULL;
+	}
+	if (!image && (depth = XftDrawDepth (draw)))
+	{
+	    Pixmap	pix;
+	    GC		gc;
+	    XGCValues	gcv;
+
+	    pix = XCreatePixmap (dpy, draw->drawable,
+				 gi.width, gi.height, depth);
+	    gcv.graphics_exposures = False;
+	    gc = XCreateGC (dpy, pix, GCGraphicsExposures, &gcv);
+	    XCopyArea (dpy, draw->drawable, pix, gc, ox, oy,
+		       gi.width, gi.height, 0, 0);
+	    XFreeGC (dpy, gc);
+	    image = XGetImage (dpy, pix, 0, 0, gi.width, gi.height, AllPlanes,
+			       ZPixmap);
+	    XFreePixmap (dpy, pix);
+	}
+	if (!image)
+	    goto bail1;
+	image->red_mask = draw->visual->red_mask;
+	image->green_mask = draw->visual->green_mask;
+	image->blue_mask = draw->visual->blue_mask;
+	if (image->byte_order != XftNativeByteOrder ())
+	    XftSwapImage (image);
+	while (n--)
+	{
+	    glyph = *g++;
+	    if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
+		xftg = _XftGlyphDefault (dpy, public);
+	    if (xftg)
+	    {
+		(*smooth) (image, xftg, x - ox, y - oy, color);
+		x += xftg->metrics.xOff;
+		y += xftg->metrics.yOff;
+	    }
+	}
+	if (image->byte_order != XftNativeByteOrder ())
+	    XftSwapImage (image);
+	XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, ox, oy,
+		   gi.width, gi.height);
+	XDestroyImage (image);
+    }
+    else
+    {
+	XftSharpGlyph	sharp = _XftSharpGlyphFind (draw, public);
+	while (n--)
+	{
+	    glyph = *g++;
+	    if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
+		xftg = _XftGlyphDefault (dpy, public);
+	    if (xftg)
+	    {
+		(*sharp) (draw, xftg, x, y);
+		x += xftg->metrics.xOff;
+		y += xftg->metrics.yOff;
+	    }
+	}
+    }
+bail1:
+    if (glyphs_loaded)
+	_XftFontManageMemory (dpy, public);
+}
+
+#define NUM_LOCAL   1024
+
+_X_HIDDEN void
+XftGlyphSpecCore (XftDraw		*draw,
+		  _Xconst XftColor	*color,
+		  XftFont		*public,
+		  _Xconst XftGlyphSpec	*glyphs,
+		  int			nglyphs)
+{
+    Display	    *dpy = draw->dpy;
+    XftFontInt	    *font = (XftFontInt *) public;
+    XftGlyph	    *xftg;
+    FT_UInt	    missing[XFT_NMISSING];
+    FcBool	    glyphs_loaded;
+    int		    nmissing;
+    int		    i;
+    XErrorHandler   prev_error;
+    int		    x1, y1, x2, y2;
+
+    /*
+     * Load missing glyphs
+     */
+    glyphs_loaded = FcFalse;
+    x1 = y1 = x2 = y2 = 0;
+    for (i = 0; i < nglyphs; i++)
+    {
+	XGlyphInfo	gi;
+	int		g_x1, g_x2, g_y1, g_y2;
+	
+	nmissing = 0;
+	if (XftFontCheckGlyph (dpy, public, FcTrue, glyphs[i].glyph, missing, &nmissing))
+	    glyphs_loaded = FcTrue;
+	if (nmissing)
+	    XftFontLoadGlyphs (dpy, public, FcTrue, missing, nmissing);
+
+	XftGlyphExtents (dpy, public, &glyphs[i].glyph, 1, &gi);
+	g_x1 = glyphs[i].x - gi.x;
+	g_y1 = glyphs[i].y - gi.y;
+	g_x2 = g_x1 + gi.width;
+	g_y2 = g_y1 + gi.height;
+	if (i)
+	{
+	    if (g_x1 < x1)
+		x1 = g_x1;
+	    if (g_y1 < y1)
+		y1 = g_y1;
+	    if (g_x2 > x2)
+		x2 = g_x2;
+	    if (g_y2 > y2)
+		y2 = g_y2;
+	}
+	else
+	{
+	    x1 = g_x1;
+	    y1 = g_y1;
+	    x2 = g_x2;
+	    y2 = g_y2;
+	}
+    }
+    
+    if (x1 == x2 || y1 == y2)
+	goto bail1;
+
+    if ((font->info.antialias || color->color.alpha != 0xffff) &&
+	_XftSmoothGlyphPossible (draw))
+    {
+	XImage		*image;
+        unsigned int    depth;
+	int		width = x2 - x1, height = y2 - y1;
+	XftSmoothGlyph	smooth = _XftSmoothGlyphFind (draw, public);
+
+	/*
+	 * Try to get bits directly from the drawable; if that fails,
+	 * use a temporary pixmap.  When it does fail, assume it
+	 * will probably fail for a while and keep using temporary
+	 * pixmaps for a while to avoid double round trips.
+	 */
+	if (draw->core.use_pixmap == 0)
+	{
+	    prev_error = XSetErrorHandler (XftGetImageErrorHandler);
+	    image = XGetImage (dpy, draw->drawable,
+			       x1, y1,
+			       width, height, AllPlanes,
+			       ZPixmap);
+	    XSetErrorHandler (prev_error);
+	    if (!image)
+		draw->core.use_pixmap = XFT_ASSUME_PIXMAP;
+	}
+	else
+	{
+	    draw->core.use_pixmap--;
+	    image = NULL;
+	}
+	if (!image && (depth = XftDrawDepth (draw)))
+	{
+	    Pixmap	pix;
+	    GC		gc;
+	    XGCValues	gcv;
+
+	    pix = XCreatePixmap (dpy, draw->drawable,
+				 width, height, depth);
+	    gcv.graphics_exposures = False;
+	    gc = XCreateGC (dpy, pix, GCGraphicsExposures, &gcv);
+	    XCopyArea (dpy, draw->drawable, pix, gc, x1, y1,
+		       width, height, 0, 0);
+	    XFreeGC (dpy, gc);
+	    image = XGetImage (dpy, pix, 0, 0, width, height, AllPlanes,
+			       ZPixmap);
+	    XFreePixmap (dpy, pix);
+	}
+	if (!image)
+	    goto bail1;
+	image->red_mask = draw->visual->red_mask;
+	image->green_mask = draw->visual->green_mask;
+	image->blue_mask = draw->visual->blue_mask;
+	if (image->byte_order != XftNativeByteOrder ())
+	    XftSwapImage (image);
+	for (i = 0; i < nglyphs; i++)
+	{
+	    FT_UInt glyph = glyphs[i].glyph;
+	    if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
+		xftg = _XftGlyphDefault (dpy, public);
+	    if (xftg)
+	    {
+		(*smooth) (image, xftg, glyphs[i].x - x1, 
+			   glyphs[i].y - y1, color);
+	    }
+	}
+	if (image->byte_order != XftNativeByteOrder ())
+	    XftSwapImage (image);
+	XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, x1, y1,
+		   width, height);
+	XDestroyImage (image);
+    }
+    else
+    {
+	XftSharpGlyph	sharp = _XftSharpGlyphFind (draw, public);
+	for (i = 0; i < nglyphs; i++)
+	{
+	    FT_UInt glyph = glyphs[i].glyph;
+	    if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
+		xftg = _XftGlyphDefault (dpy, public);
+	    if (xftg)
+		(*sharp) (draw, xftg, glyphs[i].x, glyphs[i].y);
+	}
+    }
+bail1:
+    if (glyphs_loaded)
+	_XftFontManageMemory (dpy, public);
+}
+
+_X_HIDDEN void
+XftGlyphFontSpecCore (XftDraw			*draw,
+		      _Xconst XftColor		*color,
+		      _Xconst XftGlyphFontSpec	*glyphs,
+		      int			nglyphs)
+{
+    Display	    *dpy = draw->dpy;
+    XftGlyph	    *xftg;
+    FT_UInt	    missing[XFT_NMISSING];
+    FcBool	    glyphs_loaded;
+    int		    nmissing;
+    int		    i;
+    XErrorHandler   prev_error;
+    int		    x1, y1, x2, y2;
+
+    /*
+     * Load missing glyphs
+     */
+    glyphs_loaded = FcFalse;
+    x1 = y1 = x2 = y2 = 0;
+    for (i = 0; i < nglyphs; i++)
+    {
+	XftFont		*public = glyphs[i].font;
+	XGlyphInfo	gi;
+	int		g_x1, g_x2, g_y1, g_y2;
+	
+	nmissing = 0;
+	if (XftFontCheckGlyph (dpy, public, FcTrue, glyphs[i].glyph, missing, &nmissing))
+	    glyphs_loaded = FcTrue;
+	if (nmissing)
+	    XftFontLoadGlyphs (dpy, public, FcTrue, missing, nmissing);
+	
+	XftGlyphExtents (dpy, public, &glyphs[i].glyph, 1, &gi);
+	g_x1 = glyphs[i].x - gi.x;
+	g_y1 = glyphs[i].y - gi.y;
+	g_x2 = g_x1 + gi.width;
+	g_y2 = g_y1 + gi.height;
+	if (i)
+	{
+	    if (g_x1 < x1)
+	    {
+		if (g_x1 < 0)
+		{
+		    /* do nothing if the given glyphs are out of range */
+		    short t = glyphs[i-1].font->max_advance_width
+			+ glyphs[i-1].x;
+		    if (t < 0 && glyphs[i-1].x > 0)
+			goto bail1;
+		}
+		x1 = g_x1;
+	    }
+	    if (g_y1 < y1)
+		y1 = g_y1;
+	    if (g_x2 > x2)
+		x2 = g_x2;
+	    if (g_y2 > y2)
+		y2 = g_y2;
+	}
+	else
+	{
+	    x1 = g_x1;
+	    y1 = g_y1;
+	    x2 = g_x2;
+	    y2 = g_y2;
+	}
+    }
+    
+    if (x1 == x2 || y1 == y2)
+	goto bail1;
+
+    for (i = 0; i < nglyphs; i++)
+	if (((XftFontInt *) glyphs[i].font)->info.antialias)
+	    break;
+    
+    if ((i != nglyphs || color->color.alpha != 0xffff) &&
+	_XftSmoothGlyphPossible (draw))
+    {
+	XImage		*image;
+        unsigned int    depth;
+	int		width = x2 - x1, height = y2 - y1;
+
+	/*
+	 * Try to get bits directly from the drawable; if that fails,
+	 * use a temporary pixmap.  When it does fail, assume it
+	 * will probably fail for a while and keep using temporary
+	 * pixmaps for a while to avoid double round trips.
+	 */
+	if (draw->core.use_pixmap == 0)
+	{
+	    prev_error = XSetErrorHandler (XftGetImageErrorHandler);
+	    image = XGetImage (dpy, draw->drawable,
+			       x1, y1,
+			       width, height, AllPlanes,
+			       ZPixmap);
+	    XSetErrorHandler (prev_error);
+	    if (!image)
+		draw->core.use_pixmap = XFT_ASSUME_PIXMAP;
+	}
+	else
+	{
+	    draw->core.use_pixmap--;
+	    image = NULL;
+	}
+	if (!image && (depth = XftDrawDepth (draw)))
+	{
+	    Pixmap	pix;
+	    GC		gc;
+	    XGCValues	gcv;
+
+	    pix = XCreatePixmap (dpy, draw->drawable,
+				 width, height, depth);
+	    gcv.graphics_exposures = False;
+	    gc = XCreateGC (dpy, pix, GCGraphicsExposures, &gcv);
+	    XCopyArea (dpy, draw->drawable, pix, gc, x1, y1,
+		       width, height, 0, 0);
+	    XFreeGC (dpy, gc);
+	    image = XGetImage (dpy, pix, 0, 0, width, height, AllPlanes,
+			       ZPixmap);
+	    XFreePixmap (dpy, pix);
+	}
+	if (!image)
+	    goto bail1;
+	image->red_mask = draw->visual->red_mask;
+	image->green_mask = draw->visual->green_mask;
+	image->blue_mask = draw->visual->blue_mask;
+	if (image->byte_order != XftNativeByteOrder ())
+	    XftSwapImage (image);
+	for (i = 0; i < nglyphs; i++)
+	{
+	    XftFont	    *public = glyphs[i].font;
+	    XftFontInt	    *font = (XftFontInt *) public;
+	    XftSmoothGlyph  smooth = _XftSmoothGlyphFind (draw, public);
+	    FT_UInt	    glyph = glyphs[i].glyph;
+	    
+	    if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
+		xftg = _XftGlyphDefault (dpy, public);
+	    if (xftg)
+	    {
+		(*smooth) (image, xftg, glyphs[i].x - x1, 
+			   glyphs[i].y - y1, color);
+	    }
+	}
+	if (image->byte_order != XftNativeByteOrder ())
+	    XftSwapImage (image);
+	XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, x1, y1,
+		   width, height);
+	XDestroyImage (image);
+    }
+    else
+    {
+	for (i = 0; i < nglyphs; i++)
+	{
+	    XftFont		*public = glyphs[i].font;
+	    XftFontInt		*font = (XftFontInt *) public;
+	    XftSharpGlyph	sharp = _XftSharpGlyphFind (draw, public);
+	    FT_UInt		glyph = glyphs[i].glyph;
+	    
+	    if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
+		xftg = _XftGlyphDefault (dpy, public);
+	    if (xftg)
+		(*sharp) (draw, xftg, glyphs[i].x, glyphs[i].y);
+	}
+    }
+bail1:
+    if (glyphs_loaded)
+	for (i = 0; i < nglyphs; i++)
+	    _XftFontManageMemory (dpy, glyphs[i].font);
+}
diff --git a/libXft/src/xftdpy.c b/libXft/src/xftdpy.c
index 862c7e8ab..cd50358d2 100644
--- a/libXft/src/xftdpy.c
+++ b/libXft/src/xftdpy.c
@@ -1,552 +1,552 @@
-/*
- * Copyright © 2000 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "xftint.h"
-
-_X_HIDDEN XftDisplayInfo	*_XftDisplayInfo;
-
-static int
-_XftCloseDisplay (Display *dpy, XExtCodes *codes)
-{
-    XftDisplayInfo  *info, **prev;
-
-    info = _XftDisplayInfoGet (dpy, FcFalse);
-    if (!info)
-	return 0;
-    
-    /*
-     * Get rid of any dangling unreferenced fonts
-     */
-    info->max_unref_fonts = 0;
-    XftFontManageMemory (dpy);
-    
-    /*
-     * Clean up the default values
-     */
-    if (info->defaults)
-	FcPatternDestroy (info->defaults);
-    
-    /*
-     * Unhook from the global list
-     */
-    for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next)
-	if (info->display == dpy)
-	    break;
-    *prev = info->next;
-    
-    free (info);
-    return 0;
-}
-
-
-_X_HIDDEN XftDisplayInfo *
-_XftDisplayInfoGet (Display *dpy, FcBool createIfNecessary)
-{
-    XftDisplayInfo	*info, **prev;
-    XRenderPictFormat	pf;
-    int			i;
-    int			event_base, error_base;
-
-    for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next)
-    {
-	if (info->display == dpy)
-	{
-	    /*
-	     * MRU the list
-	     */
-	    if (prev != &_XftDisplayInfo)
-	    {
-		*prev = info->next;
-		info->next = _XftDisplayInfo;
-		_XftDisplayInfo = info;
-	    }
-	    return info;
-	}
-    }
-    if (!createIfNecessary)
-	return NULL;
-
-    info = (XftDisplayInfo *) malloc (sizeof (XftDisplayInfo));
-    if (!info)
-	goto bail0;
-    info->codes = XAddExtension (dpy);
-    if (!info->codes)
-	goto bail1;
-    (void) XESetCloseDisplay (dpy, info->codes->extension, _XftCloseDisplay);
-
-    info->display = dpy;
-    info->defaults = NULL;
-    info->solidFormat = NULL;
-    info->hasRender = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
-		       (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != NULL));
-    info->use_free_glyphs = FcTrue;
-    if (info->hasRender)
-    {
-	int major, minor;
-	XRenderQueryVersion (dpy, &major, &minor);
-	if (major < 0 || (major == 0 && minor <= 2))
-	    info->use_free_glyphs = FcFalse;
-
-	pf.type = PictTypeDirect;
-	pf.depth = 32;
-	pf.direct.redMask = 0xff;
-	pf.direct.greenMask = 0xff;
-	pf.direct.blueMask = 0xff;
-	pf.direct.alphaMask = 0xff;
-	info->solidFormat = XRenderFindFormat (dpy,
-					       (PictFormatType|
-						PictFormatDepth|
-						PictFormatRedMask|
-						PictFormatGreenMask|
-						PictFormatBlueMask|
-						PictFormatAlphaMask),
-					       &pf,
-					       0);
-    }
-    if (XftDebug () & XFT_DBG_RENDER)
-    {
-	Visual		    *visual = DefaultVisual (dpy, DefaultScreen (dpy));
-	XRenderPictFormat   *format = XRenderFindVisualFormat (dpy, visual);
-	
-	printf ("XftDisplayInfoGet Default visual 0x%x ", 
-		(int) visual->visualid);
-	if (format)
-	{
-	    if (format->type == PictTypeDirect)
-	    {
-		printf ("format %d,%d,%d,%d\n",
-			format->direct.alpha,
-			format->direct.red,
-			format->direct.green,
-			format->direct.blue);
-	    }
-	    else
-	    {
-		printf ("format indexed\n");
-	    }
-	}
-	else
-	    printf ("No Render format for default visual\n");
-	
-	printf ("XftDisplayInfoGet initialized, hasRender set to \"%s\"\n",
-		info->hasRender ? "True" : "False");
-    }
-    for (i = 0; i < XFT_NUM_SOLID_COLOR; i++)
-    {
-	info->colors[i].screen = -1;
-	info->colors[i].pict = 0;
-    }
-    info->fonts = NULL;
-    
-    info->next = _XftDisplayInfo;
-    _XftDisplayInfo = info;
-
-    info->glyph_memory = 0;
-    info->max_glyph_memory = XftDefaultGetInteger (dpy,
-						   XFT_MAX_GLYPH_MEMORY, 0,
-						   XFT_DPY_MAX_GLYPH_MEMORY);
-    if (XftDebug () & XFT_DBG_CACHE)
-	printf ("global max cache memory %ld\n", info->max_glyph_memory);
-
-    
-    info->num_unref_fonts = 0;
-    info->max_unref_fonts = XftDefaultGetInteger (dpy,
-						  XFT_MAX_UNREF_FONTS, 0,
-						  XFT_DPY_MAX_UNREF_FONTS);
-    if (XftDebug() & XFT_DBG_CACHE)
-	printf ("global max unref fonts %d\n", info->max_unref_fonts);
-
-    memset (info->fontHash, '\0', sizeof (XftFont *) * XFT_NUM_FONT_HASH);
-    return info;
-    
-bail1:
-    free (info);
-bail0:
-    if (XftDebug () & XFT_DBG_RENDER)
-    {
-	printf ("XftDisplayInfoGet failed to initialize, Xft unhappy\n");
-    }
-    return NULL;
-}
-
-/*
- * Reduce memory usage in X server
- */
-
-static void
-_XftDisplayValidateMemory (XftDisplayInfo *info)
-{
-    XftFont	    *public;
-    XftFontInt	    *font;
-    unsigned long   glyph_memory;
-
-    glyph_memory = 0;
-    for (public = info->fonts; public; public = font->next)
-    {
-	font = (XftFontInt *) public;
-	glyph_memory += font->glyph_memory;
-    }
-    if (glyph_memory != info->glyph_memory)
-	printf ("Display glyph cache incorrect has %ld bytes, should have %ld\n",
-		info->glyph_memory, glyph_memory);
-}
-
-_X_HIDDEN void
-_XftDisplayManageMemory (Display *dpy)
-{
-    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, False);
-    unsigned long   glyph_memory;
-    XftFont	    *public;
-    XftFontInt	    *font;
-
-    if (!info || !info->max_glyph_memory)
-	return;
-    if (XftDebug () & XFT_DBG_CACHE)
-    {
-	if (info->glyph_memory > info->max_glyph_memory)
-	    printf ("Reduce global memory from %ld to %ld\n",
-		    info->glyph_memory, info->max_glyph_memory);
-	_XftDisplayValidateMemory (info);
-    }
-    while (info->glyph_memory > info->max_glyph_memory)
-    {
-	glyph_memory = rand () % info->glyph_memory;
-	public = info->fonts;
-	while (public)
-	{
-	    font = (XftFontInt *) public;
-
-	    if (font->glyph_memory > glyph_memory)
-	    {
-		_XftFontUncacheGlyph (dpy, public);
-		break;
-	    }
-	    public = font->next;
-	    glyph_memory -= font->glyph_memory;
-	}
-    }
-    if (XftDebug () & XFT_DBG_CACHE)
-	_XftDisplayValidateMemory (info);
-}
-
-_X_EXPORT Bool
-XftDefaultHasRender (Display *dpy)
-{
-    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, True);
-
-    if (!info)
-	return False;
-    return info->hasRender;
-}
-
-_X_EXPORT Bool
-XftDefaultSet (Display *dpy, FcPattern *defaults)
-{
-    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, True);
-
-    if (!info)
-	return False;
-    if (info->defaults)
-	FcPatternDestroy (info->defaults);
-    info->defaults = defaults;
-    if (!info->max_glyph_memory)
-	info->max_glyph_memory = XFT_DPY_MAX_GLYPH_MEMORY;
-    info->max_glyph_memory = XftDefaultGetInteger (dpy,
-						   XFT_MAX_GLYPH_MEMORY, 0,
-						   info->max_glyph_memory);
-    if (!info->max_unref_fonts)
-	info->max_unref_fonts = XFT_DPY_MAX_UNREF_FONTS;
-    info->max_unref_fonts = XftDefaultGetInteger (dpy,
-						  XFT_MAX_UNREF_FONTS, 0,
-						  info->max_unref_fonts);
-    return True;
-}
-
-_X_HIDDEN int
-XftDefaultParseBool (char *v)
-{
-    char    c0, c1;
-
-    c0 = *v;
-    if (isupper ((int)c0))
-	c0 = tolower (c0);
-    if (c0 == 't' || c0 == 'y' || c0 == '1')
-	return 1;
-    if (c0 == 'f' || c0 == 'n' || c0 == '0')
-	return 0;
-    if (c0 == 'o')
-    {
-	c1 = v[1];
-	if (isupper ((int)c1))
-	    c1 = tolower (c1);
-	if (c1 == 'n')
-	    return 1;
-	if (c1 == 'f')
-	    return 0;
-    }
-    return -1;
-}
-
-static Bool
-_XftDefaultInitBool (Display *dpy, FcPattern *pat, char *option)
-{
-    char    *v;
-    int	    i;
-
-    v = XGetDefault (dpy, "Xft", option);
-    if (v && (i = XftDefaultParseBool (v)) >= 0)
-	return FcPatternAddBool (pat, option, i != 0);
-    return True;
-}
-
-static Bool
-_XftDefaultInitDouble (Display *dpy, FcPattern *pat, char *option)
-{
-    char    *v, *e;
-    double  d;
-
-    v = XGetDefault (dpy, "Xft", option);
-    if (v)
-    {
-	d = strtod (v, &e);
-	if (e != v)
-	    return FcPatternAddDouble (pat, option, d);
-    }
-    return True;
-}
-
-static Bool
-_XftDefaultInitInteger (Display *dpy, FcPattern *pat, char *option)
-{
-    char    *v, *e;
-    int	    i;
-
-    v = XGetDefault (dpy, "Xft", option);
-    if (v)
-    {
-	if (FcNameConstant ((FcChar8 *) v, &i))
-	    return FcPatternAddInteger (pat, option, i);
-	i = strtol (v, &e, 0);
-	if (e != v)
-	    return FcPatternAddInteger (pat, option, i);
-    }
-    return True;
-}
-
-static FcPattern *
-_XftDefaultInit (Display *dpy)
-{
-    FcPattern	*pat;
-
-    pat = FcPatternCreate ();
-    if (!pat)
-	goto bail0;
-
-    if (!_XftDefaultInitDouble (dpy, pat, FC_SCALE))
-	goto bail1;
-    if (!_XftDefaultInitDouble (dpy, pat, FC_DPI))
-	goto bail1;
-    if (!_XftDefaultInitBool (dpy, pat, XFT_RENDER))
-	goto bail1;
-    if (!_XftDefaultInitInteger (dpy, pat, FC_RGBA))
-	goto bail1;
-    if (!_XftDefaultInitBool (dpy, pat, FC_ANTIALIAS))
-	goto bail1;
-#ifdef FC_EMBOLDEN
-    if (!_XftDefaultInitBool (dpy, pat, FC_EMBOLDEN))
-	goto bail1;
-#endif
-    if (!_XftDefaultInitBool (dpy, pat, FC_AUTOHINT))
-	goto bail1;
-#ifdef FC_HINT_STYLE
-    if (!_XftDefaultInitInteger (dpy, pat, FC_HINT_STYLE))
-	goto bail1;
-#endif
-    if (!_XftDefaultInitBool (dpy, pat, FC_HINTING))
-	goto bail1;
-    if (!_XftDefaultInitBool (dpy, pat, FC_MINSPACE))
-	goto bail1;
-    if (!_XftDefaultInitInteger (dpy, pat, XFT_MAX_GLYPH_MEMORY))
-	goto bail1;
-    
-    return pat;
-    
-bail1:
-    FcPatternDestroy (pat);
-bail0:
-    return NULL;
-}
-
-static FcResult
-_XftDefaultGet (Display *dpy, const char *object, int screen, FcValue *v)
-{
-    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, True);
-    FcResult	    r;
-
-    if (!info)
-	return FcResultNoMatch;
-    
-    if (!info->defaults)
-    {
-	info->defaults = _XftDefaultInit (dpy);
-	if (!info->defaults)
-	    return FcResultNoMatch;
-    }
-    r = FcPatternGet (info->defaults, object, screen, v);
-    if (r == FcResultNoId && screen > 0)
-	r = FcPatternGet (info->defaults, object, 0, v);
-    return r;
-}
-
-_X_HIDDEN Bool
-XftDefaultGetBool (Display *dpy, const char *object, int screen, Bool def)
-{
-    FcResult	    r;
-    FcValue	    v;
-
-    r = _XftDefaultGet (dpy, object, screen, &v);
-    if (r != FcResultMatch || v.type != FcTypeBool)
-	return def;
-    return v.u.b;
-}
-
-_X_HIDDEN int
-XftDefaultGetInteger (Display *dpy, const char *object, int screen, int def)
-{
-    FcResult	    r;
-    FcValue	    v;
-
-    r = _XftDefaultGet (dpy, object, screen, &v);
-    if (r != FcResultMatch || v.type != FcTypeInteger)
-	return def;
-    return v.u.i;
-}
-
-_X_HIDDEN double
-XftDefaultGetDouble (Display *dpy, const char *object, int screen, double def)
-{
-    FcResult	    r;
-    FcValue	    v;
-
-    r = _XftDefaultGet (dpy, object, screen, &v);
-    if (r != FcResultMatch || v.type != FcTypeDouble)
-	return def;
-    return v.u.d;
-}
-
-_X_EXPORT void
-XftDefaultSubstitute (Display *dpy, int screen, FcPattern *pattern)
-{
-    FcValue	v;
-    double	dpi;
-
-    if (FcPatternGet (pattern, XFT_RENDER, 0, &v) == FcResultNoMatch)
-    {
-	FcPatternAddBool (pattern, XFT_RENDER,
-			   XftDefaultGetBool (dpy, XFT_RENDER, screen, 
-					      XftDefaultHasRender (dpy)));
-    }
-    if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
-    {
-	FcPatternAddBool (pattern, FC_ANTIALIAS,
-			   XftDefaultGetBool (dpy, FC_ANTIALIAS, screen,
-					      True));
-    }
-#ifdef FC_EMBOLDEN
-    if (FcPatternGet (pattern, FC_EMBOLDEN, 0, &v) == FcResultNoMatch)
-    {
-	FcPatternAddBool (pattern, FC_EMBOLDEN,
-			   XftDefaultGetBool (dpy, FC_EMBOLDEN, screen,
-					      False));
-    }
-#endif
-    if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
-    {
-	FcPatternAddBool (pattern, FC_HINTING,
-			  XftDefaultGetBool (dpy, FC_HINTING, screen,
-					     True));
-    }
-#ifdef FC_HINT_STYLE
-    if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
-    {
-	FcPatternAddInteger (pattern, FC_HINT_STYLE,
-			     XftDefaultGetInteger (dpy, FC_HINT_STYLE, screen,
-						   FC_HINT_FULL));
-    }
-#endif
-    if (FcPatternGet (pattern, FC_AUTOHINT, 0, &v) == FcResultNoMatch)
-    {
-	FcPatternAddBool (pattern, FC_AUTOHINT,
-			  XftDefaultGetBool (dpy, FC_AUTOHINT, screen,
-					     False));
-    }
-    if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch)
-    {
-	int	subpixel = FC_RGBA_UNKNOWN;
-#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
-	if (XftDefaultHasRender (dpy))
-	{
-	    int render_order = XRenderQuerySubpixelOrder (dpy, screen);
-	    switch (render_order) {
-	    default:
-	    case SubPixelUnknown:	subpixel = FC_RGBA_UNKNOWN; break;
-	    case SubPixelHorizontalRGB:	subpixel = FC_RGBA_RGB; break;
-	    case SubPixelHorizontalBGR:	subpixel = FC_RGBA_BGR; break;
-	    case SubPixelVerticalRGB:	subpixel = FC_RGBA_VRGB; break;
-	    case SubPixelVerticalBGR:	subpixel = FC_RGBA_VBGR; break;
-	    case SubPixelNone:		subpixel = FC_RGBA_NONE; break;
-	    }
-	}
-#endif
-	FcPatternAddInteger (pattern, FC_RGBA,
-			      XftDefaultGetInteger (dpy, FC_RGBA, screen, 
-						    subpixel));
-    }
-    if (FcPatternGet (pattern, FC_MINSPACE, 0, &v) == FcResultNoMatch)
-    {
-	FcPatternAddBool (pattern, FC_MINSPACE,
-			   XftDefaultGetBool (dpy, FC_MINSPACE, screen,
-					      False));
-    }
-    if (FcPatternGet (pattern, FC_DPI, 0, &v) == FcResultNoMatch)
-    {
-	dpi = (((double) DisplayHeight (dpy, screen) * 25.4) / 
-	       (double) DisplayHeightMM (dpy, screen));
-	FcPatternAddDouble (pattern, FC_DPI, 
-			    XftDefaultGetDouble (dpy, FC_DPI, screen, 
-						 dpi));
-    }
-    if (FcPatternGet (pattern, FC_SCALE, 0, &v) == FcResultNoMatch)
-    {
-	FcPatternAddDouble (pattern, FC_SCALE,
-			    XftDefaultGetDouble (dpy, FC_SCALE, screen, 1.0));
-    }
-    if (FcPatternGet (pattern, XFT_MAX_GLYPH_MEMORY, 0, &v) == FcResultNoMatch)
-    {
-	FcPatternAddInteger (pattern, XFT_MAX_GLYPH_MEMORY,
-			     XftDefaultGetInteger (dpy, XFT_MAX_GLYPH_MEMORY,
-						   screen,
-						   XFT_FONT_MAX_GLYPH_MEMORY));
-    }
-    FcDefaultSubstitute (pattern);
-}
-
+/*
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "xftint.h"
+
+_X_HIDDEN XftDisplayInfo	*_XftDisplayInfo;
+
+static int
+_XftCloseDisplay (Display *dpy, XExtCodes *codes)
+{
+    XftDisplayInfo  *info, **prev;
+
+    info = _XftDisplayInfoGet (dpy, FcFalse);
+    if (!info)
+	return 0;
+    
+    /*
+     * Get rid of any dangling unreferenced fonts
+     */
+    info->max_unref_fonts = 0;
+    XftFontManageMemory (dpy);
+    
+    /*
+     * Clean up the default values
+     */
+    if (info->defaults)
+	FcPatternDestroy (info->defaults);
+    
+    /*
+     * Unhook from the global list
+     */
+    for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next)
+	if (info->display == dpy)
+	    break;
+    *prev = info->next;
+    
+    free (info);
+    return 0;
+}
+
+
+_X_HIDDEN XftDisplayInfo *
+_XftDisplayInfoGet (Display *dpy, FcBool createIfNecessary)
+{
+    XftDisplayInfo	*info, **prev;
+    XRenderPictFormat	pf;
+    int			i;
+    int			event_base, error_base;
+
+    for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next)
+    {
+	if (info->display == dpy)
+	{
+	    /*
+	     * MRU the list
+	     */
+	    if (prev != &_XftDisplayInfo)
+	    {
+		*prev = info->next;
+		info->next = _XftDisplayInfo;
+		_XftDisplayInfo = info;
+	    }
+	    return info;
+	}
+    }
+    if (!createIfNecessary)
+	return NULL;
+
+    info = (XftDisplayInfo *) malloc (sizeof (XftDisplayInfo));
+    if (!info)
+	goto bail0;
+    info->codes = XAddExtension (dpy);
+    if (!info->codes)
+	goto bail1;
+    (void) XESetCloseDisplay (dpy, info->codes->extension, _XftCloseDisplay);
+
+    info->display = dpy;
+    info->defaults = NULL;
+    info->solidFormat = NULL;
+    info->hasRender = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
+		       (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != NULL));
+    info->use_free_glyphs = FcTrue;
+    if (info->hasRender)
+    {
+	int major, minor;
+	XRenderQueryVersion (dpy, &major, &minor);
+	if (major < 0 || (major == 0 && minor <= 2))
+	    info->use_free_glyphs = FcFalse;
+
+	pf.type = PictTypeDirect;
+	pf.depth = 32;
+	pf.direct.redMask = 0xff;
+	pf.direct.greenMask = 0xff;
+	pf.direct.blueMask = 0xff;
+	pf.direct.alphaMask = 0xff;
+	info->solidFormat = XRenderFindFormat (dpy,
+					       (PictFormatType|
+						PictFormatDepth|
+						PictFormatRedMask|
+						PictFormatGreenMask|
+						PictFormatBlueMask|
+						PictFormatAlphaMask),
+					       &pf,
+					       0);
+    }
+    if (XftDebug () & XFT_DBG_RENDER)
+    {
+	Visual		    *visual = DefaultVisual (dpy, DefaultScreen (dpy));
+	XRenderPictFormat   *format = XRenderFindVisualFormat (dpy, visual);
+	
+	printf ("XftDisplayInfoGet Default visual 0x%x ", 
+		(int) visual->visualid);
+	if (format)
+	{
+	    if (format->type == PictTypeDirect)
+	    {
+		printf ("format %d,%d,%d,%d\n",
+			format->direct.alpha,
+			format->direct.red,
+			format->direct.green,
+			format->direct.blue);
+	    }
+	    else
+	    {
+		printf ("format indexed\n");
+	    }
+	}
+	else
+	    printf ("No Render format for default visual\n");
+	
+	printf ("XftDisplayInfoGet initialized, hasRender set to \"%s\"\n",
+		info->hasRender ? "True" : "False");
+    }
+    for (i = 0; i < XFT_NUM_SOLID_COLOR; i++)
+    {
+	info->colors[i].screen = -1;
+	info->colors[i].pict = 0;
+    }
+    info->fonts = NULL;
+    
+    info->next = _XftDisplayInfo;
+    _XftDisplayInfo = info;
+
+    info->glyph_memory = 0;
+    info->max_glyph_memory = XftDefaultGetInteger (dpy,
+						   XFT_MAX_GLYPH_MEMORY, 0,
+						   XFT_DPY_MAX_GLYPH_MEMORY);
+    if (XftDebug () & XFT_DBG_CACHE)
+	printf ("global max cache memory %ld\n", info->max_glyph_memory);
+
+    
+    info->num_unref_fonts = 0;
+    info->max_unref_fonts = XftDefaultGetInteger (dpy,
+						  XFT_MAX_UNREF_FONTS, 0,
+						  XFT_DPY_MAX_UNREF_FONTS);
+    if (XftDebug() & XFT_DBG_CACHE)
+	printf ("global max unref fonts %d\n", info->max_unref_fonts);
+
+    memset (info->fontHash, '\0', sizeof (XftFont *) * XFT_NUM_FONT_HASH);
+    return info;
+    
+bail1:
+    free (info);
+bail0:
+    if (XftDebug () & XFT_DBG_RENDER)
+    {
+	printf ("XftDisplayInfoGet failed to initialize, Xft unhappy\n");
+    }
+    return NULL;
+}
+
+/*
+ * Reduce memory usage in X server
+ */
+
+static void
+_XftDisplayValidateMemory (XftDisplayInfo *info)
+{
+    XftFont	    *public;
+    XftFontInt	    *font;
+    unsigned long   glyph_memory;
+
+    glyph_memory = 0;
+    for (public = info->fonts; public; public = font->next)
+    {
+	font = (XftFontInt *) public;
+	glyph_memory += font->glyph_memory;
+    }
+    if (glyph_memory != info->glyph_memory)
+	printf ("Display glyph cache incorrect has %ld bytes, should have %ld\n",
+		info->glyph_memory, glyph_memory);
+}
+
+_X_HIDDEN void
+_XftDisplayManageMemory (Display *dpy)
+{
+    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, False);
+    unsigned long   glyph_memory;
+    XftFont	    *public;
+    XftFontInt	    *font;
+
+    if (!info || !info->max_glyph_memory)
+	return;
+    if (XftDebug () & XFT_DBG_CACHE)
+    {
+	if (info->glyph_memory > info->max_glyph_memory)
+	    printf ("Reduce global memory from %ld to %ld\n",
+		    info->glyph_memory, info->max_glyph_memory);
+	_XftDisplayValidateMemory (info);
+    }
+    while (info->glyph_memory > info->max_glyph_memory)
+    {
+	glyph_memory = rand () % info->glyph_memory;
+	public = info->fonts;
+	while (public)
+	{
+	    font = (XftFontInt *) public;
+
+	    if (font->glyph_memory > glyph_memory)
+	    {
+		_XftFontUncacheGlyph (dpy, public);
+		break;
+	    }
+	    public = font->next;
+	    glyph_memory -= font->glyph_memory;
+	}
+    }
+    if (XftDebug () & XFT_DBG_CACHE)
+	_XftDisplayValidateMemory (info);
+}
+
+_X_EXPORT Bool
+XftDefaultHasRender (Display *dpy)
+{
+    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, True);
+
+    if (!info)
+	return False;
+    return info->hasRender;
+}
+
+_X_EXPORT Bool
+XftDefaultSet (Display *dpy, FcPattern *defaults)
+{
+    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, True);
+
+    if (!info)
+	return False;
+    if (info->defaults)
+	FcPatternDestroy (info->defaults);
+    info->defaults = defaults;
+    if (!info->max_glyph_memory)
+	info->max_glyph_memory = XFT_DPY_MAX_GLYPH_MEMORY;
+    info->max_glyph_memory = XftDefaultGetInteger (dpy,
+						   XFT_MAX_GLYPH_MEMORY, 0,
+						   info->max_glyph_memory);
+    if (!info->max_unref_fonts)
+	info->max_unref_fonts = XFT_DPY_MAX_UNREF_FONTS;
+    info->max_unref_fonts = XftDefaultGetInteger (dpy,
+						  XFT_MAX_UNREF_FONTS, 0,
+						  info->max_unref_fonts);
+    return True;
+}
+
+_X_HIDDEN int
+XftDefaultParseBool (char *v)
+{
+    char    c0, c1;
+
+    c0 = *v;
+    if (isupper ((int)c0))
+	c0 = tolower (c0);
+    if (c0 == 't' || c0 == 'y' || c0 == '1')
+	return 1;
+    if (c0 == 'f' || c0 == 'n' || c0 == '0')
+	return 0;
+    if (c0 == 'o')
+    {
+	c1 = v[1];
+	if (isupper ((int)c1))
+	    c1 = tolower (c1);
+	if (c1 == 'n')
+	    return 1;
+	if (c1 == 'f')
+	    return 0;
+    }
+    return -1;
+}
+
+static Bool
+_XftDefaultInitBool (Display *dpy, FcPattern *pat, char *option)
+{
+    char    *v;
+    int	    i;
+
+    v = XGetDefault (dpy, "Xft", option);
+    if (v && (i = XftDefaultParseBool (v)) >= 0)
+	return FcPatternAddBool (pat, option, i != 0);
+    return True;
+}
+
+static Bool
+_XftDefaultInitDouble (Display *dpy, FcPattern *pat, char *option)
+{
+    char    *v, *e;
+    double  d;
+
+    v = XGetDefault (dpy, "Xft", option);
+    if (v)
+    {
+	d = strtod (v, &e);
+	if (e != v)
+	    return FcPatternAddDouble (pat, option, d);
+    }
+    return True;
+}
+
+static Bool
+_XftDefaultInitInteger (Display *dpy, FcPattern *pat, char *option)
+{
+    char    *v, *e;
+    int	    i;
+
+    v = XGetDefault (dpy, "Xft", option);
+    if (v)
+    {
+	if (FcNameConstant ((FcChar8 *) v, &i))
+	    return FcPatternAddInteger (pat, option, i);
+	i = strtol (v, &e, 0);
+	if (e != v)
+	    return FcPatternAddInteger (pat, option, i);
+    }
+    return True;
+}
+
+static FcPattern *
+_XftDefaultInit (Display *dpy)
+{
+    FcPattern	*pat;
+
+    pat = FcPatternCreate ();
+    if (!pat)
+	goto bail0;
+
+    if (!_XftDefaultInitDouble (dpy, pat, FC_SCALE))
+	goto bail1;
+    if (!_XftDefaultInitDouble (dpy, pat, FC_DPI))
+	goto bail1;
+    if (!_XftDefaultInitBool (dpy, pat, XFT_RENDER))
+	goto bail1;
+    if (!_XftDefaultInitInteger (dpy, pat, FC_RGBA))
+	goto bail1;
+    if (!_XftDefaultInitBool (dpy, pat, FC_ANTIALIAS))
+	goto bail1;
+#ifdef FC_EMBOLDEN
+    if (!_XftDefaultInitBool (dpy, pat, FC_EMBOLDEN))
+	goto bail1;
+#endif
+    if (!_XftDefaultInitBool (dpy, pat, FC_AUTOHINT))
+	goto bail1;
+#ifdef FC_HINT_STYLE
+    if (!_XftDefaultInitInteger (dpy, pat, FC_HINT_STYLE))
+	goto bail1;
+#endif
+    if (!_XftDefaultInitBool (dpy, pat, FC_HINTING))
+	goto bail1;
+    if (!_XftDefaultInitBool (dpy, pat, FC_MINSPACE))
+	goto bail1;
+    if (!_XftDefaultInitInteger (dpy, pat, XFT_MAX_GLYPH_MEMORY))
+	goto bail1;
+    
+    return pat;
+    
+bail1:
+    FcPatternDestroy (pat);
+bail0:
+    return NULL;
+}
+
+static FcResult
+_XftDefaultGet (Display *dpy, const char *object, int screen, FcValue *v)
+{
+    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, True);
+    FcResult	    r;
+
+    if (!info)
+	return FcResultNoMatch;
+    
+    if (!info->defaults)
+    {
+	info->defaults = _XftDefaultInit (dpy);
+	if (!info->defaults)
+	    return FcResultNoMatch;
+    }
+    r = FcPatternGet (info->defaults, object, screen, v);
+    if (r == FcResultNoId && screen > 0)
+	r = FcPatternGet (info->defaults, object, 0, v);
+    return r;
+}
+
+_X_HIDDEN Bool
+XftDefaultGetBool (Display *dpy, const char *object, int screen, Bool def)
+{
+    FcResult	    r;
+    FcValue	    v;
+
+    r = _XftDefaultGet (dpy, object, screen, &v);
+    if (r != FcResultMatch || v.type != FcTypeBool)
+	return def;
+    return v.u.b;
+}
+
+_X_HIDDEN int
+XftDefaultGetInteger (Display *dpy, const char *object, int screen, int def)
+{
+    FcResult	    r;
+    FcValue	    v;
+
+    r = _XftDefaultGet (dpy, object, screen, &v);
+    if (r != FcResultMatch || v.type != FcTypeInteger)
+	return def;
+    return v.u.i;
+}
+
+_X_HIDDEN double
+XftDefaultGetDouble (Display *dpy, const char *object, int screen, double def)
+{
+    FcResult	    r;
+    FcValue	    v;
+
+    r = _XftDefaultGet (dpy, object, screen, &v);
+    if (r != FcResultMatch || v.type != FcTypeDouble)
+	return def;
+    return v.u.d;
+}
+
+_X_EXPORT void
+XftDefaultSubstitute (Display *dpy, int screen, FcPattern *pattern)
+{
+    FcValue	v;
+    double	dpi;
+
+    if (FcPatternGet (pattern, XFT_RENDER, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddBool (pattern, XFT_RENDER,
+			   XftDefaultGetBool (dpy, XFT_RENDER, screen, 
+					      XftDefaultHasRender (dpy)));
+    }
+    if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddBool (pattern, FC_ANTIALIAS,
+			   XftDefaultGetBool (dpy, FC_ANTIALIAS, screen,
+					      True));
+    }
+#ifdef FC_EMBOLDEN
+    if (FcPatternGet (pattern, FC_EMBOLDEN, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddBool (pattern, FC_EMBOLDEN,
+			   XftDefaultGetBool (dpy, FC_EMBOLDEN, screen,
+					      False));
+    }
+#endif
+    if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddBool (pattern, FC_HINTING,
+			  XftDefaultGetBool (dpy, FC_HINTING, screen,
+					     True));
+    }
+#ifdef FC_HINT_STYLE
+    if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddInteger (pattern, FC_HINT_STYLE,
+			     XftDefaultGetInteger (dpy, FC_HINT_STYLE, screen,
+						   FC_HINT_FULL));
+    }
+#endif
+    if (FcPatternGet (pattern, FC_AUTOHINT, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddBool (pattern, FC_AUTOHINT,
+			  XftDefaultGetBool (dpy, FC_AUTOHINT, screen,
+					     False));
+    }
+    if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch)
+    {
+	int	subpixel = FC_RGBA_UNKNOWN;
+#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
+	if (XftDefaultHasRender (dpy))
+	{
+	    int render_order = XRenderQuerySubpixelOrder (dpy, screen);
+	    switch (render_order) {
+	    default:
+	    case SubPixelUnknown:	subpixel = FC_RGBA_UNKNOWN; break;
+	    case SubPixelHorizontalRGB:	subpixel = FC_RGBA_RGB; break;
+	    case SubPixelHorizontalBGR:	subpixel = FC_RGBA_BGR; break;
+	    case SubPixelVerticalRGB:	subpixel = FC_RGBA_VRGB; break;
+	    case SubPixelVerticalBGR:	subpixel = FC_RGBA_VBGR; break;
+	    case SubPixelNone:		subpixel = FC_RGBA_NONE; break;
+	    }
+	}
+#endif
+	FcPatternAddInteger (pattern, FC_RGBA,
+			      XftDefaultGetInteger (dpy, FC_RGBA, screen, 
+						    subpixel));
+    }
+    if (FcPatternGet (pattern, FC_MINSPACE, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddBool (pattern, FC_MINSPACE,
+			   XftDefaultGetBool (dpy, FC_MINSPACE, screen,
+					      False));
+    }
+    if (FcPatternGet (pattern, FC_DPI, 0, &v) == FcResultNoMatch)
+    {
+	dpi = (((double) DisplayHeight (dpy, screen) * 25.4) / 
+	       (double) DisplayHeightMM (dpy, screen));
+	FcPatternAddDouble (pattern, FC_DPI, 
+			    XftDefaultGetDouble (dpy, FC_DPI, screen, 
+						 dpi));
+    }
+    if (FcPatternGet (pattern, FC_SCALE, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddDouble (pattern, FC_SCALE,
+			    XftDefaultGetDouble (dpy, FC_SCALE, screen, 1.0));
+    }
+    if (FcPatternGet (pattern, XFT_MAX_GLYPH_MEMORY, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddInteger (pattern, XFT_MAX_GLYPH_MEMORY,
+			     XftDefaultGetInteger (dpy, XFT_MAX_GLYPH_MEMORY,
+						   screen,
+						   XFT_FONT_MAX_GLYPH_MEMORY));
+    }
+    FcDefaultSubstitute (pattern);
+}
+
diff --git a/libXft/src/xftdraw.c b/libXft/src/xftdraw.c
index 7b8f84dd5..21f8538a3 100644
--- a/libXft/src/xftdraw.c
+++ b/libXft/src/xftdraw.c
@@ -1,994 +1,994 @@
-/*
- * Copyright © 2000 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "xftint.h"
-
-/*
- * Ok, this is a pain.  To share source pictures across multiple destinations,
- * the screen for each drawable must be discovered.
- */
-
-static int
-_XftDrawScreen (Display *dpy, Drawable drawable, Visual *visual)
-{
-    int		    s;
-    Window	    root;
-    int		    x, y;
-    unsigned int    width, height, borderWidth, depth;
-    /* Special case the most common environment */
-    if (ScreenCount (dpy) == 1)
-	return 0;
-    /*
-     * If we've got a visual, look for the screen that points at it.
-     * This requires no round trip.
-     */
-    if (visual)
-    {
-	for (s = 0; s < ScreenCount (dpy); s++)
-	{
-	    XVisualInfo	template, *ret;
-	    int		nret;
-
-	    template.visualid = visual->visualid;
-	    template.screen = s;
-	    ret = XGetVisualInfo (dpy, VisualIDMask|VisualScreenMask,
-				  &template, &nret);
-	    if (ret)
-	    {
-		XFree (ret);
-		return s;
-	    }
-	}
-    }
-    /*
-     * Otherwise, as the server for the drawable geometry and find
-     * the screen from the root window.
-     * This takes a round trip.
-     */
-    if (XGetGeometry (dpy, drawable, &root, &x, &y, &width, &height,
-		      &borderWidth, &depth))
-    {
-	for (s = 0; s < ScreenCount (dpy); s++)
-	{
-	    if (RootWindow (dpy, s) == root)
-		return s;
-	}
-    }
-    /*
-     * Make a guess -- it's probably wrong, but then the app probably
-     * handed us a bogus drawable in this case
-     */
-    return 0;
-}
-
-_X_HIDDEN unsigned int
-XftDrawDepth (XftDraw *draw)
-{
-    if (!draw->depth)
-    {
-	Window		    root;
-	int		    x, y;
-	unsigned int	    width, height, borderWidth, depth;
-	if (XGetGeometry (draw->dpy, draw->drawable, 
-			  &root, &x, &y, &width, &height,
-			  &borderWidth, &depth))
-	    draw->depth = depth;
-    }
-    return draw->depth;
-}
-
-_X_HIDDEN unsigned int
-XftDrawBitsPerPixel (XftDraw	*draw)
-{
-    if (!draw->bits_per_pixel)
-    {
-	XPixmapFormatValues *formats;
-	int		    nformats;
-	unsigned int	    depth;
-	
-	if ((depth = XftDrawDepth (draw)) &&
-	    (formats = XListPixmapFormats (draw->dpy, &nformats)))
-	{
-	    int	i;
-
-	    for (i = 0; i < nformats; i++)
-	    {
-		if (formats[i].depth == depth)
-		{
-		    draw->bits_per_pixel = formats[i].bits_per_pixel;
-		    break;
-		}
-	    }
-	    XFree (formats);
-	}
-    }
-    return draw->bits_per_pixel;
-}
-
-_X_EXPORT XftDraw *
-XftDrawCreate (Display   *dpy,
-	       Drawable  drawable,
-	       Visual    *visual,
-	       Colormap  colormap)
-{
-    XftDraw	*draw;
-
-    draw = (XftDraw *) malloc (sizeof (XftDraw));
-    if (!draw)
-	return NULL;
-    
-    draw->dpy = dpy;
-    draw->drawable = drawable;
-    draw->screen = _XftDrawScreen (dpy, drawable, visual);
-    draw->depth = 0;		/* don't find out unless we need to know */
-    draw->bits_per_pixel = 0;	/* don't find out unless we need to know */
-    draw->visual = visual;
-    draw->colormap = colormap;
-    draw->render.pict = 0;
-    draw->core.gc = NULL;
-    draw->core.use_pixmap = 0;
-    draw->clip_type = XftClipTypeNone;
-    draw->subwindow_mode = ClipByChildren;
-    XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw));
-    return draw;
-}
-
-_X_EXPORT XftDraw *
-XftDrawCreateBitmap (Display	*dpy,
-		     Pixmap	bitmap)
-{
-    XftDraw	*draw;
-
-    draw = (XftDraw *) malloc (sizeof (XftDraw));
-    if (!draw)
-	return NULL;
-    draw->dpy = dpy;
-    draw->drawable = (Drawable) bitmap;
-    draw->screen = _XftDrawScreen (dpy, bitmap, NULL);
-    draw->depth = 1;
-    draw->bits_per_pixel = 1;
-    draw->visual = NULL;
-    draw->colormap = 0;
-    draw->render.pict = 0;
-    draw->core.gc = NULL;
-    draw->core.use_pixmap = 0;
-    draw->clip_type = XftClipTypeNone;
-    draw->subwindow_mode = ClipByChildren;
-    XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw));
-    return draw;
-}
-
-_X_EXPORT XftDraw *
-XftDrawCreateAlpha (Display *dpy,
-		    Pixmap  pixmap,
-		    int	    depth)
-{
-    XftDraw	*draw;
-
-    draw = (XftDraw *) malloc (sizeof (XftDraw));
-    if (!draw)
-	return NULL;
-    draw->dpy = dpy;
-    draw->drawable = (Drawable) pixmap;
-    draw->screen = _XftDrawScreen (dpy, pixmap, NULL);
-    draw->depth = depth;
-    draw->bits_per_pixel = 0;	/* don't find out until we need it */
-    draw->visual = NULL;
-    draw->colormap = 0;
-    draw->render.pict = 0;
-    draw->core.gc = NULL;
-    draw->core.use_pixmap = 0;
-    draw->clip_type = XftClipTypeNone;
-    draw->subwindow_mode = ClipByChildren;
-    XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw));
-    return draw;
-}
-
-static XRenderPictFormat *
-_XftDrawFormat (XftDraw	*draw)
-{
-    XftDisplayInfo  *info = _XftDisplayInfoGet (draw->dpy, True);
-
-    if (!info || !info->hasRender)
-	return NULL;
-
-    if (draw->visual == NULL)
-    {
-	XRenderPictFormat   pf;
-
-	pf.type = PictTypeDirect;
-	pf.depth = XftDrawDepth (draw);
-	pf.direct.alpha = 0;
-	pf.direct.alphaMask = (1 << pf.depth) - 1;
-	return XRenderFindFormat (draw->dpy,
-				  (PictFormatType|
-				   PictFormatDepth|
-				   PictFormatAlpha|
-				   PictFormatAlphaMask),
-				  &pf,
-				  0);
-    }
-    else
-	return XRenderFindVisualFormat (draw->dpy, draw->visual);
-}
-
-_X_EXPORT void
-XftDrawChange (XftDraw	*draw,
-	       Drawable	drawable)
-{
-    draw->drawable = drawable;
-    if (draw->render.pict)
-    {
-	XRenderFreePicture (draw->dpy, draw->render.pict);
-	draw->render.pict = 0;
-    }
-    if (draw->core.gc)
-    {
-	XFreeGC (draw->dpy, draw->core.gc);
-	draw->core.gc = NULL;
-    }
-}
-
-_X_EXPORT Display *
-XftDrawDisplay (XftDraw *draw)
-{
-    return draw->dpy;
-}
-
-_X_EXPORT Drawable
-XftDrawDrawable (XftDraw *draw)
-{
-    return draw->drawable;
-}
-
-_X_EXPORT Colormap
-XftDrawColormap (XftDraw *draw)
-{
-    return draw->colormap;
-}
-
-_X_EXPORT Visual *
-XftDrawVisual (XftDraw *draw)
-{
-    return draw->visual;
-}
-
-_X_EXPORT void
-XftDrawDestroy (XftDraw	*draw)
-{
-    if (draw->render.pict)
-	XRenderFreePicture (draw->dpy, draw->render.pict);
-    if (draw->core.gc)
-	XFreeGC (draw->dpy, draw->core.gc);
-    switch (draw->clip_type) {
-    case XftClipTypeRegion:
-	XDestroyRegion (draw->clip.region);
-	break;
-    case XftClipTypeRectangles:
-	free (draw->clip.rect);
-	break;
-    case XftClipTypeNone:
-	break;
-    }
-    XftMemFree (XFT_MEM_DRAW, sizeof (XftDraw));
-    free (draw);
-}
-
-_X_EXPORT Picture
-XftDrawSrcPicture (XftDraw *draw, _Xconst XftColor *color)
-{
-    Display	    *dpy = draw->dpy;
-    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, True);
-    int		    i;
-    XftColor	    bitmapColor;
-
-    if (!info || !info->solidFormat)
-	return 0;
-    
-    /*
-     * Monochrome targets require special handling; the PictOp controls
-     * the color, and the color must be opaque
-     */
-    if (!draw->visual && draw->depth == 1)
-    {
-	bitmapColor.color.alpha = 0xffff;
-	bitmapColor.color.red   = 0xffff;
-	bitmapColor.color.green = 0xffff;
-	bitmapColor.color.blue  = 0xffff;
-	color = &bitmapColor;
-    }
-
-    /*
-     * See if there's one already available
-     */
-    for (i = 0; i < XFT_NUM_SOLID_COLOR; i++)
-    {
-	if (info->colors[i].pict && 
-	    info->colors[i].screen == draw->screen &&
-	    !memcmp ((void *) &color->color, 
-		     (void *) &info->colors[i].color,
-		     sizeof (XRenderColor)))
-	    return info->colors[i].pict;
-    }
-    /*
-     * Pick one to replace at random
-     */
-    i = (unsigned int) rand () % XFT_NUM_SOLID_COLOR;
-    /*
-     * Recreate if it was for the wrong screen
-     */
-    if (info->colors[i].screen != draw->screen && info->colors[i].pict)
-    {
-	XRenderFreePicture (dpy, info->colors[i].pict);
-	info->colors[i].pict = 0;
-    }
-    /*
-     * Create picture if necessary
-     */
-    if (!info->colors[i].pict)
-    {
-	Pixmap			    pix;
-        XRenderPictureAttributes    pa;
-	
-	pix = XCreatePixmap (dpy, RootWindow (dpy, draw->screen), 1, 1,
-			     info->solidFormat->depth);
-	pa.repeat = True;
-	info->colors[i].pict = XRenderCreatePicture (draw->dpy,
-						     pix,
-						     info->solidFormat,
-						     CPRepeat, &pa);
-	XFreePixmap (dpy, pix);
-    }
-    /*
-     * Set to the new color
-     */
-    info->colors[i].color = color->color;
-    info->colors[i].screen = draw->screen;
-    XRenderFillRectangle (dpy, PictOpSrc,
-			  info->colors[i].pict,
-			  &color->color, 0, 0, 1, 1);
-    return info->colors[i].pict;
-}
-
-static int
-_XftDrawOp (_Xconst XftDraw *draw, _Xconst XftColor *color)
-{
-    if (draw->visual || draw->depth != 1)
-	return PictOpOver;
-    if (color->color.alpha >= 0x8000)
-	return PictOpOver;
-    return PictOpOutReverse;
-}
-
-static FcBool
-_XftDrawRenderPrepare (XftDraw	*draw)
-{
-    if (!draw->render.pict)
-    {
-	XRenderPictFormat	    *format;
-	XRenderPictureAttributes    pa;
-	unsigned long		    mask = 0;
-
-	format = _XftDrawFormat (draw);
-	if (!format)
-	    return FcFalse;
-	
-	if (draw->subwindow_mode == IncludeInferiors)
-	{
-	    pa.subwindow_mode = IncludeInferiors;
-	    mask |= CPSubwindowMode;
-	}
-	draw->render.pict = XRenderCreatePicture (draw->dpy, draw->drawable,
-						  format, mask, &pa);
-	if (!draw->render.pict)
-	    return FcFalse;
-	switch (draw->clip_type) {
-	case XftClipTypeRegion:
-	    XRenderSetPictureClipRegion (draw->dpy, draw->render.pict,
-					 draw->clip.region);
-	    break;
-	case XftClipTypeRectangles:
-	    XRenderSetPictureClipRectangles (draw->dpy, draw->render.pict,
-					     draw->clip.rect->xOrigin,
-					     draw->clip.rect->yOrigin,
-					     XftClipRects(draw->clip.rect),
-					     draw->clip.rect->n);
-	    break;
-	case XftClipTypeNone:
-	    break;
-	}
-    }
-    return FcTrue;
-}
-
-static FcBool
-_XftDrawCorePrepare (XftDraw *draw, _Xconst XftColor *color)
-{
-    if (!draw->core.gc)
-    {
-	XGCValues	gcv;
-	unsigned long	mask = 0;
-	if (draw->subwindow_mode == IncludeInferiors)
-	{
-	    gcv.subwindow_mode = IncludeInferiors;
-	    mask |= GCSubwindowMode;
-	}
-	draw->core.gc = XCreateGC (draw->dpy, draw->drawable, mask, &gcv);
-	if (!draw->core.gc)
-	    return FcFalse;
-	switch (draw->clip_type) {
-	case XftClipTypeRegion:
-	    XSetRegion (draw->dpy, draw->core.gc, draw->clip.region);
-	    break;
-	case XftClipTypeRectangles:
-	    XSetClipRectangles (draw->dpy, draw->core.gc,
-				draw->clip.rect->xOrigin,
-				draw->clip.rect->yOrigin,
-				XftClipRects (draw->clip.rect),
-				draw->clip.rect->n,
-				Unsorted);
-	    break;
-	case XftClipTypeNone:
-	    break;
-	}
-    }
-    XSetForeground (draw->dpy, draw->core.gc, color->pixel);
-    return FcTrue;
-}
-			
-_X_EXPORT Picture
-XftDrawPicture (XftDraw *draw)
-{
-    if (!_XftDrawRenderPrepare (draw))
-	return 0;
-    return draw->render.pict;
-}
-
-#define NUM_LOCAL   1024
-
-_X_EXPORT void
-XftDrawGlyphs (XftDraw		*draw,
-	       _Xconst XftColor	*color,
-	       XftFont		*pub,
-	       int		x,
-	       int		y,
-	       _Xconst FT_UInt	*glyphs,
-	       int		nglyphs)
-{
-    XftFontInt	*font = (XftFontInt *) pub;
-
-    if (font->format)
-    {
-	Picture	    src;
-	
-	if (_XftDrawRenderPrepare (draw) &&
-	    (src = XftDrawSrcPicture (draw, color)))
-	    XftGlyphRender (draw->dpy, _XftDrawOp (draw, color),
-			     src, pub, draw->render.pict,
-			     0, 0, x, y, glyphs, nglyphs);
-    }
-    else
-    {
-	if (_XftDrawCorePrepare (draw, color))
-	    XftGlyphCore (draw, color, pub, x, y, glyphs, nglyphs);
-    }
-}
-
-_X_EXPORT void
-XftDrawString8 (XftDraw		    *draw,
-		_Xconst XftColor    *color,
-		XftFont		    *pub,
-		int		    x, 
-		int		    y,
-		_Xconst FcChar8	    *string,
-		int		    len)
-{
-    FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
-    int		    i;
-
-    if (XftDebug () & XFT_DBG_DRAW)
-	printf ("DrawString \"%*.*s\"\n", len, len, string);
-    
-    if (len <= NUM_LOCAL)
-	glyphs = glyphs_local;
-    else
-    {
-	glyphs = malloc (len * sizeof (FT_UInt));
-	if (!glyphs)
-	    return;
-    }
-    for (i = 0; i < len; i++)
-	glyphs[i] = XftCharIndex (draw->dpy, pub, string[i]);
-    XftDrawGlyphs (draw, color, pub, x, y, glyphs, len);
-    if (glyphs != glyphs_local)
-	free (glyphs);
-}
-
-_X_EXPORT void
-XftDrawString16 (XftDraw	    *draw,
-		 _Xconst XftColor   *color,
-		 XftFont	    *pub,
-		 int		    x,
-		 int		    y,
-		 _Xconst FcChar16   *string,
-		 int		    len)
-{
-    FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
-    int		    i;
-
-    if (len <= NUM_LOCAL)
-	glyphs = glyphs_local;
-    else
-    {
-	glyphs = malloc (len * sizeof (FT_UInt));
-	if (!glyphs)
-	    return;
-    }
-    for (i = 0; i < len; i++)
-	glyphs[i] = XftCharIndex (draw->dpy, pub, string[i]);
-    
-    XftDrawGlyphs (draw, color, pub, x, y, glyphs, len);
-    if (glyphs != glyphs_local)
-	free (glyphs);
-}
-
-_X_EXPORT void
-XftDrawString32 (XftDraw	    *draw,
-		 _Xconst XftColor   *color,
-		 XftFont	    *pub,
-		 int		    x,
-		 int		    y,
-		 _Xconst FcChar32   *string,
-		 int		    len)
-{
-    FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
-    int		    i;
-
-    if (len <= NUM_LOCAL)
-	glyphs = glyphs_local;
-    else
-    {
-	glyphs = malloc (len * sizeof (FT_UInt));
-	if (!glyphs)
-	    return;
-    }
-    for (i = 0; i < len; i++)
-	glyphs[i] = XftCharIndex (draw->dpy, pub, string[i]);
-    
-    XftDrawGlyphs (draw, color, pub, x, y, glyphs, len);
-    if (glyphs != glyphs_local)
-	free (glyphs);
-}
-
-_X_EXPORT void
-XftDrawStringUtf8 (XftDraw	    *draw,
-		   _Xconst XftColor *color,
-		   XftFont	    *pub,
-		   int		    x, 
-		   int		    y,
-		   _Xconst FcChar8  *string,
-		   int		    len)
-{
-    FT_UInt	    *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL];
-    FcChar32	    ucs4;
-    int		    i;
-    int		    l;
-    int		    size;
-
-    i = 0;
-    glyphs = glyphs_local;
-    size = NUM_LOCAL;
-    while (len && (l = FcUtf8ToUcs4 (string, &ucs4, len)) > 0)
-    {
-	if (i == size)
-	{
-	    glyphs_new = malloc (size * 2 * sizeof (FT_UInt));
-	    if (!glyphs_new)
-	    {
-		if (glyphs != glyphs_local)
-		    free (glyphs);
-		return;
-	    }
-	    memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt));
-	    size *= 2;
-	    if (glyphs != glyphs_local)
-		free (glyphs);
-	    glyphs = glyphs_new;
-	}
-	glyphs[i++] = XftCharIndex (draw->dpy, pub, ucs4);
-	string += l;
-	len -= l;
-    }
-    XftDrawGlyphs (draw, color, pub, x, y, glyphs, i);
-    if (glyphs != glyphs_local)
-	free (glyphs);
-}
-
-_X_EXPORT void
-XftDrawStringUtf16 (XftDraw		*draw,
-		    _Xconst XftColor	*color,
-		    XftFont		*pub,
-		    int			x,
-		    int			y,
-		    _Xconst FcChar8	*string,
-		    FcEndian		endian,
-		    int			len)
-{
-    FT_UInt	    *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL];
-    FcChar32	    ucs4;
-    int		    i;
-    int		    l;
-    int		    size;
-
-    i = 0;
-    glyphs = glyphs_local;
-    size = NUM_LOCAL;
-    while (len && (l = FcUtf16ToUcs4 (string, endian, &ucs4, len)) > 0)
-    {
-	if (i == size)
-	{
-	    glyphs_new = malloc (size * 2 * sizeof (FT_UInt));
-	    if (!glyphs_new)
-	    {
-		if (glyphs != glyphs_local)
-		    free (glyphs);
-		return;
-	    }
-	    memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt));
-	    size *= 2;
-	    if (glyphs != glyphs_local)
-		free (glyphs);
-	    glyphs = glyphs_new;
-	}
-	glyphs[i++] = XftCharIndex (draw->dpy, pub, ucs4);
-	string += l;
-	len -= l;
-    }
-    XftDrawGlyphs (draw, color, pub, x, y, glyphs, i);
-    if (glyphs != glyphs_local)
-	free (glyphs);
-}
-
-_X_EXPORT void
-XftDrawGlyphSpec (XftDraw		*draw,
-		  _Xconst XftColor	*color,
-		  XftFont		*pub,
-		  _Xconst XftGlyphSpec	*glyphs,
-		  int			len)
-{
-    XftFontInt	*font = (XftFontInt *) pub;
-
-    if (font->format)
-    {
-	Picture	src;
-
-	if (_XftDrawRenderPrepare (draw) &&
-	    (src = XftDrawSrcPicture (draw, color)))
-	{
-	    XftGlyphSpecRender (draw->dpy, _XftDrawOp (draw, color),
-				src, pub, draw->render.pict,
-				0, 0, glyphs, len);
-	}
-    }
-    else
-    {
-	if (_XftDrawCorePrepare (draw, color))
-	    XftGlyphSpecCore (draw, color, pub, glyphs, len);
-    }
-}
-
-_X_EXPORT void
-XftDrawGlyphFontSpec (XftDraw			*draw,
-		      _Xconst XftColor		*color,
-		      _Xconst XftGlyphFontSpec	*glyphs,
-		      int			len)
-{
-    int		i;
-    int		start;
-
-    i = 0;
-    while (i < len)
-    {
-	start = i;
-	if (((XftFontInt *) glyphs[i].font)->format)
-	{
-	    Picture	src;
-	    while (i < len && ((XftFontInt *) glyphs[i].font)->format)
-		i++;
-	    if (_XftDrawRenderPrepare (draw) &&
-		(src = XftDrawSrcPicture (draw, color)))
-	    {
-		XftGlyphFontSpecRender (draw->dpy, _XftDrawOp (draw, color),
-					src, draw->render.pict,
-					0, 0, glyphs + start , i - start);
-	    }
-	}
-	else
-	{
-	    while (i < len && !((XftFontInt *) glyphs[i].font)->format)
-		i++;
-	    if (_XftDrawCorePrepare (draw, color))
-		XftGlyphFontSpecCore (draw, color, glyphs + start, i - start);
-	}
-    }
-}
-
-_X_EXPORT void
-XftDrawCharSpec (XftDraw		*draw,
-		 _Xconst XftColor	*color,
-		 XftFont		*pub,
-		 _Xconst XftCharSpec	*chars,
-		 int			len)
-{
-    XftGlyphSpec    *glyphs, glyphs_local[NUM_LOCAL];
-    int		    i;
-
-    if (len <= NUM_LOCAL)
-	glyphs = glyphs_local;
-    else
-    {
-	glyphs = malloc (len * sizeof (XftGlyphSpec));
-	if (!glyphs)
-	    return;
-    }
-    for (i = 0; i < len; i++)
-    {
-	glyphs[i].glyph = XftCharIndex(draw->dpy, pub, chars[i].ucs4);
-	glyphs[i].x = chars[i].x;
-	glyphs[i].y = chars[i].y;
-    }
-
-    XftDrawGlyphSpec (draw, color, pub, glyphs, len);
-    if (glyphs != glyphs_local)
-	free (glyphs);
-}
-
-_X_EXPORT void
-XftDrawCharFontSpec (XftDraw			*draw,
-		     _Xconst XftColor		*color,
-		     _Xconst XftCharFontSpec	*chars,
-		     int			len)
-{
-    XftGlyphFontSpec	*glyphs, glyphs_local[NUM_LOCAL];
-    int			i;
-
-    if (len <= NUM_LOCAL)
-	glyphs = glyphs_local;
-    else
-    {
-	glyphs = malloc (len * sizeof (XftGlyphFontSpec));
-	if (!glyphs)
-	    return;
-    }
-    for (i = 0; i < len; i++)
-    {
-	glyphs[i].font = chars[i].font;
-	glyphs[i].glyph = XftCharIndex(draw->dpy, glyphs[i].font, chars[i].ucs4);
-	glyphs[i].x = chars[i].x;
-	glyphs[i].y = chars[i].y;
-    }
-
-    XftDrawGlyphFontSpec (draw, color, glyphs, len);
-    if (glyphs != glyphs_local)
-	free (glyphs);
-}
-
-_X_EXPORT void
-XftDrawRect (XftDraw		*draw,
-	     _Xconst XftColor	*color,
-	     int		x, 
-	     int		y,
-	     unsigned int	width,
-	     unsigned int	height)
-{
-    if (_XftDrawRenderPrepare (draw))
-    {
-	XRenderFillRectangle (draw->dpy, PictOpSrc, draw->render.pict,
-			      &color->color, x, y, width, height);
-    }
-    else if (_XftDrawCorePrepare (draw, color))
-    {
-	/* note: not XftRectCore() */
-	XSetForeground (draw->dpy, draw->core.gc, color->pixel);
-	XFillRectangle (draw->dpy, draw->drawable, draw->core.gc,
-			x, y, width, height);
-    }
-}
-
-_X_EXPORT Bool
-XftDrawSetClip (XftDraw	*draw,
-		Region	r)
-{
-    Region			n = NULL;
-
-    /*
-     * Check for quick exits
-     */
-    if (!r && draw->clip_type == XftClipTypeNone)
-	return True;
-    
-    if (r && 
-	draw->clip_type == XftClipTypeRegion && 
-	XEqualRegion (r, draw->clip.region))
-    {
-	return True;
-    }
-
-    /*
-     * Duplicate the region so future changes can be short circuited
-     */
-    if (r)
-    {
-	n = XCreateRegion ();
-	if (n)
-	{
-	    if (!XUnionRegion (n, r, n))
-	    {
-		XDestroyRegion (n);
-		return False;
-	    }
-	}
-    }
-
-    /*
-     * Destroy existing clip
-     */
-    switch (draw->clip_type) {
-    case XftClipTypeRegion:
-	XDestroyRegion (draw->clip.region);
-	break;
-    case XftClipTypeRectangles:
-	free (draw->clip.rect);
-	break;
-    case XftClipTypeNone:
-	break;
-    }
-    
-    /*
-     * Set the clip
-     */
-    if (n)
-    {
-	draw->clip_type = XftClipTypeRegion;
-	draw->clip.region = n;
-    }
-    else
-    {
-	draw->clip_type = XftClipTypeNone;
-    }
-    /*
-     * Apply new clip to existing objects
-     */
-    if (draw->render.pict)
-    {
-	if (n)
-	    XRenderSetPictureClipRegion (draw->dpy, draw->render.pict, n);
-	else
-	{
-	    XRenderPictureAttributes	pa;
-	    pa.clip_mask = None;
-	    XRenderChangePicture (draw->dpy, draw->render.pict,
-				  CPClipMask, &pa);
-	}
-    }
-    if (draw->core.gc)
-    {
-	if (n)
-	    XSetRegion (draw->dpy, draw->core.gc, draw->clip.region);
-	else
-	    XSetClipMask (draw->dpy, draw->core.gc, None);
-    }
-    return True;
-}
-
-_X_EXPORT Bool
-XftDrawSetClipRectangles (XftDraw		*draw,
-			  int			xOrigin,
-			  int			yOrigin,
-			  _Xconst XRectangle	*rects,
-			  int			n)
-{
-    XftClipRect	*new = NULL;
-
-    /*
-     * Check for quick exit
-     */
-    if (draw->clip_type == XftClipTypeRectangles &&
-	draw->clip.rect->n == n &&
-	(n == 0 || (draw->clip.rect->xOrigin == xOrigin &&
-		    draw->clip.rect->yOrigin == yOrigin)) &&
-	!memcmp (XftClipRects (draw->clip.rect), rects, n * sizeof (XRectangle)))
-    {
-	return True;
-    }
-
-    /*
-     * Duplicate the region so future changes can be short circuited
-     */
-    new = malloc (sizeof (XftClipRect) + n * sizeof (XRectangle));
-    if (!new)
-	return False;
-
-    new->n = n;
-    new->xOrigin = xOrigin;
-    new->yOrigin = yOrigin;
-    memcpy (XftClipRects (new), rects, n * sizeof (XRectangle));
-
-    /*
-     * Destroy existing clip
-     */
-    switch (draw->clip_type) {
-    case XftClipTypeRegion:
-	XDestroyRegion (draw->clip.region);
-	break;
-    case XftClipTypeRectangles:
-	free (draw->clip.rect);
-	break;
-    case XftClipTypeNone:
-	break;
-    }
-    
-    /*
-     * Set the clip
-     */
-    draw->clip_type = XftClipTypeRectangles;
-    draw->clip.rect = new;
-    /*
-     * Apply new clip to existing objects
-     */
-    if (draw->render.pict)
-    {
-	XRenderSetPictureClipRectangles (draw->dpy, draw->render.pict,
-					 new->xOrigin,
-					 new->yOrigin,
-					 XftClipRects(new),
-					 new->n);
-    }
-    if (draw->core.gc)
-    {
-	XSetClipRectangles (draw->dpy, draw->core.gc,
-			    new->xOrigin,
-			    new->yOrigin,
-			    XftClipRects (new),
-			    new->n,
-			    Unsorted);
-    }
-    return True;
-}
-
-_X_EXPORT void
-XftDrawSetSubwindowMode (XftDraw *draw, int mode)
-{
-    if (mode == draw->subwindow_mode)
-	return;
-    draw->subwindow_mode = mode;
-    if (draw->render.pict)
-    {
-	XRenderPictureAttributes    pa;
-
-	pa.subwindow_mode = mode;
-	XRenderChangePicture (draw->dpy, draw->render.pict, 
-			      CPSubwindowMode, &pa);
-    }
-    if (draw->core.gc)
-	XSetSubwindowMode (draw->dpy, draw->core.gc, mode);
-}
+/*
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "xftint.h"
+
+/*
+ * Ok, this is a pain.  To share source pictures across multiple destinations,
+ * the screen for each drawable must be discovered.
+ */
+
+static int
+_XftDrawScreen (Display *dpy, Drawable drawable, Visual *visual)
+{
+    int		    s;
+    Window	    root;
+    int		    x, y;
+    unsigned int    width, height, borderWidth, depth;
+    /* Special case the most common environment */
+    if (ScreenCount (dpy) == 1)
+	return 0;
+    /*
+     * If we've got a visual, look for the screen that points at it.
+     * This requires no round trip.
+     */
+    if (visual)
+    {
+	for (s = 0; s < ScreenCount (dpy); s++)
+	{
+	    XVisualInfo	template, *ret;
+	    int		nret;
+
+	    template.visualid = visual->visualid;
+	    template.screen = s;
+	    ret = XGetVisualInfo (dpy, VisualIDMask|VisualScreenMask,
+				  &template, &nret);
+	    if (ret)
+	    {
+		XFree (ret);
+		return s;
+	    }
+	}
+    }
+    /*
+     * Otherwise, as the server for the drawable geometry and find
+     * the screen from the root window.
+     * This takes a round trip.
+     */
+    if (XGetGeometry (dpy, drawable, &root, &x, &y, &width, &height,
+		      &borderWidth, &depth))
+    {
+	for (s = 0; s < ScreenCount (dpy); s++)
+	{
+	    if (RootWindow (dpy, s) == root)
+		return s;
+	}
+    }
+    /*
+     * Make a guess -- it's probably wrong, but then the app probably
+     * handed us a bogus drawable in this case
+     */
+    return 0;
+}
+
+_X_HIDDEN unsigned int
+XftDrawDepth (XftDraw *draw)
+{
+    if (!draw->depth)
+    {
+	Window		    root;
+	int		    x, y;
+	unsigned int	    width, height, borderWidth, depth;
+	if (XGetGeometry (draw->dpy, draw->drawable, 
+			  &root, &x, &y, &width, &height,
+			  &borderWidth, &depth))
+	    draw->depth = depth;
+    }
+    return draw->depth;
+}
+
+_X_HIDDEN unsigned int
+XftDrawBitsPerPixel (XftDraw	*draw)
+{
+    if (!draw->bits_per_pixel)
+    {
+	XPixmapFormatValues *formats;
+	int		    nformats;
+	unsigned int	    depth;
+	
+	if ((depth = XftDrawDepth (draw)) &&
+	    (formats = XListPixmapFormats (draw->dpy, &nformats)))
+	{
+	    int	i;
+
+	    for (i = 0; i < nformats; i++)
+	    {
+		if (formats[i].depth == depth)
+		{
+		    draw->bits_per_pixel = formats[i].bits_per_pixel;
+		    break;
+		}
+	    }
+	    XFree (formats);
+	}
+    }
+    return draw->bits_per_pixel;
+}
+
+_X_EXPORT XftDraw *
+XftDrawCreate (Display   *dpy,
+	       Drawable  drawable,
+	       Visual    *visual,
+	       Colormap  colormap)
+{
+    XftDraw	*draw;
+
+    draw = (XftDraw *) malloc (sizeof (XftDraw));
+    if (!draw)
+	return NULL;
+    
+    draw->dpy = dpy;
+    draw->drawable = drawable;
+    draw->screen = _XftDrawScreen (dpy, drawable, visual);
+    draw->depth = 0;		/* don't find out unless we need to know */
+    draw->bits_per_pixel = 0;	/* don't find out unless we need to know */
+    draw->visual = visual;
+    draw->colormap = colormap;
+    draw->render.pict = 0;
+    draw->core.gc = NULL;
+    draw->core.use_pixmap = 0;
+    draw->clip_type = XftClipTypeNone;
+    draw->subwindow_mode = ClipByChildren;
+    XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw));
+    return draw;
+}
+
+_X_EXPORT XftDraw *
+XftDrawCreateBitmap (Display	*dpy,
+		     Pixmap	bitmap)
+{
+    XftDraw	*draw;
+
+    draw = (XftDraw *) malloc (sizeof (XftDraw));
+    if (!draw)
+	return NULL;
+    draw->dpy = dpy;
+    draw->drawable = (Drawable) bitmap;
+    draw->screen = _XftDrawScreen (dpy, bitmap, NULL);
+    draw->depth = 1;
+    draw->bits_per_pixel = 1;
+    draw->visual = NULL;
+    draw->colormap = 0;
+    draw->render.pict = 0;
+    draw->core.gc = NULL;
+    draw->core.use_pixmap = 0;
+    draw->clip_type = XftClipTypeNone;
+    draw->subwindow_mode = ClipByChildren;
+    XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw));
+    return draw;
+}
+
+_X_EXPORT XftDraw *
+XftDrawCreateAlpha (Display *dpy,
+		    Pixmap  pixmap,
+		    int	    depth)
+{
+    XftDraw	*draw;
+
+    draw = (XftDraw *) malloc (sizeof (XftDraw));
+    if (!draw)
+	return NULL;
+    draw->dpy = dpy;
+    draw->drawable = (Drawable) pixmap;
+    draw->screen = _XftDrawScreen (dpy, pixmap, NULL);
+    draw->depth = depth;
+    draw->bits_per_pixel = 0;	/* don't find out until we need it */
+    draw->visual = NULL;
+    draw->colormap = 0;
+    draw->render.pict = 0;
+    draw->core.gc = NULL;
+    draw->core.use_pixmap = 0;
+    draw->clip_type = XftClipTypeNone;
+    draw->subwindow_mode = ClipByChildren;
+    XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw));
+    return draw;
+}
+
+static XRenderPictFormat *
+_XftDrawFormat (XftDraw	*draw)
+{
+    XftDisplayInfo  *info = _XftDisplayInfoGet (draw->dpy, True);
+
+    if (!info || !info->hasRender)
+	return NULL;
+
+    if (draw->visual == NULL)
+    {
+	XRenderPictFormat   pf;
+
+	pf.type = PictTypeDirect;
+	pf.depth = XftDrawDepth (draw);
+	pf.direct.alpha = 0;
+	pf.direct.alphaMask = (1 << pf.depth) - 1;
+	return XRenderFindFormat (draw->dpy,
+				  (PictFormatType|
+				   PictFormatDepth|
+				   PictFormatAlpha|
+				   PictFormatAlphaMask),
+				  &pf,
+				  0);
+    }
+    else
+	return XRenderFindVisualFormat (draw->dpy, draw->visual);
+}
+
+_X_EXPORT void
+XftDrawChange (XftDraw	*draw,
+	       Drawable	drawable)
+{
+    draw->drawable = drawable;
+    if (draw->render.pict)
+    {
+	XRenderFreePicture (draw->dpy, draw->render.pict);
+	draw->render.pict = 0;
+    }
+    if (draw->core.gc)
+    {
+	XFreeGC (draw->dpy, draw->core.gc);
+	draw->core.gc = NULL;
+    }
+}
+
+_X_EXPORT Display *
+XftDrawDisplay (XftDraw *draw)
+{
+    return draw->dpy;
+}
+
+_X_EXPORT Drawable
+XftDrawDrawable (XftDraw *draw)
+{
+    return draw->drawable;
+}
+
+_X_EXPORT Colormap
+XftDrawColormap (XftDraw *draw)
+{
+    return draw->colormap;
+}
+
+_X_EXPORT Visual *
+XftDrawVisual (XftDraw *draw)
+{
+    return draw->visual;
+}
+
+_X_EXPORT void
+XftDrawDestroy (XftDraw	*draw)
+{
+    if (draw->render.pict)
+	XRenderFreePicture (draw->dpy, draw->render.pict);
+    if (draw->core.gc)
+	XFreeGC (draw->dpy, draw->core.gc);
+    switch (draw->clip_type) {
+    case XftClipTypeRegion:
+	XDestroyRegion (draw->clip.region);
+	break;
+    case XftClipTypeRectangles:
+	free (draw->clip.rect);
+	break;
+    case XftClipTypeNone:
+	break;
+    }
+    XftMemFree (XFT_MEM_DRAW, sizeof (XftDraw));
+    free (draw);
+}
+
+_X_EXPORT Picture
+XftDrawSrcPicture (XftDraw *draw, _Xconst XftColor *color)
+{
+    Display	    *dpy = draw->dpy;
+    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, True);
+    int		    i;
+    XftColor	    bitmapColor;
+
+    if (!info || !info->solidFormat)
+	return 0;
+    
+    /*
+     * Monochrome targets require special handling; the PictOp controls
+     * the color, and the color must be opaque
+     */
+    if (!draw->visual && draw->depth == 1)
+    {
+	bitmapColor.color.alpha = 0xffff;
+	bitmapColor.color.red   = 0xffff;
+	bitmapColor.color.green = 0xffff;
+	bitmapColor.color.blue  = 0xffff;
+	color = &bitmapColor;
+    }
+
+    /*
+     * See if there's one already available
+     */
+    for (i = 0; i < XFT_NUM_SOLID_COLOR; i++)
+    {
+	if (info->colors[i].pict && 
+	    info->colors[i].screen == draw->screen &&
+	    !memcmp ((void *) &color->color, 
+		     (void *) &info->colors[i].color,
+		     sizeof (XRenderColor)))
+	    return info->colors[i].pict;
+    }
+    /*
+     * Pick one to replace at random
+     */
+    i = (unsigned int) rand () % XFT_NUM_SOLID_COLOR;
+    /*
+     * Recreate if it was for the wrong screen
+     */
+    if (info->colors[i].screen != draw->screen && info->colors[i].pict)
+    {
+	XRenderFreePicture (dpy, info->colors[i].pict);
+	info->colors[i].pict = 0;
+    }
+    /*
+     * Create picture if necessary
+     */
+    if (!info->colors[i].pict)
+    {
+	Pixmap			    pix;
+        XRenderPictureAttributes    pa;
+	
+	pix = XCreatePixmap (dpy, RootWindow (dpy, draw->screen), 1, 1,
+			     info->solidFormat->depth);
+	pa.repeat = True;
+	info->colors[i].pict = XRenderCreatePicture (draw->dpy,
+						     pix,
+						     info->solidFormat,
+						     CPRepeat, &pa);
+	XFreePixmap (dpy, pix);
+    }
+    /*
+     * Set to the new color
+     */
+    info->colors[i].color = color->color;
+    info->colors[i].screen = draw->screen;
+    XRenderFillRectangle (dpy, PictOpSrc,
+			  info->colors[i].pict,
+			  &color->color, 0, 0, 1, 1);
+    return info->colors[i].pict;
+}
+
+static int
+_XftDrawOp (_Xconst XftDraw *draw, _Xconst XftColor *color)
+{
+    if (draw->visual || draw->depth != 1)
+	return PictOpOver;
+    if (color->color.alpha >= 0x8000)
+	return PictOpOver;
+    return PictOpOutReverse;
+}
+
+static FcBool
+_XftDrawRenderPrepare (XftDraw	*draw)
+{
+    if (!draw->render.pict)
+    {
+	XRenderPictFormat	    *format;
+	XRenderPictureAttributes    pa;
+	unsigned long		    mask = 0;
+
+	format = _XftDrawFormat (draw);
+	if (!format)
+	    return FcFalse;
+	
+	if (draw->subwindow_mode == IncludeInferiors)
+	{
+	    pa.subwindow_mode = IncludeInferiors;
+	    mask |= CPSubwindowMode;
+	}
+	draw->render.pict = XRenderCreatePicture (draw->dpy, draw->drawable,
+						  format, mask, &pa);
+	if (!draw->render.pict)
+	    return FcFalse;
+	switch (draw->clip_type) {
+	case XftClipTypeRegion:
+	    XRenderSetPictureClipRegion (draw->dpy, draw->render.pict,
+					 draw->clip.region);
+	    break;
+	case XftClipTypeRectangles:
+	    XRenderSetPictureClipRectangles (draw->dpy, draw->render.pict,
+					     draw->clip.rect->xOrigin,
+					     draw->clip.rect->yOrigin,
+					     XftClipRects(draw->clip.rect),
+					     draw->clip.rect->n);
+	    break;
+	case XftClipTypeNone:
+	    break;
+	}
+    }
+    return FcTrue;
+}
+
+static FcBool
+_XftDrawCorePrepare (XftDraw *draw, _Xconst XftColor *color)
+{
+    if (!draw->core.gc)
+    {
+	XGCValues	gcv;
+	unsigned long	mask = 0;
+	if (draw->subwindow_mode == IncludeInferiors)
+	{
+	    gcv.subwindow_mode = IncludeInferiors;
+	    mask |= GCSubwindowMode;
+	}
+	draw->core.gc = XCreateGC (draw->dpy, draw->drawable, mask, &gcv);
+	if (!draw->core.gc)
+	    return FcFalse;
+	switch (draw->clip_type) {
+	case XftClipTypeRegion:
+	    XSetRegion (draw->dpy, draw->core.gc, draw->clip.region);
+	    break;
+	case XftClipTypeRectangles:
+	    XSetClipRectangles (draw->dpy, draw->core.gc,
+				draw->clip.rect->xOrigin,
+				draw->clip.rect->yOrigin,
+				XftClipRects (draw->clip.rect),
+				draw->clip.rect->n,
+				Unsorted);
+	    break;
+	case XftClipTypeNone:
+	    break;
+	}
+    }
+    XSetForeground (draw->dpy, draw->core.gc, color->pixel);
+    return FcTrue;
+}
+			
+_X_EXPORT Picture
+XftDrawPicture (XftDraw *draw)
+{
+    if (!_XftDrawRenderPrepare (draw))
+	return 0;
+    return draw->render.pict;
+}
+
+#define NUM_LOCAL   1024
+
+_X_EXPORT void
+XftDrawGlyphs (XftDraw		*draw,
+	       _Xconst XftColor	*color,
+	       XftFont		*pub,
+	       int		x,
+	       int		y,
+	       _Xconst FT_UInt	*glyphs,
+	       int		nglyphs)
+{
+    XftFontInt	*font = (XftFontInt *) pub;
+
+    if (font->format)
+    {
+	Picture	    src;
+	
+	if (_XftDrawRenderPrepare (draw) &&
+	    (src = XftDrawSrcPicture (draw, color)))
+	    XftGlyphRender (draw->dpy, _XftDrawOp (draw, color),
+			     src, pub, draw->render.pict,
+			     0, 0, x, y, glyphs, nglyphs);
+    }
+    else
+    {
+	if (_XftDrawCorePrepare (draw, color))
+	    XftGlyphCore (draw, color, pub, x, y, glyphs, nglyphs);
+    }
+}
+
+_X_EXPORT void
+XftDrawString8 (XftDraw		    *draw,
+		_Xconst XftColor    *color,
+		XftFont		    *pub,
+		int		    x, 
+		int		    y,
+		_Xconst FcChar8	    *string,
+		int		    len)
+{
+    FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
+    int		    i;
+
+    if (XftDebug () & XFT_DBG_DRAW)
+	printf ("DrawString \"%*.*s\"\n", len, len, string);
+    
+    if (len <= NUM_LOCAL)
+	glyphs = glyphs_local;
+    else
+    {
+	glyphs = malloc (len * sizeof (FT_UInt));
+	if (!glyphs)
+	    return;
+    }
+    for (i = 0; i < len; i++)
+	glyphs[i] = XftCharIndex (draw->dpy, pub, string[i]);
+    XftDrawGlyphs (draw, color, pub, x, y, glyphs, len);
+    if (glyphs != glyphs_local)
+	free (glyphs);
+}
+
+_X_EXPORT void
+XftDrawString16 (XftDraw	    *draw,
+		 _Xconst XftColor   *color,
+		 XftFont	    *pub,
+		 int		    x,
+		 int		    y,
+		 _Xconst FcChar16   *string,
+		 int		    len)
+{
+    FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
+    int		    i;
+
+    if (len <= NUM_LOCAL)
+	glyphs = glyphs_local;
+    else
+    {
+	glyphs = malloc (len * sizeof (FT_UInt));
+	if (!glyphs)
+	    return;
+    }
+    for (i = 0; i < len; i++)
+	glyphs[i] = XftCharIndex (draw->dpy, pub, string[i]);
+    
+    XftDrawGlyphs (draw, color, pub, x, y, glyphs, len);
+    if (glyphs != glyphs_local)
+	free (glyphs);
+}
+
+_X_EXPORT void
+XftDrawString32 (XftDraw	    *draw,
+		 _Xconst XftColor   *color,
+		 XftFont	    *pub,
+		 int		    x,
+		 int		    y,
+		 _Xconst FcChar32   *string,
+		 int		    len)
+{
+    FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
+    int		    i;
+
+    if (len <= NUM_LOCAL)
+	glyphs = glyphs_local;
+    else
+    {
+	glyphs = malloc (len * sizeof (FT_UInt));
+	if (!glyphs)
+	    return;
+    }
+    for (i = 0; i < len; i++)
+	glyphs[i] = XftCharIndex (draw->dpy, pub, string[i]);
+    
+    XftDrawGlyphs (draw, color, pub, x, y, glyphs, len);
+    if (glyphs != glyphs_local)
+	free (glyphs);
+}
+
+_X_EXPORT void
+XftDrawStringUtf8 (XftDraw	    *draw,
+		   _Xconst XftColor *color,
+		   XftFont	    *pub,
+		   int		    x, 
+		   int		    y,
+		   _Xconst FcChar8  *string,
+		   int		    len)
+{
+    FT_UInt	    *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL];
+    FcChar32	    ucs4;
+    int		    i;
+    int		    l;
+    int		    size;
+
+    i = 0;
+    glyphs = glyphs_local;
+    size = NUM_LOCAL;
+    while (len && (l = FcUtf8ToUcs4 (string, &ucs4, len)) > 0)
+    {
+	if (i == size)
+	{
+	    glyphs_new = malloc (size * 2 * sizeof (FT_UInt));
+	    if (!glyphs_new)
+	    {
+		if (glyphs != glyphs_local)
+		    free (glyphs);
+		return;
+	    }
+	    memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt));
+	    size *= 2;
+	    if (glyphs != glyphs_local)
+		free (glyphs);
+	    glyphs = glyphs_new;
+	}
+	glyphs[i++] = XftCharIndex (draw->dpy, pub, ucs4);
+	string += l;
+	len -= l;
+    }
+    XftDrawGlyphs (draw, color, pub, x, y, glyphs, i);
+    if (glyphs != glyphs_local)
+	free (glyphs);
+}
+
+_X_EXPORT void
+XftDrawStringUtf16 (XftDraw		*draw,
+		    _Xconst XftColor	*color,
+		    XftFont		*pub,
+		    int			x,
+		    int			y,
+		    _Xconst FcChar8	*string,
+		    FcEndian		endian,
+		    int			len)
+{
+    FT_UInt	    *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL];
+    FcChar32	    ucs4;
+    int		    i;
+    int		    l;
+    int		    size;
+
+    i = 0;
+    glyphs = glyphs_local;
+    size = NUM_LOCAL;
+    while (len && (l = FcUtf16ToUcs4 (string, endian, &ucs4, len)) > 0)
+    {
+	if (i == size)
+	{
+	    glyphs_new = malloc (size * 2 * sizeof (FT_UInt));
+	    if (!glyphs_new)
+	    {
+		if (glyphs != glyphs_local)
+		    free (glyphs);
+		return;
+	    }
+	    memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt));
+	    size *= 2;
+	    if (glyphs != glyphs_local)
+		free (glyphs);
+	    glyphs = glyphs_new;
+	}
+	glyphs[i++] = XftCharIndex (draw->dpy, pub, ucs4);
+	string += l;
+	len -= l;
+    }
+    XftDrawGlyphs (draw, color, pub, x, y, glyphs, i);
+    if (glyphs != glyphs_local)
+	free (glyphs);
+}
+
+_X_EXPORT void
+XftDrawGlyphSpec (XftDraw		*draw,
+		  _Xconst XftColor	*color,
+		  XftFont		*pub,
+		  _Xconst XftGlyphSpec	*glyphs,
+		  int			len)
+{
+    XftFontInt	*font = (XftFontInt *) pub;
+
+    if (font->format)
+    {
+	Picture	src;
+
+	if (_XftDrawRenderPrepare (draw) &&
+	    (src = XftDrawSrcPicture (draw, color)))
+	{
+	    XftGlyphSpecRender (draw->dpy, _XftDrawOp (draw, color),
+				src, pub, draw->render.pict,
+				0, 0, glyphs, len);
+	}
+    }
+    else
+    {
+	if (_XftDrawCorePrepare (draw, color))
+	    XftGlyphSpecCore (draw, color, pub, glyphs, len);
+    }
+}
+
+_X_EXPORT void
+XftDrawGlyphFontSpec (XftDraw			*draw,
+		      _Xconst XftColor		*color,
+		      _Xconst XftGlyphFontSpec	*glyphs,
+		      int			len)
+{
+    int		i;
+    int		start;
+
+    i = 0;
+    while (i < len)
+    {
+	start = i;
+	if (((XftFontInt *) glyphs[i].font)->format)
+	{
+	    Picture	src;
+	    while (i < len && ((XftFontInt *) glyphs[i].font)->format)
+		i++;
+	    if (_XftDrawRenderPrepare (draw) &&
+		(src = XftDrawSrcPicture (draw, color)))
+	    {
+		XftGlyphFontSpecRender (draw->dpy, _XftDrawOp (draw, color),
+					src, draw->render.pict,
+					0, 0, glyphs + start , i - start);
+	    }
+	}
+	else
+	{
+	    while (i < len && !((XftFontInt *) glyphs[i].font)->format)
+		i++;
+	    if (_XftDrawCorePrepare (draw, color))
+		XftGlyphFontSpecCore (draw, color, glyphs + start, i - start);
+	}
+    }
+}
+
+_X_EXPORT void
+XftDrawCharSpec (XftDraw		*draw,
+		 _Xconst XftColor	*color,
+		 XftFont		*pub,
+		 _Xconst XftCharSpec	*chars,
+		 int			len)
+{
+    XftGlyphSpec    *glyphs, glyphs_local[NUM_LOCAL];
+    int		    i;
+
+    if (len <= NUM_LOCAL)
+	glyphs = glyphs_local;
+    else
+    {
+	glyphs = malloc (len * sizeof (XftGlyphSpec));
+	if (!glyphs)
+	    return;
+    }
+    for (i = 0; i < len; i++)
+    {
+	glyphs[i].glyph = XftCharIndex(draw->dpy, pub, chars[i].ucs4);
+	glyphs[i].x = chars[i].x;
+	glyphs[i].y = chars[i].y;
+    }
+
+    XftDrawGlyphSpec (draw, color, pub, glyphs, len);
+    if (glyphs != glyphs_local)
+	free (glyphs);
+}
+
+_X_EXPORT void
+XftDrawCharFontSpec (XftDraw			*draw,
+		     _Xconst XftColor		*color,
+		     _Xconst XftCharFontSpec	*chars,
+		     int			len)
+{
+    XftGlyphFontSpec	*glyphs, glyphs_local[NUM_LOCAL];
+    int			i;
+
+    if (len <= NUM_LOCAL)
+	glyphs = glyphs_local;
+    else
+    {
+	glyphs = malloc (len * sizeof (XftGlyphFontSpec));
+	if (!glyphs)
+	    return;
+    }
+    for (i = 0; i < len; i++)
+    {
+	glyphs[i].font = chars[i].font;
+	glyphs[i].glyph = XftCharIndex(draw->dpy, glyphs[i].font, chars[i].ucs4);
+	glyphs[i].x = chars[i].x;
+	glyphs[i].y = chars[i].y;
+    }
+
+    XftDrawGlyphFontSpec (draw, color, glyphs, len);
+    if (glyphs != glyphs_local)
+	free (glyphs);
+}
+
+_X_EXPORT void
+XftDrawRect (XftDraw		*draw,
+	     _Xconst XftColor	*color,
+	     int		x, 
+	     int		y,
+	     unsigned int	width,
+	     unsigned int	height)
+{
+    if (_XftDrawRenderPrepare (draw))
+    {
+	XRenderFillRectangle (draw->dpy, PictOpSrc, draw->render.pict,
+			      &color->color, x, y, width, height);
+    }
+    else if (_XftDrawCorePrepare (draw, color))
+    {
+	/* note: not XftRectCore() */
+	XSetForeground (draw->dpy, draw->core.gc, color->pixel);
+	XFillRectangle (draw->dpy, draw->drawable, draw->core.gc,
+			x, y, width, height);
+    }
+}
+
+_X_EXPORT Bool
+XftDrawSetClip (XftDraw	*draw,
+		Region	r)
+{
+    Region			n = NULL;
+
+    /*
+     * Check for quick exits
+     */
+    if (!r && draw->clip_type == XftClipTypeNone)
+	return True;
+    
+    if (r && 
+	draw->clip_type == XftClipTypeRegion && 
+	XEqualRegion (r, draw->clip.region))
+    {
+	return True;
+    }
+
+    /*
+     * Duplicate the region so future changes can be short circuited
+     */
+    if (r)
+    {
+	n = XCreateRegion ();
+	if (n)
+	{
+	    if (!XUnionRegion (n, r, n))
+	    {
+		XDestroyRegion (n);
+		return False;
+	    }
+	}
+    }
+
+    /*
+     * Destroy existing clip
+     */
+    switch (draw->clip_type) {
+    case XftClipTypeRegion:
+	XDestroyRegion (draw->clip.region);
+	break;
+    case XftClipTypeRectangles:
+	free (draw->clip.rect);
+	break;
+    case XftClipTypeNone:
+	break;
+    }
+    
+    /*
+     * Set the clip
+     */
+    if (n)
+    {
+	draw->clip_type = XftClipTypeRegion;
+	draw->clip.region = n;
+    }
+    else
+    {
+	draw->clip_type = XftClipTypeNone;
+    }
+    /*
+     * Apply new clip to existing objects
+     */
+    if (draw->render.pict)
+    {
+	if (n)
+	    XRenderSetPictureClipRegion (draw->dpy, draw->render.pict, n);
+	else
+	{
+	    XRenderPictureAttributes	pa;
+	    pa.clip_mask = None;
+	    XRenderChangePicture (draw->dpy, draw->render.pict,
+				  CPClipMask, &pa);
+	}
+    }
+    if (draw->core.gc)
+    {
+	if (n)
+	    XSetRegion (draw->dpy, draw->core.gc, draw->clip.region);
+	else
+	    XSetClipMask (draw->dpy, draw->core.gc, None);
+    }
+    return True;
+}
+
+_X_EXPORT Bool
+XftDrawSetClipRectangles (XftDraw		*draw,
+			  int			xOrigin,
+			  int			yOrigin,
+			  _Xconst XRectangle	*rects,
+			  int			n)
+{
+    XftClipRect	*new = NULL;
+
+    /*
+     * Check for quick exit
+     */
+    if (draw->clip_type == XftClipTypeRectangles &&
+	draw->clip.rect->n == n &&
+	(n == 0 || (draw->clip.rect->xOrigin == xOrigin &&
+		    draw->clip.rect->yOrigin == yOrigin)) &&
+	!memcmp (XftClipRects (draw->clip.rect), rects, n * sizeof (XRectangle)))
+    {
+	return True;
+    }
+
+    /*
+     * Duplicate the region so future changes can be short circuited
+     */
+    new = malloc (sizeof (XftClipRect) + n * sizeof (XRectangle));
+    if (!new)
+	return False;
+
+    new->n = n;
+    new->xOrigin = xOrigin;
+    new->yOrigin = yOrigin;
+    memcpy (XftClipRects (new), rects, n * sizeof (XRectangle));
+
+    /*
+     * Destroy existing clip
+     */
+    switch (draw->clip_type) {
+    case XftClipTypeRegion:
+	XDestroyRegion (draw->clip.region);
+	break;
+    case XftClipTypeRectangles:
+	free (draw->clip.rect);
+	break;
+    case XftClipTypeNone:
+	break;
+    }
+    
+    /*
+     * Set the clip
+     */
+    draw->clip_type = XftClipTypeRectangles;
+    draw->clip.rect = new;
+    /*
+     * Apply new clip to existing objects
+     */
+    if (draw->render.pict)
+    {
+	XRenderSetPictureClipRectangles (draw->dpy, draw->render.pict,
+					 new->xOrigin,
+					 new->yOrigin,
+					 XftClipRects(new),
+					 new->n);
+    }
+    if (draw->core.gc)
+    {
+	XSetClipRectangles (draw->dpy, draw->core.gc,
+			    new->xOrigin,
+			    new->yOrigin,
+			    XftClipRects (new),
+			    new->n,
+			    Unsorted);
+    }
+    return True;
+}
+
+_X_EXPORT void
+XftDrawSetSubwindowMode (XftDraw *draw, int mode)
+{
+    if (mode == draw->subwindow_mode)
+	return;
+    draw->subwindow_mode = mode;
+    if (draw->render.pict)
+    {
+	XRenderPictureAttributes    pa;
+
+	pa.subwindow_mode = mode;
+	XRenderChangePicture (draw->dpy, draw->render.pict, 
+			      CPSubwindowMode, &pa);
+    }
+    if (draw->core.gc)
+	XSetSubwindowMode (draw->dpy, draw->core.gc, mode);
+}
-- 
cgit v1.2.3