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