summaryrefslogtreecommitdiffstats
path: root/src/autofit/aflatin2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/autofit/aflatin2.c')
-rw-r--r--src/autofit/aflatin2.c180
1 files changed, 106 insertions, 74 deletions
diff --git a/src/autofit/aflatin2.c b/src/autofit/aflatin2.c
index ea6af8d..b1e9658 100644
--- a/src/autofit/aflatin2.c
+++ b/src/autofit/aflatin2.c
@@ -4,7 +4,7 @@
/* */
/* Auto-fitter hinting routines for latin script (body). */
/* */
-/* Copyright 2003-2011 by */
+/* Copyright 2003-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -18,6 +18,7 @@
#include FT_ADVANCES_H
+#include "afglobal.h"
#include "aflatin.h"
#include "aflatin2.h"
#include "aferrors.h"
@@ -56,8 +57,7 @@
FT_LOCAL_DEF( void )
af_latin2_metrics_init_widths( AF_LatinMetrics metrics,
- FT_Face face,
- FT_ULong charcode )
+ FT_Face face )
{
/* scan the array of segments in each direction */
AF_GlyphHintsRec hints[1];
@@ -76,7 +76,8 @@
AF_Scaler scaler = &dummy->root.scaler;
- glyph_index = FT_Get_Char_Index( face, charcode );
+ glyph_index = FT_Get_Char_Index( face,
+ metrics->root.clazz->standard_char );
if ( glyph_index == 0 )
goto Exit;
@@ -198,8 +199,8 @@
/* 'af_latin2_blue_chars[blues]' string, then compute its top-most or */
/* bottom-most points (depending on `AF_IS_TOP_BLUE') */
- FT_TRACE5(( "blue zones computation\n" ));
- FT_TRACE5(( "------------------------------------------------\n" ));
+ FT_TRACE5(( "blue zones computation\n"
+ "======================\n\n" ));
for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
{
@@ -209,7 +210,7 @@
FT_Pos* blue_shoot;
- FT_TRACE5(( "blue %3d: ", bb ));
+ FT_TRACE5(( "blue zone %d:\n", bb ));
num_flats = 0;
num_rounds = 0;
@@ -222,8 +223,6 @@
FT_Bool round;
- FT_TRACE5(( "'%c'", *p ));
-
/* load the character in the face -- skip unknown or empty ones */
glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );
if ( glyph_index == 0 )
@@ -285,13 +284,14 @@
best_last = last;
}
}
- FT_TRACE5(( "%5d", best_y ));
+ FT_TRACE5(( " %c %d", *p, best_y ));
}
/* now check whether the point belongs to a straight or round */
/* segment; we first need to find in which contour the extremum */
/* lies, then inspect its previous and next points */
{
+ FT_Pos best_x = points[best_point].x;
FT_Int start, end, prev, next;
FT_Pos dist;
@@ -302,13 +302,16 @@
do
{
- prev = start-1;
+ prev = start - 1;
if ( prev < best_first )
prev = best_last;
- dist = points[prev].y - best_y;
- if ( dist < -5 || dist > 5 )
- break;
+ dist = FT_ABS( points[prev].y - best_y );
+ /* accept a small distance or a small angle (both values are */
+ /* heuristic; value 20 corresponds to approx. 2.9 degrees) */
+ if ( dist > 5 )
+ if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist )
+ break;
start = prev;
@@ -316,13 +319,14 @@
do
{
- next = end+1;
+ next = end + 1;
if ( next > best_last )
next = best_first;
- dist = points[next].y - best_y;
- if ( dist < -5 || dist > 5 )
- break;
+ dist = FT_ABS( points[next].y - best_y );
+ if ( dist > 5 )
+ if ( FT_ABS( points[next].x - best_x ) <= 20 * dist )
+ break;
end = next;
@@ -333,7 +337,7 @@
FT_CURVE_TAG( glyph->outline.tags[start] ) != FT_CURVE_TAG_ON ||
FT_CURVE_TAG( glyph->outline.tags[ end ] ) != FT_CURVE_TAG_ON );
- FT_TRACE5(( "%c ", round ? 'r' : 'f' ));
+ FT_TRACE5(( " (%s)\n", round ? "round" : "flat" ));
}
if ( round )
@@ -342,15 +346,13 @@
flats[num_flats++] = best_y;
}
- FT_TRACE5(( "\n" ));
-
if ( num_flats == 0 && num_rounds == 0 )
{
/*
* we couldn't find a single glyph to compute this blue zone,
* we will simply ignore it then
*/
- FT_TRACE5(( "empty\n" ));
+ FT_TRACE5(( " empty\n" ));
continue;
}
@@ -393,7 +395,13 @@
if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref )
- *blue_shoot = *blue_ref = ( shoot + ref ) / 2;
+ {
+ *blue_ref =
+ *blue_shoot = ( shoot + ref ) / 2;
+
+ FT_TRACE5(( " [overshoot smaller than reference,"
+ " taking mean value]\n" ));
+ }
}
blue->flags = 0;
@@ -408,7 +416,9 @@
if ( bb == AF_LATIN_BLUE_SMALL_TOP )
blue->flags |= AF_LATIN_BLUE_ADJUSTMENT;
- FT_TRACE5(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));
+ FT_TRACE5(( " -> reference = %ld\n"
+ " overshoot = %ld\n",
+ *blue_ref, *blue_shoot ));
}
return;
@@ -465,7 +475,7 @@
af_latin2_metrics_init( AF_LatinMetrics metrics,
FT_Face face )
{
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_CharMap oldmap = face->charmap;
FT_UInt ee;
@@ -491,14 +501,13 @@
if ( !error )
{
- /* For now, compute the standard width and height from the `o'. */
- af_latin2_metrics_init_widths( metrics, face, 'o' );
+ af_latin2_metrics_init_widths( metrics, face );
af_latin2_metrics_init_blues( metrics, face );
af_latin2_metrics_check_digits( metrics, face );
}
FT_Set_Charmap( face, oldmap );
- return AF_Err_Ok;
+ return FT_Err_Ok;
}
@@ -553,8 +562,26 @@
if ( blue )
{
- FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
- FT_Pos fitted = ( scaled + 40 ) & ~63;
+ FT_Pos scaled;
+ FT_Pos threshold;
+ FT_Pos fitted;
+ FT_UInt limit;
+ FT_UInt ppem;
+
+
+ scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
+ ppem = metrics->root.scaler.face->size->metrics.x_ppem;
+ limit = metrics->root.globals->increase_x_height;
+ threshold = 40;
+
+ /* if the `increase-x-height' property is active, */
+ /* we round up much more often */
+ if ( limit &&
+ ppem <= limit &&
+ ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN )
+ threshold = 52;
+
+ fitted = ( scaled + threshold ) & ~63;
#if 1
if ( scaled != fitted )
@@ -658,6 +685,7 @@
{
metrics->root.scaler.render_mode = scaler->render_mode;
metrics->root.scaler.face = scaler->face;
+ metrics->root.scaler.flags = scaler->flags;
af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );
af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );
@@ -680,7 +708,7 @@
{
AF_AxisHints axis = &hints->axis[dim];
FT_Memory memory = hints->memory;
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
AF_Segment segment = NULL;
AF_SegmentRec seg0;
AF_Point* contour = hints->contours;
@@ -796,17 +824,17 @@
segment->dir = first->out_dir;
segment->first = first;
segment->last = point;
- segment->pos = (FT_Short)(( min_u + max_u ) >> 1);
+ segment->pos = (FT_Short)( ( min_u + max_u ) >> 1 );
segment->min_coord = (FT_Short) min_v;
segment->max_coord = (FT_Short) max_v;
- segment->height = (FT_Short)(max_v - min_v);
+ segment->height = (FT_Short)( max_v - min_v );
/* a segment is round if it doesn't have successive */
/* on-curve points. */
{
AF_Point pt = first;
AF_Point last = point;
- AF_Flags f0 = (AF_Flags)(pt->flags & AF_FLAG_CONTROL);
+ AF_Flags f0 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL );
AF_Flags f1;
@@ -815,7 +843,7 @@
for ( ; pt != last; f0 = f1 )
{
pt = pt->next;
- f1 = (AF_Flags)(pt->flags & AF_FLAG_CONTROL);
+ f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL );
if ( !f0 && !f1 )
break;
@@ -832,7 +860,7 @@
break;
/* jump to the start of the next segment, if any */
- while ( FT_ABS(point->out_dir) != major_dir )
+ while ( FT_ABS( point->out_dir ) != major_dir )
{
point = point->next;
@@ -900,16 +928,17 @@
FT_UInt count = axis->num_segments;
FT_UInt ii, jj;
- for (ii = 0; ii < count; ii++)
+ for ( ii = 0; ii < count; ii++ )
{
if ( segments[ii].dir > 0 )
{
- for (jj = ii+1; jj < count; jj++)
+ for ( jj = ii + 1; jj < count; jj++ )
{
if ( segments[jj].dir < 0 )
{
AF_SegmentRec tmp;
+
tmp = segments[ii];
segments[ii] = segments[jj];
segments[jj] = tmp;
@@ -1036,7 +1065,7 @@
AF_Dimension dim )
{
AF_AxisHints axis = &hints->axis[dim];
- FT_Error error = AF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Memory memory = hints->memory;
AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];
@@ -1070,7 +1099,7 @@
if ( dim == AF_DIMENSION_HORZ )
{
if ( laxis->width_count > 0 )
- segment_length_threshold = (laxis->standard_width * 10 ) >> 4;
+ segment_length_threshold = ( laxis->standard_width * 10 ) >> 4;
else
segment_length_threshold = FT_DivFix( 64, hints->y_scale );
}
@@ -1116,10 +1145,11 @@
{
FT_Pos dist = seg->serif->pos - seg->pos;
- if (dist < 0)
+
+ if ( dist < 0 )
dist = -dist;
- if (dist >= laxis->standard_width >> 1)
+ if ( dist >= laxis->standard_width >> 1 )
{
/* unlink this serif, it is too distant from its reference stem */
seg->serif = NULL;
@@ -1417,7 +1447,7 @@
compare = &blue->ref;
dist = edge->fpos - compare->org;
- if (dist < 0)
+ if ( dist < 0 )
dist = -dist;
dist = FT_MulFix( dist, scale );
@@ -1521,8 +1551,8 @@
* In `light' hinting mode we disable horizontal hinting completely.
* We also do it if the face is italic.
*/
- if ( mode == FT_RENDER_MODE_LIGHT ||
- (face->style_flags & FT_STYLE_FLAG_ITALIC) != 0 )
+ if ( mode == FT_RENDER_MODE_LIGHT ||
+ ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 )
scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
hints->scaler_flags = scaler_flags;
@@ -1603,8 +1633,8 @@
FT_Int sign = 0;
FT_Int vertical = ( dim == AF_DIMENSION_VERT );
+ FT_UNUSED( base_flags );
- FT_UNUSED(base_flags);
if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ||
axis->extra_light )
@@ -1734,7 +1764,7 @@
if ( delta < 0 )
delta = -delta;
- if (delta >= 16)
+ if ( delta >= 16 )
{
dist = org_dist;
if ( dist < 48 )
@@ -1788,7 +1818,7 @@
{
FT_UNUSED( hints );
- serif->pos = base->pos + (serif->opos - base->opos);
+ serif->pos = base->pos + ( serif->opos - base->opos );
}
@@ -1870,9 +1900,10 @@
{
anchor = edge;
- anchor_drift = (anchor->pos - anchor->opos);
- if (edge2)
- anchor_drift = (anchor_drift + (edge2->pos - edge2->opos)) >> 1;
+ anchor_drift = ( anchor->pos - anchor->opos );
+ if ( edge2 )
+ anchor_drift = ( anchor_drift +
+ ( edge2->pos - edge2->opos ) ) >> 1;
}
}
}
@@ -1964,8 +1995,8 @@
edge2->flags |= AF_EDGE_DONE;
- anchor_drift = ( (anchor->pos - anchor->opos) +
- (edge2->pos - edge2->opos)) >> 1;
+ anchor_drift = ( ( anchor->pos - anchor->opos ) +
+ ( edge2->pos - edge2->opos ) ) >> 1;
FT_TRACE5(( "DRIFT: %.2f\n", anchor_drift/64.0 ));
}
@@ -1984,8 +2015,8 @@
(AF_Edge_Flags)edge->flags,
(AF_Edge_Flags)edge2->flags );
- org_left = org_pos + ((org_len - cur_len) >> 1);
- org_right = org_pos + ((org_len + cur_len) >> 1);
+ org_left = org_pos + ( ( org_len - cur_len ) >> 1 );
+ org_right = org_pos + ( ( org_len + cur_len ) >> 1 );
FT_TRACE5(( "ALIGN: left=%.2f right=%.2f ",
org_left / 64.0, org_right / 64.0 ));
@@ -2013,13 +2044,13 @@
}
/* if the span is within a single pixel, don't touch it */
- if ( FT_PIX_FLOOR(org_left) == FT_PIX_CEIL(org_right) )
+ if ( FT_PIX_FLOOR( org_left ) == FT_PIX_CEIL( org_right ) )
{
FT_TRACE5(( "single pixel stem\n" ));
goto AlignStem;
}
- if (cur_len <= 96)
+ if ( cur_len <= 96 )
{
/* we want to avoid the absolute worst case which is
* when the left and right edges of the span each represent
@@ -2027,43 +2058,43 @@
* to 25/75%, since this is much more pleasant to the eye with
* very acceptable distortion
*/
- FT_Pos frac_left = (org_left) & 63;
- FT_Pos frac_right = (org_right) & 63;
+ FT_Pos frac_left = org_left & 63;
+ FT_Pos frac_right = org_right & 63;
if ( frac_left >= 22 && frac_left <= 42 &&
frac_right >= 22 && frac_right <= 42 )
{
org = frac_left;
- fit = (org <= 32) ? 16 : 48;
- delta = FT_ABS(fit - org);
+ fit = ( org <= 32 ) ? 16 : 48;
+ delta = FT_ABS( fit - org );
displacements[count] = fit - org;
scores[count++] = delta;
- FT_TRACE5(( "dispA=%.2f (%d) ", (fit - org) / 64.0, delta ));
+ FT_TRACE5(( "dispA=%.2f (%d) ", ( fit - org ) / 64.0, delta ));
org = frac_right;
- fit = (org <= 32) ? 16 : 48;
- delta = FT_ABS(fit - org);
+ fit = ( org <= 32 ) ? 16 : 48;
+ delta = FT_ABS( fit - org );
displacements[count] = fit - org;
scores[count++] = delta;
- FT_TRACE5(( "dispB=%.2f (%d) ", (fit - org) / 64.0, delta ));
+ FT_TRACE5(( "dispB=%.2f (%d) ", ( fit - org ) / 64.0, delta ));
}
}
/* snapping the left edge to the grid */
org = org_left;
- fit = FT_PIX_ROUND(org);
- delta = FT_ABS(fit - org);
+ fit = FT_PIX_ROUND( org );
+ delta = FT_ABS( fit - org );
displacements[count] = fit - org;
scores[count++] = delta;
- FT_TRACE5(( "dispC=%.2f (%d) ", (fit - org) / 64.0, delta ));
+ FT_TRACE5(( "dispC=%.2f (%d) ", ( fit - org ) / 64.0, delta ));
/* snapping the right edge to the grid */
org = org_right;
- fit = FT_PIX_ROUND(org);
- delta = FT_ABS(fit - org);
+ fit = FT_PIX_ROUND( org );
+ delta = FT_ABS( fit - org );
displacements[count] = fit - org;
scores[count++] = delta;
- FT_TRACE5(( "dispD=%.2f (%d) ", (fit - org) / 64.0, delta ));
+ FT_TRACE5(( "dispD=%.2f (%d) ", ( fit - org ) / 64.0, delta ));
/* now find the best displacement */
{
@@ -2071,9 +2102,9 @@
FT_Pos best_disp = displacements[0];
FT_UInt nn;
- for (nn = 1; nn < count; nn++)
+ for ( nn = 1; nn < count; nn++ )
{
- if (scores[nn] < best_score)
+ if ( scores[nn] < best_score )
{
best_score = scores[nn];
best_disp = displacements[nn];
@@ -2086,7 +2117,7 @@
}
AlignStem:
- edge->pos = cur_center - (cur_len >> 1);
+ edge->pos = cur_center - ( cur_len >> 1 );
edge2->pos = edge->pos + cur_len;
FT_TRACE5(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f)"
@@ -2359,6 +2390,7 @@
AF_DEFINE_SCRIPT_CLASS( af_latin2_script_class,
AF_SCRIPT_LATIN2,
af_latin2_uniranges,
+ 'o',
sizeof ( AF_LatinMetricsRec ),