1 /*
2 * Copyright (c) 2021 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/svg/svg_base_declaration.h"
17
18 #include "base/utils/string_utils.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 const char LINECAP_ROUND[] = "round";
26 const char LINECAP_SQUARE[] = "square";
27 const char LINEJOIN_BEVEL[] = "bevel";
28 const char LINEJOIN_ROUND[] = "round";
29
30 const char DOM_SVG_SRC_FILL_OPACITY[] = "fill-opacity";
31 const char DOM_SVG_SRC_FILL_RULE[] = "fill-rule";
32 const char DOM_SVG_SRC_STROKE_DASHARRAY[] = "stroke-dasharray";
33 const char DOM_SVG_SRC_STROKE_DASHOFFSET[] = "stroke-dashoffset";
34 const char DOM_SVG_SRC_STROKE_LINECAP[] = "stroke-linecap";
35 const char DOM_SVG_SRC_STROKE_LINEJOIN[] = "stroke-linejoin";
36 const char DOM_SVG_SRC_STROKE_MITERLIMIT[] = "stroke-miterlimit";
37 const char DOM_SVG_SRC_STROKE_OPACITY[] = "stroke-opacity";
38 const char DOM_SVG_SRC_STROKE_WIDTH[] = "stroke-width";
39 const char DOM_SVG_SRC_CLIP_PATH[] = "clip-path";
40 const char DOM_SVG_SRC_CLIP_RULE[] = "clip-rule";
41 const char DOM_SVG_SRC_TRANSFORM_ORIGIN[] = "transform-origin";
42
43 const LinearMapNode<Color> COLOR_TABLE[] = {
44 { "aliceblue", Color(0xfff0f8ff) },
45 { "antiquewhite", Color(0xfffaebd7) },
46 { "aqua", Color(0xff00ffff) },
47 { "aquamarine", Color(0xff7fffd4) },
48 { "azure", Color(0xfff0ffff) },
49 { "beige", Color(0xfff5f5dc) },
50 { "bisque", Color(0xffffe4c4) },
51 { "black", Color(0XFF000000) },
52 { "blanchedalmond", Color(0xffffebcd) },
53 { "blue", Color(0xff0000ff) },
54 { "blueviolet", Color(0xff8a2be2) },
55 { "brown", Color(0xffa52a2a) },
56 { "burlywood", Color(0xffdeb887) },
57 { "cadetblue", Color(0xff5f9ea0) },
58 { "chartreuse", Color(0xff7fff00) },
59 { "chocolate", Color(0xffd2691e) },
60 { "coral", Color(0xffff7f50) },
61 { "cornflowerblue", Color(0xff6495ed) },
62 { "cornsilk", Color(0xfffff8dc) },
63 { "crimson", Color(0xffdc143c) },
64 { "cyan", Color(0xff00ffff) },
65 { "darkblue", Color(0xff00008b) },
66 { "darkcyan", Color(0xff008b8b) },
67 { "darkgoldenrod", Color(0xffb8860b) },
68 { "darkgray", Color(0xffa9a9a9) },
69 { "darkgreen", Color(0xff006400) },
70 { "darkgrey", Color(0xffa9a9a9) },
71 { "darkkhaki", Color(0xffbdb76b) },
72 { "darkmagenta", Color(0xff8b008b) },
73 { "darkolivegreen", Color(0xff556b2f) },
74 { "darkorange", Color(0xffff8c00) },
75 { "darkorchid", Color(0xff9932cc) },
76 { "darkred", Color(0xff8b0000) },
77 { "darksalmon", Color(0xffe9967a) },
78 { "darkseagreen", Color(0xff8fbc8f) },
79 { "darkslateblue", Color(0xff483d8b) },
80 { "darkslategray", Color(0xff2f4f4f) },
81 { "darkslategrey", Color(0xff2f4f4f) },
82 { "darkturquoise", Color(0xff00ced1) },
83 { "darkviolet", Color(0xff9400D3) },
84 { "deeppink", Color(0xffff1493) },
85 { "deepskyblue", Color(0xff00bfff) },
86 { "dimgray", Color(0xff696969) },
87 { "dimgrey", Color(0xff696969) },
88 { "dodgerblue", Color(0xff1e90ff) },
89 { "firebrick", Color(0xffb22222) },
90 { "floralwhite", Color(0xfffffaf0) },
91 { "forestgreen", Color(0xff228b22) },
92 { "fuchsia", Color(0xffff00ff) },
93 { "gainsboro", Color(0xffdcdcdc) },
94 { "ghostwhite", Color(0xfff8f8ff) },
95 { "gold", Color(0xffffd700) },
96 { "goldenrod", Color(0xffdaa520) },
97 { "gray", Color(0xff808080) },
98 { "green", Color(0xff008000) },
99 { "greenyellow", Color(0xffadff2f) },
100 { "grey", Color(0xff808080) },
101 { "honeydew", Color(0xfff0fff0) },
102 { "hotpink", Color(0xffff69b4) },
103 { "indianred", Color(0xffcd5c5c) },
104 { "indigo", Color(0xff4b0082) },
105 { "ivory", Color(0xfffffff0) },
106 { "khaki", Color(0xfff0e68c) },
107 { "lavender", Color(0xffe6e6fa) },
108 { "lavenderblush", Color(0xfffff0f5) },
109 { "lawngreen", Color(0xff7cfc00) },
110 { "lemonchiffon", Color(0xfffffacd) },
111 { "lightblue", Color(0xffadd8e6) },
112 { "lightcoral", Color(0xfff08080) },
113 { "lightcyan", Color(0xffe0ffff) },
114 { "lightgoldenrodyellow", Color(0xfffafad2) },
115 { "lightgray", Color(0xffd3d3d3) },
116 { "lightgreen", Color(0xff90ee90) },
117 { "lightgrey", Color(0xffd3d3d3) },
118 { "lightpink", Color(0xffffb6c1) },
119 { "lightsalmon", Color(0xffffa07a) },
120 { "lightseagreen", Color(0xff20b2aa) },
121 { "lightskyblue", Color(0xff87cefa) },
122 { "lightslategray", Color(0xff778899) },
123 { "lightslategrey", Color(0xff778899) },
124 { "lightsteelblue", Color(0xffb0c4de) },
125 { "lightyellow", Color(0xffffffe0) },
126 { "lime", Color(0xff00ff00) },
127 { "limegreen", Color(0xff32cd32) },
128 { "linen", Color(0xfffaf0e6) },
129 { "magenta", Color(0xffff00ff) },
130 { "maroon", Color(0xff800000) },
131 { "mediumaquamarine", Color(0xff66cdaa) },
132 { "mediumblue", Color(0xff0000cd) },
133 { "mediumorchid", Color(0xffba55d3) },
134 { "mediumpurple", Color(0xff9370db) },
135 { "mediumseagreen", Color(0xff3cb371) },
136 { "mediumslateblue", Color(0xff7b68ee) },
137 { "mediumspringgreen", Color(0xff00fa9a) },
138 { "mediumturquoise", Color(0xff48d1cc) },
139 { "mediumvioletred", Color(0xffc71585) },
140 { "midnightblue", Color(0xff191970) },
141 { "mintcream", Color(0xfff5fffa) },
142 { "mistyrose", Color(0xffffe4e1) },
143 { "moccasin", Color(0xffffe4b5) },
144 { "navajowhite", Color(0xffffdead) },
145 { "navy", Color(0xff000080) },
146 { "oldlace", Color(0xfffdf5e6) },
147 { "olive", Color(0xff808000) },
148 { "olivedrab", Color(0xff6b8e23) },
149 { "orange", Color(0xffffa500) },
150 { "orangered", Color(0xffff4500) },
151 { "orchid", Color(0xffda70d6) },
152 { "palegoldenrod", Color(0xffeee8aa) },
153 { "palegreen", Color(0xff98fb98) },
154 { "paleturquoise", Color(0xffafeeee) },
155 { "palevioletred", Color(0xffdb7093) },
156 { "papayawhip", Color(0xffffefd5) },
157 { "peachpuff", Color(0xffffdab9) },
158 { "peru", Color(0xffcd853f) },
159 { "pink", Color(0xffffc0cb) },
160 { "plum", Color(0xffdda0dd) },
161 { "powderblue", Color(0xffb0e0e6) },
162 { "purple", Color(0xff800080) },
163 { "red", Color(0xffff0000) },
164 { "rosybrown", Color(0xffbc8f8f) },
165 { "royalblue", Color(0xff4169e1) },
166 { "rebeccapurple", Color(0xff663399) },
167 { "saddlebrown", Color(0xff8b4513) },
168 { "salmon", Color(0xfffa8072) },
169 { "sandybrown", Color(0xfff4a460) },
170 { "seagreen", Color(0xff2e8b57) },
171 { "seashell", Color(0xfffff5ee) },
172 { "sienna", Color(0xffa0522d) },
173 { "silver", Color(0xffc0c0c0) },
174 { "skyblue", Color(0xff87ceeb) },
175 { "slateblue", Color(0xff6a5acd) },
176 { "slategray", Color(0xff708090) },
177 { "slategrey", Color(0xff708090) },
178 { "snow", Color(0xfffffafa) },
179 { "springgreen", Color(0xff00ff7f) },
180 { "steelblue", Color(0xff4682b4) },
181 { "tan", Color(0xffd2b48c) },
182 { "teal", Color(0xff008080) },
183 { "thistle", Color(0xffd8bfd8) },
184 { "tomato", Color(0xffff6347) },
185 { "turquoise", Color(0xff40e0d0) },
186 { "violet", Color(0xffee82ee) },
187 { "wheat", Color(0xfff5deb3) },
188 { "white", Color(0xffffffff) },
189 { "whitesmoke", Color(0xfff5f5f5) },
190 { "yellow", Color(0xffffff00) },
191 { "yellowgreen", Color(0xff9acd32) },
192 };
193
194 } // namespace
195
196 using namespace Framework;
197
InitSpecialized()198 void SvgBaseDeclaration::InitSpecialized()
199 {
200 AddSpecializedAttribute(DeclarationConstants::DEFAULT_SVG_BASE_ATTR);
201 }
202
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)203 bool SvgBaseDeclaration::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
204 {
205 return SetPresentationAttr(attr);
206 }
207
SetSpecializedStyle(const std::pair<std::string,std::string> & style)208 bool SvgBaseDeclaration::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
209 {
210 return SetPresentationAttr(style);
211 }
212
SetPresentationAttr(const std::pair<std::string,std::string> & attr)213 bool SvgBaseDeclaration::SetPresentationAttr(const std::pair<std::string, std::string>& attr)
214 {
215 static const LinearMapNode<void (*)(const std::string&, SvgBaseDeclaration&)> svgBaseAttrs[] = {
216 { DOM_SVG_SRC_CLIP_PATH,
217 [](const std::string& val, SvgBaseDeclaration& declaration) {
218 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
219 auto value = StringUtils::TrimStr(val);
220 if (value.find("url(") == 0) {
221 auto src = std::regex_replace(value,
222 std::regex(R"(^url\(\s*['"]?\s*#([^()]+?)\s*['"]?\s*\)$)"), "$1");
223 attrs.clipState.SetHref(src);
224 }
225 } },
226 { DOM_SVG_SRC_CLIP_RULE,
227 [](const std::string& val, SvgBaseDeclaration& declaration) {
228 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
229 attrs.clipState.SetClipRule(val);
230 } },
231 { DOM_CLIP_PATH,
232 [](const std::string& val, SvgBaseDeclaration& declaration) {
233 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
234 auto value = StringUtils::TrimStr(val);
235 if (value.find("url(") == 0) {
236 auto src = std::regex_replace(value,
237 std::regex(R"(^url\(\s*['"]?\s*#([^()]+?)\s*['"]?\s*\)$)"), "$1");
238 attrs.clipState.SetHref(src);
239 }
240 } },
241 { DOM_SVG_CLIP_RULE,
242 [](const std::string& val, SvgBaseDeclaration& declaration) {
243 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
244 attrs.clipState.SetClipRule(val);
245 } },
246 { DOM_SVG_FILL,
247 [](const std::string& val, SvgBaseDeclaration& declaration) {
248 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
249 auto value = StringUtils::TrimStr(val);
250 if (value.find("url(") == 0) {
251 auto src = std::regex_replace(value,
252 std::regex(R"(^url\(\s*['"]?\s*#([^()]+?)\s*['"]?\s*\)$)"), "$1");
253 attrs.fillState.SetHref(src);
254 } else {
255 Color fill = (val == VALUE_NONE ? Color::TRANSPARENT : declaration.GetColor(val));
256 attrs.fillState.SetColor(fill);
257 }
258 } },
259 { DOM_SVG_SRC_FILL_OPACITY,
260 [](const std::string& val, SvgBaseDeclaration& declaration) {
261 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
262 attrs.fillState.SetOpacity(std::clamp(StringToDouble(val), 0.0, 1.0));
263 } },
264 { DOM_SVG_SRC_FILL_RULE,
265 [](const std::string& val, SvgBaseDeclaration& declaration) {
266 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
267 attrs.fillState.SetFillRule(val);
268 } },
269 { DOM_SVG_FILL_OPACITY,
270 [](const std::string& val, SvgBaseDeclaration& declaration) {
271 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
272 attrs.fillState.SetOpacity(std::clamp(StringToDouble(val), 0.0, 1.0));
273 } },
274 { DOM_SVG_FILL_RULE,
275 [](const std::string& val, SvgBaseDeclaration& declaration) {
276 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
277 attrs.fillState.SetFillRule(val);
278 } },
279 { DOM_SVG_FILTER,
280 [](const std::string& val, SvgBaseDeclaration& declaration) {
281 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
282 attrs.filterId = val;
283 } },
284 { DOM_SVG_FONT_SIZE,
285 [](const std::string& val, SvgBaseDeclaration& declaration) {
286 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
287 Dimension fontSize = StringToDimension(val);
288 if (GreatOrEqual(fontSize.Value(), 0.0)) {
289 attrs.textStyle.SetFontSize(fontSize);
290 }
291 } },
292 { DOM_SVG_HREF,
293 [](const std::string& val, SvgBaseDeclaration& declaration) {
294 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
295 auto value = StringUtils::TrimStr(val);
296 if (value.substr(0, 1) == "#") {
297 attrs.href = value.substr(1);
298 }
299 } },
300 { DOM_SVG_MASK,
301 [](const std::string& val, SvgBaseDeclaration& declaration) {
302 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
303 attrs.maskId = val;
304 } },
305 { DOM_SVG_OPACITY,
306 [](const std::string& val, SvgBaseDeclaration& declaration) {
307 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
308 attrs.hasOpacity = true;
309 attrs.opacity = std::clamp(StringToDouble(val), 0.0, 1.0);
310 } },
311 { DOM_SVG_STROKE,
312 [](const std::string& val, SvgBaseDeclaration& declaration) {
313 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
314 auto value = StringUtils::TrimStr(val);
315 if (value.find("url(") == 0) {
316 auto src = std::regex_replace(value,
317 std::regex(R"(^url\(\s*['"]?\s*#([^()]+?)\s*['"]?\s*\)$)"), "$1");
318 attrs.strokeState.SetHref(src);
319 } else {
320 Color stroke = (val == VALUE_NONE ? Color::TRANSPARENT : declaration.GetColor(val));
321 attrs.strokeState.SetColor(stroke);
322 }
323 } },
324 { DOM_SVG_SRC_STROKE_DASHARRAY,
325 [](const std::string& val, SvgBaseDeclaration& declaration) {
326 if (val.empty()) {
327 return;
328 }
329 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
330 std::vector<double> lineDashVector;
331 std::string handledStr = StringUtils::ReplaceChar(val, ',', ' ');
332 StringUtils::StringSplitter(handledStr, ' ', lineDashVector);
333 attrs.strokeState.SetLineDash(lineDashVector);
334 } },
335 { DOM_SVG_SRC_STROKE_DASHOFFSET,
336 [](const std::string& val, SvgBaseDeclaration& declaration) {
337 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
338 attrs.strokeState.SetLineDashOffset(StringToDouble(val));
339 } },
340 { DOM_SVG_SRC_STROKE_LINECAP,
341 [](const std::string& val, SvgBaseDeclaration& declaration) {
342 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
343 attrs.strokeState.SetLineCap(declaration.GetLineCapStyle(val));
344 } },
345 { DOM_SVG_SRC_STROKE_LINEJOIN,
346 [](const std::string& val, SvgBaseDeclaration& declaration) {
347 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
348 attrs.strokeState.SetLineJoin(declaration.GetLineJoinStyle(val));
349 } },
350 { DOM_SVG_SRC_STROKE_MITERLIMIT,
351 [](const std::string& val, SvgBaseDeclaration& declaration) {
352 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
353 double miterLimit = StringToDouble(val);
354 if (GreatOrEqual(miterLimit, 1.0)) {
355 attrs.strokeState.SetMiterLimit(miterLimit);
356 }
357 } },
358 { DOM_SVG_SRC_STROKE_OPACITY,
359 [](const std::string& val, SvgBaseDeclaration& declaration) {
360 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
361 attrs.strokeState.SetOpacity(std::clamp(StringToDouble(val), 0.0, 1.0));
362 } },
363 { DOM_SVG_SRC_STROKE_WIDTH,
364 [](const std::string& val, SvgBaseDeclaration& declaration) {
365 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
366 Dimension lineWidth = StringToDimension(val);
367 if (GreatOrEqual(lineWidth.Value(), 0.0)) {
368 attrs.strokeState.SetLineWidth(lineWidth);
369 }
370 } },
371 { DOM_SVG_STROKE_DASHARRAY,
372 [](const std::string& val, SvgBaseDeclaration& declaration) {
373 if (val.empty()) {
374 return;
375 }
376 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
377 std::vector<double> lineDashVector;
378 StringUtils::StringSplitter(val, ' ', lineDashVector);
379 attrs.strokeState.SetLineDash(lineDashVector);
380 } },
381 { DOM_SVG_STROKE_DASHOFFSET,
382 [](const std::string& val, SvgBaseDeclaration& declaration) {
383 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
384 attrs.strokeState.SetLineDashOffset(StringToDouble(val));
385 } },
386 { DOM_SVG_STROKE_LINECAP,
387 [](const std::string& val, SvgBaseDeclaration& declaration) {
388 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
389 attrs.strokeState.SetLineCap(declaration.GetLineCapStyle(val));
390 } },
391 { DOM_SVG_STROKE_LINEJOIN,
392 [](const std::string& val, SvgBaseDeclaration& declaration) {
393 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
394 attrs.strokeState.SetLineJoin(declaration.GetLineJoinStyle(val));
395 } },
396 { DOM_SVG_STROKE_MITERLIMIT,
397 [](const std::string& val, SvgBaseDeclaration& declaration) {
398 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
399 double miterLimit = StringToDouble(val);
400 if (GreatOrEqual(miterLimit, 1.0)) {
401 attrs.strokeState.SetMiterLimit(miterLimit);
402 }
403 } },
404 { DOM_SVG_STROKE_OPACITY,
405 [](const std::string& val, SvgBaseDeclaration& declaration) {
406 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
407 attrs.strokeState.SetOpacity(std::clamp(StringToDouble(val), 0.0, 1.0));
408 } },
409 { DOM_SVG_STROKE_WIDTH,
410 [](const std::string& val, SvgBaseDeclaration& declaration) {
411 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
412 Dimension lineWidth = StringToDimension(val);
413 if (GreatOrEqual(lineWidth.Value(), 0.0)) {
414 attrs.strokeState.SetLineWidth(lineWidth);
415 }
416 } },
417 { DOM_TRANSFORM,
418 [](const std::string& val, SvgBaseDeclaration& declaration) {
419 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
420 attrs.transform = val;
421 } },
422 { DOM_SVG_SRC_TRANSFORM_ORIGIN,
423 [](const std::string& val, SvgBaseDeclaration& declaration) {
424 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
425 attrs.transformOrigin = val;
426 } },
427 { DOM_SVG_XLINK_HREF,
428 [](const std::string& val, SvgBaseDeclaration& declaration) {
429 auto& attrs = declaration.MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
430 auto value = StringUtils::TrimStr(val);
431 if (value.substr(0, 1) == "#") {
432 attrs.href = value.substr(1);
433 }
434 } }
435 };
436 auto attrIter = BinarySearchFindIndex(svgBaseAttrs, ArraySize(svgBaseAttrs), attr.first.c_str());
437 if (attrIter != -1) {
438 svgBaseAttrs[attrIter].value(attr.second, *this);
439 return true;
440 }
441 return false;
442 }
443
444 void SvgBaseDeclaration::Inherit(const RefPtr<Declaration>& parent)
445 {
446 auto svgDeclaration = AceType::DynamicCast<SvgBaseDeclaration>(parent);
447 if (!svgDeclaration) {
448 return;
449 }
450 auto& attrs = MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
451 if (!attrs.IsValid()) {
452 LOGE("attrs is invalid");
453 return;
454 }
455 if (!attrs.hasOpacity) {
456 if (svgDeclaration->HasOpacity()) {
457 attrs.opacity = svgDeclaration->GetOpacity();
458 } else {
459 attrs.opacity = 1.0; // default opacity is 1.0
460 }
461 }
462 attrs.fillState.Inherit(svgDeclaration->GetFillState());
463 attrs.strokeState.Inherit(svgDeclaration->GetStrokeState());
464 attrs.textStyle.Inherit(svgDeclaration->GetSvgTextStyle());
465 attrs.clipState.Inherit(svgDeclaration->GetClipState());
466 }
467
468 LineCapStyle SvgBaseDeclaration::GetLineCapStyle(const std::string& val) const
469 {
470 if (val == LINECAP_ROUND) {
471 return LineCapStyle::ROUND;
472 } else if (val == LINECAP_SQUARE) {
473 return LineCapStyle::SQUARE;
474 } else {
475 return LineCapStyle::BUTT;
476 }
477 }
478
479 LineJoinStyle SvgBaseDeclaration::GetLineJoinStyle(const std::string& val) const
480 {
481 if (val == LINEJOIN_BEVEL) {
482 return LineJoinStyle::BEVEL;
483 } else if (val == LINEJOIN_ROUND) {
484 return LineJoinStyle::ROUND;
485 } else {
486 return LineJoinStyle::MITER;
487 }
488 }
489
490 Color SvgBaseDeclaration::GetColor(const std::string& value) const
491 {
492 int64_t colorIndex = BinarySearchFindIndex(COLOR_TABLE, ArraySize(COLOR_TABLE), value.c_str());
493 if (colorIndex != -1) {
494 return COLOR_TABLE[colorIndex].value;
495 }
496 return Color::FromString(value);
497 }
498
499 void SvgBaseDeclaration::ReplaceAttributes(const SvgBaseAttribute& attr)
500 {
501 auto& attribute = MaybeResetAttribute<SvgBaseAttribute>(AttributeTag::SPECIALIZED_ATTR);
502 attribute = attr;
503 }
504 } // namespace OHOS::Ace
505