Re: [ft-devel] Re: possible inefficiency in gray_render_cubic
Calculate the midpoint and compare it with start and end: [...] For me, this looks good. Thanks for working on this. I am sceptical about the need to calculate both da and db. Perhaps db only will suffice. I hope that David or Werner can comment. This is something Ken can probably check: He has a large database for Ghostscript to compare rendering results, and artifacts introduced by the simplified shorthand calculation would easily show up, I think. Below is a patch according to your data (hopefully, I've understood you correctly). Please check and test. Werner == --- ftgrays.c.orig 2009-07-31 18:45:19.0 +0200 +++ ftgrays.c 2010-06-08 09:56:23.0 +0200 @@ -1007,45 +1007,40 @@ const FT_Vector* control2, const FT_Vector* to ) { -TPosdx, dy, da, db; +TPosdx, dy; +TPosmid_x, mid_y; int top, level; int*levels; FT_Vector* arc; -dx = DOWNSCALE( ras.x ) + to-x - ( control1-x 1 ); -if ( dx 0 ) - dx = -dx; -dy = DOWNSCALE( ras.y ) + to-y - ( control1-y 1 ); -if ( dy 0 ) - dy = -dy; -if ( dx dy ) - dx = dy; -da = dx; +/* Calculate midpoint and compare it with start and end. */ +mid_x = ( DOWNSCALE( ras.x ) + to-x + + 3 * ( control1-x + control2-x ) ) / 8; +mid_y = ( DOWNSCALE( ras.y ) + to-y + + 3 * ( control1-y + control2-y ) ) / 8; -dx = DOWNSCALE( ras.x ) + to-x - 3 * ( control1-x + control2-x ); +dx = DOWNSCALE( ras.x ) + to-x - ( mid_x 1 ); if ( dx 0 ) dx = -dx; -dy = DOWNSCALE( ras.y ) + to-y - 3 * ( control1-x + control2-y ); +dy = DOWNSCALE( ras.y ) + to-y - ( mid_y 1 ); if ( dy 0 ) dy = -dy; if ( dx dy ) dx = dy; -db = dx; +/* Check whether an approximation with straight lines is sufficient. */ level = 1; -da= da / ras.cubic_level; -db= db / ras.conic_level; -while ( da 0 || db 0 ) +dx= dx / ras.conic_level; +while ( dx 0 ) { - da = 2; - db = 3; + dx = 3; level++; } if ( level = 1 ) { - TPos to_x, to_y, mid_x, mid_y; + TPos to_x, to_y; to_x = UPSCALE( to-x ); @@ -1104,7 +1099,7 @@ Draw: { -TPos to_x, to_y, mid_x, mid_y; +TPos to_x, to_y; to_x = arc[0].x; ___ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] Re: possible inefficiency in gray_render_cubic
At 10:04 08/06/2010 +0200, Werner LEMBERG wrote: I am sceptical about the need to calculate both da and db. Perhaps db only will suffice. I hope that David or Werner can comment. This is something Ken can probably check: He has a large database for Ghostscript to compare rendering results, and artifacts introduced by the simplified shorthand calculation would easily show up, I think. I'd like to be able to, but at the moment GS doesn't use FreeType for anti-aliased rendering, hich is when this would get used I think ? Currently GS renders text to create a bitmap mask, and fills the mask with a colour (in PostScript colour can mean something complicated, like a pattern) It's on the schedule to replace the Ghostscript (crude) anti-aliasing with the FreeType anti-aliasing, but probably after we get the PCL and XPS interpreters to use FT (at the moment only the PS and PDF ones do). If I'm wrong please let me know and I'll be happy to put a patch through our regression testing. Ken ___ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] Re: possible inefficiency in gray_render_cubic
Werner, I think your patch is slightly wrong because you use the same values for mid_x and mid_y for both the comparison and for drawing; however, one set if values needs to go through DownScale() and the other through UpScale(); that's why I calculate separately in my hastily-prepared patch. I'll see if I can come up with something better. Graham Werner LEMBERG wrote: Calculate the midpoint and compare it with start and end: [...] For me, this looks good. Thanks for working on this. I am sceptical about the need to calculate both da and db. Perhaps db only will suffice. I hope that David or Werner can comment. This is something Ken can probably check: He has a large database for Ghostscript to compare rendering results, and artifacts introduced by the simplified shorthand calculation would easily show up, I think. Below is a patch according to your data (hopefully, I've understood you correctly). Please check and test. Werner == --- ftgrays.c.orig 2009-07-31 18:45:19.0 +0200 +++ ftgrays.c 2010-06-08 09:56:23.0 +0200 @@ -1007,45 +1007,40 @@ const FT_Vector* control2, const FT_Vector* to ) { -TPosdx, dy, da, db; +TPosdx, dy; +TPosmid_x, mid_y; int top, level; int*levels; FT_Vector* arc; -dx = DOWNSCALE( ras.x ) + to-x - ( control1-x 1 ); -if ( dx 0 ) - dx = -dx; -dy = DOWNSCALE( ras.y ) + to-y - ( control1-y 1 ); -if ( dy 0 ) - dy = -dy; -if ( dx dy ) - dx = dy; -da = dx; +/* Calculate midpoint and compare it with start and end. */ +mid_x = ( DOWNSCALE( ras.x ) + to-x + + 3 * ( control1-x + control2-x ) ) / 8; +mid_y = ( DOWNSCALE( ras.y ) + to-y + + 3 * ( control1-y + control2-y ) ) / 8; -dx = DOWNSCALE( ras.x ) + to-x - 3 * ( control1-x + control2-x ); +dx = DOWNSCALE( ras.x ) + to-x - ( mid_x 1 ); if ( dx 0 ) dx = -dx; -dy = DOWNSCALE( ras.y ) + to-y - 3 * ( control1-x + control2-y ); +dy = DOWNSCALE( ras.y ) + to-y - ( mid_y 1 ); if ( dy 0 ) dy = -dy; if ( dx dy ) dx = dy; -db = dx; +/* Check whether an approximation with straight lines is sufficient. */ level = 1; -da= da / ras.cubic_level; -db= db / ras.conic_level; -while ( da 0 || db 0 ) +dx= dx / ras.conic_level; +while ( dx 0 ) { - da = 2; - db = 3; + dx = 3; level++; } if ( level = 1 ) { - TPos to_x, to_y, mid_x, mid_y; + TPos to_x, to_y; to_x = UPSCALE( to-x ); @@ -1104,7 +1099,7 @@ Draw: { -TPos to_x, to_y, mid_x, mid_y; +TPos to_x, to_y; to_x = arc[0].x; ___ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] Re: possible inefficiency in gray_render_cubic
Another question arises: why do we divide by ras.conic_level when we are dealing with cubic splines? Surely it should be dx= dx / ras.cubic_level; or (better - we can use assignment operators in FreeType, I think ;-): dx/= ras.cubic_level; Graham Werner LEMBERG wrote: Calculate the midpoint and compare it with start and end: [...] For me, this looks good. Thanks for working on this. I am sceptical about the need to calculate both da and db. Perhaps db only will suffice. I hope that David or Werner can comment. This is something Ken can probably check: He has a large database for Ghostscript to compare rendering results, and artifacts introduced by the simplified shorthand calculation would easily show up, I think. Below is a patch according to your data (hopefully, I've understood you correctly). Please check and test. Werner == --- ftgrays.c.orig 2009-07-31 18:45:19.0 +0200 +++ ftgrays.c 2010-06-08 09:56:23.0 +0200 @@ -1007,45 +1007,40 @@ const FT_Vector* control2, const FT_Vector* to ) { -TPosdx, dy, da, db; +TPosdx, dy; +TPosmid_x, mid_y; int top, level; int*levels; FT_Vector* arc; -dx = DOWNSCALE( ras.x ) + to-x - ( control1-x 1 ); -if ( dx 0 ) - dx = -dx; -dy = DOWNSCALE( ras.y ) + to-y - ( control1-y 1 ); -if ( dy 0 ) - dy = -dy; -if ( dx dy ) - dx = dy; -da = dx; +/* Calculate midpoint and compare it with start and end. */ +mid_x = ( DOWNSCALE( ras.x ) + to-x + + 3 * ( control1-x + control2-x ) ) / 8; +mid_y = ( DOWNSCALE( ras.y ) + to-y + + 3 * ( control1-y + control2-y ) ) / 8; -dx = DOWNSCALE( ras.x ) + to-x - 3 * ( control1-x + control2-x ); +dx = DOWNSCALE( ras.x ) + to-x - ( mid_x 1 ); if ( dx 0 ) dx = -dx; -dy = DOWNSCALE( ras.y ) + to-y - 3 * ( control1-x + control2-y ); +dy = DOWNSCALE( ras.y ) + to-y - ( mid_y 1 ); if ( dy 0 ) dy = -dy; if ( dx dy ) dx = dy; -db = dx; +/* Check whether an approximation with straight lines is sufficient. */ level = 1; -da= da / ras.cubic_level; -db= db / ras.conic_level; -while ( da 0 || db 0 ) +dx= dx / ras.conic_level; +while ( dx 0 ) { - da = 2; - db = 3; + dx = 3; level++; } if ( level = 1 ) { - TPos to_x, to_y, mid_x, mid_y; + TPos to_x, to_y; to_x = UPSCALE( to-x ); @@ -1104,7 +1099,7 @@ Draw: { -TPos to_x, to_y, mid_x, mid_y; +TPos to_x, to_y; to_x = arc[0].x; ___ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] Re: possible inefficiency in gray_render_cubic
Werner, here's what I think is a better version of the start of the function. I've combined a few declarations and initialisations; probably against your house style, so please adjust as appropriate if you don't like it. Important changes: (i) dx is now divided by ras.cubic_level; (ii) mid_x and mid_y are recalculated only if necessary. 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; 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; TPos dx = DOWNSCALE( ras.x ) + to-x - ( mid_x 1 ); TPos dy = 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 = 3; 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 error = gray_render_line( RAS_VAR_ mid_x, mid_y ); if (!error) error = gray_render_line( RAS_VAR_ to_x, to_y ); return error; } Werner LEMBERG wrote: Calculate the midpoint and compare it with start and end: [...] For me, this looks good. Thanks for working on this. I am sceptical about the need to calculate both da and db. Perhaps db only will suffice. I hope that David or Werner can comment. This is something Ken can probably check: He has a large database for Ghostscript to compare rendering results, and artifacts introduced by the simplified shorthand calculation would easily show up, I think. Below is a patch according to your data (hopefully, I've understood you correctly). Please check and test. Werner == --- ftgrays.c.orig 2009-07-31 18:45:19.0 +0200 +++ ftgrays.c 2010-06-08 09:56:23.0 +0200 @@ -1007,45 +1007,40 @@ const FT_Vector* control2, const FT_Vector* to ) { -TPosdx, dy, da, db; +TPosdx, dy; +TPosmid_x, mid_y; int top, level; int*levels; FT_Vector* arc; -dx = DOWNSCALE( ras.x ) + to-x - ( control1-x 1 ); -if ( dx 0 ) - dx = -dx; -dy = DOWNSCALE( ras.y ) + to-y - ( control1-y 1 ); -if ( dy 0 ) - dy = -dy; -if ( dx dy ) - dx = dy; -da = dx; +/* Calculate midpoint and compare it with start and end. */ +mid_x = ( DOWNSCALE( ras.x ) + to-x + + 3 * ( control1-x + control2-x ) ) / 8; +mid_y = ( DOWNSCALE( ras.y ) + to-y + + 3 * ( control1-y + control2-y ) ) / 8; -dx = DOWNSCALE( ras.x ) + to-x - 3 * ( control1-x + control2-x ); +dx = DOWNSCALE( ras.x ) + to-x - ( mid_x 1 ); if ( dx 0 ) dx = -dx; -dy = DOWNSCALE( ras.y ) + to-y - 3 * ( control1-x + control2-y ); +dy = DOWNSCALE( ras.y ) + to-y - ( mid_y 1 ); if ( dy 0 ) dy = -dy; if ( dx dy ) dx = dy; -db = dx; +/* Check whether an approximation with straight lines is sufficient. */ level = 1; -da= da / ras.cubic_level; -db= db / ras.conic_level; -while ( da 0 || db 0 ) +dx= dx / ras.conic_level; +while ( dx 0 ) { - da = 2; - db = 3; + dx = 3; level++; } if ( level = 1 ) { - TPos to_x, to_y, mid_x, mid_y; + TPos to_x, to_y; to_x = UPSCALE( to-x ); @@ -1104,7 +1099,7 @@ Draw: { -TPos to_x, to_y, mid_x, mid_y; +TPos to_x, to_y; to_x = arc[0].x; ___ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel