From 51b584e6062e83e24950d5eccd826ea5a5b8af6f 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 6.8 Fixes: QTBUG-131587 Change-Id: I42c2828d66c6149cdb62c2b6271dfd49ca002db0 Reviewed-by: Eirik Aavitsland --- .../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 049a3e5885f..549e2170084 100644 --- a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp @@ -893,64 +893,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;