Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <basegfx/polygon/b2dpolypolygon.hxx>
30 : : #include <osl/diagnose.h>
31 : : #include <basegfx/polygon/b2dpolygon.hxx>
32 : : #include <basegfx/polygon/b2dpolypolygontools.hxx>
33 : : #include <rtl/instance.hxx>
34 : : #include <basegfx/matrix/b2dhommatrix.hxx>
35 : :
36 : : #include <functional>
37 : : #include <vector>
38 : : #include <algorithm>
39 : :
40 : : //////////////////////////////////////////////////////////////////////////////
41 : :
42 : 12676979 : class ImplB2DPolyPolygon
43 : : {
44 : : typedef ::std::vector< basegfx::B2DPolygon > PolygonVector;
45 : :
46 : : PolygonVector maPolygons;
47 : :
48 : : public:
49 : 196 : ImplB2DPolyPolygon() : maPolygons()
50 : : {
51 : 196 : }
52 : :
53 : 3823575 : explicit ImplB2DPolyPolygon(const basegfx::B2DPolygon& rToBeCopied) :
54 [ + - ]: 3823575 : maPolygons(1,rToBeCopied)
55 : : {
56 : 3823575 : }
57 : :
58 : 60679 : bool operator==(const ImplB2DPolyPolygon& rPolygonList) const
59 : : {
60 : : // same polygon count?
61 [ + + ]: 60679 : if(maPolygons.size() != rPolygonList.maPolygons.size())
62 : 36685 : return false;
63 : :
64 : : // compare polygon content
65 [ + + ]: 23994 : if(!(maPolygons == rPolygonList.maPolygons))
66 : 3681 : return false;
67 : :
68 : 60679 : return true;
69 : : }
70 : :
71 : 11988538 : const basegfx::B2DPolygon& getB2DPolygon(sal_uInt32 nIndex) const
72 : : {
73 : 11988538 : return maPolygons[nIndex];
74 : : }
75 : :
76 : 10815 : void setB2DPolygon(sal_uInt32 nIndex, const basegfx::B2DPolygon& rPolygon)
77 : : {
78 : 10815 : maPolygons[nIndex] = rPolygon;
79 : 10815 : }
80 : :
81 : 365370 : void insert(sal_uInt32 nIndex, const basegfx::B2DPolygon& rPolygon, sal_uInt32 nCount)
82 : : {
83 [ + - ]: 365370 : if(nCount)
84 : : {
85 : : // add nCount copies of rPolygon
86 : 365370 : PolygonVector::iterator aIndex(maPolygons.begin());
87 [ + + ]: 365370 : if( nIndex )
88 [ + - ]: 157781 : aIndex += nIndex;
89 [ + - ]: 365370 : maPolygons.insert(aIndex, nCount, rPolygon);
90 : : }
91 : 365370 : }
92 : :
93 : 11778 : void insert(sal_uInt32 nIndex, const basegfx::B2DPolyPolygon& rPolyPolygon)
94 : : {
95 : : // add all polygons from rPolyPolygon
96 : 11778 : PolygonVector::iterator aIndex(maPolygons.begin());
97 [ + + ]: 11778 : if( nIndex )
98 [ + - ]: 8734 : aIndex += nIndex;
99 [ + - ][ + - ]: 11778 : maPolygons.insert(aIndex, rPolyPolygon.begin(), rPolyPolygon.end());
[ + - ]
100 : 11778 : }
101 : :
102 : 54 : void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
103 : : {
104 [ + - ]: 54 : if(nCount)
105 : : {
106 : : // remove polygon data
107 : 54 : PolygonVector::iterator aStart(maPolygons.begin());
108 [ + - ]: 54 : aStart += nIndex;
109 [ + - ]: 54 : const PolygonVector::iterator aEnd(aStart + nCount);
110 : :
111 [ + - ]: 54 : maPolygons.erase(aStart, aEnd);
112 : : }
113 : 54 : }
114 : :
115 : 16757318 : sal_uInt32 count() const
116 : : {
117 : 16757318 : return maPolygons.size();
118 : : }
119 : :
120 : 26545 : void setClosed(bool bNew)
121 : : {
122 [ + + ]: 80794 : for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
123 : : {
124 : 54249 : maPolygons[a].setClosed(bNew);
125 : : }
126 : 26545 : }
127 : :
128 : 15 : void flip()
129 : : {
130 : : std::for_each( maPolygons.begin(),
131 : : maPolygons.end(),
132 : 15 : std::mem_fun_ref( &basegfx::B2DPolygon::flip ));
133 : 15 : }
134 : :
135 : 22 : void removeDoublePoints()
136 : : {
137 : : std::for_each( maPolygons.begin(),
138 : : maPolygons.end(),
139 : 22 : std::mem_fun_ref( &basegfx::B2DPolygon::removeDoublePoints ));
140 : 22 : }
141 : :
142 : 369452 : void transform(const basegfx::B2DHomMatrix& rMatrix)
143 : : {
144 [ + + ]: 849875 : for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
145 : : {
146 : 480423 : maPolygons[a].transform(rMatrix);
147 : : }
148 : 369452 : }
149 : :
150 : 150 : void makeUnique()
151 : : {
152 : : std::for_each( maPolygons.begin(),
153 : : maPolygons.end(),
154 : 150 : std::mem_fun_ref( &basegfx::B2DPolygon::makeUnique ));
155 : 150 : }
156 : :
157 : 11778 : const basegfx::B2DPolygon* begin() const
158 : : {
159 [ - + ]: 11778 : if(maPolygons.empty())
160 : 0 : return 0;
161 : : else
162 : 11778 : return &maPolygons.front();
163 : : }
164 : :
165 : 11778 : const basegfx::B2DPolygon* end() const
166 : : {
167 [ - + ]: 11778 : if(maPolygons.empty())
168 : 0 : return 0;
169 : : else
170 : 11778 : return (&maPolygons.back())+1;
171 : : }
172 : :
173 : 265 : basegfx::B2DPolygon* begin()
174 : : {
175 [ - + ]: 265 : if(maPolygons.empty())
176 : 0 : return 0;
177 : : else
178 : 265 : return &maPolygons.front();
179 : : }
180 : :
181 : 265 : basegfx::B2DPolygon* end()
182 : : {
183 [ - + ]: 265 : if(maPolygons.empty())
184 : 0 : return 0;
185 : : else
186 : 265 : return &(maPolygons.back())+1;
187 : : }
188 : : };
189 : :
190 : : //////////////////////////////////////////////////////////////////////////////
191 : :
192 : : namespace basegfx
193 : : {
194 : : namespace { struct DefaultPolyPolygon: public rtl::Static<B2DPolyPolygon::ImplType,
195 : : DefaultPolyPolygon> {}; }
196 : :
197 : 337892 : B2DPolyPolygon::B2DPolyPolygon() :
198 : 337892 : mpPolyPolygon(DefaultPolyPolygon::get())
199 : : {
200 : 337892 : }
201 : :
202 : 4511644 : B2DPolyPolygon::B2DPolyPolygon(const B2DPolyPolygon& rPolyPolygon) :
203 : 4511644 : mpPolyPolygon(rPolyPolygon.mpPolyPolygon)
204 : : {
205 : 4511644 : }
206 : :
207 : 3823575 : B2DPolyPolygon::B2DPolyPolygon(const B2DPolygon& rPolygon) :
208 [ + - ]: 3823575 : mpPolyPolygon( ImplB2DPolyPolygon(rPolygon) )
209 : : {
210 : 3823575 : }
211 : :
212 : 8672116 : B2DPolyPolygon::~B2DPolyPolygon()
213 : : {
214 : 8672116 : }
215 : :
216 : 102315 : B2DPolyPolygon& B2DPolyPolygon::operator=(const B2DPolyPolygon& rPolyPolygon)
217 : : {
218 : 102315 : mpPolyPolygon = rPolyPolygon.mpPolyPolygon;
219 : 102315 : return *this;
220 : : }
221 : :
222 : 150 : void B2DPolyPolygon::makeUnique()
223 : : {
224 : 150 : mpPolyPolygon.make_unique();
225 : 150 : mpPolyPolygon->makeUnique();
226 : 150 : }
227 : :
228 : 68620 : bool B2DPolyPolygon::operator==(const B2DPolyPolygon& rPolyPolygon) const
229 : : {
230 [ + + ]: 68620 : if(mpPolyPolygon.same_object(rPolyPolygon.mpPolyPolygon))
231 : 7941 : return true;
232 : :
233 : 68620 : return ((*mpPolyPolygon) == (*rPolyPolygon.mpPolyPolygon));
234 : : }
235 : :
236 : 38694 : bool B2DPolyPolygon::operator!=(const B2DPolyPolygon& rPolyPolygon) const
237 : : {
238 : 38694 : return !((*this) == rPolyPolygon);
239 : : }
240 : :
241 : 8214882 : sal_uInt32 B2DPolyPolygon::count() const
242 : : {
243 : 8214882 : return mpPolyPolygon->count();
244 : : }
245 : :
246 : 8067875 : B2DPolygon B2DPolyPolygon::getB2DPolygon(sal_uInt32 nIndex) const
247 : : {
248 : : OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B2DPolyPolygon access outside range (!)");
249 : :
250 : 8067875 : return mpPolyPolygon->getB2DPolygon(nIndex);
251 : : }
252 : :
253 : 10815 : void B2DPolyPolygon::setB2DPolygon(sal_uInt32 nIndex, const B2DPolygon& rPolygon)
254 : : {
255 : : OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B2DPolyPolygon access outside range (!)");
256 : :
257 [ + - ][ + - ]: 10815 : if(getB2DPolygon(nIndex) != rPolygon)
258 : 10815 : mpPolyPolygon->setB2DPolygon(nIndex, rPolygon);
259 : 10815 : }
260 : :
261 : 3762370 : bool B2DPolyPolygon::areControlPointsUsed() const
262 : : {
263 [ + + ]: 7616615 : for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
264 : : {
265 : 3856536 : const B2DPolygon& rPolygon = mpPolyPolygon->getB2DPolygon(a);
266 : :
267 [ + + ]: 3856536 : if(rPolygon.areControlPointsUsed())
268 : : {
269 : 2291 : return true;
270 : : }
271 : : }
272 : :
273 : 3762370 : return false;
274 : : }
275 : :
276 : 0 : void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolygon& rPolygon, sal_uInt32 nCount)
277 : : {
278 : : OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B2DPolyPolygon Insert outside range (!)");
279 : :
280 [ # # ]: 0 : if(nCount)
281 : 0 : mpPolyPolygon->insert(nIndex, rPolygon, nCount);
282 : 0 : }
283 : :
284 : 365370 : void B2DPolyPolygon::append(const B2DPolygon& rPolygon, sal_uInt32 nCount)
285 : : {
286 [ + - ]: 365370 : if(nCount)
287 : 365370 : mpPolyPolygon->insert(mpPolyPolygon->count(), rPolygon, nCount);
288 : 365370 : }
289 : :
290 : 0 : B2DPolyPolygon B2DPolyPolygon::getDefaultAdaptiveSubdivision() const
291 : : {
292 : 0 : B2DPolyPolygon aRetval;
293 : :
294 [ # # ]: 0 : for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
295 : : {
296 [ # # ][ # # ]: 0 : aRetval.append(mpPolyPolygon->getB2DPolygon(a).getDefaultAdaptiveSubdivision());
[ # # ][ # # ]
297 : : }
298 : :
299 : 0 : return aRetval;
300 : : }
301 : :
302 : 16837 : B2DRange B2DPolyPolygon::getB2DRange() const
303 : : {
304 : 16837 : B2DRange aRetval;
305 : :
306 [ + + ]: 33674 : for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
307 : : {
308 [ + - ]: 16837 : aRetval.expand(mpPolyPolygon->getB2DPolygon(a).getB2DRange());
309 : : }
310 : :
311 : 16837 : return aRetval;
312 : : }
313 : :
314 : 40 : void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolyPolygon& rPolyPolygon)
315 : : {
316 : : OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B2DPolyPolygon Insert outside range (!)");
317 : :
318 [ + - ]: 40 : if(rPolyPolygon.count())
319 : 40 : mpPolyPolygon->insert(nIndex, rPolyPolygon);
320 : 40 : }
321 : :
322 : 11745 : void B2DPolyPolygon::append(const B2DPolyPolygon& rPolyPolygon)
323 : : {
324 [ + + ]: 11745 : if(rPolyPolygon.count())
325 : 11738 : mpPolyPolygon->insert(mpPolyPolygon->count(), rPolyPolygon);
326 : 11745 : }
327 : :
328 : 54 : void B2DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
329 : : {
330 : : OSL_ENSURE(nIndex + nCount <= mpPolyPolygon->count(), "B2DPolyPolygon Remove outside range (!)");
331 : :
332 [ + - ]: 54 : if(nCount)
333 : 54 : mpPolyPolygon->remove(nIndex, nCount);
334 : 54 : }
335 : :
336 : 6843 : void B2DPolyPolygon::clear()
337 : : {
338 : 6843 : mpPolyPolygon = DefaultPolyPolygon::get();
339 : 6843 : }
340 : :
341 : 41916 : bool B2DPolyPolygon::isClosed() const
342 : : {
343 : 41916 : bool bRetval(true);
344 : :
345 : : // PolyPOlygon is closed when all contained Polygons are closed or
346 : : // no Polygon exists.
347 [ + + ][ + + ]: 83926 : for(sal_uInt32 a(0L); bRetval && a < mpPolyPolygon->count(); a++)
[ + + ]
348 : : {
349 [ + + ]: 42010 : if(!(mpPolyPolygon->getB2DPolygon(a)).isClosed())
350 : : {
351 : 32892 : bRetval = false;
352 : : }
353 : : }
354 : :
355 : 41916 : return bRetval;
356 : : }
357 : :
358 : 26729 : void B2DPolyPolygon::setClosed(bool bNew)
359 : : {
360 [ + + ]: 26729 : if(bNew != isClosed())
361 : 26545 : mpPolyPolygon->setClosed(bNew);
362 : 26729 : }
363 : :
364 : 15 : void B2DPolyPolygon::flip()
365 : : {
366 [ + - ]: 15 : if(mpPolyPolygon->count())
367 : : {
368 : 15 : mpPolyPolygon->flip();
369 : : }
370 : 15 : }
371 : :
372 : 4125 : bool B2DPolyPolygon::hasDoublePoints() const
373 : : {
374 : 4125 : bool bRetval(false);
375 : :
376 [ + + ][ + + ]: 9405 : for(sal_uInt32 a(0L); !bRetval && a < mpPolyPolygon->count(); a++)
[ + + ]
377 : : {
378 [ + + ]: 5280 : if((mpPolyPolygon->getB2DPolygon(a)).hasDoublePoints())
379 : : {
380 : 22 : bRetval = true;
381 : : }
382 : : }
383 : :
384 : 4125 : return bRetval;
385 : : }
386 : :
387 : 4125 : void B2DPolyPolygon::removeDoublePoints()
388 : : {
389 [ + + ]: 4125 : if(hasDoublePoints())
390 : 22 : mpPolyPolygon->removeDoublePoints();
391 : 4125 : }
392 : :
393 : 454607 : void B2DPolyPolygon::transform(const B2DHomMatrix& rMatrix)
394 : : {
395 [ + + ][ + + ]: 454607 : if(mpPolyPolygon->count() && !rMatrix.isIdentity())
[ + + ]
396 : : {
397 : 369452 : mpPolyPolygon->transform(rMatrix);
398 : : }
399 : 454607 : }
400 : :
401 : 11778 : const B2DPolygon* B2DPolyPolygon::begin() const
402 : : {
403 : 11778 : return mpPolyPolygon->begin();
404 : : }
405 : :
406 : 11778 : const B2DPolygon* B2DPolyPolygon::end() const
407 : : {
408 : 11778 : return mpPolyPolygon->end();
409 : : }
410 : :
411 : 265 : B2DPolygon* B2DPolyPolygon::begin()
412 : : {
413 : 265 : return mpPolyPolygon->begin();
414 : : }
415 : :
416 : 265 : B2DPolygon* B2DPolyPolygon::end()
417 : : {
418 : 265 : return mpPolyPolygon->end();
419 : : }
420 : : } // end of namespace basegfx
421 : :
422 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|