From 9f986778bd4393c5a9108426969d45aa7f10f334 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Wed, 19 Oct 2011 10:44:43 +0200
Subject: libX11 libXext libXft mesa libxcb mkfontscale pixman xserver
 xkeyboard-config git update 19 oct 2011

---
 libXft/src/xftdpy.c      |  16 +-
 libXft/src/xftfreetype.c |  43 +---
 libXft/src/xftglyphs.c   | 657 +++++++++++++++++++++++++++--------------------
 libXft/src/xftint.h      |   1 +
 4 files changed, 407 insertions(+), 310 deletions(-)

(limited to 'libXft/src')

diff --git a/libXft/src/xftdpy.c b/libXft/src/xftdpy.c
index 8f453b30d..c5b756e25 100644
--- a/libXft/src/xftdpy.c
+++ b/libXft/src/xftdpy.c
@@ -369,18 +369,16 @@ _XftDefaultInit (Display *dpy)
 	goto bail1;
     if (!_XftDefaultInitInteger (dpy, pat, FC_RGBA))
 	goto bail1;
+    if (!_XftDefaultInitInteger (dpy, pat, FC_LCD_FILTER))
+	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))
@@ -471,28 +469,24 @@ XftDefaultSubstitute (Display *dpy, int screen, FcPattern *pattern)
 			   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,
@@ -521,6 +515,12 @@ XftDefaultSubstitute (Display *dpy, int screen, FcPattern *pattern)
 			      XftDefaultGetInteger (dpy, FC_RGBA, screen,
 						    subpixel));
     }
