.gear/rules | 2 + .../tags/198726ae8bf2c95dfd4cc0b9c5aae9b07e5998b0 | 13 + .gear/tags/list | 1 + libXft.spec | 115 ++++ src/xftdpy.c | 12 + src/xftfreetype.c | 15 + src/xftglyphs.c | 641 ++++++++++++-------- src/xftint.h | 1 + 8 files changed, 544 insertions(+), 256 deletions(-) diff --git a/.gear/rules b/.gear/rules new file mode 100644 index 0000000..f78a96e --- /dev/null +++ b/.gear/rules @@ -0,0 +1,2 @@ +tar: @name@-@version@:. +diff: @name@-@version@:. . diff --git a/.gear/tags/198726ae8bf2c95dfd4cc0b9c5aae9b07e5998b0 b/.gear/tags/198726ae8bf2c95dfd4cc0b9c5aae9b07e5998b0 new file mode 100644 index 0000000..019e542 --- /dev/null +++ b/.gear/tags/198726ae8bf2c95dfd4cc0b9c5aae9b07e5998b0 @@ -0,0 +1,13 @@ +object 1a34928cd823ef1452b973bd7c4c1d12cd976bba +type commit +tag libXft-2.1.13 +tagger Adam Jackson 1215027826 -0400 + +libXft 2.1.13 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.9 (GNU/Linux) + +iEYEABECAAYFAkhr2nIACgkQW4otUKDs0NPGVACfYg/cEv9urZOEQIC94MUeljQ8 +Ev0AoOXK65nM9wFhVlm8Kbcy4Jm9y8yr +=BpXu +-----END PGP SIGNATURE----- diff --git a/.gear/tags/list b/.gear/tags/list new file mode 100644 index 0000000..ffe125a --- /dev/null +++ b/.gear/tags/list @@ -0,0 +1 @@ +198726ae8bf2c95dfd4cc0b9c5aae9b07e5998b0 libXft-2.1.13 diff --git a/libXft.spec b/libXft.spec new file mode 100644 index 0000000..27771f1 --- /dev/null +++ b/libXft.spec @@ -0,0 +1,115 @@ +Name: libXft +Version: 2.1.13 +Release: alt1 + +Summary: X FreeType Library +License: MIT/X11 +Group: System/Libraries +Url: http://xorg.freedesktop.org +Packager: Valery Inozemtsev + +Source: %name-%version.tar +Patch: %name-%version-%release.patch + +BuildRequires: fontconfig-devel libfreetype-devel libX11-devel libXau-devel libXdmcp-devel +BuildRequires: libXrender-devel xorg-proto-devel zlib-devel xorg-util-macros + +%description +X FreeType Library + +%package devel +Summary: X FreeType Library and Header Files +Group: Development/C +PreReq: xorg-proto-devel +Requires: %name = %version-%release fontconfig-devel libfreetype-devel libX11-devel libXau-devel +Requires: libXdmcp-devel libXrender-devel zlib-devel +Conflicts: XFree86-devel < 4.4 xorg-x11-devel <= 6.9.0 + +%description devel +%name-devel contains the libraries and header files needed to +develop programs which make use of %name. + +%prep +%setup -q +%patch -p1 + +%build +%autoreconf +%configure \ + --disable-static +%make_build + +%install +%make DESTDIR=%buildroot install + +%post -p %post_ldconfig + +%postun -p %postun_ldconfig + +%files +%_libdir/*.so.* + +%files devel +%_bindir/* +%_includedir/X11/Xft +%_libdir/*.so +%_pkgconfigdir/*.pc +%_man1dir/* +%_man3dir/* + +%changelog +* Thu Jul 03 2008 Valery Inozemtsev 2.1.13-alt1 +- 2.1.13 + +* Mon May 05 2008 Valery Inozemtsev 2.1.12-alt5 +- update lcd filter patch from ubuntu + +* Wed Apr 16 2008 Valery Inozemtsev 2.1.12-alt4 +- reapply subpixel rendering patch + +* Sat Feb 02 2008 Valery Inozemtsev 2.1.12-alt3 +- drop subpixel rendering patch + +* Wed Oct 30 2007 Valery Inozemtsev 2.1.12-alt2 +- merged SuSE patches + +* Fri Dec 08 2006 Valery Inozemtsev 2.1.12-alt1 +- 2.1.12: + + XftNameUnparse: re-export to public API + +* Sat Oct 14 2006 Valery Inozemtsev 2.1.11-alt1 +- 2.1.11 + +* Sun Sep 03 2006 Valery Inozemtsev 2.1.10-alt1 +- 2.1.10 + +* Mon Jul 17 2006 Valery Inozemtsev 2.1.9-alt3 +- removed subpixel rendering patch + +* Thu Jul 13 2006 Valery Inozemtsev 2.1.9-alt2 +- added libXft-2.1.9-git-coverity.patch + +* Sat Jun 03 2006 Valery Inozemtsev 2.1.9-alt1 +- 2.1.9 + +* Thu May 18 2006 Valery Inozemtsev 2.1.8.2-alt5 +- added subpixel rendering patch + +* Wed Apr 26 2006 Valery Inozemtsev 2.1.8.2-alt4 +- rebuild + +* Mon Jan 23 2006 Valery Inozemtsev 2.1.8.2-alt3 +- added requires to %name-devel from buildrequires + +* Fri Jan 20 2006 Valery Inozemtsev 2.1.8.2-alt2 +- fixed requires for %name-devel + +* Mon Dec 26 2005 Valery Inozemtsev 2.1.8.2-alt1 +- Xorg-7.0 + +* Sun Dec 04 2005 Valery Inozemtsev 2.1.8.1-alt1 +- Xorg-7.0RC3 + +* Mon Nov 21 2005 Valery Inozemtsev 2.1.8-alt0.1 +- initial build + diff --git a/src/xftdpy.c b/src/xftdpy.c index 707160f..b2abbda 100644 --- a/src/xftdpy.c +++ b/src/xftdpy.c @@ -369,6 +369,10 @@ _XftDefaultInit (Display *dpy) 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 @@ XftDefaultSubstitute (Display *dpy, int screen, FcPattern *pattern) 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, diff --git a/src/xftfreetype.c b/src/xftfreetype.c index e64e0a3..e552eb3 100644 --- a/src/xftfreetype.c +++ b/src/xftfreetype.c @@ -468,6 +468,21 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi) 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 */ diff --git a/src/xftglyphs.c b/src/xftglyphs.c index fc11da4..73e5a7e 100644 --- a/src/xftglyphs.c +++ b/src/xftglyphs.c @@ -1,4 +1,6 @@ /* + * $Id$ + * * Copyright © 2000 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -21,23 +23,14 @@ */ #include "xftint.h" -#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 }, + +#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 @@ -65,6 +58,295 @@ _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, @@ -83,20 +365,14 @@ XftFontLoadGlyphs (Display *dpy, 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; @@ -106,24 +382,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; } } @@ -144,7 +415,10 @@ 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) { /* @@ -177,7 +451,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. @@ -256,17 +530,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) { @@ -306,103 +577,13 @@ 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 ); + // compute the size of the final bitmap + ftbit = &glyphslot->bitmap; - 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) { @@ -419,29 +600,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 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 @@ -451,121 +675,24 @@ XftFontLoadGlyphs (Display *dpy, */ 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); + 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 = 0; - } - } - 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); @@ -573,8 +700,12 @@ XftFontLoadGlyphs (Display *dpy, } } } - 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); @@ -590,7 +721,7 @@ XftFontLoadGlyphs (Display *dpy, else xftg->bitmap = 0; } - } + font->glyph_memory += xftg->glyph_memory; info->glyph_memory += xftg->glyph_memory; if (XftDebug() & XFT_DBG_CACHE) @@ -601,8 +732,6 @@ XftFontLoadGlyphs (Display *dpy, } if (bufBitmap != bufLocal) free (bufBitmap); - if (bufBitmapRgba != bufLocalRgba) - free (bufBitmapRgba); XftUnlockFace (&font->public); } diff --git a/src/xftint.h b/src/xftint.h index 3aafecf..a6d6db7 100644 --- a/src/xftint.h +++ b/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 */