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