nss: upgrade to release 3.73
[LibreOffice.git] / include / basegfx / polygon / b2dpolygon.hxx
blobe74b458ec3afff2b1e3d4d2073cc2ce4ecff7cf3
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 .
20 #pragma once
22 #include <ostream>
23 #include <vector>
25 #include <sal/types.h>
26 #include <o3tl/cow_wrapper.hxx>
27 #include <basegfx/vector/b2enums.hxx>
28 #include <basegfx/basegfxdllapi.h>
30 class ImplB2DPolygon;
32 namespace basegfx
34 class B2DPoint;
35 class B2DRange;
36 class B2DHomMatrix;
37 class B2DCubicBezier;
38 class SystemDependentData;
39 class SystemDependentDataManager;
40 typedef std::shared_ptr<SystemDependentData> SystemDependentData_SharedPtr;
43 namespace basegfx
45 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC B2DPolygon
47 public:
48 typedef o3tl::cow_wrapper< ImplB2DPolygon > ImplType;
50 private:
51 // internal data.
52 ImplType mpPolygon;
54 public:
55 /// diverse constructors
56 B2DPolygon();
57 B2DPolygon(const B2DPolygon& rPolygon);
58 B2DPolygon(B2DPolygon&& rPolygon);
59 B2DPolygon(const B2DPolygon& rPolygon, sal_uInt32 nIndex, sal_uInt32 nCount);
60 B2DPolygon(std::initializer_list<basegfx::B2DPoint> rPoints);
62 ~B2DPolygon();
64 /// assignment operator
65 B2DPolygon& operator=(const B2DPolygon& rPolygon);
66 B2DPolygon& operator=(B2DPolygon&& rPolygon);
68 /// unshare this polygon with all internally shared instances
69 void makeUnique();
71 /// compare operators
72 bool operator==(const B2DPolygon& rPolygon) const;
73 bool operator!=(const B2DPolygon& rPolygon) const;
75 /// member count
76 sal_uInt32 count() const;
78 /// Coordinate interface
79 basegfx::B2DPoint const & getB2DPoint(sal_uInt32 nIndex) const;
80 void setB2DPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue);
82 /// Coordinate insert/append
83 void insert(sal_uInt32 nIndex, const basegfx::B2DPoint& rPoint, sal_uInt32 nCount = 1);
84 void append(const basegfx::B2DPoint& rPoint, sal_uInt32 nCount);
85 void append(const basegfx::B2DPoint& rPoint);
86 void reserve(sal_uInt32 nCount);
88 /// Basic ControlPoint interface
89 basegfx::B2DPoint getPrevControlPoint(sal_uInt32 nIndex) const;
90 basegfx::B2DPoint getNextControlPoint(sal_uInt32 nIndex) const;
91 void setPrevControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue);
92 void setNextControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue);
93 void setControlPoints(sal_uInt32 nIndex, const basegfx::B2DPoint& rPrev, const basegfx::B2DPoint& rNext);
95 /// ControlPoint resets
96 void resetPrevControlPoint(sal_uInt32 nIndex);
97 void resetNextControlPoint(sal_uInt32 nIndex);
98 void resetControlPoints();
100 /// Bezier segment append with control points. The current last polygon point is implicitly taken as start point.
101 void appendBezierSegment(const basegfx::B2DPoint& rNextControlPoint,
102 const basegfx::B2DPoint& rPrevControlPoint,
103 const basegfx::B2DPoint& rPoint);
105 /// This is a shortcut to append a quadratic bezier segment. The current last polygon point is implicitly taken as start point.
106 /// Note that the quadratic bezier control points will be converted to cubic bezier with 2 control points.
107 void appendQuadraticBezierSegment(const basegfx::B2DPoint& rQuadControlPoint,
108 const basegfx::B2DPoint& rPoint);
110 /// ControlPoint checks
111 bool areControlPointsUsed() const;
112 bool isPrevControlPointUsed(sal_uInt32 nIndex) const;
113 bool isNextControlPointUsed(sal_uInt32 nIndex) const;
114 B2VectorContinuity getContinuityInPoint(sal_uInt32 nIndex) const;
116 /** bezier segment access
118 This method also works when it is no bezier segment at all and will fill
119 the given B2DCubicBezier as needed.
120 In any case, the given B2DCubicBezier will be filled, if necessary with
121 the single start point (if no valid edge exists).
123 @param nIndex
124 Index of the addressed edge's start point
126 @param rTarget
127 The B2DCubicBezier to be filled. It's data WILL be changed.
129 void getBezierSegment(sal_uInt32 nIndex, B2DCubicBezier& rTarget) const;
131 /** Default adaptive subdivision access
133 This method will return a default adaptive subdivision of the polygon.
134 If the polygon does not contain any bezier curve segments, it will
135 just return itself.
137 The subdivision is created on first request and buffered, so when using
138 this subdivision You have the guarantee for fast accesses for multiple
139 usages. It is intended for tooling usage for tasks which would be hard
140 to accomplish on bezier segments (e.g. isInEpsilonRange).
142 The current default subdivision uses adaptiveSubdivideByCount with 9
143 subdivisions which gives 10 edges and 11 points per segment and is
144 usually pretty usable for processing purposes. There is no parameter
145 passing here ATM but it may be changed on demand. If needed, a TYPE
146 and PARAMETER (both defaulted) may be added to allow for switching
147 between the different kinds of subdivisioned and passing them one
148 parameter.
150 The lifetime of the buffered subdivision is based on polygon changes.
151 When changing the polygon, it will be flushed. It is buffered at the
152 refcounted implementation class, so it will survive copy by value and
153 combinations in PolyPolygons.
155 @return
156 The default (and buffered) subdivision of this polygon. It may
157 be this polygon itself when it has no bezier segments. It is guaranteed
158 to have no more bezier segments
160 B2DPolygon const & getDefaultAdaptiveSubdivision() const;
162 /** Get the B2DRange (Rectangle dimensions) of this B2DPolygon
164 A polygon may have up to three ranges:
166 (a) the range of the polygon points
167 (b) the range of the polygon points and control points
168 (c) the outer range of the subdivided bezier curve
170 Ranges (a) and (c) are produced by tools::getRange(); resp. this
171 getB2DRange(). tools::getRangeWithControlPoints handles case (b).
173 To get range (c) a simple solution would be to subdivide the polygon
174 and use getRange() on it. Since subdivision is expensive and decreases
175 the polygon quality, i added this new method. It will use a
176 methodology suggested by HDU. First, it gets the range (a).
177 Then it iterates over the bezier segments and for each it
178 first tests if the outer range of the bezier segment is already
179 contained in the result range.
181 The subdivision itself uses getAllExtremumPositions() to only
182 calculate extremum points and to expand the result accordingly.
183 Thus it calculates maximal four extremum points on the bezier
184 segment, no split is used at all.
186 @return
187 The outer range of the bezier curve/polygon
189 B2DRange const & getB2DRange() const;
191 /** append other 2D polygons
193 The default (nIndex ==0 && nCount == 0) will append
194 the whole rPoly
196 @param rPoly
197 The source polygon
199 @param nIndex
200 The index to the first point of rPoly to append
202 @param nCount
203 The number of points to append from rPoly, starting
204 from nIndex. If zero, as much as possible is appended
206 void append(const B2DPolygon& rPoly, sal_uInt32 nIndex = 0, sal_uInt32 nCount = 0);
208 /// remove points
209 void remove(sal_uInt32 nIndex, sal_uInt32 nCount = 1);
211 /// clear all points
212 void clear();
214 /// closed state interface
215 bool isClosed() const;
216 void setClosed(bool bNew);
218 /// flip polygon direction
219 void flip();
221 /// test if Polygon has double points
222 bool hasDoublePoints() const;
224 /// remove double points, at the begin/end and follow-ups, too
225 void removeDoublePoints();
227 /// apply transformation given in matrix form
228 void transform(const basegfx::B2DHomMatrix& rMatrix);
230 // exclusive management op's for SystemDependentData at B2DPolygon
231 template<class T>
232 std::shared_ptr<T> getSystemDependentData() const
234 return std::static_pointer_cast<T>(getSystemDependantDataInternal(typeid(T).hash_code()));
237 template<class T, class... Args>
238 std::shared_ptr<T> addOrReplaceSystemDependentData(SystemDependentDataManager& manager, Args&&... args) const
240 std::shared_ptr<T> r = std::make_shared<T>(manager, std::forward<Args>(args)...);
242 // tdf#129845 only add to buffer if a relevant buffer time is estimated
243 if(r->calculateCombinedHoldCyclesInSeconds() > 0)
245 basegfx::SystemDependentData_SharedPtr r2(r);
246 addOrReplaceSystemDependentDataInternal(r2);
249 return r;
252 private:
253 void addOrReplaceSystemDependentDataInternal(SystemDependentData_SharedPtr& rData) const;
254 SystemDependentData_SharedPtr getSystemDependantDataInternal(size_t hash_code) const;
257 // typedef for a vector of B2DPolygons
258 typedef ::std::vector< B2DPolygon > B2DPolygonVector;
260 template< typename charT, typename traits >
261 inline std::basic_ostream<charT, traits> & operator <<(
262 std::basic_ostream<charT, traits> & stream, const B2DPolygon& poly )
264 stream << "<" << poly.count() << ":";
265 for (sal_uInt32 i = 0; i < poly.count(); i++)
267 if (i > 0)
268 stream << "--";
269 stream << poly.getB2DPoint(i);
271 stream << ">";
273 return stream;
276 } // end of namespace basegfx
278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */