merged tag ooo/OOO330_m14
[LibreOffice.git] / basegfx / source / polygon / b2dpolypolygon.cxx
blob9b28dffd19af8eeb54d76271152b59457b6de3ea
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basegfx.hxx"
30 #include <basegfx/polygon/b2dpolypolygon.hxx>
31 #include <osl/diagnose.h>
32 #include <basegfx/polygon/b2dpolygon.hxx>
33 #include <basegfx/polygon/b2dpolypolygontools.hxx>
34 #include <rtl/instance.hxx>
35 #include <basegfx/matrix/b2dhommatrix.hxx>
37 #include <functional>
38 #include <vector>
39 #include <algorithm>
41 //////////////////////////////////////////////////////////////////////////////
43 class ImplB2DPolyPolygon
45 typedef ::std::vector< basegfx::B2DPolygon > PolygonVector;
47 PolygonVector maPolygons;
49 public:
50 ImplB2DPolyPolygon() : maPolygons()
54 ImplB2DPolyPolygon(const basegfx::B2DPolygon& rToBeCopied) :
55 maPolygons(1,rToBeCopied)
59 bool operator==(const ImplB2DPolyPolygon& rPolygonList) const
61 // same polygon count?
62 if(maPolygons.size() != rPolygonList.maPolygons.size())
63 return false;
65 // compare polygon content
66 if(!(maPolygons == rPolygonList.maPolygons))
67 return false;
69 return true;
72 const basegfx::B2DPolygon& getB2DPolygon(sal_uInt32 nIndex) const
74 return maPolygons[nIndex];
77 void setB2DPolygon(sal_uInt32 nIndex, const basegfx::B2DPolygon& rPolygon)
79 maPolygons[nIndex] = rPolygon;
82 void insert(sal_uInt32 nIndex, const basegfx::B2DPolygon& rPolygon, sal_uInt32 nCount)
84 if(nCount)
86 // add nCount copies of rPolygon
87 PolygonVector::iterator aIndex(maPolygons.begin());
88 aIndex += nIndex;
89 maPolygons.insert(aIndex, nCount, rPolygon);
93 void insert(sal_uInt32 nIndex, const basegfx::B2DPolyPolygon& rPolyPolygon)
95 const sal_uInt32 nCount = rPolyPolygon.count();
97 if(nCount)
99 // add nCount polygons from rPolyPolygon
100 maPolygons.reserve(maPolygons.size() + nCount);
101 PolygonVector::iterator aIndex(maPolygons.begin());
102 aIndex += nIndex;
104 for(sal_uInt32 a(0L); a < nCount; a++)
106 aIndex = maPolygons.insert(aIndex, rPolyPolygon.getB2DPolygon(a));
107 aIndex++;
112 void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
114 if(nCount)
116 // remove polygon data
117 PolygonVector::iterator aStart(maPolygons.begin());
118 aStart += nIndex;
119 const PolygonVector::iterator aEnd(aStart + nCount);
121 maPolygons.erase(aStart, aEnd);
125 sal_uInt32 count() const
127 return maPolygons.size();
130 void setClosed(bool bNew)
132 for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
134 maPolygons[a].setClosed(bNew);
138 void flip()
140 std::for_each( maPolygons.begin(),
141 maPolygons.end(),
142 std::mem_fun_ref( &basegfx::B2DPolygon::flip ));
145 void removeDoublePoints()
147 std::for_each( maPolygons.begin(),
148 maPolygons.end(),
149 std::mem_fun_ref( &basegfx::B2DPolygon::removeDoublePoints ));
152 void transform(const basegfx::B2DHomMatrix& rMatrix)
154 for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
156 maPolygons[a].transform(rMatrix);
160 void makeUnique()
162 std::for_each( maPolygons.begin(),
163 maPolygons.end(),
164 std::mem_fun_ref( &basegfx::B2DPolygon::makeUnique ));
167 const basegfx::B2DPolygon* begin() const
169 if(maPolygons.empty())
170 return 0;
171 else
172 return &maPolygons.front();
175 const basegfx::B2DPolygon* end() const
177 if(maPolygons.empty())
178 return 0;
179 else
180 return (&maPolygons.back())+1;
183 basegfx::B2DPolygon* begin()
185 if(maPolygons.empty())
186 return 0;
187 else
188 return &maPolygons.front();
191 basegfx::B2DPolygon* end()
193 if(maPolygons.empty())
194 return 0;
195 else
196 return &(maPolygons.back())+1;
200 //////////////////////////////////////////////////////////////////////////////
202 namespace basegfx
204 namespace { struct DefaultPolyPolygon: public rtl::Static<B2DPolyPolygon::ImplType,
205 DefaultPolyPolygon> {}; }
207 B2DPolyPolygon::B2DPolyPolygon() :
208 mpPolyPolygon(DefaultPolyPolygon::get())
212 B2DPolyPolygon::B2DPolyPolygon(const B2DPolyPolygon& rPolyPolygon) :
213 mpPolyPolygon(rPolyPolygon.mpPolyPolygon)
217 B2DPolyPolygon::B2DPolyPolygon(const B2DPolygon& rPolygon) :
218 mpPolyPolygon( ImplB2DPolyPolygon(rPolygon) )
222 B2DPolyPolygon::~B2DPolyPolygon()
226 B2DPolyPolygon& B2DPolyPolygon::operator=(const B2DPolyPolygon& rPolyPolygon)
228 mpPolyPolygon = rPolyPolygon.mpPolyPolygon;
229 return *this;
232 void B2DPolyPolygon::makeUnique()
234 mpPolyPolygon.make_unique();
235 mpPolyPolygon->makeUnique();
238 bool B2DPolyPolygon::operator==(const B2DPolyPolygon& rPolyPolygon) const
240 if(mpPolyPolygon.same_object(rPolyPolygon.mpPolyPolygon))
241 return true;
243 return ((*mpPolyPolygon) == (*rPolyPolygon.mpPolyPolygon));
246 bool B2DPolyPolygon::operator!=(const B2DPolyPolygon& rPolyPolygon) const
248 return !((*this) == rPolyPolygon);
251 sal_uInt32 B2DPolyPolygon::count() const
253 return mpPolyPolygon->count();
256 B2DPolygon B2DPolyPolygon::getB2DPolygon(sal_uInt32 nIndex) const
258 OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B2DPolyPolygon access outside range (!)");
260 return mpPolyPolygon->getB2DPolygon(nIndex);
263 void B2DPolyPolygon::setB2DPolygon(sal_uInt32 nIndex, const B2DPolygon& rPolygon)
265 OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B2DPolyPolygon access outside range (!)");
267 if(getB2DPolygon(nIndex) != rPolygon)
268 mpPolyPolygon->setB2DPolygon(nIndex, rPolygon);
271 bool B2DPolyPolygon::areControlPointsUsed() const
273 for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
275 const B2DPolygon& rPolygon = mpPolyPolygon->getB2DPolygon(a);
277 if(rPolygon.areControlPointsUsed())
279 return true;
283 return false;
286 void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolygon& rPolygon, sal_uInt32 nCount)
288 OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B2DPolyPolygon Insert outside range (!)");
290 if(nCount)
291 mpPolyPolygon->insert(nIndex, rPolygon, nCount);
294 void B2DPolyPolygon::append(const B2DPolygon& rPolygon, sal_uInt32 nCount)
296 if(nCount)
297 mpPolyPolygon->insert(mpPolyPolygon->count(), rPolygon, nCount);
300 B2DPolyPolygon B2DPolyPolygon::getDefaultAdaptiveSubdivision() const
302 B2DPolyPolygon aRetval;
304 for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
306 aRetval.append(mpPolyPolygon->getB2DPolygon(a).getDefaultAdaptiveSubdivision());
309 return aRetval;
312 B2DRange B2DPolyPolygon::getB2DRange() const
314 B2DRange aRetval;
316 for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
318 aRetval.expand(mpPolyPolygon->getB2DPolygon(a).getB2DRange());
321 return aRetval;
324 void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolyPolygon& rPolyPolygon)
326 OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B2DPolyPolygon Insert outside range (!)");
328 if(rPolyPolygon.count())
329 mpPolyPolygon->insert(nIndex, rPolyPolygon);
332 void B2DPolyPolygon::append(const B2DPolyPolygon& rPolyPolygon)
334 if(rPolyPolygon.count())
335 mpPolyPolygon->insert(mpPolyPolygon->count(), rPolyPolygon);
338 void B2DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
340 OSL_ENSURE(nIndex + nCount <= mpPolyPolygon->count(), "B2DPolyPolygon Remove outside range (!)");
342 if(nCount)
343 mpPolyPolygon->remove(nIndex, nCount);
346 void B2DPolyPolygon::clear()
348 mpPolyPolygon = DefaultPolyPolygon::get();
351 bool B2DPolyPolygon::isClosed() const
353 bool bRetval(true);
355 // PolyPOlygon is closed when all contained Polygons are closed or
356 // no Polygon exists.
357 for(sal_uInt32 a(0L); bRetval && a < mpPolyPolygon->count(); a++)
359 if(!(mpPolyPolygon->getB2DPolygon(a)).isClosed())
361 bRetval = false;
365 return bRetval;
368 void B2DPolyPolygon::setClosed(bool bNew)
370 if(bNew != isClosed())
371 mpPolyPolygon->setClosed(bNew);
374 void B2DPolyPolygon::flip()
376 if(mpPolyPolygon->count())
378 mpPolyPolygon->flip();
382 bool B2DPolyPolygon::hasDoublePoints() const
384 bool bRetval(false);
386 for(sal_uInt32 a(0L); !bRetval && a < mpPolyPolygon->count(); a++)
388 if((mpPolyPolygon->getB2DPolygon(a)).hasDoublePoints())
390 bRetval = true;
394 return bRetval;
397 void B2DPolyPolygon::removeDoublePoints()
399 if(hasDoublePoints())
400 mpPolyPolygon->removeDoublePoints();
403 void B2DPolyPolygon::transform(const B2DHomMatrix& rMatrix)
405 if(mpPolyPolygon->count() && !rMatrix.isIdentity())
407 mpPolyPolygon->transform(rMatrix);
411 const B2DPolygon* B2DPolyPolygon::begin() const
413 return mpPolyPolygon->begin();
416 const B2DPolygon* B2DPolyPolygon::end() const
418 return mpPolyPolygon->end();
421 B2DPolygon* B2DPolyPolygon::begin()
423 return mpPolyPolygon->begin();
426 B2DPolygon* B2DPolyPolygon::end()
428 return mpPolyPolygon->end();
430 } // end of namespace basegfx
432 // eof