• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkFontMgr_ohos_DEFINED
9 #define SkFontMgr_ohos_DEFINED
10 
11 #include <algorithm>
12 #include <map>
13 #include <mutex>
14 #include <string>
15 #include <vector>
16 
17 #include "include/core/SkFontMgr.h"
18 #include "include/core/SkFontStyle.h"
19 #include "include/core/SkRefCnt.h"
20 #include "include/core/SkStream.h"
21 #include "include/core/SkString.h"
22 #include "include/core/SkTypeface.h"
23 #include "include/private/SkTArray.h"
24 
25 class SkFontMgr;
26 
27 enum FontVariants {
28     kNone_FontVariant = 0,
29     kCompact_FontVariant = 1,
30     kElegant_FontVariant = 2,
31     kLast_FontVariant = kElegant_FontVariant,
32 };
33 typedef uint32_t FontVariant;
34 
35 struct FontVariationAxis {
36     std::string tag;
37     float value;
38 };
39 
40 struct FontFamilyItem {
41     SkTypeface* typeface;
42     std::string lang;
43     int weight;
44     int index;
45     int variant;
46     std::vector<FontVariationAxis> variationAxes;
47     int hwFontFamilyType;
48 };
49 
50 struct FamilyAliasObj {
51     std::string toName;
52     int weight;
53 };
54 
55 class SkTypeface_OHOS : public SkWeakRefCnt {
56 public:
SkTypeface_OHOS(SkTypeface * typeface,const std::string & familyName,const std::string & lang,FontVariant variantStyle,const std::vector<FontVariationAxis> & variationAxes,int fontWeight,int hwFontFamilyType)57     SkTypeface_OHOS(SkTypeface* typeface,
58                        const std::string& familyName,
59                        const std::string& lang,
60                        FontVariant variantStyle,
61                        const std::vector<FontVariationAxis>& variationAxes,
62                        int fontWeight,
63                        int hwFontFamilyType)
64         : fTypeface(typeface)
65         , fLang(lang)
66         , fVariantStyle(variantStyle)
67         , fFamilyName(familyName.c_str())
68         , variationAxes(variationAxes)
69         , fontWeight(fontWeight)
70         , hwFontFamilyType(hwFontFamilyType)
71     { }
72 
73     ~SkTypeface_OHOS() override = default;
74 
getFamilyName()75     const SkString& getFamilyName() const {
76         return fFamilyName;
77     }
78 
getFontVariant()79     FontVariant getFontVariant() const {
80         return fVariantStyle;
81     }
82 
getFontVariationAxes()83     const std::vector<FontVariationAxis>& getFontVariationAxes() const {
84         return variationAxes;
85     }
86 
getWghtValue()87     float getWghtValue() const {
88         for (auto axis : variationAxes) {
89             if (axis.tag == "wght") {
90                 return axis.value;
91             }
92         }
93         return 0.0f;
94     }
95 
getFontWeight()96     int getFontWeight() const {
97         return fontWeight;
98     }
99 
getLangTag()100     const std::string getLangTag() const {
101         return fLang;
102     }
103 
getHwFontFamilyType()104     int getHwFontFamilyType() const {
105         return hwFontFamilyType;
106     }
107 
108 protected:
109     SkTypeface* fTypeface = nullptr;
110     std::string fLang;
111     const FontVariant fVariantStyle = kNone_FontVariant;
112     SkString fFamilyName;
113     std::vector<FontVariationAxis> variationAxes;
114     int fontWeight = 400; // default font weight is 400.
115     int hwFontFamilyType = 0;
116 };
117 
118 class SkLanguage {
119 public:
SkLanguage()120     SkLanguage() { }
SkLanguage(const SkString & tag)121     SkLanguage(const SkString& tag) : fTag(tag) { }
SkLanguage(const char * tag)122     SkLanguage(const char* tag) : fTag(tag) { }
SkLanguage(const char * tag,size_t len)123     SkLanguage(const char* tag, size_t len) : fTag(tag, len) { }
SkLanguage(const SkLanguage & b)124     SkLanguage(const SkLanguage& b) : fTag(b.fTag) { }
125     ~SkLanguage() = default;
126 
127     /** Gets a BCP 47 language identifier for this SkLanguage.
128         @return a BCP 47 language identifier representing this language
129     */
getTag()130     const SkString& getTag() const { return fTag; }
131 
132     /** Performs BCP 47 fallback to return an SkLanguage one step more general.
133         @return an SkLanguage one step more general
134     */
getParent()135     SkLanguage getParent() const {
136         SkASSERT(!fTag.isEmpty());
137         const char* tag = fTag.c_str();
138 
139         // strip off the rightmost "-.*"
140         const char* parentTagEnd = strrchr(tag, '-');
141         if (parentTagEnd == nullptr) {
142             return SkLanguage();
143         }
144         size_t parentTagLen = parentTagEnd - tag;
145         return SkLanguage(tag, parentTagLen);
146     }
147 
148     bool operator==(const SkLanguage& b) const {
149         return fTag == b.fTag;
150     }
151     bool operator!=(const SkLanguage& b) const {
152         return fTag != b.fTag;
153     }
154     SkLanguage& operator=(const SkLanguage& b) {
155         fTag = b.fTag;
156         return *this;
157     }
158 
159 private:
160     //! BCP 47 language identifier
161     SkString fTag;
162 };
163 
164 class SkFontStyleSet_OHOS : public SkFontStyleSet {
165 public:
166     SkFontStyleSet_OHOS(const std::vector<FontFamilyItem>& items, bool fallback = false) {
167         for (size_t i = 0; i < items.size(); ++i) {
168             const auto& item = items[i];
169             auto typeface = item.typeface;
170             int fontWeight = item.weight;
171             fStyles.push_back().reset(SkRef(typeface));
172             SkString skFamilyName;
173             typeface->getFamilyName(&skFamilyName);
174             std::string familyName(skFamilyName.c_str());
175             std::transform(familyName.begin(), familyName.end(), familyName.begin(),
176                 [](unsigned char c) -> unsigned char { return std::tolower(c); });
177             std::vector<FontVariationAxis> variationAxis;
178             if (item.variationAxes.size() > 0) {
179                 for (size_t index = 0; index < item.variationAxes.size(); ++index) {
180                     auto variationAxes = item.variationAxes[index];
181                     variationAxis.push_back({ .tag = variationAxes.tag, .value = variationAxes.value });
182                 }
183             }
184             fStylesHost.push_back().reset(new SkTypeface_OHOS(
185                 item.typeface, familyName, item.lang, item.variant,
186                 variationAxis, fontWeight, item.hwFontFamilyType));
187         }
188     }
189 
190     ~SkFontStyleSet_OHOS() override = default;
191 
count()192     int count() override {
193         return fStyles.count();
194     }
195 
getStyle(int index,SkFontStyle * style,SkString * name)196     void getStyle(int index, SkFontStyle* style, SkString* name) override {
197         if (index < 0 || fStyles.count() <= index) {
198             return;
199         }
200         if (style) {
201             *style = fStyles[index]->fontStyle();
202         }
203         if (name) {
204             name->reset();
205         }
206     }
207 
createTypeface(int index)208     SkTypeface* createTypeface(int index) override {
209         if (index < 0 || fStyles.count() <= index) {
210             return nullptr;
211         }
212         return SkRef(fStyles[index].get());
213     }
214 
matchStyle(const SkFontStyle & pattern)215     SkTypeface* matchStyle(const SkFontStyle& pattern) override {
216         return static_cast<SkTypeface*>(matchStyleCSS3(pattern));
217     }
218 
haveVariant(FontVariant variant)219     bool haveVariant(FontVariant variant) {
220         for (int i = 0; i < fStylesHost.count(); ++i) {
221             if (fStylesHost[i]->getFontVariant() == variant) {
222                 return true;
223             }
224         }
225         return false;
226     }
227 
getWghtValue(int index)228     float getWghtValue(int index) {
229         if (index < 0 || fStylesHost.count() <= index) {
230             return 0.0f;
231         }
232         return fStylesHost[index]->getWghtValue();
233     }
234 
getFontWeight(int index)235     int getFontWeight(int index) {
236         if (index < 0 || fStylesHost.count() <= index) {
237             return 400;
238         }
239         return fStylesHost[index]->getFontWeight();
240     }
241 
matchLanguage(const SkString & lang)242     bool matchLanguage(const SkString& lang) {
243         for (int i = 0; i < fStylesHost.count(); ++i) {
244             SkString langTag(fStylesHost[i]->getLangTag().c_str());
245             if (langTag.startsWith(lang.c_str())) {
246                 return true;
247             }
248         }
249         return false;
250     }
251 
getHwFontFamilyType()252     int getHwFontFamilyType() {
253         if (fStylesHost.count() <= 0) {
254             return 0;
255         }
256         return fStylesHost[0]->getHwFontFamilyType();
257     }
258 
259 private:
260     SkTArray<sk_sp<SkTypeface>> fStyles;
261     SkTArray<sk_sp<SkTypeface_OHOS>> fStylesHost;
262     SkString fFallbackFor;
263 
264     friend struct NameToFamily;
265     friend class SkFontMgr_OHOS;
266 
267     typedef SkFontStyleSet INHERITED;
268 };
269 
270 struct NameToFamily {
271     SkString name;
272     SkFontStyleSet_OHOS* styleSet;
273 };
274 
275 SK_API sk_sp<SkFontMgr> SkFontMgr_New_OHOS();
276 
277 class SkFontMgr_OHOS : public SkFontMgr {
278 public:
279     using BuildFamilyMapCallback = std::function<void(SkTArray<NameToFamily, true>&,
280                                                         SkTArray<NameToFamily, true>&,
281                                                         SkTArray<sk_sp<SkFontStyleSet_OHOS>>&,
282                                                         std::map<std::string, FamilyAliasObj>&)>;
283 
284     SkFontMgr_OHOS();
285     ~SkFontMgr_OHOS() override = default;
286 
287     SkString onMatchFamilyStyleCharacterOHOS(const char familyName[],
288                                                     const SkFontStyle& style,
289                                                     const char* bcp47[],
290                                                     int bcp47Count,
291                                                     SkUnichar character);
292 
293   SkString onMatchFamilyStyleCharacterHwFont(const char familyName[],
294                                            const SkFontStyle& style,
295                                            const char* bcp47[],
296                                            int bcp47Count,
297                                            SkUnichar character);
298 
setBuildFamilyMapCallback(BuildFamilyMapCallback && callback)299     static void setBuildFamilyMapCallback(BuildFamilyMapCallback&& callback) {
300         buildFamilyMapCallback = std::move(callback);
301     }
302 
303 protected:
304     int onCountFamilies() const override;
305     void onGetFamilyName(int index, SkString* familyName) const override;
306     SkFontStyleSet* onCreateStyleSet(int index) const override;
307     SkFontStyleSet* onMatchFamily(const char familyName[]) const override;
308     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
309                                            const SkFontStyle& style) const override;
310     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface,
311                                          const SkFontStyle& style) const override;
312 
313     static sk_sp<SkTypeface> find_family_style_character(
314             const SkString& familyName,
315             const SkTArray<NameToFamily, true>& fallbackNameToFamilyMap,
316             const SkFontStyle& style, bool elegant,
317             const SkString& langTag, SkUnichar character);
318 
319     virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
320                                                     const SkFontStyle& style,
321                                                     const char* bcp47[],
322                                                     int bcp47Count,
323                                                     SkUnichar character) const override;
324     sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData> data, int ttcIndex) const override;
325     sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override;
326     sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
327                                             int ttcIndex) const override;
328     sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
329                                            const SkFontArguments& args) const override;
330     sk_sp<SkTypeface> onMakeFromFontData(std::unique_ptr<SkFontData> data) const override;
331     sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle style) const override;
332 
333 private:
334     void buildNameToFamilyMap();
335     void findDefaultStyleSet();
336     static BuildFamilyMapCallback buildFamilyMapCallback;
337     SkString find_family_style_character_ohos(
338         const SkString& familyName,
339         const SkTArray<NameToFamily, true>& fallbackNameToFamilyMap,
340         const SkFontStyle& style, bool elegant,
341         const SkString& langTag, SkUnichar character);
342     SkString find_family_style_character_hwfont(
343         const SkString& familyName,
344         const SkTArray<NameToFamily, true>& fallbackNameToFamilyMap,
345         const SkFontStyle& style, bool elegant,
346         const SkString& langTag, SkUnichar character);
347     void addToCache(const NameToFamily* item);
348     SkString findFromCache(const SkString& familyName, const SkFontStyle& style, bool elegant,
349                            const SkString& langTag, SkUnichar character);
350 
351     void addToHwFontCache(const NameToFamily* item);
352     SkString findFromHwFontCache(const SkString& familyName, const SkFontStyle& style, bool elegant,
353                            const SkString& langTag, SkUnichar character);
354 
355     SkTArray<sk_sp<SkFontStyleSet_OHOS>> fStyleSets;
356     sk_sp<SkFontStyleSet> fDefaultStyleSet;
357 
358     std::mutex mutexCache;
359     SkTArray<const NameToFamily*, true> familyMapCache;
360     SkTArray<const NameToFamily*, true> hwFontFamilyMapCache;
361     SkTArray<NameToFamily, true> fNameToFamilyMap;
362     SkTArray<NameToFamily, true> fFallbackNameToFamilyMap;
363     std::map<std::string, FamilyAliasObj> fAliasMap;
364 
365     typedef SkFontMgr INHERITED;
366 };
367 
368 #endif // SkFontMgr_ohos_DEFINED
369