Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_BASEGFX_RANGE_B2IBOX_HXX
21 : #define INCLUDED_BASEGFX_RANGE_B2IBOX_HXX
22 :
23 : #include <ostream>
24 : #include <vector>
25 :
26 : #include <basegfx/point/b2ipoint.hxx>
27 : #include <basegfx/point/b2dpoint.hxx>
28 : #include <basegfx/tuple/b2ituple.hxx>
29 : #include <basegfx/tuple/b2i64tuple.hxx>
30 : #include <basegfx/range/basicbox.hxx>
31 : #include <basegfx/basegfxdllapi.h>
32 :
33 : namespace basegfx
34 : {
35 : /** A two-dimensional interval over integers
36 :
37 : This is most easily depicted as a set of integers, bounded by
38 : a lower and an upper value - but excluding the upper
39 : value. All inbetween values are included in the set (see also
40 : http://en.wikipedia.org/wiki/Interval_%28mathematics%29).
41 :
42 : The set is half-open, i.e. the lower bound is included, the
43 : upper bound not (if you're used to the notation - we're
44 : talking about [a,b) here, compared to closed [a,b] or fully
45 : open intervals (a,b)).
46 :
47 : If you don't need a half-open interval, check B2IRange.
48 :
49 : That means, isInside(val) will return true also for values of
50 : val=a, but not for val=b.
51 :
52 : Alternatively, consider this a rectangle, where the rightmost
53 : pixel column and the bottommost pixel row are excluded - this
54 : is much like polygon filling. As a result, filling a given
55 : rectangle with basebmp::BitmapDevice::fillPolyPolygon(), will
56 : affect exactly the same set of pixel as isInside() would
57 : return true for.
58 :
59 : @see B2IRange
60 : */
61 : class B2IBox
62 : {
63 : public:
64 : typedef sal_Int32 ValueType;
65 : typedef Int32Traits TraitsType;
66 :
67 1134962 : B2IBox() {}
68 :
69 : /// Create degenerate interval that's still empty
70 : explicit B2IBox(const B2ITuple& rTuple)
71 : : maRangeX(rTuple.getX()),
72 : maRangeY(rTuple.getY())
73 : {
74 : }
75 :
76 : /// Create proper interval between the two given points
77 5526307 : B2IBox(sal_Int32 x1,
78 : sal_Int32 y1,
79 : sal_Int32 x2,
80 : sal_Int32 y2) :
81 : maRangeX(x1),
82 5526307 : maRangeY(y1)
83 : {
84 5526307 : maRangeX.expand(x2);
85 5526307 : maRangeY.expand(y2);
86 5526307 : }
87 :
88 : /// Create proper interval between the two given points
89 5732834 : B2IBox(const B2ITuple& rTuple1,
90 : const B2ITuple& rTuple2) :
91 : maRangeX(rTuple1.getX()),
92 5732834 : maRangeY(rTuple1.getY())
93 : {
94 5732834 : expand( rTuple2 );
95 5732834 : }
96 :
97 : /** Check if the interval set is empty
98 :
99 : @return false, if no value is in this set - having a
100 : single value included will still return false.
101 : */
102 4356630 : bool isEmpty() const
103 : {
104 4356630 : return maRangeX.isEmpty() || maRangeY.isEmpty();
105 : }
106 :
107 : /// reset the object to empty state again, clearing all values
108 : void reset()
109 : {
110 : maRangeX.reset();
111 : maRangeY.reset();
112 : }
113 :
114 : bool operator==( const B2IBox& rBox ) const
115 : {
116 : return (maRangeX == rBox.maRangeX
117 : && maRangeY == rBox.maRangeY);
118 : }
119 :
120 : bool operator!=( const B2IBox& rBox ) const
121 : {
122 : return (maRangeX != rBox.maRangeX
123 : || maRangeY != rBox.maRangeY);
124 : }
125 :
126 : /// get lower bound of the set. returns arbitrary values for empty sets.
127 28131669 : sal_Int32 getMinX() const
128 : {
129 28131669 : return maRangeX.getMinimum();
130 : }
131 :
132 : /// get lower bound of the set. returns arbitrary values for empty sets.
133 28131669 : sal_Int32 getMinY() const
134 : {
135 28131669 : return maRangeY.getMinimum();
136 : }
137 :
138 : /// get upper bound of the set. returns arbitrary values for empty sets.
139 27356191 : sal_Int32 getMaxX() const
140 : {
141 27356191 : return maRangeX.getMaximum();
142 : }
143 :
144 : /// get upper bound of the set. returns arbitrary values for empty sets.
145 27356191 : sal_Int32 getMaxY() const
146 : {
147 27356191 : return maRangeY.getMaximum();
148 : }
149 :
150 : /// return difference between upper and lower X value. returns 0 for empty sets.
151 2132614 : sal_Int64 getWidth() const
152 : {
153 2132614 : return maRangeX.getRange();
154 : }
155 :
156 : /// return difference between upper and lower Y value. returns 0 for empty sets.
157 2132584 : sal_Int64 getHeight() const
158 : {
159 2132584 : return maRangeY.getRange();
160 : }
161 :
162 : /// get lower bound of the set. returns arbitrary values for empty sets.
163 7531141 : B2IPoint getMinimum() const
164 : {
165 : return B2IPoint(
166 : maRangeX.getMinimum(),
167 : maRangeY.getMinimum()
168 7531141 : );
169 : }
170 :
171 : /// get upper bound of the set. returns arbitrary values for empty sets.
172 3750542 : B2IPoint getMaximum() const
173 : {
174 : return B2IPoint(
175 : maRangeX.getMaximum(),
176 : maRangeY.getMaximum()
177 3750542 : );
178 : }
179 :
180 : /// return difference between upper and lower value. returns (0,0) for empty sets.
181 : B2I64Tuple getRange() const
182 : {
183 : return B2I64Tuple(
184 : maRangeX.getRange(),
185 : maRangeY.getRange()
186 : );
187 : }
188 :
189 : /// return center point of set. returns (0,0) for empty sets.
190 : B2DPoint getCenter() const
191 : {
192 : return B2DPoint(
193 : maRangeX.getCenter(),
194 : maRangeY.getCenter()
195 : );
196 : }
197 :
198 : /// yields true if point is contained in set
199 1833312136 : bool isInside(const B2ITuple& rTuple) const
200 : {
201 : return (
202 1833312136 : maRangeX.isInside(rTuple.getX())
203 1833312136 : && maRangeY.isInside(rTuple.getY())
204 1833312136 : );
205 : }
206 :
207 : /// yields true if rBox is inside, or equal to set
208 : bool isInside(const B2IBox& rBox) const
209 : {
210 : return (
211 : maRangeX.isInside(rBox.maRangeX)
212 : && maRangeY.isInside(rBox.maRangeY)
213 : );
214 : }
215 :
216 : /// yields true if rBox at least partly inside set
217 : bool overlaps(const B2IBox& rBox) const
218 : {
219 : return (
220 : maRangeX.overlaps(rBox.maRangeX)
221 : && maRangeY.overlaps(rBox.maRangeY)
222 : );
223 : }
224 :
225 : /// add point to the set, expanding as necessary
226 5732834 : void expand(const B2ITuple& rTuple)
227 : {
228 5732834 : maRangeX.expand(rTuple.getX());
229 5732834 : maRangeY.expand(rTuple.getY());
230 5732834 : }
231 :
232 : /// add rBox to the set, expanding as necessary
233 : void expand(const B2IBox& rBox)
234 : {
235 : maRangeX.expand(rBox.maRangeX);
236 : maRangeY.expand(rBox.maRangeY);
237 : }
238 :
239 : /// calc set intersection
240 4846949 : void intersect(const B2IBox& rBox)
241 : {
242 4846949 : maRangeX.intersect(rBox.maRangeX);
243 4846949 : maRangeY.intersect(rBox.maRangeY);
244 4846949 : }
245 :
246 : /// grow set by nValue on all sides
247 : void grow(sal_Int32 nValue)
248 : {
249 : maRangeX.grow(nValue);
250 : maRangeY.grow(nValue);
251 : }
252 :
253 : private:
254 : BasicBox maRangeX;
255 : BasicBox maRangeY;
256 : };
257 :
258 : } // end of namespace basegfx
259 :
260 : template< typename charT, typename traits >
261 : inline std::basic_ostream<charT, traits> & operator <<(
262 : std::basic_ostream<charT, traits> & stream, const basegfx::B2IBox& box )
263 : {
264 : if (box.isEmpty())
265 : return stream << "EMPTY";
266 : else
267 : return stream << box.getWidth() << 'x' << box.getHeight()
268 : << "@(" << box.getMinX() << "," << box.getMinY() << ")";
269 : }
270 :
271 : #endif // INCLUDED_BASEGFX_RANGE_B2IBOX_HXX
272 :
273 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|