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 .
19 #ifndef INCLUDED_TOOLS_POLY_HXX
20 #define INCLUDED_TOOLS_POLY_HXX
22 #include <tools/toolsdllapi.h>
23 #include <tools/gen.hxx>
24 #include <o3tl/typed_flags_set.hxx>
25 #include <o3tl/cow_wrapper.hxx>
29 #define POLY_APPEND (0xFFFF)
30 #define POLYPOLY_APPEND (0xFFFF)
32 enum class PolyOptimizeFlags
{
40 template<> struct typed_flags
<PolyOptimizeFlags
> : is_typed_flags
<PolyOptimizeFlags
, 0x0007> {};
50 enum class PolyFlags
: sal_uInt8
52 Normal
, // start-/endpoint of a curve or a line
53 Smooth
, // smooth transition between curves
54 Control
, // control handles of a Bezier curve
55 Symmetric
// smooth and symmetrical transition between curves
60 struct ImplPolyPolygon
;
70 class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Polygon
73 typedef o3tl::cow_wrapper
<ImplPolygon
> ImplType
;
75 ImplType mpImplPolygon
;
78 static void ImplReduceEdges( tools::Polygon
& rPoly
, const double& rArea
, sal_uInt16 nPercent
);
79 void ImplRead( SvStream
& rIStream
);
80 void ImplWrite( SvStream
& rOStream
) const;
84 Polygon( sal_uInt16 nSize
);
85 Polygon( sal_uInt16 nPoints
, const Point
* pPtAry
,
86 const PolyFlags
* pFlagAry
= nullptr );
87 Polygon( const tools::Rectangle
& rRect
);
88 Polygon( const tools::Rectangle
& rRect
,
89 sal_uInt32 nHorzRound
, sal_uInt32 nVertRound
);
90 Polygon( const Point
& rCenter
,
91 long nRadX
, long nRadY
);
92 Polygon( const tools::Rectangle
& rBound
,
93 const Point
& rStart
, const Point
& rEnd
,
94 PolyStyle ePolyStyle
= PolyStyle::Arc
,
95 bool bWholeCircle
= false );
96 Polygon( const Point
& rBezPt1
, const Point
& rCtrlPt1
,
97 const Point
& rBezPt2
, const Point
& rCtrlPt2
,
100 Polygon( const tools::Polygon
& rPoly
);
101 Polygon( tools::Polygon
&& rPoly
) noexcept
;
104 void SetPoint( const Point
& rPt
, sal_uInt16 nPos
);
105 const Point
& GetPoint( sal_uInt16 nPos
) const;
107 void SetFlags( sal_uInt16 nPos
, PolyFlags eFlags
);
108 PolyFlags
GetFlags( sal_uInt16 nPos
) const;
109 bool HasFlags() const;
113 void SetSize( sal_uInt16 nNewSize
);
114 sal_uInt16
GetSize() const;
118 tools::Rectangle
GetBoundRect() const;
119 bool IsInside( const Point
& rPt
) const;
120 double CalcDistance( sal_uInt16 nPt1
, sal_uInt16 nPt2
) const;
121 void Clip( const tools::Rectangle
& rRect
);
122 void Optimize( PolyOptimizeFlags nOptimizeFlags
);
124 /** Adaptive subdivision of polygons with curves
126 This method adaptively subdivides bezier arcs within the
127 polygon to straight line segments and returns the resulting
131 The resulting subdivided polygon
134 This parameter controls the amount of subdivision. The
135 original curve is guaranteed to not differ by more than this
136 amount per bezier segment from the subdivided
137 lines. Concretely, if the polygon is in device coordinates and
138 d equals 1.0, then the difference between the subdivided and
139 the original polygon is guaranteed to be smaller than one
142 void AdaptiveSubdivide( tools::Polygon
& rResult
, const double d
= 1.0 ) const;
143 static Polygon
SubdivideBezier( const Polygon
& rPoly
);
145 void Move( long nHorzMove
, long nVertMove
);
146 void Translate( const Point
& rTrans
);
147 void Scale( double fScaleX
, double fScaleY
);
148 void Rotate( const Point
& rCenter
, double fSin
, double fCos
);
149 void Rotate( const Point
& rCenter
, sal_uInt16 nAngle10
);
151 void Insert( sal_uInt16 nPos
, const Point
& rPt
);
152 void Insert( sal_uInt16 nPos
, const tools::Polygon
& rPoly
);
154 const Point
& operator[]( sal_uInt16 nPos
) const { return GetPoint( nPos
); }
155 Point
& operator[]( sal_uInt16 nPos
);
157 tools::Polygon
& operator=( const tools::Polygon
& rPoly
);
158 tools::Polygon
& operator=( tools::Polygon
&& rPoly
) noexcept
;
159 bool operator==( const tools::Polygon
& rPoly
) const;
160 bool operator!=( const tools::Polygon
& rPoly
) const
161 { return !(Polygon::operator==( rPoly
)); }
162 bool IsEqual( const tools::Polygon
& rPoly
) const;
164 // streaming a Polygon does ignore PolyFlags, so use the Write Or Read
165 // method to take care of PolyFlags
166 TOOLS_DLLPUBLIC
friend SvStream
& ReadPolygon( SvStream
& rIStream
, tools::Polygon
& rPoly
);
167 TOOLS_DLLPUBLIC
friend SvStream
& WritePolygon( SvStream
& rOStream
, const tools::Polygon
& rPoly
);
169 void Read( SvStream
& rIStream
);
170 void Write( SvStream
& rOStream
) const;
172 Point
* GetPointAry();
173 const Point
* GetConstPointAry() const;
174 const PolyFlags
* GetConstFlagAry() const;
176 // convert to ::basegfx::B2DPolygon and return
177 ::basegfx::B2DPolygon
getB2DPolygon() const;
179 // constructor to convert from ::basegfx::B2DPolygon
180 // #i76339# made explicit
181 explicit Polygon(const ::basegfx::B2DPolygon
& rPolygon
);
185 class SAL_WARN_UNUSED TOOLS_DLLPUBLIC PolyPolygon
188 o3tl::cow_wrapper
<ImplPolyPolygon
> mpImplPolyPolygon
;
190 enum class PolyClipOp
{
194 TOOLS_DLLPRIVATE
void ImplDoOperation( const tools::PolyPolygon
& rPolyPoly
, tools::PolyPolygon
& rResult
, PolyClipOp nOperation
) const;
197 PolyPolygon( sal_uInt16 nInitSize
= 16 );
198 PolyPolygon( const tools::Polygon
& rPoly
);
199 PolyPolygon( const tools::PolyPolygon
& rPolyPoly
);
200 PolyPolygon( tools::PolyPolygon
&& rPolyPoly
) noexcept
;
203 void Insert( const tools::Polygon
& rPoly
, sal_uInt16 nPos
= POLYPOLY_APPEND
);
204 void Remove( sal_uInt16 nPos
);
205 void Replace( const Polygon
& rPoly
, sal_uInt16 nPos
);
206 const tools::Polygon
& GetObject( sal_uInt16 nPos
) const;
212 sal_uInt16
Count() const;
213 tools::Rectangle
GetBoundRect() const;
214 void Clip( const tools::Rectangle
& rRect
);
215 void Optimize( PolyOptimizeFlags nOptimizeFlags
);
217 /** Adaptive subdivision of polygons with curves
219 This method adaptively subdivides bezier arcs within the
220 polygon to straight line segments and returns the resulting
224 The resulting subdivided polygon
226 If the polygon is in device coordinates, then the difference between the subdivided and
227 the original polygon is guaranteed to be smaller than one
230 void AdaptiveSubdivide( tools::PolyPolygon
& rResult
) const;
231 static tools::PolyPolygon
SubdivideBezier( const tools::PolyPolygon
& rPolyPoly
);
233 void GetIntersection( const tools::PolyPolygon
& rPolyPoly
, tools::PolyPolygon
& rResult
) const;
234 void GetUnion( const tools::PolyPolygon
& rPolyPoly
, tools::PolyPolygon
& rResult
) const;
236 void Move( long nHorzMove
, long nVertMove
);
237 void Translate( const Point
& rTrans
);
238 void Scale( double fScaleX
, double fScaleY
);
239 void Rotate( const Point
& rCenter
, double fSin
, double fCos
);
240 void Rotate( const Point
& rCenter
, sal_uInt16 nAngle10
);
242 const tools::Polygon
& operator[]( sal_uInt16 nPos
) const { return GetObject( nPos
); }
243 tools::Polygon
& operator[]( sal_uInt16 nPos
);
245 tools::PolyPolygon
& operator=( const tools::PolyPolygon
& rPolyPoly
);
246 tools::PolyPolygon
& operator=( tools::PolyPolygon
&& rPolyPoly
) noexcept
;
247 bool operator==( const tools::PolyPolygon
& rPolyPoly
) const;
248 bool operator!=( const tools::PolyPolygon
& rPolyPoly
) const
249 { return !(PolyPolygon::operator==( rPolyPoly
)); }
251 TOOLS_DLLPUBLIC
friend SvStream
& ReadPolyPolygon( SvStream
& rIStream
, tools::PolyPolygon
& rPolyPoly
);
252 TOOLS_DLLPUBLIC
friend SvStream
& WritePolyPolygon( SvStream
& rOStream
, const tools::PolyPolygon
& rPolyPoly
);
254 void Read( SvStream
& rIStream
);
255 void Write( SvStream
& rOStream
) const;
257 // convert to ::basegfx::B2DPolyPolygon and return
258 ::basegfx::B2DPolyPolygon
getB2DPolyPolygon() const;
260 // constructor to convert from ::basegfx::B2DPolyPolygon
261 // #i76339# made explicit
262 explicit PolyPolygon(const ::basegfx::B2DPolyPolygon
& rPolyPolygon
);
265 } /* namespace tools */
267 typedef std::vector
< tools::PolyPolygon
> PolyPolyVector
;
271 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */