1/*
2 * Copyright (C) 2003-2016 Apple 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
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include <algorithm>
29#include <wtf/JSONValues.h>
30#include <wtf/Forward.h>
31
32#if PLATFORM(MAC) && defined __OBJC__
33#import <Foundation/NSGeometry.h>
34#endif
35
36#if USE(CG)
37typedef struct CGSize CGSize;
38#endif
39
40#if PLATFORM(MAC)
41#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
42typedef struct CGSize NSSize;
43#else
44typedef struct _NSSize NSSize;
45#endif
46#endif
47
48#if PLATFORM(IOS_FAMILY)
49#ifndef NSSize
50#define NSSize CGSize
51#endif
52#endif
53
54#if PLATFORM(WIN)
55typedef struct tagSIZE SIZE;
56
57struct D2D_SIZE_U;
58typedef D2D_SIZE_U D2D1_SIZE_U;
59
60struct D2D_SIZE_F;
61typedef D2D_SIZE_F D2D1_SIZE_F;
62#endif
63
64namespace WTF {
65class TextStream;
66}
67
68namespace WebCore {
69
70class FloatSize;
71
72class IntSize {
73public:
74 IntSize() : m_width(0), m_height(0) { }
75 IntSize(int width, int height) : m_width(width), m_height(height) { }
76 WEBCORE_EXPORT explicit IntSize(const FloatSize&); // don't do this implicitly since it's lossy
77
78 int width() const { return m_width; }
79 int height() const { return m_height; }
80
81 void setWidth(int width) { m_width = width; }
82 void setHeight(int height) { m_height = height; }
83
84 bool isEmpty() const { return m_width <= 0 || m_height <= 0; }
85 bool isZero() const { return !m_width && !m_height; }
86
87 float aspectRatio() const { return static_cast<float>(m_width) / static_cast<float>(m_height); }
88
89 void expand(int width, int height)
90 {
91 m_width += width;
92 m_height += height;
93 }
94
95 void contract(int width, int height)
96 {
97 m_width -= width;
98 m_height -= height;
99 }
100
101 void scale(float widthScale, float heightScale)
102 {
103 m_width = static_cast<int>(static_cast<float>(m_width) * widthScale);
104 m_height = static_cast<int>(static_cast<float>(m_height) * heightScale);
105 }
106
107 void scale(float scale)
108 {
109 this->scale(scale, scale);
110 }
111
112 IntSize expandedTo(const IntSize& other) const
113 {
114 return IntSize(std::max(m_width, other.m_width), std::max(m_height, other.m_height));
115 }
116
117 IntSize shrunkTo(const IntSize& other) const
118 {
119 return IntSize(std::min(m_width, other.m_width), std::min(m_height, other.m_height));
120 }
121
122 void clampNegativeToZero()
123 {
124 *this = expandedTo(IntSize());
125 }
126
127 void clampToMinimumSize(const IntSize& minimumSize)
128 {
129 if (m_width < minimumSize.width())
130 m_width = minimumSize.width();
131 if (m_height < minimumSize.height())
132 m_height = minimumSize.height();
133 }
134
135 WEBCORE_EXPORT IntSize constrainedBetween(const IntSize& min, const IntSize& max) const;
136
137 template <typename T = WTF::CrashOnOverflow>
138 Checked<unsigned, T> area() const
139 {
140 return Checked<unsigned, T>(abs(m_width)) * abs(m_height);
141 }
142
143 size_t unclampedArea() const
144 {
145 return static_cast<size_t>(abs(m_width)) * abs(m_height);
146 }
147
148 int diagonalLengthSquared() const
149 {
150 return m_width * m_width + m_height * m_height;
151 }
152
153 IntSize transposedSize() const
154 {
155 return IntSize(m_height, m_width);
156 }
157
158#if USE(CG)
159 WEBCORE_EXPORT explicit IntSize(const CGSize&); // don't do this implicitly since it's lossy
160 WEBCORE_EXPORT operator CGSize() const;
161#endif
162
163#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)
164 WEBCORE_EXPORT explicit IntSize(const NSSize &); // don't do this implicitly since it's lossy
165 WEBCORE_EXPORT operator NSSize() const;
166#endif
167
168#if PLATFORM(WIN)
169 IntSize(const SIZE&);
170 operator SIZE() const;
171 IntSize(const D2D1_SIZE_U&);
172 explicit IntSize(const D2D1_SIZE_F&); // don't do this implicitly since it's lossy;
173 operator D2D1_SIZE_U() const;
174 operator D2D1_SIZE_F() const;
175#endif
176
177 String toJSONString() const;
178 Ref<JSON::Object> toJSONObject() const;
179
180private:
181 int m_width, m_height;
182};
183
184inline IntSize& operator+=(IntSize& a, const IntSize& b)
185{
186 a.setWidth(a.width() + b.width());
187 a.setHeight(a.height() + b.height());
188 return a;
189}
190
191inline IntSize& operator-=(IntSize& a, const IntSize& b)
192{
193 a.setWidth(a.width() - b.width());
194 a.setHeight(a.height() - b.height());
195 return a;
196}
197
198inline IntSize operator+(const IntSize& a, const IntSize& b)
199{
200 return IntSize(a.width() + b.width(), a.height() + b.height());
201}
202
203inline IntSize operator-(const IntSize& a, const IntSize& b)
204{
205 return IntSize(a.width() - b.width(), a.height() - b.height());
206}
207
208inline IntSize operator-(const IntSize& size)
209{
210 return IntSize(-size.width(), -size.height());
211}
212
213inline bool operator==(const IntSize& a, const IntSize& b)
214{
215 return a.width() == b.width() && a.height() == b.height();
216}
217
218inline bool operator!=(const IntSize& a, const IntSize& b)
219{
220 return a.width() != b.width() || a.height() != b.height();
221}
222
223WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const IntSize&);
224
225} // namespace WebCore
226
227namespace WTF {
228template<> struct DefaultHash<WebCore::IntSize>;
229template<> struct HashTraits<WebCore::IntSize>;
230
231template<typename Type> struct LogArgument;
232template <>
233struct LogArgument<WebCore::IntSize> {
234 static String toString(const WebCore::IntSize& size)
235 {
236 return size.toJSONString();
237 }
238};
239}
240
241