ref: 8a317cf7ab1a13f9b4b7fbf678454c92c21cfddf
parent: e20df4a167995e46d0900651be1c30f134638666
author: David Turner <[email protected]>
date: Wed Sep 27 03:52:48 EDT 2006
* 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 <freetype/ftlcdfil.h>
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2006-09-27 David Turner <[email protected]>
+
+ * 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 <freetype/ftlcdfil.h>
+
2006-09-26 David Bustin
* src/pfr/pfrobjs.c (pfr_face_get_kerning): Skip adjustment bytes
--- a/include/freetype/config/ftheader.h
+++ b/include/freetype/config/ftheader.h
@@ -665,6 +665,17 @@
*/
#define FT_TRIGONOMETRY_H <freetype/fttrigon.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 <freetype/ftlcdfil.h>
+
/* */
#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h>
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -3311,7 +3311,7 @@
*/
#define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 2
-#define FREETYPE_PATCH 1
+#define FREETYPE_PATCH 2
/*************************************************************************/
@@ -3348,7 +3348,6 @@
FT_Int *amajor,
FT_Int *aminor,
FT_Int *apatch );
-
/* */
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -650,6 +650,10 @@
#define FT_DEBUG_HOOK_UNPATENTED_HINTING 1
+ typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap,
+ FT_Render_Mode render_mode,
+ FT_Byte* weights );
+
/*************************************************************************/
/* */
/* <Struct> */
@@ -722,6 +726,11 @@
FT_ULong raster_pool_size; /* size of render pool in bytes */
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;
--- a/src/base/Jamfile
+++ b/src/base/Jamfile
@@ -34,7 +34,7 @@
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 ;
--- 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,13 +157,37 @@
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;
bitmap->width = width;
@@ -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,15 +241,19 @@
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 */
@@ -231,7 +260,7 @@
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;