xref: /aoo42x/main/tools/inc/tools/poly.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
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.
14  *
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).
20  *
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.
25  *
26  ************************************************************************/
27 #ifndef _TL_POLY_HXX
28 #define _TL_POLY_HXX
29 
30 #include "tools/toolsdllapi.h"
31 #include <tools/gen.hxx>
32 #include <tools/debug.hxx>
33 
34 #include <vector>
35 
36 // -----------
37 // - Defines -
38 // -----------
39 
40 #define POLY_APPEND				(0xFFFF)
41 #define POLYPOLY_APPEND			(0xFFFF)
42 
43 // ------------------------------------------------------------------------
44 
45 #define POLY_OPTIMIZE_NONE		0x00000000UL
46 #define POLY_OPTIMIZE_OPEN		0x00000001UL
47 #define POLY_OPTIMIZE_CLOSE		0x00000002UL
48 #define POLY_OPTIMIZE_NO_SAME	0x00000004UL
49 #define POLY_OPTIMIZE_REDUCE	0x00000008UL
50 #define POLY_OPTIMIZE_EDGES		0x00000010UL
51 
52 // -------------
53 // - PolyStyle -
54 // -------------
55 
56 enum PolyStyle
57 {
58     POLY_ARC = 1,
59     POLY_PIE = 2,
60     POLY_CHORD = 3
61 };
62 
63 // -------------
64 // - PolyFlags -
65 // -------------
66 
67 #ifndef ENUM_POLYFLAGS_DECLARED
68 #define ENUM_POLYFLAGS_DECLARED
69 enum PolyFlags
70 {
71     POLY_NORMAL,
72     POLY_SMOOTH,
73     POLY_CONTROL,
74     POLY_SYMMTR
75 };
76 #endif
77 
78 // ----------------
79 // - PolyOptimize -
80 // ----------------
81 
82 class PolyOptimizeData
83 {
84 private:
85 
86 	enum DataType	{ DATA_NONE = 0, DATA_ABSOLUT = 1, DATA_PERCENT = 2 };
87 	DataType		eType;
88 	union			{ sal_uIntPtr mnAbsolut; sal_uInt16 mnPercent; };
89 
90 public:
91 
92 					PolyOptimizeData() : eType( DATA_NONE ) {}
93 					PolyOptimizeData( sal_uIntPtr nAbsolut ) : eType( DATA_ABSOLUT ), mnAbsolut( nAbsolut ) {}
94 					PolyOptimizeData( sal_uInt16 nPercent ) : eType( DATA_PERCENT ), mnPercent( nPercent ) {}
95 
96 	sal_uIntPtr			GetAbsValue() const { DBG_ASSERT( eType == DATA_ABSOLUT, "Wrong data type" ); return mnAbsolut; }
97 	sal_uInt16			GetPercentValue() const { DBG_ASSERT( eType == DATA_PERCENT, "Wrong data type" ); return mnPercent; }
98 };
99 
100 // -----------
101 // - Polygon -
102 // -----------
103 
104 class SvStream;
105 class ImplPolygon;
106 class ImplPolyPolygon;
107 class PolyPolygon;
108 
109 namespace basegfx
110 {
111 	class B2DPolygon;
112 	class B2DPolyPolygon;
113 } // end of namespace basegfx
114 
115 class TOOLS_DLLPUBLIC Polygon
116 {
117 private:
118 
119     ImplPolygon*        mpImplPolygon;
120 
121     TOOLS_DLLPRIVATE inline void ImplMakeUnique();
122 
123 //#if 0 // _SOLAR__PRIVATE
124 
125 public:
126 
127     Point*              ImplGetPointAry();
128     sal_uInt8*               ImplGetFlagAry();
129 
130 	static void			ImplReduceEdges( Polygon& rPoly, const double& rArea, sal_uInt16 nPercent );
131 	void				ImplRead( SvStream& rIStream );
132 	void				ImplWrite( SvStream& rOStream ) const;
133 
134 //#endif // __PRIVATE
135 
136 public:
137                         Polygon();
138                         Polygon( sal_uInt16 nSize );
139                         Polygon( sal_uInt16 nPoints, const Point* pPtAry,
140                                  const sal_uInt8* pFlagAry = NULL );
141                         Polygon( const Rectangle& rRect );
142                         Polygon( const Rectangle& rRect,
143 								 sal_uIntPtr nHorzRound, sal_uIntPtr nVertRound );
144                         Polygon( const Point& rCenter,
145 								 long nRadX, long nRadY,
146                                  sal_uInt16 nPoints = 0 );
147                         Polygon( const Rectangle& rBound,
148                                  const Point& rStart, const Point& rEnd,
149                                  PolyStyle ePolyStyle = POLY_ARC );
150 						Polygon( const Point& rBezPt1, const Point& rCtrlPt1,
151 								 const Point& rBezPt2, const Point& rCtrlPt2,
152 								 sal_uInt16 nPoints = 0 );
153 
154                         Polygon( const Polygon& rPoly );
155                         ~Polygon();
156 
157     void                SetPoint( const Point& rPt, sal_uInt16 nPos );
158     const Point&        GetPoint( sal_uInt16 nPos ) const;
159 
160     void                SetFlags( sal_uInt16 nPos, PolyFlags eFlags );
161     PolyFlags           GetFlags( sal_uInt16 nPos ) const;
162 	sal_Bool			HasFlags() const;
163 
164     sal_Bool                IsControl( sal_uInt16 nPos ) const;
165     sal_Bool                IsSmooth( sal_uInt16 nPos ) const;
166 	sal_Bool				IsRect() const;
167 
168     void                SetSize( sal_uInt16 nNewSize );
169     sal_uInt16              GetSize() const;
170 
171     void                Clear();
172 
173     Rectangle           GetBoundRect() const;
174     double              GetArea() const;
175     double              GetSignedArea() const;
176     sal_Bool                IsInside( const Point& rPt ) const;
177     sal_Bool                IsRightOrientated() const;
178     double              CalcDistance( sal_uInt16 nPt1, sal_uInt16 nPt2 );
179     void                Clip( const Rectangle& rRect, sal_Bool bPolygon = sal_True );
180 	void				Optimize( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* pData = NULL );
181 
182     /** Adaptive subdivision of polygons with curves
183 
184     	This method adaptively subdivides bezier arcs within the
185     	polygon to straight line segments and returns the resulting
186     	polygon.
187 
188         @param rResult
189         The resulting subdivided polygon
190 
191         @param d
192         This parameter controls the amount of subdivision. The
193         original curve is guaranteed to not differ by more than this
194         amount per bezier segment from the subdivided
195         lines. Concretely, if the polygon is in device coordinates and
196         d equals 1.0, then the difference between the subdivided and
197         the original polygon is guaranteed to be smaller than one
198         pixel.
199      */
200     void 				AdaptiveSubdivide( Polygon& rResult, const double d = 1.0 ) const;
201 
202 	void				GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
203 	void				GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
204 	void				GetDifference( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
205 	void				GetXOR( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
206 
207     void                Move( long nHorzMove, long nVertMove );
208     void                Translate( const Point& rTrans );
209     void                Scale( double fScaleX, double fScaleY );
210     void                Rotate( const Point& rCenter, double fSin, double fCos );
211     void                Rotate( const Point& rCenter, sal_uInt16 nAngle10 );
212     void                SlantX( long nYRef, double fSin, double fCos );
213     void                SlantY( long nXRef, double fSin, double fCos );
214     void                Distort( const Rectangle& rRefRect, const Polygon& rDistortedRect );
215 
216     void                Insert( sal_uInt16 nPos, const Point& rPt, PolyFlags eFlags = POLY_NORMAL );
217     void                Insert( sal_uInt16 nPos, const Polygon& rPoly );
218     void                Remove( sal_uInt16 nPos, sal_uInt16 nCount );
219 
220     const Point&        operator[]( sal_uInt16 nPos ) const { return GetPoint( nPos ); }
221     Point&              operator[]( sal_uInt16 nPos );
222 
223     Polygon&            operator=( const Polygon& rPoly );
224     sal_Bool                operator==( const Polygon& rPoly ) const;
225     sal_Bool                operator!=( const Polygon& rPoly ) const
226                             { return !(Polygon::operator==( rPoly )); }
227 	sal_Bool			IsEqual( const Polygon& rPoly ) const;
228 
229 	// streaming a Polygon does ignore PolyFlags, so use the Write Or Read
230 	// method to take care of PolyFlags
231     TOOLS_DLLPUBLIC friend SvStream&    operator>>( SvStream& rIStream, Polygon& rPoly );
232     TOOLS_DLLPUBLIC friend SvStream&    operator<<( SvStream& rOStream, const Polygon& rPoly );
233 
234 	void				Read( SvStream& rIStream );
235 	void				Write( SvStream& rOStream ) const;
236 
237     const Point*        GetConstPointAry() const;
238     const sal_uInt8*         GetConstFlagAry() const;
239 
240 	// convert to ::basegfx::B2DPolygon and return
241 	::basegfx::B2DPolygon getB2DPolygon() const;
242 
243 	// constructor to convert from ::basegfx::B2DPolygon
244 	// #i76339# made explicit
245 	explicit Polygon(const ::basegfx::B2DPolygon& rPolygon);
246 };
247 
248 // ---------------
249 // - PolyPolygon -
250 // ---------------
251 
252 class TOOLS_DLLPUBLIC PolyPolygon
253 {
254 private:
255 
256     ImplPolyPolygon*    mpImplPolyPolygon;
257 
258 //#if 0 // _SOLAR__PRIVATE
259     TOOLS_DLLPRIVATE void  ImplDoOperation( const PolyPolygon& rPolyPoly, PolyPolygon& rResult, sal_uIntPtr nOperation ) const;
260     TOOLS_DLLPRIVATE void *ImplCreateArtVpath() const;
261     TOOLS_DLLPRIVATE void  ImplSetFromArtVpath( void *pVpath );
262 //#endif // __PRIVATE
263 
264 public:
265 
266                         PolyPolygon( sal_uInt16 nInitSize = 16, sal_uInt16 nResize = 16 );
267                         PolyPolygon( const Polygon& rPoly );
268                         PolyPolygon( sal_uInt16 nPoly, const sal_uInt16* pPointCountAry,
269                                      const Point* pPtAry );
270                         PolyPolygon( const PolyPolygon& rPolyPoly );
271                         ~PolyPolygon();
272 
273     void                Insert( const Polygon& rPoly, sal_uInt16 nPos = POLYPOLY_APPEND );
274     void                Remove( sal_uInt16 nPos );
275     void                Replace( const Polygon& rPoly, sal_uInt16 nPos );
276     const Polygon&      GetObject( sal_uInt16 nPos ) const;
277 
278 	sal_Bool				IsRect() const;
279 
280     void                Clear();
281 
282     sal_uInt16              Count() const;
283     Rectangle           GetBoundRect() const;
284     void                Clip( const Rectangle& rRect );
285 	void				Optimize( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* pData = NULL );
286 
287     /** Adaptive subdivision of polygons with curves
288 
289     	This method adaptively subdivides bezier arcs within the
290     	polygon to straight line segments and returns the resulting
291     	polygon.
292 
293         @param rResult
294         The resulting subdivided polygon
295 
296         @param d
297         This parameter controls the amount of subdivision. The
298         original curve is guaranteed to not differ by more than this
299         amount per bezier segment from the subdivided
300         lines. Concretely, if the polygon is in device coordinates and
301         d equals 1.0, then the difference between the subdivided and
302         the original polygon is guaranteed to be smaller than one
303         pixel.
304      */
305     void 				AdaptiveSubdivide( PolyPolygon& rResult, const double d = 1.0 ) const;
306 
307 	void				GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
308 	void				GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
309 	void				GetDifference( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
310 	void				GetXOR( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
311 
312     void                Move( long nHorzMove, long nVertMove );
313     void                Translate( const Point& rTrans );
314     void                Scale( double fScaleX, double fScaleY );
315     void                Rotate( const Point& rCenter, double fSin, double fCos );
316     void                Rotate( const Point& rCenter, sal_uInt16 nAngle10 );
317     void                SlantX( long nYRef, double fSin, double fCos );
318     void                SlantY( long nXRef, double fSin, double fCos );
319     void                Distort( const Rectangle& rRefRect, const Polygon& rDistortedRect );
320 
321     const Polygon&      operator[]( sal_uInt16 nPos ) const { return GetObject( nPos ); }
322     Polygon&            operator[]( sal_uInt16 nPos );
323 
324     PolyPolygon&        operator=( const PolyPolygon& rPolyPoly );
325     sal_Bool                operator==( const PolyPolygon& rPolyPoly ) const;
326     sal_Bool                operator!=( const PolyPolygon& rPolyPoly ) const
327                             { return !(PolyPolygon::operator==( rPolyPoly )); }
328 
329 	sal_Bool			IsEqual( const PolyPolygon& rPolyPoly ) const;
330 
331     TOOLS_DLLPUBLIC friend SvStream&    operator>>( SvStream& rIStream, PolyPolygon& rPolyPoly );
332     TOOLS_DLLPUBLIC friend SvStream&    operator<<( SvStream& rOStream, const PolyPolygon& rPolyPoly );
333 
334 	void				Read( SvStream& rIStream );
335 	void				Write( SvStream& rOStream ) const;
336 
337 	// convert to ::basegfx::B2DPolyPolygon and return
338 	::basegfx::B2DPolyPolygon getB2DPolyPolygon() const;
339 
340 	// constructor to convert from ::basegfx::B2DPolyPolygon
341  	// #i76339# made explicit
342  	explicit PolyPolygon(const ::basegfx::B2DPolyPolygon& rPolyPolygon);
343 };
344 
345 typedef std::vector< PolyPolygon > PolyPolyVector;
346 
347 #endif  // _SV_POLY_HXX
348