Branch libreoffice-5-0-4
[LibreOffice.git] / include / tools / poly.hxx
blobaf157b2137f7c5cd9b5b0f15166210c9a175c856
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef INCLUDED_TOOLS_POLY_HXX
20 #define INCLUDED_TOOLS_POLY_HXX
22 #include <tools/toolsdllapi.h>
23 #include <tools/gen.hxx>
24 #include <tools/debug.hxx>
25 #include <o3tl/typed_flags_set.hxx>
27 #include <vector>
29 #define POLY_APPEND (0xFFFF)
30 #define POLYPOLY_APPEND (0xFFFF)
32 enum class PolyOptimizeFlags {
33 NONE = 0x0000,
34 OPEN = 0x0001,
35 CLOSE = 0x0002,
36 NO_SAME = 0x0004,
37 REDUCE = 0x0008,
38 EDGES = 0x0010,
40 namespace o3tl
42 template<> struct typed_flags<PolyOptimizeFlags> : is_typed_flags<PolyOptimizeFlags, 0x001f> {};
45 enum PolyStyle
47 POLY_ARC = 1,
48 POLY_PIE = 2,
49 POLY_CHORD = 3
52 #ifndef ENUM_POLYFLAGS_DECLARED
53 #define ENUM_POLYFLAGS_DECLARED
54 enum PolyFlags
56 POLY_NORMAL,
57 POLY_SMOOTH,
58 POLY_CONTROL,
59 POLY_SYMMTR
61 #endif
63 class SAL_WARN_UNUSED PolyOptimizeData
65 private:
67 enum DataType { DATA_NONE = 0, DATA_ABSOLUT = 1, DATA_PERCENT = 2 };
68 DataType eType;
69 union { sal_uIntPtr mnAbsolut; sal_uInt16 mnPercent; };
71 public:
72 PolyOptimizeData() : eType( DATA_NONE ) {}
73 PolyOptimizeData( sal_uIntPtr nAbsolut ) : eType( DATA_ABSOLUT ), mnAbsolut( nAbsolut ) {}
74 PolyOptimizeData( sal_uInt16 nPercent ) : eType( DATA_PERCENT ), mnPercent( nPercent ) {}
76 sal_uIntPtr GetAbsValue() const { (void) eType; DBG_ASSERT( eType == DATA_ABSOLUT, "Wrong data type" ); return mnAbsolut; }
77 sal_uInt16 GetPercentValue() const { (void) eType; DBG_ASSERT( eType == DATA_PERCENT, "Wrong data type" ); return mnPercent; }
80 class SvStream;
81 class ImplPolygon;
82 class ImplPolyPolygon;
83 namespace tools { class PolyPolygon; }
85 namespace basegfx
87 class B2DPolygon;
88 class B2DPolyPolygon;
91 class TOOLS_DLLPUBLIC SAL_WARN_UNUSED Polygon
93 private:
94 ImplPolygon* mpImplPolygon;
96 TOOLS_DLLPRIVATE inline void ImplMakeUnique();
98 public:
99 static void ImplReduceEdges( Polygon& rPoly, const double& rArea, sal_uInt16 nPercent );
100 void ImplRead( SvStream& rIStream );
101 void ImplWrite( SvStream& rOStream ) const;
103 public:
104 Polygon();
105 Polygon( sal_uInt16 nSize );
106 Polygon( sal_uInt16 nPoints, const Point* pPtAry,
107 const sal_uInt8* pFlagAry = NULL );
108 Polygon( const Rectangle& rRect );
109 Polygon( const Rectangle& rRect,
110 sal_uIntPtr nHorzRound, sal_uIntPtr nVertRound );
111 Polygon( const Point& rCenter,
112 long nRadX, long nRadY,
113 sal_uInt16 nPoints = 0 );
114 Polygon( const Rectangle& rBound,
115 const Point& rStart, const Point& rEnd,
116 PolyStyle ePolyStyle = POLY_ARC,
117 bool bWholeCircle = false );
118 Polygon( const Point& rBezPt1, const Point& rCtrlPt1,
119 const Point& rBezPt2, const Point& rCtrlPt2,
120 sal_uInt16 nPoints = 0 );
122 Polygon( const Polygon& rPoly );
123 ~Polygon();
125 void SetPoint( const Point& rPt, sal_uInt16 nPos );
126 const Point& GetPoint( sal_uInt16 nPos ) const;
128 void SetFlags( sal_uInt16 nPos, PolyFlags eFlags );
129 PolyFlags GetFlags( sal_uInt16 nPos ) const;
130 bool HasFlags() const;
132 bool IsRect() const;
134 void SetSize( sal_uInt16 nNewSize );
135 sal_uInt16 GetSize() const;
137 void Clear();
139 Rectangle GetBoundRect() const;
140 double GetSignedArea() const;
141 bool IsInside( const Point& rPt ) const;
142 bool IsRightOrientated() const;
143 double CalcDistance( sal_uInt16 nPt1, sal_uInt16 nPt2 );
144 void Clip( const Rectangle& rRect, bool bPolygon = true );
145 void Optimize( PolyOptimizeFlags nOptimizeFlags, const PolyOptimizeData* pData = NULL );
147 /** Adaptive subdivision of polygons with curves
149 This method adaptively subdivides bezier arcs within the
150 polygon to straight line segments and returns the resulting
151 polygon.
153 @param rResult
154 The resulting subdivided polygon
156 @param d
157 This parameter controls the amount of subdivision. The
158 original curve is guaranteed to not differ by more than this
159 amount per bezier segment from the subdivided
160 lines. Concretely, if the polygon is in device coordinates and
161 d equals 1.0, then the difference between the subdivided and
162 the original polygon is guaranteed to be smaller than one
163 pixel.
165 void AdaptiveSubdivide( Polygon& rResult, const double d = 1.0 ) const;
166 static Polygon SubdivideBezier( const Polygon& rPoly );
168 void Move( long nHorzMove, long nVertMove );
169 void Translate( const Point& rTrans );
170 void Scale( double fScaleX, double fScaleY );
171 void Rotate( const Point& rCenter, double fSin, double fCos );
172 void Rotate( const Point& rCenter, sal_uInt16 nAngle10 );
174 void Insert( sal_uInt16 nPos, const Point& rPt, PolyFlags eFlags = POLY_NORMAL );
175 void Insert( sal_uInt16 nPos, const Polygon& rPoly );
177 const Point& operator[]( sal_uInt16 nPos ) const { return GetPoint( nPos ); }
178 Point& operator[]( sal_uInt16 nPos );
180 Polygon& operator=( const Polygon& rPoly );
181 bool operator==( const Polygon& rPoly ) const;
182 bool operator!=( const Polygon& rPoly ) const
183 { return !(Polygon::operator==( rPoly )); }
184 bool IsEqual( const Polygon& rPoly ) const;
186 // streaming a Polygon does ignore PolyFlags, so use the Write Or Read
187 // method to take care of PolyFlags
188 TOOLS_DLLPUBLIC friend SvStream& ReadPolygon( SvStream& rIStream, Polygon& rPoly );
189 TOOLS_DLLPUBLIC friend SvStream& WritePolygon( SvStream& rOStream, const Polygon& rPoly );
191 void Read( SvStream& rIStream );
192 void Write( SvStream& rOStream ) const;
194 const Point* GetConstPointAry() const;
195 const sal_uInt8* GetConstFlagAry() const;
197 // convert to ::basegfx::B2DPolygon and return
198 ::basegfx::B2DPolygon getB2DPolygon() const;
200 // constructor to convert from ::basegfx::B2DPolygon
201 // #i76339# made explicit
202 explicit Polygon(const ::basegfx::B2DPolygon& rPolygon);
205 namespace tools {
207 class TOOLS_DLLPUBLIC SAL_WARN_UNUSED PolyPolygon
209 private:
210 ImplPolyPolygon* mpImplPolyPolygon;
212 TOOLS_DLLPRIVATE void ImplDoOperation( const tools::PolyPolygon& rPolyPoly, tools::PolyPolygon& rResult, sal_uIntPtr nOperation ) const;
213 TOOLS_DLLPRIVATE void *ImplCreateArtVpath() const;
214 TOOLS_DLLPRIVATE void ImplSetFromArtVpath( void *pVpath );
216 public:
217 PolyPolygon( sal_uInt16 nInitSize = 16, sal_uInt16 nResize = 16 );
218 PolyPolygon( const Polygon& rPoly );
219 PolyPolygon( const tools::PolyPolygon& rPolyPoly );
220 ~PolyPolygon();
222 void Insert( const Polygon& rPoly, sal_uInt16 nPos = POLYPOLY_APPEND );
223 void Remove( sal_uInt16 nPos );
224 void Replace( const Polygon& rPoly, sal_uInt16 nPos );
225 const Polygon& GetObject( sal_uInt16 nPos ) const;
227 bool IsRect() const;
229 void Clear();
231 sal_uInt16 Count() const;
232 Rectangle GetBoundRect() const;
233 void Clip( const Rectangle& rRect );
234 void Optimize( PolyOptimizeFlags nOptimizeFlags, const PolyOptimizeData* pData = NULL );
236 /** Adaptive subdivision of polygons with curves
238 This method adaptively subdivides bezier arcs within the
239 polygon to straight line segments and returns the resulting
240 polygon.
242 @param rResult
243 The resulting subdivided polygon
245 @param d
246 This parameter controls the amount of subdivision. The
247 original curve is guaranteed to not differ by more than this
248 amount per bezier segment from the subdivided
249 lines. Concretely, if the polygon is in device coordinates and
250 d equals 1.0, then the difference between the subdivided and
251 the original polygon is guaranteed to be smaller than one
252 pixel.
254 void AdaptiveSubdivide( tools::PolyPolygon& rResult, const double d = 1.0 ) const;
255 static tools::PolyPolygon SubdivideBezier( const tools::PolyPolygon& rPolyPoly );
257 void GetIntersection( const tools::PolyPolygon& rPolyPoly, tools::PolyPolygon& rResult ) const;
258 void GetUnion( const tools::PolyPolygon& rPolyPoly, tools::PolyPolygon& rResult ) const;
260 void Move( long nHorzMove, long nVertMove );
261 void Translate( const Point& rTrans );
262 void Scale( double fScaleX, double fScaleY );
263 void Rotate( const Point& rCenter, double fSin, double fCos );
264 void Rotate( const Point& rCenter, sal_uInt16 nAngle10 );
266 const Polygon& operator[]( sal_uInt16 nPos ) const { return GetObject( nPos ); }
267 Polygon& operator[]( sal_uInt16 nPos );
269 tools::PolyPolygon& operator=( const tools::PolyPolygon& rPolyPoly );
270 bool operator==( const tools::PolyPolygon& rPolyPoly ) const;
271 bool operator!=( const tools::PolyPolygon& rPolyPoly ) const
272 { return !(PolyPolygon::operator==( rPolyPoly )); }
274 bool IsEqual( const tools::PolyPolygon& rPolyPoly ) const;
276 TOOLS_DLLPUBLIC friend SvStream& ReadPolyPolygon( SvStream& rIStream, tools::PolyPolygon& rPolyPoly );
277 TOOLS_DLLPUBLIC friend SvStream& WritePolyPolygon( SvStream& rOStream, const tools::PolyPolygon& rPolyPoly );
279 void Read( SvStream& rIStream );
280 void Write( SvStream& rOStream ) const;
282 // convert to ::basegfx::B2DPolyPolygon and return
283 ::basegfx::B2DPolyPolygon getB2DPolyPolygon() const;
285 // constructor to convert from ::basegfx::B2DPolyPolygon
286 // #i76339# made explicit
287 explicit PolyPolygon(const ::basegfx::B2DPolyPolygon& rPolyPolygon);
290 } /* namespace tools */
292 typedef std::vector< tools::PolyPolygon > PolyPolyVector;
295 template<typename charT, typename traits>
296 inline std::basic_ostream<charT, traits> & operator <<(
297 std::basic_ostream<charT, traits> & stream, const tools::PolyPolygon& rPolyPoly)
299 if (!rPolyPoly.Count())
300 stream << "EMPTY";
301 for (sal_uInt16 i = 0; i < rPolyPoly.Count(); ++i)
302 stream << "[" << i << "] " << rPolyPoly.GetObject(i);
303 return stream;
306 #endif
308 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */