qtbase/src/plugins/platforms/wasm/qwasmfontdatabase.h
Eskil Abrahamsen Blomfeldt 1685070930 Use emoji segmenter to apply emoji fonts automatically
Colorful emojis in Unicode are not isolated to specific ranges
of code points like other writing systems. Instead, there are
a set of rules defining whether a sequence of characters should
be displayed in color or black/white.

    http://www.unicode.org/reports/tr51/

For instance, appending a variation selector to a character can
turn it into a color emoji, even if it is a code point that
predates the invention of emojis.

In addition, sequences of joined characters that are determined
to be a color emoji sequence should be parsed by a single emoji
font, so that it can apply things like skin color, etc.

In general, users expect emojis and emoji sequences to be shown
in the preferred color font of the system, even if a selected
font has black/white characters for the symbols.

This patch applies the emoji segmenter to strings to isolate
sequences that should be in color. As an implementation hack,
we mark this in the QScriptItems as a special "emoji" script.
Note that this is not a real Unicode script and only exists
internally for this reason, because the "emojiness" of the
resulting glyph overrides the original script of the
individual characters when selecting fonts. This way, we can
use a lot of the same logic for itemizing the strings and
looking up fonts, and we don't need to increase the size of
the QScriptItem. (It is just an implementation detail and
is not exposed to the user, so it can be replaced by other
approaches later if we need to.)

When matching an emoji sequence, we always try to apply a
color font and ignore all others. The exception is if there
is no color font at all on the system, then we will find a
black and white font which supports the characters instead
as a final failsafe.

In addition, each platform will put its default emoji font
at the top of the fallbacks list in order to make this the
preference in case there are more than one. This patch also
adds API to override this with an application-defined emoji
font, since this is a common use case.

Note: The font includes an environment variable to disable
the feature as a fail safe. A flag to disable it per QFont
will be added in a follow-up.

Fixes: QTBUG-111801
Change-Id: I9431ec34d56772ab8688814963073b83b23002ae
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
Reviewed-by: <carl@carlschwan.eu>
2024-11-19 16:26:55 +01:00

50 lines
1.5 KiB
C++

// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef QWASMFONTDATABASE_H
#define QWASMFONTDATABASE_H
#include <QtGui/private/qfreetypefontdatabase_p.h>
#include <emscripten/val.h>
QT_BEGIN_NAMESPACE
class QWasmFontDatabase : public QFreeTypeFontDatabase
{
public:
QWasmFontDatabase();
static QWasmFontDatabase *get();
void populateFontDatabase() override;
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QStringList fallbacksForFamily(const QString &family, QFont::Style style,
QFont::StyleHint styleHint,
QFontDatabasePrivate::ExtendedScript script) const override;
void releaseHandle(void *handle) override;
QFont defaultFont() const override;
void populateLocalfonts();
void populateLocalFontFamilies(emscripten::val families);
void populateLocalFontFamilies(const QStringList &famliies, bool allFamilies);
static void beginFontDatabaseStartupTask();
static void endFontDatabaseStartupTask();
static void refFontFileLoading();
static void derefFontFileLoading();
static void endAllFontFileLoading();
private:
bool m_localFontsApiSupported = false;
bool m_queryLocalFontsPermission = false;
enum FontFamilyLoadSet {
NoFontFamilies,
DefaultFontFamilies,
AllFontFamilies,
};
FontFamilyLoadSet m_localFontFamilyLoadSet;
QStringList m_extraLocalFontFamilies;
};
QT_END_NAMESPACE
#endif