From b19b0810cd887a4c1036121b0d3e9bb93278a0a9 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 2 Mar 2005 11:24:23 +0000 Subject: [PATCH] * src/autofit/afdummy.c, src/autofit/afdummy.h (af_dummy_script_class): Fix type. * src/autofit/aflatin.c, src/autofit/aflatin.h (af_latin_script_class): Fix type. * src/autofit/rules.mk (AUTOF_DRV_SRC): Fix typo. Formatting. --- ChangeLog | 59 +++++-- src/autofit/afangles.h | 8 +- src/autofit/afdummy.c | 6 +- src/autofit/afdummy.h | 10 +- src/autofit/afhints.c | 236 +++++++++++++++------------ src/autofit/aflatin.c | 357 +++++++++++++++++++++++------------------ src/autofit/aflatin.h | 147 +++++++++-------- src/autofit/afloader.c | 223 +++++++++++++------------ src/autofit/rules.mk | 28 ++-- src/sfnt/ttkern.c | 3 +- src/sfnt/ttsbit.h | 2 +- src/sfnt/ttsbit0.c | 12 +- 12 files changed, 617 insertions(+), 474 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7027a7306..78ab9c346 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,20 +1,59 @@ +2005-03-02 Werner Lemberg + + * src/autofit/afdummy.c, src/autofit/afdummy.h + (af_dummy_script_class): Fix type. + + * src/autofit/aflatin.c, src/autofit/aflatin.h + (af_latin_script_class): Fix type. + + * src/autofit/rules.mk (AUTOF_DRV_SRC): Fix typo. + 2005-03-01 David Turner - * src/sfnt/{ttkern.c,ttsbit.h,ttsbit0.c,ttload.c},: removing compiler - warnings + * src/sfnt/ttkern.c (tt_face_load_kern, tt_face_get_kerning), + src/sfnt/ttsbit0.c (tt_face_load_sbit_strikes, + tt_sbit_decoder_load_byte_aligned, tt_sbit_decoder_load_compound, + tt_sbit_decoder_load_image), src/sfnt/ttload.c + (tt_face_load_metrics): Remove compiler warnings + -- redundant variables, missing initializations, etc. - * src/autofit/{rules.mk,module.mk,afangles.h}: adding missing files + * src/sfnt/ttsbit.h: Handle FT_OPTIMIZE_MEMORY. - * src/autofit/afloader.c: fixing small bug that could crash the engine - with certain fonts. + * src/autofit/rules.mk, src/autofit/module.mk, + src/autofit/afangles.h: New files. - * src/autofit/{afhints.h,afhints.c,aflatin.h,aflatin.c,afloader.c}: - various bug-fixes and drastic heap usage reduction improvements. + * src/autofit/afhints.c (af_axis_hints_new_segment, + af_axis_hints_new_edge): New functions. + (af_glyph_hints_done): Do proper deallocation. + (af_glyph_hints_reload): Only reallocate points array. This + drastically reduces heap usage. - * include/freetype/config/ftmodule.h: the auto-fitter is now the - only supported auto-hinting module + * src/autofit/afhints.h (AF_PointRec, AF_SegmentRec): Optimize + member types and positions. + (AF_AxisHintsRec): Add `max_segments' and `max_edges'. + (af_axis_hints_new_segment, af_axis_hints_new_edge): New prototypes. - * include/freetype/config/ftstdlib.h: adding FT_INT_MAX definition + * src/autofit/aflatin.c (af_latin_metricsc_scale): Don't call + AF_SCALER_EQUAL_SCALES. + (af_latin_hints_compute_segments): Change return type to FT_Error. + Update all callers. + Improve segment allocation. + (af_latin_hints_compute_edges): Change return type to FT_Error. + Update all callers. + Improve edge allocation and link handling. + (af_latin_hints_detect_features): Change return type to FT_Error. + Update all callers. + + * src/autofit/aflatin.h: Updated. + + * src/autofit/afloader.c (af_loader_load_g) + : Assure axis->num_edges > 1. This fixes + a bug with certain fonts. + + * include/freetype/config/ftmodule.h: The auto-fitter is now the + only supported auto-hinting module. + + * include/freetype/config/ftstdlib.h (FT_INT_MAX): New macro. 2005-02-28 Werner Lemberg diff --git a/src/autofit/afangles.h b/src/autofit/afangles.h index 593b40cc3..f33f9e108 100644 --- a/src/autofit/afangles.h +++ b/src/autofit/afangles.h @@ -1,3 +1,7 @@ -/* this is a dummy file. used to please the build system. It is never - * included by the auto-fitter sources +/* + * afangles.h + * + * This is a dummy file, used to please the build system. It is never + * included by the auto-fitter sources. + * */ diff --git a/src/autofit/afdummy.c b/src/autofit/afdummy.c index 2d5f89839..aa753c831 100644 --- a/src/autofit/afdummy.c +++ b/src/autofit/afdummy.c @@ -22,7 +22,8 @@ } - FT_LOCAL_DEF( const AF_ScriptClassRec ) af_dummy_script_class = + FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec + af_dummy_script_class = { AF_SCRIPT_NONE, NULL, @@ -35,3 +36,6 @@ (AF_Script_InitHintsFunc) af_dummy_hints_init, (AF_Script_ApplyHintsFunc) af_dummy_hints_apply }; + + +/* END */ diff --git a/src/autofit/afdummy.h b/src/autofit/afdummy.h index f4594c0f9..6c292bd53 100644 --- a/src/autofit/afdummy.h +++ b/src/autofit/afdummy.h @@ -5,14 +5,18 @@ FT_BEGIN_HEADER - /* a dummy script metrics class used when no hinting should - * be performed. This is the default for non-latin glyphs ! + /* A dummy script metrics class used when no hinting should + * be performed. This is the default for non-latin glyphs! */ - FT_LOCAL( const AF_ScriptClassRec ) af_dummy_script_class; + FT_CALLBACK_TABLE const AF_ScriptClassRec + af_dummy_script_class; /* */ FT_END_HEADER #endif /* __AFDUMMY_H__ */ + + +/* END */ diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c index 9e85ae13e..235f7af11 100644 --- a/src/autofit/afhints.c +++ b/src/autofit/afhints.c @@ -9,11 +9,13 @@ FT_Error error = 0; AF_Segment segment = NULL; + if ( axis->num_segments >= axis->max_segments ) { FT_Int old_max = axis->max_segments; FT_Int new_max = old_max; - FT_Int big_max = FT_INT_MAX / sizeof(*segment); + FT_Int big_max = FT_INT_MAX / sizeof ( *segment ); + if ( old_max >= big_max ) { @@ -21,7 +23,7 @@ goto Exit; } - new_max += (new_max >> 1) + 4; + new_max += ( new_max >> 1 ) + 4; if ( new_max < old_max || new_max > big_max ) new_max = big_max; @@ -39,21 +41,24 @@ return error; } + FT_LOCAL( FT_Error) af_axis_hints_new_edge( AF_AxisHints axis, FT_Int fpos, FT_Memory memory, AF_Edge *aedge ) { - FT_Error error = 0; - AF_Edge edge = NULL; - AF_Edge edges; + FT_Error error = 0; + AF_Edge edge = NULL; + AF_Edge edges; + if ( axis->num_edges >= axis->max_edges ) { FT_Int old_max = axis->max_edges; FT_Int new_max = old_max; - FT_Int big_max = FT_INT_MAX / sizeof(*edge); + FT_Int big_max = FT_INT_MAX / sizeof ( *edge ); + if ( old_max >= big_max ) { @@ -61,7 +66,7 @@ goto Exit; } - new_max += (new_max >> 1) + 4; + new_max += ( new_max >> 1 ) + 4; if ( new_max < old_max || new_max > big_max ) new_max = big_max; @@ -82,8 +87,8 @@ axis->num_edges++; - FT_ZERO(edge); - edge->fpos = (FT_Short) fpos; + FT_ZERO( edge ); + edge->fpos = (FT_Short)fpos; Exit: *aedge = edge; @@ -95,22 +100,36 @@ #include - static const char* af_dir_str( AF_Direction dir ) + static const char* + af_dir_str( AF_Direction dir ) { const char* result; - switch (dir) + + 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_RIGHT: result = "right"; break; - default: result = "none"; + 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"; } + return result; } -#define AF_INDEX_NUM(ptr,base) ( (ptr) ? ((ptr)-(base)) : -1 ) + +#define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 ) + void af_glyph_hints_dump_points( AF_GlyphHints hints ) @@ -119,11 +138,15 @@ AF_Point limit = points + hints->num_points; AF_Point point; + printf( "Table of points:\n" ); - printf( " [ index | xorg | yorg | xscale | yscale | xfit | yfit | flags ]\n" ); + printf( " [ index | xorg | yorg | xscale | yscale " + "| xfit | yfit | flags ]\n" ); + for ( point = points; point < limit; point++ ) { - printf( " [ %5d | %5d | %5d | %-5.2f | %-5.2f | %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n", + printf( " [ %5d | %5d | %5d | %-5.2f | %-5.2f " + "| %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n", point - points, point->fx, point->fy, @@ -131,28 +154,28 @@ point->oy/64.0, point->x/64.0, point->y/64.0, - (point->flags & AF_FLAG_WEAK_INTERPOLATION) ? 'w' : ' ', - (point->flags & AF_FLAG_INFLECTION) ? 'i' : ' ', - (point->flags & AF_FLAG_EXTREMA_X) ? '<' : ' ', - (point->flags & AF_FLAG_EXTREMA_Y) ? 'v' : ' ', - (point->flags & AF_FLAG_ROUND_X) ? '(' : ' ', - (point->flags & AF_FLAG_ROUND_Y) ? 'u' : ' ' - ); + ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ', + ( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ', + ( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ', + ( point->flags & AF_FLAG_EXTREMA_Y ) ? 'v' : ' ', + ( point->flags & AF_FLAG_ROUND_X ) ? '(' : ' ', + ( point->flags & AF_FLAG_ROUND_Y ) ? 'u' : ' '); } printf( "\n" ); } - /* A function used to dump the array of linked segments */ + /* A function to dump the array of linked segments. */ void af_glyph_hints_dump_segments( AF_GlyphHints hints ) { - AF_Point points = hints->points; - FT_Int dimension; + AF_Point points = hints->points; + FT_Int dimension; + for ( dimension = 1; dimension >= 0; dimension-- ) { - AF_AxisHints axis = &hints->axis[dimension]; + AF_AxisHints axis = &hints->axis[dimension]; AF_Segment segments = axis->segments; AF_Segment limit = segments + axis->num_segments; AF_Segment seg; @@ -183,18 +206,21 @@ void af_glyph_hints_dump_edges( AF_GlyphHints hints ) { - FT_Int dimension; + FT_Int dimension; + for ( dimension = 1; dimension >= 0; dimension-- ) { - AF_AxisHints axis = &hints->axis[ dimension ]; + AF_AxisHints axis = &hints->axis[dimension]; AF_Edge edges = axis->edges; AF_Edge limit = edges + axis->num_edges; AF_Edge edge; - /* note: AF_DIMENSION_HORZ corresponds to _vertical_ edges - * since they have constant X coordinate - */ + + /* + * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges + * since they have constant a X coordinate. + */ printf ( "Table of %s edges:\n", dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ); printf ( " [ index | pos | dir | link |" @@ -202,7 +228,8 @@ 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 ), @@ -212,13 +239,10 @@ edge->opos / 64.0, edge->pos / 64.0 ); } - printf( "\n" ); } } - - #endif /* AF_DEBUG */ @@ -359,7 +383,6 @@ } - FT_LOCAL_DEF( void ) af_glyph_hints_init( AF_GlyphHints hints, FT_Memory memory ) @@ -369,7 +392,6 @@ } - FT_LOCAL_DEF( void ) af_glyph_hints_done( AF_GlyphHints hints ) { @@ -378,12 +400,15 @@ FT_Memory memory = hints->memory; AF_Dimension dim; - /* note that we don't need to free the segment and edge - * buffers, since they're really within the hints->points array - */ + + /* + * note that we don't need to free the segment and edge + * buffers, since they are really within the hints->points array + */ for ( dim = 0; dim < 2; dim++ ) { - AF_AxisHints axis = &hints->axis[ dim ]; + AF_AxisHints axis = &hints->axis[dim]; + axis->num_segments = 0; axis->max_segments = 0; @@ -407,7 +432,6 @@ } - FT_LOCAL_DEF( void ) af_glyph_hints_rescale( AF_GlyphHints hints, AF_ScriptMetrics metrics ) @@ -417,18 +441,19 @@ FT_LOCAL_DEF( FT_Error ) - af_glyph_hints_reload( AF_GlyphHints hints, - 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; - 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; + FT_Error error = FT_Err_Ok; + AF_Point points; + FT_UInt old_max, new_max; + 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->scaler_flags = scaler->flags; hints->num_points = 0; @@ -439,13 +464,12 @@ hints->axis[1].num_segments = 0; hints->axis[1].num_edges = 0; - /* first of all, reallocate the contours array when necessary - */ - new_max = (FT_UInt) outline->n_contours; + /* first of all, reallocate the contours array when necessary */ + new_max = (FT_UInt)outline->n_contours; old_max = hints->max_contours; if ( new_max > old_max ) { - new_max = (new_max + 3) & ~3; + new_max = ( new_max + 3 ) & ~3; if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) goto Exit; @@ -453,10 +477,11 @@ hints->max_contours = new_max; } - /* then, reallocate the points arrays if needed -- - * note that we reserved two additional point positions, used to - * hint metrics appropriately - */ + /* + * then, reallocate the points arrays if needed -- + * note that we reserve two additional point positions, used to + * hint metrics appropriately + */ new_max = (FT_UInt)( outline->n_points + 2 ); old_max = hints->max_points; if ( new_max > old_max ) @@ -472,17 +497,17 @@ hints->num_points = outline->n_points; hints->num_contours = outline->n_contours; - /* We can't rely on the value of `FT_Outline.flags' to know the fill */ - /* direction used for a glyph, given that some fonts are broken (e.g. */ - /* the Arphic ones). We thus recompute it each time we need to. */ - /* */ - hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_UP; - hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_LEFT; + /* We can't rely on the value of `FT_Outline.flags' to know the fill */ + /* direction used for a glyph, given that some fonts are broken (e.g., */ + /* the Arphic ones). We thus recompute it each time we need to. */ + /* */ + hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP; + hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT; if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT ) { - hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_DOWN; - hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_RIGHT; + hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN; + hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT; } hints->x_scale = x_scale; @@ -499,7 +524,7 @@ AF_Point point_limit = points + hints->num_points; - /* compute coordinates & bezier flags */ + /* compute coordinates & Bezier flags */ { FT_Vector* vec = outline->points; char* tag = outline->tags; @@ -582,9 +607,9 @@ { for ( point = points; point < point_limit; point++ ) { - AF_Point prev; - AF_Point next; - FT_Pos in_x, in_y, out_x, out_y; + AF_Point prev; + AF_Point next; + FT_Pos in_x, in_y, out_x, out_y; prev = point->prev; @@ -625,8 +650,7 @@ } } - /* compute inflection points - */ + /* compute inflection points */ af_glyph_hints_compute_inflections( hints ); Exit: @@ -635,18 +659,19 @@ FT_LOCAL_DEF( void ) - af_glyph_hints_save( AF_GlyphHints hints, - FT_Outline* outline ) + af_glyph_hints_save( AF_GlyphHints hints, + FT_Outline* outline ) { AF_Point point = hints->points; AF_Point limit = point + hints->num_points; FT_Vector* vec = outline->points; char* tag = outline->tags; + for ( ; point < limit; point++, vec++, tag++ ) { - vec->x = (FT_Pos) point->x; - vec->y = (FT_Pos) point->y; + vec->x = (FT_Pos)point->x; + vec->y = (FT_Pos)point->y; if ( point->flags & AF_FLAG_CONIC ) tag[0] = FT_CURVE_TAG_CONIC; @@ -658,22 +683,23 @@ } - /* - * - * E D G E P O I N T G R I D - F I T T I N G - * - */ + /**************************************************************** + * + * EDGE POINT GRID-FITTING + * + ****************************************************************/ FT_LOCAL_DEF( void ) af_glyph_hints_align_edge_points( AF_GlyphHints hints, AF_Dimension dim ) { - AF_AxisHints axis = & hints->axis[ dim ]; + AF_AxisHints axis = & hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; AF_Edge edge; + for ( edge = edges; edge < edge_limit; edge++ ) { /* move the points of each segment */ @@ -712,15 +738,16 @@ } - /* - * - * S T R O N G P O I N T I N T E R P O L A T I O N - * - */ + /**************************************************************** + * + * STRONG POINT INTERPOLATION + * + ****************************************************************/ /* hint the strong points -- this is equivalent to the TrueType `IP' */ /* hinting instruction */ + FT_LOCAL_DEF( void ) af_glyph_hints_align_strong_points( AF_GlyphHints hints, AF_Dimension dim ) @@ -743,6 +770,7 @@ AF_Point point; AF_Edge edge; + for ( point = points; point < point_limit; point++ ) { FT_Pos u, ou, fu; /* point position */ @@ -752,8 +780,9 @@ if ( point->flags & touch_flag ) continue; - /* if this point is candidate to weak interpolation, we will */ + /* if this point is candidate to weak interpolation, we */ /* interpolate it after all strong points have been processed */ + if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) && !( point->flags & AF_FLAG_INFLECTION ) ) continue; @@ -831,7 +860,6 @@ } } - Store_Point: /* save the point position */ @@ -846,11 +874,12 @@ } - /* - * - * W E A K P O I N T I N T E R P O L A T I O N - * - */ + /**************************************************************** + * + * WEAK POINT INTERPOLATION + * + ****************************************************************/ + static void af_iup_shift( AF_Point p1, @@ -974,7 +1003,7 @@ } } - point = points; + point = points; for ( ; contour < contour_limit; contour++ ) { @@ -1039,3 +1068,6 @@ point->y = point->u; } } + + +/* END */ diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c index fa5d56574..79e89ce72 100644 --- a/src/autofit/aflatin.c +++ b/src/autofit/aflatin.c @@ -1,12 +1,13 @@ #include "aflatin.h" - /***************************************************************************/ - /***************************************************************************/ - /***** *****/ - /***** L A T I N G L O B A L M E T R I C S *****/ - /***** *****/ - /***************************************************************************/ - /***************************************************************************/ + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L O B A L M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ static void af_latin_metrics_init_widths( AF_LatinMetrics metrics, @@ -15,19 +16,21 @@ /* scan the array of segments in each direction */ AF_GlyphHintsRec hints[1]; + af_glyph_hints_init( hints, face->memory ); - metrics->axis[ AF_DIMENSION_HORZ ].width_count = 0; - metrics->axis[ AF_DIMENSION_VERT ].width_count = 0; + metrics->axis[AF_DIMENSION_HORZ].width_count = 0; + metrics->axis[AF_DIMENSION_VERT].width_count = 0; - /* For now, compute the standard width and height from the `o' */ + /* For now, compute the standard width and height from the `o'. */ { - FT_Error error; - FT_UInt glyph_index; - AF_Dimension dim; + FT_Error error; + FT_UInt glyph_index; + AF_Dimension dim; AF_ScriptMetricsRec dummy[1]; AF_Scaler scaler = &dummy->scaler; + glyph_index = FT_Get_Char_Index( face, 'o' ); if ( glyph_index == 0 ) goto Exit; @@ -52,17 +55,19 @@ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { - AF_LatinAxis axis = & metrics->axis[ dim ]; - AF_AxisHints axhints = & hints->axis[ dim ]; + AF_LatinAxis axis = &metrics->axis[dim]; + AF_AxisHints axhints = &hints->axis[dim]; AF_Segment seg, limit, link; - FT_UInt num_widths = 0; + + FT_UInt num_widths = 0; FT_Pos edge_distance_threshold = 32000; + error = af_latin_hints_compute_segments( hints, dim ); if ( error ) goto Exit; - af_latin_hints_link_segments ( hints, dim ); + af_latin_hints_link_segments( hints, dim ); seg = axhints->segments; limit = seg + axhints->num_segments; @@ -70,6 +75,7 @@ for ( ; seg < limit; seg++ ) { link = seg->link; + /* we only consider stem segments there! */ if ( link && link->link == seg && link > seg ) { @@ -93,7 +99,7 @@ edge_distance_threshold = axis->widths[0].org; /* Now, compute the edge distance threshold as a fraction of the */ - /* smallest width in the font. Set it in `hinter->glyph' too! */ + /* smallest width in the font. Set it in `hinter->glyph' too! */ if ( edge_distance_threshold == 32000 ) edge_distance_threshold = 50; @@ -111,7 +117,7 @@ #define AF_LATIN_MAX_TEST_CHARACTERS 12 - static const char* const af_latin_blue_chars[ AF_LATIN_MAX_BLUES ] = + static const char* const af_latin_blue_chars[AF_LATIN_MAX_BLUES] = { "THEZOCQS", "HEZLOCUS", @@ -126,16 +132,17 @@ af_latin_metrics_init_blues( AF_LatinMetrics metrics, FT_Face face ) { - FT_Pos flats [ AF_LATIN_MAX_TEST_CHARACTERS ]; - FT_Pos rounds[ AF_LATIN_MAX_TEST_CHARACTERS ]; + FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS]; + FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS]; FT_Int num_flats; FT_Int num_rounds; FT_Int bb; AF_LatinBlue blue; FT_Error error; - AF_LatinAxis axis = &metrics->axis[ AF_DIMENSION_VERT ]; + AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; FT_GlyphSlot glyph = face->glyph; + /* we compute the blues simply by loading each character from the */ /* 'af_latin_blue_chars[blues]' string, then compute its top-most or */ /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ @@ -150,6 +157,7 @@ FT_Pos* blue_ref; FT_Pos* blue_shoot; + AF_LOG(( "blue %3d: ", bb )); num_flats = 0; @@ -276,10 +284,11 @@ if ( num_flats == 0 && num_rounds == 0 ) { - /* we couldn't find a single glyph to compute this blue zone, - * we will simply ignore it then - */ - AF_LOG(( "empty !!\n" )); + /* + * we couldn't find a single glyph to compute this blue zone, + * we will simply ignore it then + */ + AF_LOG(( "empty!\n" )); continue; } @@ -289,15 +298,15 @@ af_sort_pos( num_rounds, rounds ); af_sort_pos( num_flats, flats ); - blue = & axis->blues[ axis->blue_count ]; + blue = & axis->blues[axis->blue_count]; blue_ref = & blue->ref.org; blue_shoot = & blue->shoot.org; - axis->blue_count ++; + axis->blue_count++; if ( num_flats == 0 ) { - *blue_ref = + *blue_ref = *blue_shoot = rounds[num_rounds / 2]; } else if ( num_rounds == 0 ) @@ -326,13 +335,14 @@ } blue->flags = 0; - if ( AF_LATIN_IS_TOP_BLUE(bb) ) + 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. - */ + /* + * 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; @@ -347,12 +357,14 @@ af_latin_metrics_init( AF_LatinMetrics metrics, FT_Face face ) { - FT_Error error; - FT_CharMap oldmap = face->charmap; + FT_Error error; + FT_CharMap oldmap = face->charmap; + /* do we have a Unicode charmap in there? */ error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); - if ( error ) goto Exit; + if ( error ) + goto Exit; metrics->units_per_em = face->units_per_EM; @@ -366,15 +378,16 @@ static void - af_latin_metrics_scale_dim( AF_LatinMetrics metrics, - AF_Scaler scaler, - AF_Dimension dim ) + af_latin_metrics_scale_dim( AF_LatinMetrics metrics, + AF_Scaler scaler, + AF_Dimension dim ) { FT_Fixed scale; FT_Pos delta; AF_LatinAxis axis; FT_UInt nn; + if ( dim == AF_DIMENSION_HORZ ) { scale = scaler->x_scale; @@ -386,7 +399,7 @@ delta = scaler->y_delta; } - axis = & metrics->axis[ dim ]; + axis = & metrics->axis[dim]; if ( axis->org_scale == scale && axis->org_delta == delta ) return; @@ -394,14 +407,16 @@ axis->org_scale = scale; axis->org_delta = delta; - /* correct X and Y scale to optimize the alignment of the top of small - * letters to the pixel grid - */ + /* + * 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; + 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 ) @@ -446,38 +461,38 @@ metrics->root.scaler.y_delta = delta; } - /* scale the standard widths - */ + /* scale the standard widths */ for ( nn = 0; nn < axis->width_count; nn++ ) { AF_Width width = axis->widths + nn; + width->cur = FT_MulFix( width->org, scale ); width->fit = width->cur; } if ( dim == AF_DIMENSION_VERT ) { - /* scale the blue zones - */ + /* scale the blue zones */ for ( nn = 0; nn < axis->blue_count; nn++ ) { - AF_LatinBlue blue = & axis->blues[nn]; + 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->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 - */ + /* a blue zone is only active if it is less than 3/4 pixels tall */ dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); if ( dist <= 48 && dist >= -48 ) { FT_Pos delta, delta2; + delta = blue->shoot.org - blue->ref.org; delta2 = delta; if ( delta < 0 ) @@ -514,13 +529,13 @@ } - /***************************************************************************/ - /***************************************************************************/ - /***** *****/ - /***** L A T I N G L Y P H A N A L Y S I S *****/ - /***** *****/ - /***************************************************************************/ - /***************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H A N A L Y S I S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ FT_LOCAL_DEF( FT_Error ) af_latin_hints_compute_segments( AF_GlyphHints hints, @@ -528,17 +543,17 @@ { AF_AxisHints axis = &hints->axis[dim]; FT_Memory memory = hints->memory; - FT_Error error = 0; - AF_Segment segment = NULL; - AF_Point* contour = hints->contours; - AF_Point* contour_limit = contour + hints->num_contours; + FT_Error error = FT_Err_Ok; + AF_Segment segment = NULL; + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; AF_Direction major_dir, segment_dir; #ifdef AF_HINT_METRICS - AF_Point min_point = 0; - AF_Point max_point = 0; - FT_Pos min_coord = 32000; - FT_Pos max_coord = -32000; + AF_Point min_point = 0; + AF_Point max_point = 0; + FT_Pos min_coord = 32000; + FT_Pos max_coord = -32000; #endif major_dir = FT_ABS( axis->major_dir ); @@ -552,6 +567,7 @@ AF_Point point = hints->points; AF_Point limit = point + hints->num_points; + for ( ; point < limit; point++ ) { point->u = point->fx; @@ -563,6 +579,7 @@ AF_Point point = hints->points; AF_Point limit = point + hints->num_points; + for ( ; point < limit; point++ ) { point->u = point->fy; @@ -570,7 +587,6 @@ } } - /* do each contour separately */ for ( ; contour < contour_limit; contour++ ) { @@ -709,6 +725,7 @@ /* we need to ensure that there are edges on the left-most and */ /* right-most points of the glyph in order to hint the metrics; */ /* we do this by inserting fake segments when needed */ + if ( dim == AF_DIMENSION_HORZ ) { AF_Point point = hints->points; @@ -763,7 +780,7 @@ { /* clear all segment fields */ error = af_axis_hints_new_segment( axis, memory, &segment ); - if ( error) + if ( error ) goto Exit; segment->dir = segment_dir; @@ -794,6 +811,7 @@ AF_Direction major_dir = axis->major_dir; AF_Segment seg1, seg2; + /* now compare each segment to the others */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) { @@ -871,9 +889,9 @@ AF_AxisHints axis = &hints->axis[dim]; FT_Error error = 0; FT_Memory memory = hints->memory; - AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; + AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; - AF_Segment segments = axis->segments; + AF_Segment segments = axis->segments; AF_Segment segment_limit = segments + axis->num_segments; AF_Segment seg; @@ -881,6 +899,7 @@ FT_Fixed scale; FT_Pos edge_distance_threshold; + axis->num_edges = 0; scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale @@ -918,6 +937,7 @@ AF_Edge found = 0; FT_Int ee; + /* look for an edge corresponding to the segment */ for ( ee = 0; ee < axis->num_edges; ee++ ) { @@ -940,6 +960,7 @@ { AF_Edge edge; + /* insert a new edge in the list and */ /* sort according to the position */ error = af_axis_hints_new_edge( axis, seg->pos, memory, &edge ); @@ -947,7 +968,7 @@ goto Exit; /* add the segment to the new edge's list */ - FT_ZERO(edge); + FT_ZERO( edge ); edge->first = seg; edge->last = seg; @@ -981,16 +1002,17 @@ /* first of all, set the `edge' field in each segment -- this is */ /* required in order to compute edge links */ - /* Note that I've tried to remove this loop, setting - * the "edge" field of each segment directly in the - * code above. For some reason, it slows down execution - * speed -- on a Sun. + /* + * Note that removing this loop and setting the `edge' field of each + * segment directly in the code above slows down execution speed for + * some reasons on platforms like the Sun. */ { AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; AF_Edge edge; + for ( edge = edges; edge < edge_limit; edge++ ) { seg = edge->first; @@ -999,8 +1021,8 @@ { seg->edge = edge; seg = seg->edge_next; - } - while ( seg != edge->first ); + + } while ( seg != edge->first ); } /* now, compute each edge properties */ @@ -1121,11 +1143,13 @@ { FT_Error error; + error = af_latin_hints_compute_segments( hints, dim ); if ( !error ) { - af_latin_hints_link_segments ( hints, dim ); - error = af_latin_hints_compute_edges ( hints, dim ); + af_latin_hints_link_segments( hints, dim ); + + error = af_latin_hints_compute_edges( hints, dim ); } return error; } @@ -1145,12 +1169,12 @@ /* compute which blue zones are active, i.e. have their scaled */ /* size < 3/4 pixels */ - /* for each horizontal edge search the blue zone which is closest */ + /* for each horizontal edge search the blue zone which is closest */ for ( ; edge < edge_limit; edge++ ) { - FT_Int bb; - AF_Width best_blue = NULL; - FT_Pos best_dist; /* initial threshold */ + FT_Int bb; + AF_Width best_blue = NULL; + FT_Pos best_dist; /* initial threshold */ /* compute the initial threshold as a fraction of the EM size */ @@ -1164,16 +1188,16 @@ AF_LatinBlue blue = latin->blues + bb; FT_Bool is_top_blue, is_major_dir; - /* skip inactive blue zones (i.e. those that are too small - */ - if ( !(blue->flags & AF_LATIN_BLUE_ACTIVE) ) + + /* skip inactive blue zones (i.e., those that are too small) */ + if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) continue; /* if it is a top zone, check for right edges -- if it is a bottom */ /* zone, check for left edges */ /* */ /* of course, that's for TrueType */ - is_top_blue = (blue->flags & AF_LATIN_BLUE_TOP) != 0; + is_top_blue = ( blue->flags & AF_LATIN_BLUE_TOP ) != 0; is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); /* if it is a top zone, the edge must be against the major */ @@ -1181,7 +1205,7 @@ /* direction */ if ( is_top_blue ^ is_major_dir ) { - FT_Pos dist; + FT_Pos dist; /* first of all, compare it to the reference position */ @@ -1234,35 +1258,39 @@ { FT_Render_Mode mode; + 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; + /* + * 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... - */ + /* compute flags depending on render mode, etc... */ mode = metrics->root.scaler.render_mode; - /* we snap the width of vertical stems for the monochrome and - * horizontal LCD rendering targets only. - */ + /* + * We snap the width of vertical stems for the monochrome and + * horizontal LCD rendering targets only. + */ if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) hints->other_flags |= AF_LATIN_HINTS_HORZ_SNAP; - /* we snap the width of horizontal stems for the monochrome and - * vertical LCD rendering targets only. - */ + /* + * We snap the width of horizontal stems for the monochrome and + * vertical LCD rendering targets only. + */ if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) hints->other_flags |= AF_LATIN_HINTS_VERT_SNAP; - /* XXX - */ + /* + * We adjust stems to full pixels only if we don't use the `light' mode. + */ if ( mode != FT_RENDER_MODE_LIGHT ) hints->other_flags |= AF_LATIN_HINTS_STEM_ADJUST; @@ -1273,17 +1301,17 @@ } - - /***************************************************************************/ - /***************************************************************************/ - /***** *****/ - /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ - /***** *****/ - /***************************************************************************/ - /***************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ /* snap a given width in scaled coordinates to one of the */ /* current standard widths */ + static FT_Pos af_latin_snap_width( AF_Width widths, FT_Int count, @@ -1339,7 +1367,7 @@ AF_Edge_Flags stem_flags ) { AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; - AF_LatinAxis axis = & metrics->axis[ dim ]; + AF_LatinAxis axis = & metrics->axis[dim]; FT_Pos dist = width; FT_Int sign = 0; FT_Int vertical = AF_HINTS_DO_VERTICAL( hints ); @@ -1358,7 +1386,6 @@ ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) { /* smooth hinting process: very lightly quantize the stem width */ - /* */ /* leave the widths of serifs alone */ @@ -1377,8 +1404,8 @@ { FT_Pos delta; - /* compare to standard width - */ + + /* compare to standard width */ if ( axis->width_count > 0 ) { delta = dist - axis->widths[0].cur; @@ -1388,7 +1415,7 @@ if ( delta < 40 ) { - dist = axis->widths[ 0 ].cur; + dist = axis->widths[0].cur; if ( dist < 48 ) dist = 48; @@ -1420,13 +1447,14 @@ else { /* strong hinting process: snap the stem width to integer pixels */ - /* */ + dist = af_latin_snap_width( axis->widths, axis->width_count, dist ); if ( vertical ) { /* in the case of vertical hinting, always round */ /* the stem heights to integer pixels */ + if ( dist >= 64 ) dist = ( dist + 16 ) & ~63; else @@ -1438,6 +1466,7 @@ { /* monochrome horizontal hinting: snap widths to integer pixels */ /* with a different threshold */ + if ( dist < 64 ) dist = 64; else @@ -1448,6 +1477,7 @@ /* for horizontal anti-aliased hinting, we adopt a more subtle */ /* approach: we strengthen small stems, round stems whose size */ /* is between 1 and 2 pixels to an integer, otherwise nothing */ + if ( dist < 48 ) dist = ( dist + 64 ) >> 1; @@ -1468,8 +1498,8 @@ } - /* align one stem edge relative to the previous stem edge */ + static void af_latin_align_linked_edge( AF_GlyphHints hints, AF_Dimension dim, @@ -1484,6 +1514,7 @@ base_edge->flags, stem_edge->flags ); + stem_edge->pos = base_edge->pos + fitted_width; } @@ -1498,11 +1529,12 @@ serif->pos = base->pos + (serif->opos - base->opos); } + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ - /**** E D G E H I N T I N G ****/ + /**** E D G E H I N T I N G ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ @@ -1510,20 +1542,21 @@ FT_LOCAL_DEF( void ) - af_latin_hint_edges( AF_GlyphHints hints, - AF_Dimension dim ) + af_latin_hint_edges( AF_GlyphHints hints, + AF_Dimension dim ) { - AF_AxisHints axis = & hints->axis[dim]; - AF_Edge edges = axis->edges; + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; FT_Int n_edges; AF_Edge edge; - AF_Edge anchor = 0; + AF_Edge anchor = 0; FT_Int has_serifs = 0; /* we begin by aligning all stems relative to the blue zone */ /* if needed -- that's only for horizontal edges */ + if ( dim == AF_DIMENSION_VERT ) { for ( edge = edges; edge < edge_limit; edge++ ) @@ -1694,16 +1727,16 @@ org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); - cur_len = af_latin_compute_stem_width( hints, dim, org_len, - edge->flags, edge2->flags ); + cur_len = af_latin_compute_stem_width( + hints, dim, org_len, edge->flags, edge2->flags ); cur_pos1 = FT_PIX_ROUND( org_pos ); - delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center ); + delta1 = cur_pos1 + ( cur_len >> 1 ) - org_center; if ( delta1 < 0 ) delta1 = -delta1; cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len; - delta2 = ( cur_pos2 + ( cur_len >> 1 ) - org_center ); + delta2 = cur_pos2 + ( cur_len >> 1 ) - org_center; if ( delta2 < 0 ) delta2 = -delta2; @@ -1722,7 +1755,7 @@ /* make sure that lowercase m's maintain their symmetry */ /* In general, lowercase m's have six vertical edges if they are sans */ - /* serif, or twelve if they are avec serif. This implementation is */ + /* serif, or twelve if they are with serifs. This implementation is */ /* based on that assumption, and seems to work very well with most */ /* faces. However, if for a certain face this assumption is not */ /* true, the m is just rendered like before. In addition, any stem */ @@ -1783,9 +1816,10 @@ if ( has_serifs || !anchor ) { - /* now hint the remaining edges (serifs and single) in order - * to complete our processing - */ + /* + * now hint the remaining edges (serifs and single) in order + * to complete our processing + */ for ( edge = edges; edge < edge_limit; edge++ ) { if ( edge->flags & AF_EDGE_DONE ) @@ -1824,34 +1858,33 @@ FT_Error error; AF_Dimension dim; + error = af_glyph_hints_reload( hints, outline ); if ( error ) goto Exit; - /* analyze glyph outline - */ - if ( AF_HINTS_DO_HORIZONTAL(hints) ) + /* analyze glyph outline */ + if ( AF_HINTS_DO_HORIZONTAL( hints ) ) { error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ ); if ( error ) goto Exit; } - if ( AF_HINTS_DO_VERTICAL(hints) ) + if ( AF_HINTS_DO_VERTICAL( hints ) ) { - error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT ); + error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT ); if ( error ) goto Exit; af_latin_hints_compute_blue_edges( hints, metrics ); } - /* grid-fit the outline - */ + /* grid-fit the outline */ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { - if ( (dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL(hints)) || - (dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL(hints)) ) + if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || + ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) { af_latin_hint_edges( hints, dim ); af_glyph_hints_align_edge_points( hints, dim ); @@ -1865,33 +1898,39 @@ return error; } - /***************************************************************************/ - /***************************************************************************/ - /***** *****/ - /***** L A T I N S C R I P T C L A S S *****/ - /***** *****/ - /***************************************************************************/ - /***************************************************************************/ + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N S C R I P T C L A S S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + 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 } }; - FT_LOCAL_DEF( const AF_ScriptClassRec ) af_latin_script_class = + FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec + af_latin_script_class = { AF_SCRIPT_LATIN, af_latin_uniranges, sizeof( AF_LatinMetricsRec ), - (AF_Script_InitMetricsFunc) af_latin_metrics_init, - (AF_Script_ScaleMetricsFunc) af_latin_metrics_scale, - (AF_Script_DoneMetricsFunc) NULL, - (AF_Script_InitHintsFunc) af_latin_hints_init, - (AF_Script_ApplyHintsFunc) af_latin_hints_apply + (AF_Script_InitMetricsFunc) af_latin_metrics_init, + (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_latin_hints_init, + (AF_Script_ApplyHintsFunc) af_latin_hints_apply }; + +/* END */ diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h index 9b7f8fee1..945175f00 100644 --- a/src/autofit/aflatin.h +++ b/src/autofit/aflatin.h @@ -3,32 +3,33 @@ #include "afhints.h" + FT_BEGIN_HEADER - /* - * the latin-specific script class - * - */ - FT_LOCAL( const AF_ScriptClassRec ) af_latin_script_class; - /***************************************************************************/ - /***************************************************************************/ - /***** *****/ - /***** L A T I N G L O B A L M E T R I C S *****/ - /***** *****/ - /***************************************************************************/ - /***************************************************************************/ + /* the latin-specific script class */ - /* - * the following declarations could be embedded in the file "aflatin.c" - * they've been made semi-public to allow alternate script hinters to - * re-use some of them - */ + FT_CALLBACK_TABLE const AF_ScriptClassRec + af_latin_script_class; - /* - * Latin (global) metrics management - * - */ + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L O B A L M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* + * The following declarations could be embedded in the file `aflatin.c'; + * they have been made semi-public to allow alternate script hinters to + * re-use some of them. + */ + + + /* Latin (global) metrics management */ enum { @@ -42,45 +43,47 @@ FT_BEGIN_HEADER AF_LATIN_BLUE_MAX }; + #define AF_LATIN_IS_TOP_BLUE( b ) ( (b) == AF_LATIN_BLUE_CAPITAL_TOP || \ (b) == AF_LATIN_BLUE_SMALL_F_TOP || \ (b) == AF_LATIN_BLUE_SMALL_TOP ) -#define AF_LATIN_MAX_WIDTHS 16 -#define AF_LATIN_MAX_BLUES AF_LATIN_BLUE_MAX +#define AF_LATIN_MAX_WIDTHS 16 +#define AF_LATIN_MAX_BLUES AF_LATIN_BLUE_MAX + enum { - 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_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 }; - typedef struct AF_LatinBlueRec_ + typedef struct AF_LatinBlueRec_ { - AF_WidthRec ref; - AF_WidthRec shoot; - FT_UInt flags; + AF_WidthRec ref; + AF_WidthRec shoot; + FT_UInt flags; } AF_LatinBlueRec, *AF_LatinBlue; - typedef struct AF_LatinAxisRec_ + typedef struct AF_LatinAxisRec_ { FT_Fixed scale; FT_Pos delta; FT_UInt width_count; - AF_WidthRec widths[ AF_LATIN_MAX_WIDTHS ]; + AF_WidthRec widths[AF_LATIN_MAX_WIDTHS]; FT_Pos edge_distance_threshold; - /* ignored for horizontal metrics */ + /* ignored for horizontal metrics */ FT_Bool control_overshoot; FT_UInt blue_count; - AF_LatinBlueRec blues[ AF_LATIN_BLUE_MAX ]; + AF_LatinBlueRec blues[AF_LATIN_BLUE_MAX]; FT_Fixed org_scale; FT_Pos org_delta; @@ -88,16 +91,15 @@ FT_BEGIN_HEADER } AF_LatinAxisRec, *AF_LatinAxis; - typedef struct AF_LatinMetricsRec_ + typedef struct AF_LatinMetricsRec_ { - AF_ScriptMetricsRec root; - FT_UInt units_per_em; - AF_LatinAxisRec axis[ AF_DIMENSION_MAX ]; + AF_ScriptMetricsRec root; + FT_UInt units_per_em; + AF_LatinAxisRec axis[AF_DIMENSION_MAX]; } AF_LatinMetricsRec, *AF_LatinMetrics; - FT_LOCAL( FT_Error ) af_latin_metrics_init( AF_LatinMetrics metrics, FT_Face face ); @@ -108,52 +110,58 @@ FT_BEGIN_HEADER - /***************************************************************************/ - /***************************************************************************/ - /***** *****/ - /***** L A T I N G L Y P H A N A L Y S I S *****/ - /***** *****/ - /***************************************************************************/ - /***************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H A N A L Y S I S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ enum { - AF_LATIN_HINTS_HORZ_SNAP = (1 << 0), /* enable stem width snapping */ - AF_LATIN_HINTS_VERT_SNAP = (1 << 1), /* enable stem height snapping */ - AF_LATIN_HINTS_STEM_ADJUST = (1 << 2), /* enable stem width/height adjustment */ - AF_LATIN_HINTS_MONO = (1 << 3) /* indicate monochrome rendering */ + AF_LATIN_HINTS_HORZ_SNAP = ( 1 << 0 ), /* enable stem width snapping */ + AF_LATIN_HINTS_VERT_SNAP = ( 1 << 1 ), /* enable stem height snapping */ + AF_LATIN_HINTS_STEM_ADJUST = ( 1 << 2 ), /* enable stem width/height + adjustment */ + AF_LATIN_HINTS_MONO = ( 1 << 3 ) /* indicate monochrome + rendering */ }; -#define AF_LATIN_HINTS_DO_HORZ_SNAP(h) \ - AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_HORZ_SNAP) -#define AF_LATIN_HINTS_DO_VERT_SNAP(h) \ - AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_VERT_SNAP) +#define AF_LATIN_HINTS_DO_HORZ_SNAP( h ) \ + AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_HORZ_SNAP ) -#define AF_LATIN_HINTS_DO_STEM_ADJUST(h) \ - AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_STEM_ADJUST) +#define AF_LATIN_HINTS_DO_VERT_SNAP( h ) \ + AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_VERT_SNAP ) -#define AF_LATIN_HINTS_DO_MONO(h) \ - AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_MONO) +#define AF_LATIN_HINTS_DO_STEM_ADJUST( h ) \ + AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_STEM_ADJUST ) + +#define AF_LATIN_HINTS_DO_MONO( h ) \ + AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_MONO ) - /* this shouldn't normally be exported. However, other scripts might - * like to use this function as-is - */ + /* + * This shouldn't normally be exported. However, other scripts might + * like to use this function as-is. + */ FT_LOCAL( FT_Error ) af_latin_hints_compute_segments( AF_GlyphHints hints, AF_Dimension dim ); - /* this shouldn't normally be exported. However, other scripts might - * want to use this function as-is - */ + /* + * This shouldn't normally be exported. However, other scripts might + * want to use this function as-is. + */ FT_LOCAL( void ) af_latin_hints_link_segments( AF_GlyphHints hints, AF_Dimension dim ); - /* this shouldn't normally be exported. However, other scripts might - * want to use this function as-is - */ + /* + * This shouldn't normally be exported. However, other scripts might + * want to use this function as-is. + */ FT_LOCAL( FT_Error ) af_latin_hints_compute_edges( AF_GlyphHints hints, AF_Dimension dim ); @@ -167,3 +175,6 @@ FT_BEGIN_HEADER FT_END_HEADER #endif /* __AFLATIN_H__ */ + + +/* END */ diff --git a/src/autofit/afloader.c b/src/autofit/afloader.c index b88d29dc1..791fffb2a 100644 --- a/src/autofit/afloader.c +++ b/src/autofit/afloader.c @@ -3,12 +3,14 @@ #include "afglobal.h" #include "aflatin.h" + FT_LOCAL_DEF( FT_Error ) af_loader_init( AF_Loader loader, FT_Memory memory ) { FT_Error error; + FT_ZERO( loader ); af_glyph_hints_init( &loader->hints, memory ); @@ -28,13 +30,14 @@ FT_LOCAL_DEF( FT_Error ) - af_loader_reset( AF_Loader loader, - FT_Face face ) + af_loader_reset( AF_Loader loader, + FT_Face face ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; + loader->face = face; - loader->globals = (AF_FaceGlobals) face->autohint.data; + loader->globals = (AF_FaceGlobals)face->autohint.data; FT_GlyphLoader_Rewind( loader->gloader ); @@ -43,16 +46,19 @@ error = af_face_globals_new( face, &loader->globals ); if ( !error ) { - face->autohint.data = (FT_Pointer) loader->globals; - face->autohint.finalizer = (FT_Generic_Finalizer) af_face_globals_free; + face->autohint.data = + (FT_Pointer)loader->globals; + face->autohint.finalizer = + (FT_Generic_Finalizer)af_face_globals_free; } } + return error; } FT_LOCAL_DEF( void ) - af_loader_done( AF_Loader loader ) + af_loader_done( AF_Loader loader ) { af_glyph_hints_done( &loader->hints ); @@ -71,7 +77,7 @@ FT_Int32 load_flags, FT_UInt depth ) { - FT_Error error = 0; + FT_Error error; FT_Face face = loader->face; FT_GlyphLoader gloader = loader->gloader; AF_ScriptMetrics metrics = loader->metrics; @@ -79,6 +85,7 @@ FT_GlyphSlot slot = face->glyph; FT_Slot_Internal internal = slot->internal; + error = FT_Load_Glyph( face, glyph_index, load_flags ); if ( error ) goto Exit; @@ -88,6 +95,7 @@ { FT_Matrix inverse; + loader->trans_matrix = internal->glyph_matrix; loader->trans_delta = internal->glyph_delta; @@ -102,115 +110,114 @@ switch ( slot->format ) { - case FT_GLYPH_FORMAT_OUTLINE: - /* translate the loaded glyph when an internal transform - * is needed - */ - if ( loader->transformed ) - FT_Outline_Translate( &slot->outline, - loader->trans_delta.x, - loader->trans_delta.y ); + case FT_GLYPH_FORMAT_OUTLINE: + /* translate the loaded glyph when an internal transform is needed */ + if ( loader->transformed ) + 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 */ - error = FT_GlyphLoader_CheckPoints( gloader, - slot->outline.n_points + 4, - slot->outline.n_contours ); - if ( error ) - goto Exit; + /* copy the outline points in the loader's current */ + /* extra points which is used to keep original glyph coordinates */ + error = FT_GlyphLoader_CheckPoints( gloader, + slot->outline.n_points + 4, + slot->outline.n_contours ); + if ( error ) + goto Exit; - FT_ARRAY_COPY( gloader->current.outline.points, - slot->outline.points, - slot->outline.n_points ); + FT_ARRAY_COPY( gloader->current.outline.points, + slot->outline.points, + slot->outline.n_points ); - FT_ARRAY_COPY( gloader->current.extra_points, - slot->outline.points, - slot->outline.n_points ); + FT_ARRAY_COPY( gloader->current.extra_points, + slot->outline.points, + slot->outline.n_points ); - FT_ARRAY_COPY( gloader->current.outline.contours, - slot->outline.contours, - slot->outline.n_contours ); + FT_ARRAY_COPY( gloader->current.outline.contours, + slot->outline.contours, + slot->outline.n_contours ); - FT_ARRAY_COPY( gloader->current.outline.tags, - slot->outline.tags, - slot->outline.n_points ); + FT_ARRAY_COPY( gloader->current.outline.tags, + slot->outline.tags, + slot->outline.n_points ); - gloader->current.outline.n_points = slot->outline.n_points; - gloader->current.outline.n_contours = slot->outline.n_contours; + gloader->current.outline.n_points = slot->outline.n_points; + gloader->current.outline.n_contours = slot->outline.n_contours; - /* compute original horizontal phantom points (and ignore */ - /* vertical ones) */ - loader->pp1.x = hints->x_delta; - loader->pp1.y = hints->y_delta; - loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, - hints->x_scale ) + hints->x_delta; - loader->pp2.y = hints->y_delta; + /* compute original horizontal phantom points (and ignore */ + /* vertical ones) */ + loader->pp1.x = hints->x_delta; + loader->pp1.y = hints->y_delta; + loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, + hints->x_scale ) + hints->x_delta; + loader->pp2.y = hints->y_delta; - /* be sure to check for spacing glyphs */ - if ( slot->outline.n_points == 0 ) - goto Hint_Metrics; + /* be sure to check for spacing glyphs */ + if ( slot->outline.n_points == 0 ) + goto Hint_Metrics; - /* now load the slot image into the auto-outline and run the */ - /* automatic hinting process */ - metrics->clazz->script_hints_apply( hints, - &gloader->current.outline, - metrics ); + /* now load the slot image into the auto-outline and run the */ + /* automatic hinting process */ + 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 */ + /* we now need to hint the metrics according to the change in */ + /* width/positioning that occured during the hinting process */ + { + FT_Pos old_advance, old_rsb, old_lsb, new_lsb; + FT_Pos pp1x_uh, pp2x_uh; + AF_AxisHints axis = &hints->axis[ AF_DIMENSION_HORZ ]; + AF_Edge edge1 = axis->edges; /* leftmost edge */ + AF_Edge edge2 = edge1 + + axis->num_edges - 1; /* rightmost edge */ + + + if ( axis->num_edges > 1 ) { - FT_Pos old_advance, old_rsb, old_lsb, new_lsb; - FT_Pos pp1x_uh, pp2x_uh; - AF_AxisHints axis = &hints->axis[ AF_DIMENSION_HORZ ]; - AF_Edge edge1 = axis->edges; /* leftmost edge */ - AF_Edge edge2 = edge1 + - axis->num_edges - 1; /* rightmost edge */ + old_advance = loader->pp2.x; + old_rsb = old_advance - edge2->opos; + old_lsb = edge1->opos; + new_lsb = edge1->pos; + /* remember unhinted values to later account */ + /* for rounding errors */ - if ( axis->num_edges > 1 ) - { - old_advance = loader->pp2.x; - old_rsb = old_advance - edge2->opos; - old_lsb = edge1->opos; - new_lsb = edge1->pos; + pp1x_uh = new_lsb - old_lsb; + pp2x_uh = edge2->pos + old_rsb; - /* remember unhinted values to later account */ - /* for rounding errors */ + /* prefer too much space over too little space */ + /* for very small sizes */ - pp1x_uh = new_lsb - old_lsb; - pp2x_uh = edge2->pos + old_rsb; + if ( old_lsb < 24 ) + pp1x_uh -= 5; - /* prefer too much space over too little space */ - /* for very small sizes */ + if ( old_rsb < 24 ) + pp2x_uh += 5; - if ( old_lsb < 24 ) - pp1x_uh -= 5; + loader->pp1.x = FT_PIX_ROUND( pp1x_uh ); + loader->pp2.x = FT_PIX_ROUND( pp2x_uh ); - if ( old_rsb < 24 ) - pp2x_uh += 5; - - loader->pp1.x = FT_PIX_ROUND( pp1x_uh ); - loader->pp2.x = FT_PIX_ROUND( pp2x_uh ); - - slot->lsb_delta = loader->pp1.x - pp1x_uh; - slot->rsb_delta = loader->pp2.x - pp2x_uh; + slot->lsb_delta = loader->pp1.x - pp1x_uh; + slot->rsb_delta = loader->pp2.x - pp2x_uh; #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 */ - FT_GlyphLoader_Add( gloader ); - break; + } + 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 */ + FT_GlyphLoader_Add( gloader ); + break; case FT_GLYPH_FORMAT_COMPOSITE: { @@ -231,7 +238,7 @@ num_subglyphs ); gloader->current.num_subglyphs = num_subglyphs; - num_base_subgs = gloader->base.num_subglyphs; + num_base_subgs = gloader->base.num_subglyphs; /* now, read each subglyph independently */ for ( nn = 0; nn < num_subglyphs; nn++ ) @@ -325,8 +332,8 @@ x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta; y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta; - x = FT_PIX_ROUND(x); - y = FT_PIX_ROUND(y); + x = FT_PIX_ROUND( x ); + y = FT_PIX_ROUND( y ); } { @@ -364,10 +371,10 @@ FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); - bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); - bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); - bbox.xMax = FT_PIX_CEIL( bbox.xMax ); - bbox.yMax = FT_PIX_CEIL( bbox.yMax ); + bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); + bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); + bbox.xMax = FT_PIX_CEIL( bbox.xMax ); + bbox.yMax = FT_PIX_CEIL( bbox.yMax ); slot->metrics.width = bbox.xMax - bbox.xMin; slot->metrics.height = bbox.yMax - bbox.yMin; @@ -383,8 +390,6 @@ slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, x_scale ); #else - /* 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 @@ -413,8 +418,6 @@ } - - FT_LOCAL_DEF( FT_Error ) af_loader_load_glyph( AF_Loader loader, FT_Face face, @@ -425,6 +428,7 @@ FT_Size size = face->size; AF_ScalerRec scaler; + if ( !size ) return FT_Err_Invalid_Argument; @@ -444,7 +448,9 @@ { AF_ScriptMetrics metrics; - error = af_face_globals_get_metrics( loader->globals, gindex, &metrics ); + + error = af_face_globals_get_metrics( loader->globals, gindex, + &metrics ); if ( !error ) { loader->metrics = metrics; @@ -467,3 +473,6 @@ Exit: return error; } + + +/* END */ diff --git a/src/autofit/rules.mk b/src/autofit/rules.mk index 1d65e6f0f..ff20f1aa3 100644 --- a/src/autofit/rules.mk +++ b/src/autofit/rules.mk @@ -3,7 +3,7 @@ # -# AUTO driver directory +# AUTOF driver directory # AUTOF_DIR := $(SRC_DIR)/autofit @@ -13,23 +13,23 @@ AUTOF_DIR := $(SRC_DIR)/autofit AUTOF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(AUTOF_DIR)) -# AUTO driver sources (i.e., C files) +# AUTOF driver sources (i.e., C files) # -AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \ - $(AUTOF_DIR)/afdummy.c \ - $(AUTOF_DIR)/afglobal.c \ - $(AUTOF_DIR)/afhints.c \ - $(AUTOF_DIR)/afhints.c \ - $(AUTOF_DIR)/afloader.c \ +AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \ + $(AUTOF_DIR)/afdummy.c \ + $(AUTOF_DIR)/afglobal.c \ + $(AUTOF_DIR)/afhints.c \ + $(AUTOF_DIR)/aflatin.c \ + $(AUTOF_DIR)/afloader.c \ $(AUTOF_DIR)/afmodule.c -# AUTO driver headers +# AUTOF driver headers # -AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \ +AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \ $(AUTOF_DIR)/aftypes.h -# AUTO driver object(s) +# AUTOF driver object(s) # # AUTOF_DRV_OBJ_M is used during `multi' builds. # AUTOF_DRV_OBJ_S is used during `single' builds. @@ -37,19 +37,19 @@ AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h) \ AUTOF_DRV_OBJ_M := $(AUTOF_DRV_SRC:$(AUTOF_DIR)/%.c=$(OBJ_DIR)/%.$O) AUTOF_DRV_OBJ_S := $(OBJ_DIR)/autofit.$O -# AUTO driver source file for single build +# AUTOF driver source file for single build # AUTOF_DRV_SRC_S := $(AUTOF_DIR)/autofit.c -# AUTO driver - single object +# AUTOF driver - single object # $(AUTOF_DRV_OBJ_S): $(AUTOF_DRV_SRC_S) $(AUTOF_DRV_SRC) \ $(FREETYPE_H) $(AUTOF_DRV_H) $(AUTOF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(AUTOF_DRV_SRC_S)) -# AUTO driver - multiple objects +# AUTOF driver - multiple objects # $(OBJ_DIR)/%.$O: $(AUTOF_DIR)/%.c $(FREETYPE_H) $(AUTOF_DRV_H) $(AUTOF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) diff --git a/src/sfnt/ttkern.c b/src/sfnt/ttkern.c index 2b6a1687d..f00e3d8b6 100644 --- a/src/sfnt/ttkern.c +++ b/src/sfnt/ttkern.c @@ -197,7 +197,8 @@ FT_UInt coverage = FT_NEXT_USHORT( p ); FT_Int value = 0; - FT_UNUSED(version); + FT_UNUSED( version ); + next = base + length; diff --git a/src/sfnt/ttsbit.h b/src/sfnt/ttsbit.h index e5b486c6c..d2734dd81 100644 --- a/src/sfnt/ttsbit.h +++ b/src/sfnt/ttsbit.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/sfnt/ttsbit0.c b/src/sfnt/ttsbit0.c index c27786db3..fb9462ea4 100644 --- a/src/sfnt/ttsbit0.c +++ b/src/sfnt/ttsbit0.c @@ -535,11 +535,11 @@ static FT_Error - tt_sbit_decoder_load_bit_aligned ( TT_SBitDecoder decoder, - FT_Byte* p, - FT_Byte* limit, - FT_Int x_pos, - FT_Int y_pos ) + tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, + FT_Byte* p, + FT_Byte* limit, + FT_Int x_pos, + FT_Int y_pos ) { FT_Error error = SFNT_Err_Ok; FT_Byte* line; @@ -629,7 +629,7 @@ FT_Int x_pos, FT_Int y_pos ) { - FT_Error error = 0; + FT_Error error = SFNT_Err_Ok; FT_UInt num_components, nn;