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 "frameworks/core/components/svg/parse/svg_node.h"
17
18 #include "frameworks/core/components/svg/parse/svg_gradient.h"
19
20 namespace OHOS::Ace {
21
ConvertDimensionToPx(const Dimension & value,const Size & viewPort,SvgLengthType type) const22 double SvgNode::ConvertDimensionToPx(const Dimension& value, const Size& viewPort, SvgLengthType type) const
23 {
24 switch (value.Unit()) {
25 case DimensionUnit::PERCENT: {
26 if (type == SvgLengthType::HORIZONTAL) {
27 return value.Value() * viewPort.Width();
28 }
29 if (type == SvgLengthType::VERTICAL) {
30 return value.Value() * viewPort.Height();
31 }
32 if (type == SvgLengthType::OTHER) {
33 return value.Value() * sqrt(viewPort.Width() * viewPort.Height());
34 }
35 return 0.0;
36 }
37 case DimensionUnit::PX:
38 return value.Value();
39 default:
40 auto context = context_.Upgrade();
41 if (context) {
42 return context->NormalizeToPx(value);
43 }
44 return 0.0;
45 }
46 }
47
AsClipPathCommands(const Size & viewPort,const std::string & href) const48 std::string SvgNode::AsClipPathCommands(const Size& viewPort,
49 const std::string& href) const
50 {
51 auto svgContext = svgContext_.Upgrade();
52 if (!svgContext) {
53 LOGE("AsClipPathCommands failed, svgContext is null");
54 return "";
55 }
56 if (href.empty()) {
57 return "";
58 }
59 auto refSvgNode = svgContext->GetSvgNodeById(href);
60 if (!refSvgNode) {
61 LOGE("refSvgNode is null");
62 return "";
63 }
64 #ifndef USE_ROSEN_DRAWING
65 auto skPath = refSvgNode->AsPath(viewPort);
66 SkString outString;
67 SkParsePath::ToSVGString(skPath, &outString);
68 return outString.c_str();
69 #else
70 auto rsPath = refSvgNode->AsPath(viewPort);
71 return rsPath.ConvertToSVGString();
72 #endif
73 }
74
GetGradient(const std::string & href)75 std::optional<Gradient> SvgNode::GetGradient(const std::string& href)
76 {
77 auto svgContext = svgContext_.Upgrade();
78 if (!svgContext) {
79 LOGE("Gradient failed, svgContext is null");
80 return std::nullopt;
81 }
82 if (href.empty()) {
83 return std::nullopt;
84 }
85 auto refSvgNode = svgContext->GetSvgNodeById(href);
86 if (!refSvgNode) {
87 LOGE("refSvgNode is null");
88 return std::nullopt;
89 }
90 auto svgGradient = DynamicCast<SvgGradient>(refSvgNode);
91 if (svgGradient) {
92 return std::make_optional(svgGradient->GetGradient());
93 }
94 return std::nullopt;
95 }
96
CreateBoxComponent(const LayoutParam & layoutParam,const std::string & clipPathHref)97 RefPtr<BoxComponent> SvgNode::CreateBoxComponent(const LayoutParam& layoutParam, const std::string& clipPathHref)
98 {
99 auto boxComponent = AceType::MakeRefPtr<BoxComponent>();
100 if (!clipPathHref.empty()) {
101 auto pathCommands = AsClipPathCommands(layoutParam.GetMaxSize(), clipPathHref);
102 if (!pathCommands.empty()) {
103 auto clipPath = AceType::MakeRefPtr<ClipPath>();
104 auto path = AceType::MakeRefPtr<Path>();
105 path->SetValue(pathCommands);
106 clipPath->SetBasicShape(path);
107 boxComponent->SetClipPath(clipPath);
108 }
109 }
110 return boxComponent;
111 }
112
113 } // namespace OHOS::Ace
114