[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#641197: marked as done (libxft2: Include Ubuntu LCD filter patch)



Your message dated Sat, 16 Jun 2012 21:17:08 +0000
with message-id <E1Sg0Mm-0005Y9-LB@franck.debian.org>
and subject line Bug#641197: fixed in xft 2.3.1-1
has caused the Debian Bug report #641197,
regarding libxft2: Include Ubuntu LCD filter patch
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
641197: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=641197
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: libxft2
Version: 2.2.0-3
Severity: wishlist

Dear Maintainer,

xft does not utilise the lcdfilter option.  An example is when using
Openbox and GTK2 based apps with the following configuration in
~/fonts.conf.

 <match target="font">
   <edit mode="assign" name="lcdfilter">
   <const>lcddefault</const>
   </edit>
 </match>

The result is that the fonts rendered by Openbox look slightly different to those rendered by GTK2.

I researched and found that Ubuntu had added a patch in the following version that utilises lcdfilter:

http://archive.ubuntu.com/ubuntu/pool/main/x/xft/xft_2.1.14-2ubuntu1.diff.gz

I tested the patch on 2.2.0-3 and it has worked well and my Window Manager fonts now look the same as GTK2.
Attached is the patch (100-libXft-2.1.10-lcd-filter-3.patch)

-- System Information:
Debian Release: wheezy/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 3.0.0-1-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_AU.utf8, LC_CTYPE=en_AU.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libxft2 depends on:
ii  libc6              2.13-20  
ii  libfontconfig1     2.8.0-3  
ii  libfreetype6       2.4.6-2  
ii  libx11-6           2:1.4.4-1
ii  libxrender1        1:0.9.6-2
ii  multiarch-support  2.13-20  

libxft2 recommends no packages.

libxft2 suggests no packages.

-- no debconf information
--- a/src/xftdpy.c
+++ b/src/xftdpy.c
@@ -369,6 +369,10 @@
 	goto bail1;
     if (!_XftDefaultInitInteger (dpy, pat, FC_RGBA))
 	goto bail1;
+#ifdef FC_LCD_FILTER
+    if (!_XftDefaultInitInteger (dpy, pat, FC_LCD_FILTER))
+	goto bail1;
+#endif
     if (!_XftDefaultInitBool (dpy, pat, FC_ANTIALIAS))
 	goto bail1;
 #ifdef FC_EMBOLDEN
@@ -521,6 +525,14 @@
 			      XftDefaultGetInteger (dpy, FC_RGBA, screen, 
 						    subpixel));
     }
