[smooth] Restore the span buffering for direct mode only.

The buffer size FT_MAX_GRAY_SPANS is set to 10 spans, which should be
enough to cover the entire scanline for simple glyphs in most cases:
each slightly slanted edge needs up to two spans, plus a filling span
in-between.  This is not new, we used to do it before cb4388783c.

* src/smooth/ftgrays.c (gray_TWorker): Add `spans' and `num_spans'.
(gray_hline, gray_sweep): Implement the span buffering.
(gray_raster_render): Use negative `num_spans' to avoid the direct
mode.
This commit is contained in:
Alexei Podtelezhnikov 2019-06-13 00:17:36 -04:00
parent 59e0c6f92e
commit e7ac9288ac
2 changed files with 39 additions and 6 deletions

View File

@ -1,3 +1,17 @@
2019-06-13 Alexei Podtelezhnikov <apodtele@gmail.com>
[smooth] Restore the span buffering for direct mode only.
The buffer size FT_MAX_GRAY_SPANS is set to 10 spans, which should be
enough to cover the entire scanline for simple glyphs in most cases:
each slightly slanted edge needs up to two spans, plus a filling span
in-between. This is not new, we used to do it before cb4388783cecc.
* src/smooth/ftgrays.c (gray_TWorker): Add `spans' and `num_spans'.
(gray_hline, gray_sweep): Implement the span buffering.
(gray_raster_render): Use negative `num_spans' to avoid the direct
mode.
2019-06-12 Alexei Podtelezhnikov <apodtele@gmail.com>
* include/freetype/ftmodapi.h (FT_DebugHook_Func): Return error.

View File

@ -432,6 +432,9 @@ typedef ptrdiff_t FT_PtrDist;
#define FT_MAX_GRAY_POOL ( 2048 / sizeof ( TCell ) )
#endif
/* FT_Span buffer size for direct rendering only */
#define FT_MAX_GRAY_SPANS 10
#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
/* We disable the warning `structure was padded due to */
@ -465,6 +468,8 @@ typedef ptrdiff_t FT_PtrDist;
FT_Raster_Span_Func render_span;
void* render_span_data;
FT_Span spans[FT_MAX_GRAY_SPANS];
int num_spans;
} gray_TWorker, *gray_PWorker;
@ -1226,16 +1231,21 @@ typedef ptrdiff_t FT_PtrDist;
coverage = 255;
}
if ( ras.render_span ) /* for FT_RASTER_FLAG_DIRECT only */
if ( ras.num_spans >= 0 ) /* for FT_RASTER_FLAG_DIRECT only */
{
FT_Span span;
FT_Span* span = ras.spans + ras.num_spans++;
span.x = (short)x;
span.len = (unsigned short)acount;
span.coverage = (unsigned char)coverage;
span->x = (short)x;
span->len = (unsigned short)acount;
span->coverage = (unsigned char)coverage;
ras.render_span( y, 1, &span, ras.render_span_data );
if ( ras.num_spans == FT_MAX_GRAY_SPANS )
{
/* flush the span buffer and reset the count */
ras.render_span( y, ras.num_spans, ras.spans, ras.render_span_data );
ras.num_spans = 0;
}
}
else
{
@ -1309,6 +1319,13 @@ typedef ptrdiff_t FT_PtrDist;
if ( cover != 0 )
gray_hline( RAS_VAR_ x, y, cover, ras.max_ex - x );
if ( ras.num_spans > 0 ) /* for FT_RASTER_FLAG_DIRECT only */
{
/* flush the span buffer and reset the count */
ras.render_span( y, ras.num_spans, ras.spans, ras.render_span_data );
ras.num_spans = 0;
}
}
}
@ -1778,6 +1795,7 @@ typedef ptrdiff_t FT_PtrDist;
ras.render_span = (FT_Raster_Span_Func)params->gray_spans;
ras.render_span_data = params->user;
ras.num_spans = 0;
ras.min_ex = params->clip_box.xMin;
ras.min_ey = params->clip_box.yMin;
@ -1807,6 +1825,7 @@ typedef ptrdiff_t FT_PtrDist;
ras.render_span = (FT_Raster_Span_Func)NULL;
ras.render_span_data = NULL;
ras.num_spans = -1; /* invalid */
ras.min_ex = 0;
ras.min_ey = 0;