merged tag ooo/OOO330_m14
[LibreOffice.git] / basegfx / source / range / b2dpolyrange.cxx
blobe212e083ef554318f4292b0be9b6238421c899d7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: b2dmultirange.cxx,v $
10 * $Revision: 1.8 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basegfx.hxx"
33 #include <basegfx/range/b2dpolyrange.hxx>
35 #include <basegfx/range/b2drange.hxx>
36 #include <basegfx/range/b2drangeclipper.hxx>
37 #include <basegfx/tuple/b2dtuple.hxx>
38 #include <basegfx/polygon/b2dpolypolygon.hxx>
40 #include <boost/bind.hpp>
41 #include <boost/tuple/tuple.hpp>
42 #include <algorithm>
43 #include <vector>
45 static basegfx::B2VectorOrientation flipOrientation(
46 basegfx::B2VectorOrientation eOrient)
48 return eOrient == basegfx::ORIENTATION_POSITIVE ?
49 basegfx::ORIENTATION_NEGATIVE : basegfx::ORIENTATION_POSITIVE;
52 namespace basegfx
54 class ImplB2DPolyRange
56 void updateBounds()
58 maBounds.reset();
59 std::for_each(maRanges.begin(),
60 maRanges.end(),
61 boost::bind(
62 (void (B2DRange::*)(const B2DRange&))(
63 &B2DRange::expand),
64 boost::ref(maBounds),
65 _1));
68 public:
69 ImplB2DPolyRange() :
70 maBounds(),
71 maRanges(),
72 maOrient()
75 explicit ImplB2DPolyRange( const B2DPolyRange::ElementType& rElem ) :
76 maBounds( boost::get<0>(rElem) ),
77 maRanges( 1, boost::get<0>(rElem) ),
78 maOrient( 1, boost::get<1>(rElem) )
81 explicit ImplB2DPolyRange( const B2DRange& rRange, B2VectorOrientation eOrient ) :
82 maBounds( rRange ),
83 maRanges( 1, rRange ),
84 maOrient( 1, eOrient )
87 bool operator==(const ImplB2DPolyRange& rRHS) const
89 return maRanges == rRHS.maRanges && maOrient == rRHS.maOrient;
92 sal_uInt32 count() const
94 return maRanges.size();
97 B2DPolyRange::ElementType getElement(sal_uInt32 nIndex) const
99 return boost::make_tuple(maRanges[nIndex],
100 maOrient[nIndex]);
103 void setElement(sal_uInt32 nIndex, const B2DPolyRange::ElementType& rElement )
105 maRanges[nIndex] = boost::get<0>(rElement);
106 maOrient[nIndex] = boost::get<1>(rElement);
107 updateBounds();
110 void setElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient )
112 maRanges[nIndex] = rRange;
113 maOrient[nIndex] = eOrient;
114 updateBounds();
117 void insertElement(sal_uInt32 nIndex, const B2DPolyRange::ElementType& rElement, sal_uInt32 nCount)
119 maRanges.insert(maRanges.begin()+nIndex, nCount, boost::get<0>(rElement));
120 maOrient.insert(maOrient.begin()+nIndex, nCount, boost::get<1>(rElement));
121 maBounds.expand(boost::get<0>(rElement));
124 void insertElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount)
126 maRanges.insert(maRanges.begin()+nIndex, nCount, rRange);
127 maOrient.insert(maOrient.begin()+nIndex, nCount, eOrient);
128 maBounds.expand(rRange);
131 void appendElement(const B2DPolyRange::ElementType& rElement, sal_uInt32 nCount)
133 maRanges.insert(maRanges.end(), nCount, boost::get<0>(rElement));
134 maOrient.insert(maOrient.end(), nCount, boost::get<1>(rElement));
135 maBounds.expand(boost::get<0>(rElement));
138 void appendElement(const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount)
140 maRanges.insert(maRanges.end(), nCount, rRange);
141 maOrient.insert(maOrient.end(), nCount, eOrient);
142 maBounds.expand(rRange);
145 void insertPolyRange(sal_uInt32 nIndex, const ImplB2DPolyRange& rPolyRange)
147 maRanges.insert(maRanges.begin()+nIndex, rPolyRange.maRanges.begin(), rPolyRange.maRanges.end());
148 maOrient.insert(maOrient.begin()+nIndex, rPolyRange.maOrient.begin(), rPolyRange.maOrient.end());
149 updateBounds();
152 void appendPolyRange(const ImplB2DPolyRange& rPolyRange)
154 maRanges.insert(maRanges.end(),
155 rPolyRange.maRanges.begin(),
156 rPolyRange.maRanges.end());
157 maOrient.insert(maOrient.end(),
158 rPolyRange.maOrient.begin(),
159 rPolyRange.maOrient.end());
160 updateBounds();
163 void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
165 maRanges.erase(maRanges.begin()+nIndex,maRanges.begin()+nIndex+nCount);
166 maOrient.erase(maOrient.begin()+nIndex,maOrient.begin()+nIndex+nCount);
167 updateBounds();
170 void clear()
172 std::vector<B2DRange> aTmpRanges;
173 std::vector<B2VectorOrientation> aTmpOrient;
175 maRanges.swap(aTmpRanges);
176 maOrient.swap(aTmpOrient);
178 maBounds.reset();
181 void flip()
183 std::for_each(maOrient.begin(),
184 maOrient.end(),
185 boost::bind(
186 &flipOrientation,
187 _1));
190 B2DRange getBounds() const
192 return maBounds;
195 template< typename ValueType > bool isInside( const ValueType& rValue ) const
197 if( !maBounds.isInside( rValue ) )
198 return false;
200 // cannot use boost::bind here, since isInside is overloaded.
201 // It is currently not possible to resolve the overload
202 // by considering one of the other template arguments.
203 std::vector<B2DRange>::const_iterator aCurr( maRanges.begin() );
204 const std::vector<B2DRange>::const_iterator aEnd ( maRanges.end() );
205 while( aCurr != aEnd )
206 if( aCurr->isInside( rValue ) )
207 return true;
209 return false;
212 bool overlaps( const B2DRange& rRange ) const
214 if( !maBounds.overlaps( rRange ) )
215 return false;
217 const std::vector<B2DRange>::const_iterator aEnd( maRanges.end() );
218 return std::find_if( maRanges.begin(),
219 aEnd,
220 boost::bind<bool>( boost::mem_fn( &B2DRange::overlaps ),
222 boost::cref(rRange) ) ) != aEnd;
225 B2DPolyPolygon solveCrossovers() const
227 return tools::solveCrossovers(maRanges,maOrient);
230 const B2DRange* begin() const
232 if(maRanges.empty())
233 return 0;
234 else
235 return &maRanges.front();
238 const B2DRange* end() const
240 if(maRanges.empty())
241 return 0;
242 else
243 return (&maRanges.back())+1;
246 B2DRange* begin()
248 if(maRanges.empty())
249 return 0;
250 else
251 return &maRanges.front();
254 B2DRange* end()
256 if(maRanges.empty())
257 return 0;
258 else
259 return (&maRanges.back())+1;
262 private:
263 B2DRange maBounds;
264 std::vector<B2DRange> maRanges;
265 std::vector<B2VectorOrientation> maOrient;
268 B2DPolyRange::B2DPolyRange() :
269 mpImpl()
272 B2DPolyRange::~B2DPolyRange()
275 B2DPolyRange::B2DPolyRange( const ElementType& rElem ) :
276 mpImpl( ImplB2DPolyRange( rElem ) )
279 B2DPolyRange::B2DPolyRange( const B2DRange& rRange, B2VectorOrientation eOrient ) :
280 mpImpl( ImplB2DPolyRange( rRange, eOrient ) )
283 B2DPolyRange::B2DPolyRange( const B2DPolyRange& rRange ) :
284 mpImpl( rRange.mpImpl )
287 B2DPolyRange& B2DPolyRange::operator=( const B2DPolyRange& rRange )
289 mpImpl = rRange.mpImpl;
290 return *this;
293 void B2DPolyRange::makeUnique()
295 mpImpl.make_unique();
298 bool B2DPolyRange::operator==(const B2DPolyRange& rRange) const
300 if(mpImpl.same_object(rRange.mpImpl))
301 return true;
303 return ((*mpImpl) == (*rRange.mpImpl));
306 bool B2DPolyRange::operator!=(const B2DPolyRange& rRange) const
308 return !(*this == rRange);
311 sal_uInt32 B2DPolyRange::count() const
313 return mpImpl->count();
316 B2DPolyRange::ElementType B2DPolyRange::getElement(sal_uInt32 nIndex) const
318 return mpImpl->getElement(nIndex);
321 void B2DPolyRange::setElement(sal_uInt32 nIndex, const ElementType& rElement )
323 mpImpl->setElement(nIndex, rElement);
326 void B2DPolyRange::setElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient )
328 mpImpl->setElement(nIndex, rRange, eOrient );
331 void B2DPolyRange::insertElement(sal_uInt32 nIndex, const ElementType& rElement, sal_uInt32 nCount)
333 mpImpl->insertElement(nIndex, rElement, nCount );
336 void B2DPolyRange::insertElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount)
338 mpImpl->insertElement(nIndex, rRange, eOrient, nCount );
341 void B2DPolyRange::appendElement(const ElementType& rElement, sal_uInt32 nCount)
343 mpImpl->appendElement(rElement, nCount);
346 void B2DPolyRange::appendElement(const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount)
348 mpImpl->appendElement(rRange, eOrient, nCount );
351 void B2DPolyRange::insertPolyRange(sal_uInt32 nIndex, const B2DPolyRange& rRange)
353 mpImpl->insertPolyRange(nIndex, *rRange.mpImpl);
356 void B2DPolyRange::appendPolyRange(const B2DPolyRange& rRange)
358 mpImpl->appendPolyRange(*rRange.mpImpl);
361 void B2DPolyRange::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
363 mpImpl->remove(nIndex, nCount);
366 void B2DPolyRange::clear()
368 mpImpl->clear();
371 void B2DPolyRange::flip()
373 mpImpl->flip();
376 B2DRange B2DPolyRange::getBounds() const
378 return mpImpl->getBounds();
381 bool B2DPolyRange::isInside( const B2DTuple& rTuple ) const
383 return mpImpl->isInside(rTuple);
386 bool B2DPolyRange::isInside( const B2DRange& rRange ) const
388 return mpImpl->isInside(rRange);
391 bool B2DPolyRange::overlaps( const B2DRange& rRange ) const
393 return mpImpl->overlaps(rRange);
396 B2DPolyPolygon B2DPolyRange::solveCrossovers() const
398 return mpImpl->solveCrossovers();
401 const B2DRange* B2DPolyRange::begin() const
403 return mpImpl->begin();
406 const B2DRange* B2DPolyRange::end() const
408 return mpImpl->end();
411 B2DRange* B2DPolyRange::begin()
413 return mpImpl->begin();
416 B2DRange* B2DPolyRange::end()
418 return mpImpl->end();
421 } // end of namespace basegfx
423 // eof