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 FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_SIZE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_SIZE_H
18 
19 #include <iomanip>
20 #include <limits>
21 #include <sstream>
22 #include <string>
23 
24 #include "base/utils/utils.h"
25 
26 namespace OHOS::Ace {
27 
28 class Size {
29 public:
30     static constexpr double INFINITE_SIZE = std::numeric_limits<double>::max();
31     Size() = default;
32     ~Size() = default;
Size(double width,double height)33     Size(double width, double height) : width_(width), height_(height) {}
34 
IsValueInfinite(double inputValue)35     inline static bool IsValueInfinite(double inputValue)
36     {
37         return NearEqual(inputValue, INFINITE_SIZE);
38     }
39 
ErrorSize()40     static Size ErrorSize()
41     {
42         return Size((std::numeric_limits<double>::max)(), (std::numeric_limits<double>::max)());
43     }
44 
IsErrorSize()45     bool IsErrorSize() const
46     {
47         return operator==(ErrorSize());
48     }
49 
Width()50     double Width() const
51     {
52         return width_;
53     }
54 
Height()55     double Height() const
56     {
57         return height_;
58     }
59 
SetWidth(double width)60     void SetWidth(double width)
61     {
62         width_ = width;
63     }
64 
SetHeight(double height)65     void SetHeight(double height)
66     {
67         height_ = height;
68     }
69 
SetSize(const Size & size)70     void SetSize(const Size& size)
71     {
72         width_ = size.Width();
73         height_ = size.Height();
74     }
75 
IsWidthInfinite()76     bool IsWidthInfinite() const
77     {
78         return NearEqual(width_, INFINITE_SIZE);
79     }
80 
IsHeightInfinite()81     bool IsHeightInfinite() const
82     {
83         return NearEqual(height_, INFINITE_SIZE);
84     }
85 
IsInfinite()86     bool IsInfinite() const
87     {
88         return NearEqual(width_, INFINITE_SIZE) || NearEqual(height_, INFINITE_SIZE);
89     }
90 
IsEmpty()91     bool IsEmpty() const
92     {
93         return NearEqual(width_, 0.0) || NearEqual(height_, 0.0);
94     }
95 
AddHeight(double height)96     Size& AddHeight(double height)
97     {
98         height_ += height;
99         return *this;
100     }
101 
AddWidth(double value)102     Size& AddWidth(double value)
103     {
104         width_ += value;
105         return *this;
106     }
107 
MinusHeight(double height)108     Size& MinusHeight(double height)
109     {
110         height_ -= height;
111         return *this;
112     }
113 
MinusWidth(double width)114     Size& MinusWidth(double width)
115     {
116         width_ -= width;
117         return *this;
118     }
119 
IsValid()120     bool IsValid() const
121     {
122         return width_ > 0.0 && height_ > 0.0;
123     }
124 
125     Size operator+(const Size& size) const
126     {
127         return Size(width_ + size.Width(), height_ + size.Height());
128     }
129 
130     Size operator-(const Size& size) const
131     {
132         return Size(width_ - size.Width(), height_ - size.Height());
133     }
134 
135     Size operator*(double value) const
136     {
137         return Size(width_ * value, height_ * value);
138     }
139 
140     Size operator/(double value) const
141     {
142         if (NearZero(value)) {
143             return ErrorSize();
144         }
145         return Size(width_ / value, height_ / value);
146     }
147 
148     bool operator==(const Size& size) const
149     {
150         return NearEqual(width_, size.width_) && NearEqual(height_, size.height_);
151     }
152 
153     bool operator!=(const Size& size) const
154     {
155         return !operator==(size);
156     }
157 
158     Size operator+=(const Size& size)
159     {
160         width_ += size.Width();
161         height_ += size.Height();
162         return *this;
163     }
164 
165     Size operator-=(const Size& size)
166     {
167         width_ -= size.Width();
168         height_ -= size.Height();
169         return *this;
170     }
171 
ApplyScale(double scale)172     void ApplyScale(double scale)
173     {
174         width_ *= scale;
175         height_ *= scale;
176     }
177 
178     /*
179      * Please make sure that two sizes are both valid.
180      * You can use IsValid() to see if a size is valid.
181      */
182     bool operator>(const Size& size) const
183     {
184         if (IsValid() && size.IsValid()) {
185             return GreatOrEqual(width_, size.width_) && GreatOrEqual(height_, size.height_);
186         } else {
187             return false;
188         }
189     }
190 
191     /*
192      * Please make sure that two sizes are both valid.
193      * You can use IsValid() to see if a size is valid.
194      */
195     bool operator<(const Size& size) const
196     {
197         if (IsValid() && size.IsValid()) {
198             return LessOrEqual(width_, size.width_) && LessOrEqual(height_, size.height_);
199         } else {
200             return false;
201         }
202     }
203 
204     template<class T>
CalcRatio(const T & rectangle)205     static double CalcRatio(const T& rectangle)
206     {
207         if (NearZero(static_cast<double>(rectangle.Height()))) {
208             return INFINITE_SIZE;
209         }
210         return static_cast<double>(rectangle.Width()) / static_cast<double>(rectangle.Height());
211     }
212 
ToString()213     std::string ToString() const
214     {
215         std::stringstream ss;
216         ss << "[" << std::fixed << std::setprecision(2);
217         if (NearEqual(width_, INFINITE_SIZE)) {
218             ss << "INFINITE";
219         } else {
220             ss << width_;
221         }
222         ss << " x ";
223         if (NearEqual(height_, INFINITE_SIZE)) {
224             ss << "INFINITE";
225         } else {
226             ss << height_;
227         }
228         ss << "]";
229         std::string output = ss.str();
230         return output;
231     }
232 
233 private:
234     double width_ = 0.0;
235     double height_ = 0.0;
236 };
237 } // namespace OHOS::Ace
238 
239 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_SIZE_H
240