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