--- xftdpy.c.orig	2004-03-10 17:07:29.000000000 -0500
+++ xftdpy.c	2004-05-07 23:14:12.000000000 -0400
@@ -387,6 +387,8 @@
 	goto bail1;
     if (!_XftDefaultInitInteger (dpy, pat, XFT_MAX_GLYPH_MEMORY))
 	goto bail1;
+    if (!_XftDefaultInitInteger (dpy, pat, XFT_FILTER_TYPE))
+	goto bail1;
     
     return pat;
     
@@ -536,6 +538,11 @@
 						   screen,
 						   XFT_FONT_MAX_GLYPH_MEMORY));
     }
+    if (FcPatternGet (pattern, XFT_FILTER_TYPE, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddInteger (pattern, XFT_FILTER_TYPE,
+			     XftDefaultGetInteger (dpy, XFT_FILTER_TYPE, screen, 0));
+    }
     FcDefaultSubstitute (pattern);
 }
 
--- xftfreetype.c.orig	2004-03-19 13:54:08.000000000 -0500
+++ xftfreetype.c	2004-05-07 23:13:46.000000000 -0400
@@ -671,6 +671,19 @@
     }
 
     /*
+     * Which filter to use for subpixel rendering
+     */
+    switch (FcPatternGetInteger (pattern, XFT_FILTER_TYPE, 0, &fi->filter_type)) {
+    case FcResultNoMatch:
+	fi->filter_type = 0;
+	break;
+    case FcResultMatch:
+	break;
+    default:
+	goto bail1;
+    }
+
+    /*
      * Step over hash value in the structure
      */
     hash = 0;
--- xftglyphs.c.orig	2003-04-30 20:13:17.000000000 -0400
+++ xftglyphs.c	2004-05-09 14:38:12.051940804 -0400
@@ -29,20 +29,23 @@
 #include <freetype/ftoutln.h>
 #include <fontconfig/fcfreetype.h>
 
