bug 973380 - fix font metrics initialization for non-scalable fonts in the gfxFT2Fonts backend. r=karlt

This commit is contained in:
Jonathan Kew 2014-02-17 07:45:57 +00:00
parent 7d5050a3db
commit 2f66ba6147

View File

@ -81,7 +81,8 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics,
gfxFloat emHeight;
// Scale for vertical design metric conversion: pixels per design unit.
gfxFloat yScale;
// If this remains at 0.0, we can't use metrics from OS/2 etc.
gfxFloat yScale = 0.0;
if (FT_IS_SCALABLE(mFace)) {
// Prefer FT_Size_Metrics::x_scale to x_ppem as x_ppem does not
// have subpixel accuracy.
@ -93,11 +94,17 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics,
yScale = FLOAT_FROM_26_6(FLOAT_FROM_16_16(ftMetrics.y_scale));
emHeight = mFace->units_per_EM * yScale;
} else { // Not scalable.
// FT_Size_Metrics doc says x_scale is "only relevant for scalable
// font formats".
gfxFloat emUnit = mFace->units_per_EM;
emHeight = ftMetrics.y_ppem;
yScale = emHeight / emUnit;
// FT_Face doc says units_per_EM and a bunch of following fields
// are "only relevant to scalable outlines". If it's an sfnt,
// we can get units_per_EM from the 'head' table instead; otherwise,
// we don't have a unitsPerEm value so we can't compute/use yScale.
const TT_Header* head =
static_cast<TT_Header*>(FT_Get_Sfnt_Table(mFace, ft_sfnt_head));
if (head) {
gfxFloat emUnit = head->Units_Per_EM;
emHeight = ftMetrics.y_ppem;
yScale = emHeight / emUnit;
}
}
TT_OS2 *os2 =
@ -108,7 +115,7 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics,
aMetrics->maxAdvance = FLOAT_FROM_26_6(ftMetrics.max_advance);
gfxFloat lineHeight;
if (os2 && os2->sTypoAscender) {
if (os2 && os2->sTypoAscender && yScale > 0.0) {
aMetrics->emAscent = os2->sTypoAscender * yScale;
aMetrics->emDescent = -os2->sTypoDescender * yScale;
FT_Short typoHeight =
@ -150,7 +157,7 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics,
aMetrics->xHeight = -extents.y_bearing;
aMetrics->aveCharWidth = extents.x_advance;
} else {
if (os2 && os2->sxHeight) {
if (os2 && os2->sxHeight && yScale > 0.0) {
aMetrics->xHeight = os2->sxHeight * yScale;
} else {
// CSS 2.1, section 4.3.2 Lengths: "In the cases where it is
@ -195,7 +202,7 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics,
// Therefore get the underline position directly from the table
// ourselves when this table exists. Use FreeType's metrics for
// other (including older PostScript) fonts.
if (mFace->underline_position && mFace->underline_thickness) {
if (mFace->underline_position && mFace->underline_thickness && yScale > 0.0) {
aMetrics->underlineSize = mFace->underline_thickness * yScale;
TT_Postscript *post = static_cast<TT_Postscript*>
(FT_Get_Sfnt_Table(mFace, ft_sfnt_post));
@ -211,7 +218,7 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics,
aMetrics->underlineOffset = -aMetrics->underlineSize;
}
if (os2 && os2->yStrikeoutSize && os2->yStrikeoutPosition) {
if (os2 && os2->yStrikeoutSize && os2->yStrikeoutPosition && yScale > 0.0) {
aMetrics->strikeoutSize = os2->yStrikeoutSize * yScale;
aMetrics->strikeoutOffset = os2->yStrikeoutPosition * yScale;
} else { // No strikeout info.