1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3cb93a386Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4cb93a386Sopenharmony_ci * you may not use this file except in compliance with the License.
5cb93a386Sopenharmony_ci * You may obtain a copy of the License at
6cb93a386Sopenharmony_ci *
7cb93a386Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8cb93a386Sopenharmony_ci *
9cb93a386Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10cb93a386Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11cb93a386Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cb93a386Sopenharmony_ci * See the License for the specific language governing permissions and
13cb93a386Sopenharmony_ci * limitations under the License.
14cb93a386Sopenharmony_ci */
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ci#include "HmSymbolConfig_ohos.h"
17cb93a386Sopenharmony_ci
18cb93a386Sopenharmony_ci#include <functional>
19cb93a386Sopenharmony_ci#include <fstream>
20cb93a386Sopenharmony_ci
21cb93a386Sopenharmony_ci#include "securec.h"
22cb93a386Sopenharmony_ci
23cb93a386Sopenharmony_ci#include "include/private/SkOnce.h"
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_ci#ifdef SK_BUILD_FONT_MGR_FOR_OHOS
26cb93a386Sopenharmony_ci#include <parameters.h>
27cb93a386Sopenharmony_ci#endif
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ci#ifdef ENABLE_DEBUG
30cb93a386Sopenharmony_ci
31cb93a386Sopenharmony_ci#define LOGE(fmt, args...)        \
32cb93a386Sopenharmony_ci    printf("E %s:%d  %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args)
33cb93a386Sopenharmony_ci#define LOGI(fmt, args...)        \
34cb93a386Sopenharmony_ci    printf("I %s:%d - " fmt,  __FUNCTION__, __LINE__, ##args)
35cb93a386Sopenharmony_ci#define LOGW(fmt, args...)        \
36cb93a386Sopenharmony_ci    printf("W %s:%d  %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args)
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_ci#else
39cb93a386Sopenharmony_ci
40cb93a386Sopenharmony_ci#define LOGE        SkDEBUGF
41cb93a386Sopenharmony_ci#define LOGI        SkDEBUGF
42cb93a386Sopenharmony_ci#define LOGW        SkDEBUGF
43cb93a386Sopenharmony_ci
44cb93a386Sopenharmony_ci#endif
45cb93a386Sopenharmony_ci
46cb93a386Sopenharmony_ciusing PiecewiseParaKeyFunc = std::function<void(const char*, const Json::Value&, PiecewiseParameter&)>;
47cb93a386Sopenharmony_ciusing SymbolKeyFunc = std::function<void(const char*, const Json::Value&, SymbolLayersGroups&)>;
48cb93a386Sopenharmony_ciusing SymnolAniFunc = std::function<void(const char*, const Json::Value&, AnimationPara&)>;
49cb93a386Sopenharmony_ci
50cb93a386Sopenharmony_ciusing SymbolKeyFuncMap = std::unordered_map<std::string, SymbolKeyFunc>;
51cb93a386Sopenharmony_ciconst char SPECIAL_ANIMATIONS[] = "special_animations";
52cb93a386Sopenharmony_ciconst char COMMON_ANIMATIONS[] = "common_animations";
53cb93a386Sopenharmony_ciconst char SYMBOL_LAYERS_GROUPING[] = "symbol_layers_grouping";
54cb93a386Sopenharmony_ciconst char ANIMATION_TYPE[] = "animation_type";
55cb93a386Sopenharmony_ciconst char ANIMATION_TYPES[] = "animation_types";
56cb93a386Sopenharmony_ciconst char ANIMATION_PARAMETERS[] = "animation_parameters";
57cb93a386Sopenharmony_ciconst char ANIMATION_MODE[] = "animation_mode";
58cb93a386Sopenharmony_ciconst char GROUP_PARAMETERS[] = "group_parameters";
59cb93a386Sopenharmony_ciconst char CURVE[] = "curve";
60cb93a386Sopenharmony_ciconst char CURVE_ARGS[] = "curve_args";
61cb93a386Sopenharmony_ciconst char DURATION[] = "duration";
62cb93a386Sopenharmony_ciconst char DELAY[] = "delay";
63cb93a386Sopenharmony_ciconst char NATIVE_GLYPH_ID[] = "native_glyph_id";
64cb93a386Sopenharmony_ciconst char SYMBOL_GLYPH_ID[] = "symbol_glyph_id";
65cb93a386Sopenharmony_ciconst char LAYERS[] = "layers";
66cb93a386Sopenharmony_ciconst char RENDER_MODES[] = "render_modes";
67cb93a386Sopenharmony_ciconst char MODE[] = "mode";
68cb93a386Sopenharmony_ciconst char RENDER_GROUPS[] = "render_groups";
69cb93a386Sopenharmony_ciconst char GROUP_INDEXES[] = "group_indexes";
70cb93a386Sopenharmony_ciconst char DEFAULT_COLOR[] = "default_color";
71cb93a386Sopenharmony_ciconst char FIX_ALPHA[] = "fix_alpha";
72cb93a386Sopenharmony_ciconst char LAYER_INDEXES[] = "layer_indexes";
73cb93a386Sopenharmony_ciconst char MASK_INDEXES[] = "mask_indexes";
74cb93a386Sopenharmony_ciconst char GROUP_SETTINGS[] = "group_settings";
75cb93a386Sopenharmony_ciconst char ANIMATION_INDEX[] = "animation_index";
76cb93a386Sopenharmony_ciconst char COMMON_SUB_TYPE[] = "common_sub_type";
77cb93a386Sopenharmony_ciconst char ANIMATION_SETTINGS[] = "animation_settings";
78cb93a386Sopenharmony_ciconst char PROPERTIES[] = "properties";
79cb93a386Sopenharmony_ci
80cb93a386Sopenharmony_ciconst int NO_ERROR = 0; // no error
81cb93a386Sopenharmony_ciconst int ERROR_CONFIG_NOT_FOUND = 1; // the configuration document is not found
82cb93a386Sopenharmony_ciconst int ERROR_CONFIG_FORMAT_NOT_SUPPORTED = 2; // the formation of configuration is not supported
83cb93a386Sopenharmony_ciconst int ERROR_CONFIG_INVALID_VALUE_TYPE = 4; // invalid value type in the configuration
84cb93a386Sopenharmony_ciconst int ERROR_TYPE_COUNT = 11;
85cb93a386Sopenharmony_ci
86cb93a386Sopenharmony_cistatic const std::map<std::string, AnimationType> ANIMATIONS_TYPES = {
87cb93a386Sopenharmony_ci    {"scale", AnimationType::SCALE_TYPE},
88cb93a386Sopenharmony_ci    {"appear", AnimationType::APPEAR_TYPE},
89cb93a386Sopenharmony_ci    {"disappear", AnimationType::DISAPPEAR_TYPE},
90cb93a386Sopenharmony_ci    {"bounce", AnimationType::BOUNCE_TYPE},
91cb93a386Sopenharmony_ci    {"variable_color", AnimationType::VARIABLE_COLOR_TYPE},
92cb93a386Sopenharmony_ci    {"pulse", AnimationType::PULSE_TYPE},
93cb93a386Sopenharmony_ci    {"replace_appear", AnimationType::REPLACE_APPEAR_TYPE},
94cb93a386Sopenharmony_ci    {"replace_disappear", AnimationType::REPLACE_DISAPPEAR_TYPE}};
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_cistatic const std::map<std::string, CurveType> CURVE_TYPES = {
97cb93a386Sopenharmony_ci    {"spring", CurveType::SPRING},
98cb93a386Sopenharmony_ci    {"linear", CurveType::LINEAR},
99cb93a386Sopenharmony_ci    {"friction", CurveType::FRICTION},
100cb93a386Sopenharmony_ci    {"sharp", CurveType::SHARP}};
101cb93a386Sopenharmony_ci
102cb93a386Sopenharmony_ci/* To get the display text of an error
103cb93a386Sopenharmony_ci * \param err the id of an error
104cb93a386Sopenharmony_ci * \return The text to explain the error
105cb93a386Sopenharmony_ci */
106cb93a386Sopenharmony_ciconst char* ErrInfoToString(int err)
107cb93a386Sopenharmony_ci{
108cb93a386Sopenharmony_ci    const static std::array<const char*, ERROR_TYPE_COUNT> errInfoToString{
109cb93a386Sopenharmony_ci        "successful",                                                      // NO_ERROR = 0
110cb93a386Sopenharmony_ci        "config file is not found",                              // ERROR_CONFIG_NOT_FOUND
111cb93a386Sopenharmony_ci        "the format of config file is not supported", // ERROR_CONFIG_FORMAT_NOT_SUPPORTED
112cb93a386Sopenharmony_ci        "missing tag",                                         // ERROR_CONFIG_MISSING_TAG
113cb93a386Sopenharmony_ci        "invalid value type",                           // ERROR_CONFIG_INVALID_VALUE_TYPE
114cb93a386Sopenharmony_ci        "font file is not exist",                                  // ERROR_FONT_NOT_EXIST
115cb93a386Sopenharmony_ci        "invalid font stream",                                // ERROR_FONT_INVALID_STREAM
116cb93a386Sopenharmony_ci        "no font stream",                                          // ERROR_FONT_NO_STREAM
117cb93a386Sopenharmony_ci        "family is not found",                                   // ERROR_FAMILY_NOT_FOUND
118cb93a386Sopenharmony_ci        "no available family in the system",                   //ERROR_NO_AVAILABLE_FAMILY
119cb93a386Sopenharmony_ci        "no such directory"                                         // ERROR_DIR_NOT_FOUND
120cb93a386Sopenharmony_ci    };
121cb93a386Sopenharmony_ci    if (err >= 0 && err < ERROR_TYPE_COUNT) {
122cb93a386Sopenharmony_ci        return errInfoToString[err];
123cb93a386Sopenharmony_ci    }
124cb93a386Sopenharmony_ci    return "unknown error";
125cb93a386Sopenharmony_ci}
126cb93a386Sopenharmony_ci
127cb93a386Sopenharmony_ci/* To log the error information
128cb93a386Sopenharmony_ci * \param err the id of an error
129cb93a386Sopenharmony_ci * \param key the key which indicates the the part with the error
130cb93a386Sopenharmony_ci * \param expected the expected type of json node.
131cb93a386Sopenharmony_ci * \n     It's used only for err 'ERROR_CONFIG_INVALID_VALUE_TYPE'
132cb93a386Sopenharmony_ci * \param actual the actual type of json node.
133cb93a386Sopenharmony_ci * \n     It's used only for err 'ERROR_CONFIG_INVALID_VALUE_TYPE'
134cb93a386Sopenharmony_ci * \return err
135cb93a386Sopenharmony_ci */
136cb93a386Sopenharmony_ciint LogErrInfo(int err, const char* key, Json::ValueType expected = Json::nullValue,
137cb93a386Sopenharmony_ci    Json::ValueType actual = Json::nullValue)
138cb93a386Sopenharmony_ci{
139cb93a386Sopenharmony_ci    if (err != ERROR_CONFIG_INVALID_VALUE_TYPE) {
140cb93a386Sopenharmony_ci        LOGE("%s : %s\n", ErrInfoToString(err), key);
141cb93a386Sopenharmony_ci    } else {
142cb93a386Sopenharmony_ci        const char* types[] = {
143cb93a386Sopenharmony_ci            "null",
144cb93a386Sopenharmony_ci            "int",
145cb93a386Sopenharmony_ci            "unit",
146cb93a386Sopenharmony_ci            "real",
147cb93a386Sopenharmony_ci            "string",
148cb93a386Sopenharmony_ci            "boolean",
149cb93a386Sopenharmony_ci            "array",
150cb93a386Sopenharmony_ci            "object",
151cb93a386Sopenharmony_ci        };
152cb93a386Sopenharmony_ci        int size = sizeof(types) / sizeof(char*);
153cb93a386Sopenharmony_ci        if ((expected >= 0 && expected < size) &&
154cb93a386Sopenharmony_ci            (actual >= 0 && actual < size)) {
155cb93a386Sopenharmony_ci            LOGE("%s : '%s' should be '%s', but here it's '%s'\n",
156cb93a386Sopenharmony_ci                ErrInfoToString(err), key, types[expected], types[actual]);
157cb93a386Sopenharmony_ci        } else {
158cb93a386Sopenharmony_ci            LOGE("%s : %s\n", ErrInfoToString(err), key);
159cb93a386Sopenharmony_ci        }
160cb93a386Sopenharmony_ci    }
161cb93a386Sopenharmony_ci    return err;
162cb93a386Sopenharmony_ci}
163cb93a386Sopenharmony_ci
164cb93a386Sopenharmony_ci/* To get the data of font configuration file
165cb93a386Sopenharmony_ci * \param fname the full name of the font configuration file
166cb93a386Sopenharmony_ci * \param[out] size the size of data returned to the caller
167cb93a386Sopenharmony_ci * \return The pointer of content of the file
168cb93a386Sopenharmony_ci * \note The returned pointer should be freed by the caller
169cb93a386Sopenharmony_ci */
170cb93a386Sopenharmony_cistd::unique_ptr<char[]> GetDataFromFile(const char* fname, int& size)
171cb93a386Sopenharmony_ci{
172cb93a386Sopenharmony_ci    auto file = std::make_unique<std::ifstream>(fname);
173cb93a386Sopenharmony_ci    if (file == nullptr || !file->is_open()) {
174cb93a386Sopenharmony_ci        size = 0;
175cb93a386Sopenharmony_ci        return nullptr;
176cb93a386Sopenharmony_ci    }
177cb93a386Sopenharmony_ci
178cb93a386Sopenharmony_ci    file->seekg(0, std::ios::end);
179cb93a386Sopenharmony_ci    size = static_cast<int>(file->tellg()); // get the length of file
180cb93a386Sopenharmony_ci    if (size <= 0) {
181cb93a386Sopenharmony_ci        size = 0;
182cb93a386Sopenharmony_ci        return nullptr;
183cb93a386Sopenharmony_ci    }
184cb93a386Sopenharmony_ci    auto data = std::make_unique<char[]>(size);
185cb93a386Sopenharmony_ci    if (data == nullptr) {
186cb93a386Sopenharmony_ci        size = 0;
187cb93a386Sopenharmony_ci        return nullptr;
188cb93a386Sopenharmony_ci    }
189cb93a386Sopenharmony_ci    file->seekg(0, std::ios::beg);
190cb93a386Sopenharmony_ci    file->read(data.get(), size); // read data a block
191cb93a386Sopenharmony_ci    return data;
192cb93a386Sopenharmony_ci}
193cb93a386Sopenharmony_ci
194cb93a386Sopenharmony_cibool HmSymbolConfig_OHOS::GetHmSymbolEnable()
195cb93a386Sopenharmony_ci{
196cb93a386Sopenharmony_ci#ifdef SK_BUILD_FONT_MGR_FOR_OHOS
197cb93a386Sopenharmony_ci    static bool isHMSymbolEnable =
198cb93a386Sopenharmony_ci        (std::atoi(OHOS::system::GetParameter("persist.sys.graphic.hmsymbolcfg.enable", "1").c_str()) != 0);
199cb93a386Sopenharmony_ci    return isHMSymbolEnable;
200cb93a386Sopenharmony_ci#else
201cb93a386Sopenharmony_ci    return true;
202cb93a386Sopenharmony_ci#endif
203cb93a386Sopenharmony_ci}
204cb93a386Sopenharmony_ci
205cb93a386Sopenharmony_ciHmSymbolConfig_OHOS* HmSymbolConfig_OHOS::GetInstance()
206cb93a386Sopenharmony_ci{
207cb93a386Sopenharmony_ci    static HmSymbolConfig_OHOS singleton;
208cb93a386Sopenharmony_ci    return &singleton;
209cb93a386Sopenharmony_ci}
210cb93a386Sopenharmony_ci
211cb93a386Sopenharmony_ciSymbolLayersGroups HmSymbolConfig_OHOS::GetSymbolLayersGroups(uint16_t glyphId)
212cb93a386Sopenharmony_ci{
213cb93a386Sopenharmony_ci    SymbolLayersGroups symbolLayersGroups;
214cb93a386Sopenharmony_ci    if (hmSymbolConfig_.size() == 0) {
215cb93a386Sopenharmony_ci        return symbolLayersGroups;
216cb93a386Sopenharmony_ci    }
217cb93a386Sopenharmony_ci    auto iter = hmSymbolConfig_.find(glyphId);
218cb93a386Sopenharmony_ci    if (iter != hmSymbolConfig_.end()) {
219cb93a386Sopenharmony_ci        symbolLayersGroups = iter->second;
220cb93a386Sopenharmony_ci    }
221cb93a386Sopenharmony_ci    return symbolLayersGroups;
222cb93a386Sopenharmony_ci}
223cb93a386Sopenharmony_ci
224cb93a386Sopenharmony_cistd::vector<std::vector<PiecewiseParameter>> HmSymbolConfig_OHOS::GetGroupParameters(AnimationType type,
225cb93a386Sopenharmony_ci    uint16_t groupSum, uint16_t animationMode, CommonSubType commonSubType)
226cb93a386Sopenharmony_ci{
227cb93a386Sopenharmony_ci    std::vector<std::vector<PiecewiseParameter>> groupParametersOut;
228cb93a386Sopenharmony_ci    if (animationInfos_.empty()) {
229cb93a386Sopenharmony_ci        return groupParametersOut;
230cb93a386Sopenharmony_ci    }
231cb93a386Sopenharmony_ci    std::unordered_map<AnimationType, AnimationInfo>::iterator iter = animationInfos_.find(type);
232cb93a386Sopenharmony_ci    if (iter == animationInfos_.end()) {
233cb93a386Sopenharmony_ci        return groupParametersOut;
234cb93a386Sopenharmony_ci    }
235cb93a386Sopenharmony_ci    auto key = EncodeAnimationAttribute(groupSum, animationMode, commonSubType);
236cb93a386Sopenharmony_ci    auto para = iter->second.animationParas.find(key);
237cb93a386Sopenharmony_ci    if (para != iter->second.animationParas.end()) {
238cb93a386Sopenharmony_ci        groupParametersOut = para->second.groupParameters;
239cb93a386Sopenharmony_ci    }
240cb93a386Sopenharmony_ci    return groupParametersOut;
241cb93a386Sopenharmony_ci}
242cb93a386Sopenharmony_ci
243cb93a386Sopenharmony_ci/* check the system font configuration document
244cb93a386Sopenharmony_ci * \param fname the full name of the font configuration document
245cb93a386Sopenharmony_ci * \return NO_ERROR successful
246cb93a386Sopenharmony_ci * \return ERROR_CONFIG_NOT_FOUND config document is not found
247cb93a386Sopenharmony_ci * \return ERROR_CONFIG_FORMAT_NOT_SUPPORTED config document format is not supported
248cb93a386Sopenharmony_ci */
249cb93a386Sopenharmony_ciint HmSymbolConfig_OHOS::CheckConfigFile(const char* fname, Json::Value& root)
250cb93a386Sopenharmony_ci{
251cb93a386Sopenharmony_ci    int size = 0;
252cb93a386Sopenharmony_ci    auto data = GetDataFromFile(fname, size);
253cb93a386Sopenharmony_ci    if (data == nullptr) {
254cb93a386Sopenharmony_ci        return LogErrInfo(ERROR_CONFIG_NOT_FOUND, fname);
255cb93a386Sopenharmony_ci    }
256cb93a386Sopenharmony_ci    JSONCPP_STRING errs;
257cb93a386Sopenharmony_ci    Json::CharReaderBuilder charReaderBuilder;
258cb93a386Sopenharmony_ci    std::unique_ptr<Json::CharReader> jsonReader(charReaderBuilder.newCharReader());
259cb93a386Sopenharmony_ci    bool isJson = jsonReader->parse(data.get(), data.get() + size, &root, &errs);
260cb93a386Sopenharmony_ci    if (!isJson || !errs.empty()) {
261cb93a386Sopenharmony_ci        return LogErrInfo(ERROR_CONFIG_FORMAT_NOT_SUPPORTED, fname);
262cb93a386Sopenharmony_ci    }
263cb93a386Sopenharmony_ci    return NO_ERROR;
264cb93a386Sopenharmony_ci}
265cb93a386Sopenharmony_ci
266cb93a386Sopenharmony_ciint HmSymbolConfig_OHOS::ParseConfigOfHmSymbol(const char* fname, SkString fontDir)
267cb93a386Sopenharmony_ci{
268cb93a386Sopenharmony_ci    std::lock_guard<std::mutex> lock(hmSymbolMut_);
269cb93a386Sopenharmony_ci    if (GetInit()) {
270cb93a386Sopenharmony_ci        return NO_ERROR;
271cb93a386Sopenharmony_ci    }
272cb93a386Sopenharmony_ci    if (fname == nullptr || strlen(fname) == 0) {
273cb93a386Sopenharmony_ci        return ERROR_CONFIG_NOT_FOUND;
274cb93a386Sopenharmony_ci    }
275cb93a386Sopenharmony_ci    Clear();
276cb93a386Sopenharmony_ci    if (fontDir.size() == 0) {
277cb93a386Sopenharmony_ci        fontDir.append(".");
278cb93a386Sopenharmony_ci    }
279cb93a386Sopenharmony_ci    std::string fullname(fontDir.c_str(), fontDir.size());
280cb93a386Sopenharmony_ci    char separator = '/';
281cb93a386Sopenharmony_ci#if defined(SK_BUILD_FONT_MGR_FOR_PREVIEW_WIN)
282cb93a386Sopenharmony_ci    separator = '\\';
283cb93a386Sopenharmony_ci#endif
284cb93a386Sopenharmony_ci    if (fontDir[fontDir.size() - 1] != separator) {
285cb93a386Sopenharmony_ci        fullname += separator;
286cb93a386Sopenharmony_ci    }
287cb93a386Sopenharmony_ci    std::string fnameStr(fname, strlen(fname));
288cb93a386Sopenharmony_ci    fullname += fnameStr;
289cb93a386Sopenharmony_ci    Json::Value root;
290cb93a386Sopenharmony_ci    int err = CheckConfigFile(fullname.c_str(), root);
291cb93a386Sopenharmony_ci    if (err != NO_ERROR) {
292cb93a386Sopenharmony_ci        return err;
293cb93a386Sopenharmony_ci    }
294cb93a386Sopenharmony_ci
295cb93a386Sopenharmony_ci    const char* key = nullptr;
296cb93a386Sopenharmony_ci    std::vector<std::string> tags = {COMMON_ANIMATIONS, SPECIAL_ANIMATIONS, SYMBOL_LAYERS_GROUPING};
297cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < tags.size(); i++) {
298cb93a386Sopenharmony_ci        key = tags[i].c_str();
299cb93a386Sopenharmony_ci        if (!root.isMember(key) || !root[key].isArray()) {
300cb93a386Sopenharmony_ci            continue;
301cb93a386Sopenharmony_ci        }
302cb93a386Sopenharmony_ci        if (!strcmp(key, COMMON_ANIMATIONS) || !strcmp(key, SPECIAL_ANIMATIONS)) {
303cb93a386Sopenharmony_ci            ParseSymbolAnimations(root[key], &animationInfos_);
304cb93a386Sopenharmony_ci        } else {
305cb93a386Sopenharmony_ci            ParseSymbolLayersGrouping(root[key]);
306cb93a386Sopenharmony_ci        }
307cb93a386Sopenharmony_ci    }
308cb93a386Sopenharmony_ci    root.clear();
309cb93a386Sopenharmony_ci    SetInit(true);
310cb93a386Sopenharmony_ci    return NO_ERROR;
311cb93a386Sopenharmony_ci}
312cb93a386Sopenharmony_ci
313cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseSymbolAnimations(const Json::Value& root,
314cb93a386Sopenharmony_ci    std::unordered_map<AnimationType, AnimationInfo>* animationInfos)
315cb93a386Sopenharmony_ci{
316cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
317cb93a386Sopenharmony_ci        if (!root[i].isObject()) {
318cb93a386Sopenharmony_ci            SkDebugf("animation is not object!");
319cb93a386Sopenharmony_ci            continue;
320cb93a386Sopenharmony_ci        }
321cb93a386Sopenharmony_ci
322cb93a386Sopenharmony_ci        if (!root[i].isMember(ANIMATION_TYPE) || !root[i].isMember(ANIMATION_PARAMETERS)) {
323cb93a386Sopenharmony_ci            continue;
324cb93a386Sopenharmony_ci        }
325cb93a386Sopenharmony_ci        AnimationInfo animationInfo;
326cb93a386Sopenharmony_ci        if (!root[i][ANIMATION_TYPE].isString()) {
327cb93a386Sopenharmony_ci            SkDebugf("animation_type is not string!");
328cb93a386Sopenharmony_ci            continue;
329cb93a386Sopenharmony_ci        }
330cb93a386Sopenharmony_ci        const std::string animationType = root[i][ANIMATION_TYPE].asCString();
331cb93a386Sopenharmony_ci        ParseAnimationType(animationType, animationInfo.animationType);
332cb93a386Sopenharmony_ci
333cb93a386Sopenharmony_ci        if (!root[i][ANIMATION_PARAMETERS].isArray()) {
334cb93a386Sopenharmony_ci            SkDebugf("animation_parameters is not array!");
335cb93a386Sopenharmony_ci            continue;
336cb93a386Sopenharmony_ci        }
337cb93a386Sopenharmony_ci        ParseSymbolAnimationParas(root[i][ANIMATION_PARAMETERS], animationInfo.animationParas);
338cb93a386Sopenharmony_ci        animationInfos->insert({animationInfo.animationType, animationInfo});
339cb93a386Sopenharmony_ci    }
340cb93a386Sopenharmony_ci}
341cb93a386Sopenharmony_ci
342cb93a386Sopenharmony_ciuint32_t HmSymbolConfig_OHOS::EncodeAnimationAttribute(uint16_t groupSum, uint16_t animationMode,
343cb93a386Sopenharmony_ci    CommonSubType commonSubType)
344cb93a386Sopenharmony_ci{
345cb93a386Sopenharmony_ci    uint32_t result = static_cast<uint32_t>(groupSum);
346cb93a386Sopenharmony_ci    result = (result << oneByteBitsLen) + static_cast<uint32_t>(animationMode);
347cb93a386Sopenharmony_ci    result = (result << oneByteBitsLen) + static_cast<uint32_t>(commonSubType);
348cb93a386Sopenharmony_ci    return result;
349cb93a386Sopenharmony_ci}
350cb93a386Sopenharmony_ci
351cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseSymbolAnimationParas(const Json::Value& root,
352cb93a386Sopenharmony_ci    std::map<uint32_t, AnimationPara>& animationParas)
353cb93a386Sopenharmony_ci{
354cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
355cb93a386Sopenharmony_ci        if (!root[i].isObject()) {
356cb93a386Sopenharmony_ci            SkDebugf("animation_parameter is not object!");
357cb93a386Sopenharmony_ci            continue;
358cb93a386Sopenharmony_ci        }
359cb93a386Sopenharmony_ci        AnimationPara animationPara;
360cb93a386Sopenharmony_ci        ParseSymbolAnimationPara(root[i], animationPara);
361cb93a386Sopenharmony_ci        uint32_t attributeKey = EncodeAnimationAttribute(animationPara.groupParameters.size(),
362cb93a386Sopenharmony_ci            animationPara.animationMode, animationPara.commonSubType);
363cb93a386Sopenharmony_ci        animationParas.insert({attributeKey, animationPara});
364cb93a386Sopenharmony_ci    }
365cb93a386Sopenharmony_ci}
366cb93a386Sopenharmony_ci
367cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseSymbolAnimationPara(const Json::Value& root, AnimationPara& animationPara)
368cb93a386Sopenharmony_ci{
369cb93a386Sopenharmony_ci    const char* key = nullptr;
370cb93a386Sopenharmony_ci    std::vector<std::string> tags = {ANIMATION_MODE, COMMON_SUB_TYPE, GROUP_PARAMETERS};
371cb93a386Sopenharmony_ci    using SymnolAniFuncMap = std::unordered_map<std::string, SymnolAniFunc>;
372cb93a386Sopenharmony_ci    SymnolAniFuncMap funcMap = {
373cb93a386Sopenharmony_ci        {ANIMATION_MODE, [](const char* key, const Json::Value& root, AnimationPara& animationPara)
374cb93a386Sopenharmony_ci            {
375cb93a386Sopenharmony_ci                if (!root[key].isInt()) {
376cb93a386Sopenharmony_ci                    SkDebugf("animation_mode is not int!");
377cb93a386Sopenharmony_ci                    return;
378cb93a386Sopenharmony_ci                }
379cb93a386Sopenharmony_ci                animationPara.animationMode = root[key].asInt();
380cb93a386Sopenharmony_ci            }
381cb93a386Sopenharmony_ci        },
382cb93a386Sopenharmony_ci        {COMMON_SUB_TYPE, [this](const char* key, const Json::Value& root, AnimationPara& animationPara)
383cb93a386Sopenharmony_ci            {
384cb93a386Sopenharmony_ci                if (!root[key].isString()) {
385cb93a386Sopenharmony_ci                    SkDebugf("sub_type is not string!");
386cb93a386Sopenharmony_ci                    return;
387cb93a386Sopenharmony_ci                }
388cb93a386Sopenharmony_ci                const char* subTypeStr = root[key].asCString();
389cb93a386Sopenharmony_ci                ParseSymbolCommonSubType(subTypeStr, animationPara.commonSubType);
390cb93a386Sopenharmony_ci            }
391cb93a386Sopenharmony_ci        },
392cb93a386Sopenharmony_ci        {GROUP_PARAMETERS, [this](const char* key, const Json::Value& root, AnimationPara& animationPara)
393cb93a386Sopenharmony_ci            {
394cb93a386Sopenharmony_ci                if (!root[key].isArray()) {
395cb93a386Sopenharmony_ci                    SkDebugf("group_parameters is not array!");
396cb93a386Sopenharmony_ci                    return;
397cb93a386Sopenharmony_ci                }
398cb93a386Sopenharmony_ci                ParseSymbolGroupParas(root[key], animationPara.groupParameters);
399cb93a386Sopenharmony_ci            }
400cb93a386Sopenharmony_ci        }
401cb93a386Sopenharmony_ci    };
402cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < tags.size(); i++) {
403cb93a386Sopenharmony_ci        key = tags[i].c_str();
404cb93a386Sopenharmony_ci        if (!root.isMember(key)) {
405cb93a386Sopenharmony_ci            continue;
406cb93a386Sopenharmony_ci        }
407cb93a386Sopenharmony_ci        if (funcMap.count(key) > 0) {
408cb93a386Sopenharmony_ci            funcMap[key](key, root, animationPara);
409cb93a386Sopenharmony_ci        }
410cb93a386Sopenharmony_ci    }
411cb93a386Sopenharmony_ci}
412cb93a386Sopenharmony_ci
413cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseSymbolCommonSubType(const char* subTypeStr, CommonSubType& commonSubType)
414cb93a386Sopenharmony_ci{
415cb93a386Sopenharmony_ci    using SymbolAniSubFuncMap = std::unordered_map<std::string, std::function<void(CommonSubType&)>>;
416cb93a386Sopenharmony_ci    SymbolAniSubFuncMap funcMap = {
417cb93a386Sopenharmony_ci        {
418cb93a386Sopenharmony_ci            "up",
419cb93a386Sopenharmony_ci            [](CommonSubType& commonSubType) {
420cb93a386Sopenharmony_ci                commonSubType = CommonSubType::UP;
421cb93a386Sopenharmony_ci            }
422cb93a386Sopenharmony_ci        },
423cb93a386Sopenharmony_ci        {
424cb93a386Sopenharmony_ci            "down",
425cb93a386Sopenharmony_ci            [](CommonSubType& commonSubType) {
426cb93a386Sopenharmony_ci                commonSubType = CommonSubType::DOWN;
427cb93a386Sopenharmony_ci            }
428cb93a386Sopenharmony_ci        }
429cb93a386Sopenharmony_ci    };
430cb93a386Sopenharmony_ci    if (funcMap.count(subTypeStr) > 0) {
431cb93a386Sopenharmony_ci        funcMap[subTypeStr](commonSubType);
432cb93a386Sopenharmony_ci        return;
433cb93a386Sopenharmony_ci    }
434cb93a386Sopenharmony_ci    SkDebugf("%{public}s is invalid value!", subTypeStr);
435cb93a386Sopenharmony_ci}
436cb93a386Sopenharmony_ci
437cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseSymbolGroupParas(const Json::Value& root,
438cb93a386Sopenharmony_ci    std::vector<std::vector<PiecewiseParameter>>& groupParameters)
439cb93a386Sopenharmony_ci{
440cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
441cb93a386Sopenharmony_ci        if (!root[i].isArray()) {
442cb93a386Sopenharmony_ci            SkDebugf("group_parameter is not array!");
443cb93a386Sopenharmony_ci            continue;
444cb93a386Sopenharmony_ci        }
445cb93a386Sopenharmony_ci        std::vector<PiecewiseParameter> piecewiseParameters;
446cb93a386Sopenharmony_ci        for (unsigned int j = 0; j < root[i].size(); j++) {
447cb93a386Sopenharmony_ci            if (!root[i][j].isObject()) {
448cb93a386Sopenharmony_ci                SkDebugf("piecewise_parameter is not object!");
449cb93a386Sopenharmony_ci                continue;
450cb93a386Sopenharmony_ci            }
451cb93a386Sopenharmony_ci            PiecewiseParameter piecewiseParameter;
452cb93a386Sopenharmony_ci            ParseSymbolPiecewisePara(root[i][j], piecewiseParameter);
453cb93a386Sopenharmony_ci            piecewiseParameters.push_back(piecewiseParameter);
454cb93a386Sopenharmony_ci        }
455cb93a386Sopenharmony_ci
456cb93a386Sopenharmony_ci        groupParameters.push_back(piecewiseParameters);
457cb93a386Sopenharmony_ci    }
458cb93a386Sopenharmony_ci}
459cb93a386Sopenharmony_ci
460cb93a386Sopenharmony_ci
461cb93a386Sopenharmony_cistatic void PiecewiseParaCurveCase(const char* key, const Json::Value& root, PiecewiseParameter& piecewiseParameter)
462cb93a386Sopenharmony_ci{
463cb93a386Sopenharmony_ci    if (!root[key].isString()) {
464cb93a386Sopenharmony_ci        SkDebugf("curve is not string!");
465cb93a386Sopenharmony_ci        return;
466cb93a386Sopenharmony_ci    }
467cb93a386Sopenharmony_ci    const std::string curveTypeStr = root[key].asCString();
468cb93a386Sopenharmony_ci    auto iter = CURVE_TYPES.find(curveTypeStr);
469cb93a386Sopenharmony_ci    if (iter != CURVE_TYPES.end()) {
470cb93a386Sopenharmony_ci        piecewiseParameter.curveType = iter->second;
471cb93a386Sopenharmony_ci        return;
472cb93a386Sopenharmony_ci    }
473cb93a386Sopenharmony_ci    SkDebugf("curve is invalid value!");
474cb93a386Sopenharmony_ci}
475cb93a386Sopenharmony_ci
476cb93a386Sopenharmony_cistatic void PiecewiseParaDurationCase(const char* key, const Json::Value& root,
477cb93a386Sopenharmony_ci    PiecewiseParameter& piecewiseParameter)
478cb93a386Sopenharmony_ci{
479cb93a386Sopenharmony_ci    if (!root[key].isNumeric()) {
480cb93a386Sopenharmony_ci        SkDebugf("duration is not numeric!");
481cb93a386Sopenharmony_ci        return;
482cb93a386Sopenharmony_ci    }
483cb93a386Sopenharmony_ci    piecewiseParameter.duration = static_cast<uint32_t>(root[key].asDouble());
484cb93a386Sopenharmony_ci}
485cb93a386Sopenharmony_ci
486cb93a386Sopenharmony_cistatic void PiecewiseParaDelayCase(const char* key, const Json::Value& root, PiecewiseParameter& piecewiseParameter)
487cb93a386Sopenharmony_ci{
488cb93a386Sopenharmony_ci    if (!root[key].isNumeric()) {
489cb93a386Sopenharmony_ci        SkDebugf("delay is not numeric!");
490cb93a386Sopenharmony_ci        return;
491cb93a386Sopenharmony_ci    }
492cb93a386Sopenharmony_ci    piecewiseParameter.delay = static_cast<int>(root[key].asDouble());
493cb93a386Sopenharmony_ci}
494cb93a386Sopenharmony_ci
495cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseSymbolPiecewisePara(const Json::Value& root, PiecewiseParameter& piecewiseParameter)
496cb93a386Sopenharmony_ci{
497cb93a386Sopenharmony_ci    const char* key = nullptr;
498cb93a386Sopenharmony_ci    std::vector<std::string> tags = {CURVE, CURVE_ARGS, DURATION, DELAY, PROPERTIES};
499cb93a386Sopenharmony_ci    using PiecewiseFuncMap = std::unordered_map<std::string, PiecewiseParaKeyFunc>;
500cb93a386Sopenharmony_ci    PiecewiseFuncMap funcMap = {
501cb93a386Sopenharmony_ci        {CURVE, PiecewiseParaCurveCase},
502cb93a386Sopenharmony_ci        {CURVE_ARGS, [this](const char* key, const Json::Value& root, PiecewiseParameter& piecewiseParameter)
503cb93a386Sopenharmony_ci            {
504cb93a386Sopenharmony_ci                if (!root[key].isObject()) {
505cb93a386Sopenharmony_ci                    SkDebugf("curve_args is not object!");
506cb93a386Sopenharmony_ci                    return;
507cb93a386Sopenharmony_ci                }
508cb93a386Sopenharmony_ci                ParseSymbolCurveArgs(root[key], piecewiseParameter.curveArgs);
509cb93a386Sopenharmony_ci            }
510cb93a386Sopenharmony_ci        },
511cb93a386Sopenharmony_ci        {DURATION, PiecewiseParaDurationCase},
512cb93a386Sopenharmony_ci        {DELAY, PiecewiseParaDelayCase},
513cb93a386Sopenharmony_ci        {PROPERTIES, [this](const char* key, const Json::Value& root, PiecewiseParameter& piecewiseParameter)
514cb93a386Sopenharmony_ci            {
515cb93a386Sopenharmony_ci                if (!root[key].isObject()) {
516cb93a386Sopenharmony_ci                    SkDebugf("properties is not object!");
517cb93a386Sopenharmony_ci                    return;
518cb93a386Sopenharmony_ci                }
519cb93a386Sopenharmony_ci                ParseSymbolProperties(root[key], piecewiseParameter.properties);
520cb93a386Sopenharmony_ci            }
521cb93a386Sopenharmony_ci        }
522cb93a386Sopenharmony_ci    };
523cb93a386Sopenharmony_ci
524cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < tags.size(); i++) {
525cb93a386Sopenharmony_ci        key = tags[i].c_str();
526cb93a386Sopenharmony_ci        if (!root.isMember(key)) {
527cb93a386Sopenharmony_ci            continue;
528cb93a386Sopenharmony_ci        }
529cb93a386Sopenharmony_ci        if (funcMap.count(key) > 0) {
530cb93a386Sopenharmony_ci            funcMap[key](key, root, piecewiseParameter);
531cb93a386Sopenharmony_ci        }
532cb93a386Sopenharmony_ci    }
533cb93a386Sopenharmony_ci}
534cb93a386Sopenharmony_ci
535cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseSymbolCurveArgs(const Json::Value& root, std::map<std::string, float>& curveArgs)
536cb93a386Sopenharmony_ci{
537cb93a386Sopenharmony_ci    if (root.empty()) {
538cb93a386Sopenharmony_ci        return;
539cb93a386Sopenharmony_ci    }
540cb93a386Sopenharmony_ci
541cb93a386Sopenharmony_ci    for (Json::Value::const_iterator iter = root.begin(); iter != root.end(); ++iter) {
542cb93a386Sopenharmony_ci        std::string name = iter.name();
543cb93a386Sopenharmony_ci        const char* memberName = name.c_str();
544cb93a386Sopenharmony_ci        if (!root[memberName].isNumeric()) {
545cb93a386Sopenharmony_ci            SkDebugf("%{public}s is not numeric!", memberName);
546cb93a386Sopenharmony_ci            continue;
547cb93a386Sopenharmony_ci        }
548cb93a386Sopenharmony_ci        curveArgs.insert({std::string(memberName), root[memberName].asFloat()});
549cb93a386Sopenharmony_ci    }
550cb93a386Sopenharmony_ci}
551cb93a386Sopenharmony_ci
552cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseSymbolProperties(const Json::Value& root,
553cb93a386Sopenharmony_ci    std::map<std::string, std::vector<float>>& properties)
554cb93a386Sopenharmony_ci{
555cb93a386Sopenharmony_ci    for (Json::Value::const_iterator iter = root.begin(); iter != root.end(); ++iter) {
556cb93a386Sopenharmony_ci        std::string name = iter.name();
557cb93a386Sopenharmony_ci        const char* memberName = name.c_str();
558cb93a386Sopenharmony_ci        if (!root[memberName].isArray()) {
559cb93a386Sopenharmony_ci            SkDebugf("%{public}s is not array!", memberName);
560cb93a386Sopenharmony_ci            continue;
561cb93a386Sopenharmony_ci        }
562cb93a386Sopenharmony_ci
563cb93a386Sopenharmony_ci        std::vector<float> propertyValues;
564cb93a386Sopenharmony_ci        for (unsigned int i = 0; i < root[memberName].size(); i++) {
565cb93a386Sopenharmony_ci            if (!root[memberName][i].isNumeric()) {
566cb93a386Sopenharmony_ci                SkDebugf("property value is not numeric!");
567cb93a386Sopenharmony_ci                continue;
568cb93a386Sopenharmony_ci            }
569cb93a386Sopenharmony_ci            propertyValues.push_back(root[memberName][i].asFloat());
570cb93a386Sopenharmony_ci        }
571cb93a386Sopenharmony_ci
572cb93a386Sopenharmony_ci        properties.insert({std::string(memberName), propertyValues});
573cb93a386Sopenharmony_ci    }
574cb93a386Sopenharmony_ci}
575cb93a386Sopenharmony_ci
576cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseSymbolLayersGrouping(const Json::Value& root)
577cb93a386Sopenharmony_ci{
578cb93a386Sopenharmony_ci    std::unordered_map<uint16_t, SymbolLayersGroups>* hmSymbolConfig
579cb93a386Sopenharmony_ci        = &hmSymbolConfig_;
580cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
581cb93a386Sopenharmony_ci        if (!root[i].isObject()) {
582cb93a386Sopenharmony_ci            SkDebugf("symbol_layers_grouping[%{public}d] is not object!", i);
583cb93a386Sopenharmony_ci            continue;
584cb93a386Sopenharmony_ci        }
585cb93a386Sopenharmony_ci        ParseOneSymbol(root[i], hmSymbolConfig);
586cb93a386Sopenharmony_ci    }
587cb93a386Sopenharmony_ci}
588cb93a386Sopenharmony_ci
589cb93a386Sopenharmony_cistatic void SymbolGlyphCase(const char* key, const Json::Value& root, SymbolLayersGroups& symbolLayersGroups)
590cb93a386Sopenharmony_ci{
591cb93a386Sopenharmony_ci    if (!root[key].isInt()) {
592cb93a386Sopenharmony_ci        SkDebugf("symbol_glyph_id is not int!");
593cb93a386Sopenharmony_ci        return;
594cb93a386Sopenharmony_ci    }
595cb93a386Sopenharmony_ci    symbolLayersGroups.symbolGlyphId = root[key].asInt();
596cb93a386Sopenharmony_ci}
597cb93a386Sopenharmony_ci
598cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseOneSymbolNativeCase(const char* key, const Json::Value& root,
599cb93a386Sopenharmony_ci    SymbolLayersGroups& symbolLayersGroups, uint16_t& nativeGlyphId)
600cb93a386Sopenharmony_ci{
601cb93a386Sopenharmony_ci    if (!root[key].isInt()) {
602cb93a386Sopenharmony_ci        SkDebugf("native_glyph_id is not int!");
603cb93a386Sopenharmony_ci        return;
604cb93a386Sopenharmony_ci    }
605cb93a386Sopenharmony_ci    nativeGlyphId = root[key].asInt();
606cb93a386Sopenharmony_ci}
607cb93a386Sopenharmony_ci
608cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseOneSymbolLayerCase(const char* key, const Json::Value& root,
609cb93a386Sopenharmony_ci    SymbolLayersGroups& symbolLayersGroups)
610cb93a386Sopenharmony_ci{
611cb93a386Sopenharmony_ci    if (!root[key].isArray()) {
612cb93a386Sopenharmony_ci        SkDebugf("layers is not array!");
613cb93a386Sopenharmony_ci        return;
614cb93a386Sopenharmony_ci    }
615cb93a386Sopenharmony_ci    ParseLayers(root[key], symbolLayersGroups.layers);
616cb93a386Sopenharmony_ci}
617cb93a386Sopenharmony_ci
618cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseOneSymbolRenderCase(const char* key, const Json::Value& root,
619cb93a386Sopenharmony_ci    SymbolLayersGroups& symbolLayersGroups)
620cb93a386Sopenharmony_ci{
621cb93a386Sopenharmony_ci    if (!root[key].isArray()) {
622cb93a386Sopenharmony_ci        SkDebugf("render_modes is not array!");
623cb93a386Sopenharmony_ci        return;
624cb93a386Sopenharmony_ci    }
625cb93a386Sopenharmony_ci    ParseRenderModes(root[key], symbolLayersGroups.renderModeGroups);
626cb93a386Sopenharmony_ci}
627cb93a386Sopenharmony_ci
628cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseOneSymbolAnimateCase(const char* key, const Json::Value& root,
629cb93a386Sopenharmony_ci    SymbolLayersGroups& symbolLayersGroups)
630cb93a386Sopenharmony_ci{
631cb93a386Sopenharmony_ci    if (!root[key].isArray()) {
632cb93a386Sopenharmony_ci        SkDebugf("animation_settings is not array!");
633cb93a386Sopenharmony_ci        return;
634cb93a386Sopenharmony_ci    }
635cb93a386Sopenharmony_ci    ParseAnimationSettings(root[key], symbolLayersGroups.animationSettings);
636cb93a386Sopenharmony_ci}
637cb93a386Sopenharmony_ci
638cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseOneSymbol(const Json::Value& root,
639cb93a386Sopenharmony_ci    std::unordered_map<uint16_t, SymbolLayersGroups>* hmSymbolConfig)
640cb93a386Sopenharmony_ci{
641cb93a386Sopenharmony_ci    const char* key = nullptr;
642cb93a386Sopenharmony_ci    std::vector<std::string> tags = {NATIVE_GLYPH_ID, SYMBOL_GLYPH_ID, LAYERS, RENDER_MODES, ANIMATION_SETTINGS};
643cb93a386Sopenharmony_ci    uint16_t nativeGlyphId;
644cb93a386Sopenharmony_ci    SymbolLayersGroups symbolLayersGroups;
645cb93a386Sopenharmony_ci
646cb93a386Sopenharmony_ci    SymbolKeyFuncMap funcMap = {
647cb93a386Sopenharmony_ci        {NATIVE_GLYPH_ID, [this, &nativeGlyphId](const char* key, const Json::Value& root,
648cb93a386Sopenharmony_ci            SymbolLayersGroups& symbolLayersGroups)
649cb93a386Sopenharmony_ci            {
650cb93a386Sopenharmony_ci                ParseOneSymbolNativeCase(key, root, symbolLayersGroups, nativeGlyphId);
651cb93a386Sopenharmony_ci            }
652cb93a386Sopenharmony_ci        },
653cb93a386Sopenharmony_ci        {SYMBOL_GLYPH_ID, SymbolGlyphCase},
654cb93a386Sopenharmony_ci        {LAYERS, [this](const char* key, const Json::Value& root, SymbolLayersGroups& symbolLayersGroups)
655cb93a386Sopenharmony_ci            {
656cb93a386Sopenharmony_ci                ParseOneSymbolLayerCase(key, root, symbolLayersGroups);
657cb93a386Sopenharmony_ci            }
658cb93a386Sopenharmony_ci        },
659cb93a386Sopenharmony_ci        {RENDER_MODES, [this](const char* key, const Json::Value& root, SymbolLayersGroups& symbolLayersGroups)
660cb93a386Sopenharmony_ci            {
661cb93a386Sopenharmony_ci                ParseOneSymbolRenderCase(key, root, symbolLayersGroups);
662cb93a386Sopenharmony_ci            }
663cb93a386Sopenharmony_ci        },
664cb93a386Sopenharmony_ci        {ANIMATION_SETTINGS, [this](const char* key, const Json::Value& root,
665cb93a386Sopenharmony_ci            SymbolLayersGroups& symbolLayersGroups)
666cb93a386Sopenharmony_ci            {
667cb93a386Sopenharmony_ci                ParseOneSymbolAnimateCase(key, root, symbolLayersGroups);
668cb93a386Sopenharmony_ci            }
669cb93a386Sopenharmony_ci        }
670cb93a386Sopenharmony_ci    };
671cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < tags.size(); i++) {
672cb93a386Sopenharmony_ci        key = tags[i].c_str();
673cb93a386Sopenharmony_ci        if (!root.isMember(key)) {
674cb93a386Sopenharmony_ci            continue;
675cb93a386Sopenharmony_ci        }
676cb93a386Sopenharmony_ci        if (funcMap.count(key) > 0) {
677cb93a386Sopenharmony_ci            funcMap[key](key, root, symbolLayersGroups);
678cb93a386Sopenharmony_ci        }
679cb93a386Sopenharmony_ci    }
680cb93a386Sopenharmony_ci    hmSymbolConfig->insert({nativeGlyphId, symbolLayersGroups});
681cb93a386Sopenharmony_ci}
682cb93a386Sopenharmony_ci
683cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseLayers(const Json::Value& root, std::vector<std::vector<size_t>>& layers)
684cb93a386Sopenharmony_ci{
685cb93a386Sopenharmony_ci    const char* key = "components";
686cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
687cb93a386Sopenharmony_ci        if (!root[i].isObject()) {
688cb93a386Sopenharmony_ci            SkDebugf("layer is not object!");
689cb93a386Sopenharmony_ci            continue;
690cb93a386Sopenharmony_ci        }
691cb93a386Sopenharmony_ci
692cb93a386Sopenharmony_ci        if (!root[i].isMember(key)) {
693cb93a386Sopenharmony_ci            continue;
694cb93a386Sopenharmony_ci        }
695cb93a386Sopenharmony_ci        if (!root[i][key].isArray()) {
696cb93a386Sopenharmony_ci            SkDebugf("components is not array!");
697cb93a386Sopenharmony_ci            continue;
698cb93a386Sopenharmony_ci        }
699cb93a386Sopenharmony_ci        std::vector<size_t> components;
700cb93a386Sopenharmony_ci        ParseComponets(root[i][key], components);
701cb93a386Sopenharmony_ci        layers.push_back(components);
702cb93a386Sopenharmony_ci    }
703cb93a386Sopenharmony_ci}
704cb93a386Sopenharmony_ci
705cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseComponets(const Json::Value& root, std::vector<size_t>& components)
706cb93a386Sopenharmony_ci{
707cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
708cb93a386Sopenharmony_ci        if (!root[i].isInt()) {
709cb93a386Sopenharmony_ci            SkDebugf("component is not int!");
710cb93a386Sopenharmony_ci            continue;
711cb93a386Sopenharmony_ci        }
712cb93a386Sopenharmony_ci        components.push_back(root[i].asInt());
713cb93a386Sopenharmony_ci    }
714cb93a386Sopenharmony_ci}
715cb93a386Sopenharmony_ci
716cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseRenderModes(const Json::Value& root, std::map<SymbolRenderingStrategy,
717cb93a386Sopenharmony_ci    std::vector<RenderGroup>>& renderModesGroups)
718cb93a386Sopenharmony_ci{
719cb93a386Sopenharmony_ci    std::unordered_map<std::string, SymbolRenderingStrategy> strategeMap = {
720cb93a386Sopenharmony_ci        {"monochrome", SymbolRenderingStrategy::SINGLE},
721cb93a386Sopenharmony_ci        {"multicolor", SymbolRenderingStrategy::MULTIPLE_COLOR},
722cb93a386Sopenharmony_ci        {"hierarchical", SymbolRenderingStrategy::MULTIPLE_OPACITY},
723cb93a386Sopenharmony_ci    };
724cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
725cb93a386Sopenharmony_ci        if (!root[i].isObject()) {
726cb93a386Sopenharmony_ci            SkDebugf("render_mode is not object!");
727cb93a386Sopenharmony_ci            continue;
728cb93a386Sopenharmony_ci        }
729cb93a386Sopenharmony_ci
730cb93a386Sopenharmony_ci        SymbolRenderingStrategy renderingStrategy;
731cb93a386Sopenharmony_ci        std::vector<RenderGroup> renderGroups;
732cb93a386Sopenharmony_ci        if (root[i].isMember(MODE)) {
733cb93a386Sopenharmony_ci            if (!root[i][MODE].isString()) {
734cb93a386Sopenharmony_ci                SkDebugf("mode is not string!");
735cb93a386Sopenharmony_ci                continue;
736cb93a386Sopenharmony_ci            }
737cb93a386Sopenharmony_ci            std::string modeValue = root[i][MODE].asCString();
738cb93a386Sopenharmony_ci            if (strategeMap.count(modeValue) > 0) {
739cb93a386Sopenharmony_ci                renderingStrategy = strategeMap[modeValue];
740cb93a386Sopenharmony_ci            } else {
741cb93a386Sopenharmony_ci                SkDebugf("%{public}s is invalid value!", modeValue.c_str());
742cb93a386Sopenharmony_ci                continue;
743cb93a386Sopenharmony_ci            }
744cb93a386Sopenharmony_ci        }
745cb93a386Sopenharmony_ci        if (root[i].isMember(RENDER_GROUPS)) {
746cb93a386Sopenharmony_ci            if (!root[i][RENDER_GROUPS].isArray()) {
747cb93a386Sopenharmony_ci                SkDebugf("render_groups is not array!");
748cb93a386Sopenharmony_ci                continue;
749cb93a386Sopenharmony_ci            }
750cb93a386Sopenharmony_ci            ParseRenderGroups(root[i][RENDER_GROUPS], renderGroups);
751cb93a386Sopenharmony_ci        }
752cb93a386Sopenharmony_ci        renderModesGroups.insert({renderingStrategy, renderGroups});
753cb93a386Sopenharmony_ci    }
754cb93a386Sopenharmony_ci}
755cb93a386Sopenharmony_ci
756cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseRenderGroups(const Json::Value& root, std::vector<RenderGroup>& renderGroups)
757cb93a386Sopenharmony_ci{
758cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
759cb93a386Sopenharmony_ci        if (!root[i].isObject()) {
760cb93a386Sopenharmony_ci            SkDebugf("render_group is not object!");
761cb93a386Sopenharmony_ci            continue;
762cb93a386Sopenharmony_ci        }
763cb93a386Sopenharmony_ci
764cb93a386Sopenharmony_ci        RenderGroup renderGroup;
765cb93a386Sopenharmony_ci        if (root[i].isMember(GROUP_INDEXES) && root[i][GROUP_INDEXES].isArray()) {
766cb93a386Sopenharmony_ci            ParseGroupIndexes(root[i][GROUP_INDEXES], renderGroup.groupInfos);
767cb93a386Sopenharmony_ci        }
768cb93a386Sopenharmony_ci        if (root[i].isMember(DEFAULT_COLOR) && root[i][DEFAULT_COLOR].isString()) {
769cb93a386Sopenharmony_ci            ParseDefaultColor(root[i][DEFAULT_COLOR].asCString(), renderGroup);
770cb93a386Sopenharmony_ci        }
771cb93a386Sopenharmony_ci        if (root[i].isMember(FIX_ALPHA) && root[i][FIX_ALPHA].isDouble()) {
772cb93a386Sopenharmony_ci            renderGroup.color.a = root[i][FIX_ALPHA].asFloat();
773cb93a386Sopenharmony_ci        }
774cb93a386Sopenharmony_ci        renderGroups.push_back(renderGroup);
775cb93a386Sopenharmony_ci    }
776cb93a386Sopenharmony_ci}
777cb93a386Sopenharmony_ci
778cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseGroupIndexes(const Json::Value& root, std::vector<GroupInfo>& groupInfos)
779cb93a386Sopenharmony_ci{
780cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
781cb93a386Sopenharmony_ci        GroupInfo groupInfo;
782cb93a386Sopenharmony_ci        if (root[i].isMember(LAYER_INDEXES)) {
783cb93a386Sopenharmony_ci            if (!root[i][LAYER_INDEXES].isArray()) {
784cb93a386Sopenharmony_ci                SkDebugf("layer_indexes is not array!");
785cb93a386Sopenharmony_ci                continue;
786cb93a386Sopenharmony_ci            }
787cb93a386Sopenharmony_ci            ParseLayerOrMaskIndexes(root[i][LAYER_INDEXES], groupInfo.layerIndexes);
788cb93a386Sopenharmony_ci        }
789cb93a386Sopenharmony_ci        if (root[i].isMember(MASK_INDEXES)) {
790cb93a386Sopenharmony_ci            if (!root[i][MASK_INDEXES].isArray()) {
791cb93a386Sopenharmony_ci                SkDebugf("mask_indexes is not array!");
792cb93a386Sopenharmony_ci                continue;
793cb93a386Sopenharmony_ci            }
794cb93a386Sopenharmony_ci            ParseLayerOrMaskIndexes(root[i][MASK_INDEXES], groupInfo.maskIndexes);
795cb93a386Sopenharmony_ci        }
796cb93a386Sopenharmony_ci        groupInfos.push_back(groupInfo);
797cb93a386Sopenharmony_ci    }
798cb93a386Sopenharmony_ci}
799cb93a386Sopenharmony_ci
800cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseLayerOrMaskIndexes(const Json::Value& root, std::vector<size_t>& indexes)
801cb93a386Sopenharmony_ci{
802cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
803cb93a386Sopenharmony_ci        if (!root[i].isInt()) {
804cb93a386Sopenharmony_ci            SkDebugf("index is not int!");
805cb93a386Sopenharmony_ci            continue;
806cb93a386Sopenharmony_ci        }
807cb93a386Sopenharmony_ci        indexes.push_back(root[i].asInt());
808cb93a386Sopenharmony_ci    }
809cb93a386Sopenharmony_ci}
810cb93a386Sopenharmony_ci
811cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseDefaultColor(const char* defaultColorStr, RenderGroup& renderGroup)
812cb93a386Sopenharmony_ci{
813cb93a386Sopenharmony_ci    char defaultColorHex[defaultColorHexLen];
814cb93a386Sopenharmony_ci    defaultColorHex[0] = '0';
815cb93a386Sopenharmony_ci    defaultColorHex[1] = 'X';
816cb93a386Sopenharmony_ci    if (strlen(defaultColorStr) == defaultColorStrLen) {
817cb93a386Sopenharmony_ci        for (unsigned int i = 1; i < defaultColorStrLen; i++) {
818cb93a386Sopenharmony_ci            defaultColorHex[i + 1] = defaultColorStr[i];
819cb93a386Sopenharmony_ci        }
820cb93a386Sopenharmony_ci        defaultColorHex[defaultColorHexLen - 1] = '\0';
821cb93a386Sopenharmony_ci    } else {
822cb93a386Sopenharmony_ci        SkDebugf("%{public}s is invalid value!", defaultColorStr);
823cb93a386Sopenharmony_ci        return;
824cb93a386Sopenharmony_ci    }
825cb93a386Sopenharmony_ci
826cb93a386Sopenharmony_ci    char* endPtr = nullptr;
827cb93a386Sopenharmony_ci    int defaultColorInt = strtol(defaultColorHex, &endPtr, hexFlag);
828cb93a386Sopenharmony_ci    renderGroup.color.r = (defaultColorInt >> twoBytesBitsLen) & 0xFF;
829cb93a386Sopenharmony_ci    renderGroup.color.g = (defaultColorInt >> oneByteBitsLen) & 0xFF;
830cb93a386Sopenharmony_ci    renderGroup.color.b = defaultColorInt & 0xFF;
831cb93a386Sopenharmony_ci}
832cb93a386Sopenharmony_ci
833cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseAnimationSettings(const Json::Value& root,
834cb93a386Sopenharmony_ci    std::vector<AnimationSetting>& animationSettings)
835cb93a386Sopenharmony_ci{
836cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
837cb93a386Sopenharmony_ci        if (!root[i].isObject()) {
838cb93a386Sopenharmony_ci            SkDebugf("animation_setting is not object!");
839cb93a386Sopenharmony_ci            continue;
840cb93a386Sopenharmony_ci        }
841cb93a386Sopenharmony_ci        AnimationSetting animationSetting;
842cb93a386Sopenharmony_ci        ParseAnimationSetting(root[i], animationSetting);
843cb93a386Sopenharmony_ci        animationSettings.push_back(animationSetting);
844cb93a386Sopenharmony_ci    }
845cb93a386Sopenharmony_ci}
846cb93a386Sopenharmony_ci
847cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseAnimationSetting(const Json::Value& root, AnimationSetting& animationSetting)
848cb93a386Sopenharmony_ci{
849cb93a386Sopenharmony_ci    if (root.isMember(ANIMATION_TYPES) && root[ANIMATION_TYPES].isArray()) {
850cb93a386Sopenharmony_ci        ParseAnimationTypes(root[ANIMATION_TYPES], animationSetting.animationTypes);
851cb93a386Sopenharmony_ci    }
852cb93a386Sopenharmony_ci
853cb93a386Sopenharmony_ci    if (root.isMember(GROUP_SETTINGS) && root[GROUP_SETTINGS].isArray()) {
854cb93a386Sopenharmony_ci        ParseGroupSettings(root[GROUP_SETTINGS], animationSetting.groupSettings);
855cb93a386Sopenharmony_ci    }
856cb93a386Sopenharmony_ci}
857cb93a386Sopenharmony_ci
858cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseAnimationTypes(const Json::Value& root, std::vector<AnimationType>& animationTypes)
859cb93a386Sopenharmony_ci{
860cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
861cb93a386Sopenharmony_ci        if (!root[i].isString()) {
862cb93a386Sopenharmony_ci            SkDebugf("animation_types is not string!");
863cb93a386Sopenharmony_ci            continue;
864cb93a386Sopenharmony_ci        }
865cb93a386Sopenharmony_ci        const std::string animationTypeStr = root[i].asCString();
866cb93a386Sopenharmony_ci        AnimationType animationType;
867cb93a386Sopenharmony_ci        ParseAnimationType(animationTypeStr, animationType);
868cb93a386Sopenharmony_ci        animationTypes.push_back(animationType);
869cb93a386Sopenharmony_ci    }
870cb93a386Sopenharmony_ci}
871cb93a386Sopenharmony_ci
872cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseAnimationType(const std::string& animationTypeStr, AnimationType& animationType)
873cb93a386Sopenharmony_ci{
874cb93a386Sopenharmony_ci    auto iter = ANIMATIONS_TYPES.find(animationTypeStr);
875cb93a386Sopenharmony_ci    if (iter != ANIMATIONS_TYPES.end()) {
876cb93a386Sopenharmony_ci        animationType = iter->second;
877cb93a386Sopenharmony_ci    } else {
878cb93a386Sopenharmony_ci        SkDebugf("%{public}s is invalid value!", animationTypeStr.c_str());
879cb93a386Sopenharmony_ci    }
880cb93a386Sopenharmony_ci}
881cb93a386Sopenharmony_ci
882cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseGroupSettings(const Json::Value& root, std::vector<GroupSetting>& groupSettings)
883cb93a386Sopenharmony_ci{
884cb93a386Sopenharmony_ci    for (unsigned int i = 0; i < root.size(); i++) {
885cb93a386Sopenharmony_ci        if (!root[i].isObject()) {
886cb93a386Sopenharmony_ci            SkDebugf("group_setting is not object!");
887cb93a386Sopenharmony_ci            continue;
888cb93a386Sopenharmony_ci        }
889cb93a386Sopenharmony_ci        GroupSetting groupSetting;
890cb93a386Sopenharmony_ci        ParseGroupSetting(root[i], groupSetting);
891cb93a386Sopenharmony_ci        groupSettings.push_back(groupSetting);
892cb93a386Sopenharmony_ci    }
893cb93a386Sopenharmony_ci}
894cb93a386Sopenharmony_ci
895cb93a386Sopenharmony_civoid HmSymbolConfig_OHOS::ParseGroupSetting(const Json::Value& root, GroupSetting& groupSetting)
896cb93a386Sopenharmony_ci{
897cb93a386Sopenharmony_ci    if (root.isMember(GROUP_INDEXES)) {
898cb93a386Sopenharmony_ci        if (!root[GROUP_INDEXES].isArray()) {
899cb93a386Sopenharmony_ci            SkDebugf("group_indexes is not array!");
900cb93a386Sopenharmony_ci        } else {
901cb93a386Sopenharmony_ci            ParseGroupIndexes(root[GROUP_INDEXES], groupSetting.groupInfos);
902cb93a386Sopenharmony_ci        }
903cb93a386Sopenharmony_ci    }
904cb93a386Sopenharmony_ci
905cb93a386Sopenharmony_ci    if (root.isMember(ANIMATION_INDEX)) {
906cb93a386Sopenharmony_ci        if (!root[ANIMATION_INDEX].isInt()) {
907cb93a386Sopenharmony_ci            SkDebugf("animation_index is not int!");
908cb93a386Sopenharmony_ci        } else {
909cb93a386Sopenharmony_ci            groupSetting.animationIndex = root[ANIMATION_INDEX].asInt();
910cb93a386Sopenharmony_ci        }
911cb93a386Sopenharmony_ci    }
912cb93a386Sopenharmony_ci}