diff --git a/ChangeLog b/ChangeLog index 1887e7328..20e60005a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2006-09-27 David Turner + + * include/freetype/freetype.h: bumping FT_FREETYPE_PATCH to 2 + for an upcoming 2.2.2 release + + * include/freetype/ftlcdfil.h, src/freetype/ftlcdfil.c: + added a new API to support color filtering of subpixel glyph + bitmaps. In default build, the function FT_Library_SetLcdFilter + returns FT_Err_Unimplemented_Feature; you need to #define + FT_CONFIG_OPTION_SUBPIXEL_RENDERING in ftoption.h to compile + the real implementation + + * src/smooth/ftsmooth.c: adding support for sub-pixel color + filtering; simplifying a few function calls + + * include/freetype/config/ftheader.h: adding FT_LCD_FILTER_H + macro that points to + 2006-09-26 David Bustin * src/pfr/pfrobjs.c (pfr_face_get_kerning): Skip adjustment bytes diff --git a/include/freetype/config/ftheader.h b/include/freetype/config/ftheader.h index 7d663d994..097ff666e 100644 --- a/include/freetype/config/ftheader.h +++ b/include/freetype/config/ftheader.h @@ -665,6 +665,17 @@ */ #define FT_TRIGONOMETRY_H + /************************************************************************* + * + * @macro: + * FT_LCD_FILTER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType 2 API used to perform color filtering for subpixel rendering + */ +#define FT_LCD_FILTER_H + /* */ #define FT_ERROR_DEFINITIONS_H diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index 5e6b6c36f..6344b6ca9 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -3311,7 +3311,7 @@ FT_BEGIN_HEADER */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 2 -#define FREETYPE_PATCH 1 +#define FREETYPE_PATCH 2 /*************************************************************************/ @@ -3349,7 +3349,6 @@ FT_BEGIN_HEADER FT_Int *aminor, FT_Int *apatch ); - /* */ diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index 38eef7b3c..2e7c8952c 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -650,6 +650,10 @@ FT_BEGIN_HEADER #define FT_DEBUG_HOOK_UNPATENTED_HINTING 1 + typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap, + FT_Render_Mode render_mode, + FT_Byte* weights ); + /*************************************************************************/ /* */ /* */ @@ -723,6 +727,11 @@ FT_BEGIN_HEADER FT_DebugHook_Func debug_hooks[4]; +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + FT_Byte lcd_filter_weights[5]; + FT_Bitmap_LcdFilterFunc lcd_filter; +#endif + } FT_LibraryRec; diff --git a/src/base/Jamfile b/src/base/Jamfile index 2c486d116..8999a22c3 100644 --- a/src/base/Jamfile +++ b/src/base/Jamfile @@ -34,7 +34,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ; local _sources = system init glyph mm bdf bbox debug xf86 type1 pfr stroke winfnt otval bitmap synth - gxval + gxval lcdfil ; Library $(FT2_LIB) : ft$(_sources).c ; diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c index 3045a75c1..f17f1a6e9 100644 --- a/src/smooth/ftsmooth.c +++ b/src/smooth/ftsmooth.c @@ -98,9 +98,7 @@ FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector* origin, - FT_Render_Mode required_mode, - FT_Int hmul, - FT_Int vmul ) + FT_Render_Mode required_mode ) { FT_Error error; FT_Outline* outline = NULL; @@ -108,6 +106,9 @@ FT_UInt width, height, height_org, width_org, pitch; FT_Bitmap* bitmap; FT_Memory memory; + FT_Int hmul = (mode == FT_RENDER_MODE_LCD); + FT_Int vmul = (mode == FT_RENDER_MODE_LCD_V); + FT_Pos x_shift, y_shift, x_left, y_top; FT_Raster_Params params; @@ -156,12 +157,36 @@ pitch = width; if ( hmul ) { - width = width * hmul; + width = width * 3; pitch = FT_PAD_CEIL( width, 4 ); } if ( vmul ) - height *= vmul; + height *= 3; + + x_shift = (FT_Int) cbox.xMin; + y_shift = (FT_Int) cbox.yMin; + x_left = (FT_Int)( cbox.xMin >> 6 ); + y_top = (FT_Int)( cbox.yMax >> 6 ); + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + if ( slot->library->lcd_filter ) + { + if ( hmul ) + { + x_shift -= 64; + width += 6; + pitch = FT_PAD_CEIL( width, 4 ); + x_left -= 1; + } + if ( vmul ) + { + y_shift -= 64; + height += 6; + y_top += 1; + } + } +#endif bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; bitmap->num_grays = 256; @@ -169,14 +194,14 @@ bitmap->rows = height; bitmap->pitch = pitch; + /* translate outline to render it into the bitmap */ + FT_Outline_Translate( outline, -x_shift, -y_shift ); + if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) goto Exit; slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - /* translate outline to render it into the bitmap */ - FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); - /* set up parameters */ params.target = bitmap; params.source = outline; @@ -194,13 +219,13 @@ for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) - vec->x *= hmul; + vec->x *= 3; if ( vmul ) for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) - vec->y *= vmul; + vec->y *= 3; } /* render outline into the bitmap */ @@ -216,22 +241,26 @@ for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) - vec->x /= hmul; + vec->x /= 3; if ( vmul ) for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) - vec->y /= vmul; + vec->y /= 3; } + if ( slot->library->lcd_filter ) + slot->library->lcd_filter( bitmap, mode, + slot->library->lcd_filter_weights ); + #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ /* render outline into bitmap */ error = render->raster_render( render->raster, ¶ms ); /* expand it horizontally */ - if ( hmul > 1 ) + if ( hmul ) { FT_Byte* line = bitmap->buffer + ( height - height_org ) * pitch; FT_UInt hh; @@ -246,19 +275,18 @@ for ( xx = width_org; xx > 0; xx-- ) { FT_UInt pixel = line[xx-1]; - FT_UInt count = hmul; - for ( count = hmul; count > 0; count-- ) - end[-count] = (FT_Byte)pixel; - - end -= hmul; + end[-3] = (FT_Byte)pixel; + end[-2] = (FT_Byte)pixel; + end[-1] = (FT_Byte)pixel; + end -= 3; } } } /* expand it vertically */ - if ( vmul > 1 ) + if ( vmul ) { FT_Byte* read = bitmap->buffer + ( height - height_org ) * pitch; FT_Byte* write = bitmap->buffer; @@ -267,28 +295,28 @@ for ( hh = height_org; hh > 0; hh-- ) { - FT_UInt count = vmul; + memcpy( write, read, pitch ); + write += pitch; + memcpy( write, read, pitch ); + write += pitch; - for ( count = vmul; count > 0; count-- ) - { - memcpy( write, read, pitch ); - write += pitch; - } - read += pitch; + memcpy( write, read, pitch ); + write += pitch; + read += pitch; } } #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); + FT_Outline_Translate( outline, x_shift, y_shift ); if ( error ) goto Exit; slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 ); - slot->bitmap_top = (FT_Int)( cbox.yMax >> 6 ); + slot->bitmap_left = x_left; + slot->bitmap_top = y_top; Exit: if ( outline && origin ) @@ -309,8 +337,7 @@ mode = FT_RENDER_MODE_NORMAL; return ft_smooth_render_generic( render, slot, mode, origin, - FT_RENDER_MODE_NORMAL, - 0, 0 ); + FT_RENDER_MODE_NORMAL ); } @@ -324,8 +351,7 @@ FT_Error error; error = ft_smooth_render_generic( render, slot, mode, origin, - FT_RENDER_MODE_LCD, - 3, 0 ); + FT_RENDER_MODE_LCD ); if ( !error ) slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD; @@ -343,8 +369,7 @@ FT_Error error; error = ft_smooth_render_generic( render, slot, mode, origin, - FT_RENDER_MODE_LCD_V, - 0, 3 ); + FT_RENDER_MODE_LCD_V ); if ( !error ) slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V;