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 "skia_path.h"
17
18 #include "include/core/SkMatrix.h"
19 #include "include/pathops/SkPathOps.h"
20 #include "skia_matrix.h"
21
22 #include "draw/path.h"
23
24 namespace OHOS {
25 namespace Rosen {
26 namespace Drawing {
SkiaPath()27 SkiaPath::SkiaPath() noexcept : path_() {}
28
SkiaPath(const SkiaPath & other)29 SkiaPath::SkiaPath(const SkiaPath& other) noexcept
30 {
31 path_ = other.path_;
32 }
33
operator =(const SkiaPath & other)34 SkiaPath& SkiaPath::operator=(const SkiaPath& other) noexcept
35 {
36 path_ = other.path_;
37 return *this;
38 }
39
Clone()40 PathImpl* SkiaPath::Clone()
41 {
42 return new SkiaPath(*this);
43 }
44
MoveTo(scalar x,scalar y)45 void SkiaPath::MoveTo(scalar x, scalar y)
46 {
47 path_.moveTo(x, y);
48 }
49
LineTo(scalar x,scalar y)50 void SkiaPath::LineTo(scalar x, scalar y)
51 {
52 path_.lineTo(x, y);
53 }
54
ArcTo(scalar pt1X,scalar pt1Y,scalar pt2X,scalar pt2Y,scalar startAngle,scalar sweepAngle)55 void SkiaPath::ArcTo(scalar pt1X, scalar pt1Y, scalar pt2X, scalar pt2Y, scalar startAngle, scalar sweepAngle)
56 {
57 path_.arcTo(SkRect::MakeLTRB(pt1X, pt1Y, pt2X, pt2Y), startAngle, sweepAngle, false);
58 }
59
ArcTo(scalar rx,scalar ry,scalar angle,PathDirection direction,scalar endX,scalar endY)60 void SkiaPath::ArcTo(scalar rx, scalar ry, scalar angle, PathDirection direction, scalar endX, scalar endY)
61 {
62 #if defined(USE_CANVASKIT0310_SKIA)
63 SkPathDirection pathDir = static_cast<SkPathDirection>(direction);
64 #else
65 SkPath::Direction pathDir = static_cast<SkPath::Direction>(direction);
66 #endif
67 SkPath::ArcSize arcLarge = SkPath::ArcSize::kSmall_ArcSize;
68 path_.arcTo(rx, ry, angle, arcLarge, pathDir, endX, endY);
69 }
70
CubicTo(scalar ctrlPt1X,scalar ctrlPt1Y,scalar ctrlPt2X,scalar ctrlPt2Y,scalar endPtX,scalar endPtY)71 void SkiaPath::CubicTo(scalar ctrlPt1X, scalar ctrlPt1Y, scalar ctrlPt2X, scalar ctrlPt2Y, scalar endPtX, scalar endPtY)
72 {
73 path_.cubicTo(ctrlPt1X, ctrlPt1Y, ctrlPt2X, ctrlPt2Y, endPtX, endPtY);
74 }
75
QuadTo(scalar ctrlPtX,scalar ctrlPtY,scalar endPtX,scalar endPtY)76 void SkiaPath::QuadTo(scalar ctrlPtX, scalar ctrlPtY, scalar endPtX, scalar endPtY)
77 {
78 path_.quadTo(ctrlPtX, ctrlPtY, endPtX, endPtY);
79 }
80
AddRect(scalar left,scalar top,scalar right,scalar bottom,PathDirection dir)81 void SkiaPath::AddRect(scalar left, scalar top, scalar right, scalar bottom, PathDirection dir)
82 {
83 #if defined(USE_CANVASKIT0310_SKIA)
84 SkPathDirection pathDir = static_cast<SkPathDirection>(dir);
85 #else
86 SkPath::Direction pathDir = static_cast<SkPath::Direction>(dir);
87 #endif
88 path_.addRect(SkRect::MakeLTRB(left, top, right, bottom), pathDir);
89 }
90
AddOval(scalar left,scalar top,scalar right,scalar bottom,PathDirection dir)91 void SkiaPath::AddOval(scalar left, scalar top, scalar right, scalar bottom, PathDirection dir)
92 {
93 #if defined(USE_CANVASKIT0310_SKIA)
94 SkPathDirection pathDir = static_cast<SkPathDirection>(dir);
95 #else
96 SkPath::Direction pathDir = static_cast<SkPath::Direction>(dir);
97 #endif
98 path_.addOval(SkRect::MakeLTRB(left, top, right, bottom), pathDir);
99 }
100
AddArc(scalar left,scalar top,scalar right,scalar bottom,scalar startAngle,scalar sweepAngle)101 void SkiaPath::AddArc(scalar left, scalar top, scalar right, scalar bottom, scalar startAngle, scalar sweepAngle)
102 {
103 path_.addArc(SkRect::MakeLTRB(left, top, right, bottom), startAngle, sweepAngle);
104 }
105
AddPoly(const std::vector<Point> & points,int count,bool close)106 void SkiaPath::AddPoly(const std::vector<Point>& points, int count, bool close)
107 {
108 std::vector<SkPoint> pt;
109 for (auto i = 0; i < count; ++i) {
110 pt.emplace_back(SkPoint::Make(points[i].GetX(), points[i].GetY()));
111 }
112 path_.addPoly(&pt[0], count, close);
113 }
114
AddCircle(scalar x,scalar y,scalar radius,PathDirection dir)115 void SkiaPath::AddCircle(scalar x, scalar y, scalar radius, PathDirection dir)
116 {
117 #if defined(USE_CANVASKIT0310_SKIA)
118 SkPathDirection pathDir = static_cast<SkPathDirection>(dir);
119 #else
120 SkPath::Direction pathDir = static_cast<SkPath::Direction>(dir);
121 #endif
122 path_.addCircle(x, y, radius, pathDir);
123 }
124
AddRoundRect(scalar left,scalar top,scalar right,scalar bottom,scalar xRadius,scalar yRadius,PathDirection dir)125 void SkiaPath::AddRoundRect(
126 scalar left, scalar top, scalar right, scalar bottom, scalar xRadius, scalar yRadius, PathDirection dir)
127 {
128 #if defined(USE_CANVASKIT0310_SKIA)
129 SkPathDirection pathDir = static_cast<SkPathDirection>(dir);
130 #else
131 SkPath::Direction pathDir = static_cast<SkPath::Direction>(dir);
132 #endif
133 path_.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom), xRadius, yRadius, pathDir);
134 }
135
AddPath(const Path & src,scalar dx,scalar dy)136 void SkiaPath::AddPath(const Path& src, scalar dx, scalar dy)
137 {
138 auto skPathImpl = src.GetImpl<SkiaPath>();
139 if (skPathImpl != nullptr) {
140 path_.addPath(skPathImpl->GetPath(), dx, dy);
141 }
142 }
143
AddPath(const Path & src)144 void SkiaPath::AddPath(const Path& src)
145 {
146 auto skPathImpl = src.GetImpl<SkiaPath>();
147 if (skPathImpl != nullptr) {
148 path_.addPath(skPathImpl->GetPath());
149 }
150 }
151
AddPathWithMatrix(const Path & src,const Matrix & matrix)152 void SkiaPath::AddPathWithMatrix(const Path& src, const Matrix& matrix)
153 {
154 auto skPathImpl = src.GetImpl<SkiaPath>();
155 auto skMatrixImpl = matrix.GetImpl<SkiaMatrix>();
156 if (skPathImpl != nullptr && skMatrixImpl != nullptr) {
157 path_.addPath(skPathImpl->GetPath(), skMatrixImpl->ExportSkiaMatrix());
158 }
159 }
160
GetBounds() const161 Rect SkiaPath::GetBounds() const
162 {
163 SkRect rect = path_.getBounds();
164 return Rect(rect.left(), rect.top(), rect.width(), rect.height());
165 }
166
SetFillStyle(PathFillType fillstyle)167 void SkiaPath::SetFillStyle(PathFillType fillstyle)
168 {
169 #if defined(USE_CANVASKIT0310_SKIA)
170 SkPathFillType ft = static_cast<SkPathFillType>(fillstyle);
171 #else
172 SkPath::FillType ft = static_cast<SkPath::FillType>(fillstyle);
173 #endif
174 path_.setFillType(ft);
175 }
176
Interpolate(const Path & ending,scalar weight,Path & out)177 bool SkiaPath::Interpolate(const Path& ending, scalar weight, Path& out)
178 {
179 bool isSuccess = false;
180 auto skPathImpl1 = ending.GetImpl<SkiaPath>();
181 auto skPathImpl2 = out.GetImpl<SkiaPath>();
182 if (skPathImpl1 != nullptr && skPathImpl2 != nullptr) {
183 SkPath interp;
184 isSuccess = path_.interpolate(skPathImpl1->GetPath(), weight, &interp);
185 skPathImpl2->SetPath(interp);
186 }
187 return isSuccess;
188 }
189
Transform(const Matrix & matrix)190 void SkiaPath::Transform(const Matrix& matrix)
191 {
192 auto skMatrixImpl = matrix.GetImpl<SkiaMatrix>();
193 if (skMatrixImpl != nullptr) {
194 path_.transform(skMatrixImpl->ExportSkiaMatrix());
195 }
196 }
197
Offset(scalar dx,scalar dy)198 void SkiaPath::Offset(scalar dx, scalar dy)
199 {
200 path_.offset(dx, dy);
201 }
202
OpWith(const Path & path1,const Path & path2,PathOp op)203 bool SkiaPath::OpWith(const Path& path1, const Path& path2, PathOp op)
204 {
205 SkPathOp pathOp = static_cast<SkPathOp>(op);
206 bool isOpSuccess = false;
207
208 auto skPathImpl1 = path1.GetImpl<SkiaPath>();
209 auto skPathImpl2 = path2.GetImpl<SkiaPath>();
210 if (skPathImpl1 != nullptr && skPathImpl2 != nullptr) {
211 isOpSuccess = Op(skPathImpl1->GetPath(), skPathImpl2->GetPath(), pathOp, &path_);
212 }
213
214 if (isOpSuccess) {
215 return true;
216 }
217 return false;
218 }
219
Reset()220 void SkiaPath::Reset()
221 {
222 path_.reset();
223 }
224
Close()225 void SkiaPath::Close()
226 {
227 path_.close();
228 }
229
SetPath(const SkPath & path)230 void SkiaPath::SetPath(const SkPath& path)
231 {
232 path_ = path;
233 }
234
GetPath() const235 const SkPath& SkiaPath::GetPath() const
236 {
237 return path_;
238 }
239 } // namespace Drawing
240 } // namespace Rosen
241 } // namespace OHOS
242