1 /*
2 * Copyright (c) 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 "skia_typeface.h"
17
18 #include "include/core/SkFontMgr.h"
19 #include "include/core/SkFontStyle.h"
20 #include "include/core/SkStream.h"
21 #include "include/core/SkString.h"
22 #include "include/private/SkTHash.h"
23 #include "skia_adapter/skia_convert_utils.h"
24 #include "skia_adapter/skia_data.h"
25 #include "skia_adapter/skia_memory_stream.h"
26
27 #include "utils/log.h"
28
29 namespace OHOS {
30 namespace Rosen {
31 namespace Drawing {
SkiaTypeface(sk_sp<SkTypeface> skTypeface)32 SkiaTypeface::SkiaTypeface(sk_sp<SkTypeface> skTypeface) : skTypeface_(skTypeface) {}
33
GetTypeface() const34 sk_sp<SkTypeface> SkiaTypeface::GetTypeface() const
35 {
36 return skTypeface_;
37 }
38
GetFamilyName() const39 std::string SkiaTypeface::GetFamilyName() const
40 {
41 std::string name;
42 if (!skTypeface_) {
43 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
44 return name;
45 }
46 SkString skName;
47 skTypeface_->getFamilyName(&skName);
48 SkiaConvertUtils::SkStringCastToStdString(skName, name);
49 return name;
50 }
51
GetFontPath() const52 std::string SkiaTypeface::GetFontPath() const
53 {
54 std::string path;
55 if (!skTypeface_) {
56 LOGE("SkTypeface nullptr");
57 return path;
58 }
59 SkString skName;
60 skTypeface_->getFontPath(&skName);
61 SkiaConvertUtils::SkStringCastToStdString(skName, path);
62 return path;
63 }
64
GetFontStyle() const65 FontStyle SkiaTypeface::GetFontStyle() const
66 {
67 FontStyle fontStyle;
68 if (!skTypeface_) {
69 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
70 return fontStyle;
71 }
72 SkFontStyle skFontStyle = skTypeface_->fontStyle();
73 SkiaConvertUtils::SkFontStyleCastToDrawingFontStyle(skFontStyle, fontStyle);
74 return fontStyle;
75 }
76
GetTableSize(uint32_t tag) const77 size_t SkiaTypeface::GetTableSize(uint32_t tag) const
78 {
79 if (!skTypeface_) {
80 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
81 return 0;
82 }
83 return skTypeface_->getTableSize(tag);
84 }
85
GetTableData(uint32_t tag,size_t offset,size_t length,void * data) const86 size_t SkiaTypeface::GetTableData(uint32_t tag, size_t offset, size_t length, void* data) const
87 {
88 if (!skTypeface_) {
89 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
90 return 0;
91 }
92 return skTypeface_->getTableData(tag, offset, length, data);
93 }
94
GetItalic() const95 bool SkiaTypeface::GetItalic() const
96 {
97 if (!skTypeface_) {
98 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
99 return false;
100 }
101 return skTypeface_->isItalic();
102 }
103
GetUniqueID() const104 uint32_t SkiaTypeface::GetUniqueID() const
105 {
106 if (!skTypeface_) {
107 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
108 return 0;
109 }
110 return skTypeface_->uniqueID();
111 }
112
GetUnitsPerEm() const113 int32_t SkiaTypeface::GetUnitsPerEm() const
114 {
115 if (!skTypeface_) {
116 LOGD("SkiaTypeface::GetUnitsPerEm, skTypeface nullptr");
117 return 0;
118 }
119 return skTypeface_->getUnitsPerEm();
120 }
121
MakeClone(const FontArguments & args) const122 std::shared_ptr<Typeface> SkiaTypeface::MakeClone(const FontArguments& args) const
123 {
124 if (!skTypeface_) {
125 LOGD("SkiaTypeface::MakeClone, skTypeface nullptr");
126 return nullptr;
127 }
128
129 SkFontArguments skArgs;
130 SkiaConvertUtils::DrawingFontArgumentsCastToSkFontArguments(args, skArgs);
131
132 auto cloned = skTypeface_->makeClone(skArgs);
133 if (!cloned) {
134 return nullptr;
135 }
136 cloned->setIsCustomTypeface(skTypeface_->isCustomTypeface());
137 std::shared_ptr<TypefaceImpl> typefaceImpl = std::make_shared<SkiaTypeface>(cloned);
138 return std::make_shared<Typeface>(typefaceImpl);
139 }
140
IsCustomTypeface() const141 bool SkiaTypeface::IsCustomTypeface() const
142 {
143 if (!skTypeface_) {
144 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
145 return false;
146 }
147 return skTypeface_->isCustomTypeface();
148 }
149
IsThemeTypeface() const150 bool SkiaTypeface::IsThemeTypeface() const
151 {
152 if (!skTypeface_) {
153 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
154 return false;
155 }
156 return skTypeface_->isThemeTypeface();
157 }
158
GetSkTypeface()159 sk_sp<SkTypeface> SkiaTypeface::GetSkTypeface()
160 {
161 if (!skTypeface_) {
162 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
163 return nullptr;
164 }
165 return skTypeface_;
166 }
167
MakeDefault()168 std::shared_ptr<Typeface> SkiaTypeface::MakeDefault()
169 {
170 sk_sp<SkTypeface> skTypeface = SkTypeface::MakeDefault();
171 if (!skTypeface) {
172 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
173 return nullptr;
174 }
175 std::shared_ptr<TypefaceImpl> typefaceImpl = std::make_shared<SkiaTypeface>(skTypeface);
176 return std::make_shared<Typeface>(typefaceImpl);
177 }
178
MakeFromFile(const char path[],int index)179 std::shared_ptr<Typeface> SkiaTypeface::MakeFromFile(const char path[], int index)
180 {
181 sk_sp<SkTypeface> skTypeface = SkTypeface::MakeFromFile(path, index);
182 if (!skTypeface) {
183 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
184 return nullptr;
185 }
186 skTypeface->setIsCustomTypeface(true);
187 std::shared_ptr<TypefaceImpl> typefaceImpl = std::make_shared<SkiaTypeface>(skTypeface);
188 return std::make_shared<Typeface>(typefaceImpl);
189 }
190
MakeFromFile(const char path[],const FontArguments & fontArguments)191 std::shared_ptr<Typeface> SkiaTypeface::MakeFromFile(const char path[], const FontArguments& fontArguments)
192 {
193 std::unique_ptr<SkStreamAsset> skStream = SkStreamAsset::MakeFromFile(path);
194 if (skStream == nullptr) {
195 LOGD("SkiaTypeface::MakeFromFile, skStream nullptr.");
196 return nullptr;
197 }
198 auto skFontMgr = SkFontMgr::RefDefault();
199 if (skFontMgr == nullptr) {
200 LOGD("SkiaTypeface::MakeFromFile, skFontMgr nullptr.");
201 return nullptr;
202 }
203 SkFontArguments skFontArguments;
204 SkiaConvertUtils::DrawingFontArgumentsCastToSkFontArguments(fontArguments, skFontArguments);
205 sk_sp<SkTypeface> skTypeface = skFontMgr->makeFromStream(std::move(skStream), skFontArguments);
206 if (!skTypeface) {
207 LOGD("SkiaTypeface::MakeFromFile, skTypeface nullptr.");
208 return nullptr;
209 }
210 skTypeface->setIsCustomTypeface(true);
211 std::shared_ptr<TypefaceImpl> typefaceImpl = std::make_shared<SkiaTypeface>(skTypeface);
212 return std::make_shared<Typeface>(typefaceImpl);
213 }
214
GetSystemFonts()215 std::vector<std::shared_ptr<Typeface>> SkiaTypeface::GetSystemFonts()
216 {
217 std::vector<sk_sp<SkTypeface>> skTypefaces = SkTypeface::GetSystemFonts();
218 if (skTypefaces.empty()) {
219 return {};
220 }
221 std::vector<std::shared_ptr<Typeface>> typefaces;
222 typefaces.reserve(skTypefaces.size());
223 for (auto& item : skTypefaces) {
224 item->setIsCustomTypeface(false);
225 std::shared_ptr<TypefaceImpl> typefaceImpl = std::make_shared<SkiaTypeface>(item);
226 typefaces.emplace_back(std::make_shared<Typeface>(typefaceImpl));
227 }
228 return typefaces;
229 }
230
MakeFromStream(std::unique_ptr<MemoryStream> memoryStream,int32_t index)231 std::shared_ptr<Typeface> SkiaTypeface::MakeFromStream(std::unique_ptr<MemoryStream> memoryStream, int32_t index)
232 {
233 if (!memoryStream) {
234 LOGD("SkiaTypeface::MakeFromStream, memoryStream nullptr");
235 return nullptr;
236 }
237 std::unique_ptr<SkStreamAsset> skMemoryStream = memoryStream->GetImpl<SkiaMemoryStream>()->GetSkMemoryStream();
238 sk_sp<SkTypeface> skTypeface = SkTypeface::MakeFromStream(std::move(skMemoryStream), index);
239 if (!skTypeface) {
240 LOGD("SkiaTypeface::MakeFromStream, skTypeface nullptr");
241 return nullptr;
242 }
243 skTypeface->setIsCustomTypeface(true);
244 std::shared_ptr<TypefaceImpl> typefaceImpl = std::make_shared<SkiaTypeface>(skTypeface);
245 return std::make_shared<Typeface>(typefaceImpl);
246 }
247
MakeFromName(const char familyName[],FontStyle fontStyle)248 std::shared_ptr<Typeface> SkiaTypeface::MakeFromName(const char familyName[], FontStyle fontStyle)
249 {
250 SkFontStyle skFontStyle;
251 SkiaConvertUtils::DrawingFontStyleCastToSkFontStyle(fontStyle, skFontStyle);
252 sk_sp<SkTypeface> skTypeface = SkTypeface::MakeFromName(familyName, skFontStyle);
253 if (!skTypeface) {
254 LOGD("SkiaTypeface::MakeFromName, skTypeface nullptr");
255 return nullptr;
256 }
257 std::shared_ptr<TypefaceImpl> typefaceImpl = std::make_shared<SkiaTypeface>(skTypeface);
258 return std::make_shared<Typeface>(typefaceImpl);
259 }
260
SerializeTypeface(SkTypeface * typeface,void * ctx)261 sk_sp<SkData> SkiaTypeface::SerializeTypeface(SkTypeface* typeface, void* ctx)
262 {
263 if (!typeface) {
264 LOGD("typeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
265 return nullptr;
266 }
267 TextBlob::Context* textblobCtx = reinterpret_cast<TextBlob::Context*>(ctx);
268 if (textblobCtx != nullptr && typeface->isCustomTypeface()) {
269 sk_sp<SkTypeface> typefacePtr = sk_ref_sp(typeface);
270 auto typefaceImpl = std::make_shared<SkiaTypeface>(typefacePtr);
271 auto customTypeface = std::make_shared<Typeface>(typefaceImpl);
272 textblobCtx->SetTypeface(customTypeface);
273 }
274 return typeface->serialize();
275 }
276
DeserializeTypeface(const void * data,size_t length,void * ctx)277 sk_sp<SkTypeface> SkiaTypeface::DeserializeTypeface(const void* data, size_t length, void* ctx)
278 {
279 if (data == nullptr) {
280 LOGD("data nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
281 return nullptr;
282 }
283
284 TextBlob::Context* textblobCtx = reinterpret_cast<TextBlob::Context*>(ctx);
285 if (textblobCtx == nullptr || textblobCtx->GetTypeface() == nullptr) {
286 SkMemoryStream stream(data, length);
287 return SkTypeface::MakeDeserialize(&stream);
288 }
289 auto& typeface = textblobCtx->GetTypeface();
290 if (typeface == nullptr) {
291 LOGD("typeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
292 return nullptr;
293 }
294 auto skiaTypeface = typeface->GetImpl<SkiaTypeface>();
295 if (skiaTypeface == nullptr) {
296 LOGD("skiaTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
297 return nullptr;
298 }
299 auto skTypeface = skiaTypeface->GetSkTypeface();
300 return skTypeface;
301 }
302
Serialize() const303 std::shared_ptr<Data> SkiaTypeface::Serialize() const
304 {
305 if (!skTypeface_) {
306 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
307 return nullptr;
308 }
309 auto skData = skTypeface_->serialize(SkTypeface::SerializeBehavior::kDoIncludeData);
310 auto data = std::make_shared<Data>();
311 auto skiaData = data->GetImpl<SkiaData>();
312 if (!skiaData) {
313 LOGD("skiaData nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
314 return nullptr;
315 }
316 skiaData->SetSkData(skData);
317 return data;
318 }
319
Deserialize(const void * data,size_t size)320 std::shared_ptr<Typeface> SkiaTypeface::Deserialize(const void* data, size_t size)
321 {
322 SkMemoryStream stream(data, size);
323 auto skTypeface = SkTypeface::MakeDeserialize(&stream);
324 if (!skTypeface) {
325 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
326 return nullptr;
327 }
328 auto typefaceImpl = std::make_shared<SkiaTypeface>(skTypeface);
329 return std::make_shared<Typeface>(typefaceImpl);
330 }
331
GetHash() const332 uint32_t SkiaTypeface::GetHash() const
333 {
334 if (!skTypeface_) {
335 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
336 return 0;
337 }
338 return skTypeface_->GetHash();
339 }
340
SetHash(uint32_t hash)341 void SkiaTypeface::SetHash(uint32_t hash)
342 {
343 if (!skTypeface_) {
344 LOGD("skTypeface nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
345 return;
346 }
347 skTypeface_->SetHash(hash);
348 }
349
350 } // namespace Drawing
351 } // namespace Rosen
352 } // namespace OHOS