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