aboutsummaryrefslogtreecommitdiff
path: root/freetype/src/base/ftlcdfil.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2009-06-28 22:07:26 +0000
committermarha <marha@users.sourceforge.net>2009-06-28 22:07:26 +0000
commit3562e78743202e43aec8727005182a2558117eca (patch)
tree8f9113a77d12470c5c851a2a8e4cb02e89df7d43 /freetype/src/base/ftlcdfil.c
downloadvcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.gz
vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.bz2
vcxsrv-3562e78743202e43aec8727005182a2558117eca.zip
Checked in the following released items:
xkeyboard-config-1.4.tar.gz ttf-bitstream-vera-1.10.tar.gz font-alias-1.0.1.tar.gz font-sun-misc-1.0.0.tar.gz font-sun-misc-1.0.0.tar.gz font-sony-misc-1.0.0.tar.gz font-schumacher-misc-1.0.0.tar.gz font-mutt-misc-1.0.0.tar.gz font-misc-misc-1.0.0.tar.gz font-misc-meltho-1.0.0.tar.gz font-micro-misc-1.0.0.tar.gz font-jis-misc-1.0.0.tar.gz font-isas-misc-1.0.0.tar.gz font-dec-misc-1.0.0.tar.gz font-daewoo-misc-1.0.0.tar.gz font-cursor-misc-1.0.0.tar.gz font-arabic-misc-1.0.0.tar.gz font-winitzki-cyrillic-1.0.0.tar.gz font-misc-cyrillic-1.0.0.tar.gz font-cronyx-cyrillic-1.0.0.tar.gz font-screen-cyrillic-1.0.1.tar.gz font-xfree86-type1-1.0.1.tar.gz font-adobe-utopia-type1-1.0.1.tar.gz font-ibm-type1-1.0.0.tar.gz font-bitstream-type1-1.0.0.tar.gz font-bitstream-speedo-1.0.0.tar.gz font-bh-ttf-1.0.0.tar.gz font-bh-type1-1.0.0.tar.gz font-bitstream-100dpi-1.0.0.tar.gz font-bh-lucidatypewriter-100dpi-1.0.0.tar.gz font-bh-100dpi-1.0.0.tar.gz font-adobe-utopia-100dpi-1.0.1.tar.gz font-adobe-100dpi-1.0.0.tar.gz font-util-1.0.1.tar.gz font-bitstream-75dpi-1.0.0.tar.gz font-bh-lucidatypewriter-75dpi-1.0.0.tar.gz font-adobe-utopia-75dpi-1.0.1.tar.gz font-bh-75dpi-1.0.0.tar.gz bdftopcf-1.0.1.tar.gz font-adobe-75dpi-1.0.0.tar.gz mkfontscale-1.0.6.tar.gz openssl-0.9.8k.tar.gz bigreqsproto-1.0.2.tar.gz xtrans-1.2.2.tar.gz resourceproto-1.0.2.tar.gz inputproto-1.4.4.tar.gz compositeproto-0.4.tar.gz damageproto-1.1.0.tar.gz zlib-1.2.3.tar.gz xkbcomp-1.0.5.tar.gz freetype-2.3.9.tar.gz pthreads-w32-2-8-0-release.tar.gz pixman-0.12.0.tar.gz kbproto-1.0.3.tar.gz evieext-1.0.2.tar.gz fixesproto-4.0.tar.gz recordproto-1.13.2.tar.gz randrproto-1.2.2.tar.gz scrnsaverproto-1.1.0.tar.gz renderproto-0.9.3.tar.gz xcmiscproto-1.1.2.tar.gz fontsproto-2.0.2.tar.gz xextproto-7.0.3.tar.gz xproto-7.0.14.tar.gz libXdmcp-1.0.2.tar.gz libxkbfile-1.0.5.tar.gz libfontenc-1.0.4.tar.gz libXfont-1.3.4.tar.gz libX11-1.1.5.tar.gz libXau-1.0.4.tar.gz libxcb-1.1.tar.gz xorg-server-1.5.3.tar.gz
Diffstat (limited to 'freetype/src/base/ftlcdfil.c')
-rw-r--r--freetype/src/base/ftlcdfil.c351
1 files changed, 351 insertions, 0 deletions
diff --git a/freetype/src/base/ftlcdfil.c b/freetype/src/base/ftlcdfil.c
new file mode 100644
index 000000000..80640111c
--- /dev/null
+++ b/freetype/src/base/ftlcdfil.c
@@ -0,0 +1,351 @@
+/***************************************************************************/
+/* */
+/* ftlcdfil.c */
+/* */
+/* FreeType API for color filtering of subpixel bitmap glyphs (body). */
+/* */
+/* Copyright 2006, 2008, 2009 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_LCD_FILTER_H
+#include FT_IMAGE_H
+#include FT_INTERNAL_OBJECTS_H
+
+
+#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+
+/* define USE_LEGACY to implement the legacy filter */
+#define USE_LEGACY
+
+ /* FIR filter used by the default and light filters */
+ static void
+ _ft_lcd_filter_fir( FT_Bitmap* bitmap,
+ FT_Render_Mode mode,
+ FT_Library library )
+ {
+ FT_Byte* weights = library->lcd_weights;
+ FT_UInt width = (FT_UInt)bitmap->width;
+ FT_UInt height = (FT_UInt)bitmap->rows;
+
+
+ /* horizontal in-place FIR filter */
+ if ( mode == FT_RENDER_MODE_LCD && width >= 4 )
+ {
+ FT_Byte* line = bitmap->buffer;
+
+
+ for ( ; height > 0; height--, line += bitmap->pitch )
+ {
+ FT_UInt fir[5];
+ FT_UInt val1, xx;
+
+
+ val1 = line[0];
+ fir[0] = weights[2] * val1;
+ fir[1] = weights[3] * val1;
+ fir[2] = weights[4] * val1;
+ fir[3] = 0;
+ fir[4] = 0;
+
+ val1 = line[1];
+ fir[0] += weights[1] * val1;
+ fir[1] += weights[2] * val1;
+ fir[2] += weights[3] * val1;
+ fir[3] += weights[4] * val1;
+
+ for ( xx = 2; xx < width; xx++ )
+ {
+ FT_UInt val, pix;
+
+
+ val = line[xx];
+ pix = fir[0] + weights[0] * val;
+ fir[0] = fir[1] + weights[1] * val;
+ fir[1] = fir[2] + weights[2] * val;
+ fir[2] = fir[3] + weights[3] * val;
+ fir[3] = weights[4] * val;
+
+ pix >>= 8;
+ pix |= -( pix >> 8 );
+ line[xx - 2] = (FT_Byte)pix;
+ }
+
+ {
+ FT_UInt pix;
+
+
+ pix = fir[0] >> 8;
+ pix |= -( pix >> 8 );
+ line[xx - 2] = (FT_Byte)pix;
+
+ pix = fir[1] >> 8;
+ pix |= -( pix >> 8 );
+ line[xx - 1] = (FT_Byte)pix;
+ }
+ }
+ }
+
+ /* vertical in-place FIR filter */
+ else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 )
+ {
+ FT_Byte* column = bitmap->buffer;
+ FT_Int pitch = bitmap->pitch;
+
+
+ for ( ; width > 0; width--, column++ )
+ {
+ FT_Byte* col = column;
+ FT_UInt fir[5];
+ FT_UInt val1, yy;
+
+
+ val1 = col[0];
+ fir[0] = weights[2] * val1;
+ fir[1] = weights[3] * val1;
+ fir[2] = weights[4] * val1;
+ fir[3] = 0;
+ fir[4] = 0;
+ col += pitch;
+
+ val1 = col[0];
+ fir[0] += weights[1] * val1;
+ fir[1] += weights[2] * val1;
+ fir[2] += weights[3] * val1;
+ fir[3] += weights[4] * val1;
+ col += pitch;
+
+ for ( yy = 2; yy < height; yy++ )
+ {
+ FT_UInt val, pix;
+
+
+ val = col[0];
+ pix = fir[0] + weights[0] * val;
+ fir[0] = fir[1] + weights[1] * val;
+ fir[1] = fir[2] + weights[2] * val;
+ fir[2] = fir[3] + weights[3] * val;
+ fir[3] = weights[4] * val;
+
+ pix >>= 8;
+ pix |= -( pix >> 8 );
+ col[-2 * pitch] = (FT_Byte)pix;
+ col += pitch;
+ }
+
+ {
+ FT_UInt pix;
+
+
+ pix = fir[0] >> 8;
+ pix |= -( pix >> 8 );
+ col[-2 * pitch] = (FT_Byte)pix;
+
+ pix = fir[1] >> 8;
+ pix |= -( pix >> 8 );
+ col[-pitch] = (FT_Byte)pix;
+ }
+ }
+ }
+ }
+
+
+#ifdef USE_LEGACY
+
+ /* intra-pixel filter used by the legacy filter */
+ static void
+ _ft_lcd_filter_legacy( FT_Bitmap* bitmap,
+ FT_Render_Mode mode,
+ FT_Library library )
+ {
+ FT_UInt width = (FT_UInt)bitmap->width;
+ FT_UInt height = (FT_UInt)bitmap->rows;
+ FT_Int pitch = bitmap->pitch;
+
+ static const int filters[3][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 }
+ };
+
+ FT_UNUSED( library );
+
+
+ /* horizontal in-place intra-pixel filter */
+ if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
+ {
+ FT_Byte* line = bitmap->buffer;
+
+
+ for ( ; height > 0; height--, line += pitch )
+ {
+ FT_UInt xx;
+
+
+ for ( xx = 0; xx < width; xx += 3 )
+ {
+ FT_UInt r = 0;
+ FT_UInt g = 0;
+ FT_UInt b = 0;
+ FT_UInt p;
+
+
+ p = line[xx];
+ r += filters[0][0] * p;
+ g += filters[0][1] * p;
+ b += filters[0][2] * p;
+
+ p = line[xx + 1];
+ r += filters[1][0] * p;
+ g += filters[1][1] * p;
+ b += filters[1][2] * p;
+
+ p = line[xx + 2];
+ r += filters[2][0] * p;
+ g += filters[2][1] * p;
+ b += filters[2][2] * p;
+
+ line[xx] = (FT_Byte)( r / 65536 );
+ line[xx + 1] = (FT_Byte)( g / 65536 );
+ line[xx + 2] = (FT_Byte)( b / 65536 );
+ }
+ }
+ }
+ else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )
+ {
+ FT_Byte* column = bitmap->buffer;
+
+
+ for ( ; width > 0; width--, column++ )
+ {
+ FT_Byte* col = column;
+ FT_Byte* col_end = col + height * pitch;
+
+
+ for ( ; col < col_end; col += 3 * pitch )
+ {
+ FT_UInt r = 0;
+ FT_UInt g = 0;
+ FT_UInt b = 0;
+ FT_UInt p;
+
+
+ p = col[0];
+ r += filters[0][0] * p;
+ g += filters[0][1] * p;
+ b += filters[0][2] * p;
+
+ p = col[pitch];
+ r += filters[1][0] * p;
+ g += filters[1][1] * p;
+ b += filters[1][2] * p;
+
+ p = col[pitch * 2];
+ r += filters[2][0] * p;
+ g += filters[2][1] * p;
+ b += filters[2][2] * p;
+
+ col[0] = (FT_Byte)( r / 65536 );
+ col[pitch] = (FT_Byte)( g / 65536 );
+ col[2 * pitch] = (FT_Byte)( b / 65536 );
+ }
+ }
+ }
+ }
+
+#endif /* USE_LEGACY */
+
+
+ FT_EXPORT_DEF( FT_Error )
+ FT_Library_SetLcdFilter( FT_Library library,
+ FT_LcdFilter filter )
+ {
+ static const FT_Byte light_filter[5] =
+ { 0, 85, 86, 85, 0 };
+ /* the values here sum up to a value larger than 256, */
+ /* providing a cheap gamma correction */
+ static const FT_Byte default_filter[5] =
+ { 0x10, 0x40, 0x70, 0x40, 0x10 };
+
+
+ if ( library == NULL )
+ return FT_Err_Invalid_Argument;
+
+ switch ( filter )
+ {
+ case FT_LCD_FILTER_NONE:
+ library->lcd_filter_func = NULL;
+ library->lcd_extra = 0;
+ break;
+
+ case FT_LCD_FILTER_DEFAULT:
+#if defined( FT_FORCE_LEGACY_LCD_FILTER )
+
+ library->lcd_filter_func = _ft_lcd_filter_legacy;
+ library->lcd_extra = 0;
+
+#elif defined( FT_FORCE_LIGHT_LCD_FILTER )
+
+ ft_memcpy( library->lcd_weights, light_filter, 5 );
+ library->lcd_filter_func = _ft_lcd_filter_fir;
+ library->lcd_extra = 2;
+
+#else
+
+ ft_memcpy( library->lcd_weights, default_filter, 5 );
+ library->lcd_filter_func = _ft_lcd_filter_fir;
+ library->lcd_extra = 2;
+
+#endif
+
+ break;
+
+ case FT_LCD_FILTER_LIGHT:
+ ft_memcpy( library->lcd_weights, light_filter, 5 );
+ library->lcd_filter_func = _ft_lcd_filter_fir;
+ library->lcd_extra = 2;
+ break;
+
+#ifdef USE_LEGACY
+
+ case FT_LCD_FILTER_LEGACY:
+ library->lcd_filter_func = _ft_lcd_filter_legacy;
+ library->lcd_extra = 0;
+ break;
+
+#endif
+
+ default:
+ return FT_Err_Invalid_Argument;
+ }
+
+ library->lcd_filter = filter;
+ return 0;
+ }
+
+#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+
+ FT_EXPORT_DEF( FT_Error )
+ FT_Library_SetLcdFilter( FT_Library library,
+ FT_LcdFilter filter )
+ {
+ FT_UNUSED( library );
+ FT_UNUSED( filter );
+
+ return FT_Err_Unimplemented_Feature;
+ }
+
+#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+
+
+/* END */