1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
22 #include "tools/toolsdllapi.h"
23 #include <tools/gen.hxx>
24 #include <tools/debug.hxx>
28 #define POLY_APPEND (0xFFFF)
29 #define POLYPOLY_APPEND (0xFFFF)
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
45 #ifndef ENUM_POLYFLAGS_DECLARED
46 #define ENUM_POLYFLAGS_DECLARED
56 class SAL_WARN_UNUSED PolyOptimizeData
60 enum DataType
{ DATA_NONE
= 0, DATA_ABSOLUT
= 1, DATA_PERCENT
= 2 };
62 union { sal_uIntPtr mnAbsolut
; sal_uInt16 mnPercent
; };
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
) {}
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
; }
75 class ImplPolyPolygon
;
84 class TOOLS_DLLPUBLIC SAL_WARN_UNUSED Polygon
87 ImplPolygon
* mpImplPolygon
;
89 TOOLS_DLLPRIVATE
inline void ImplMakeUnique();
92 static void ImplReduceEdges( Polygon
& rPoly
, const double& rArea
, sal_uInt16 nPercent
);
93 void ImplRead( SvStream
& rIStream
);
94 void ImplWrite( SvStream
& rOStream
) const;
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 );
115 Polygon( const Polygon
& rPoly
);
118 void SetPoint( const Point
& rPt
, sal_uInt16 nPos
);
119 const Point
& GetPoint( sal_uInt16 nPos
) const;
121 void SetFlags( sal_uInt16 nPos
, PolyFlags eFlags
);
122 PolyFlags
GetFlags( sal_uInt16 nPos
) const;
123 sal_Bool
HasFlags() const;
125 sal_Bool
IsRect() const;
127 void SetSize( sal_uInt16 nNewSize
);
128 sal_uInt16
GetSize() const;
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
);
140 /** Adaptive subdivision of polygons with curves
142 This method adaptively subdivides bezier arcs within the
143 polygon to straight line segments and returns the resulting
147 The resulting subdivided polygon
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
158 void AdaptiveSubdivide( Polygon
& rResult
, const double d
= 1.0 ) const;
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
);
166 void Insert( sal_uInt16 nPos
, const Point
& rPt
, PolyFlags eFlags
= POLY_NORMAL
);
167 void Insert( sal_uInt16 nPos
, const Polygon
& rPoly
);
169 const Point
& operator[]( sal_uInt16 nPos
) const { return GetPoint( nPos
); }
170 Point
& operator[]( sal_uInt16 nPos
);
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;
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
);
183 void Read( SvStream
& rIStream
);
184 void Write( SvStream
& rOStream
) const;
186 const Point
* GetConstPointAry() const;
187 const sal_uInt8
* GetConstFlagAry() const;
189 // convert to ::basegfx::B2DPolygon and return
190 ::basegfx::B2DPolygon
getB2DPolygon() const;
192 // constructor to convert from ::basegfx::B2DPolygon
193 // #i76339# made explicit
194 explicit Polygon(const ::basegfx::B2DPolygon
& rPolygon
);
197 class TOOLS_DLLPUBLIC SAL_WARN_UNUSED PolyPolygon
200 ImplPolyPolygon
* mpImplPolyPolygon
;
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
);
207 PolyPolygon( sal_uInt16 nInitSize
= 16, sal_uInt16 nResize
= 16 );
208 PolyPolygon( const Polygon
& rPoly
);
209 PolyPolygon( const PolyPolygon
& rPolyPoly
);
212 void Insert( const Polygon
& rPoly
, sal_uInt16 nPos
= POLYPOLY_APPEND
);
213 void Remove( sal_uInt16 nPos
);
214 void Replace( const Polygon
& rPoly
, sal_uInt16 nPos
);
215 const Polygon
& GetObject( sal_uInt16 nPos
) const;
217 sal_Bool
IsRect() const;
221 sal_uInt16
Count() const;
222 Rectangle
GetBoundRect() const;
223 void Clip( const Rectangle
& rRect
);
224 void Optimize( sal_uIntPtr nOptimizeFlags
, const PolyOptimizeData
* pData
= NULL
);
226 /** Adaptive subdivision of polygons with curves
228 This method adaptively subdivides bezier arcs within the
229 polygon to straight line segments and returns the resulting
233 The resulting subdivided polygon
236 This parameter controls the amount of subdivision. The
237 original curve is guaranteed to not differ by more than this
238 amount per bezier segment from the subdivided
239 lines. Concretely, if the polygon is in device coordinates and
240 d equals 1.0, then the difference between the subdivided and
241 the original polygon is guaranteed to be smaller than one
244 void AdaptiveSubdivide( PolyPolygon
& rResult
, const double d
= 1.0 ) const;
246 void GetIntersection( const PolyPolygon
& rPolyPoly
, PolyPolygon
& rResult
) const;
247 void GetUnion( const PolyPolygon
& rPolyPoly
, PolyPolygon
& rResult
) const;
249 void Move( long nHorzMove
, long nVertMove
);
250 void Translate( const Point
& rTrans
);
251 void Scale( double fScaleX
, double fScaleY
);
252 void Rotate( const Point
& rCenter
, double fSin
, double fCos
);
253 void Rotate( const Point
& rCenter
, sal_uInt16 nAngle10
);
255 const Polygon
& operator[]( sal_uInt16 nPos
) const { return GetObject( nPos
); }
256 Polygon
& operator[]( sal_uInt16 nPos
);
258 PolyPolygon
& operator=( const PolyPolygon
& rPolyPoly
);
259 sal_Bool
operator==( const PolyPolygon
& rPolyPoly
) const;
260 sal_Bool
operator!=( const PolyPolygon
& rPolyPoly
) const
261 { return !(PolyPolygon::operator==( rPolyPoly
)); }
263 sal_Bool
IsEqual( const PolyPolygon
& rPolyPoly
) const;
265 TOOLS_DLLPUBLIC
friend SvStream
& operator>>( SvStream
& rIStream
, PolyPolygon
& rPolyPoly
);
266 TOOLS_DLLPUBLIC
friend SvStream
& operator<<( SvStream
& rOStream
, const PolyPolygon
& rPolyPoly
);
268 void Read( SvStream
& rIStream
);
269 void Write( SvStream
& rOStream
) const;
271 // convert to ::basegfx::B2DPolyPolygon and return
272 ::basegfx::B2DPolyPolygon
getB2DPolyPolygon() const;
274 // constructor to convert from ::basegfx::B2DPolyPolygon
275 // #i76339# made explicit
276 explicit PolyPolygon(const ::basegfx::B2DPolyPolygon
& rPolyPolygon
);
279 typedef std::vector
< PolyPolygon
> PolyPolyVector
;
283 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */