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