Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 : #ifndef _TL_POLY_HXX
20 : #define _TL_POLY_HXX
21 :
22 : #include "tools/toolsdllapi.h"
23 : #include <tools/gen.hxx>
24 : #include <tools/debug.hxx>
25 :
26 : #include <vector>
27 :
28 : #define POLY_APPEND (0xFFFF)
29 : #define POLYPOLY_APPEND (0xFFFF)
30 :
31 : #define POLY_OPTIMIZE_NONE 0x00000000UL
32 : #define POLY_OPTIMIZE_OPEN 0x00000001UL
33 : #define POLY_OPTIMIZE_CLOSE 0x00000002UL
34 : #define POLY_OPTIMIZE_NO_SAME 0x00000004UL
35 : #define POLY_OPTIMIZE_REDUCE 0x00000008UL
36 : #define POLY_OPTIMIZE_EDGES 0x00000010UL
37 :
38 : enum PolyStyle
39 : {
40 : POLY_ARC = 1,
41 : POLY_PIE = 2,
42 : POLY_CHORD = 3
43 : };
44 :
45 : #ifndef ENUM_POLYFLAGS_DECLARED
46 : #define ENUM_POLYFLAGS_DECLARED
47 : enum PolyFlags
48 : {
49 : POLY_NORMAL,
50 : POLY_SMOOTH,
51 : POLY_CONTROL,
52 : POLY_SYMMTR
53 : };
54 : #endif
55 :
56 : class SAL_WARN_UNUSED PolyOptimizeData
57 : {
58 : private:
59 :
60 : enum DataType { DATA_NONE = 0, DATA_ABSOLUT = 1, DATA_PERCENT = 2 };
61 : DataType eType;
62 : union { sal_uIntPtr mnAbsolut; sal_uInt16 mnPercent; };
63 :
64 : public:
65 : PolyOptimizeData() : eType( DATA_NONE ) {}
66 : PolyOptimizeData( sal_uIntPtr nAbsolut ) : eType( DATA_ABSOLUT ), mnAbsolut( nAbsolut ) {}
67 : PolyOptimizeData( sal_uInt16 nPercent ) : eType( DATA_PERCENT ), mnPercent( nPercent ) {}
68 :
69 : sal_uIntPtr GetAbsValue() const { (void) eType; DBG_ASSERT( eType == DATA_ABSOLUT, "Wrong data type" ); return mnAbsolut; }
70 : sal_uInt16 GetPercentValue() const { (void) eType; DBG_ASSERT( eType == DATA_PERCENT, "Wrong data type" ); return mnPercent; }
71 : };
72 :
73 : class SvStream;
74 : class ImplPolygon;
75 : class ImplPolyPolygon;
76 : class PolyPolygon;
77 :
78 : namespace basegfx
79 : {
80 : class B2DPolygon;
81 : class B2DPolyPolygon;
82 : }
83 :
84 : class TOOLS_DLLPUBLIC SAL_WARN_UNUSED Polygon
85 : {
86 : private:
87 : ImplPolygon* mpImplPolygon;
88 :
89 : TOOLS_DLLPRIVATE inline void ImplMakeUnique();
90 :
91 : public:
92 : static void ImplReduceEdges( Polygon& rPoly, const double& rArea, sal_uInt16 nPercent );
93 : void ImplRead( SvStream& rIStream );
94 : void ImplWrite( SvStream& rOStream ) const;
95 :
96 : public:
97 : Polygon();
98 : Polygon( sal_uInt16 nSize );
99 : Polygon( sal_uInt16 nPoints, const Point* pPtAry,
100 : const sal_uInt8* pFlagAry = NULL );
101 : Polygon( const Rectangle& rRect );
102 : Polygon( const Rectangle& rRect,
103 : sal_uIntPtr nHorzRound, sal_uIntPtr nVertRound );
104 : Polygon( const Point& rCenter,
105 : long nRadX, long nRadY,
106 : sal_uInt16 nPoints = 0 );
107 : Polygon( const Rectangle& rBound,
108 : const Point& rStart, const Point& rEnd,
109 : PolyStyle ePolyStyle = POLY_ARC,
110 : sal_Bool bWholeCircle = sal_False );
111 : Polygon( const Point& rBezPt1, const Point& rCtrlPt1,
112 : const Point& rBezPt2, const Point& rCtrlPt2,
113 : sal_uInt16 nPoints = 0 );
114 :
115 : Polygon( const Polygon& rPoly );
116 : ~Polygon();
117 :
118 : void SetPoint( const Point& rPt, sal_uInt16 nPos );
119 : const Point& GetPoint( sal_uInt16 nPos ) const;
120 :
121 : void SetFlags( sal_uInt16 nPos, PolyFlags eFlags );
122 : PolyFlags GetFlags( sal_uInt16 nPos ) const;
123 : sal_Bool HasFlags() const;
124 :
125 : sal_Bool IsRect() const;
126 :
127 : void SetSize( sal_uInt16 nNewSize );
128 : sal_uInt16 GetSize() const;
129 :
130 : void Clear();
131 :
132 : Rectangle GetBoundRect() const;
133 : double GetSignedArea() const;
134 : sal_Bool IsInside( const Point& rPt ) const;
135 : sal_Bool IsRightOrientated() const;
136 : double CalcDistance( sal_uInt16 nPt1, sal_uInt16 nPt2 );
137 : void Clip( const Rectangle& rRect, sal_Bool bPolygon = sal_True );
138 : void Optimize( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* pData = NULL );
139 :
140 : /** Adaptive subdivision of polygons with curves
141 :
142 : This method adaptively subdivides bezier arcs within the
143 : polygon to straight line segments and returns the resulting
144 : polygon.
145 :
146 : @param rResult
147 : The resulting subdivided polygon
148 :
149 : @param d
150 : This parameter controls the amount of subdivision. The
151 : original curve is guaranteed to not differ by more than this
152 : amount per bezier segment from the subdivided
153 : lines. Concretely, if the polygon is in device coordinates and
154 : d equals 1.0, then the difference between the subdivided and
155 : the original polygon is guaranteed to be smaller than one
156 : pixel.
157 : */
158 : void AdaptiveSubdivide( Polygon& rResult, const double d = 1.0 ) const;
159 :
160 : void Move( long nHorzMove, long nVertMove );
161 : void Translate( const Point& rTrans );
162 : void Scale( double fScaleX, double fScaleY );
163 : void Rotate( const Point& rCenter, double fSin, double fCos );
164 : void Rotate( const Point& rCenter, sal_uInt16 nAngle10 );
165 :
166 : void Insert( sal_uInt16 nPos, const Point& rPt, PolyFlags eFlags = POLY_NORMAL );
167 : void Insert( sal_uInt16 nPos, const Polygon& rPoly );
168 :
169 5588 : const Point& operator[]( sal_uInt16 nPos ) const { return GetPoint( nPos ); }
170 : Point& operator[]( sal_uInt16 nPos );
171 :
172 : Polygon& operator=( const Polygon& rPoly );
173 : sal_Bool operator==( const Polygon& rPoly ) const;
174 : sal_Bool operator!=( const Polygon& rPoly ) const
175 : { return !(Polygon::operator==( rPoly )); }
176 : sal_Bool IsEqual( const Polygon& rPoly ) const;
177 :
178 : // streaming a Polygon does ignore PolyFlags, so use the Write Or Read
179 : // method to take care of PolyFlags
180 : TOOLS_DLLPUBLIC friend SvStream& operator>>( SvStream& rIStream, Polygon& rPoly );
181 : TOOLS_DLLPUBLIC friend SvStream& operator<<( SvStream& rOStream, const Polygon& rPoly );
182 :
183 : void Read( SvStream& rIStream );
184 : void Write( SvStream& rOStream ) const;
185 :
186 : const Point* GetConstPointAry() const;
187 : const sal_uInt8* GetConstFlagAry() const;
188 :
189 : // convert to ::basegfx::B2DPolygon and return
190 : ::basegfx::B2DPolygon getB2DPolygon() const;
191 :
192 : // constructor to convert from ::basegfx::B2DPolygon
193 : // #i76339# made explicit
194 : explicit Polygon(const ::basegfx::B2DPolygon& rPolygon);
195 : };
196 :
197 : class TOOLS_DLLPUBLIC SAL_WARN_UNUSED PolyPolygon
198 : {
199 : private:
200 : ImplPolyPolygon* mpImplPolyPolygon;
201 :
202 : TOOLS_DLLPRIVATE void ImplDoOperation( const PolyPolygon& rPolyPoly, PolyPolygon& rResult, sal_uIntPtr nOperation ) const;
203 : TOOLS_DLLPRIVATE void *ImplCreateArtVpath() const;
204 : TOOLS_DLLPRIVATE void ImplSetFromArtVpath( void *pVpath );
205 :
206 : public:
207 : PolyPolygon( sal_uInt16 nInitSize = 16, sal_uInt16 nResize = 16 );
208 : PolyPolygon( const Polygon& rPoly );
209 : PolyPolygon( sal_uInt16 nPoly, const sal_uInt16* pPointCountAry,
210 : const Point* pPtAry );
211 : PolyPolygon( const PolyPolygon& rPolyPoly );
212 : ~PolyPolygon();
213 :
214 : void Insert( const Polygon& rPoly, sal_uInt16 nPos = POLYPOLY_APPEND );
215 : void Remove( sal_uInt16 nPos );
216 : void Replace( const Polygon& rPoly, sal_uInt16 nPos );
217 : const Polygon& GetObject( sal_uInt16 nPos ) const;
218 :
219 : sal_Bool IsRect() const;
220 :
221 : void Clear();
222 :
223 : sal_uInt16 Count() const;
224 : Rectangle GetBoundRect() const;
225 : void Clip( const Rectangle& rRect );
226 : void Optimize( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* pData = NULL );
227 :
228 : /** Adaptive subdivision of polygons with curves
229 :
230 : This method adaptively subdivides bezier arcs within the
231 : polygon to straight line segments and returns the resulting
232 : polygon.
233 :
234 : @param rResult
235 : The resulting subdivided polygon
236 :
237 : @param d
238 : This parameter controls the amount of subdivision. The
239 : original curve is guaranteed to not differ by more than this
240 : amount per bezier segment from the subdivided
241 : lines. Concretely, if the polygon is in device coordinates and
242 : d equals 1.0, then the difference between the subdivided and
243 : the original polygon is guaranteed to be smaller than one
244 : pixel.
245 : */
246 : void AdaptiveSubdivide( PolyPolygon& rResult, const double d = 1.0 ) const;
247 :
248 : void GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
249 : void GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const;
250 :
251 : void Move( long nHorzMove, long nVertMove );
252 : void Translate( const Point& rTrans );
253 : void Scale( double fScaleX, double fScaleY );
254 : void Rotate( const Point& rCenter, double fSin, double fCos );
255 : void Rotate( const Point& rCenter, sal_uInt16 nAngle10 );
256 :
257 95 : const Polygon& operator[]( sal_uInt16 nPos ) const { return GetObject( nPos ); }
258 : Polygon& operator[]( sal_uInt16 nPos );
259 :
260 : PolyPolygon& operator=( const PolyPolygon& rPolyPoly );
261 : sal_Bool operator==( const PolyPolygon& rPolyPoly ) const;
262 : sal_Bool operator!=( const PolyPolygon& rPolyPoly ) const
263 : { return !(PolyPolygon::operator==( rPolyPoly )); }
264 :
265 : sal_Bool IsEqual( const PolyPolygon& rPolyPoly ) const;
266 :
267 : TOOLS_DLLPUBLIC friend SvStream& operator>>( SvStream& rIStream, PolyPolygon& rPolyPoly );
268 : TOOLS_DLLPUBLIC friend SvStream& operator<<( SvStream& rOStream, const PolyPolygon& rPolyPoly );
269 :
270 : void Read( SvStream& rIStream );
271 : void Write( SvStream& rOStream ) const;
272 :
273 : // convert to ::basegfx::B2DPolyPolygon and return
274 : ::basegfx::B2DPolyPolygon getB2DPolyPolygon() const;
275 :
276 : // constructor to convert from ::basegfx::B2DPolyPolygon
277 : // #i76339# made explicit
278 : explicit PolyPolygon(const ::basegfx::B2DPolyPolygon& rPolyPolygon);
279 : };
280 :
281 : typedef std::vector< PolyPolygon > PolyPolyVector;
282 :
283 : #endif
284 :
285 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|