Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/basegfx/matrix/b2dhommatrixtools.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 <sal/types.h>
23
#include <basegfx/matrix/b2dhommatrix.hxx>
24
#include <basegfx/vector/b2dvector.hxx>
25
#include <basegfx/tuple/b2dtuple.hxx>
26
#include <utility>
27
#include <basegfx/basegfxdllapi.h>
28
29
namespace basegfx { class B2DPoint; }
30
namespace basegfx { class B2DRange; }
31
32
namespace basegfx::utils
33
{
34
        /** If the rotation angle is an approximate multiple of pi/2,
35
            force fSin/fCos to -1/0/1, to maintain orthogonality (which
36
            might also be advantageous for the other cases, but: for
37
            multiples of pi/2, the exact values _can_ be attained. It
38
            would be largely unintuitive, if a 180 degrees rotation
39
            would introduce slight roundoff errors, instead of exactly
40
            mirroring the coordinate system)
41
         */
42
        void createSinCosOrthogonal(double& o_rSin, double& rCos, double fRadiant);
43
44
        /** Tooling methods for on-the-fly matrix generation e.g. for inline
45
            multiplications
46
         */
47
        BASEGFX_DLLPUBLIC B2DHomMatrix createScaleB2DHomMatrix(double fScaleX, double fScaleY);
48
        BASEGFX_DLLPUBLIC B2DHomMatrix createShearXB2DHomMatrix(double fShearX);
49
        BASEGFX_DLLPUBLIC B2DHomMatrix createShearYB2DHomMatrix(double fShearY);
50
        BASEGFX_DLLPUBLIC B2DHomMatrix createRotateB2DHomMatrix(double fRadiant);
51
        BASEGFX_DLLPUBLIC B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY);
52
53
        /// inline versions for parameters as tuples
54
        inline B2DHomMatrix createScaleB2DHomMatrix(const B2DTuple& rScale)
55
441
        {
56
441
            return createScaleB2DHomMatrix(rScale.getX(), rScale.getY());
57
441
        }
58
59
        inline B2DHomMatrix createTranslateB2DHomMatrix(const B2DTuple& rTranslate)
60
0
        {
61
0
            return createTranslateB2DHomMatrix(rTranslate.getX(), rTranslate.getY());
62
0
        }
63
64
        /** Tooling methods for faster completely combined matrix creation
65
            when scale, shearX, rotation and translation needs to be done in
66
            exactly that order. It's faster since it directly calculates
67
            each matrix value based on a symbolic calculation of the three
68
            matrix multiplications.
69
            Inline versions for parameters as tuples added, too.
70
         */
71
        BASEGFX_DLLPUBLIC B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix(
72
            double fScaleX, double fScaleY,
73
            double fShearX,
74
            double fRadiant,
75
            double fTranslateX, double fTranslateY);
76
        inline B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix(
77
            const B2DTuple& rScale,
78
            double fShearX,
79
            double fRadiant,
80
            const B2DTuple& rTranslate)
81
101k
        {
82
101k
            return createScaleShearXRotateTranslateB2DHomMatrix(
83
101k
                rScale.getX(), rScale.getY(),
84
101k
                fShearX,
85
101k
                fRadiant,
86
101k
                rTranslate.getX(), rTranslate.getY());
87
101k
        }
88
89
        BASEGFX_DLLPUBLIC B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(
90
            double fShearX,
91
            double fRadiant,
92
            double fTranslateX, double fTranslateY);
93
        inline B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(
94
            double fShearX,
95
            double fRadiant,
96
            const B2DTuple& rTranslate)
97
441
        {
98
441
            return createShearXRotateTranslateB2DHomMatrix(
99
441
                fShearX,
100
441
                fRadiant,
101
441
                rTranslate.getX(), rTranslate.getY());
102
441
        }
103
104
        BASEGFX_DLLPUBLIC B2DHomMatrix createScaleTranslateB2DHomMatrix(
105
            double fScaleX, double fScaleY,
106
            double fTranslateX, double fTranslateY);
107
        inline B2DHomMatrix createScaleTranslateB2DHomMatrix(
108
            const B2DTuple& rScale,
109
            const B2DTuple& rTranslate)
110
449
        {
111
449
            return createScaleTranslateB2DHomMatrix(
112
449
                rScale.getX(), rScale.getY(),
113
449
                rTranslate.getX(), rTranslate.getY());
114
449
        }
115
116
        /// special for the often used case of rotation around a point
