1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PolygonPoint.hxx,v $
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_POINT_HXX
32 #define _POLYGON_POINT_HXX
36 //////////////////////////////////////////////////////////////////////////////
38 template < class Point
> class SimplePointEntry
44 : maPoint(Point::getEmptyPoint())
48 SimplePointEntry(const Point
& rInitPoint
)
53 const Point
& getPoint() const
58 void setPoint(const Point
& rValue
)
63 bool operator==(const SimplePointEntry
& rEntry
) const
65 return (maPoint
== rEntry
.maPoint
);
69 //////////////////////////////////////////////////////////////////////////////
71 template < class Vector
> class SimpleBezierEntry
78 : maBackward(Vector::getEmptyVector()),
79 maForward(Vector::getEmptyVector())
83 SimpleBezierEntry(const Vector
& rInitBackward
, const Vector
& rInitForward
)
84 : maBackward(rInitBackward
),
85 maForward(rInitForward
)
89 const Vector
& getBackwardVector() const
94 void setBackwardVector(const Vector
& rValue
)
99 const Vector
& getForwardVector() const
104 void setForwardVector(const Vector
& rValue
)
109 bool isBezierNeeded()
111 if(maBackward
!= Vector::getEmptyVector() || maForward
!= Vector::getEmptyVector())
116 bool operator==(const SimpleBezierEntry
& 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 PolygonPointList
132 typedef SimplePointEntry
< Point
> LocalSimplePointEntry
;
133 typedef SimpleBezierEntry
< Vector
> LocalSimpleBezierEntry
;
134 typedef ::std::vector
< LocalSimplePointEntry
> SimplePointVector
;
135 typedef ::std::vector
< LocalSimpleBezierEntry
> SimpleBezierVector
;
137 sal_uInt32 mnBezierCount
;
138 SimplePointVector maPoints
;
139 SimpleBezierVector
* mpVectors
;
141 unsigned mbIsClosed
: 1;
143 void implTryToReduceToPointVector()
145 if(!mnBezierCount
&& mpVectors
)
153 bool isBezier() const
155 return bool(mnBezierCount
);
158 bool isClosed() const
160 return bool(mbIsClosed
);
163 void setClosed(bool bNew
)
168 sal_uInt32
count() const
170 return maPoints
.size();
178 // complete initialization with defaults
181 PolygonPointList(const PolygonPointList
& rSource
)
183 maPoints(rSource
.maPoints
),
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 PolygonPointList(const PolygonPointList
& rSource
, sal_uInt32 nIndex
, sal_uInt32 nCount
)
199 mbIsClosed(rSource
.mbIsClosed
)
201 // complete initialization using partly copy
206 SimplePointVector::const_iterator
aStart(rSource
.maPoints
.begin());
208 SimplePointVector::const_iterator
aEnd(aStart
);
210 maPoints
.insert(0L, aStart
, aEnd
);
214 if(rSource
.mpVectors
&& rSource
.mnBezierCount
)
216 mpVectors
= new SimpleBezierVector();
217 mpVectors
->reserve(nCount
);
219 SimpleBezierVector::iterator
aStart(mpVectors
->begin());
221 SimpleBezierVector::iterator
aEnd(aStart
);
224 for( ; aStart
!= aEnd
; ++aStart
)
226 if(aStart
->IsBezierNeeded())
231 mpVectors
->push_back(*aStart
);
234 // maybe vectors are not needed anymore, try to reduce memory footprint
235 implTryToReduceToPointVector();
248 bool isEqual(const PolygonPointList
& rPointList
) const
251 if(maPoints
.size() != rPointList
.maPoints
.size())
254 // if zero points the polys are equal
258 // if bezier count used it needs to be equal
259 if(mnBezierCount
!= rPointList
.mnBezierCount
)
262 // compare point content
263 if(maPoints
!= rPointList
.maPoints
)
266 // beziercounts are equal: if it's zero, we are done
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
290 return ((*mpVectors
)[nIndex
]).getBackwardVector();
292 return Vector::getEmptyVector();
295 void setBackwardVector(sal_uInt32 nIndex
, const Vector
& rValue
)
299 LocalSimpleBezierEntry
& 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
)
314 bool bEmptyVector(rValue
== Vector::getEmptyVector());
319 mpVectors
= new SimpleBezierVector(maPoints
.size());
320 ((*mpVectors
)[nIndex
]).setBackwardVector(rValue
);
325 const Vector
& getForwardVector(sal_uInt32 nIndex
) const
328 return ((*mpVectors
)[nIndex
]).getForwardVector();
330 return Vector::getEmptyVector();
333 void setForwardVector(sal_uInt32 nIndex
, const Vector
& rValue
)
337 LocalSimpleBezierEntry
& 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
)
352 bool bEmptyVector(rValue
== Vector::getEmptyVector());
357 mpVectors
= new SimpleBezierVector(maPoints
.size());
358 ((*mpVectors
)[nIndex
]).setForwardVector(rValue
);
363 void insert(sal_uInt32 nIndex
, const Point
& rPoint
, sal_uInt32 nCount
)
367 // maybe vectors are not needed anymore, try to reduce memory footprint
368 implTryToReduceToPointVector();
370 // add nCount copies of rPoint
372 LocalSimplePointEntry
aNode(rPoint
);
373 SimplePointVector::iterator
aIndex(maPoints
.begin());
375 maPoints
.insert(aIndex
, nCount
, aNode
);
378 // add nCount empty entries to keep indices synchronized
381 LocalSimpleBezierEntry aNode
;
382 SimpleBezierVector::iterator
aIndex(mpVectors
->begin());
384 mpVectors
->insert(aIndex
, nCount
, aNode
);
389 void insert(sal_uInt32 nIndex
, const PolygonPointList
& rSource
)
391 const sal_uInt32
nCount(rSource
.maPoints
.size());
395 // instert point data
397 SimplePointVector::iterator
aIndex(maPoints
.begin());
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());
412 SimpleBezierVector::iterator
aStart(rSource
.mpVectors
->begin());
413 SimpleBezierVector::iterator
aEnd(rSource
.mpVectors
->end());
417 mpVectors
= new SimpleBezierVector(maPoints
.size() - nCount
);
420 mpVectors
->insert(aIndex
, aStart
, aEnd
);
422 mnBezierCount
+= rSource
.mnBezierCount
;
426 // maybe vectors are not needed anymore, try to reduce memory footprint
427 implTryToReduceToPointVector();
429 // add nCount empty entries to keep indices synchronized
432 LocalSimpleBezierEntry aNode
;
433 SimpleBezierVector::iterator
aIndex(mpVectors
->begin());
435 mpVectors
->insert(aIndex
, nCount
, aNode
);
441 void remove(sal_uInt32 nIndex
, sal_uInt32 nCount
)
445 // maybe vectors are not needed anymore, try to reduce memory footprint
446 implTryToReduceToPointVector();
450 SimplePointVector::iterator
aStart(maPoints
.begin());
452 const SimplePointVector::iterator
aEnd(aStart
+ nCount
);
454 maPoints
.erase(aStart
, aEnd
);
457 // remove bezier data
460 SimpleBezierVector::iterator
aStart(mpVectors
->begin());
462 const SimpleBezierVector::iterator
aEnd(aStart
+ nCount
);
464 // take care for correct mnBezierCount BEFORE erase
467 SimpleBezierVector::iterator
aTestIter(aStart
);
469 for( ; mnBezierCount
&& aTestIter
!= aEnd
; ++aTestIter
)
471 if(aTestIter
->isBezierNeeded())
479 mpVectors
->erase(aStart
, aEnd
);
483 // try to reduce, maybe 0L == mnBezierCount
484 implTryToReduceToPointVector();
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);
502 SimplePointVector::iterator
aStart(maPoints
.begin());
503 SimplePointVector::iterator
aEnd(maPoints
.end());
505 for(sal_uInt32
a(0); a
< nHalfSize
; a
++)
507 LocalSimplePointEntry aTemp
= *aStart
;
516 SimpleBezierVector::iterator
aStart(mpVectors
->begin());
517 SimpleBezierVector::iterator
aEnd(mpVectors
->end());
519 for(sal_uInt32
a(0); a
< nHalfSize
; a
++)
521 LocalSimpleBezierEntry aTemp
= *aStart
;
522 aTemp
.doInvertForFlip();
524 aStart
->doInvertForFlip();
529 // also flip vectors of middle point (if existing)
530 if(maPoints
.size() % 2)
532 (*mpVectors
)[nHalfSize
].doInvertForFlip();
539 //////////////////////////////////////////////////////////////////////////////
541 #endif _POLYGON_POINT_HXX