• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #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 #include <cinttypes>
21 
22 #include "common/rs_common_def.h"
23 #include "common/rs_vector2.h"
24 #include "common/rs_vector4.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         T data0 = vector[0];
59         T data1 = vector[1];
60         T data2 = vector[2];
61         T data3 = vector[3];
62         data_[0] = data0;
63         data_[1] = data1;
64         data_[2] = data2;
65         data_[3] = data3;
66     }
RectT(const T * v)67     explicit RectT(const T* v)
68     {
69         T data0 = v[0];
70         T data1 = v[1];
71         T data2 = v[2];
72         T data3 = v[3];
73         data_[0] = data0;
74         data_[1] = data1;
75         data_[2] = data2;
76         data_[3] = data3;
77     }
78     ~RectT() = default;
79 
80     inline bool operator==(const RectT<T>& rect) const
81     {
82         return ROSEN_EQ<T>(left_, rect.left_) && ROSEN_EQ<T>(top_, rect.top_) &&
83             ROSEN_EQ<T>(width_, rect.width_) && ROSEN_EQ<T>(height_, rect.height_);
84     }
85 
86     inline bool operator!=(const RectT<T>& rect) const
87     {
88         return !operator==(rect);
89     }
90 
91     inline bool IsNearEqual(const RectT<T>& rect, T threshold = std::numeric_limits<T>::epsilon()) const
92     {
93         return ROSEN_EQ<T>(left_, rect.left_, threshold) && ROSEN_EQ<T>(top_, rect.top_, threshold) &&
94             ROSEN_EQ<T>(width_, rect.width_, threshold) && ROSEN_EQ<T>(height_, rect.height_, threshold);
95     }
96 
97     inline RectT& operator=(const RectT& other)
98     {
99         const T* oData = other.data_;
100         T data0 = oData[0];
101         T data1 = oData[1];
102         T data2 = oData[2];
103         T data3 = oData[3];
104         data_[0] = data0;
105         data_[1] = data1;
106         data_[2] = data2;
107         data_[3] = data3;
108         return *this;
109     }
SetAll(T left,T top,T width,T height)110     void SetAll(T left, T top, T width, T height)
111     {
112         data_[0] = left;
113         data_[1] = top;
114         data_[2] = width;
115         data_[3] = height;
116     }
GetRight()117     T GetRight() const
118     {
119         return left_ + width_;
120     }
GetLeft()121     T GetLeft() const
122     {
123         return left_;
124     }
GetBottom()125     T GetBottom() const
126     {
127         return top_ + height_;
128     }
GetTop()129     T GetTop() const
130     {
131         return top_;
132     }
GetWidth()133     T GetWidth() const
134     {
135         return width_;
136     }
GetHeight()137     T GetHeight() const
138     {
139         return height_;
140     }
SetRight(T right)141     void SetRight(T right)
142     {
143         width_ = right - left_;
144     }
SetBottom(T bottom)145     void SetBottom(T bottom)
146     {
147         height_ = bottom - top_;
148     }
Move(T x,T y)149     void Move(T x, T y)
150     {
151         left_ += x;
152         top_ += y;
153     }
Clear()154     void Clear()
155     {
156         left_ = 0;
157         top_ = 0;
158         width_ = 0;
159         height_ = 0;
160     }
IsEmpty()161     bool IsEmpty() const
162     {
163         return width_ <= 0 || height_ <= 0;
164     }
Intersect(T x,T y)165     bool Intersect(T x, T y) const
166     {
167         return (x >= left_) && (x < GetRight()) && (y >= top_) && (y < GetBottom());
168     }
IsInsideOf(const RectT<T> & rect)169     bool IsInsideOf(const RectT<T>& rect) const
170     {
171         return (top_ >= rect.top_ && left_ >= rect.left_ &&
172             GetBottom() <= rect.GetBottom() && GetRight() <= rect.GetRight());
173     }
Intersect(const RectT<T> & other)174     bool Intersect(const RectT<T>& other) const
175     {
176         return !IsEmpty() && !other.IsEmpty() && (left_ <= other.left_ + other.width_) &&
177                (other.left_ <= left_ + width_) && (top_ <= other.top_ + other.height_) &&
178                (other.top_ <= top_ + height_);
179     }
IntersectRect(const RectT<T> & rect)180     RectT<T> IntersectRect(const RectT<T>& rect) const
181     {
182         T left = std::max(left_, rect.left_);
183         T top = std::max(top_, rect.top_);
184         T width = std::min(GetRight(), rect.GetRight()) - left;
185         T height = std::min(GetBottom(), rect.GetBottom()) - top;
186         return ((width <= 0) || (height <= 0)) ? RectT<T>() : RectT<T>(left, top, width, height);
187     }
JoinRect(const RectT<T> & rect)188     RectT<T> JoinRect(const RectT<T>& rect) const
189     {
190         if (rect.IsEmpty()) {
191             return RectT<T>(left_, top_, width_, height_);
192         }
193         if (IsEmpty()) {
194             return rect;
195         }
196         T left = std::min(left_, rect.left_);
197         T top = std::min(top_, rect.top_);
198         T width = std::max(GetRight(), rect.GetRight()) - left;
199         T height = std::max(GetBottom(), rect.GetBottom()) - top;
200         return ((width <= 0) || (height <= 0)) ? RectT<T>() : RectT<T>(left, top, width, height);
201     }
Offset(const T x,const T y)202     RectT<T> Offset(const T x, const T y) const
203     {
204         return RectT<T>(left_ + x, top_ + y, width_, height_);
205     }
206     template<typename P>
ConvertTo()207     RectT<P> ConvertTo() const
208     {
209         return RectT<P>(static_cast<P>(left_), static_cast<P>(top_), static_cast<P>(width_), static_cast<P>(height_));
210     }
ToString()211     std::string ToString() const
212     {
213         return std::string("[") + std::to_string(left_) + ", " + std::to_string(top_) + ", " +
214             std::to_string(width_) + ", " + std::to_string(height_) + "]";
215     }
216 
217     // outset: left, top, right, bottom
MakeOutset(Vector4<T> outset)218     RectT<T> MakeOutset(Vector4<T> outset) const
219     {
220         return RectT(left_ - outset.x_,
221                      top_ - outset.y_,
222                      width_ + outset.x_ + outset.z_,
223                      height_ + outset.y_ + outset.w_);
224     }
225 
226     #ifdef ROSEN_OHOS
Marshalling(Parcel & parcel)227     bool Marshalling(Parcel& parcel) const
228     {
229         if (!(RSMarshallingHelper::Marshalling(parcel, left_) &&
230                 RSMarshallingHelper::Marshalling(parcel, top_) &&
231                 RSMarshallingHelper::Marshalling(parcel, width_) &&
232                 RSMarshallingHelper::Marshalling(parcel, height_))) {
233             return false;
234         }
235         return true;
236     }
237 
Unmarshalling(Parcel & parcel)238     [[nodiscard]] static RectT<T>* Unmarshalling(Parcel& parcel)
239     {
240         auto rect = std::make_unique<RectT<T>>();
241         if (!(RSMarshallingHelper::Unmarshalling(parcel, rect->left_) &&
242                 RSMarshallingHelper::Unmarshalling(parcel, rect->top_) &&
243                 RSMarshallingHelper::Unmarshalling(parcel, rect->width_) &&
244                 RSMarshallingHelper::Unmarshalling(parcel, rect->height_))) {
245             return nullptr;
246         }
247         return rect.release();
248     }
249     #endif
250 };
251 
252 typedef RectT<int> RectI;
253 typedef RectT<float> RectF;
254 
255 /*
256     RectIComparator: Used for comparing rects
257     RectI_Hash_Func: provide hash value for rect comparing
258 */
259 struct RectIComparator {
operatorRectIComparator260     bool operator()(const std::pair<NodeId, RectI>& p1, const std::pair<NodeId, RectI>& p2) const
261     {
262         return p2.second.IsInsideOf(p1.second);
263     }
264 };
265 
266 struct RectI_Hash_Func {
operatorRectI_Hash_Func267     size_t operator()(const std::pair<NodeId, RectI>& p) const
268     {
269         // this is set for all rects can be compared
270         int hash_value = 0;
271         return std::hash<int>()(hash_value);
272     }
273 };
274 
275 typedef std::unordered_set<std::pair<NodeId, RectI>, RectI_Hash_Func, RectIComparator> OcclusionRectISet;
276 
277 struct FilterRectIComparator {
operatorFilterRectIComparator278     bool operator()(const std::pair<NodeId, RectI>& p1, const std::pair<NodeId, RectI>& p2) const
279     {
280         return p1.second == p2.second;
281     }
282 };
283 
284 struct Filter_RectI_Hash_Func {
operatorFilter_RectI_Hash_Func285     size_t operator()(const std::pair<NodeId, RectI>& p) const
286     {
287         return std::hash<NodeId>()(p.first);
288     }
289 };
290 typedef std::unordered_set<std::pair<NodeId, RectI>, Filter_RectI_Hash_Func, FilterRectIComparator> FilterRectISet;
291 
292 template<typename T>
293 class RRectT {
294 public:
295     RectT<T> rect_ = RectT<T>();
296     Vector2f radius_[4] = { { 0, 0 } };
297 
RRectT()298     RRectT() {}
299     ~RRectT() = default;
300 
RRectT(RectT<T> rect,float rx,float ry)301     RRectT(RectT<T> rect, float rx, float ry)
302     {
303         rect_ = rect;
304         Vector2f vec = Vector2f(rx, ry);
305         radius_[0] = vec;
306         radius_[1] = vec;
307         radius_[2] = vec;
308         radius_[3] = vec;
309     }
RRectT(RectT<T> rect,const Vector2f * radius)310     RRectT(RectT<T> rect, const Vector2f* radius)
311     {
312         rect_ = rect;
313         radius_[0] = radius[0];
314         radius_[1] = radius[1];
315         radius_[2] = radius[2];
316         radius_[3] = radius[3];
317     }
RRectT(RectT<T> rect,const Vector4f & radius)318     RRectT(RectT<T> rect, const Vector4f& radius)
319     {
320         rect_ = rect;
321         radius_[0] = { radius[0], radius[0] };
322         radius_[1] = { radius[1], radius[1] };
323         radius_[2] = { radius[2], radius[2] };
324         radius_[3] = { radius[3], radius[3] };
325     }
326 
SetValues(RectT<T> rect,const Vector2f * radius)327     void SetValues(RectT<T> rect, const Vector2f* radius)
328     {
329         rect_ = rect;
330         radius_[0] = radius[0];
331         radius_[1] = radius[1];
332         radius_[2] = radius[2];
333         radius_[3] = radius[3];
334     }
335 
ToString()336     std::string ToString() const
337     {
338         return std::string("rect [") +
339             std::to_string(rect_.left_) + ", " +
340             std::to_string(rect_.top_) + ", " +
341             std::to_string(rect_.width_) + ", " +
342             std::to_string(rect_.height_) +
343             "] radius: [" +
344             "(" + std::to_string(radius_[0].x_) + "," + std::to_string(radius_[0].y_) + ")," + //0: topLeft Corner
345             "(" + std::to_string(radius_[1].x_) + "," + std::to_string(radius_[1].y_) + ")," + //1: topRight Corner
346             "(" + std::to_string(radius_[2].x_) + "," + std::to_string(radius_[2].y_) + ")," + //2: bottomRight Corner
347             "(" + std::to_string(radius_[3].x_) + "," + std::to_string(radius_[3].y_) + ")]";  //3: bottomLeft Corner
348     }
349 
350     RRectT Inset(const Vector4<T> radius) const;
351     RRectT operator-(const RRectT<T>& other) const;
352     RRectT operator+(const RRectT<T>& other) const;
353     RRectT operator/(float scale) const;
354     RRectT operator*(float scale) const;
355     RRectT& operator-=(const RRectT<T>& other);
356     RRectT& operator+=(const RRectT<T>& other);
357     RRectT& operator*=(float scale);
358     RRectT& operator=(const RRectT<T>& other);
359     bool operator==(const RRectT& other) const;
360     bool operator!=(const RRectT& other) const;
361     bool IsNearEqual(const RRectT& other, T threshold = std::numeric_limits<T>::epsilon()) const;
362 };
363 
364 typedef RRectT<float> RRect;
365 
366 template<typename T>
Inset(const Vector4<T> width)367 RRectT<T> RRectT<T>::Inset(const Vector4<T> width) const
368 {
369     RRectT<T> rrect;
370     rrect.rect_.SetAll(rect_.GetLeft() + width.x_, rect_.GetTop() + width.y_,
371         rect_.GetWidth() - (width.x_ + width.z_),
372         rect_.GetHeight() - (width.y_ + width.w_));
373 
374     rrect.radius_[0] = radius_[0] - Vector2(width.x_, width.y_); // 0: topLeft Corner
375     rrect.radius_[1] = radius_[1] - Vector2(width.z_, width.y_); // 1: topRight Corner
376     rrect.radius_[2] = radius_[2] - Vector2(width.z_, width.w_); // 2: bottomRight Corner
377     rrect.radius_[3] = radius_[3] - Vector2(width.x_, width.w_); // 3: bottomLeft Corner
378     return rrect;
379 }
380 
381 template<typename T>
382 RRectT<T> RRectT<T>::operator-(const RRectT<T>& other) const
383 {
384     RRectT<T> rrect;
385     rrect.rect_.SetAll(rect_.GetLeft() - other.rect_.GetLeft(), rect_.GetTop() - other.rect_.GetTop(),
386         rect_.GetWidth() - other.rect_.GetWidth(), rect_.GetHeight() - other.rect_.GetHeight());
387     for (int index = 0; index < 4; index++) {
388         rrect.radius_[index] = radius_[index] - other.radius_[index];
389     }
390     return rrect;
391 }
392 
393 template<typename T>
394 RRectT<T> RRectT<T>::operator+(const RRectT<T>& other) const
395 {
396     RRectT<T> rrect;
397     rrect.rect_.SetAll(rect_.GetLeft() + other.rect_.GetLeft(), rect_.GetTop() + other.rect_.GetTop(),
398         rect_.GetWidth() + other.rect_.GetWidth(), rect_.GetHeight() + other.rect_.GetHeight());
399     for (int index = 0; index < 4; index++) {
400         rrect.radius_[index] = radius_[index] + other.radius_[index];
401     }
402     return rrect;
403 }
404 
405 template<typename T>
406 RRectT<T> RRectT<T>::operator/(float scale) const
407 {
408     if (ROSEN_EQ<float>(scale, 0)) {
409         return *this;
410     }
411     RRectT<T> rrect;
412     rrect.rect_.SetAll(rect_.GetLeft() / scale, rect_.GetTop() / scale,
413         rect_.GetWidth() / scale, rect_.GetHeight() / scale);
414     for (int index = 0; index < 4; index++) {
415         rrect.radius_[index] = radius_[index] / scale;
416     }
417     return rrect;
418 }
419 
420 template<typename T>
421 RRectT<T> RRectT<T>::operator*(float scale) const
422 {
423     RRectT<T> rrect;
424     rrect.rect_.SetAll(rect_.GetLeft() * scale, rect_.GetTop() * scale,
425         rect_.GetWidth() * scale, rect_.GetHeight() * scale);
426     for (int index = 0; index < 4; index++) {
427         rrect.radius_[index] = radius_[index] * scale;
428     }
429     return rrect;
430 }
431 
432 template<typename T>
433 RRectT<T>& RRectT<T>::operator-=(const RRectT<T>& other)
434 {
435     rect_.SetAll(rect_.GetLeft() - other.rect_.GetLeft(), rect_.GetTop() - other.rect_.GetTop(),
436         rect_.GetWidth() - other.rect_.GetWidth(), rect_.GetHeight() - other.rect_.GetHeight());
437     for (int index = 0; index < 4; index++) {
438         radius_[index] = radius_[index] - other.radius_[index];
439     }
440     return *this;
441 }
442 
443 template<typename T>
444 RRectT<T>& RRectT<T>::operator+=(const RRectT<T>& other)
445 {
446     rect_.SetAll(rect_.GetLeft() + other.rect_.GetLeft(), rect_.GetTop() + other.rect_.GetTop(),
447         rect_.GetWidth() + other.rect_.GetWidth(), rect_.GetHeight() + other.rect_.GetHeight());
448     for (int index = 0; index < 4; index++) {
449         radius_[index] = radius_[index] + other.radius_[index];
450     }
451     return *this;
452 }
453 
454 template<typename T>
455 RRectT<T>& RRectT<T>::operator*=(float scale)
456 {
457     rect_.SetAll(rect_.GetLeft() * scale, rect_.GetTop() * scale,
458         rect_.GetWidth() * scale, rect_.GetHeight() * scale);
459     for (int index = 0; index < 4; index++) {
460         radius_[index] = radius_[index] * scale;
461     }
462     return *this;
463 }
464 
465 template<typename T>
466 RRectT<T>& RRectT<T>::operator=(const RRectT<T>& other)
467 {
468     rect_ = other.rect_;
469     for (int index = 0; index < 4; index++) {
470         radius_[index] = other.radius_[index];
471     }
472     return *this;
473 }
474 
475 template<typename T>
476 inline bool RRectT<T>::operator==(const RRectT& other) const
477 {
478     return (rect_ == other.rect_) && (radius_[0] == other.radius_[0]) &&
479         (radius_[1] == other.radius_[1]) && (radius_[2] == other.radius_[2]) &&
480         (radius_[3] == other.radius_[3]);
481 }
482 
483 template<typename T>
484 inline bool RRectT<T>::operator!=(const RRectT& other) const
485 {
486     return !operator==(other);
487 }
488 
489 template<typename T>
IsNearEqual(const RRectT & rrectT,T threshold)490 inline bool RRectT<T>::IsNearEqual(const RRectT& rrectT, T threshold) const
491 {
492     return (rect_.IsNearEqual(rrectT.rect_, threshold)) && (radius_[0].IsNearEqual(rrectT.radius_[0], threshold)) &&
493         (radius_[1].IsNearEqual(rrectT.radius_[1], threshold)) &&
494         (radius_[2].IsNearEqual(rrectT.radius_[2], threshold)) &&
495         (radius_[3].IsNearEqual(rrectT.radius_[3], threshold));
496 }
497 } // namespace Rosen
498 } // namespace OHOS
499 #endif
500