1 /*
2 * Copyright (c) 2012, Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef LayoutUnit_h
32 #define LayoutUnit_h
33
34 #include "wtf/Assertions.h"
35 #include "wtf/MathExtras.h"
36 #include "wtf/SaturatedArithmetic.h"
37 #include <limits.h>
38 #include <limits>
39 #include <stdlib.h>
40
41 namespace WebCore {
42
43 #ifdef NDEBUG
44
45 #define REPORT_OVERFLOW(doesOverflow) ((void)0)
46
47 #else
48
49 #define REPORT_OVERFLOW(doesOverflow) do \
50 if (!(doesOverflow)) { \
51 WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, "!(%s)", #doesOverflow); \
52 } \
53 while (0)
54
55 #endif
56
57 static const int kFixedPointDenominator = 64;
58
59 const int intMaxForLayoutUnit = INT_MAX / kFixedPointDenominator;
60 const int intMinForLayoutUnit = INT_MIN / kFixedPointDenominator;
61
62 class LayoutUnit {
63 public:
LayoutUnit()64 LayoutUnit() : m_value(0) { }
LayoutUnit(int value)65 LayoutUnit(int value) { setValue(value); }
LayoutUnit(unsigned short value)66 LayoutUnit(unsigned short value) { setValue(value); }
LayoutUnit(unsigned value)67 LayoutUnit(unsigned value) { setValue(value); }
LayoutUnit(unsigned long value)68 LayoutUnit(unsigned long value) { m_value = clampTo<int>(value * kFixedPointDenominator); }
LayoutUnit(unsigned long long value)69 LayoutUnit(unsigned long long value) { m_value = clampTo<int>(value * kFixedPointDenominator); }
LayoutUnit(float value)70 LayoutUnit(float value) { m_value = clampTo<float>(value * kFixedPointDenominator, static_cast<float>(INT_MIN), static_cast<float>(INT_MAX)); }
LayoutUnit(double value)71 LayoutUnit(double value) { m_value = clampTo<double>(value * kFixedPointDenominator, static_cast<double>(INT_MIN), static_cast<double>(INT_MAX)); }
72
fromFloatCeil(float value)73 static LayoutUnit fromFloatCeil(float value)
74 {
75 LayoutUnit v;
76 v.m_value = clampToInteger(ceilf(value * kFixedPointDenominator));
77 return v;
78 }
79
fromFloatFloor(float value)80 static LayoutUnit fromFloatFloor(float value)
81 {
82 LayoutUnit v;
83 v.m_value = clampToInteger(floorf(value * kFixedPointDenominator));
84 return v;
85 }
86
fromFloatRound(float value)87 static LayoutUnit fromFloatRound(float value)
88 {
89 if (value >= 0)
90 return clamp(value + epsilon() / 2.0f);
91 return clamp(value - epsilon() / 2.0f);
92 }
93
toInt()94 int toInt() const { return m_value / kFixedPointDenominator; }
toFloat()95 float toFloat() const { return static_cast<float>(m_value) / kFixedPointDenominator; }
toDouble()96 double toDouble() const { return static_cast<double>(m_value) / kFixedPointDenominator; }
ceilToFloat()97 float ceilToFloat() const
98 {
99 float floatValue = toFloat();
100 if (static_cast<int>(floatValue * kFixedPointDenominator) == m_value)
101 return floatValue;
102 if (floatValue > 0)
103 return nextafterf(floatValue, std::numeric_limits<float>::max());
104 return nextafterf(floatValue, std::numeric_limits<float>::min());
105 }
toUnsigned()106 unsigned toUnsigned() const { REPORT_OVERFLOW(m_value >= 0); return toInt(); }
107
108 operator int() const { return toInt(); }
109 operator unsigned() const { return toUnsigned(); }
110 operator float() const { return toFloat(); }
111 operator double() const { return toDouble(); }
112 operator bool() const { return m_value; }
113
114 LayoutUnit operator++(int)
115 {
116 m_value += kFixedPointDenominator;
117 return *this;
118 }
119
rawValue()120 inline int rawValue() const { return m_value; }
setRawValue(int value)121 inline void setRawValue(int value) { m_value = value; }
setRawValue(long long value)122 void setRawValue(long long value)
123 {
124 REPORT_OVERFLOW(value > std::numeric_limits<int>::min() && value < std::numeric_limits<int>::max());
125 m_value = static_cast<int>(value);
126 }
127
abs()128 LayoutUnit abs() const
129 {
130 LayoutUnit returnValue;
131 returnValue.setRawValue(::abs(m_value));
132 return returnValue;
133 }
134 #if OS(MACOSX)
wtf_ceil()135 int wtf_ceil() const
136 #else
137 int ceil() const
138 #endif
139 {
140 if (UNLIKELY(m_value >= INT_MAX - kFixedPointDenominator + 1))
141 return intMaxForLayoutUnit;
142
143 if (m_value >= 0)
144 return (m_value + kFixedPointDenominator - 1) / kFixedPointDenominator;
145 return toInt();
146 }
round()147 int round() const
148 {
149 if (m_value > 0)
150 return saturatedAddition(rawValue(), kFixedPointDenominator / 2) / kFixedPointDenominator;
151 return saturatedSubtraction(rawValue(), (kFixedPointDenominator / 2) - 1) / kFixedPointDenominator;
152 }
153
floor()154 int floor() const
155 {
156 if (UNLIKELY(m_value <= INT_MIN + kFixedPointDenominator - 1))
157 return intMinForLayoutUnit;
158
159 if (m_value >= 0)
160 return toInt();
161 return (m_value - kFixedPointDenominator + 1) / kFixedPointDenominator;
162 }
163
fraction()164 LayoutUnit fraction() const
165 {
166 // Add the fraction to the size (as opposed to the full location) to avoid overflows.
167 // Compute fraction using the mod operator to preserve the sign of the value as it may affect rounding.
168 LayoutUnit fraction;
169 fraction.setRawValue(rawValue() % kFixedPointDenominator);
170 return fraction;
171 }
172
mightBeSaturated()173 bool mightBeSaturated() const
174 {
175 return rawValue() == std::numeric_limits<int>::max()
176 || rawValue() == std::numeric_limits<int>::min();
177 }
178
epsilon()179 static float epsilon() { return 1.0f / kFixedPointDenominator; }
180
max()181 static const LayoutUnit max()
182 {
183 LayoutUnit m;
184 m.m_value = std::numeric_limits<int>::max();
185 return m;
186 }
min()187 static const LayoutUnit min()
188 {
189 LayoutUnit m;
190 m.m_value = std::numeric_limits<int>::min();
191 return m;
192 }
193
194 // Versions of max/min that are slightly smaller/larger than max/min() to allow for roinding without overflowing.
nearlyMax()195 static const LayoutUnit nearlyMax()
196 {
197 LayoutUnit m;
198 m.m_value = std::numeric_limits<int>::max() - kFixedPointDenominator / 2;
199 return m;
200 }
nearlyMin()201 static const LayoutUnit nearlyMin()
202 {
203 LayoutUnit m;
204 m.m_value = std::numeric_limits<int>::min() + kFixedPointDenominator / 2;
205 return m;
206 }
207
clamp(double value)208 static LayoutUnit clamp(double value)
209 {
210 return clampTo<LayoutUnit>(value, LayoutUnit::min(), LayoutUnit::max());
211 }
212
213 private:
isInBounds(int value)214 static bool isInBounds(int value)
215 {
216 return ::abs(value) <= std::numeric_limits<int>::max() / kFixedPointDenominator;
217 }
isInBounds(unsigned value)218 static bool isInBounds(unsigned value)
219 {
220 return value <= static_cast<unsigned>(std::numeric_limits<int>::max()) / kFixedPointDenominator;
221 }
isInBounds(double value)222 static bool isInBounds(double value)
223 {
224 return ::fabs(value) <= std::numeric_limits<int>::max() / kFixedPointDenominator;
225 }
226
setValue(int value)227 inline void setValue(int value)
228 {
229 if (value > intMaxForLayoutUnit)
230 m_value = std::numeric_limits<int>::max();
231 else if (value < intMinForLayoutUnit)
232 m_value = std::numeric_limits<int>::min();
233 else
234 m_value = value * kFixedPointDenominator;
235 }
setValue(unsigned value)236 inline void setValue(unsigned value)
237 {
238 if (value >= static_cast<unsigned>(intMaxForLayoutUnit))
239 m_value = std::numeric_limits<int>::max();
240 else
241 m_value = value * kFixedPointDenominator;
242 }
243
244 int m_value;
245 };
246
247 inline bool operator<=(const LayoutUnit& a, const LayoutUnit& b)
248 {
249 return a.rawValue() <= b.rawValue();
250 }
251
252 inline bool operator<=(const LayoutUnit& a, float b)
253 {
254 return a.toFloat() <= b;
255 }
256
257 inline bool operator<=(const LayoutUnit& a, int b)
258 {
259 return a <= LayoutUnit(b);
260 }
261
262 inline bool operator<=(const float a, const LayoutUnit& b)
263 {
264 return a <= b.toFloat();
265 }
266
267 inline bool operator<=(const int a, const LayoutUnit& b)
268 {
269 return LayoutUnit(a) <= b;
270 }
271
272 inline bool operator>=(const LayoutUnit& a, const LayoutUnit& b)
273 {
274 return a.rawValue() >= b.rawValue();
275 }
276
277 inline bool operator>=(const LayoutUnit& a, int b)
278 {
279 return a >= LayoutUnit(b);
280 }
281
282 inline bool operator>=(const float a, const LayoutUnit& b)
283 {
284 return a >= b.toFloat();
285 }
286
287 inline bool operator>=(const LayoutUnit& a, float b)
288 {
289 return a.toFloat() >= b;
290 }
291
292 inline bool operator>=(const int a, const LayoutUnit& b)
293 {
294 return LayoutUnit(a) >= b;
295 }
296
297 inline bool operator<(const LayoutUnit& a, const LayoutUnit& b)
298 {
299 return a.rawValue() < b.rawValue();
300 }
301
302 inline bool operator<(const LayoutUnit& a, int b)
303 {
304 return a < LayoutUnit(b);
305 }
306
307 inline bool operator<(const LayoutUnit& a, float b)
308 {
309 return a.toFloat() < b;
310 }
311
312 inline bool operator<(const LayoutUnit& a, double b)
313 {
314 return a.toDouble() < b;
315 }
316
317 inline bool operator<(const int a, const LayoutUnit& b)
318 {
319 return LayoutUnit(a) < b;
320 }
321
322 inline bool operator<(const float a, const LayoutUnit& b)
323 {
324 return a < b.toFloat();
325 }
326
327 inline bool operator>(const LayoutUnit& a, const LayoutUnit& b)
328 {
329 return a.rawValue() > b.rawValue();
330 }
331
332 inline bool operator>(const LayoutUnit& a, double b)
333 {
334 return a.toDouble() > b;
335 }
336
337 inline bool operator>(const LayoutUnit& a, float b)
338 {
339 return a.toFloat() > b;
340 }
341
342 inline bool operator>(const LayoutUnit& a, int b)
343 {
344 return a > LayoutUnit(b);
345 }
346
347 inline bool operator>(const int a, const LayoutUnit& b)
348 {
349 return LayoutUnit(a) > b;
350 }
351
352 inline bool operator>(const float a, const LayoutUnit& b)
353 {
354 return a > b.toFloat();
355 }
356
357 inline bool operator>(const double a, const LayoutUnit& b)
358 {
359 return a > b.toDouble();
360 }
361
362 inline bool operator!=(const LayoutUnit& a, const LayoutUnit& b)
363 {
364 return a.rawValue() != b.rawValue();
365 }
366
367 inline bool operator!=(const LayoutUnit& a, float b)
368 {
369 return a != LayoutUnit(b);
370 }
371
372 inline bool operator!=(const int a, const LayoutUnit& b)
373 {
374 return LayoutUnit(a) != b;
375 }
376
377 inline bool operator!=(const LayoutUnit& a, int b)
378 {
379 return a != LayoutUnit(b);
380 }
381
382 inline bool operator==(const LayoutUnit& a, const LayoutUnit& b)
383 {
384 return a.rawValue() == b.rawValue();
385 }
386
387 inline bool operator==(const LayoutUnit& a, int b)
388 {
389 return a == LayoutUnit(b);
390 }
391
392 inline bool operator==(const int a, const LayoutUnit& b)
393 {
394 return LayoutUnit(a) == b;
395 }
396
397 inline bool operator==(const LayoutUnit& a, float b)
398 {
399 return a.toFloat() == b;
400 }
401
402 inline bool operator==(const float a, const LayoutUnit& b)
403 {
404 return a == b.toFloat();
405 }
406
407 // For multiplication that's prone to overflow, this bounds it to LayoutUnit::max() and ::min()
boundedMultiply(const LayoutUnit & a,const LayoutUnit & b)408 inline LayoutUnit boundedMultiply(const LayoutUnit& a, const LayoutUnit& b)
409 {
410 int64_t result = static_cast<int64_t>(a.rawValue()) * static_cast<int64_t>(b.rawValue()) / kFixedPointDenominator;
411 int32_t high = static_cast<int32_t>(result >> 32);
412 int32_t low = static_cast<int32_t>(result);
413 uint32_t saturated = (static_cast<uint32_t>(a.rawValue() ^ b.rawValue()) >> 31) + std::numeric_limits<int>::max();
414 // If the higher 32 bits does not match the lower 32 with sign extension the operation overflowed.
415 if (high != low >> 31)
416 result = saturated;
417
418 LayoutUnit returnVal;
419 returnVal.setRawValue(static_cast<int>(result));
420 return returnVal;
421 }
422
423 inline LayoutUnit operator*(const LayoutUnit& a, const LayoutUnit& b)
424 {
425 return boundedMultiply(a, b);
426 }
427
428 inline double operator*(const LayoutUnit& a, double b)
429 {
430 return a.toDouble() * b;
431 }
432
433 inline float operator*(const LayoutUnit& a, float b)
434 {
435 return a.toFloat() * b;
436 }
437
438 inline LayoutUnit operator*(const LayoutUnit& a, int b)
439 {
440 return a * LayoutUnit(b);
441 }
442
443 inline LayoutUnit operator*(const LayoutUnit& a, unsigned short b)
444 {
445 return a * LayoutUnit(b);
446 }
447
448 inline LayoutUnit operator*(const LayoutUnit& a, unsigned b)
449 {
450 return a * LayoutUnit(b);
451 }
452
453 inline LayoutUnit operator*(const LayoutUnit& a, unsigned long b)
454 {
455 return a * LayoutUnit(b);
456 }
457
458 inline LayoutUnit operator*(const LayoutUnit& a, unsigned long long b)
459 {
460 return a * LayoutUnit(b);
461 }
462
463 inline LayoutUnit operator*(unsigned short a, const LayoutUnit& b)
464 {
465 return LayoutUnit(a) * b;
466 }
467
468 inline LayoutUnit operator*(unsigned a, const LayoutUnit& b)
469 {
470 return LayoutUnit(a) * b;
471 }
472
473 inline LayoutUnit operator*(unsigned long a, const LayoutUnit& b)
474 {
475 return LayoutUnit(a) * b;
476 }
477
478 inline LayoutUnit operator*(unsigned long long a, const LayoutUnit& b)
479 {
480 return LayoutUnit(a) * b;
481 }
482
483 inline LayoutUnit operator*(const int a, const LayoutUnit& b)
484 {
485 return LayoutUnit(a) * b;
486 }
487
488 inline float operator*(const float a, const LayoutUnit& b)
489 {
490 return a * b.toFloat();
491 }
492
493 inline double operator*(const double a, const LayoutUnit& b)
494 {
495 return a * b.toDouble();
496 }
497
498 inline LayoutUnit operator/(const LayoutUnit& a, const LayoutUnit& b)
499 {
500 LayoutUnit returnVal;
501 long long rawVal = static_cast<long long>(kFixedPointDenominator) * a.rawValue() / b.rawValue();
502 returnVal.setRawValue(clampTo<int>(rawVal));
503 return returnVal;
504 }
505
506 inline float operator/(const LayoutUnit& a, float b)
507 {
508 return a.toFloat() / b;
509 }
510
511 inline double operator/(const LayoutUnit& a, double b)
512 {
513 return a.toDouble() / b;
514 }
515
516 inline LayoutUnit operator/(const LayoutUnit& a, int b)
517 {
518 return a / LayoutUnit(b);
519 }
520
521 inline LayoutUnit operator/(const LayoutUnit& a, unsigned short b)
522 {
523 return a / LayoutUnit(b);
524 }
525
526 inline LayoutUnit operator/(const LayoutUnit& a, unsigned b)
527 {
528 return a / LayoutUnit(b);
529 }
530
531 inline LayoutUnit operator/(const LayoutUnit& a, unsigned long b)
532 {
533 return a / LayoutUnit(b);
534 }
535
536 inline LayoutUnit operator/(const LayoutUnit& a, unsigned long long b)
537 {
538 return a / LayoutUnit(b);
539 }
540
541 inline float operator/(const float a, const LayoutUnit& b)
542 {
543 return a / b.toFloat();
544 }
545
546 inline double operator/(const double a, const LayoutUnit& b)
547 {
548 return a / b.toDouble();
549 }
550
551 inline LayoutUnit operator/(const int a, const LayoutUnit& b)
552 {
553 return LayoutUnit(a) / b;
554 }
555
556 inline LayoutUnit operator/(unsigned short a, const LayoutUnit& b)
557 {
558 return LayoutUnit(a) / b;
559 }
560
561 inline LayoutUnit operator/(unsigned a, const LayoutUnit& b)
562 {
563 return LayoutUnit(a) / b;
564 }
565
566 inline LayoutUnit operator/(unsigned long a, const LayoutUnit& b)
567 {
568 return LayoutUnit(a) / b;
569 }
570
571 inline LayoutUnit operator/(unsigned long long a, const LayoutUnit& b)
572 {
573 return LayoutUnit(a) / b;
574 }
575
576 inline LayoutUnit operator+(const LayoutUnit& a, const LayoutUnit& b)
577 {
578 LayoutUnit returnVal;
579 returnVal.setRawValue(saturatedAddition(a.rawValue(), b.rawValue()));
580 return returnVal;
581 }
582
583 inline LayoutUnit operator+(const LayoutUnit& a, int b)
584 {
585 return a + LayoutUnit(b);
586 }
587
588 inline float operator+(const LayoutUnit& a, float b)
589 {
590 return a.toFloat() + b;
591 }
592
593 inline double operator+(const LayoutUnit& a, double b)
594 {
595 return a.toDouble() + b;
596 }
597
598 inline LayoutUnit operator+(const int a, const LayoutUnit& b)
599 {
600 return LayoutUnit(a) + b;
601 }
602
603 inline float operator+(const float a, const LayoutUnit& b)
604 {
605 return a + b.toFloat();
606 }
607
608 inline double operator+(const double a, const LayoutUnit& b)
609 {
610 return a + b.toDouble();
611 }
612
613 inline LayoutUnit operator-(const LayoutUnit& a, const LayoutUnit& b)
614 {
615 LayoutUnit returnVal;
616 returnVal.setRawValue(saturatedSubtraction(a.rawValue(), b.rawValue()));
617 return returnVal;
618 }
619
620 inline LayoutUnit operator-(const LayoutUnit& a, int b)
621 {
622 return a - LayoutUnit(b);
623 }
624
625 inline LayoutUnit operator-(const LayoutUnit& a, unsigned b)
626 {
627 return a - LayoutUnit(b);
628 }
629
630 inline float operator-(const LayoutUnit& a, float b)
631 {
632 return a.toFloat() - b;
633 }
634
635 inline LayoutUnit operator-(const int a, const LayoutUnit& b)
636 {
637 return LayoutUnit(a) - b;
638 }
639
640 inline float operator-(const float a, const LayoutUnit& b)
641 {
642 return a - b.toFloat();
643 }
644
645 inline LayoutUnit operator-(const LayoutUnit& a)
646 {
647 LayoutUnit returnVal;
648 returnVal.setRawValue(-a.rawValue());
649 return returnVal;
650 }
651
652 // For returning the remainder after a division with integer results.
intMod(const LayoutUnit & a,const LayoutUnit & b)653 inline LayoutUnit intMod(const LayoutUnit& a, const LayoutUnit& b)
654 {
655 // This calculates the modulo so that: a = static_cast<int>(a / b) * b + intMod(a, b).
656 LayoutUnit returnVal;
657 returnVal.setRawValue(a.rawValue() % b.rawValue());
658 return returnVal;
659 }
660
661 inline LayoutUnit operator%(const LayoutUnit& a, const LayoutUnit& b)
662 {
663 // This calculates the modulo so that: a = (a / b) * b + a % b.
664 LayoutUnit returnVal;
665 long long rawVal = (static_cast<long long>(kFixedPointDenominator) * a.rawValue()) % b.rawValue();
666 returnVal.setRawValue(rawVal / kFixedPointDenominator);
667 return returnVal;
668 }
669
670 inline LayoutUnit operator%(const LayoutUnit& a, int b)
671 {
672 return a % LayoutUnit(b);
673 }
674
675 inline LayoutUnit operator%(int a, const LayoutUnit& b)
676 {
677 return LayoutUnit(a) % b;
678 }
679
680 inline LayoutUnit& operator+=(LayoutUnit& a, const LayoutUnit& b)
681 {
682 a.setRawValue(saturatedAddition(a.rawValue(), b.rawValue()));
683 return a;
684 }
685
686 inline LayoutUnit& operator+=(LayoutUnit& a, int b)
687 {
688 a = a + b;
689 return a;
690 }
691
692 inline LayoutUnit& operator+=(LayoutUnit& a, float b)
693 {
694 a = a + b;
695 return a;
696 }
697
698 inline float& operator+=(float& a, const LayoutUnit& b)
699 {
700 a = a + b;
701 return a;
702 }
703
704 inline LayoutUnit& operator-=(LayoutUnit& a, int b)
705 {
706 a = a - b;
707 return a;
708 }
709
710 inline LayoutUnit& operator-=(LayoutUnit& a, const LayoutUnit& b)
711 {
712 a.setRawValue(saturatedSubtraction(a.rawValue(), b.rawValue()));
713 return a;
714 }
715
716 inline LayoutUnit& operator-=(LayoutUnit& a, float b)
717 {
718 a = a - b;
719 return a;
720 }
721
722 inline float& operator-=(float& a, const LayoutUnit& b)
723 {
724 a = a - b;
725 return a;
726 }
727
728 inline LayoutUnit& operator*=(LayoutUnit& a, const LayoutUnit& b)
729 {
730 a = a * b;
731 return a;
732 }
733 // operator*=(LayoutUnit& a, int b) is supported by the operator above plus LayoutUnit(int).
734
735 inline LayoutUnit& operator*=(LayoutUnit& a, float b)
736 {
737 a = a * b;
738 return a;
739 }
740
741 inline float& operator*=(float& a, const LayoutUnit& b)
742 {
743 a = a * b;
744 return a;
745 }
746
747 inline LayoutUnit& operator/=(LayoutUnit& a, const LayoutUnit& b)
748 {
749 a = a / b;
750 return a;
751 }
752 // operator/=(LayoutUnit& a, int b) is supported by the operator above plus LayoutUnit(int).
753
754 inline LayoutUnit& operator/=(LayoutUnit& a, float b)
755 {
756 a = a / b;
757 return a;
758 }
759
760 inline float& operator/=(float& a, const LayoutUnit& b)
761 {
762 a = a / b;
763 return a;
764 }
765
snapSizeToPixel(LayoutUnit size,LayoutUnit location)766 inline int snapSizeToPixel(LayoutUnit size, LayoutUnit location)
767 {
768 LayoutUnit fraction = location.fraction();
769 return (fraction + size).round() - fraction.round();
770 }
771
roundToInt(LayoutUnit value)772 inline int roundToInt(LayoutUnit value)
773 {
774 return value.round();
775 }
776
floorToInt(LayoutUnit value)777 inline int floorToInt(LayoutUnit value)
778 {
779 return value.floor();
780 }
781
absoluteValue(const LayoutUnit & value)782 inline LayoutUnit absoluteValue(const LayoutUnit& value)
783 {
784 return value.abs();
785 }
786
layoutMod(const LayoutUnit & numerator,const LayoutUnit & denominator)787 inline LayoutUnit layoutMod(const LayoutUnit& numerator, const LayoutUnit& denominator)
788 {
789 return numerator % denominator;
790 }
791
isIntegerValue(const LayoutUnit value)792 inline bool isIntegerValue(const LayoutUnit value)
793 {
794 return value.toInt() == value;
795 }
796
797 } // namespace WebCore
798
799 #endif // LayoutUnit_h
800