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