+#ifdef FC_LCD_FILTER
+    if (FcPatternGet (pattern, FC_LCD_FILTER, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddInteger (pattern, FC_LCD_FILTER,
+			     XftDefaultGetInteger (dpy, FC_LCD_FILTER, screen,
+						   FC_LCD_DEFAULT));
+    }
+#endif
     if (FcPatternGet (pattern, FC_MINSPACE, 0, &v) == FcResultNoMatch)
     {
 	FcPatternAddBool (pattern, FC_MINSPACE,
--- a/src/xftfreetype.c
+++ b/src/xftfreetype.c
@@ -469,6 +469,21 @@
 	goto bail1;
     }
     
+#ifdef FC_LCD_FILTER 
+    /*
+     * 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;
+    }
+#endif
+    
     /*
      * Get matrix and transform values
      */
--- a/src/xftglyphs.c
+++ b/src/xftglyphs.c
@@ -21,27 +21,18 @@
  */
 
 #include "xftint.h"
-#include <freetype/ftoutln.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 },
+#if FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH < 20202
+#  error  "FreeType 2.2.2 or later required to compile this version of libXft"
 #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 },
-};
+
+#include FT_OUTLINE_H
+#include FT_LCD_FILTER_H
+#include FT_SYNTHESIS_H
 
 /*
  * Validate the memory info for a font
@@ -69,6 +60,295 @@
 		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,
@@ -87,20 +367,14 @@
     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		    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 +384,19 @@
     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,7 +417,10 @@
 	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 +453,7 @@
 	/*
 	 * 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 +532,14 @@
 	    }
 	}
 
-	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 +579,13 @@
 	    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);
+        // compute the size of the final bitmap
+        ftbit  = &glyphslot->bitmap;
 
-	    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;
+        pitch  = (width+3) & ~3;
 	
 	if (XftDebug() & XFT_DBG_GLYPH)
 	{
@@ -423,29 +602,72 @@
 		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 char    den[] = { " .:;=+*#" };
-			for (x = 0; x < pitch; x++)
+                        static const char    den[] = { " .:;=+*#" };
+                        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'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);
+
+        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,121 +677,23 @@
 	 */
 	glyph = (Glyph) glyphindex;
 
-	if (subpixel)
-	{
-	    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++)
-	    {
-		in = in_line;
-		out = (unsigned int *) out_line;
-		in_line += pitch * vmul;
-		out_line += pitchrgba;
-		for (x = 0; x < width * hmul; x += hmul)
-		{
-		    red = green = blue = 0;
-		    o = 0;
-		    for (s = 0; s < 3; s++)
-		    {
-			red += filters[rf][s]*in[x+o];
-			green += filters[gf][s]*in[x+o];
-			blue += filters[bf][s]*in[x+o];
-			o += os;
-		    }
-		    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)
+	xftg->glyph_memory = size + sizeof (XftGlyph);
+ 	    if (font->format)
 	    {
 		if (!font->glyphset)
 		    font->glyphset = XRenderCreateGlyphSet (dpy, font->format);
-		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;
-	    }
-	}
-	else
-	{
-	    xftg->glyph_memory = size + sizeof (XftGlyph);
-	    if (font->format)
-	    {
-		/*
-		 * swap bit order around; FreeType is always MSBFirst
-		 */
-		if (!font->info.antialias)
+	    if ( mode == FT_RENDER_MODE_MONO )
 		{
+		  /* swap bits in each byte */
 		    if (BitmapBitOrder (dpy) != MSBFirst)
 		    {
-			unsigned char   *line;
-			unsigned char   c;
-			int		    i;
+		      unsigned char   *line = (unsigned char*)bufBitmap;
+		      int             i = size;
 
-			line = (unsigned char *) bufBitmap;
-			i = size;
 			while (i--)
 			{
-			    c = *line;
+			  int  c = *line;
+
 			    c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
 			    c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
 			    c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
@@ -577,8 +701,12 @@
 			}
 		    }
 		}
-		if (!font->glyphset)
-		    font->glyphset = XRenderCreateGlyphSet (dpy, font->format);
+            else if ( mode != FT_RENDER_MODE_NORMAL )
+            {
+                /* invert ARGB <=> BGRA */
+                if (ImageByteOrder (dpy) != XftNativeByteOrder ())
+                    XftSwapCARD32 ((CARD32 *) bufBitmap, size >> 2);
+            }
 		XRenderAddGlyphs (dpy, font->glyphset, &glyph,
 				  &xftg->metrics, 1, 
 				  (char *) bufBitmap, size);
@@ -594,7 +722,7 @@
 		else
 		    xftg->bitmap = NULL;
 	    }
-	}
+
 	font->glyph_memory += xftg->glyph_memory;
 	info->glyph_memory += xftg->glyph_memory;
 	if (XftDebug() & XFT_DBG_CACHE)
@@ -605,8 +733,6 @@
     }
     if (bufBitmap != bufLocal)
 	free (bufBitmap);
-    if (bufBitmapRgba != bufLocalRgba)
-	free (bufBitmapRgba);
     XftUnlockFace (&font->public);
 }
 
--- a/src/xftint.h
+++ b/src/xftint.h
@@ -145,6 +145,7 @@
     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 */

--- End Message ---
--- Begin Message ---
Source: xft
Source-Version: 2.3.1-1

We believe that the bug you reported is fixed in the latest version of
xft, which is due to be installed in the Debian FTP archive:

libxft-dev_2.3.1-1_amd64.deb
  to main/x/xft/libxft-dev_2.3.1-1_amd64.deb
libxft2-dbg_2.3.1-1_amd64.deb
  to main/x/xft/libxft2-dbg_2.3.1-1_amd64.deb
libxft2-udeb_2.3.1-1_amd64.udeb
  to main/x/xft/libxft2-udeb_2.3.1-1_amd64.udeb
libxft2_2.3.1-1_amd64.deb
  to main/x/xft/libxft2_2.3.1-1_amd64.deb
xft_2.3.1-1.diff.gz
  to main/x/xft/xft_2.3.1-1.diff.gz
xft_2.3.1-1.dsc
  to main/x/xft/xft_2.3.1-1.dsc
xft_2.3.1.orig.tar.gz
  to main/x/xft/xft_2.3.1.orig.tar.gz



