1 /*
2  * Copyright (c) 2020-2021 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 /**
17  * @addtogroup UI_Utils
18  * @{
19  *
20  * @brief Defines basic UI utils.
21  *
22  * @since 1.0
23  * @version 1.0
24  */
25 
26 /**
27  * @file rect.h
28  *
29  * @brief Defines a rectangle, including the position data of the four boundaries of the rectangle, and provides
30  *        functions for rectangle inclusion, intersection, and aggregation.
31  * @since 1.0
32  * @version 1.0
33  */
34 
35 #ifndef GRAPHIC_LITE_RECT_H
36 #define GRAPHIC_LITE_RECT_H
37 
38 #include "gfx_utils/graphic_math.h"
39 #include "gfx_utils/graphic_types.h"
40 #include "gfx_utils/heap_base.h"
41 
42 namespace OHOS {
43 /**
44  * @brief Defines a rectangle, including the position data of the four boundaries of the rectangle, and provides
45  *        functions for rectangle inclusion, intersection, and aggregation.
46  * @since 1.0
47  * @version 1.0
48  */
49 template <typename T> class CommonRect : public HeapBase {
50 public:
51     /**
52      * @brief A constructor used to create a <b>CommonRect</b> instance.
53      * @since 1.0
54      * @version 1.0
55      */
CommonRect()56     CommonRect() : left_(0), top_(0), right_(0), bottom_(0) {}
57 
58     /**
59      * @brief A destructor used to delete the <b>CommonRect</b> instance.
60      * @since 1.0
61      * @version 1.0
62      */
~CommonRect()63     ~CommonRect() {}
64 
65     /**
66      * @brief A constructor used to create a <b>CommonRect</b> instance based on the coordinates of the four boundaries.
67      * @param left Indicates the coordinate of the left boundary.
68      * @param top Indicates the coordinate of the top boundary.
69      * @param right Indicates the coordinate of the right boundary.
70      * @param bottom Indicates the coordinate of the bottom boundary.
71      * @since 1.0
72      * @version 1.0
73      */
CommonRect(T left,T top,T right,T bottom)74     CommonRect(T left, T top, T right, T bottom) : left_(left), top_(top), right_(right), bottom_(bottom) {}
75 
76     /**
77      * @brief A constructor used to create a <b>CommonRect</b> instance by copying another rectangle.
78      *
79      * @param other Indicates the rectangle to copy.
80      * @since 1.0
81      * @version 1.0
82      */
83     CommonRect(const CommonRect<T>& other) = default;
84 
85     /**
86      * @brief A constructor used to create a <b>CommonRect</b> instance by copying another rectangle.
87      *
88      * @param other Indicates the rectangle to copy.
89      * @since 1.0
90      * @version 1.0
91      */
92     CommonRect(CommonRect<T>&& other) = default;
93 
94     /**
95      * @brief Sets the coordinates of the four boundaries of a rectangle.
96      *
97      * @param left Indicates the coordinate of the left boundary.
98      * @param top Indicates the coordinate of the top boundary.
99      * @param right Indicates the coordinate of the right boundary.
100      * @param bottom Indicates the coordinate of the bottom boundary.
101      * @since 1.0
102      * @version 1.0
103      */
SetRect(T left,T top,T right,T bottom)104     void SetRect(T left, T top, T right, T bottom)
105     {
106         left_ = left;
107         right_ = right;
108         top_ = top;
109         bottom_ = bottom;
110     }
111 
112     /**
113      * @brief Obtains the rectangle width.
114      * @return Returns the rectangle width.
115      * @since 1.0
116      * @version 1.0
117      */
GetWidth()118     T GetWidth() const
119     {
120         return right_ - left_ + 1;
121     }
122 
123     /**
124      * @brief Obtains the rectangle height.
125      * @return Returns the rectangle height.
126      * @since 1.0
127      * @version 1.0
128      */
GetHeight()129     T GetHeight() const
130     {
131         return bottom_ - top_ + 1;
132     }
133 
134     /**
135      * @brief Obtains the left boundary coordinate of the rectangle.
136      * @return Returns the left boundary coordinate.
137      * @since 1.0
138      * @version 1.0
139      */
GetX()140     T GetX() const
141     {
142         return left_;
143     }
144 
145     /**
146      * @brief Obtains the top boundary coordinate of the rectangle.
147      * @return Returns the top boundary coordinate.
148      * @since 1.0
149      * @version 1.0
150      */
GetY()151     T GetY() const
152     {
153         return top_;
154     }
155 
156     /**
157      * @brief Obtains the left boundary coordinate of the rectangle.
158      * @return Returns the left boundary coordinate.
159      * @since 1.0
160      * @version 1.0
161      */
GetLeft()162     T GetLeft() const
163     {
164         return left_;
165     }
166 
167     /**
168      * @brief Obtains the top boundary coordinate of the rectangle.
169      * @return Returns the top boundary coordinate.
170      * @since 1.0
171      * @version 1.0
172      */
GetTop()173     T GetTop() const
174     {
175         return top_;
176     }
177 
178     /**
179      * @brief Obtains the right boundary coordinate of the rectangle.
180      * @return Returns the right boundary coordinate.
181      * @since 1.0
182      * @version 1.0
183      */
GetRight()184     T GetRight() const
185     {
186         return right_;
187     }
188 
189     /**
190      * @brief Obtains the bottom boundary coordinate of the rectangle.
191      * @return Returns the bottom boundary coordinate.
192      * @since 1.0
193      * @version 1.0
194      */
GetBottom()195     T GetBottom() const
196     {
197         return bottom_;
198     }
199 
200     /**
201      * @brief Changes the left boundary coordinate of the rectangle without changing the rectangle width.
202      * @param x Indicates the coordinate of the left boundary.
203      * @since 1.0
204      * @version 1.0
205      */
SetX(T x)206     void SetX(T x)
207     {
208         right_ += x - left_;
209         left_ = x;
210     }
211 
212     /**
213      * @brief Changes the top boundary coordinate of the rectangle without changing the rectangle height.
214      * @param y Indicates the coordinate of the top boundary.
215      * @since 1.0
216      * @version 1.0
217      */
SetY(T y)218     void SetY(T y)
219     {
220         bottom_ += y - top_;
221         top_ = y;
222     }
223 
224     /**
225      * @brief Changes the coordinates of the left and top boundaries of the rectangle without changing the rectangle
226      *        width and height.
227      * @param x Indicates the coordinate of the left boundary.
228      * @param y Indicates the coordinate of the top boundary.
229      * @since 1.0
230      * @version 1.0
231      */
SetPosition(T x,T y)232     void SetPosition(T x, T y)
233     {
234         right_ += x - left_;
235         bottom_ += y - top_;
236         left_ = x;
237         top_ = y;
238     }
239 
240     /**
241      * @brief Changes the width of the rectangle without changing the coordinate of the left boundary.
242      * @param width Indicates the width of the rectangle.
243      * @since 1.0
244      * @version 1.0
245      */
SetWidth(T width)246     void SetWidth(T width)
247     {
248         right_ = left_ + width - 1;
249     }
250 
251     /**
252      * @brief Changes the height of the rectangle without changing the coordinate of the top boundary.
253      * @param height Indicates the height of the rectangle.
254      * @since 1.0
255      * @version 1.0
256      */
SetHeight(T height)257     void SetHeight(T height)
258     {
259         bottom_ = top_ + height - 1;
260     }
261 
262     /**
263      * @brief Sets the coordinate of the left boundary of a rectangle.
264      * @param left Indicates the coordinate of the left boundary.
265      * @since 1.0
266      * @version 1.0
267      */
SetLeft(T left)268     void SetLeft(T left)
269     {
270         left_ = left;
271     }
272 
273     /**
274      * @brief Sets the coordinate of the top boundary of a rectangle.
275      * @param top Indicates the coordinate of the top boundary.
276      * @since 1.0
277      * @version 1.0
278      */
SetTop(T top)279     void SetTop(T top)
280     {
281         top_ = top;
282     }
283 
284     /**
285      * @brief Sets the coordinate of the right boundary of a rectangle.
286      * @param right Indicates the coordinate of the right boundary.
287      * @since 1.0
288      * @version 1.0
289      */
SetRight(T right)290     void SetRight(T right)
291     {
292         right_ = right;
293     }
294 
295     /**
296      * @brief Sets the coordinate of the bottom boundary of a rectangle.
297      * @param bottom Indicates the coordinate of the bottom boundary.
298      * @since 1.0
299      * @version 1.0
300      */
SetBottom(T bottom)301     void SetBottom(T bottom)
302     {
303         bottom_ = bottom;
304     }
305 
306     /**
307      * @brief Sets the width and height of a rectangle.
308      * @param width Indicates the width of the rectangle.
309      * @param height Indicates the height of the rectangle.
310      * @since 1.0
311      * @version 1.0
312      */
Resize(T width,T height)313     void Resize(T width, T height)
314     {
315         right_ = left_ + width - 1;
316         bottom_ = top_ + height - 1;
317     }
318 
319     /**
320      * @brief Obtains the area of a rectangle.
321      * @return Returns the area of the rectangle.
322      * @since 1.0
323      * @version 1.0
324      */
GetSize()325     uint32_t GetSize() const
326     {
327         return static_cast<uint32_t>(right_ - left_ + 1) * (bottom_ - top_ + 1);
328     }
329 
330     /**
331      * @brief Checks whether two rectangles intersect.
332      * @param rect1 Indicates the first rectangle to check.
333      * @param rect2 Indicates the second rectangle to check.
334      * @return Returns <b>true</b> if the two rectangles intersect; returns <b>false</b> otherwise.
335      * @since 1.0
336      * @version 1.0
337      */
Intersect(const CommonRect<T> & rect1,const CommonRect<T> & rect2)338     bool Intersect(const CommonRect<T>& rect1, const CommonRect<T>& rect2)
339     {
340         /* Get the smaller area from 'rect1' and 'rect2' */
341         left_ = MATH_MAX(rect1.left_, rect2.left_);
342         top_ = MATH_MAX(rect1.top_, rect2.top_);
343         right_ = MATH_MIN(rect1.right_, rect2.right_);
344         bottom_ = MATH_MIN(rect1.bottom_, rect2.bottom_);
345         if ((left_ > right_) || (top_ > bottom_)) {
346             return false;
347         }
348 
349         return true;
350     }
351 
352     /**
353      * @brief Obtains the minimum rectangle that contains another two rectangles.
354      * @param rect1 Indicates the first rectangle to contain.
355      * @param rect2 Indicates the second rectangle to contain.
356      * @since 1.0
357      * @version 1.0
358      */
Join(const CommonRect<T> & rect1,const CommonRect<T> & rect2)359     void Join(const CommonRect<T>& rect1, const CommonRect<T>& rect2)
360     {
361         left_ = MATH_MIN(rect1.left_, rect2.left_);
362         top_ = MATH_MIN(rect1.top_, rect2.top_);
363         right_ = MATH_MAX(rect1.right_, rect2.right_);
364         bottom_ = MATH_MAX(rect1.bottom_, rect2.bottom_);
365     }
366 
367     /**
368      * @brief Checks whether the rectangle contains a coordinate point.
369      * @param point Indicates the coordinate point.
370      * @return Returns <b>true</b> if the input coordinate point is contained; returns <b>false</b> otherwise.
371      * @since 1.0
372      * @version 1.0
373      */
IsContains(const Vector2<T> & point)374     bool IsContains(const Vector2<T>& point) const
375     {
376         bool isContains = false;
377 
378         if ((point.x_ >= this->left_) && (point.x_ <= this->right_) && (point.y_ >= this->top_) &&
379             (point.y_ <= this->bottom_)) {
380             isContains = true;
381         }
382 
383         return isContains;
384     }
385 
386     /**
387      * @brief Checks whether the rectangle contains a coordinate point.
388      * @param point Indicates the coordinate point.
389      * @return Returns <b>true</b> if the input coordinate point is contained; returns <b>false</b> otherwise.
390      * @since 1.0
391      * @version 1.0
392      */
IsContains(const Point & point)393     bool IsContains(const Point& point) const
394     {
395         bool isContains = false;
396 
397         if ((point.x >= this->left_) && (point.x <= this->right_) && (point.y >= this->top_) &&
398             (point.y <= this->bottom_)) {
399             isContains = true;
400         }
401 
402         return isContains;
403     }
404 
405     /**
406      * @brief Checks whether the rectangle is adjacent to another rectangle horizontally or vertically.
407      * @param other Indicates the rectangle to be used for check.
408      * @return Returns <b>true</b> if the rectangle is adjacent to the input rectangle; returns <b>false</b> otherwise.
409      * @since 1.0
410      * @version 1.0
411      */
IsExtends(const CommonRect<T> & other)412     bool IsExtends(const CommonRect<T>& other) const
413     {
414         if (left_ == other.left_ && right_ == other.right_) {
415             return (top_ == other.bottom_ + 1) || (bottom_ == other.top_ - 1);
416         }
417 
418         if (top_ == other.top_ && bottom_ == other.bottom_) {
419             return (left_ == other.right_ + 1) || (right_ == other.left_ - 1);
420         }
421 
422         return false;
423     }
424 
425     /**
426      * @brief Checks whether the rectangle intersects with another rectangle.
427      * @param other Indicates the rectangle to be used for check.
428      * @return Returns <b>true</b> if the two rectangles intersect; returns <b>false</b> otherwise.
429      * @since 1.0
430      * @version 1.0
431      */
IsIntersect(const CommonRect<T> & other)432     bool IsIntersect(const CommonRect<T>& other) const
433     {
434         if ((this->left_ <= other.right_) && (this->right_ >= other.left_) && (this->top_ <= other.bottom_) &&
435             (this->bottom_ >= other.top_)) {
436             return true;
437         } else {
438             return false;
439         }
440     }
441 
442     /**
443      * @brief Checks whether the rectangle contains another rectangle.
444      *
445      * @param other Indicates the rectangle to be used for check.
446      * @return Returns <b>true</b> if the input rectangle is contained; returns <b>false</b> otherwise.
447      * @since 1.0
448      * @version 1.0
449      */
IsContains(const CommonRect<T> & other)450     bool IsContains(const CommonRect<T>& other) const
451     {
452         bool isContains = false;
453 
454         if (other.left_ >= this->left_ && other.top_ >= this->top_ && other.right_ <= this->right_ &&
455             other.bottom_ <= this->bottom_) {
456             isContains = true;
457         }
458 
459         return isContains;
460     }
461 
462     void Inflate(T delta);
463     void operator=(const CommonRect<T>& other)
464     {
465         left_ = other.left_;
466         right_ = other.right_;
467         top_ = other.top_;
468         bottom_ = other.bottom_;
469     }
470     void operator=(const CommonRect<T>&& other)
471     {
472         left_ = other.left_;
473         right_ = other.right_;
474         top_ = other.top_;
475         bottom_ = other.bottom_;
476     }
477     bool operator==(const CommonRect<T>& other) const
478     {
479         if (left_ == other.left_ && right_ == other.right_ && top_ == other.top_ && bottom_ == other.bottom_) {
480             return true;
481         } else {
482             return false;
483         }
484     }
485 
Normalize()486     void Normalize()
487     {
488         T t;
489         if (left_ > right_) {
490             t = left_;
491             left_ = right_;
492             right_ = t;
493         }
494         if (top_ > bottom_) {
495             t = top_;
496             top_ = bottom_;
497             bottom_ = t;
498         }
499     }
500 
501 protected:
502     T left_;
503     T top_;
504     T right_;
505     T bottom_;
506 };
507 using Rect = CommonRect<int16_t>;
508 using Rect32 = CommonRect<int32_t>;
509 } // namespace OHOS
510 #endif // GRAPHIC_LITE_RECT_H
511