#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftobjs.h>
#include <freetype/ftoutln.h>
#include "ftsmooth.h"
#include "ftgrays.h"
#include "ftsmerrs.h"
static FT_Error
ft_smooth_set_mode( FT_Renderer render,
FT_ULong mode_tag,
FT_Pointer data )
{ … }
static FT_Error
ft_smooth_transform( FT_Renderer render,
FT_GlyphSlot slot,
const FT_Matrix* matrix,
const FT_Vector* delta )
{ … }
static void
ft_smooth_get_cbox( FT_Renderer render,
FT_GlyphSlot slot,
FT_BBox* cbox )
{ … }
TOrigin;
#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
static FT_Error
ft_smooth_init( FT_Module module )
{
FT_Renderer render = (FT_Renderer)module;
FT_Vector* sub = render->root.library->lcd_geometry;
sub[0].x = -21;
sub[0].y = 0;
sub[1].x = 0;
sub[1].y = 0;
sub[2].x = 21;
sub[2].y = 0;
render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
return 0;
}
static void
ft_smooth_lcd_spans( int y,
int count,
const FT_Span* spans,
void* target_ )
{
TOrigin* target = (TOrigin*)target_;
unsigned char* dst_line = target->origin - y * target->pitch;
unsigned char* dst;
unsigned short w;
for ( ; count--; spans++ )
for ( dst = dst_line + spans->x * 3, w = spans->len; w--; dst += 3 )
*dst = spans->coverage;
}
static FT_Error
ft_smooth_raster_lcd( FT_Renderer render,
FT_Outline* outline,
FT_Bitmap* bitmap )
{
FT_Error error = FT_Err_Ok;
FT_Vector* sub = render->root.library->lcd_geometry;
FT_Pos x, y;
FT_Raster_Params params;
TOrigin target;
params.source = outline;
params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
params.gray_spans = ft_smooth_lcd_spans;
params.user = ⌖
params.clip_box.xMin = 0;
params.clip_box.yMin = 0;
params.clip_box.xMax = bitmap->width;
params.clip_box.yMax = bitmap->rows;
if ( bitmap->pitch < 0 )
target.origin = bitmap->buffer;
else
target.origin = bitmap->buffer
+ ( bitmap->rows - 1 ) * (unsigned int)bitmap->pitch;
target.pitch = bitmap->pitch;
FT_Outline_Translate( outline,
-sub[0].x,
-sub[0].y );
error = render->raster_render( render->raster, ¶ms );
x = sub[0].x;
y = sub[0].y;
if ( error )
goto Exit;
target.origin++;
FT_Outline_Translate( outline,
sub[0].x - sub[1].x,
sub[0].y - sub[1].y );
error = render->raster_render( render->raster, ¶ms );
x = sub[1].x;
y = sub[1].y;
if ( error )
goto Exit;
target.origin++;
FT_Outline_Translate( outline,
sub[1].x - sub[2].x,
sub[1].y - sub[2].y );
error = render->raster_render( render->raster, ¶ms );
x = sub[2].x;
y = sub[2].y;
Exit:
FT_Outline_Translate( outline, x, y );
return error;
}
static FT_Error
ft_smooth_raster_lcdv( FT_Renderer render,
FT_Outline* outline,
FT_Bitmap* bitmap )
{
FT_Error error = FT_Err_Ok;
int pitch = bitmap->pitch;
FT_Vector* sub = render->root.library->lcd_geometry;
FT_Pos x, y;
FT_Raster_Params params;
params.target = bitmap;
params.source = outline;
params.flags = FT_RASTER_FLAG_AA;
bitmap->pitch *= 3;
bitmap->rows /= 3;
FT_Outline_Translate( outline,
-sub[0].y,
sub[0].x );
error = render->raster_render( render->raster, ¶ms );
x = sub[0].y;
y = -sub[0].x;
if ( error )
goto Exit;
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 );
x = sub[1].y;
y = -sub[1].x;
bitmap->buffer -= pitch;
if ( error )
goto Exit;
bitmap->buffer += 2 * pitch;
FT_Outline_Translate( outline,
sub[1].y - sub[2].y,
sub[2].x - sub[1].x );
error = render->raster_render( render->raster, ¶ms );
x = sub[2].y;
y = -sub[2].x;
bitmap->buffer -= 2 * pitch;
Exit:
FT_Outline_Translate( outline, x, y );
bitmap->pitch /= 3;
bitmap->rows *= 3;
return error;
}
#else
static FT_Error
ft_smooth_init( FT_Module module )
{ … }
static FT_Error
ft_smooth_raster_lcd( FT_Renderer render,
FT_Outline* outline,
FT_Bitmap* bitmap )
{ … }
static FT_Error
ft_smooth_raster_lcdv( FT_Renderer render,
FT_Outline* outline,
FT_Bitmap* bitmap )
{ … }
#endif
#define SCALE …
static void
ft_smooth_overlap_spans( int y,
int count,
const FT_Span* spans,
void* target_ )
{ … }
static FT_Error
ft_smooth_raster_overlap( FT_Renderer render,
FT_Outline* outline,
FT_Bitmap* bitmap )
{ … }
#undef SCALE
static FT_Error
ft_smooth_render( FT_Renderer render,
FT_GlyphSlot slot,
FT_Render_Mode mode,
const FT_Vector* origin )
{ … }
FT_DEFINE_RENDERER(
ft_smooth_renderer_class,
FT_MODULE_RENDERER,
sizeof ( FT_RendererRec ),
"smooth",
0x10000L,
0x20000L,
NULL,
(FT_Module_Constructor)ft_smooth_init,
(FT_Module_Destructor) NULL,
(FT_Module_Requester) NULL,
FT_GLYPH_FORMAT_OUTLINE,
(FT_Renderer_RenderFunc) ft_smooth_render,
(FT_Renderer_TransformFunc)ft_smooth_transform,
(FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox,
(FT_Renderer_SetModeFunc) ft_smooth_set_mode,
(FT_Raster_Funcs*)&ft_grays_raster
)