Coverage Report

Created: 2026-02-26 07:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtsvg/src/svg/qsvgdocument_p.h
Line
Count
Source
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
6
#ifndef QSVGDOCUMENT_P_H
7
#define QSVGDOCUMENT_P_H
8
9
//
10
//  W A R N I N G
11
//  -------------
12
//
13
// This file is not part of the Qt API.  It exists purely as an
14
// implementation detail.  This header file may change from version to
15
// version without notice, or even be removed.
16
//
17
// We mean it.
18
//
19
20
#include "qsvgstructure_p.h"
21
#include "qtsvgglobal.h"
22
#include "qtsvgglobal_p.h"
23
24
#include "QtCore/qrect.h"
25
#include "QtCore/qhash.h"
26
#include "QtCore/qxmlstream.h"
27
#include "QtCore/qscopedvaluerollback.h"
28
#include "QtCore/qsharedpointer.h"
29
#include "qsvgstyle_p.h"
30
#include "qsvgfont_p.h"
31
#include "private/qsvganimator_p.h"
32
33
QT_BEGIN_NAMESPACE
34
35
class QPainter;
36
class QByteArray;
37
class QSvgFont;
38
class QTransform;
39
40
class Q_SVG_EXPORT QSvgDocument : public QSvgStructureNode
41
{
42
public:
43
    static std::unique_ptr<QSvgDocument> load(const QString &file, QtSvg::Options options = {},
44
                                  QtSvg::AnimatorType type = QtSvg::AnimatorType::Automatic);
45
    static std::unique_ptr<QSvgDocument> load(const QByteArray &contents, QtSvg::Options options = {},
46
                                  QtSvg::AnimatorType type = QtSvg::AnimatorType::Automatic);
47
    static std::unique_ptr<QSvgDocument> load(QXmlStreamReader *contents, QtSvg::Options options = {},
48
                                  QtSvg::AnimatorType type = QtSvg::AnimatorType::Automatic);
49
    static bool isLikelySvg(QIODevice *device, bool *isCompressed = nullptr);
50
public:
51
    QSvgDocument(QtSvg::Options options, QtSvg::AnimatorType type);
52
    ~QSvgDocument();
53
    Type type() const override;
54
55
    inline QSize size() const;
56
    void setWidth(int len, bool percent);
57
    void setHeight(int len, bool percent);
58
    inline int width() const;
59
    inline int height() const;
60
    inline bool widthPercent() const;
61
    inline bool heightPercent() const;
62
63
    inline bool preserveAspectRatio() const;
64
    void setPreserveAspectRatio(bool on);
65
66
    inline QRectF viewBox() const;
67
    void setViewBox(const QRectF &rect);
68
0
    bool isCalculatingImplicitViewBox() { return m_calculatingImplicitViewBox; }
69
70
    QtSvg::Options options() const;
71
72
    void drawCommand(QPainter *, QSvgExtraStates &) override;
73
74
    void draw(QPainter *p);
75
    void draw(QPainter *p, const QRectF &bounds);
76
    void draw(QPainter *p, const QString &id,
77
              const QRectF &bounds=QRectF());
78
79
    QTransform transformForElement(const QString &id) const;
80
    QRectF boundsOnElement(const QString &id) const;
81
    bool   elementExists(const QString &id) const;
82
83
    void addSvgFont(QSvgFont *);
84
    QSvgFont *svgFont(const QString &family) const;
85
    void addNamedNode(const QString &id, QSvgNode *node);
86
    QSvgNode *namedNode(const QString &id) const;
87
    void addNamedStyle(const QString &id, QSvgPaintStyleProperty *style);
88
    QSvgPaintStyleProperty *namedStyle(const QString &id) const;
89
90
    void restartAnimation();
91
    inline qint64 currentElapsed() const;
92
    bool animated() const;
93
    void setAnimated(bool a);
94
    inline int animationDuration() const;
95
    int currentFrame() const;
96
    void setCurrentFrame(int);
97
    void setFramesPerSecond(int num);
98
99
    QSharedPointer<QSvgAbstractAnimator> animator() const;
100
101
private:
102
    void mapSourceToTarget(QPainter *p, const QRectF &targetRect, const QRectF &sourceRect = QRectF());
103
private:
104
    QSize  m_size;
105
    bool   m_widthPercent;
106
    bool   m_heightPercent;
107
108
    mutable bool m_calculatingImplicitViewBox = false;
109
    mutable bool m_implicitViewBox = true;
110
    mutable QRectF m_viewBox;
111
    bool m_preserveAspectRatio = false;
112
113
    QHash<QString, QSvgRefCounter<QSvgFont> > m_fonts;
114
    QHash<QString, QSvgNode *> m_namedNodes;
115
    QHash<QString, QSvgRefCounter<QSvgPaintStyleProperty> > m_namedStyles;
116
117
    bool  m_animated;
118
    int   m_fps;
119
120
    QSvgExtraStates m_states;
121
122
    const QtSvg::Options m_options;
123
    QSharedPointer<QSvgAbstractAnimator> m_animator;
124
};
125
126
Q_SVG_EXPORT QDebug operator<<(QDebug debug, const QSvgDocument &doc);
127
128
inline std::optional<int> calculateSizeValue(bool isPercent, int sizeValue, qreal viewBoxSizeValue)
129
0
{
130
0
    if (!isPercent)
131
0
        return sizeValue;
132
133
0
    const double valueAsDouble = 0.01 * sizeValue * viewBoxSizeValue;
134
0
    if (valueAsDouble < (std::numeric_limits<int>::min)() || valueAsDouble > (std::numeric_limits<int>::max)())
135
0
        return {};
136
0
    return qRound(valueAsDouble);
137
0
}
138
139
inline QSize QSvgDocument::size() const
140
5.71k
{
141
5.71k
    if (m_size.isEmpty())
142
5.56k
        return viewBox().size().toSize();
143
152
    if (m_widthPercent || m_heightPercent) {
144
0
        const std::optional<int> width = calculateSizeValue(m_widthPercent, m_size.width(), viewBox().size().width());
145
0
        const std::optional<int> height = calculateSizeValue(m_heightPercent, m_size.height(), viewBox().size().height());
146
0
        if (!width || !height)
147
0
            return {};
148
149
0
        return QSize(*width, *height);
150
0
    }
151
152
    return m_size;
152
152
}
153
154
inline int QSvgDocument::width() const
155
0
{
156
0
    return size().width();
157
0
}
158
159
inline int QSvgDocument::height() const
160
0
{
161
0
    return size().height();
162
0
}
163
164
inline bool QSvgDocument::widthPercent() const
165
0
{
166
0
    return m_widthPercent;
167
0
}
168
169
inline bool QSvgDocument::heightPercent() const
170
0
{
171
0
    return m_heightPercent;
172
0
}
173
174
inline QRectF QSvgDocument::viewBox() const
175
8.25k
{
176
8.25k
    if (m_viewBox.isNull()) {
177
1.62k
        QScopedValueRollback<bool> guard(m_calculatingImplicitViewBox, true);
178
1.62k
        m_viewBox = bounds();
179
1.62k
        m_implicitViewBox = true;
180
1.62k
    }
181
182
8.25k
    return m_viewBox;
183
8.25k
}
184
185
inline bool QSvgDocument::preserveAspectRatio() const
186
889
{
187
889
    return m_preserveAspectRatio;
188
889
}
189
190
inline qint64 QSvgDocument::currentElapsed() const
191
0
{
192
0
    return m_animator->currentElapsed();
193
0
}
194
195
inline int QSvgDocument::animationDuration() const
196
0
{
197
0
    return m_animator->animationDuration();
198
0
}
199
200
QT_END_NAMESPACE
201
202
#endif // QSVGDOCUMENT_P_H