Commit 9d0a3bd84804926c13808060fc9585a76648ef83

Alexei Podtelezhnikov 2016-09-06T23:59:33

[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.

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 );
   }