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/mask_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 namespace {
25 Pen defaultPen;
26 }
27
CreateFromData(const CmdListData & data,bool isCopy)28 std::shared_ptr<MaskCmdList> MaskCmdList::CreateFromData(const CmdListData& data, bool isCopy)
29 {
30 auto cmdList = std::make_shared<MaskCmdList>();
31 if (isCopy) {
32 cmdList->opAllocator_.BuildFromDataWithCopy(data.first, data.second);
33 } else {
34 cmdList->opAllocator_.BuildFromData(data.first, data.second);
35 }
36 return cmdList;
37 }
38
Playback(MaskPlayer & player) const39 bool MaskCmdList::Playback(MaskPlayer &player) const
40 {
41 uint32_t offset = 0;
42 size_t totalSize = opAllocator_.GetSize();
43 do {
44 if (totalSize < offset || totalSize - offset < sizeof(OpItem)) {
45 LOGD("MaskCmdList::Playback size error");
46 return false;
47 }
48 void* itemPtr = opAllocator_.OffsetToAddr(offset, sizeof(OpItem));
49 OpItem* curOpItemPtr = static_cast<OpItem*>(itemPtr);
50 if (curOpItemPtr != nullptr) {
51 if (!player.Playback(curOpItemPtr->GetType(), itemPtr, totalSize - offset)) {
52 LOGD("MaskCmdList::Playback failed!");
53 break;
54 }
55
56 offset = curOpItemPtr->GetNextOpItemOffset();
57 } else {
58 LOGE("MaskCmdList::Playback failed, opItem is nullptr");
59 break;
60 }
61 } while (offset != 0);
62
63 return true;
64 }
65
Playback(std::shared_ptr<Path> & path,Brush & brush) const66 bool MaskCmdList::Playback(std::shared_ptr<Path>& path, Brush& brush) const
67 {
68 MaskPlayer player(path, brush, *this);
69 return Playback(player);
70 }
71
Playback(std::shared_ptr<Path> & path,Pen & pen,Brush & brush) const72 bool MaskCmdList::Playback(std::shared_ptr<Path>& path, Pen& pen, Brush& brush) const
73 {
74 MaskPlayer player(path, brush, pen, *this);
75 return Playback(player);
76 }
77
78 /* OpItem */
79 std::unordered_map<uint32_t, MaskPlayer::MaskPlaybackFunc> MaskPlayer::opPlaybackFuncLUT_ = {
80 { MaskOpItem::MASK_BRUSH_OPITEM, MaskBrushOpItem::Playback },
81 { MaskOpItem::MASK_PATH_OPITEM, MaskPathOpItem::Playback },
82 { MaskOpItem::MASK_PEN_OPITEM, MaskPenOpItem::Playback },
83 };
84
MaskPlayer(std::shared_ptr<Path> & path,Brush & brush,const CmdList & cmdList)85 MaskPlayer::MaskPlayer(std::shared_ptr<Path>& path, Brush& brush, const CmdList& cmdList)
86 : path_(path), brush_(brush), pen_(defaultPen), cmdList_(cmdList) {}
87
MaskPlayer(std::shared_ptr<Path> & path,Brush & brush,Pen & pen,const CmdList & cmdList)88 MaskPlayer::MaskPlayer(std::shared_ptr<Path>& path, Brush& brush, Pen& pen, const CmdList& cmdList)
89 : path_(path), brush_(brush), pen_(pen), cmdList_(cmdList) {}
90
Playback(uint32_t type,const void * opItem,size_t leftOpAllocatorSize)91 bool MaskPlayer::Playback(uint32_t type, const void* opItem, size_t leftOpAllocatorSize)
92 {
93 if (type == MaskOpItem::OPITEM_HEAD) {
94 return true;
95 }
96
97 auto it = opPlaybackFuncLUT_.find(type);
98 if (it == opPlaybackFuncLUT_.end() || it->second == nullptr) {
99 return false;
100 }
101
102 auto func = it->second;
103 (*func)(*this, opItem, leftOpAllocatorSize);
104
105 return true;
106 }
107
MaskBrushOpItem(const BrushHandle & brushHandle)108 MaskBrushOpItem::MaskBrushOpItem(const BrushHandle& brushHandle)
109 : MaskOpItem(MASK_BRUSH_OPITEM), brushHandle_(brushHandle) {}
110
Playback(MaskPlayer & player,const void * opItem,size_t leftOpAllocatorSize)111 void MaskBrushOpItem::Playback(MaskPlayer& player, const void* opItem, size_t leftOpAllocatorSize)
112 {
113 if (opItem != nullptr && leftOpAllocatorSize >= sizeof(MaskBrushOpItem)) {
114 const auto* op = static_cast<const MaskBrushOpItem*>(opItem);
115 op->Playback(player.brush_, player.cmdList_);
116 }
117 }
118
Playback(Brush & brush,const CmdList & cmdList) const119 void MaskBrushOpItem::Playback(Brush& brush, const CmdList& cmdList) const
120 {
121 auto colorSpace = CmdListHelper::GetColorSpaceFromCmdList(
122 cmdList, brushHandle_.colorSpaceHandle);
123 auto shaderEffect = CmdListHelper::GetShaderEffectFromCmdList(
124 cmdList, brushHandle_.shaderEffectHandle);
125 auto colorFilter = CmdListHelper::GetColorFilterFromCmdList(
126 cmdList, brushHandle_.colorFilterHandle);
127 auto imageFilter = CmdListHelper::GetImageFilterFromCmdList(
128 cmdList, brushHandle_.imageFilterHandle);
129 auto maskFilter = CmdListHelper::GetMaskFilterFromCmdList(
130 cmdList, brushHandle_.maskFilterHandle);
131
132 Filter filter;
133 filter.SetColorFilter(colorFilter);
134 filter.SetImageFilter(imageFilter);
135 filter.SetMaskFilter(maskFilter);
136 filter.SetFilterQuality(brushHandle_.filterQuality);
137
138 const Color4f color4f = { brushHandle_.color.GetRedF(), brushHandle_.color.GetGreenF(),
139 brushHandle_.color.GetBlueF(), brushHandle_.color.GetAlphaF() };
140
141 brush.SetColor(color4f, colorSpace);
142 brush.SetShaderEffect(shaderEffect);
143 brush.SetBlendMode(brushHandle_.mode);
144 brush.SetAntiAlias(brushHandle_.isAntiAlias);
145 brush.SetFilter(filter);
146 }
147
MaskPathOpItem(const OpDataHandle & pathHandle)148 MaskPathOpItem::MaskPathOpItem(const OpDataHandle& pathHandle)
149 : MaskOpItem(MASK_PATH_OPITEM), pathHandle_(pathHandle) {}
150
Playback(MaskPlayer & player,const void * opItem,size_t leftOpAllocatorSize)151 void MaskPathOpItem::Playback(MaskPlayer& player, const void* opItem, size_t leftOpAllocatorSize)
152 {
153 if (opItem != nullptr && leftOpAllocatorSize >= sizeof(MaskPathOpItem)) {
154 const auto* op = static_cast<const MaskPathOpItem*>(opItem);
155 op->Playback(player.path_, player.cmdList_);
156 }
157 }
158
Playback(std::shared_ptr<Path> & path,const CmdList & cmdList) const159 void MaskPathOpItem::Playback(std::shared_ptr<Path>& path, const CmdList& cmdList) const
160 {
161 auto readPath = CmdListHelper::GetPathFromCmdList(cmdList, pathHandle_);
162 path = readPath;
163 }
164
MaskPenOpItem(const PenHandle & penHandle)165 MaskPenOpItem::MaskPenOpItem(const PenHandle& penHandle)
166 : MaskOpItem(MASK_PEN_OPITEM), penHandle_(penHandle) {}
167
Playback(MaskPlayer & player,const void * opItem,size_t leftOpAllocatorSize)168 void MaskPenOpItem::Playback(MaskPlayer &player, const void *opItem, size_t leftOpAllocatorSize)
169 {
170 if (opItem != nullptr && leftOpAllocatorSize >= sizeof(MaskPenOpItem)) {
171 const auto* op = static_cast<const MaskPenOpItem*>(opItem);
172 op->Playback(player.pen_, player.cmdList_);
173 }
174 }
175
Playback(Pen & pen,const CmdList & cmdList) const176 void MaskPenOpItem::Playback(Pen& pen, const CmdList& cmdList) const
177 {
178 pen.SetWidth(penHandle_.width);
179 pen.SetMiterLimit(penHandle_.miterLimit);
180 pen.SetJoinStyle(penHandle_.joinStyle);
181 pen.SetCapStyle(penHandle_.capStyle);
182
183 auto pathEffect = CmdListHelper::GetPathEffectFromCmdList(cmdList, penHandle_.pathEffectHandle);
184 pen.SetPathEffect(pathEffect);
185 pen.SetColor(penHandle_.color);
186 }
187 } // namespace Drawing
188 } // namespace Rosen
189 } // namespace OHOS
190