tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / include / basegfx / polygon / b2dpolygon.hxx
blob5cbcbd7caea2f1e64ac85dfef17752f15dfde43a
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 <memory>
23 #include <ostream>
24 #include <vector>
26 #include <sal/types.h>
27 #include <o3tl/cow_wrapper.hxx>
28 #include <basegfx/vector/b2enums.hxx>
29 #include <basegfx/utils/systemdependentdata.hxx>
30 #include <basegfx/basegfxdllapi.h>
32 class ImplB2DPolygon;
34 namespace basegfx
36 class B2DPoint;
37 class B2DRange;
38 class B2DHomMatrix;
39 class B2DCubicBezier;
40 class B2DVector;
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;
74 /// member count
75 sal_uInt32 count() const;
77 /// Coordinate interface
78 basegfx::B2DPoint const & getB2DPoint(sal_uInt32 nIndex) const;
79 void setB2DPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue);
81 /// Coordinate insert/append
82 void insert(sal_uInt32 nIndex, const basegfx::B2DPoint& rPoint, sal_uInt32 nCount = 1);
83 void append(const basegfx::B2DPoint& rPoint, sal_uInt32 nCount);
84 void append(const basegfx::B2DPoint& rPoint);
85 void reserve(sal_uInt32 nCount);
87 /// Basic ControlPoint interface
88 basegfx::B2DPoint getPrevControlPoint(sal_uInt32 nIndex) const;
89 basegfx::B2DPoint getNextControlPoint(sal_uInt32 nIndex) const;
90 void setPrevControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue);
91 void setNextControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue);
92 void setControlPoints(sal_uInt32 nIndex, const basegfx::B2DPoint& rPrev, const basegfx::B2DPoint& rNext);
94 /// ControlPoint resets
95 void resetPrevControlPoint(sal_uInt32 nIndex);
96 void resetNextControlPoint(sal_uInt32 nIndex);
97 void resetControlPoints();
99 /// Bezier segment append with control points. The current last polygon point is implicitly taken as start point.
100 void appendBezierSegment(const basegfx::B2DPoint& rNextControlPoint,
101 const basegfx::B2DPoint& rPrevControlPoint,
102 const basegfx::B2DPoint& rPoint);
104 /// This is a shortcut to append a quadratic bezier segment. The current last polygon point is implicitly taken as start point.
105 /// Note that the quadratic bezier control points will be converted to cubic bezier with 2 control points.
106 void appendQuadraticBezierSegment(const basegfx::B2DPoint& rQuadControlPoint,
107 const basegfx::B2DPoint& rPoint);
109 /// ControlPoint checks
110 bool areControlPointsUsed() const;
111 bool isPrevControlPointUsed(sal_uInt32 nIndex) const;
112 bool isNextControlPointUsed(sal_uInt32 nIndex) const;
113 B2VectorContinuity getContinuityInPoint(sal_uInt32 nIndex) const;
115 /** bezier segment access
117 This method also works when it is no bezier segment at all and will fill
118 the given B2DCubicBezier as needed.
119 In any case, the given B2DCubicBezier will be filled, if necessary with
120 the single start point (if no valid edge exists).
122 @param nIndex
123 Index of the addressed edge's start point
125 @param rTarget
126 The B2DCubicBezier to be filled. It's data WILL be changed.
128 void getBezierSegment(sal_uInt32 nIndex, B2DCubicBezier& rTarget) const;
130 /** Default adaptive subdivision access
132 This method will return a default adaptive subdivision of the polygon.
133 If the polygon does not contain any bezier curve segments, it will
134 just return itself.
136 The subdivision is created on first request and buffered, so when using
137 this subdivision You have the guarantee for fast accesses for multiple
138 usages. It is intended for tooling usage for tasks which would be hard
139 to accomplish on bezier segments (e.g. isInEpsilonRange).
141 The current default subdivision uses adaptiveSubdivideByCount with 9
142 subdivisions which gives 10 edges and 11 points per segment and is
143 usually pretty usable for processing purposes. There is no parameter
144 passing here ATM but it may be changed on demand. If needed, a TYPE
145 and PARAMETER (both defaulted) may be added to allow for switching
146 between the different kinds of subdivisioned and passing them one
147 parameter.
149 The lifetime of the buffered subdivision is based on polygon changes.
150 When changing the polygon, it will be flushed. It is buffered at the
151 refcounted implementation class, so it will survive copy by value and
152 combinations in PolyPolygons.
154 @return
155 The default (and buffered) subdivision of this polygon. It may
156 be this polygon itself when it has no bezier segments. It is guaranteed
157 to have no more bezier segments
159 B2DPolygon const & getDefaultAdaptiveSubdivision() const;
161 /** Get the B2DRange (Rectangle dimensions) of this B2DPolygon
163 A polygon may have up to three ranges:
165 (a) the range of the polygon points
166 (b) the range of the polygon points and control points
167 (c) the outer range of the subdivided bezier curve
169 Ranges (a) and (c) are produced by tools::getRange(); resp. this
170 getB2DRange(). tools::getRangeWithControlPoints handles case (b).
172 To get range (c) a simple solution would be to subdivide the polygon
173 and use getRange() on it. Since subdivision is expensive and decreases
174 the polygon quality, i added this new method. It will use a
175 methodology suggested by HDU. First, it gets the range (a).
176 Then it iterates over the bezier segments and for each it
177 first tests if the outer range of the bezier segment is already
178 contained in the result range.
180 The subdivision itself uses getAllExtremumPositions() to only
181 calculate extremum points and to expand the result accordingly.
182 Thus it calculates maximal four extremum points on the bezier
183 segment, no split is used at all.
185 @return
186 The outer range of the bezier curve/polygon
188 B2DRange const & getB2DRange() const;
190 /** append other 2D polygons
192 The default (nIndex ==0 && nCount == 0) will append
193 the whole rPoly
195 @param rPoly
196 The source polygon
198 @param nIndex
199 The index to the first point of rPoly to append
201 @param nCount
202 The number of points to append from rPoly, starting
203 from nIndex. If zero, as much as possible is appended
205 void append(const B2DPolygon& rPoly, sal_uInt32 nIndex = 0, sal_uInt32 nCount = 0);
207 /// remove points
208 void remove(sal_uInt32 nIndex, sal_uInt32 nCount = 1);
210 /// clear all points
211 void clear();
213 /// closed state interface
214 bool isClosed() const;
215 void setClosed(bool bNew);
217 /// flip polygon direction
218 void flip();
220 /// test if Polygon has double points
221 bool hasDoublePoints() const;
223 /// remove double points, at the begin/end and follow-ups, too
224 void removeDoublePoints();
226 /// apply transformation given in matrix form
227 void transform(const basegfx::B2DHomMatrix& rMatrix);
229 // exclusive management op's for SystemDependentData at B2DPolygon
230 template<class T>
231 std::shared_ptr<T> getSystemDependentData(basegfx::SDD_Type aType) const
233 return std::static_pointer_cast<T>(getSystemDependantDataInternal(aType));
236 template<class T, class... Args>
237 std::shared_ptr<T> addOrReplaceSystemDependentData(Args&&... args) const
239 std::shared_ptr<T> r = std::make_shared<T>(std::forward<Args>(args)...);
241 // tdf#129845 only add to buffer if a relevant buffer time is estimated
242 if(r->calculateCombinedHoldCyclesInSeconds() > 0)
244 basegfx::SystemDependentData_SharedPtr r2(r);
245 addOrReplaceSystemDependentDataInternal(r2);
248 return r;
251 private:
252 void addOrReplaceSystemDependentDataInternal(SystemDependentData_SharedPtr& rData) const;
253 SystemDependentData_SharedPtr getSystemDependantDataInternal(basegfx::SDD_Type aType) const;
254 const basegfx::B2DVector& getPrevControlVector(sal_uInt32 nIndex) const;
255 const basegfx::B2DVector& getNextControlVector(sal_uInt32 nIndex) const;
258 // typedef for a vector of B2DPolygons
259 typedef ::std::vector< B2DPolygon > B2DPolygonVector;
261 template< typename charT, typename traits >
262 inline std::basic_ostream<charT, traits> & operator <<(
263 std::basic_ostream<charT, traits> & stream, const B2DPolygon& poly )
265 stream << "<" << poly.count() << ":";
266 for (sal_uInt32 i = 0; i < poly.count(); i++)
268 if (i > 0)
269 stream << "--";
270 stream << poly.getB2DPoint(i);
272 stream << ">";
274 return stream;
277 } // end of namespace basegfx
279 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */