2003-01-11 David Chester <davidchester@qmx.net>

* include/freetype/config/ftoption.h, src/autohint/ahglobal.h,
        src/autohint/ahglobal.c, src/autohint/ahglyph.c,
        src/autohint/ahtypes.h:

          included David Chester's patches to the auto-hinter in order to
          slightly improve the output. Note that everything is controlled
          through the new FT_CONFIG_OPTION_CHESTER_HINTS defined at the
          end of "ftoption.h", there are also individual FT_CONFIG_CHESTER_XXX
          macros to control individual "features".

          Note that all improvements are enabled by default, but can be
          tweaked for optimization and testing purpose. The configuration
          macros will most likely disappear in the short future.

2003-01-11  David Turner  <david@freetype.org>

        * include/freetype/internal/fnttypes.h: fixed a structure field
        definition to avoid memory overwrites
This commit is contained in:
David Turner 2003-01-12 18:26:10 +00:00
parent 0fb0820fee
commit 7f0c4e9cc2
9 changed files with 351 additions and 10 deletions

View File

@ -1,3 +1,24 @@
2003-01-11 David Chester <davidchester@qmx.net>
* include/freetype/config/ftoption.h, src/autohint/ahglobal.h,
src/autohint/ahglobal.c, src/autohint/ahglyph.c,
src/autohint/ahtypes.h:
included David Chester's patches to the auto-hinter in order to
slightly improve the output. Note that everything is controlled
through the new FT_CONFIG_OPTION_CHESTER_HINTS defined at the
end of "ftoption.h", there are also individual FT_CONFIG_CHESTER_XXX
macros to control individual "features".
Note that all improvements are enabled by default, but can be
tweaked for optimization and testing purpose. The configuration
macros will most likely disappear in the short future.
2003-01-11 David Turner <david@freetype.org>
* include/freetype/internal/fnttypes.h: fixed a structure field
definition to avoid memory overwrites
2003-01-08 Huw Dawies <huw@codeweavers.com>
* src/winfonts/winfnt.c: read 16 bytes into "reserved2", not "reserved"

View File

@ -469,6 +469,17 @@ FT_BEGIN_HEADER
/* */
#undef FT_CONFIG_OPTION_CHESTER_HINTS
#ifdef FT_CONFIG_OPTION_CHESTER_HINTS
# define FT_CONFIG_CHESTER_SMALL_F
# define FT_CONFIG_CHESTER_ASCENDER
# define FT_CONFIG_CHESTER_SERIF
# define FT_CONFIG_CHESTER_STEM
#endif /* FT_CONFIG_OPTION_CHESTER_HINTS */
FT_END_HEADER

View File

@ -108,7 +108,7 @@ FT_BEGIN_HEADER
FT_UShort B_space;
FT_UShort C_space;
FT_UShort color_table_offset;
FT_Byte reserved2[4];
FT_Byte reserved2[16];
} WinFNT_HeaderRec, *WinFNT_Header;

View File

@ -32,6 +32,9 @@
{
"THEZOCQS",
"HEZLOCUS",
#ifdef FT_CONFIG_CHESTER_SMALL_F
"fijkdbh",
#endif
"xzroesc",
"xzroesc",
"pqgjy"

View File

@ -32,8 +32,18 @@
FT_BEGIN_HEADER
#define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || \
(b) == AH_BLUE_SMALL_TOP )
#ifdef FT_CONFIG_CHESTER_SMALL_F
# define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || \
(b) == AH_BLUE_SMALL_F_TOP || \
(b) == AH_BLUE_SMALL_TOP )
#else /* !CHESTER_SMALL_F */
# define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || \
(b) == AH_BLUE_SMALL_TOP )
#endif /* !CHESTER_SMALL_F */
/* compute global metrics automatically */

View File

