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