Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qohosplatformfontdatabase.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtCore/private/qcore_ohos_p.h>
5#include <QtCore/qfileinfo.h>
6
9#include <QtCore/private/qnapi_p.h>
10#include <fontconfig/fontconfig.h>
11
12using namespace std::string_literals;
13
15
16// Defined in gui/text/qfontdatabase.cpp
17Q_GUI_EXPORT QFontDatabase::WritingSystem qt_writing_system_for_script(int script);
18
19namespace {
20
21using SystemFontType = QtOhosQpa::enums::ohos::graphics::text::SystemFontType;
22
23bool ohosNoUiChildMode = false;
24
25QStringList getAllFontPaths()
26{
27 if (ohosNoUiChildMode)
28 return {};
29
30 auto fontsPaths = QOhosJsThreadGateway::evalWithPromise<std::vector<std::string>>(
31 [](QOhosJsState &jsState, QOhosTaskPromise<std::vector<std::string>> evalPromise) {
32 auto thenCatchPromises = std::move(evalPromise).makeThenCatchBranches(Q_FUNC_INFO);
33 jsState.evalToPromiseOrRejectOnThrow(
34 "@ohos.graphics.text.getSystemFontFullNamesByType(*)",
35 {jsState.mapOhosEnumToJs(SystemFontType::ALL)})
36 .onThen(
37 [thenPromise = std::move(thenCatchPromises.first)](const QOhosCallbackInfo &cbInfo) mutable {
38 auto fontsNamesArray = cbInfo.getFirstArg<QNapi::Array>(Q_FUNC_INFO);
39
40 if (fontsNamesArray.Length() == 0) {
41 thenPromise({});
42 return;
43 }
44
45 auto fontsNames = QNapi::getArrayElements<std::vector<std::string>, QNapi::String>(fontsNamesArray);
46 auto sharedThenPromise = QtOhos::moveToSharedPtr(std::move(thenPromise).makeChained(Q_FUNC_INFO));
47 auto pathsCollector = std::make_shared<QOhosConsumer<std::string>>(
48 [sharedThenPromise, pushSize = fontsNames.size(), result = std::vector<std::string>()](auto element) mutable {
49 result.push_back(std::move(element));
50 if (result.size() == pushSize)
51 (*sharedThenPromise)(std::move(result));
52 });
53
54 for (const auto &fontName : fontsNames) {
55 cbInfo.jsState().evalToPromiseOrRejectOnThrow(
56 "@ohos.graphics.text.getFontDescriptorByFullName(*)",
57 {fontName, cbInfo.jsState().mapOhosEnumToJs(SystemFontType::ALL)})
58 .onThen(
59 [pathsCollector](const QOhosCallbackInfo &cbInfo) {
60 auto fontDescriptor = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
61 auto optFontPath = QNapi::getOptionalPropOrEmpty<QNapi::String>(fontDescriptor, "path");
62 (*pathsCollector)(!optFontPath.IsEmpty() ? optFontPath.Utf8Value() : ""s);
63 })
64 .onCatch(
65 [pathsCollector, fontName](const QOhosCallbackInfo &cbInfo) {
66 QtOhos::logJsCallbackError(
67 cbInfo, ("getFontDescriptorByFullName("s + fontName + ") failed"s).c_str());
68 (*pathsCollector)(""s);
69 });
70 }
71 })
72 .onCatch(
73 [catchPromise = std::move(thenCatchPromises.second)](const QOhosCallbackInfo &cbInfo) {
74 QtOhos::logJsCallbackError(cbInfo, "getSystemFontFullNamesByType() failed");
75 catchPromise({});
76 });
77 },
78 Q_FUNC_INFO);
79
80 QStringList result;
81 std::transform(
82 fontsPaths.begin(), fontsPaths.end(),
83 std::back_inserter(result), QString::fromStdString);
84 result.removeAll(QString());
85 result.sort();
86
87 return result;
88}
89
90std::string getDefaultFontFamily(QOhosJsState &jsState)
91{
92 if (ohosNoUiChildMode)
93 return "";
94
95 std::string defaultFontFamily;
96 auto genericFonts = jsState.eval<QNapi::Array>("@ohos.font.getUIFontConfig().generic");
97 if (genericFonts.Length() > 0) {
98 auto firstFont = QNapi::checkedCast<QNapi::Object>(genericFonts.Get(0U));
99 defaultFontFamily = firstFont.get<QNapi::String>("family");
100 } else {
101 qFatal("Failed to get system default font family name."
102 " The reason is: empty `@ohos.font.getUIFontConfig().generic` array.");
103 }
104
105 return defaultFontFamily;
106}
107
108void registerSystemFonts()
109{
110 QStringList fontPaths = getAllFontPaths();
111 fontPaths.removeDuplicates();
112
113 QSet<QString> uniqueFontDirs;
114 for (const QString &fontPath : fontPaths)
115 uniqueFontDirs.insert(QFileInfo(fontPath).absolutePath());
116
117 FcConfig *config = FcConfigGetCurrent();
118 if (config != nullptr) {
119 for (const QString &dir : uniqueFontDirs)
120 FcConfigAppFontAddDir(config, reinterpret_cast<const FcChar8 *>(dir.toUtf8().constData()));
121 FcConfigBuildFonts(config);
122 } else {
123 qOhosPrintfError("Failed to get fontconfig current configuration.");
124 std::abort();
125 }
126}
127
128}
129
131{
132 ohosNoUiChildMode = true;
133}
134
136{
137 FcInit();
138
139 registerSystemFonts();
140
141 QFontconfigDatabase::populateFontDatabase();
142}
143
145 QFont::Style style,
146 QFont::StyleHint styleHint,
147 QFontDatabasePrivate::ExtendedScript script) const
148{
149 QStringList result;
150
151 const QFontDatabase::WritingSystem ws = qt_writing_system_for_script(script);
152 const bool defaultFontSupportsScript =
153 ws == QFontDatabase::Any ||
154 QFontDatabase::writingSystems(defaultFont().family()).contains(ws);
155
156 if (defaultFontSupportsScript)
157 result.append(defaultFont().family());
158
159 if (styleHint == QFont::Monospace || styleHint == QFont::Courier)
160 result.append(QString::fromUtf8(qgetenv("Droid Sans Mono;Droid Sans;Noto Sans")).split(QLatin1Char(';')));
161 else if (styleHint == QFont::Serif)
162 result.append(QString::fromUtf8(qgetenv("Noto Serif")).split(QLatin1Char(';')));
163 else
164 result.append(QString::fromUtf8(qgetenv("Roboto;Droid Sans")).split(QLatin1Char(';')));
165 result.append(QFontconfigDatabase::fallbacksForFamily(family, style, styleHint, script));
166
167 return result;
168}
169
171{
172 static const char * const preferredDefaultFontFamily = "HarmonyOS Sans SC";
173 static const QString defaultFontFamily =
174 QFontDatabase::families().contains(QLatin1String(preferredDefaultFontFamily))
175 ? QString::fromStdString(preferredDefaultFontFamily)
176 : QOhosJsThreadGateway::eval(
177 [&](auto &jsState) {
178 return QString::fromStdString(getDefaultFontFamily(jsState));
179 },
180 Q_FUNC_INFO);
181 return QFont(defaultFontFamily);
182}
183
184QT_END_NAMESPACE
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QFontDatabasePrivate::ExtendedScript script) const override
Returns a list of alternative fonts for the specified family and style and script using the styleHint...
QFont defaultFont() const override
Returns the default system font.
void populateFontDatabase() override
This function is called once at startup by Qt's internal font database.
QDebug Q_GUI_EXPORT & operator<<(QDebug &s, const QVectorPath &path)