Date: Wed, 23 Jan 2008 00:39:33 +0300 (MSK) From: Alexander Zhuravlev <zaa@zaa.pp.ru> To: FreeBSD-gnats-submit@freebsd.org Cc: gnome@freebsd.org Subject: [PATCH] LCD filtering for print/freetype2 and x11-fonts/libXft ports Message-ID: <20080122213933.1208BBDB3@orion.ulstu.ru>
next in thread | raw e-mail | index | archive | help
>Submitter-Id: current-users >Originator: Alexander Zhuravlev >Organization: >Confidential: no >Synopsis: [PATCH] LCD filtering for print/freetype2 and x11-fonts/libXft ports >Severity: non-critical >Priority: medium >Category: ports >Class: maintainer-update >Release: FreeBSD 6.2-RELEASE-p7 i386 >Environment: System: FreeBSD orion.ulstu.ru 6.2-RELEASE-p7 FreeBSD 6.2-RELEASE-p7 #3: Wed Aug 29 19:16:07 MSD 2007 root@orion.ulstu.ru:/usr/obj/usr/src/sys/ORION i386 >Description: Hello, Attached patches add LCD filtering support to print/freetype2 and x11-fonts/libXft ports. I've used them for a couple of months and did not encounter any issues. You may consider possibility to include them into FreeBSD ports collection. ps. in case if you do not know about LCD filtering, feel free to check those resources: http://bugs.freedesktop.org/show_bug.cgi?id=10301 http://article.gmane.org/gmane.comp.fonts.freetype.user/2238 http://david.freetype.org/lcd/ Best regards, >How-To-Repeat: >Fix: --- ports-print-freetype2-lcd-filtering.diff begins here --- diff -urbBNp freetype2.orig/Makefile freetype2/Makefile --- freetype2.orig/Makefile 2007-10-25 03:36:27.000000000 +0400 +++ freetype2/Makefile 2008-01-22 22:38:56.000000000 +0300 @@ -44,6 +44,10 @@ CFLAGS+= -DTT_CONFIG_OPTION_BYTECODE_INT #PATCH_DIST_STRIP+= -p1 .endif +.if defined(WITH_LCD_FILTERING) +CFLAGS+= -DFT_CONFIG_OPTION_SUBPIXEL_RENDERING +.endif + pre-everything:: .if !defined(WITHOUT_TTF_BYTECODE_ENABLED) @${ECHO_MSG} @@ -57,6 +61,16 @@ pre-everything:: @${ECHO_MSG} "use of the interpreter." @${ECHO_MSG} .endif +.if !defined(WITH_LCD_FILTERING) + @${ECHO_MSG} + @${ECHO_MSG} "You may want not to enable LCD filtering." + @${ECHO_MSG} + @${ECHO_MSG} "Hit Ctrl-C now and use \"make WITH_LCD_FILTERING=yes\"" + @${ECHO_MSG} + @${ECHO_MSG} "Note that there are possible patent issues related to the" + @${ECHO_MSG} "use of the LCD filtering technology." + @${ECHO_MSG} +.endif pre-patch: @${REINPLACE_CMD} -e 's|[(]libdir[)]/pkgconfig|(prefix)/libdata/pkgconfig|g' \ --- ports-print-freetype2-lcd-filtering.diff ends here --- --- ports-x11-fonts-libXft-lcd-filtering.diff begins here --- diff -urbBNp libXft.orig/Makefile libXft/Makefile --- libXft.orig/Makefile 2007-05-20 00:29:31.000000000 +0400 +++ libXft/Makefile 2008-01-23 00:20:52.000000000 +0300 @@ -22,4 +22,12 @@ USE_XORG= xproto:both xrender MAN1= xft-config.1 MAN3= Xft.3 -.include <bsd.port.mk> +OPTIONS+= LCD_FILTERING "Enable LCD Filtering Support" Off + +.include <bsd.port.pre.mk> + +.if defined(WITH_LCD_FILTERING) +EXTRA_PATCHES+= ${PATCHDIR}/libXft-2.1.7-lcd-filter-2.patch +.endif + +.include <bsd.port.post.mk> diff -urbBNp libXft.orig/files/libXft-2.1.7-lcd-filter-2.patch libXft/files/libXft-2.1.7-lcd-filter-2.patch --- libXft.orig/files/libXft-2.1.7-lcd-filter-2.patch 1970-01-01 03:00:00.000000000 +0300 +++ libXft/files/libXft-2.1.7-lcd-filter-2.patch 2008-01-23 00:20:35.000000000 +0300 @@ -0,0 +1,778 @@ +--- src/xftglyphs.c.orig 2006-12-07 13:17:19.000000000 +0300 ++++ src/xftglyphs.c 2007-11-19 23:56:34.000000000 +0300 +@@ -23,23 +23,14 @@ + */ + + #include "xftint.h" +-#include <freetype/ftoutln.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 }, ++#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 +@@ -67,6 +58,294 @@ _XftFontValidateMemory (Display *dpy, Xf + 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, +@@ -85,20 +364,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; +@@ -108,24 +381,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; + } + } + +@@ -146,7 +414,10 @@ XftFontLoadGlyphs (Display *dpy, + if (xftg->glyph_memory) + continue; + ++ FT_Library_SetLcdFilter( _XftFTlibrary, FT_LCD_FILTER_DEFAULT ); ++ + error = FT_Load_Glyph (face, glyphindex, font->info.load_flags); ++ + if (error) + { + /* +@@ -179,7 +450,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. +@@ -258,17 +529,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) + { +@@ -308,103 +576,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); ++ // 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) + { +@@ -421,153 +599,99 @@ 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"); + } + } + +- /* +- * Use the glyph index as the wire encoding; it +- * might be more efficient for some locales to map +- * these by first usage to smaller values, but that +- * would require persistently storing the map when +- * glyphs were freed. +- */ +- glyph = (Glyph) glyphindex; ++ size = _compute_xrender_bitmap_size( &local, glyphslot, mode ); ++ if ( size < 0 ) ++ continue; + +- 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; ++ xftg->metrics.width = local.width; ++ xftg->metrics.height = local.rows; ++ xftg->metrics.x = - glyphslot->bitmap_left; ++ xftg->metrics.y = glyphslot->bitmap_top; + + /* +- * Filter the glyph to soften the color fringes ++ * If the glyph is relatively large (> 1% of server memory), ++ * don't send it until necessary + */ +- widthrgba = width; +- pitchrgba = (widthrgba * 4 + 3) & ~3; +- sizergba = pitchrgba * height; ++ if (!need_bitmaps && size > info->max_glyph_memory / 100) ++ continue; + +- 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) ++ /* ++ * Make sure there's enough buffer space for the glyph ++ */ ++ if (size > bufSize) + { +- if (bufBitmapRgba != bufLocalRgba) +- free (bufBitmapRgba); +- bufBitmapRgba = (unsigned char *) malloc (sizergba); +- if (!bufBitmapRgba) ++ if (bufBitmap != bufLocal) ++ free (bufBitmap); ++ bufBitmap = (unsigned char *) malloc (size); ++ if (!bufBitmap) + 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; +- } ++ bufSize = size; + } ++ memset (bufBitmap, 0, size); ++ ++ local.buffer = bufBitmap; + +- xftg->glyph_memory = sizergba + sizeof (XftGlyph); ++ _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 ++ * these by first usage to smaller values, but that ++ * would require persistently storing the map when ++ * glyphs were freed. ++ */ ++ glyph = (Glyph) glyphindex; ++ ++ 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); +@@ -575,8 +699,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); +@@ -592,7 +720,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) +@@ -603,8 +731,6 @@ XftFontLoadGlyphs (Display *dpy, + } + if (bufBitmap != bufLocal) + free (bufBitmap); +- if (bufBitmapRgba != bufLocalRgba) +- free (bufBitmapRgba); + XftUnlockFace (&font->public); + } + --- ports-x11-fonts-libXft-lcd-filtering.diff ends here ---
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080122213933.1208BBDB3>