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 <basegfx/matrix/b2dhommatrix.hxx>
29 class ImplB2DPolyPolygon
31 basegfx::B2DPolygonVector maPolygons
;
34 ImplB2DPolyPolygon() : maPolygons()
38 explicit ImplB2DPolyPolygon(const basegfx::B2DPolygon
& rToBeCopied
) :
39 maPolygons(1,rToBeCopied
)
43 bool operator==(const ImplB2DPolyPolygon
& rPolygonList
) const
45 // same polygon count?
46 if(maPolygons
.size() != rPolygonList
.maPolygons
.size())
49 // compare polygon content
50 if(!(maPolygons
== rPolygonList
.maPolygons
))
56 const basegfx::B2DPolygon
& getB2DPolygon(sal_uInt32 nIndex
) const
58 return maPolygons
[nIndex
];
61 void setB2DPolygon(sal_uInt32 nIndex
, const basegfx::B2DPolygon
& rPolygon
)
63 maPolygons
[nIndex
] = rPolygon
;
66 void insert(sal_uInt32 nIndex
, const basegfx::B2DPolygon
& rPolygon
, sal_uInt32 nCount
)
70 // add nCount copies of rPolygon
71 basegfx::B2DPolygonVector::iterator
aIndex(maPolygons
.begin());
74 maPolygons
.insert(aIndex
, nCount
, rPolygon
);
78 void insert(sal_uInt32 nIndex
, const basegfx::B2DPolyPolygon
& rPolyPolygon
)
80 // add nCount polygons from rPolyPolygon
81 basegfx::B2DPolygonVector::iterator
aIndex(maPolygons
.begin());
84 maPolygons
.insert(aIndex
, rPolyPolygon
.begin(), rPolyPolygon
.end());
87 void remove(sal_uInt32 nIndex
, sal_uInt32 nCount
)
91 // remove polygon data
92 basegfx::B2DPolygonVector::iterator
aStart(maPolygons
.begin());
94 const basegfx::B2DPolygonVector::iterator
aEnd(aStart
+ nCount
);
96 maPolygons
.erase(aStart
, aEnd
);
100 sal_uInt32
count() const
102 return maPolygons
.size();
105 void setClosed(bool bNew
)
107 for(basegfx::B2DPolygon
& rPolygon
: maPolygons
)
109 rPolygon
.setClosed(bNew
);
115 for (auto& aPolygon
: maPolygons
)
119 void removeDoublePoints()
121 for (auto& aPolygon
: maPolygons
)
122 aPolygon
.removeDoublePoints();
125 void transform(const basegfx::B2DHomMatrix
& rMatrix
)
127 for (auto& aPolygon
: maPolygons
)
128 aPolygon
.transform(rMatrix
);
133 for (auto& aPolygon
: maPolygons
)
134 aPolygon
.makeUnique();
137 const basegfx::B2DPolygon
* begin() const
139 if (maPolygons
.empty())
142 return maPolygons
.data();
145 const basegfx::B2DPolygon
* end() const
147 if (maPolygons
.empty())
150 return maPolygons
.data() + maPolygons
.size();
153 basegfx::B2DPolygon
* begin()
155 if (maPolygons
.empty())
158 return maPolygons
.data();
161 basegfx::B2DPolygon
* end()
163 if (maPolygons
.empty())
166 return maPolygons
.data() + maPolygons
.size();
173 B2DPolyPolygon::B2DPolyPolygon() = default;
175 B2DPolyPolygon::B2DPolyPolygon(const B2DPolyPolygon
&) = default;
177 B2DPolyPolygon::B2DPolyPolygon(B2DPolyPolygon
&&) = default;
179 B2DPolyPolygon::B2DPolyPolygon(const B2DPolygon
& rPolygon
) :
180 mpPolyPolygon( ImplB2DPolyPolygon(rPolygon
) )
184 B2DPolyPolygon::~B2DPolyPolygon() = default;
186 B2DPolyPolygon
& B2DPolyPolygon::operator=(const B2DPolyPolygon
&) = default;
188 B2DPolyPolygon
& B2DPolyPolygon::operator=(B2DPolyPolygon
&&) = default;
190 void B2DPolyPolygon::makeUnique()
192 mpPolyPolygon
.make_unique();
193 mpPolyPolygon
->makeUnique();
196 bool B2DPolyPolygon::operator==(const B2DPolyPolygon
& rPolyPolygon
) const
198 if(mpPolyPolygon
.same_object(rPolyPolygon
.mpPolyPolygon
))
201 return ((*mpPolyPolygon
) == (*rPolyPolygon
.mpPolyPolygon
));
204 bool B2DPolyPolygon::operator!=(const B2DPolyPolygon
& rPolyPolygon
) const
206 return !((*this) == rPolyPolygon
);
209 sal_uInt32
B2DPolyPolygon::count() const
211 return mpPolyPolygon
->count();
214 B2DPolygon
const & B2DPolyPolygon::getB2DPolygon(sal_uInt32 nIndex
) const
216 OSL_ENSURE(nIndex
< mpPolyPolygon
->count(), "B2DPolyPolygon access outside range (!)");
218 return mpPolyPolygon
->getB2DPolygon(nIndex
);
221 void B2DPolyPolygon::setB2DPolygon(sal_uInt32 nIndex
, const B2DPolygon
& rPolygon
)
223 OSL_ENSURE(nIndex
< mpPolyPolygon
->count(), "B2DPolyPolygon access outside range (!)");
225 if(getB2DPolygon(nIndex
) != rPolygon
)
226 mpPolyPolygon
->setB2DPolygon(nIndex
, rPolygon
);
229 bool B2DPolyPolygon::areControlPointsUsed() const
231 for(sal_uInt32
a(0); a
< mpPolyPolygon
->count(); a
++)
233 const B2DPolygon
& rPolygon
= mpPolyPolygon
->getB2DPolygon(a
);
235 if(rPolygon
.areControlPointsUsed())
244 void B2DPolyPolygon::insert(sal_uInt32 nIndex
, const B2DPolygon
& rPolygon
, sal_uInt32 nCount
)
246 OSL_ENSURE(nIndex
<= mpPolyPolygon
->count(), "B2DPolyPolygon Insert outside range (!)");
249 mpPolyPolygon
->insert(nIndex
, rPolygon
, nCount
);
252 void B2DPolyPolygon::append(const B2DPolygon
& rPolygon
, sal_uInt32 nCount
)
255 mpPolyPolygon
->insert(mpPolyPolygon
->count(), rPolygon
, nCount
);
258 B2DPolyPolygon
B2DPolyPolygon::getDefaultAdaptiveSubdivision() const
260 B2DPolyPolygon aRetval
;
262 for(sal_uInt32
a(0); a
< mpPolyPolygon
->count(); a
++)
264 aRetval
.append(mpPolyPolygon
->getB2DPolygon(a
).getDefaultAdaptiveSubdivision());
270 B2DRange
B2DPolyPolygon::getB2DRange() const
274 for(sal_uInt32
a(0); a
< mpPolyPolygon
->count(); a
++)
276 aRetval
.expand(mpPolyPolygon
->getB2DPolygon(a
).getB2DRange());
282 void B2DPolyPolygon::insert(sal_uInt32 nIndex
, const B2DPolyPolygon
& rPolyPolygon
)
284 OSL_ENSURE(nIndex
<= mpPolyPolygon
->count(), "B2DPolyPolygon Insert outside range (!)");
286 if(rPolyPolygon
.count())
287 mpPolyPolygon
->insert(nIndex
, rPolyPolygon
);
290 void B2DPolyPolygon::append(const B2DPolyPolygon
& rPolyPolygon
)
292 if(rPolyPolygon
.count())
293 mpPolyPolygon
->insert(mpPolyPolygon
->count(), rPolyPolygon
);
296 void B2DPolyPolygon::remove(sal_uInt32 nIndex
, sal_uInt32 nCount
)
298 OSL_ENSURE(nIndex
+ nCount
<= mpPolyPolygon
->count(), "B2DPolyPolygon Remove outside range (!)");
301 mpPolyPolygon
->remove(nIndex
, nCount
);
304 void B2DPolyPolygon::clear()
306 *mpPolyPolygon
= ImplB2DPolyPolygon();
309 bool B2DPolyPolygon::isClosed() const
313 // PolyPOlygon is closed when all contained Polygons are closed or
314 // no Polygon exists.
315 for(sal_uInt32
a(0); bRetval
&& a
< mpPolyPolygon
->count(); a
++)
317 if(!mpPolyPolygon
->getB2DPolygon(a
).isClosed())
326 void B2DPolyPolygon::setClosed(bool bNew
)
328 if(bNew
!= isClosed())
329 mpPolyPolygon
->setClosed(bNew
);
332 void B2DPolyPolygon::flip()
334 if(mpPolyPolygon
->count())
336 mpPolyPolygon
->flip();
340 bool B2DPolyPolygon::hasDoublePoints() const
344 for(sal_uInt32
a(0); !bRetval
&& a
< mpPolyPolygon
->count(); a
++)
346 if(mpPolyPolygon
->getB2DPolygon(a
).hasDoublePoints())
355 void B2DPolyPolygon::removeDoublePoints()
357 if(hasDoublePoints())
358 mpPolyPolygon
->removeDoublePoints();
361 void B2DPolyPolygon::transform(const B2DHomMatrix
& rMatrix
)
363 if(mpPolyPolygon
->count() && !rMatrix
.isIdentity())
365 mpPolyPolygon
->transform(rMatrix
);
369 const B2DPolygon
* B2DPolyPolygon::begin() const
371 return mpPolyPolygon
->begin();
374 const B2DPolygon
* B2DPolyPolygon::end() const
376 return mpPolyPolygon
->end();
379 B2DPolygon
* B2DPolyPolygon::begin()
381 return mpPolyPolygon
->begin();
384 B2DPolygon
* B2DPolyPolygon::end()
386 return mpPolyPolygon
->end();
388 } // end of namespace basegfx
390 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */