From 501f78855e9a2212cd8c9a9f50c1728e9e945f2c 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. Pick-to: 6.8 Change-Id: I9ce7025449106a2376bd0ed02ce07b59c79438bd Reviewed-by: Eirik Aavitsland (cherry picked from commit d5cef74d8d71458500f979c0d31a7241b3fef9db) Reviewed-by: Qt Cherry-pick Bot --- .../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 549e2170084..e0c5b762d58 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; @@ -1029,6 +1035,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), @@ -1052,10 +1061,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 5c98773dad3..874717fd118 100644 --- a/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h +++ b/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h @@ -136,6 +136,7 @@ private: FaceId m_faceId; QString m_uniqueFamilyName; QList m_variableAxes; + DWRITE_PIXEL_GEOMETRY m_pixelGeometry = DWRITE_PIXEL_GEOMETRY_RGB; }; QT_END_NAMESPACE