diff options
author | Eskil Abrahamsen Blomfeldt <[email protected]> | 2023-12-14 11:10:51 +0100 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <[email protected]> | 2023-12-15 00:06:06 +0100 |
commit | 05de036a8855adbdd882942d2fb61c231b02bf5a (patch) | |
tree | 40c071aca89ed8a0caaced8d91b10a92c51965ec | |
parent | 15051e205facddd8bc3f290c65ad854ec1b25091 (diff) |
Fix synthesized bold on Windows
There were a couple of problems with synthesizing boldness on
Windows: For the DirectWrite font database, this was not implemented
at all, so this change adds support for it.
For the default GDI font database, the font engine is correctly created
for a font with synthetic bold, but the function that retrieves the
contours from the font does not apply the transformation. So when
generating the distance fields for Qt Quick, we would get the
unemboldened contours. The fix for this is simply to fall back to
using DirectWrite for fonts that require any synthetization. This will
later become the default anyway.
Pick-to: 6.5 6.6 6.7
Fixes: QTBUG-119995
Change-Id: I5b4e3b19d0d71c6599746172da0bee41e8fb3940
Reviewed-by: Volker Hilsheimer <[email protected]>
-rw-r--r-- | src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp | 35 | ||||
-rw-r--r-- | src/gui/text/windows/qwindowsfontdatabase.cpp | 5 |
2 files changed, 29 insertions, 11 deletions
diff --git a/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp b/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp index 31870d4a081..b897e1f1db1 100644 --- a/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp +++ b/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp @@ -243,28 +243,43 @@ QFontEngine *QWindowsDirectWriteFontDatabase::fontEngine(const QFontDef &fontDef IDWriteFontFace *face = reinterpret_cast<IDWriteFontFace *>(handle); Q_ASSERT(face != nullptr); + DWRITE_FONT_SIMULATIONS simulations = DWRITE_FONT_SIMULATIONS_NONE; + if (fontDef.weight >= QFont::DemiBold || fontDef.style != QFont::StyleNormal) { + DirectWriteScope<IDWriteFontFace3> face3; + if (SUCCEEDED(face->QueryInterface(__uuidof(IDWriteFontFace3), + reinterpret_cast<void **>(&face3)))) { + if (fontDef.weight >= QFont::DemiBold && face3->GetWeight() < DWRITE_FONT_WEIGHT_DEMI_BOLD) + simulations |= DWRITE_FONT_SIMULATIONS_BOLD; + + if (fontDef.style != QFont::StyleNormal && face3->GetStyle() == DWRITE_FONT_STYLE_NORMAL) + simulations |= DWRITE_FONT_SIMULATIONS_OBLIQUE; + } + } + DirectWriteScope<IDWriteFontFace5> newFace; - if (!fontDef.variableAxisValues.isEmpty()) { + if (!fontDef.variableAxisValues.isEmpty() || simulations != DWRITE_FONT_SIMULATIONS_NONE) { DirectWriteScope<IDWriteFontFace5> face5; if (SUCCEEDED(face->QueryInterface(__uuidof(IDWriteFontFace5), reinterpret_cast<void **>(&face5)))) { DirectWriteScope<IDWriteFontResource> font; if (SUCCEEDED(face5->GetFontResource(&font))) { UINT32 fontAxisCount = font->GetFontAxisCount(); - QVarLengthArray<DWRITE_FONT_AXIS_VALUE, 8> fontAxisValues(fontAxisCount); - if (SUCCEEDED(face5->GetFontAxisValues(fontAxisValues.data(), fontAxisCount))) { - for (UINT32 i = 0; i < fontAxisCount; ++i) { - if (auto maybeTag = QFont::Tag::fromValue(qToBigEndian<UINT32>(fontAxisValues[i].axisTag))) { - if (fontDef.variableAxisValues.contains(*maybeTag)) - fontAxisValues[i].value = fontDef.variableAxisValues.value(*maybeTag); + + if (!fontDef.variableAxisValues.isEmpty()) { + if (SUCCEEDED(face5->GetFontAxisValues(fontAxisValues.data(), fontAxisCount))) { + for (UINT32 i = 0; i < fontAxisCount; ++i) { + if (auto maybeTag = QFont::Tag::fromValue(qToBigEndian<UINT32>(fontAxisValues[i].axisTag))) { + if (fontDef.variableAxisValues.contains(*maybeTag)) + fontAxisValues[i].value = fontDef.variableAxisValues.value(*maybeTag); + } } } } - if (SUCCEEDED(font->CreateFontFace(DWRITE_FONT_SIMULATIONS_NONE, - fontAxisValues.data(), - fontAxisCount, + if (SUCCEEDED(font->CreateFontFace(simulations, + !fontDef.variableAxisValues.isEmpty() ? fontAxisValues.data() : nullptr, + !fontDef.variableAxisValues.isEmpty() ? fontAxisCount : 0, &newFace))) { face = *newFace; } else { diff --git a/src/gui/text/windows/qwindowsfontdatabase.cpp b/src/gui/text/windows/qwindowsfontdatabase.cpp index b227cf677e7..ef516068a7a 100644 --- a/src/gui/text/windows/qwindowsfontdatabase.cpp +++ b/src/gui/text/windows/qwindowsfontdatabase.cpp @@ -1225,6 +1225,7 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, const Q HRESULT hr = data->directWriteGdiInterop->CreateFontFaceFromHdc(data->hdc, &directWriteFontFace); if (SUCCEEDED(hr)) { bool isColorFont = false; + bool needsSimulation = false; #if QT_CONFIG(direct2d) IDWriteFontFace2 *directWriteFontFace2 = nullptr; if (SUCCEEDED(directWriteFontFace->QueryInterface(__uuidof(IDWriteFontFace2), @@ -1232,10 +1233,12 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, const Q if (directWriteFontFace2->IsColorFont()) isColorFont = directWriteFontFace2->GetPaletteEntryCount() > 0; + needsSimulation = directWriteFontFace2->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE; + directWriteFontFace2->Release(); } #endif // direct2d - useDw = useDw || useDirectWrite(hintingPreference, fam, isColorFont); + useDw = useDw || useDirectWrite(hintingPreference, fam, isColorFont) || needsSimulation; qCDebug(lcQpaFonts) << __FUNCTION__ << request.families.first() << request.pointSize << "pt" << "hintingPreference=" << hintingPreference << "color=" << isColorFont |