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