LibreOffice Module tools (master) 1
poly.hxx
Go to the documentation of this file.
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 INCLUDED_TOOLS_POLY_HXX
20#define INCLUDED_TOOLS_POLY_HXX
21
22#include <rtl/ustring.hxx>
23#include <tools/toolsdllapi.h>
24#include <tools/gen.hxx>
25#include <tools/degree.hxx>
27#include <o3tl/cow_wrapper.hxx>
28
29#include <vector>
30
31#define POLY_APPEND (0xFFFF)
32#define POLYPOLY_APPEND (0xFFFF)
33
35 NONE = 0x0000,
36 CLOSE = 0x0001,
37 NO_SAME = 0x0002,
38 EDGES = 0x0004,
39};
40namespace o3tl
41{
42 template<> struct typed_flags<PolyOptimizeFlags> : is_typed_flags<PolyOptimizeFlags, 0x0007> {};
43}
44
45enum class PolyStyle
46{
47 Arc = 1,
48 Pie = 2,
49 Chord = 3
50};
51
52enum class PolyFlags : sal_uInt8
53{
54 Normal, // start-/endpoint of a curve or a line
55 Smooth, // smooth transition between curves
56 Control, // control handles of a Bezier curve
57 Symmetric // smooth and symmetrical transition between curves
58};
59
60class SvStream;
61class ImplPolygon;
62struct ImplPolyPolygon;
63
64namespace basegfx
65{
66 class B2DPolygon;
67 class B2DPolyPolygon;
68}
69
70namespace tools {
71
73{
74public:
76private:
78
79public:
80 static void ImplReduceEdges( tools::Polygon& rPoly, const double& rArea, sal_uInt16 nPercent );
81 void ImplRead( SvStream& rIStream );
82 void ImplWrite( SvStream& rOStream ) const;
83
84public:
85 Polygon();
86 explicit Polygon( sal_uInt16 nSize );
87 Polygon( sal_uInt16 nPoints, const Point* pPtAry,
88 const PolyFlags* pFlagAry = nullptr );
89 explicit Polygon( const tools::Rectangle& rRect );
90 Polygon( const tools::Rectangle& rRect,
91 sal_uInt32 nHorzRound, sal_uInt32 nVertRound );
92 Polygon( const Point& rCenter,
93 tools::Long nRadX, tools::Long nRadY );
94 Polygon( const tools::Rectangle& rBound,
95 const Point& rStart, const Point& rEnd,
96 PolyStyle ePolyStyle = PolyStyle::Arc,
97 const bool bClockWiseArcDirection = false);
98 Polygon( const Point& rBezPt1, const Point& rCtrlPt1,
99 const Point& rBezPt2, const Point& rCtrlPt2,
100 sal_uInt16 nPoints );
101
102 Polygon( const tools::Polygon& rPoly );
103 Polygon( tools::Polygon&& rPoly) noexcept;
104 ~Polygon();
105
106 void SetPoint( const Point& rPt, sal_uInt16 nPos );
107 const Point& GetPoint( sal_uInt16 nPos ) const;
108
109 void SetFlags( sal_uInt16 nPos, PolyFlags eFlags );
110 PolyFlags GetFlags( sal_uInt16 nPos ) const;
111 bool HasFlags() const;
112
113 bool IsRect() const;
114
115 void SetSize( sal_uInt16 nNewSize );
116 sal_uInt16 GetSize() const;
117
118 void Clear();
119
120 tools::Rectangle GetBoundRect() const;
121 bool Contains( const Point& rPt ) const;
122 double CalcDistance( sal_uInt16 nPt1, sal_uInt16 nPt2 ) const;
123 void Clip( const tools::Rectangle& rRect );
124 void Optimize( PolyOptimizeFlags nOptimizeFlags );
125
144 void AdaptiveSubdivide( tools::Polygon& rResult, const double d = 1.0 ) const;
145 static Polygon SubdivideBezier( const Polygon& rPoly );
146
147 void Move( tools::Long nHorzMove, tools::Long nVertMove );
148 void Translate( const Point& rTrans );
149 void Scale( double fScaleX, double fScaleY );
150 void Rotate( const Point& rCenter, double fSin, double fCos );
151 void Rotate( const Point& rCenter, Degree10 nAngle10 );
152
153 void Insert( sal_uInt16 nPos, const Point& rPt );
154 void Insert( sal_uInt16 nPos, const tools::Polygon& rPoly );
155
156 const Point& operator[]( sal_uInt16 nPos ) const { return GetPoint( nPos ); }
157 Point& operator[]( sal_uInt16 nPos );
158
159 tools::Polygon& operator=( const tools::Polygon& rPoly );
160 tools::Polygon& operator=( tools::Polygon&& rPoly ) noexcept;
161 bool operator==( const tools::Polygon& rPoly ) const;
162 bool operator!=( const tools::Polygon& rPoly ) const
163 { return !(Polygon::operator==( rPoly )); }
164 bool IsEqual( const tools::Polygon& rPoly ) const;
165
166 // streaming a Polygon does ignore PolyFlags, so use the Write Or Read
167 // method to take care of PolyFlags
168 TOOLS_DLLPUBLIC friend SvStream& ReadPolygon( SvStream& rIStream, tools::Polygon& rPoly );
169 TOOLS_DLLPUBLIC friend SvStream& WritePolygon( SvStream& rOStream, const tools::Polygon& rPoly );
170
171 void Read( SvStream& rIStream );
172 void Write( SvStream& rOStream ) const;
173
174 Point * GetPointAry();
175 const Point* GetConstPointAry() const;
176 const PolyFlags* GetConstFlagAry() const;
177
178 // convert to ::basegfx::B2DPolygon and return
179 ::basegfx::B2DPolygon getB2DPolygon() const;
180
181 // constructor to convert from ::basegfx::B2DPolygon
182 // #i76339# made explicit
183 explicit Polygon(const ::basegfx::B2DPolygon& rPolygon);
184};
185
186
188{
189private:
191
192 enum class PolyClipOp {
193 INTERSECT,
194 UNION
195 };
196 TOOLS_DLLPRIVATE void ImplDoOperation( const tools::PolyPolygon& rPolyPoly, tools::PolyPolygon& rResult, PolyClipOp nOperation ) const;
197
198public:
199 explicit PolyPolygon( sal_uInt16 nInitSize = 16 );
200 explicit PolyPolygon( const tools::Polygon& rPoly );
201 explicit PolyPolygon( const tools::Rectangle& );
202 PolyPolygon( const tools::PolyPolygon& rPolyPoly );
203 PolyPolygon( tools::PolyPolygon&& rPolyPoly ) noexcept;
204 ~PolyPolygon();
205
206 void Insert( const tools::Polygon& rPoly, sal_uInt16 nPos = POLYPOLY_APPEND );
207 void Remove( sal_uInt16 nPos );
208 void Replace( const Polygon& rPoly, sal_uInt16 nPos );
209 const tools::Polygon& GetObject( sal_uInt16 nPos ) const;
210
211 bool IsRect() const;
212
213 void Clear();
214
215 sal_uInt16 Count() const;
216 tools::Rectangle GetBoundRect() const;
217 void Clip( const tools::Rectangle& rRect );
218 void Optimize( PolyOptimizeFlags nOptimizeFlags );
219
233 void AdaptiveSubdivide( tools::PolyPolygon& rResult ) const;
234 static tools::PolyPolygon SubdivideBezier( const tools::PolyPolygon& rPolyPoly );
235
236 void GetIntersection( const tools::PolyPolygon& rPolyPoly, tools::PolyPolygon& rResult ) const;
237 void GetUnion( const tools::PolyPolygon& rPolyPoly, tools::PolyPolygon& rResult ) const;
238
239 void Move( tools::Long nHorzMove, tools::Long nVertMove );
240 void Translate( const Point& rTrans );
241 void Scale( double fScaleX, double fScaleY );
242 void Rotate( const Point& rCenter, double fSin, double fCos );
243 void Rotate( const Point& rCenter, Degree10 nAngle10 );
244
245 const tools::Polygon& operator[]( sal_uInt16 nPos ) const { return GetObject( nPos ); }
246 tools::Polygon& operator[]( sal_uInt16 nPos );
247
248 tools::PolyPolygon& operator=( const tools::PolyPolygon& rPolyPoly );
249 tools::PolyPolygon& operator=( tools::PolyPolygon&& rPolyPoly ) noexcept;
250 bool operator==( const tools::PolyPolygon& rPolyPoly ) const;
251 bool operator!=( const tools::PolyPolygon& rPolyPoly ) const
252 { return !(PolyPolygon::operator==( rPolyPoly )); }
253
254 TOOLS_DLLPUBLIC friend SvStream& ReadPolyPolygon( SvStream& rIStream, tools::PolyPolygon& rPolyPoly );
255 TOOLS_DLLPUBLIC friend SvStream& WritePolyPolygon( SvStream& rOStream, const tools::PolyPolygon& rPolyPoly );
256
257 void Read( SvStream& rIStream );
258 void Write( SvStream& rOStream ) const;
259
260 // convert to ::basegfx::B2DPolyPolygon and return
261 ::basegfx::B2DPolyPolygon getB2DPolyPolygon() const;
262
263 // constructor to convert from ::basegfx::B2DPolyPolygon
264 // #i76339# made explicit
265 explicit PolyPolygon(const ::basegfx::B2DPolyPolygon& rPolyPolygon);
266};
267
268template< typename charT, typename traits >
269inline std::basic_ostream<charT, traits> & operator <<(
270 std::basic_ostream<charT, traits> & stream, const Polygon& poly )
271{
272 stream << "<" << poly.GetSize() << ":";
273 for (sal_uInt16 i = 0; i < poly.GetSize(); i++)
274 {
275 if (i > 0)
276 stream << "--";
277 stream << poly.GetPoint(i);
278
279 OUString aFlag;
280 if (poly.GetFlags(i) == PolyFlags::Normal)
281 aFlag = "Normal";
282 else if (poly.GetFlags(i) == PolyFlags::Smooth)
283 aFlag = "Smooth";
284 else if (poly.GetFlags(i) == PolyFlags::Control)
285 aFlag = "Control";
286 else if (poly.GetFlags(i) == PolyFlags::Symmetric)
287 aFlag = "Symmetric";
288
289 stream << ";f=" << aFlag;
290 }
291 stream << ">";
292 return stream;
293}
294
295template< typename charT, typename traits >
296inline std::basic_ostream<charT, traits> & operator <<(
297 std::basic_ostream<charT, traits> & stream, const PolyPolygon& poly )
298{
299 stream << "[" << poly.Count() << ":";
300 for (sal_uInt16 i = 0; i < poly.Count(); i++)
301 {
302 if (i > 0)
303 stream << ",";
304 stream << poly.GetObject(i);
305 }
306 stream << "]";
307 return stream;
308}
309
310} /* namespace tools */
311
312typedef std::vector< tools::PolyPolygon > PolyPolyVector;
313
314#endif
315
316/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const short CLOSE
bool operator==(const BigInt &rVal1, const BigInt &rVal2)
Definition: bigint.cxx:806
Definition: gen.hxx:78
bool operator!=(const tools::PolyPolygon &rPolyPoly) const
Definition: poly.hxx:251
PolyPolygon(const ::basegfx::B2DPolyPolygon &rPolyPolygon)
bool operator==(const tools::PolyPolygon &rPolyPoly) const
Definition: poly2.cxx:381
o3tl::cow_wrapper< ImplPolyPolygon > mpImplPolyPolygon
Definition: poly.hxx:190
const tools::Polygon & operator[](sal_uInt16 nPos) const
Definition: poly.hxx:245
bool operator!=(const tools::Polygon &rPoly) const
Definition: poly.hxx:162
const Point & operator[](sal_uInt16 nPos) const
Definition: poly.hxx:156
bool operator==(const tools::Polygon &rPoly) const
Definition: poly.cxx:1599
ImplType mpImplPolygon
Definition: poly.hxx:77
PolyFlags GetFlags(sal_uInt16 nPos) const
Definition: poly.cxx:978
sal_uInt16 GetSize() const
Definition: poly.cxx:1018
const Point & GetPoint(sal_uInt16 nPos) const
Definition: poly.cxx:970
o3tl::cow_wrapper< ImplPolygon > ImplType
Definition: poly.hxx:75
Polygon(const ::basegfx::B2DPolygon &rPolygon)
virtual void Insert(SotClipboardFormatId nFormat, const OUString &rFormatName) override
virtual css::uno::Reference< css::embed::XEmbeddedObject > GetObject() override
Reference< XOutputStream > stream
void SetFlags(EVControlBits &rBits, EVControlBits nMask, bool bOn)
sal_uInt16 nPos
void Clear(EHistoryType eHistory)
NONE
Clip
int i
Note: this class is a true marvel of engineering: because the author could not decide whether it's be...
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &stream, const tools::Rectangle &rectangle)
Definition: gen.hxx:808
SvStream & WritePolyPolygon(SvStream &rOStream, const tools::PolyPolygon &rPolyPoly)
Definition: poly2.cxx:419
long Long
Definition: long.hxx:34
SvStream & ReadPolyPolygon(SvStream &rIStream, tools::PolyPolygon &rPolyPoly)
Definition: poly2.cxx:386
SvStream & ReadPolygon(SvStream &rIStream, tools::Polygon &rPoly)
Definition: poly.cxx:1625
SvStream & WritePolygon(SvStream &rOStream, const tools::Polygon &rPoly)
Definition: poly.cxx:1652
PolyFlags
Definition: poly.hxx:53
#define POLYPOLY_APPEND
Definition: poly.hxx:32
PolyStyle
Definition: poly.hxx:46
std::vector< tools::PolyPolygon > PolyPolyVector
Definition: poly.hxx:312
PolyOptimizeFlags
Definition: poly.hxx:34
#define TOOLS_DLLPRIVATE
Definition: toolsdllapi.h:30
#define TOOLS_DLLPUBLIC
Definition: toolsdllapi.h:28
unsigned char sal_uInt8
#define SAL_WARN_UNUSED
Count