Remove experimental auto-hinting 'warp' mode.
This feature was always experimental, and probably nevery worked properly. This patch completely removes it from the source code, except for a documentation block describing it for historical purpose.
This commit is contained in:
parent
15e889800a
commit
2f11522a2a
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2021-07-12 David Turner <david@freetype.org>
|
||||
|
||||
Remove experimental auto-hinting 'warp' mode.
|
||||
|
||||
This feature was always experimental, and probably nevery worked
|
||||
properly. This patch completely removes it from the source code,
|
||||
except for a documentation block describing it for historical
|
||||
purpose.
|
||||
|
||||
* devel/ftoption.h: Remove AF_CONFIG_OPTION_USE_WARPER.
|
||||
* include/freetype/config/ftoption.h: Remove AF_CONFIG_OPTION_USE_WARPER.
|
||||
* include/freetype/ftdriver.h: Document 'warping' property as obsolete.
|
||||
* src/autofit/*: Remove any warp mode related code.
|
||||
|
||||
2021-07-12 David Turner <david@freetype.org>
|
||||
|
||||
Remove experimental "Latin2" writing system (FT_OPTION_AUTOFIT2)
|
||||
|
|
|
@ -907,24 +907,6 @@ FT_BEGIN_HEADER
|
|||
#endif
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Compile 'autofit' module with warp hinting. The idea of the warping
|
||||
* code is to slightly scale and shift a glyph within a single dimension so
|
||||
* that as much of its segments are aligned (more or less) on the grid. To
|
||||
* find out the optimal scaling and shifting value, various parameter
|
||||
* combinations are tried and scored.
|
||||
*
|
||||
* You can switch warping on and off with the `warping` property of the
|
||||
* auto-hinter (see file `ftdriver.h` for more information; by default it
|
||||
* is switched off).
|
||||
*
|
||||
* This experimental option is not active if the rendering mode is
|
||||
* `FT_RENDER_MODE_LIGHT`.
|
||||
*/
|
||||
#define AF_CONFIG_OPTION_USE_WARPER
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Use TrueType-like size metrics for 'light' auto-hinting.
|
||||
|
|
|
@ -909,24 +909,6 @@ FT_BEGIN_HEADER
|
|||
#endif
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Compile 'autofit' module with warp hinting. The idea of the warping
|
||||
* code is to slightly scale and shift a glyph within a single dimension so
|
||||
* that as much of its segments are aligned (more or less) on the grid. To
|
||||
* find out the optimal scaling and shifting value, various parameter
|
||||
* combinations are tried and scored.
|
||||
*
|
||||
* You can switch warping on and off with the `warping` property of the
|
||||
* auto-hinter (see file `ftdriver.h` for more information; by default it
|
||||
* is switched off).
|
||||
*
|
||||
* This experimental option is not active if the rendering mode is
|
||||
* `FT_RENDER_MODE_LIGHT`.
|
||||
*/
|
||||
#define AF_CONFIG_OPTION_USE_WARPER
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Use TrueType-like size metrics for 'light' auto-hinting.
|
||||
|
|
|
@ -1162,11 +1162,11 @@ FT_BEGIN_HEADER
|
|||
* warping
|
||||
*
|
||||
* @description:
|
||||
* **Experimental only**
|
||||
* **Obsolete**
|
||||
*
|
||||
* If FreeType gets compiled with option `AF_CONFIG_OPTION_USE_WARPER` to
|
||||
* activate the warp hinting code in the auto-hinter, this property
|
||||
* switches warping on and off.
|
||||
* This property was always experimental and probably never worked
|
||||
* correctly. It was entirely removed from the FreeType 2 sources.
|
||||
* This entry is only here for historical reference.
|
||||
*
|
||||
* Warping only works in 'normal' auto-hinting mode replacing it. The
|
||||
* idea of the code is to slightly scale and shift a glyph along the
|
||||
|
@ -1175,36 +1175,6 @@ FT_BEGIN_HEADER
|
|||
* out a glyph's optimal scaling and shifting value, various parameter
|
||||
* combinations are tried and scored.
|
||||
*
|
||||
* By default, warping is off.
|
||||
*
|
||||
* @note:
|
||||
* This property can be used with @FT_Property_Get also.
|
||||
*
|
||||
* This property can be set via the `FREETYPE_PROPERTIES` environment
|
||||
* variable (using values 1 and 0 for 'on' and 'off', respectively).
|
||||
*
|
||||
* The warping code can also change advance widths. Have a look at the
|
||||
* `lsb_delta` and `rsb_delta` fields in the @FT_GlyphSlotRec structure
|
||||
* for details on improving inter-glyph distances while rendering.
|
||||
*
|
||||
* Since warping is a global property of the auto-hinter it is best to
|
||||
* change its value before rendering any face. Otherwise, you should
|
||||
* reload all faces that get auto-hinted in 'normal' hinting mode.
|
||||
*
|
||||
* @example:
|
||||
* This example shows how to switch on warping (omitting the error
|
||||
* handling).
|
||||
*
|
||||
* ```
|
||||
* FT_Library library;
|
||||
* FT_Bool warping = 1;
|
||||
*
|
||||
*
|
||||
* FT_Init_FreeType( &library );
|
||||
*
|
||||
* FT_Property_Set( library, "autofitter", "warping", &warping );
|
||||
* ```
|
||||
*
|
||||
* @since:
|
||||
* 2.6
|
||||
*
|
||||
|
|
|
@ -37,11 +37,6 @@
|
|||
#include "aferrors.h"
|
||||
|
||||
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
#include "afwarp.h"
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* The macro FT_COMPONENT is used in trace mode. It is an implicit
|
||||
|
@ -1400,11 +1395,6 @@
|
|||
/* compute flags depending on render mode, etc. */
|
||||
mode = metrics->root.scaler.render_mode;
|
||||
|
||||
#if 0 /* AF_CONFIG_OPTION_USE_WARPER */
|
||||
if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )
|
||||
metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
|
||||
#endif
|
||||
|
||||
scaler_flags = hints->scaler_flags;
|
||||
other_flags = 0;
|
||||
|
||||
|
@ -1433,12 +1423,6 @@
|
|||
|
||||
scaler_flags |= AF_SCALER_FLAG_NO_ADVANCE;
|
||||
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
/* get (global) warper flag */
|
||||
if ( !metrics->root.globals->module->warping )
|
||||
scaler_flags |= AF_SCALER_FLAG_NO_WARPER;
|
||||
#endif
|
||||
|
||||
hints->scaler_flags = scaler_flags;
|
||||
hints->other_flags = other_flags;
|
||||
|
||||
|
@ -2321,25 +2305,6 @@
|
|||
if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||
|
||||
( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) )
|
||||
{
|
||||
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
if ( dim == AF_DIMENSION_HORZ &&
|
||||
metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL &&
|
||||
AF_HINTS_DO_WARP( hints ) )
|
||||
{
|
||||
AF_WarperRec warper;
|
||||
FT_Fixed scale;
|
||||
FT_Pos delta;
|
||||
|
||||
|
||||
af_warper_compute( &warper, hints, (AF_Dimension)dim,
|
||||
&scale, &delta );
|
||||
af_glyph_hints_scale_dim( hints, (AF_Dimension)dim,
|
||||
scale, delta );
|
||||
continue;
|
||||
}
|
||||
#endif /* AF_CONFIG_OPTION_USE_WARPER */
|
||||
|
||||
af_cjk_hint_edges( hints, (AF_Dimension)dim );
|
||||
af_cjk_align_edge_points( hints, (AF_Dimension)dim );
|
||||
af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim );
|
||||
|
|
|
@ -1688,33 +1688,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 */
|
||||
|
|
|
@ -408,10 +408,6 @@ FT_BEGIN_HEADER
|
|||
#define AF_HINTS_DO_ADVANCE( h ) \
|
||||
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
|
||||
|
||||
#define AF_HINTS_DO_WARP( h ) \
|
||||
!AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_WARPER )
|
||||
|
||||
|
||||
|
||||
FT_LOCAL( AF_Direction )
|
||||
af_direction_compute( FT_Pos dx,
|
||||
|
@ -459,14 +455,6 @@ FT_BEGIN_HEADER
|
|||
af_glyph_hints_align_weak_points( AF_GlyphHints hints,
|
||||
AF_Dimension dim );
|
||||
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_scale_dim( AF_GlyphHints hints,
|
||||
AF_Dimension dim,
|
||||
FT_Fixed scale,
|
||||
FT_Pos delta );
|
||||
#endif
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_done( AF_GlyphHints hints );
|
||||
|
||||
|
|
|
@ -27,11 +27,6 @@
|
|||
#include "aferrors.h"
|
||||
|
||||
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
#include "afwarp.h"
|
||||
#endif
|
||||
|
||||
|
||||
static FT_Error
|
||||
af_indic_metrics_init( AF_CJKMetrics metrics,
|
||||
FT_Face face )
|
||||
|
|
|
@ -24,11 +24,6 @@
|
|||
#include "aferrors.h"
|
||||
|
||||
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
#include "afwarp.h"
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* The macro FT_COMPONENT is used in trace mode. It is an implicit
|
||||
|
@ -2636,11 +2631,6 @@
|
|||
/* compute flags depending on render mode, etc. */
|
||||
mode = metrics->root.scaler.render_mode;
|
||||
|
||||
#if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */
|
||||
if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )
|
||||
metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
|
||||
#endif
|
||||
|
||||
scaler_flags = hints->scaler_flags;
|
||||
other_flags = 0;
|
||||
|
||||
|
@ -2678,12 +2668,6 @@
|
|||
( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 )
|
||||
scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
|
||||
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
/* get (global) warper flag */
|
||||
if ( !metrics->root.globals->module->warping )
|
||||
scaler_flags |= AF_SCALER_FLAG_NO_WARPER;
|
||||
#endif
|
||||
|
||||
hints->scaler_flags = scaler_flags;
|
||||
hints->other_flags = other_flags;
|
||||
|
||||
|
@ -3600,24 +3584,6 @@
|
|||
/* grid-fit the outline */
|
||||
for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
|
||||
{
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
if ( dim == AF_DIMENSION_HORZ &&
|
||||
metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL &&
|
||||
AF_HINTS_DO_WARP( hints ) )
|
||||
{
|
||||
AF_WarperRec warper;
|
||||
FT_Fixed scale;
|
||||
FT_Pos delta;
|
||||
|
||||
|
||||
af_warper_compute( &warper, hints, (AF_Dimension)dim,
|
||||
&scale, &delta );
|
||||
af_glyph_hints_scale_dim( hints, (AF_Dimension)dim,
|
||||
scale, delta );
|
||||
continue;
|
||||
}
|
||||
#endif /* AF_CONFIG_OPTION_USE_WARPER */
|
||||
|
||||
if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||
|
||||
( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) )
|
||||
{
|
||||
|
|
|
@ -190,35 +190,6 @@
|
|||
|
||||
return error;
|
||||
}
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
else if ( !ft_strcmp( property_name, "warping" ) )
|
||||
{
|
||||
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
|
||||
if ( value_is_string )
|
||||
{
|
||||
const char* s = (const char*)value;
|
||||
long w = ft_strtol( s, NULL, 10 );
|
||||
|
||||
|
||||
if ( w == 0 )
|
||||
module->warping = 0;
|
||||
else if ( w == 1 )
|
||||
module->warping = 1;
|
||||
else
|
||||
return FT_THROW( Invalid_Argument );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
FT_Bool* warping = (FT_Bool*)value;
|
||||
|
||||
|
||||
module->warping = *warping;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif /* AF_CONFIG_OPTION_USE_WARPER */
|
||||
else if ( !ft_strcmp( property_name, "darkening-parameters" ) )
|
||||
{
|
||||
FT_Int* darken_params;
|
||||
|
@ -322,9 +293,6 @@
|
|||
AF_Module module = (AF_Module)ft_module;
|
||||
FT_UInt fallback_style = module->fallback_style;
|
||||
FT_UInt default_script = module->default_script;
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
FT_Bool warping = module->warping;
|
||||
#endif
|
||||
|
||||
|
||||
if ( !ft_strcmp( property_name, "glyph-to-script-map" ) )
|
||||
|
@ -371,17 +339,6 @@
|
|||
|
||||
return error;
|
||||
}
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
else if ( !ft_strcmp( property_name, "warping" ) )
|
||||
{
|
||||
FT_Bool* val = (FT_Bool*)value;
|
||||
|
||||
|
||||
*val = warping;
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif /* AF_CONFIG_OPTION_USE_WARPER */
|
||||
else if ( !ft_strcmp( property_name, "darkening-parameters" ) )
|
||||
{
|
||||
FT_Int* darken_params = module->darken_params;
|
||||
|
@ -447,9 +404,6 @@
|
|||
|
||||
module->fallback_style = AF_STYLE_FALLBACK;
|
||||
module->default_script = AF_SCRIPT_DEFAULT;
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
module->warping = 0;
|
||||
#endif
|
||||
module->no_stem_darkening = TRUE;
|
||||
|
||||
module->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1;
|
||||
|
|
|
@ -37,9 +37,6 @@ FT_BEGIN_HEADER
|
|||
|
||||
FT_UInt fallback_style;
|
||||
FT_UInt default_script;
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
FT_Bool warping;
|
||||
#endif
|
||||
FT_Bool no_stem_darkening;
|
||||
FT_Int darken_params[8];
|
||||
|
||||
|
|
|
@ -172,7 +172,6 @@ extern void* _af_debug_hints;
|
|||
#define AF_SCALER_FLAG_NO_HORIZONTAL 1U /* disable horizontal hinting */
|
||||
#define AF_SCALER_FLAG_NO_VERTICAL 2U /* disable vertical hinting */
|
||||
#define AF_SCALER_FLAG_NO_ADVANCE 4U /* disable advance hinting */
|
||||
#define AF_SCALER_FLAG_NO_WARPER 8U /* disable warper */
|
||||
|
||||
|
||||
typedef struct AF_ScalerRec_
|
||||
|
|
|
@ -1,373 +0,0 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afwarp.c
|
||||
*
|
||||
* Auto-fitter warping algorithm (body).
|
||||
*
|
||||
* Copyright (C) 2006-2021 by
|
||||
* David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
*
|
||||
* This file is part of the FreeType project, and may only be used,
|
||||
* modified, and distributed under the terms of the FreeType project
|
||||
* license, LICENSE.TXT. By continuing to use, modify, or distribute
|
||||
* this file you indicate that you have read the license and
|
||||
* understand and accept it fully.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* The idea of the warping code is to slightly scale and shift a glyph
|
||||
* within a single dimension so that as much of its segments are aligned
|
||||
* (more or less) on the grid. To find out the optimal scaling and
|
||||
* shifting value, various parameter combinations are tried and scored.
|
||||
*/
|
||||
|
||||
#include "afwarp.h"
|
||||
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* The macro FT_COMPONENT is used in trace mode. It is an implicit
|
||||
* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
|
||||
* messages during execution.
|
||||
*/
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT afwarp
|
||||
|
||||
|
||||
/* The weights cover the range 0/64 - 63/64 of a pixel. Obviously, */
|
||||
/* values around a half pixel (which means exactly between two grid */
|
||||
/* lines) gets the worst weight. */
|
||||
#if 1
|
||||
static const AF_WarpScore
|
||||
af_warper_weights[64] =
|
||||
{
|
||||
35, 32, 30, 25, 20, 15, 12, 10, 5, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, -1, -2, -5, -8,-10,-10,-20,-20,-30,-30,
|
||||
|
||||
-30,-30,-20,-20,-10,-10, -8, -5, -2, -1, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 1, 5, 10, 12, 15, 20, 25, 30, 32,
|
||||
};
|
||||
#else
|
||||
static const AF_WarpScore
|
||||
af_warper_weights[64] =
|
||||
{
|
||||
30, 20, 10, 5, 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, -1, -2, -2, -5, -5,-10,-10,-15,-20,
|
||||
|
||||
-20,-15,-15,-10,-10, -5, -5, -2, -2, -1, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4, 5, 10, 20,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* Score segments for a given `scale' and `delta' in the range */
|
||||
/* `xx1' to `xx2', and store the best result in `warper'. If */
|
||||
/* the new best score is equal to the old one, prefer the */
|
||||
/* value with a smaller distortion (around `base_distort'). */
|
||||
|
||||
static void
|
||||
af_warper_compute_line_best( AF_Warper warper,
|
||||
FT_Fixed scale,
|
||||
FT_Pos delta,
|
||||
FT_Pos xx1,
|
||||
FT_Pos xx2,
|
||||
AF_WarpScore base_distort,
|
||||
AF_Segment segments,
|
||||
FT_Int num_segments )
|
||||
{
|
||||
FT_Int idx_min, idx_max, idx0;
|
||||
FT_Int nn;
|
||||
AF_WarpScore scores[65];
|
||||
|
||||
|
||||
for ( nn = 0; nn < 65; nn++ )
|
||||
scores[nn] = 0;
|
||||
|
||||
idx0 = xx1 - warper->t1;
|
||||
|
||||
/* compute minimum and maximum indices */
|
||||
{
|
||||
FT_Pos xx1min = warper->x1min;
|
||||
FT_Pos xx1max = warper->x1max;
|
||||
FT_Pos w = xx2 - xx1;
|
||||
|
||||
|
||||
if ( xx1min + w < warper->x2min )
|
||||
xx1min = warper->x2min - w;
|
||||
|
||||
if ( xx1max + w > warper->x2max )
|
||||
xx1max = warper->x2max - w;
|
||||
|
||||
idx_min = xx1min - warper->t1;
|
||||
idx_max = xx1max - warper->t1;
|
||||
|
||||
if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 )
|
||||
{
|
||||
FT_TRACE5(( "invalid indices:\n" ));
|
||||
FT_TRACE5(( " min=%d max=%d, xx1=%ld xx2=%ld,\n",
|
||||
idx_min, idx_max, xx1, xx2 ));
|
||||
FT_TRACE5(( " x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n",
|
||||
warper->x1min, warper->x1max,
|
||||
warper->x2min, warper->x2max ));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for ( nn = 0; nn < num_segments; nn++ )
|
||||
{
|
||||
FT_Pos len = segments[nn].max_coord - segments[nn].min_coord;
|
||||
FT_Pos y0 = FT_MulFix( segments[nn].pos, scale ) + delta;
|
||||
FT_Pos y = y0 + ( idx_min - idx0 );
|
||||
FT_Int idx;
|
||||
|
||||
|
||||
/* score the length of the segments for the given range */
|
||||
for ( idx = idx_min; idx <= idx_max; idx++, y++ )
|
||||
scores[idx] += af_warper_weights[y & 63] * len;
|
||||
}
|
||||
|
||||
/* find best score */
|
||||
{
|
||||
FT_Int idx;
|
||||
|
||||
|
||||
for ( idx = idx_min; idx <= idx_max; idx++ )
|
||||
{
|
||||
AF_WarpScore score = scores[idx];
|
||||
AF_WarpScore distort = base_distort + ( idx - idx0 );
|
||||
|
||||
|
||||
if ( score > warper->best_score ||
|
||||
( score == warper->best_score &&
|
||||
distort < warper->best_distort ) )
|
||||
{
|
||||
warper->best_score = score;
|
||||
warper->best_distort = distort;
|
||||
warper->best_scale = scale;
|
||||
warper->best_delta = delta + ( idx - idx0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Compute optimal scaling and delta values for a given glyph and */
|
||||
/* dimension. */
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
af_warper_compute( AF_Warper warper,
|
||||
AF_GlyphHints hints,
|
||||
AF_Dimension dim,
|
||||
FT_Fixed *a_scale,
|
||||
FT_Pos *a_delta )
|
||||
{
|
||||
AF_AxisHints axis;
|
||||
AF_Point points;
|
||||
|
||||
FT_Fixed org_scale;
|
||||
FT_Pos org_delta;
|
||||
|
||||
FT_Int nn, num_points, num_segments;
|
||||
FT_Int X1, X2;
|
||||
FT_Int w;
|
||||
|
||||
AF_WarpScore base_distort;
|
||||
AF_Segment segments;
|
||||
|
||||
|
||||
/* get original scaling transformation */
|
||||
if ( dim == AF_DIMENSION_VERT )
|
||||
{
|
||||
org_scale = hints->y_scale;
|
||||
org_delta = hints->y_delta;
|
||||
}
|
||||
else
|
||||
{
|
||||
org_scale = hints->x_scale;
|
||||
org_delta = hints->x_delta;
|
||||
}
|
||||
|
||||
warper->best_scale = org_scale;
|
||||
warper->best_delta = org_delta;
|
||||
warper->best_score = FT_INT_MIN;
|
||||
warper->best_distort = 0;
|
||||
|
||||
axis = &hints->axis[dim];
|
||||
segments = axis->segments;
|
||||
num_segments = axis->num_segments;
|
||||
points = hints->points;
|
||||
num_points = hints->num_points;
|
||||
|
||||
*a_scale = org_scale;
|
||||
*a_delta = org_delta;
|
||||
|
||||
/* get X1 and X2, minimum and maximum in original coordinates */
|
||||
if ( num_segments < 1 )
|
||||
return;
|
||||
|
||||
#if 1
|
||||
X1 = X2 = points[0].fx;
|
||||
for ( nn = 1; nn < num_points; nn++ )
|
||||
{
|
||||
FT_Int X = points[nn].fx;
|
||||
|
||||
|
||||
if ( X < X1 )
|
||||
X1 = X;
|
||||
if ( X > X2 )
|
||||
X2 = X;
|
||||
}
|
||||
#else
|
||||
X1 = X2 = segments[0].pos;
|
||||
for ( nn = 1; nn < num_segments; nn++ )
|
||||
{
|
||||
FT_Int X = segments[nn].pos;
|
||||
|
||||
|
||||
if ( X < X1 )
|
||||
X1 = X;
|
||||
if ( X > X2 )
|
||||
X2 = X;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( X1 >= X2 )
|
||||
return;
|
||||
|
||||
warper->x1 = FT_MulFix( X1, org_scale ) + org_delta;
|
||||
warper->x2 = FT_MulFix( X2, org_scale ) + org_delta;
|
||||
|
||||
warper->t1 = AF_WARPER_FLOOR( warper->x1 );
|
||||
warper->t2 = AF_WARPER_CEIL( warper->x2 );
|
||||
|
||||
/* examine a half pixel wide range around the maximum coordinates */
|
||||
warper->x1min = warper->x1 & ~31;
|
||||
warper->x1max = warper->x1min + 32;
|
||||
warper->x2min = warper->x2 & ~31;
|
||||
warper->x2max = warper->x2min + 32;
|
||||
|
||||
if ( warper->x1max > warper->x2 )
|
||||
warper->x1max = warper->x2;
|
||||
|
||||
if ( warper->x2min < warper->x1 )
|
||||
warper->x2min = warper->x1;
|
||||
|
||||
warper->w0 = warper->x2 - warper->x1;
|
||||
|
||||
if ( warper->w0 <= 64 )
|
||||
{
|
||||
warper->x1max = warper->x1;
|
||||
warper->x2min = warper->x2;
|
||||
}
|
||||
|
||||
/* examine (at most) a pixel wide range around the natural width */
|
||||
warper->wmin = warper->x2min - warper->x1max;
|
||||
warper->wmax = warper->x2max - warper->x1min;
|
||||
|
||||
#if 1
|
||||
/* some heuristics to reduce the number of widths to be examined */
|
||||
{
|
||||
int margin = 16;
|
||||
|
||||
|
||||
if ( warper->w0 <= 128 )
|
||||
{
|
||||
margin = 8;
|
||||
if ( warper->w0 <= 96 )
|
||||
margin = 4;
|
||||
}
|
||||
|
||||
if ( warper->wmin < warper->w0 - margin )
|
||||
warper->wmin = warper->w0 - margin;
|
||||
|
||||
if ( warper->wmax > warper->w0 + margin )
|
||||
warper->wmax = warper->w0 + margin;
|
||||
}
|
||||
|
||||
if ( warper->wmin < warper->w0 * 3 / 4 )
|
||||
warper->wmin = warper->w0 * 3 / 4;
|
||||
|
||||
if ( warper->wmax > warper->w0 * 5 / 4 )
|
||||
warper->wmax = warper->w0 * 5 / 4;
|
||||
#else
|
||||
/* no scaling, just translation */
|
||||
warper->wmin = warper->wmax = warper->w0;
|
||||
#endif
|
||||
|
||||
for ( w = warper->wmin; w <= warper->wmax; w++ )
|
||||
{
|
||||
FT_Fixed new_scale;
|
||||
FT_Pos new_delta;
|
||||
FT_Pos xx1, xx2;
|
||||
|
||||
|
||||
/* compute min and max positions for given width, */
|
||||
/* assuring that they stay within the coordinate ranges */
|
||||
xx1 = warper->x1;
|
||||
xx2 = warper->x2;
|
||||
if ( w >= warper->w0 )
|
||||
{
|
||||
xx1 -= w - warper->w0;
|
||||
if ( xx1 < warper->x1min )
|
||||
{
|
||||
xx2 += warper->x1min - xx1;
|
||||
xx1 = warper->x1min;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xx1 -= w - warper->w0;
|
||||
if ( xx1 > warper->x1max )
|
||||
{
|
||||
xx2 -= xx1 - warper->x1max;
|
||||
xx1 = warper->x1max;
|
||||
}
|
||||
}
|
||||
|
||||
if ( xx1 < warper->x1 )
|
||||
base_distort = warper->x1 - xx1;
|
||||
else
|
||||
base_distort = xx1 - warper->x1;
|
||||
|
||||
if ( xx2 < warper->x2 )
|
||||
base_distort += warper->x2 - xx2;
|
||||
else
|
||||
base_distort += xx2 - warper->x2;
|
||||
|
||||
/* give base distortion a greater weight while scoring */
|
||||
base_distort *= 10;
|
||||
|
||||
new_scale = org_scale + FT_DivFix( w - warper->w0, X2 - X1 );
|
||||
new_delta = xx1 - FT_MulFix( X1, new_scale );
|
||||
|
||||
af_warper_compute_line_best( warper, new_scale, new_delta, xx1, xx2,
|
||||
base_distort,
|
||||
segments, num_segments );
|
||||
}
|
||||
|
||||
{
|
||||
FT_Fixed best_scale = warper->best_scale;
|
||||
FT_Pos best_delta = warper->best_delta;
|
||||
|
||||
|
||||
hints->xmin_delta = FT_MulFix( X1, best_scale - org_scale )
|
||||
+ best_delta;
|
||||
hints->xmax_delta = FT_MulFix( X2, best_scale - org_scale )
|
||||
+ best_delta;
|
||||
|
||||
*a_scale = best_scale;
|
||||
*a_delta = best_delta;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* !AF_CONFIG_OPTION_USE_WARPER */
|
||||
|
||||
/* ANSI C doesn't like empty source files */
|
||||
typedef int _af_warp_dummy;
|
||||
|
||||
#endif /* !AF_CONFIG_OPTION_USE_WARPER */
|
||||
|
||||
/* END */
|
|
@ -1,66 +0,0 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* afwarp.h
|
||||
*
|
||||
* Auto-fitter warping algorithm (specification).
|
||||
*
|
||||
* Copyright (C) 2006-2021 by
|
||||
* David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
*
|
||||
* This file is part of the FreeType project, and may only be used,
|
||||
* modified, and distributed under the terms of the FreeType project
|
||||
* license, LICENSE.TXT. By continuing to use, modify, or distribute
|
||||
* this file you indicate that you have read the license and
|
||||
* understand and accept it fully.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef AFWARP_H_
|
||||
#define AFWARP_H_
|
||||
|
||||
#include "afhints.h"
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
#define AF_WARPER_SCALE
|
||||
|
||||
#define AF_WARPER_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 )
|
||||
#define AF_WARPER_CEIL( x ) AF_WARPER_FLOOR( (x) + 63 )
|
||||
|
||||
|
||||
typedef FT_Int32 AF_WarpScore;
|
||||
|
||||
typedef struct AF_WarperRec_
|
||||
{
|
||||
FT_Pos x1, x2;
|
||||
FT_Pos t1, t2;
|
||||
FT_Pos x1min, x1max;
|
||||
FT_Pos x2min, x2max;
|
||||
FT_Pos w0, wmin, wmax;
|
||||
|
||||
FT_Fixed best_scale;
|
||||
FT_Pos best_delta;
|
||||
AF_WarpScore best_score;
|
||||
AF_WarpScore best_distort;
|
||||
|
||||
} AF_WarperRec, *AF_Warper;
|
||||
|
||||
|
||||
#ifdef AF_CONFIG_OPTION_USE_WARPER
|
||||
FT_LOCAL( void )
|
||||
af_warper_compute( AF_Warper warper,
|
||||
AF_GlyphHints hints,
|
||||
AF_Dimension dim,
|
||||
FT_Fixed *a_scale,
|
||||
FT_Pos *a_delta );
|
||||
#endif
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* AFWARP_H_ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -30,7 +30,6 @@
|
|||
#include "afmodule.c"
|
||||
#include "afranges.c"
|
||||
#include "afshaper.c"
|
||||
#include "afwarp.c"
|
||||
|
||||
|
||||
/* END */
|
||||
|
|
|
@ -40,7 +40,6 @@ AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \
|
|||
$(AUTOF_DIR)/afmodule.c \
|
||||
$(AUTOF_DIR)/afranges.c \
|
||||
$(AUTOF_DIR)/afshaper.c \
|
||||
$(AUTOF_DIR)/afwarp.c
|
||||
|
||||
# AUTOF driver headers
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue