Use native emoji font support on Qt6.9

This commit is contained in:
Nicolas Werner 2025-04-04 14:56:15 +02:00
parent b3026e2978
commit 5cfc8b55e3
No known key found for this signature in database
GPG key ID: C8D75E610773F2D9
3 changed files with 63 additions and 42 deletions

View file

@ -598,9 +598,18 @@ UserSettings::setEmojiFontFamily(QString family)
if (family == emojiFont_)
return;
if (family == tr("Default")) {
emojiFont_ = QStringLiteral("emoji");
#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
if (emojiFont_.isEmpty()) {
QFontDatabase::removeApplicationEmojiFontFamily(emojiFont_);
}
#endif
if (family.isEmpty() || family == QStringLiteral("emoji")) {
emojiFont_.clear();
} else {
#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
QFontDatabase::addApplicationEmojiFontFamily(family);
#endif
emojiFont_ = family;
}
@ -1256,7 +1265,7 @@ UserSettingsModel::data(const QModelIndex &index, int role) const
return data(index, Values).toStringList().indexOf(i->font());
}
case EmojiFont: {
if (i->emojiFont().isEmpty())
if (i->emojiFont().isEmpty() || i->emojiFont() == QLatin1String("emoji"))
return 0;
else
return data(index, Values).toStringList().indexOf(i->emojiFont());
@ -2006,7 +2015,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int
// More special handling for the default font option
auto v = value.toInt();
i->setEmojiFontFamily(
v == 0 ? QStringLiteral("emoji")
v <= 0 ? QString()
: QFontDatabase::families(QFontDatabase::WritingSystem::Symbol).at(v - 1));
return true;
} else

View file

@ -301,52 +301,57 @@ utils::codepointIsEmoji(uint code)
QString
utils::replaceEmoji(const QString &body)
{
QString fmtBody;
fmtBody.reserve(body.size());
if constexpr (QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)) {
return body;
} else {
QString fmtBody;
fmtBody.reserve(body.size());
QVector<uint> utf32_string = body.toUcs4();
QVector<uint> utf32_string = body.toUcs4();
bool insideFontBlock = false;
bool insideTag = false;
for (auto &code : utf32_string) {
if (code == U'<')
insideTag = true;
else if (code == U'>')
insideTag = false;
bool insideFontBlock = false;
bool insideTag = false;
for (auto &code : utf32_string) {
if (code == U'<')
insideTag = true;
else if (code == U'>')
insideTag = false;
if (!insideTag && utils::codepointIsEmoji(code)) {
if (!insideFontBlock) {
fmtBody += QStringLiteral("<font face=\"") % UserSettings::instance()->emojiFont() %
(UserSettings::instance()->enlargeEmojiOnlyMessages()
? QStringLiteral("\" size=\"4\">")
: QStringLiteral("\">"));
insideFontBlock = true;
} else if (code == 0xfe0f) {
// BUG(Nico):
// Workaround https://bugreports.qt.io/browse/QTBUG-97401
// See also https://github.com/matrix-org/matrix-react-sdk/pull/1458/files
// Nheko bug: https://github.com/Nheko-Reborn/nheko/issues/439
continue;
if (!insideTag && utils::codepointIsEmoji(code)) {
if (!insideFontBlock) {
fmtBody += QStringLiteral("<font face=\"") %
UserSettings::instance()->emojiFont() %
(UserSettings::instance()->enlargeEmojiOnlyMessages()
? QStringLiteral("\" size=\"4\">")
: QStringLiteral("\">"));
insideFontBlock = true;
} else if (code == 0xfe0f) {
// BUG(Nico):
// Workaround https://bugreports.qt.io/browse/QTBUG-97401
// See also https://github.com/matrix-org/matrix-react-sdk/pull/1458/files
// Nheko bug: https://github.com/Nheko-Reborn/nheko/issues/439
continue;
}
} else {
if (insideFontBlock) {
fmtBody += QStringLiteral("</font>");
insideFontBlock = false;
}
}
} else {
if (insideFontBlock) {
fmtBody += QStringLiteral("</font>");
insideFontBlock = false;
if (QChar::requiresSurrogates(code)) {
QChar emoji[] = {static_cast<ushort>(QChar::highSurrogate(code)),
static_cast<ushort>(QChar::lowSurrogate(code))};
fmtBody.append(emoji, 2);
} else {
fmtBody.append(QChar(static_cast<ushort>(code)));
}
}
if (QChar::requiresSurrogates(code)) {
QChar emoji[] = {static_cast<ushort>(QChar::highSurrogate(code)),
static_cast<ushort>(QChar::lowSurrogate(code))};
fmtBody.append(emoji, 2);
} else {
fmtBody.append(QChar(static_cast<ushort>(code)));
if (insideFontBlock) {
fmtBody += QStringLiteral("</font>");
}
}
if (insideFontBlock) {
fmtBody += QStringLiteral("</font>");
}
return fmtBody;
return fmtBody;
}
}
void

View file

@ -373,6 +373,13 @@ main(int argc, char *argv[])
font.setPointSizeF(settings.lock()->fontSize());
app.setFont(font);
#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
if (auto emojiFont = settings.lock()->emojiFont(); !emojiFont.isEmpty()) {
QFontDatabase::addApplicationEmojiFontFamily(emojiFont);
}
#endif
settings.lock()->applyTheme();
if (QLocale().language() == QLocale::C)