3052a379f72d4c015378ba415b57d30d87d08904
[WebKit-https.git] / Source / WebCore / platform / graphics / IntSize.h
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/Forward.h>
30
31 #if PLATFORM(MAC) && defined __OBJC__
32 #import <Foundation/NSGeometry.h>
33 #endif
34
35 #if USE(CG)
36 typedef struct CGSize CGSize;
37 #endif
38
39 #if PLATFORM(MAC)
40 #ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
41 typedef struct CGSize NSSize;
42 #else
43 typedef struct _NSSize NSSize;
44 #endif
45 #endif
46
47 #if PLATFORM(IOS_FAMILY)
48 #ifndef NSSize
49 #define NSSize CGSize
50 #endif
51 #endif
52
53 #if PLATFORM(WIN)
54 typedef struct tagSIZE SIZE;
55
56 struct D2D_SIZE_U;
57 typedef D2D_SIZE_U D2D1_SIZE_U;
58
59 struct D2D_SIZE_F;
60 typedef D2D_SIZE_F D2D1_SIZE_F;
61 #endif
62
63 namespace WTF {
64 class TextStream;
65 }
66
67 namespace WebCore {
68
69 class FloatSize;
70
71 class IntSize {
72 public:
73     IntSize() : m_width(0), m_height(0) { }
74     IntSize(int width, int height) : m_width(width), m_height(height) { }
75     WEBCORE_EXPORT explicit IntSize(const FloatSize&); // don't do this implicitly since it's lossy
76     
77     int width() const { return m_width; }
78     int height() const { return m_height; }
79
80     void setWidth(int width) { m_width = width; }
81     void setHeight(int height) { m_height = height; }
82
83     bool isEmpty() const { return m_width <= 0 || m_height <= 0; }
84     bool isZero() const { return !m_width && !m_height; }
85
86     float aspectRatio() const { return static_cast<float>(m_width) / static_cast<float>(m_height); }
87     
88     void expand(int width, int height)
89     {
90         m_width += width;
91         m_height += height;
92     }
93
94     void contract(int width, int height)
95     {
96         m_width -= width;
97         m_height -= height;
98     }
99
100     void scale(float widthScale, float heightScale)
101     {
102         m_width = static_cast<int>(static_cast<float>(m_width) * widthScale);
103         m_height = static_cast<int>(static_cast<float>(m_height) * heightScale);
104     }
105     
106     void scale(float scale)
107     {
108         this->scale(scale, scale);
109     }
110
111     IntSize expandedTo(const IntSize& other) const
112     {
113         return IntSize(std::max(m_width, other.m_width), std::max(m_height, other.m_height));
114     }
115
116     IntSize shrunkTo(const IntSize& other) const
117     {
118         return IntSize(std::min(m_width, other.m_width), std::min(m_height, other.m_height));
119     }
120
121     void clampNegativeToZero()
122     {
123         *this = expandedTo(IntSize());
124     }
125
126     void clampToMinimumSize(const IntSize& minimumSize)
127     {
128         if (m_width < minimumSize.width())
129             m_width = minimumSize.width();
130         if (m_height < minimumSize.height())
131             m_height = minimumSize.height();
132     }
133
134     WEBCORE_EXPORT IntSize constrainedBetween(const IntSize& min, const IntSize& max) const;
135
136     template <typename T = WTF::CrashOnOverflow>
137     Checked<unsigned, T> area() const
138     {
139         return Checked<unsigned, T>(abs(m_width)) * abs(m_height);
140     }
141
142     size_t unclampedArea() const
143     {
144         return static_cast<size_t>(abs(m_width)) * abs(m_height);
145     }
146
147     int diagonalLengthSquared() const
148     {
149         return m_width * m_width + m_height * m_height;
150     }
151
152     IntSize transposedSize() const
153     {
154         return IntSize(m_height, m_width);
155     }
156
157 #if USE(CG)
158     WEBCORE_EXPORT explicit IntSize(const CGSize&); // don't do this implicitly since it's lossy
159     WEBCORE_EXPORT operator CGSize() const;
160 #endif
161
162 #if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)
163     WEBCORE_EXPORT explicit IntSize(const NSSize &); // don't do this implicitly since it's lossy
164     WEBCORE_EXPORT operator NSSize() const;
165 #endif
166
167 #if PLATFORM(WIN)
168     IntSize(const SIZE&);
169     operator SIZE() const;
170     IntSize(const D2D1_SIZE_U&);
171     explicit IntSize(const D2D1_SIZE_F&); // don't do this implicitly since it's lossy;
172     operator D2D1_SIZE_U() const;
173     operator D2D1_SIZE_F() const;
174 #endif
175
176 private:
177     int m_width, m_height;
178 };
179
180 inline IntSize& operator+=(IntSize& a, const IntSize& b)
181 {
182     a.setWidth(a.width() + b.width());
183     a.setHeight(a.height() + b.height());
184     return a;
185 }
186
187 inline IntSize& operator-=(IntSize& a, const IntSize& b)
188 {
189     a.setWidth(a.width() - b.width());
190     a.setHeight(a.height() - b.height());
191     return a;
192 }
193
194 inline IntSize operator+(const IntSize& a, const IntSize& b)
195 {
196     return IntSize(a.width() + b.width(), a.height() + b.height());
197 }
198
199 inline IntSize operator-(const IntSize& a, const IntSize& b)
200 {
201     return IntSize(a.width() - b.width(), a.height() - b.height());
202 }
203
204 inline IntSize operator-(const IntSize& size)
205 {
206     return IntSize(-size.width(), -size.height());
207 }
208
209 inline bool operator==(const IntSize& a, const IntSize& b)
210 {
211     return a.width() == b.width() && a.height() == b.height();
212 }
213
214 inline bool operator!=(const IntSize& a, const IntSize& b)
215 {
216     return a.width() != b.width() || a.height() != b.height();
217 }
218
219 WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const IntSize&);
220
221 } // namespace WebCore
222
223 namespace WTF {
224 template<> struct DefaultHash<WebCore::IntSize>;
225 template<> struct HashTraits<WebCore::IntSize>;
226 }