From 992f81931e18fb140b3df9a31be397dcbd88456d Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 26 Nov 2024 10:50:35 +0100 Subject: [PATCH] Windows: Fix arbitrary outline on emojis Emojis would sometimes get an outline in a seemingly random color. This was because the color run is not initialized to the first layer. MoveNext() should be called on the initially to move it to the first layer, so the first layer we rendered would end up being a monochrome version of the glyph with a random palette index. [ChangeLog][Windows] Fixed an issue where emojis would sometimes get an outline. Pick-to: 6.5 Fixes: QTBUG-131587 Change-Id: I42c2828d66c6149cdb62c2b6271dfd49ca002db0 Reviewed-by: Eirik Aavitsland (cherry picked from commit 51b584e6062e83e24950d5eccd826ea5a5b8af6f) Reviewed-by: Qt Cherry-pick Bot --- .../windows/qwindowsfontenginedirectwrite.cpp | 103 +++++++++--------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp index 764c2854f43..79d90e0ff81 100644 --- a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp @@ -832,64 +832,65 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t, image.fill(0xffffffff); } - BOOL ok = true; - if (SUCCEEDED(hr)) { + BOOL ok = true; while (SUCCEEDED(hr) && ok) { - const DWRITE_COLOR_GLYPH_RUN *colorGlyphRun = 0; - hr = enumerator->GetCurrentRun(&colorGlyphRun); - if (FAILED(hr)) { // No colored runs, only outline - qErrnoWarning(hr, "%s: IDWriteColorGlyphRunEnumerator::GetCurrentRun failed", __FUNCTION__); - break; - } - - IDWriteGlyphRunAnalysis *colorGlyphsAnalysis = NULL; - hr = factory2->CreateGlyphRunAnalysis( - &colorGlyphRun->glyphRun, - &transform, - renderMode, - measureMode, - gridFitMode, - DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE, - 0.0, 0.0, - &colorGlyphsAnalysis - ); - - if (FAILED(hr)) { - qErrnoWarning(hr, "%s: CreateGlyphRunAnalysis failed for color run", __FUNCTION__); - break; - } - - float r, g, b, a; - if (colorGlyphRun->paletteIndex == 0xFFFF) { - r = float(color.redF()); - g = float(color.greenF()); - b = float(color.blueF()); - a = float(color.alphaF()); - } else { - r = qBound(0.0f, colorGlyphRun->runColor.r, 1.0f); - g = qBound(0.0f, colorGlyphRun->runColor.g, 1.0f); - b = qBound(0.0f, colorGlyphRun->runColor.b, 1.0f); - a = qBound(0.0f, colorGlyphRun->runColor.a, 1.0f); - } - - if (!qFuzzyIsNull(a)) { - renderGlyphRun(&image, - r, - g, - b, - a, - colorGlyphsAnalysis, - boundingRect, - renderMode); - } - colorGlyphsAnalysis->Release(); - hr = enumerator->MoveNext(&ok); if (FAILED(hr)) { qErrnoWarning(hr, "%s: IDWriteColorGlyphRunEnumerator::MoveNext failed", __FUNCTION__); break; } + + if (ok) { + const DWRITE_COLOR_GLYPH_RUN *colorGlyphRun = 0; + hr = enumerator->GetCurrentRun(&colorGlyphRun); + if (FAILED(hr)) { // No colored runs, only outline + qErrnoWarning(hr, "%s: IDWriteColorGlyphRunEnumerator::GetCurrentRun failed", __FUNCTION__); + break; + } + + IDWriteGlyphRunAnalysis *colorGlyphsAnalysis = NULL; + hr = factory2->CreateGlyphRunAnalysis( + &colorGlyphRun->glyphRun, + &transform, + renderMode, + measureMode, + gridFitMode, + DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE, + 0.0, 0.0, + &colorGlyphsAnalysis + ); + + if (FAILED(hr)) { + qErrnoWarning(hr, "%s: CreateGlyphRunAnalysis failed for color run", __FUNCTION__); + break; + } + + float r, g, b, a; + if (colorGlyphRun->paletteIndex == 0xFFFF) { + r = float(color.redF()); + g = float(color.greenF()); + b = float(color.blueF()); + a = 1.0; + } else { + r = qBound(0.0f, colorGlyphRun->runColor.r, 1.0f); + g = qBound(0.0f, colorGlyphRun->runColor.g, 1.0f); + b = qBound(0.0f, colorGlyphRun->runColor.b, 1.0f); + a = qBound(0.0f, colorGlyphRun->runColor.a, 1.0f); + } + + if (!qFuzzyIsNull(a)) { + renderGlyphRun(&image, + r, + g, + b, + a, + colorGlyphsAnalysis, + boundingRect, + renderMode); + } + colorGlyphsAnalysis->Release(); + } } } else { float r, g, b, a;