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 blink {
     42 
     43 #if !ERROR_DISABLED
     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<int>(value * kFixedPointDenominator); }
     72     LayoutUnit(double value) { m_value = clampTo<int>(value * kFixedPointDenominator); }
     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     ALWAYS_INLINE void setValue(int value)
    224     {
    225         m_value = saturatedSet(value, kLayoutUnitFractionalBits);
    226     }
    227 
    228     inline void setValue(unsigned value)
    229     {
    230         m_value = saturatedSet(value, kLayoutUnitFractionalBits);
    231     }
    232 
    233     int m_value;
    234 };
    235 
    236 inline bool operator<=(const LayoutUnit& a, const LayoutUnit& b)
    237 {
    238     return a.rawValue() <= b.rawValue();
    239 }
    240 
    241 inline bool operator<=(const LayoutUnit& a, float b)
    242 {
    243     return a.toFloat() <= b;
    244 }
    245 
    246 inline bool operator<=(const LayoutUnit& a, int b)
    247 {
    248     return a <= LayoutUnit(b);
    249 }
    250 
    251 inline bool operator<=(const float a, const LayoutUnit& b)
    252 {
    253     return a <= b.toFloat();
    254 }
    255 
    256 inline bool operator<=(const int a, const LayoutUnit& b)
    257 {
    258     return LayoutUnit(a) <= b;
    259 }
    260 
    261 inline bool operator>=(const LayoutUnit& a, const LayoutUnit& b)
    262 {
    263     return a.rawValue() >= b.rawValue();
    264 }
    265 
    266 inline bool operator>=(const LayoutUnit& a, int b)
    267 {
    268     return a >= LayoutUnit(b);
    269 }
    270 
    271 inline bool operator>=(const float a, const LayoutUnit& b)
    272 {
    273     return a >= b.toFloat();
    274 }
    275 
    276 inline bool operator>=(const LayoutUnit& a, float b)
    277 {
    278     return a.toFloat() >= b;
    279 }
    280 
    281 inline bool operator>=(const int a, const LayoutUnit& b)
    282 {
    283     return LayoutUnit(a) >= b;
    284 }
    285 
    286 inline bool operator<(const LayoutUnit& a, const LayoutUnit& b)
    287 {
    288     return a.rawValue() < b.rawValue();
    289 }
    290 
    291 inline bool operator<(const LayoutUnit& a, int b)
    292 {
    293     return a < LayoutUnit(b);
    294 }
    295 
    296 inline bool operator<(const LayoutUnit& a, float b)
    297 {
    298     return a.toFloat() < b;
    299 }
    300 
    301 inline bool operator<(const LayoutUnit& a, double b)
    302 {
    303     return a.toDouble() < b;
    304 }
    305 
    306 inline bool operator<(const int a, const LayoutUnit& b)
    307 {
    308     return LayoutUnit(a) < b;
    309 }
    310 
    311 inline bool operator<(const float a, const LayoutUnit& b)
    312 {
    313     return a < b.toFloat();
    314 }
    315 
    316 inline bool operator>(const LayoutUnit& a, const LayoutUnit& b)
    317 {
    318     return a.rawValue() > b.rawValue();
    319 }
    320 
    321 inline bool operator>(const LayoutUnit& a, double b)
    322 {
    323     return a.toDouble() > b;
    324 }
    325 
    326 inline bool operator>(const LayoutUnit& a, float b)
    327 {
    328     return a.toFloat() > b;
    329 }
    330 
    331 inline bool operator>(const LayoutUnit& a, int b)
    332 {
    333     return a > LayoutUnit(b);
    334 }
    335 
    336 inline bool operator>(const int a, const LayoutUnit& b)
    337 {
    338     return LayoutUnit(a) > b;
    339 }
    340 
    341 inline bool operator>(const float a, const LayoutUnit& b)
    342 {
    343     return a > b.toFloat();
    344 }
    345 
    346 inline bool operator>(const double a, const LayoutUnit& b)
    347 {
    348     return a > b.toDouble();
    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 != LayoutUnit(b);
    359 }
    360 
    361 inline bool operator!=(const int a, const LayoutUnit& b)
    362 {
    363     return LayoutUnit(a) != b;
    364 }
    365 
    366 inline bool operator!=(const LayoutUnit& a, int b)
    367 {
    368     return a != LayoutUnit(b);
    369 }
    370 
    371 inline bool operator==(const LayoutUnit& a, const LayoutUnit& b)
    372 {
    373     return a.rawValue() == b.rawValue();
    374 }
    375 
    376 inline bool operator==(const LayoutUnit& a, int b)
    377 {
    378     return a == LayoutUnit(b);
    379 }
    380 
    381 inline bool operator==(const int a, const LayoutUnit& b)
    382 {
    383     return LayoutUnit(a) == b;
    384 }
    385 
    386 inline bool operator==(const LayoutUnit& a, float b)
    387 {
    388     return a.toFloat() == b;
    389 }
    390 
    391 inline bool operator==(const float a, const LayoutUnit& b)
    392 {
    393     return a == b.toFloat();
    394 }
    395 
    396 // For multiplication that's prone to overflow, this bounds it to LayoutUnit::max() and ::min()
    397 inline LayoutUnit boundedMultiply(const LayoutUnit& a, const LayoutUnit& b)
    398 {
    399     int64_t result = static_cast<int64_t>(a.rawValue()) * static_cast<int64_t>(b.rawValue()) / kFixedPointDenominator;
    400     int32_t high = static_cast<int32_t>(result >> 32);
    401     int32_t low = static_cast<int32_t>(result);
    402     uint32_t saturated = (static_cast<uint32_t>(a.rawValue() ^ b.rawValue()) >> 31) + std::numeric_limits<int>::max();
    403     // If the higher 32 bits does not match the lower 32 with sign extension the operation overflowed.
    404     if (high != low >> 31)
    405         result = saturated;
    406 
    407     LayoutUnit returnVal;
    408     returnVal.setRawValue(static_cast<int>(result));
    409     return returnVal;
    410 }
    411 
    412 inline LayoutUnit operator*(const LayoutUnit& a, const LayoutUnit& b)
    413 {
    414     return boundedMultiply(a, b);
    415 }
    416 
    417 inline double operator*(const LayoutUnit& a, double b)
    418 {
    419     return a.toDouble() * b;
    420 }
    421 
    422 inline float operator*(const LayoutUnit& a, float b)
    423 {
    424     return a.toFloat() * b;
    425 }
    426 
    427 inline LayoutUnit operator*(const LayoutUnit& a, int b)
    428 {
    429     return a * LayoutUnit(b);
    430 }
    431 
    432 inline LayoutUnit operator*(const LayoutUnit& a, unsigned short b)
    433 {
    434     return a * LayoutUnit(b);
    435 }
    436 
    437 inline LayoutUnit operator*(const LayoutUnit& a, unsigned b)
    438 {
    439     return a * LayoutUnit(b);
    440 }
    441 
    442 inline LayoutUnit operator*(const LayoutUnit& a, unsigned long b)
    443 {
    444     return a * LayoutUnit(b);
    445 }
    446 
    447 inline LayoutUnit operator*(const LayoutUnit& a, unsigned long long b)
    448 {
    449     return a * LayoutUnit(b);
    450 }
    451 
    452 inline LayoutUnit operator*(unsigned short a, const LayoutUnit& b)
    453 {
    454     return LayoutUnit(a) * b;
    455 }
    456 
    457 inline LayoutUnit operator*(unsigned a, const LayoutUnit& b)
    458 {
    459     return LayoutUnit(a) * b;
    460 }
    461 
    462 inline LayoutUnit operator*(unsigned long a, const LayoutUnit& b)
    463 {
    464     return LayoutUnit(a) * b;
    465 }
    466 
    467 inline LayoutUnit operator*(unsigned long long a, const LayoutUnit& b)
    468 {
    469     return LayoutUnit(a) * b;
    470 }
    471 
    472 inline LayoutUnit operator*(const int a, const LayoutUnit& b)
    473 {
    474     return LayoutUnit(a) * b;
    475 }
    476 
    477 inline float operator*(const float a, const LayoutUnit& b)
    478 {
    479     return a * b.toFloat();
    480 }
    481 
    482 inline double operator*(const double a, const LayoutUnit& b)
    483 {
    484     return a * b.toDouble();
    485 }
    486 
    487 inline LayoutUnit operator/(const LayoutUnit& a, const LayoutUnit& b)
    488 {
    489     LayoutUnit returnVal;
    490     long long rawVal = static_cast<long long>(kFixedPointDenominator) * a.rawValue() / b.rawValue();
    491     returnVal.setRawValue(clampTo<int>(rawVal));
    492     return returnVal;
    493 }
    494 
    495 inline float operator/(const LayoutUnit& a, float b)
    496 {
    497     return a.toFloat() / b;
    498 }
    499 
    500 inline double operator/(const LayoutUnit& a, double b)
    501 {
    502     return a.toDouble() / b;
    503 }
    504 
    505 inline LayoutUnit operator/(const LayoutUnit& a, int b)
    506 {
    507     return a / LayoutUnit(b);
    508 }
    509 
    510 inline LayoutUnit operator/(const LayoutUnit& a, unsigned short b)
    511 {
    512     return a / LayoutUnit(b);
    513 }
    514 
    515 inline LayoutUnit operator/(const LayoutUnit& a, unsigned b)
    516 {
    517     return a / LayoutUnit(b);
    518 }
    519 
    520 inline LayoutUnit operator/(const LayoutUnit& a, unsigned long b)
    521 {
    522     return a / LayoutUnit(b);
    523 }
    524 
    525 inline LayoutUnit operator/(const LayoutUnit& a, unsigned long long b)
    526 {
    527     return a / LayoutUnit(b);
    528 }
    529 
    530 inline float operator/(const float a, const LayoutUnit& b)
    531 {
    532     return a / b.toFloat();
    533 }
    534 
    535 inline double operator/(const double a, const LayoutUnit& b)
    536 {
    537     return a / b.toDouble();
    538 }
    539 
    540 inline LayoutUnit operator/(const int a, const LayoutUnit& b)
    541 {
    542     return LayoutUnit(a) / b;
    543 }
    544 
    545 inline LayoutUnit operator/(unsigned short a, const LayoutUnit& b)
    546 {
    547     return LayoutUnit(a) / b;
    548 }
    549 
    550 inline LayoutUnit operator/(unsigned a, const LayoutUnit& b)
    551 {
    552     return LayoutUnit(a) / b;
    553 }
    554 
    555 inline LayoutUnit operator/(unsigned long a, const LayoutUnit& b)
    556 {
    557     return LayoutUnit(a) / b;
    558 }
    559 
    560 inline LayoutUnit operator/(unsigned long long a, const LayoutUnit& b)
    561 {
    562     return LayoutUnit(a) / b;
    563 }
    564 
    565 ALWAYS_INLINE LayoutUnit operator+(const LayoutUnit& a, const LayoutUnit& b)
    566 {
    567     LayoutUnit returnVal;
    568     returnVal.setRawValue(saturatedAddition(a.rawValue(), b.rawValue()));
    569     return returnVal;
    570 }
    571 
    572 inline LayoutUnit operator+(const LayoutUnit& a, int b)
    573 {
    574     return a + LayoutUnit(b);
    575 }
    576 
    577 inline float operator+(const LayoutUnit& a, float b)
    578 {
    579     return a.toFloat() + b;
    580 }
    581 
    582 inline double operator+(const LayoutUnit& a, double b)
    583 {
    584     return a.toDouble() + b;
    585 }
    586 
    587 inline LayoutUnit operator+(const int a, const LayoutUnit& b)
    588 {
    589     return LayoutUnit(a) + b;
    590 }
    591 
    592 inline float operator+(const float a, const LayoutUnit& b)
    593 {
    594     return a + b.toFloat();
    595 }
    596 
    597 inline double operator+(const double a, const LayoutUnit& b)
    598 {
    599     return a + b.toDouble();
    600 }
    601 
    602 ALWAYS_INLINE LayoutUnit operator-(const LayoutUnit& a, const LayoutUnit& b)
    603 {
    604     LayoutUnit returnVal;
    605     returnVal.setRawValue(saturatedSubtraction(a.rawValue(), b.rawValue()));
    606     return returnVal;
    607 }
    608 
    609 inline LayoutUnit operator-(const LayoutUnit& a, int b)
    610 {
    611     return a - LayoutUnit(b);
    612 }
    613 
    614 inline LayoutUnit operator-(const LayoutUnit& a, unsigned b)
    615 {
    616     return a - LayoutUnit(b);
    617 }
    618 
    619 inline float operator-(const LayoutUnit& a, float b)
    620 {
    621     return a.toFloat() - b;
    622 }
    623 
    624 inline LayoutUnit operator-(const int a, const LayoutUnit& b)
    625 {
    626     return LayoutUnit(a) - b;
    627 }
    628 
    629 inline float operator-(const float a, const LayoutUnit& b)
    630 {
    631     return a - b.toFloat();
    632 }
    633 
    634 inline LayoutUnit operator-(const LayoutUnit& a)
    635 {
    636     LayoutUnit returnVal;
    637     returnVal.setRawValue(-a.rawValue());
    638     return returnVal;
    639 }
    640 
    641 // For returning the remainder after a division with integer results.
    642 inline LayoutUnit intMod(const LayoutUnit& a, const LayoutUnit& b)
    643 {
    644     // This calculates the modulo so that: a = static_cast<int>(a / b) * b + intMod(a, b).
    645     LayoutUnit returnVal;
    646     returnVal.setRawValue(a.rawValue() % b.rawValue());
    647     return returnVal;
    648 }
    649 
    650 inline LayoutUnit operator%(const LayoutUnit& a, const LayoutUnit& b)
    651 {
    652     // This calculates the modulo so that: a = (a / b) * b + a % b.
    653     LayoutUnit returnVal;
    654     long long rawVal = (static_cast<long long>(kFixedPointDenominator) * a.rawValue()) % b.rawValue();
    655     returnVal.setRawValue(rawVal / kFixedPointDenominator);
    656     return returnVal;
    657 }
    658 
    659 inline LayoutUnit operator%(const LayoutUnit& a, int b)
    660 {
    661     return a % LayoutUnit(b);
    662 }
    663 
    664 inline LayoutUnit operator%(int a, const LayoutUnit& b)
    665 {
    666     return LayoutUnit(a) % b;
    667 }
    668 
    669 inline LayoutUnit& operator+=(LayoutUnit& a, const LayoutUnit& b)
    670 {
    671     a.setRawValue(saturatedAddition(a.rawValue(), b.rawValue()));
    672     return a;
    673 }
    674 
    675 inline LayoutUnit& operator+=(LayoutUnit& a, int b)
    676 {
    677     a = a + b;
    678     return a;
    679 }
    680 
    681 inline LayoutUnit& operator+=(LayoutUnit& a, float b)
    682 {
    683     a = a + b;
    684     return a;
    685 }
    686 
    687 inline float& operator+=(float& a, const LayoutUnit& b)
    688 {
    689     a = a + b;
    690     return a;
    691 }
    692 
    693 inline LayoutUnit& operator-=(LayoutUnit& a, int b)
    694 {
    695     a = a - b;
    696     return a;
    697 }
    698 
    699 inline LayoutUnit& operator-=(LayoutUnit& a, const LayoutUnit& b)
    700 {
    701     a.setRawValue(saturatedSubtraction(a.rawValue(), b.rawValue()));
    702     return a;
    703 }
    704 
    705 inline LayoutUnit& operator-=(LayoutUnit& a, float b)
    706 {
    707     a = a - b;
    708     return a;
    709 }
    710 
    711 inline float& operator-=(float& a, const LayoutUnit& b)
    712 {
    713     a = a - b;
    714     return a;
    715 }
    716 
    717 inline LayoutUnit& operator*=(LayoutUnit& a, const LayoutUnit& b)
    718 {
    719     a = a * b;
    720     return a;
    721 }
    722 // operator*=(LayoutUnit& a, int b) is supported by the operator above plus LayoutUnit(int).
    723 
    724 inline LayoutUnit& operator*=(LayoutUnit& a, float b)
    725 {
    726     a = a * b;
    727     return a;
    728 }
    729 
    730 inline float& operator*=(float& a, const LayoutUnit& b)
    731 {
    732     a = a * b;
    733     return a;
    734 }
    735 
    736 inline LayoutUnit& operator/=(LayoutUnit& a, const LayoutUnit& b)
    737 {
    738     a = a / b;
    739     return a;
    740 }
    741 // operator/=(LayoutUnit& a, int b) is supported by the operator above plus LayoutUnit(int).
    742 
    743 inline LayoutUnit& operator/=(LayoutUnit& a, float b)
    744 {
    745     a = a / b;
    746     return a;
    747 }
    748 
    749 inline float& operator/=(float& a, const LayoutUnit& b)
    750 {
    751     a = a / b;
    752     return a;
    753 }
    754 
    755 inline int snapSizeToPixel(LayoutUnit size, LayoutUnit location)
    756 {
    757     LayoutUnit fraction = location.fraction();
    758     return (fraction + size).round() - fraction.round();
    759 }
    760 
    761 inline int roundToInt(LayoutUnit value)
    762 {
    763     return value.round();
    764 }
    765 
    766 inline int floorToInt(LayoutUnit value)
    767 {
    768     return value.floor();
    769 }
    770 
    771 inline LayoutUnit absoluteValue(const LayoutUnit& value)
    772 {
    773     return value.abs();
    774 }
    775 
    776 inline LayoutUnit layoutMod(const LayoutUnit& numerator, const LayoutUnit& denominator)
    777 {
    778     return numerator % denominator;
    779 }
    780 
    781 inline bool isIntegerValue(const LayoutUnit value)
    782 {
    783     return value.toInt() == value;
    784 }
    785 
    786 inline LayoutUnit clampToLayoutUnit(LayoutUnit value, LayoutUnit min, LayoutUnit max)
    787 {
    788     if (value >= max)
    789         return max;
    790     if (value <= min)
    791         return min;
    792     return value;
    793 }
    794 
    795 } // namespace blink
    796 
    797 #endif // LayoutUnit_h
    798