Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / basegfx / source / polygon / b2dpolypolygon.cxx
blob7075782fe843b1d6723ad058ff9386972e41e56f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <basegfx/polygon/b2dpolypolygon.hxx>
21 #include <osl/diagnose.h>
22 #include <basegfx/polygon/b2dpolygon.hxx>
23 #include <basegfx/polygon/b2dpolypolygontools.hxx>
24 #include <rtl/instance.hxx>
25 #include <basegfx/matrix/b2dhommatrix.hxx>
27 #include <functional>
28 #include <algorithm>
30 //////////////////////////////////////////////////////////////////////////////
32 class ImplB2DPolyPolygon
34 basegfx::B2DPolygonVector maPolygons;
36 public:
37 ImplB2DPolyPolygon() : maPolygons()
41 explicit ImplB2DPolyPolygon(const basegfx::B2DPolygon& rToBeCopied) :
42 maPolygons(1,rToBeCopied)
46 bool operator==(const ImplB2DPolyPolygon& rPolygonList) const
48 // same polygon count?
49 if(maPolygons.size() != rPolygonList.maPolygons.size())
50 return false;
52 // compare polygon content
53 if(!(maPolygons == rPolygonList.maPolygons))
54 return false;
56 return true;
59 const basegfx::B2DPolygon& getB2DPolygon(sal_uInt32 nIndex) const
61 return maPolygons[nIndex];
64 void setB2DPolygon(sal_uInt32 nIndex, const basegfx::B2DPolygon& rPolygon)
66 maPolygons[nIndex] = rPolygon;
69 void insert(sal_uInt32 nIndex, const basegfx::B2DPolygon& rPolygon, sal_uInt32 nCount)
71 if(nCount)
73 // add nCount copies of rPolygon
74 basegfx::B2DPolygonVector::iterator aIndex(maPolygons.begin());
75 if( nIndex )
76 aIndex += nIndex;
77 maPolygons.insert(aIndex, nCount, rPolygon);
81 void insert(sal_uInt32 nIndex, const basegfx::B2DPolyPolygon& rPolyPolygon)
83 // add nCount polygons from rPolyPolygon
84 basegfx::B2DPolygonVector::iterator aIndex(maPolygons.begin());
85 if( nIndex )
86 aIndex += nIndex;
87 maPolygons.insert(aIndex, rPolyPolygon.begin(), rPolyPolygon.end());
90 void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
92 if(nCount)
94 // remove polygon data
95 basegfx::B2DPolygonVector::iterator aStart(maPolygons.begin());
96 aStart += nIndex;
97 const basegfx::B2DPolygonVector::iterator aEnd(aStart + nCount);
99 maPolygons.erase(aStart, aEnd);
103 sal_uInt32 count() const
105 return maPolygons.size();
108 void setClosed(bool bNew)
110 for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
112 maPolygons[a].setClosed(bNew);
116 void flip()
118 std::for_each( maPolygons.begin(),
119 maPolygons.end(),
120 std::mem_fun_ref( &basegfx::B2DPolygon::flip ));
123 void removeDoublePoints()
125 std::for_each( maPolygons.begin(),
126 maPolygons.end(),
127 std::mem_fun_ref( &basegfx::B2DPolygon::removeDoublePoints ));
130 void transform(const basegfx::B2DHomMatrix& rMatrix)
132 for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
134 maPolygons[a].transform(rMatrix);
138 void makeUnique()
140 std::for_each( maPolygons.begin(),
141 maPolygons.end(),
142 std::mem_fun_ref( &basegfx::B2DPolygon::makeUnique ));
145 const basegfx::B2DPolygon* begin() const
147 if(maPolygons.empty())
148 return 0;
149 else
150 return &maPolygons.front();
153 const basegfx::B2DPolygon* end() const
155 if(maPolygons.empty())
156 return 0;
157 else
158 return (&maPolygons.back())+1;
161 basegfx::B2DPolygon* begin()
163 if(maPolygons.empty())
164 return 0;
165 else
166 return &maPolygons.front();
169 basegfx::B2DPolygon* end()
171 if(maPolygons.empty())
172 return 0;
173 else
174 return &(maPolygons.back())+1;
178 //////////////////////////////////////////////////////////////////////////////
180 namespace basegfx
182 namespace { struct DefaultPolyPolygon: public rtl::Static<B2DPolyPolygon::ImplType,
183 DefaultPolyPolygon> {}; }
185 B2DPolyPolygon::B2DPolyPolygon() :
186 mpPolyPolygon(DefaultPolyPolygon::get())
190 B2DPolyPolygon::B2DPolyPolygon(const B2DPolyPolygon& rPolyPolygon) :
191 mpPolyPolygon(rPolyPolygon.mpPolyPolygon)
195 B2DPolyPolygon::B2DPolyPolygon(const B2DPolygon& rPolygon) :
196 mpPolyPolygon( ImplB2DPolyPolygon(rPolygon) )
200 B2DPolyPolygon::~B2DPolyPolygon()
204 B2DPolyPolygon& B2DPolyPolygon::operator=(const B2DPolyPolygon& rPolyPolygon)
206 mpPolyPolygon = rPolyPolygon.mpPolyPolygon;
207 return *this;
210 void B2DPolyPolygon::makeUnique()
212 mpPolyPolygon.make_unique();
213 mpPolyPolygon->makeUnique();
216 bool B2DPolyPolygon::operator==(const B2DPolyPolygon& rPolyPolygon) const
218 if(mpPolyPolygon.same_object(rPolyPolygon.mpPolyPolygon))
219 return true;
221 return ((*mpPolyPolygon) == (*rPolyPolygon.mpPolyPolygon));
224 bool B2DPolyPolygon::operator!=(const B2DPolyPolygon& rPolyPolygon) const
226 return !((*this) == rPolyPolygon);
229 sal_uInt32 B2DPolyPolygon::count() const
231 return mpPolyPolygon->count();
234 B2DPolygon B2DPolyPolygon::getB2DPolygon(sal_uInt32 nIndex) const
236 OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B2DPolyPolygon access outside range (!)");
238 return mpPolyPolygon->getB2DPolygon(nIndex);
241 void B2DPolyPolygon::setB2DPolygon(sal_uInt32 nIndex, const B2DPolygon& rPolygon)
243 OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B2DPolyPolygon access outside range (!)");
245 if(getB2DPolygon(nIndex) != rPolygon)
246 mpPolyPolygon->setB2DPolygon(nIndex, rPolygon);
249 bool B2DPolyPolygon::areControlPointsUsed() const
251 for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
253 const B2DPolygon& rPolygon = mpPolyPolygon->getB2DPolygon(a);
255 if(rPolygon.areControlPointsUsed())
257 return true;
261 return false;
264 void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolygon& rPolygon, sal_uInt32 nCount)
266 OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B2DPolyPolygon Insert outside range (!)");
268 if(nCount)
269 mpPolyPolygon->insert(nIndex, rPolygon, nCount);
272 void B2DPolyPolygon::append(const B2DPolygon& rPolygon, sal_uInt32 nCount)
274 if(nCount)
275 mpPolyPolygon->insert(mpPolyPolygon->count(), rPolygon, nCount);
278 B2DPolyPolygon B2DPolyPolygon::getDefaultAdaptiveSubdivision() const
280 B2DPolyPolygon aRetval;
282 for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
284 aRetval.append(mpPolyPolygon->getB2DPolygon(a).getDefaultAdaptiveSubdivision());
287 return aRetval;
290 B2DRange B2DPolyPolygon::getB2DRange() const
292 B2DRange aRetval;
294 for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
296 aRetval.expand(mpPolyPolygon->getB2DPolygon(a).getB2DRange());
299 return aRetval;
302 void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolyPolygon& rPolyPolygon)
304 OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B2DPolyPolygon Insert outside range (!)");
306 if(rPolyPolygon.count())
307 mpPolyPolygon->insert(nIndex, rPolyPolygon);
310 void B2DPolyPolygon::append(const B2DPolyPolygon& rPolyPolygon)
312 if(rPolyPolygon.count())
313 mpPolyPolygon->insert(mpPolyPolygon->count(), rPolyPolygon);
316 void B2DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
318 OSL_ENSURE(nIndex + nCount <= mpPolyPolygon->count(), "B2DPolyPolygon Remove outside range (!)");
320 if(nCount)
321 mpPolyPolygon->remove(nIndex, nCount);
324 void B2DPolyPolygon::clear()
326 mpPolyPolygon = DefaultPolyPolygon::get();
329 bool B2DPolyPolygon::isClosed() const
331 bool bRetval(true);
333 // PolyPOlygon is closed when all contained Polygons are closed or
334 // no Polygon exists.
335 for(sal_uInt32 a(0L); bRetval && a < mpPolyPolygon->count(); a++)
337 if(!(mpPolyPolygon->getB2DPolygon(a)).isClosed())
339 bRetval = false;
343 return bRetval;
346 void B2DPolyPolygon::setClosed(bool bNew)
348 if(bNew != isClosed())
349 mpPolyPolygon->setClosed(bNew);
352 void B2DPolyPolygon::flip()
354 if(mpPolyPolygon->count())
356 mpPolyPolygon->flip();
360 bool B2DPolyPolygon::hasDoublePoints() const
362 bool bRetval(false);
364 for(sal_uInt32 a(0L); !bRetval && a < mpPolyPolygon->count(); a++)
366 if((mpPolyPolygon->getB2DPolygon(a)).hasDoublePoints())
368 bRetval = true;
372 return bRetval;
375 void B2DPolyPolygon::removeDoublePoints()
377 if(hasDoublePoints())
378 mpPolyPolygon->removeDoublePoints();
381 void B2DPolyPolygon::transform(const B2DHomMatrix& rMatrix)
383 if(mpPolyPolygon->count() && !rMatrix.isIdentity())
385 mpPolyPolygon->transform(rMatrix);
389 const B2DPolygon* B2DPolyPolygon::begin() const
391 return mpPolyPolygon->begin();
394 const B2DPolygon* B2DPolyPolygon::end() const
396 return mpPolyPolygon->end();
399 B2DPolygon* B2DPolyPolygon::begin()
401 return mpPolyPolygon->begin();
404 B2DPolygon* B2DPolyPolygon::end()
406 return mpPolyPolygon->end();
408 } // end of namespace basegfx
410 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */