1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/common/font_manager.h"
17
18 #include "base/i18n/localization.h"
19 #include "core/components/text/render_text.h"
20 #include "core/components_ng/base/frame_node.h"
21 #ifdef ENABLE_ROSEN_BACKEND
22 #ifdef TEXGINE_SUPPORT_FOR_OHOS
23 #include "foundation/graphic/graphic_2d/rosen/modules/texgine/src/font_config.h"
24 #include "foundation/graphic/graphic_2d/rosen/modules/texgine/src/font_parser.h"
25 #endif
26 #endif
27 #ifdef USE_PLATFORM_FONT
28 #include "core/common/font/font_platform_proxy.h"
29 #endif
30
31 namespace OHOS::Ace {
32
33 std::string FontManager::appCustomFont_ = "";
34 float FontManager::fontWeightScale_ = 1.0f;
35 bool FontManager::isDefaultFontChanged_ = false;
36
RegisterFont(const std::string & familyName,const std::string & familySrc,const RefPtr<PipelineBase> & context,const std::string & bundleName,const std::string & moduleName)37 void FontManager::RegisterFont(const std::string& familyName, const std::string& familySrc,
38 const RefPtr<PipelineBase>& context, const std::string& bundleName, const std::string& moduleName)
39 {
40 if (std::find(std::begin(fontNames_), std::end(fontNames_), familyName) == std::end(fontNames_)) {
41 fontNames_.emplace_back(familyName);
42 }
43
44 for (auto iter = fontLoaders_.begin(); iter != fontLoaders_.end(); ++iter) {
45 auto& fontLoader = *iter;
46 if (fontLoader->GetFamilyName() == familyName) {
47 return;
48 }
49 }
50 RefPtr<FontLoader> fontLoader = FontLoader::Create(familyName, familySrc);
51 fontLoaders_.emplace_back(fontLoader);
52 fontLoader->AddFont(context, bundleName, moduleName);
53
54 fontLoader->SetVariationChanged([weak = WeakClaim(this), familyName]() {
55 auto fontManager = weak.Upgrade();
56 CHECK_NULL_VOID(fontManager);
57 fontManager->VaryFontCollectionWithFontWeightScale();
58 });
59 }
60
SetFontFamily(const char * familyName,const char * familySrc)61 void FontManager::SetFontFamily(const char* familyName, const char* familySrc)
62 {
63 RefPtr<FontLoader> fontLoader = FontLoader::Create(familyName, familySrc);
64 fontLoader->SetDefaultFontFamily(familyName, familySrc);
65 }
66
IsDefaultFontChanged()67 bool FontManager::IsDefaultFontChanged()
68 {
69 // For AutoUI Test,render Text with High precision
70 if (SystemProperties::GetDebugAutoUIEnabled()) {
71 isDefaultFontChanged_ = true;
72 }
73 return isDefaultFontChanged_;
74 }
75
IsUseAppCustomFont() const76 bool FontManager::IsUseAppCustomFont() const
77 {
78 return !appCustomFont_.empty();
79 }
80
SetAppCustomFont(const std::string & familyName)81 void FontManager::SetAppCustomFont(const std::string& familyName)
82 {
83 appCustomFont_ = familyName;
84 }
85
GetAppCustomFont() const86 const std::string& FontManager::GetAppCustomFont() const
87 {
88 return appCustomFont_;
89 }
90
GetSystemFontList(std::vector<std::string> & fontList)91 void FontManager::GetSystemFontList(std::vector<std::string>& fontList)
92 {
93 #ifdef USE_PLATFORM_FONT
94 auto fontPlatform = FontPlatformProxy::GetInstance().GetFontPlatform();
95 if (fontPlatform) {
96 fontPlatform->GetSystemFontList(fontList);
97 }
98 #else
99 #ifdef ENABLE_ROSEN_BACKEND
100 #ifdef TEXGINE_SUPPORT_FOR_OHOS
101 Rosen::TextEngine::FontParser fontParser;
102 std::vector<Rosen::TextEngine::FontParser::FontDescriptor> systemFontList;
103 auto locale = Localization::GetInstance()->GetFontLocale();
104 systemFontList = fontParser.GetVisibilityFonts(locale);
105 for (size_t i = 0; i < systemFontList.size(); ++i) {
106 std::string fontName = systemFontList[i].fullName;
107 fontList.emplace_back(fontName);
108 }
109 #endif
110 #endif
111 #endif
112 }
113
GetUIFontConfig(FontConfigJsonInfo & info)114 void FontManager::GetUIFontConfig(FontConfigJsonInfo& info)
115 {
116 #ifdef ENABLE_ROSEN_BACKEND
117 #ifdef TEXGINE_SUPPORT_FOR_OHOS
118 Rosen::TextEngine::FontConfigJson fontConfigJson;
119 fontConfigJson.ParseFile();
120 auto rosenInfo = fontConfigJson.GetFontConfigJsonInfo();
121 // rosenInfo to FontConfigJsonInfo
122 for (size_t i = 0; i < rosenInfo->fontDirSet.size(); ++i) {
123 info.fontDirSet.emplace_back(rosenInfo->fontDirSet[i]);
124 }
125 for (size_t i = 0; i < rosenInfo->genericSet.size(); ++i) {
126 FontGenericInfo genericInfo;
127 genericInfo.familyName = rosenInfo->genericSet[i].familyName;
128 for (size_t j = 0; j < rosenInfo->genericSet[i].aliasSet.size(); ++j) {
129 AliasInfo aliasInfo;
130 aliasInfo.familyName = rosenInfo->genericSet[i].aliasSet[j].familyName;
131 aliasInfo.weight = rosenInfo->genericSet[i].aliasSet[j].weight;
132 genericInfo.aliasSet.emplace_back(aliasInfo);
133 }
134 for (size_t j = 0; j < rosenInfo->genericSet[i].adjustSet.size(); ++j) {
135 AdjustInfo adjustInfo;
136 adjustInfo.origValue = rosenInfo->genericSet[i].adjustSet[j].origValue;
137 adjustInfo.newValue = rosenInfo->genericSet[i].adjustSet[j].newValue;
138 genericInfo.adjustSet.emplace_back(adjustInfo);
139 }
140 info.genericSet.emplace_back(genericInfo);
141 }
142 for (size_t i = 0; i < rosenInfo->fallbackGroupSet.size(); ++i) {
143 FallbackGroup fallbackGroupInfo;
144 fallbackGroupInfo.groupName = rosenInfo->fallbackGroupSet[i].groupName;
145 for (size_t j = 0; j < rosenInfo->fallbackGroupSet[i].fallbackInfoSet.size(); ++j) {
146 FallbackInfo fallbackInfo;
147 fallbackInfo.familyName = rosenInfo->fallbackGroupSet[i].fallbackInfoSet[j].familyName;
148 fallbackInfo.font = rosenInfo->fallbackGroupSet[i].fallbackInfoSet[j].font;
149 fallbackGroupInfo.fallbackInfoSet.emplace_back(fallbackInfo);
150 }
151 info.fallbackGroupSet.emplace_back(fallbackGroupInfo);
152 }
153 #endif
154 #endif
155 }
156
GetSystemFont(const std::string & fontName,FontInfo & fontInfo)157 bool FontManager::GetSystemFont(const std::string& fontName, FontInfo& fontInfo)
158 {
159 bool isGetFont = false;
160 #ifdef USE_PLATFORM_FONT
161 auto fontPlatform = FontPlatformProxy::GetInstance().GetFontPlatform();
162 if (fontPlatform) {
163 isGetFont = fontPlatform->GetSystemFont(fontName, fontInfo);
164 }
165 #else
166 #ifdef ENABLE_ROSEN_BACKEND
167 #ifdef TEXGINE_SUPPORT_FOR_OHOS
168 Rosen::TextEngine::FontParser fontParser;
169 std::unique_ptr<Rosen::TextEngine::FontParser::FontDescriptor> systemFontDesc;
170 auto locale = Localization::GetInstance()->GetFontLocale();
171 systemFontDesc = fontParser.GetVisibilityFontByName(fontName, locale);
172 CHECK_NULL_RETURN(systemFontDesc, false);
173 if (fontName == systemFontDesc->fullName) {
174 fontInfo.path = systemFontDesc->path;
175 fontInfo.postScriptName = systemFontDesc->postScriptName;
176 fontInfo.fullName = systemFontDesc->fullName;
177 fontInfo.family = systemFontDesc->fontFamily;
178 fontInfo.subfamily = systemFontDesc->fontSubfamily;
179 fontInfo.weight = static_cast<uint32_t>(systemFontDesc->weight);
180 fontInfo.width = static_cast<uint32_t>(systemFontDesc->width);
181 fontInfo.italic = systemFontDesc->italic;
182 fontInfo.monoSpace = systemFontDesc->monoSpace;
183 fontInfo.symbolic = systemFontDesc->symbolic;
184 isGetFont = true;
185 }
186 #endif
187 #endif
188 #endif
189 return isGetFont;
190 }
191
RegisterCallback(const WeakPtr<RenderNode> & node,const std::string & familyName,const std::function<void ()> & callback)192 bool FontManager::RegisterCallback(
193 const WeakPtr<RenderNode>& node, const std::string& familyName, const std::function<void()>& callback)
194 {
195 CHECK_NULL_RETURN(callback, false);
196 for (auto& fontLoader : fontLoaders_) {
197 if (fontLoader->GetFamilyName() == familyName) {
198 fontLoader->SetOnLoaded(node, callback);
199 }
200 }
201 return false;
202 }
203
GetFontNames() const204 const std::vector<std::string>& FontManager::GetFontNames() const
205 {
206 return fontNames_;
207 }
208
AddFontNode(const WeakPtr<RenderNode> & node)209 void FontManager::AddFontNode(const WeakPtr<RenderNode>& node)
210 {
211 if (fontNodes_.find(node) == fontNodes_.end()) {
212 fontNodes_.emplace(node);
213 }
214 }
215
RemoveFontNode(const WeakPtr<RenderNode> & node)216 void FontManager::RemoveFontNode(const WeakPtr<RenderNode>& node)
217 {
218 fontNodes_.erase(node);
219 }
220
RebuildFontNode()221 void FontManager::RebuildFontNode()
222 {
223 #ifndef NG_BUILD
224 for (auto iter = fontNodes_.begin(); iter != fontNodes_.end();) {
225 auto fontNode = iter->Upgrade();
226 CHECK_NULL_VOID(fontNode);
227 auto renderNode = DynamicCast<RenderNode>(fontNode);
228 if (renderNode) {
229 renderNode->MarkNeedLayout();
230 ++iter;
231 } else {
232 iter = fontNodes_.erase(iter);
233 }
234 }
235 #else
236 for (auto iter = fontNodesNG_.begin(); iter != fontNodesNG_.end();) {
237 auto fontNode = iter->Upgrade();
238 CHECK_NULL_VOID(fontNode);
239 auto uiNode = DynamicCast<NG::UINode>(fontNode);
240 if (uiNode) {
241 uiNode->MarkDirtyNode(NG::PROPERTY_UPDATE_LAYOUT);
242 ++iter;
243 } else {
244 iter = fontNodesNG_.erase(iter);
245 }
246 }
247 #endif
248 }
249
UnRegisterCallback(const WeakPtr<RenderNode> & node)250 void FontManager::UnRegisterCallback(const WeakPtr<RenderNode>& node)
251 {
252 for (auto& fontLoader : fontLoaders_) {
253 fontLoader->RemoveCallback(node);
254 }
255 }
256
RebuildFontNodeNG()257 void FontManager::RebuildFontNodeNG()
258 {
259 for (auto iter = fontNodesNG_.begin(); iter != fontNodesNG_.end();) {
260 auto fontNode = iter->Upgrade();
261 CHECK_NULL_VOID(fontNode);
262 auto uiNode = DynamicCast<NG::UINode>(fontNode);
263 if (uiNode) {
264 uiNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
265 ++iter;
266 } else {
267 iter = fontNodesNG_.erase(iter);
268 }
269 }
270 for (auto iter = observers_.begin(); iter != observers_.end();) {
271 auto fontNode = iter->Upgrade();
272 CHECK_NULL_VOID(fontNode);
273 if (fontNode) {
274 fontNode->OnFontChanged();
275 ++iter;
276 } else {
277 iter = observers_.erase(iter);
278 }
279 }
280 }
281
UpdateFontWeightScale()282 void FontManager::UpdateFontWeightScale()
283 {
284 float fontWeightScale = SystemProperties::GetFontWeightScale();
285 if (!NearEqual(fontWeightScale, fontWeightScale_)) {
286 fontWeightScale_ = fontWeightScale;
287 VaryFontCollectionWithFontWeightScale();
288 }
289 }
290
AddVariationNode(const WeakPtr<RenderNode> & node)291 void FontManager::AddVariationNode(const WeakPtr<RenderNode>& node)
292 {
293 if (variationNodes_.find(node) == variationNodes_.end()) {
294 variationNodes_.emplace(node);
295 }
296 }
297
RemoveVariationNode(const WeakPtr<RenderNode> & node)298 void FontManager::RemoveVariationNode(const WeakPtr<RenderNode>& node)
299 {
300 variationNodes_.erase(node);
301 }
302
NotifyVariationNodes()303 void FontManager::NotifyVariationNodes()
304 {
305 #ifndef NG_BUILD
306 for (const auto& node : variationNodes_) {
307 auto refNode = node.Upgrade();
308 CHECK_NULL_VOID(refNode);
309 auto renderNode = DynamicCast<RenderNode>(refNode);
310 CHECK_NULL_VOID(renderNode);
311 auto text = DynamicCast<RenderText>(renderNode);
312 if (text) {
313 text->MarkNeedMeasure();
314 }
315 renderNode->MarkNeedLayout();
316 }
317 #else
318 for (const auto& node : variationNodesNG_) {
319 auto uiNode = node.Upgrade();
320 CHECK_NULL_VOID(uiNode);
321 auto frameNode = DynamicCast<NG::FrameNode>(uiNode);
322 if (frameNode) {
323 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
324 }
325 uiNode->MarkDirtyNode(NG::PROPERTY_UPDATE_LAYOUT);
326 }
327 #endif
328 }
329
RegisterCallbackNG(const WeakPtr<NG::UINode> & node,const std::string & familyName,const std::function<void ()> & callback)330 bool FontManager::RegisterCallbackNG(
331 const WeakPtr<NG::UINode>& node, const std::string& familyName, const std::function<void()>& callback)
332 {
333 CHECK_NULL_RETURN(callback, false);
334 for (auto& fontLoader : fontLoaders_) {
335 if (fontLoader->GetFamilyName() == familyName) {
336 fontLoader->SetOnLoadedNG(node, callback);
337 }
338 }
339 return false;
340 }
341
AddFontNodeNG(const WeakPtr<NG::UINode> & node)342 void FontManager::AddFontNodeNG(const WeakPtr<NG::UINode>& node)
343 {
344 if (fontNodesNG_.find(node) == fontNodesNG_.end()) {
345 fontNodesNG_.emplace(node);
346 }
347 }
348
RemoveFontNodeNG(const WeakPtr<NG::UINode> & node)349 void FontManager::RemoveFontNodeNG(const WeakPtr<NG::UINode>& node)
350 {
351 fontNodesNG_.erase(node);
352 }
353
UnRegisterCallbackNG(const WeakPtr<NG::UINode> & node)354 void FontManager::UnRegisterCallbackNG(const WeakPtr<NG::UINode>& node)
355 {
356 for (auto& fontLoader : fontLoaders_) {
357 fontLoader->RemoveCallbackNG(node);
358 }
359 }
360
AddVariationNodeNG(const WeakPtr<NG::UINode> & node)361 void FontManager::AddVariationNodeNG(const WeakPtr<NG::UINode>& node)
362 {
363 if (variationNodesNG_.find(node) == variationNodesNG_.end()) {
364 variationNodesNG_.emplace(node);
365 }
366 }
367
RemoveVariationNodeNG(const WeakPtr<NG::UINode> & node)368 void FontManager::RemoveVariationNodeNG(const WeakPtr<NG::UINode>& node)
369 {
370 variationNodesNG_.erase(node);
371 }
372
AddFontObserver(WeakPtr<FontChangeObserver> node)373 void FontManager::AddFontObserver(WeakPtr<FontChangeObserver> node)
374 {
375 if (observers_.find(node) == observers_.end()) {
376 observers_.emplace(node);
377 }
378 }
379
RemoveFontChangeObserver(WeakPtr<FontChangeObserver> node)380 void FontManager::RemoveFontChangeObserver(WeakPtr<FontChangeObserver> node)
381 {
382 observers_.erase(node);
383 }
384
385 } // namespace OHOS::Ace
386