• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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_loader.h"
17 
18 #include "base/network/download_manager.h"
19 #include "core/components/font/rosen_font_collection.h"
20 #include "core/pipeline/base/rosen_render_context.h"
21 
22 namespace OHOS::Ace {
23 
24 const std::regex RAWFILE_APP_RES_PATH_REGEX(R"(^resource://RAWFILE/(.*)$)");
25 constexpr uint32_t RAWFILE_RESOURCE_MATCH_SIZE = 2;
26 
RosenFontLoader(const std::string & familyName,const std::string & familySrc)27 RosenFontLoader::RosenFontLoader(const std::string& familyName, const std::string& familySrc)
28     : FontLoader(familyName, familySrc) {}
29 
AddFont(const RefPtr<PipelineBase> & context)30 void RosenFontLoader::AddFont(const RefPtr<PipelineBase>& context)
31 {
32     if (familySrc_.empty()) {
33         return;
34     }
35 
36     if (familySrc_.substr(0, strlen(FONT_SRC_NETWORK)) == FONT_SRC_NETWORK) {
37         // Get font from NetWork.
38         LoadFromNetwork(context);
39     } else if (familySrc_.substr(0, strlen(FONT_SRC_RESOURCE)) == FONT_SRC_RESOURCE) {
40         // Get font from Resource.
41         LoadFromResource(context);
42     } else {
43         // Get font from asset.
44         LoadFromAsset(context);
45     }
46 }
47 
LoadFromNetwork(const OHOS::Ace::RefPtr<OHOS::Ace::PipelineBase> & context)48 void RosenFontLoader::LoadFromNetwork(const OHOS::Ace::RefPtr<OHOS::Ace::PipelineBase>& context)
49 {
50     auto weakContext = AceType::WeakClaim(AceType::RawPtr(context));
51     context->GetTaskExecutor()->PostTask(
52         [weak = AceType::WeakClaim(this), weakContext] {
53             auto fontLoader = weak.Upgrade();
54             auto context = weakContext.Upgrade();
55             if (!fontLoader || !context) {
56                 return;
57             }
58             std::vector<uint8_t> fontData;
59             if (!DownloadManager::GetInstance().Download(fontLoader->familySrc_, fontData) || fontData.empty()) {
60                 return;
61             }
62             context->GetTaskExecutor()->PostTask(
63                 [fontData, weak] {
64                     auto fontLoader = weak.Upgrade();
65                     if (!fontLoader) {
66                         return;
67                     }
68                     // Load font.
69                     RosenFontCollection::GetInstance().LoadFontFromList(
70                         fontData.data(), fontData.size(), fontLoader->familyName_);
71                     fontLoader->isLoaded_ = true;
72 
73                     // When font is already loaded, notify all which used this font.
74                     fontLoader->NotifyCallbacks();
75                 },
76                 TaskExecutor::TaskType::UI);
77         },
78         TaskExecutor::TaskType::BACKGROUND);
79 }
80 
LoadFromResource(const OHOS::Ace::RefPtr<OHOS::Ace::PipelineBase> & context)81 void RosenFontLoader::LoadFromResource(const OHOS::Ace::RefPtr<OHOS::Ace::PipelineBase>& context)
82 {
83     auto weakContext = AceType::WeakClaim(AceType::RawPtr(context));
84     context->GetTaskExecutor()->PostTask(
85         [weak = AceType::WeakClaim(this), weakContext] {
86             auto fontLoader = weak.Upgrade();
87             auto context = weakContext.Upgrade();
88             if (!fontLoader || !context) {
89                 return;
90             }
91             auto themeManager = context->GetThemeManager();
92             if (!themeManager) {
93                 LOGE("No theme manager!");
94                 return;
95             }
96             auto themeConstants =  themeManager->GetThemeConstants();
97             std::string rawFile;
98             std::unique_ptr<uint8_t[]> data;
99             size_t dataLen = 0;
100             std::smatch matches;
101             if (std::regex_match(fontLoader->familySrc_, matches, RAWFILE_APP_RES_PATH_REGEX)
102                 && matches.size() == RAWFILE_RESOURCE_MATCH_SIZE) {
103                 rawFile = matches[1].str();
104             }
105             if (rawFile.empty()) {
106                 return;
107             }
108             if (!themeConstants->GetRawFileData(rawFile, dataLen, data) || !data.get()) {
109                 LOGE("Get raw file data failed!");
110                 return;
111             }
112 
113             auto fontDataPtr = data.get();
114             std::vector<uint8_t> fontData;
115             for (size_t i = 0; i < dataLen; i++) {
116                 fontData.emplace_back(fontDataPtr[i]);
117             }
118             context->GetTaskExecutor()->PostTask(
119                 [fontData, weak] {
120                     auto fontLoader = weak.Upgrade();
121                     if (!fontLoader) {
122                         return;
123                     }
124                     // Load font.
125                     RosenFontCollection::GetInstance().LoadFontFromList(fontData.data(), fontData.size(),
126                         fontLoader->familyName_);
127                     fontLoader->isLoaded_ = true;
128 
129                     // When font is already loaded, notify all which used this font.
130                     fontLoader->NotifyCallbacks();
131                 },
132                 TaskExecutor::TaskType::UI);
133         },
134         TaskExecutor::TaskType::BACKGROUND);
135 }
136 
LoadFromAsset(const OHOS::Ace::RefPtr<OHOS::Ace::PipelineBase> & context)137 void RosenFontLoader::LoadFromAsset(const OHOS::Ace::RefPtr<OHOS::Ace::PipelineBase>& context)
138 {
139     auto weakContext = AceType::WeakClaim(AceType::RawPtr(context));
140     context->GetTaskExecutor()->PostTask(
141         [weak = AceType::WeakClaim(this), weakContext] {
142             auto fontLoader = weak.Upgrade();
143             auto context = weakContext.Upgrade();
144             if (!fontLoader || !context) {
145                 return;
146             }
147             auto assetManager = context->GetAssetManager();
148             if (!assetManager) {
149                 LOGE("No asset manager!");
150                 return;
151             }
152             std::string assetSrc(fontLoader->familySrc_);
153             if (assetSrc[0] == '/') {
154                 assetSrc = assetSrc.substr(1); // get the asset src without '/'.
155             } else if (assetSrc[0] == '.' && assetSrc.size() > 2 && assetSrc[1] == '/') {
156                 assetSrc = assetSrc.substr(2); // get the asset src without './'.
157             }
158             auto assetData = assetManager->GetAsset(assetSrc);
159             if (!assetData) {
160                 LOGE("No asset data!");
161                 return;
162             }
163 
164             context->GetTaskExecutor()->PostTask(
165                 [assetData, weak] {
166                     auto fontLoader = weak.Upgrade();
167                     if (!fontLoader) {
168                         return;
169                     }
170                     // Load font.
171                     RosenFontCollection::GetInstance().LoadFontFromList(
172                         assetData->GetData(), assetData->GetSize(), fontLoader->familyName_);
173                     fontLoader->isLoaded_ = true;
174 
175                     // When font is already loaded, notify all which used this font.
176                     fontLoader->NotifyCallbacks();
177                 },
178                 TaskExecutor::TaskType::UI);
179         },
180         TaskExecutor::TaskType::BACKGROUND);
181 }
182 
NotifyCallbacks()183 void RosenFontLoader::NotifyCallbacks()
184 {
185     for (const auto& [node, callback] : callbacksNG_) {
186         if (callback) {
187             callback();
188         }
189     }
190     callbacksNG_.clear();
191     if (variationChanged_) {
192         variationChanged_();
193     }
194 }
195 
196 } // namespace OHOS::Ace
197