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/utils/system_properties.h"
19 #include "base/utils/utils.h"
20 #include "core/components/text/render_text.h"
21 #include "core/pipeline/base/render_node.h"
22 #include "core/components_ng/base/frame_node.h"
23 #ifdef ENABLE_ROSEN_BACKEND
24 #ifdef TEXGINE_SUPPORT_FOR_OHOS
25 #include "foundation/graphic/graphic_2d/rosen/modules/texgine/src/font_parser.h"
26 #endif
27 #endif
28
29 namespace OHOS::Ace {
30
31 float FontManager::fontWeightScale_ = 1.0f;
32
RegisterFont(const std::string & familyName,const std::string & familySrc,const RefPtr<PipelineBase> & context)33 void FontManager::RegisterFont(
34 const std::string& familyName, const std::string& familySrc, const RefPtr<PipelineBase>& context)
35 {
36 if (std::find(std::begin(fontNames_), std::end(fontNames_), familyName) == std::end(fontNames_)) {
37 fontNames_.emplace_back(familyName);
38 }
39
40 for (auto iter = fontLoaders_.begin(); iter != fontLoaders_.end(); ++iter) {
41 auto& fontLoader = *iter;
42 if (fontLoader->GetFamilyName() == familyName) {
43 LOGI("Font is already loaded!");
44 return;
45 }
46 }
47 RefPtr<FontLoader> fontLoader = FontLoader::Create(familyName, familySrc);
48 fontLoaders_.emplace_back(fontLoader);
49 fontLoader->AddFont(context);
50
51 fontLoader->SetVariationChanged([weak = WeakClaim(this), familyName]() {
52 auto fontManager = weak.Upgrade();
53 CHECK_NULL_VOID_NOLOG(fontManager);
54 fontManager->VaryFontCollectionWithFontWeightScale();
55 });
56 }
57
58
GetSystemFontList(std::vector<std::string> & fontList)59 void FontManager::GetSystemFontList(std::vector<std::string>& fontList)
60 {
61 #ifdef ENABLE_ROSEN_BACKEND
62 #ifdef TEXGINE_SUPPORT_FOR_OHOS
63 Rosen::TextEngine::FontParser fontParser;
64 std::vector<Rosen::TextEngine::FontParser::FontDescriptor> systemFontList;
65 systemFontList = fontParser.GetVisibilityFonts();
66 for (size_t i = 0; i < systemFontList.size(); ++i) {
67 std::string fontName = systemFontList[i].fullName;
68 fontList.emplace_back(fontName);
69 }
70 #endif
71 #endif
72 }
73
GetSystemFont(const std::string & fontName,FontInfo & fontInfo)74 bool FontManager::GetSystemFont(const std::string& fontName, FontInfo& fontInfo)
75 {
76 bool isGetFont = false;
77 #ifdef ENABLE_ROSEN_BACKEND
78 #ifdef TEXGINE_SUPPORT_FOR_OHOS
79 Rosen::TextEngine::FontParser fontParser;
80 std::vector<Rosen::TextEngine::FontParser::FontDescriptor> systemFontList;
81 systemFontList = fontParser.GetVisibilityFonts();
82 for (size_t i = 0; i < systemFontList.size(); ++i) {
83 if (fontName == systemFontList[i].fullName) {
84 fontInfo.path = systemFontList[i].path;
85 fontInfo.postScriptName = systemFontList[i].postScriptName;
86 fontInfo.fullName = systemFontList[i].fullName;
87 fontInfo.family = systemFontList[i].fontFamily;
88 fontInfo.subfamily = systemFontList[i].fontSubfamily;
89 fontInfo.weight = systemFontList[i].weight;
90 fontInfo.width = systemFontList[i].width;
91 fontInfo.italic = systemFontList[i].italic;
92 fontInfo.monoSpace = systemFontList[i].monoSpace;
93 fontInfo.symbolic = systemFontList[i].symbolic;
94 isGetFont = true;
95 break;
96 }
97 }
98 #endif
99 #endif
100 return isGetFont;
101 }
102
RegisterCallback(const WeakPtr<RenderNode> & node,const std::string & familyName,const std::function<void ()> & callback)103 bool FontManager::RegisterCallback(
104 const WeakPtr<RenderNode>& node, const std::string& familyName, const std::function<void()>& callback)
105 {
106 CHECK_NULL_RETURN(callback, false);
107 bool isCustomFont = false;
108 for (auto& fontLoader : fontLoaders_) {
109 if (fontLoader->GetFamilyName() == familyName) {
110 fontLoader->SetOnLoaded(node, callback);
111 isCustomFont = true;
112 }
113 }
114 return isCustomFont;
115 }
116
GetFontNames() const117 const std::vector<std::string>& FontManager::GetFontNames() const
118 {
119 return fontNames_;
120 }
121
AddFontNode(const WeakPtr<RenderNode> & node)122 void FontManager::AddFontNode(const WeakPtr<RenderNode>& node)
123 {
124 if (fontNodes_.find(node) == fontNodes_.end()) {
125 fontNodes_.emplace(node);
126 }
127 }
128
RemoveFontNode(const WeakPtr<RenderNode> & node)129 void FontManager::RemoveFontNode(const WeakPtr<RenderNode>& node)
130 {
131 fontNodes_.erase(node);
132 }
133
RebuildFontNode()134 void FontManager::RebuildFontNode()
135 {
136 #ifndef NG_BUILD
137 for (auto iter = fontNodes_.begin(); iter != fontNodes_.end();) {
138 auto fontNode = iter->Upgrade();
139 CHECK_NULL_VOID(fontNode);
140 auto renderNode = DynamicCast<RenderNode>(fontNode);
141 if (renderNode) {
142 renderNode->MarkNeedLayout();
143 ++iter;
144 } else {
145 iter = fontNodes_.erase(iter);
146 }
147 }
148 #else
149 for (auto iter = fontNodesNG_.begin(); iter != fontNodesNG_.end();) {
150 auto fontNode = iter->Upgrade();
151 CHECK_NULL_VOID(fontNode);
152 auto uiNode = DynamicCast<NG::UINode>(fontNode);
153 if (uiNode) {
154 uiNode->MarkDirtyNode(NG::PROPERTY_UPDATE_LAYOUT);
155 ++iter;
156 } else {
157 iter = fontNodesNG_.erase(iter);
158 }
159 }
160 #endif
161 }
162
UnRegisterCallback(const WeakPtr<RenderNode> & node)163 void FontManager::UnRegisterCallback(const WeakPtr<RenderNode>& node)
164 {
165 for (auto& fontLoader : fontLoaders_) {
166 fontLoader->RemoveCallback(node);
167 }
168 }
169
UpdateFontWeightScale()170 void FontManager::UpdateFontWeightScale()
171 {
172 float fontWeightScale = SystemProperties::GetFontWeightScale();
173 if (!NearEqual(fontWeightScale, fontWeightScale_)) {
174 fontWeightScale_ = fontWeightScale;
175 VaryFontCollectionWithFontWeightScale();
176 }
177 }
178
AddVariationNode(const WeakPtr<RenderNode> & node)179 void FontManager::AddVariationNode(const WeakPtr<RenderNode>& node)
180 {
181 if (variationNodes_.find(node) == variationNodes_.end()) {
182 variationNodes_.emplace(node);
183 }
184 }
185
RemoveVariationNode(const WeakPtr<RenderNode> & node)186 void FontManager::RemoveVariationNode(const WeakPtr<RenderNode>& node)
187 {
188 variationNodes_.erase(node);
189 }
190
NotifyVariationNodes()191 void FontManager::NotifyVariationNodes()
192 {
193 #ifndef NG_BUILD
194 for (const auto& node : variationNodes_) {
195 auto refNode = node.Upgrade();
196 CHECK_NULL_VOID(refNode);
197 auto renderNode = DynamicCast<RenderNode>(refNode);
198 CHECK_NULL_VOID(renderNode);
199 auto text = DynamicCast<RenderText>(renderNode);
200 if (text) {
201 text->MarkNeedMeasure();
202 }
203 renderNode->MarkNeedLayout();
204 }
205 #else
206 for (const auto& node : variationNodesNG_) {
207 auto uiNode = node.Upgrade();
208 CHECK_NULL_VOID(uiNode);
209 auto frameNode = DynamicCast<NG::FrameNode>(uiNode);
210 if (frameNode) {
211 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
212 }
213 uiNode->MarkDirtyNode(NG::PROPERTY_UPDATE_LAYOUT);
214 }
215 #endif
216 }
217
RegisterCallbackNG(const WeakPtr<NG::UINode> & node,const std::string & familyName,const std::function<void ()> & callback)218 bool FontManager::RegisterCallbackNG(
219 const WeakPtr<NG::UINode>& node, const std::string& familyName, const std::function<void()>& callback)
220 {
221 CHECK_NULL_RETURN(callback, false);
222 bool isCustomFont = false;
223 for (auto& fontLoader : fontLoaders_) {
224 if (fontLoader->GetFamilyName() == familyName) {
225 fontLoader->SetOnLoadedNG(node, callback);
226 isCustomFont = true;
227 }
228 }
229 return isCustomFont;
230 }
231
AddFontNodeNG(const WeakPtr<NG::UINode> & node)232 void FontManager::AddFontNodeNG(const WeakPtr<NG::UINode>& node)
233 {
234 if (fontNodesNG_.find(node) == fontNodesNG_.end()) {
235 fontNodesNG_.emplace(node);
236 }
237 }
238
RemoveFontNodeNG(const WeakPtr<NG::UINode> & node)239 void FontManager::RemoveFontNodeNG(const WeakPtr<NG::UINode>& node)
240 {
241 fontNodesNG_.erase(node);
242 }
243
UnRegisterCallbackNG(const WeakPtr<NG::UINode> & node)244 void FontManager::UnRegisterCallbackNG(const WeakPtr<NG::UINode>& node)
245 {
246 for (auto& fontLoader : fontLoaders_) {
247 fontLoader->RemoveCallbackNG(node);
248 }
249 }
250
AddVariationNodeNG(const WeakPtr<NG::UINode> & node)251 void FontManager::AddVariationNodeNG(const WeakPtr<NG::UINode>& node)
252 {
253 if (variationNodesNG_.find(node) == variationNodesNG_.end()) {
254 variationNodesNG_.emplace(node);
255 }
256 }
257
RemoveVariationNodeNG(const WeakPtr<NG::UINode> & node)258 void FontManager::RemoveVariationNodeNG(const WeakPtr<NG::UINode>& node)
259 {
260 variationNodesNG_.erase(node);
261 }
262
263 } // namespace OHOS::Ace
264