Add option to disable emoji parsing

There is a very small overhead to this, so we provide a
way to manually disable it if you know you are displaying
text without any emoji sequences.

Task-number: QTBUG-111801
Change-Id: I231b3dfab368ef2cf3b17dd57cd4e3160ed38192
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2024-11-25 15:01:18 +01:00
parent 906aa1533f
commit a317b28d87
7 changed files with 63 additions and 1 deletions

View File

@ -1956,7 +1956,6 @@ namespace {
void QTextEngine::itemize() const
{
static bool disableEmojiSegmenter = qEnvironmentVariableIntValue("QT_DISABLE_EMOJI_SEGMENTER") > 0;
validate();
if (layoutData->items.size())
return;
@ -1987,6 +1986,9 @@ 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);
QVarLengthArray<CharacterCategory> categorizedString;
if (!disableEmojiSegmenter) {
// Parse emoji sequences

View File

@ -272,6 +272,9 @@ QList<QTextOption::Tab> QTextOption::tabs() const
\value AddSpaceForLineAndParagraphSeparators While determining the line-break positions take into account the
space added for drawing a separator character.
\value SuppressColors Suppress all color changes in the character formats (except the main selection).
\value [since 6.9] DisableEmojiParsing By default, Qt will detect emoji sequences in input strings
and prioritize using color fonts to display them. This extra step can be disabled by setting the
DisableEmojiParsing flag if it is known in advance that it will not be needed.
*/
/*!

View File

@ -74,6 +74,7 @@ public:
SuppressColors = 0x8,
ShowDocumentTerminator = 0x10,
ShowDefaultIgnorables = 0x20,
DisableEmojiParsing = 0x40,
IncludeTrailingSpaces = 0x80000000,
};
Q_DECLARE_FLAGS(Flags, Flag)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -19,6 +19,8 @@ private slots:
void tst_render();
void tst_differentScriptsBackgrounds();
void tst_synthesizedObliqueAndRotation();
void tst_disableEmojiParsing_data();
void tst_disableEmojiParsing();
private:
QDir htmlDir;
@ -126,6 +128,57 @@ void tst_Text::tst_synthesizedObliqueAndRotation()
QBASELINE_CHECK(image, "tst_synthesizedObliqueAndRotation");
}
void tst_Text::tst_disableEmojiParsing_data()
{
QTest::addColumn<QString>("html");
QStringList htmlFiles;
// first add generic test files
for (const auto &qssFile : htmlDir.entryList({QStringLiteral("emoji*.html")}, QDir::Files | QDir::Readable))
htmlFiles << htmlDir.absoluteFilePath(qssFile);
// then test-function specific files
const QString testFunction = QString(QTest::currentTestFunction()).remove("tst_").toLower();
if (htmlDir.cd(testFunction)) {
for (const auto &htmlFile : htmlDir.entryList({QStringLiteral("*.html")}, QDir::Files | QDir::Readable))
htmlFiles << htmlDir.absoluteFilePath(htmlFile);
htmlDir.cdUp();
}
for (const auto &htmlFile : htmlFiles) {
QFileInfo fileInfo(htmlFile);
QFile file(htmlFile);
QVERIFY(file.open(QFile::ReadOnly));
QString html = QString::fromUtf8(file.readAll());
QBaselineTest::newRow(fileInfo.baseName().toUtf8()) << html;
}
}
void tst_Text::tst_disableEmojiParsing()
{
QFETCH(QString, html);
QTextDocument textDocument;
textDocument.setPageSize(QSizeF(800, 600));
textDocument.setHtml(html);
QTextOption opt = textDocument.defaultTextOption();
opt.setFlags(QTextOption::DisableEmojiParsing);
textDocument.setDefaultTextOption(opt);
QImage image(800, 600, QImage::Format_ARGB32);
image.fill(Qt::white);
{
QPainter painter(&image);
QAbstractTextDocumentLayout::PaintContext context;
context.palette.setColor(QPalette::Text, Qt::black);
textDocument.documentLayout()->draw(&painter, context);
}
QBASELINE_CHECK(image, "tst_disableEmojiParsing");
}
QBASELINETEST_MAIN(tst_Text)