[ft-devel] preliminary analysis of the problem with cubic spline optimisation

2010-08-29 Thread Graham Asher
The aim is to draw a straight line between the start end end of a cubic 
spline, instead of rendering the curve correctly, if the curve deviates 
by less than a certain value from the straight line. The code in 
gray_render_cubic in ftgrays.c checks only the midpoint of the curve. 
However, this is not necessarily the furthest point from the straight 
line. If the sequence start, control1, control2, end is not monotonic in 
one of the dimensions x, y, an s-shaped curve is produced with points 
further from the line than the midpoint, which may even lie on the line. 
This situation occurs in 's' for the sample font.


With this information I can easily produce a fix, simply by testing for 
non-monotonicity and disabling the optimisation in such circumstances, 
but I shall see if I can up with something slightly better.


Graham


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


[ft-devel] Re: preliminary analysis of the problem with cubic spline optimisation

2010-08-29 Thread Graham Asher
Correction: it's not monotonicity that matters, but having the two 
control points on different sides of the straight line.


Graham Asher wrote:
The aim is to draw a straight line between the start end end of a 
cubic spline, instead of rendering the curve correctly, if the curve 
deviates by less than a certain value from the straight line. The code 
in gray_render_cubic in ftgrays.c checks only the midpoint of the 
curve. However, this is not necessarily the furthest point from the 
straight line. If the sequence start, control1, control2, end is not 
monotonic in one of the dimensions x, y, an s-shaped curve is produced 
with points further from the line than the midpoint, which may even 
lie on the line. This situation occurs in 's' for the sample font.


With this information I can easily produce a fix, simply by testing 
for non-monotonicity and disabling the optimisation in such 
circumstances, but I shall see if I can up with something slightly 
better.


Graham





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


[ft-devel] tentative fix for cubic spline bug

2010-08-29 Thread Graham Asher
Here's a fix that works. I'm trying to think of a faster way of doing 
it. The fix splits the cubic spline in two, guaranteeing that the 
resulting curves have their control points on the same side of the 
straight lines from start to end, then performs the original test for 
the distance (or rather maximum difference of x or y coord) of the curve 
midpoints from the straight lines. Below is a modified version of the 
start of gray_render_cubic. Suggestions for better fixes cheerfully 
welcomed. At least we now know what the problem is.


Graham

-

 static int
 gray_render_cubic( RAS_ARG_ FT_Vector*  control1,
 FT_Vector*  control2,
 FT_Vector*  to )
 {
   int top, level;
   int*levels;
   FT_Vector*  arc;
   int error = 0;

   /*
   Split the cubic into two, creating 7 points,
   then find the midpoints of the first and second curves.
   Find how far they are from the straight lines joining
   the start and end of the two curves. If they are close enough
   we can draw them as straight lines.
   */
   int x0, x1, x2, x3, x4, x5, x6, midx0, midx1;
   int y0, y1, y2, y3, y4, y5, y6, midy0, midy1;
   TPos dx0, dx1, dy0, dy1;
  
   x0 = DOWNSCALE(ras.x);

   x6 = to-x;
   x1 = (x0 + control1-x) / 2;
   x3 = (control1-x + control2-x) / 2;
   x5 = (control2-x + x6) / 2;
   x2 = (x1 + x3) / 2;
   x4 = (x3 + x5) / 2;
   x3 = (x2 + x4) / 2;   
   midx0 = (x0 + x3 + 3 * (x1 + x2)) / 8;

   midx1 = (x3 + x6 + 3 * (x4 + x5)) / 8;
   dx0 = x0 + x3 - (midx0  1); if (dx0  0) dx0 = -dx0;
   dx1 = x3 + x6 - (midx1  1); if (dx1  0) dx1 = -dx1;

   y0 = DOWNSCALE(ras.y);
   y6 = to-y;
   y1 = (y0 + control1-y) / 2;
   y3 = (control1-y + control2-y) / 2;
   y5 = (control2-y + y6) / 2;
   y2 = (y1 + y3) / 2;
   y4 = (y3 + y5) / 2;
   y3 = (y2 + y4) / 2;   
   midy0 = (y0 + y3 + 3 * (y1 + y2)) / 8;

   midy1 = (y3 + y6 + 3 * (y4 + y5)) / 8;
   dy0 = y0 + y3 - (midy0  1); if (dy0  0) dy0 = -dy0;
   dy1 = y3 + y6 - (midy1  1); if (dy1  0) dy1 = -dy1;

   if (dx0  dx1)
   dx0 = dx1;
   if (dx0  dy0)
   dx0 = dy0;
   if (dx0  dy1)
   dx0 = dy1;

   level = 1;
   dx0 /= ras.cubic_level;
   while ( dx0  0 )
   {
 dx0 = 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)
 x3 = ( ras.x + to_x +
   3 * UPSCALE( control1-x + control2-x ) ) / 8;
 y3 = ( ras.y + to_y +
   3 * UPSCALE( control1-y + control2-y ) ) / 8;
#endif

 error = gray_render_line( RAS_VAR_ x3, y3 );
 if (!error)
   error = gray_render_line( RAS_VAR_ to_x, to_y );
 return error;
   }


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


Re: [ft-devel] Re: preliminary analysis of the problem with cubic spline optimisation

2010-08-29 Thread James Cloos
 GA == Graham Asher graham.as...@btinternet.com writes:

GA Correction: it's not monotonicity that matters, but having the two
GA control points on different sides of the straight line.

Wouldn't the midpoint also fail to be the furthest point from the line
whenever the two off-curve control points are on the same side of the
midpoint?

-JimC
-- 
James Cloos cl...@jhcloos.com OpenPGP: 1024D/ED7DAEA6

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


Re: [ft-devel] Re: preliminary analysis of the problem with cubic spline optimisation

2010-08-29 Thread Graham Asher
It can happen, though. In fact I now don't think it can happen. If 
there are any good mathematicians out there (better than me at this, 
which sets quite a low bar), please confirm that no point on a cubic 
spline curve with both control points on the same side of the straight 
line from start to end can be further from the line than the curve's 
midpoint as defined by bisection of the curve.


Graham


Graham Asher wrote:
No, in nearly all cases the midpoint is the point on the curve 
furthest from the straight line when both control points are on the 
same side. It can happen, though. I'm now working on a fix depending 
on finding how far the furthest control point is from the straight 
line. No point on the curve can be further from the straight line than 
both control points.


Graham

James Cloos wrote:

GA == Graham Asher graham.as...@btinternet.com writes:



GA Correction: it's not monotonicity that matters, but having the two
GA control points on different sides of the straight line.

Wouldn't the midpoint also fail to be the furthest point from the line
whenever the two off-curve control points are on the same side of the
midpoint?

-JimC
  



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




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