[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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
diff --git a/ChangeLog b/ChangeLog
index efb1406..c332389 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2016-09-06 Alexei Podtelezhnikov <apodtele@gmail.com>
+ [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 <apodtele@gmail.com>
+
[smooth] Improve contour start (take 2).
* src/smooth/ftgrays.c (gray_move_to): Call `gray_set_cell' directly
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 059a6bd..5aa6472 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 );
}