1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/nsStyleCoord.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,438 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* representation of length values in computed style data */ 1.10 + 1.11 +#ifndef nsStyleCoord_h___ 1.12 +#define nsStyleCoord_h___ 1.13 + 1.14 +#include "nsCoord.h" 1.15 +#include "nsStyleConsts.h" 1.16 + 1.17 +enum nsStyleUnit { 1.18 + eStyleUnit_Null = 0, // (no value) value is not specified 1.19 + eStyleUnit_Normal = 1, // (no value) 1.20 + eStyleUnit_Auto = 2, // (no value) 1.21 + eStyleUnit_None = 3, // (no value) 1.22 + eStyleUnit_Percent = 10, // (float) 1.0 == 100% 1.23 + eStyleUnit_Factor = 11, // (float) a multiplier 1.24 + eStyleUnit_Degree = 12, // (float) angle in degrees 1.25 + eStyleUnit_Grad = 13, // (float) angle in grads 1.26 + eStyleUnit_Radian = 14, // (float) angle in radians 1.27 + eStyleUnit_Turn = 15, // (float) angle in turns 1.28 + eStyleUnit_FlexFraction = 16, // (float) <flex> in fr units 1.29 + eStyleUnit_Coord = 20, // (nscoord) value is twips 1.30 + eStyleUnit_Integer = 30, // (int) value is simple integer 1.31 + eStyleUnit_Enumerated = 32, // (int) value has enumerated meaning 1.32 + 1.33 + // The following are allocated types. They are weak pointers to 1.34 + // values allocated by nsStyleContext::Alloc. 1.35 + eStyleUnit_Calc = 40 // (Calc*) calc() toplevel; always present 1.36 + // to distinguish 50% from calc(50%), etc. 1.37 +}; 1.38 + 1.39 +typedef union { 1.40 + int32_t mInt; // nscoord is a int32_t for now 1.41 + float mFloat; 1.42 + // An mPointer is a weak pointer to a value that is guaranteed to 1.43 + // outlive the nsStyleCoord. In the case of nsStyleCoord::Calc*, it 1.44 + // is a pointer owned by the style context, allocated through 1.45 + // nsStyleContext::Alloc (and, therefore, is never stored in the rule 1.46 + // tree). 1.47 + void* mPointer; 1.48 +} nsStyleUnion; 1.49 + 1.50 +/** 1.51 + * Class that hold a single size specification used by the style 1.52 + * system. The size specification consists of two parts -- a number 1.53 + * and a unit. The number is an integer, a floating point value, an 1.54 + * nscoord, or undefined, and the unit is an nsStyleUnit. Checking 1.55 + * the unit is a must before asking for the value in any particular 1.56 + * form. 1.57 + */ 1.58 +class nsStyleCoord { 1.59 +public: 1.60 + struct Calc { 1.61 + // Every calc() expression evaluates to a length plus a percentage. 1.62 + nscoord mLength; 1.63 + float mPercent; 1.64 + bool mHasPercent; // whether there was any % syntax, even if 0 1.65 + 1.66 + bool operator==(const Calc& aOther) const { 1.67 + return mLength == aOther.mLength && 1.68 + mPercent == aOther.mPercent && 1.69 + mHasPercent == aOther.mHasPercent; 1.70 + } 1.71 + bool operator!=(const Calc& aOther) const { return !(*this == aOther); } 1.72 + }; 1.73 + 1.74 + nsStyleCoord(nsStyleUnit aUnit = eStyleUnit_Null); 1.75 + enum CoordConstructorType { CoordConstructor }; 1.76 + inline nsStyleCoord(nscoord aValue, CoordConstructorType); 1.77 + nsStyleCoord(int32_t aValue, nsStyleUnit aUnit); 1.78 + nsStyleCoord(float aValue, nsStyleUnit aUnit); 1.79 + inline nsStyleCoord(const nsStyleCoord& aCopy); 1.80 + inline nsStyleCoord(const nsStyleUnion& aValue, nsStyleUnit aUnit); 1.81 + 1.82 + nsStyleCoord& operator=(const nsStyleCoord& aOther) 1.83 + { 1.84 + mUnit = aOther.mUnit; 1.85 + mValue = aOther.mValue; 1.86 + return *this; 1.87 + } 1.88 + bool operator==(const nsStyleCoord& aOther) const; 1.89 + bool operator!=(const nsStyleCoord& aOther) const; 1.90 + 1.91 + nsStyleUnit GetUnit() const { 1.92 + NS_ASSERTION(mUnit != eStyleUnit_Null, "reading uninitialized value"); 1.93 + return mUnit; 1.94 + } 1.95 + 1.96 + bool IsAngleValue() const { 1.97 + return eStyleUnit_Degree <= mUnit && mUnit <= eStyleUnit_Turn; 1.98 + } 1.99 + 1.100 + bool IsCalcUnit() const { 1.101 + return eStyleUnit_Calc == mUnit; 1.102 + } 1.103 + 1.104 + bool IsPointerValue() const { 1.105 + return IsCalcUnit(); 1.106 + } 1.107 + 1.108 + bool IsCoordPercentCalcUnit() const { 1.109 + return mUnit == eStyleUnit_Coord || 1.110 + mUnit == eStyleUnit_Percent || 1.111 + IsCalcUnit(); 1.112 + } 1.113 + 1.114 + // Does this calc() expression have any percentages inside it? Can be 1.115 + // called only when IsCalcUnit() is true. 1.116 + bool CalcHasPercent() const { 1.117 + return GetCalcValue()->mHasPercent; 1.118 + } 1.119 + 1.120 + bool HasPercent() const { 1.121 + return mUnit == eStyleUnit_Percent || 1.122 + (IsCalcUnit() && CalcHasPercent()); 1.123 + } 1.124 + 1.125 + bool ConvertsToLength() const { 1.126 + return mUnit == eStyleUnit_Coord || 1.127 + (IsCalcUnit() && !CalcHasPercent()); 1.128 + } 1.129 + 1.130 + nscoord GetCoordValue() const; 1.131 + int32_t GetIntValue() const; 1.132 + float GetPercentValue() const; 1.133 + float GetFactorValue() const; 1.134 + float GetAngleValue() const; 1.135 + double GetAngleValueInRadians() const; 1.136 + float GetFlexFractionValue() const; 1.137 + Calc* GetCalcValue() const; 1.138 + void GetUnionValue(nsStyleUnion& aValue) const; 1.139 + uint32_t HashValue(uint32_t aHash) const; 1.140 + 1.141 + void Reset(); // sets to null 1.142 + void SetCoordValue(nscoord aValue); 1.143 + void SetIntValue(int32_t aValue, nsStyleUnit aUnit); 1.144 + void SetPercentValue(float aValue); 1.145 + void SetFactorValue(float aValue); 1.146 + void SetAngleValue(float aValue, nsStyleUnit aUnit); 1.147 + void SetFlexFractionValue(float aValue); 1.148 + void SetNormalValue(); 1.149 + void SetAutoValue(); 1.150 + void SetNoneValue(); 1.151 + void SetCalcValue(Calc* aValue); 1.152 + 1.153 +private: 1.154 + nsStyleUnit mUnit; 1.155 + nsStyleUnion mValue; 1.156 +}; 1.157 + 1.158 +/** 1.159 + * Class that represents a set of top/right/bottom/left nsStyleCoords. 1.160 + * This is commonly used to hold the widths of the borders, margins, 1.161 + * or paddings of a box. 1.162 + */ 1.163 +class nsStyleSides { 1.164 +public: 1.165 + nsStyleSides(); 1.166 + 1.167 +// nsStyleSides& operator=(const nsStyleSides& aCopy); // use compiler's version 1.168 + bool operator==(const nsStyleSides& aOther) const; 1.169 + bool operator!=(const nsStyleSides& aOther) const; 1.170 + 1.171 + inline nsStyleUnit GetUnit(mozilla::css::Side aSide) const; 1.172 + inline nsStyleUnit GetLeftUnit() const; 1.173 + inline nsStyleUnit GetTopUnit() const; 1.174 + inline nsStyleUnit GetRightUnit() const; 1.175 + inline nsStyleUnit GetBottomUnit() const; 1.176 + 1.177 + inline nsStyleCoord Get(mozilla::css::Side aSide) const; 1.178 + inline nsStyleCoord GetLeft() const; 1.179 + inline nsStyleCoord GetTop() const; 1.180 + inline nsStyleCoord GetRight() const; 1.181 + inline nsStyleCoord GetBottom() const; 1.182 + 1.183 + void Reset(); 1.184 + 1.185 + inline void Set(mozilla::css::Side aSide, const nsStyleCoord& aCoord); 1.186 + inline void SetLeft(const nsStyleCoord& aCoord); 1.187 + inline void SetTop(const nsStyleCoord& aCoord); 1.188 + inline void SetRight(const nsStyleCoord& aCoord); 1.189 + inline void SetBottom(const nsStyleCoord& aCoord); 1.190 + 1.191 +protected: 1.192 + uint8_t mUnits[4]; 1.193 + nsStyleUnion mValues[4]; 1.194 +}; 1.195 + 1.196 +/** 1.197 + * Class that represents a set of top-left/top-right/bottom-left/bottom-right 1.198 + * nsStyleCoord pairs. This is used to hold the dimensions of the 1.199 + * corners of a box (for, e.g., border-radius and outline-radius). 1.200 + */ 1.201 +class nsStyleCorners { 1.202 +public: 1.203 + nsStyleCorners(); 1.204 + 1.205 + // use compiler's version 1.206 + //nsStyleCorners& operator=(const nsStyleCorners& aCopy); 1.207 + bool operator==(const nsStyleCorners& aOther) const; 1.208 + bool operator!=(const nsStyleCorners& aOther) const; 1.209 + 1.210 + // aCorner is always one of NS_CORNER_* defined in nsStyleConsts.h 1.211 + inline nsStyleUnit GetUnit(uint8_t aHalfCorner) const; 1.212 + 1.213 + inline nsStyleCoord Get(uint8_t aHalfCorner) const; 1.214 + 1.215 + void Reset(); 1.216 + 1.217 + inline void Set(uint8_t aHalfCorner, const nsStyleCoord& aCoord); 1.218 + 1.219 +protected: 1.220 + uint8_t mUnits[8]; 1.221 + nsStyleUnion mValues[8]; 1.222 +}; 1.223 + 1.224 + 1.225 +// ------------------------- 1.226 +// nsStyleCoord inlines 1.227 +// 1.228 +inline nsStyleCoord::nsStyleCoord(nscoord aValue, CoordConstructorType) 1.229 + : mUnit(eStyleUnit_Coord) 1.230 +{ 1.231 + mValue.mInt = aValue; 1.232 +} 1.233 + 1.234 +// FIXME: In C++0x we can rely on the default copy constructor since 1.235 +// default copy construction is defined properly for unions. But when 1.236 +// can we actually use that? (It seems to work in gcc 4.4.) 1.237 +inline nsStyleCoord::nsStyleCoord(const nsStyleCoord& aCopy) 1.238 + : mUnit(aCopy.mUnit) 1.239 +{ 1.240 + if ((eStyleUnit_Percent <= mUnit) && (mUnit < eStyleUnit_Coord)) { 1.241 + mValue.mFloat = aCopy.mValue.mFloat; 1.242 + } 1.243 + else if (IsPointerValue()) { 1.244 + mValue.mPointer = aCopy.mValue.mPointer; 1.245 + } 1.246 + else { 1.247 + mValue.mInt = aCopy.mValue.mInt; 1.248 + } 1.249 +} 1.250 + 1.251 +inline nsStyleCoord::nsStyleCoord(const nsStyleUnion& aValue, nsStyleUnit aUnit) 1.252 + : mUnit(aUnit), mValue(aValue) 1.253 +{ 1.254 +} 1.255 + 1.256 +inline bool nsStyleCoord::operator!=(const nsStyleCoord& aOther) const 1.257 +{ 1.258 + return !((*this) == aOther); 1.259 +} 1.260 + 1.261 +inline nscoord nsStyleCoord::GetCoordValue() const 1.262 +{ 1.263 + NS_ASSERTION((mUnit == eStyleUnit_Coord), "not a coord value"); 1.264 + if (mUnit == eStyleUnit_Coord) { 1.265 + return mValue.mInt; 1.266 + } 1.267 + return 0; 1.268 +} 1.269 + 1.270 +inline int32_t nsStyleCoord::GetIntValue() const 1.271 +{ 1.272 + NS_ASSERTION((mUnit == eStyleUnit_Enumerated) || 1.273 + (mUnit == eStyleUnit_Integer), "not an int value"); 1.274 + if ((mUnit == eStyleUnit_Enumerated) || 1.275 + (mUnit == eStyleUnit_Integer)) { 1.276 + return mValue.mInt; 1.277 + } 1.278 + return 0; 1.279 +} 1.280 + 1.281 +inline float nsStyleCoord::GetPercentValue() const 1.282 +{ 1.283 + NS_ASSERTION(mUnit == eStyleUnit_Percent, "not a percent value"); 1.284 + if (mUnit == eStyleUnit_Percent) { 1.285 + return mValue.mFloat; 1.286 + } 1.287 + return 0.0f; 1.288 +} 1.289 + 1.290 +inline float nsStyleCoord::GetFactorValue() const 1.291 +{ 1.292 + NS_ASSERTION(mUnit == eStyleUnit_Factor, "not a factor value"); 1.293 + if (mUnit == eStyleUnit_Factor) { 1.294 + return mValue.mFloat; 1.295 + } 1.296 + return 0.0f; 1.297 +} 1.298 + 1.299 +inline float nsStyleCoord::GetAngleValue() const 1.300 +{ 1.301 + NS_ASSERTION(mUnit >= eStyleUnit_Degree && 1.302 + mUnit <= eStyleUnit_Turn, "not an angle value"); 1.303 + if (mUnit >= eStyleUnit_Degree && mUnit <= eStyleUnit_Turn) { 1.304 + return mValue.mFloat; 1.305 + } 1.306 + return 0.0f; 1.307 +} 1.308 + 1.309 +inline float nsStyleCoord::GetFlexFractionValue() const 1.310 +{ 1.311 + NS_ASSERTION(mUnit == eStyleUnit_FlexFraction, "not a fr value"); 1.312 + if (mUnit == eStyleUnit_FlexFraction) { 1.313 + return mValue.mFloat; 1.314 + } 1.315 + return 0.0f; 1.316 +} 1.317 + 1.318 +inline nsStyleCoord::Calc* nsStyleCoord::GetCalcValue() const 1.319 +{ 1.320 + NS_ASSERTION(IsCalcUnit(), "not a pointer value"); 1.321 + if (IsCalcUnit()) { 1.322 + return static_cast<Calc*>(mValue.mPointer); 1.323 + } 1.324 + return nullptr; 1.325 +} 1.326 + 1.327 + 1.328 +inline void nsStyleCoord::GetUnionValue(nsStyleUnion& aValue) const 1.329 +{ 1.330 + aValue = mValue; 1.331 +} 1.332 + 1.333 +// ------------------------- 1.334 +// nsStyleSides inlines 1.335 +// 1.336 +inline bool nsStyleSides::operator!=(const nsStyleSides& aOther) const 1.337 +{ 1.338 + return !((*this) == aOther); 1.339 +} 1.340 + 1.341 +inline nsStyleUnit nsStyleSides::GetUnit(mozilla::css::Side aSide) const 1.342 +{ 1.343 + return (nsStyleUnit)mUnits[aSide]; 1.344 +} 1.345 + 1.346 +inline nsStyleUnit nsStyleSides::GetLeftUnit() const 1.347 +{ 1.348 + return GetUnit(NS_SIDE_LEFT); 1.349 +} 1.350 + 1.351 +inline nsStyleUnit nsStyleSides::GetTopUnit() const 1.352 +{ 1.353 + return GetUnit(NS_SIDE_TOP); 1.354 +} 1.355 + 1.356 +inline nsStyleUnit nsStyleSides::GetRightUnit() const 1.357 +{ 1.358 + return GetUnit(NS_SIDE_RIGHT); 1.359 +} 1.360 + 1.361 +inline nsStyleUnit nsStyleSides::GetBottomUnit() const 1.362 +{ 1.363 + return GetUnit(NS_SIDE_BOTTOM); 1.364 +} 1.365 + 1.366 +inline nsStyleCoord nsStyleSides::Get(mozilla::css::Side aSide) const 1.367 +{ 1.368 + return nsStyleCoord(mValues[aSide], nsStyleUnit(mUnits[aSide])); 1.369 +} 1.370 + 1.371 +inline nsStyleCoord nsStyleSides::GetLeft() const 1.372 +{ 1.373 + return Get(NS_SIDE_LEFT); 1.374 +} 1.375 + 1.376 +inline nsStyleCoord nsStyleSides::GetTop() const 1.377 +{ 1.378 + return Get(NS_SIDE_TOP); 1.379 +} 1.380 + 1.381 +inline nsStyleCoord nsStyleSides::GetRight() const 1.382 +{ 1.383 + return Get(NS_SIDE_RIGHT); 1.384 +} 1.385 + 1.386 +inline nsStyleCoord nsStyleSides::GetBottom() const 1.387 +{ 1.388 + return Get(NS_SIDE_BOTTOM); 1.389 +} 1.390 + 1.391 +inline void nsStyleSides::Set(mozilla::css::Side aSide, const nsStyleCoord& aCoord) 1.392 +{ 1.393 + mUnits[aSide] = aCoord.GetUnit(); 1.394 + aCoord.GetUnionValue(mValues[aSide]); 1.395 +} 1.396 + 1.397 +inline void nsStyleSides::SetLeft(const nsStyleCoord& aCoord) 1.398 +{ 1.399 + Set(NS_SIDE_LEFT, aCoord); 1.400 +} 1.401 + 1.402 +inline void nsStyleSides::SetTop(const nsStyleCoord& aCoord) 1.403 +{ 1.404 + Set(NS_SIDE_TOP, aCoord); 1.405 +} 1.406 + 1.407 +inline void nsStyleSides::SetRight(const nsStyleCoord& aCoord) 1.408 +{ 1.409 + Set(NS_SIDE_RIGHT, aCoord); 1.410 +} 1.411 + 1.412 +inline void nsStyleSides::SetBottom(const nsStyleCoord& aCoord) 1.413 +{ 1.414 + Set(NS_SIDE_BOTTOM, aCoord); 1.415 +} 1.416 + 1.417 +// ------------------------- 1.418 +// nsStyleCorners inlines 1.419 +// 1.420 +inline bool nsStyleCorners::operator!=(const nsStyleCorners& aOther) const 1.421 +{ 1.422 + return !((*this) == aOther); 1.423 +} 1.424 + 1.425 +inline nsStyleUnit nsStyleCorners::GetUnit(uint8_t aCorner) const 1.426 +{ 1.427 + return (nsStyleUnit)mUnits[aCorner]; 1.428 +} 1.429 + 1.430 +inline nsStyleCoord nsStyleCorners::Get(uint8_t aCorner) const 1.431 +{ 1.432 + return nsStyleCoord(mValues[aCorner], nsStyleUnit(mUnits[aCorner])); 1.433 +} 1.434 + 1.435 +inline void nsStyleCorners::Set(uint8_t aCorner, const nsStyleCoord& aCoord) 1.436 +{ 1.437 + mUnits[aCorner] = aCoord.GetUnit(); 1.438 + aCoord.GetUnionValue(mValues[aCorner]); 1.439 +} 1.440 + 1.441 +#endif /* nsStyleCoord_h___ */