diff options
Diffstat (limited to 'src/3rdparty/freetype/src/autofit/afhints.c')
-rw-r--r-- | src/3rdparty/freetype/src/autofit/afhints.c | 260 |
1 files changed, 168 insertions, 92 deletions
diff --git a/src/3rdparty/freetype/src/autofit/afhints.c b/src/3rdparty/freetype/src/autofit/afhints.c index ed111c4117..e4a378fbf7 100644 --- a/src/3rdparty/freetype/src/autofit/afhints.c +++ b/src/3rdparty/freetype/src/autofit/afhints.c @@ -4,7 +4,7 @@ * * Auto-fitter hinting routines (body). * - * Copyright (C) 2003-2019 by + * Copyright (C) 2003-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -18,8 +18,8 @@ #include "afhints.h" #include "aferrors.h" -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_DEBUG_H +#include <freetype/internal/ftcalc.h> +#include <freetype/internal/ftdebug.h> /************************************************************************** @@ -32,6 +32,104 @@ #define FT_COMPONENT afhints + FT_LOCAL_DEF( void ) + af_sort_pos( FT_UInt count, + FT_Pos* table ) + { + FT_UInt i, j; + FT_Pos swap; + + + for ( i = 1; i < count; i++ ) + { + for ( j = i; j > 0; j-- ) + { + if ( table[j] >= table[j - 1] ) + break; + + swap = table[j]; + table[j] = table[j - 1]; + table[j - 1] = swap; + } + } + } + + + FT_LOCAL_DEF( void ) + af_sort_and_quantize_widths( FT_UInt* count, + AF_Width table, + FT_Pos threshold ) + { + FT_UInt i, j; + FT_UInt cur_idx; + FT_Pos cur_val; + FT_Pos sum; + AF_WidthRec swap; + + + if ( *count == 1 ) + return; + + /* sort */ + 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; + } + } + + cur_idx = 0; + cur_val = table[cur_idx].org; + + /* compute and use mean values for clusters not larger than */ + /* `threshold'; this is very primitive and might not yield */ + /* the best result, but normally, using reference character */ + /* `o', `*count' is 2, so the code below is fully sufficient */ + for ( i = 1; i < *count; i++ ) + { + if ( table[i].org - cur_val > threshold || + i == *count - 1 ) + { + sum = 0; + + /* fix loop for end of array */ + if ( table[i].org - cur_val <= threshold && + i == *count - 1 ) + i++; + + for ( j = cur_idx; j < i; j++ ) + { + sum += table[j].org; + table[j].org = 0; + } + table[cur_idx].org = sum / (FT_Pos)j; + + if ( i < *count - 1 ) + { + cur_idx = i + 1; + cur_val = table[cur_idx].org; + } + } + } + + cur_idx = 1; + + /* compress array to remove zero values */ + for ( i = 1; i < *count; i++ ) + { + if ( table[i].org ) + table[cur_idx++] = table[i]; + } + + *count = cur_idx; + } + /* Get new segment for given axis. */ FT_LOCAL_DEF( FT_Error ) @@ -53,9 +151,9 @@ } else 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)( FT_INT_MAX / sizeof ( *segment ) ); + FT_UInt old_max = axis->max_segments; + FT_UInt new_max = old_max; + FT_UInt big_max = FT_INT_MAX / sizeof ( *segment ); if ( old_max >= big_max ) @@ -95,7 +193,7 @@ /* Get new edge for given axis, direction, and position, */ /* without initializing the edge itself. */ - FT_LOCAL( FT_Error ) + FT_LOCAL_DEF( FT_Error ) af_axis_hints_new_edge( AF_AxisHints axis, FT_Int fpos, AF_Direction dir, @@ -118,9 +216,9 @@ } else 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)( FT_INT_MAX / sizeof ( *edge ) ); + FT_UInt old_max = axis->max_edges; + FT_UInt new_max = old_max; + FT_UInt big_max = FT_INT_MAX / sizeof ( *edge ); if ( old_max >= big_max ) @@ -222,8 +320,9 @@ static char* - af_print_idx( char* p, - int idx ) + af_print_idx( char* p, + size_t n, + int idx ) { if ( idx == -1 ) { @@ -232,7 +331,7 @@ p[2] = '\0'; } else - ft_sprintf( p, "%d", idx ); + ft_snprintf( p, n, "%d", idx ); return p; } @@ -359,12 +458,12 @@ " %5d %5d %7.2f %7.2f %7.2f %7.2f" " %5s %5s %5s %5s\n", point_idx, - af_print_idx( buf1, + af_print_idx( buf1, 16, af_get_edge_index( hints, segment_idx_1, 1 ) ), - af_print_idx( buf2, segment_idx_1 ), - af_print_idx( buf3, + af_print_idx( buf2, 16, segment_idx_1 ), + af_print_idx( buf3, 16, af_get_edge_index( hints, segment_idx_0, 0 ) ), - af_print_idx( buf4, segment_idx_0 ), + af_print_idx( buf4, 16, segment_idx_0 ), ( point->flags & AF_FLAG_NEAR ) ? " near " : ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) @@ -373,23 +472,27 @@ point->fx, point->fy, - point->ox / 64.0, - point->oy / 64.0, - point->x / 64.0, - point->y / 64.0, - - af_print_idx( buf5, af_get_strong_edge_index( hints, - point->before, - 1 ) ), - af_print_idx( buf6, af_get_strong_edge_index( hints, - point->after, - 1 ) ), - af_print_idx( buf7, af_get_strong_edge_index( hints, - point->before, - 0 ) ), - af_print_idx( buf8, af_get_strong_edge_index( hints, - point->after, - 0 ) ) )); + (double)point->ox / 64, + (double)point->oy / 64, + (double)point->x / 64, + (double)point->y / 64, + + af_print_idx( buf5, 16, + af_get_strong_edge_index( hints, + point->before, + 1 ) ), + af_print_idx( buf6, 16, + af_get_strong_edge_index( hints, + point->after, + 1 ) ), + af_print_idx( buf7, 16, + af_get_strong_edge_index( hints, + point->before, + 0 ) ), + af_print_idx( buf8, 16, + af_get_strong_edge_index( hints, + point->after, + 0 ) ) )); } AF_DUMP(( "\n" )); } @@ -476,9 +579,12 @@ AF_INDEX_NUM( seg->first, points ), AF_INDEX_NUM( seg->last, points ), - af_print_idx( buf1, AF_INDEX_NUM( seg->link, segments ) ), - af_print_idx( buf2, AF_INDEX_NUM( seg->serif, segments ) ), - af_print_idx( buf3, AF_INDEX_NUM( seg->edge, edges ) ), + af_print_idx( buf1, 16, + AF_INDEX_NUM( seg->link, segments ) ), + af_print_idx( buf2, 16, + AF_INDEX_NUM( seg->serif, segments ) ), + af_print_idx( buf3, 16, + AF_INDEX_NUM( seg->edge, edges ) ), seg->height, seg->height - ( seg->max_coord - seg->min_coord ), @@ -499,7 +605,7 @@ FT_Error af_glyph_hints_get_num_segments( AF_GlyphHints hints, FT_Int dimension, - FT_Int* num_segments ) + FT_UInt* num_segments ) { AF_Dimension dim; AF_AxisHints axis; @@ -525,7 +631,7 @@ FT_Error af_glyph_hints_get_segment_offset( AF_GlyphHints hints, FT_Int dimension, - FT_Int idx, + FT_UInt idx, FT_Pos *offset, FT_Bool *is_blue, FT_Pos *blue_offset ) @@ -542,7 +648,7 @@ axis = &hints->axis[dim]; - if ( idx < 0 || idx >= axis->num_segments ) + if ( idx >= axis->num_segments ) return FT_THROW( Invalid_Argument ); seg = &axis->segments[idx]; @@ -594,13 +700,13 @@ if ( dimension == AF_DIMENSION_HORZ ) AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n", "vertical", - 65536.0 * 64.0 / hints->x_scale, - 10.0 * hints->x_scale / 65536.0 / 64.0 )); + 65536 * 64 / (double)hints->x_scale, + 10 * (double)hints->x_scale / 65536 / 64 )); else AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n", "horizontal", - 65536.0 * 64.0 / hints->y_scale, - 10.0 * hints->y_scale / 65536.0 / 64.0 )); + 65536 * 64 / (double)hints->y_scale, + 10 * (double)hints->y_scale / 65536 / 64 )); if ( axis->num_edges ) { @@ -616,14 +722,16 @@ AF_DUMP(( " %5d %7.2f %5s %4s %5s" " %c %7.2f %7.2f %11s\n", AF_INDEX_NUM( edge, edges ), - (int)edge->opos / 64.0, + (double)(int)edge->opos / 64, af_dir_str( (AF_Direction)edge->dir ), - af_print_idx( buf1, AF_INDEX_NUM( edge->link, edges ) ), - af_print_idx( buf2, AF_INDEX_NUM( edge->serif, edges ) ), + af_print_idx( buf1, 16, + AF_INDEX_NUM( edge->link, edges ) ), + af_print_idx( buf2, 16, + AF_INDEX_NUM( edge->serif, edges ) ), edge->blue_edge ? 'y' : 'n', - edge->opos / 64.0, - edge->pos / 64.0, + (double)edge->opos / 64, + (double)edge->pos / 64, af_edge_flags_to_string( edge->flags ) )); AF_DUMP(( "\n" )); } @@ -764,7 +872,7 @@ { FT_Error error = FT_Err_Ok; AF_Point points; - FT_UInt old_max, new_max; + FT_Int old_max, new_max; FT_Fixed x_scale = hints->x_scale; FT_Fixed y_scale = hints->y_scale; FT_Pos x_delta = hints->x_delta; @@ -781,8 +889,8 @@ hints->axis[1].num_edges = 0; /* first of all, reallocate the contours array if necessary */ - new_max = (FT_UInt)outline->n_contours; - old_max = (FT_UInt)hints->max_contours; + new_max = outline->n_contours; + old_max = hints->max_contours; if ( new_max <= AF_CONTOURS_EMBEDDED ) { @@ -797,12 +905,12 @@ if ( hints->contours == hints->embedded.contours ) hints->contours = NULL; - new_max = ( new_max + 3 ) & ~3U; /* round up to a multiple of 4 */ + new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */ if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) goto Exit; - hints->max_contours = (FT_Int)new_max; + hints->max_contours = new_max; } /* @@ -810,8 +918,8 @@ * note that we reserve two additional point positions, used to * hint metrics appropriately */ - new_max = (FT_UInt)( outline->n_points + 2 ); - old_max = (FT_UInt)hints->max_points; + new_max = outline->n_points + 2; + old_max = hints->max_points; if ( new_max <= AF_POINTS_EMBEDDED ) { @@ -826,12 +934,12 @@ if ( hints->points == hints->embedded.points ) hints->points = NULL; - new_max = ( new_max + 2 + 7 ) & ~7U; /* round up to a multiple of 8 */ + new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */ if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) goto Exit; - hints->max_points = (FT_Int)new_max; + hints->max_points = new_max; } hints->num_points = outline->n_points; @@ -855,9 +963,6 @@ hints->x_delta = x_delta; hints->y_delta = y_delta; - hints->xmin_delta = 0; - hints->xmax_delta = 0; - points = hints->points; if ( hints->num_points == 0 ) goto Exit; @@ -1221,7 +1326,7 @@ { AF_AxisHints axis = & hints->axis[dim]; AF_Segment segments = axis->segments; - AF_Segment segment_limit = segments + axis->num_segments; + AF_Segment segment_limit = FT_OFFSET( segments, axis->num_segments ); AF_Segment seg; @@ -1298,7 +1403,7 @@ 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; + AF_Edge edge_limit = FT_OFFSET( edges, axis->num_edges ); FT_UInt touch_flag; @@ -1688,33 +1793,4 @@ } -#ifdef AF_CONFIG_OPTION_USE_WARPER - - /* Apply (small) warp scale and warp delta for given dimension. */ - - FT_LOCAL_DEF( void ) - af_glyph_hints_scale_dim( AF_GlyphHints hints, - AF_Dimension dim, - FT_Fixed scale, - FT_Pos delta ) - { - AF_Point points = hints->points; - AF_Point points_limit = points + hints->num_points; - AF_Point point; - - - if ( dim == AF_DIMENSION_HORZ ) - { - for ( point = points; point < points_limit; point++ ) - point->x = FT_MulFix( point->fx, scale ) + delta; - } - else - { - for ( point = points; point < points_limit; point++ ) - point->y = FT_MulFix( point->fy, scale ) + delta; - } - } - -#endif /* AF_CONFIG_OPTION_USE_WARPER */ - /* END */ |