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