diff --git a/gfx/thebes/gfxFT2Utils.cpp b/gfx/thebes/gfxFT2Utils.cpp index acc058e73353..28d3e2ffe321 100644 --- a/gfx/thebes/gfxFT2Utils.cpp +++ b/gfx/thebes/gfxFT2Utils.cpp @@ -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(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 (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.