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