1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/nsStyleCoord.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,347 @@ 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 +#include "nsStyleCoord.h" 1.12 +#include "mozilla/HashFunctions.h" 1.13 + 1.14 +nsStyleCoord::nsStyleCoord(nsStyleUnit aUnit) 1.15 + : mUnit(aUnit) 1.16 +{ 1.17 + NS_ASSERTION(aUnit < eStyleUnit_Percent, "not a valueless unit"); 1.18 + if (aUnit >= eStyleUnit_Percent) { 1.19 + mUnit = eStyleUnit_Null; 1.20 + } 1.21 + mValue.mInt = 0; 1.22 +} 1.23 + 1.24 +nsStyleCoord::nsStyleCoord(int32_t aValue, nsStyleUnit aUnit) 1.25 + : mUnit(aUnit) 1.26 +{ 1.27 + //if you want to pass in eStyleUnit_Coord, don't. instead, use the 1.28 + //constructor just above this one... MMP 1.29 + NS_ASSERTION((aUnit == eStyleUnit_Enumerated) || 1.30 + (aUnit == eStyleUnit_Integer), "not an int value"); 1.31 + if ((aUnit == eStyleUnit_Enumerated) || 1.32 + (aUnit == eStyleUnit_Integer)) { 1.33 + mValue.mInt = aValue; 1.34 + } 1.35 + else { 1.36 + mUnit = eStyleUnit_Null; 1.37 + mValue.mInt = 0; 1.38 + } 1.39 +} 1.40 + 1.41 +nsStyleCoord::nsStyleCoord(float aValue, nsStyleUnit aUnit) 1.42 + : mUnit(aUnit) 1.43 +{ 1.44 + if (aUnit < eStyleUnit_Percent || aUnit >= eStyleUnit_Coord) { 1.45 + NS_NOTREACHED("not a float value"); 1.46 + Reset(); 1.47 + } else { 1.48 + mValue.mFloat = aValue; 1.49 + } 1.50 +} 1.51 + 1.52 +bool nsStyleCoord::operator==(const nsStyleCoord& aOther) const 1.53 +{ 1.54 + if (mUnit != aOther.mUnit) { 1.55 + return false; 1.56 + } 1.57 + switch (mUnit) { 1.58 + case eStyleUnit_Null: 1.59 + case eStyleUnit_Normal: 1.60 + case eStyleUnit_Auto: 1.61 + case eStyleUnit_None: 1.62 + return true; 1.63 + case eStyleUnit_Percent: 1.64 + case eStyleUnit_Factor: 1.65 + case eStyleUnit_Degree: 1.66 + case eStyleUnit_Grad: 1.67 + case eStyleUnit_Radian: 1.68 + case eStyleUnit_Turn: 1.69 + case eStyleUnit_FlexFraction: 1.70 + return mValue.mFloat == aOther.mValue.mFloat; 1.71 + case eStyleUnit_Coord: 1.72 + case eStyleUnit_Integer: 1.73 + case eStyleUnit_Enumerated: 1.74 + return mValue.mInt == aOther.mValue.mInt; 1.75 + case eStyleUnit_Calc: 1.76 + return *this->GetCalcValue() == *aOther.GetCalcValue(); 1.77 + } 1.78 + NS_ABORT_IF_FALSE(false, "unexpected unit"); 1.79 + return false; 1.80 +} 1.81 + 1.82 +uint32_t nsStyleCoord::HashValue(uint32_t aHash = 0) const 1.83 +{ 1.84 + aHash = mozilla::AddToHash(aHash, mUnit); 1.85 + 1.86 + switch (mUnit) { 1.87 + case eStyleUnit_Null: 1.88 + case eStyleUnit_Normal: 1.89 + case eStyleUnit_Auto: 1.90 + case eStyleUnit_None: 1.91 + return mozilla::AddToHash(aHash, true); 1.92 + case eStyleUnit_Percent: 1.93 + case eStyleUnit_Factor: 1.94 + case eStyleUnit_Degree: 1.95 + case eStyleUnit_Grad: 1.96 + case eStyleUnit_Radian: 1.97 + case eStyleUnit_Turn: 1.98 + case eStyleUnit_FlexFraction: 1.99 + return mozilla::AddToHash(aHash, mValue.mFloat); 1.100 + case eStyleUnit_Coord: 1.101 + case eStyleUnit_Integer: 1.102 + case eStyleUnit_Enumerated: 1.103 + return mozilla::AddToHash(aHash, mValue.mInt); 1.104 + case eStyleUnit_Calc: 1.105 + Calc* calcValue = GetCalcValue(); 1.106 + aHash = mozilla::AddToHash(aHash, calcValue->mLength); 1.107 + if (HasPercent()) { 1.108 + return mozilla::AddToHash(aHash, calcValue->mPercent); 1.109 + } 1.110 + return aHash; 1.111 + } 1.112 + NS_ABORT_IF_FALSE(false, "unexpected unit"); 1.113 + return aHash; 1.114 +} 1.115 + 1.116 +void nsStyleCoord::Reset() 1.117 +{ 1.118 + mUnit = eStyleUnit_Null; 1.119 + mValue.mInt = 0; 1.120 +} 1.121 + 1.122 +void nsStyleCoord::SetCoordValue(nscoord aValue) 1.123 +{ 1.124 + mUnit = eStyleUnit_Coord; 1.125 + mValue.mInt = aValue; 1.126 +} 1.127 + 1.128 +void nsStyleCoord::SetIntValue(int32_t aValue, nsStyleUnit aUnit) 1.129 +{ 1.130 + NS_ASSERTION((aUnit == eStyleUnit_Enumerated) || 1.131 + (aUnit == eStyleUnit_Integer), "not an int value"); 1.132 + if ((aUnit == eStyleUnit_Enumerated) || 1.133 + (aUnit == eStyleUnit_Integer)) { 1.134 + mUnit = aUnit; 1.135 + mValue.mInt = aValue; 1.136 + } 1.137 + else { 1.138 + Reset(); 1.139 + } 1.140 +} 1.141 + 1.142 +void nsStyleCoord::SetPercentValue(float aValue) 1.143 +{ 1.144 + mUnit = eStyleUnit_Percent; 1.145 + mValue.mFloat = aValue; 1.146 +} 1.147 + 1.148 +void nsStyleCoord::SetFactorValue(float aValue) 1.149 +{ 1.150 + mUnit = eStyleUnit_Factor; 1.151 + mValue.mFloat = aValue; 1.152 +} 1.153 + 1.154 +void nsStyleCoord::SetAngleValue(float aValue, nsStyleUnit aUnit) 1.155 +{ 1.156 + if (aUnit == eStyleUnit_Degree || 1.157 + aUnit == eStyleUnit_Grad || 1.158 + aUnit == eStyleUnit_Radian || 1.159 + aUnit == eStyleUnit_Turn) { 1.160 + mUnit = aUnit; 1.161 + mValue.mFloat = aValue; 1.162 + } else { 1.163 + NS_NOTREACHED("not an angle value"); 1.164 + Reset(); 1.165 + } 1.166 +} 1.167 + 1.168 +void nsStyleCoord::SetFlexFractionValue(float aValue) 1.169 +{ 1.170 + mUnit = eStyleUnit_FlexFraction; 1.171 + mValue.mFloat = aValue; 1.172 +} 1.173 + 1.174 +void nsStyleCoord::SetCalcValue(Calc* aValue) 1.175 +{ 1.176 + mUnit = eStyleUnit_Calc; 1.177 + mValue.mPointer = aValue; 1.178 +} 1.179 + 1.180 +void nsStyleCoord::SetNormalValue() 1.181 +{ 1.182 + mUnit = eStyleUnit_Normal; 1.183 + mValue.mInt = 0; 1.184 +} 1.185 + 1.186 +void nsStyleCoord::SetAutoValue() 1.187 +{ 1.188 + mUnit = eStyleUnit_Auto; 1.189 + mValue.mInt = 0; 1.190 +} 1.191 + 1.192 +void nsStyleCoord::SetNoneValue() 1.193 +{ 1.194 + mUnit = eStyleUnit_None; 1.195 + mValue.mInt = 0; 1.196 +} 1.197 + 1.198 +// accessors that are not inlined 1.199 + 1.200 +double 1.201 +nsStyleCoord::GetAngleValueInRadians() const 1.202 +{ 1.203 + double angle = mValue.mFloat; 1.204 + 1.205 + switch (GetUnit()) { 1.206 + case eStyleUnit_Radian: return angle; 1.207 + case eStyleUnit_Turn: return angle * 2 * M_PI; 1.208 + case eStyleUnit_Degree: return angle * M_PI / 180.0; 1.209 + case eStyleUnit_Grad: return angle * M_PI / 200.0; 1.210 + 1.211 + default: 1.212 + NS_NOTREACHED("unrecognized angular unit"); 1.213 + return 0.0; 1.214 + } 1.215 +} 1.216 + 1.217 +nsStyleSides::nsStyleSides() 1.218 +{ 1.219 + memset(this, 0x00, sizeof(nsStyleSides)); 1.220 +} 1.221 + 1.222 +bool nsStyleSides::operator==(const nsStyleSides& aOther) const 1.223 +{ 1.224 + NS_FOR_CSS_SIDES(i) { 1.225 + if (nsStyleCoord(mValues[i], (nsStyleUnit)mUnits[i]) != 1.226 + nsStyleCoord(aOther.mValues[i], (nsStyleUnit)aOther.mUnits[i])) { 1.227 + return false; 1.228 + } 1.229 + } 1.230 + return true; 1.231 +} 1.232 + 1.233 +void nsStyleSides::Reset() 1.234 +{ 1.235 + memset(this, 0x00, sizeof(nsStyleSides)); 1.236 +} 1.237 + 1.238 +nsStyleCorners::nsStyleCorners() 1.239 +{ 1.240 + memset(this, 0x00, sizeof(nsStyleCorners)); 1.241 +} 1.242 + 1.243 +bool 1.244 +nsStyleCorners::operator==(const nsStyleCorners& aOther) const 1.245 +{ 1.246 + NS_FOR_CSS_HALF_CORNERS(i) { 1.247 + if (nsStyleCoord(mValues[i], (nsStyleUnit)mUnits[i]) != 1.248 + nsStyleCoord(aOther.mValues[i], (nsStyleUnit)aOther.mUnits[i])) { 1.249 + return false; 1.250 + } 1.251 + } 1.252 + return true; 1.253 +} 1.254 + 1.255 +void nsStyleCorners::Reset() 1.256 +{ 1.257 + memset(this, 0x00, sizeof(nsStyleCorners)); 1.258 +} 1.259 + 1.260 +// Validation of NS_SIDE_IS_VERTICAL and NS_HALF_CORNER_IS_X. 1.261 +#define CASE(side, result) \ 1.262 + static_assert(NS_SIDE_IS_VERTICAL(side) == result, \ 1.263 + "NS_SIDE_IS_VERTICAL is wrong") 1.264 +CASE(NS_SIDE_TOP, false); 1.265 +CASE(NS_SIDE_RIGHT, true); 1.266 +CASE(NS_SIDE_BOTTOM, false); 1.267 +CASE(NS_SIDE_LEFT, true); 1.268 +#undef CASE 1.269 + 1.270 +#define CASE(corner, result) \ 1.271 + static_assert(NS_HALF_CORNER_IS_X(corner) == result, \ 1.272 + "NS_HALF_CORNER_IS_X is wrong") 1.273 +CASE(NS_CORNER_TOP_LEFT_X, true); 1.274 +CASE(NS_CORNER_TOP_LEFT_Y, false); 1.275 +CASE(NS_CORNER_TOP_RIGHT_X, true); 1.276 +CASE(NS_CORNER_TOP_RIGHT_Y, false); 1.277 +CASE(NS_CORNER_BOTTOM_RIGHT_X, true); 1.278 +CASE(NS_CORNER_BOTTOM_RIGHT_Y, false); 1.279 +CASE(NS_CORNER_BOTTOM_LEFT_X, true); 1.280 +CASE(NS_CORNER_BOTTOM_LEFT_Y, false); 1.281 +#undef CASE 1.282 + 1.283 +// Validation of NS_HALF_TO_FULL_CORNER. 1.284 +#define CASE(corner, result) \ 1.285 + static_assert(NS_HALF_TO_FULL_CORNER(corner) == result, \ 1.286 + "NS_HALF_TO_FULL_CORNER is wrong") 1.287 +CASE(NS_CORNER_TOP_LEFT_X, NS_CORNER_TOP_LEFT); 1.288 +CASE(NS_CORNER_TOP_LEFT_Y, NS_CORNER_TOP_LEFT); 1.289 +CASE(NS_CORNER_TOP_RIGHT_X, NS_CORNER_TOP_RIGHT); 1.290 +CASE(NS_CORNER_TOP_RIGHT_Y, NS_CORNER_TOP_RIGHT); 1.291 +CASE(NS_CORNER_BOTTOM_RIGHT_X, NS_CORNER_BOTTOM_RIGHT); 1.292 +CASE(NS_CORNER_BOTTOM_RIGHT_Y, NS_CORNER_BOTTOM_RIGHT); 1.293 +CASE(NS_CORNER_BOTTOM_LEFT_X, NS_CORNER_BOTTOM_LEFT); 1.294 +CASE(NS_CORNER_BOTTOM_LEFT_Y, NS_CORNER_BOTTOM_LEFT); 1.295 +#undef CASE 1.296 + 1.297 +// Validation of NS_FULL_TO_HALF_CORNER. 1.298 +#define CASE(corner, vert, result) \ 1.299 + static_assert(NS_FULL_TO_HALF_CORNER(corner, vert) == result, \ 1.300 + "NS_FULL_TO_HALF_CORNER is wrong") 1.301 +CASE(NS_CORNER_TOP_LEFT, false, NS_CORNER_TOP_LEFT_X); 1.302 +CASE(NS_CORNER_TOP_LEFT, true, NS_CORNER_TOP_LEFT_Y); 1.303 +CASE(NS_CORNER_TOP_RIGHT, false, NS_CORNER_TOP_RIGHT_X); 1.304 +CASE(NS_CORNER_TOP_RIGHT, true, NS_CORNER_TOP_RIGHT_Y); 1.305 +CASE(NS_CORNER_BOTTOM_RIGHT, false, NS_CORNER_BOTTOM_RIGHT_X); 1.306 +CASE(NS_CORNER_BOTTOM_RIGHT, true, NS_CORNER_BOTTOM_RIGHT_Y); 1.307 +CASE(NS_CORNER_BOTTOM_LEFT, false, NS_CORNER_BOTTOM_LEFT_X); 1.308 +CASE(NS_CORNER_BOTTOM_LEFT, true, NS_CORNER_BOTTOM_LEFT_Y); 1.309 +#undef CASE 1.310 + 1.311 +// Validation of NS_SIDE_TO_{FULL,HALF}_CORNER. 1.312 +#define CASE(side, second, result) \ 1.313 + static_assert(NS_SIDE_TO_FULL_CORNER(side, second) == result, \ 1.314 + "NS_SIDE_TO_FULL_CORNER is wrong") 1.315 +CASE(NS_SIDE_TOP, false, NS_CORNER_TOP_LEFT); 1.316 +CASE(NS_SIDE_TOP, true, NS_CORNER_TOP_RIGHT); 1.317 + 1.318 +CASE(NS_SIDE_RIGHT, false, NS_CORNER_TOP_RIGHT); 1.319 +CASE(NS_SIDE_RIGHT, true, NS_CORNER_BOTTOM_RIGHT); 1.320 + 1.321 +CASE(NS_SIDE_BOTTOM, false, NS_CORNER_BOTTOM_RIGHT); 1.322 +CASE(NS_SIDE_BOTTOM, true, NS_CORNER_BOTTOM_LEFT); 1.323 + 1.324 +CASE(NS_SIDE_LEFT, false, NS_CORNER_BOTTOM_LEFT); 1.325 +CASE(NS_SIDE_LEFT, true, NS_CORNER_TOP_LEFT); 1.326 +#undef CASE 1.327 + 1.328 +#define CASE(side, second, parallel, result) \ 1.329 + static_assert(NS_SIDE_TO_HALF_CORNER(side, second, parallel) == result, \ 1.330 + "NS_SIDE_TO_HALF_CORNER is wrong") 1.331 +CASE(NS_SIDE_TOP, false, true, NS_CORNER_TOP_LEFT_X); 1.332 +CASE(NS_SIDE_TOP, false, false, NS_CORNER_TOP_LEFT_Y); 1.333 +CASE(NS_SIDE_TOP, true, true, NS_CORNER_TOP_RIGHT_X); 1.334 +CASE(NS_SIDE_TOP, true, false, NS_CORNER_TOP_RIGHT_Y); 1.335 + 1.336 +CASE(NS_SIDE_RIGHT, false, false, NS_CORNER_TOP_RIGHT_X); 1.337 +CASE(NS_SIDE_RIGHT, false, true, NS_CORNER_TOP_RIGHT_Y); 1.338 +CASE(NS_SIDE_RIGHT, true, false, NS_CORNER_BOTTOM_RIGHT_X); 1.339 +CASE(NS_SIDE_RIGHT, true, true, NS_CORNER_BOTTOM_RIGHT_Y); 1.340 + 1.341 +CASE(NS_SIDE_BOTTOM, false, true, NS_CORNER_BOTTOM_RIGHT_X); 1.342 +CASE(NS_SIDE_BOTTOM, false, false, NS_CORNER_BOTTOM_RIGHT_Y); 1.343 +CASE(NS_SIDE_BOTTOM, true, true, NS_CORNER_BOTTOM_LEFT_X); 1.344 +CASE(NS_SIDE_BOTTOM, true, false, NS_CORNER_BOTTOM_LEFT_Y); 1.345 + 1.346 +CASE(NS_SIDE_LEFT, false, false, NS_CORNER_BOTTOM_LEFT_X); 1.347 +CASE(NS_SIDE_LEFT, false, true, NS_CORNER_BOTTOM_LEFT_Y); 1.348 +CASE(NS_SIDE_LEFT, true, false, NS_CORNER_TOP_LEFT_X); 1.349 +CASE(NS_SIDE_LEFT, true, true, NS_CORNER_TOP_LEFT_Y); 1.350 +#undef CASE