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