Skip to content

Commit

Permalink
Load fonts using QML FontLoader instead of adding to font db
Browse files Browse the repository at this point in the history
This should fix the case for loading fonts via URL in the wasm case.
  • Loading branch information
blammit committed Feb 6, 2024
1 parent d5d65d1 commit b4e37be
Show file tree
Hide file tree
Showing 12 changed files with 55 additions and 77 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ set (VENUS_QML_MODULE_SOURCES
components/ToastNotification.qml
components/Utils.js
components/ValueRange.qml
components/VenusFontLoader.qml
components/VerticalGauge.qml
components/ViewGradient.qml
components/ClassAndVrmInstance.qml
Expand Down
1 change: 1 addition & 0 deletions Global.qml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ QtObject {
property VeQItemTableModel dataServiceModel: null
property var firmwareUpdate

property var fontLoader
property var inputPanel
property var dialogLayer
property var notificationLayer
Expand Down
6 changes: 6 additions & 0 deletions Main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,12 @@ Window {
}
}
}

VenusFontLoader {
id: fontLoader

Component.onCompleted: Global.fontLoader = fontLoader
}
}

FrameRateVisualizer {}
Expand Down
2 changes: 1 addition & 1 deletion components/ControlCard.qml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Rectangle {
display: C.AbstractButton.TextBesideIcon
icon.color: Theme.color_font_primary

font.family: Language.fontFamily
font.family: Global.fontLoader.name
font.pixelSize: Theme.font_size_body1
color: Theme.color_font_primary
}
Expand Down
11 changes: 11 additions & 0 deletions components/VenusFontLoader.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
** Copyright (C) 2023 Victron Energy B.V.
** See LICENSE.txt for license information.
*/

import QtQuick
import Victron.VenusOS

FontLoader {
source: Language.fontFileUrl
}
2 changes: 1 addition & 1 deletion components/controls/Button.qml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ CT.Button {

icon.color: root.color

font.family: Language.fontFamily
font.family: Global.fontLoader.name
font.pixelSize: Theme.font_size_body1
flat: true

Expand Down
2 changes: 1 addition & 1 deletion components/controls/Label.qml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ import Victron.VenusOS

C.Label {
color: Theme.color_font_primary
font.family: Language.fontFamily
font.family: Global.fontLoader.name
font.pixelSize: Theme.font_size_body1
}
2 changes: 1 addition & 1 deletion components/controls/TextField.qml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Victron.VenusOS
CT.TextField {
id: root

font.family: Language.fontFamily
font.family: Global.fontLoader.name
font.pixelSize: Theme.font_size_body2

leftPadding: Theme.geometry_textField_horizontalMargin
Expand Down
4 changes: 2 additions & 2 deletions components/listitems/ListRadioButtonGroup.qml
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ ListNavigationItem {
? !modelData.readOnly
: !model.readOnly)
primaryLabel.font.family: Array.isArray(root.optionModel)
? modelData.fontFamily || Language.fontFamily
: model.fontFamily || Language.fontFamily
? modelData.fontFamily || Global.fontLoader.name
: model.fontFamily || Global.fontLoader.name

visible: (userHasWriteAccess && enabled) || checked
checked: root.currentIndex === model.index
Expand Down
5 changes: 5 additions & 0 deletions pages/settings/PageSettingsDisplay.qml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ Page {
model: languageModel
delegate: FontLoader {
source: model.fontFileUrl
onStatusChanged: {
if (status === FontLoader.Ready) {
languageModel.setFontFamily(source, name)
}
}
}
}

Expand Down
89 changes: 23 additions & 66 deletions src/language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,79 +17,31 @@ using namespace Victron::VenusOS;

namespace {

QString defaultFontFileName()
QUrl fontUrlForLanguage(QLocale::Language language)
{
return QStringLiteral(":/fonts/MuseoSans-500.otf");
}

QString fontFileNameForLanguage(QLocale::Language language)
{
QString fileName;

static const QHash<QLocale::Language, QString> fontFileNames = {
{ QLocale::Arabic, QStringLiteral("DejaVuSans.ttf") },
{ QLocale::Chinese, QStringLiteral("DroidSansFallback.ttf") },
{ QLocale::Thai, QStringLiteral("NotoSansThai.ttf") },
};

#if defined(VENUS_WEBASSEMBLY_BUILD)
// On wasm, the root dir contains symlinks to the required font files.
fileName = fontFileNames.value(language);
// On wasm, the server contains symlinks to the required font files in the root dir.
QString fileName = fontFileNames.value(language);
if (!fileName.isEmpty()) {
fileName = "/" + fileName;
return QUrl("http://127.0.0.1/" + fileName);
}
#elif not defined(VENUS_DESKTOP_BUILD)
// On device, look for the system-installed font files.
fileName = fontFileNames.value(language);
QString fileName = fontFileNames.value(language);
if (!fileName.isEmpty()) {
fileName = "/usr/lib/fonts/" + fileName;
return QUrl::fromLocalFile("/usr/lib/fonts/" + fileName);
}
#else
// On other platforms, use the default font for all languages.
Q_UNUSED(language)
fileName = defaultFontFileName();
#endif

return !fileName.isEmpty() && QFile::exists(fileName) ? fileName : defaultFontFileName();
}

QUrl filePathToUrl(const QString &path)
{
if (path.isEmpty()) {
return QUrl();
}

if (path.startsWith(':')) {
// Convert to QML-friendly "qrc:/" resource path.
return QUrl(QStringLiteral("qrc%1").arg(path));
}

return QUrl::fromLocalFile(path);
}

QString fontFamilyForLanguage(QLocale::Language language)
{
static QHash<QString, int> fontIds;

const QString fontFileName = fontFileNameForLanguage(language);
if (!fontIds.contains(fontFileName)) {
fontIds.insert(fontFileName, QFontDatabase::addApplicationFont(fontFileName));
}

int fontId = fontIds.value(fontFileName, -1);
if (fontId < 0) {
qWarning() << "Fall back to default font, cannot load" << fontFileName << "for locale" << QLocale(language).name();
if (!fontIds.contains(defaultFontFileName())) {
fontIds.insert(fontFileName, QFontDatabase::addApplicationFont(defaultFontFileName()));
}
fontId = fontIds.value(defaultFontFileName(), -1);
if (fontId < 0) {
qWarning() << "Unable to fall back to default font!";
return QString();
}
}

return QFontDatabase::applicationFontFamilies(fontId).value(0);
// Use the default font on other platforms, or if the default font supports this language.
static const QUrl defaultFontUrl = QUrl("qrc:/fonts/MuseoSans-500.otf");
return defaultFontUrl;
}

}
Expand Down Expand Up @@ -168,6 +120,18 @@ int LanguageModel::languageAt(int index) const
return m_languages.at(index).language;
}

void LanguageModel::setFontFamily(const QUrl &fontUrl, const QString &fontFamily)
{
for (int i = 0; i < m_languages.count(); ++i) {
if (m_languages.at(i).fontFileUrl == fontUrl) {
m_languages[i].fontFamily = fontFamily;
static const QList<int> roles = { FontFamilyRole };
emit dataChanged(createIndex(i, 0), createIndex(i, 0), roles);
break;
}
}
}

int LanguageModel::rowCount(const QModelIndex &) const
{
return static_cast<int>(m_languages.count());
Expand Down Expand Up @@ -195,7 +159,7 @@ QVariant LanguageModel::data(const QModelIndex &index, int role) const

void LanguageModel::addLanguage(const QString &name, const QString &code, const QLocale::Language &language)
{
m_languages.append({name, code, filePathToUrl(fontFileNameForLanguage(language)), fontFamilyForLanguage(language), language });
m_languages.append({name, code, fontUrlForLanguage(language), QString(), language });
}

QHash<int, QByteArray> LanguageModel::roleNames() const
Expand Down Expand Up @@ -244,7 +208,6 @@ void Language::setCurrentLanguage(QLocale::Language language)
if (language != m_currentLanguage && installTranslatorForLanguage(language)) {
emit currentLanguageChanged();
emit fontFileUrlChanged();
emit fontFamilyChanged();
}
}

Expand All @@ -253,11 +216,6 @@ QUrl Language::fontFileUrl() const
return m_fontFileUrl;
}

