forked from minhngoc25a/freetype2
Compare commits
9 Commits
Author | SHA1 | Date |
---|---|---|
Alexei Podtelezhnikov | fcfd6c17ff | |
Alexei Podtelezhnikov | d526705f5e | |
Alexei Podtelezhnikov | 11ffff2c91 | |
Alexei Podtelezhnikov | b5a29cce2f | |
Alexei Podtelezhnikov | 66006dbfa4 | |
Alexei Podtelezhnikov | e47feb03cc | |
Alexei Podtelezhnikov | 51dd542e55 | |
Alexei Podtelezhnikov | 3f663bc648 | |
Alexei Podtelezhnikov | 8901ff06d0 |
|
@ -3351,7 +3351,7 @@ FT_BEGIN_HEADER
|
||||||
/* with subpixel-rendered glyphs to prevent color-fringing! A */
|
/* with subpixel-rendered glyphs to prevent color-fringing! A */
|
||||||
/* subpixel-rendered glyph must first be filtered with a filter that */
|
/* subpixel-rendered glyph must first be filtered with a filter that */
|
||||||
/* gives equal weight to the three color primaries and does not */
|
/* gives equal weight to the three color primaries and does not */
|
||||||
/* exceed a sum of 0x100, see section @lcd_filtering. Then the */
|
/* exceed a sum of 0x100, see section @lcd_rendering. Then the */
|
||||||
/* only difference to gray linear blending is that subpixel-rendered */
|
/* only difference to gray linear blending is that subpixel-rendered */
|
||||||
/* linear blending is done 3~times per pixel: red foreground subpixel */
|
/* linear blending is done 3~times per pixel: red foreground subpixel */
|
||||||
/* to red background subpixel and so on for green and blue. */
|
/* to red background subpixel and so on for green and blue. */
|
||||||
|
|
|
@ -120,7 +120,7 @@
|
||||||
/* gzip */
|
/* gzip */
|
||||||
/* lzw */
|
/* lzw */
|
||||||
/* bzip2 */
|
/* bzip2 */
|
||||||
/* lcd_filtering */
|
/* lcd_rendering */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -36,10 +36,10 @@ FT_BEGIN_HEADER
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
*
|
*
|
||||||
* @section:
|
* @section:
|
||||||
* lcd_filtering
|
* lcd_rendering
|
||||||
*
|
*
|
||||||
* @title:
|
* @title:
|
||||||
* LCD Filtering
|
* LCD Rendering
|
||||||
*
|
*
|
||||||
* @abstract:
|
* @abstract:
|
||||||
* Reduce color fringes of subpixel-rendered bitmaps.
|
* Reduce color fringes of subpixel-rendered bitmaps.
|
||||||
|
@ -298,6 +298,54 @@ FT_BEGIN_HEADER
|
||||||
typedef FT_Byte FT_LcdFiveTapFilter[FT_LCD_FILTER_FIVE_TAPS];
|
typedef FT_Byte FT_LcdFiveTapFilter[FT_LCD_FILTER_FIVE_TAPS];
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* @func:
|
||||||
|
* FT_Library_SetLcdGeometry
|
||||||
|
*
|
||||||
|
* @description:
|
||||||
|
* This function can be used to modify default positions of color
|
||||||
|
* subpixels, which controls Harmony LCD rendering.
|
||||||
|
*
|
||||||
|
* @input:
|
||||||
|
* library ::
|
||||||
|
* A handle to the target library instance.
|
||||||
|
*
|
||||||
|
* sub ::
|
||||||
|
* A pointer to an array of 3 vectors in 26.6 fractional pixel format;
|
||||||
|
* the function modifies the default values, see the note below.
|
||||||
|
*
|
||||||
|
* @return:
|
||||||
|
* FreeType error code. 0~means success.
|
||||||
|
*
|
||||||
|
* @note:
|
||||||
|
* This function does nothing and returns `FT_Err_Unimplemented_Feature'
|
||||||
|
* in the context of ClearType-style subpixel rendering when
|
||||||
|
* FT_CONFIG_OPTION_SUBPIXEL_RENDERING is defined in your build of the
|
||||||
|
* library.
|
||||||
|
*
|
||||||
|
* Subpixel geometry examples:
|
||||||
|
*
|
||||||
|
* - {{-21, 0}, {0, 0}, {21, 0}} is the default, corresponding 3 color
|
||||||
|
* stripes shifted by a third of a pixel. This could be an RGB panel.
|
||||||
|
*
|
||||||
|
* - {{21, 0}, {0, 0}, {-21, 0}} looks the same as the default but
|
||||||
|
* offers you possibility to specify that this is a BGR panel instead,
|
||||||
|
* while keeping the bitmap in the same RGB888 format.
|
||||||
|
*
|
||||||
|
* - {{0, 21}, {0, 0}, {0, -21}} is the vertical RGB, but the bitmap
|
||||||
|
* stays RGB888 as a result.
|
||||||
|
*
|
||||||
|
* - {{32, -21}, {-32, -21}, {0, 42}} is a certain PenTile arrangement.
|
||||||
|
*
|
||||||
|
* @since:
|
||||||
|
* 2.9.x
|
||||||
|
*/
|
||||||
|
FT_EXPORT( FT_Error )
|
||||||
|
FT_Library_SetLcdGeometry( FT_Library library,
|
||||||
|
FT_Vector* sub );
|
||||||
|
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -312,11 +312,11 @@ FT_BEGIN_HEADER
|
||||||
FT_CMap_Done( FT_CMap cmap );
|
FT_CMap_Done( FT_CMap cmap );
|
||||||
|
|
||||||
|
|
||||||
/* adds LCD padding to Min and Max boundaries */
|
/* add LCD padding to CBox */
|
||||||
FT_BASE( void )
|
FT_BASE( void )
|
||||||
ft_lcd_padding( FT_Pos* Min,
|
ft_lcd_padding( FT_BBox* cbox,
|
||||||
FT_Pos* Max,
|
FT_GlyphSlot slot,
|
||||||
FT_GlyphSlot slot );
|
FT_Render_Mode mode );
|
||||||
|
|
||||||
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
|
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
|
||||||
|
|
||||||
|
@ -392,8 +392,8 @@ FT_BEGIN_HEADER
|
||||||
/* */
|
/* */
|
||||||
/* lcd_weights :: */
|
/* lcd_weights :: */
|
||||||
/* lcd_filter_func :: */
|
/* lcd_filter_func :: */
|
||||||
/* If subpixel rendering is activated, the LCD filtering weights */
|
/* These fields specify the LCD filtering weights and callback */
|
||||||
/* and callback function. */
|
/* function for ClearType-style subpixel rendering. */
|
||||||
/* */
|
/* */
|
||||||
/* refcount :: */
|
/* refcount :: */
|
||||||
/* A counter initialized to~1 at the time an @FT_Face structure is */
|
/* A counter initialized to~1 at the time an @FT_Face structure is */
|
||||||
|
@ -897,11 +897,15 @@ FT_BEGIN_HEADER
|
||||||
/* interpreter. Currently, only the TrueType */
|
/* interpreter. Currently, only the TrueType */
|
||||||
/* bytecode debugger uses this. */
|
/* bytecode debugger uses this. */
|
||||||
/* */
|
/* */
|
||||||
/* lcd_weights :: If subpixel rendering is activated, the LCD */
|
/* lcd_weights :: The LCD filter weights for ClearType-style */
|
||||||
/* filter weights, if any. */
|
/* subpixel rendering. */
|
||||||
/* */
|
/* */
|
||||||
/* lcd_filter_func :: If subpixel rendering is activated, the LCD */
|
/* lcd_filter_func :: The LCD filtering callback function for */
|
||||||
/* filtering callback function. */
|
/* for ClearType-style subpixel rendering. */
|
||||||
|
/* */
|
||||||
|
/* lcd_geometry :: This array specifies LCD subpixel geometry */
|
||||||
|
/* and controls Harmony LCD rendering technique, */
|
||||||
|
/* alternative to ClearType. */
|
||||||
/* */
|
/* */
|
||||||
/* pic_container :: Contains global structs and tables, instead */
|
/* pic_container :: Contains global structs and tables, instead */
|
||||||
/* of defining them globally. */
|
/* of defining them globally. */
|
||||||
|
@ -933,6 +937,8 @@ FT_BEGIN_HEADER
|
||||||
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
|
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
|
||||||
FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */
|
FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */
|
||||||
FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */
|
FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */
|
||||||
|
#else
|
||||||
|
FT_Vector lcd_geometry[3]; /* RGB subpixel positions */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FT_CONFIG_OPTION_PIC
|
#ifdef FT_CONFIG_OPTION_PIC
|
||||||
|
|
|
@ -34,9 +34,9 @@
|
||||||
|
|
||||||
/* add padding according to filter weights */
|
/* add padding according to filter weights */
|
||||||
FT_BASE_DEF (void)
|
FT_BASE_DEF (void)
|
||||||
ft_lcd_padding( FT_Pos* Min,
|
ft_lcd_padding( FT_BBox* cbox,
|
||||||
FT_Pos* Max,
|
FT_GlyphSlot slot,
|
||||||
FT_GlyphSlot slot )
|
FT_Render_Mode mode )
|
||||||
{
|
{
|
||||||
FT_Byte* lcd_weights;
|
FT_Byte* lcd_weights;
|
||||||
FT_Bitmap_LcdFilterFunc lcd_filter_func;
|
FT_Bitmap_LcdFilterFunc lcd_filter_func;
|
||||||
|
@ -56,10 +56,20 @@
|
||||||
|
|
||||||
if ( lcd_filter_func == ft_lcd_filter_fir )
|
if ( lcd_filter_func == ft_lcd_filter_fir )
|
||||||
{
|
{
|
||||||
*Min -= lcd_weights[0] ? 43 :
|
if ( mode == FT_RENDER_MODE_LCD )
|
||||||
lcd_weights[1] ? 22 : 0;
|
{
|
||||||
*Max += lcd_weights[4] ? 43 :
|
cbox->xMin -= lcd_weights[0] ? 43 :
|
||||||
lcd_weights[3] ? 22 : 0;
|
lcd_weights[1] ? 22 : 0;
|
||||||
|
cbox->xMax += lcd_weights[4] ? 43 :
|
||||||
|
lcd_weights[3] ? 22 : 0;
|
||||||
|
}
|
||||||
|
else if ( mode == FT_RENDER_MODE_LCD_V )
|
||||||
|
{
|
||||||
|
cbox->yMin -= lcd_weights[0] ? 43 :
|
||||||
|
lcd_weights[1] ? 22 : 0;
|
||||||
|
cbox->yMax += lcd_weights[4] ? 43 :
|
||||||
|
lcd_weights[3] ? 22 : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,18 +351,56 @@
|
||||||
return FT_Err_Ok;
|
return FT_Err_Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FT_EXPORT_DEF( FT_Error )
|
||||||
|
FT_Library_SetLcdGeometry( FT_Library library,
|
||||||
|
FT_Vector* sub )
|
||||||
|
{
|
||||||
|
FT_UNUSED( library );
|
||||||
|
FT_UNUSED( sub );
|
||||||
|
|
||||||
|
return FT_THROW( Unimplemented_Feature );
|
||||||
|
}
|
||||||
|
|
||||||
#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
|
#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
|
||||||
|
|
||||||
/* add padding according to accommodate outline shifts */
|
/* add padding to accommodate outline shifts */
|
||||||
FT_BASE_DEF (void)
|
FT_BASE_DEF (void)
|
||||||
ft_lcd_padding( FT_Pos* Min,
|
ft_lcd_padding( FT_BBox* cbox,
|
||||||
FT_Pos* Max,
|
FT_GlyphSlot slot,
|
||||||
FT_GlyphSlot slot )
|
FT_Render_Mode mode )
|
||||||
{
|
{
|
||||||
FT_UNUSED( slot );
|
FT_Vector* sub = slot->library->lcd_geometry;
|
||||||
|
|
||||||
*Min -= 21;
|
if ( mode == FT_RENDER_MODE_LCD )
|
||||||
*Max += 21;
|
{
|
||||||
|
cbox->xMin -= FT_MAX( FT_MAX( sub[0].x, sub[1].x ), sub[2].x );
|
||||||
|
cbox->xMax -= FT_MIN( FT_MIN( sub[0].x, sub[1].x ), sub[2].x );
|
||||||
|
cbox->yMin -= FT_MAX( FT_MAX( sub[0].y, sub[1].y ), sub[2].y );
|
||||||
|
cbox->yMax -= FT_MIN( FT_MIN( sub[0].y, sub[1].y ), sub[2].y );
|
||||||
|
}
|
||||||
|
else if ( mode == FT_RENDER_MODE_LCD_V )
|
||||||
|
{
|
||||||
|
cbox->xMin -= FT_MAX( FT_MAX( sub[0].y, sub[1].y ), sub[2].y );
|
||||||
|
cbox->xMax -= FT_MIN( FT_MIN( sub[0].y, sub[1].y ), sub[2].y );
|
||||||
|
cbox->yMin += FT_MIN( FT_MIN( sub[0].x, sub[1].x ), sub[2].x );
|
||||||
|
cbox->yMax += FT_MAX( FT_MAX( sub[0].x, sub[1].x ), sub[2].x );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_EXPORT_DEF( FT_Error )
|
||||||
|
FT_Library_SetLcdGeometry( FT_Library library,
|
||||||
|
FT_Vector* sub )
|
||||||
|
{
|
||||||
|
if ( !library )
|
||||||
|
return FT_THROW( Invalid_Library_Handle );
|
||||||
|
|
||||||
|
if ( !sub )
|
||||||
|
return FT_THROW( Invalid_Argument );
|
||||||
|
|
||||||
|
ft_memcpy( library->lcd_geometry, sub, 3 * sizeof( FT_Vector ) );
|
||||||
|
|
||||||
|
return FT_THROW( Unimplemented_Feature );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -403,12 +403,12 @@
|
||||||
|
|
||||||
case FT_RENDER_MODE_LCD:
|
case FT_RENDER_MODE_LCD:
|
||||||
pixel_mode = FT_PIXEL_MODE_LCD;
|
pixel_mode = FT_PIXEL_MODE_LCD;
|
||||||
ft_lcd_padding( &cbox.xMin, &cbox.xMax, slot );
|
ft_lcd_padding( &cbox, slot, mode );
|
||||||
goto Round;
|
goto Round;
|
||||||
|
|
||||||
case FT_RENDER_MODE_LCD_V:
|
case FT_RENDER_MODE_LCD_V:
|
||||||
pixel_mode = FT_PIXEL_MODE_LCD_V;
|
pixel_mode = FT_PIXEL_MODE_LCD_V;
|
||||||
ft_lcd_padding( &cbox.yMin, &cbox.yMax, slot );
|
ft_lcd_padding( &cbox, slot, mode );
|
||||||
goto Round;
|
goto Round;
|
||||||
|
|
||||||
case FT_RENDER_MODE_NORMAL:
|
case FT_RENDER_MODE_NORMAL:
|
||||||
|
|
|
@ -31,6 +31,22 @@
|
||||||
static FT_Error
|
static FT_Error
|
||||||
ft_smooth_init( FT_Renderer render )
|
ft_smooth_init( FT_Renderer render )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
|
||||||
|
|
||||||
|
FT_Vector* sub = render->root.library->lcd_geometry;
|
||||||
|
|
||||||
|
|
||||||
|
/* set up default subpixel geometry for striped RGB panels. */
|
||||||
|
sub[0].x = -21;
|
||||||
|
sub[0].y = 0;
|
||||||
|
sub[1].x = 0;
|
||||||
|
sub[1].y = 0;
|
||||||
|
sub[2].x = 21;
|
||||||
|
sub[2].y = 0;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
|
render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -235,33 +251,33 @@
|
||||||
unsigned int width = bitmap->width;
|
unsigned int width = bitmap->width;
|
||||||
int pitch = bitmap->pitch;
|
int pitch = bitmap->pitch;
|
||||||
|
|
||||||
|
FT_Vector* sub = slot->library->lcd_geometry;
|
||||||
|
|
||||||
/* Render 3 separate monochrome bitmaps, shifting the outline */
|
|
||||||
/* by 1/3 pixel. */
|
/* Render 3 separate monochrome bitmaps, shifting the outline. */
|
||||||
width /= 3;
|
width /= 3;
|
||||||
|
|
||||||
bitmap->buffer += width;
|
FT_Outline_Translate( outline, -sub[0].x, -sub[0].y );
|
||||||
|
|
||||||
error = render->raster_render( render->raster, ¶ms );
|
error = render->raster_render( render->raster, ¶ms );
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
FT_Outline_Translate( outline, -21, 0 );
|
|
||||||
x_shift -= 21;
|
|
||||||
bitmap->buffer += width;
|
bitmap->buffer += width;
|
||||||
|
FT_Outline_Translate( outline, sub[0].x - sub[1].x, sub[0].y - sub[1].y );
|
||||||
error = render->raster_render( render->raster, ¶ms );
|
error = render->raster_render( render->raster, ¶ms );
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
FT_Outline_Translate( outline, 42, 0 );
|
bitmap->buffer += width;
|
||||||
x_shift += 42;
|
FT_Outline_Translate( outline, sub[1].x - sub[2].x, sub[1].y - sub[2].y );
|
||||||
|
error = render->raster_render( render->raster, ¶ms );
|
||||||
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
|
x_shift -= sub[2].x;
|
||||||
|
y_shift -= sub[2].y;
|
||||||
bitmap->buffer -= 2 * width;
|
bitmap->buffer -= 2 * width;
|
||||||
|
|
||||||
error = render->raster_render( render->raster, ¶ms );
|
|
||||||
if ( error )
|
|
||||||
goto Exit;
|
|
||||||
|
|
||||||
/* XXX: Rearrange the bytes according to FT_PIXEL_MODE_LCD. */
|
/* XXX: Rearrange the bytes according to FT_PIXEL_MODE_LCD. */
|
||||||
/* XXX: It is more efficient to render every third byte above. */
|
/* XXX: It is more efficient to render every third byte above. */
|
||||||
|
|
||||||
|
@ -286,34 +302,36 @@
|
||||||
{
|
{
|
||||||
int pitch = bitmap->pitch;
|
int pitch = bitmap->pitch;
|
||||||
|
|
||||||
|
FT_Vector* sub = slot->library->lcd_geometry;
|
||||||
|
|
||||||
/* Render 3 separate monochrome bitmaps, shifting the outline */
|
|
||||||
/* by 1/3 pixel. Triple the pitch to render on each third row. */
|
/* Render 3 separate monochrome bitmaps, shifting the outline. */
|
||||||
|
/* Notice that the subpixel geometry vectors are rotated. */
|
||||||
|
/* Triple the pitch to render on each third row. */
|
||||||
bitmap->pitch *= 3;
|
bitmap->pitch *= 3;
|
||||||
bitmap->rows /= 3;
|
bitmap->rows /= 3;
|
||||||
|
|
||||||
bitmap->buffer += pitch;
|
FT_Outline_Translate( outline, -sub[0].y, sub[0].x );
|
||||||
|
|
||||||
error = render->raster_render( render->raster, ¶ms );
|
error = render->raster_render( render->raster, ¶ms );
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
FT_Outline_Translate( outline, 0, 21 );
|
|
||||||
y_shift += 21;
|
|
||||||
bitmap->buffer += pitch;
|
bitmap->buffer += pitch;
|
||||||
|
FT_Outline_Translate( outline, sub[0].y - sub[1].y, sub[1].x - sub[0].x );
|
||||||
error = render->raster_render( render->raster, ¶ms );
|
error = render->raster_render( render->raster, ¶ms );
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
FT_Outline_Translate( outline, 0, -42 );
|
bitmap->buffer += pitch;
|
||||||
y_shift -= 42;
|
FT_Outline_Translate( outline, sub[1].y - sub[2].y, sub[2].x - sub[1].x );
|
||||||
|
error = render->raster_render( render->raster, ¶ms );
|
||||||
|
if ( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
|
x_shift -= sub[2].y;
|
||||||
|
y_shift += sub[2].x;
|
||||||
bitmap->buffer -= 2 * pitch;
|
bitmap->buffer -= 2 * pitch;
|
||||||
|
|
||||||
error = render->raster_render( render->raster, ¶ms );
|
|
||||||
if ( error )
|
|
||||||
goto Exit;
|
|
||||||
|
|
||||||
bitmap->pitch /= 3;
|
bitmap->pitch /= 3;
|
||||||
bitmap->rows *= 3;
|
bitmap->rows *= 3;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue