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>
41 //////////////////////////////////////////////////////////////////////////////
43 class ImplB2DPolyPolygon
45 typedef ::std::vector
< basegfx::B2DPolygon
> PolygonVector
;
47 PolygonVector maPolygons
;
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())
65 // compare polygon content
66 if(!(maPolygons
== rPolygonList
.maPolygons
))
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
)
86 // add nCount copies of rPolygon
87 PolygonVector::iterator
aIndex(maPolygons
.begin());
89 maPolygons
.insert(aIndex
, nCount
, rPolygon
);
93 void insert(sal_uInt32 nIndex
, const basegfx::B2DPolyPolygon
& rPolyPolygon
)
95 const sal_uInt32 nCount
= rPolyPolygon
.count();
99 // add nCount polygons from rPolyPolygon
100 maPolygons
.reserve(maPolygons
.size() + nCount
);
101 PolygonVector::iterator
aIndex(maPolygons
.begin());
104 for(sal_uInt32
a(0L); a
< nCount
; a
++)
106 aIndex
= maPolygons
.insert(aIndex
, rPolyPolygon
.getB2DPolygon(a
));
112 void remove(sal_uInt32 nIndex
, sal_uInt32 nCount
)
116 // remove polygon data
117 PolygonVector::iterator
aStart(maPolygons
.begin());
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
);
140 std::for_each( maPolygons
.begin(),
142 std::mem_fun_ref( &basegfx::B2DPolygon::flip
));
145 void removeDoublePoints()
147 std::for_each( maPolygons
.begin(),
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
);
162 std::for_each( maPolygons
.begin(),
164 std::mem_fun_ref( &basegfx::B2DPolygon::makeUnique
));
167 const basegfx::B2DPolygon
* begin() const
169 if(maPolygons
.empty())
172 return &maPolygons
.front();
175 const basegfx::B2DPolygon
* end() const
177 if(maPolygons
.empty())
180 return (&maPolygons
.back())+1;
183 basegfx::B2DPolygon
* begin()
185 if(maPolygons
.empty())
188 return &maPolygons
.front();
191 basegfx::B2DPolygon
* end()
193 if(maPolygons
.empty())
196 return &(maPolygons
.back())+1;
200 //////////////////////////////////////////////////////////////////////////////
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
;
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
))
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())
286 void B2DPolyPolygon::insert(sal_uInt32 nIndex
, const B2DPolygon
& rPolygon
, sal_uInt32 nCount
)
288 OSL_ENSURE(nIndex
<= mpPolyPolygon
->count(), "B2DPolyPolygon Insert outside range (!)");
291 mpPolyPolygon
->insert(nIndex
, rPolygon
, nCount
);
294 void B2DPolyPolygon::append(const B2DPolygon
& rPolygon
, sal_uInt32 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());
312 B2DRange
B2DPolyPolygon::getB2DRange() const
316 for(sal_uInt32
a(0L); a
< mpPolyPolygon
->count(); a
++)
318 aRetval
.expand(mpPolyPolygon
->getB2DPolygon(a
).getB2DRange());
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 (!)");
343 mpPolyPolygon
->remove(nIndex
, nCount
);
346 void B2DPolyPolygon::clear()
348 mpPolyPolygon
= DefaultPolyPolygon::get();
351 bool B2DPolyPolygon::isClosed() const
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())
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
386 for(sal_uInt32
a(0L); !bRetval
&& a
< mpPolyPolygon
->count(); a
++)
388 if((mpPolyPolygon
->getB2DPolygon(a
)).hasDoublePoints())
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