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 $
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>
45 static basegfx::B2VectorOrientation
flipOrientation(
46 basegfx::B2VectorOrientation eOrient
)
48 return eOrient
== basegfx::ORIENTATION_POSITIVE
?
49 basegfx::ORIENTATION_NEGATIVE
: basegfx::ORIENTATION_POSITIVE
;
54 class ImplB2DPolyRange
59 std::for_each(maRanges
.begin(),
62 (void (B2DRange::*)(const B2DRange
&))(
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
) :
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
],
103 void setElement(sal_uInt32 nIndex
, const B2DPolyRange::ElementType
& rElement
)
105 maRanges
[nIndex
] = boost::get
<0>(rElement
);
106 maOrient
[nIndex
] = boost::get
<1>(rElement
);
110 void setElement(sal_uInt32 nIndex
, const B2DRange
& rRange
, B2VectorOrientation eOrient
)
112 maRanges
[nIndex
] = rRange
;
113 maOrient
[nIndex
] = eOrient
;
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());
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());
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
);
172 std::vector
<B2DRange
> aTmpRanges
;
173 std::vector
<B2VectorOrientation
> aTmpOrient
;
175 maRanges
.swap(aTmpRanges
);
176 maOrient
.swap(aTmpOrient
);
183 std::for_each(maOrient
.begin(),
190 B2DRange
getBounds() const
195 template< typename ValueType
> bool isInside( const ValueType
& rValue
) const
197 if( !maBounds
.isInside( rValue
) )
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
) )
212 bool overlaps( const B2DRange
& rRange
) const
214 if( !maBounds
.overlaps( rRange
) )
217 const std::vector
<B2DRange
>::const_iterator
aEnd( maRanges
.end() );
218 return std::find_if( maRanges
.begin(),
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
235 return &maRanges
.front();
238 const B2DRange
* end() const
243 return (&maRanges
.back())+1;
251 return &maRanges
.front();
259 return (&maRanges
.back())+1;
264 std::vector
<B2DRange
> maRanges
;
265 std::vector
<B2VectorOrientation
> maOrient
;
268 B2DPolyRange::B2DPolyRange() :
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
;
293 void B2DPolyRange::makeUnique()
295 mpImpl
.make_unique();
298 bool B2DPolyRange::operator==(const B2DPolyRange
& rRange
) const
300 if(mpImpl
.same_object(rRange
.mpImpl
))
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()
371 void B2DPolyRange::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