@ -1350,10 +1350,20 @@
else
edge2 = seg2->edge;
#ifdef FT_CONFIG_CHESTER_SERIF
if ( is_serif )
{
edge->serif = edge2;
edge2->flags |= AH_EDGE_SERIF;
}
else
edge->link = edge2;
#else /* !CHESTER_SERIF */
if ( is_serif )
edge->serif = edge2;
else
edge->link = edge2;
#endif
}
seg = seg->edge_next;
@ -1477,8 +1487,14 @@
/* compute the initial threshold as a fraction of the EM size */
best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale );
#ifdef FT_CONFIG_CHESTER_SMALL_F
if ( best_dist > 64 / 2 )
best_dist = 64 / 2;
#else
if ( best_dist > 64 / 4 )
best_dist = 64 / 4;
best_dist = 64 / 4;
#endif
for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )
{

View File

@ -88,6 +88,137 @@
/* compute the snapped width of a given stem */
#ifdef FT_CONFIG_CHESTER_SERIF
static FT_Pos
ah_compute_stem_width( AH_Hinter hinter,
int vertical,
FT_Pos width,
AH_Edge_Flags base_flags,
AH_Edge_Flags stem_flags )
{
AH_Globals globals = &hinter->globals->scaled;
FT_Pos dist = width;
FT_Int sign = 0;
if ( dist < 0 )
{
dist = -width;
sign = 1;
}
if ( !hinter->do_stem_adjust )
{
/* leave stem widths unchanged */
}
else if ( ( vertical && !hinter->do_vert_snapping ) ||
( !vertical && !hinter->do_horz_snapping ) )
{
/* smooth hinting process, very lightly quantize the stem width */
/* */
/* leave the widths of serifs alone */
if ( ( stem_flags & AH_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )
goto Done_Width;
else if ( ( base_flags & AH_EDGE_ROUND ) )
{
if ( dist < 96 )
dist = 64;
}
else if ( dist < 56 )
dist = 56;
{
FT_Pos delta = dist - globals->stds[vertical];
if ( delta < 0 )
delta = -delta;
if ( delta < 40 )
{
dist = globals->stds[vertical];
if ( dist < 48 )
dist = 48;
goto Done_Width;
}
if ( dist < 3 * 64 )
{
delta = ( dist & 63 );
dist &= -64;
if ( delta < 10 )
dist += delta;
else if ( delta < 32 )
dist += 10;
else if ( delta < 54 )
dist += 54;
else
dist += delta;
}
else
dist = ( dist + 32 ) & -64;
}
}
else
{
/* strong hinting process, snap the stem width to integer pixels */
/* */
if ( vertical )
{
dist = ah_snap_width( globals->heights, globals->num_heights, dist );
/* in the case of vertical hinting, always round */
/* the stem heights to integer pixels */
if ( dist >= 64 )
dist = ( dist + 16 ) & -64;
else
dist = 64;
}
else
{
dist = ah_snap_width( globals->widths, globals->num_widths, dist );
if ( hinter->flags & AH_HINTER_MONOCHROME )
{
/* monochrome horizontal hinting: snap widths to integer pixels */
/* with a different threshold */
if ( dist < 64 )
dist = 64;
else
dist = ( dist + 32 ) & -64;
}
else
{
/* for horizontal anti-aliased hinting, we adopt a more subtle */
/* approach: we strengthen small stems, round stems whose size */
/* is between 1 and 2 pixels to an integer, otherwise nothing */
if ( dist < 48 )
dist = ( dist + 64 ) >> 1;
else if ( dist < 128 )
dist = ( dist + 22 ) & -64;
else
/* XXX: round otherwise, prevent color fringes in LCD mode */
dist = ( dist + 32 ) & -64;
}
}
}
Done_Width:
if ( sign )
dist = -dist;
return dist;
}
#else /* !CHESTER_SERIF */
static FT_Pos
ah_compute_stem_width( AH_Hinter hinter,
int vertical,
@ -201,6 +332,7 @@
return dist;
}
#endif /* !CHESTER_SERIF */
/* align one stem edge relative to the previous stem edge */
@ -212,9 +344,18 @@
{
FT_Pos dist = stem_edge->opos - base_edge->opos;
#ifdef FT_CONFIG_CHESTER_SERIF
FT_Pos fitted_width = ah_compute_stem_width( hinter,
vertical,
dist,
base_edge->flags,
stem_edge->flags );
stem_edge->pos = base_edge->pos + fitted_width;
#else
stem_edge->pos = base_edge->pos +
ah_compute_stem_width( hinter, vertical, dist );
#endif
}
@ -368,12 +509,61 @@
if ( !anchor )
{
#ifdef FT_CONFIG_CHESTER_STEM
FT_Pos org_len, org_center, cur_len;
FT_Pos cur_pos1, error1, error2, u_off, d_off;
org_len = edge2->opos - edge->opos;
cur_len = ah_compute_stem_width( hinter, dimension, org_len,
edge->flags, edge2->flags );
if (cur_len <= 64 )
u_off = d_off = 32;
else
{
u_off = 38;
d_off = 26;
}
if ( cur_len < 96 )
{
org_center = edge->opos + ( org_len >> 1 );
cur_pos1 = ( org_center + 32 ) & -64;
error1 = org_center - ( cur_pos1 - u_off );
if ( error1 < 0 )
error1 = -error1;
error2 = org_center - ( cur_pos1 + d_off );
if ( error2 < 0 )
error2 = -error2;
if ( error1 < error2 )
cur_pos1 -= u_off;
else
cur_pos1 += d_off;
edge->pos = cur_pos1 - cur_len / 2;
edge2->pos = cur_pos1 + cur_len / 2;
}
else
edge->pos = ( edge->opos + 32 ) & -64;
anchor = edge;
edge->flags |= AH_EDGE_DONE;
ah_align_linked_edge( hinter, edge, edge2, dimension );
#else /* !CHESTER_STEM */
edge->pos = ( edge->opos + 32 ) & -64;
anchor = edge;
edge->flags |= AH_EDGE_DONE;
ah_align_linked_edge( hinter, edge, edge2, dimension );
#endif /* !CHESTER_STEM */
}
else
{
@ -385,7 +575,70 @@
org_len = edge2->opos - edge->opos;
org_center = org_pos + ( org_len >> 1 );
#ifdef FT_CONFIG_CHESTER_SERIF
cur_len = ah_compute_stem_width( hinter, dimension, org_len,
edge->flags, edge2->flags );
#else /* !CHESTER_SERIF */
cur_len = ah_compute_stem_width( hinter, dimension, org_len );
#endif /* !CHESTER_SERIF */
#ifdef FT_CONFIG_CHESTER_STEM
if ( cur_len < 96 )
{
FT_Pos u_off, d_off;
cur_pos1 = ( org_center + 32 ) & -64;
if (cur_len <= 64 )
u_off = d_off = 32;
else
{
u_off = 38;
d_off = 26;
}
delta1 = org_center - (cur_pos1 - u_off);
if ( delta1 < 0 )
delta1 = -delta1;
delta2 = org_center - (cur_pos1 + d_off);
if ( delta2 < 0 )
delta2 = -delta2;
if ( delta1 < delta2 )
cur_pos1 -= u_off;
else
cur_pos1 += d_off;
edge->pos = cur_pos1 - cur_len / 2;
edge2->pos = cur_pos1 + cur_len / 2;
}
else
{
org_pos = anchor->pos + (edge->opos - anchor->opos);
org_len = edge2->opos - edge->opos;
org_center = org_pos + ( org_len >> 1 );
cur_len = ah_compute_stem_width( hinter, dimension, org_len,
edge->flags, edge2->flags );
cur_pos1 = ( org_pos + 32 ) & -64;
delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center );
if ( delta1 < 0 )
delta1 = -delta1;
cur_pos2 = ( ( org_pos + org_len + 32 ) & -64 ) - cur_len;
delta2 = ( cur_pos2 + ( cur_len >> 1 ) - org_center );
if ( delta2 < 0 )
delta2 = -delta2;
edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
edge2->pos = edge->pos + cur_len;
}
#else /* !CHESTER_STEM */
cur_pos1 = ( org_pos + 32 ) & -64;
delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center );
@ -400,6 +653,8 @@
edge->pos = ( delta1 <= delta2 ) ? cur_pos1 : cur_pos2;
edge2->pos = edge->pos + cur_len;
#endif /* !CHESTER_STEM */
edge->flags |= AH_EDGE_DONE;
edge2->flags |= AH_EDGE_DONE;

View File

@ -385,12 +385,26 @@ FT_BEGIN_HEADER
} AH_OutlineRec, *AH_Outline;
#define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */
#define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */
#define AH_BLUE_SMALL_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1 ) /* xzroesc */
#define AH_BLUE_SMALL_BOTTOM ( AH_BLUE_SMALL_TOP + 1 ) /* xzroesc */
#define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */
#define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 )
#ifdef FT_CONFIG_CHESTER_SMALL_F
# define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */
# define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */
# define AH_BLUE_SMALL_F_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1 ) /* fijkdbh */
# define AH_BLUE_SMALL_TOP ( AH_BLUE_SMALL_F_TOP + 1 ) /* xzroesc */
# define AH_BLUE_SMALL_BOTTOM ( AH_BLUE_SMALL_TOP + 1 ) /* xzroesc */
# define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */
# define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 )
#else /* !CHESTER_SMALL_F */
# define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */
# define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */
# define AH_BLUE_SMALL_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1) /* xzroesc */
# define AH_BLUE_SMALL_BOTTOM ( AH_BLUE_SMALL_TOP + 1 ) /* xzroesc */
# define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */
# define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 )
#endif /* !CHESTER_SMALL_F */
typedef FT_Int AH_Blue;

View File

@ -566,16 +566,27 @@
size->ttmetrics.y_ratio = 0x10000L;
}
#ifdef FT_CONFIG_CHESTER_ASCENDER
/* Compute root ascender, descender, test height, and max_advance */
metrics->ascender = ( FT_MulFix( face->root.ascender,
metrics->y_scale ) + 63 ) & -64;
metrics->descender = ( FT_MulFix( face->root.descender,
metrics->y_scale ) + 0 ) & -64;
#else /* !CHESTER_ASCENDER */
/* Compute root ascender, descender, test height, and max_advance */
metrics->ascender = ( FT_MulFix( face->root.ascender,
metrics->y_scale ) + 32 ) & -64;
metrics->descender = ( FT_MulFix( face->root.descender,
metrics->y_scale ) + 32 ) & -64;
#endif /* !CHESTER_ASCENDER */
metrics->height = ( FT_MulFix( face->root.height,
metrics->y_scale ) + 32 ) & -64;
metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
metrics->x_scale ) + 32 ) & -64;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/* set to `invalid' by default */
size->strike_index = 0xFFFFU;