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