shithub: freetype+ttf2subf

Download patch

ref: 6e88087d6962714e2cf1d1ddba56cfeb2cf9c02c
parent: 0b3cb8a8afb15247ee55477f73e25e0ca3038e5b
author: Alexei Podtelezhnikov <[email protected]>
date: Thu May 5 19:41:03 EDT 2016

[smooth] More efficient accounting of conic splits and draws.

A single decrement counter of segments to draw, instead of an array,
contains all the information necessary to decide when to split and
when to draw a conic segment. The number of splits before each draw is
equal to the number of trailing zeros in the counter.

* src/smooth/ftgrays.c (gray_TWorker): Remove `lev_stack'.
(gray_render_conic): Updated to use decrement counter of segments.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2016-05-05  Alexei Podtelezhnikov  <[email protected]>
+
+	[smooth] More efficient accounting of conic splits and draws.
+
+	A single decrement counter of segments to draw, instead of an array,
+	contains all the information necessary to decide when to split and
+	when to draw a conic segment. The number of splits before each draw is
+	equal to the number of trailing zeros in the counter.
+
+	* src/smooth/ftgrays.c (gray_TWorker): Remove `lev_stack'.
+	(gray_render_conic): Updated to use decrement counter of segments.
+
 2016-05-05  Werner Lemberg  <[email protected]>
 
 	[cff, truetype] Fix logic for `FT_Property_Set'.
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -369,7 +369,7 @@
 
 
   /* These macros speed up repetitive divisions by replacing them */
-  /* with multiplications and right shifts.                       */ 
+  /* with multiplications and right shifts.                       */
 #define FT_UDIVPREP( b )                                       \
   long  b ## _r = (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b )
 #define FT_UDIV( a, b )                                        \
@@ -435,7 +435,6 @@
     TPos    x,  y;
 
     FT_Vector   bez_stack[32 * 3 + 1];
-    int         lev_stack[32];
 
     FT_Outline  outline;
     FT_Bitmap   target;
@@ -1068,50 +1067,44 @@
   gray_render_conic( RAS_ARG )
   {
     TPos        dx, dy;
-    int         top, level;
-    int*        levels = ras.lev_stack;
+    int         draw, split, level;
     FT_Vector*  arc = ras.bez_stack;
 
 
-    top      = 0;
-
     dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x );
     dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y );
     if ( dx < dy )
       dx = dy;
 
-    if ( dx < ONE_PIXEL / 4 )
-      goto Draw;
+    /* We can calculate the number of necessary bisections because  */
+    /* each bisection predictably reduces deviation exactly 4-fold. */
 
-    /* we can calculate the number of necessary bisections because  */
-    /* each bisection predictably reduces deviation at least 4-fold */
     level = 0;
-    do
+    while ( dx > ONE_PIXEL / 4 )
     {
       dx >>= 2;
       level++;
-    } while ( dx > ONE_PIXEL / 4 );
+    }
 
-    levels[0] = level;
+    /* We use decrement counter to count the total number of segments */
+    /* to draw starting from 2^level. Before each draw we split as    */
+    /* many times as there are trailing zeros in the counter.         */
 
+    draw = 1 << level;
     do
     {
-      level = levels[top];
-      if ( level > 0 )
+      split = 1;
+      while ( ( draw & split ) == 0 )
       {
         gray_split_conic( arc );
         arc += 2;
-        top++;
-        levels[top] = levels[top - 1] = level - 1;
-        continue;
+        split <<= 1;
       }
 
-    Draw:
       gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
-      top--;
       arc -= 2;
 
-    } while ( top >= 0 );
+    } while ( --draw );
   }