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 <vector>
10#include <mutex>
11
12#include "SkFontDescriptor.h"
13#include "SkFontHost_FreeType_common.h"
14#include "SkFontStyle.h"
15#include "SkStream.h"
16#include "SkString.h"
17#include "SkTypes.h"
18
19#include "FontInfo_ohos.h"
20#include "SkTypeface_ohos.h"
21
22#include "HmSymbolConfig_ohos.h"
23
24#ifdef ENABLE_DEBUG
25
26#define LOGE(fmt, args...)        \
27    printf("E %s:%d  %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args)
28#define LOGI(fmt, args...)        \
29    printf("I %s:%d - " fmt,  __FUNCTION__, __LINE__, ##args)
30#define LOGW(fmt, args...)        \
31    printf("W %s:%d  %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args)
32
33#else
34
35#define LOGE        SkDEBUGF
36#define LOGI        SkDEBUGF
37#define LOGW        SkDEBUGF
38
39#endif
40
41struct FontInfo;
42struct FallbackInfo;
43struct GenericFamily;
44struct FallbackSetPos;
45
46using TypefaceSet = std::vector<sk_sp<SkTypeface_OHOS>>;
47using GenericFamilySet = std::vector<std::unique_ptr<GenericFamily>>;
48using FallbackSet = std::vector<std::unique_ptr<FallbackInfo>>;
49using FallbackForMap = SkTHashMap<SkString, FallbackSetPos>;
50using NamesMap = SkTHashMap<SkString, int>;
51using Coordinate = SkFontArguments::VariationPosition::Coordinate;
52using AxisDefinitions = SkTypeface_FreeType::Scanner::AxisDefinitions;
53
54/*!
55 * Error code definition
56 */
57namespace ErrorCode {
58
59enum {
60    NO_ERROR = 0,                           // no error
61    ERROR_CONFIG_NOT_FOUND,                 // the configuration document is not found
62    ERROR_CONFIG_FORMAT_NOT_SUPPORTED,      // the formation of configuration is not supported
63    ERROR_CONFIG_MISSING_TAG,               // missing tag in the configuration
64    ERROR_CONFIG_INVALID_VALUE_TYPE,        // invalid value type in the configuration
65    ERROR_FONT_NOT_EXIST,                   // the font file is not exist
66    ERROR_FONT_INVALID_STREAM,              // the stream is not recognized
67    ERROR_FONT_NO_STREAM,                   // no stream in the font data
68    ERROR_FAMILY_NOT_FOUND,                 // the family name is not found in the system
69    ERROR_NO_AVAILABLE_FAMILY,              // no available family in the system
70    ERROR_DIR_NOT_FOUND,                    // the directory is not exist
71
72    ERROR_TYPE_COUNT,
73};
74
75} /* namespace ErrorCode */
76
77/*!
78 *  \brief To manage the related information of a 'fallbackFor' family name
79 */
80struct FallbackSetPos {
81    unsigned int index; // the index of the first font style set in the fallback set for a specified family name
82    unsigned int count; // the count of font style sets for a specified family name
83};
84
85/*!
86 * \brief To manage the information for a generic family item
87 */
88struct GenericFamily {
89    SkString familyName; // the specified family name of the font style set
90    std::shared_ptr<TypefaceSet> typefaceSet; // the typeface set of the font style set
91    virtual ~GenericFamily() = default;
92};
93
94/*!
95 * \brief To manage the information for a fallback family item
96 */
97struct FallbackInfo : GenericFamily {
98    SkString langs; // the language for which the font style set is
99};
100
101/*!
102 * \brief To parse the font configuration document and manage the system fonts
103 */
104class FontConfig_OHOS {
105public:
106    explicit FontConfig_OHOS(const SkTypeface_FreeType::Scanner& fontScanner,
107        const char* fname = nullptr);
108    virtual ~FontConfig_OHOS() = default;
109    const FallbackForMap& getFallbackForMap() const;
110    const FallbackSet& getFallbackSet() const;
111    int getFamilyCount() const;
112    int getDefaultFamily(SkString* familyName) const;
113    int getFamilyName(int index, SkString* familyName) const;
114    int getTypefaceCount(int styleIndex, bool isFallback = false) const;
115    int getStyleIndex(const char* familyName, bool& isFallback) const;
116
117    sk_sp<SkTypeface_OHOS> getTypefaceSP(int styleIndex, int index, bool isFallback = false) const;
118    SkTypeface_OHOS* getTypeface(int styleIndex, int index, bool isFallback = false) const;
119    SkTypeface_OHOS* getTypeface(int styleIndex, const SkFontStyle& style,
120        bool isFallback = false) const;
121
122#if ENABLE_DEBUG
123    void dumpFont(const FontInfo& font) const;
124    void dumpGeneric() const;
125    void dumpFallback() const;
126#endif
127    bool hasError(int err, const SkString& text) const;
128    int getErrorCount() const;
129
130    static sk_sp<SkTypeface_OHOS> matchFontStyle(const TypefaceSet& typefaceSet, const SkFontStyle& pattern);
131
132    static const char* errToString(int err);
133private:
134    const uint32_t defaultColorHexLen = 9;
135    const uint32_t defaultColorStrLen = 7;
136    const uint32_t hexFlag = 16;
137    const uint32_t twoBytesBitsLen = 16;
138    const uint32_t oneByteBitsLen = 8;
139
140    struct AliasInfo;
141    struct AdjustInfo;
142    struct VariationInfo;
143    struct TtcIndexInfo;
144    using AliasMap = SkTHashMap<SkString, std::vector<AliasInfo>>;
145    using AjdustMap = SkTHashMap<SkString, std::vector<AdjustInfo>>;
146    using VariationMap = SkTHashMap<SkString, std::vector<VariationInfo>>;
147    using TtcIndexMap = SkTHashMap<SkString, TtcIndexInfo>;
148
149    /*!
150     * \brief To manage the adjust information
151     */
152    struct AdjustInfo {
153        int origValue; // the real value of the font weight
154        int newValue; // the specified value of weight for a font
155    };
156
157    /*!
158     * \brief To manage the alias information of
159     */
160    struct AliasInfo {
161        int pos; // the index of a font style set in generic family list.
162        int weight; // the weight of the font style set. 0 means no specified weight
163    };
164
165    /*!
166     * \brief To manage the variation information
167     */
168    struct VariationInfo {
169        VariationInfo() : weight(-1), width(-1), slant(-1){}
170        std::vector<Coordinate> axis; // the axis set such as 'wght', 'wdth' and 'slnt'.
171        int weight; // the value of mapping weight
172        int width;  // the value of mapping width
173        int slant; // the value of mapping slant
174    };
175
176    /*!
177     * \brief To manage the 'index' information for ttc fonts
178     */
179    struct TtcIndexInfo {
180        SkString familyName; // the family name of the first typeface in a ttc font
181        int ttcIndex; // the index of a typeface in a ttc font
182    };
183
184    /*!
185     * \brief To manage the information of errors happened
186     */
187    struct ErrorInfo {
188        ErrorInfo(int err, const char* text) : err(err), text(SkString(text)){}
189        ErrorInfo(int err, SkString& text) : err(err), text(std::move(text)){}
190        int err; // error id
191        SkString text; // the part with error
192    };
193
194    std::vector<SkString> fontDirSet; // the directories where the fonts are
195
196    FallbackForMap    fallbackForMap; // a hash table to save the fallbackFor pairs
197    GenericFamilySet genericFamilySet; // the font style set list of generic family
198    FallbackSet fallbackSet; // the font style set list of fallback family
199
200    NamesMap genericNames; // a map to store the index of a family for generic family
201    NamesMap fallbackNames; // a map to store the index of a family for fallback family
202
203    std::vector<ErrorInfo> errSet; // the errors happened
204    AliasMap aliasMap; // to save alias information temporarily
205    AjdustMap adjustMap; // to save adjust information temporarily
206    VariationMap variationMap; // to save variation information temporarily
207    TtcIndexMap ttcIndexMap; // to save 'index' information temporarily
208
209    mutable std::mutex fontMutex;
210
211    int parseConfig(const char* fname);
212    int checkConfigFile(const char* fname, Json::Value& root);
213    int parseFontDir(const char* fname, const Json::Value& root);
214    int parseGeneric(const Json::Value& root);
215    int parseFallback(const Json::Value& root);
216    int parseFallbackItem(const Json::Value& root);
217    int parseAlias(const Json::Value& root, std::vector<AliasInfo>& aliasSet);
218    int parseAdjust(const Json::Value& root, std::vector<AdjustInfo>& adjustSet);
219    int parseVariation(const Json::Value& root, std::vector<VariationInfo>& variationSet);
220    int parseTtcIndex(const Json::Value& root, const SkString& familyName);
221    void getAxisValues(const AxisDefinitions& axisDefinitions,
222        const VariationInfo& variation, FontInfo& font) const;
223    bool insertTtcFont(int count, FontInfo& font);
224    bool insertVariableFont(const AxisDefinitions& axisDefinitions, FontInfo& font);
225    TypefaceSet* getTypefaceSet(const SkString& familyName, SkString& specifiedName) const;
226
227    int loadFont(const SkTypeface_FreeType::Scanner& scanner, const char* fname);
228    int scanFonts(const SkTypeface_FreeType::Scanner& fontScanner);
229    void resetGenericValue();
230    void buildSubTypefaceSet(const std::shared_ptr<TypefaceSet>& typefaceSet,
231        std::shared_ptr<TypefaceSet>& subSet, const SkString& familyName, int weight);
232    void resetFallbackValue();
233    int logErrInfo(int err, const char* key, Json::ValueType expected = Json::nullValue,
234        Json::ValueType actual = Json::nullValue);
235    static void sortTypefaceSet(std::shared_ptr<TypefaceSet>& typefaceSet);
236    static uint32_t getFontStyleDifference(const SkFontStyle& style1, const SkFontStyle& style2);
237    static char* getFileData(const char* fname, int& size);
238    FontConfig_OHOS(const FontConfig_OHOS&) = delete;
239    FontConfig_OHOS& operator = (const FontConfig_OHOS&) = delete;
240    FontConfig_OHOS(FontConfig_OHOS&&) = delete;
241    FontConfig_OHOS& operator = (FontConfig_OHOS&&) = delete;
242    int checkProductFile(const char* fname);
243    bool judgeFileExist();
244};
245
246#endif /* FONTCONFIG_OHOS_H */
247