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: b2dpolypolygon.cxx,v $
10 * $Revision: 1.21.4.1 $
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/polygon/b2dpolypolygon.hxx>
34 #include <osl/diagnose.h>
35 #include <basegfx/polygon/b2dpolygon.hxx>
36 #include <basegfx/polygon/b2dpolypolygontools.hxx>
37 #include <rtl/instance.hxx>
38 #include <basegfx/matrix/b2dhommatrix.hxx>
44 //////////////////////////////////////////////////////////////////////////////
46 class ImplB2DPolyPolygon
48 typedef ::std::vector
< basegfx::B2DPolygon
> PolygonVector
;
50 PolygonVector maPolygons
;
53 ImplB2DPolyPolygon() : maPolygons()
57 ImplB2DPolyPolygon(const basegfx::B2DPolygon
& rToBeCopied
) :
58 maPolygons(1,rToBeCopied
)
62 bool operator==(const ImplB2DPolyPolygon
& rPolygonList
) const
64 // same polygon count?
65 if(maPolygons
.size() != rPolygonList
.maPolygons
.size())
68 // compare polygon content
69 if(!(maPolygons
== rPolygonList
.maPolygons
))
75 const basegfx::B2DPolygon
& getB2DPolygon(sal_uInt32 nIndex
) const
77 return maPolygons
[nIndex
];
80 void setB2DPolygon(sal_uInt32 nIndex
, const basegfx::B2DPolygon
& rPolygon
)
82 maPolygons
[nIndex
] = rPolygon
;
85 void insert(sal_uInt32 nIndex
, const basegfx::B2DPolygon
& rPolygon
, sal_uInt32 nCount
)
89 // add nCount copies of rPolygon
90 PolygonVector::iterator
aIndex(maPolygons
.begin());
92 maPolygons
.insert(aIndex
, nCount
, rPolygon
);
96 void insert(sal_uInt32 nIndex
, const basegfx::B2DPolyPolygon
& rPolyPolygon
)
98 const sal_uInt32 nCount
= rPolyPolygon
.count();
102 // add nCount polygons from rPolyPolygon
103 maPolygons
.reserve(maPolygons
.size() + nCount
);
104 PolygonVector::iterator
aIndex(maPolygons
.begin());
107 for(sal_uInt32
a(0L); a
< nCount
; a
++)
109 aIndex
= maPolygons
.insert(aIndex
, rPolyPolygon
.getB2DPolygon(a
));
115 void remove(sal_uInt32 nIndex
, sal_uInt32 nCount
)
119 // remove polygon data
120 PolygonVector::iterator
aStart(maPolygons
.begin());
122 const PolygonVector::iterator
aEnd(aStart
+ nCount
);
124 maPolygons
.erase(aStart
, aEnd
);
128 sal_uInt32
count() const
130 return maPolygons
.size();
133 void setClosed(bool bNew
)
135 for(sal_uInt32
a(0L); a
< maPolygons
.size(); a
++)
137 maPolygons
[a
].setClosed(bNew
);
143 std::for_each( maPolygons
.begin(),
145 std::mem_fun_ref( &basegfx::B2DPolygon::flip
));
148 void removeDoublePoints()
150 std::for_each( maPolygons
.begin(),
152 std::mem_fun_ref( &basegfx::B2DPolygon::removeDoublePoints
));
155 void transform(const basegfx::B2DHomMatrix
& rMatrix
)
157 for(sal_uInt32
a(0L); a
< maPolygons
.size(); a
++)
159 maPolygons
[a
].transform(rMatrix
);
165 std::for_each( maPolygons
.begin(),
167 std::mem_fun_ref( &basegfx::B2DPolygon::makeUnique
));
171 //////////////////////////////////////////////////////////////////////////////
175 namespace { struct DefaultPolyPolygon
: public rtl::Static
<B2DPolyPolygon::ImplType
,
176 DefaultPolyPolygon
> {}; }
178 B2DPolyPolygon::B2DPolyPolygon() :
179 mpPolyPolygon(DefaultPolyPolygon::get())
183 B2DPolyPolygon::B2DPolyPolygon(const B2DPolyPolygon
& rPolyPolygon
) :
184 mpPolyPolygon(rPolyPolygon
.mpPolyPolygon
)
188 B2DPolyPolygon::B2DPolyPolygon(const B2DPolygon
& rPolygon
) :
189 mpPolyPolygon( ImplB2DPolyPolygon(rPolygon
) )
193 B2DPolyPolygon::~B2DPolyPolygon()
197 B2DPolyPolygon
& B2DPolyPolygon::operator=(const B2DPolyPolygon
& rPolyPolygon
)
199 mpPolyPolygon
= rPolyPolygon
.mpPolyPolygon
;
203 void B2DPolyPolygon::makeUnique()
205 mpPolyPolygon
.make_unique();
206 mpPolyPolygon
->makeUnique();
209 bool B2DPolyPolygon::operator==(const B2DPolyPolygon
& rPolyPolygon
) const
211 if(mpPolyPolygon
.same_object(rPolyPolygon
.mpPolyPolygon
))
214 return ((*mpPolyPolygon
) == (*rPolyPolygon
.mpPolyPolygon
));
217 bool B2DPolyPolygon::operator!=(const B2DPolyPolygon
& rPolyPolygon
) const
219 return !((*this) == rPolyPolygon
);
222 sal_uInt32
B2DPolyPolygon::count() const
224 return mpPolyPolygon
->count();
227 B2DPolygon
B2DPolyPolygon::getB2DPolygon(sal_uInt32 nIndex
) const
229 OSL_ENSURE(nIndex
< mpPolyPolygon
->count(), "B2DPolyPolygon access outside range (!)");
231 return mpPolyPolygon
->getB2DPolygon(nIndex
);
234 void B2DPolyPolygon::setB2DPolygon(sal_uInt32 nIndex
, const B2DPolygon
& rPolygon
)
236 OSL_ENSURE(nIndex
< mpPolyPolygon
->count(), "B2DPolyPolygon access outside range (!)");
238 if(getB2DPolygon(nIndex
) != rPolygon
)
239 mpPolyPolygon
->setB2DPolygon(nIndex
, rPolygon
);
242 bool B2DPolyPolygon::areControlPointsUsed() const
244 for(sal_uInt32
a(0L); a
< mpPolyPolygon
->count(); a
++)
246 const B2DPolygon
& rPolygon
= mpPolyPolygon
->getB2DPolygon(a
);
248 if(rPolygon
.areControlPointsUsed())
257 void B2DPolyPolygon::insert(sal_uInt32 nIndex
, const B2DPolygon
& rPolygon
, sal_uInt32 nCount
)
259 OSL_ENSURE(nIndex
<= mpPolyPolygon
->count(), "B2DPolyPolygon Insert outside range (!)");
262 mpPolyPolygon
->insert(nIndex
, rPolygon
, nCount
);
265 void B2DPolyPolygon::append(const B2DPolygon
& rPolygon
, sal_uInt32 nCount
)
268 mpPolyPolygon
->insert(mpPolyPolygon
->count(), rPolygon
, nCount
);
271 B2DPolyPolygon
B2DPolyPolygon::getDefaultAdaptiveSubdivision() const
273 B2DPolyPolygon aRetval
;
275 for(sal_uInt32
a(0L); a
< mpPolyPolygon
->count(); a
++)
277 aRetval
.append(mpPolyPolygon
->getB2DPolygon(a
).getDefaultAdaptiveSubdivision());
283 B2DRange
B2DPolyPolygon::getB2DRange() const
287 for(sal_uInt32
a(0L); a
< mpPolyPolygon
->count(); a
++)
289 aRetval
.expand(mpPolyPolygon
->getB2DPolygon(a
).getB2DRange());
295 void B2DPolyPolygon::insert(sal_uInt32 nIndex
, const B2DPolyPolygon
& rPolyPolygon
)
297 OSL_ENSURE(nIndex
<= mpPolyPolygon
->count(), "B2DPolyPolygon Insert outside range (!)");
299 if(rPolyPolygon
.count())
300 mpPolyPolygon
->insert(nIndex
, rPolyPolygon
);
303 void B2DPolyPolygon::append(const B2DPolyPolygon
& rPolyPolygon
)
305 if(rPolyPolygon
.count())
306 mpPolyPolygon
->insert(mpPolyPolygon
->count(), rPolyPolygon
);
309 void B2DPolyPolygon::remove(sal_uInt32 nIndex
, sal_uInt32 nCount
)
311 OSL_ENSURE(nIndex
+ nCount
<= mpPolyPolygon
->count(), "B2DPolyPolygon Remove outside range (!)");
314 mpPolyPolygon
->remove(nIndex
, nCount
);
317 void B2DPolyPolygon::clear()
319 mpPolyPolygon
= DefaultPolyPolygon::get();
322 bool B2DPolyPolygon::isClosed() const
326 // PolyPOlygon is closed when all contained Polygons are closed or
327 // no Polygon exists.
328 for(sal_uInt32
a(0L); bRetval
&& a
< mpPolyPolygon
->count(); a
++)
330 if(!(mpPolyPolygon
->getB2DPolygon(a
)).isClosed())
339 void B2DPolyPolygon::setClosed(bool bNew
)
341 if(bNew
!= isClosed())
342 mpPolyPolygon
->setClosed(bNew
);
345 void B2DPolyPolygon::flip()
347 if(mpPolyPolygon
->count())
349 mpPolyPolygon
->flip();
353 bool B2DPolyPolygon::hasDoublePoints() const
357 for(sal_uInt32
a(0L); !bRetval
&& a
< mpPolyPolygon
->count(); a
++)
359 if((mpPolyPolygon
->getB2DPolygon(a
)).hasDoublePoints())
368 void B2DPolyPolygon::removeDoublePoints()
370 if(hasDoublePoints())
371 mpPolyPolygon
->removeDoublePoints();
374 void B2DPolyPolygon::transform(const B2DHomMatrix
& rMatrix
)
376 if(mpPolyPolygon
->count() && !rMatrix
.isIdentity())
378 mpPolyPolygon
->transform(rMatrix
);
381 } // end of namespace basegfx