1 | /* |
2 | * Copyright (C) 2003-2016 Apple Inc. All rights reserved. |
3 | * Copyright (C) 2005 Nokia. All rights reserved. |
4 | * 2008 Eric Seidel <eric@webkit.org> |
5 | * |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions |
8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. |
14 | * |
15 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
16 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
18 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
21 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
22 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
23 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
25 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | #pragma once |
29 | |
30 | #include "IntPoint.h" |
31 | #include <wtf/JSONValues.h> |
32 | #include <wtf/MathExtras.h> |
33 | #include <wtf/text/WTFString.h> |
34 | |
35 | #if PLATFORM(IOS_FAMILY) |
36 | #include <CoreGraphics/CoreGraphics.h> |
37 | #endif |
38 | |
39 | #if USE(CG) |
40 | typedef struct CGSize CGSize; |
41 | #endif |
42 | |
43 | #if PLATFORM(MAC) |
44 | #ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES |
45 | typedef struct CGSize NSSize; |
46 | #else |
47 | typedef struct _NSSize NSSize; |
48 | #endif |
49 | #endif // PLATFORM(MAC) |
50 | |
51 | #if PLATFORM(WIN) |
52 | struct D2D_SIZE_F; |
53 | typedef D2D_SIZE_F D2D1_SIZE_F; |
54 | #endif |
55 | |
56 | namespace WTF { |
57 | class TextStream; |
58 | } |
59 | |
60 | namespace WebCore { |
61 | |
62 | class IntSize; |
63 | |
64 | class FloatSize { |
65 | public: |
66 | FloatSize() { } |
67 | FloatSize(float width, float height) : m_width(width), m_height(height) { } |
68 | WEBCORE_EXPORT FloatSize(const IntSize&); |
69 | |
70 | static FloatSize narrowPrecision(double width, double height); |
71 | |
72 | float width() const { return m_width; } |
73 | float height() const { return m_height; } |
74 | |
75 | void setWidth(float width) { m_width = width; } |
76 | void setHeight(float height) { m_height = height; } |
77 | |
78 | bool isEmpty() const { return m_width <= 0 || m_height <= 0; } |
79 | WEBCORE_EXPORT bool isZero() const; |
80 | bool isExpressibleAsIntSize() const; |
81 | |
82 | float aspectRatio() const { return m_width / m_height; } |
83 | |
84 | void expand(float width, float height) |
85 | { |
86 | m_width += width; |
87 | m_height += height; |
88 | } |
89 | |
90 | void scale(float s) |
91 | { |
92 | m_width *= s; |
93 | m_height *= s; |
94 | } |
95 | |
96 | void scale(float scaleX, float scaleY) |
97 | { |
98 | m_width *= scaleX; |
99 | m_height *= scaleY; |
100 | } |
101 | |
102 | FloatSize scaled(float s) const |
103 | { |
104 | return { m_width * s, m_height * s }; |
105 | } |
106 | |
107 | FloatSize scaled(float scaleX, float scaleY) const |
108 | { |
109 | return { m_width * scaleX, m_height * scaleY }; |
110 | } |
111 | |
112 | WEBCORE_EXPORT FloatSize constrainedBetween(const FloatSize& min, const FloatSize& max) const; |
113 | |
114 | FloatSize expandedTo(const FloatSize& other) const |
115 | { |
116 | return FloatSize(m_width > other.m_width ? m_width : other.m_width, |
117 | m_height > other.m_height ? m_height : other.m_height); |
118 | } |
119 | |
120 | FloatSize shrunkTo(const FloatSize& other) const |
121 | { |
122 | return FloatSize(m_width < other.m_width ? m_width : other.m_width, |
123 | m_height < other.m_height ? m_height : other.m_height); |
124 | } |
125 | |
126 | WEBCORE_EXPORT float diagonalLength() const; |
127 | |
128 | float diagonalLengthSquared() const |
129 | { |
130 | return m_width * m_width + m_height * m_height; |
131 | } |
132 | |
133 | float area() const |
134 | { |
135 | return m_width * m_height; |
136 | } |
137 | |
138 | FloatSize transposedSize() const |
139 | { |
140 | return FloatSize(m_height, m_width); |
141 | } |
142 | |
143 | #if USE(CG) |
144 | WEBCORE_EXPORT explicit FloatSize(const CGSize&); // don't do this implicitly since it's lossy |
145 | WEBCORE_EXPORT operator CGSize() const; |
146 | #endif |
147 | |
148 | #if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES) |
149 | WEBCORE_EXPORT explicit FloatSize(const NSSize&); // don't do this implicitly since it's lossy |
150 | operator NSSize() const; |
151 | #endif |
152 | |
153 | #if PLATFORM(WIN) |
154 | WEBCORE_EXPORT FloatSize(const D2D1_SIZE_F&); |
155 | operator D2D1_SIZE_F() const; |
156 | #endif |
157 | |
158 | String toJSONString() const; |
159 | Ref<JSON::Object> toJSONObject() const; |
160 | |
161 | private: |
162 | float m_width { 0 }; |
163 | float m_height { 0 }; |
164 | }; |
165 | |
166 | inline FloatSize& operator+=(FloatSize& a, const FloatSize& b) |
167 | { |
168 | a.setWidth(a.width() + b.width()); |
169 | a.setHeight(a.height() + b.height()); |
170 | return a; |
171 | } |
172 | |
173 | inline FloatSize& operator-=(FloatSize& a, const FloatSize& b) |
174 | { |
175 | a.setWidth(a.width() - b.width()); |
176 | a.setHeight(a.height() - b.height()); |
177 | return a; |
178 | } |
179 | |
180 | inline FloatSize operator+(const FloatSize& a, const FloatSize& b) |
181 | { |
182 | return FloatSize(a.width() + b.width(), a.height() + b.height()); |
183 | } |
184 | |
185 | inline FloatSize operator-(const FloatSize& a, const FloatSize& b) |
186 | { |
187 | return FloatSize(a.width() - b.width(), a.height() - b.height()); |
188 | } |
189 | |
190 | inline FloatSize operator-(const FloatSize& size) |
191 | { |
192 | return FloatSize(-size.width(), -size.height()); |
193 | } |
194 | |
195 | inline FloatSize operator*(const FloatSize& a, float b) |
196 | { |
197 | return FloatSize(a.width() * b, a.height() * b); |
198 | } |
199 | |
200 | inline FloatSize operator*(float a, const FloatSize& b) |
201 | { |
202 | return FloatSize(a * b.width(), a * b.height()); |
203 | } |
204 | |
205 | inline FloatSize operator*(const FloatSize& a, const FloatSize& b) |
206 | { |
207 | return FloatSize(a.width() * b.width(), a.height() * b.height()); |
208 | } |
209 | |
210 | inline FloatSize operator/(const FloatSize& a, const FloatSize& b) |
211 | { |
212 | return FloatSize(a.width() / b.width(), a.height() / b.height()); |
213 | } |
214 | |
215 | inline FloatSize operator/(const FloatSize& a, float b) |
216 | { |
217 | return FloatSize(a.width() / b, a.height() / b); |
218 | } |
219 | |
220 | inline FloatSize operator/(float a, const FloatSize& b) |
221 | { |
222 | return FloatSize(a / b.width(), a / b.height()); |
223 | } |
224 | |
225 | inline bool operator==(const FloatSize& a, const FloatSize& b) |
226 | { |
227 | return a.width() == b.width() && a.height() == b.height(); |
228 | } |
229 | |
230 | inline bool areEssentiallyEqual(const FloatSize& a, const FloatSize& b) |
231 | { |
232 | return WTF::areEssentiallyEqual(a.width(), b.width()) && WTF::areEssentiallyEqual(a.height(), b.height()); |
233 | } |
234 | |
235 | inline bool operator!=(const FloatSize& a, const FloatSize& b) |
236 | { |
237 | return a.width() != b.width() || a.height() != b.height(); |
238 | } |
239 | |
240 | inline IntSize roundedIntSize(const FloatSize& p) |
241 | { |
242 | return IntSize(clampToInteger(roundf(p.width())), clampToInteger(roundf(p.height()))); |
243 | } |
244 | |
245 | inline IntSize flooredIntSize(const FloatSize& p) |
246 | { |
247 | return IntSize(clampToInteger(floorf(p.width())), clampToInteger(floorf(p.height()))); |
248 | } |
249 | |
250 | inline IntSize expandedIntSize(const FloatSize& p) |
251 | { |
252 | return IntSize(clampToInteger(ceilf(p.width())), clampToInteger(ceilf(p.height()))); |
253 | } |
254 | |
255 | inline IntPoint flooredIntPoint(const FloatSize& p) |
256 | { |
257 | return IntPoint(clampToInteger(floorf(p.width())), clampToInteger(floorf(p.height()))); |
258 | } |
259 | |
260 | WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const FloatSize&); |
261 | |
262 | } // namespace WebCore |
263 | |
264 | namespace WTF { |
265 | template<> struct DefaultHash<WebCore::FloatSize>; |
266 | template<> struct HashTraits<WebCore::FloatSize>; |
267 | |
268 | template<typename Type> struct LogArgument; |
269 | template <> |
270 | struct LogArgument<WebCore::FloatSize> { |
271 | static String toString(const WebCore::FloatSize& size) |
272 | { |
273 | return size.toJSONString(); |
274 | } |
275 | }; |
276 | |
277 | } // namespace WTF |
278 | |