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/flutter_font_collection.h"
17
18 #include "txt/src/minikin/FontFamily.h"
19 #include "txt/src/minikin/FontLanguageListCache.h"
20
21 #include "base/i18n/localization.h"
22 #include "base/log/ace_trace.h"
23 #include "base/log/log.h"
24 #include "base/utils/system_properties.h"
25 #include "base/utils/utils.h"
26 #include "core/common/ace_engine.h"
27
28 namespace OHOS::Ace {
29
30 FlutterFontCollection FlutterFontCollection::instance;
31
GetFontCollection()32 std::shared_ptr<txt::FontCollection> FlutterFontCollection::GetFontCollection()
33 {
34 if (!isUseFlutterEngine) {
35 if (!isCompleted_) {
36 isCompleted_ = future_.get();
37 }
38 return fontCollection_->GetFontCollection();
39 }
40 std::call_once(fontFlag_, [this]() {
41 fontCollection_ = std::make_unique<flutter::FontCollection>();
42 if (fontCollection_->GetFontCollection()) {
43 std::string emptyLocale;
44 // 0x4e2d is unicode for '中'.
45 fontCollection_->GetFontCollection()->MatchFallbackFont(0x4e2d, emptyLocale);
46 fontCollection_->GetFontCollection()->GetMinikinFontCollectionForFamilies({ "sans-serif" }, emptyLocale);
47 }
48 });
49 return fontCollection_->GetFontCollection();
50 }
51
LoadFontFromList(const uint8_t * fontData,size_t length,std::string familyName)52 void FlutterFontCollection::LoadFontFromList(const uint8_t* fontData, size_t length, std::string familyName)
53 {
54 auto it = std::find(families_.begin(), families_.end(), familyName);
55 if (it != families_.end()) {
56 return;
57 }
58
59 families_.emplace_back(familyName);
60
61 if (!isUseFlutterEngine) {
62 if (!isCompleted_) {
63 isCompleted_ = future_.get();
64 }
65 fontCollection_->LoadFontFromList(fontData, length, familyName);
66 return;
67 }
68
69 if (fontCollection_) {
70 fontCollection_->LoadFontFromList(fontData, length, familyName);
71 }
72 }
73
CreateFontCollection(const fml::RefPtr<fml::TaskRunner> & ioTaskRunner)74 void FlutterFontCollection::CreateFontCollection(const fml::RefPtr<fml::TaskRunner>& ioTaskRunner)
75 {
76 Localization::GetInstance()->SetOnMymrChange([ioTaskRunner](bool isZawgyiMyanmar) {
77 if (ioTaskRunner) {
78 ioTaskRunner->PostTask(
79 [isZawgyiMyanmar]() { FlutterFontCollection::GetInstance().SetIsZawgyiMyanmar(isZawgyiMyanmar); });
80 }
81 });
82
83 if (isInit_ || !ioTaskRunner) {
84 return;
85 }
86 isInit_ = true;
87 isUseFlutterEngine = false;
88
89 ioTaskRunner->PostTask([&fontCollection = fontCollection_, &promise = promise_]() mutable {
90 fontCollection = std::make_unique<flutter::FontCollection>();
91 if (fontCollection->GetFontCollection()) {
92 // Initialize weight scale
93 float fontWeightScale = SystemProperties::GetFontWeightScale();
94 if (GreatNotEqual(fontWeightScale, 0.0)) {
95 fontCollection->GetFontCollection()->VaryFontCollectionWithFontWeightScale(fontWeightScale);
96 }
97
98 auto locale = Localization::GetInstance()->GetFontLocale();
99 uint32_t langListId = locale.empty() ? minikin::FontLanguageListCache::kEmptyListId
100 : minikin::FontStyle::registerLanguageList(locale);
101 const minikin::FontLanguages& langs = minikin::FontLanguageListCache::getById(langListId);
102 locale = langs.size() ? langs[0].getString() : "";
103 // 0x4e2d is unicode for '中'.
104 fontCollection->GetFontCollection()->MatchFallbackFont(0x4e2d, locale);
105 fontCollection->GetFontCollection()->GetMinikinFontCollectionForFamilies({ "sans-serif" }, locale);
106 }
107 promise.set_value(true);
108 });
109 }
110
GetInstance()111 FlutterFontCollection& FlutterFontCollection::GetInstance()
112 {
113 return instance;
114 }
115
VaryFontCollectionWithFontWeightScale(float fontWeightScale)116 void FlutterFontCollection::VaryFontCollectionWithFontWeightScale(float fontWeightScale)
117 {
118 if (LessOrEqual(fontWeightScale, 0.0)) {
119 return;
120 }
121
122 if (!isUseFlutterEngine) {
123 if (!isCompleted_) {
124 return;
125 }
126 if (fontCollection_ && fontCollection_->GetFontCollection()) {
127 fontCollection_->GetFontCollection()->VaryFontCollectionWithFontWeightScale(fontWeightScale);
128 }
129 return;
130 }
131
132 if (fontCollection_ && fontCollection_->GetFontCollection()) {
133 fontCollection_->GetFontCollection()->VaryFontCollectionWithFontWeightScale(fontWeightScale);
134 }
135 }
136
LoadSystemFont()137 void FlutterFontCollection::LoadSystemFont()
138 {
139 ACE_FUNCTION_TRACE();
140 if (!isUseFlutterEngine) {
141 if (!isCompleted_) {
142 return;
143 }
144 if (fontCollection_ && fontCollection_->GetFontCollection()) {
145 fontCollection_->GetFontCollection()->LoadSystemFont();
146 }
147 return;
148 }
149
150 if (fontCollection_ && fontCollection_->GetFontCollection()) {
151 fontCollection_->GetFontCollection()->LoadSystemFont();
152 }
153 }
154
SetIsZawgyiMyanmar(bool isZawgyiMyanmar)155 void FlutterFontCollection::SetIsZawgyiMyanmar(bool isZawgyiMyanmar)
156 {
157 ACE_FUNCTION_TRACE();
158
159 if (isZawgyiMyanmar_ == isZawgyiMyanmar) {
160 return;
161 }
162 isZawgyiMyanmar_ = isZawgyiMyanmar;
163
164 if (!isUseFlutterEngine) {
165 if (!isCompleted_) {
166 isCompleted_ = future_.get();
167 }
168 if (fontCollection_ && fontCollection_->GetFontCollection()) {
169 fontCollection_->GetFontCollection()->SetIsZawgyiMyanmar(isZawgyiMyanmar);
170 }
171 return;
172 }
173
174 if (fontCollection_ && fontCollection_->GetFontCollection()) {
175 fontCollection_->GetFontCollection()->SetIsZawgyiMyanmar(isZawgyiMyanmar);
176 }
177
178 AceEngine::Get().NotifyContainers([](const RefPtr<Container>& container) {
179 if (container) {
180 container->NotifyFontNodes();
181 }
182 });
183 }
184
UnloadFont()185 void FlutterFontCollection::UnloadFont()
186 {
187 families_.clear();
188 }
189
190 } // namespace OHOS::Ace
191