1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
30 //////////////////////////////////////////////////////////////////////////////
32 class ImplB2DPolyPolygon
34 basegfx::B2DPolygonVector maPolygons
;
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())
52 // compare polygon content
53 if(!(maPolygons
== rPolygonList
.maPolygons
))
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
)
73 // add nCount copies of rPolygon
74 basegfx::B2DPolygonVector::iterator
aIndex(maPolygons
.begin());
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());
87 maPolygons
.insert(aIndex
, rPolyPolygon
.begin(), rPolyPolygon
.end());
90 void remove(sal_uInt32 nIndex
, sal_uInt32 nCount
)
94 // remove polygon data
95 basegfx::B2DPolygonVector::iterator
aStart(maPolygons
.begin());
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
);
118 std::for_each( maPolygons
.begin(),
120 std::mem_fun_ref( &basegfx::B2DPolygon::flip
));
123 void removeDoublePoints()
125 std::for_each( maPolygons
.begin(),
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
);
140 std::for_each( maPolygons
.begin(),
142 std::mem_fun_ref( &basegfx::B2DPolygon::makeUnique
));
145 const basegfx::B2DPolygon
* begin() const
147 if(maPolygons
.empty())
150 return &maPolygons
.front();
153 const basegfx::B2DPolygon
* end() const
155 if(maPolygons
.empty())
158 return (&maPolygons
.back())+1;
161 basegfx::B2DPolygon
* begin()
163 if(maPolygons
.empty())
166 return &maPolygons
.front();
169 basegfx::B2DPolygon
* end()
171 if(maPolygons
.empty())
174 return &(maPolygons
.back())+1;
178 //////////////////////////////////////////////////////////////////////////////
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
;
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
))
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())
264 void B2DPolyPolygon::insert(sal_uInt32 nIndex
, const B2DPolygon
& rPolygon
, sal_uInt32 nCount
)
266 OSL_ENSURE(nIndex
<= mpPolyPolygon
->count(), "B2DPolyPolygon Insert outside range (!)");
269 mpPolyPolygon
->insert(nIndex
, rPolygon
, nCount
);
272 void B2DPolyPolygon::append(const B2DPolygon
& rPolygon
, sal_uInt32 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());
290 B2DRange
B2DPolyPolygon::getB2DRange() const
294 for(sal_uInt32
a(0L); a
< mpPolyPolygon
->count(); a
++)
296 aRetval
.expand(mpPolyPolygon
->getB2DPolygon(a
).getB2DRange());
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 (!)");
321 mpPolyPolygon
->remove(nIndex
, nCount
);
324 void B2DPolyPolygon::clear()
326 mpPolyPolygon
= DefaultPolyPolygon::get();
329 bool B2DPolyPolygon::isClosed() const
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())
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
364 for(sal_uInt32
a(0L); !bRetval
&& a
< mpPolyPolygon
->count(); a
++)
366 if((mpPolyPolygon
->getB2DPolygon(a
)).hasDoublePoints())
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: */