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