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 "skia_region.h"
17 
18 #include "include/core/SkRegion.h"
19 #include "include/core/SkRect.h"
20 #include "src/core/SkReadBuffer.h"
21 #include "src/core/SkWriteBuffer.h"
22 
23 #include "utils/data.h"
24 #include "utils/region.h"
25 #include "utils/log.h"
26 #include "skia_path.h"
27 
28 namespace OHOS {
29 namespace Rosen {
30 namespace Drawing {
31 
SkiaRegion()32 SkiaRegion::SkiaRegion() noexcept : skRegion_(std::make_shared<SkRegion>()) {}
33 
Contains(int32_t x,int32_t y) const34 bool SkiaRegion::Contains(int32_t x, int32_t y) const
35 {
36     return skRegion_->contains(x, y);
37 }
38 
SetRect(const RectI & rectI)39 bool SkiaRegion::SetRect(const RectI& rectI)
40 {
41     auto skIRect = SkIRect::MakeLTRB(rectI.GetLeft(), rectI.GetTop(), rectI.GetRight(), rectI.GetBottom());
42     return skRegion_->setRect(skIRect);
43 }
44 
SetPath(const Path & path,const Region & clip)45 bool SkiaRegion::SetPath(const Path& path, const Region& clip)
46 {
47     auto skPath = path.GetImpl<SkiaPath>()->GetPath();
48     auto skRegion = clip.GetImpl<SkiaRegion>()->GetSkRegion();
49     if (skRegion == nullptr) {
50         LOGD("SkiaRegion::SetPath, skRegion is nullptr");
51         return false;
52     }
53 
54     return skRegion_->setPath(skPath, *skRegion);
55 }
56 
GetBoundaryPath(Path * path) const57 bool SkiaRegion::GetBoundaryPath(Path* path) const
58 {
59     if (!path) {
60         return skRegion_->getBoundaryPath(nullptr);
61     }
62     auto skiaPath = path->GetImpl<SkiaPath>();
63     if (!skiaPath) {
64         LOGD("SkiaRegion::GetBoundaryPath, skiaPath is nullptr");
65         return skRegion_->getBoundaryPath(nullptr);
66     }
67     SkPath skPath = skiaPath->GetPath();
68     bool res = skRegion_->getBoundaryPath(&skPath);
69     skiaPath->SetPath(skPath);
70     return res;
71 }
72 
IsIntersects(const Region & other) const73 bool SkiaRegion::IsIntersects(const Region& other) const
74 {
75     auto skRegion = other.GetImpl<SkiaRegion>()->GetSkRegion();
76     if (skRegion == nullptr) {
77         LOGD("SkiaRegion::IsIntersects, skRegion is nullptr");
78         return false;
79     }
80 
81     return skRegion_->intersects(*skRegion);
82 }
83 
IsEmpty() const84 bool SkiaRegion::IsEmpty() const
85 {
86     return skRegion_->isEmpty();
87 }
88 
IsRect() const89 bool SkiaRegion::IsRect() const
90 {
91     return skRegion_->isRect();
92 }
93 
IsRegionContained(const Region & other) const94 bool SkiaRegion::IsRegionContained(const Region& other) const
95 {
96     auto skRegion = other.GetImpl<SkiaRegion>()->GetSkRegion();
97     if (skRegion == nullptr) {
98         LOGD("SkiaRegion::IsRegionContained, skRegion is nullptr");
99         return false;
100     }
101 
102     return skRegion_->contains(*skRegion);
103 }
104 
Op(const Region & region,RegionOp op)105 bool SkiaRegion::Op(const Region& region, RegionOp op)
106 {
107     auto skRegion = region.GetImpl<SkiaRegion>()->GetSkRegion();
108     if (skRegion == nullptr) {
109         LOGD("SkiaRegion::Op, skRegion is nullptr");
110         return false;
111     }
112     return skRegion_->op(*skRegion, static_cast<SkRegion::Op>(op));
113 }
114 
QuickReject(const RectI & rectI) const115 bool SkiaRegion::QuickReject(const RectI& rectI) const
116 {
117     auto skIRect = SkIRect::MakeLTRB(rectI.GetLeft(), rectI.GetTop(), rectI.GetRight(), rectI.GetBottom());
118     return skRegion_->quickReject(skIRect);
119 }
120 
Clone(const Region & other)121 void SkiaRegion::Clone(const Region& other)
122 {
123     auto skRegion = other.GetImpl<SkiaRegion>()->GetSkRegion();
124     if (skRegion == nullptr) {
125         LOGD("SkiaRegion::Clone, skRegion is nullptr");
126         return;
127     }
128     *skRegion_ = *skRegion;
129 }
130 
Serialize() const131 std::shared_ptr<Data> SkiaRegion::Serialize() const
132 {
133     SkBinaryWriteBuffer writer;
134     writer.writeRegion(*skRegion_);
135     size_t length = writer.bytesWritten();
136     std::shared_ptr<Data> data = std::make_shared<Data>();
137     data->BuildUninitialized(length);
138     writer.writeToMemory(data->WritableData());
139     return data;
140 }
141 
Deserialize(std::shared_ptr<Data> data)142 bool SkiaRegion::Deserialize(std::shared_ptr<Data> data)
143 {
144     if (data == nullptr) {
145         LOGD("SkiaRegion::Deserialize, data is invalid!");
146         return false;
147     }
148     SkReadBuffer reader(data->GetData(), data->GetSize());
149     reader.readRegion(skRegion_.get());
150     return true;
151 }
152 
GetSkRegion() const153 std::shared_ptr<SkRegion> SkiaRegion::GetSkRegion() const
154 {
155     return skRegion_;
156 }
157 } // namespace Drawing
158 } // namespace Rosen
159 } // namespace OHOS
160