[smooth] Use direct rendering mode in Harmony.
Instead of rendering 3 bitmaps side by side and reshuffling, we use direct rendering to deliver the bitmaps on each third byte. * src/smooth/ftsmooth.c (ft_smooth_raster_lcd) [!FT_CONFIG_OPTION_SUBPIXEL_RENDERING]: Set up direct mode with... (ft_smooth_lcd_spans): ... new span function.
This commit is contained in:
parent
2d67511a14
commit
19d39f43d2
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2020-07-03 Alexei Podtelezhnikov <apodtele@gmail.com>
|
||||||
|
|
||||||
|
[smooth] Use direct rendering mode in Harmony.
|
||||||
|
|
||||||
|
Instead of rendering 3 bitmaps side by side and reshuffling, we use
|
||||||
|
direct rendering to deliver the bitmaps on each third byte.
|
||||||
|
|
||||||
|
* src/smooth/ftsmooth.c (ft_smooth_raster_lcd)
|
||||||
|
[!FT_CONFIG_OPTION_SUBPIXEL_RENDERING]: Set up direct mode with...
|
||||||
|
(ft_smooth_lcd_spans): ... new span function.
|
||||||
|
|
||||||
2020-07-03 Alexei Podtelezhnikov <apodtele@gmail.com>
|
2020-07-03 Alexei Podtelezhnikov <apodtele@gmail.com>
|
||||||
|
|
||||||
[smooth] Separate LCD paths from gray rendering.
|
[smooth] Separate LCD paths from gray rendering.
|
||||||
|
|
|
@ -76,6 +76,13 @@
|
||||||
FT_Outline_Get_CBox( &slot->outline, cbox );
|
FT_Outline_Get_CBox( &slot->outline, cbox );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct TOrigin_
|
||||||
|
{
|
||||||
|
unsigned char* origin; /* pixmap origin at the bottom-left */
|
||||||
|
int pitch; /* pitch to go down one row */
|
||||||
|
|
||||||
|
} TOrigin;
|
||||||
|
|
||||||
#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
|
#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
|
||||||
|
|
||||||
/* initialize renderer -- init its raster */
|
/* initialize renderer -- init its raster */
|
||||||
|
@ -99,24 +106,58 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This function writes every third byte in direct rendering mode */
|
||||||
|
static void
|
||||||
|
ft_smooth_lcd_spans( int y,
|
||||||
|
int count,
|
||||||
|
const FT_Span* spans,
|
||||||
|
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
|
static FT_Error
|
||||||
ft_smooth_raster_lcd( FT_Renderer render,
|
ft_smooth_raster_lcd( FT_Renderer render,
|
||||||
FT_Outline* outline,
|
FT_Outline* outline,
|
||||||
FT_Bitmap* bitmap )
|
FT_Bitmap* bitmap )
|
||||||
{
|
{
|
||||||
FT_Error error = FT_Err_Ok;
|
FT_Error error = FT_Err_Ok;
|
||||||
unsigned int width = bitmap->width / 3;
|
|
||||||
FT_Vector* sub = render->root.library->lcd_geometry;
|
FT_Vector* sub = render->root.library->lcd_geometry;
|
||||||
FT_Pos x, y;
|
FT_Pos x, y;
|
||||||
|
|
||||||
FT_Raster_Params params;
|
FT_Raster_Params params;
|
||||||
|
TOrigin target;
|
||||||
|
|
||||||
|
|
||||||
params.target = bitmap;
|
|
||||||
params.source = outline;
|
|
||||||
params.flags = FT_RASTER_FLAG_AA;
|
|
||||||
|
|
||||||
/* Render 3 separate coverage bitmaps, shifting the outline. */
|
/* Render 3 separate coverage bitmaps, shifting the outline. */
|
||||||
|
/* Set up direct rendering to record them on each third byte. */
|
||||||
|
params.target = bitmap;
|
||||||
|
params.source = outline;
|
||||||
|
params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
|
||||||
|
params.gray_spans = (FT_SpanFunc)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,
|
FT_Outline_Translate( outline,
|
||||||
-sub[0].x,
|
-sub[0].x,
|
||||||
-sub[0].y );
|
-sub[0].y );
|
||||||
|
@ -126,57 +167,23 @@
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
bitmap->buffer += width;
|
target.origin++;
|
||||||
FT_Outline_Translate( outline,
|
FT_Outline_Translate( outline,
|
||||||
sub[0].x - sub[1].x,
|
sub[0].x - sub[1].x,
|
||||||
sub[0].y - sub[1].y );
|
sub[0].y - sub[1].y );
|
||||||
error = render->raster_render( render->raster, ¶ms );
|
error = render->raster_render( render->raster, ¶ms );
|
||||||
x = sub[1].x;
|
x = sub[1].x;
|
||||||
y = sub[1].y;
|
y = sub[1].y;
|
||||||
bitmap->buffer -= width;
|
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
bitmap->buffer += 2 * width;
|
target.origin++;
|
||||||
FT_Outline_Translate( outline,
|
FT_Outline_Translate( outline,
|
||||||
sub[1].x - sub[2].x,
|
sub[1].x - sub[2].x,
|
||||||
sub[1].y - sub[2].y );
|
sub[1].y - sub[2].y );
|
||||||
error = render->raster_render( render->raster, ¶ms );
|
error = render->raster_render( render->raster, ¶ms );
|
||||||
x = sub[2].x;
|
x = sub[2].x;
|
||||||
y = sub[2].y;
|
y = sub[2].y;
|
||||||
bitmap->buffer -= 2 * width;
|
|
||||||
if ( error )
|
|
||||||
goto Exit;
|
|
||||||
|
|
||||||
/* XXX: Rearrange the bytes according to FT_PIXEL_MODE_LCD. */
|
|
||||||
/* XXX: It is more efficient to render every third byte above. */
|
|
||||||
{
|
|
||||||
FT_Memory memory = render->root.memory;
|
|
||||||
FT_Byte* line;
|
|
||||||
FT_Byte* temp = NULL;
|
|
||||||
FT_UInt i, j;
|
|
||||||
|
|
||||||
unsigned int height = bitmap->rows;
|
|
||||||
int pitch = bitmap->pitch;
|
|
||||||
|
|
||||||
|
|
||||||
if ( FT_ALLOC( temp, (FT_ULong)pitch ) )
|
|
||||||
goto Exit;
|
|
||||||
|
|
||||||
for ( i = 0; i < height; i++ )
|
|
||||||
{
|
|
||||||
line = bitmap->buffer + i * (FT_ULong)pitch;
|
|
||||||
for ( j = 0; j < width; j++ )
|
|
||||||
{
|
|
||||||
temp[3 * j ] = line[j];
|
|
||||||
temp[3 * j + 1] = line[j + width];
|
|
||||||
temp[3 * j + 2] = line[j + width + width];
|
|
||||||
}
|
|
||||||
FT_MEM_COPY( line, temp, pitch );
|
|
||||||
}
|
|
||||||
|
|
||||||
FT_FREE( temp );
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
FT_Outline_Translate( outline, x, y );
|
FT_Outline_Translate( outline, x, y );
|
||||||
|
|
Loading…
Reference in New Issue