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_B2IBOX_HXX
21 : #define _BGFX_RANGE_B2IBOX_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/basicbox.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 most easily depicted as a set of integers, bounded by
37 : a lower and an upper value - but excluding the upper
38 : value. All inbetween values are included in the set (see also
39 : http://en.wikipedia.org/wiki/Interval_%28mathematics%29).
40 :
41 : The set is half-open, i.e. the lower bound is included, the
42 : upper bound not (if you're used to the notation - we're
43 : talking about [a,b) here, compared to closed [a,b] or fully
44 : open intervals (a,b)).
45 :
46 : If you don't need a half-open interval, check B2IRange.
47 :
48 : That means, isInside(val) will return true also for values of
49 : val=a, but not for val=b.
50 :
51 : Alternatively, consider this a rectangle, where the rightmost
52 : pixel column and the bottommost pixel row are excluded - this
53 : is much like polygon filling. As a result, filling a given
54 : rectangle with basebmp::BitmapDevice::fillPolyPolygon(), will
55 : affect exactly the same set of pixel as isInside() would
56 : return true for.
57 :
58 : @see B2IRange
59 : */
60 : class B2IBox
61 : {
62 : public:
63 : typedef sal_Int32 ValueType;
64 : typedef Int32Traits TraitsType;
65 :
66 33214 : B2IBox() {}
67 :
68 : /// Create degenerate interval that's still empty
69 : explicit B2IBox(const B2ITuple& rTuple)
70 : : maRangeX(rTuple.getX()),
71 : maRangeY(rTuple.getY())
72 : {
73 : }
74 :
75 : /// Create proper interval between the two given points
76 68735 : B2IBox(sal_Int32 x1,
77 : sal_Int32 y1,
78 : sal_Int32 x2,
79 : sal_Int32 y2) :
80 : maRangeX(x1),
81 68735 : maRangeY(y1)
82 : {
83 68735 : maRangeX.expand(x2);
84 68735 : maRangeY.expand(y2);
85 68735 : }
86 :
87 : /// Create proper interval between the two given points
88 178564 : B2IBox(const B2ITuple& rTuple1,
89 : const B2ITuple& rTuple2) :
90 : maRangeX(rTuple1.getX()),
91 178564 : maRangeY(rTuple1.getY())
92 : {
93 178564 : expand( rTuple2 );
94 178564 : }
95 :
96 : /** Check if the interval set is empty
97 :
98 : @return false, if no value is in this set - having a
99 : single value included will still return false.
100 : */
101 37449 : bool isEmpty() const
102 : {
103 37449 : return maRangeX.isEmpty() || maRangeY.isEmpty();
104 : }
105 :
106 : /// reset the object to empty state again, clearing all values
107 : void reset()
108 : {
109 : maRangeX.reset();
110 : maRangeY.reset();
111 : }
112 :
113 : bool operator==( const B2IBox& rBox ) const
114 : {
115 : return (maRangeX == rBox.maRangeX
116 : && maRangeY == rBox.maRangeY);
117 : }
118 :
119 : bool operator!=( const B2IBox& rBox ) const
120 : {
121 : return (maRangeX != rBox.maRangeX
122 : || maRangeY != rBox.maRangeY);
123 : }
124 :
125 : /// get lower bound of the set. returns arbitrary values for empty sets.
126 487973 : sal_Int32 getMinX() const
127 : {
128 487973 : return maRangeX.getMinimum();
129 : }
130 :
131 : /// get lower bound of the set. returns arbitrary values for empty sets.
132 487973 : sal_Int32 getMinY() const
133 : {
134 487973 : return maRangeY.getMinimum();
135 : }
136 :
137 : /// get upper bound of the set. returns arbitrary values for empty sets.
138 487965 : sal_Int32 getMaxX() const
139 : {
140 487965 : return maRangeX.getMaximum();
141 : }
142 :
143 : /// get upper bound of the set. returns arbitrary values for empty sets.
144 487965 : sal_Int32 getMaxY() const
145 : {
146 487965 : return maRangeY.getMaximum();
147 : }
148 :
149 : /// return difference between upper and lower X value. returns 0 for empty sets.
150 3908 : sal_Int64 getWidth() const
151 : {
152 3908 : return maRangeX.getRange();
153 : }
154 :
155 : /// return difference between upper and lower Y value. returns 0 for empty sets.
156 3908 : sal_Int64 getHeight() const
157 : {
158 3908 : return maRangeY.getRange();
159 : }
160 :
161 : /// get lower bound of the set. returns arbitrary values for empty sets.
162 69385 : B2IPoint getMinimum() const
163 : {
164 : return B2IPoint(
165 : maRangeX.getMinimum(),
166 : maRangeY.getMinimum()
167 69385 : );
168 : }
169 :
170 : /// get upper bound of the set. returns arbitrary values for empty sets.
171 34691 : B2IPoint getMaximum() const
172 : {
173 : return B2IPoint(
174 : maRangeX.getMaximum(),
175 : maRangeY.getMaximum()
176 34691 : );
177 : }
178 :
179 : /// return difference between upper and lower value. returns (0,0) for empty sets.
180 : B2I64Tuple getRange() const
181 : {
182 : return B2I64Tuple(
183 : maRangeX.getRange(),
184 : maRangeY.getRange()
185 : );
186 : }
187 :
188 : /// return center point of set. returns (0,0) for empty sets.
189 : B2DPoint getCenter() const
190 : {
191 : return B2DPoint(
192 : maRangeX.getCenter(),
193 : maRangeY.getCenter()
194 : );
195 : }
196 :
197 : /// yields true if point is contained in set
198 306121 : bool isInside(const B2ITuple& rTuple) const
199 : {
200 : return (
201 306121 : maRangeX.isInside(rTuple.getX())
202 306073 : && maRangeY.isInside(rTuple.getY())
203 612194 : );
204 : }
205 :
206 : /// yields true if rBox is inside, or equal to set
207 : bool isInside(const B2IBox& rBox) const
208 : {
209 : return (
210 : maRangeX.isInside(rBox.maRangeX)
211 : && maRangeY.isInside(rBox.maRangeY)
212 : );
213 : }
214 :
215 : /// yields true if rBox at least partly inside set
216 : bool overlaps(const B2IBox& rBox) const
217 : {
218 : return (
219 : maRangeX.overlaps(rBox.maRangeX)
220 : && maRangeY.overlaps(rBox.maRangeY)
221 : );
222 : }
223 :
224 : /// add point to the set, expanding as necessary
225 178564 : void expand(const B2ITuple& rTuple)
226 : {
227 178564 : maRangeX.expand(rTuple.getX());
228 178564 : maRangeY.expand(rTuple.getY());
229 178564 : }
230 :
231 : /// add rBox to the set, expanding as necessary
232 : void expand(const B2IBox& rBox)
233 : {
234 : maRangeX.expand(rBox.maRangeX);
235 : maRangeY.expand(rBox.maRangeY);
236 : }
237 :
238 : /// calc set intersection
239 46296 : void intersect(const B2IBox& rBox)
240 : {
241 46296 : maRangeX.intersect(rBox.maRangeX);
242 46296 : maRangeY.intersect(rBox.maRangeY);
243 46296 : }
244 :
245 : /// grow set by nValue on all sides
246 : void grow(sal_Int32 nValue)
247 : {
248 : maRangeX.grow(nValue);
249 : maRangeY.grow(nValue);
250 : }
251 :
252 : private:
253 : BasicBox maRangeX;
254 : BasicBox maRangeY;
255 : };
256 :
257 : } // end of namespace basegfx
258 :
259 : #endif /* _BGFX_RANGE_B2IBOX_HXX */
260 :
261 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|