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 "render/rs_path.h"
17
18 #ifndef USE_ROSEN_DRAWING
19 #include "include/core/SkPath.h"
20 #include "include/core/SkMatrix.h"
21 #include "include/core/SkPathMeasure.h"
22 #include "include/utils/SkParsePath.h"
23 #else
24 #include "draw/path.h"
25 #include "utils/matrix.h"
26 #include "utils/scalar.h"
27 #endif
28
29 #include "platform/common/rs_log.h"
30
31 namespace OHOS {
32 namespace Rosen {
CreateRSPath()33 std::shared_ptr<RSPath> RSPath::CreateRSPath()
34 {
35 return std::make_shared<RSPath>();
36 }
37
38 #ifndef USE_ROSEN_DRAWING
CreateRSPath(const SkPath & skPath)39 std::shared_ptr<RSPath> RSPath::CreateRSPath(const SkPath& skPath)
40 {
41 auto rsPath = std::make_shared<RSPath>();
42 rsPath->SetSkiaPath(skPath);
43 return rsPath;
44 }
45 #else
CreateRSPath(const Drawing::Path & path)46 std::shared_ptr<RSPath> RSPath::CreateRSPath(const Drawing::Path& path)
47 {
48 auto rsPath = std::make_shared<RSPath>();
49 rsPath->SetDrawingPath(path);
50 return rsPath;
51 }
52 #endif
53
CreateRSPath(const std::string & path)54 std::shared_ptr<RSPath> RSPath::CreateRSPath(const std::string& path)
55 {
56 #ifndef USE_ROSEN_DRAWING
57 SkPath skAnimationPath;
58 SkParsePath::FromSVGString(path.c_str(), &skAnimationPath);
59 return RSPath::CreateRSPath(skAnimationPath);
60 #else
61 Drawing::Path drAnimationPath;
62 drAnimationPath.BuildFromSVGString(path);
63 return RSPath::CreateRSPath(drAnimationPath);
64 #endif
65 }
66
RSPath()67 RSPath::RSPath()
68 {
69 #ifndef USE_ROSEN_DRAWING
70 skPath_ = new SkPath();
71 #else
72 drPath_ = new Drawing::Path();
73 #endif
74 }
75
~RSPath()76 RSPath::~RSPath()
77 {
78 #ifndef USE_ROSEN_DRAWING
79 if (skPath_) {
80 delete skPath_;
81 }
82 #else
83 if (drPath_) {
84 delete drPath_;
85 }
86 #endif
87 }
88
89 #ifndef USE_ROSEN_DRAWING
GetSkiaPath() const90 const SkPath& RSPath::GetSkiaPath() const
91 {
92 return *skPath_;
93 }
94
SetSkiaPath(const SkPath & skPath)95 void RSPath::SetSkiaPath(const SkPath& skPath)
96 {
97 if (skPath_) {
98 delete skPath_;
99 }
100 skPath_ = new SkPath(skPath);
101 }
102 #else
GetDrawingPath() const103 const Drawing::Path& RSPath::GetDrawingPath() const
104 {
105 return *drPath_;
106 }
107
SetDrawingPath(const Drawing::Path & path)108 void RSPath::SetDrawingPath(const Drawing::Path& path)
109 {
110 if (drPath_) {
111 delete drPath_;
112 }
113 drPath_ = new Drawing::Path(path);
114 }
115 #endif
116
Reverse()117 std::shared_ptr<RSPath> RSPath::Reverse()
118 {
119 #ifndef USE_ROSEN_DRAWING
120 SkPath path;
121 path.reverseAddPath(*skPath_);
122 #else
123 Drawing::Path path;
124 path.ReverseAddPath(*drPath_);
125 #endif
126 return CreateRSPath(path);
127 }
128
GetDistance() const129 float RSPath::GetDistance() const
130 {
131 #ifndef USE_ROSEN_DRAWING
132 SkPathMeasure pathMeasure(*skPath_, false);
133 return pathMeasure.getLength();
134 #else
135 return drPath_->GetLength(false);
136 #endif
137 }
138
139 template<>
GetPosTan(float distance,Vector2f & pos,float & degrees) const140 bool RSPath::GetPosTan(float distance, Vector2f& pos, float& degrees) const
141 {
142 #ifndef USE_ROSEN_DRAWING
143 SkPoint position;
144 SkVector tangent;
145 SkPathMeasure pathMeasure(*skPath_, false);
146 bool ret = pathMeasure.getPosTan(distance, &position, &tangent);
147 if (!ret) {
148 ROSEN_LOGE("SkPathMeasure get failed");
149 return false;
150 }
151 pos.data_[0] = position.x();
152 pos.data_[1] = position.y();
153 degrees = SkRadiansToDegrees(std::atan2(tangent.y(), tangent.x()));
154 #else
155 Drawing::Point position;
156 Drawing::Point tangent;
157 bool ret = drPath_->GetPositionAndTangent(distance, position, tangent, false);
158 if (!ret) {
159 ROSEN_LOGE("PathMeasure get failed");
160 return false;
161 }
162 pos.data_[0] = position.GetX();
163 pos.data_[1] = position.GetY();
164 degrees = Drawing::ConvertRadiansToDegrees(std::atan2(tangent.GetY(), tangent.GetX()));
165 #endif
166 return true;
167 }
168
169 template<>
GetPosTan(float distance,Vector4f & pos,float & degrees) const170 bool RSPath::GetPosTan(float distance, Vector4f& pos, float& degrees) const
171 {
172 Vector2f position;
173 bool res = GetPosTan(distance, position, degrees);
174 if (!res) {
175 #ifndef USE_ROSEN_DRAWING
176 ROSEN_LOGD("SkPathMeasure get failed");
177 #else
178 ROSEN_LOGD("PathMeasure get failed");
179 #endif
180 return false;
181 }
182 pos[0] = position[0];
183 pos[1] = position[1];
184 return res;
185 }
186 } // namespace Rosen
187 } // namespace OHOS
188