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