diff --git a/ChangeLog b/ChangeLog index 158d337db..ea61d4d3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2003-12-24 David Turner + + * fixed compilation problems in the cache sub-system + + * partial updates to src/autofit + + * MERRY X-MAS ! + 2003-12-23 Werner Lemberg * src/cff/cffgload.c (cff_lookup_glyph_by_stdcharcode): Handle @@ -7,11 +15,14 @@ * include/freetype/internal/ftobjs.h (FT_PAD_FLOOR, FT_PAD_ROUND, FT_PAD_CEIL, FT_PIX_FLOOR, FT_PIX_ROUND, FT_CEIL): New macros. They - are used to avoid compiler warnings with very pedantic compilers. + are used to avoid compiler warnings with very pedantic compilers. Note that `(x) & -64' causes a warning if (x) is not signed. Use `(x) & ~63' instead! Updated all related code. + * include/freetype/ftstroke.h, src/base/ftstroke.c: added support + for extraction of "inside" and "outside" borders + 2003-12-22 Werner Lemberg * include/freetype/ftwinfnt.h (FT_WinFNT_ID_*): New definitions diff --git a/Jamfile b/Jamfile index 6d944669f..11443f181 100644 --- a/Jamfile +++ b/Jamfile @@ -61,7 +61,8 @@ FT2_BUILD_INCLUDE ?= ; # IMPORTANT: You'll need to change the content of "ftmodule.h" as well # if you modify this list or provide your own. # -FT2_COMPONENTS ?= gzip # support for gzip-compressed files +FT2_COMPONENTS ?= autofit # auto-fitter + gzip # support for gzip-compressed files autohint # auto-hinter base # base component (public APIs) bdf # BDF font driver diff --git a/src/autofit/afangles.c b/src/autofit/afangles.c index 83729e5d1..10a8cff25 100644 --- a/src/autofit/afangles.c +++ b/src/autofit/afangles.c @@ -2,6 +2,7 @@ /* this table was generated for AF_ANGLE_PI = 256 */ #define AF_ANGLE_MAX_ITERS 8 +#define AF_TRIG_MAX_ITERS 9 static const FT_Fixed af_angle_arctan_table[9] = @@ -118,7 +119,7 @@ if ( theta >= 0 ) theta = FT_PAD_ROUND( theta, 4 ); else - theta = - FT_PAD_ROUND( -theta, 4 ); + theta = - FT_PAD_ROUND( theta, 4 ); vec->x = x; vec->y = theta; @@ -171,8 +172,8 @@ af_sort_pos( FT_UInt count, FT_Pos* table ) { - FT_Int i, j; - FT_Pos swap; + FT_UInt i, j; + FT_Pos swap; for ( i = 1; i < count; i++ ) @@ -188,4 +189,26 @@ } } } - \ No newline at end of file + + + FT_LOCAL_DEF( void ) + af_sort_widths( FT_UInt count, + AF_Width table ) + { + FT_UInt i, j; + AF_WidthRec swap; + + + for ( i = 1; i < count; i++ ) + { + for ( j = i; j > 0; j-- ) + { + if ( table[j].org > table[j - 1].org ) + break; + + swap = table[j]; + table[j] = table[j - 1]; + table[j - 1] = swap; + } + } + } diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c index 6f1540cc6..e3f569b45 100644 --- a/src/autofit/afglobal.c +++ b/src/autofit/afglobal.c @@ -3,19 +3,19 @@ /* populate this list when you add new scripts */ - static AF_ScriptClass const af_script_class_list[] = + static AF_ScriptClass const af_script_classes[] = { & af_latin_script_class, NULL /* do not remove */ }; -#define AF_SCRIPT_LIST_DEFAULT 0 /* index of default script in 'af_script_class_list' */ +#define AF_SCRIPT_LIST_DEFAULT 0 /* index of default script in 'af_script_classes' */ #define AF_SCRIPT_LIST_NONE 255 /* indicates an uncovered glyph */ /* * note that glyph_scripts[] is used to map each glyph into - * an index into the 'af_script_class_list' array. + * an index into the 'af_script_classes' array. * */ typedef struct AF_FaceGlobalsRec_ @@ -26,7 +26,7 @@ AF_ScriptMetrics metrics[ AF_SCRIPT_MAX ]; - } AF_FaceGlobalsRec, *AF_FaceGlobals; + } AF_FaceGlobalsRec; @@ -143,7 +143,6 @@ } } - Exit: *aglobals = globals; return error; } @@ -163,7 +162,7 @@ { AF_ScriptClass clazz = af_script_classes[nn]; - FT_ASSERT( globals->metrics[nn].clazz == clazz ); + FT_ASSERT( globals->metrics[nn]->clazz == clazz ); if ( clazz->script_metrics_done ) clazz->script_metrics_done( globals->metrics[nn] ); @@ -172,7 +171,7 @@ } } - globals->glyph_count = NULL; + globals->glyph_count = 0; globals->glyph_scripts = NULL; /* no need to free this one !! */ globals->face = NULL; FT_FREE( globals ); @@ -185,7 +184,7 @@ FT_UInt gindex, AF_ScriptMetrics *ametrics ) { - FT_Script script; + AF_Script script; AF_ScriptMetrics metrics = NULL; FT_UInt index; AF_ScriptClass clazz; @@ -198,7 +197,7 @@ } index = globals->glyph_scripts[ gindex ]; - clazz = af_script_class_list[ index ]; + clazz = af_script_classes[ index ]; metrics = globals->metrics[ clazz->script ]; if ( metrics == NULL ) { @@ -211,7 +210,7 @@ if ( clazz->script_metrics_init ) { - error = clazz->script_metrics_init( metrics, face ); + error = clazz->script_metrics_init( metrics, globals->face ); if ( error ) { if ( clazz->script_metrics_done ) diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c index 3c1e10b5c..04275f36d 100644 --- a/src/autofit/afhints.c +++ b/src/autofit/afhints.c @@ -171,8 +171,8 @@ } while ( end->fx == first->fx && end->fy == first->fy ); - angle_seg = af_angle( end->fx - start->fx, - end->fy - start->fy ); + angle_seg = af_angle_atan( end->fx - start->fx, + end->fy - start->fy ); /* extend the segment start whenever possible */ before = start; @@ -187,8 +187,8 @@ } while ( before->fx == start->fx && before->fy == start->fy ); - angle_in = af_angle( start->fx - before->fx, - start->fy - before->fy ); + angle_in = af_angle_atan( start->fx - before->fx, + start->fy - before->fy ); } while ( angle_in == angle_seg ); @@ -211,10 +211,8 @@ } while ( end->fx == after->fx && end->fy == after->fy ); - vec.x = after->fx - end->fx; - vec.y = after->fy - end->fy; - angle_out = af_angle( after->fx - end->fx, - after->fy - end->fy ); + angle_out = af_angle_atan( after->fx - end->fx, + after->fy - end->fy ); } while ( angle_out == angle_seg ); @@ -295,15 +293,19 @@ FT_LOCAL_DEF( FT_Error ) af_glyph_hints_reset( AF_GlyphHints hints, - FT_Outline* outline, - FT_Fixed x_scale, - FT_Fixed y_scale, - FT_Pos x_delta, - FT_Pos y_delta ) + AF_Scaler scaler, + FT_Outline* outline ) { - FT_Error error = AF_Err_Ok; - + 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; + + hints->scaler_flags = scaler->flags; + hints->other_flags = 0; hints->num_points = 0; hints->num_contours = 0; @@ -350,7 +352,7 @@ #undef OFF_INCREMENT #define OFF_INCREMENT( _off, _type, _count ) \ - ((((_off) + sizeof(_type)) & ~(sizeof(_type)) + ((_count)*sizeof(_type))) + ( FT_PAD_CEIL( _off, sizeof(_type) ) + (_count)*sizeof(_type)) off1 = OFF_INCREMENT( 0, AF_PointRec, new_max ); off2 = OFF_INCREMENT( off1, AF_SegmentRec, new_max ); @@ -467,7 +469,7 @@ contour_index++; if ( point + 1 < point_limit ) { - end = points + source->contours[contour_index]; + end = points + outline->contours[contour_index]; first = point + 1; prev = end; } @@ -524,8 +526,8 @@ if ( point->out_dir != AF_DIR_NONE ) goto Is_Weak_Point; - angle_in = af_angle( in_x, in_y ); - angle_out = af_angle( out_x, out_y ); + angle_in = af_angle_atan( in_x, in_y ); + angle_out = af_angle_atan( out_x, out_y ); delta = af_angle_diff( angle_in, angle_out ); if ( delta < 2 && delta > -2 ) @@ -616,7 +618,7 @@ AF_Dimension dim ) { AF_Point points = hints->points; - AF_Point point_limit = points + hints->num_points;; + AF_Point point_limit = points + hints->num_points; AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; @@ -650,7 +652,7 @@ !( point->flags & AF_FLAG_INFLECTION ) ) continue; - if ( dimension ) + if ( dim == AF_DIMENSION_VERT ) { u = point->fy; ou = point->oy; diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h index dda37537d..7283cc39e 100644 --- a/src/autofit/afhints.h +++ b/src/autofit/afhints.h @@ -179,10 +179,25 @@ FT_BEGIN_HEADER AF_Point* contours; AF_AxisHintsRec axis[ AF_DIMENSION_MAX ]; + + FT_UInt32 scaler_flags; /* copy of scaler flags */ + FT_UInt32 other_flags; /* free for script-specific implementations */ + AF_ScriptMetrics metrics; } AF_GlyphHintsRec; +#define AF_HINTS_TEST_SCALER(h,f) ( (h)->scaler_flags & (f) ) +#define AF_HINTS_TEST_OTHER(h,f) ( (h)->other_flags & (f) ) + +#define AF_HINTS_DO_HORIZONTAL(h) \ + !AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_HORIZONTAL) + +#define AF_HINTS_DO_VERTICAL(h) \ + !AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_VERTICAL) + +#define AF_HINTS_DO_ADVANCE(h) \ + !AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_ADVANCE) FT_LOCAL( AF_Direction ) @@ -201,11 +216,8 @@ FT_BEGIN_HEADER */ FT_LOCAL( FT_Error ) af_glyph_hints_reset( AF_GlyphHints hints, - FT_Outline* outline, - FT_Fixed x_scale, - FT_Fixed y_scale, - FT_Pos x_delta, - FT_Pos y_delta ); + AF_Scaler scaler, + FT_Outline* outline ); FT_LOCAL( void ) af_glyph_hints_align_edge_points( AF_GlyphHints hints, diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c index de727c05f..ac9a7c607 100644 --- a/src/autofit/aflatin.c +++ b/src/autofit/aflatin.c @@ -22,20 +22,27 @@ /* For now, compute the standard width and height from the `o' */ { + FT_Error error; FT_UInt glyph_index; AF_Dimension dim; + AF_ScalerRec scaler[1]; glyph_index = FT_Get_Char_Index( face, 'o' ); if ( glyph_index == 0 ) goto Exit; - error = FT_Load_Glyph( hinter->face, glyph_index, FT_LOAD_NO_SCALE ); + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); if ( error || face->glyph->outline.n_points <= 0 ) goto Exit; - error = af_glyph_hints_reset( hints, &face->glyph->outline, - 0x10000L, 0x10000L ); + 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, &face->glyph->outline ); if ( error ) goto Exit; @@ -67,16 +74,16 @@ dist = -dist; if ( num_widths < AF_LATIN_MAX_WIDTHS ) - axis->widths[ num_widths++ ] = dist; + axis->widths[ num_widths++ ].org = dist; } } - af_sort_pos( axis->widths, num_widths ); + af_sort_widths( num_widths, axis->widths ); axis->width_count = num_widths; /* we will now try to find the smallest width */ - if ( num_widths > 0 && axis->widths[0] < edge_distance_threshold ) - edge_distance_threshold = axis->widths[0]; + if ( num_widths > 0 && axis->widths[0].org < edge_distance_threshold ) + 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! */ @@ -129,7 +136,7 @@ AF_LOG(( "blue zones computation\n" )); AF_LOG(( "------------------------------------------------\n" )); - for ( bb = 0; bb < AF_BLUE_MAX; bb++ ) + for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) { const char* p = af_latin_blue_chars[bb]; const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; @@ -275,7 +282,7 @@ 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; @@ -284,7 +291,7 @@ if ( num_flats == 0 ) { *blue_ref = - *blue->shoot = rounds[num_rounds / 2]; + *blue_shoot = rounds[num_rounds / 2]; } else if ( num_rounds == 0 ) { @@ -366,7 +373,7 @@ delta = scaler->y_delta; } - axis = metrics->axis[ dim ]; + axis = & metrics->axis[ dim ]; if ( axis->scale == scale && axis->delta == delta ) return; @@ -414,8 +421,8 @@ af_latin_metrics_scale( AF_LatinMetrics metrics, AF_Scaler scaler ) { - af_latin_metrics_scale( metrics, scaler, AF_DIMENSION_HORZ ); - af_latin_metrics_scale( metrics, scaler, AF_DIMENSION_VERT ); + af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); + af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); } @@ -437,7 +444,7 @@ FT_Int num_segments = 0; AF_Point* contour = hints->contours; AF_Point* contour_limit = contour + hints->num_contours; - AF_Direction major_dir; + AF_Direction major_dir, segment_dir; #ifdef AF_HINT_METRICS AF_Point min_point = 0; @@ -802,7 +809,7 @@ /* */ /*********************************************************************/ - edge_distance_threshold = FT_MulFix( outline->edge_distance_threshold, + edge_distance_threshold = FT_MulFix( hints->edge_distance_threshold, scale ); if ( edge_distance_threshold > 64 / 4 ) edge_distance_threshold = 64 / 4; @@ -863,7 +870,7 @@ edge->last = seg; } } - *p_num_edges = (FT_Int)( edge_limit - edges ); + axis->num_edges = (FT_Int)( edge_limit - edges ); /*********************************************************************/ @@ -1012,7 +1019,7 @@ { af_latin_hints_compute_segments( hints, dim ); af_latin_hints_link_segments ( hints, dim ); - af_latin_hints_compute_edges ( hints dim ); + af_latin_hints_compute_edges ( hints, dim ); } @@ -1039,7 +1046,7 @@ /* compute the initial threshold as a fraction of the EM size */ - best_dist = FT_MulFix( metrics->units_pe_EM / 40, scale ); + best_dist = FT_MulFix( metrics->units_per_em / 40, scale ); if ( best_dist > 64 / 2 ) best_dist = 64 / 2; @@ -1051,14 +1058,14 @@ /* skip inactive blue zones (i.e. those that are too small */ - if ( !(bb->flags & AF_LATIN_BLUE_ACTIVE) ) + 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 XXX */ - is_top_blue = (bb->flags & AF_LATIN_BLUE_TOP) != 0; + /* of course, that's for TrueType */ + 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 */ @@ -1074,7 +1081,7 @@ if ( dist < 0 ) dist = -dist; - dist = FT_MulFix( dist, y_scale ); + dist = FT_MulFix( dist, scale ); if ( dist < best_dist ) { best_dist = dist; @@ -1091,12 +1098,12 @@ if ( is_top_blue ^ is_under_ref ) { - blue = _pos = globals->blue_shoots + blue; + blue = latin->blues + bb; dist = edge->fpos - blue->shoot.org; if ( dist < 0 ) dist = -dist; - dist = FT_MulFix( dist, y_scale ); + dist = FT_MulFix( dist, scale ); if ( dist < best_dist ) { best_dist = dist; @@ -1116,20 +1123,52 @@ static FT_Error af_latin_hints_init( AF_GlyphHints hints, AF_Scaler scaler, + FT_Outline* outline, AF_LatinMetrics metrics ) { - FT_Error error; + FT_Error error; + FT_Render_Mode mode; + + error = af_glyph_hints_reset( hints, scaler, outline ); + if (error) + goto Exit; + + + /* compute flags depending on render mode, etc... + */ + + mode = scaler->render_mode; + + /* 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. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) + hints->other_flags |= AF_LATIN_HINTS_VERT_SNAP; + + /* XXX + */ + if ( mode != FT_RENDER_MODE_LIGHT ) + hints->other_flags |= AF_LATIN_HINTS_STEM_ADJUST; - error = af_glyph_hints_reset( hints, &scaler->outline, - scaler->x_scale, - scaler->y_scale, - scaler->x_delta, - scaler->y_delta ); - if (error) - goto Exit; + if ( mode == FT_RENDER_MODE_MONO ) + hints->other_flags |= AF_LATIN_HINTS_MONO; - af_latin_hints_detect_features( hints, metrics ); - af_latin_hints_compute_blue_edges( hints, metrics ); + /* 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; @@ -1193,17 +1232,21 @@ /* compute the snapped width of a given stem */ static FT_Pos - af_latin_compute_stem_width( AF_GylphHints hints, + af_latin_compute_stem_width( AF_GlyphHints hints, AF_Dimension dim, FT_Pos width, AF_Edge_Flags base_flags, AF_Edge_Flags stem_flags ) { - AF_Globals globals = &hinter->globals->scaled; - FT_Pos dist = width; - FT_Int sign = 0; - FT_Bool vertical = FT_BOOL( dim == AF_DIMENSION_VERT ); + AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; + AF_LatinAxis axis = & metrics->axis[ dim ]; + FT_Pos dist = width; + FT_Int sign = 0; + FT_Int vertical = AF_HINTS_DO_VERTICAL( hints ); + + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ) + return width; if ( dist < 0 ) { @@ -1211,12 +1254,8 @@ sign = 1; } - if ( !hinter->do_stem_adjust ) - { - /* leave stem widths unchanged */ - } - else if ( ( vertical && !hinter->do_vert_snapping ) || - ( !vertical && !hinter->do_horz_snapping ) ) + if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAPPING( hints ) ) || + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAPPING( hints ) ) ) { /* smooth hinting process: very lightly quantize the stem width */ /* */ @@ -1234,20 +1273,27 @@ else if ( dist < 56 ) dist = 56; + if ( axis->width_count > 0 ) { - FT_Pos delta = dist - globals->stds[vertical]; - + FT_Pos delta; - if ( delta < 0 ) - delta = -delta; - - if ( delta < 40 ) + /* compare to standard width + */ + if ( axis->width_count > 0 ) { - dist = globals->stds[vertical]; - if ( dist < 48 ) - dist = 48; + delta = dist - axis->widths[0].cur; + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + dist = axis->widths[ 0 ].cur; + if ( dist < 48 ) + dist = 48; - goto Done_Width; + goto Done_Width; + } } if ( dist < 3 * 64 ) @@ -1275,10 +1321,10 @@ { /* strong hinting process: snap the stem width to integer pixels */ /* */ + dist = af_latin_snap_width( axis->widths, axis->width_count, dist ); + if ( vertical ) { - dist = af_snap_width( globals->heights, globals->num_heights, dist ); - /* in the case of vertical hinting, always round */ /* the stem heights to integer pixels */ if ( dist >= 64 ) @@ -1288,9 +1334,7 @@ } else { - dist = af_snap_width( globals->widths, globals->num_widths, dist ); - - if ( hinter->flags & AF_HINTER_MONOCHROME ) + if ( AF_LATIN_HINTS_DO_MONO( hints ) ) { /* monochrome horizontal hinting: snap widths to integer pixels */ /* with a different threshold */ @@ -1310,7 +1354,7 @@ else if ( dist < 128 ) dist = ( dist + 22 ) & ~63; else - /* XXX: round otherwise to prevent color fringes in LCD mode */ + /* round otherwise to prevent color fringes in LCD mode */ dist = ( dist + 32 ) & ~63; } } @@ -1384,8 +1428,8 @@ { for ( edge = edges; edge < edge_limit; edge++ ) { - AF_Width* blue; - AF_Edge edge1, edge2; + AF_Width blue; + AF_Edge edge1, edge2; if ( edge->flags & AF_EDGE_DONE ) @@ -1446,7 +1490,7 @@ /* this should not happen, but it's better to be safe */ if ( edge2->blue_edge || edge2 < edge ) { - af_latin_align_linked_edge( hinter, edge2, edge, dimension ); + af_latin_align_linked_edge( hints, dim, edge2, edge ); edge->flags |= AF_EDGE_DONE; continue; } @@ -1510,8 +1554,8 @@ org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); - cur_len = af_compute_stem_width( hinter, dimension, org_len, - edge->flags, edge2->flags ); + cur_len = af_latin_compute_stem_width( hints, dim, org_len, + edge->flags, edge2->flags ); if ( cur_len < 96 ) { @@ -1550,8 +1594,8 @@ org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); - cur_len = af_compute_stem_width( hinter, dimension, 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 ); @@ -1648,14 +1692,14 @@ continue; if ( edge->serif ) - af_align_serif_edge( hinter, edge->serif, edge, dimension ); + af_latin_align_serif_edge( hints, edge->serif, edge ); else if ( !anchor ) { edge->pos = FT_PIX_ROUND( edge->opos ); anchor = edge; } else - edge->pos = anchor->pos + + edge->pos = anchor->pos + FT_PIX_ROUND( edge->opos - anchor->opos ); edge->flags |= AF_EDGE_DONE; @@ -1677,8 +1721,20 @@ AF_Scaler scaler, AF_LatinMetrics metrics ) { - /* XXX */ - return FT_Err_Unimplemented; + AF_Dimension dim; + + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + if ( (dim == AF_DIMENSION_HORZ && AF_LATIN_HINTS_DO_HORIZONTAL(hints)) || + (dim == AF_DIMENSION_VERT && AF_LATIN_HINTS_DO_VERTICAL(hints)) ) + { + af_latin_hint_edges( hints, dim ); + af_glyph_hints_align_edge_points( hints, dim ); + af_glyph_hints_align_strong_points( hints, dim ); + af_glyph_hints_align_weak_points( hints, dim ); + } + } + return 0; } /***************************************************************************/ @@ -1699,7 +1755,7 @@ FT_LOCAL_DEF( const AF_ScriptClassRec ) af_latin_script_class = { AF_SCRIPT_LATIN, - &af_latin_script_uniranges, + af_latin_uniranges, sizeof( AF_LatinMetricsRec ), (AF_Script_InitMetricsFunc) af_latin_metrics_init, diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h index 816c5c5b8..a2595038a 100644 --- a/src/autofit/aflatin.h +++ b/src/autofit/aflatin.h @@ -9,7 +9,7 @@ FT_BEGIN_HEADER * the latin-specific script class * */ - FT_LOCAL( const FT_ScriptClassRec ) af_latin_script_class; + FT_LOCAL( const AF_ScriptClassRec ) af_latin_script_class; /***************************************************************************/ /***************************************************************************/ @@ -54,7 +54,7 @@ FT_BEGIN_HEADER AF_LATIN_BLUE_ACTIVE = (1 << 0), AF_LATIN_BLUE_TOP = (1 << 1), - AF_LATIN_BLUE_MAX + AF_LATIN_BLUE_FLAG_MAX }; @@ -79,7 +79,7 @@ FT_BEGIN_HEADER /* ignored for horizontal metrics */ FT_Bool control_overshoot; FT_UInt blue_count; - AF_LatinBlueRec blues; + AF_LatinBlueRec blues[ AF_LATIN_BLUE_MAX ]; } AF_LatinAxisRec, *AF_LatinAxis; @@ -93,6 +93,7 @@ FT_BEGIN_HEADER } AF_LatinMetricsRec, *AF_LatinMetrics; + FT_LOCAL( FT_Error ) af_latin_metrics_init( AF_LatinMetrics metrics, FT_Face face ); @@ -111,6 +112,26 @@ FT_BEGIN_HEADER /***************************************************************************/ /***************************************************************************/ + 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 */ + }; + +#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_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 diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h index 33cb46475..0f1d243cc 100644 --- a/src/autofit/aftypes.h +++ b/src/autofit/aftypes.h @@ -3,6 +3,9 @@ #include #include FT_FREETYPE_H +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H FT_BEGIN_HEADER @@ -44,10 +47,15 @@ FT_BEGIN_HEADER } AF_WidthRec, *AF_Width; - AF_LOCAL( void ) + FT_LOCAL( void ) af_sort_pos( FT_UInt count, FT_Pos* table ); + FT_LOCAL( void ) + af_sort_widths( FT_UInt count, + AF_Width widths ); + + /**************************************************************************/ /**************************************************************************/ /***** *****/ @@ -75,8 +83,8 @@ FT_BEGIN_HEADER * */ FT_LOCAL( AF_Angle ) - af_angle( FT_Pos dx, - FT_Pos dy ); + af_angle_atan( FT_Pos dx, + FT_Pos dy ); /* @@ -109,7 +117,7 @@ FT_BEGIN_HEADER typedef struct AF_OutlineRec_ { FT_Face face; - FT_OutlineRec outline; + FT_Outline outline; FT_UInt outline_resolution; FT_Int advance; @@ -231,8 +239,9 @@ FT_BEGIN_HEADER FT_UInt32 first; FT_UInt32 last; - } AF_Script_UniRangeRec, *AF_Script_UniRange; + } AF_Script_UniRangeRec; + typedef const AF_Script_UniRangeRec * AF_Script_UniRange; typedef struct AF_ScriptClassRec_ { diff --git a/src/cache/ftccache.c b/src/cache/ftccache.c index 5ce7982e0..64e5fce5f 100644 --- a/src/cache/ftccache.c +++ b/src/cache/ftccache.c @@ -460,7 +460,7 @@ } } goto AddNode; - } + } FT_EXPORT_DEF( FT_Error ) @@ -529,7 +529,7 @@ { FT_UFast i, count; FTC_Manager manager = cache->manager; - FTC_Node free = NULL; + FTC_Node frees = NULL; count = cache->p + cache->mask; for ( i = 0; i < count; i++ ) @@ -547,8 +547,8 @@ if ( cache->clazz.node_remove_faceid( node, face_id, cache ) ) { *pnode = node->link; - node->link = free; - free = node; + node->link = frees; + frees = node; } else pnode = &node->link; @@ -557,12 +557,12 @@ /* remove all nodes in the free list */ - while ( free ) + while ( frees ) { FTC_Node node; - node = free; - free = node->link; + node = frees; + frees = node->link; manager->cur_weight -= cache->clazz.node_weight( node, cache ); ftc_node_mru_unlink( node, manager ); diff --git a/src/cache/ftcmru.c b/src/cache/ftcmru.c index 2c696fcc4..ca0b69265 100644 --- a/src/cache/ftcmru.c +++ b/src/cache/ftcmru.c @@ -258,7 +258,6 @@ FTC_MruNode *anode ) { FTC_MruNode node; - FT_Error error = 0; node = FTC_MruList_Find( list, key ); if ( node == NULL ) diff --git a/src/cache/ftcsbits.c b/src/cache/ftcsbits.c index 78c3182a5..07c45121d 100644 --- a/src/cache/ftcsbits.c +++ b/src/cache/ftcsbits.c @@ -235,7 +235,7 @@ FT_ULong size; - FT_ASSERT( snode->count <= FTC_SBITS_ITEM_PER_NODE ); + FT_ASSERT( snode->count <= FTC_SBIT_ITEM_PER_NODE ); /* the node itself */ size = sizeof ( *snode );