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