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 "base/utils/system_properties.h"
20 #include "base/utils/utils.h"
21 #include "core/components/text/render_text.h"
22 #include "core/pipeline/base/render_node.h"
23 #include "core/components_ng/base/frame_node.h"
24 #ifdef ENABLE_ROSEN_BACKEND
25 #ifdef TEXGINE_SUPPORT_FOR_OHOS
26 #include "foundation/graphic/graphic_2d/rosen/modules/texgine/src/font_parser.h"
27 #include "foundation/graphic/graphic_2d/rosen/modules/texgine/src/font_config.h"
28 #endif
29 #endif
30
31 namespace OHOS::Ace {
32
33 float FontManager::fontWeightScale_ = 1.0f;
34 bool FontManager::isDefaultFontChanged_ = false;
35
RegisterFont(const std::string & familyName,const std::string & familySrc,const RefPtr<PipelineBase> & context,const std::string & bundleName,const std::string & moduleName)36 void FontManager::RegisterFont(const std::string& familyName, const std::string& familySrc,
37 const RefPtr<PipelineBase>& context, const std::string& bundleName, const std::string& moduleName)
38 {
39 if (std::find(std::begin(fontNames_), std::end(fontNames_), familyName) == std::end(fontNames_)) {
40 fontNames_.emplace_back(familyName);
41 }
42
43 for (auto iter = fontLoaders_.begin(); iter != fontLoaders_.end(); ++iter) {
44 auto& fontLoader = *iter;
45 if (fontLoader->GetFamilyName() == familyName) {
46 return;
47 }
48 }
49 RefPtr<FontLoader> fontLoader = FontLoader::Create(familyName, familySrc);
50 fontLoaders_.emplace_back(fontLoader);
51 fontLoader->AddFont(context, bundleName, moduleName);
52
53 fontLoader->SetVariationChanged([weak = WeakClaim(this), familyName]() {
54 auto fontManager = weak.Upgrade();
55 CHECK_NULL_VOID(fontManager);
56 fontManager->VaryFontCollectionWithFontWeightScale();
57 });
58 }
59
SetFontFamily(const char * familyName,const char * familySrc)60 void FontManager::SetFontFamily(const char* familyName, const char* familySrc)
61 {
62 isDefaultFontChanged_ = true;
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
GetSystemFontList(std::vector<std::string> & fontList)76 void FontManager::GetSystemFontList(std::vector<std::string>& fontList)
77 {
78 #ifdef ENABLE_ROSEN_BACKEND
79 #ifdef TEXGINE_SUPPORT_FOR_OHOS
80 Rosen::TextEngine::FontParser fontParser;
81 std::vector<Rosen::TextEngine::FontParser::FontDescriptor> systemFontList;
82 auto locale = Localization::GetInstance()->GetFontLocale();
83 systemFontList = fontParser.GetVisibilityFonts(locale);
84 for (size_t i = 0; i < systemFontList.size(); ++i) {
85 std::string fontName = systemFontList[i].fullName;
86 fontList.emplace_back(fontName);
87 }
88 #endif
89 #endif
90 }
91
GetUIFontConfig(FontConfigJsonInfo & info)92 void FontManager::GetUIFontConfig(FontConfigJsonInfo& info)
93 {
94 #ifdef ENABLE_ROSEN_BACKEND
95 #ifdef TEXGINE_SUPPORT_FOR_OHOS
96 Rosen::TextEngine::FontConfigJson fontConfigJson;
97 fontConfigJson.ParseFile();
98 auto rosenInfo = fontConfigJson.GetFontConfigJsonInfo();
99 // rosenInfo to FontConfigJsonInfo
100 for (size_t i = 0; i < rosenInfo->fontDirSet.size(); ++i) {
101 info.fontDirSet.emplace_back(rosenInfo->fontDirSet[i]);
102 }
103 for (size_t i = 0; i < rosenInfo->genericSet.size(); ++i) {
104 FontGenericInfo genericInfo;
105 genericInfo.familyName = rosenInfo->genericSet[i].familyName;
106 for (size_t j = 0; j < rosenInfo->genericSet[i].aliasSet.size(); ++j) {
107 AliasInfo aliasInfo;
108 aliasInfo.familyName = rosenInfo->genericSet[i].aliasSet[j].familyName;
109 aliasInfo.weight = rosenInfo->genericSet[i].aliasSet[j].weight;
110 genericInfo.aliasSet.emplace_back(aliasInfo);
111 }
112 for (size_t j = 0; j < rosenInfo->genericSet[i].adjustSet.size(); ++j) {
113 AdjustInfo adjustInfo;
114 adjustInfo.origValue = rosenInfo->genericSet[i].adjustSet[j].origValue;
115 adjustInfo.newValue = rosenInfo->genericSet[i].adjustSet[j].newValue;
116 genericInfo.adjustSet.emplace_back(adjustInfo);
117 }
118 info.genericSet.emplace_back(genericInfo);
119 }
120 for (size_t i = 0; i < rosenInfo->fallbackGroupSet.size(); ++i) {
121 FallbackGroup fallbackGroupInfo;
122 fallbackGroupInfo.groupName = rosenInfo->fallbackGroupSet[i].groupName;
123 for (size_t j = 0; j < rosenInfo->fallbackGroupSet[i].fallbackInfoSet.size(); ++j) {
124 FallbackInfo fallbackInfo;
125 fallbackInfo.familyName = rosenInfo->fallbackGroupSet[i].fallbackInfoSet[j].familyName;
126 fallbackInfo.font = rosenInfo->fallbackGroupSet[i].fallbackInfoSet[j].font;
127 fallbackGroupInfo.fallbackInfoSet.emplace_back(fallbackInfo);
128 }
129 info.fallbackGroupSet.emplace_back(fallbackGroupInfo);
130 }
131 #endif
132 #endif
133 }
134
GetSystemFont(const std::string & fontName,FontInfo & fontInfo)135 bool FontManager::GetSystemFont(const std::string& fontName, FontInfo& fontInfo)
136 {
137 bool isGetFont = false;
138 #ifdef ENABLE_ROSEN_BACKEND
139 #ifdef TEXGINE_SUPPORT_FOR_OHOS
140 Rosen::TextEngine::FontParser fontParser;
141 std::unique_ptr<Rosen::TextEngine::FontParser::FontDescriptor> systemFontDesc;
142 auto locale = Localization::GetInstance()->GetFontLocale();
143 systemFontDesc = fontParser.GetVisibilityFontByName(fontName, locale);
144 CHECK_NULL_RETURN(systemFontDesc, false);
145 if (fontName == systemFontDesc->fullName) {
146 fontInfo.path = systemFontDesc->path;
147 fontInfo.postScriptName = systemFontDesc->postScriptName;
148 fontInfo.fullName = systemFontDesc->fullName;
149 fontInfo.family = systemFontDesc->fontFamily;
150 fontInfo.subfamily = systemFontDesc->fontSubfamily;
151 fontInfo.weight = systemFontDesc->weight;
152 fontInfo.width = systemFontDesc->width;
153 fontInfo.italic = systemFontDesc->italic;
154 fontInfo.monoSpace = systemFontDesc->monoSpace;
155 fontInfo.symbolic = systemFontDesc->symbolic;
156 isGetFont = true;
157 }
158 #endif
159 #endif
160 return isGetFont;
161 }
162
RegisterCallback(const WeakPtr<RenderNode> & node,const std::string & familyName,const std::function<void ()> & callback)163 bool FontManager::RegisterCallback(
164 const WeakPtr<RenderNode>& node, const std::string& familyName, const std::function<void()>& callback)
165 {
166 CHECK_NULL_RETURN(callback, false);
167 bool isCustomFont = false;
168 for (auto& fontLoader : fontLoaders_) {
169 if (fontLoader->GetFamilyName() == familyName) {
170 fontLoader->SetOnLoaded(node, callback);
171 isCustomFont = true;
172 }
173 }
174 return isCustomFont;
175 }
176
GetFontNames() const177 const std::vector<std::string>& FontManager::GetFontNames() const
178 {
179 return fontNames_;
180 }
181
AddFontNode(const WeakPtr<RenderNode> & node)182 void FontManager::AddFontNode(const WeakPtr<RenderNode>& node)
183 {
184 if (fontNodes_.find(node) == fontNodes_.end()) {
185 fontNodes_.emplace(node);
186 }
187 }
188
RemoveFontNode(const WeakPtr<RenderNode> & node)189 void FontManager::RemoveFontNode(const WeakPtr<RenderNode>& node)
190 {
191 fontNodes_.erase(node);
192 }
193
RebuildFontNode()194 void FontManager::RebuildFontNode()
195 {
196 #ifndef NG_BUILD
197 for (auto iter = fontNodes_.begin(); iter != fontNodes_.end();) {
198 auto fontNode = iter->Upgrade();
199 CHECK_NULL_VOID(fontNode);
200 auto renderNode = DynamicCast<RenderNode>(fontNode);
201 if (renderNode) {
202 renderNode->MarkNeedLayout();
203 ++iter;
204 } else {
205 iter = fontNodes_.erase(iter);
206 }
207 }
208 #else
209 for (auto iter = fontNodesNG_.begin(); iter != fontNodesNG_.end();) {
210 auto fontNode = iter->Upgrade();
211 CHECK_NULL_VOID(fontNode);
212 auto uiNode = DynamicCast<NG::UINode>(fontNode);
213 if (uiNode) {
214 uiNode->MarkDirtyNode(NG::PROPERTY_UPDATE_LAYOUT);
215 ++iter;
216 } else {
217 iter = fontNodesNG_.erase(iter);
218 }
219 }
220 #endif
221 }
222
UnRegisterCallback(const WeakPtr<RenderNode> & node)223 void FontManager::UnRegisterCallback(const WeakPtr<RenderNode>& node)
224 {
225 for (auto& fontLoader : fontLoaders_) {
226 fontLoader->RemoveCallback(node);
227 }
228 }
229
UpdateFontWeightScale()230 void FontManager::UpdateFontWeightScale()
231 {
232 float fontWeightScale = SystemProperties::GetFontWeightScale();
233 if (!NearEqual(fontWeightScale, fontWeightScale_)) {
234 fontWeightScale_ = fontWeightScale;
235 VaryFontCollectionWithFontWeightScale();
236 }
237 }
238
AddVariationNode(const WeakPtr<RenderNode> & node)239 void FontManager::AddVariationNode(const WeakPtr<RenderNode>& node)
240 {
241 if (variationNodes_.find(node) == variationNodes_.end()) {
242 variationNodes_.emplace(node);
243 }
244 }
245
RemoveVariationNode(const WeakPtr<RenderNode> & node)246 void FontManager::RemoveVariationNode(const WeakPtr<RenderNode>& node)
247 {
248 variationNodes_.erase(node);
249 }
250
NotifyVariationNodes()251 void FontManager::NotifyVariationNodes()
252 {
253 #ifndef NG_BUILD
254 for (const auto& node : variationNodes_) {
255 auto refNode = node.Upgrade();
256 CHECK_NULL_VOID(refNode);
257 auto renderNode = DynamicCast<RenderNode>(refNode);
258 CHECK_NULL_VOID(renderNode);
259 auto text = DynamicCast<RenderText>(renderNode);
260 if (text) {
261 text->MarkNeedMeasure();
262 }
263 renderNode->MarkNeedLayout();
264 }
265 #else
266 for (const auto& node : variationNodesNG_) {
267 auto uiNode = node.Upgrade();
268 CHECK_NULL_VOID(uiNode);
269 auto frameNode = DynamicCast<NG::FrameNode>(uiNode);
270 if (frameNode) {
271 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
272 }
273 uiNode->MarkDirtyNode(NG::PROPERTY_UPDATE_LAYOUT);
274 }
275 #endif
276 }
277
RegisterCallbackNG(const WeakPtr<NG::UINode> & node,const std::string & familyName,const std::function<void ()> & callback)278 bool FontManager::RegisterCallbackNG(
279 const WeakPtr<NG::UINode>& node, const std::string& familyName, const std::function<void()>& callback)
280 {
281 CHECK_NULL_RETURN(callback, false);
282 bool isCustomFont = false;
283 for (auto& fontLoader : fontLoaders_) {
284 if (fontLoader->GetFamilyName() == familyName) {
285 fontLoader->SetOnLoadedNG(node, callback);
286 isCustomFont = true;
287 }
288 }
289 return isCustomFont;
290 }
291
AddFontNodeNG(const WeakPtr<NG::UINode> & node)292 void FontManager::AddFontNodeNG(const WeakPtr<NG::UINode>& node)
293 {
294 if (fontNodesNG_.find(node) == fontNodesNG_.end()) {
295 fontNodesNG_.emplace(node);
296 }
297 }
298
RemoveFontNodeNG(const WeakPtr<NG::UINode> & node)299 void FontManager::RemoveFontNodeNG(const WeakPtr<NG::UINode>& node)
300 {
301 fontNodesNG_.erase(node);
302 }
303
UnRegisterCallbackNG(const WeakPtr<NG::UINode> & node)304 void FontManager::UnRegisterCallbackNG(const WeakPtr<NG::UINode>& node)
305 {
306 for (auto& fontLoader : fontLoaders_) {
307 fontLoader->RemoveCallbackNG(node);
308 }
309 }
310
AddVariationNodeNG(const WeakPtr<NG::UINode> & node)311 void FontManager::AddVariationNodeNG(const WeakPtr<NG::UINode>& node)
312 {
313 if (variationNodesNG_.find(node) == variationNodesNG_.end()) {
314 variationNodesNG_.emplace(node);
315 }
316 }
317
RemoveVariationNodeNG(const WeakPtr<NG::UINode> & node)318 void FontManager::RemoveVariationNodeNG(const WeakPtr<NG::UINode>& node)
319 {
320 variationNodesNG_.erase(node);
321 }
322
323 } // namespace OHOS::Ace
324