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