095aaa0f3f7460498e07b6e909b777dc2284464b
[WebKit-https.git] / Source / WebCore / platform / LayoutUnit.h
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 #pragma once
32
33 #include "ValueToString.h"
34 #include <limits.h>
35 #include <limits>
36 #include <math.h>
37 #include <stdlib.h>
38 #include <wtf/MathExtras.h>
39 #include <wtf/SaturatedArithmetic.h>
40
41 namespace WTF {
42 class TextStream;
43 }
44
45 namespace WebCore {
46
47 #ifdef NDEBUG
48
49 #define REPORT_OVERFLOW(doesOverflow) ((void)0)
50
51 #else
52
53 #define REPORT_OVERFLOW(doesOverflow) do \
54     if (!(doesOverflow)) { \
55         WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, "!(%s)", #doesOverflow); \
56     } \
57 while (0)
58
59 #endif
60
61 static const int kFixedPointDenominator = 64;
62 const int intMaxForLayoutUnit = INT_MAX / kFixedPointDenominator;
63 const int intMinForLayoutUnit = INT_MIN / kFixedPointDenominator;
64
65 class LayoutUnit {
66 public:
67     LayoutUnit() : m_value(0) { }
68     LayoutUnit(int value) { setValue(value); }
69     LayoutUnit(unsigned short value) { setValue(value); }
70     LayoutUnit(unsigned value) { setValue(value); }
71     LayoutUnit(unsigned long value)
72     {
73         m_value = clampTo<int>(value * kFixedPointDenominator);
74     }
75     LayoutUnit(unsigned long long value)
76     {
77         m_value = clampTo<int>(value * kFixedPointDenominator);
78     }
79     LayoutUnit(float value)
80     {
81         m_value = clampToInteger(value * kFixedPointDenominator);
82     }
83     LayoutUnit(double value)
84     {
85         m_value = clampToInteger(value * kFixedPointDenominator);
86     }
87
88     static LayoutUnit fromPixel(int value)
89     {
90         return LayoutUnit(value);
91     }
92
93     static LayoutUnit fromFloatCeil(float value)
94     {
95         LayoutUnit v;
96         v.m_value = clampToInteger(ceilf(value * kFixedPointDenominator));
97         return v;
98     }
99
100     static LayoutUnit fromFloatFloor(float value)
101     {
102         LayoutUnit v;
103         v.m_value = clampToInteger(floorf(value * kFixedPointDenominator));
104         return v;
105     }
106
107     static LayoutUnit fromFloatRound(float value)
108     {
109         if (value >= 0)
110             return clamp(value + epsilon() / 2.0f);
111         return clamp(value - epsilon() / 2.0f);
112     }
113
114     int toInt() const { return m_value / kFixedPointDenominator; }
115     float toFloat() const { return static_cast<float>(m_value) / kFixedPointDenominator; }
116     double toDouble() const { return static_cast<double>(m_value) / kFixedPointDenominator; }
117     unsigned toUnsigned() const { REPORT_OVERFLOW(m_value >= 0); return toInt(); }
118
119     operator int() const { return toInt(); }
120     operator float() const { return toFloat(); }
121     operator double() const { return toDouble(); }
122     explicit operator bool() const { return m_value; }
123
124     LayoutUnit& operator++()
125     {
126         m_value += kFixedPointDenominator;
127         return *this;
128     }
129
130     inline int rawValue() const { return m_value; }
131     inline void setRawValue(int value) { m_value = value; }
132     void setRawValue(long long value)
133     {
134         REPORT_OVERFLOW(value > std::numeric_limits<int>::min() && value < std::numeric_limits<int>::max());
135         m_value = static_cast<int>(value);
136     }
137
138     LayoutUnit abs() const
139     {
140         LayoutUnit returnValue;
141         returnValue.setRawValue(::abs(m_value));
142         return returnValue;
143     }
144     int ceil() const
145     {
146         if (UNLIKELY(m_value >= INT_MAX - kFixedPointDenominator + 1))
147             return intMaxForLayoutUnit;
148         if (m_value >= 0)
149             return (m_value + kFixedPointDenominator - 1) / kFixedPointDenominator;
150         return toInt();
151     }
152
153     int round() const
154     {
155         if (m_value > 0)
156             return saturatedAddition(rawValue(), kFixedPointDenominator / 2) / kFixedPointDenominator;
157         return saturatedSubtraction(rawValue(), (kFixedPointDenominator / 2) - 1) / kFixedPointDenominator;
158     }
159
160     int floor() const
161     {
162         if (UNLIKELY(m_value <= INT_MIN + kFixedPointDenominator - 1))
163             return intMinForLayoutUnit;
164         if (m_value >= 0)
165             return toInt();
166         return (m_value - kFixedPointDenominator + 1) / kFixedPointDenominator;
167     }
168
169     float ceilToFloat() const
170     {
171         float floatValue = toFloat();
172         if (static_cast<int>(floatValue * kFixedPointDenominator) == m_value)
173             return floatValue;
174         if (floatValue > 0)
175             return nextafterf(floatValue, std::numeric_limits<float>::max());
176         return nextafterf(floatValue, std::numeric_limits<float>::min());
177     }
178
179     LayoutUnit fraction() const
180     {   
181         // Add the fraction to the size (as opposed to the full location) to avoid overflows.
182         // Compute fraction using the mod operator to preserve the sign of the value as it may affect rounding.
183         LayoutUnit fraction;
184         fraction.setRawValue(rawValue() % kFixedPointDenominator);
185         return fraction;
186     }
187
188     bool mightBeSaturated() const
189     {
190         return rawValue() == std::numeric_limits<int>::max()
191             || rawValue() == std::numeric_limits<int>::min();
192     }
193
194     static float epsilon() { return 1.0f / kFixedPointDenominator; }
195
196     static const LayoutUnit max()
197     {
198         LayoutUnit m;
199         m.m_value = std::numeric_limits<int>::max();
200         return m;
201     }
202     static const LayoutUnit min()
203     {
204         LayoutUnit m;
205         m.m_value = std::numeric_limits<int>::min();
206         return m;
207     }
208
209     // Versions of max/min that are slightly smaller/larger than max/min() to allow for roinding without overflowing.
210     static const LayoutUnit nearlyMax()
211     {
212         LayoutUnit m;
213         m.m_value = std::numeric_limits<int>::max() - kFixedPointDenominator / 2;
214         return m;
215     }
216     static const LayoutUnit nearlyMin()
217     {
218         LayoutUnit m;
219         m.m_value = std::numeric_limits<int>::min() + kFixedPointDenominator / 2;
220         return m;
221     }
222     
223     static LayoutUnit clamp(double value)
224     {
225         return clampTo<LayoutUnit>(value, LayoutUnit::min(), LayoutUnit::max());
226     }
227
228 private:
229     static bool isInBounds(int value)
230     {
231         return ::abs(value) <= std::numeric_limits<int>::max() / kFixedPointDenominator;
232     }
233     static bool isInBounds(unsigned value)
234     {
235         return value <= static_cast<unsigned>(std::numeric_limits<int>::max()) / kFixedPointDenominator;
236     }
237     static bool isInBounds(double value)
238     {
239         return ::fabs(value) <= std::numeric_limits<int>::max() / kFixedPointDenominator;
240     }
241
242     inline void setValue(int value)
243     {
244         if (value > intMaxForLayoutUnit)
245             m_value = std::numeric_limits<int>::max();
246         else if (value < intMinForLayoutUnit)
247             m_value = std::numeric_limits<int>::min();
248         else
249             m_value = value * kFixedPointDenominator;
250     }
251     inline void setValue(unsigned value)
252     {
253         if (value >= static_cast<unsigned>(intMaxForLayoutUnit))
254             m_value = std::numeric_limits<int>::max();
255         else
256             m_value = value * kFixedPointDenominator;
257     }
258
259     int m_value;
260 };
261
262 inline bool operator<=(const LayoutUnit& a, const LayoutUnit& b)
263 {
264     return a.rawValue() <= b.rawValue();
265 }
266
267 inline bool operator<=(const LayoutUnit& a, float b)
268 {
269     return a.toFloat() <= b;
270 }
271
272 inline bool operator<=(const LayoutUnit& a, int b)
273 {
274     return a <= LayoutUnit(b);
275 }
276
277 inline bool operator<=(const float a, const LayoutUnit& b)
278 {
279     return a <= b.toFloat();
280 }
281
282 inline bool operator<=(const int a, const LayoutUnit& b)
283 {
284     return LayoutUnit(a) <= b;
285 }
286
287 inline bool operator>=(const LayoutUnit& a, const LayoutUnit& b)
288 {
289     return a.rawValue() >= b.rawValue();
290 }
291
292 inline bool operator>=(const LayoutUnit& a, int b)
293 {
294     return a >= LayoutUnit(b);
295 }
296
297 inline bool operator>=(const float a, const LayoutUnit& b)
298 {
299     return a >= b.toFloat();
300 }
301
302 inline bool operator>=(const LayoutUnit& a, float b)
303 {
304     return a.toFloat() >= b;
305 }
306
307 inline bool operator>=(const int a, const LayoutUnit& b)
308 {
309     return LayoutUnit(a) >= b;
310 }
311
312 inline bool operator<(const LayoutUnit& a, const LayoutUnit& b)
313 {
314     return a.rawValue() < b.rawValue();
315 }
316
317 inline bool operator<(const LayoutUnit& a, int b)
318 {
319     return a < LayoutUnit(b);
320 }
321
322 inline bool operator<(const LayoutUnit& a, float b)
323 {
324     return a.toFloat() < b;
325 }
326
327 inline bool operator<(const LayoutUnit& a, double b)
328 {
329     return a.toDouble() < b;
330 }
331
332 inline bool operator<(const int a, const LayoutUnit& b)
333 {
334     return LayoutUnit(a) < b;
335 }
336
337 inline bool operator<(const float a, const LayoutUnit& b)
338 {
339     return a < b.toFloat();
340 }
341
342 inline bool operator>(const LayoutUnit& a, const LayoutUnit& b)
343 {
344     return a.rawValue() > b.rawValue();
345 }
346
347 inline bool operator>(const LayoutUnit& a, double b)
348 {
349     return a.toDouble() > b;
350 }
351
352 inline bool operator>(const LayoutUnit& a, float b)
353 {
354     return a.toFloat() > b;
355 }
356
357 inline bool operator>(const LayoutUnit& a, int b)
358 {
359     return a > LayoutUnit(b);
360 }
361
362 inline bool operator>(const int a, const LayoutUnit& b)
363 {
364     return LayoutUnit(a) > b;
365 }
366
367 inline bool operator>(const float a, const LayoutUnit& b)
368 {
369     return a > b.toFloat();
370 }
371
372 inline bool operator>(const double a, const LayoutUnit& b)
373 {
374     return a > b.toDouble();
375 }
376
377 inline bool operator!=(const LayoutUnit& a, const LayoutUnit& b)
378 {
379     return a.rawValue() != b.rawValue();
380 }
381
382 inline bool operator!=(const LayoutUnit& a, float b)
383 {
384     return a != LayoutUnit(b);
385 }
386
387 inline bool operator!=(const int a, const LayoutUnit& b)
388 {
389     return LayoutUnit(a) != b;
390 }
391
392 inline bool operator!=(const LayoutUnit& a, int b)
393 {
394     return a != LayoutUnit(b);
395 }
396
397 inline bool operator==(const LayoutUnit& a, const LayoutUnit& b)
398 {
399     return a.rawValue() == b.rawValue();
400 }
401
402 inline bool operator==(const LayoutUnit& a, int b)
403 {
404     return a == LayoutUnit(b);
405 }
406
407 inline bool operator==(const int a, const LayoutUnit& b)
408 {
409     return LayoutUnit(a) == b;
410 }
411
412 inline bool operator==(const LayoutUnit& a, float b)
413 {
414     return a.toFloat() == b;
415 }
416
417 inline bool operator==(const float a, const LayoutUnit& b)
418 {
419     return a == b.toFloat();
420 }
421
422 // For multiplication that's prone to overflow, this bounds it to LayoutUnit::max() and ::min()
423 inline LayoutUnit boundedMultiply(const LayoutUnit& a, const LayoutUnit& b)
424 {
425     int64_t result = static_cast<int64_t>(a.rawValue()) * static_cast<int64_t>(b.rawValue()) / kFixedPointDenominator;
426     int32_t high = static_cast<int32_t>(result >> 32);
427     int32_t low = static_cast<int32_t>(result);
428     uint32_t saturated = (static_cast<uint32_t>(a.rawValue() ^ b.rawValue()) >> 31) + std::numeric_limits<int>::max();
429     // If the higher 32 bits does not match the lower 32 with sign extension the operation overflowed.
430     if (high != low >> 31)
431         result = saturated;
432
433     LayoutUnit returnVal;
434     returnVal.setRawValue(static_cast<int>(result));
435     return returnVal;
436 }
437
438 inline LayoutUnit operator*(const LayoutUnit& a, const LayoutUnit& b)
439 {
440     return boundedMultiply(a, b);
441 }
442
443 inline double operator*(const LayoutUnit& a, double b)
444 {
445     return a.toDouble() * b;
446 }
447
448 inline float operator*(const LayoutUnit& a, float b)
449 {
450     return a.toFloat() * b;
451 }
452
453 inline LayoutUnit operator*(const LayoutUnit& a, int b)
454 {
455     return a * LayoutUnit(b);
456 }
457
458 inline LayoutUnit operator*(const LayoutUnit& a, unsigned short b)
459 {
460     return a * LayoutUnit(b);
461 }
462
463 inline LayoutUnit operator*(const LayoutUnit& a, unsigned b)
464 {
465     return a * LayoutUnit(b);
466 }
467
468 inline LayoutUnit operator*(const LayoutUnit& a, unsigned long b)
469 {
470     return a * LayoutUnit(b);
471 }
472
473 inline LayoutUnit operator*(const LayoutUnit& a, unsigned long long b)
474 {
475     return a * LayoutUnit(b);
476 }
477
478 inline LayoutUnit operator*(unsigned short a, const LayoutUnit& b)
479 {
480     return LayoutUnit(a) * b;
481 }
482
483 inline LayoutUnit operator*(unsigned a, const LayoutUnit& b)
484 {
485     return LayoutUnit(a) * b;
486 }
487
488 inline LayoutUnit operator*(unsigned long a, const LayoutUnit& b)
489 {
490     return LayoutUnit(a) * b;
491 }
492
493 inline LayoutUnit operator*(unsigned long long a, const LayoutUnit& b)
494 {
495     return LayoutUnit(a) * b;
496 }
497
498 inline LayoutUnit operator*(const int a, const LayoutUnit& b)
499 {
500     return LayoutUnit(a) * b;
501 }
502
503 inline float operator*(const float a, const LayoutUnit& b)
504 {
505     return a * b.toFloat();
506 }
507
508 inline double operator*(const double a, const LayoutUnit& b)
509 {
510     return a * b.toDouble();
511 }
512
513 inline LayoutUnit operator/(const LayoutUnit& a, const LayoutUnit& b)
514 {
515     LayoutUnit returnVal;
516     long long rawVal = static_cast<long long>(kFixedPointDenominator) * a.rawValue() / b.rawValue();
517     returnVal.setRawValue(clampTo<int>(rawVal));
518     return returnVal;
519 }
520
521 inline float operator/(const LayoutUnit& a, float b)
522 {
523     return a.toFloat() / b;
524 }
525
526 inline double operator/(const LayoutUnit& a, double b)
527 {
528     return a.toDouble() / b;
529 }
530
531 inline LayoutUnit operator/(const LayoutUnit& a, int b)
532 {
533     return a / LayoutUnit(b);
534 }
535
536 inline LayoutUnit operator/(const LayoutUnit& a, unsigned short b)
537 {
538     return a / LayoutUnit(b);
539 }
540
541 inline LayoutUnit operator/(const LayoutUnit& a, unsigned b)
542 {
543     return a / LayoutUnit(b);
544 }
545
546 inline LayoutUnit operator/(const LayoutUnit& a, unsigned long b)
547 {
548     return a / LayoutUnit(b);
549 }
550
551 inline LayoutUnit operator/(const LayoutUnit& a, unsigned long long b)
552 {
553     return a / LayoutUnit(b);
554 }
555
556 inline float operator/(const float a, const LayoutUnit& b)
557 {
558     return a / b.toFloat();
559 }
560
561 inline double operator/(const double a, const LayoutUnit& b)
562 {
563     return a / b.toDouble();
564 }
565
566 inline LayoutUnit operator/(const int a, const LayoutUnit& b)
567 {
568     return LayoutUnit(a) / b;
569 }
570
571 inline LayoutUnit operator/(unsigned short a, const LayoutUnit& b)
572 {
573     return LayoutUnit(a) / b;
574 }
575
576 inline LayoutUnit operator/(unsigned a, const LayoutUnit& b)
577 {
578     return LayoutUnit(a) / b;
579 }
580
581 inline LayoutUnit operator/(unsigned long a, const LayoutUnit& b)
582 {
583     return LayoutUnit(a) / b;
584 }
585
586 inline LayoutUnit operator/(unsigned long long a, const LayoutUnit& b)
587 {
588     return LayoutUnit(a) / b;
589 }
590
591 inline LayoutUnit operator+(const LayoutUnit& a, const LayoutUnit& b)
592 {
593     LayoutUnit returnVal;
594     returnVal.setRawValue(saturatedAddition(a.rawValue(), b.rawValue()));
595     return returnVal;
596 }
597
598 inline LayoutUnit operator+(const LayoutUnit& a, int b)
599 {
600     return a + LayoutUnit(b);
601 }
602
603 inline float operator+(const LayoutUnit& a, float b)
604 {
605     return a.toFloat() + b;
606 }
607
608 inline double operator+(const LayoutUnit& a, double b)
609 {
610     return a.toDouble() + b;
611 }
612
613 inline LayoutUnit operator+(const int a, const LayoutUnit& b)
614 {
615     return LayoutUnit(a) + b;
616 }
617
618 inline float operator+(const float a, const LayoutUnit& b)
619 {
620     return a + b.toFloat();
621 }
622
623 inline double operator+(const double a, const LayoutUnit& b)
624 {
625     return a + b.toDouble();
626 }
627
628 inline LayoutUnit operator-(const LayoutUnit& a, const LayoutUnit& b)
629 {
630     LayoutUnit returnVal;
631     returnVal.setRawValue(saturatedSubtraction(a.rawValue(), b.rawValue()));
632     return returnVal;
633 }
634
635 inline LayoutUnit operator-(const LayoutUnit& a, int b)
636 {
637     return a - LayoutUnit(b);
638 }
639
640 inline LayoutUnit operator-(const LayoutUnit& a, unsigned b)
641 {
642     return a - LayoutUnit(b);
643 }
644
645 inline float operator-(const LayoutUnit& a, float b)
646 {
647     return a.toFloat() - b;
648 }
649
650 inline LayoutUnit operator-(const int a, const LayoutUnit& b)
651 {
652     return LayoutUnit(a) - b;
653 }
654
655 inline float operator-(const float a, const LayoutUnit& b)
656 {
657     return a - b.toFloat();
658 }
659
660 inline LayoutUnit operator-(const LayoutUnit& a)
661 {
662     LayoutUnit returnVal;
663     returnVal.setRawValue(-a.rawValue());
664     return returnVal;
665 }
666
667 // For returning the remainder after a division with integer results.
668 inline LayoutUnit intMod(const LayoutUnit& a, const LayoutUnit& b)
669 {
670     // This calculates the modulo so that: a = static_cast<int>(a / b) * b + intMod(a, b).
671     LayoutUnit returnVal;
672     returnVal.setRawValue(a.rawValue() % b.rawValue());
673     return returnVal;
674 }
675
676 inline LayoutUnit operator%(const LayoutUnit& a, const LayoutUnit& b)
677 {
678     // This calculates the modulo so that: a = (a / b) * b + a % b.
679     LayoutUnit returnVal;
680     long long rawVal = (static_cast<long long>(kFixedPointDenominator) * a.rawValue()) % b.rawValue();
681     returnVal.setRawValue(rawVal / kFixedPointDenominator);
682     return returnVal;
683 }
684
685 inline LayoutUnit operator%(const LayoutUnit& a, int b)
686 {
687     return a % LayoutUnit(b);
688 }
689
690 inline LayoutUnit operator%(int a, const LayoutUnit& b)
691 {
692     return LayoutUnit(a) % b;
693 }
694
695 inline LayoutUnit& operator+=(LayoutUnit& a, const LayoutUnit& b)
696 {
697     a.setRawValue(saturatedAddition(a.rawValue(), b.rawValue()));
698     return a;
699 }
700
701 inline LayoutUnit& operator+=(LayoutUnit& a, int b)
702 {
703     a = a + b;
704     return a;
705 }
706
707 inline LayoutUnit& operator+=(LayoutUnit& a, float b)
708 {
709     a = a + b;
710     return a;
711 }
712
713 inline float& operator+=(float& a, const LayoutUnit& b)
714 {
715     a = a + b;
716     return a;
717 }
718
719 inline LayoutUnit& operator-=(LayoutUnit& a, int b)
720 {
721     a = a - b;
722     return a;
723 }
724
725 inline LayoutUnit& operator-=(LayoutUnit& a, const LayoutUnit& b)
726 {
727     a.setRawValue(saturatedSubtraction(a.rawValue(), b.rawValue()));
728     return a;
729 }
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
762 inline LayoutUnit& operator/=(LayoutUnit& a, const LayoutUnit& b)
763 {
764     a = a / b;
765     return a;
766 }
767 // operator/=(LayoutUnit& a, int b) is supported by the operator above plus LayoutUnit(int).
768
769 inline LayoutUnit& operator/=(LayoutUnit& a, float b)
770 {
771     a = a / b;
772     return a;
773 }
774
775 inline float& operator/=(float& a, const LayoutUnit& b)
776 {
777     a = a / b;
778     return a;
779 }
780
781 WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const LayoutUnit&);
782
783 inline int roundToInt(LayoutUnit value)
784 {
785     return value.round();
786 }
787
788 inline int floorToInt(LayoutUnit value)
789 {
790     return value.floor();
791 }
792
793 inline float roundToDevicePixel(LayoutUnit value, float pixelSnappingFactor, bool needsDirectionalRounding = false)
794 {
795     double valueToRound = value.toDouble();
796     if (needsDirectionalRounding)
797         valueToRound -= LayoutUnit::epsilon() / (2 * kFixedPointDenominator);
798
799     if (valueToRound >= 0)
800         return round(valueToRound * pixelSnappingFactor) / pixelSnappingFactor;
801
802     // This adjusts directional rounding on negative halfway values. It produces the same direction for both negative and positive values.
803     // Instead of rounding negative halfway cases away from zero, we translate them to positive values before rounding.
804     // It helps snapping relative negative coordinates to the same position as if they were positive absolute coordinates.
805     unsigned translateOrigin = -value.rawValue();
806     return (round((valueToRound + translateOrigin) * pixelSnappingFactor) / pixelSnappingFactor) - translateOrigin;
807 }
808
809 inline float floorToDevicePixel(LayoutUnit value, float pixelSnappingFactor)
810 {
811     return floorf((value.rawValue() * pixelSnappingFactor) / kFixedPointDenominator) / pixelSnappingFactor;
812 }
813
814 inline float ceilToDevicePixel(LayoutUnit value, float pixelSnappingFactor)
815 {
816     return ceilf((value.rawValue() * pixelSnappingFactor) / kFixedPointDenominator) / pixelSnappingFactor;
817 }
818
819 inline LayoutUnit absoluteValue(const LayoutUnit& value)
820 {
821     return value.abs();
822 }
823
824 inline bool isIntegerValue(const LayoutUnit value)
825 {
826     return value.toInt() == value;
827 }
828
829 #ifndef NDEBUG
830 // This structure is used by PODIntervalTree for debugging.
831 template <>
832 struct ValueToString<LayoutUnit> {
833     static String string(const LayoutUnit value) { return String::number(value.toFloat()); }
834 };
835 #endif
836
837 } // namespace WebCore