• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef RENDER_SERVICE_CLIENT_CORE_COMMON_RS_RECT_H
17 #define RENDER_SERVICE_CLIENT_CORE_COMMON_RS_RECT_H
18 #include <cmath>
19 #include <unordered_set>
20 
21 #include "common/rs_common_def.h"
22 #include "common/rs_vector2.h"
23 #include "common/rs_vector4.h"
24 #include "platform/common/rs_log.h"
25 #include "transaction/rs_marshalling_helper.h"
26 
27 namespace OHOS {
28 namespace Rosen {
29 template<typename T>
30 class RectT {
31 public:
32     union {
33         struct {
34             T left_;
35             T top_;
36             T width_;
37             T height_;
38         };
39         T data_[4]; // 4 is size of data or structure
40     };
41 
RectT()42     RectT()
43     {
44         data_[0] = 0;
45         data_[1] = 0;
46         data_[2] = 0;
47         data_[3] = 0;
48     }
RectT(T left,T top,T width,T height)49     RectT(T left, T top, T width, T height)
50     {
51         data_[0] = left;
52         data_[1] = top;
53         data_[2] = width;
54         data_[3] = height;
55     }
RectT(Vector4<T> vector)56     RectT(Vector4<T> vector)
57     {
58         data_[0] = vector[0];
59         data_[1] = vector[1];
60         data_[2] = vector[2];
61         data_[3] = vector[3];
62     }
RectT(const T * v)63     explicit RectT(const T* v)
64     {
65         data_[0] = v[0];
66         data_[1] = v[1];
67         data_[2] = v[2];
68         data_[3] = v[3];
69     }
70     ~RectT() = default;
71 
72     inline bool operator==(const RectT<T>& rect) const
73     {
74         return ROSEN_EQ<T>(left_, rect.left_) && ROSEN_EQ<T>(top_, rect.top_) &&
75             ROSEN_EQ<T>(width_, rect.width_) && ROSEN_EQ<T>(height_, rect.height_);
76     }
77 
78     inline bool operator!=(const RectT<T>& rect) const
79     {
80         return !operator==(rect);
81     }
82 
83     inline RectT& operator=(const RectT& other)
84     {
85         const T* oData = other.data_;
86         data_[0] = oData[0];
87         data_[1] = oData[1];
88         data_[2] = oData[2];
89         data_[3] = oData[3];
90         return *this;
91     }
SetAll(T left,T top,T width,T height)92     void SetAll(T left, T top, T width, T height)
93     {
94         data_[0] = left;
95         data_[1] = top;
96         data_[2] = width;
97         data_[3] = height;
98     }
GetRight()99     T GetRight() const
100     {
101         return left_ + width_;
102     }
GetLeft()103     T GetLeft() const
104     {
105         return left_;
106     }
GetBottom()107     T GetBottom() const
108     {
109         return top_ + height_;
110     }
GetTop()111     T GetTop() const
112     {
113         return top_;
114     }
GetWidth()115     T GetWidth() const
116     {
117         return width_;
118     }
GetHeight()119     T GetHeight() const
120     {
121         return height_;
122     }
SetRight(T right)123     void SetRight(T right)
124     {
125         width_ = right - left_;
126     }
SetBottom(T bottom)127     void SetBottom(T bottom)
128     {
129         height_ = bottom - top_;
130     }
Move(T x,T y)131     void Move(T x, T y)
132     {
133         left_ += x;
134         top_ += y;
135     }
Clear()136     void Clear()
137     {
138         left_ = 0;
139         top_ = 0;
140         width_ = 0;
141         height_ = 0;
142     }
IsEmpty()143     bool IsEmpty() const
144     {
145         return width_ <= 0 || height_ <= 0;
146     }
Intersect(T x,T y)147     bool Intersect(T x, T y) const
148     {
149         return (x >= left_) && (x < GetRight()) && (y >= top_) && (y < GetBottom());
150     }
IsInsideOf(const RectT<T> & rect)151     bool IsInsideOf(const RectT<T>& rect) const
152     {
153         return (top_ >= rect.top_ && left_ >= rect.left_ &&
154             GetBottom() <= rect.GetBottom() && GetRight() <= rect.GetRight());
155     }
IntersectRect(const RectT<T> & rect)156     RectT<T> IntersectRect(const RectT<T>& rect) const
157     {
158         T left = std::max(left_, rect.left_);
159         T top = std::max(top_, rect.top_);
160         T width = std::min(GetRight(), rect.GetRight()) - left;
161         T height = std::min(GetBottom(), rect.GetBottom()) - top;
162         return ((width <= 0) || (height <= 0)) ? RectT<T>() : RectT<T>(left, top, width, height);
163     }
JoinRect(const RectT<T> & rect)164     RectT<T> JoinRect(const RectT<T>& rect) const
165     {
166         if (rect.IsEmpty()) {
167             return RectT<T>(left_, top_, width_, height_);
168         }
169         if (IsEmpty()) {
170             return rect;
171         }
172         T left = std::min(left_, rect.left_);
173         T top = std::min(top_, rect.top_);
174         T width = std::max(GetRight(), rect.GetRight()) - left;
175         T height = std::max(GetBottom(), rect.GetBottom()) - top;
176         return ((width <= 0) || (height <= 0)) ? RectT<T>() : RectT<T>(left, top, width, height);
177     }
Offset(const T x,const T y)178     RectT<T> Offset(const T x, const T y) const
179     {
180         return RectT<T>(left_ + x, top_ + y, width_, height_);
181     }
182     template<typename P>
ConvertTo()183     RectT<P> ConvertTo()
184     {
185         return RectT<P>(static_cast<P>(left_), static_cast<P>(top_), static_cast<P>(width_), static_cast<P>(height_));
186     }
ToString()187     std::string ToString() const
188     {
189         return std::string("(") + std::to_string(left_) + ", " + std::to_string(top_) + ", " +
190             std::to_string(width_) + ", " + std::to_string(height_) + ")";
191     }
192 
193     #ifdef ROSEN_OHOS
Marshalling(Parcel & parcel)194     bool Marshalling(Parcel& parcel) const
195     {
196         if (!(RSMarshallingHelper::Marshalling(parcel, left_) &&
197                 RSMarshallingHelper::Marshalling(parcel, top_) &&
198                 RSMarshallingHelper::Marshalling(parcel, width_) &&
199                 RSMarshallingHelper::Marshalling(parcel, height_))) {
200             ROSEN_LOGE("RectT::Marshalling failed!");
201             return false;
202         }
203         return true;
204     }
205 
Unmarshalling(Parcel & parcel)206     [[nodiscard]] static RectT<T>* Unmarshalling(Parcel& parcel)
207     {
208         auto rect = std::make_unique<RectT<T>>();
209         if (!(RSMarshallingHelper::Unmarshalling(parcel, rect->left_) &&
210                 RSMarshallingHelper::Unmarshalling(parcel, rect->top_) &&
211                 RSMarshallingHelper::Unmarshalling(parcel, rect->width_) &&
212                 RSMarshallingHelper::Unmarshalling(parcel, rect->height_))) {
213             ROSEN_LOGE("RectT::Unmarshalling failed!");
214             return nullptr;
215         }
216         return rect.release();
217     }
218     #endif
219 };
220 
221 typedef RectT<int> RectI;
222 typedef RectT<float> RectF;
223 
224 /*
225     RectIComparator: Used for comparing rects
226     RectI_Hash_Func: provide hash value for rect comparing
227 */
228 struct RectIComparator {
operatorRectIComparator229     bool operator()(const RectI& r1, const RectI& r2) const
230     {
231         return r2.IsInsideOf(r1);
232     }
233 };
234 
235 struct RectI_Hash_Func {
operatorRectI_Hash_Func236     size_t operator()(const RectI& _r) const
237     {
238         // this is set for all rects can be compared
239         int hash_value = 0;
240         return std::hash<int>()(hash_value);
241     }
242 };
243 
244 typedef std::unordered_set<RectI, RectI_Hash_Func, RectIComparator> OcclusionRectISet;
245 
246 template<typename T>
247 class RRectT {
248 public:
249     RectT<T> rect_ = RectT<T>();
250     Vector2f radius_[4] = { { 0, 0 } };
251 
RRectT()252     RRectT() {}
253     ~RRectT() = default;
254 
RRectT(RectT<T> rect,float rx,float ry)255     RRectT(RectT<T> rect, float rx, float ry)
256     {
257         rect_ = rect;
258         Vector2f vec = Vector2f(rx, ry);
259         radius_[0] = vec;
260         radius_[1] = vec;
261         radius_[2] = vec;
262         radius_[3] = vec;
263     }
RRectT(RectT<T> rect,const Vector2f * radius)264     RRectT(RectT<T> rect, const Vector2f* radius)
265     {
266         rect_ = rect;
267         radius_[0] = radius[0];
268         radius_[1] = radius[1];
269         radius_[2] = radius[2];
270         radius_[3] = radius[3];
271     }
RRectT(RectT<T> rect,const Vector4f & radius)272     RRectT(RectT<T> rect, const Vector4f& radius)
273     {
274         rect_ = rect;
275         radius_[0] = { radius[0], radius[0] };
276         radius_[1] = { radius[1], radius[1] };
277         radius_[2] = { radius[2], radius[2] };
278         radius_[3] = { radius[3], radius[3] };
279     }
280 
SetValues(RectT<T> rect,const Vector2f * radius)281     void SetValues(RectT<T> rect, const Vector2f* radius)
282     {
283         rect_ = rect;
284         radius_[0] = radius[0];
285         radius_[1] = radius[1];
286         radius_[2] = radius[2];
287         radius_[3] = radius[3];
288     }
289 
290     RRectT operator-(const RRectT<T>& other) const;
291     RRectT operator+(const RRectT<T>& other) const;
292     RRectT operator/(float scale) const;
293     RRectT operator*(float scale) const;
294     RRectT& operator-=(const RRectT<T>& other);
295     RRectT& operator+=(const RRectT<T>& other);
296     RRectT& operator*=(float scale);
297     RRectT& operator=(const RRectT<T>& other);
298     bool operator==(const RRectT& other) const;
299     bool operator!=(const RRectT& other) const;
300 };
301 
302 typedef RRectT<float> RRect;
303 
304 template<typename T>
305 RRectT<T> RRectT<T>::operator-(const RRectT<T>& other) const
306 {
307     RRectT<T> rrect;
308     rrect.rect_.SetAll(rect_.GetLeft() - other.rect_.GetLeft(), rect_.GetTop() - other.rect_.GetTop(),
309         rect_.GetWidth() - other.rect_.GetWidth(), rect_.GetHeight() - other.rect_.GetHeight());
310     for (int index = 0; index < 4; index++) {
311         rrect.radius_[index] = radius_[index] - other.radius_[index];
312     }
313     return rrect;
314 }
315 
316 template<typename T>
317 RRectT<T> RRectT<T>::operator+(const RRectT<T>& other) const
318 {
319     RRectT<T> rrect;
320     rrect.rect_.SetAll(rect_.GetLeft() + other.rect_.GetLeft(), rect_.GetTop() + other.rect_.GetTop(),
321         rect_.GetWidth() + other.rect_.GetWidth(), rect_.GetHeight() + other.rect_.GetHeight());
322     for (int index = 0; index < 4; index++) {
323         rrect.radius_[index] = radius_[index] + other.radius_[index];
324     }
325     return rrect;
326 }
327 
328 template<typename T>
329 RRectT<T> RRectT<T>::operator/(float scale) const
330 {
331     if (ROSEN_EQ<float>(scale, 0)) {
332         return *this;
333     }
334     RRectT<T> rrect;
335     rrect.rect_.SetAll(rect_.GetLeft() / scale, rect_.GetTop() / scale,
336         rect_.GetWidth() / scale, rect_.GetHeight() / scale);
337     for (int index = 0; index < 4; index++) {
338         rrect.radius_[index] = radius_[index] / scale;
339     }
340     return rrect;
341 }
342 
343 template<typename T>
344 RRectT<T> RRectT<T>::operator*(float scale) const
345 {
346     RRectT<T> rrect;
347     rrect.rect_.SetAll(rect_.GetLeft() * scale, rect_.GetTop() * scale,
348         rect_.GetWidth() * scale, rect_.GetHeight() * scale);
349     for (int index = 0; index < 4; index++) {
350         rrect.radius_[index] = radius_[index] * scale;
351     }
352     return rrect;
353 }
354 
355 template<typename T>
356 RRectT<T>& RRectT<T>::operator-=(const RRectT<T>& other)
357 {
358     rect_.SetAll(rect_.GetLeft() - other.rect_.GetLeft(), rect_.GetTop() - other.rect_.GetTop(),
359         rect_.GetWidth() - other.rect_.GetWidth(), rect_.GetHeight() - other.rect_.GetHeight());
360     for (int index = 0; index < 4; index++) {
361         radius_[index] = radius_[index] - other.radius_[index];
362     }
363     return *this;
364 }
365 
366 template<typename T>
367 RRectT<T>& RRectT<T>::operator+=(const RRectT<T>& other)
368 {
369     rect_.SetAll(rect_.GetLeft() + other.rect_.GetLeft(), rect_.GetTop() + other.rect_.GetTop(),
370         rect_.GetWidth() + other.rect_.GetWidth(), rect_.GetHeight() + other.rect_.GetHeight());
371     for (int index = 0; index < 4; index++) {
372         radius_[index] = radius_[index] + other.radius_[index];
373     }
374     return *this;
375 }
376 
377 template<typename T>
378 RRectT<T>& RRectT<T>::operator*=(float scale)
379 {
380     rect_.SetAll(rect_.GetLeft() * scale, rect_.GetTop() * scale,
381         rect_.GetWidth() * scale, rect_.GetHeight() * scale);
382     for (int index = 0; index < 4; index++) {
383         radius_[index] = radius_[index] * scale;
384     }
385     return *this;
386 }
387 
388 template<typename T>
389 RRectT<T>& RRectT<T>::operator=(const RRectT<T>& other)
390 {
391     rect_ = other.rect_;
392     for (int index = 0; index < 4; index++) {
393         radius_[index] = other.radius_[index];
394     }
395     return *this;
396 }
397 
398 template<typename T>
399 inline bool RRectT<T>::operator==(const RRectT& other) const
400 {
401     return (rect_ == other.rect_) && (radius_[0] == other.radius_[0]) &&
402         (radius_[1] == other.radius_[1]) && (radius_[2] == other.radius_[2]) &&
403         (radius_[3] == other.radius_[3]);
404 }
405 
406 template<typename T>
407 inline bool RRectT<T>::operator!=(const RRectT& other) const
408 {
409     return !operator==(other);
410 }
411 } // namespace Rosen
412 } // namespace OHOS
413 #endif
414