1 /*
2 * Copyright (c) 2023 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 "recording/path_cmd_list.h"
17
18 #include "recording/cmd_list_helper.h"
19 #include "utils/log.h"
20
21 namespace OHOS {
22 namespace Rosen {
23 namespace Drawing {
24 static constexpr int32_t FUNCTION_OVERLOADING_1 = 1;
25 static constexpr int32_t FUNCTION_OVERLOADING_2 = 2;
26
CreateFromData(const CmdListData & data,bool isCopy)27 std::shared_ptr<PathCmdList> PathCmdList::CreateFromData(const CmdListData& data, bool isCopy)
28 {
29 auto cmdList = std::make_shared<PathCmdList>();
30 if (isCopy) {
31 cmdList->opAllocator_.BuildFromDataWithCopy(data.first, data.second);
32 } else {
33 cmdList->opAllocator_.BuildFromData(data.first, data.second);
34 }
35 return cmdList;
36 }
37
Playback() const38 std::shared_ptr<Path> PathCmdList::Playback() const
39 {
40 uint32_t offset = 0;
41 auto path = std::make_shared<Path>();
42 PathPlayer player(*path, *this);
43 do {
44 void* itemPtr = opAllocator_.OffsetToAddr(offset);
45 OpItem* curOpItemPtr = static_cast<OpItem*>(itemPtr);
46 if (curOpItemPtr != nullptr) {
47 if (!player.Playback(curOpItemPtr->GetType(), itemPtr)) {
48 LOGE("PathCmdList::Playback failed!");
49 break;
50 }
51
52 offset = curOpItemPtr->GetNextOpItemOffset();
53 } else {
54 LOGE("PathCmdList::Playback failed, opItem is nullptr");
55 break;
56 }
57 } while (offset != 0);
58
59 return path;
60 }
61
62 /* OpItem */
63 std::unordered_map<uint32_t, PathPlayer::PathPlaybackFunc> PathPlayer::opPlaybackFuncLUT_ = {
64 { PathOpItem::BUILDFROMSVG_OPITEM, BuildFromSVGOpItem::Playback },
65 { PathOpItem::MOVETO_OPITEM, MoveToOpItem::Playback },
66 { PathOpItem::LINETO_OPITEM, LineToOpItem::Playback },
67 { PathOpItem::ARCTO_OPITEM, ArcToOpItem::Playback },
68 { PathOpItem::CUBICTO_OPITEM, CubicToOpItem::Playback },
69 { PathOpItem::QUADTO_OPITEM, QuadToOpItem::Playback },
70 { PathOpItem::ADDRECT_OPITEM, AddRectOpItem::Playback },
71 { PathOpItem::ADDOVAL_OPITEM, AddOvalOpItem::Playback },
72 { PathOpItem::ADDARC_OPITEM, AddArcOpItem::Playback },
73 { PathOpItem::ADDPOLY_OPITEM, AddPolyOpItem::Playback },
74 { PathOpItem::ADDCIRCLE_OPITEM, AddCircleOpItem::Playback },
75 { PathOpItem::ADDRRECT_OPITEM, AddRoundRectOpItem::Playback },
76 { PathOpItem::ADDPATH_OPITEM, AddPathOpItem::Playback },
77 { PathOpItem::ADDPATHWITHMATRIX_OPITEM, AddPathWithMatrixOpItem::Playback },
78 { PathOpItem::REVERSEADDPATH_OPITEM, ReverseAddPathOpItem::Playback },
79 { PathOpItem::SETFILLSTYLE_OPITEM, SetFillStyleOpItem::Playback },
80 { PathOpItem::BUILDFROMINTERPOLATE_OPITEM, BuildFromInterpolateOpItem::Playback },
81 { PathOpItem::TRANSFORM_OPITEM, TransformOpItem::Playback },
82 { PathOpItem::OFFSET_OPITEM, OffsetOpItem::Playback },
83 { PathOpItem::PATHOPWITH_OPITEM, PathOpWithOpItem::Playback },
84 { PathOpItem::RESET_OPITEM, ResetOpItem::Playback },
85 { PathOpItem::CLOSE_OPITEM, CloseOpItem::Playback },
86 };
87
PathPlayer(Path & path,const CmdList & cmdList)88 PathPlayer::PathPlayer(Path& path, const CmdList& cmdList) : path_(path), cmdList_(cmdList) {}
89
Playback(uint32_t type,const void * opItem)90 bool PathPlayer::Playback(uint32_t type, const void* opItem)
91 {
92 if (type == PathOpItem::OPITEM_HEAD) {
93 return true;
94 }
95
96 auto it = opPlaybackFuncLUT_.find(type);
97 if (it == opPlaybackFuncLUT_.end() || it->second == nullptr) {
98 return false;
99 }
100
101 auto func = it->second;
102 (*func)(*this, opItem);
103
104 return true;
105 }
106
BuildFromSVGOpItem(const uint32_t offset,const size_t size)107 BuildFromSVGOpItem::BuildFromSVGOpItem(const uint32_t offset, const size_t size)
108 : PathOpItem(BUILDFROMSVG_OPITEM), offset_(offset), size_(size) {}
109
Playback(PathPlayer & player,const void * opItem)110 void BuildFromSVGOpItem::Playback(PathPlayer& player, const void* opItem)
111 {
112 if (opItem != nullptr) {
113 const auto* op = static_cast<const BuildFromSVGOpItem*>(opItem);
114 op->Playback(player.path_, player.cmdList_);
115 }
116 }
117
Playback(Path & path,const CmdList & cmdList) const118 void BuildFromSVGOpItem::Playback(Path& path, const CmdList& cmdList) const
119 {
120 std::string str(static_cast<const char*>(cmdList.GetCmdListData(offset_)), size_);
121 path.BuildFromSVGString(str);
122 }
123
MoveToOpItem(const scalar x,const scalar y)124 MoveToOpItem::MoveToOpItem(const scalar x, const scalar y) : PathOpItem(MOVETO_OPITEM), x_(x), y_(y) {}
125
Playback(PathPlayer & player,const void * opItem)126 void MoveToOpItem::Playback(PathPlayer& player, const void* opItem)
127 {
128 if (opItem != nullptr) {
129 const auto* op = static_cast<const MoveToOpItem*>(opItem);
130 op->Playback(player.path_);
131 }
132 }
133
Playback(Path & path) const134 void MoveToOpItem::Playback(Path& path) const
135 {
136 path.MoveTo(x_, y_);
137 }
138
LineToOpItem(const scalar x,const scalar y)139 LineToOpItem::LineToOpItem(const scalar x, const scalar y) : PathOpItem(LINETO_OPITEM), x_(x), y_(y) {}
140
Playback(PathPlayer & player,const void * opItem)141 void LineToOpItem::Playback(PathPlayer& player, const void* opItem)
142 {
143 if (opItem != nullptr) {
144 const auto* op = static_cast<const LineToOpItem*>(opItem);
145 op->Playback(player.path_);
146 }
147 }
148
Playback(Path & path) const149 void LineToOpItem::Playback(Path& path) const
150 {
151 path.LineTo(x_, y_);
152 }
153
ArcToOpItem(const Point & pt1,const Point & pt2,const scalar startAngle,const scalar sweepAngle)154 ArcToOpItem::ArcToOpItem(const Point& pt1, const Point& pt2, const scalar startAngle, const scalar sweepAngle)
155 : PathOpItem(ARCTO_OPITEM), pt1_(pt1), pt2_(pt2), startAngle_(startAngle), sweepAngle_(sweepAngle),
156 direction_(PathDirection::CW_DIRECTION), methodIndex_(FUNCTION_OVERLOADING_1) {}
157
ArcToOpItem(const scalar rx,const scalar ry,const scalar angle,const PathDirection direction,const scalar endX,const scalar endY)158 ArcToOpItem::ArcToOpItem(const scalar rx, const scalar ry, const scalar angle, const PathDirection direction,
159 const scalar endX, const scalar endY) : PathOpItem(ARCTO_OPITEM), pt1_(rx, ry), pt2_(endX, endY),
160 startAngle_(angle), sweepAngle_(0), direction_(direction), methodIndex_(FUNCTION_OVERLOADING_2) {}
161
Playback(PathPlayer & player,const void * opItem)162 void ArcToOpItem::Playback(PathPlayer& player, const void* opItem)
163 {
164 if (opItem != nullptr) {
165 const auto* op = static_cast<const ArcToOpItem*>(opItem);
166 op->Playback(player.path_);
167 }
168 }
169
Playback(Path & path) const170 void ArcToOpItem::Playback(Path& path) const
171 {
172 if (methodIndex_ == FUNCTION_OVERLOADING_1) {
173 path.ArcTo(pt1_, pt2_, startAngle_, sweepAngle_);
174 } else if (methodIndex_ == FUNCTION_OVERLOADING_2) {
175 path.ArcTo(pt1_.GetX(), pt1_.GetY(), startAngle_, direction_, pt2_.GetX(), pt2_.GetY());
176 }
177 }
178
CubicToOpItem(const Point & ctrlPt1,const Point & ctrlPt2,const Point & endPt)179 CubicToOpItem::CubicToOpItem(const Point& ctrlPt1, const Point& ctrlPt2, const Point& endPt)
180 : PathOpItem(CUBICTO_OPITEM), ctrlPt1_(ctrlPt1), ctrlPt2_(ctrlPt2), endPt_(endPt) {}
181
Playback(PathPlayer & player,const void * opItem)182 void CubicToOpItem::Playback(PathPlayer& player, const void* opItem)
183 {
184 if (opItem != nullptr) {
185 const auto* op = static_cast<const CubicToOpItem*>(opItem);
186 op->Playback(player.path_);
187 }
188 }
189
Playback(Path & path) const190 void CubicToOpItem::Playback(Path& path) const
191 {
192 path.CubicTo(ctrlPt1_, ctrlPt2_, endPt_);
193 }
194
QuadToOpItem(const Point & ctrlPt,const Point & endPt)195 QuadToOpItem::QuadToOpItem(const Point& ctrlPt, const Point& endPt)
196 : PathOpItem(QUADTO_OPITEM), ctrlPt_(ctrlPt), endPt_(endPt) {}
197
Playback(PathPlayer & player,const void * opItem)198 void QuadToOpItem::Playback(PathPlayer& player, const void* opItem)
199 {
200 if (opItem != nullptr) {
201 const auto* op = static_cast<const QuadToOpItem*>(opItem);
202 op->Playback(player.path_);
203 }
204 }
205
Playback(Path & path) const206 void QuadToOpItem::Playback(Path& path) const
207 {
208 path.QuadTo(ctrlPt_, endPt_);
209 }
210
AddRectOpItem(const Rect & rect,PathDirection dir)211 AddRectOpItem::AddRectOpItem(const Rect& rect, PathDirection dir)
212 : PathOpItem(ADDRECT_OPITEM), rect_(rect), dir_(dir) {}
213
Playback(PathPlayer & player,const void * opItem)214 void AddRectOpItem::Playback(PathPlayer& player, const void* opItem)
215 {
216 if (opItem != nullptr) {
217 const auto* op = static_cast<const AddRectOpItem*>(opItem);
218 op->Playback(player.path_);
219 }
220 }
221
Playback(Path & path) const222 void AddRectOpItem::Playback(Path& path) const
223 {
224 path.AddRect(rect_, dir_);
225 }
226
AddOvalOpItem(const Rect & oval,PathDirection dir)227 AddOvalOpItem::AddOvalOpItem(const Rect& oval, PathDirection dir)
228 : PathOpItem(ADDOVAL_OPITEM), rect_(oval), dir_(dir) {}
229
Playback(PathPlayer & player,const void * opItem)230 void AddOvalOpItem::Playback(PathPlayer& player, const void* opItem)
231 {
232 if (opItem != nullptr) {
233 const auto* op = static_cast<const AddOvalOpItem*>(opItem);
234 op->Playback(player.path_);
235 }
236 }
237
Playback(Path & path) const238 void AddOvalOpItem::Playback(Path& path) const
239 {
240 path.AddOval(rect_, dir_);
241 }
242
AddArcOpItem(const Rect & oval,const scalar startAngle,const scalar sweepAngle)243 AddArcOpItem::AddArcOpItem(const Rect& oval, const scalar startAngle, const scalar sweepAngle)
244 : PathOpItem(ADDARC_OPITEM), rect_(oval), startAngle_(startAngle), sweepAngle_(sweepAngle) {}
245
Playback(PathPlayer & player,const void * opItem)246 void AddArcOpItem::Playback(PathPlayer& player, const void* opItem)
247 {
248 if (opItem != nullptr) {
249 const auto* op = static_cast<const AddArcOpItem*>(opItem);
250 op->Playback(player.path_);
251 }
252 }
253
Playback(Path & path) const254 void AddArcOpItem::Playback(Path& path) const
255 {
256 path.AddArc(rect_, startAngle_, sweepAngle_);
257 }
258
AddPolyOpItem(const std::pair<uint32_t,size_t> & points,int32_t count,bool close)259 AddPolyOpItem::AddPolyOpItem(const std::pair<uint32_t, size_t>& points, int32_t count, bool close)
260 : PathOpItem(ADDPOLY_OPITEM), points_(points), count_(count), close_(close) {}
261
Playback(PathPlayer & player,const void * opItem)262 void AddPolyOpItem::Playback(PathPlayer& player, const void* opItem)
263 {
264 if (opItem != nullptr) {
265 const auto* op = static_cast<const AddPolyOpItem*>(opItem);
266 op->Playback(player.path_, player.cmdList_);
267 }
268 }
269
Playback(Path & path,const CmdList & cmdList) const270 void AddPolyOpItem::Playback(Path& path, const CmdList& cmdList) const
271 {
272 std::vector<Point> points = CmdListHelper::GetVectorFromCmdList<Point>(cmdList, points_);
273 path.AddPoly(points, count_, close_);
274 }
275
AddCircleOpItem(const scalar x,const scalar y,const scalar radius,PathDirection dir)276 AddCircleOpItem::AddCircleOpItem(const scalar x, const scalar y, const scalar radius, PathDirection dir)
277 : PathOpItem(ADDCIRCLE_OPITEM), x_(x), y_(y), radius_(radius), dir_(dir) {}
278
Playback(PathPlayer & player,const void * opItem)279 void AddCircleOpItem::Playback(PathPlayer& player, const void* opItem)
280 {
281 if (opItem != nullptr) {
282 const auto* op = static_cast<const AddCircleOpItem*>(opItem);
283 op->Playback(player.path_);
284 }
285 }
286
Playback(Path & path) const287 void AddCircleOpItem::Playback(Path& path) const
288 {
289 path.AddCircle(x_, y_, radius_, dir_);
290 }
291
AddRoundRectOpItem(const std::pair<uint32_t,size_t> & radiusXYData,const Rect & rect,PathDirection dir)292 AddRoundRectOpItem::AddRoundRectOpItem(const std::pair<uint32_t, size_t>& radiusXYData, const Rect& rect,
293 PathDirection dir) : PathOpItem(ADDRRECT_OPITEM), radiusXYData_(radiusXYData), rect_(rect), dir_(dir) {}
294
Playback(PathPlayer & player,const void * opItem)295 void AddRoundRectOpItem::Playback(PathPlayer& player, const void* opItem)
296 {
297 if (opItem != nullptr) {
298 const auto* op = static_cast<const AddRoundRectOpItem*>(opItem);
299 op->Playback(player.path_, player.cmdList_);
300 }
301 }
302
Playback(Path & path,const CmdList & cmdList) const303 void AddRoundRectOpItem::Playback(Path& path, const CmdList& cmdList) const
304 {
305 auto radiusXYData = CmdListHelper::GetVectorFromCmdList<Point>(cmdList, radiusXYData_);
306 RoundRect roundRect(rect_, radiusXYData);
307
308 path.AddRoundRect(roundRect, dir_);
309 }
310
AddPathOpItem(const CmdListHandle & src,const scalar x,const scalar y)311 AddPathOpItem::AddPathOpItem(const CmdListHandle& src, const scalar x, const scalar y)
312 : PathOpItem(ADDPATH_OPITEM), src_(src), x_(x), y_(y), methodIndex_(FUNCTION_OVERLOADING_1) {}
313
AddPathOpItem(const CmdListHandle & src)314 AddPathOpItem::AddPathOpItem(const CmdListHandle& src)
315 : PathOpItem(ADDPATH_OPITEM), src_(src), x_(0), y_(0), methodIndex_(FUNCTION_OVERLOADING_2) {}
316
Playback(PathPlayer & player,const void * opItem)317 void AddPathOpItem::Playback(PathPlayer& player, const void* opItem)
318 {
319 if (opItem != nullptr) {
320 const auto* op = static_cast<const AddPathOpItem*>(opItem);
321 op->Playback(player.path_, player.cmdList_);
322 }
323 }
324
Playback(Path & path,const CmdList & cmdList) const325 void AddPathOpItem::Playback(Path& path, const CmdList& cmdList) const
326 {
327 auto srcPath = CmdListHelper::GetFromCmdList<PathCmdList, Path>(cmdList, src_);
328 if (srcPath == nullptr) {
329 return;
330 }
331
332 if (methodIndex_ == FUNCTION_OVERLOADING_1) {
333 path.AddPath(*srcPath, x_, y_);
334 } else if (methodIndex_ == FUNCTION_OVERLOADING_2) {
335 path.AddPath(*srcPath);
336 }
337 }
338
AddPathWithMatrixOpItem(const CmdListHandle & src,const Matrix & matrix)339 AddPathWithMatrixOpItem::AddPathWithMatrixOpItem(const CmdListHandle& src, const Matrix& matrix)
340 : PathOpItem(ADDPATHWITHMATRIX_OPITEM), src_(src)
341 {
342 matrix.GetAll(matrixBuffer_);
343 }
344
Playback(PathPlayer & player,const void * opItem)345 void AddPathWithMatrixOpItem::Playback(PathPlayer& player, const void* opItem)
346 {
347 if (opItem != nullptr) {
348 const auto* op = static_cast<const AddPathWithMatrixOpItem*>(opItem);
349 op->Playback(player.path_, player.cmdList_);
350 }
351 }
352
Playback(Path & path,const CmdList & cmdList) const353 void AddPathWithMatrixOpItem::Playback(Path& path, const CmdList& cmdList) const
354 {
355 auto srcPath = CmdListHelper::GetFromCmdList<PathCmdList, Path>(cmdList, src_);
356 if (srcPath == nullptr) {
357 return;
358 }
359
360 Matrix matrix;
361 for (uint32_t i = 0; i < matrixBuffer_.size(); i++) {
362 matrix.Set(static_cast<Matrix::Index>(i), matrixBuffer_[i]);
363 }
364
365 path.AddPath(*srcPath, matrix);
366 }
367
ReverseAddPathOpItem(const CmdListHandle & src)368 ReverseAddPathOpItem::ReverseAddPathOpItem(const CmdListHandle& src)
369 : PathOpItem(REVERSEADDPATH_OPITEM), src_(src) {}
370
Playback(PathPlayer & player,const void * opItem)371 void ReverseAddPathOpItem::Playback(PathPlayer& player, const void* opItem)
372 {
373 if (opItem != nullptr) {
374 const auto* op = static_cast<const ReverseAddPathOpItem*>(opItem);
375 op->Playback(player.path_, player.cmdList_);
376 }
377 }
378
Playback(Path & path,const CmdList & cmdList) const379 void ReverseAddPathOpItem::Playback(Path& path, const CmdList& cmdList) const
380 {
381 auto srcPath = CmdListHelper::GetFromCmdList<PathCmdList, Path>(cmdList, src_);
382 if (srcPath == nullptr) {
383 return;
384 }
385
386 path.ReverseAddPath(*srcPath);
387 }
388
SetFillStyleOpItem(PathFillType fillstyle)389 SetFillStyleOpItem::SetFillStyleOpItem(PathFillType fillstyle)
390 : PathOpItem(SETFILLSTYLE_OPITEM), fillstyle_(fillstyle) {}
391
Playback(PathPlayer & player,const void * opItem)392 void SetFillStyleOpItem::Playback(PathPlayer& player, const void* opItem)
393 {
394 if (opItem != nullptr) {
395 const auto* op = static_cast<const SetFillStyleOpItem*>(opItem);
396 op->Playback(player.path_);
397 }
398 }
399
Playback(Path & path) const400 void SetFillStyleOpItem::Playback(Path& path) const
401 {
402 path.SetFillStyle(fillstyle_);
403 }
404
BuildFromInterpolateOpItem(const CmdListHandle & src,const CmdListHandle & ending,const scalar weight)405 BuildFromInterpolateOpItem::BuildFromInterpolateOpItem(const CmdListHandle& src, const CmdListHandle& ending,
406 const scalar weight) : PathOpItem(BUILDFROMINTERPOLATE_OPITEM), src_(src), ending_(ending), weight_(weight) {}
407
Playback(PathPlayer & player,const void * opItem)408 void BuildFromInterpolateOpItem::Playback(PathPlayer& player, const void* opItem)
409 {
410 if (opItem != nullptr) {
411 const auto* op = static_cast<const BuildFromInterpolateOpItem*>(opItem);
412 op->Playback(player.path_, player.cmdList_);
413 }
414 }
415
Playback(Path & path,const CmdList & cmdList) const416 void BuildFromInterpolateOpItem::Playback(Path& path, const CmdList& cmdList) const
417 {
418 auto srcPath = CmdListHelper::GetFromCmdList<PathCmdList, Path>(cmdList, src_);
419 auto endingPath = CmdListHelper::GetFromCmdList<PathCmdList, Path>(cmdList, ending_);
420 if (srcPath == nullptr || endingPath == nullptr) {
421 return;
422 }
423
424 path.BuildFromInterpolate(*srcPath, *endingPath, weight_);
425 }
426
TransformOpItem(const Matrix & matrix)427 TransformOpItem::TransformOpItem(const Matrix& matrix) : PathOpItem(TRANSFORM_OPITEM)
428 {
429 matrix.GetAll(matrixBuffer_);
430 }
431
Playback(PathPlayer & player,const void * opItem)432 void TransformOpItem::Playback(PathPlayer& player, const void* opItem)
433 {
434 if (opItem != nullptr) {
435 const auto* op = static_cast<const TransformOpItem*>(opItem);
436 op->Playback(player.path_);
437 }
438 }
439
Playback(Path & path) const440 void TransformOpItem::Playback(Path& path) const
441 {
442 Matrix matrix;
443 for (uint32_t i = 0; i < matrixBuffer_.size(); i++) {
444 matrix.Set(static_cast<Matrix::Index>(i), matrixBuffer_[i]);
445 }
446
447 path.Transform(matrix);
448 }
449
OffsetOpItem(const scalar dx,const scalar dy)450 OffsetOpItem::OffsetOpItem(const scalar dx, const scalar dy) : PathOpItem(OFFSET_OPITEM), x_(dx), y_(dy) {}
451
Playback(PathPlayer & player,const void * opItem)452 void OffsetOpItem::Playback(PathPlayer& player, const void* opItem)
453 {
454 if (opItem != nullptr) {
455 const auto* op = static_cast<const OffsetOpItem*>(opItem);
456 op->Playback(player.path_);
457 }
458 }
459
Playback(Path & path) const460 void OffsetOpItem::Playback(Path& path) const
461 {
462 path.Offset(x_, y_);
463 }
464
PathOpWithOpItem(const CmdListHandle & path1,const CmdListHandle & path2,PathOp op)465 PathOpWithOpItem::PathOpWithOpItem(const CmdListHandle& path1, const CmdListHandle& path2, PathOp op)
466 : PathOpItem(PATHOPWITH_OPITEM), path1_(path1), path2_(path2), op_(op) {}
467
Playback(PathPlayer & player,const void * opItem)468 void PathOpWithOpItem::Playback(PathPlayer& player, const void* opItem)
469 {
470 if (opItem != nullptr) {
471 const auto* op = static_cast<const PathOpWithOpItem*>(opItem);
472 op->Playback(player.path_, player.cmdList_);
473 }
474 }
475
Playback(Path & path,const CmdList & cmdList) const476 void PathOpWithOpItem::Playback(Path& path, const CmdList& cmdList) const
477 {
478 auto path1 = CmdListHelper::GetFromCmdList<PathCmdList, Path>(cmdList, path1_);
479 auto path2 = CmdListHelper::GetFromCmdList<PathCmdList, Path>(cmdList, path2_);
480 if (path1 == nullptr || path2 == nullptr) {
481 return;
482 }
483
484 path.Op(*path1, *path2, op_);
485 }
486
ResetOpItem()487 ResetOpItem::ResetOpItem() : PathOpItem(RESET_OPITEM) {}
488
Playback(PathPlayer & player,const void * opItem)489 void ResetOpItem::Playback(PathPlayer& player, const void* opItem)
490 {
491 if (opItem != nullptr) {
492 const auto* op = static_cast<const ResetOpItem*>(opItem);
493 op->Playback(player.path_);
494 }
495 }
496
Playback(Path & path) const497 void ResetOpItem::Playback(Path& path) const
498 {
499 path.Reset();
500 }
501
CloseOpItem()502 CloseOpItem::CloseOpItem() : PathOpItem(CLOSE_OPITEM) {}
503
Playback(PathPlayer & player,const void * opItem)504 void CloseOpItem::Playback(PathPlayer& player, const void* opItem)
505 {
506 if (opItem != nullptr) {
507 const auto* op = static_cast<const CloseOpItem*>(opItem);
508 op->Playback(player.path_);
509 }
510 }
511
Playback(Path & path) const512 void CloseOpItem::Playback(Path& path) const
513 {
514 path.Close();
515 }
516 } // namespace Drawing
517 } // namespace Rosen
518 } // namespace OHOS
519