diff --git a/ChangeLog b/ChangeLog index efb140633..c33238952 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2016-09-06 Alexei Podtelezhnikov + + [smooth] Operate in absolute bitmap coordinates. + + Simpler bitmap addressing improves performance by 1.5%. + + * src/smooth/ftgrays.c (gray_TWorker): Remove count fields. + (gray_dump_cells, gray_find_cell, gray_set_cell, gray_hline, + gray_sweep, gray_convert_glyph, gray_raster_render): Updated. + 2016-09-06 Alexei Podtelezhnikov [smooth] Improve contour start (take 2). diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c index 059a6bde0..5aa64720b 100644 --- a/src/smooth/ftgrays.c +++ b/src/smooth/ftgrays.c @@ -433,7 +433,6 @@ typedef ptrdiff_t FT_PtrDist; TCoord ex, ey; TCoord min_ex, max_ex; TCoord min_ey, max_ey; - TCoord count_ex, count_ey; TArea area; TCoord cover; @@ -481,17 +480,17 @@ typedef ptrdiff_t FT_PtrDist; static void gray_dump_cells( RAS_ARG ) { - int yindex; + int y; - for ( yindex = 0; yindex < ras.count_ey; yindex++ ) + for ( y = ras.min_ey; y < ras.max_ey; y++ ) { - PCell cell; + PCell cell = ras.ycells[y - ras.min_ey]; - printf( "%3d:", yindex ); + printf( "%3d:", y ); - for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) + for ( ; cell != NULL; cell = cell->next ) printf( " (%3d, c:%4d, a:%6d)", cell->x, cell->cover, cell->area ); printf( "\n" ); @@ -512,10 +511,10 @@ typedef ptrdiff_t FT_PtrDist; TCoord x = ras.ex; - if ( x > ras.count_ex ) - x = ras.count_ex; + if ( x > ras.max_ex ) + x = ras.max_ex; - pcell = &ras.ycells[ras.ey]; + pcell = &ras.ycells[ras.ey - ras.min_ey]; for (;;) { cell = *pcell; @@ -578,14 +577,11 @@ typedef ptrdiff_t FT_PtrDist; /* All cells that are on the left of the clipping region go to the */ /* min_ex - 1 horizontal position. */ - ey -= ras.min_ey; - if ( ex > ras.max_ex ) ex = ras.max_ex; - ex -= ras.min_ex; - if ( ex < 0 ) - ex = -1; + if ( ex < ras.min_ex ) + ex = ras.min_ex - 1; /* are we moving to a different cell ? */ if ( ex != ras.ex || ey != ras.ey ) @@ -600,8 +596,8 @@ typedef ptrdiff_t FT_PtrDist; ras.ey = ey; } - ras.invalid = ( (unsigned int)ey >= (unsigned int)ras.count_ey || - ex >= ras.count_ex ); + ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey || + ex >= ras.max_ex ); } @@ -1281,17 +1277,15 @@ typedef ptrdiff_t FT_PtrDist; if ( ras.render_span ) /* for FT_RASTER_FLAG_DIRECT only */ { - span.x = (short)( x + ras.min_ex ); + span.x = (short)x; span.len = (unsigned short)acount; span.coverage = (unsigned char)coverage; - ras.render_span( y + ras.min_ey, 1, &span, ras.render_span_data ); + ras.render_span( y, 1, &span, ras.render_span_data ); } else { - unsigned char* q = ras.target.origin - - ras.target.pitch * ( y + ras.min_ey ) + - x + ras.min_ex; + unsigned char* q = ras.target.origin - ras.target.pitch * y + x; unsigned char c = (unsigned char)coverage; @@ -1319,7 +1313,7 @@ typedef ptrdiff_t FT_PtrDist; static void gray_sweep( RAS_ARG ) { - int yindex; + int y; if ( ras.num_cells == 0 ) @@ -1327,11 +1321,11 @@ typedef ptrdiff_t FT_PtrDist; FT_TRACE7(( "gray_sweep: start\n" )); - for ( yindex = 0; yindex < ras.count_ey; yindex++ ) + for ( y = ras.min_ey; y < ras.max_ey; y++ ) { - PCell cell = ras.ycells[yindex]; + PCell cell = ras.ycells[y - ras.min_ey]; TCoord cover = 0; - TCoord x = 0; + TCoord x = ras.min_ex; for ( ; cell != NULL; cell = cell->next ) @@ -1340,21 +1334,21 @@ typedef ptrdiff_t FT_PtrDist; if ( cell->x > x && cover != 0 ) - gray_hline( RAS_VAR_ x, yindex, (TArea)cover * ( ONE_PIXEL * 2 ), + gray_hline( RAS_VAR_ x, y, (TArea)cover * ( ONE_PIXEL * 2 ), cell->x - x ); cover += cell->cover; area = (TArea)cover * ( ONE_PIXEL * 2 ) - cell->area; - if ( area != 0 && cell->x >= 0 ) - gray_hline( RAS_VAR_ cell->x, yindex, area, 1 ); + if ( area != 0 && cell->x >= ras.min_ex ) + gray_hline( RAS_VAR_ cell->x, y, area, 1 ); x = cell->x + 1; } if ( cover != 0 ) - gray_hline( RAS_VAR_ x, yindex, (TArea)cover * ( ONE_PIXEL * 2 ), - ras.count_ex - x ); + gray_hline( RAS_VAR_ x, y, (TArea)cover * ( ONE_PIXEL * 2 ), + ras.max_ex - x ); } FT_TRACE7(( "gray_sweep: end\n" )); @@ -1769,6 +1763,7 @@ typedef ptrdiff_t FT_PtrDist; { TCell buffer[FT_MAX_GRAY_POOL]; TCoord band_size = FT_MAX_GRAY_POOL / 8; + TCoord count = ras.max_ey - ras.min_ey; int num_bands; TCoord min, max, max_y; TCoord bands[32]; /* enough to accommodate bisections */ @@ -1776,11 +1771,11 @@ typedef ptrdiff_t FT_PtrDist; /* set up vertical bands */ - if ( ras.count_ey > band_size ) + if ( count > band_size ) { /* two divisions rounded up */ - num_bands = (int)( ( ras.count_ey + band_size - 1) / band_size ); - band_size = ( ras.count_ey + num_bands - 1 ) / num_bands; + num_bands = (int)( ( count + band_size - 1) / band_size ); + band_size = ( count + num_bands - 1 ) / num_bands; } min = ras.min_ey; @@ -1826,7 +1821,6 @@ typedef ptrdiff_t FT_PtrDist; ras.invalid = 1; ras.min_ey = band[1]; ras.max_ey = ras.ey = band[0]; - ras.count_ey = width; error = gray_convert_glyph_inner( RAS_VAR ); @@ -1971,9 +1965,6 @@ typedef ptrdiff_t FT_PtrDist; if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey ) return 0; - ras.count_ex = ras.max_ex - ras.min_ex; - ras.count_ey = ras.max_ey - ras.min_ey; - return gray_convert_glyph( RAS_VAR ); }