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 #ifdef ENABLE_TEXT_ENHANCE 9 #include <json/json.h> 10 #include <mutex> 11 #include <vector> 12 #include <functional> 13 14 #include "FontInfo_ohos.h" 15 #include "HmSymbolConfig_ohos.h" 16 #include "SkFontDescriptor.h" 17 #include "SkFontHost_FreeType_common.h" 18 #include "SkFontScanner_FreeType_priv.h" 19 #include "SkFontStyle.h" 20 #include "SkStream.h" 21 #include "SkString.h" 22 #include "SkTypeface_FreeType.h" 23 #include "SkTypeface_ohos.h" 24 #include "SkTypes.h" 25 26 /*! 27 * Error code definition 28 */ 29 namespace ErrorCode { 30 31 enum { 32 NO_ERROR = 0, // no error 33 ERROR_CONFIG_NOT_FOUND, // the configuration document is not found 34 ERROR_CONFIG_FORMAT_NOT_SUPPORTED, // the formation of configuration is not supported 35 ERROR_CONFIG_MISSING_TAG, // missing tag in the configuration 36 ERROR_CONFIG_INVALID_VALUE_TYPE, // invalid value type in the configuration 37 ERROR_FONT_NOT_EXIST, // the font file is not exist 38 ERROR_FONT_INVALID_STREAM, // the stream is not recognized 39 ERROR_FONT_NO_STREAM, // no stream in the font data 40 ERROR_FAMILY_NOT_FOUND, // the family name is not found in the system 41 ERROR_NO_AVAILABLE_FAMILY, // no available family in the system 42 ERROR_DIR_NOT_FOUND, // the directory is not exist 43 ERROR_CONFIG_FUN_NOT_DEFINED, // the symbol load config func is not register 44 45 ERROR_TYPE_COUNT, 46 }; 47 } /* namespace ErrorCode */ 48 49 constexpr size_t RANGE_SIZE = 11; 50 constexpr size_t UNICODE_RANGE_SIZE = 332; 51 using UnicodeRange = std::array<uint32_t, RANGE_SIZE>; 52 53 /*! 54 * \brief To parse the font configuration document and manage the system fonts 55 */ 56 class FontConfig_OHOS { 57 public: 58 enum FontType : uint32_t { Generic = 0, Fallback, NumOfFontType }; 59 60 // to map the json document's font object 61 struct FontJson { 62 uint32_t type = 0; 63 uint32_t slant = 0; 64 uint32_t index = 0; 65 uint32_t weight = 400; 66 std::string alias; 67 std::string family; 68 std::string lang; 69 std::string file; 70 UnicodeRange range { UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX, 71 UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX }; 72 }; 73 74 struct Font { 75 FontType type = FontType::Generic; 76 // slant: 0 - normal, 1 - italic, 2 - oblique 77 uint32_t slant = 0; 78 // the ttc font index, only valid for ttc font 79 uint32_t index = 0; 80 // only valid for the font with alias 81 uint32_t weight = 0; 82 std::string alias; 83 // essential for the every font 84 std::string family; 85 // only valid for the fallback font 86 std::string lang; 87 // all the typefaces of this font 88 std::vector<sk_sp<SkTypeface_OHOS>> typefaces; 89 90 // may be redundant move 91 explicit Font(FontJson& info); 92 }; 93 94 explicit FontConfig_OHOS(const SkFontScanner_FreeType& fontScanner, const char* fname = nullptr); 95 virtual ~FontConfig_OHOS() = default; 96 sk_sp<SkTypeface> matchFallback(SkUnichar character, const SkFontStyle& style) const; 97 sk_sp<SkTypeface> matchFallback(size_t index, SkUnichar character, const SkFontStyle& style) const; 98 std::vector<size_t> matchFallbackByBCP47(std::function<int(const std::string&)>) const; 99 int getFamilyCount() const; 100 int getDefaultFamily(SkString& familyName) const; 101 int getFamilyName(size_t index, SkString& familyName) const; 102 size_t getTypefaceCount(size_t styleIndex, bool isFallback = false) const; 103 bool getStyleIndex(const char* familyName, bool& isFallback, size_t& index) const; 104 sk_sp<SkTypeface_OHOS> getFallbackTypeface(const SkString& familyName, const SkFontStyle& style) const; forAll(std::function<void (Font &)> func)105 void forAll(std::function<void(Font&)> func) 106 { 107 fFontCollection.forAll(func); 108 } 109 110 sk_sp<SkTypeface_OHOS> getTypefaceSP(size_t styleIndex, size_t index, bool isFallback = false) const; 111 sk_sp<SkTypeface_OHOS> getTypeface(size_t styleIndex, size_t index, bool isFallback = false) const; 112 sk_sp<SkTypeface_OHOS> getTypeface(size_t styleIndex, const SkFontStyle& style, bool isFallback = false) const; 113 114 static sk_sp<SkTypeface_OHOS> matchFontStyle( 115 const std::vector<sk_sp<SkTypeface_OHOS>>& typefaceSet, const SkFontStyle& pattern); 116 117 private: 118 struct FontCollection { 119 std::vector<Font> fFallback; 120 std::vector<Font> fGeneric; 121 std::unordered_map<std::string, std::pair<size_t, FontType>> fIndexMap; 122 std::array<std::vector<size_t>, UNICODE_RANGE_SIZE> fRangeToIndex; 123 124 void emplaceFont(FontJson&& fj, sk_sp<SkTypeface_OHOS>&& typeface); 125 bool getIndexByFamilyName(const std::string& family, std::pair<size_t, FontType>& res) const; 126 const std::vector<Font>& getSet(bool isFallback) const; 127 void forAll(std::function<void(Font&)> func); 128 } fFontCollection; 129 130 std::vector<std::string> fFontDir; // the directories where the fonts are 131 const SkFontScanner_FreeType& fFontScanner; 132 mutable std::mutex fFontMutex; 133 static const std::map<std::pair<uint32_t, uint32_t>, int16_t> fRangeMap; 134 135 int parseConfig(const char* fname); 136 int checkConfigFile(const char* fname, Json::Value& root); 137 int parseFontDir(const char* fname, const Json::Value& root); 138 int parseFonts(const Json::Value& root); 139 140 int loadFont(const char* fname, FontJson& font, sk_sp<SkTypeface_OHOS>& typeface); 141 void loadHMSymbol(); 142 static bool containRange(const UnicodeRange& range, size_t index); 143 static void sortTypefaceSet(std::vector<sk_sp<SkTypeface_OHOS>>& typefaceSet); 144 static uint32_t getFontStyleDifference(const SkFontStyle& style1, const SkFontStyle& style2); 145 static int16_t charRangeIndex(SkUnichar unicode); 146 FontConfig_OHOS(const FontConfig_OHOS&) = delete; 147 FontConfig_OHOS& operator=(const FontConfig_OHOS&) = delete; 148 FontConfig_OHOS(FontConfig_OHOS&&) = delete; 149 FontConfig_OHOS& operator=(FontConfig_OHOS&&) = delete; 150 int checkProductFile(const char* fname); 151 bool judgeFileExist(); 152 }; 153 154 #endif // ENABLE_TEXT_ENHANCE 155 #endif /* FONTCONFIG_OHOS_H */ 156