[truetype] Improve emulation of vertical metrics.
This commit also improves the start values of vertical phantom points. Kudos to Greg Hitchcock for help. * src/truetype/ttgload.c (TT_Get_VMetrics): Add parameter to pass `yMax' value. Replace code with fixed Microsoft definition. (tt_get_metrics): Updated. (TT_LOADER_SET_PP): Add explanation how to initialize phantom points, taken from both the OpenType specification and private communication with Greg (which will eventually be added to the standard). Fix horizontal position of `pp3' and `pp4'. * src/truetype/ttgload.h: Updated. * src/truetype/ttdriver.c (tt_get_advances): Updated. * docs/CHANGES: Updated.
This commit is contained in:
parent
b1d97810c9
commit
7e4b0fbfdd
22
ChangeLog
22
ChangeLog
@ -1,3 +1,25 @@
|
||||
2013-11-06 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[truetype] Improve emulation of vertical metrics.
|
||||
|
||||
This commit also improves the start values of vertical phantom
|
||||
points. Kudos to Greg Hitchcock for help.
|
||||
|
||||
* src/truetype/ttgload.c (TT_Get_VMetrics): Add parameter to pass
|
||||
`yMax' value. Replace code with fixed Microsoft definition.
|
||||
(tt_get_metrics): Updated.
|
||||
(TT_LOADER_SET_PP): Add explanation how to initialize phantom
|
||||
points, taken from both the OpenType specification and private
|
||||
communication with Greg (which will eventually be added to the
|
||||
standard).
|
||||
Fix horizontal position of `pp3' and `pp4'.
|
||||
|
||||
* src/truetype/ttgload.h: Updated.
|
||||
|
||||
* src/truetype/ttdriver.c (tt_get_advances): Updated.
|
||||
|
||||
* docs/CHANGES: Updated.
|
||||
|
||||
2013-11-05 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* builds/windows/vc2010/freetype.vcxproj: s/v110/v100/.
|
||||
|
10
docs/CHANGES
10
docs/CHANGES
@ -11,6 +11,10 @@ CHANGES BETWEEN 2.5 and 2.5.1
|
||||
- Many fields of the `PCLT' table in SFNT based fonts (if accessed
|
||||
with `FT_Get_Sfnt_Table') were computed incorrectly.
|
||||
|
||||
- In TrueType fonts, hinting of composite glyphs could sometimes
|
||||
deliver incorrect positions of components or even distorted
|
||||
shapes.
|
||||
|
||||
|
||||
II. IMPORTANT CHANGES
|
||||
|
||||
@ -76,6 +80,12 @@ CHANGES BETWEEN 2.5 and 2.5.1
|
||||
to set selector bit 6 to get results for selector bits 7-10,
|
||||
which is wrong.
|
||||
|
||||
- Improved computation of emulated vertical metrics for TrueType
|
||||
fonts.
|
||||
|
||||
- Fixed horizontal start-up position of vertical phantom points in
|
||||
TrueType bytecode.
|
||||
|
||||
|
||||
======================================================================
|
||||
|
||||
|
@ -215,7 +215,8 @@
|
||||
FT_UShort ah;
|
||||
|
||||
|
||||
TT_Get_VMetrics( face, start + nn, &tsb, &ah );
|
||||
/* since we don't need `tsb', we use zero for `yMax' parameter */
|
||||
TT_Get_VMetrics( face, start + nn, 0, &tsb, &ah );
|
||||
advances[nn] = ah;
|
||||
}
|
||||
}
|
||||
|
@ -85,45 +85,30 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Return the vertical metrics in font units for a given glyph. */
|
||||
/* Greg Hitchcock from Microsoft told us that if there were no `vmtx' */
|
||||
/* table, typoAscender/Descender from the `OS/2' table would be used */
|
||||
/* instead, and if there were no `OS/2' table, use ascender/descender */
|
||||
/* from the `hhea' table. But that is not what Microsoft's rasterizer */
|
||||
/* apparently does: It uses the ppem value as the advance height, and */
|
||||
/* sets the top side bearing to be zero. */
|
||||
/* See macro `TT_LOADER_SET_PP' below for explanations. */
|
||||
/* */
|
||||
FT_LOCAL_DEF( void )
|
||||
TT_Get_VMetrics( TT_Face face,
|
||||
FT_UInt idx,
|
||||
FT_Pos yMax,
|
||||
FT_Short* tsb,
|
||||
FT_UShort* ah )
|
||||
{
|
||||
if ( face->vertical_info )
|
||||
( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah );
|
||||
|
||||
#if 1 /* Empirically determined, at variance with what MS said */
|
||||
|
||||
else
|
||||
{
|
||||
*tsb = 0;
|
||||
*ah = face->root.units_per_EM;
|
||||
}
|
||||
|
||||
#else /* This is what MS said to do. It isn't what they do, however. */
|
||||
|
||||
else if ( face->os2.version != 0xFFFFU )
|
||||
{
|
||||
*tsb = face->os2.sTypoAscender;
|
||||
*tsb = face->os2.sTypoAscender - yMax;
|
||||
*ah = face->os2.sTypoAscender - face->os2.sTypoDescender;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
*tsb = face->horizontal.Ascender;
|
||||
*tsb = face->horizontal.Ascender - yMax;
|
||||
*ah = face->horizontal.Ascender - face->horizontal.Descender;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
FT_TRACE5(( " advance height (font units): %d\n", *ah ));
|
||||
FT_TRACE5(( " top side bearing (font units): %d\n", *tsb ));
|
||||
}
|
||||
@ -146,6 +131,7 @@
|
||||
&left_bearing,
|
||||
&advance_width );
|
||||
TT_Get_VMetrics( face, glyph_index,
|
||||
loader->bbox.yMax,
|
||||
&top_bearing,
|
||||
&advance_height );
|
||||
|
||||
@ -1263,18 +1249,78 @@
|
||||
}
|
||||
|
||||
|
||||
/* Calculate the four phantom points. */
|
||||
/* The first two stand for horizontal origin and advance. */
|
||||
/* The last two stand for vertical advance and origin. */
|
||||
/*
|
||||
* Calculate the phantom points
|
||||
*
|
||||
* Defining the right side bearing (rsb) as
|
||||
*
|
||||
* rsb = aw - (lsb + xmax - xmin)
|
||||
*
|
||||
* (with `aw' the advance width, `lsb' the left side bearing, and `xmin'
|
||||
* and `xmax' the glyph's minimum and maximum x value), the OpenType
|
||||
* specification defines the initial position of horizontal phantom points
|
||||
* as
|
||||
*
|
||||
* pp1 = (xmin - lsb, 0) ,
|
||||
* pp2 = (pp1 + aw, 0) .
|
||||
*
|
||||
* However, the specification lacks the precise definition of vertical
|
||||
* phantom points. Greg Hitchcock provided the following explanation.
|
||||
*
|
||||
* - a `vmtx' table is present
|
||||
*
|
||||
* For any glyph, the minimum and maximum y values (`ymin' and `ymax')
|
||||
* are given in the `glyf' table, the top side bearing (tsb) and advance
|
||||
* height (ah) are given in the `vmtx' table. The bottom side bearing
|
||||
* (bsb) is then calculated as
|
||||
*
|
||||
* bsb = ah - (tsb + ymax - ymin) ,
|
||||
*
|
||||
* and the initial position of vertical phantom points is
|
||||
*
|
||||
* pp3 = (x, ymax + tsb) ,
|
||||
* pp4 = (x, pp3 - ah) .
|
||||
*
|
||||
* See below for value `x'.
|
||||
*
|
||||
* - no `vmtx' table in the font
|
||||
*
|
||||
* If there is an `OS/2' table, we set
|
||||
*
|
||||
* DefaultAscender = sTypoAscender ,
|
||||
* DefaultDescender = sTypoDescender ,
|
||||
*
|
||||
* otherwise we use data from the `hhea' table:
|
||||
*
|
||||
* DefaultAscender = Ascender ,
|
||||
* DefaultDescender = Descender .
|
||||
*
|
||||
* With these two variables we can now set
|
||||
*
|
||||
* ah = DefaultAscender - sDefaultDescender ,
|
||||
* tsb = DefaultAscender - yMax ,
|
||||
*
|
||||
* and proceed as if a `vmtx' table was present.
|
||||
*
|
||||
* Usually we have
|
||||
*
|
||||
* x = aw / 2 ,
|
||||
*
|
||||
* but there is a compatibility case where it can be set to
|
||||
*
|
||||
* x = -DefaultDescender -
|
||||
* ((DefaultAscender - DefaultDescender - aw) / 2) .
|
||||
*
|
||||
*/
|
||||
#define TT_LOADER_SET_PP( loader ) \
|
||||
do { \
|
||||
(loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \
|
||||
(loader)->pp1.y = 0; \
|
||||
(loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \
|
||||
(loader)->pp2.y = 0; \
|
||||
(loader)->pp3.x = 0; \
|
||||
(loader)->pp3.y = (loader)->top_bearing + (loader)->bbox.yMax; \
|
||||
(loader)->pp4.x = 0; \
|
||||
(loader)->pp3.x = (loader)->advance / 2; \
|
||||
(loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing; \
|
||||
(loader)->pp4.x = (loader)->advance / 2; \
|
||||
(loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \
|
||||
} while ( 0 )
|
||||
|
||||
|
@ -43,6 +43,7 @@ FT_BEGIN_HEADER
|
||||
FT_LOCAL( void )
|
||||
TT_Get_VMetrics( TT_Face face,
|
||||
FT_UInt idx,
|
||||
FT_Pos yMax,
|
||||
FT_Short* tsb,
|
||||
FT_UShort* ah );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user