summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/freetype/src/autofit/afhints.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/freetype/src/autofit/afhints.c')
-rw-r--r--src/3rdparty/freetype/src/autofit/afhints.c260
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 */