autohinter: Don't change digit widths if all widths are the same.
This fixes FreeDesktop bug #21197. * src/autofit/afglobal.c (AF_DIGIT): New macro. (af_face_globals_compute_script_coverage): Mark ASCII digits in `glyph_scripts' array. (af_face_globals_get_metrics): Updated. (af_face_globals_is_digit): New function. * src/autofit/afglobal.h: Updated. (AF_ScriptMetricsRec): Add `digits_have_same_width' flag. * src/autofit/aflatin.c: Include FT_ADVANCES_H. (af_latin_metrics_check_digits): New function. (af_latin_metrics_init): Use it. * src/autofit/aflatin.h: Updated. * src/autofit/afcjk.c (af_cjk_metrics_init): Updated. * src/autofit/aflatin2.c: Similar changes as with aflatin.c. * src/autofit/afloader.c (af_loader_load_g): Test digit width. * docs/CHANGES: Document it.
This commit is contained in:
parent
b5a460597a
commit
8b84c9d19f
25
ChangeLog
25
ChangeLog
@ -1,3 +1,28 @@
|
||||
2009-04-27 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
autohinter: Don't change digit widths if all widths are the same.
|
||||
This fixes FreeDesktop bug #21197.
|
||||
|
||||
* src/autofit/afglobal.c (AF_DIGIT): New macro.
|
||||
(af_face_globals_compute_script_coverage): Mark ASCII digits in
|
||||
`glyph_scripts' array.
|
||||
(af_face_globals_get_metrics): Updated.
|
||||
(af_face_globals_is_digit): New function.
|
||||
* src/autofit/afglobal.h: Updated.
|
||||
(AF_ScriptMetricsRec): Add `digits_have_same_width' flag.
|
||||
|
||||
* src/autofit/aflatin.c: Include FT_ADVANCES_H.
|
||||
(af_latin_metrics_check_digits): New function.
|
||||
(af_latin_metrics_init): Use it.
|
||||
* src/autofit/aflatin.h: Updated.
|
||||
* src/autofit/afcjk.c (af_cjk_metrics_init): Updated.
|
||||
|
||||
* src/autofit/aflatin2.c: Similar changes as with aflatin.c.
|
||||
|
||||
* src/autofit/afloader.c (af_loader_load_g): Test digit width.
|
||||
|
||||
* docs/CHANGES: Document it.
|
||||
|
||||
2009-04-26 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
Make ftgrays compile with _STANDALONE_ and FT_STATIC_RASTER again.
|
||||
|
@ -1,6 +1,12 @@
|
||||
CHANGES BETWEEN 2.3.10 and 2.3.9
|
||||
|
||||
I. IMPORTANT CHANGES
|
||||
I. IMPORTANT BUG FIXES
|
||||
|
||||
- If all ASCII digits in a font have the same (unscaled) width,
|
||||
the autohinter respects this and won't change it.
|
||||
|
||||
|
||||
II. IMPORTANT CHANGES
|
||||
|
||||
- Support for the SFNT cmap 13 table format (as defined by the new
|
||||
OpenType 1.6 specification) has been added.
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* Auto-fitter hinting routines for CJK script (body). */
|
||||
/* */
|
||||
/* Copyright 2006, 2007, 2008 by */
|
||||
/* Copyright 2006, 2007, 2008, 2009 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -58,9 +58,12 @@
|
||||
|
||||
if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
|
||||
face->charmap = NULL;
|
||||
|
||||
/* latin's version would suffice */
|
||||
af_latin_metrics_init_widths( metrics, face, 0x7530 );
|
||||
else
|
||||
{
|
||||
/* latin's version would suffice */
|
||||
af_latin_metrics_init_widths( metrics, face, 0x7530 );
|
||||
af_latin_metrics_check_digits( metrics, face );
|
||||
}
|
||||
|
||||
FT_Set_Charmap( face, oldmap );
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* Auto-fitter routines to compute global hinting values (body). */
|
||||
/* */
|
||||
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 by */
|
||||
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -51,8 +51,10 @@
|
||||
|
||||
/* index of default script in `af_script_classes' */
|
||||
#define AF_SCRIPT_LIST_DEFAULT 2
|
||||
/* indicates an uncovered glyph */
|
||||
#define AF_SCRIPT_LIST_NONE 255
|
||||
/* a bit mask indicating an uncovered glyph */
|
||||
#define AF_SCRIPT_LIST_NONE 0x7F
|
||||
/* if this flag is set, we have an ASCII digit */
|
||||
#define AF_DIGIT 0x80
|
||||
|
||||
|
||||
/*
|
||||
@ -80,7 +82,7 @@
|
||||
FT_Face face = globals->face;
|
||||
FT_CharMap old_charmap = face->charmap;
|
||||
FT_Byte* gscripts = globals->glyph_scripts;
|
||||
FT_UInt ss;
|
||||
FT_UInt ss, i;
|
||||
|
||||
|
||||
/* the value 255 means `uncovered glyph' */
|
||||
@ -144,6 +146,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* mark ASCII digits */
|
||||
for ( i = 0x30; i <= 0x39; i++ )
|
||||
{
|
||||
FT_UInt gindex = FT_Get_Char_Index( face, i );
|
||||
|
||||
|
||||
if ( gindex != 0 && gindex < globals->glyph_count )
|
||||
gscripts[gindex] |= AF_DIGIT;
|
||||
}
|
||||
|
||||
Exit:
|
||||
/*
|
||||
* By default, all uncovered glyphs are set to the latin script.
|
||||
@ -253,7 +265,7 @@
|
||||
|
||||
gidx = script;
|
||||
if ( gidx == 0 || gidx + 1 >= script_max )
|
||||
gidx = globals->glyph_scripts[gindex];
|
||||
gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_LIST_NONE;
|
||||
|
||||
clazz = AF_SCRIPT_CLASSES_GET[gidx];
|
||||
if ( script == 0 )
|
||||
@ -294,4 +306,15 @@
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Bool )
|
||||
af_face_globals_is_digit( AF_FaceGlobals globals,
|
||||
FT_UInt gindex )
|
||||
{
|
||||
if ( gindex < globals->glyph_count )
|
||||
return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT );
|
||||
|
||||
return (FT_Bool)0;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
|
@ -5,7 +5,7 @@
|
||||
/* Auto-fitter routines to compute global hinting values */
|
||||
/* (specification). */
|
||||
/* */
|
||||
/* Copyright 2003, 2004, 2005, 2007 by */
|
||||
/* Copyright 2003, 2004, 2005, 2007, 2009 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -56,7 +56,11 @@ FT_BEGIN_HEADER
|
||||
FT_LOCAL( void )
|
||||
af_face_globals_free( AF_FaceGlobals globals );
|
||||
|
||||
/* */
|
||||
FT_LOCAL_DEF( FT_Bool )
|
||||
af_face_globals_is_digit( AF_FaceGlobals globals,
|
||||
FT_UInt gindex );
|
||||
|
||||
/* */
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* Auto-fitter hinting routines for latin script (body). */
|
||||
/* */
|
||||
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 by */
|
||||
/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -16,6 +16,8 @@
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include FT_ADVANCES_H
|
||||
|
||||
#include "aflatin.h"
|
||||
#include "aferrors.h"
|
||||
|
||||
@ -146,7 +148,8 @@
|
||||
#define AF_LATIN_MAX_TEST_CHARACTERS 12
|
||||
|
||||
|
||||
static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES][AF_LATIN_MAX_TEST_CHARACTERS+1] =
|
||||
static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES]
|
||||
[AF_LATIN_MAX_TEST_CHARACTERS + 1] =
|
||||
{
|
||||
"THEZOCQS",
|
||||
"HEZLOCUS",
|
||||
@ -379,7 +382,7 @@
|
||||
blue->flags |= AF_LATIN_BLUE_TOP;
|
||||
|
||||
/*
|
||||
* The following flags is used later to adjust the y and x scales
|
||||
* The following flag is used later to adjust the y and x scales
|
||||
* in order to optimize the pixel grid alignment of the top of small
|
||||
* letters.
|
||||
*/
|
||||
@ -393,6 +396,52 @@
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
af_latin_metrics_check_digits( AF_LatinMetrics metrics,
|
||||
FT_Face face )
|
||||
{
|
||||
FT_UInt i;
|
||||
FT_Bool started = 0, same_width = 1;
|
||||
|
||||
|
||||
/* check whether all ASCII digits have the same advance width; */
|
||||
/* digit `0' is 0x30 in all supported charmaps */
|
||||
for ( i = 0x30; i <= 0x39; i++ )
|
||||
{
|
||||
FT_UInt glyph_index;
|
||||
FT_Fixed advance, old_advance;
|
||||
|
||||
|
||||
glyph_index = FT_Get_Char_Index( face, i );
|
||||
if ( glyph_index == 0 )
|
||||
continue;
|
||||
|
||||
if ( FT_Get_Advance( face, glyph_index,
|
||||
FT_LOAD_NO_SCALE |
|
||||
FT_LOAD_NO_HINTING |
|
||||
FT_LOAD_IGNORE_TRANSFORM,
|
||||
&advance ) )
|
||||
continue;
|
||||
|
||||
if ( started )
|
||||
{
|
||||
if ( advance != old_advance )
|
||||
{
|
||||
same_width = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
old_advance = advance;
|
||||
started = 1;
|
||||
}
|
||||
}
|
||||
|
||||
metrics->root.digits_have_same_width = same_width;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
af_latin_metrics_init( AF_LatinMetrics metrics,
|
||||
FT_Face face )
|
||||
@ -426,6 +475,7 @@
|
||||
/* For now, compute the standard width and height from the `o'. */
|
||||
af_latin_metrics_init_widths( metrics, face, 'o' );
|
||||
af_latin_metrics_init_blues( metrics, face );
|
||||
af_latin_metrics_check_digits( metrics, face );
|
||||
}
|
||||
|
||||
FT_Set_Charmap( face, oldmap );
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* Auto-fitter hinting routines for latin script (specification). */
|
||||
/* */
|
||||
/* Copyright 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* Copyright 2003, 2004, 2005, 2006, 2007, 2009 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -137,6 +137,10 @@ FT_BEGIN_HEADER
|
||||
FT_Face face,
|
||||
FT_ULong charcode );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_latin_metrics_check_digits( AF_LatinMetrics metrics,
|
||||
FT_Face face );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
@ -16,6 +16,8 @@
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include FT_ADVANCES_H
|
||||
|
||||
#include "aflatin.h"
|
||||
#include "aflatin2.h"
|
||||
#include "aferrors.h"
|
||||
@ -401,6 +403,52 @@
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
af_latin2_metrics_check_digits( AF_LatinMetrics metrics,
|
||||
FT_Face face )
|
||||
{
|
||||
FT_UInt i;
|
||||
FT_Bool started = 0, same_width = 1;
|
||||
|
||||
|
||||
/* check whether all ASCII digits have the same advance width; */
|
||||
/* digit `0' is 0x30 in all supported charmaps */
|
||||
for ( i = 0x30; i <= 0x39; i++ )
|
||||
{
|
||||
FT_UInt glyph_index;
|
||||
FT_Fixed advance, old_advance;
|
||||
|
||||
|
||||
glyph_index = FT_Get_Char_Index( face, i );
|
||||
if ( glyph_index == 0 )
|
||||
continue;
|
||||
|
||||
if ( FT_Get_Advance( face, glyph_index,
|
||||
FT_LOAD_NO_SCALE |
|
||||
FT_LOAD_NO_HINTING |
|
||||
FT_LOAD_IGNORE_TRANSFORM,
|
||||
&advance ) )
|
||||
continue;
|
||||
|
||||
if ( started )
|
||||
{
|
||||
if ( advance != old_advance )
|
||||
{
|
||||
same_width = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
old_advance = advance;
|
||||
started = 1;
|
||||
}
|
||||
}
|
||||
|
||||
metrics->root.digits_have_same_width = same_width;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
af_latin2_metrics_init( AF_LatinMetrics metrics,
|
||||
FT_Face face )
|
||||
@ -434,6 +482,7 @@
|
||||
/* For now, compute the standard width and height from the `o'. */
|
||||
af_latin2_metrics_init_widths( metrics, face, 'o' );
|
||||
af_latin2_metrics_init_blues( metrics, face );
|
||||
af_latin2_metrics_check_digits( metrics, face );
|
||||
}
|
||||
|
||||
FT_Set_Charmap( face, oldmap );
|
||||
|
@ -183,9 +183,9 @@
|
||||
|
||||
if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) )
|
||||
{
|
||||
old_rsb = loader->pp2.x - edge2->opos;
|
||||
old_lsb = edge1->opos;
|
||||
new_lsb = edge1->pos;
|
||||
old_rsb = loader->pp2.x - edge2->opos;
|
||||
old_lsb = edge1->opos;
|
||||
new_lsb = edge1->pos;
|
||||
|
||||
/* remember unhinted values to later account */
|
||||
/* for rounding errors */
|
||||
@ -216,8 +216,9 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_Pos pp1x = loader->pp1.x;
|
||||
FT_Pos pp2x = loader->pp2.x;
|
||||
FT_Pos pp1x = loader->pp1.x;
|
||||
FT_Pos pp2x = loader->pp2.x;
|
||||
|
||||
|
||||
loader->pp1.x = FT_PIX_ROUND( pp1x );
|
||||
loader->pp2.x = FT_PIX_ROUND( pp2x );
|
||||
@ -228,8 +229,9 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_Pos pp1x = loader->pp1.x;
|
||||
FT_Pos pp2x = loader->pp2.x;
|
||||
FT_Pos pp1x = loader->pp1.x;
|
||||
FT_Pos pp2x = loader->pp2.x;
|
||||
|
||||
|
||||
loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta );
|
||||
loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta );
|
||||
@ -412,7 +414,8 @@
|
||||
slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y );
|
||||
|
||||
/* for mono-width fonts (like Andale, Courier, etc.) we need */
|
||||
/* to keep the original rounded advance width */
|
||||
/* to keep the original rounded advance width; ditto for */
|
||||
/* digits if all have the same advance width */
|
||||
#if 0
|
||||
if ( !FT_IS_FIXED_WIDTH( slot->face ) )
|
||||
slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
|
||||
@ -420,13 +423,9 @@
|
||||
slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
|
||||
x_scale );
|
||||
#else
|
||||
if ( !FT_IS_FIXED_WIDTH( slot->face ) )
|
||||
{
|
||||
/* non-spacing glyphs must stay as-is */
|
||||
if ( slot->metrics.horiAdvance )
|
||||
slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
|
||||
}
|
||||
else
|
||||
if ( FT_IS_FIXED_WIDTH( slot->face ) ||
|
||||
( af_face_globals_is_digit( loader->globals, glyph_index ) &&
|
||||
metrics->digits_have_same_width ) )
|
||||
{
|
||||
slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
|
||||
metrics->scaler.x_scale );
|
||||
@ -436,6 +435,12 @@
|
||||
slot->lsb_delta = 0;
|
||||
slot->rsb_delta = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* non-spacing glyphs must stay as-is */
|
||||
if ( slot->metrics.horiAdvance )
|
||||
slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
|
||||
}
|
||||
#endif
|
||||
|
||||
slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance,
|
||||
|
@ -285,6 +285,7 @@ extern void* _af_debug_hints;
|
||||
{
|
||||
AF_ScriptClass clazz;
|
||||
AF_ScalerRec scaler;
|
||||
FT_Bool digits_have_same_width;
|
||||
|
||||
} AF_ScriptMetricsRec, *AF_ScriptMetrics;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user