A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to 641197@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Cyril Brulebois <kibi@debian.org> (supplier of updated xft package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmaster@debian.org)


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Format: 1.8
Date: Sat, 16 Jun 2012 22:04:44 +0200
Source: xft
Binary: libxft2 libxft2-udeb libxft2-dbg libxft-dev
Architecture: source amd64
Version: 2.3.1-1
Distribution: unstable
Urgency: low
Maintainer: Debian X Strike Force <debian-x@lists.debian.org>
Changed-By: Cyril Brulebois <kibi@debian.org>
Description: 
 libxft-dev - FreeType-based font drawing library for X (development files)
 libxft2    - FreeType-based font drawing library for X
 libxft2-dbg - FreeType-based font drawing library for X (unstripped)
 libxft2-udeb - FreeType-based font drawing library for X (udeb)
Closes: 641197
Changes: 
 xft (2.3.1-1) unstable; urgency=low
 .
   * New upstream release:
     - Subpixel LCD text rendering improvements (Closes: #641197).
Checksums-Sha1: 
 e3072bc5d007ca936599d63e51ab19824435dd3c 1451 xft_2.3.1-1.dsc
 5232f135bf110b2ab9d833499b664228622bd832 391992 xft_2.3.1.orig.tar.gz
 364bcd785b29057a50823334abf6728dd7d7bf1d 20930 xft_2.3.1-1.diff.gz
 68fe72661eab0c340d92e825f87d206df02beac6 60994 libxft2_2.3.1-1_amd64.deb
 442c5ebc0fdda378b3dacec9d494c06d31985bc3 33766 libxft2-udeb_2.3.1-1_amd64.udeb
 e7dedd61be2736564c036b150659bafce58b5bc6 200186 libxft2-dbg_2.3.1-1_amd64.deb
 0106f08b92cb528fcc7de4af6911d634e4f8457d 74458 libxft-dev_2.3.1-1_amd64.deb
Checksums-Sha256: 
 60d6b1279d8492e98e5cf0282209898871fa9f5ba2a9f4c9243f8cdaf51bdab6 1451 xft_2.3.1-1.dsc
 df3765d1454bb148fc0886f0723dc9f40430243a06e94414475c6af2a72e8915 391992 xft_2.3.1.orig.tar.gz
 d8b26c364338a1a77290e4c91c0a9410a5982f0dc6fe070ba84158ac0c3942c0 20930 xft_2.3.1-1.diff.gz
 dbb5d280b6df228a2589a905e7e8d12a8821e0031f472f951c279de9ac78c91e 60994 libxft2_2.3.1-1_amd64.deb
 c45c6bcc6d8aff9e65a3a82171847b39a6219d44e708e8e259b9ecb060ebe266 33766 libxft2-udeb_2.3.1-1_amd64.udeb
 d691bf4918831246fbec9d0c3701f02b1ce112e8a07a4591f57c7080759d1d02 200186 libxft2-dbg_2.3.1-1_amd64.deb
 894e2851a910b622dba0296d328c8f3d0850aaaae74fcabecc7a0b6f391195d4 74458 libxft-dev_2.3.1-1_amd64.deb
Files: 
 d2609feb47e9dc3e9c36ab48119239ba 1451 devel optional xft_2.3.1-1.dsc
 946a157090eec5c3041cf17530d93f59 391992 devel optional xft_2.3.1.orig.tar.gz
 b7044127ec01c2de70ca5fd733a850bf 20930 devel optional xft_2.3.1-1.diff.gz
 a7b83166a1c813e582ea71c7f60cafd0 60994 libs optional libxft2_2.3.1-1_amd64.deb
 e56f166c6df4a158cabf67415c2200b9 33766 debian-installer optional libxft2-udeb_2.3.1-1_amd64.udeb
 043b5e01d8f88a45dd6c887b712c7492 200186 debug extra libxft2-dbg_2.3.1-1_amd64.deb
 505b0aeffa923bea0367187475835b63 74458 libdevel optional libxft-dev_2.3.1-1_amd64.deb
Package-Type: udeb

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iEYEARECAAYFAk/c6O0ACgkQeGfVPHR5Nd1mKwCeOht3KTab2T2B71gMejFa9cST
rY8An1c1Nip5VNLYr22f2mieQhrVRy6N
=cvyS
-----END PGP SIGNATURE-----



--- End Message ---

Reply to: