Line data Source code
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/. */
5 :
6 : /* representation of length values in computed style data */
7 :
8 : #include "mozilla/HashFunctions.h"
9 : #include "mozilla/PodOperations.h"
10 :
11 : // nsStyleCoord.h must not be the first header in a unified source file,
12 : // otherwise it may not build with MSVC due to a bug in our STL wrapper.
13 : // See bug 1331102.
14 : #include "nsStyleCoord.h"
15 :
16 : using namespace mozilla;
17 :
18 3485 : nsStyleCoord::nsStyleCoord(nsStyleUnit aUnit)
19 3485 : : mUnit(aUnit)
20 : {
21 3485 : NS_ASSERTION(aUnit < eStyleUnit_Percent, "not a valueless unit");
22 3485 : if (aUnit >= eStyleUnit_Percent) {
23 0 : mUnit = eStyleUnit_Null;
24 : }
25 3485 : mValue.mInt = 0;
26 3485 : }
27 :
28 94 : nsStyleCoord::nsStyleCoord(int32_t aValue, nsStyleUnit aUnit)
29 94 : : mUnit(aUnit)
30 : {
31 : //if you want to pass in eStyleUnit_Coord, don't. instead, use the
32 : //constructor just above this one... MMP
33 94 : NS_ASSERTION((aUnit == eStyleUnit_Enumerated) ||
34 : (aUnit == eStyleUnit_Integer), "not an int value");
35 94 : if ((aUnit == eStyleUnit_Enumerated) ||
36 : (aUnit == eStyleUnit_Integer)) {
37 94 : mValue.mInt = aValue;
38 : }
39 : else {
40 0 : mUnit = eStyleUnit_Null;
41 0 : mValue.mInt = 0;
42 : }
43 94 : }
44 :
45 749 : nsStyleCoord::nsStyleCoord(float aValue, nsStyleUnit aUnit)
46 749 : : mUnit(aUnit)
47 : {
48 749 : if (aUnit < eStyleUnit_Percent || aUnit >= eStyleUnit_Coord) {
49 0 : NS_NOTREACHED("not a float value");
50 0 : mUnit = eStyleUnit_Null;
51 0 : mValue.mInt = 0;
52 : } else {
53 749 : mValue.mFloat = aValue;
54 : }
55 749 : }
56 :
57 19984 : bool nsStyleCoord::operator==(const nsStyleCoord& aOther) const
58 : {
59 19984 : if (mUnit != aOther.mUnit) {
60 3 : return false;
61 : }
62 19981 : switch (mUnit) {
63 : case eStyleUnit_Null:
64 : case eStyleUnit_Normal:
65 : case eStyleUnit_Auto:
66 : case eStyleUnit_None:
67 5885 : return true;
68 : case eStyleUnit_Percent:
69 : case eStyleUnit_Factor:
70 : case eStyleUnit_Degree:
71 : case eStyleUnit_Grad:
72 : case eStyleUnit_Radian:
73 : case eStyleUnit_Turn:
74 : case eStyleUnit_FlexFraction:
75 5528 : return mValue.mFloat == aOther.mValue.mFloat;
76 : case eStyleUnit_Coord:
77 : case eStyleUnit_Integer:
78 : case eStyleUnit_Enumerated:
79 8481 : return mValue.mInt == aOther.mValue.mInt;
80 : case eStyleUnit_Calc:
81 87 : return *this->GetCalcValue() == *aOther.GetCalcValue();
82 : }
83 0 : MOZ_ASSERT(false, "unexpected unit");
84 : return false;
85 : }
86 :
87 60138 : void nsStyleCoord::Reset()
88 : {
89 60138 : Reset(mUnit, mValue);
90 60138 : }
91 :
92 1986 : void nsStyleCoord::SetCoordValue(nscoord aValue)
93 : {
94 1986 : Reset();
95 1986 : mUnit = eStyleUnit_Coord;
96 1986 : mValue.mInt = aValue;
97 1986 : }
98 :
99 29 : void nsStyleCoord::SetIntValue(int32_t aValue, nsStyleUnit aUnit)
100 : {
101 29 : NS_ASSERTION((aUnit == eStyleUnit_Enumerated) ||
102 : (aUnit == eStyleUnit_Integer), "not an int value");
103 29 : Reset();
104 29 : if ((aUnit == eStyleUnit_Enumerated) ||
105 : (aUnit == eStyleUnit_Integer)) {
106 29 : mUnit = aUnit;
107 29 : mValue.mInt = aValue;
108 : }
109 29 : }
110 :
111 253 : void nsStyleCoord::SetPercentValue(float aValue)
112 : {
113 253 : Reset();
114 253 : mUnit = eStyleUnit_Percent;
115 253 : mValue.mFloat = aValue;
116 253 : }
117 :
118 505 : void nsStyleCoord::SetFactorValue(float aValue)
119 : {
120 505 : Reset();
121 505 : mUnit = eStyleUnit_Factor;
122 505 : mValue.mFloat = aValue;
123 505 : }
124 :
125 0 : void nsStyleCoord::SetAngleValue(float aValue, nsStyleUnit aUnit)
126 : {
127 0 : Reset();
128 0 : if (aUnit == eStyleUnit_Degree ||
129 0 : aUnit == eStyleUnit_Grad ||
130 0 : aUnit == eStyleUnit_Radian ||
131 : aUnit == eStyleUnit_Turn) {
132 0 : mUnit = aUnit;
133 0 : mValue.mFloat = aValue;
134 : } else {
135 0 : NS_NOTREACHED("not an angle value");
136 : }
137 0 : }
138 :
139 0 : void nsStyleCoord::SetFlexFractionValue(float aValue)
140 : {
141 0 : Reset();
142 0 : mUnit = eStyleUnit_FlexFraction;
143 0 : mValue.mFloat = aValue;
144 0 : }
145 :
146 127 : void nsStyleCoord::SetCalcValue(Calc* aValue)
147 : {
148 127 : Reset();
149 127 : mUnit = eStyleUnit_Calc;
150 127 : mValue.mPointer = aValue;
151 127 : aValue->AddRef();
152 127 : }
153 :
154 12 : void nsStyleCoord::SetNormalValue()
155 : {
156 12 : Reset();
157 12 : mUnit = eStyleUnit_Normal;
158 12 : mValue.mInt = 0;
159 12 : }
160 :
161 5 : void nsStyleCoord::SetAutoValue()
162 : {
163 5 : Reset();
164 5 : mUnit = eStyleUnit_Auto;
165 5 : mValue.mInt = 0;
166 5 : }
167 :
168 65 : void nsStyleCoord::SetNoneValue()
169 : {
170 65 : Reset();
171 65 : mUnit = eStyleUnit_None;
172 65 : mValue.mInt = 0;
173 65 : }
174 :
175 : // accessors that are not inlined
176 :
177 : double
178 0 : nsStyleCoord::GetAngleValueInDegrees() const
179 : {
180 0 : return GetAngleValueInRadians() * (180.0 / M_PI);
181 : }
182 :
183 : double
184 0 : nsStyleCoord::GetAngleValueInRadians() const
185 : {
186 0 : double angle = mValue.mFloat;
187 :
188 0 : switch (GetUnit()) {
189 0 : case eStyleUnit_Radian: return angle;
190 0 : case eStyleUnit_Turn: return angle * 2 * M_PI;
191 0 : case eStyleUnit_Degree: return angle * M_PI / 180.0;
192 0 : case eStyleUnit_Grad: return angle * M_PI / 200.0;
193 :
194 : default:
195 0 : NS_NOTREACHED("unrecognized angular unit");
196 0 : return 0.0;
197 : }
198 : }
199 :
200 368 : nsStyleSides::nsStyleSides()
201 : {
202 1840 : NS_FOR_CSS_SIDES(i) {
203 1472 : mUnits[i] = eStyleUnit_Null;
204 : }
205 368 : mozilla::PodArrayZero(mValues);
206 368 : }
207 :
208 759 : nsStyleSides::nsStyleSides(const nsStyleSides& aOther)
209 : {
210 3795 : NS_FOR_CSS_SIDES(i) {
211 3036 : mUnits[i] = eStyleUnit_Null;
212 : }
213 759 : *this = aOther;
214 759 : }
215 :
216 1176 : nsStyleSides::~nsStyleSides()
217 : {
218 588 : Reset();
219 588 : }
220 :
221 : nsStyleSides&
222 759 : nsStyleSides::operator=(const nsStyleSides& aCopy)
223 : {
224 759 : if (this != &aCopy) {
225 3795 : NS_FOR_CSS_SIDES(i) {
226 6072 : nsStyleCoord::SetValue(mUnits[i], mValues[i],
227 9108 : aCopy.mUnits[i], aCopy.mValues[i]);
228 : }
229 : }
230 759 : return *this;
231 : }
232 :
233 1838 : bool nsStyleSides::operator==(const nsStyleSides& aOther) const
234 : {
235 9186 : NS_FOR_CSS_SIDES(i) {
236 14698 : if (nsStyleCoord(mValues[i], (nsStyleUnit)mUnits[i]) !=
237 14698 : nsStyleCoord(aOther.mValues[i], (nsStyleUnit)aOther.mUnits[i])) {
238 1 : return false;
239 : }
240 : }
241 1837 : return true;
242 : }
243 :
244 588 : void nsStyleSides::Reset()
245 : {
246 2940 : NS_FOR_CSS_SIDES(i) {
247 2352 : nsStyleCoord::Reset(mUnits[i], mValues[i]);
248 : }
249 588 : }
250 :
251 52 : nsStyleCorners::nsStyleCorners()
252 : {
253 468 : NS_FOR_CSS_HALF_CORNERS(i) {
254 416 : mUnits[i] = eStyleUnit_Null;
255 : }
256 52 : mozilla::PodArrayZero(mValues);
257 52 : }
258 :
259 135 : nsStyleCorners::nsStyleCorners(const nsStyleCorners& aOther)
260 : {
261 1215 : NS_FOR_CSS_HALF_CORNERS(i) {
262 1080 : mUnits[i] = eStyleUnit_Null;
263 : }
264 135 : *this = aOther;
265 135 : }
266 :
267 188 : nsStyleCorners::~nsStyleCorners()
268 : {
269 94 : Reset();
270 94 : }
271 :
272 : nsStyleCorners&
273 135 : nsStyleCorners::operator=(const nsStyleCorners& aCopy)
274 : {
275 135 : if (this != &aCopy) {
276 1215 : NS_FOR_CSS_HALF_CORNERS(i) {
277 2160 : nsStyleCoord::SetValue(mUnits[i], mValues[i],
278 3240 : aCopy.mUnits[i], aCopy.mValues[i]);
279 : }
280 : }
281 135 : return *this;
282 : }
283 :
284 : bool
285 586 : nsStyleCorners::operator==(const nsStyleCorners& aOther) const
286 : {
287 5274 : NS_FOR_CSS_HALF_CORNERS(i) {
288 9376 : if (nsStyleCoord(mValues[i], (nsStyleUnit)mUnits[i]) !=
289 9376 : nsStyleCoord(aOther.mValues[i], (nsStyleUnit)aOther.mUnits[i])) {
290 0 : return false;
291 : }
292 : }
293 586 : return true;
294 : }
295 :
296 94 : void nsStyleCorners::Reset()
297 : {
298 846 : NS_FOR_CSS_HALF_CORNERS(i) {
299 752 : nsStyleCoord::Reset(mUnits[i], mValues[i]);
300 : }
301 94 : }
302 :
303 : // Validation of SideIsVertical.
304 : #define CASE(side, result) \
305 : static_assert(SideIsVertical(side) == result, \
306 : "SideIsVertical is wrong")
307 : CASE(eSideTop, false);
308 : CASE(eSideRight, true);
309 : CASE(eSideBottom, false);
310 : CASE(eSideLeft, true);
311 : #undef CASE
312 :
313 : // Validation of HalfCornerIsX.
314 : #define CASE(corner, result) \
315 : static_assert(HalfCornerIsX(corner) == result, \
316 : "HalfCornerIsX is wrong")
317 : CASE(eCornerTopLeftX, true);
318 : CASE(eCornerTopLeftY, false);
319 : CASE(eCornerTopRightX, true);
320 : CASE(eCornerTopRightY, false);
321 : CASE(eCornerBottomRightX, true);
322 : CASE(eCornerBottomRightY, false);
323 : CASE(eCornerBottomLeftX, true);
324 : CASE(eCornerBottomLeftY, false);
325 : #undef CASE
326 :
327 : // Validation of HalfToFullCorner.
328 : #define CASE(corner, result) \
329 : static_assert(HalfToFullCorner(corner) == result, \
330 : "HalfToFullCorner is wrong")
331 : CASE(eCornerTopLeftX, eCornerTopLeft);
332 : CASE(eCornerTopLeftY, eCornerTopLeft);
333 : CASE(eCornerTopRightX, eCornerTopRight);
334 : CASE(eCornerTopRightY, eCornerTopRight);
335 : CASE(eCornerBottomRightX, eCornerBottomRight);
336 : CASE(eCornerBottomRightY, eCornerBottomRight);
337 : CASE(eCornerBottomLeftX, eCornerBottomLeft);
338 : CASE(eCornerBottomLeftY, eCornerBottomLeft);
339 : #undef CASE
340 :
341 : // Validation of FullToHalfCorner.
342 : #define CASE(corner, vert, result) \
343 : static_assert(FullToHalfCorner(corner, vert) == result, \
344 : "FullToHalfCorner is wrong")
345 : CASE(eCornerTopLeft, false, eCornerTopLeftX);
346 : CASE(eCornerTopLeft, true, eCornerTopLeftY);
347 : CASE(eCornerTopRight, false, eCornerTopRightX);
348 : CASE(eCornerTopRight, true, eCornerTopRightY);
349 : CASE(eCornerBottomRight, false, eCornerBottomRightX);
350 : CASE(eCornerBottomRight, true, eCornerBottomRightY);
351 : CASE(eCornerBottomLeft, false, eCornerBottomLeftX);
352 : CASE(eCornerBottomLeft, true, eCornerBottomLeftY);
353 : #undef CASE
354 :
355 : // Validation of SideToFullCorner.
356 : #define CASE(side, second, result) \
357 : static_assert(SideToFullCorner(side, second) == result, \
358 : "SideToFullCorner is wrong")
359 : CASE(eSideTop, false, eCornerTopLeft);
360 : CASE(eSideTop, true, eCornerTopRight);
361 :
362 : CASE(eSideRight, false, eCornerTopRight);
363 : CASE(eSideRight, true, eCornerBottomRight);
364 :
365 : CASE(eSideBottom, false, eCornerBottomRight);
366 : CASE(eSideBottom, true, eCornerBottomLeft);
367 :
368 : CASE(eSideLeft, false, eCornerBottomLeft);
369 : CASE(eSideLeft, true, eCornerTopLeft);
370 : #undef CASE
371 :
372 : // Validation of SideToHalfCorner.
373 : #define CASE(side, second, parallel, result) \
374 : static_assert(SideToHalfCorner(side, second, parallel) == result, \
375 : "SideToHalfCorner is wrong")
376 : CASE(eSideTop, false, true, eCornerTopLeftX);
377 : CASE(eSideTop, false, false, eCornerTopLeftY);
378 : CASE(eSideTop, true, true, eCornerTopRightX);
379 : CASE(eSideTop, true, false, eCornerTopRightY);
380 :
381 : CASE(eSideRight, false, false, eCornerTopRightX);
382 : CASE(eSideRight, false, true, eCornerTopRightY);
383 : CASE(eSideRight, true, false, eCornerBottomRightX);
384 : CASE(eSideRight, true, true, eCornerBottomRightY);
385 :
386 : CASE(eSideBottom, false, true, eCornerBottomRightX);
387 : CASE(eSideBottom, false, false, eCornerBottomRightY);
388 : CASE(eSideBottom, true, true, eCornerBottomLeftX);
389 : CASE(eSideBottom, true, false, eCornerBottomLeftY);
390 :
391 : CASE(eSideLeft, false, false, eCornerBottomLeftX);
392 : CASE(eSideLeft, false, true, eCornerBottomLeftY);
393 : CASE(eSideLeft, true, false, eCornerTopLeftX);
394 : CASE(eSideLeft, true, true, eCornerTopLeftY);
395 : #undef CASE
|