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