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#pragma once
32
33#include <limits.h>
34#include <limits>
35#include <math.h>
36#include <stdlib.h>
37#include <wtf/MathExtras.h>
38#include <wtf/SaturatedArithmetic.h>
39#include <wtf/text/ValueToString.h>
40
41namespace WTF {
42class TextStream;
43}
44
45namespace WebCore {
46
47#ifdef NDEBUG
48
49#define REPORT_OVERFLOW(doesOverflow) ((void)0)
50
51#else
52
53#define REPORT_OVERFLOW(doesOverflow) do \
54 if (!(doesOverflow)) { \
55 WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, "!(%s)", #doesOverflow); \
56 } \
57while (0)
58
59#endif
60
61static const int kFixedPointDenominator = 64;
62const int intMaxForLayoutUnit = INT_MAX / kFixedPointDenominator;
63const int intMinForLayoutUnit = INT_MIN / kFixedPointDenominator;
64
65class LayoutUnit {
66public:
67 LayoutUnit() : m_value(0) { }
68 LayoutUnit(int value) { setValue(value); }
69 LayoutUnit(unsigned short value) { setValue(value); }
70 LayoutUnit(unsigned value) { setValue(value); }
71 LayoutUnit(unsigned long value)
72 {
73 m_value = clampTo<int>(value * kFixedPointDenominator);
74 }
75 LayoutUnit(unsigned long long value)
76 {
77 m_value = clampTo<int>(value * kFixedPointDenominator);
78 }
79 LayoutUnit(float value)
80 {
81 m_value = clampToInteger(value * kFixedPointDenominator);
82 }
83 LayoutUnit(double value)
84 {
85 m_value = clampToInteger(value * kFixedPointDenominator);
86 }
87
88 static LayoutUnit fromFloatCeil(float value)
89 {
90 LayoutUnit v;
91 v.m_value = clampToInteger(ceilf(value * kFixedPointDenominator));
92 return v;
93 }
94
95 static LayoutUnit fromFloatFloor(float value)
96 {
97 LayoutUnit v;
98 v.m_value = clampToInteger(floorf(value * kFixedPointDenominator));
99 return v;
100 }
101
102 static LayoutUnit fromFloatRound(float value)
103 {
104 if (value >= 0)
105 return clamp(value + epsilon() / 2.0f);
106 return clamp(value - epsilon() / 2.0f);
107 }
108
109 int toInt() const { return m_value / kFixedPointDenominator; }
110 float toFloat() const { return static_cast<float>(m_value) / kFixedPointDenominator; }
111 double toDouble() const { return static_cast<double>(m_value) / kFixedPointDenominator; }
112 unsigned toUnsigned() const { REPORT_OVERFLOW(m_value >= 0); return toInt(); }
113
114 operator int() const { return toInt(); }
115 operator float() const { return toFloat(); }
116 operator double() const { return toDouble(); }
117 explicit operator bool() const { return m_value; }
118
119 LayoutUnit& operator++()
120 {
121 m_value += kFixedPointDenominator;
122 return *this;
123 }
124
125 inline int rawValue() const { return m_value; }
126 inline void setRawValue(int value) { m_value = value; }
127 void setRawValue(long long value)
128 {
129 REPORT_OVERFLOW(value > std::numeric_limits<int>::min() && value < std::numeric_limits<int>::max());
130 m_value = static_cast<int>(value);
131 }
132
133 LayoutUnit abs() const
134 {
135 LayoutUnit returnValue;
136 returnValue.setRawValue(::abs(m_value));
137 return returnValue;
138 }
139 int ceil() const
140 {
141 if (UNLIKELY(m_value >= INT_MAX - kFixedPointDenominator + 1))
142 return intMaxForLayoutUnit;
143 if (m_value >= 0)
144 return (m_value + kFixedPointDenominator - 1) / kFixedPointDenominator;
145 return toInt();
146 }
147
148 int round() const
149 {
150 if (m_value > 0)
151 return saturatedAddition(rawValue(), kFixedPointDenominator / 2) / kFixedPointDenominator;
152 return saturatedSubtraction(rawValue(), (kFixedPointDenominator / 2) - 1) / kFixedPointDenominator;
153 }
154
155 int floor() const
156 {
157 if (UNLIKELY(m_value <= INT_MIN + kFixedPointDenominator - 1))
158 return intMinForLayoutUnit;
159 if (m_value >= 0)
160 return toInt();
161 return (m_value - kFixedPointDenominator + 1) / kFixedPointDenominator;
162 }
163
164 float ceilToFloat() const
165 {
166 float floatValue = toFloat();
167 if (static_cast<int>(floatValue * kFixedPointDenominator) == m_value)
168 return floatValue;
169 if (floatValue > 0)
170 return nextafterf(floatValue, std::numeric_limits<float>::max());
171 return nextafterf(floatValue, std::numeric_limits<float>::min());
172 }
173
174 LayoutUnit fraction() const
175 {
176 // Add the fraction to the size (as opposed to the full location) to avoid overflows.
177 // Compute fraction using the mod operator to preserve the sign of the value as it may affect rounding.
178 LayoutUnit fraction;
179 fraction.setRawValue(rawValue() % kFixedPointDenominator);
180 return fraction;
181 }
182
183 bool mightBeSaturated() const
184 {
185 return rawValue() == std::numeric_limits<int>::max()
186 || rawValue() == std::numeric_limits<int>::min();
187 }
188
189 static float epsilon() { return 1.0f / kFixedPointDenominator; }
190
191 static const LayoutUnit max()
192 {
193 LayoutUnit m;
194 m.m_value = std::numeric_limits<int>::max();
195 return m;
196 }
197 static const LayoutUnit min()
198 {
199 LayoutUnit m;
200 m.m_value = std::numeric_limits<int>::min();
201 return m;
202 }
203
204 // Versions of max/min that are slightly smaller/larger than max/min() to allow for roinding without overflowing.
205 static const LayoutUnit nearlyMax()
206 {
207 LayoutUnit m;
208 m.m_value = std::numeric_limits<int>::max() - kFixedPointDenominator / 2;
209 return m;
210 }
211 static const LayoutUnit nearlyMin()
212 {
213 LayoutUnit m;
214 m.m_value = std::numeric_limits<int>::min() + kFixedPointDenominator / 2;
215 return m;
216 }
217
218 static LayoutUnit clamp(double value)
219 {
220 return clampTo<LayoutUnit>(value, LayoutUnit::min(), LayoutUnit::max());
221 }
222
223private:
224 static bool isInBounds(int value)
225 {
226 return ::abs(value) <= std::numeric_limits<int>::max() / kFixedPointDenominator;
227 }
228 static bool isInBounds(unsigned value)
229 {
230 return value <= static_cast<unsigned>(std::numeric_limits<int>::max()) / kFixedPointDenominator;
231 }
232 static bool isInBounds(double value)
233 {
234 return ::fabs(value) <= std::numeric_limits<int>::max() / kFixedPointDenominator;
235 }
236
237 inline void setValue(int value)
238 {
239 if (value > intMaxForLayoutUnit)
240 m_value = std::numeric_limits<int>::max();
241 else if (value < intMinForLayoutUnit)
242 m_value = std::numeric_limits<int>::min();
243 else
244 m_value = value * kFixedPointDenominator;
245 }
246 inline void setValue(unsigned value)
247 {
248 if (value >= static_cast<unsigned>(intMaxForLayoutUnit))
249 m_value = std::numeric_limits<int>::max();
250 else
251 m_value = value * kFixedPointDenominator;
252 }
253
254 int m_value;
255};
256
257inline bool operator<=(const LayoutUnit& a, const LayoutUnit& b)
258{
259 return a.rawValue() <= b.rawValue();
260}
261
262inline bool operator<=(const LayoutUnit& a, float b)
263{
264 return a.toFloat() <= b;
265}
266
267inline bool operator<=(const LayoutUnit& a, int b)
268{
269 return a <= LayoutUnit(b);
270}
271
272inline bool operator<=(const float a, const LayoutUnit& b)
273{
274 return a <= b.toFloat();
275}
276
277inline bool operator<=(const int a, const LayoutUnit& b)
278{
279 return LayoutUnit(a) <= b;
280}
281
282inline bool operator>=(const LayoutUnit& a, const LayoutUnit& b)
283{
284 return a.rawValue() >= b.rawValue();
285}
286
287inline bool operator>=(const LayoutUnit& a, int b)
288{
289 return a >= LayoutUnit(b);
290}
291
292inline bool operator>=(const float a, const LayoutUnit& b)
293{
294 return a >= b.toFloat();
295}
296
297inline bool operator>=(const LayoutUnit& a, float b)
298{
299 return a.toFloat() >= b;
300}
301
302inline bool operator>=(const int a, const LayoutUnit& b)
303{
304 return LayoutUnit(a) >= b;
305}
306
307inline bool operator<(const LayoutUnit& a, const LayoutUnit& b)
308{
309 return a.rawValue() < b.rawValue();
310}
311
312inline bool operator<(const LayoutUnit& a, int b)
313{
314 return a < LayoutUnit(b);
315}
316
317inline bool operator<(const LayoutUnit& a, float b)
318{
319 return a.toFloat() < b;
320}
321
322inline bool operator<(const LayoutUnit& a, double b)
323{
324 return a.toDouble() < b;
325}
326
327inline bool operator<(const int a, const LayoutUnit& b)
328{
329 return LayoutUnit(a) < b;
330}
331
332inline bool operator<(const float a, const LayoutUnit& b)
333{
334 return a < b.toFloat();
335}
336
337inline bool operator>(const LayoutUnit& a, const LayoutUnit& b)
338{
339 return a.rawValue() > b.rawValue();
340}
341
342inline bool operator>(const LayoutUnit& a, double b)
343{
344 return a.toDouble() > b;
345}
346
347inline bool operator>(const LayoutUnit& a, float b)
348{
349 return a.toFloat() > b;
350}
351
352inline bool operator>(const LayoutUnit& a, int b)
353{
354 return a > LayoutUnit(b);
355}
356
357inline bool operator>(const int a, const LayoutUnit& b)
358{
359 return LayoutUnit(a) > b;
360}
361
362inline bool operator>(const float a, const LayoutUnit& b)
363{
364 return a > b.toFloat();
365}
366
367inline bool operator>(const double a, const LayoutUnit& b)
368{
369 return a > b.toDouble();
370}
371
372inline bool operator!=(const LayoutUnit& a, const LayoutUnit& b)
373{
374 return a.rawValue() != b.rawValue();
375}
376
377inline bool operator!=(const LayoutUnit& a, float b)
378{
379 return a != LayoutUnit(b);
380}
381
382inline bool operator!=(const int a, const LayoutUnit& b)
383{
384 return LayoutUnit(a) != b;
385}
386
387inline bool operator!=(const LayoutUnit& a, int b)
388{
389 return a != LayoutUnit(b);
390}
391
392inline bool operator==(const LayoutUnit& a, const LayoutUnit& b)
393{
394 return a.rawValue() == b.rawValue();
395}
396
397inline bool operator==(const LayoutUnit& a, int b)
398{
399 return a == LayoutUnit(b);
400}
401
402inline bool operator==(const int a, const LayoutUnit& b)
403{
404 return LayoutUnit(a) == b;
405}
406
407inline bool operator==(const LayoutUnit& a, float b)
408{
409 return a.toFloat() == b;
410}
411
412inline bool operator==(const float a, const LayoutUnit& b)
413{
414 return a == b.toFloat();
415}
416
417// For multiplication that's prone to overflow, this bounds it to LayoutUnit::max() and ::min()
418inline LayoutUnit boundedMultiply(const LayoutUnit& a, const LayoutUnit& b)
419{
420 int64_t result = static_cast<int64_t>(a.rawValue()) * static_cast<int64_t>(b.rawValue()) / kFixedPointDenominator;
421 int32_t high = static_cast<int32_t>(result >> 32);
422 int32_t low = static_cast<int32_t>(result);
423 uint32_t saturated = (static_cast<uint32_t>(a.rawValue() ^ b.rawValue()) >> 31) + std::numeric_limits<int>::max();
424 // If the higher 32 bits does not match the lower 32 with sign extension the operation overflowed.
425 if (high != low >> 31)
426 result = saturated;
427
428 LayoutUnit returnVal;
429 returnVal.setRawValue(static_cast<int>(result));
430 return returnVal;
431}
432
433inline LayoutUnit operator*(const LayoutUnit& a, const LayoutUnit& b)
434{
435 return boundedMultiply(a, b);
436}
437
438inline double operator*(const LayoutUnit& a, double b)
439{
440 return a.toDouble() * b;
441}
442
443inline float operator*(const LayoutUnit& a, float b)
444{
445 return a.toFloat() * b;
446}
447
448inline LayoutUnit operator*(const LayoutUnit& a, int b)
449{
450 return a * LayoutUnit(b);
451}
452
453inline LayoutUnit operator*(const LayoutUnit& a, unsigned short b)
454{
455 return a * LayoutUnit(b);
456}
457
458inline LayoutUnit operator*(const LayoutUnit& a, unsigned b)
459{
460 return a * LayoutUnit(b);
461}
462
463inline LayoutUnit operator*(const LayoutUnit& a, unsigned long b)
464{
465 return a * LayoutUnit(b);
466}
467
468inline LayoutUnit operator*(const LayoutUnit& a, unsigned long long b)
469{
470 return a * LayoutUnit(b);
471}
472
473inline LayoutUnit operator*(unsigned short a, const LayoutUnit& b)
474{
475 return LayoutUnit(a) * b;
476}
477
478inline LayoutUnit operator*(unsigned a, const LayoutUnit& b)
479{
480 return LayoutUnit(a) * b;
481}
482
483inline LayoutUnit operator*(unsigned long a, const LayoutUnit& b)
484{
485 return LayoutUnit(a) * b;
486}
487
488inline LayoutUnit operator*(unsigned long long a, const LayoutUnit& b)
489{
490 return LayoutUnit(a) * b;
491}
492
493inline LayoutUnit operator*(const int a, const LayoutUnit& b)
494{
495 return LayoutUnit(a) * b;
496}
497
498inline float operator*(const float a, const LayoutUnit& b)
499{
500 return a * b.toFloat();
501}
502
503inline double operator*(const double a, const LayoutUnit& b)
504{
505 return a * b.toDouble();
506}
507
508inline LayoutUnit operator/(const LayoutUnit& a, const LayoutUnit& b)
509{
510 LayoutUnit returnVal;
511 long long rawVal = static_cast<long long>(kFixedPointDenominator) * a.rawValue() / b.rawValue();
512 returnVal.setRawValue(clampTo<int>(rawVal));
513 return returnVal;
514}
515
516inline float operator/(const LayoutUnit& a, float b)
517{
518 return a.toFloat() / b;
519}
520
521inline double operator/(const LayoutUnit& a, double b)
522{
523 return a.toDouble() / b;
524}
525
526inline LayoutUnit operator/(const LayoutUnit& a, int b)
527{
528 return a / LayoutUnit(b);
529}
530
531inline LayoutUnit operator/(const LayoutUnit& a, unsigned short b)
532{
533 return a / LayoutUnit(b);
534}
535
536inline LayoutUnit operator/(const LayoutUnit& a, unsigned b)
537{
538 return a / LayoutUnit(b);
539}
540
541inline LayoutUnit operator/(const LayoutUnit& a, unsigned long b)
542{
543 return a / LayoutUnit(b);
544}
545
546inline LayoutUnit operator/(const LayoutUnit& a, unsigned long long b)
547{
548 return a / LayoutUnit(b);
549}
550
551inline float operator/(const float a, const LayoutUnit& b)
552{
553 return a / b.toFloat();
554}
555
556inline double operator/(const double a, const LayoutUnit& b)
557{
558 return a / b.toDouble();
559}
560
561inline LayoutUnit operator/(const int a, const LayoutUnit& b)
562{
563 return LayoutUnit(a) / b;
564}
565
566inline LayoutUnit operator/(unsigned short a, const LayoutUnit& b)
567{
568 return LayoutUnit(a) / b;
569}
570
571inline LayoutUnit operator/(unsigned a, const LayoutUnit& b)
572{
573 return LayoutUnit(a) / b;
574}
575
576inline LayoutUnit operator/(unsigned long a, const LayoutUnit& b)
577{
578 return LayoutUnit(a) / b;
579}
580
581inline LayoutUnit operator/(unsigned long long a, const LayoutUnit& b)
582{
583 return LayoutUnit(a) / b;
584}
585
586inline LayoutUnit operator+(const LayoutUnit& a, const LayoutUnit& b)
587{
588 LayoutUnit returnVal;
589 returnVal.setRawValue(saturatedAddition(a.rawValue(), b.rawValue()));
590 return returnVal;
591}
592
593inline LayoutUnit operator+(const LayoutUnit& a, int b)
594{
595 return a + LayoutUnit(b);
596}
597
598inline float operator+(const LayoutUnit& a, float b)
599{
600 return a.toFloat() + b;
601}
602
603inline double operator+(const LayoutUnit& a, double b)
604{
605 return a.toDouble() + b;
606}
607
608inline LayoutUnit operator+(const int a, const LayoutUnit& b)
609{
610 return LayoutUnit(a) + b;
611}
612
613inline float operator+(const float a, const LayoutUnit& b)
614{
615 return a + b.toFloat();
616}
617
618inline double operator+(const double a, const LayoutUnit& b)
619{
620 return a + b.toDouble();
621}
622
623inline LayoutUnit operator-(const LayoutUnit& a, const LayoutUnit& b)
624{
625 LayoutUnit returnVal;
626 returnVal.setRawValue(saturatedSubtraction(a.rawValue(), b.rawValue()));
627 return returnVal;
628}
629
630inline LayoutUnit operator-(const LayoutUnit& a, int b)
631{
632 return a - LayoutUnit(b);
633}
634
635inline LayoutUnit operator-(const LayoutUnit& a, unsigned b)
636{
637 return a - LayoutUnit(b);
638}
639
640inline float operator-(const LayoutUnit& a, float b)
641{
642 return a.toFloat() - b;
643}
644
645inline LayoutUnit operator-(const int a, const LayoutUnit& b)
646{
647 return LayoutUnit(a) - b;
648}
649
650inline float operator-(const float a, const LayoutUnit& b)
651{
652 return a - b.toFloat();
653}
654
655inline LayoutUnit operator-(const LayoutUnit& a)
656{
657 LayoutUnit returnVal;
658 returnVal.setRawValue(-a.rawValue());
659 return returnVal;
660}
661
662// For returning the remainder after a division with integer results.
663inline LayoutUnit intMod(const LayoutUnit& a, const LayoutUnit& b)
664{
665 // This calculates the modulo so that: a = static_cast<int>(a / b) * b + intMod(a, b).
666 LayoutUnit returnVal;
667 returnVal.setRawValue(a.rawValue() % b.rawValue());
668 return returnVal;
669}
670
671inline LayoutUnit operator%(const LayoutUnit& a, const LayoutUnit& b)
672{
673 // This calculates the modulo so that: a = (a / b) * b + a % b.
674 LayoutUnit returnVal;
675 long long rawVal = (static_cast<long long>(kFixedPointDenominator) * a.rawValue()) % b.rawValue();
676 returnVal.setRawValue(rawVal / kFixedPointDenominator);
677 return returnVal;
678}
679
680inline LayoutUnit operator%(const LayoutUnit& a, int b)
681{
682 return a % LayoutUnit(b);
683}
684
685inline LayoutUnit operator%(int a, const LayoutUnit& b)
686{
687 return LayoutUnit(a) % b;
688}
689
690inline LayoutUnit& operator+=(LayoutUnit& a, const LayoutUnit& b)
691{
692 a.setRawValue(saturatedAddition(a.rawValue(), b.rawValue()));
693 return a;
694}
695
696inline LayoutUnit& operator+=(LayoutUnit& a, int b)
697{
698 a = a + b;
699 return a;
700}
701
702inline LayoutUnit& operator+=(LayoutUnit& a, float b)
703{
704 a = a + b;
705 return a;
706}
707
708inline float& operator+=(float& a, const LayoutUnit& b)
709{
710 a = a + b;
711 return a;
712}
713
714inline LayoutUnit& operator-=(LayoutUnit& a, int b)
715{
716 a = a - b;
717 return a;
718}
719
720inline LayoutUnit& operator-=(LayoutUnit& a, const LayoutUnit& b)
721{
722 a.setRawValue(saturatedSubtraction(a.rawValue(), b.rawValue()));
723 return a;
724}
725
726inline LayoutUnit& operator-=(LayoutUnit& a, float b)
727{
728 a = a - b;
729 return a;
730}
731
732inline float& operator-=(float& a, const LayoutUnit& b)
733{
734 a = a - b;
735 return a;
736}
737
738inline LayoutUnit& operator*=(LayoutUnit& a, const LayoutUnit& b)
739{
740 a = a * b;
741 return a;
742}
743// operator*=(LayoutUnit& a, int b) is supported by the operator above plus LayoutUnit(int).
744
745inline LayoutUnit& operator*=(LayoutUnit& a, float b)
746{
747 a = a * b;
748 return a;
749}
750
751inline float& operator*=(float& a, const LayoutUnit& b)
752{
753 a = a * b;
754 return a;
755}
756
757inline LayoutUnit& operator/=(LayoutUnit& a, const LayoutUnit& b)
758{
759 a = a / b;
760 return a;
761}
762// operator/=(LayoutUnit& a, int b) is supported by the operator above plus LayoutUnit(int).
763
764inline LayoutUnit& operator/=(LayoutUnit& a, float b)
765{
766 a = a / b;
767 return a;
768}
769
770inline float& operator/=(float& a, const LayoutUnit& b)
771{
772 a = a / b;
773 return a;
774}
775
776WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const LayoutUnit&);
777
778inline int roundToInt(LayoutUnit value)
779{
780 return value.round();
781}
782
783inline int floorToInt(LayoutUnit value)
784{
785 return value.floor();
786}
787
788inline float roundToDevicePixel(LayoutUnit value, float pixelSnappingFactor, bool needsDirectionalRounding = false)
789{
790 double valueToRound = value.toDouble();
791 if (needsDirectionalRounding)
792 valueToRound -= LayoutUnit::epsilon() / (2 * kFixedPointDenominator);
793
794 if (valueToRound >= 0)
795 return round(valueToRound * pixelSnappingFactor) / pixelSnappingFactor;
796
797 // This adjusts directional rounding on negative halfway values. It produces the same direction for both negative and positive values.
798 // Instead of rounding negative halfway cases away from zero, we translate them to positive values before rounding.
799 // It helps snapping relative negative coordinates to the same position as if they were positive absolute coordinates.
800 unsigned translateOrigin = -value.rawValue();
801 return (round((valueToRound + translateOrigin) * pixelSnappingFactor) / pixelSnappingFactor) - translateOrigin;
802}
803
804inline float floorToDevicePixel(LayoutUnit value, float pixelSnappingFactor)
805{
806 return floorf((value.rawValue() * pixelSnappingFactor) / kFixedPointDenominator) / pixelSnappingFactor;
807}
808
809inline float ceilToDevicePixel(LayoutUnit value, float pixelSnappingFactor)
810{
811 return ceilf((value.rawValue() * pixelSnappingFactor) / kFixedPointDenominator) / pixelSnappingFactor;
812}
813
814inline LayoutUnit absoluteValue(const LayoutUnit& value)
815{
816 return value.abs();
817}
818
819inline bool isIntegerValue(const LayoutUnit value)
820{
821 return value.toInt() == value;
822}
823
824inline namespace StringLiterals {
825
826inline LayoutUnit operator"" _lu(unsigned long long value)
827{
828 return LayoutUnit(value);
829}
830
831}
832
833} // namespace WebCore
834
835#ifndef NDEBUG
836
837namespace WTF {
838
839// This structure is used by PODIntervalTree for debugging.
840template<> struct ValueToString<WebCore::LayoutUnit> {
841 static String string(WebCore::LayoutUnit value) { return String::numberToStringFixedPrecision(value.toFloat()); }
842};
843
844} // namespace WTF
845
846#endif
847