From 37c3340b1402de61a537a012044575252005ec96 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 12 Dec 2024 08:09:21 +0100 Subject: [PATCH] Fix DirectWrite subpixel antialiasing on BGR screens On monitors where the subpixel arrangement is blue, green, red, our DirectWrite rendering would give the wrong subppixel antialiasing, causing color fringes on text. Like we do with Freetype, we determine subpixel arrangement of the primary screen and use this as the default. Change-Id: I9ce7025449106a2376bd0ed02ce07b59c79438bd Reviewed-by: Eirik Aavitsland (cherry picked from commit d5cef74d8d71458500f979c0d31a7241b3fef9db) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 501f78855e9a2212cd8c9a9f50c1728e9e945f2c) --- .../windows/qwindowsfontenginedirectwrite.cpp | 19 ++++++++++++++++--- .../windows/qwindowsfontenginedirectwrite_p.h | 1 + 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp index 79d90e0ff8..42f8544be0 100644 --- a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp @@ -217,6 +217,12 @@ QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *di m_fontEngineData->directWriteFactory->AddRef(); m_directWriteFontFace->AddRef(); + IDWriteRenderingParams *renderingParams = nullptr; + if (SUCCEEDED(m_fontEngineData->directWriteFactory->CreateRenderingParams(&renderingParams))) { + m_pixelGeometry = renderingParams->GetPixelGeometry(); + renderingParams->Release(); + } + fontDef.pixelSize = pixelSize; collectMetrics(); cache_cost = m_xHeight.toInt() * m_xHeight.toInt() * 2000; @@ -968,6 +974,9 @@ void QWindowsFontEngineDirectWrite::renderGlyphRun(QImage *destination, float blueAlpha = a * *src++ / 255.0; float averageAlpha = (redAlpha + greenAlpha + blueAlpha) / 3.0; + if (m_pixelGeometry == DWRITE_PIXEL_GEOMETRY_BGR) + qSwap(redAlpha, blueAlpha); + QRgb currentRgb = dest[x]; dest[x] = qRgba(qRound(qRed(currentRgb) * (1.0 - averageAlpha) + averageAlpha * r), qRound(qGreen(currentRgb) * (1.0 - averageAlpha) + averageAlpha * g), @@ -991,10 +1000,14 @@ void QWindowsFontEngineDirectWrite::renderGlyphRun(QImage *destination, BYTE *src = alphaValues + width * 3 * y; for (int x = 0; x < width; ++x) { - dest[x] = *(src + 0) << 16 - | *(src + 1) << 8 - | *(src + 2); + BYTE redAlpha = *(src + 0); + BYTE greenAlpha = *(src + 1); + BYTE blueAlpha = *(src + 2); + if (m_pixelGeometry == DWRITE_PIXEL_GEOMETRY_BGR) + qSwap(redAlpha, blueAlpha); + + dest[x] = qRgb(redAlpha, greenAlpha, blueAlpha); src += 3; } } diff --git a/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h b/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h index d7c9a79267..2e8da22f8b 100644 --- a/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h +++ b/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h @@ -133,6 +133,7 @@ private: QFixed m_maxAdvanceWidth; FaceId m_faceId; QString m_uniqueFamilyName; + DWRITE_PIXEL_GEOMETRY m_pixelGeometry = DWRITE_PIXEL_GEOMETRY_RGB; }; QT_END_NAMESPACE