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 "texgine/src/font_config.h"
24 #include "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 TAG_LOGI(AceLogTag::ACE_FONT,
53 "RegisterFont "
54 "[familyName:%{public}s],[familySrc:%{public}s],[bundleName:%{public}s],[moduleName:%{public}s]",
55 familyName.c_str(), familySrc.c_str(), bundleName.c_str(), moduleName.c_str());
56 fontLoader->AddFont(context, bundleName, moduleName);
57
58 fontLoader->SetVariationChanged([weak = WeakClaim(this), familyName]() {
59 auto fontManager = weak.Upgrade();
60 CHECK_NULL_VOID(fontManager);
61 fontManager->VaryFontCollectionWithFontWeightScale();
62 });
63 }
64
SetFontFamily(const char * familyName,const std::vector<std::string> & familySrc)65 void FontManager::SetFontFamily(const char* familyName, const std::vector<std::string>& familySrc)
66 {
67 RefPtr<FontLoader> fontLoader = FontLoader::CreateFontLoader(familyName, familySrc);
68 CHECK_NULL_VOID(fontLoader);
69 fontLoader->SetDefaultFontFamily(familyName, familySrc);
70 FontNodeChangeStyleNG();
71 }
72
IsDefaultFontChanged()73 bool FontManager::IsDefaultFontChanged()
74 {
75 // For AutoUI Test,render Text with High precision
76 if (SystemProperties::GetDebugAutoUIEnabled()) {
77 isDefaultFontChanged_ = true;
78 }
79 return isDefaultFontChanged_;
80 }
81
IsUseAppCustomFont() const82 bool FontManager::IsUseAppCustomFont() const
83 {
84 return !appCustomFont_.empty();
85 }
86
SetAppCustomFont(const std::string & familyName)87 void FontManager::SetAppCustomFont(const std::string& familyName)
88 {
89 appCustomFont_ = familyName;
90 }
91
GetAppCustomFont() const92 const std::string& FontManager::GetAppCustomFont() const
93 {
94 return appCustomFont_;
95 }
96
GetSystemFontList(std::vector<std::string> & fontList)97 void FontManager::GetSystemFontList(std::vector<std::string>& fontList)
98 {
99 #ifdef USE_PLATFORM_FONT
100 auto fontPlatform = FontPlatformProxy::GetInstance().GetFontPlatform();
101 if (fontPlatform) {
102 fontPlatform->GetSystemFontList(fontList);
103 }
104 #else
105 #ifdef ENABLE_ROSEN_BACKEND
106 #ifdef TEXGINE_SUPPORT_FOR_OHOS
107 Rosen::TextEngine::FontParser fontParser;
108 std::vector<Rosen::TextEngine::FontParser::FontDescriptor> systemFontList;
109 auto locale = Localization::GetInstance()->GetFontLocale();
110 systemFontList = fontParser.GetVisibilityFonts(locale);
111 for (size_t i = 0; i < systemFontList.size(); ++i) {
112 std::string fontName = systemFontList[i].fullName;
113 fontList.emplace_back(fontName);
114 }
115 #endif
116 #endif
117 #endif
118 }
119
GetUIFontConfig(FontConfigJsonInfo & info)120 void FontManager::GetUIFontConfig(FontConfigJsonInfo& info)
121 {
122 #ifdef ENABLE_ROSEN_BACKEND
123 #ifdef TEXGINE_SUPPORT_FOR_OHOS
124 Rosen::TextEngine::FontConfigJson fontConfigJson;
125 fontConfigJson.ParseFile();
126 auto rosenInfo = fontConfigJson.GetFontConfigJsonInfo();
127 // rosenInfo to FontConfigJsonInfo
128 for (size_t i = 0; i < rosenInfo->fontDirSet.size(); ++i) {
129 info.fontDirSet.emplace_back(rosenInfo->fontDirSet[i]);
130 }
131 for (size_t i = 0; i < rosenInfo->genericSet.size(); ++i) {
132 FontGenericInfo genericInfo;
133 genericInfo.familyName = rosenInfo->genericSet[i].familyName;
134 for (size_t j = 0; j < rosenInfo->genericSet[i].aliasSet.size(); ++j) {
135 AliasInfo aliasInfo;
136 aliasInfo.familyName = rosenInfo->genericSet[i].aliasSet[j].familyName;
137 aliasInfo.weight = rosenInfo->genericSet[i].aliasSet[j].weight;
138 genericInfo.aliasSet.emplace_back(aliasInfo);
139 }
140 for (size_t j = 0; j < rosenInfo->genericSet[i].adjustSet.size(); ++j) {
141 AdjustInfo adjustInfo;
142 adjustInfo.origValue = rosenInfo->genericSet[i].adjustSet[j].origValue;
143 adjustInfo.newValue = rosenInfo->genericSet[i].adjustSet[j].newValue;
144 genericInfo.adjustSet.emplace_back(adjustInfo);
145 }
146 info.genericSet.emplace_back(genericInfo);
147 }
148 for (size_t i = 0; i < rosenInfo->fallbackGroupSet.size(); ++i) {
149 FallbackGroup fallbackGroupInfo;
150 fallbackGroupInfo.groupName = rosenInfo->fallbackGroupSet[i].groupName;
151 for (size_t j = 0; j < rosenInfo->fallbackGroupSet[i].fallbackInfoSet.size(); ++j) {
152 FallbackInfo fallbackInfo;
153 fallbackInfo.familyName = rosenInfo->fallbackGroupSet[i].fallbackInfoSet[j].familyName;
154 fallbackInfo.font = rosenInfo->fallbackGroupSet[i].fallbackInfoSet[j].font;
155 fallbackGroupInfo.fallbackInfoSet.emplace_back(fallbackInfo);
156 }
157 info.fallbackGroupSet.emplace_back(fallbackGroupInfo);
158 }
159 #endif
160 #endif
161 }
162
GetSystemFont(const std::string & fontName,FontInfo & fontInfo)163 bool FontManager::GetSystemFont(const std::string& fontName, FontInfo& fontInfo)
164 {
165 bool isGetFont = false;
166 #ifdef USE_PLATFORM_FONT
167 auto fontPlatform = FontPlatformProxy::GetInstance().GetFontPlatform();
168 if (fontPlatform) {
169 isGetFont = fontPlatform->GetSystemFont(fontName, fontInfo);
170 }
171 #else
172 #ifdef ENABLE_ROSEN_BACKEND
173 #ifdef TEXGINE_SUPPORT_FOR_OHOS
174 Rosen::TextEngine::FontParser fontParser;
175 std::unique_ptr<Rosen::TextEngine::FontParser::FontDescriptor> systemFontDesc;
176 auto locale = Localization::GetInstance()->GetFontLocale();
177 systemFontDesc = fontParser.GetVisibilityFontByName(fontName, locale);
178 CHECK_NULL_RETURN(systemFontDesc, false);
179 if (fontName == systemFontDesc->fullName) {
180 fontInfo.path = systemFontDesc->path;
181 fontInfo.postScriptName = systemFontDesc->postScriptName;
182 fontInfo.fullName = systemFontDesc->fullName;
183 fontInfo.family = systemFontDesc->fontFamily;
184 fontInfo.subfamily = systemFontDesc->fontSubfamily;
185 fontInfo.weight = static_cast<uint32_t>(systemFontDesc->weight);
186 fontInfo.width = static_cast<uint32_t>(systemFontDesc->width);
187 fontInfo.italic = systemFontDesc->italic;
188 fontInfo.monoSpace = systemFontDesc->monoSpace;
189 fontInfo.symbolic = systemFontDesc->symbolic;
190 isGetFont = true;
191 }
192 #endif
193 #endif
194 #endif
195 return isGetFont;
196 }
197
RegisterCallback(const WeakPtr<RenderNode> & node,const std::string & familyName,const std::function<void ()> & callback)198 bool FontManager::RegisterCallback(
199 const WeakPtr<RenderNode>& node, const std::string& familyName, const std::function<void()>& callback)
200 {
201 CHECK_NULL_RETURN(callback, false);
202 for (auto& fontLoader : fontLoaders_) {
203 if (fontLoader->GetFamilyName() == familyName) {
204 fontLoader->SetOnLoaded(node, callback);
205 }
206 }
207 return false;
208 }
209
GetFontNames() const210 const std::vector<std::string>& FontManager::GetFontNames() const
211 {
212 return fontNames_;
213 }
214
AddFontNode(const WeakPtr<RenderNode> & node)215 void FontManager::AddFontNode(const WeakPtr<RenderNode>& node)
216 {
217 if (fontNodes_.find(node) == fontNodes_.end()) {
218 fontNodes_.emplace(node);
219 }
220 }
221
RemoveFontNode(const WeakPtr<RenderNode> & node)222 void FontManager::RemoveFontNode(const WeakPtr<RenderNode>& node)
223 {
224 fontNodes_.erase(node);
225 }
226
RebuildFontNode()227 void FontManager::RebuildFontNode()
228 {
229 #ifndef NG_BUILD
230 for (auto iter = fontNodes_.begin(); iter != fontNodes_.end();) {
231 auto fontNode = iter->Upgrade();
232 CHECK_NULL_VOID(fontNode);
233 auto renderNode = DynamicCast<RenderNode>(fontNode);
234 if (renderNode) {
235 renderNode->MarkNeedLayout();
236 ++iter;
237 } else {
238 iter = fontNodes_.erase(iter);
239 }
240 }
241 #else
242 for (auto iter = fontNodesNG_.begin(); iter != fontNodesNG_.end();) {
243 auto fontNode = iter->Upgrade();
244 CHECK_NULL_VOID(fontNode);
245 auto uiNode = DynamicCast<NG::UINode>(fontNode);
246 if (uiNode) {
247 uiNode->MarkDirtyNode(NG::PROPERTY_UPDATE_LAYOUT);
248 ++iter;
249 } else {
250 iter = fontNodesNG_.erase(iter);
251 }
252 }
253 #endif
254 }
255
UnRegisterCallback(const WeakPtr<RenderNode> & node)256 void FontManager::UnRegisterCallback(const WeakPtr<RenderNode>& node)
257 {
258 for (auto& fontLoader : fontLoaders_) {
259 fontLoader->RemoveCallback(node);
260 }
261 }
262
FontNodeChangeStyleNG()263 void FontManager::FontNodeChangeStyleNG()
264 {
265 for (auto iter = fontNodesNG_.begin(); iter != fontNodesNG_.end();) {
266 auto fontNode = iter->Upgrade();
267 CHECK_NULL_VOID(fontNode);
268 auto frameNode = DynamicCast<NG::FrameNode>(fontNode);
269 if (frameNode) {
270 frameNode->OnPropertyChangeMeasure();
271 }
272 ++iter;
273 }
274 }
275
RebuildFontNodeNG()276 void FontManager::RebuildFontNodeNG()
277 {
278 for (auto iter = fontNodesNG_.begin(); iter != fontNodesNG_.end();) {
279 auto fontNode = iter->Upgrade();
280 if (!fontNode) {
281 iter = fontNodesNG_.erase(iter);
282 continue;
283 }
284 auto uiNode = DynamicCast<NG::UINode>(fontNode);
285 if (uiNode) {
286 uiNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
287 auto frameNode = DynamicCast<NG::FrameNode>(fontNode);
288 if (frameNode) {
289 frameNode->OnPropertyChangeMeasure();
290 }
291 ++iter;
292 } else {
293 iter = fontNodesNG_.erase(iter);
294 }
295 }
296 for (auto iter = observers_.begin(); iter != observers_.end();) {
297 auto fontNode = iter->Upgrade();
298 if (fontNode) {
299 fontNode->OnFontChanged();
300 ++iter;
301 } else {
302 iter = observers_.erase(iter);
303 }
304 }
305 }
306
UpdateFontWeightScale()307 void FontManager::UpdateFontWeightScale()
308 {
309 float fontWeightScale = SystemProperties::GetFontWeightScale();
310 if (!NearEqual(fontWeightScale, fontWeightScale_)) {
311 fontWeightScale_ = fontWeightScale;
312 VaryFontCollectionWithFontWeightScale();
313 }
314 }
315
AddVariationNode(const WeakPtr<RenderNode> & node)316 void FontManager::AddVariationNode(const WeakPtr<RenderNode>& node)
317 {
318 if (variationNodes_.find(node) == variationNodes_.end()) {
319 variationNodes_.emplace(node);
320 }
321 }
322
RemoveVariationNode(const WeakPtr<RenderNode> & node)323 void FontManager::RemoveVariationNode(const WeakPtr<RenderNode>& node)
324 {
325 variationNodes_.erase(node);
326 }
327
NotifyVariationNodes()328 void FontManager::NotifyVariationNodes()
329 {
330 #ifndef NG_BUILD
331 for (const auto& node : variationNodes_) {
332 auto refNode = node.Upgrade();
333 CHECK_NULL_VOID(refNode);
334 auto renderNode = DynamicCast<RenderNode>(refNode);
335 CHECK_NULL_VOID(renderNode);
336 auto text = DynamicCast<RenderText>(renderNode);
337 if (text) {
338 text->MarkNeedMeasure();
339 }
340 renderNode->MarkNeedLayout();
341 }
342 #else
343 for (const auto& node : variationNodesNG_) {
344 auto uiNode = node.Upgrade();
345 CHECK_NULL_VOID(uiNode);
346 auto frameNode = DynamicCast<NG::FrameNode>(uiNode);
347 if (frameNode) {
348 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
349 }
350 uiNode->MarkDirtyNode(NG::PROPERTY_UPDATE_LAYOUT);
351 }
352 #endif
353 }
354
RegisterCallbackNG(const WeakPtr<NG::UINode> & node,const std::string & familyName,const std::function<void ()> & callback)355 bool FontManager::RegisterCallbackNG(
356 const WeakPtr<NG::UINode>& node, const std::string& familyName, const std::function<void()>& callback)
357 {
358 CHECK_NULL_RETURN(callback, false);
359 for (auto& fontLoader : fontLoaders_) {
360 if (fontLoader->GetFamilyName() == familyName) {
361 fontLoader->SetOnLoadedNG(node, callback);
362 }
363 }
364 return false;
365 }
366
AddFontNodeNG(const WeakPtr<NG::UINode> & node)367 void FontManager::AddFontNodeNG(const WeakPtr<NG::UINode>& node)
368 {
369 if (fontNodesNG_.find(node) == fontNodesNG_.end()) {
370 fontNodesNG_.emplace(node);
371 }
372 }
373
RemoveFontNodeNG(const WeakPtr<NG::UINode> & node)374 void FontManager::RemoveFontNodeNG(const WeakPtr<NG::UINode>& node)
375 {
376 fontNodesNG_.erase(node);
377 }
378
UnRegisterCallbackNG(const WeakPtr<NG::UINode> & node)379 void FontManager::UnRegisterCallbackNG(const WeakPtr<NG::UINode>& node)
380 {
381 for (auto& fontLoader : fontLoaders_) {
382 fontLoader->RemoveCallbackNG(node);
383 }
384 }
385
AddVariationNodeNG(const WeakPtr<NG::UINode> & node)386 void FontManager::AddVariationNodeNG(const WeakPtr<NG::UINode>& node)
387 {
388 if (variationNodesNG_.find(node) == variationNodesNG_.end()) {
389 variationNodesNG_.emplace(node);
390 }
391 }
392
RemoveVariationNodeNG(const WeakPtr<NG::UINode> & node)393 void FontManager::RemoveVariationNodeNG(const WeakPtr<NG::UINode>& node)
394 {
395 variationNodesNG_.erase(node);
396 }
397
AddFontObserver(WeakPtr<FontChangeObserver> node)398 void FontManager::AddFontObserver(WeakPtr<FontChangeObserver> node)
399 {
400 if (observers_.find(node) == observers_.end()) {
401 observers_.emplace(node);
402 }
403 }
404
RemoveFontChangeObserver(WeakPtr<FontChangeObserver> node)405 void FontManager::RemoveFontChangeObserver(WeakPtr<FontChangeObserver> node)
406 {
407 observers_.erase(node);
408 }
409
GetFontNames()410 std::vector<std::string> FontManager::GetFontNames()
411 {
412 return fontNames_;
413 }
414
415 } // namespace OHOS::Ace
416