Support variation selector when emoji segmenter is disabled

This amends cb2633468413d8c2a9e28d4c4a10b25e90dd3116.

The patch excluded the ad hoc parsing of variation selector
except when Qt was built without the emoji segmenter. The
reasoning being that the emoji parsing handles this correctly
now.

However, when setting the QT_DISABLE_EMOJI_SEGMENTER variable
in the environment, this is supposed to work as a fail safe
which gives you the original behavior, in case there are
regressions. Therefore, the variation selector handling needs
to be run also when this environment variable is set.

Pick-to: 6.9
Change-Id: I2669d29016a552775461aad13e50459baecdc26f
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2024-11-29 15:27:10 +01:00 committed by Volker Hilsheimer
parent c316712fb8
commit aaf7437db3
3 changed files with 15 additions and 9 deletions

View File

@ -1627,6 +1627,16 @@ QFontEngine::GlyphCacheEntry &QFontEngine::GlyphCacheEntry::operator=(const Glyp
return *this;
}
bool QFontEngine::disableEmojiSegmenter()
{
#if defined(QT_NO_EMOJISEGMENTER)
return true;
#else
static const bool sDisableEmojiSegmenter = qEnvironmentVariableIntValue("QT_DISABLE_EMOJI_SEGMENTER") > 0;
return sDisableEmojiSegmenter;
#endif
}
// ------------------------------------------------------------------
// The box font engine
// ------------------------------------------------------------------
@ -1997,9 +2007,8 @@ int QFontEngineMulti::stringToCMap(const QChar *str, int len,
int glyph_pos = 0;
QStringIterator it(str, str + len);
#if defined(QT_NO_EMOJISEGMENTER)
const bool enableVariationSelectorHack = disableEmojiSegmenter();
char32_t previousUcs4 = 0;
#endif
int lastFallback = -1;
while (it.hasNext()) {
@ -2060,12 +2069,11 @@ int QFontEngineMulti::stringToCMap(const QChar *str, int len,
}
}
#if defined(QT_NO_EMOJISEGMENTER)
// For variant-selectors, they are modifiers to the previous character. If we
// end up with different font selections for the selector and the character it
// modifies, we try applying the selector font to the preceding character as well
const int variantSelectorBlock = 0xFE00;
if ((ucs4 & 0xFFF0) == variantSelectorBlock && glyph_pos > 0) {
if (enableVariationSelectorHack && (ucs4 & 0xFFF0) == variantSelectorBlock && glyph_pos > 0) {
int selectorFontEngine = glyphs->glyphs[glyph_pos] >> 24;
int precedingCharacterFontEngine = glyphs->glyphs[glyph_pos - 1] >> 24;
@ -2099,15 +2107,12 @@ int QFontEngineMulti::stringToCMap(const QChar *str, int len,
}
}
}
#endif
}
it.advance();
++glyph_pos;
#if defined(QT_NO_EMOJISEGMENTER)
previousUcs4 = ucs4;
#endif
}
*nglyphs = glyph_pos;

View File

@ -260,6 +260,8 @@ public:
virtual bool hasUnreliableGlyphOutline() const;
virtual bool expectsGammaCorrectedBlending() const;
static bool disableEmojiSegmenter();
enum HintStyle {
HintNone,
HintLight,

View File

@ -1987,8 +1987,7 @@ void QTextEngine::itemize() const
}
#if !defined(QT_NO_EMOJISEGMENTER)
static const bool sDisableEmojiSegmenter = qEnvironmentVariableIntValue("QT_DISABLE_EMOJI_SEGMENTER") > 0;
const bool disableEmojiSegmenter = sDisableEmojiSegmenter || option.flags().testFlag(QTextOption::DisableEmojiParsing);
const bool disableEmojiSegmenter = QFontEngine::disableEmojiSegmenter() || option.flags().testFlag(QTextOption::DisableEmojiParsing);
QVarLengthArray<CharacterCategory> categorizedString;
if (!disableEmojiSegmenter) {