From e664efadddc49bee32b337571e329f150006a84b Mon Sep 17 00:00:00 2001 From: David Turner Date: Fri, 4 Jun 2004 17:41:59 +0000 Subject: [PATCH] * src/autofit/*: important fixes to the auto-fitter. The output now seems to be 100% equivalent to the auto-hinter, while being about 2% faster (which proves that script-specific algorithm selection isn't a performance problem). to test it, change "autohint" to "autofit" in and recompile. a few more testing is needed before making this the official auto-hinting module --- ChangeLog | 17 ++++- src/autofit/afangles.c | 96 +++++++++++++++++++++++-- src/autofit/afdummy.c | 13 ++-- src/autofit/afglobal.c | 2 +- src/autofit/afhints.c | 39 ++++++----- src/autofit/afhints.h | 10 +-- src/autofit/aflatin.c | 154 +++++++++++++++++++++++++++++++---------- src/autofit/aflatin.h | 7 +- src/autofit/afloader.c | 61 ++++++++-------- src/autofit/aftypes.h | 26 ++++++- src/tools/cordic.py | 15 ++-- 11 files changed, 329 insertions(+), 111 deletions(-) diff --git a/ChangeLog b/ChangeLog index 892ef74c6..0890dc410 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2004-06-04 David Turner + + * src/autofit/*: important fixes to the auto-fitter. The output + now seems to be 100% equivalent to the auto-hinter, while being + about 2% faster (which proves that script-specific algorithm + selection isn't a performance problem). + + to test it, change "autohint" to "autofit" in + and recompile. + + a few more testing is needed before making this the official + auto-hinting module + 2004-06-02 Werner Lemberg * src/truetype/ttgload.c (compute_glyph_metrics): Fix compiler @@ -24,7 +37,7 @@ 2004-05-17 Werner Lemberg - * src/base/ftbbox.c (BBox_Conic_Check): Fix boundary cases. + * src/base/ftbbox.c (BBox_Conic_Check): Fix boundary cases. Reported by Mikey Anbary . 2004-05-15 Werner Lemberg @@ -173,7 +186,7 @@ consistency. (pcf_cmap_init, pcf_cmap_done, pcf_cmap_char_index, pcf_cmap_char_next): Don't use PCF_XXX but FT_XXX arguments which - are typecast to the proper PCF_XXX types within the function. + are typecast to the proper PCF_XXX types within the function. Update code accordingly. (pcf_cmap_class): Remove casts. (PCF_Face_Done, PCF_Face_Init, PCF_Set_Pixel_Size): Don't use diff --git a/src/autofit/afangles.c b/src/autofit/afangles.c index 10a8cff25..e42c962d1 100644 --- a/src/autofit/afangles.c +++ b/src/autofit/afangles.c @@ -1,8 +1,57 @@ #include "aftypes.h" +/* + * a python script used to generate the following table + * + +import sys, math + +units = 256 +scale = units/math.pi +comma = "" + +print "" +print "table of arctan( 1/2^n ) for PI = " + repr(units/65536.0) + " units" + +r = [-1] + range(32) + +for n in r: + + if n >= 0: + x = 1.0/(2.0**n) # tangent value + else: + x = 2.0**(-n) + + angle = math.atan(x) # arctangent + angle2 = angle*scale # arctangent in FT_Angle units + + # determine which integer value for angle gives the best tangent + lo = int(angle2) + hi = lo + 1 + tlo = math.tan(lo/scale) + thi = math.tan(hi/scale) + + errlo = abs( tlo - x ) + errhi = abs( thi - x ) + + angle2 = hi + if errlo < errhi: + angle2 = lo + + if angle2 <= 0: + break + + sys.stdout.write( comma + repr( int(angle2) ) ) + comma = ", " + +* +* end of python script +*/ + + /* this table was generated for AF_ANGLE_PI = 256 */ #define AF_ANGLE_MAX_ITERS 8 -#define AF_TRIG_MAX_ITERS 9 +#define AF_TRIG_MAX_ITERS 8 static const FT_Fixed af_angle_arctan_table[9] = @@ -69,7 +118,7 @@ { x = -x; y = -y; - theta = 2 * AF_ANGLE_PI2; + theta = AF_ANGLE_PI; } if ( y > 0 ) @@ -115,11 +164,13 @@ } } while ( ++i < AF_TRIG_MAX_ITERS ); +#if 0 /* round theta */ if ( theta >= 0 ) - theta = FT_PAD_ROUND( theta, 4 ); + theta = FT_PAD_ROUND( theta, 2 ); else - theta = - FT_PAD_ROUND( theta, 4 ); + theta = - FT_PAD_ROUND( -theta, 2 ); +#endif vec->x = x; vec->y = theta; @@ -212,3 +263,40 @@ } } } + + +#ifdef TEST +#include +#include + +int main( void ) +{ + int angle; + int dist; + + for ( dist = 100; dist < 1000; dist++ ) + { + for ( angle = AF_ANGLE_PI; angle < AF_ANGLE_2PI*4; angle++ ) + { + double a = (angle*3.1415926535)/(1.0*AF_ANGLE_PI); + int dx, dy, angle1, angle2, delta; + + dx = dist * cos(a); + dy = dist * sin(a); + + angle1 = ((atan2(dy,dx)*AF_ANGLE_PI)/3.1415926535); + angle2 = af_angle_atan( dx, dy ); + delta = (angle2 - angle1) % AF_ANGLE_2PI; + if ( delta < 0 ) + delta = -delta; + + if ( delta >= 2 ) + { + printf( "dist:%4d angle:%4d => (%4d,%4d) angle1:%4d angle2:%4d\n", + dist, angle, dx, dy, angle1, angle2 ); + } + } + } + return 0; +} +#endif diff --git a/src/autofit/afdummy.c b/src/autofit/afdummy.c index bae5f70a3..3a13140d9 100644 --- a/src/autofit/afdummy.c +++ b/src/autofit/afdummy.c @@ -3,20 +3,21 @@ static FT_Error af_dummy_hints_init( AF_GlyphHints hints, - FT_Outline* outline, AF_ScriptMetrics metrics ) { - return af_glyph_hints_reset( hints, - &metrics->scaler, - metrics, - outline ); + af_glyph_hints_rescale( hints, + metrics ); + return 0; } static FT_Error af_dummy_hints_apply( AF_GlyphHints hints, FT_Outline* outline ) { - af_glyph_hints_save( hints, outline ); + FT_UNUSED( hints ); + FT_UNUSED( outline ); + + return 0; } diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c index cadc80347..54852ab31 100644 --- a/src/autofit/afglobal.c +++ b/src/autofit/afglobal.c @@ -12,7 +12,7 @@ NULL /* do not remove */ }; -#define AF_SCRIPT_LIST_DEFAULT 0 /* index of default script in 'af_script_classes' */ +#define AF_SCRIPT_LIST_DEFAULT 1 /* index of default script in 'af_script_classes' */ #define AF_SCRIPT_LIST_NONE 255 /* indicates an uncovered glyph */ /* diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c index d0dca1526..a1a50dce3 100644 --- a/src/autofit/afhints.c +++ b/src/autofit/afhints.c @@ -10,11 +10,11 @@ switch (dir) { - case AF_DIR_UP: result = "up"; break; - case AF_DIR_DOWN: result = "down"; break; - case AF_DIR_LEFT: result = "left"; break; + case AF_DIR_UP: result = "up"; break; + case AF_DIR_DOWN: result = "down"; break; + case AF_DIR_LEFT: result = "left"; break; case AF_DIR_RIGHT: result = "right"; break; - default: result = "none"; + default: result = "none"; } return result; } @@ -111,7 +111,7 @@ for ( edge = edges; edge < limit; edge++ ) { - printf ( " [ %5d | %4d | %5s | %4d | %5d | %c | %5.2f | %5.2f ]\n", + printf ( " [ %5d | %4d | %5s | %4d | %5d | %c | %5.2f | %5.2f ]\n", edge - edges, (int)edge->fpos, af_dir_str( edge->dir ), @@ -314,26 +314,29 @@ + FT_LOCAL_DEF( void ) + af_glyph_hints_rescale( AF_GlyphHints hints, + AF_ScriptMetrics metrics ) + { + hints->metrics = metrics; + } + + FT_LOCAL_DEF( FT_Error ) - af_glyph_hints_reset( AF_GlyphHints hints, - AF_Scaler scaler, - AF_ScriptMetrics metrics, - FT_Outline* outline ) + af_glyph_hints_reload( AF_GlyphHints hints, + FT_Outline* outline ) { FT_Error error = FT_Err_Ok; AF_Point points; FT_UInt old_max, new_max; - FT_Fixed x_scale = scaler->x_scale; - FT_Fixed y_scale = scaler->y_scale; - FT_Pos x_delta = scaler->x_delta; - FT_Pos y_delta = scaler->y_delta; + AF_Scaler scaler = &hints->metrics->scaler; + FT_Fixed x_scale = hints->x_scale; + FT_Fixed y_scale = hints->y_scale; + FT_Pos x_delta = hints->x_delta; + FT_Pos y_delta = hints->y_delta; FT_Memory memory = hints->memory; - hints->metrics = metrics; - - hints->scaler_flags = scaler->flags; - hints->other_flags = 0; - + hints->scaler_flags = scaler->flags; hints->num_points = 0; hints->num_contours = 0; diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h index c69cdc66c..40fd613a4 100644 --- a/src/autofit/afhints.h +++ b/src/autofit/afhints.h @@ -214,11 +214,13 @@ FT_BEGIN_HEADER /* recomputes all AF_Point in a AF_GlyphHints from the definitions * in a source outline */ + FT_LOCAL( void ) + af_glyph_hints_rescale( AF_GlyphHints hints, + AF_ScriptMetrics metrics ); + FT_LOCAL( FT_Error ) - af_glyph_hints_reset( AF_GlyphHints hints, - AF_Scaler scaler, - AF_ScriptMetrics metrics, - FT_Outline* outline ); + af_glyph_hints_reload( AF_GlyphHints hints, + FT_Outline* outline ); FT_LOCAL( void ) af_glyph_hints_save( AF_GlyphHints hints, diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c index 9a20110fb..ce0f8c961 100644 --- a/src/autofit/aflatin.c +++ b/src/autofit/aflatin.c @@ -25,8 +25,8 @@ FT_Error error; FT_UInt glyph_index; AF_Dimension dim; - AF_ScalerRec scaler[1]; - + AF_ScriptMetricsRec dummy[1]; + AF_Scaler scaler = &dummy->scaler; glyph_index = FT_Get_Char_Index( face, 'o' ); if ( glyph_index == 0 ) @@ -36,15 +36,17 @@ if ( error || face->glyph->outline.n_points <= 0 ) goto Exit; + FT_ZERO( dummy ); + scaler->x_scale = scaler->y_scale = 0x10000L; scaler->x_delta = scaler->y_delta = 0; scaler->face = face; scaler->render_mode = 0; scaler->flags = 0; - error = af_glyph_hints_reset( hints, scaler, - (AF_ScriptMetrics) metrics, - &face->glyph->outline ); + af_glyph_hints_rescale( hints, dummy ); + + error = af_glyph_hints_reload( hints, &face->glyph->outline ); if ( error ) goto Exit; @@ -324,6 +326,13 @@ if ( AF_LATIN_IS_TOP_BLUE(bb) ) blue->flags |= AF_LATIN_BLUE_TOP; + /* the following flags is used later to adjust the y and x scales + * in order to optimize the pixel grid alignment of the top of small + * letters. + */ + if ( bb == AF_LATIN_BLUE_SMALL_TOP ) + blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; + AF_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot )); } @@ -382,8 +391,44 @@ axis->org_scale = scale; axis->org_delta = delta; - /* XXX: TODO: Correct Y and X scale according to Chester rules + /* correct X and Y scale to optimize the alignment of the top of small + * letters to the pixel grid */ + { + AF_LatinAxis axis = &metrics->axis[ AF_DIMENSION_VERT ]; + AF_LatinBlue blue = NULL; + FT_UInt nn; + + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + if ( axis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT ) + { + blue = &axis->blues[nn]; + break; + } + } + + if ( blue ) + { + FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); + FT_Pos fitted = FT_PIX_ROUND( scaled ); + + + if ( scaled != fitted ) + { + if ( dim == AF_DIMENSION_HORZ ) + { + if ( fitted < scaled ) + scale -= scale/50; /* x_scale = x_scale*0.98 */ + } + else + { + scale = FT_MulDiv( scale, fitted, scaled ); + } + } + } + } + axis->scale = scale; axis->delta = delta; @@ -417,17 +462,41 @@ AF_LatinBlue blue = & axis->blues[nn]; FT_Pos dist; - blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; - blue->ref.fit = blue->ref.cur; - + blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; + blue->ref.fit = blue->ref.cur; blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; blue->shoot.fit = blue->shoot.cur; + blue->flags &= ~AF_LATIN_BLUE_ACTIVE; /* a blue zone is only active when it is less than 3/4 pixels tall */ dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); - if ( dist >= 48 || dist <= -48 ) - blue->flags |= ~AF_LATIN_BLUE_ACTIVE; + if ( dist <= 48 && dist >= -48 ) + { + FT_Pos delta, delta2; + + delta = blue->shoot.org - blue->ref.org; + delta2 = delta; + if ( delta < 0 ) + delta2 = -delta2; + + delta2 = FT_MulFix( delta2, scale ); + + if ( delta2 < 32 ) + delta2 = 0; + else if ( delta2 < 64 ) + delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); + else + delta2 = FT_PIX_ROUND( delta2 ); + + if ( delta < 0 ) + delta2 = -delta2; + + blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); + blue->shoot.fit = blue->ref.fit + delta2; + + blue->flags |= AF_LATIN_BLUE_ACTIVE; + } } } } @@ -437,6 +506,9 @@ af_latin_metrics_scale( AF_LatinMetrics metrics, AF_Scaler scaler ) { + if ( AF_SCALER_EQUAL_SCALES( scaler, &metrics->root.scaler ) ) + return; + af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); } @@ -791,6 +863,7 @@ AF_Dimension dim ) { AF_AxisHints axis = &hints->axis[dim]; + AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge, edge_limit; @@ -825,7 +898,7 @@ /* */ /*********************************************************************/ - edge_distance_threshold = FT_MulFix( hints->edge_distance_threshold, + edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, scale ); if ( edge_distance_threshold > 64 / 4 ) edge_distance_threshold = 64 / 4; @@ -1138,18 +1211,19 @@ static FT_Error af_latin_hints_init( AF_GlyphHints hints, - FT_Outline* outline, AF_LatinMetrics metrics ) { - FT_Error error; FT_Render_Mode mode; - error = af_glyph_hints_reset( hints, &metrics->root.scaler, - (AF_ScriptMetrics) metrics, - outline ); - if (error) - goto Exit; + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + /* correct x_scale and y_scale when needed, since they may have + * been modified af_latin_scale_dim above + */ + hints->x_scale = metrics->axis[ AF_DIMENSION_HORZ ].scale; + hints->x_delta = metrics->axis[ AF_DIMENSION_HORZ ].delta; + hints->y_scale = metrics->axis[ AF_DIMENSION_VERT ].scale; + hints->y_delta = metrics->axis[ AF_DIMENSION_VERT ].delta; /* compute flags depending on render mode, etc... */ @@ -1176,21 +1250,11 @@ if ( mode == FT_RENDER_MODE_MONO ) hints->other_flags |= AF_LATIN_HINTS_MONO; - /* analyze glyph outline - */ - if ( AF_HINTS_DO_HORIZONTAL(hints) ) - af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ ); - - if ( AF_HINTS_DO_VERTICAL(hints) ) - { - af_latin_hints_detect_features( hints, AF_DIMENSION_VERT ); - af_latin_hints_compute_blue_edges( hints, metrics ); - } - - Exit: - return error; + return 0; } + + /***************************************************************************/ /***************************************************************************/ /***** *****/ @@ -1738,10 +1802,26 @@ FT_Outline* outline, AF_LatinMetrics metrics ) { + FT_Error error; AF_Dimension dim; - FT_UNUSED( metrics ); + error = af_glyph_hints_reload( hints, outline ); + if ( error ) + goto Exit; + /* analyze glyph outline + */ + if ( AF_HINTS_DO_HORIZONTAL(hints) ) + af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ ); + + if ( AF_HINTS_DO_VERTICAL(hints) ) + { + af_latin_hints_detect_features( hints, AF_DIMENSION_VERT ); + af_latin_hints_compute_blue_edges( hints, metrics ); + } + + /* grid-fit the outline + */ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { if ( (dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL(hints)) || @@ -1755,7 +1835,8 @@ } af_glyph_hints_save( hints, outline ); - return 0; + Exit: + return error; } /***************************************************************************/ @@ -1768,11 +1849,12 @@ static const AF_Script_UniRangeRec af_latin_uniranges[] = { - { 32, 127 }, /* XXX: TODO: Add new Unicode ranges here !! */ + { 32, 127 }, /* XXX: TODO: Add new Unicode ranges here !! */ { 160, 255 }, - { 0, 0 } + { 0, 0 } }; + FT_LOCAL_DEF( const AF_ScriptClassRec ) af_latin_script_class = { AF_SCRIPT_LATIN, diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h index a52e42101..e7e8e4842 100644 --- a/src/autofit/aflatin.h +++ b/src/autofit/aflatin.h @@ -51,9 +51,10 @@ FT_BEGIN_HEADER enum { - AF_LATIN_BLUE_ACTIVE = (1 << 0), - AF_LATIN_BLUE_TOP = (1 << 1), - + AF_LATIN_BLUE_ACTIVE = (1 << 0), + AF_LATIN_BLUE_TOP = (1 << 1), + AF_LATIN_BLUE_ADJUSTMENT = (1 << 2), /* used for scale adjustment */ + /* optimization */ AF_LATIN_BLUE_FLAG_MAX }; diff --git a/src/autofit/afloader.c b/src/autofit/afloader.c index ed422384e..5b476314d 100644 --- a/src/autofit/afloader.c +++ b/src/autofit/afloader.c @@ -105,16 +105,9 @@ * is needed */ if ( loader->transformed ) - { - FT_Vector* point = slot->outline.points; - FT_Vector* limit = point + slot->outline.n_points; - - for ( ; point < limit; point++ ) - { - point->x += loader->trans_delta.x; - point->y += loader->trans_delta.y; - } - } + FT_Outline_Translate( &slot->outline, + loader->trans_delta.x, + loader->trans_delta.y ); /* copy the outline points in the loader's current */ /* extra points which is used to keep original glyph coordinates */ @@ -157,16 +150,10 @@ /* now load the slot image into the auto-outline and run the */ /* automatic hinting process */ - error = metrics->clazz->script_hints_init( hints, - &gloader->current.outline, - metrics ); - if ( error ) - goto Exit; - - /* apply the hints */ metrics->clazz->script_hints_apply( hints, &gloader->current.outline, metrics ); + /* we now need to hint the metrics according to the change in */ /* width/positioning that occured during the hinting process */ { @@ -175,20 +162,27 @@ AF_Edge edge1 = axis->edges; /* leftmost edge */ AF_Edge edge2 = edge1 + axis->num_edges - 1; /* rightmost edge */ + if ( edge2 > edge1 ) + { + old_advance = loader->pp2.x; + old_rsb = old_advance - edge2->opos; + old_lsb = edge1->opos; + new_lsb = edge1->pos; - old_advance = loader->pp2.x; - old_rsb = old_advance - edge2->opos; - old_lsb = edge1->opos; - new_lsb = edge1->pos; - - loader->pp1.x = FT_PIX_ROUND( new_lsb - old_lsb ); - loader->pp2.x = FT_PIX_ROUND( edge2->pos + old_rsb ); + loader->pp1.x = FT_PIX_ROUND( new_lsb - old_lsb ); + loader->pp2.x = FT_PIX_ROUND( edge2->pos + old_rsb ); #if 0 - /* try to fix certain bad advance computations */ - if ( loader->pp2.x + loader->pp1.x == edge2->pos && old_rsb > 4 ) - loader->pp2.x += 64; + /* try to fix certain bad advance computations */ + if ( loader->pp2.x + loader->pp1.x == edge2->pos && old_rsb > 4 ) + loader->pp2.x += 64; #endif + } + else + { + loader->pp1.x = FT_PIX_ROUND( loader->pp1.x ); + loader->pp2.x = FT_PIX_ROUND( loader->pp2.x ); + } } /* good, we simply add the glyph to our loader's base */ @@ -366,7 +360,13 @@ slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, x_scale ); #else - slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + /* for mono-width fonts (like Andale, Courier, etc.) we need */ + /* to keep the original rounded advance width */ + if ( !FT_IS_FIXED_WIDTH( slot->face ) ) + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + else + slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, + metrics->scaler.x_scale ); #endif slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); @@ -434,8 +434,13 @@ load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; load_flags &= ~FT_LOAD_RENDER; + error = metrics->clazz->script_hints_init( &loader->hints, metrics ); + if ( error ) + goto Exit; + error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 ); } } + Exit: return error; } diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h index abd2ff5fa..5d0371fcb 100644 --- a/src/autofit/aftypes.h +++ b/src/autofit/aftypes.h @@ -1,3 +1,20 @@ +/*************************************************************************** + * + * FreeType auto-fitter + * + * (c) 2004 David Turner + * + * The auto-fitter is a complete rewrite of the old auto-hinter. + * its main feature is the ability to differentiate between different + * scripts in order to apply language-specific rules. + * + * the code has also been compartimentized into several entities that + * should make algorithmic experimentation easier than with the old + * code. + * + * finally, we get rid of the Catharon license, since this code is + * released under the FreeType one. + */ #ifndef __AFTYPES_H__ #define __AFTYPES_H__ @@ -73,7 +90,7 @@ FT_BEGIN_HEADER typedef FT_Int AF_Angle; -#define AF_ANGLE_PI 128 +#define AF_ANGLE_PI 256 #define AF_ANGLE_2PI (AF_ANGLE_PI*2) #define AF_ANGLE_PI2 (AF_ANGLE_PI/2) #define AF_ANGLE_PI4 (AF_ANGLE_PI/4) @@ -164,6 +181,12 @@ FT_BEGIN_HEADER } AF_ScalerRec, *AF_Scaler; +#define AF_SCALER_EQUAL_SCALES(a,b) \ + ( (a)->x_scale == (b)->x_scale && \ + (a)->y_scale == (b)->y_scale && \ + (a)->x_delta == (b)->x_delta && \ + (a)->y_delta == (b)->y_delta ) + /**************************************************************************/ /**************************************************************************/ @@ -228,7 +251,6 @@ FT_BEGIN_HEADER typedef FT_Error (*AF_Script_InitHintsFunc)( AF_GlyphHints hints, - FT_Outline* outline, AF_ScriptMetrics metrics ); typedef void (*AF_Script_ApplyHintsFunc)( AF_GlyphHints hints, diff --git a/src/tools/cordic.py b/src/tools/cordic.py index bb1a238e0..1906b6b1f 100644 --- a/src/tools/cordic.py +++ b/src/tools/cordic.py @@ -1,7 +1,8 @@ # compute arctangent table for CORDIC computations in fttrigon.c import sys, math -units = 64*65536.0 # don't change !! +#units = 64*65536.0 # don't change !! +units = 256 scale = units/math.pi shrink = 1.0 comma = "" @@ -23,7 +24,7 @@ def print_val( n, x ): errlo = abs( alo - ax ) errhi = abs( ahi - ax ) - + if ( errlo < errhi ): hi = lo @@ -44,8 +45,8 @@ for n in r: x = 1.0/(2.0**n) # tangent value else: x = 2.0**(-n) - - angle = math.atan(x) # arctangent + + angle = math.atan(x) # arctangent angle2 = angle*scale # arctangent in FT_Angle units # determine which integer value for angle gives the best tangent @@ -63,12 +64,12 @@ for n in r: if angle2 <= 0: break - + sys.stdout.write( comma + repr( int(angle2) ) ) comma = ", " - + shrink = shrink * math.cos( angle2/scale) - + print print "shrink factor = " + repr( shrink )