--- 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 #include -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 */