• 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 FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_DIMENSION_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_DIMENSION_H
18 
19 #include <string>
20 
21 #include "base/utils/macros.h"
22 #include "base/utils/system_properties.h"
23 #include "base/utils/utils.h"
24 
25 #define NEAR_ZERO(value) ((value > 0.0) ? ((value - 0.0) <= 0.000001f) : ((0.0 - value) <= 0.000001f))
26 
27 namespace OHOS::Ace {
28 
29 enum class DimensionUnit {
30     /*
31      * Logical pixel used in Ace1.0. It's based on frontend design width.
32      * For example, when a frontend with 750px design width running on a
33      * device with 1080 pixels width, 1px represents 1.44 pixels.
34      */
35     PX = 0,
36     /*
37      * Density independent pixels, one vp is one pixel on a 160 dpi screen.
38      */
39     VP,
40     /*
41      * Scale independent pixels. This is like VP but will be scaled by
42      * user's font size preference.
43      */
44     FP,
45     /*
46      * The percentage of either a value from the element's parent or from
47      * another property of the element itself.
48      */
49     PERCENT,
50     /*
51      * logic pixels used in ACE2.0 instead of PX, and PX is the physical pixels in ACE2.0
52      */
53     LPX,
54     /*
55      * The value is calculated from the element's parent and another property of the element itself.
56      */
57     AUTO,
58     /*
59      * The value is expression.
60      */
61     CALC,
62 };
63 
64 /*
65  * Dimension contains a value and an unit to represent different
66  * scales in one class.
67  */
68 class ACE_EXPORT Dimension {
69 public:
70     constexpr Dimension() = default;
71     ~Dimension() = default;
value_(value)72     constexpr explicit Dimension(double value, DimensionUnit unit = DimensionUnit::PX) : value_(value), unit_(unit) {}
73 
Reset()74     void Reset()
75     {
76         value_ = 0.0;
77         unit_ = DimensionUnit::PX;
78     }
79 
ResetInvalidValue()80     void ResetInvalidValue()
81     {
82         if (std::isnan(value_)) {
83             Reset();
84         }
85     }
86 
Value()87     constexpr double Value() const
88     {
89         return value_;
90     }
91 
SetValue(double value)92     void SetValue(double value)
93     {
94         value_ = value;
95     }
96 
Unit()97     constexpr DimensionUnit Unit() const
98     {
99         return unit_;
100     }
101 
SetUnit(DimensionUnit unit)102     void SetUnit(DimensionUnit unit)
103     {
104         unit_ = unit;
105     }
106 
IsValid()107     bool IsValid() const
108     {
109         return GreatNotEqual(value_, 0.0);
110     }
111 
IsNonNegative()112     bool IsNonNegative() const
113     {
114         return NonNegative(value_);
115     }
116 
IsNonPositive()117     bool IsNonPositive() const
118     {
119         return NonPositive(value_);
120     }
121 
IsNegative()122     bool IsNegative() const
123     {
124         return !NonNegative(value_);
125     }
126 
127     // Deprecated: don't use this to covert to px.
ConvertToPx(double dipScale)128     double ConvertToPx(double dipScale) const
129     {
130         if (unit_ == DimensionUnit::VP || unit_ == DimensionUnit::FP) {
131             return value_ * dipScale;
132         }
133         return value_;
134     }
135 
136     // Percentage unit conversion is not supported.
137     double ConvertToVp() const;
138 
139     // Percentage unit conversion is not supported.
140     double ConvertToPx() const;
141 
142     // support percentage unit conversion
143     double ConvertToPxWithSize(double size) const;
144 
145     bool NormalizeToPx(double vpScale, double fpScale, double lpxScale, double parentLength, double& result) const;
146 
147     constexpr Dimension operator*(double value) const
148     {
149         return Dimension(value_ * value, unit_);
150     }
151 
152     constexpr Dimension operator/(double value) const
153     {
154         // NearZero cannot be used in a constant expression
155         if (NEAR_ZERO(value)) {
156             return {};
157         }
158         return Dimension(value_ / value, unit_);
159     }
160 
161     bool operator==(const Dimension& dimension) const
162     {
163         return (unit_ == dimension.unit_) && NearEqual(value_, dimension.value_);
164     }
165 
166     bool operator!=(const Dimension& dimension) const
167     {
168         return !operator==(dimension);
169     }
170 
171     /*
172      * Add two dimensions using the same unit.
173      */
174     constexpr Dimension operator+(const Dimension& dimension) const
175     {
176         if (NEAR_ZERO(dimension.Value())) {
177             return *this;
178         }
179         ACE_DCHECK(unit_ == dimension.unit_);
180         return Dimension(value_ + dimension.value_, unit_);
181     }
182 
183     /*
184      * Add a new dimension to itself using same unit.
185      */
186     Dimension& operator+=(const Dimension& dimension)
187     {
188         ACE_DCHECK(unit_ == dimension.unit_);
189         value_ += dimension.value_;
190         return *this;
191     }
192 
193     /*
194      * Minus a dimension using the same unit.
195      */
196     constexpr Dimension operator-(const Dimension& dimension) const
197     {
198         if (NEAR_ZERO(dimension.Value())) {
199             return *this;
200         }
201         ACE_DCHECK(unit_ == dimension.unit_);
202         return Dimension(value_ - dimension.value_, unit_);
203     }
204 
205     /*
206      * The opposite of dimension.
207      */
208     constexpr Dimension operator-() const
209     {
210         return Dimension(-value_, unit_);
211     }
212 
213     /*
214      * Minus a dimension to itself using the same unit.
215      */
216     Dimension& operator-=(const Dimension& dimension)
217     {
218         ACE_DCHECK(unit_ == dimension.unit_);
219         value_ -= dimension.value_;
220         return *this;
221     }
222 
223     bool operator>(const Dimension& dimension) const
224     {
225         ACE_DCHECK(unit_ == dimension.unit_);
226         return (value_ > dimension.value_);
227     }
228 
229     bool operator<(const Dimension& dimension) const
230     {
231         ACE_DCHECK(unit_ == dimension.unit_);
232         return (value_ < dimension.value_);
233     }
234 
235     std::string ToString() const;
236 
237 private:
238     double value_ = 0.0;
239     DimensionUnit unit_ = DimensionUnit::PX;
240 };
241 
242 // literal operators for dimension
243 inline constexpr Dimension operator""_vp(long double value)
244 {
245     return Dimension(static_cast<double>(value), DimensionUnit::VP);
246 }
247 
248 inline constexpr Dimension operator""_px(long double value)
249 {
250     return Dimension(static_cast<double>(value), DimensionUnit::PX);
251 }
252 
253 inline constexpr Dimension operator""_fp(long double value)
254 {
255     return Dimension(static_cast<double>(value), DimensionUnit::FP);
256 }
257 
258 inline constexpr Dimension operator""_pct(long double value)
259 {
260     return Dimension(static_cast<double>(value), DimensionUnit::PERCENT);
261 }
262 
263 } // namespace OHOS::Ace
264 
265 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_DIMENSION_H
266