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#ifndef LayoutPoint_h
32#define LayoutPoint_h
33
34#include "FloatPoint.h"
35#include "LayoutSize.h"
36
37namespace WebCore {
38
39class LayoutPoint {
40public:
41    LayoutPoint() : m_x(0), m_y(0) { }
42    LayoutPoint(LayoutUnit x, LayoutUnit y) : m_x(x), m_y(y) { }
43    LayoutPoint(const IntPoint& point) : m_x(point.x()), m_y(point.y()) { }
44    explicit LayoutPoint(const FloatPoint& size) : m_x(size.x()), m_y(size.y()) { }
45    explicit LayoutPoint(const LayoutSize& size) : m_x(size.width()), m_y(size.height()) { }
46
47    static LayoutPoint zero() { return LayoutPoint(); }
48
49    LayoutUnit x() const { return m_x; }
50    LayoutUnit y() const { return m_y; }
51
52    void setX(LayoutUnit x) { m_x = x; }
53    void setY(LayoutUnit y) { m_y = y; }
54
55    void move(const LayoutSize& s) { move(s.width(), s.height()); }
56    void moveBy(const LayoutPoint& offset) { move(offset.x(), offset.y()); }
57    void move(LayoutUnit dx, LayoutUnit dy) { m_x += dx; m_y += dy; }
58    void scale(float sx, float sy)
59    {
60        m_x *= sx;
61        m_y *= sy;
62    }
63
64    LayoutPoint expandedTo(const LayoutPoint& other) const
65    {
66        return LayoutPoint(std::max(m_x, other.m_x), std::max(m_y, other.m_y));
67    }
68
69    LayoutPoint shrunkTo(const LayoutPoint& other) const
70    {
71        return LayoutPoint(std::min(m_x, other.m_x), std::min(m_y, other.m_y));
72    }
73
74    void clampNegativeToZero()
75    {
76        *this = expandedTo(zero());
77    }
78
79    LayoutPoint transposedPoint() const
80    {
81        return LayoutPoint(m_y, m_x);
82    }
83
84    LayoutPoint fraction() const
85    {
86        return LayoutPoint(m_x.fraction(), m_y.fraction());
87    }
88
89    operator FloatPoint() const { return FloatPoint(m_x, m_y); }
90
91private:
92    LayoutUnit m_x, m_y;
93};
94
95inline LayoutPoint& operator+=(LayoutPoint& a, const LayoutSize& b)
96{
97    a.move(b.width(), b.height());
98    return a;
99}
100
101inline LayoutPoint& operator-=(LayoutPoint& a, const LayoutSize& b)
102{
103    a.move(-b.width(), -b.height());
104    return a;
105}
106
107inline LayoutPoint operator+(const LayoutPoint& a, const LayoutSize& b)
108{
109    return LayoutPoint(a.x() + b.width(), a.y() + b.height());
110}
111
112inline LayoutPoint operator+(const LayoutPoint& a, const LayoutPoint& b)
113{
114    return LayoutPoint(a.x() + b.x(), a.y() + b.y());
115}
116
117inline LayoutSize operator-(const LayoutPoint& a, const LayoutPoint& b)
118{
119    return LayoutSize(a.x() - b.x(), a.y() - b.y());
120}
121
122inline LayoutPoint operator-(const LayoutPoint& a, const LayoutSize& b)
123{
124    return LayoutPoint(a.x() - b.width(), a.y() - b.height());
125}
126
127inline LayoutPoint operator-(const LayoutPoint& point)
128{
129    return LayoutPoint(-point.x(), -point.y());
130}
131
132inline bool operator==(const LayoutPoint& a, const LayoutPoint& b)
133{
134    return a.x() == b.x() && a.y() == b.y();
135}
136
137inline bool operator!=(const LayoutPoint& a, const LayoutPoint& b)
138{
139    return a.x() != b.x() || a.y() != b.y();
140}
141
142inline LayoutPoint toLayoutPoint(const LayoutSize& size)
143{
144    return LayoutPoint(size.width(), size.height());
145}
146
147inline LayoutSize toLayoutSize(const LayoutPoint& point)
148{
149    return LayoutSize(point.x(), point.y());
150}
151
152inline IntPoint flooredIntPoint(const LayoutPoint& point)
153{
154    return IntPoint(point.x().floor(), point.y().floor());
155}
156
157inline IntPoint roundedIntPoint(const LayoutPoint& point)
158{
159    return IntPoint(point.x().round(), point.y().round());
160}
161
162inline IntPoint roundedIntPoint(const LayoutSize& size)
163{
164    return roundedIntPoint(toLayoutPoint(size));
165}
166
167inline IntPoint ceiledIntPoint(const LayoutPoint& point)
168{
169    return IntPoint(point.x().ceil(), point.y().ceil());
170}
171
172inline LayoutPoint flooredLayoutPoint(const FloatPoint& p)
173{
174    return LayoutPoint(LayoutUnit::fromFloatFloor(p.x()), LayoutUnit::fromFloatFloor(p.y()));
175}
176
177inline LayoutPoint ceiledLayoutPoint(const FloatPoint& p)
178{
179    return LayoutPoint(LayoutUnit::fromFloatCeil(p.x()), LayoutUnit::fromFloatCeil(p.y()));
180}
181
182inline IntSize pixelSnappedIntSize(const LayoutSize& s, const LayoutPoint& p)
183{
184    return IntSize(snapSizeToPixel(s.width(), p.x()), snapSizeToPixel(s.height(), p.y()));
185}
186
187inline FloatPoint roundedForPainting(const LayoutPoint& point, float pixelSnappingFactor, bool directionalRoundingToRight = true, bool directionalRoundingToBottom = true)
188{
189#if ENABLE(SUBPIXEL_LAYOUT)
190    return FloatPoint(roundToDevicePixel(point.x(), pixelSnappingFactor, !directionalRoundingToRight), roundToDevicePixel(point.y(), pixelSnappingFactor, !directionalRoundingToBottom));
191#else
192    UNUSED_PARAM(pixelSnappingFactor);
193    UNUSED_PARAM(directionalRoundingToRight);
194    UNUSED_PARAM(directionalRoundingToBottom);
195    return FloatPoint(point);
196#endif
197}
198
199inline FloatPoint flooredForPainting(const LayoutPoint& point, float pixelSnappingFactor)
200{
201#if ENABLE(SUBPIXEL_LAYOUT)
202    return FloatPoint(floorToDevicePixel(point.x(), pixelSnappingFactor), floorToDevicePixel(point.y(), pixelSnappingFactor));
203#else
204    UNUSED_PARAM(pixelSnappingFactor);
205    return FloatPoint(point);
206#endif
207}
208
209inline FloatPoint ceiledForPainting(const LayoutPoint& point, float pixelSnappingFactor)
210{
211#if ENABLE(SUBPIXEL_LAYOUT)
212    return FloatPoint(ceilToDevicePixel(point.x(), pixelSnappingFactor), ceilToDevicePixel(point.y(), pixelSnappingFactor));
213#else
214    UNUSED_PARAM(pixelSnappingFactor);
215    return FloatPoint(point);
216#endif
217}
218
219inline LayoutPoint roundedLayoutPoint(const FloatPoint& p)
220{
221#if ENABLE(SUBPIXEL_LAYOUT)
222    return LayoutPoint(p);
223#else
224    return roundedIntPoint(p);
225#endif
226}
227
228} // namespace WebCore
229
230#endif // LayoutPoint_h
231