-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 },
+int filter_inter[][3] = {
+    { 65536*1/3,  0,          0         },
+    { 65538*1/3,  65536*1/3,  0         },
+    { 65536*1/3,  65538*1/3,  65536*1/3 },
+    { 0,          65536*1/3,  65538*1/3 },
+    { 0,          0,          65536*1/3 },
+};
+
+int filter_intra[][3] = {
+    { 65538*9/13, 65538*1/6,  65538*1/13 },
+    { 65538*3/13, 65538*4/6,  65538*3/13 },
+    { 65538*1/13, 65538*1/6,  65538*9/13 },
+};
+
+int (*filters[][2])[3] = {
+    { filter_inter, filter_inter + sizeof(filter_inter)/sizeof(filter_inter[0]) },
+    { filter_intra, filter_intra + sizeof(filter_intra)/sizeof(filter_intra[0]) },
 };
 
 /*
@@ -103,6 +106,7 @@
     FT_Vector	    vector;
     Bool	    subpixel = False;
     FT_Face	    face;
+    int 	    (*filter_begin)[3], (*filter_end)[3], filter_extra;
 
     if (!info)
 	return;
@@ -133,6 +137,16 @@
 	}
     }
 
+    if (subpixel)
+    {
+	int i = font->info.filter_type;
+	if (i < 0 || i >= sizeof(filters)/sizeof(filters[0]))
+	    i = 0;
+	filter_begin = filters[i][0];
+	filter_end = filters[i][1];
+	filter_extra = (filter_end - filter_begin - 3)/2;
+    }
+
     while (nglyph--)
     {
 	glyphindex = *glyphs++;
@@ -203,19 +217,34 @@
 
 		}
 	    }
-	    left = FLOOR(left);
-	    right = CEIL(right);
-	    bottom = FLOOR(bottom);
-	    top = CEIL(top);
-
 	} else {
-	    left  = FLOOR( glyphslot->metrics.horiBearingX );
-	    right = CEIL( glyphslot->metrics.horiBearingX + glyphslot->metrics.width );
+	    left  = glyphslot->metrics.horiBearingX;
+	    right = glyphslot->metrics.horiBearingX + glyphslot->metrics.width;
 
-	    top    = CEIL( glyphslot->metrics.horiBearingY );
-	    bottom = FLOOR( glyphslot->metrics.horiBearingY - glyphslot->metrics.height );
+	    top    = glyphslot->metrics.horiBearingY;
+	    bottom = glyphslot->metrics.horiBearingY - glyphslot->metrics.height;
+	}
+
+	if (subpixel) {
+	    switch (font->info.rgba) {
+	    case FC_RGBA_RGB:
+	    case FC_RGBA_BGR:
+	    default:
+		left -= (filter_extra << 6)/3;
+		right += (filter_extra << 6)/3;
+		break;
+	    case FC_RGBA_VRGB:
+	    case FC_RGBA_VBGR:
+		bottom -= (filter_extra << 6)/3;
+		top += (filter_extra << 6)/3;
+		break;
+	    }
 	}
 
+	left = FLOOR(left);
+	right = CEIL(right);
+	bottom = FLOOR(bottom);
+	top = CEIL(top);
 	width = TRUNC(right - left);
 	height = TRUNC( top - bottom );
 
@@ -457,8 +486,9 @@
 	    unsigned int    *out;
 	    unsigned int    red, green, blue;
 	    int		    rf, gf, bf;
-	    int		    s;
+	    int		    (*s)[3];
 	    int		    o, os;
+	    int 	    lim_min, lim_max;
 	    
 	    /*
 	     * Filter the glyph to soften the color fringes
@@ -499,6 +529,19 @@
 	    out_line = bufBitmapRgba;
 	    for (y = 0; y < height; y++)
 	    {
+		switch (font->info.rgba) {
+		case FC_RGBA_RGB:
+		case FC_RGBA_BGR:
+		default:
+		    lim_min = 0;
+		    lim_max = width * hmul;
+		    break;
+		case FC_RGBA_VRGB:
+		case FC_RGBA_VBGR:
+		    lim_min = bufBitmap - in_line;
+		    lim_max = bufBitmap + height * pitch * vmul - in_line;
+		    break;
+		}
 		in = in_line;
 		out = (unsigned int *) out_line;
 		in_line += pitch * vmul;
@@ -506,12 +549,15 @@
 		for (x = 0; x < width * hmul; x += hmul)
 		{
 		    red = green = blue = 0;
-		    o = 0;
-		    for (s = 0; s < 3; s++)
+		    o = -filter_extra*os;
+		    for (s = filter_begin; s < filter_end; s++)
 		    {
-			red += filters[rf][s]*in[x+o];
-			green += filters[gf][s]*in[x+o];
-			blue += filters[bf][s]*in[x+o];
+			if (x+o >= lim_min && x+o < lim_max)
+			{
+			    red += (*s)[rf]*in[x+o];
+			    green += (*s)[gf]*in[x+o];
+			    blue += (*s)[bf]*in[x+o];
+			}
 			o += os;
 		    }
 		    red = red / 65536;
--- Xft.h.orig	2004-03-22 10:02:59.000000000 -0500
+++ Xft.h	2004-05-07 22:36:36.000000000 -0400
@@ -55,6 +55,7 @@
 #define XFT_XLFD		"xlfd"
 #define XFT_MAX_GLYPH_MEMORY	"maxglyphmemory"
 #define XFT_MAX_UNREF_FONTS	"maxunreffonts"
+#define XFT_FILTER_TYPE		"filtertype"
 
 extern FT_Library	_XftFTlibrary;
 
--- xftint.h.orig	2004-03-10 17:07:29.000000000 -0500
+++ xftint.h	2004-05-07 22:58:14.000000000 -0400
@@ -114,6 +114,7 @@
     FcBool		transform;	/* non-identify matrix? */
     FT_Int		load_flags;	/* glyph load flags */
     FcBool		render;		/* whether to use the Render extension */
+    int 		filter_type;    /* which subpixel filter */
     /*
      * Internal fields
      */
