• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FONTCONFIG_OHOS_H
6 #define FONTCONFIG_OHOS_H
7 
8 #include <json/json.h>
9 #include <mutex>
10 #include <vector>
11 
12 #include "FontInfo_ohos.h"
13 #include "HmSymbolConfig_ohos.h"
14 #include "SkFontDescriptor.h"
15 #include "SkFontHost_FreeType_common.h"
16 #include "SkFontStyle.h"
17 #include "SkStream.h"
18 #include "SkString.h"
19 #include "SkTypeface_ohos.h"
20 #include "SkTypes.h"
21 
22 /*!
23  * Error code definition
24  */
25 namespace ErrorCode {
26 
27 enum {
28     NO_ERROR = 0,                      // no error
29     ERROR_CONFIG_NOT_FOUND,            // the configuration document is not found
30     ERROR_CONFIG_FORMAT_NOT_SUPPORTED, // the formation of configuration is not supported
31     ERROR_CONFIG_MISSING_TAG,          // missing tag in the configuration
32     ERROR_CONFIG_INVALID_VALUE_TYPE,   // invalid value type in the configuration
33     ERROR_FONT_NOT_EXIST,              // the font file is not exist
34     ERROR_FONT_INVALID_STREAM,         // the stream is not recognized
35     ERROR_FONT_NO_STREAM,              // no stream in the font data
36     ERROR_FAMILY_NOT_FOUND,            // the family name is not found in the system
37     ERROR_NO_AVAILABLE_FAMILY,         // no available family in the system
38     ERROR_DIR_NOT_FOUND,               // the directory is not exist
39 
40     ERROR_TYPE_COUNT,
41 };
42 } /* namespace ErrorCode */
43 
44 
45 /*!
46  * \brief To parse the font configuration document and manage the system fonts
47  */
48 class FontConfig_OHOS {
49 public:
50     enum FontType : uint32_t { Generic = 0, Fallback, NumOfFontType };
51 
52     // to map the json document's font object
53     struct FontJson {
54         uint32_t type = 0;
55         uint32_t slant = 0;
56         uint32_t index = 0;
57         uint32_t weight = 400;
58         std::string alias;
59         std::string family;
60         std::string lang;
61         std::string file;
62     };
63 
64     struct Font {
65         FontType type = FontType::Generic;
66         // slant: 0 - normal, 1 - italic, 2 - oblique
67         uint32_t slant = 0;
68         // the ttc font index, only valid for ttc font
69         uint32_t index = 0;
70         // only valid for the font with alias
71         uint32_t weight = 0;
72         std::string alias;
73         // essential for the every font
74         std::string family;
75         // only valid for the fallback font
76         std::string lang;
77         // all the typefaces of this font
78         std::vector<sk_sp<SkTypeface_OHOS>> typefaces;
79         // the unicode range of this font
80         std::array<uint32_t, 4> range{};
81 
82         // may be redundant move
FontFont83         explicit Font(FontJson&& info)
84             : slant(info.slant), weight(info.weight), alias(std::move(info.alias)),
85               family(std::move(info.family)), lang(std::move(info.lang))
86         {
87             this->type = info.type >= FontType::NumOfFontType ? FontType::Generic : static_cast<FontType>(info.type);
88         }
89 
90         bool containChar(SkUnichar unicode) const;
91     };
92 
93     explicit FontConfig_OHOS(const SkTypeface_FreeType::Scanner& fontScanner, const char* fname = nullptr);
94     virtual ~FontConfig_OHOS() = default;
95     SkTypeface* matchFallback(SkUnichar character, const SkFontStyle& style) const;
96     SkTypeface* matchFallback(size_t index, SkUnichar character, const SkFontStyle& style) const;
97     std::vector<size_t> matchFallbackByBCP47(std::function<int(const std::string&)>) const;
98     int getFamilyCount() const;
99     int getDefaultFamily(SkString& familyName) const;
100     int getFamilyName(size_t index, SkString& familyName) const;
101     size_t getTypefaceCount(size_t styleIndex, bool isFallback = false) const;
102     bool getStyleIndex(const char* familyName, bool& isFallback, size_t& index) const;
103     sk_sp<SkTypeface_OHOS> getFallbackTypeface(const SkString& familyName, const SkFontStyle& style) const;
forAll(std::function<void (Font &)> func)104     void forAll(std::function<void(Font&)> func)
105     {
106         fFontCollection.forAll(func);
107     }
108 
109     sk_sp<SkTypeface_OHOS> getTypefaceSP(size_t styleIndex, size_t index, bool isFallback = false) const;
110     SkTypeface_OHOS* getTypeface(size_t styleIndex, size_t index, bool isFallback = false) const;
111     SkTypeface_OHOS* getTypeface(size_t styleIndex, const SkFontStyle& style, bool isFallback = false) const;
112 
113     static sk_sp<SkTypeface_OHOS> matchFontStyle(
114         const std::vector<sk_sp<SkTypeface_OHOS>>& typefaceSet, const SkFontStyle& pattern);
115 
116 private:
117     struct {
118         std::vector<Font> fFallback;
119         std::vector<Font> fGeneric;
120         std::unordered_map<std::string, std::pair<size_t, FontType>> fIndexMap;
121 
emplaceFont__anonb203d7010208122         void emplaceFont(FontJson&& fj, sk_sp<SkTypeface_OHOS>&& typeface, const std::array<uint32_t, 4>& range)
123         {
124             if (fj.family.empty()) {
125                 return;
126             }
127             Font f(std::move(fj));
128             // copy the range, the range is a 128bit number stored in 4 uint32_t
129             f.range = range;
130             auto& targetVec = (f.type == FontType::Generic) ? fGeneric : fFallback;
131             auto& targetName = (f.type == FontType::Generic) ? f.alias : f.family;
132             // generic must have alias
133             auto exist = fIndexMap.find(targetName);
134             // if not found, insert directly
135             if (exist == fIndexMap.end()) {
136                 fIndexMap.emplace(targetName, std::make_pair(targetVec.size(), f.type));
137                 targetVec.emplace_back(f);
138                 targetVec.back().typefaces.emplace_back(typeface);
139             } else {
140                 // if exist, add the typeface to the font
141                 targetVec[exist->second.first].typefaces.emplace_back(typeface);
142             }
143         }
144 
getIndexByFamilyName__anonb203d7010208145         bool getIndexByFamilyName(const std::string& family, std::pair<size_t, FontType>& res) const
146         {
147             if (fIndexMap.count(family)) {
148                 res = fIndexMap.at(family);
149                 return true;
150             }
151             return false;
152         }
153 
getSet__anonb203d7010208154         const std::vector<Font>& getSet(bool isFallback) const
155         {
156             return isFallback ? fFallback : fGeneric;
157         }
158 
forAll__anonb203d7010208159         void forAll(std::function<void(Font&)> func)
160         {
161             for (auto& f : fFallback) {
162                 func(f);
163             }
164             for (auto& f : fGeneric) {
165                 func(f);
166             }
167         }
168     } fFontCollection;
169 
170     std::vector<std::string> fFontDir; // the directories where the fonts are
171     const SkTypeface_FreeType::Scanner& fFontScanner;
172     mutable std::mutex fFontMutex;
173 
174     int parseConfig(const char* fname);
175     int checkConfigFile(const char* fname, Json::Value& root);
176     int parseFontDir(const char* fname, const Json::Value& root);
177     int parseFonts(const Json::Value& root);
178 
179     int loadFont(const char* fname, FontJson& font, sk_sp<SkTypeface_OHOS>& typeface, std::array<uint32_t, 4>& range);
180     void loadHMSymbol();
181     static void sortTypefaceSet(std::vector<sk_sp<SkTypeface_OHOS>>& typefaceSet);
182     static uint32_t getFontStyleDifference(const SkFontStyle& style1, const SkFontStyle& style2);
183     FontConfig_OHOS(const FontConfig_OHOS&) = delete;
184     FontConfig_OHOS& operator=(const FontConfig_OHOS&) = delete;
185     FontConfig_OHOS(FontConfig_OHOS&&) = delete;
186     FontConfig_OHOS& operator=(FontConfig_OHOS&&) = delete;
187     int checkProductFile(const char* fname);
188     bool judgeFileExist();
189 };
190 
191 #endif /* FONTCONFIG_OHOS_H */
192