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_B2IRANGE_HXX
21 : #define INCLUDED_BASEGFX_RANGE_B2IRANGE_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/basicrange.hxx>
31 : #include <basegfx/basegfxdllapi.h>
32 :
33 : namespace basegfx
34 : {
35 : /** A two-dimensional interval over integers
36 :
37 : This is a set of real numbers, bounded by a lower and an upper
38 : pair. All inbetween values are included in the set (see also
39 : http://en.wikipedia.org/wiki/Interval_%28mathematics%29).
40 :
41 : Probably you rather want B2IBox for integers.
42 :
43 : The set is closed, i.e. the upper and the lower bound are
44 : included (if you're used to the notation - we're talking about
45 : [a,b] here, compared to half-open [a,b) or open intervals
46 : (a,b)).
47 :
48 : That means, isInside(val) will return true also for values of
49 : val=a or val=b.
50 :
51 : @see B2IBox
52 : */
53 : class B2IRange
54 : {
55 : public:
56 : typedef sal_Int32 ValueType;
57 : typedef Int32Traits TraitsType;
58 :
59 0 : B2IRange() {}
60 :
61 : /// Create degenerate interval consisting of a single point
62 : explicit B2IRange(const B2ITuple& rTuple)
63 : : maRangeX(rTuple.getX()),
64 : maRangeY(rTuple.getY())
65 : {
66 : }
67 :
68 : /// Create proper interval between the two given integer pairs
69 0 : B2IRange(sal_Int32 x1,
70 : sal_Int32 y1,
71 : sal_Int32 x2,
72 : sal_Int32 y2)
73 : : maRangeX(x1),
74 0 : maRangeY(y1)
75 : {
76 0 : maRangeX.expand(x2);
77 0 : maRangeY.expand(y2);
78 0 : }
79 :
80 : /// Create proper interval between the two given points
81 0 : B2IRange(const B2ITuple& rTuple1,
82 : const B2ITuple& rTuple2)
83 : : maRangeX(rTuple1.getX()),
84 0 : maRangeY(rTuple1.getY())
85 : {
86 0 : expand( rTuple2 );
87 0 : }
88 :
89 : /** Check if the interval set is empty
90 :
91 : @return false, if no value is in this set - having a
92 : single point included will already return true.
93 : */
94 0 : bool isEmpty() const
95 : {
96 0 : return maRangeX.isEmpty() || maRangeY.isEmpty();
97 : }
98 :
99 : /// reset the object to empty state again, clearing all values
100 0 : void reset()
101 : {
102 0 : maRangeX.reset();
103 0 : maRangeY.reset();
104 0 : }
105 :
106 : bool operator==( const B2IRange& rRange ) const
107 : {
108 : return (maRangeX == rRange.maRangeX
109 : && maRangeY == rRange.maRangeY);
110 : }
111 :
112 0 : bool operator!=( const B2IRange& rRange ) const
113 : {
114 0 : return (maRangeX != rRange.maRangeX
115 0 : || maRangeY != rRange.maRangeY);
116 : }
117 :
118 : /// get lower bound of the set. returns arbitrary values for empty sets.
119 0 : sal_Int32 getMinX() const
120 : {
121 0 : return maRangeX.getMinimum();
122 : }
123 :
124 : /// get lower bound of the set. returns arbitrary values for empty sets.
125 0 : sal_Int32 getMinY() const
126 : {
127 0 : return maRangeY.getMinimum();
128 : }
129 :
130 : /// get upper bound of the set. returns arbitrary values for empty sets.
131 0 : sal_Int32 getMaxX() const
132 : {
133 0 : return maRangeX.getMaximum();
134 : }
135 :
136 : /// get upper bound of the set. returns arbitrary values for empty sets.
137 0 : sal_Int32 getMaxY() const
138 : {
139 0 : return maRangeY.getMaximum();
140 : }
141 :
142 : /// return difference between upper and lower X value. returns 0 for empty sets.
143 0 : sal_Int64 getWidth() const
144 : {
145 0 : return maRangeX.getRange();
146 : }
147 :
148 : /// return difference between upper and lower Y value. returns 0 for empty sets.
149 0 : sal_Int64 getHeight() const
150 : {
151 0 : return maRangeY.getRange();
152 : }
153 :
154 : /// get lower bound of the set. returns arbitrary values for empty sets.
155 0 : B2IPoint getMinimum() const
156 : {
157 : return B2IPoint(
158 : maRangeX.getMinimum(),
159 : maRangeY.getMinimum()
160 0 : );
161 : }
162 :
163 : /// get upper bound of the set. returns arbitrary values for empty sets.
164 0 : B2IPoint getMaximum() const
165 : {
166 : return B2IPoint(
167 : maRangeX.getMaximum(),
168 : maRangeY.getMaximum()
169 0 : );
170 : }
171 :
172 : /// return difference between upper and lower point. returns (0,0) for empty sets.
173 0 : B2I64Tuple getRange() const
174 : {
175 : return B2I64Tuple(
176 : maRangeX.getRange(),
177 : maRangeY.getRange()
178 0 : );
179 : }
180 :
181 : /// return center point of set. returns (0,0) for empty sets.
182 : B2DPoint getCenter() const
183 : {
184 : return B2DPoint(
185 : maRangeX.getCenter(),
186 : maRangeY.getCenter()
187 : );
188 : }
189 :
190 : /// yields true if given point is contained in set
191 0 : bool isInside(const B2ITuple& rTuple) const
192 : {
193 : return (
194 0 : maRangeX.isInside(rTuple.getX())
195 0 : && maRangeY.isInside(rTuple.getY())
196 0 : );
197 : }
198 :
199 : /// yields true if rRange is inside, or equal to set
200 : bool isInside(const B2IRange& rRange) const
201 : {
202 : return (
203 : maRangeX.isInside(rRange.maRangeX)
204 : && maRangeY.isInside(rRange.maRangeY)
205 : );
206 : }
207 :
208 : /// yields true if rRange at least partly inside set
209 : bool overlaps(const B2IRange& rRange) const
210 : {
211 : return (
212 : maRangeX.overlaps(rRange.maRangeX)
213 : && maRangeY.overlaps(rRange.maRangeY)
214 : );
215 : }
216 :
217 : /// yields true if overlaps(rRange) does, and the overlap is larger than infinitesimal
218 : bool overlapsMore(const B2IRange& rRange) const
219 : {
220 : return (
221 : maRangeX.overlapsMore(rRange.maRangeX)
222 : && maRangeY.overlapsMore(rRange.maRangeY)
223 : );
224 : }
225 :
226 : /// add point to the set, expanding as necessary
227 0 : void expand(const B2ITuple& rTuple)
228 : {
229 0 : maRangeX.expand(rTuple.getX());
230 0 : maRangeY.expand(rTuple.getY());
231 0 : }
232 :
233 : /// add rRange to the set, expanding as necessary
234 : void expand(const B2IRange& rRange)
235 : {
236 : maRangeX.expand(rRange.maRangeX);
237 : maRangeY.expand(rRange.maRangeY);
238 : }
239 :
240 : /// calc set intersection
241 0 : void intersect(const B2IRange& rRange)
242 : {
243 0 : maRangeX.intersect(rRange.maRangeX);
244 0 : maRangeY.intersect(rRange.maRangeY);
245 0 : }
246 :
247 : /// grow set by nValue on all sides
248 : void grow(sal_Int32 nValue)
249 : {
250 : maRangeX.grow(nValue);
251 : maRangeY.grow(nValue);
252 : }
253 :
254 : private:
255 : typedef ::basegfx::BasicRange< ValueType, TraitsType > MyBasicRange;
256 :
257 : MyBasicRange maRangeX;
258 : MyBasicRange maRangeY;
259 : };
260 :
261 : /** Compute the set difference of the two given ranges
262 :
263 : This method calculates the symmetric difference (aka XOR)
264 : between the two given ranges, and returning the resulting
265 : ranges. Thus, the result will contain all areas where one, but
266 : not both ranges lie.
267 :
268 : @param o_rResult
269 : Result vector. The up to four difference ranges are returned
270 : within this vector
271 :
272 : @param rFirst
273 : The first range
274 :
275 : @param rSecond
276 : The second range
277 :
278 : @return the input vector
279 : */
280 : BASEGFX_DLLPUBLIC ::std::vector< B2IRange >& computeSetDifference( ::std::vector< B2IRange >& o_rResult,
281 : const B2IRange& rFirst,
282 : const B2IRange& rSecond );
283 :
284 : } // end of namespace basegfx
285 :
286 : template< typename charT, typename traits >
287 : inline std::basic_ostream<charT, traits> & operator <<(
288 : std::basic_ostream<charT, traits> & stream, const basegfx::B2IRange& range )
289 : {
290 : if (range.isEmpty())
291 : return stream << "EMPTY";
292 : else
293 : return stream << range.getWidth() << 'x' << range.getHeight()
294 : << "@(" << range.getMinX() << "," << range.getMinY() << ")";
295 : }
296 :
297 : #endif // INCLUDED_BASEGFX_RANGE_B2IRANGE_HXX
298 :
299 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|