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