117
        BASEGFX_DLLPUBLIC B2DHomMatrix createRotateAroundPoint(
118
            double fPointX, double fPointY,
119
            double fRadiant);
120
        inline B2DHomMatrix createRotateAroundPoint(
121
            const B2DTuple& rPoint,
122
            double fRadiant)
123
4
        {
124
4
            return createRotateAroundPoint(
125
4
                rPoint.getX(), rPoint.getY(),
126
4
                fRadiant);
127
4
        }
128
129
        /// special for creating a mapping for a Range rotated around it's center
130
        /// while keeping AspectRatio unchanged and staying inside the given Range
131
        /// by optimally using the available space (no overlap or outside allowed)
132
        B2DHomMatrix createRotateAroundCenterKeepAspectRatioStayInsideRange(
133
            const basegfx::B2DRange& rTargetRange,
134
            double fRotate);
135
136
        /// special for the case to map from source range to target range
137
        BASEGFX_DLLPUBLIC B2DHomMatrix createSourceRangeTargetRangeTransform(
138
            const B2DRange& rSourceRange,
139
            const B2DRange& rTargetRange);
140
141
        /// create based on given CoordinateSystem which is defined by origin and x/yaxis
142
        BASEGFX_DLLPUBLIC B2DHomMatrix createCoordinateSystemTransform(
143
            const B2DPoint& rOrigin,
144
            const B2DVector& rX,
145
            const B2DVector& rY);
146
147
        /// get column vector from B2dHomMatrix, e.g. to extract coordinate system origin and x/yaxis
148
        BASEGFX_DLLPUBLIC B2DTuple getColumn(const B2DHomMatrix& rMatrix, sal_uInt16 nCol);
149
150
151
        class BASEGFX_DLLPUBLIC B2DHomMatrixBufferedDecompose
152
        {
153
        private:
154
            B2DVector              maScale;
155
            B2DVector              maTranslate;
156
            double                 mfRotate;
157
            double                 mfShearX;
158
159
        public:
160
            B2DHomMatrixBufferedDecompose(const B2DHomMatrix& rB2DHomMatrix = B2DHomMatrix())
161
9.11k
            :   mfRotate(0.0),
162
9.11k
                mfShearX(0.0)
163
9.11k
            {
164
9.11k
                rB2DHomMatrix.decompose(maScale, maTranslate, mfRotate, mfShearX);
165
9.11k
            }
166
167
            // data access
168
            B2DHomMatrix getB2DHomMatrix() const
169
0
            {
170
0
                return createScaleShearXRotateTranslateB2DHomMatrix(
171
0
                    maScale, mfShearX, mfRotate, maTranslate);
172
0
            }
173
174
9.11k
            const B2DVector& getScale() const { return maScale; }
175
9.11k
            const B2DVector& getTranslate() const { return maTranslate; }
176
9.11k
            double getRotate() const { return mfRotate; }
177
9.11k
            double getShearX() const { return mfShearX; }
178
        };
179
180
        class BASEGFX_DLLPUBLIC B2DHomMatrixBufferedOnDemandDecompose
181
        {
182
        private:
183
            B2DHomMatrix           maB2DHomMatrix;
184
            B2DVector              maScale;
185
            B2DVector              maTranslate;
186
            double                 mfRotate;
187
            double                 mfShearX;
188
189
            bool                   mbDecomposed : 1;
190
191
            void impCheckDecompose()
192
0
            {
193
0
                if(!mbDecomposed)
194
0
                {
195
0
                    maB2DHomMatrix.decompose(maScale, maTranslate, mfRotate, mfShearX);
196
0
                    mbDecomposed = true;
197
0
                }
198
0
            }
199
200
        public:
201
            B2DHomMatrixBufferedOnDemandDecompose(B2DHomMatrix aB2DHomMatrix = B2DHomMatrix())
202
            :   maB2DHomMatrix(std::move(aB2DHomMatrix)),
203
                mfRotate(0.0),
204
                mfShearX(0.0),
205
                mbDecomposed(false)
206
0
            {
207
0
            }
208
209
            // data access
210
0
            const B2DHomMatrix& getB2DHomMatrix() const { return maB2DHomMatrix; }
211
0
            const B2DVector& getScale() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return maScale; }
212
0
            const B2DVector& getTranslate() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return maTranslate; }
213
0
            double getRotate() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return mfRotate; }
214
0
            double getShearX() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return mfShearX; }
215
        };
216
} // end of namespace basegfx::utils
217
218
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */