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