merge the formfield patch from ooo-build
[ooovba.git] / basegfx / source / inc / polygontemplate.hxx
blobc0c5ec191ce620ad49da2fd913f9dcec59186754
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: polygontemplate.hxx,v $
10 * $Revision: 1.8 $
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 #ifndef _POLYGON_TEMPLATE_HXX
32 #define _POLYGON_TEMPLATE_HXX
34 #include <vector>
36 //////////////////////////////////////////////////////////////////////////////
38 template < class Point > class ImplSimplePointEntry
40 Point maPoint;
42 public:
43 ImplSimplePointEntry()
44 : maPoint(Point::getEmptyPoint())
48 ImplSimplePointEntry(const Point& rInitPoint)
49 : maPoint(rInitPoint)
53 const Point& getPoint() const
55 return maPoint;
58 void setPoint(const Point& rValue)
60 maPoint = rValue;
63 bool operator==(const ImplSimplePointEntry& rEntry) const
65 return (maPoint == rEntry.maPoint);
69 //////////////////////////////////////////////////////////////////////////////
71 template < class Vector > class ImplSimpleBezierEntry
73 Vector maBackward;
74 Vector maForward;
76 public:
77 ImplSimpleBezierEntry()
78 : maBackward(Vector::getEmptyVector()),
79 maForward(Vector::getEmptyVector())
83 ImplSimpleBezierEntry(const Vector& rInitBackward, const Vector& rInitForward)
84 : maBackward(rInitBackward),
85 maForward(rInitForward)
89 const Vector& getBackwardVector() const
91 return maBackward;
94 void setBackwardVector(const Vector& rValue)
96 maBackward = rValue;
99 const Vector& getForwardVector() const
101 return maForward;
104 void setForwardVector(const Vector& rValue)
106 maForward = rValue;
109 bool isBezierNeeded()
111 if(!maBackward.equalZero() || !maForward.equalZero())
112 return true;
113 return false;
116 bool operator==(const ImplSimpleBezierEntry& rEntry) const
118 return ((maBackward == rEntry.maBackward) && (maForward == rEntry.maForward));
121 void doInvertForFlip()
123 maBackward = -maBackward;
124 maForward = -maForward;
128 //////////////////////////////////////////////////////////////////////////////
130 template < class Point, class Vector > class ImplPolygonTemplate
132 typedef ImplSimplePointEntry< Point > LocalImplSimplePointEntry;
133 typedef ImplSimpleBezierEntry< Vector > LocalImplSimpleBezierEntry;
134 typedef ::std::vector< LocalImplSimplePointEntry > SimplePointVector;
135 typedef ::std::vector< LocalImplSimpleBezierEntry > SimpleBezierVector;
137 sal_uInt32 mnBezierCount;
138 SimplePointVector maPoints;
139 SimpleBezierVector* mpVectors;
141 unsigned mbIsClosed : 1;
143 void implTryToReduceToPointVector()
145 if(!mnBezierCount && mpVectors)
147 delete mpVectors;
148 mpVectors = 0L;
152 public:
153 bool isBezier() const
155 return bool(mnBezierCount);
158 bool isClosed() const
160 return bool(mbIsClosed);
163 void setClosed(bool bNew)
165 mbIsClosed = bNew;
168 sal_uInt32 count() const
170 return maPoints.size();
173 ImplPolygonTemplate()
174 : mnBezierCount(0L),
175 mpVectors(0L),
176 mbIsClosed(false)
178 // complete initialization with defaults
181 ImplPolygonTemplate(const ImplPolygonTemplate& rSource)
182 : mnBezierCount(0L),
183 maPoints(rSource.maPoints),
184 mpVectors(0L),
185 mbIsClosed(rSource.mbIsClosed)
187 // complete initialization using copy
188 if(rSource.mpVectors && rSource.mnBezierCount)
190 mpVectors = new SimpleBezierVector(*rSource.mpVectors);
191 mnBezierCount = rSource.mnBezierCount;
195 ImplPolygonTemplate(const ImplPolygonTemplate& rSource, sal_uInt32 nIndex, sal_uInt32 nCount)
196 : mnBezierCount(0L),
197 maPoints(nCount),
198 mpVectors(0L),
199 mbIsClosed(rSource.mbIsClosed)
201 // complete initialization using partly copy
202 if(nCount)
204 // copy point data
206 SimplePointVector::const_iterator aStart(rSource.maPoints.begin());
207 aStart += nIndex;
208 SimplePointVector::const_iterator aEnd(aStart);
209 aEnd += nCount;
210 maPoints.insert(0L, aStart, aEnd);
213 // copy bezier data
214 if(rSource.mpVectors && rSource.mnBezierCount)
216 mpVectors = new SimpleBezierVector();
217 mpVectors->reserve(nCount);
219 SimpleBezierVector::iterator aStart(mpVectors->begin());
220 aStart += nIndex;
221 SimpleBezierVector::iterator aEnd(aStart);
222 aEnd += nCount;
224 for( ; aStart != aEnd; ++aStart )
226 if(aStart->isBezierNeeded())
228 mnBezierCount++;
231 mpVectors->push_back(*aStart);
234 // maybe vectors are not needed anymore, try to reduce memory footprint
235 implTryToReduceToPointVector();
240 ~ImplPolygonTemplate()
242 if(mpVectors)
244 delete mpVectors;
248 bool isEqual(const ImplPolygonTemplate& rPointList) const
250 // same point count?
251 if(maPoints.size() != rPointList.maPoints.size())
252 return false;
254 // if zero points the polys are equal
255 if(!maPoints.size())
256 return true;
258 // if bezier count used it needs to be equal
259 if(mnBezierCount != rPointList.mnBezierCount)
260 return false;
262 // compare point content
263 if(maPoints != rPointList.maPoints)
264 return false;
266 // beziercounts are equal: if it's zero, we are done
267 if(!mnBezierCount)
268 return true;
270 // beziercounts are equal and not zero; compare them
271 OSL_ENSURE(0L != mpVectors, "Error: Bezier list needs to exist here(!)");
272 OSL_ENSURE(0L != rPointList.mpVectors, "Error: Bezier list needs to exist here(!)");
274 return (*mpVectors == *rPointList.mpVectors);
277 const Point& getPoint(sal_uInt32 nIndex) const
279 return maPoints[nIndex].getPoint();
282 void setPoint(sal_uInt32 nIndex, const Point& rValue)
284 maPoints[nIndex].setPoint(rValue);
287 const Vector& getBackwardVector(sal_uInt32 nIndex) const
289 if(mpVectors)
290 return ((*mpVectors)[nIndex]).getBackwardVector();
291 else
292 return Vector::getEmptyVector();
295 void setBackwardVector(sal_uInt32 nIndex, const Vector& rValue)
297 if(mpVectors)
299 LocalImplSimpleBezierEntry& rDest = (*mpVectors)[nIndex];
300 bool bBezierNeededBefore(rDest.isBezierNeeded());
301 ((*mpVectors)[nIndex]).setBackwardVector(rValue);
302 bool bBezierNeededAfter(rDest.isBezierNeeded());
304 if(bBezierNeededBefore != bBezierNeededAfter)
306 if(bBezierNeededAfter)
307 mnBezierCount++;
308 else
309 mnBezierCount--;
312 else
314 bool bEmptyVector(rValue.equalZero());
316 if(bEmptyVector)
317 return;
319 mpVectors = new SimpleBezierVector(maPoints.size());
320 ((*mpVectors)[nIndex]).setBackwardVector(rValue);
321 mnBezierCount++;
325 const Vector& getForwardVector(sal_uInt32 nIndex) const
327 if(mpVectors)
328 return ((*mpVectors)[nIndex]).getForwardVector();
329 else
330 return Vector::getEmptyVector();
333 void setForwardVector(sal_uInt32 nIndex, const Vector& rValue)
335 if(mpVectors)
337 LocalImplSimpleBezierEntry& rDest = (*mpVectors)[nIndex];
338 bool bBezierNeededBefore(rDest.isBezierNeeded());
339 ((*mpVectors)[nIndex]).setForwardVector(rValue);
340 bool bBezierNeededAfter(rDest.isBezierNeeded());
342 if(bBezierNeededBefore != bBezierNeededAfter)
344 if(bBezierNeededAfter)
345 mnBezierCount++;
346 else
347 mnBezierCount--;
350 else
352 bool bEmptyVector(rValue.equalZero());
354 if(bEmptyVector)
355 return;
357 mpVectors = new SimpleBezierVector(maPoints.size());
358 ((*mpVectors)[nIndex]).setForwardVector(rValue);
359 mnBezierCount++;
363 void insert(sal_uInt32 nIndex, const Point& rPoint, sal_uInt32 nCount)
365 if(nCount)
367 // maybe vectors are not needed anymore, try to reduce memory footprint
368 implTryToReduceToPointVector();
370 // add nCount copies of rPoint
372 LocalImplSimplePointEntry aNode(rPoint);
373 SimplePointVector::iterator aIndex(maPoints.begin());
374 aIndex += nIndex;
375 maPoints.insert(aIndex, nCount, aNode);
378 // add nCount empty entries to keep indices synchronized
379 if(mpVectors)
381 LocalImplSimpleBezierEntry aNode;
382 SimpleBezierVector::iterator aIndex(mpVectors->begin());
383 aIndex += nIndex;
384 mpVectors->insert(aIndex, nCount, aNode);
389 void insert(sal_uInt32 nIndex, const ImplPolygonTemplate& rSource)
391 const sal_uInt32 nCount(rSource.maPoints.size());
393 if(nCount)
395 // instert point data
397 SimplePointVector::iterator aIndex(maPoints.begin());
398 aIndex += nIndex;
400 SimplePointVector::const_iterator aStart(rSource.maPoints.begin());
401 SimplePointVector::const_iterator aEnd(rSource.maPoints.end());
403 maPoints.insert(aIndex, aStart, aEnd);
406 // insert bezier data
407 if(rSource.mpVectors && rSource.mnBezierCount)
409 SimpleBezierVector::iterator aIndex(mpVectors->begin());
410 aIndex += nIndex;
412 SimpleBezierVector::iterator aStart(rSource.mpVectors->begin());
413 SimpleBezierVector::iterator aEnd(rSource.mpVectors->end());
415 if(!mpVectors)
417 mpVectors = new SimpleBezierVector(maPoints.size() - nCount);
420 mpVectors->insert(aIndex, aStart, aEnd);
422 mnBezierCount += rSource.mnBezierCount;
424 else
426 // maybe vectors are not needed anymore, try to reduce memory footprint
427 implTryToReduceToPointVector();
429 // add nCount empty entries to keep indices synchronized
430 if(mpVectors)
432 LocalImplSimpleBezierEntry aNode;
433 SimpleBezierVector::iterator aIndex(mpVectors->begin());
434 aIndex += nIndex;
435 mpVectors->insert(aIndex, nCount, aNode);
441 void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
443 if(nCount)
445 // maybe vectors are not needed anymore, try to reduce memory footprint
446 implTryToReduceToPointVector();
448 // remove point data
450 SimplePointVector::iterator aStart(maPoints.begin());
451 aStart += nIndex;
452 const SimplePointVector::iterator aEnd(aStart + nCount);
454 maPoints.erase(aStart, aEnd);
457 // remove bezier data
458 if(mpVectors)
460 SimpleBezierVector::iterator aStart(mpVectors->begin());
461 aStart += nIndex;
462 const SimpleBezierVector::iterator aEnd(aStart + nCount);
464 // take care for correct mnBezierCount BEFORE erase
465 if(mnBezierCount)
467 SimpleBezierVector::iterator aTestIter(aStart);
469 for( ; mnBezierCount && aTestIter != aEnd; ++aTestIter)
471 if(aTestIter->isBezierNeeded())
472 mnBezierCount--;
476 if(mnBezierCount)
478 // erase nodes
479 mpVectors->erase(aStart, aEnd);
481 else
483 // try to reduce, maybe 0L == mnBezierCount
484 implTryToReduceToPointVector();
490 void flip()
492 if(maPoints.size() > 1)
494 // maybe vectors are not needed anymore, try to reduce memory footprint
495 implTryToReduceToPointVector();
497 // calculate half size
498 const sal_uInt32 nHalfSize(maPoints.size() >> 1L);
500 // flip point data
502 SimplePointVector::iterator aStart(maPoints.begin());
503 SimplePointVector::iterator aEnd(maPoints.end());
505 for(sal_uInt32 a(0); a < nHalfSize; a++)
507 LocalImplSimplePointEntry aTemp = *aStart;
508 *aStart++ = *aEnd;
509 *aEnd-- = aTemp;
513 // flip bezier data
514 if(mpVectors)
516 SimpleBezierVector::iterator aStart(mpVectors->begin());
517 SimpleBezierVector::iterator aEnd(mpVectors->end());
519 for(sal_uInt32 a(0); a < nHalfSize; a++)
521 LocalImplSimpleBezierEntry aTemp = *aStart;
522 aTemp.doInvertForFlip();
523 *aStart = *aEnd;
524 aStart->doInvertForFlip();
525 aStart++;
526 *aEnd-- = aTemp;
529 // also flip vectors of middle point (if existing)
530 if(maPoints.size() % 2)
532 (*mpVectors)[nHalfSize].doInvertForFlip();
539 //////////////////////////////////////////////////////////////////////////////
541 #endif _POLYGON_TEMPLATE_HXX