Windows: Fix rendering of MingLiU fonts at some scales

At certain sizes and scales, GDI will clip away the bottom line
of pixels when rendering the MingLiU fonts. Since DirectWrite
renders it correctly, we force the use of DirectWrite in this case.
This also requires supporting classic GDI rendering in the DirectWrite
engine, to make sure the rendering still looks correct.

Note that this does not cover the corner case where the font is loaded
directly from data with QRawFont.

[ChangeLog][QtGui][Windows] Fixed rendering error when using the
MingLiU fonts at certain combinations of pixel size and scale.

Task-number: QTBUG-49346
Change-Id: Ie026c0d5932717858c4536dae077013eb6a1eafc
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
bb10
Eskil Abrahamsen Blomfeldt 2016-10-17 13:35:45 +02:00
parent 9d696af6cd
commit ce2ae6ebd8
2 changed files with 24 additions and 8 deletions

View File

@ -110,13 +110,21 @@ static void createDirectWriteFactory(IDWriteFactory **factory)
*factory = static_cast<IDWriteFactory *>(result);
}
static inline bool useDirectWrite(QFont::HintingPreference hintingPreference, bool isColorFont = false)
static inline bool useDirectWrite(QFont::HintingPreference hintingPreference,
const QString &familyName = QString(),
bool isColorFont = false)
{
const unsigned options = QWindowsIntegration::instance()->options();
if (Q_UNLIKELY(options & QWindowsIntegration::DontUseDirectWriteFonts))
return false;
if (isColorFont)
return (options & QWindowsIntegration::DontUseColorFonts) == 0;
// At some scales, GDI will misrender the MingLiU font, so we force use of
// DirectWrite to work around the issue.
if (Q_UNLIKELY(familyName.startsWith(QLatin1String("MingLiU"))))
return true;
return hintingPreference == QFont::PreferNoHinting
|| hintingPreference == QFont::PreferVerticalHinting
|| (QHighDpiScaling::isActive() && hintingPreference == QFont::PreferDefaultHinting);
@ -1875,7 +1883,7 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request,
#endif
const QFont::HintingPreference hintingPreference =
static_cast<QFont::HintingPreference>(request.hintingPreference);
const bool useDw = useDirectWrite(hintingPreference, isColorFont);
const bool useDw = useDirectWrite(hintingPreference, fam, isColorFont);
qCDebug(lcQpaFonts) << __FUNCTION__ << request.family << request.pointSize
<< "pt" << "hintingPreference=" << hintingPreference << "color=" << isColorFont
<< dpi << "dpi" << "useDirectWrite=" << useDw;

View File

@ -185,6 +185,18 @@ namespace {
}
static DWRITE_RENDERING_MODE hintingPreferenceToRenderingMode(QFont::HintingPreference hintingPreference)
{
switch (hintingPreference) {
case QFont::PreferNoHinting:
return DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
case QFont::PreferVerticalHinting:
return DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
default:
return DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC;
}
}
/*!
\class QWindowsFontEngineDirectWrite
\brief Windows font engine using Direct Write.
@ -661,9 +673,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
transform.m22 = xform.m22();
DWRITE_RENDERING_MODE renderMode =
fontDef.hintingPreference == QFont::PreferNoHinting
? DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC
: DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
hintingPreferenceToRenderingMode(QFont::HintingPreference(fontDef.hintingPreference));
IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(
@ -950,9 +960,7 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
transform.m22 = matrix.m22();
DWRITE_RENDERING_MODE renderMode =
fontDef.hintingPreference == QFont::PreferNoHinting
? DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC
: DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
hintingPreferenceToRenderingMode(QFont::HintingPreference(fontDef.hintingPreference));
IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(