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)
40typedef struct CGSize CGSize;
41#endif
42
43#if PLATFORM(MAC)
44#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
45typedef struct CGSize NSSize;
46#else
47typedef struct _NSSize NSSize;
48#endif
49#endif // PLATFORM(MAC)
50
51#if PLATFORM(WIN)
52struct D2D_SIZE_F;
53typedef D2D_SIZE_F D2D1_SIZE_F;
54#endif
55
56namespace WTF {
57class TextStream;
58}
59
60namespace WebCore {
61
62class IntSize;
63
64class FloatSize {
65public:
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
161private:
162 float m_width { 0 };
163 float m_height { 0 };
164};
165
166inline 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
173inline 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
180inline FloatSize operator+(const FloatSize& a, const FloatSize& b)
181{
182 return FloatSize(a.width() + b.width(), a.height() + b.height());
183}
184
185inline FloatSize operator-(const FloatSize& a, const FloatSize& b)
186{
187 return FloatSize(a.width() - b.width(), a.height() - b.height());
188}
189
190inline FloatSize operator-(const FloatSize& size)
191{
192 return FloatSize(-size.width(), -size.height());
193}
194
195inline FloatSize operator*(const FloatSize& a, float b)
196{
197 return FloatSize(a.width() * b, a.height() * b);
198}
199
200inline FloatSize operator*(float a, const FloatSize& b)
201{
202 return FloatSize(a * b.width(), a * b.height());
203}
204
205inline FloatSize operator*(const FloatSize& a, const FloatSize& b)
206{
207 return FloatSize(a.width() * b.width(), a.height() * b.height());
208}
209
210inline FloatSize operator/(const FloatSize& a, const FloatSize& b)
211{
212 return FloatSize(a.width() / b.width(), a.height() / b.height());
213}
214
215inline FloatSize operator/(const FloatSize& a, float b)
216{
217 return FloatSize(a.width() / b, a.height() / b);
218}
219
220inline FloatSize operator/(float a, const FloatSize& b)
221{
222 return FloatSize(a / b.width(), a / b.height());
223}
224
225inline bool operator==(const FloatSize& a, const FloatSize& b)
226{
227 return a.width() == b.width() && a.height() == b.height();
228}
229
230inline 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
235inline bool operator!=(const FloatSize& a, const FloatSize& b)
236{
237 return a.width() != b.width() || a.height() != b.height();
238}
239
240inline IntSize roundedIntSize(const FloatSize& p)
241{
242 return IntSize(clampToInteger(roundf(p.width())), clampToInteger(roundf(p.height())));
243}
244
245inline IntSize flooredIntSize(const FloatSize& p)
246{
247 return IntSize(clampToInteger(floorf(p.width())), clampToInteger(floorf(p.height())));
248}
249
250inline IntSize expandedIntSize(const FloatSize& p)
251{
252 return IntSize(clampToInteger(ceilf(p.width())), clampToInteger(ceilf(p.height())));
253}
254
255inline IntPoint flooredIntPoint(const FloatSize& p)
256{
257 return IntPoint(clampToInteger(floorf(p.width())), clampToInteger(floorf(p.height())));
258}
259
260WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const FloatSize&);
261
262} // namespace WebCore
263
264namespace WTF {
265template<> struct DefaultHash<WebCore::FloatSize>;
266template<> struct HashTraits<WebCore::FloatSize>;
267
268template<typename Type> struct LogArgument;
269template <>
270struct LogArgument<WebCore::FloatSize> {
271 static String toString(const WebCore::FloatSize& size)
272 {
273 return size.toJSONString();
274 }
275};
276
277} // namespace WTF
278