Commit 2f11522a authored by David Turner's avatar David Turner
Browse files

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.
parent 15e88980
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_
......
/****************************************************************************
*
* 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;