[cff] Update advance width handling to OpenType 1.7.
Problem reported by Behdad. * src/cff/cffdrivr.c (cff_get_advances): Handle SFNT case separately. * src/cff/cffgload.c (cff_slot_load): Use advance width and side bearing values from `hmtx' table if present.
This commit is contained in:
parent
67b912d2fa
commit
5cd2155113
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2015-04-10 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
|
[cff] Update advance width handling to OpenType 1.7.
|
||||||
|
|
||||||
|
Problem reported by Behdad.
|
||||||
|
|
||||||
|
* src/cff/cffdrivr.c (cff_get_advances): Handle SFNT case
|
||||||
|
separately.
|
||||||
|
|
||||||
|
* src/cff/cffgload.c (cff_slot_load): Use advance width and side
|
||||||
|
bearing values from `hmtx' table if present.
|
||||||
|
|
||||||
2015-04-03 Alexei Podtelezhnikov <apodtele@gmail.com>
|
2015-04-03 Alexei Podtelezhnikov <apodtele@gmail.com>
|
||||||
|
|
||||||
* src/autofit/afhints.c (af_glyph_hints_reload): Use do-while loop.
|
* src/autofit/afhints.c (af_glyph_hints_reload): Use do-while loop.
|
||||||
|
|
|
@ -1111,7 +1111,7 @@ FT_BEGIN_HEADER
|
||||||
/* This field also contains the associated */
|
/* This field also contains the associated */
|
||||||
/* vertical metrics table (`vmtx'), if found. */
|
/* vertical metrics table (`vmtx'), if found. */
|
||||||
/* IMPORTANT: The contents of this field is */
|
/* IMPORTANT: The contents of this field is */
|
||||||
/* undefined if the `verticalInfo' field is */
|
/* undefined if the `vertical_info' field is */
|
||||||
/* unset. */
|
/* unset. */
|
||||||
/* */
|
/* */
|
||||||
/* num_names :: The number of name records within this */
|
/* num_names :: The number of name records within this */
|
||||||
|
|
|
@ -195,6 +195,68 @@
|
||||||
FT_GlyphSlot slot = face->glyph;
|
FT_GlyphSlot slot = face->glyph;
|
||||||
|
|
||||||
|
|
||||||
|
if ( FT_IS_SFNT( face ) )
|
||||||
|
{
|
||||||
|
/* OpenType 1.7 mandates that the data from `hmtx' table be used; */
|
||||||
|
/* it is no longer necessary that those values are identical to */
|
||||||
|
/* the values in the `CFF' table */
|
||||||
|
|
||||||
|
TT_Face ttface = (TT_Face)face;
|
||||||
|
FT_Short dummy;
|
||||||
|
|
||||||
|
|
||||||
|
if ( flags & FT_LOAD_VERTICAL_LAYOUT )
|
||||||
|
{
|
||||||
|
/* check whether we have data from the `vmtx' table at all; */
|
||||||
|
/* otherwise we extract the info from the CFF glyphstrings */
|
||||||
|
/* (instead of synthesizing a global value using the `OS/2' */
|
||||||
|
/* table) */
|
||||||
|
if ( !ttface->vertical_info )
|
||||||
|
goto Missing_Table;
|
||||||
|
|
||||||
|
for ( nn = 0; nn < count; nn++ )
|
||||||
|
{
|
||||||
|
FT_UShort ah;
|
||||||
|
|
||||||
|
|
||||||
|
( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
|
||||||
|
1,
|
||||||
|
start + nn,
|
||||||
|
&dummy,
|
||||||
|
&ah );
|
||||||
|
|
||||||
|
FT_TRACE5(( " idx %d: advance height %d font units\n",
|
||||||
|
start + nn, ah ));
|
||||||
|
advances[nn] = ah;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* check whether we have data from the `hmtx' table at all */
|
||||||
|
if ( !ttface->horizontal.number_Of_HMetrics )
|
||||||
|
goto Missing_Table;
|
||||||
|
|
||||||
|
for ( nn = 0; nn < count; nn++ )
|
||||||
|
{
|
||||||
|
FT_UShort aw;
|
||||||
|
|
||||||
|
|
||||||
|
( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
|
||||||
|
0,
|
||||||
|
start + nn,
|
||||||
|
&dummy,
|
||||||
|
&aw );
|
||||||
|
|
||||||
|
FT_TRACE5(( " idx %d: advance width %d font units\n",
|
||||||
|
start + nn, aw ));
|
||||||
|
advances[nn] = aw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Missing_Table:
|
||||||
flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
|
flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
|
||||||
|
|
||||||
for ( nn = 0; nn < count; nn++ )
|
for ( nn = 0; nn < count; nn++ )
|
||||||
|
|
|
@ -2725,7 +2725,7 @@
|
||||||
face->vertical_info &&
|
face->vertical_info &&
|
||||||
face->vertical.number_Of_VMetrics > 0 );
|
face->vertical.number_Of_VMetrics > 0 );
|
||||||
|
|
||||||
/* get the vertical metrics from the vtmx table if we have one */
|
/* get the vertical metrics from the vmtx table if we have one */
|
||||||
if ( has_vertical_info )
|
if ( has_vertical_info )
|
||||||
{
|
{
|
||||||
(void)( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
|
(void)( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
|
||||||
|
@ -2953,25 +2953,43 @@
|
||||||
FT_Bool has_vertical_info;
|
FT_Bool has_vertical_info;
|
||||||
|
|
||||||
|
|
||||||
/* copy the _unscaled_ advance width */
|
if ( face->horizontal.number_Of_HMetrics )
|
||||||
metrics->horiAdvance = decoder.glyph_width;
|
{
|
||||||
glyph->root.linearHoriAdvance = decoder.glyph_width;
|
FT_Short horiBearingX = 0;
|
||||||
|
FT_UShort horiAdvance = 0;
|
||||||
|
|
||||||
|
|
||||||
|
( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
|
||||||
|
glyph_index,
|
||||||
|
&horiBearingX,
|
||||||
|
&horiAdvance );
|
||||||
|
metrics->horiAdvance = horiAdvance;
|
||||||
|
metrics->horiBearingX = horiBearingX;
|
||||||
|
glyph->root.linearHoriAdvance = horiAdvance;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* copy the _unscaled_ advance width */
|
||||||
|
metrics->horiAdvance = decoder.glyph_width;
|
||||||
|
glyph->root.linearHoriAdvance = decoder.glyph_width;
|
||||||
|
}
|
||||||
|
|
||||||
glyph->root.internal->glyph_transformed = 0;
|
glyph->root.internal->glyph_transformed = 0;
|
||||||
|
|
||||||
has_vertical_info = FT_BOOL( face->vertical_info &&
|
has_vertical_info = FT_BOOL( face->vertical_info &&
|
||||||
face->vertical.number_Of_VMetrics > 0 );
|
face->vertical.number_Of_VMetrics > 0 );
|
||||||
|
|
||||||
/* get the vertical metrics from the vtmx table if we have one */
|
/* get the vertical metrics from the vmtx table if we have one */
|
||||||
if ( has_vertical_info )
|
if ( has_vertical_info )
|
||||||
{
|
{
|
||||||
FT_Short vertBearingY = 0;
|
FT_Short vertBearingY = 0;
|
||||||
FT_UShort vertAdvance = 0;
|
FT_UShort vertAdvance = 0;
|
||||||
|
|
||||||
|
|
||||||
(void)( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
|
( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
|
||||||
glyph_index,
|
glyph_index,
|
||||||
&vertBearingY,
|
&vertBearingY,
|
||||||
&vertAdvance );
|
&vertAdvance );
|
||||||
metrics->vertBearingY = vertBearingY;
|
metrics->vertBearingY = vertBearingY;
|
||||||
metrics->vertAdvance = vertAdvance;
|
metrics->vertAdvance = vertAdvance;
|
||||||
}
|
}
|
||||||
|
@ -3046,7 +3064,9 @@
|
||||||
metrics->width = cbox.xMax - cbox.xMin;
|
metrics->width = cbox.xMax - cbox.xMin;
|
||||||
metrics->height = cbox.yMax - cbox.yMin;
|
metrics->height = cbox.yMax - cbox.yMin;
|
||||||
|
|
||||||
metrics->horiBearingX = cbox.xMin;
|
if ( !face->horizontal.number_Of_HMetrics )
|
||||||
|
metrics->horiBearingX = cbox.xMin;
|
||||||
|
|
||||||
metrics->horiBearingY = cbox.yMax;
|
metrics->horiBearingY = cbox.yMax;
|
||||||
|
|
||||||
if ( has_vertical_info )
|
if ( has_vertical_info )
|
||||||
|
|
Loading…
Reference in New Issue