Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */