• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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