[autofit] Document warper.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c
index 9859370..a68ce42 100644
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -1152,6 +1152,8 @@
#ifdef AF_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,
diff --git a/src/autofit/afwarp.c b/src/autofit/afwarp.c
index f5bb9b1..801ff31 100644
--- a/src/autofit/afwarp.c
+++ b/src/autofit/afwarp.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter warping algorithm (body). */
/* */
-/* Copyright 2006, 2007 by */
+/* Copyright 2006, 2007, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -16,10 +16,20 @@
/***************************************************************************/
+ /*
+ * 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_USE_WARPER
+ /* 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] =
@@ -43,6 +53,11 @@
#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,
@@ -100,6 +115,7 @@
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;
}
@@ -115,9 +131,9 @@
AF_WarpScore distort = base_distort + ( idx - idx0 );
- if ( score > warper->best_score ||
+ if ( score > warper->best_score ||
( score == warper->best_score &&
- distort < warper->best_distort ) )
+ distort < warper->best_distort ) )
{
warper->best_score = score;
warper->best_distort = distort;
@@ -129,6 +145,9 @@
}
+ /* 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,
@@ -215,6 +234,7 @@
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;
@@ -234,10 +254,12 @@
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;
@@ -273,6 +295,8 @@
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 )
@@ -304,6 +328,7 @@
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 );
@@ -331,7 +356,7 @@
#else /* !AF_USE_WARPER */
-char af_warper_dummy = 0; /* make compiler happy */
+ char af_warper_dummy = 0; /* make compiler happy */
#endif /* !AF_USE_WARPER */