1 /*
2 * Copyright (c) 2021-2023 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/components/font/rosen_font_collection.h"
17
18 #ifndef USE_GRAPHIC_TEXT_GINE
19 #include "txt/src/minikin/FontFamily.h"
20 #include "txt/src/minikin/FontLanguageListCache.h"
21 #else
22 #include "core/components_ng/render/adapter/txt_font_collection.h"
23 #include "rosen_text/font_collection.h"
24 #endif
25 #ifndef USE_ROSEN_DRAWING
26 #include "include/core/SkTypeface.h"
27 #endif
28 #include "core/common/ace_engine.h"
29
30 namespace OHOS::Ace {
31
32 RosenFontCollection RosenFontCollection::instance;
33
34 #ifndef USE_GRAPHIC_TEXT_GINE
GetFontCollection()35 std::shared_ptr<txt::FontCollection> RosenFontCollection::GetFontCollection()
36 {
37 std::call_once(fontFlag_, [this]() {
38 auto rosenCollection = RSFontCollection::GetInstance(false);
39 auto collectionTxtBase = rosenCollection->GetFontCollection();
40 auto collectionTxt = std::static_pointer_cast<rosen::FontCollectionTxt>(collectionTxtBase);
41 if (collectionTxt) {
42 fontCollection_ = collectionTxt->GetFontCollection();
43 dynamicFontManager_ = collectionTxt->GetDynamicFontManager();
44 } else {
45 TAG_LOGW(AceLogTag::ACE_FONT, "Fail to get font Follection!");
46 }
47 });
48 return fontCollection_;
49 }
50
51 #ifndef USE_ROSEN_DRAWING
GetDynamicFontManager()52 sk_sp<txt::DynamicFontManager> RosenFontCollection::GetDynamicFontManager()
53 #else
54 std::shared_ptr<RSFontMgr> RosenFontCollection::GetDynamicFontManager()
55 #endif
56 {
57 return dynamicFontManager_;
58 }
59 #else
GetFontCollection()60 std::shared_ptr<Rosen::FontCollection> RosenFontCollection::GetFontCollection()
61 {
62 std::call_once(fontFlag_, [this]() {
63 auto fontCollection = AceType::DynamicCast<NG::TxtFontCollection>(NG::FontCollection::Current());
64 fontCollection_ = fontCollection->GetRawFontCollection();
65 });
66 return fontCollection_;
67 }
68 #endif
69
LoadFontFromList(const uint8_t * fontData,size_t length,std::string familyName)70 void RosenFontCollection::LoadFontFromList(const uint8_t* fontData, size_t length, std::string familyName)
71 {
72 std::call_once(fontFlag_, [this]() {
73 #ifndef USE_GRAPHIC_TEXT_GINE
74 auto rosenCollection = RSFontCollection::GetInstance(false);
75 auto collectionTxtBase = rosenCollection->GetFontCollection();
76 auto collectionTxt = std::static_pointer_cast<rosen::FontCollectionTxt>(collectionTxtBase);
77 if (collectionTxt) {
78 fontCollection_ = collectionTxt->GetFontCollection();
79 dynamicFontManager_ = collectionTxt->GetDynamicFontManager();
80 }
81 #else
82 auto fontCollection = AceType::DynamicCast<NG::TxtFontCollection>(NG::FontCollection::Current());
83 fontCollection_ = fontCollection->GetRawFontCollection();
84 #endif
85 });
86
87 if (families_.find(familyName) != families_.end()) {
88 return;
89 }
90
91 families_.emplace(familyName);
92
93 if (fontCollection_) {
94 #ifndef USE_GRAPHIC_TEXT_GINE
95 #ifndef USE_ROSEN_DRAWING
96 std::unique_ptr<SkStreamAsset> font_stream = std::make_unique<SkMemoryStream>(fontData, length, true);
97 sk_sp<SkTypeface> typeface = SkTypeface::MakeFromStream(std::move(font_stream));
98 txt::TypefaceFontAssetProvider& font_provider = dynamicFontManager_->font_provider();
99 if (familyName.empty()) {
100 font_provider.RegisterTypeface(typeface);
101 } else {
102 font_provider.RegisterTypeface(typeface, familyName);
103 }
104 fontCollection_->ClearFontFamilyCache();
105 #else
106 TAG_LOGW(AceLogTag::ACE_FONT, "Drawing is not supported dynamic font");
107 #endif
108 #else
109 fontCollection_->LoadFont(familyName, fontData, length);
110 #endif
111 }
112 }
113
InitializeFontCollection()114 void RosenFontCollection::InitializeFontCollection()
115 {
116 std::call_once(fontFlag_, [this]() {
117 #ifndef USE_GRAPHIC_TEXT_GINE
118 auto rosenCollection = RSFontCollection::GetInstance(false);
119 auto collectionTxtBase = rosenCollection->GetFontCollection();
120 auto collectionTxt = std::static_pointer_cast<rosen::FontCollectionTxt>(collectionTxtBase);
121 if (collectionTxt) {
122 fontCollection_ = collectionTxt->GetFontCollection();
123 dynamicFontManager_ = collectionTxt->GetDynamicFontManager();
124 }
125 #else
126 auto fontCollection = AceType::DynamicCast<NG::TxtFontCollection>(NG::FontCollection::Current());
127 fontCollection_ = fontCollection->GetRawFontCollection();
128 #endif
129 });
130 }
131
LoadThemeFont(const char * fontFamily,std::unique_ptr<char[]> buffer,size_t size)132 void RosenFontCollection::LoadThemeFont(const char* fontFamily, std::unique_ptr<char[]> buffer, size_t size)
133 {
134 const std::string familyName = fontFamily;
135 const uint8_t* data = reinterpret_cast<uint8_t*>(buffer.get());
136 if (fontCollection_) {
137 #ifndef USE_GRAPHIC_TEXT_GINE
138 #ifndef USE_ROSEN_DRAWING
139 std::unique_ptr<SkStreamAsset> font_stream = std::make_unique<SkMemoryStream>(data, size, true);
140 sk_sp<SkTypeface> typeface = SkTypeface::MakeFromStream(std::move(font_stream));
141 txt::TypefaceFontAssetProvider& font_provider = dynamicFontManager_->font_provider();
142 if (familyName.empty()) {
143 font_provider.RegisterTypeface(typeface);
144 } else {
145 font_provider.RegisterTypeface(typeface, familyName);
146 }
147 fontCollection_->ClearFontFamilyCache();
148 #else
149 TAG_LOGW(AceLogTag::ACE_FONT, "Drawing is not supported");
150 #endif
151 #else
152 fontCollection_->LoadThemeFont("", nullptr, 0);
153 TAG_LOGI(AceLogTag::ACE_FONT, "LoadThemeFont [%{public}s:%{public}d]", familyName.c_str(),
154 static_cast<int32_t>(size));
155 fontCollection_->LoadThemeFont(familyName, data, size);
156 #endif
157 }
158 }
159
LoadFontFamily(const char * fontFamily,const char * familySrc)160 void RosenFontCollection::LoadFontFamily(const char* fontFamily, const char* familySrc)
161 {
162 const std::string path = familySrc;
163 if (currentFamily_ == path) {
164 TAG_LOGI(AceLogTag::ACE_FONT, "This font has already been registered.");
165 return;
166 }
167 InitializeFontCollection();
168 auto ret = StdFilesystemExists(path);
169 if (!ret) {
170 TAG_LOGW(AceLogTag::ACE_FONT, "FontFamily %{public}s not exist", path.c_str());
171 return;
172 }
173
174 std::ifstream ifs(path, std::ios_base::in);
175 if (!ifs.is_open()) {
176 TAG_LOGW(AceLogTag::ACE_FONT, "FontFamily file open fail, %{public}s", path.c_str());
177 return;
178 }
179 ifs.seekg(0, ifs.end);
180 if (!ifs.good()) {
181 ifs.close();
182 TAG_LOGW(AceLogTag::ACE_FONT, "font file is bad");
183 return;
184 }
185 auto size = ifs.tellg();
186 if (ifs.fail()) {
187 ifs.close();
188 TAG_LOGW(AceLogTag::ACE_FONT, "get size failed");
189 return;
190 }
191 ifs.seekg(ifs.beg);
192 if (!ifs.good()) {
193 ifs.close();
194 TAG_LOGW(AceLogTag::ACE_FONT, "file seek failed");
195 return;
196 }
197 std::unique_ptr<char[]> buffer = std::make_unique<char[]>(size);
198 ifs.read(buffer.get(), size);
199 if (!ifs.good()) {
200 ifs.close();
201 TAG_LOGW(AceLogTag::ACE_FONT, "read file failed");
202 return;
203 }
204 ifs.close();
205 currentFamily_ = path;
206 LoadThemeFont(fontFamily, std::move(buffer), size);
207 }
208
StdFilesystemExists(const std::string & path)209 bool RosenFontCollection::StdFilesystemExists(const std::string &path)
210 {
211 std::ifstream f(path.c_str());
212 return f.good();
213 }
214
GetInstance()215 RosenFontCollection& RosenFontCollection::GetInstance()
216 {
217 return instance;
218 }
219
VaryFontCollectionWithFontWeightScale(float fontWeightScale)220 void RosenFontCollection::VaryFontCollectionWithFontWeightScale(float fontWeightScale)
221 {
222 if (LessOrEqual(fontWeightScale, 0.0)) {
223 return;
224 }
225
226 #ifndef USE_GRAPHIC_TEXT_GINE
227 if (fontCollection_) {
228 fontCollection_->VaryFontCollectionWithFontWeightScale(fontWeightScale);
229 }
230 #endif
231 }
232
LoadSystemFont()233 void RosenFontCollection::LoadSystemFont()
234 {
235 ACE_FUNCTION_TRACE();
236
237 #ifndef USE_GRAPHIC_TEXT_GINE
238 if (fontCollection_) {
239 fontCollection_->LoadSystemFont();
240 }
241 #endif
242 }
243
SetIsZawgyiMyanmar(bool isZawgyiMyanmar)244 void RosenFontCollection::SetIsZawgyiMyanmar(bool isZawgyiMyanmar)
245 {
246 ACE_FUNCTION_TRACE();
247
248 if (isZawgyiMyanmar_ == isZawgyiMyanmar) {
249 return;
250 }
251 isZawgyiMyanmar_ = isZawgyiMyanmar;
252
253 #ifndef USE_GRAPHIC_TEXT_GINE
254 if (fontCollection_) {
255 fontCollection_->SetIsZawgyiMyanmar(isZawgyiMyanmar);
256 }
257 #endif
258
259 AceEngine::Get().NotifyContainers([](const RefPtr<Container>& container) {
260 if (container) {
261 container->NotifyFontNodes();
262 }
263 });
264 }
265
266 } // namespace OHOS::Ace
267