QString Language::fontFamily() const
{
return m_fontFamily;
}

void Language::setCurrentLanguageCode(const QString &code)
{
const QLocale::Language lang = QLocale::codeToLanguage(code);
Expand Down Expand Up @@ -308,8 +266,7 @@ bool Language::installTranslatorForLanguage(QLocale::Language language)
}

m_currentLanguage = language;
m_fontFileUrl = filePathToUrl(fontFileNameForLanguage(language));
m_fontFamily = fontFamilyForLanguage(language);
m_fontFileUrl = fontUrlForLanguage(language);

return true;
}
Expand Down
7 changes: 2 additions & 5 deletions src/language.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class LanguageModel : public QAbstractListModel
QString currentDisplayText() const;

Q_INVOKABLE int languageAt(int index) const;
Q_INVOKABLE void setFontFamily(const QUrl &fontUrl, const QString &fontFamily);

int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Expand Down Expand Up @@ -82,7 +83,6 @@ class Language : public QObject
QML_SINGLETON
Q_PROPERTY(QLocale::Language current READ getCurrentLanguage WRITE setCurrentLanguage NOTIFY currentLanguageChanged FINAL)
Q_PROPERTY(QUrl fontFileUrl READ fontFileUrl NOTIFY fontFileUrlChanged FINAL)
Q_PROPERTY(QString fontFamily READ fontFamily NOTIFY fontFamilyChanged FINAL)

public:
static Language* create(QQmlEngine *engine = nullptr, QJSEngine *jsEngine = nullptr);
Expand All @@ -102,21 +102,18 @@ class Language : public QObject
void setCurrentLanguage(QLocale::Language language);

QUrl fontFileUrl() const;
QString fontFamily() const;

Q_SIGNALS:
void currentLanguageChanged();
void fontFileUrlChanged();
void fontFamilyChanged();

private:
explicit Language(QQmlEngine* engine);
bool installTranslatorForLanguage(QLocale::Language language);

QUrl m_fontFileUrl;
QString m_fontFamily;
QLocale::Language m_currentLanguage = QLocale::AnyLanguage;
QHash<QLocale::Language, QTranslator*> m_loadedTranslators;
QUrl m_fontFileUrl;
};

} /* VenusOS */
Expand Down

0 comments on commit b4e37be

Please sign in to comment.