1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.. All rights reserved.
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 "txt/typeface_font_asset_provider.h"
17 
18 #include "include/core/SkString.h"
19 #include "include/core/SkTypeface.h"
20 #include "utils/text_log.h"
21 
22 namespace txt {
23 TypefaceFontAssetProvider::TypefaceFontAssetProvider() = default;
24 
25 TypefaceFontAssetProvider::~TypefaceFontAssetProvider() = default;
26 
GetFamilyCount() const27 size_t TypefaceFontAssetProvider::GetFamilyCount() const
28 {
29     std::unique_lock lock(assetMutex_);
30     return familyNames_.size();
31 }
32 
GetFamilyName(int index) const33 std::string TypefaceFontAssetProvider::GetFamilyName(int index) const
34 {
35     std::unique_lock lock(assetMutex_);
36     if ((index < 0) || (index >= static_cast<int>(familyNames_.size()))) {
37         TEXT_LOGW("Invalid index:%{public}d", index);
38         return "";
39     }
40     return familyNames_[index];
41 }
42 
MatchFamily(const std::string & familyName)43 SkFontStyleSet* TypefaceFontAssetProvider::MatchFamily(const std::string& familyName)
44 {
45     std::unique_lock lock(assetMutex_);
46     auto found = registeredFamilies_.find(CanonicalFamilyName(familyName));
47     if (found == registeredFamilies_.end()) {
48         return nullptr;
49     }
50     return SkRef(found->second.get());
51 }
52 
RegisterTypeface(sk_sp<SkTypeface> typeface)53 void TypefaceFontAssetProvider::RegisterTypeface(sk_sp<SkTypeface> typeface)
54 {
55     if (typeface == nullptr) {
56         return;
57     }
58 
59     SkString name;
60     typeface->getFamilyName(&name);
61 
62     std::string familyName(name.c_str(), name.size());
63     RegisterTypeface(std::move(typeface), std::move(familyName));
64 }
65 
RegisterTypeface(sk_sp<SkTypeface> typeface,std::string familyNameAlias)66 void TypefaceFontAssetProvider::RegisterTypeface(sk_sp<SkTypeface> typeface, std::string familyNameAlias)
67 {
68     if (familyNameAlias.empty()) {
69         return;
70     }
71 
72     std::unique_lock lock(assetMutex_);
73 
74     std::string canonicalName = CanonicalFamilyName(familyNameAlias);
75     auto iter = registeredFamilies_.find(canonicalName);
76     if (typeface != nullptr) {
77         if (iter == registeredFamilies_.end()) {
78             familyNames_.push_back(familyNameAlias);
79             auto value = std::make_pair(canonicalName, sk_make_sp<TypefaceFontStyleSet>());
80             iter = registeredFamilies_.emplace(value).first;
81         }
82         iter->second->registerTypeface(std::move(typeface));
83     } else if (iter != registeredFamilies_.end()) {
84         iter->second->unregisterTypefaces();
85         registeredFamilies_.erase(iter);
86         for (auto it = familyNames_.begin(); it != familyNames_.end(); it++) {
87             if (*it == familyNameAlias) {
88                 familyNames_.erase(it);
89                 break;
90             }
91         }
92     }
93 }
94 
95 TypefaceFontStyleSet::TypefaceFontStyleSet() = default;
96 
97 TypefaceFontStyleSet::~TypefaceFontStyleSet() = default;
98 
registerTypeface(sk_sp<SkTypeface> typeface)99 void TypefaceFontStyleSet::registerTypeface(sk_sp<SkTypeface> typeface)
100 {
101     if (typeface != nullptr) {
102         typefaces_.emplace_back(std::move(typeface));
103     }
104 }
105 
unregisterTypefaces()106 void TypefaceFontStyleSet::unregisterTypefaces()
107 {
108     typefaces_.erase(typefaces_.begin(), typefaces_.end());
109 }
110 
count()111 int TypefaceFontStyleSet::count()
112 {
113     return typefaces_.size();
114 }
115 
getStyle(int index,SkFontStyle * style,SkString * name)116 void TypefaceFontStyleSet::getStyle(int index, SkFontStyle* style, SkString* name)
117 {
118     SkASSERT(static_cast<size_t>(index) < typefaces_.size());
119     if (static_cast<size_t>(index) >= typefaces_.size()) {
120         return;
121     }
122     if (style) {
123         *style = typefaces_[index]->fontStyle();
124     }
125     if (name) {
126         name->reset();
127     }
128 }
129 
createTypeface(int index)130 SkTypeface* TypefaceFontStyleSet::createTypeface(int index)
131 {
132     if (index < static_cast<int>(typefaces_.size())) {
133         return SkRef(typefaces_[index].get());
134     }
135     return nullptr;
136 }
137 
matchStyle(const SkFontStyle & pattern)138 SkTypeface* TypefaceFontStyleSet::matchStyle(const SkFontStyle& pattern)
139 {
140     return matchStyleCSS3(pattern);
141 }
142 } // namespace txt
143