• 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 blink {
42 
43 #if !ERROR_DISABLED
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<int>(value * kFixedPointDenominator); }
LayoutUnit(double value)72     LayoutUnit(double value) { m_value = clampTo<int>(value * kFixedPointDenominator); }
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     ALWAYS_INLINE void setValue(int value)
224     {
225         m_value = saturatedSet(value, kLayoutUnitFractionalBits);
226     }
227 
setValue(unsigned value)228     inline void setValue(unsigned value)
229     {
230         m_value = saturatedSet(value, kLayoutUnitFractionalBits);
231     }
232 
233     int m_value;
234 };
235 
236 inline bool operator<=(const LayoutUnit& a, const LayoutUnit& b)
237 {
238     return a.rawValue() <= b.rawValue();
239 }
240 
241 inline bool operator<=(const LayoutUnit& a, float b)
242 {
243     return a.toFloat() <= b;
244 }
245 
246 inline bool operator<=(const LayoutUnit& a, int b)
247 {
248     return a <= LayoutUnit(b);
249 }
250 
251 inline bool operator<=(const float a, const LayoutUnit& b)
252 {
253     return a <= b.toFloat();
254 }
255 
256 inline bool operator<=(const int a, const LayoutUnit& b)
257 {
258     return LayoutUnit(a) <= b;
259 }
260 
261 inline bool operator>=(const LayoutUnit& a, const LayoutUnit& b)
262 {
263     return a.rawValue() >= b.rawValue();
264 }
265 
266 inline bool operator>=(const LayoutUnit& a, int b)
267 {
268     return a >= LayoutUnit(b);
269 }
270 
271 inline bool operator>=(const float a, const LayoutUnit& b)
272 {
273     return a >= b.toFloat();
274 }
275 
276 inline bool operator>=(const LayoutUnit& a, float b)
277 {
278     return a.toFloat() >= b;
279 }
280 
281 inline bool operator>=(const int a, const LayoutUnit& b)
282 {
283     return LayoutUnit(a) >= b;
284 }
285 
286 inline bool operator<(const LayoutUnit& a, const LayoutUnit& b)
287 {
288     return a.rawValue() < b.rawValue();
289 }
290 
291 inline bool operator<(const LayoutUnit& a, int b)
292 {
293     return a < LayoutUnit(b);
294 }
295 
296 inline bool operator<(const LayoutUnit& a, float b)
297 {
298     return a.toFloat() < b;
299 }
300 
301 inline bool operator<(const LayoutUnit& a, double b)
302 {
303     return a.toDouble() < b;
304 }
305 
306 inline bool operator<(const int a, const LayoutUnit& b)
307 {
308     return LayoutUnit(a) < b;
309 }
310 
311 inline bool operator<(const float a, const LayoutUnit& b)
312 {
313     return a < b.toFloat();
314 }
315 
316 inline bool operator>(const LayoutUnit& a, const LayoutUnit& b)
317 {
318     return a.rawValue() > b.rawValue();
319 }
320 
321 inline bool operator>(const LayoutUnit& a, double b)
322 {
323     return a.toDouble() > b;
324 }
325 
326 inline bool operator>(const LayoutUnit& a, float b)
327 {
328     return a.toFloat() > b;
329 }
330 
331 inline bool operator>(const LayoutUnit& a, int b)
332 {
333     return a > LayoutUnit(b);
334 }
335 
336 inline bool operator>(const int a, const LayoutUnit& b)
337 {
338     return LayoutUnit(a) > b;
339 }
340 
341 inline bool operator>(const float a, const LayoutUnit& b)
342 {
343     return a > b.toFloat();
344 }
345 
346 inline bool operator>(const double a, const LayoutUnit& b)
347 {
348     return a > b.toDouble();
349 }
350 
351 inline bool operator!=(const LayoutUnit& a, const LayoutUnit& b)
352 {
353     return a.rawValue() != b.rawValue();
354 }
355 
356 inline bool operator!=(const LayoutUnit& a, float b)
357 {
358     return a != LayoutUnit(b);
359 }
360 
361 inline bool operator!=(const int a, const LayoutUnit& b)
362 {
363     return LayoutUnit(a) != b;
364 }
365 
366 inline bool operator!=(const LayoutUnit& a, int b)
367 {
368     return a != LayoutUnit(b);
369 }
370 
371 inline bool operator==(const LayoutUnit& a, const LayoutUnit& b)
372 {
373     return a.rawValue() == b.rawValue();
374 }
375 
376 inline bool operator==(const LayoutUnit& a, int b)
377 {
378     return a == LayoutUnit(b);
379 }
380 
381 inline bool operator==(const int a, const LayoutUnit& b)
382 {
383     return LayoutUnit(a) == b;
384 }
385 
386 inline bool operator==(const LayoutUnit& a, float b)
387 {
388     return a.toFloat() == b;
389 }
390 
391 inline bool operator==(const float a, const LayoutUnit& b)
392 {
393     return a == b.toFloat();
394 }
395 
396 // For multiplication that's prone to overflow, this bounds it to LayoutUnit::max() and ::min()
boundedMultiply(const LayoutUnit & a,const LayoutUnit & b)397 inline LayoutUnit boundedMultiply(const LayoutUnit& a, const LayoutUnit& b)
398 {
399     int64_t result = static_cast<int64_t>(a.rawValue()) * static_cast<int64_t>(b.rawValue()) / kFixedPointDenominator;
400     int32_t high = static_cast<int32_t>(result >> 32);
401     int32_t low = static_cast<int32_t>(result);
402     uint32_t saturated = (static_cast<uint32_t>(a.rawValue() ^ b.rawValue()) >> 31) + std::numeric_limits<int>::max();
403     // If the higher 32 bits does not match the lower 32 with sign extension the operation overflowed.
404     if (high != low >> 31)
405         result = saturated;
406 
407     LayoutUnit returnVal;
408     returnVal.setRawValue(static_cast<int>(result));
409     return returnVal;
410 }
411 
412 inline LayoutUnit operator*(const LayoutUnit& a, const LayoutUnit& b)
413 {
414     return boundedMultiply(a, b);
415 }
416 
417 inline double operator*(const LayoutUnit& a, double b)
418 {
419     return a.toDouble() * b;
420 }
421 
422 inline float operator*(const LayoutUnit& a, float b)
423 {
424     return a.toFloat() * b;
425 }
426 
427 inline LayoutUnit operator*(const LayoutUnit& a, int b)
428 {
429     return a * LayoutUnit(b);
430 }
431 
432 inline LayoutUnit operator*(const LayoutUnit& a, unsigned short b)
433 {
434     return a * LayoutUnit(b);
435 }
436 
437 inline LayoutUnit operator*(const LayoutUnit& a, unsigned b)
438 {
439     return a * LayoutUnit(b);
440 }
441 
442 inline LayoutUnit operator*(const LayoutUnit& a, unsigned long b)
443 {
444     return a * LayoutUnit(b);
445 }
446 
447 inline LayoutUnit operator*(const LayoutUnit& a, unsigned long long b)
448 {
449     return a * LayoutUnit(b);
450 }
451 
452 inline LayoutUnit operator*(unsigned short a, const LayoutUnit& b)
453 {
454     return LayoutUnit(a) * b;
455 }
456 
457 inline LayoutUnit operator*(unsigned a, const LayoutUnit& b)
458 {
459     return LayoutUnit(a) * b;
460 }
461 
462 inline LayoutUnit operator*(unsigned long a, const LayoutUnit& b)
463 {
464     return LayoutUnit(a) * b;
465 }
466 
467 inline LayoutUnit operator*(unsigned long long a, const LayoutUnit& b)
468 {
469     return LayoutUnit(a) * b;
470 }
471 
472 inline LayoutUnit operator*(const int a, const LayoutUnit& b)
473 {
474     return LayoutUnit(a) * b;
475 }
476 
477 inline float operator*(const float a, const LayoutUnit& b)
478 {
479     return a * b.toFloat();
480 }
481 
482 inline double operator*(const double a, const LayoutUnit& b)
483 {
484     return a * b.toDouble();
485 }
486 
487 inline LayoutUnit operator/(const LayoutUnit& a, const LayoutUnit& b)
488 {
489     LayoutUnit returnVal;
490     long long rawVal = static_cast<long long>(kFixedPointDenominator) * a.rawValue() / b.rawValue();
491     returnVal.setRawValue(clampTo<int>(rawVal));
492     return returnVal;
493 }
494 
495 inline float operator/(const LayoutUnit& a, float b)
496 {
497     return a.toFloat() / b;
498 }
499 
500 inline double operator/(const LayoutUnit& a, double b)
501 {
502     return a.toDouble() / b;
503 }
504 
505 inline LayoutUnit operator/(const LayoutUnit& a, int b)
506 {
507     return a / LayoutUnit(b);
508 }
509 
510 inline LayoutUnit operator/(const LayoutUnit& a, unsigned short b)
511 {
512     return a / LayoutUnit(b);
513 }
514 
515 inline LayoutUnit operator/(const LayoutUnit& a, unsigned b)
516 {
517     return a / LayoutUnit(b);
518 }
519 
520 inline LayoutUnit operator/(const LayoutUnit& a, unsigned long b)
521 {
522     return a / LayoutUnit(b);
523 }
524 
525 inline LayoutUnit operator/(const LayoutUnit& a, unsigned long long b)
526 {
527     return a / LayoutUnit(b);
528 }
529 
530 inline float operator/(const float a, const LayoutUnit& b)
531 {
532     return a / b.toFloat();
533 }
534 
535 inline double operator/(const double a, const LayoutUnit& b)
536 {
537     return a / b.toDouble();
538 }
539 
540 inline LayoutUnit operator/(const int a, const LayoutUnit& b)
541 {
542     return LayoutUnit(a) / b;
543 }
544 
545 inline LayoutUnit operator/(unsigned short a, const LayoutUnit& b)
546 {
547     return LayoutUnit(a) / b;
548 }
549 
550 inline LayoutUnit operator/(unsigned a, const LayoutUnit& b)
551 {
552     return LayoutUnit(a) / b;
553 }
554 
555 inline LayoutUnit operator/(unsigned long a, const LayoutUnit& b)
556 {
557     return LayoutUnit(a) / b;
558 }
559 
560 inline LayoutUnit operator/(unsigned long long a, const LayoutUnit& b)
561 {
562     return LayoutUnit(a) / b;
563 }
564 
565 ALWAYS_INLINE LayoutUnit operator+(const LayoutUnit& a, const LayoutUnit& b)
566 {
567     LayoutUnit returnVal;
568     returnVal.setRawValue(saturatedAddition(a.rawValue(), b.rawValue()));
569     return returnVal;
570 }
571 
572 inline LayoutUnit operator+(const LayoutUnit& a, int b)
573 {
574     return a + LayoutUnit(b);
575 }
576 
577 inline float operator+(const LayoutUnit& a, float b)
578 {
579     return a.toFloat() + b;
580 }
581 
582 inline double operator+(const LayoutUnit& a, double b)
583 {
584     return a.toDouble() + b;
585 }
586 
587 inline LayoutUnit operator+(const int a, const LayoutUnit& b)
588 {
589     return LayoutUnit(a) + b;
590 }
591 
592 inline float operator+(const float a, const LayoutUnit& b)
593 {
594     return a + b.toFloat();
595 }
596 
597 inline double operator+(const double a, const LayoutUnit& b)
598 {
599     return a + b.toDouble();
600 }
601 
602 ALWAYS_INLINE LayoutUnit operator-(const LayoutUnit& a, const LayoutUnit& b)
603 {
604     LayoutUnit returnVal;
605     returnVal.setRawValue(saturatedSubtraction(a.rawValue(), b.rawValue()));
606     return returnVal;
607 }
608 
609 inline LayoutUnit operator-(const LayoutUnit& a, int b)
610 {
611     return a - LayoutUnit(b);
612 }
613 
614 inline LayoutUnit operator-(const LayoutUnit& a, unsigned b)
615 {
616     return a - LayoutUnit(b);
617 }
618 
619 inline float operator-(const LayoutUnit& a, float b)
620 {
621     return a.toFloat() - b;
622 }
623 
624 inline LayoutUnit operator-(const int a, const LayoutUnit& b)
625 {
626     return LayoutUnit(a) - b;
627 }
628 
629 inline float operator-(const float a, const LayoutUnit& b)
630 {
631     return a - b.toFloat();
632 }
633 
634 inline LayoutUnit operator-(const LayoutUnit& a)
635 {
636     LayoutUnit returnVal;
637     returnVal.setRawValue(-a.rawValue());
638     return returnVal;
639 }
640 
641 // For returning the remainder after a division with integer results.
intMod(const LayoutUnit & a,const LayoutUnit & b)642 inline LayoutUnit intMod(const LayoutUnit& a, const LayoutUnit& b)
643 {
644     // This calculates the modulo so that: a = static_cast<int>(a / b) * b + intMod(a, b).
645     LayoutUnit returnVal;
646     returnVal.setRawValue(a.rawValue() % b.rawValue());
647     return returnVal;
648 }
649 
650 inline LayoutUnit operator%(const LayoutUnit& a, const LayoutUnit& b)
651 {
652     // This calculates the modulo so that: a = (a / b) * b + a % b.
653     LayoutUnit returnVal;
654     long long rawVal = (static_cast<long long>(kFixedPointDenominator) * a.rawValue()) % b.rawValue();
655     returnVal.setRawValue(rawVal / kFixedPointDenominator);
656     return returnVal;
657 }
658 
659 inline LayoutUnit operator%(const LayoutUnit& a, int b)
660 {
661     return a % LayoutUnit(b);
662 }
663 
664 inline LayoutUnit operator%(int a, const LayoutUnit& b)
665 {
666     return LayoutUnit(a) % b;
667 }
668 
669 inline LayoutUnit& operator+=(LayoutUnit& a, const LayoutUnit& b)
670 {
671     a.setRawValue(saturatedAddition(a.rawValue(), b.rawValue()));
672     return a;
673 }
674 
675 inline LayoutUnit& operator+=(LayoutUnit& a, int b)
676 {
677     a = a + b;
678     return a;
679 }
680 
681 inline LayoutUnit& operator+=(LayoutUnit& a, float b)
682 {
683     a = a + b;
684     return a;
685 }
686 
687 inline float& operator+=(float& a, const LayoutUnit& b)
688 {
689     a = a + b;
690     return a;
691 }
692 
693 inline LayoutUnit& operator-=(LayoutUnit& a, int b)
694 {
695     a = a - b;
696     return a;
697 }
698 
699 inline LayoutUnit& operator-=(LayoutUnit& a, const LayoutUnit& b)
700 {
701     a.setRawValue(saturatedSubtraction(a.rawValue(), b.rawValue()));
702     return a;
703 }
704 
705 inline LayoutUnit& operator-=(LayoutUnit& a, float b)
706 {
707     a = a - b;
708     return a;
709 }
710 
711 inline float& operator-=(float& a, const LayoutUnit& b)
712 {
713     a = a - b;
714     return a;
715 }
716 
717 inline LayoutUnit& operator*=(LayoutUnit& a, const LayoutUnit& b)
718 {
719     a = a * b;
720     return a;
721 }
722 // operator*=(LayoutUnit& a, int b) is supported by the operator above plus LayoutUnit(int).
723 
724 inline LayoutUnit& operator*=(LayoutUnit& a, float b)
725 {
726     a = a * b;
727     return a;
728 }
729 
730 inline float& operator*=(float& a, const LayoutUnit& b)
731 {
732     a = a * b;
733     return a;
734 }
735 
736 inline LayoutUnit& operator/=(LayoutUnit& a, const LayoutUnit& b)
737 {
738     a = a / b;
739     return a;
740 }
741 // operator/=(LayoutUnit& a, int b) is supported by the operator above plus LayoutUnit(int).
742 
743 inline LayoutUnit& operator/=(LayoutUnit& a, float b)
744 {
745     a = a / b;
746     return a;
747 }
748 
749 inline float& operator/=(float& a, const LayoutUnit& b)
750 {
751     a = a / b;
752     return a;
753 }
754 
snapSizeToPixel(LayoutUnit size,LayoutUnit location)755 inline int snapSizeToPixel(LayoutUnit size, LayoutUnit location)
756 {
757     LayoutUnit fraction = location.fraction();
758     return (fraction + size).round() - fraction.round();
759 }
760 
roundToInt(LayoutUnit value)761 inline int roundToInt(LayoutUnit value)
762 {
763     return value.round();
764 }
765 
floorToInt(LayoutUnit value)766 inline int floorToInt(LayoutUnit value)
767 {
768     return value.floor();
769 }
770 
absoluteValue(const LayoutUnit & value)771 inline LayoutUnit absoluteValue(const LayoutUnit& value)
772 {
773     return value.abs();
774 }
775 
layoutMod(const LayoutUnit & numerator,const LayoutUnit & denominator)776 inline LayoutUnit layoutMod(const LayoutUnit& numerator, const LayoutUnit& denominator)
777 {
778     return numerator % denominator;
779 }
780 
isIntegerValue(const LayoutUnit value)781 inline bool isIntegerValue(const LayoutUnit value)
782 {
783     return value.toInt() == value;
784 }
785 
clampToLayoutUnit(LayoutUnit value,LayoutUnit min,LayoutUnit max)786 inline LayoutUnit clampToLayoutUnit(LayoutUnit value, LayoutUnit min, LayoutUnit max)
787 {
788     if (value >= max)
789         return max;
790     if (value <= min)
791         return min;
792     return value;
793 }
794 
795 } // namespace blink
796 
797 #endif // LayoutUnit_h
798