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_TEMPLATE_HXX
29 #define _POLYGON_TEMPLATE_HXX
33 //////////////////////////////////////////////////////////////////////////////
35 template < class Point
> class ImplSimplePointEntry
40 ImplSimplePointEntry()
41 : maPoint(Point::getEmptyPoint())
45 ImplSimplePointEntry(const Point
& rInitPoint
)
50 const Point
& getPoint() const
55 void setPoint(const Point
& rValue
)
60 bool operator==(const ImplSimplePointEntry
& rEntry
) const
62 return (maPoint
== rEntry
.maPoint
);
66 //////////////////////////////////////////////////////////////////////////////
68 template < class Vector
> class ImplSimpleBezierEntry
74 ImplSimpleBezierEntry()
75 : maBackward(Vector::getEmptyVector()),
76 maForward(Vector::getEmptyVector())
80 ImplSimpleBezierEntry(const Vector
& rInitBackward
, const Vector
& rInitForward
)
81 : maBackward(rInitBackward
),
82 maForward(rInitForward
)
86 const Vector
& getBackwardVector() const
91 void setBackwardVector(const Vector
& rValue
)
96 const Vector
& getForwardVector() const
101 void setForwardVector(const Vector
& rValue
)
106 bool isBezierNeeded()
108 if(!maBackward
.equalZero() || !maForward
.equalZero())
113 bool operator==(const ImplSimpleBezierEntry
& 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 ImplPolygonTemplate
129 typedef ImplSimplePointEntry
< Point
> LocalImplSimplePointEntry
;
130 typedef ImplSimpleBezierEntry
< Vector
> LocalImplSimpleBezierEntry
;
131 typedef ::std::vector
< LocalImplSimplePointEntry
> SimplePointVector
;
132 typedef ::std::vector
< LocalImplSimpleBezierEntry
> SimpleBezierVector
;
134 sal_uInt32 mnBezierCount
;
135 SimplePointVector maPoints
;
136 SimpleBezierVector
* mpVectors
;
138 unsigned mbIsClosed
: 1;
140 void implTryToReduceToPointVector()
142 if(!mnBezierCount
&& mpVectors
)
150 bool isBezier() const
152 return bool(mnBezierCount
);
155 bool isClosed() const
157 return bool(mbIsClosed
);
160 void setClosed(bool bNew
)
165 sal_uInt32
count() const
167 return maPoints
.size();
170 ImplPolygonTemplate()
175 // complete initialization with defaults
178 ImplPolygonTemplate(const ImplPolygonTemplate
& rSource
)
180 maPoints(rSource
.maPoints
),
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 ImplPolygonTemplate(const ImplPolygonTemplate
& rSource
, sal_uInt32 nIndex
, sal_uInt32 nCount
)
196 mbIsClosed(rSource
.mbIsClosed
)
198 // complete initialization using partly copy
203 SimplePointVector::const_iterator
aStart(rSource
.maPoints
.begin());
205 SimplePointVector::const_iterator
aEnd(aStart
);
207 maPoints
.insert(0L, aStart
, aEnd
);
211 if(rSource
.mpVectors
&& rSource
.mnBezierCount
)
213 mpVectors
= new SimpleBezierVector();
214 mpVectors
->reserve(nCount
);
216 SimpleBezierVector::iterator
aStart(mpVectors
->begin());
218 SimpleBezierVector::iterator
aEnd(aStart
);
221 for( ; aStart
!= aEnd
; ++aStart
)
223 if(aStart
->isBezierNeeded())
228 mpVectors
->push_back(*aStart
);
231 // maybe vectors are not needed anymore, try to reduce memory footprint
232 implTryToReduceToPointVector();
237 ~ImplPolygonTemplate()
245 bool isEqual(const ImplPolygonTemplate
& rPointList
) const
248 if(maPoints
.size() != rPointList
.maPoints
.size())
251 // if zero points the polys are equal
255 // if bezier count used it needs to be equal
256 if(mnBezierCount
!= rPointList
.mnBezierCount
)
259 // compare point content
260 if(maPoints
!= rPointList
.maPoints
)
263 // beziercounts are equal: if it's zero, we are done
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
287 return ((*mpVectors
)[nIndex
]).getBackwardVector();
289 return Vector::getEmptyVector();
292 void setBackwardVector(sal_uInt32 nIndex
, const Vector
& rValue
)
296 LocalImplSimpleBezierEntry
& 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
)
311 bool bEmptyVector(rValue
.equalZero());
316 mpVectors
= new SimpleBezierVector(maPoints
.size());
317 ((*mpVectors
)[nIndex
]).setBackwardVector(rValue
);
322 const Vector
& getForwardVector(sal_uInt32 nIndex
) const
325 return ((*mpVectors
)[nIndex
]).getForwardVector();
327 return Vector::getEmptyVector();
330 void setForwardVector(sal_uInt32 nIndex
, const Vector
& rValue
)
334 LocalImplSimpleBezierEntry
& 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
)
349 bool bEmptyVector(rValue
.equalZero());
354 mpVectors
= new SimpleBezierVector(maPoints
.size());
355 ((*mpVectors
)[nIndex
]).setForwardVector(rValue
);
360 void insert(sal_uInt32 nIndex
, const Point
& rPoint
, sal_uInt32 nCount
)
364 // maybe vectors are not needed anymore, try to reduce memory footprint
365 implTryToReduceToPointVector();
367 // add nCount copies of rPoint
369 LocalImplSimplePointEntry
aNode(rPoint
);
370 SimplePointVector::iterator
aIndex(maPoints
.begin());
372 maPoints
.insert(aIndex
, nCount
, aNode
);
375 // add nCount empty entries to keep indices synchronized
378 LocalImplSimpleBezierEntry aNode
;
379 SimpleBezierVector::iterator
aIndex(mpVectors
->begin());
381 mpVectors
->insert(aIndex
, nCount
, aNode
);
386 void insert(sal_uInt32 nIndex
, const ImplPolygonTemplate
& rSource
)
388 const sal_uInt32
nCount(rSource
.maPoints
.size());
392 // instert point data
394 SimplePointVector::iterator
aIndex(maPoints
.begin());
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());
409 SimpleBezierVector::iterator
aStart(rSource
.mpVectors
->begin());
410 SimpleBezierVector::iterator
aEnd(rSource
.mpVectors
->end());
414 mpVectors
= new SimpleBezierVector(maPoints
.size() - nCount
);
417 mpVectors
->insert(aIndex
, aStart
, aEnd
);
419 mnBezierCount
+= rSource
.mnBezierCount
;
423 // maybe vectors are not needed anymore, try to reduce memory footprint
424 implTryToReduceToPointVector();
426 // add nCount empty entries to keep indices synchronized
429 LocalImplSimpleBezierEntry aNode
;
430 SimpleBezierVector::iterator
aIndex(mpVectors
->begin());
432 mpVectors
->insert(aIndex
, nCount
, aNode
);
438 void remove(sal_uInt32 nIndex
, sal_uInt32 nCount
)
442 // maybe vectors are not needed anymore, try to reduce memory footprint
443 implTryToReduceToPointVector();
447 SimplePointVector::iterator
aStart(maPoints
.begin());
449 const SimplePointVector::iterator
aEnd(aStart
+ nCount
);
451 maPoints
.erase(aStart
, aEnd
);
454 // remove bezier data
457 SimpleBezierVector::iterator
aStart(mpVectors
->begin());
459 const SimpleBezierVector::iterator
aEnd(aStart
+ nCount
);
461 // take care for correct mnBezierCount BEFORE erase
464 SimpleBezierVector::iterator
aTestIter(aStart
);
466 for( ; mnBezierCount
&& aTestIter
!= aEnd
; ++aTestIter
)
468 if(aTestIter
->isBezierNeeded())
476 mpVectors
->erase(aStart
, aEnd
);
480 // try to reduce, maybe 0L == mnBezierCount
481 implTryToReduceToPointVector();
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);
499 SimplePointVector::iterator
aStart(maPoints
.begin());
500 SimplePointVector::iterator
aEnd(maPoints
.end());
502 for(sal_uInt32
a(0); a
< nHalfSize
; a
++)
504 LocalImplSimplePointEntry aTemp
= *aStart
;
513 SimpleBezierVector::iterator
aStart(mpVectors
->begin());
514 SimpleBezierVector::iterator
aEnd(mpVectors
->end());
516 for(sal_uInt32
a(0); a
< nHalfSize
; a
++)
518 LocalImplSimpleBezierEntry aTemp
= *aStart
;
519 aTemp
.doInvertForFlip();
521 aStart
->doInvertForFlip();
526 // also flip vectors of middle point (if existing)
527 if(maPoints
.size() % 2)
529 (*mpVectors
)[nHalfSize
].doInvertForFlip();
536 //////////////////////////////////////////////////////////////////////////////
538 #endif _POLYGON_TEMPLATE_HXX