1 | /* |
2 | * Copyright (C) 2003, 2006, 2009 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. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include "config.h" |
27 | #include "IntRect.h" |
28 | |
29 | #include "FloatRect.h" |
30 | #include "LayoutRect.h" |
31 | #include <algorithm> |
32 | #include <wtf/text/TextStream.h> |
33 | |
34 | namespace WebCore { |
35 | |
36 | IntRect::IntRect(const FloatRect& r) |
37 | : m_location(clampToInteger(r.x()), clampToInteger(r.y())) |
38 | , m_size(clampToInteger(r.width()), clampToInteger(r.height())) |
39 | { |
40 | } |
41 | |
42 | IntRect::IntRect(const LayoutRect& r) |
43 | : m_location(r.x(), r.y()) |
44 | , m_size(r.width(), r.height()) |
45 | { |
46 | } |
47 | |
48 | bool IntRect::intersects(const IntRect& other) const |
49 | { |
50 | // Checking emptiness handles negative widths as well as zero. |
51 | return !isEmpty() && !other.isEmpty() |
52 | && x() < other.maxX() && other.x() < maxX() |
53 | && y() < other.maxY() && other.y() < maxY(); |
54 | } |
55 | |
56 | bool IntRect::contains(const IntRect& other) const |
57 | { |
58 | return x() <= other.x() && maxX() >= other.maxX() |
59 | && y() <= other.y() && maxY() >= other.maxY(); |
60 | } |
61 | |
62 | void IntRect::intersect(const IntRect& other) |
63 | { |
64 | int l = std::max(x(), other.x()); |
65 | int t = std::max(y(), other.y()); |
66 | int r = std::min(maxX(), other.maxX()); |
67 | int b = std::min(maxY(), other.maxY()); |
68 | |
69 | // Return a clean empty rectangle for non-intersecting cases. |
70 | if (l >= r || t >= b) { |
71 | l = 0; |
72 | t = 0; |
73 | r = 0; |
74 | b = 0; |
75 | } |
76 | |
77 | m_location.setX(l); |
78 | m_location.setY(t); |
79 | m_size.setWidth(r - l); |
80 | m_size.setHeight(b - t); |
81 | } |
82 | |
83 | void IntRect::unite(const IntRect& other) |
84 | { |
85 | // Handle empty special cases first. |
86 | if (other.isEmpty()) |
87 | return; |
88 | if (isEmpty()) { |
89 | *this = other; |
90 | return; |
91 | } |
92 | |
93 | int l = std::min(x(), other.x()); |
94 | int t = std::min(y(), other.y()); |
95 | int r = std::max(maxX(), other.maxX()); |
96 | int b = std::max(maxY(), other.maxY()); |
97 | |
98 | m_location.setX(l); |
99 | m_location.setY(t); |
100 | m_size.setWidth(r - l); |
101 | m_size.setHeight(b - t); |
102 | } |
103 | |
104 | void IntRect::uniteIfNonZero(const IntRect& other) |
105 | { |
106 | // Handle empty special cases first. |
107 | if (!other.width() && !other.height()) |
108 | return; |
109 | if (!width() && !height()) { |
110 | *this = other; |
111 | return; |
112 | } |
113 | |
114 | int left = std::min(x(), other.x()); |
115 | int top = std::min(y(), other.y()); |
116 | int right = std::max(maxX(), other.maxX()); |
117 | int bottom = std::max(maxY(), other.maxY()); |
118 | |
119 | m_location.setX(left); |
120 | m_location.setY(top); |
121 | m_size.setWidth(right - left); |
122 | m_size.setHeight(bottom - top); |
123 | } |
124 | |
125 | void IntRect::scale(float s) |
126 | { |
127 | m_location.setX((int)(x() * s)); |
128 | m_location.setY((int)(y() * s)); |
129 | m_size.setWidth((int)(width() * s)); |
130 | m_size.setHeight((int)(height() * s)); |
131 | } |
132 | |
133 | static inline int distanceToInterval(int pos, int start, int end) |
134 | { |
135 | if (pos < start) |
136 | return start - pos; |
137 | if (pos > end) |
138 | return end - pos; |
139 | return 0; |
140 | } |
141 | |
142 | IntSize IntRect::differenceToPoint(const IntPoint& point) const |
143 | { |
144 | int xdistance = distanceToInterval(point.x(), x(), maxX()); |
145 | int ydistance = distanceToInterval(point.y(), y(), maxY()); |
146 | return IntSize(xdistance, ydistance); |
147 | } |
148 | |
149 | TextStream& operator<<(TextStream& ts, const IntRect& r) |
150 | { |
151 | if (ts.hasFormattingFlag(TextStream::Formatting::SVGStyleRect)) |
152 | return ts << "at (" << r.x() << "," << r.y() << ") size " << r.width() << "x" << r.height(); |
153 | |
154 | return ts << r.location() << " " << r.size(); |
155 | } |
156 | |
157 | } // namespace WebCore |
158 | |