Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* representation of length values in computed style data */
8 #include "nsStyleCoord.h"
9 #include "mozilla/HashFunctions.h"
11 nsStyleCoord::nsStyleCoord(nsStyleUnit aUnit)
12 : mUnit(aUnit)
13 {
14 NS_ASSERTION(aUnit < eStyleUnit_Percent, "not a valueless unit");
15 if (aUnit >= eStyleUnit_Percent) {
16 mUnit = eStyleUnit_Null;
17 }
18 mValue.mInt = 0;
19 }
21 nsStyleCoord::nsStyleCoord(int32_t aValue, nsStyleUnit aUnit)
22 : mUnit(aUnit)
23 {
24 //if you want to pass in eStyleUnit_Coord, don't. instead, use the
25 //constructor just above this one... MMP
26 NS_ASSERTION((aUnit == eStyleUnit_Enumerated) ||
27 (aUnit == eStyleUnit_Integer), "not an int value");
28 if ((aUnit == eStyleUnit_Enumerated) ||
29 (aUnit == eStyleUnit_Integer)) {
30 mValue.mInt = aValue;
31 }
32 else {
33 mUnit = eStyleUnit_Null;
34 mValue.mInt = 0;
35 }
36 }
38 nsStyleCoord::nsStyleCoord(float aValue, nsStyleUnit aUnit)
39 : mUnit(aUnit)
40 {
41 if (aUnit < eStyleUnit_Percent || aUnit >= eStyleUnit_Coord) {
42 NS_NOTREACHED("not a float value");
43 Reset();
44 } else {
45 mValue.mFloat = aValue;
46 }
47 }
49 bool nsStyleCoord::operator==(const nsStyleCoord& aOther) const
50 {
51 if (mUnit != aOther.mUnit) {
52 return false;
53 }
54 switch (mUnit) {
55 case eStyleUnit_Null:
56 case eStyleUnit_Normal:
57 case eStyleUnit_Auto:
58 case eStyleUnit_None:
59 return true;
60 case eStyleUnit_Percent:
61 case eStyleUnit_Factor:
62 case eStyleUnit_Degree:
63 case eStyleUnit_Grad:
64 case eStyleUnit_Radian:
65 case eStyleUnit_Turn:
66 case eStyleUnit_FlexFraction:
67 return mValue.mFloat == aOther.mValue.mFloat;
68 case eStyleUnit_Coord:
69 case eStyleUnit_Integer:
70 case eStyleUnit_Enumerated:
71 return mValue.mInt == aOther.mValue.mInt;
72 case eStyleUnit_Calc:
73 return *this->GetCalcValue() == *aOther.GetCalcValue();
74 }
75 NS_ABORT_IF_FALSE(false, "unexpected unit");
76 return false;
77 }
79 uint32_t nsStyleCoord::HashValue(uint32_t aHash = 0) const
80 {
81 aHash = mozilla::AddToHash(aHash, mUnit);
83 switch (mUnit) {
84 case eStyleUnit_Null:
85 case eStyleUnit_Normal:
86 case eStyleUnit_Auto:
87 case eStyleUnit_None:
88 return mozilla::AddToHash(aHash, true);
89 case eStyleUnit_Percent:
90 case eStyleUnit_Factor:
91 case eStyleUnit_Degree:
92 case eStyleUnit_Grad:
93 case eStyleUnit_Radian:
94 case eStyleUnit_Turn:
95 case eStyleUnit_FlexFraction:
96 return mozilla::AddToHash(aHash, mValue.mFloat);
97 case eStyleUnit_Coord:
98 case eStyleUnit_Integer:
99 case eStyleUnit_Enumerated:
100 return mozilla::AddToHash(aHash, mValue.mInt);
101 case eStyleUnit_Calc:
102 Calc* calcValue = GetCalcValue();
103 aHash = mozilla::AddToHash(aHash, calcValue->mLength);
104 if (HasPercent()) {
105 return mozilla::AddToHash(aHash, calcValue->mPercent);
106 }
107 return aHash;
108 }
109 NS_ABORT_IF_FALSE(false, "unexpected unit");
110 return aHash;
111 }
113 void nsStyleCoord::Reset()
114 {
115 mUnit = eStyleUnit_Null;
116 mValue.mInt = 0;
117 }
119 void nsStyleCoord::SetCoordValue(nscoord aValue)
120 {
121 mUnit = eStyleUnit_Coord;
122 mValue.mInt = aValue;
123 }
125 void nsStyleCoord::SetIntValue(int32_t aValue, nsStyleUnit aUnit)
126 {
127 NS_ASSERTION((aUnit == eStyleUnit_Enumerated) ||
128 (aUnit == eStyleUnit_Integer), "not an int value");
129 if ((aUnit == eStyleUnit_Enumerated) ||
130 (aUnit == eStyleUnit_Integer)) {
131 mUnit = aUnit;
132 mValue.mInt = aValue;
133 }
134 else {
135 Reset();
136 }
137 }
139 void nsStyleCoord::SetPercentValue(float aValue)
140 {
141 mUnit = eStyleUnit_Percent;
142 mValue.mFloat = aValue;
143 }
145 void nsStyleCoord::SetFactorValue(float aValue)
146 {
147 mUnit = eStyleUnit_Factor;
148 mValue.mFloat = aValue;
149 }
151 void nsStyleCoord::SetAngleValue(float aValue, nsStyleUnit aUnit)
152 {
153 if (aUnit == eStyleUnit_Degree ||
154 aUnit == eStyleUnit_Grad ||
155 aUnit == eStyleUnit_Radian ||
156 aUnit == eStyleUnit_Turn) {
157 mUnit = aUnit;
158 mValue.mFloat = aValue;
159 } else {
160 NS_NOTREACHED("not an angle value");
161 Reset();
162 }
163 }
165 void nsStyleCoord::SetFlexFractionValue(float aValue)
166 {
167 mUnit = eStyleUnit_FlexFraction;
168 mValue.mFloat = aValue;
169 }
171 void nsStyleCoord::SetCalcValue(Calc* aValue)
172 {
173 mUnit = eStyleUnit_Calc;
174 mValue.mPointer = aValue;
175 }
177 void nsStyleCoord::SetNormalValue()
178 {
179 mUnit = eStyleUnit_Normal;
180 mValue.mInt = 0;
181 }
183 void nsStyleCoord::SetAutoValue()
184 {
185 mUnit = eStyleUnit_Auto;
186 mValue.mInt = 0;
187 }
189 void nsStyleCoord::SetNoneValue()
190 {
191 mUnit = eStyleUnit_None;
192 mValue.mInt = 0;
193 }
195 // accessors that are not inlined
197 double
198 nsStyleCoord::GetAngleValueInRadians() const
199 {
200 double angle = mValue.mFloat;
202 switch (GetUnit()) {
203 case eStyleUnit_Radian: return angle;
204 case eStyleUnit_Turn: return angle * 2 * M_PI;
205 case eStyleUnit_Degree: return angle * M_PI / 180.0;
206 case eStyleUnit_Grad: return angle * M_PI / 200.0;
208 default:
209 NS_NOTREACHED("unrecognized angular unit");
210 return 0.0;
211 }
212 }
214 nsStyleSides::nsStyleSides()
215 {
216 memset(this, 0x00, sizeof(nsStyleSides));
217 }
219 bool nsStyleSides::operator==(const nsStyleSides& aOther) const
220 {
221 NS_FOR_CSS_SIDES(i) {
222 if (nsStyleCoord(mValues[i], (nsStyleUnit)mUnits[i]) !=
223 nsStyleCoord(aOther.mValues[i], (nsStyleUnit)aOther.mUnits[i])) {
224 return false;
225 }
226 }
227 return true;
228 }
230 void nsStyleSides::Reset()
231 {
232 memset(this, 0x00, sizeof(nsStyleSides));
233 }
235 nsStyleCorners::nsStyleCorners()
236 {
237 memset(this, 0x00, sizeof(nsStyleCorners));
238 }
240 bool
241 nsStyleCorners::operator==(const nsStyleCorners& aOther) const
242 {
243 NS_FOR_CSS_HALF_CORNERS(i) {
244 if (nsStyleCoord(mValues[i], (nsStyleUnit)mUnits[i]) !=
245 nsStyleCoord(aOther.mValues[i], (nsStyleUnit)aOther.mUnits[i])) {
246 return false;
247 }
248 }
249 return true;
250 }
252 void nsStyleCorners::Reset()
253 {
254 memset(this, 0x00, sizeof(nsStyleCorners));
255 }
257 // Validation of NS_SIDE_IS_VERTICAL and NS_HALF_CORNER_IS_X.
258 #define CASE(side, result) \
259 static_assert(NS_SIDE_IS_VERTICAL(side) == result, \
260 "NS_SIDE_IS_VERTICAL is wrong")
261 CASE(NS_SIDE_TOP, false);
262 CASE(NS_SIDE_RIGHT, true);
263 CASE(NS_SIDE_BOTTOM, false);
264 CASE(NS_SIDE_LEFT, true);
265 #undef CASE
267 #define CASE(corner, result) \
268 static_assert(NS_HALF_CORNER_IS_X(corner) == result, \
269 "NS_HALF_CORNER_IS_X is wrong")
270 CASE(NS_CORNER_TOP_LEFT_X, true);
271 CASE(NS_CORNER_TOP_LEFT_Y, false);
272 CASE(NS_CORNER_TOP_RIGHT_X, true);
273 CASE(NS_CORNER_TOP_RIGHT_Y, false);
274 CASE(NS_CORNER_BOTTOM_RIGHT_X, true);
275 CASE(NS_CORNER_BOTTOM_RIGHT_Y, false);
276 CASE(NS_CORNER_BOTTOM_LEFT_X, true);
277 CASE(NS_CORNER_BOTTOM_LEFT_Y, false);
278 #undef CASE
280 // Validation of NS_HALF_TO_FULL_CORNER.
281 #define CASE(corner, result) \
282 static_assert(NS_HALF_TO_FULL_CORNER(corner) == result, \
283 "NS_HALF_TO_FULL_CORNER is wrong")
284 CASE(NS_CORNER_TOP_LEFT_X, NS_CORNER_TOP_LEFT);
285 CASE(NS_CORNER_TOP_LEFT_Y, NS_CORNER_TOP_LEFT);
286 CASE(NS_CORNER_TOP_RIGHT_X, NS_CORNER_TOP_RIGHT);
287 CASE(NS_CORNER_TOP_RIGHT_Y, NS_CORNER_TOP_RIGHT);
288 CASE(NS_CORNER_BOTTOM_RIGHT_X, NS_CORNER_BOTTOM_RIGHT);
289 CASE(NS_CORNER_BOTTOM_RIGHT_Y, NS_CORNER_BOTTOM_RIGHT);
290 CASE(NS_CORNER_BOTTOM_LEFT_X, NS_CORNER_BOTTOM_LEFT);
291 CASE(NS_CORNER_BOTTOM_LEFT_Y, NS_CORNER_BOTTOM_LEFT);
292 #undef CASE
294 // Validation of NS_FULL_TO_HALF_CORNER.
295 #define CASE(corner, vert, result) \
296 static_assert(NS_FULL_TO_HALF_CORNER(corner, vert) == result, \
297 "NS_FULL_TO_HALF_CORNER is wrong")
298 CASE(NS_CORNER_TOP_LEFT, false, NS_CORNER_TOP_LEFT_X);
299 CASE(NS_CORNER_TOP_LEFT, true, NS_CORNER_TOP_LEFT_Y);
300 CASE(NS_CORNER_TOP_RIGHT, false, NS_CORNER_TOP_RIGHT_X);
301 CASE(NS_CORNER_TOP_RIGHT, true, NS_CORNER_TOP_RIGHT_Y);
302 CASE(NS_CORNER_BOTTOM_RIGHT, false, NS_CORNER_BOTTOM_RIGHT_X);
303 CASE(NS_CORNER_BOTTOM_RIGHT, true, NS_CORNER_BOTTOM_RIGHT_Y);
304 CASE(NS_CORNER_BOTTOM_LEFT, false, NS_CORNER_BOTTOM_LEFT_X);
305 CASE(NS_CORNER_BOTTOM_LEFT, true, NS_CORNER_BOTTOM_LEFT_Y);
306 #undef CASE
308 // Validation of NS_SIDE_TO_{FULL,HALF}_CORNER.
309 #define CASE(side, second, result) \
310 static_assert(NS_SIDE_TO_FULL_CORNER(side, second) == result, \
311 "NS_SIDE_TO_FULL_CORNER is wrong")
312 CASE(NS_SIDE_TOP, false, NS_CORNER_TOP_LEFT);
313 CASE(NS_SIDE_TOP, true, NS_CORNER_TOP_RIGHT);
315 CASE(NS_SIDE_RIGHT, false, NS_CORNER_TOP_RIGHT);
316 CASE(NS_SIDE_RIGHT, true, NS_CORNER_BOTTOM_RIGHT);
318 CASE(NS_SIDE_BOTTOM, false, NS_CORNER_BOTTOM_RIGHT);
319 CASE(NS_SIDE_BOTTOM, true, NS_CORNER_BOTTOM_LEFT);
321 CASE(NS_SIDE_LEFT, false, NS_CORNER_BOTTOM_LEFT);
322 CASE(NS_SIDE_LEFT, true, NS_CORNER_TOP_LEFT);
323 #undef CASE
325 #define CASE(side, second, parallel, result) \
326 static_assert(NS_SIDE_TO_HALF_CORNER(side, second, parallel) == result, \
327 "NS_SIDE_TO_HALF_CORNER is wrong")
328 CASE(NS_SIDE_TOP, false, true, NS_CORNER_TOP_LEFT_X);
329 CASE(NS_SIDE_TOP, false, false, NS_CORNER_TOP_LEFT_Y);
330 CASE(NS_SIDE_TOP, true, true, NS_CORNER_TOP_RIGHT_X);
331 CASE(NS_SIDE_TOP, true, false, NS_CORNER_TOP_RIGHT_Y);
333 CASE(NS_SIDE_RIGHT, false, false, NS_CORNER_TOP_RIGHT_X);
334 CASE(NS_SIDE_RIGHT, false, true, NS_CORNER_TOP_RIGHT_Y);
335 CASE(NS_SIDE_RIGHT, true, false, NS_CORNER_BOTTOM_RIGHT_X);
336 CASE(NS_SIDE_RIGHT, true, true, NS_CORNER_BOTTOM_RIGHT_Y);
338 CASE(NS_SIDE_BOTTOM, false, true, NS_CORNER_BOTTOM_RIGHT_X);
339 CASE(NS_SIDE_BOTTOM, false, false, NS_CORNER_BOTTOM_RIGHT_Y);
340 CASE(NS_SIDE_BOTTOM, true, true, NS_CORNER_BOTTOM_LEFT_X);
341 CASE(NS_SIDE_BOTTOM, true, false, NS_CORNER_BOTTOM_LEFT_Y);
343 CASE(NS_SIDE_LEFT, false, false, NS_CORNER_BOTTOM_LEFT_X);
344 CASE(NS_SIDE_LEFT, false, true, NS_CORNER_BOTTOM_LEFT_Y);
345 CASE(NS_SIDE_LEFT, true, false, NS_CORNER_TOP_LEFT_X);
346 CASE(NS_SIDE_LEFT, true, true, NS_CORNER_TOP_LEFT_Y);
347 #undef CASE