/src/libreoffice/include/basegfx/curve/b2dcubicbezier.hxx
Line | Count | Source |
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 | | |
20 | | #pragma once |
21 | | |
22 | | #include <basegfx/point/b2dpoint.hxx> |
23 | | #include <basegfx/basegfxdllapi.h> |
24 | | |
25 | | #include <vector> |
26 | | |
27 | | namespace basegfx |
28 | | { |
29 | | class B2DPolygon; |
30 | | } |
31 | | namespace basegfx { class B2DRange; } |
32 | | namespace basegfx { class B2DVector; } |
33 | | |
34 | | namespace basegfx |
35 | | { |
36 | | class BASEGFX_DLLPUBLIC B2DCubicBezier |
37 | | { |
38 | | private: |
39 | | B2DPoint maStartPoint; |
40 | | B2DPoint maEndPoint; |
41 | | B2DPoint maControlPointA; |
42 | | B2DPoint maControlPointB; |
43 | | |
44 | | public: |
45 | | B2DCubicBezier(); |
46 | | B2DCubicBezier(const B2DCubicBezier& rBezier); |
47 | | B2DCubicBezier(const B2DPoint& rStart, const B2DPoint& rControlPointA, const B2DPoint& rControlPointB, const B2DPoint& rEnd); |
48 | | |
49 | | // assignment operator |
50 | | B2DCubicBezier& operator=(const B2DCubicBezier& rBezier); |
51 | | |
52 | | // compare operators |
53 | | bool operator==(const B2DCubicBezier& rBezier) const; |
54 | | bool equal(const B2DCubicBezier& rBezier) const; |
55 | | |
56 | | // test if vectors are used |
57 | | bool isBezier() const; |
58 | | |
59 | | // test if contained bezier is trivial and reset vectors accordingly |
60 | | void testAndSolveTrivialBezier(); |
61 | | |
62 | | /** get length of edge |
63 | | |
64 | | This method handles beziers and simple edges. For |
65 | | beziers, the deviation describes the maximum allowed |
66 | | deviation from the real edge length. The default |
67 | | allows a deviation of 1% from the correct length. |
68 | | |
69 | | For beziers, there is no direct way to get the length, |
70 | | thus this method may subdivide the bezier edge and may |
71 | | not be cheap. |
72 | | |
73 | | @param fDeviation |
74 | | The maximal allowed deviation between correct length |
75 | | and bezier edge length |
76 | | |
77 | | @return |
78 | | The length of the edge |
79 | | */ |
80 | | double getLength(double fDeviation = 0.01) const; |
81 | | |
82 | | // get distance between start and end point |
83 | | SAL_DLLPRIVATE double getEdgeLength() const; |
84 | | |
85 | | // get length of control polygon |
86 | | SAL_DLLPRIVATE double getControlPolygonLength() const; |
87 | | |
88 | | // data interface |
89 | 17.2M | const B2DPoint& getStartPoint() const { return maStartPoint; } |
90 | 30.6M | void setStartPoint(const B2DPoint& rValue) { maStartPoint = rValue; } |
91 | | |
92 | 37.6M | const B2DPoint& getEndPoint() const { return maEndPoint; } |
93 | 27.6M | void setEndPoint(const B2DPoint& rValue) { maEndPoint = rValue; } |
94 | | |
95 | 5.48M | const B2DPoint& getControlPointA() const { return maControlPointA; } |
96 | 27.6M | void setControlPointA(const B2DPoint& rValue) { maControlPointA = rValue; } |
97 | | |
98 | 3.70M | const B2DPoint& getControlPointB() const { return maControlPointB; } |
99 | 27.6M | void setControlPointB(const B2DPoint& rValue) { maControlPointB = rValue; } |
100 | | |
101 | | /** get the tangent in point t |
102 | | |
103 | | This method handles all the exceptions, e.g. when control point |
104 | | A is equal to start point and/or control point B is equal to end |
105 | | point |
106 | | |
107 | | @param t |
108 | | The bezier index in the range [0.0 .. 1.0]. It will be truncated. |
109 | | |
110 | | @return |
111 | | The tangent vector in point t |
112 | | */ |
113 | | B2DVector getTangent(double t) const; |
114 | | |
115 | | /** adaptive subdivide by angle criteria |
116 | | no start point is added, but all necessary created edges |
117 | | and the end point |
118 | | #i37443# allow the criteria to get unsharp in recursions |
119 | | */ |
120 | | SAL_DLLPRIVATE void adaptiveSubdivideByAngle(B2DPolygon& rTarget, double fAngleBound) const; |
121 | | |
122 | | /** #i37443# adaptive subdivide by nCount subdivisions |
123 | | no start point is added, but all necessary created edges |
124 | | and the end point |
125 | | */ |
126 | | SAL_DLLPRIVATE void adaptiveSubdivideByCount(B2DPolygon& rTarget, sal_uInt32 nCount) const; |
127 | | |
128 | | /** Subdivide cubic bezier segment. |
129 | | |
130 | | This function adaptively subdivides the bezier |
131 | | segment into as much straight line segments as necessary, |
132 | | such that the maximal orthogonal distance from any of the |
133 | | segments to the true curve is less than the given error |
134 | | value. |
135 | | No start point is added, but all necessary created edges |
136 | | and the end point |
137 | | |
138 | | @param rPoly |
139 | | Output polygon. The subdivided bezier segment is added to |
140 | | this polygon via B2DPolygon::append(). |
141 | | |
142 | | @param rCurve |
143 | | The cubic bezier curve to subdivide |
144 | | |
145 | | @param fDistanceBound |
146 | | Bound on the maximal distance of the approximation to the |
147 | | true curve. |
148 | | |
149 | | @param nRecurseLimit |
150 | | Bound on recursion for the bezier case. |
151 | | */ |
152 | | void adaptiveSubdivideByDistance(B2DPolygon& rTarget, double fDistanceBound, int nRecurseLimit = 30) const; |
153 | | |
154 | | // get point at given relative position |
155 | | B2DPoint interpolatePoint(double t) const; |
156 | | |
157 | | // calculate the smallest distance from given point to this cubic bezier segment |
158 | | // and return the value. The relative position on the segment is returned in rCut. |
159 | | SAL_DLLPRIVATE double getSmallestDistancePointToBezierSegment(const B2DPoint& rTestPoint, double& rCut) const; |
160 | | |
161 | | // do a split at position t and fill both resulting segments |
162 | | void split(double t, B2DCubicBezier* pBezierA, B2DCubicBezier* pBezierB) const; |
163 | | |
164 | | // extract snippet from fStart to fEnd from this bezier |
165 | | B2DCubicBezier snippet(double fStart, double fEnd) const; |
166 | | |
167 | | // get range including control points |
168 | | B2DRange getRange() const; |
169 | | |
170 | | /** Get the minimum extremum position t |
171 | | |
172 | | @param rfResult |
173 | | Will be changed and might possibly be set to a found split value, which should be in the |
174 | | range [0.0 .. 1.0]. It will be the smallest current extremum; there may be more |
175 | | |
176 | | @return |
177 | | Returns true if there was at least one extremum found |
178 | | */ |
179 | | SAL_DLLPRIVATE bool getMinimumExtremumPosition(double& rfResult) const; |
180 | | |
181 | | /** Get all extremum pos of this segment |
182 | | |
183 | | This method will calculate all extremum positions of the segment |
184 | | and add them to rResults if they are in the range ]0.0 .. 1.0[ |
185 | | |
186 | | @param rResults |
187 | | The vector of doubles where the results will be added. Evtl. |
188 | | existing contents will be removed since an empty vector is a |
189 | | necessary result to express that there are no extreme positions |
190 | | anymore. Since there is an upper maximum of 4 values, it makes |
191 | | sense to use reserve(4) at the vector as preparation. |
192 | | */ |
193 | | SAL_DLLPRIVATE void getAllExtremumPositions(::std::vector< double >& rResults) const; |
194 | | |
195 | | /// apply transformation given in matrix form |
196 | | void transform(const basegfx::B2DHomMatrix& rMatrix); |
197 | | |
198 | | /// fround content |
199 | | SAL_DLLPRIVATE void fround(); |
200 | | }; |
201 | | } // end of namespace basegfx |
202 | | |
203 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |