• 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 kLayoutUnitFractionalBits = 6;
58 static const int kFixedPointDenominator = 1 << kLayoutUnitFractionalBits;
59 
60 const int intMaxForLayoutUnit = INT_MAX / kFixedPointDenominator;
61 const int intMinForLayoutUnit = INT_MIN / kFixedPointDenominator;
62 
63 class LayoutUnit {
64 public:
LayoutUnit()65     LayoutUnit() : m_value(0) { }
LayoutUnit(int value)66     LayoutUnit(int value) { setValue(value); }
LayoutUnit(unsigned short value)67     LayoutUnit(unsigned short value) { setValue(value); }
LayoutUnit(unsigned value)68     LayoutUnit(unsigned value) { setValue(value); }
LayoutUnit(unsigned long value)69     LayoutUnit(unsigned long value) { m_value = clampTo<int>(value * kFixedPointDenominator); }
LayoutUnit(unsigned long long value)70     LayoutUnit(unsigned long long value) { m_value = clampTo<int>(value * kFixedPointDenominator); }
LayoutUnit(float value)71     LayoutUnit(float value) { m_value = clampTo<float>(value * kFixedPointDenominator, static_cast<float>(INT_MIN), static_cast<float>(INT_MAX)); }
LayoutUnit(double value)72     LayoutUnit(double value) { m_value = clampTo<double>(value * kFixedPointDenominator, static_cast<double>(INT_MIN), static_cast<double>(INT_MAX)); }
73 
fromFloatCeil(float value)74     static LayoutUnit fromFloatCeil(float value)
75     {
76         LayoutUnit v;
77         v.m_value = clampToInteger(ceilf(value * kFixedPointDenominator));
78         return v;
79     }
80 
fromFloatFloor(float value)81     static LayoutUnit fromFloatFloor(float value)
82     {
83         LayoutUnit v;
84         v.m_value = clampToInteger(floorf(value * kFixedPointDenominator));
85         return v;
86     }
87 
fromFloatRound(float value)88     static LayoutUnit fromFloatRound(float value)
89     {
90         if (value >= 0)
91             return clamp(value + epsilon() / 2.0f);
92         return clamp(value - epsilon() / 2.0f);
93     }
94 
toInt()95     int toInt() const { return m_value / kFixedPointDenominator; }
toFloat()96     float toFloat() const { return static_cast<float>(m_value) / kFixedPointDenominator; }
toDouble()97     double toDouble() const { return static_cast<double>(m_value) / kFixedPointDenominator; }
ceilToFloat()98     float ceilToFloat() const
99     {
100         float floatValue = toFloat();
101         if (static_cast<int>(floatValue * kFixedPointDenominator) == m_value)
102             return floatValue;
103         if (floatValue > 0)
104             return nextafterf(floatValue, std::numeric_limits<float>::max());
105         return nextafterf(floatValue, std::numeric_limits<float>::min());
106     }
toUnsigned()107     unsigned toUnsigned() const { REPORT_OVERFLOW(m_value >= 0); return toInt(); }
108 
109     operator int() const { return toInt(); }
110     operator unsigned() const { return toUnsigned(); }
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     ALWAYS_INLINE int round() const
148     {
149         return saturatedAddition(rawValue(), kFixedPointDenominator / 2) >> kLayoutUnitFractionalBits;
150     }
151 
floor()152     int floor() const
153     {
154         if (UNLIKELY(m_value <= INT_MIN + kFixedPointDenominator - 1))
155             return intMinForLayoutUnit;
156 
157         return m_value >> kLayoutUnitFractionalBits;
158     }
159 
fraction()160     LayoutUnit fraction() const
161     {
162         // Add the fraction to the size (as opposed to the full location) to avoid overflows.
163         // Compute fraction using the mod operator to preserve the sign of the value as it may affect rounding.
164         LayoutUnit fraction;
165         fraction.setRawValue(rawValue() % kFixedPointDenominator);
166         return fraction;
167     }
168 
mightBeSaturated()169     bool mightBeSaturated() const
170     {
171         return rawValue() == std::numeric_limits<int>::max()
172             || rawValue() == std::numeric_limits<int>::min();
173     }
174 
epsilon()175     static float epsilon() { return 1.0f / kFixedPointDenominator; }
176 
max()177     static const LayoutUnit max()
178     {
179         LayoutUnit m;
180         m.m_value = std::numeric_limits<int>::max();
181         return m;
182     }
min()183     static const LayoutUnit min()
184     {
185         LayoutUnit m;
186         m.m_value = std::numeric_limits<int>::min();
187         return m;
188     }
189 
190     // Versions of max/min that are slightly smaller/larger than max/min() to allow for roinding without overflowing.
nearlyMax()191     static const LayoutUnit nearlyMax()
192     {
193         LayoutUnit m;
194         m.m_value = std::numeric_limits<int>::max() - kFixedPointDenominator / 2;
195         return m;
196     }
nearlyMin()197     static const LayoutUnit nearlyMin()
198     {
199         LayoutUnit m;
200         m.m_value = std::numeric_limits<int>::min() + kFixedPointDenominator / 2;
201         return m;
202     }
203 
clamp(double value)204     static LayoutUnit clamp(double value)
205     {
206         return clampTo<LayoutUnit>(value, LayoutUnit::min(), LayoutUnit::max());
207     }
208 
209 private:
isInBounds(int value)210     static bool isInBounds(int value)
211     {
212         return ::abs(value) <= std::numeric_limits<int>::max() / kFixedPointDenominator;
213     }
isInBounds(unsigned value)214     static bool isInBounds(unsigned value)
215     {
216         return value <= static_cast<unsigned>(std::numeric_limits<int>::max()) / kFixedPointDenominator;
217     }
isInBounds(double value)218     static bool isInBounds(double value)
219     {
220         return ::fabs(value) <= std::numeric_limits<int>::max() / kFixedPointDenominator;
221     }
222 
setValue(int value)223     inline void setValue(int value)
224     {
225         if (value > intMaxForLayoutUnit)
226             m_value = std::numeric_limits<int>::max();
227         else if (value < intMinForLayoutUnit)
228             m_value = std::numeric_limits<int>::min();
229         else
230             m_value = value * kFixedPointDenominator;
231     }
setValue(unsigned value)232     inline void setValue(unsigned value)
233     {
234         if (value >= static_cast<unsigned>(intMaxForLayoutUnit))
235             m_value = std::numeric_limits<int>::max();
236         else
237             m_value = value * kFixedPointDenominator;
238     }
239 
240     int m_value;
241 };
242 
243 inline bool operator<=(const LayoutUnit& a, const LayoutUnit& b)
244 {
245     return a.rawValue() <= b.rawValue();
246 }
247 
248 inline bool operator<=(const LayoutUnit& a, float b)
249 {
250     return a.toFloat() <= b;
251 }
252 
253 inline bool operator<=(const LayoutUnit& a, int b)
254 {
255     return a <= LayoutUnit(b);
256 }
257 
258 inline bool operator<=(const float a, const LayoutUnit& b)
259 {
260     return a <= b.toFloat();
261 }
262 
263 inline bool operator<=(const int a, const LayoutUnit& b)
264 {
265     return LayoutUnit(a) <= b;
266 }
267 
268 inline bool operator>=(const LayoutUnit& a, const LayoutUnit& b)
269 {
270     return a.rawValue() >= b.rawValue();
271 }
272 
273 inline bool operator>=(const LayoutUnit& a, int b)
274 {
275     return a >= LayoutUnit(b);
276 }
277 
278 inline bool operator>=(const float a, const LayoutUnit& b)
279 {
280     return a >= b.toFloat();
281 }
282 
283 inline bool operator>=(const LayoutUnit& a, float b)
284 {
285     return a.toFloat() >= b;
286 }
287 
288 inline bool operator>=(const int a, const LayoutUnit& b)
289 {
290     return LayoutUnit(a) >= b;
291 }
292 
293 inline bool operator<(const LayoutUnit& a, const LayoutUnit& b)
294 {
295     return a.rawValue() < b.rawValue();
296 }
297 
298 inline bool operator<(const LayoutUnit& a, int b)
299 {
300     return a < LayoutUnit(b);
301 }
302 
303 inline bool operator<(const LayoutUnit& a, float b)
304 {
305     return a.toFloat() < b;
306 }
307 
308 inline bool operator<(const LayoutUnit& a, double b)
309 {
310     return a.toDouble() < b;
311 }
312 
313 inline bool operator<(const int a, const LayoutUnit& b)
314 {
315     return LayoutUnit(a) < b;
316 }
317 
318 inline bool operator<(const float a, const LayoutUnit& b)
319 {
320     return a < b.toFloat();
321 }
322 
323 inline bool operator>(const LayoutUnit& a, const LayoutUnit& b)
324 {
325     return a.rawValue() > b.rawValue();
326 }
327 
328 inline bool operator>(const LayoutUnit& a, double b)
329 {
330     return a.toDouble() > b;
331 }
332 
333 inline bool operator>(const LayoutUnit& a, float b)
334 {
335     return a.toFloat() > b;
336 }
337 
338 inline bool operator>(const LayoutUnit& a, int b)
339 {
340     return a > LayoutUnit(b);
341 }
342 
343 inline bool operator>(const int a, const LayoutUnit& b)
344 {
345     return LayoutUnit(a) > b;
346 }
347 
348 inline bool operator>(const float a, const LayoutUnit& b)
349 {
350     return a > b.toFloat();
351 }
352 
353 inline bool operator>(const double a, const LayoutUnit& b)
354 {
355     return a > b.toDouble();
356 }
357 
358 inline bool operator!=(const LayoutUnit& a, const LayoutUnit& b)
359 {
360     return a.rawValue() != b.rawValue();
361 }
362 
363 inline bool operator!=(const LayoutUnit& a, float b)
364 {
365     return a != LayoutUnit(b);
366 }
367 
368 inline bool operator!=(const int a, const LayoutUnit& b)
369 {
370     return LayoutUnit(a) != b;
371 }
372 
373 inline bool operator!=(const LayoutUnit& a, int b)
374 {
375     return a != LayoutUnit(b);
376 }
377 
378 inline bool operator==(const LayoutUnit& a, const LayoutUnit& b)
379 {
380     return a.rawValue() == b.rawValue();
381 }
382 
383 inline bool operator==(const LayoutUnit& a, int b)
384 {
385     return a == LayoutUnit(b);
386 }
387 
388 inline bool operator==(const int a, const LayoutUnit& b)
389 {
390     return LayoutUnit(a) == b;
391 }
392 
393 inline bool operator==(const LayoutUnit& a, float b)
394 {
395     return a.toFloat() == b;
396 }
397 
398 inline bool operator==(const float a, const LayoutUnit& b)
399 {
400     return a == b.toFloat();
401 }
402 
403 // For multiplication that's prone to overflow, this bounds it to LayoutUnit::max() and ::min()
boundedMultiply(const LayoutUnit & a,const LayoutUnit & b)404 inline LayoutUnit boundedMultiply(const LayoutUnit& a, const LayoutUnit& b)
405 {
406     int64_t result = static_cast<int64_t>(a.rawValue()) * static_cast<int64_t>(b.rawValue()) / kFixedPointDenominator;
407     int32_t high = static_cast<int32_t>(result >> 32);
408     int32_t low = static_cast<int32_t>(result);
409     uint32_t saturated = (static_cast<uint32_t>(a.rawValue() ^ b.rawValue()) >> 31) + std::numeric_limits<int>::max();
410     // If the higher 32 bits does not match the lower 32 with sign extension the operation overflowed.
411     if (high != low >> 31)
412         result = saturated;
413 
414     LayoutUnit returnVal;
415     returnVal.setRawValue(static_cast<int>(result));
416     return returnVal;
417 }
418 
419 inline LayoutUnit operator*(const LayoutUnit& a, const LayoutUnit& b)
420 {
421     return boundedMultiply(a, b);
422 }
423 
424 inline double operator*(const LayoutUnit& a, double b)
425 {
426     return a.toDouble() * b;
427 }
428 
429 inline float operator*(const LayoutUnit& a, float b)
430 {
431     return a.toFloat() * b;
432 }
433 
434 inline LayoutUnit operator*(const LayoutUnit& a, int b)
435 {
436     return a * LayoutUnit(b);
437 }
438 
439 inline LayoutUnit operator*(const LayoutUnit& a, unsigned short b)
440 {
441     return a * LayoutUnit(b);
442 }
443 
444 inline LayoutUnit operator*(const LayoutUnit& a, unsigned b)
445 {
446     return a * LayoutUnit(b);
447 }
448 
449 inline LayoutUnit operator*(const LayoutUnit& a, unsigned long b)
450 {
451     return a * LayoutUnit(b);
452 }
453 
454 inline LayoutUnit operator*(const LayoutUnit& a, unsigned long long b)
455 {
456     return a * LayoutUnit(b);
457 }
458 
459 inline LayoutUnit operator*(unsigned short a, const LayoutUnit& b)
460 {
461     return LayoutUnit(a) * b;
462 }
463 
464 inline LayoutUnit operator*(unsigned a, const LayoutUnit& b)
465 {
466     return LayoutUnit(a) * b;
467 }
468 
469 inline LayoutUnit operator*(unsigned long a, const LayoutUnit& b)
470 {
471     return LayoutUnit(a) * b;
472 }
473 
474 inline LayoutUnit operator*(unsigned long long a, const LayoutUnit& b)
475 {
476     return LayoutUnit(a) * b;
477 }
478 
479 inline LayoutUnit operator*(const int a, const LayoutUnit& b)
480 {
481     return LayoutUnit(a) * b;
482 }
483 
484 inline float operator*(const float a, const LayoutUnit& b)
485 {
486     return a * b.toFloat();
487 }
488 
489 inline double operator*(const double a, const LayoutUnit& b)
490 {
491     return a * b.toDouble();
492 }
493 
494 inline LayoutUnit operator/(const LayoutUnit& a, const LayoutUnit& b)
495 {
496     LayoutUnit returnVal;
497     long long rawVal = static_cast<long long>(kFixedPointDenominator) * a.rawValue() / b.rawValue();
498     returnVal.setRawValue(clampTo<int>(rawVal));
499     return returnVal;
500 }
501 
502 inline float operator/(const LayoutUnit& a, float b)
503 {
504     return a.toFloat() / b;
505 }
506 
507 inline double operator/(const LayoutUnit& a, double b)
508 {
509     return a.toDouble() / b;
510 }
511 
512 inline LayoutUnit operator/(const LayoutUnit& a, int b)
513 {
514     return a / LayoutUnit(b);
515 }
516 
517 inline LayoutUnit operator/(const LayoutUnit& a, unsigned short b)
518 {
519     return a / LayoutUnit(b);
520 }
521 
522 inline LayoutUnit operator/(const LayoutUnit& a, unsigned b)
523 {
524     return a / LayoutUnit(b);
525 }
526 
527 inline LayoutUnit operator/(const LayoutUnit& a, unsigned long b)
528 {
529     return a / LayoutUnit(b);
530 }
531 
532 inline LayoutUnit operator/(const LayoutUnit& a, unsigned long long b)
533 {
534     return a / LayoutUnit(b);
535 }
536 
537 inline float operator/(const float a, const LayoutUnit& b)
538 {
539     return a / b.toFloat();
540 }
541 
542 inline double operator/(const double a, const LayoutUnit& b)
543 {
544     return a / b.toDouble();
545 }
546 
547 inline LayoutUnit operator/(const int a, const LayoutUnit& b)
548 {
549     return LayoutUnit(a) / b;
550 }
551 
552 inline LayoutUnit operator/(unsigned short a, const LayoutUnit& b)
553 {
554     return LayoutUnit(a) / b;
555 }
556 
557 inline LayoutUnit operator/(unsigned a, const LayoutUnit& b)
558 {
559     return LayoutUnit(a) / b;
560 }
561 
562 inline LayoutUnit operator/(unsigned long a, const LayoutUnit& b)
563 {
564     return LayoutUnit(a) / b;
565 }
566 
567 inline LayoutUnit operator/(unsigned long long a, const LayoutUnit& b)
568 {
569     return LayoutUnit(a) / b;
570 }
571 
572 ALWAYS_INLINE LayoutUnit operator+(const LayoutUnit& a, const LayoutUnit& b)
573 {
574     LayoutUnit returnVal;
575     returnVal.setRawValue(saturatedAddition(a.rawValue(), b.rawValue()));
576     return returnVal;
577 }
578 
579 inline LayoutUnit operator+(const LayoutUnit& a, int b)
580 {
581     return a + LayoutUnit(b);
582 }
583 
584 inline float operator+(const LayoutUnit& a, float b)
585 {
586     return a.toFloat() + b;
587 }
588 
589 inline double operator+(const LayoutUnit& a, double b)
590 {
591     return a.toDouble() + b;
592 }
593 
594 inline LayoutUnit operator+(const int a, const LayoutUnit& b)
595 {
596     return LayoutUnit(a) + b;
597 }
598 
599 inline float operator+(const float a, const LayoutUnit& b)
600 {
601     return a + b.toFloat();
602 }
603 
604 inline double operator+(const double a, const LayoutUnit& b)
605 {
606     return a + b.toDouble();
607 }
608 
609 ALWAYS_INLINE LayoutUnit operator-(const LayoutUnit& a, const LayoutUnit& b)
610 {
611     LayoutUnit returnVal;
612     returnVal.setRawValue(saturatedSubtraction(a.rawValue(), b.rawValue()));
613     return returnVal;
614 }
615 
616 inline LayoutUnit operator-(const LayoutUnit& a, int b)
617 {
618     return a - LayoutUnit(b);
619 }
620 
621 inline LayoutUnit operator-(const LayoutUnit& a, unsigned b)
622 {
623     return a - LayoutUnit(b);
624 }
625 
626 inline float operator-(const LayoutUnit& a, float b)
627 {
628     return a.toFloat() - b;
629 }
630 
631 inline LayoutUnit operator-(const int a, const LayoutUnit& b)
632 {
633     return LayoutUnit(a) - b;
634 }
635 
636 inline float operator-(const float a, const LayoutUnit& b)
637 {
638     return a - b.toFloat();
639 }
640 
641 inline LayoutUnit operator-(const LayoutUnit& a)
642 {
643     LayoutUnit returnVal;
644     returnVal.setRawValue(-a.rawValue());
645     return returnVal;
646 }
647 
648 // For returning the remainder after a division with integer results.
intMod(const LayoutUnit & a,const LayoutUnit & b)649 inline LayoutUnit intMod(const LayoutUnit& a, const LayoutUnit& b)
650 {
651     // This calculates the modulo so that: a = static_cast<int>(a / b) * b + intMod(a, b).
652     LayoutUnit returnVal;
653     returnVal.setRawValue(a.rawValue() % b.rawValue());
654     return returnVal;
655 }
656 
657 inline LayoutUnit operator%(const LayoutUnit& a, const LayoutUnit& b)
658 {
659     // This calculates the modulo so that: a = (a / b) * b + a % b.
660     LayoutUnit returnVal;
661     long long rawVal = (static_cast<long long>(kFixedPointDenominator) * a.rawValue()) % b.rawValue();
662     returnVal.setRawValue(rawVal / kFixedPointDenominator);
663     return returnVal;
664 }
665 
666 inline LayoutUnit operator%(const LayoutUnit& a, int b)
667 {
668     return a % LayoutUnit(b);
669 }
670 
671 inline LayoutUnit operator%(int a, const LayoutUnit& b)
672 {
673     return LayoutUnit(a) % b;
674 }
675 
676 inline LayoutUnit& operator+=(LayoutUnit& a, const LayoutUnit& b)
677 {
678     a.setRawValue(saturatedAddition(a.rawValue(), b.rawValue()));
679     return a;
680 }
681 
682 inline LayoutUnit& operator+=(LayoutUnit& a, int b)
683 {
684     a = a + b;
685     return a;
686 }
687 
688 inline LayoutUnit& operator+=(LayoutUnit& a, float b)
689 {
690     a = a + b;
691     return a;
692 }
693 
694 inline float& operator+=(float& a, const LayoutUnit& b)
695 {
696     a = a + b;
697     return a;
698 }
699 
700 inline LayoutUnit& operator-=(LayoutUnit& a, int b)
701 {
702     a = a - b;
703     return a;
704 }
705 
706 inline LayoutUnit& operator-=(LayoutUnit& a, const LayoutUnit& b)
707 {
708     a.setRawValue(saturatedSubtraction(a.rawValue(), b.rawValue()));
709     return a;
710 }
711 
712 inline LayoutUnit& operator-=(LayoutUnit& a, float b)
713 {
714     a = a - b;
715     return a;
716 }
717 
718 inline float& operator-=(float& a, const LayoutUnit& b)
719 {
720     a = a - b;
721     return a;
722 }
723 
724 inline LayoutUnit& operator*=(LayoutUnit& a, const LayoutUnit& b)
725 {
726     a = a * b;
727     return a;
728 }
729 // operator*=(LayoutUnit& a, int b) is supported by the operator above plus LayoutUnit(int).
730 
731 inline LayoutUnit& operator*=(LayoutUnit& a, float b)
732 {
733     a = a * b;
734     return a;
735 }
736 
737 inline float& operator*=(float& a, const LayoutUnit& b)
738 {
739     a = a * b;
740     return a;
741 }
742 
743 inline LayoutUnit& operator/=(LayoutUnit& a, const LayoutUnit& b)
744 {
745     a = a / b;
746     return a;
747 }
748 // operator/=(LayoutUnit& a, int b) is supported by the operator above plus LayoutUnit(int).
749 
750 inline LayoutUnit& operator/=(LayoutUnit& a, float b)
751 {
752     a = a / b;
753     return a;
754 }
755 
756 inline float& operator/=(float& a, const LayoutUnit& b)
757 {
758     a = a / b;
759     return a;
760 }
761 
snapSizeToPixel(LayoutUnit size,LayoutUnit location)762 inline int snapSizeToPixel(LayoutUnit size, LayoutUnit location)
763 {
764     LayoutUnit fraction = location.fraction();
765     return (fraction + size).round() - fraction.round();
766 }
767 
roundToInt(LayoutUnit value)768 inline int roundToInt(LayoutUnit value)
769 {
770     return value.round();
771 }
772 
floorToInt(LayoutUnit value)773 inline int floorToInt(LayoutUnit value)
774 {
775     return value.floor();
776 }
777 
absoluteValue(const LayoutUnit & value)778 inline LayoutUnit absoluteValue(const LayoutUnit& value)
779 {
780     return value.abs();
781 }
782 
layoutMod(const LayoutUnit & numerator,const LayoutUnit & denominator)783 inline LayoutUnit layoutMod(const LayoutUnit& numerator, const LayoutUnit& denominator)
784 {
785     return numerator % denominator;
786 }
787 
isIntegerValue(const LayoutUnit value)788 inline bool isIntegerValue(const LayoutUnit value)
789 {
790     return value.toInt() == value;
791 }
792 
clampToLayoutUnit(LayoutUnit value,LayoutUnit min,LayoutUnit max)793 inline LayoutUnit clampToLayoutUnit(LayoutUnit value, LayoutUnit min, LayoutUnit max)
794 {
795     if (value >= max)
796         return max;
797     if (value <= min)
798         return min;
799     return value;
800 }
801 
802 } // namespace WebCore
803 
804 #endif // LayoutUnit_h
805