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