+    if (FcPatternGet (pattern, FC_LCD_FILTER, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddInteger (pattern, FC_LCD_FILTER,
+			     XftDefaultGetInteger (dpy, FC_LCD_FILTER, screen,
+						   FC_LCD_DEFAULT));
+    }
     if (FcPatternGet (pattern, FC_MINSPACE, 0, &v) == FcResultNoMatch)
     {
 	FcPatternAddBool (pattern, FC_MINSPACE,
diff --git a/libXft/src/xftfreetype.c b/libXft/src/xftfreetype.c
index 3f8dfef8c..a3b833299 100644
--- a/libXft/src/xftfreetype.c
+++ b/libXft/src/xftfreetype.c
@@ -176,13 +176,8 @@ _XftUnlockFile (XftFtFile *f)
 	_XftLockError ("too many file unlocks");
 }
 
-#if HAVE_FT_BITMAP_SIZE_Y_PPEM
 #define X_SIZE(face,i) ((face)->available_sizes[i].x_ppem)
 #define Y_SIZE(face,i) ((face)->available_sizes[i].y_ppem)
-#else
-#define X_SIZE(face,i) ((face)->available_sizes[i].width << 6)
-#define Y_SIZE(face,i) ((face)->available_sizes[i].height << 6)
-#endif
 
 _X_HIDDEN FcBool
 _XftSetFace (XftFtFile *f, FT_F26Dot6 xsize, FT_F26Dot6 ysize, FT_Matrix *matrix)
@@ -224,12 +219,9 @@ _XftSetFace (XftFtFile *f, FT_F26Dot6 xsize, FT_F26Dot6 ysize, FT_Matrix *matrix
 	     * files have but a single strike per file, we can
 	     * simply try both sizes.
 	     */
-	    if (
-#if HAVE_FT_BITMAP_SIZE_Y_PPEM
-		FT_Set_Char_Size (face, face->available_sizes[best].x_ppem,
+	    if (FT_Set_Char_Size (face, face->available_sizes[best].x_ppem,
 				  face->available_sizes[best].y_ppem, 0, 0) != 0
 		&&
-#endif
 		FT_Set_Char_Size (face, face->available_sizes[best].width << 6,
 				  face->available_sizes[best].height << 6,
 				  0, 0) != 0)
@@ -379,9 +371,7 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
     double	    aspect;
     FcMatrix	    *font_matrix;
     FcBool	    hinting, vertical_layout, autohint, global_advance;
-#ifdef FC_HINT_STYLE
     int             hint_style;
-#endif
     FcChar32	    hash, *hashp;
     FT_Face	    face;
     int		    nhash;
@@ -469,6 +459,19 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
 	goto bail1;
     }
 
+    /*
+     * Get lcd_filter value
+     */
+    switch (FcPatternGetInteger (pattern, FC_LCD_FILTER, 0, &fi->lcd_filter)) {
+    case FcResultNoMatch:
+	fi->lcd_filter = FC_LCD_DEFAULT;
+	break;
+    case FcResultMatch:
+	break;
+    default:
+	goto bail1;
+    }
+
     /*
      * Get matrix and transform values
      */
@@ -542,7 +545,6 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
 	goto bail1;
     }
 
-#ifdef FC_EMBOLDEN
     switch (FcPatternGetBool (pattern, FC_EMBOLDEN, 0, &fi->embolden)) {
     case FcResultNoMatch:
 	fi->embolden = FcFalse;
@@ -552,11 +554,7 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
     default:
 	goto bail1;
     }
-#else
-    fi->embolden = FcFalse;
-#endif
 
-#ifdef FC_HINT_STYLE
     switch (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style)) {
     case FcResultNoMatch:
 	hint_style = FC_HINT_FULL;
@@ -566,12 +564,9 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
     default:
 	goto bail1;
     }
-#endif
 
     if (!hinting
-#ifdef FC_HINT_STYLE
 	|| hint_style == FC_HINT_NONE
-#endif
 	)
     {
 	fi->load_flags |= FT_LOAD_NO_HINTING;
@@ -582,15 +577,11 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
      */
     if (fi->antialias)
     {
-#ifdef FC_HINT_STYLE
-#ifdef FT_LOAD_TARGET_LIGHT
 	if (FC_HINT_NONE < hint_style && hint_style < FC_HINT_FULL)
 	{
 	    fi->load_flags |= FT_LOAD_TARGET_LIGHT;
 	}
 	else
-#endif
-#endif
 	{
 	    /* autohinter will snap stems to integer widths, when
 	     * the LCD targets are used.
@@ -598,23 +589,17 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
 	    switch (fi->rgba) {
 	    case FC_RGBA_RGB:
 	    case FC_RGBA_BGR:
-#ifdef FT_LOAD_TARGET_LCD
 		fi->load_flags |= FT_LOAD_TARGET_LCD;
-#endif
 		break;
 	    case FC_RGBA_VRGB:
 	    case FC_RGBA_VBGR:
-#ifdef FT_LOAD_TARGET_LCD_V
 		fi->load_flags |= FT_LOAD_TARGET_LCD_V;
-#endif
 		break;
 	    }
 	}
     }
-#ifdef FT_LOAD_TARGET_MONO
     else
 	fi->load_flags |= FT_LOAD_TARGET_MONO;
-#endif
 
     /* set vertical layout if requested */
     switch (FcPatternGetBool (pattern, FC_VERTICAL_LAYOUT, 0, &vertical_layout)) {
diff --git a/libXft/src/xftglyphs.c b/libXft/src/xftglyphs.c
index e0cfdea8a..2639d12aa 100644
--- a/libXft/src/xftglyphs.c
+++ b/libXft/src/xftglyphs.c
@@ -22,27 +22,12 @@
 
 #include "xftint.h"
 #include <freetype/ftoutln.h>
+#include <freetype/ftlcdfil.h>
 
 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
 #include <freetype/ftsynth.h>
 #endif
 
-static const int    filters[3][3] = {
-    /* red */
-#if 0
-{    65538*4/7,65538*2/7,65538*1/7 },
-    /* green */
-{    65536*1/4, 65536*2/4, 65537*1/4 },
-    /* blue */
-{    65538*1/7,65538*2/7,65538*4/7 },
-#endif
-{    65538*9/13,65538*3/13,65538*1/13 },
-    /* green */
-{    65538*1/6, 65538*4/6, 65538*1/6 },
-    /* blue */
-{    65538*1/13,65538*3/13,65538*9/13 },
-};
-
 /*
  * Validate the memory info for a font
  */
@@ -69,6 +54,293 @@ _XftFontValidateMemory (Display *dpy, XftFont *public)
 		font->glyph_memory, glyph_memory);
 }
 
+/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot
+ * into a different format. For example, we want to convert a
+ * FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit
+ * ARGB or ABGR bitmap.
+ *
+ * this function prepares a target descriptor for this operation.
+ *
+ * input :: target bitmap descriptor. The function will set its
+ *          'width', 'rows' and 'pitch' fields, and only these
+ *
+ * slot  :: the glyph slot containing the source bitmap. this
+ *          function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP
+ *
+ * mode  :: the requested final rendering mode. supported values are
+ *          MONO, NORMAL (i.e. gray), LCD and LCD_V
+ *
+ * the function returns the size in bytes of the corresponding buffer,
+ * it's up to the caller to allocate the corresponding memory block
+ * before calling _fill_xrender_bitmap
+ *
+ * it also returns -1 in case of error (e.g. incompatible arguments,
+ * like trying to convert a gray bitmap into a monochrome one)
+ */
+static int
+_compute_xrender_bitmap_size( FT_Bitmap*	target,
+			      FT_GlyphSlot	slot,
+			      FT_Render_Mode	mode )
+{
+    FT_Bitmap*	ftbit;
+    int		width, height, pitch;
+
+    if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
+	return -1;
+
+    // compute the size of the final bitmap
+    ftbit = &slot->bitmap;
+
+    width = ftbit->width;
+    height = ftbit->rows;
+    pitch = (width+3) & ~3;
+
+    switch ( ftbit->pixel_mode )
+    {
+    case FT_PIXEL_MODE_MONO:
+	if ( mode == FT_RENDER_MODE_MONO )
+	{
+	    pitch = (((width+31) & ~31) >> 3);
+	    break;
+	}
+	/* fall-through */
+
+    case FT_PIXEL_MODE_GRAY:
+	if ( mode == FT_RENDER_MODE_LCD ||
+	     mode == FT_RENDER_MODE_LCD_V )
+	{
+	    /* each pixel is replicated into a 32-bit ARGB value */
+	    pitch = width*4;
+	}
+	break;
+
+    case FT_PIXEL_MODE_LCD:
+	if ( mode != FT_RENDER_MODE_LCD )
+	    return -1;
+
+	/* horz pixel triplets are packed into 32-bit ARGB values */
+	width /= 3;
+	pitch = width*4;
+	break;
+
+    case FT_PIXEL_MODE_LCD_V:
+	if ( mode != FT_RENDER_MODE_LCD_V )
+	    return -1;
+
+	/* vert pixel triplets are packed into 32-bit ARGB values */
+	height /= 3;
+	pitch = width*4;
+	break;
+
+    default:  /* unsupported source format */
+	return -1;
+    }
+
+    target->width = width;
+    target->rows = height;
+    target->pitch = pitch;
+    target->buffer = NULL;
+
+    return pitch * height;
+}
+
+/* this functions converts the glyph bitmap found in a FT_GlyphSlot
+ * into a different format (see _compute_xrender_bitmap_size)
+ *
+ * you should call this function after _compute_xrender_bitmap_size
+ *
+ * target :: target bitmap descriptor. Note that its 'buffer' pointer
+ *           must point to memory allocated by the caller
+ *
+ * slot   :: the glyph slot containing the source bitmap
+ *
+ * mode   :: the requested final rendering mode
+ *
+ * bgr    :: boolean, set if BGR or VBGR pixel ordering is needed
+ */
+static void
+_fill_xrender_bitmap( FT_Bitmap*	target,
+		      FT_GlyphSlot	slot,
+		      FT_Render_Mode	mode,
+		      int		bgr )
+{
+    FT_Bitmap*   ftbit = &slot->bitmap;
+
+    {
+	unsigned char*	srcLine	= ftbit->buffer;
+        unsigned char*	dstLine	= target->buffer;
+        int		src_pitch = ftbit->pitch;
+        int		width = target->width;
+        int		height = target->rows;
+        int		pitch = target->pitch;
+        int		subpixel;
+        int		h;
+
+        subpixel = ( mode == FT_RENDER_MODE_LCD ||
+		     mode == FT_RENDER_MODE_LCD_V );
+
+	if ( src_pitch < 0 )
+	    srcLine -= src_pitch*(ftbit->rows-1);
+
+	switch ( ftbit->pixel_mode )
+	{
+	case FT_PIXEL_MODE_MONO:
+	    if ( subpixel )  /* convert mono to ARGB32 values */
+	    {
+		for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+		{
+		    int x;
+
+		    for ( x = 0; x < width; x++ )
+		    {
+			if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
+			    ((unsigned int*)dstLine)[x] = 0xffffffffU;
+		    }
+		}
+	    }
+	    else if ( mode == FT_RENDER_MODE_NORMAL )  /* convert mono to 8-bit gray */
+	    {
+		for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+		{
+		    int x;
+
+		    for ( x = 0; x < width; x++ )
+		    {
+			if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
+			    dstLine[x] = 0xff;
+		    }
+		}
+	    }
+	    else  /* copy mono to mono */
+	    {
+		int bytes = (width+7) >> 3;
+
+		for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+		    memcpy( dstLine, srcLine, bytes );
+	    }
+	    break;
+
+	case FT_PIXEL_MODE_GRAY:
+	    if ( subpixel )  /* convert gray to ARGB32 values */
+	    {
+		for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+		{
+		    int		   x;
+		    unsigned int*  dst = (unsigned int*)dstLine;
+
+		    for ( x = 0; x < width; x++ )
+		    {
+			unsigned int pix = srcLine[x];
+
+			pix |= (pix << 8);
+			pix |= (pix << 16);
+
+			dst[x] = pix;
+		    }
+		}
+	    }
+	    else  /* copy gray into gray */
+	    {
+		for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+		    memcpy( dstLine, srcLine, width );
+	    }
+	    break;
+
+	case FT_PIXEL_MODE_LCD:
+	    if ( !bgr )
+	    {
+		/* convert horizontal RGB into ARGB32 */
+		for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+		{
+		    int		   x;
+		    unsigned char* src = srcLine;
+		    unsigned int*  dst = (unsigned int*)dstLine;
+
+		    for ( x = 0; x < width; x++, src += 3 )
+		    {
+			unsigned int pix;
+
+			pix = ((unsigned int)src[0] << 16) |
+			      ((unsigned int)src[1] <<  8) |
+			      ((unsigned int)src[2]      ) |
+			      ((unsigned int)src[1] << 24) ;
+
+			dst[x] = pix;
+		    }
+		}
+	    }
+	    else
+	    {
+		/* convert horizontal BGR into ARGB32 */
+		for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+		{
+		    int		   x;
+		    unsigned char* src = srcLine;
+		    unsigned int*  dst = (unsigned int*)dstLine;
+
+		    for ( x = 0; x < width; x++, src += 3 )
+		    {
+			unsigned int pix;
+
+			pix = ((unsigned int)src[2] << 16) |
+			      ((unsigned int)src[1] <<  8) |
+			      ((unsigned int)src[0]      ) |
+			      ((unsigned int)src[1] << 24) ;
+
+			dst[x] = pix;
+		    }
+		}
+	    }
+	    break;
+
+	default:  /* FT_PIXEL_MODE_LCD_V */
+	    /* convert vertical RGB into ARGB32 */
+	    if ( !bgr )
+	    {
+		for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
+		{
+		    int		   x;
+		    unsigned char* src = srcLine;
+		    unsigned int*  dst = (unsigned int*)dstLine;
+
+		    for ( x = 0; x < width; x++, src += 1 )
+		    {
+			unsigned int  pix;
+
+			pix = ((unsigned int)src[0]           << 16) |
+			      ((unsigned int)src[src_pitch]   <<  8) |
+			      ((unsigned int)src[src_pitch*2]      ) |
+			      ((unsigned int)src[src_pitch]   << 24) ;
+
+			dst[x] = pix;
+		    }
+		}
+	    }
+	    else
+	    {
+	    for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
+		{
+		    int		   x;
+		    unsigned char* src = srcLine;
+		    unsigned int*  dst = (unsigned int*)dstLine;
+
+		    for ( x = 0; x < width; x++, src += 1 )
+		    {
+			unsigned int  pix;
+
+			pix = ((unsigned int)src[src_pitch*2] << 16) |
+			      ((unsigned int)src[src_pitch]   <<  8) |
+			      ((unsigned int)src[0]                ) |
+			      ((unsigned int)src[src_pitch]   << 24) ;
+
+			dst[x] = pix;
+		    }
+		}
+	    }
+	}
+    }
+}
+
 _X_EXPORT void
 XftFontLoadGlyphs (Display	    *dpy,
 		   XftFont	    *pub,
@@ -86,21 +358,15 @@ XftFontLoadGlyphs (Display	    *dpy,
     unsigned char   bufLocal[4096];
     unsigned char   *bufBitmap = bufLocal;
     int		    bufSize = sizeof (bufLocal);
-    int		    size, pitch;
-    unsigned char   bufLocalRgba[4096];
-    unsigned char   *bufBitmapRgba = bufLocalRgba;
-    int		    bufSizeRgba = sizeof (bufLocalRgba);
-    int		    sizergba, pitchrgba, widthrgba;
+    int		    size;
     int		    width;
     int		    height;
     int		    left, right, top, bottom;
-    int		    hmul = 1;
-    int		    vmul = 1;
-    FT_Bitmap	    ftbit;
-    FT_Matrix	    matrix;
+    FT_Bitmap*	    ftbit;
+    FT_Bitmap	    local;
     FT_Vector	    vector;
-    Bool	    subpixel = False;
     FT_Face	    face;
+    FT_Render_Mode  mode = FT_RENDER_MODE_MONO;
 
     if (!info)
 	return;
@@ -110,24 +376,19 @@ XftFontLoadGlyphs (Display	    *dpy,
     if (!face)
 	return;
 
-    matrix.xx = matrix.yy = 0x10000L;
-    matrix.xy = matrix.yx = 0;
-
     if (font->info.antialias)
     {
 	switch (font->info.rgba) {
 	case FC_RGBA_RGB:
 	case FC_RGBA_BGR:
-	    matrix.xx *= 3;
-	    subpixel = True;
-	    hmul = 3;
+	    mode = FT_RENDER_MODE_LCD;
 	    break;
 	case FC_RGBA_VRGB:
 	case FC_RGBA_VBGR:
-	    matrix.yy *= 3;
-	    vmul = 3;
-	    subpixel = True;
+	    mode = FT_RENDER_MODE_LCD_V;
 	    break;
+	default:
+	    mode = FT_RENDER_MODE_NORMAL;
 	}
     }
 
@@ -148,6 +409,8 @@ XftFontLoadGlyphs (Display	    *dpy,
 	if (xftg->glyph_memory)
 	    continue;
 
+	FT_Library_SetLcdFilter( _XftFTlibrary, font->info.lcd_filter);
+
 	error = FT_Load_Glyph (face, glyphindex, font->info.load_flags);
 	if (error)
 	{
@@ -181,7 +444,7 @@ XftFontLoadGlyphs (Display	    *dpy,
 	/*
 	 * Compute glyph metrics from FreeType information
 	 */
-	if(font->info.transform && glyphslot->format != ft_glyph_format_bitmap)
+	if(font->info.transform && glyphslot->format != FT_GLYPH_FORMAT_BITMAP)
 	{
 	    /*
 	     * calculate the true width by transforming all four corners.
@@ -260,17 +523,14 @@ XftFontLoadGlyphs (Display	    *dpy,
 	    }
 	}
 
-	if (font->info.antialias)
-	    pitch = (width * hmul + 3) & ~3;
-	else
-	    pitch = ((width + 31) & ~31) >> 3;
-
-	size = pitch * height * vmul;
+	if ( glyphslot->format != FT_GLYPH_FORMAT_BITMAP )
+	{
+	    error = FT_Render_Glyph( face->glyph, mode );
+	    if (error)
+		continue;
+	}
 
-	xftg->metrics.width = width;
-	xftg->metrics.height = height;
-	xftg->metrics.x = -TRUNC(left);
-	xftg->metrics.y = TRUNC(top);
+	FT_Library_SetLcdFilter( _XftFTlibrary, FT_LCD_FILTER_NONE );
 
 	if (font->info.spacing >= FC_MONO)
 	{
@@ -310,103 +570,8 @@ XftFontLoadGlyphs (Display	    *dpy,
 	    xftg->metrics.yOff = -TRUNC(ROUND(glyphslot->advance.y));
 	}
 
-	/*
-	 * If the glyph is relatively large (> 1% of server memory),
-	 * don't send it until necessary
-	 */
-	if (!need_bitmaps && size > info->max_glyph_memory / 100)
-	    continue;
-
-	/*
-	 * Make sure there's enough buffer space for the glyph
-	 */
-	if (size > bufSize)
-	{
-	    if (bufBitmap != bufLocal)
-		free (bufBitmap);
-	    bufBitmap = (unsigned char *) malloc (size);
-	    if (!bufBitmap)
-		continue;
-	    bufSize = size;
-	}
-	memset (bufBitmap, 0, size);
-
-	/*
-	 * Rasterize into the local buffer
-	 */
-	switch (glyphslot->format) {
-	case ft_glyph_format_outline:
-	    ftbit.width      = width * hmul;
-	    ftbit.rows       = height * vmul;
-	    ftbit.pitch      = pitch;
-	    if (font->info.antialias)
-		ftbit.pixel_mode = ft_pixel_mode_grays;
-	    else
-		ftbit.pixel_mode = ft_pixel_mode_mono;
-
-	    ftbit.buffer     = bufBitmap;
-
-	    if (subpixel)
-		FT_Outline_Transform (&glyphslot->outline, &matrix);
-
-	    FT_Outline_Translate ( &glyphslot->outline, -left*hmul, -bottom*vmul );
-
-	    FT_Outline_Get_Bitmap( _XftFTlibrary, &glyphslot->outline, &ftbit );
-	    break;
-	case ft_glyph_format_bitmap:
-	    if (font->info.antialias)
-	    {
-		unsigned char	*srcLine, *dstLine;
-		int		height;
-		int		x;
-		int	    h, v;
-
-		srcLine = glyphslot->bitmap.buffer;
-		dstLine = bufBitmap;
-		height = glyphslot->bitmap.rows;
-		while (height--)
-		{
-		    for (x = 0; x < glyphslot->bitmap.width; x++)
-		    {
-			/* always MSB bitmaps */
-			unsigned char	a = ((srcLine[x >> 3] & (0x80 >> (x & 7))) ?
-					     0xff : 0x00);
-			if (subpixel)
-			{
-			    for (v = 0; v < vmul; v++)
-				for (h = 0; h < hmul; h++)
-				    dstLine[v * pitch + x*hmul + h] = a;
-			}
-			else
-			    dstLine[x] = a;
-		    }
-		    dstLine += pitch * vmul;
-		    srcLine += glyphslot->bitmap.pitch;
-		}
-	    }
-	    else
-	    {
-		unsigned char	*srcLine, *dstLine;
-		int		h, bytes;
-
-		srcLine = glyphslot->bitmap.buffer;
-		dstLine = bufBitmap;
-		h = glyphslot->bitmap.rows;
-		bytes = (glyphslot->bitmap.width + 7) >> 3;
-		while (h--)
-		{
-		    memcpy (dstLine, srcLine, bytes);
-		    dstLine += pitch;
-		    srcLine += glyphslot->bitmap.pitch;
-		}
-	    }
-	    break;
-	default:
-	    if (XftDebug() & XFT_DBG_GLYPH)
-		printf ("glyph %d is not in a usable format\n",
-			(int) glyphindex);
-	    continue;
-	}
+	width = ftbit->width;
+	height = ftbit->rows;
 
 	if (XftDebug() & XFT_DBG_GLYPH)
 	{
@@ -423,29 +588,72 @@ XftFontLoadGlyphs (Display	    *dpy,
 		int		x, y;
 		unsigned char	*line;
 
-		line = bufBitmap;
-		for (y = 0; y < height * vmul; y++)
+		line = ftbit->buffer;
+		if (ftbit->pitch < 0)
+		    line -= ftbit->pitch*(height-1);
+
+		for (y = 0; y < height; y++)
 		{
 		    if (font->info.antialias)
 		    {
 			static const char    den[] = { " .:;=+*#" };
-			for (x = 0; x < pitch; x++)
+			for (x = 0; x < width; x++)
 			    printf ("%c", den[line[x] >> 5]);
 		    }
 		    else
 		    {
-			for (x = 0; x < pitch * 8; x++)
+			for (x = 0; x < width * 8; x++)
 			{
 			    printf ("%c", line[x>>3] & (1 << (x & 7)) ? '#' : ' ');
 			}
 		    }
 		    printf ("|\n");
-		    line += pitch;
+		    line += ftbit->pitch;
 		}
 		printf ("\n");
 	    }
 	}
 
+	size = _compute_xrender_bitmap_size( &local, glyphslot, mode );
+	if ( size < 0 )
+	    continue;
+
+	xftg->metrics.width  = local.width;
+	xftg->metrics.height = local.rows;
+	xftg->metrics.x      = - glyphslot->bitmap_left;
+	xftg->metrics.y      =   glyphslot->bitmap_top;
+
+	/*
+	 * If the glyph is relatively large (> 1% of server memory),
+	 * don't send it until necessary.
+	 */
+	if (!need_bitmaps && size > info->max_glyph_memory / 100)
+	    continue;
+
+	/*
+	 * Make sure there is enough buffer space for the glyph.
+	 */
+	if (size > bufSize)
+	{
+	    if (bufBitmap != bufLocal)
+		free (bufBitmap);
+	    bufBitmap = (unsigned char *) malloc (size);
+	    if (!bufBitmap)
+		continue;
+	    bufSize = size;
+	}
+	memset (bufBitmap, 0, size);
+
+	local.buffer = bufBitmap;
+
+	_fill_xrender_bitmap( &local, glyphslot, mode,
+			      (font->info.rgba == FC_RGBA_BGR ||
+			       font->info.rgba == FC_RGBA_VBGR ) );
+
+	/*
+	 * Copy or convert into local buffer.
+	 */
+
 	/*
 	 * Use the glyph index as the wire encoding; it
 	 * might be more efficient for some locales to map
@@ -455,146 +663,51 @@ XftFontLoadGlyphs (Display	    *dpy,
 	 */
 	glyph = (Glyph) glyphindex;
 
-	if (subpixel)
+	xftg->glyph_memory = size + sizeof (XftGlyph);
+	if (font->format)
 	{
-	    int		    x, y;
-	    unsigned char   *in_line, *out_line, *in;
-	    unsigned int    *out;
-	    unsigned int    red, green, blue;
-	    int		    rf, gf, bf;
-	    int		    s;
-	    int		    o, os;
-
-	    /*
-	     * Filter the glyph to soften the color fringes
-	     */
-	    widthrgba = width;
-	    pitchrgba = (widthrgba * 4 + 3) & ~3;
-	    sizergba = pitchrgba * height;
-
-	    os = 1;
-	    switch (font->info.rgba) {
-	    case FC_RGBA_VRGB:
-		os = pitch;
-	    case FC_RGBA_RGB:
-	    default:
-		rf = 0;
-		gf = 1;
-		bf = 2;
-		break;
-	    case FC_RGBA_VBGR:
-		os = pitch;
-	    case FC_RGBA_BGR:
-		bf = 0;
-		gf = 1;
-		rf = 2;
-		break;
-	    }
-	    if (sizergba > bufSizeRgba)
-	    {
-		if (bufBitmapRgba != bufLocalRgba)
-		    free (bufBitmapRgba);
-		bufBitmapRgba = (unsigned char *) malloc (sizergba);
-		if (!bufBitmapRgba)
-		    continue;
-		bufSizeRgba = sizergba;
-	    }
-	    memset (bufBitmapRgba, 0, sizergba);
-	    in_line = bufBitmap;
-	    out_line = bufBitmapRgba;
-	    for (y = 0; y < height; y++)
+	    if (!font->glyphset)
+		font->glyphset = XRenderCreateGlyphSet (dpy, font->format);
+	    if ( mode == FT_RENDER_MODE_MONO )
 	    {
-		in = in_line;
-		out = (unsigned int *) out_line;
-		in_line += pitch * vmul;
-		out_line += pitchrgba;
-		for (x = 0; x < width * hmul; x += hmul)
+		/* swap bits in each byte */
+		if (BitmapBitOrder (dpy) != MSBFirst)
 		{
-		    red = green = blue = 0;
-		    o = 0;
-		    for (s = 0; s < 3; s++)
+		    unsigned char   *line = (unsigned char*)bufBitmap;
+		    int		    i = size;
+
+		    while (i--)
 		    {
-			red += filters[rf][s]*in[x+o];
-			green += filters[gf][s]*in[x+o];
-			blue += filters[bf][s]*in[x+o];
-			o += os;
+			int c = *line;
+			c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
+			c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
+			c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
+			*line++ = c;
 		    }
-		    red = red / 65536;
-		    green = green / 65536;
-		    blue = blue / 65536;
-		    *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
 		}
 	    }
-
-	    xftg->glyph_memory = sizergba + sizeof (XftGlyph);
-	    if (font->format)
+	    else if ( mode != FT_RENDER_MODE_NORMAL )
 	    {
-		if (!font->glyphset)
-		    font->glyphset = XRenderCreateGlyphSet (dpy, font->format);
+		/* invert ARGB <=> BGRA */
 		if (ImageByteOrder (dpy) != XftNativeByteOrder ())
-		    XftSwapCARD32 ((CARD32 *) bufBitmapRgba, sizergba >> 2);
-		XRenderAddGlyphs (dpy, font->glyphset, &glyph,
-				  &xftg->metrics, 1,
-				  (char *) bufBitmapRgba, sizergba);
-	    }
-	    else
-	    {
-		if (sizergba)
-		{
-		    xftg->bitmap = malloc (sizergba);
-		    if (xftg->bitmap)
-			memcpy (xftg->bitmap, bufBitmapRgba, sizergba);
-		}
-		else
-		    xftg->bitmap = NULL;
+		    XftSwapCARD32 ((CARD32 *) bufBitmap, size >> 2);
 	    }
+	    XRenderAddGlyphs (dpy, font->glyphset, &glyph,
+			      &xftg->metrics, 1,
+			      (char *) bufBitmap, size);
 	}
 	else
 	{
-	    xftg->glyph_memory = size + sizeof (XftGlyph);
-	    if (font->format)
+	    if (size)
 	    {
-		/*
-		 * swap bit order around; FreeType is always MSBFirst
-		 */
-		if (!font->info.antialias)
-		{
-		    if (BitmapBitOrder (dpy) != MSBFirst)
-		    {
-			unsigned char   *line;
-			unsigned char   c;
-			int		    i;
-
-			line = (unsigned char *) bufBitmap;
-			i = size;
-			while (i--)
-			{
-			    c = *line;
-			    c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
-			    c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
-			    c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
-			    *line++ = c;
-			}
-		    }
-		}
-		if (!font->glyphset)
-		    font->glyphset = XRenderCreateGlyphSet (dpy, font->format);
-		XRenderAddGlyphs (dpy, font->glyphset, &glyph,
-				  &xftg->metrics, 1,
-				  (char *) bufBitmap, size);
+		xftg->bitmap = malloc (size);
+		if (xftg->bitmap)
+		    memcpy (xftg->bitmap, bufBitmap, size);
 	    }
 	    else
-	    {
-		if (size)
-		{
-		    xftg->bitmap = malloc (size);
-		    if (xftg->bitmap)
-			memcpy (xftg->bitmap, bufBitmap, size);
-		}
-		else
-		    xftg->bitmap = NULL;
-	    }
+		xftg->bitmap = NULL;
 	}
+
 	font->glyph_memory += xftg->glyph_memory;
 	info->glyph_memory += xftg->glyph_memory;
 	if (XftDebug() & XFT_DBG_CACHE)
@@ -605,8 +718,6 @@ XftFontLoadGlyphs (Display	    *dpy,
     }
     if (bufBitmap != bufLocal)
 	free (bufBitmap);
-    if (bufBitmapRgba != bufLocalRgba)
-	free (bufBitmapRgba);
     XftUnlockFace (&font->public);
 }
 
diff --git a/libXft/src/xftint.h b/libXft/src/xftint.h
index eb9257ea7..5cb57aeab 100644
--- a/libXft/src/xftint.h
+++ b/libXft/src/xftint.h
@@ -145,6 +145,7 @@ struct _XftFontInfo {
     FcBool		antialias;	/* doing antialiasing */
     FcBool		embolden;	/* force emboldening */
     int			rgba;		/* subpixel order */
+    int			lcd_filter;	/* lcd filter */
     FT_Matrix		matrix;		/* glyph transformation matrix */
     FcBool		transform;	/* non-identify matrix? */
     FT_Int		load_flags;	/* glyph load flags */
-- 
cgit v1.2.3