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>
50 lines
1.5 KiB
C++
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
|