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