1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components/declaration/span/span_declaration.h"
17 
18 #include "core/components/common/properties/text_style_parser.h"
19 #include "core/components/declaration/common/declaration_constants.h"
20 #include "frameworks/bridge/common/utils/utils.h"
21 
22 namespace OHOS::Ace {
23 namespace {
24 
25 constexpr Dimension DEFAULT_FONT_SIZE = 14.0_px;
26 
27 } // namespace
28 
29 using namespace Framework;
30 
InitCommonEvent()31 void SpanDeclaration::InitCommonEvent()
32 {
33     AddCommonEvent(EventTag::COMMON_RAW_EVENT);
34     AddCommonEvent(EventTag::COMMON_GESTURE_EVENT);
35     AddCommonEvent(EventTag::COMMON_REMOTE_MESSAGE_GESTURE_EVENT);
36 }
37 
InitSpecialized()38 void SpanDeclaration::InitSpecialized()
39 {
40     AddSpecializedAttribute(DeclarationConstants::DEFAULT_SPAN_ATTR);
41     AddSpecializedStyle(DeclarationConstants::DEFAULT_SPAN_STYLE);
42 }
43 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)44 bool SpanDeclaration::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
45 {
46     static const LinearMapNode<void (*)(const std::string&, SpanDeclaration&)> spanStyleOperators[] = {
47         { DOM_SHOW,
48             [](const std::string& val, SpanDeclaration& declaration) { declaration.SetIsShow(StringToBool(val)); } },
49         { DOM_VALUE, [](const std::string& val, SpanDeclaration& declaration) { declaration.SetSpanData(val); } },
50     };
51     auto spanStyleIter = BinarySearchFindIndex(spanStyleOperators, ArraySize(spanStyleOperators), attr.first.c_str());
52     if (spanStyleIter != -1) {
53         spanStyleOperators[spanStyleIter].value(attr.second, *this);
54         return true;
55     }
56     return false;
57 }
58 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)59 bool SpanDeclaration::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
60 {
61     static const LinearMapNode<void (*)(const std::string&, SpanDeclaration&)> spanStyleOperators[] = {
62         { DOM_TEXT_ALLOW_SCALE,
63             [](const std::string& val, SpanDeclaration& declaration) {
64                 auto& specializedStyle = declaration.MaybeResetStyle<SpanStyle>(StyleTag::SPECIALIZED_STYLE);
65                 if (specializedStyle.IsValid()) {
66                     specializedStyle.spanStyle.SetAllowScale(StringToBool(val));
67                 }
68                 declaration.isSetAllowScale_ = true;
69             } },
70         { DOM_TEXT_COLOR,
71             [](const std::string& val, SpanDeclaration& declaration) {
72                 auto& specializedStyle = declaration.MaybeResetStyle<SpanStyle>(StyleTag::SPECIALIZED_STYLE);
73                 if (specializedStyle.IsValid()) {
74                     auto textColor = val.empty() ? Color::BLACK : declaration.ParseColor(val);
75                     specializedStyle.spanStyle.SetTextColor(textColor);
76                 }
77                 declaration.isSetFontColor_ = true;
78             } },
79         { DOM_TEXT_FONT_FAMILY,
80             [](const std::string& val, SpanDeclaration& declaration) {
81                 auto& specializedStyle = declaration.MaybeResetStyle<SpanStyle>(StyleTag::SPECIALIZED_STYLE);
82                 if (specializedStyle.IsValid()) {
83                     specializedStyle.spanStyle.SetFontFamilies(declaration.ParseFontFamilies(val));
84                 }
85                 declaration.isSetFontFamily_ = true;
86             } },
87         { DOM_TEXT_FONT_FEATURE_SETTINGS,
88             [](const std::string& val, SpanDeclaration& declaration) {
89                 auto& specializedStyle = declaration.MaybeResetStyle<SpanStyle>(StyleTag::SPECIALIZED_STYLE);
90                 if (specializedStyle.IsValid()) {
91                     specializedStyle.spanStyle.SetFontFeatures(ParseFontFeatureSettings(val));
92                 }
93                 declaration.isSetFontFeatures_ = true;
94             } },
95         { DOM_TEXT_FONT_SIZE,
96             [](const std::string& val, SpanDeclaration& declaration) {
97                 auto& specializedStyle = declaration.MaybeResetStyle<SpanStyle>(StyleTag::SPECIALIZED_STYLE);
98                 if (specializedStyle.IsValid()) {
99                     auto fontSize = val.empty() ? DEFAULT_FONT_SIZE : declaration.ParseDimension(val);
100                     specializedStyle.spanStyle.SetFontSize(fontSize);
101                 }
102                 declaration.isSetFontSize_ = true;
103             } },
104         { DOM_TEXT_FONT_STYLE,
105             [](const std::string& val, SpanDeclaration& declaration) {
106                 auto& specializedStyle = declaration.MaybeResetStyle<SpanStyle>(StyleTag::SPECIALIZED_STYLE);
107                 if (specializedStyle.IsValid()) {
108                     specializedStyle.spanStyle.SetFontStyle(ConvertStrToFontStyle(val));
109                 }
110                 declaration.isSetFontStyle_ = true;
111             } },
112         { DOM_TEXT_FONT_VARIANT,
113             [](const std::string& val, SpanDeclaration& declaration) {
114                 auto& specializedStyle = declaration.MaybeResetStyle<SpanStyle>(StyleTag::SPECIALIZED_STYLE);
115                 if (specializedStyle.IsValid()) {
116                     specializedStyle.spanStyle.SetFontFeatures(ParseFontVariants(val));
117                 }
118                 declaration.isSetFontFeatures_ = true;
119             } },
120         { DOM_TEXT_FONT_WEIGHT,
121             [](const std::string& val, SpanDeclaration& declaration) {
122                 auto& specializedStyle = declaration.MaybeResetStyle<SpanStyle>(StyleTag::SPECIALIZED_STYLE);
123                 if (specializedStyle.IsValid()) {
124                     specializedStyle.spanStyle.SetFontWeight(ConvertStrToFontWeight(val));
125                 }
126                 declaration.isSetFontWeight_ = true;
127             } },
128         { DOM_TEXT_DECORATION,
129             [](const std::string& val, SpanDeclaration& declaration) {
130                 auto& specializedStyle = declaration.MaybeResetStyle<SpanStyle>(StyleTag::SPECIALIZED_STYLE);
131                 if (specializedStyle.IsValid()) {
132                     specializedStyle.spanStyle.SetTextDecoration(ConvertStrToTextDecoration(val));
133                 }
134                 declaration.isSetTextDecoration_ = true;
135             } },
136         { DOM_TEXT_DECORATION_COLOR,
137             [](const std::string& val, SpanDeclaration& declaration) {
138                 auto& specializedStyle = declaration.MaybeResetStyle<SpanStyle>(StyleTag::SPECIALIZED_STYLE);
139                 if (specializedStyle.IsValid()) {
140                     specializedStyle.spanStyle.SetTextDecorationColor(declaration.ParseColor(val));
141                 }
142                 declaration.isSetTextDecorationColor_ = true;
143             } },
144         { DOM_TEXT_DECORATION_STYLE,
145             [](const std::string& val, SpanDeclaration& declaration) {
146                 auto& specializedStyle = declaration.MaybeResetStyle<SpanStyle>(StyleTag::SPECIALIZED_STYLE);
147                 if (specializedStyle.IsValid()) {
148                     specializedStyle.spanStyle.SetTextDecorationStyle(ConvertStrToTextDecorationStyle(val));
149                 }
150                 declaration.isSetTextDecorationStyle_ = true;
151             } },
152     };
153     auto spanStyleIter = BinarySearchFindIndex(spanStyleOperators, ArraySize(spanStyleOperators), style.first.c_str());
154     if (spanStyleIter != -1) {
155         spanStyleOperators[spanStyleIter].value(style.second, *this);
156     }
157 
158     // span has no box component, set true to prevent setting style to box (empty object).
159     return true;
160 }
161 
162 } // namespace OHOS::Ace
163