Freetype: Fix wrong line spacing for Courier New

The regular variant of Monotype's "Courier New" font, the one
which is included by default on Windows, has an EBLC table, which
overrides the ascent and descent for certain sizes. The Freetype
engine doesn't automatically respect this, so there is a hack
in place to fetch the correct values for us.

But there were two issues with that code, which lead to us getting
the wrong line spacing for that particular font: The first was that
we did not update the height metric for the font. This is used,
together with the ascent and descent, to calculate the leading of
the font. So when we set the height of text lines in a layout, we
would get a leading based on the height for the scalable font
and the ascent/descent from the EBLC table, and this would not match
up.

Also, as reported elsewhere on the Internet, the descent value in
the EBLC table for Courier New is set to a positive value instead
of a negative one. This must be a bug in the font, so we special
case it and fix the value to avoid bogus line spacing later.

[ChangeLog][Qt Gui][Text] Fixed line spacing with some scalable fonts
containing bitmaps with the Freetype font engine.

Task-number: QTBUG-50090
Change-Id: I95165dde7b8ffac6d7f9ac43baadb3eb75d28abe
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
bb10
Eskil Abrahamsen Blomfeldt 2016-09-28 16:29:41 +02:00
parent c35eff2ace
commit 22bf1f28f9
1 changed files with 6 additions and 0 deletions

View File

@ -781,8 +781,14 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
FT_Select_Size(face, i);
if (face->size->metrics.ascender + face->size->metrics.descender > 0) {
FT_Pos leading = metrics.height - metrics.ascender + metrics.descender;
metrics.ascender = face->size->metrics.ascender;
metrics.descender = face->size->metrics.descender;
if (metrics.descender > 0
&& QString::fromUtf8(face->family_name) == QLatin1String("Courier New")) {
metrics.descender *= -1;
}
metrics.height = metrics.ascender - metrics.descender + leading;
}
FT_Set_Char_Size(face, xsize, ysize, 0, 0);