freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ft-devel] a satisfactory fix for the cubic spline bug


From: Graham Asher
Subject: [ft-devel] a satisfactory fix for the cubic spline bug
Date: Mon, 30 Aug 2010 10:59:11 +0100
User-agent: Thunderbird 2.0.0.24 (Windows/20100228)

I thought about this overnight and realised that we can slightly modify the existing heuristic to get a much simpler fix. Instead of trying to find points on the curve or trying to measure the distance from a point to a straight line, we adapt the earlier idea, used in existing FreeType code, of finding the maximum coordinate difference (that is, whichever is greater of dx and dy):

* existing method: use max coordinate difference between middle of spline, found by bisection, and middle of straight line

* new method: use max coordinate difference between either of the two control points and the middle of the straight line

This yields the following code (start of gray_render_cubic), which works, fixes the bug, and is probably faster, because it is certainly simpler. I don't think I'll go any further than this.

 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;

   /*
   Find the furthest distance of a coordinate of a control point from the
   midpoint of the line.
   */
   int dx1, dy1, dx2, dy2;
   int midx = (DOWNSCALE(ras.x) + to->x) / 2;
   int midy = (DOWNSCALE(ras.y) + to->y) / 2;
   dx1 = control1->x - midx; if (dx1 < 0) dx1 = -dx1;
   dy1 = control1->y - midy; if (dy1 < 0) dy1 = -dy1;
   dx2 = control2->x - midx; if (dx2 < 0) dx2 = -dx2;
   dy2 = control2->y - midy; if (dy2 < 0) dy2 = -dy2;
   if (dx1 < dy1)
       dx1 = dy1;
   if (dx1 < dx2)
       dx1 = dx2;
   if (dx1 < dy2)
       dx1 = dy2;

   if (dx1 <= ras.cubic_level)
return gray_render_line( RAS_VAR_ to->x, to->y );
   level = 1;
   dx1 /= ras.cubic_level;
   while ( dx1 > 0 )
   {
     dx1 >>= 2;
     level++;
   }


Graham




reply via email to

[Prev in Thread] Current Thread [Next in Thread]