Re: [ft-devel] version 3 of the spline flattening patch

2010-09-20 Thread Werner LEMBERG

  Here is a third and I hope final version of the spline flattening
  patch, incorporating the latest version of David Bevan's cubic
  spline flattening routine.

Thanks a lot, Graham and David!  The code is now in the git
repository, with minor changes, mainly for readability and to replace
`labs' with `FT_ABS'.  Please test and check whether everything is OK.

There is still one pending valgrind warning to fix (not related to the
flattening patch), then I'll do a new release.


Werner

___
Freetype-devel mailing list
Freetype-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/freetype-devel


[ft-devel] version 3 of the spline flattening patch

2010-09-19 Thread Graham Asher
 Here is a third and I hope final version of the spline flattening 
patch, incorporating the latest version of David Bevan's cubic spline 
flattening routine.


Notes:

1. As with the previous versions, it solves the bug in flattening 
s-shaped curves (cubic with control points on both sides of the chord).


2. I have incorporated David's latest code as is. However, I have 
expanded his comments, most importantly (i) by giving the reference to 
Hain's paper in full rather than as a tinyurl, so as to make it easier 
to find elsewhere if it is moved or if the tinyurl service is 
discontinued, and (ii) by incorporating a detailed explanation he 
provided of the calculation of L.


3. It may be thought advisable to split the patch into two: one for 
cubics, which is essential because it fixes a bug, and one for conics, 
which is not essential but gives some speed improvement and simpler 
code. I leave that up to Werner.



Graham

diff --git a/C:\\DOCUME~1\\Graham\\LOCALS~1\\Temp\\ftgrays_c8f5b9.c 
b/C:\\DOCUME~1\\Graham\\LOCALS~1\\Temp\\ftgrays_f4f03b.c
index 0b94143..a3a7a31 100644
--- a/C:\\DOCUME~1\\Graham\\LOCALS~1\\Temp\\ftgrays_c8f5b9.c
+++ b/C:\\DOCUME~1\\Graham\\LOCALS~1\\Temp\\ftgrays_f4f03b.c
@@ -90,6 +90,9 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_smooth
 
+/* The maximum distance of a curve from the chord, in 64ths of a pixel; */
+/* used when flattening curves. */
+#define FT_MAX_CURVE_DEVIATION 16
 
 #ifdef _STANDALONE_
 
@@ -354,8 +357,6 @@ typedef ptrdiff_t  FT_PtrDist;
 
 int  band_size;
 int  band_shoot;
-int  conic_level;
-int  cubic_level;
 
 ft_jmp_buf  jump_buffer;
 
@@ -888,31 +889,18 @@ typedef ptrdiff_t  FT_PtrDist;
 if ( dx  dy )
   dx = dy;
 
-level = 1;
-dx = dx / ras.conic_level;
-while ( dx  0 )
+if ( dx = FT_MAX_CURVE_DEVIATION )
 {
-  dx = 2;
-  level++;
+  gray_render_line( RAS_VAR_ UPSCALE( to-x ), UPSCALE( to-y ) );
+  return;
 }
 
-/* a shortcut to speed things up */
-if ( level = 1 )
+level = 1;
+dx /= FT_MAX_CURVE_DEVIATION;
+while ( dx  1 )
 {
-  /* we compute the mid-point directly in order to avoid */
-  /* calling gray_split_conic()  */
-  TPos  to_x, to_y, mid_x, mid_y;
-
-
-  to_x  = UPSCALE( to-x );
-  to_y  = UPSCALE( to-y );
-  mid_x = ( ras.x + to_x + 2 * UPSCALE( control-x ) ) / 4;
-  mid_y = ( ras.y + to_y + 2 * UPSCALE( control-y ) ) / 4;
-
-  gray_render_line( RAS_VAR_ mid_x, mid_y );
-  gray_render_line( RAS_VAR_ to_x, to_y );
-
-  return;
+  dx = 2;
+  level++;
 }
 
 arc   = ras.bez_stack;
@@ -957,21 +945,9 @@ typedef ptrdiff_t  FT_PtrDist;
   }
 
 Draw:
-  {
-TPos  to_x, to_y, mid_x, mid_y;
-
-
-to_x  = arc[0].x;
-to_y  = arc[0].y;
-mid_x = ( ras.x + to_x + 2 * arc[1].x ) / 4;
-mid_y = ( ras.y + to_y + 2 * arc[1].y ) / 4;
-
-gray_render_line( RAS_VAR_ mid_x, mid_y );
-gray_render_line( RAS_VAR_ to_x, to_y );
-
-top--;
-arc -= 2;
-  }
+  gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
+  top--;
+  arc -= 2;
 }
 
 return;
@@ -1011,55 +987,8 @@ typedef ptrdiff_t  FT_PtrDist;
   const FT_Vector*  control2,
   const FT_Vector*  to )
   {
-int top, level;
-int*levels;
 FT_Vector*  arc;
-int mid_x = ( DOWNSCALE( ras.x ) + to-x +
-  3 * (control1-x + control2-x ) ) / 8;
-int mid_y = ( DOWNSCALE( ras.y ) + to-y +
-  3 * (control1-y + control2-y ) ) / 8;
-TPosdx = DOWNSCALE( ras.x ) + to-x - ( mid_x  1 );
-TPosdy = DOWNSCALE( ras.y ) + to-y - ( mid_y  1 );
-
 
-if ( dx  0 )
-  dx = -dx;
-if ( dy  0 )
-  dy = -dy;
-if ( dx  dy )
-  dx = dy;
-
-level = 1;
-dx /= ras.cubic_level;
-while ( dx  0 )
-{
-  dx = 2;
-  level++;
-}
-
-if ( level = 1 )
-{
-  TPos  to_x, to_y;
-
-
-  to_x  = UPSCALE( to-x );
-  to_y  = UPSCALE( to-y );
-
-  /* Recalculation of midpoint is needed only if */
-  /* UPSCALE and DOWNSCALE have any effect.  */
-
-#if ( PIXEL_BITS != 6 )
-  mid_x = ( ras.x + to_x +
-3 * UPSCALE( control1-x + control2-x ) ) / 8;
-  mid_y = ( ras.y + to_y +
-3 * UPSCALE( control1-y + control2-y ) ) / 8;
-#endif
-
-  gray_render_line( RAS_VAR_ mid_x, mid_y );
-  gray_render_line( RAS_VAR_ to_x, to_y );
-
-  return;
-}
 
 arc  = ras.bez_stack;
 arc[0].x = UPSCALE( to-x );
@@ -1071,60 +1000,98 @@ typedef ptrdiff_t  FT_PtrDist;
 arc[3].x = ras.x;
 arc[3].y = ras.y;
 
-levels= ras.lev_stack;
-top   = 0;
-levels[0] = level;
-
-while ( top = 0 )
+for (;;)
 {
-  level = levels[top];
-  if ( level  1 )
-  {
-