OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012, Google Inc. All rights reserved. | 2 * Copyright (c) 2012, Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 return floatValue; | 114 return floatValue; |
115 if (floatValue > 0) | 115 if (floatValue > 0) |
116 return nextafterf(floatValue, std::numeric_limits<float>::max()); | 116 return nextafterf(floatValue, std::numeric_limits<float>::max()); |
117 return nextafterf(floatValue, std::numeric_limits<float>::min()); | 117 return nextafterf(floatValue, std::numeric_limits<float>::min()); |
118 } | 118 } |
119 unsigned toUnsigned() const { | 119 unsigned toUnsigned() const { |
120 REPORT_OVERFLOW(m_value >= 0); | 120 REPORT_OVERFLOW(m_value >= 0); |
121 return toInt(); | 121 return toInt(); |
122 } | 122 } |
123 | 123 |
124 // Conversion to int or unsigned is lossy. 'explicit' on these operators won't
work because | 124 // Conversion to int or unsigned is lossy. 'explicit' on these operators won't |
125 // there are also other implicit conversion paths (e.g. operator bool then to
int which would | 125 // work because there are also other implicit conversion paths (e.g. operator |
126 // generate wrong result). Use toInt() and toUnsigned() instead. | 126 // bool then to int which would generate wrong result). Use toInt() and |
| 127 // toUnsigned() instead. |
127 operator int() const = delete; | 128 operator int() const = delete; |
128 operator unsigned() const = delete; | 129 operator unsigned() const = delete; |
129 | 130 |
130 operator double() const { return toDouble(); } | 131 operator double() const { return toDouble(); } |
131 operator float() const { return toFloat(); } | 132 operator float() const { return toFloat(); } |
132 operator bool() const { return m_value; } | 133 operator bool() const { return m_value; } |
133 | 134 |
134 LayoutUnit operator++(int) { | 135 LayoutUnit operator++(int) { |
135 m_value += kFixedPointDenominator; | 136 m_value += kFixedPointDenominator; |
136 return *this; | 137 return *this; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 | 172 |
172 LayoutUnit clampNegativeToZero() const { | 173 LayoutUnit clampNegativeToZero() const { |
173 return std::max(*this, LayoutUnit()); | 174 return std::max(*this, LayoutUnit()); |
174 } | 175 } |
175 | 176 |
176 LayoutUnit clampPositiveToZero() const { | 177 LayoutUnit clampPositiveToZero() const { |
177 return std::min(*this, LayoutUnit()); | 178 return std::min(*this, LayoutUnit()); |
178 } | 179 } |
179 | 180 |
180 LayoutUnit fraction() const { | 181 LayoutUnit fraction() const { |
181 // Add the fraction to the size (as opposed to the full location) to avoid o
verflows. | 182 // Add the fraction to the size (as opposed to the full location) to avoid |
182 // Compute fraction using the mod operator to preserve the sign of the value
as it may affect rounding. | 183 // overflows. Compute fraction using the mod operator to preserve the sign |
| 184 // of the value as it may affect rounding. |
183 LayoutUnit fraction; | 185 LayoutUnit fraction; |
184 fraction.setRawValue(rawValue() % kFixedPointDenominator); | 186 fraction.setRawValue(rawValue() % kFixedPointDenominator); |
185 return fraction; | 187 return fraction; |
186 } | 188 } |
187 | 189 |
188 bool mightBeSaturated() const { | 190 bool mightBeSaturated() const { |
189 return rawValue() == std::numeric_limits<int>::max() || | 191 return rawValue() == std::numeric_limits<int>::max() || |
190 rawValue() == std::numeric_limits<int>::min(); | 192 rawValue() == std::numeric_limits<int>::min(); |
191 } | 193 } |
192 | 194 |
193 static float epsilon() { return 1.0f / kFixedPointDenominator; } | 195 static float epsilon() { return 1.0f / kFixedPointDenominator; } |
194 | 196 |
195 static const LayoutUnit max() { | 197 static const LayoutUnit max() { |
196 LayoutUnit m; | 198 LayoutUnit m; |
197 m.m_value = std::numeric_limits<int>::max(); | 199 m.m_value = std::numeric_limits<int>::max(); |
198 return m; | 200 return m; |
199 } | 201 } |
200 static const LayoutUnit min() { | 202 static const LayoutUnit min() { |
201 LayoutUnit m; | 203 LayoutUnit m; |
202 m.m_value = std::numeric_limits<int>::min(); | 204 m.m_value = std::numeric_limits<int>::min(); |
203 return m; | 205 return m; |
204 } | 206 } |
205 | 207 |
206 // Versions of max/min that are slightly smaller/larger than max/min() to allo
w for roinding without overflowing. | 208 // Versions of max/min that are slightly smaller/larger than max/min() to |
| 209 // allow for roinding without overflowing. |
207 static const LayoutUnit nearlyMax() { | 210 static const LayoutUnit nearlyMax() { |
208 LayoutUnit m; | 211 LayoutUnit m; |
209 m.m_value = std::numeric_limits<int>::max() - kFixedPointDenominator / 2; | 212 m.m_value = std::numeric_limits<int>::max() - kFixedPointDenominator / 2; |
210 return m; | 213 return m; |
211 } | 214 } |
212 static const LayoutUnit nearlyMin() { | 215 static const LayoutUnit nearlyMin() { |
213 LayoutUnit m; | 216 LayoutUnit m; |
214 m.m_value = std::numeric_limits<int>::min() + kFixedPointDenominator / 2; | 217 m.m_value = std::numeric_limits<int>::min() + kFixedPointDenominator / 2; |
215 return m; | 218 return m; |
216 } | 219 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 } | 370 } |
368 | 371 |
369 inline bool operator==(const LayoutUnit& a, float b) { | 372 inline bool operator==(const LayoutUnit& a, float b) { |
370 return a.toFloat() == b; | 373 return a.toFloat() == b; |
371 } | 374 } |
372 | 375 |
373 inline bool operator==(const float a, const LayoutUnit& b) { | 376 inline bool operator==(const float a, const LayoutUnit& b) { |
374 return a == b.toFloat(); | 377 return a == b.toFloat(); |
375 } | 378 } |
376 | 379 |
377 // For multiplication that's prone to overflow, this bounds it to LayoutUnit::ma
x() and ::min() | 380 // For multiplication that's prone to overflow, this bounds it to |
| 381 // LayoutUnit::max() and ::min() |
378 inline LayoutUnit boundedMultiply(const LayoutUnit& a, const LayoutUnit& b) { | 382 inline LayoutUnit boundedMultiply(const LayoutUnit& a, const LayoutUnit& b) { |
379 int64_t result = static_cast<int64_t>(a.rawValue()) * | 383 int64_t result = static_cast<int64_t>(a.rawValue()) * |
380 static_cast<int64_t>(b.rawValue()) / kFixedPointDenominator; | 384 static_cast<int64_t>(b.rawValue()) / kFixedPointDenominator; |
381 int32_t high = static_cast<int32_t>(result >> 32); | 385 int32_t high = static_cast<int32_t>(result >> 32); |
382 int32_t low = static_cast<int32_t>(result); | 386 int32_t low = static_cast<int32_t>(result); |
383 uint32_t saturated = | 387 uint32_t saturated = |
384 (static_cast<uint32_t>(a.rawValue() ^ b.rawValue()) >> 31) + | 388 (static_cast<uint32_t>(a.rawValue() ^ b.rawValue()) >> 31) + |
385 std::numeric_limits<int>::max(); | 389 std::numeric_limits<int>::max(); |
386 // If the higher 32 bits does not match the lower 32 with sign extension the o
peration overflowed. | 390 // If the higher 32 bits does not match the lower 32 with sign extension the |
| 391 // operation overflowed. |
387 if (high != low >> 31) | 392 if (high != low >> 31) |
388 result = saturated; | 393 result = saturated; |
389 | 394 |
390 LayoutUnit returnVal; | 395 LayoutUnit returnVal; |
391 returnVal.setRawValue(static_cast<int>(result)); | 396 returnVal.setRawValue(static_cast<int>(result)); |
392 return returnVal; | 397 return returnVal; |
393 } | 398 } |
394 | 399 |
395 inline LayoutUnit operator*(const LayoutUnit& a, const LayoutUnit& b) { | 400 inline LayoutUnit operator*(const LayoutUnit& a, const LayoutUnit& b) { |
396 return boundedMultiply(a, b); | 401 return boundedMultiply(a, b); |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 } | 582 } |
578 | 583 |
579 inline LayoutUnit operator-(const LayoutUnit& a) { | 584 inline LayoutUnit operator-(const LayoutUnit& a) { |
580 LayoutUnit returnVal; | 585 LayoutUnit returnVal; |
581 returnVal.setRawValue(saturatedNegative(a.rawValue())); | 586 returnVal.setRawValue(saturatedNegative(a.rawValue())); |
582 return returnVal; | 587 return returnVal; |
583 } | 588 } |
584 | 589 |
585 // For returning the remainder after a division with integer results. | 590 // For returning the remainder after a division with integer results. |
586 inline LayoutUnit intMod(const LayoutUnit& a, const LayoutUnit& b) { | 591 inline LayoutUnit intMod(const LayoutUnit& a, const LayoutUnit& b) { |
587 // This calculates the modulo so that: a = static_cast<int>(a / b) * b + intMo
d(a, b). | 592 // This calculates the modulo so that: a = static_cast<int>(a / b) * b + |
| 593 // intMod(a, b). |
588 LayoutUnit returnVal; | 594 LayoutUnit returnVal; |
589 returnVal.setRawValue(a.rawValue() % b.rawValue()); | 595 returnVal.setRawValue(a.rawValue() % b.rawValue()); |
590 return returnVal; | 596 return returnVal; |
591 } | 597 } |
592 | 598 |
593 inline LayoutUnit operator%(const LayoutUnit& a, const LayoutUnit& b) { | 599 inline LayoutUnit operator%(const LayoutUnit& a, const LayoutUnit& b) { |
594 // This calculates the modulo so that: a = (a / b) * b + a % b. | 600 // This calculates the modulo so that: a = (a / b) * b + a % b. |
595 LayoutUnit returnVal; | 601 LayoutUnit returnVal; |
596 long long rawVal = | 602 long long rawVal = |
597 (static_cast<long long>(kFixedPointDenominator) * a.rawValue()) % | 603 (static_cast<long long>(kFixedPointDenominator) * a.rawValue()) % |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 return value; | 724 return value; |
719 } | 725 } |
720 | 726 |
721 inline std::ostream& operator<<(std::ostream& stream, const LayoutUnit& value) { | 727 inline std::ostream& operator<<(std::ostream& stream, const LayoutUnit& value) { |
722 return stream << value.toString(); | 728 return stream << value.toString(); |
723 } | 729 } |
724 | 730 |
725 } // namespace blink | 731 } // namespace blink |
726 | 732 |
727 #endif // LayoutUnit_h | 733 #endif // LayoutUnit_h |
OLD | NEW |