merged tag ooo/OOO330_m14
[LibreOffice.git] / basegfx / source / inc / PolygonPoint.hxx
blob49b9cd19758bd93e07e8b050aa40d9c14114e272
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 #ifndef _POLYGON_POINT_HXX
29 #define _POLYGON_POINT_HXX
31 #include <vector>
33 //////////////////////////////////////////////////////////////////////////////
35 template < class Point > class SimplePointEntry
37 Point maPoint;
39 public:
40 SimplePointEntry()
41 : maPoint(Point::getEmptyPoint())
45 SimplePointEntry(const Point& rInitPoint)
46 : maPoint(rInitPoint)
50 const Point& getPoint() const
52 return maPoint;
55 void setPoint(const Point& rValue)
57 maPoint = rValue;
60 bool operator==(const SimplePointEntry& rEntry) const
62 return (maPoint == rEntry.maPoint);
66 //////////////////////////////////////////////////////////////////////////////
68 template < class Vector > class SimpleBezierEntry
70 Vector maBackward;
71 Vector maForward;
73 public:
74 SimpleBezierEntry()
75 : maBackward(Vector::getEmptyVector()),
76 maForward(Vector::getEmptyVector())
80 SimpleBezierEntry(const Vector& rInitBackward, const Vector& rInitForward)
81 : maBackward(rInitBackward),
82 maForward(rInitForward)
86 const Vector& getBackwardVector() const
88 return maBackward;
91 void setBackwardVector(const Vector& rValue)
93 maBackward = rValue;
96 const Vector& getForwardVector() const
98 return maForward;
101 void setForwardVector(const Vector& rValue)
103 maForward = rValue;
106 bool isBezierNeeded()
108 if(maBackward != Vector::getEmptyVector() || maForward != Vector::getEmptyVector())
109 return true;
110 return false;
113 bool operator==(const SimpleBezierEntry& rEntry) const
115 return ((maBackward == rEntry.maBackward) && (maForward == rEntry.maForward));
118 void doInvertForFlip()
120 maBackward = -maBackward;
121 maForward = -maForward;
125 //////////////////////////////////////////////////////////////////////////////
127 template < class Point, class Vector > class PolygonPointList
129 typedef SimplePointEntry< Point > LocalSimplePointEntry;
130 typedef SimpleBezierEntry< Vector > LocalSimpleBezierEntry;
131 typedef ::std::vector< LocalSimplePointEntry > SimplePointVector;
132 typedef ::std::vector< LocalSimpleBezierEntry > SimpleBezierVector;
134 sal_uInt32 mnBezierCount;
135 SimplePointVector maPoints;
136 SimpleBezierVector* mpVectors;
138 unsigned mbIsClosed : 1;
140 void implTryToReduceToPointVector()
142 if(!mnBezierCount && mpVectors)
144 delete mpVectors;
145 mpVectors = 0L;
149 public:
150 bool isBezier() const
152 return bool(mnBezierCount);
155 bool isClosed() const
157 return bool(mbIsClosed);
160 void setClosed(bool bNew)
162 mbIsClosed = bNew;
165 sal_uInt32 count() const
167 return maPoints.size();
170 PolygonPointList()
171 : mnBezierCount(0L),
172 mpVectors(0L),
173 mbIsClosed(false)
175 // complete initialization with defaults
178 PolygonPointList(const PolygonPointList& rSource)
179 : mnBezierCount(0L),
180 maPoints(rSource.maPoints),
181 mpVectors(0L),
182 mbIsClosed(rSource.mbIsClosed)
184 // complete initialization using copy
185 if(rSource.mpVectors && rSource.mnBezierCount)
187 mpVectors = new SimpleBezierVector(*rSource.mpVectors);
188 mnBezierCount = rSource.mnBezierCount;
192 PolygonPointList(const PolygonPointList& rSource, sal_uInt32 nIndex, sal_uInt32 nCount)
193 : mnBezierCount(0L),
194 maPoints(nCount),
195 mpVectors(0L),
196 mbIsClosed(rSource.mbIsClosed)
198 // complete initialization using partly copy
199 if(nCount)
201 // copy point data
203 SimplePointVector::const_iterator aStart(rSource.maPoints.begin());
204 aStart += nIndex;
205 SimplePointVector::const_iterator aEnd(aStart);
206 aEnd += nCount;
207 maPoints.insert(0L, aStart, aEnd);
210 // copy bezier data
211 if(rSource.mpVectors && rSource.mnBezierCount)
213 mpVectors = new SimpleBezierVector();
214 mpVectors->reserve(nCount);
216 SimpleBezierVector::iterator aStart(mpVectors->begin());
217 aStart += nIndex;
218 SimpleBezierVector::iterator aEnd(aStart);
219 aEnd += nCount;
221 for( ; aStart != aEnd; ++aStart )
223 if(aStart->IsBezierNeeded())
225 mnBezierCount++;
228 mpVectors->push_back(*aStart);
231 // maybe vectors are not needed anymore, try to reduce memory footprint
232 implTryToReduceToPointVector();
237 ~PolygonPointList()
239 if(mpVectors)
241 delete mpVectors;
245 bool isEqual(const PolygonPointList& rPointList) const
247 // same point count?
248 if(maPoints.size() != rPointList.maPoints.size())
249 return false;
251 // if zero points the polys are equal
252 if(!maPoints.size())
253 return true;
255 // if bezier count used it needs to be equal
256 if(mnBezierCount != rPointList.mnBezierCount)
257 return false;
259 // compare point content
260 if(maPoints != rPointList.maPoints)
261 return false;
263 // beziercounts are equal: if it's zero, we are done
264 if(!mnBezierCount)
265 return true;
267 // beziercounts are equal and not zero; compare them
268 OSL_ENSURE(0L != mpVectors, "Error: Bezier list needs to exist here(!)");
269 OSL_ENSURE(0L != rPointList.mpVectors, "Error: Bezier list needs to exist here(!)");
271 return (*mpVectors == *rPointList.mpVectors);
274 const Point& getPoint(sal_uInt32 nIndex) const
276 return maPoints[nIndex].getPoint();
279 void setPoint(sal_uInt32 nIndex, const Point& rValue)
281 maPoints[nIndex].setPoint(rValue);
284 const Vector& getBackwardVector(sal_uInt32 nIndex) const
286 if(mpVectors)
287 return ((*mpVectors)[nIndex]).getBackwardVector();
288 else
289 return Vector::getEmptyVector();
292 void setBackwardVector(sal_uInt32 nIndex, const Vector& rValue)
294 if(mpVectors)
296 LocalSimpleBezierEntry& rDest = (*mpVectors)[nIndex];
297 bool bBezierNeededBefore(rDest.isBezierNeeded());
298 ((*mpVectors)[nIndex]).setBackwardVector(rValue);
299 bool bBezierNeededAfter(rDest.isBezierNeeded());
301 if(bBezierNeededBefore != bBezierNeededAfter)
303 if(bBezierNeededAfter)
304 mnBezierCount++;
305 else
306 mnBezierCount--;
309 else
311 bool bEmptyVector(rValue == Vector::getEmptyVector());
313 if(bEmptyVector)
314 return;
316 mpVectors = new SimpleBezierVector(maPoints.size());
317 ((*mpVectors)[nIndex]).setBackwardVector(rValue);
318 mnBezierCount++;
322 const Vector& getForwardVector(sal_uInt32 nIndex) const
324 if(mpVectors)
325 return ((*mpVectors)[nIndex]).getForwardVector();
326 else
327 return Vector::getEmptyVector();
330 void setForwardVector(sal_uInt32 nIndex, const Vector& rValue)
332 if(mpVectors)
334 LocalSimpleBezierEntry& rDest = (*mpVectors)[nIndex];
335 bool bBezierNeededBefore(rDest.isBezierNeeded());
336 ((*mpVectors)[nIndex]).setForwardVector(rValue);
337 bool bBezierNeededAfter(rDest.isBezierNeeded());
339 if(bBezierNeededBefore != bBezierNeededAfter)
341 if(bBezierNeededAfter)
342 mnBezierCount++;
343 else
344 mnBezierCount--;
347 else
349 bool bEmptyVector(rValue == Vector::getEmptyVector());
351 if(bEmptyVector)
352 return;
354 mpVectors = new SimpleBezierVector(maPoints.size());
355 ((*mpVectors)[nIndex]).setForwardVector(rValue);
356 mnBezierCount++;
360 void insert(sal_uInt32 nIndex, const Point& rPoint, sal_uInt32 nCount)
362 if(nCount)
364 // maybe vectors are not needed anymore, try to reduce memory footprint
365 implTryToReduceToPointVector();
367 // add nCount copies of rPoint
369 LocalSimplePointEntry aNode(rPoint);
370 SimplePointVector::iterator aIndex(maPoints.begin());
371 aIndex += nIndex;
372 maPoints.insert(aIndex, nCount, aNode);
375 // add nCount empty entries to keep indices synchronized
376 if(mpVectors)
378 LocalSimpleBezierEntry aNode;
379 SimpleBezierVector::iterator aIndex(mpVectors->begin());
380 aIndex += nIndex;
381 mpVectors->insert(aIndex, nCount, aNode);
386 void insert(sal_uInt32 nIndex, const PolygonPointList& rSource)
388 const sal_uInt32 nCount(rSource.maPoints.size());
390 if(nCount)
392 // instert point data
394 SimplePointVector::iterator aIndex(maPoints.begin());
395 aIndex += nIndex;
397 SimplePointVector::const_iterator aStart(rSource.maPoints.begin());
398 SimplePointVector::const_iterator aEnd(rSource.maPoints.end());
400 maPoints.insert(aIndex, aStart, aEnd);
403 // insert bezier data
404 if(rSource.mpVectors && rSource.mnBezierCount)
406 SimpleBezierVector::iterator aIndex(mpVectors->begin());
407 aIndex += nIndex;
409 SimpleBezierVector::iterator aStart(rSource.mpVectors->begin());
410 SimpleBezierVector::iterator aEnd(rSource.mpVectors->end());
412 if(!mpVectors)
414 mpVectors = new SimpleBezierVector(maPoints.size() - nCount);
417 mpVectors->insert(aIndex, aStart, aEnd);
419 mnBezierCount += rSource.mnBezierCount;
421 else
423 // maybe vectors are not needed anymore, try to reduce memory footprint
424 implTryToReduceToPointVector();
426 // add nCount empty entries to keep indices synchronized
427 if(mpVectors)
429 LocalSimpleBezierEntry aNode;
430 SimpleBezierVector::iterator aIndex(mpVectors->begin());
431 aIndex += nIndex;
432 mpVectors->insert(aIndex, nCount, aNode);
438 void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
440 if(nCount)
442 // maybe vectors are not needed anymore, try to reduce memory footprint
443 implTryToReduceToPointVector();
445 // remove point data
447 SimplePointVector::iterator aStart(maPoints.begin());
448 aStart += nIndex;
449 const SimplePointVector::iterator aEnd(aStart + nCount);
451 maPoints.erase(aStart, aEnd);
454 // remove bezier data
455 if(mpVectors)
457 SimpleBezierVector::iterator aStart(mpVectors->begin());
458 aStart += nIndex;
459 const SimpleBezierVector::iterator aEnd(aStart + nCount);
461 // take care for correct mnBezierCount BEFORE erase
462 if(mnBezierCount)
464 SimpleBezierVector::iterator aTestIter(aStart);
466 for( ; mnBezierCount && aTestIter != aEnd; ++aTestIter)
468 if(aTestIter->isBezierNeeded())
469 mnBezierCount--;
473 if(mnBezierCount)
475 // erase nodes
476 mpVectors->erase(aStart, aEnd);
478 else
480 // try to reduce, maybe 0L == mnBezierCount
481 implTryToReduceToPointVector();
487 void flip()
489 if(maPoints.size() > 1)
491 // maybe vectors are not needed anymore, try to reduce memory footprint
492 implTryToReduceToPointVector();
494 // calculate half size
495 const sal_uInt32 nHalfSize(maPoints.size() >> 1L);
497 // flip point data
499 SimplePointVector::iterator aStart(maPoints.begin());
500 SimplePointVector::iterator aEnd(maPoints.end());
502 for(sal_uInt32 a(0); a < nHalfSize; a++)
504 LocalSimplePointEntry aTemp = *aStart;
505 *aStart++ = *aEnd;
506 *aEnd-- = aTemp;
510 // flip bezier data
511 if(mpVectors)
513 SimpleBezierVector::iterator aStart(mpVectors->begin());
514 SimpleBezierVector::iterator aEnd(mpVectors->end());
516 for(sal_uInt32 a(0); a < nHalfSize; a++)
518 LocalSimpleBezierEntry aTemp = *aStart;
519 aTemp.doInvertForFlip();
520 *aStart = *aEnd;
521 aStart->doInvertForFlip();
522 aStart++;
523 *aEnd-- = aTemp;
526 // also flip vectors of middle point (if existing)
527 if(maPoints.size() % 2)
529 (*mpVectors)[nHalfSize].doInvertForFlip();
536 //////////////////////////////////////////////////////////////////////////////
538 #endif _POLYGON_POINT_HXX