Coverage Report

Created: 2026-01-25 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtsvg/src/svg/qsvggraphics_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
4
#ifndef QSVGGRAPHICS_P_H
5
#define QSVGGRAPHICS_P_H
6
7
//
8
//  W A R N I N G
9
//  -------------
10
//
11
// This file is not part of the Qt API.  It exists purely as an
12
// implementation detail.  This header file may change from version to
13
// version without notice, or even be removed.
14
//
15
// We mean it.
16
//
17
18
#include "qsvgnode_p.h"
19
20
#include "QtGui/qpainterpath.h"
21
#include "QtGui/qimage.h"
22
#include "QtGui/qtextlayout.h"
23
#include "QtCore/qloggingcategory.h"
24
25
#include <optional>
26
27
QT_BEGIN_NAMESPACE
28
29
Q_DECLARE_LOGGING_CATEGORY(lcSvgDraw);
30
31
class QSvgGlyph;
32
class QTextCharFormat;
33
34
class Q_SVG_EXPORT QSvgDummyNode : public QSvgNode
35
{
36
public:
37
    void drawCommand(QPainter *, QSvgExtraStates &) override;
38
    Type type() const override;
39
};
40
41
class Q_SVG_EXPORT QSvgEllipse : public QSvgNode
42
{
43
public:
44
    QSvgEllipse(QSvgNode *parent, const QRectF &rect);
45
    bool separateFillStroke(const QSvgExtraStates &) const override;
46
    void drawCommand(QPainter *p, QSvgExtraStates &states) override;
47
    Type type() const override;
48
    QRectF internalFastBounds(QPainter *p, QSvgExtraStates &states) const override;
49
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states) const override;
50
    QRectF decoratedInternalBounds(QPainter *p, QSvgExtraStates &states) const override;
51
0
    QRectF rect() const { return m_bounds; }
52
private:
53
    QRectF m_bounds;
54
};
55
56
class Q_SVG_EXPORT QSvgCircle : public QSvgEllipse
57
{
58
public:
59
0
    QSvgCircle(QSvgNode *parent, const QRectF &rect) : QSvgEllipse(parent, rect) { }
60
    Type type() const override;
61
};
62
63
class Q_SVG_EXPORT QSvgImage : public QSvgNode
64
{
65
public:
66
    QSvgImage(QSvgNode *parent,
67
              const QImage &image,
68
              const QString &filename,
69
              const QRectF &bounds);
70
    void drawCommand(QPainter *p, QSvgExtraStates &states) override;
71
    Type type() const override;
72
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states) const override;
73
74
0
    QRectF rect() const { return m_bounds; }
75
0
    const QImage &image() const { return m_image; }
76
0
    QString filename() const { return m_filename; }
77
private:
78
    QString m_filename;
79
    QImage m_image;
80
    QRectF m_bounds;
81
};
82
83
class Q_SVG_EXPORT QSvgLine : public QSvgNode
84
{
85
public:
86
    QSvgLine(QSvgNode *parent, const QLineF &line);
87
    void drawCommand(QPainter *p, QSvgExtraStates &states) override;
88
    Type type() const override;
89
    QRectF internalFastBounds(QPainter *p, QSvgExtraStates &states) const override;
90
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states) const override;
91
    QRectF decoratedInternalBounds(QPainter *p, QSvgExtraStates &states) const override;
92
    bool requiresGroupRendering() const override;
93
0
    QLineF line() const { return m_line; }
94
private:
95
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states, BoundsMode mode) const;
96
    QLineF m_line;
97
};
98
99
class Q_SVG_EXPORT QSvgPath : public QSvgNode
100
{
101
public:
102
    QSvgPath(QSvgNode *parent, const QPainterPath &qpath);
103
    bool separateFillStroke(const QSvgExtraStates &) const override;
104
    void drawCommand(QPainter *p, QSvgExtraStates &states) override;
105
    Type type() const override;
106
    QRectF internalFastBounds(QPainter *p, QSvgExtraStates &states) const override;
107
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states) const override;
108
    QRectF decoratedInternalBounds(QPainter *p, QSvgExtraStates &states) const override;
109
    bool requiresGroupRendering() const override;
110
15.4k
    const QPainterPath &path() const { return m_path; }
111
private:
112
    QPainterPath m_path;
113
};
114
115
class Q_SVG_EXPORT QSvgPolygon : public QSvgNode
116
{
117
public:
118
    QSvgPolygon(QSvgNode *parent, const QPolygonF &poly);
119
    bool separateFillStroke(const QSvgExtraStates &) const override;
120
    void drawCommand(QPainter *p, QSvgExtraStates &states) override;
121
    Type type() const override;
122
    QRectF internalFastBounds(QPainter *p, QSvgExtraStates &states) const override;
123
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states) const override;
124
    QRectF decoratedInternalBounds(QPainter *p, QSvgExtraStates &states) const override;
125
    bool requiresGroupRendering() const override;
126
0
    const QPolygonF &polygon() const { return m_poly; }
127
private:
128
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states, BoundsMode mode) const;
129
    QPolygonF m_poly;
130
};
131
132
class Q_SVG_EXPORT QSvgPolyline : public QSvgNode
133
{
134
public:
135
    QSvgPolyline(QSvgNode *parent, const QPolygonF &poly);
136
    bool separateFillStroke(const QSvgExtraStates &) const override;
137
    void drawCommand(QPainter *p, QSvgExtraStates &states) override;
138
    Type type() const override;
139
    QRectF internalFastBounds(QPainter *p, QSvgExtraStates &states) const override;
140
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states) const override;
141
    QRectF decoratedInternalBounds(QPainter *p, QSvgExtraStates &states) const override;
142
    bool requiresGroupRendering() const override;
143
0
    const QPolygonF &polygon() const { return m_poly; }
144
private:
145
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states, BoundsMode mode) const;
146
    QPolygonF m_poly;
147
};
148
149
class Q_SVG_EXPORT QSvgRect : public QSvgNode
150
{
151
public:
152
    QSvgRect(QSvgNode *paren, const QRectF &rect, qreal rx=0, qreal ry=0);
153
    Type type() const override;
154
    bool separateFillStroke(const QSvgExtraStates &) const override;
155
    void drawCommand(QPainter *p, QSvgExtraStates &states) override;
156
    QRectF internalFastBounds(QPainter *p, QSvgExtraStates &states) const override;
157
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states) const override;
158
    QRectF decoratedInternalBounds(QPainter *p, QSvgExtraStates &states) const override;
159
0
    QRectF rect() const { return m_rect; }
160
0
    QPointF radius() const { return { m_rx, m_ry }; }
161
private:
162
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states, BoundsMode mode) const;
163
    QRectF m_rect;
164
    qreal m_rx, m_ry;
165
};
166
167
class  QSvgTspan;
168
169
class Q_SVG_EXPORT QSvgText : public QSvgNode
170
{
171
public:
172
    enum WhitespaceMode
173
    {
174
        Default,
175
        Preserve
176
    };
177
178
    QSvgText(QSvgNode *parent, const QPointF &coord);
179
    ~QSvgText();
180
    void setTextArea(const QSizeF &size);
181
182
    void drawCommand(QPainter *p, QSvgExtraStates &states) override;
183
    bool shouldDrawNode(QPainter *p, QSvgExtraStates &states) const override;
184
    Type type() const override;
185
    bool separateFillStroke(const QSvgExtraStates &) const override;
186
187
0
    void addTspan(QSvgTspan *tspan) {m_tspans.append(tspan);}
188
0
    const QList<QSvgTspan *> tspans() const { return m_tspans; }
189
    void addText(QStringView text);
190
0
    void addLineBreak() {m_tspans.append(LINEBREAK);}
191
0
    void setWhitespaceMode(WhitespaceMode mode) {m_mode = mode;}
192
193
    QRectF internalFastBounds(QPainter *p, QSvgExtraStates &states) const override;
194
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states) const override;
195
196
0
    QPointF position() const { return m_coord; }
197
0
    QSizeF size() const { return m_size; }
198
0
    WhitespaceMode whitespaceMode() const { return m_mode; }
199
200
private:
201
    void draw_helper(QPainter *p, QSvgExtraStates &states, QRectF *boundingRect = nullptr) const;
202
203
    static QSvgTspan * const LINEBREAK;
204
205
    QPointF m_coord;
206
    QSizeF m_size;
207
208
    // 'm_tspans' is also used to store characters outside tspans and line breaks.
209
    // If a 'm_tspan' item is null, it indicates a line break.
210
    QList<QSvgTspan *> m_tspans;
211
212
    Type m_type;
213
    WhitespaceMode m_mode;
214
215
    mutable std::optional<QList<const QSvgGlyph *> > m_glyphsToDraw;
216
};
217
218
class Q_SVG_EXPORT QSvgTspan : public QSvgNode
219
{
220
public:
221
    // tspans are also used to store normal text, so the 'isProperTspan' is used to separate text from tspan.
222
    QSvgTspan(QSvgNode *parent, bool isProperTspan = true)
223
0
        : QSvgNode(parent), m_mode(QSvgText::Default), m_isTspan(isProperTspan)
224
0
    {
225
0
    }
226
0
    ~QSvgTspan() { };
227
0
    Type type() const override { return Tspan; }
228
0
    void drawCommand(QPainter *, QSvgExtraStates &) override { Q_ASSERT(!"Tspans should be drawn through QSvgText::draw()."); }
229
0
    void addText(QStringView text) {m_text += text;}
230
0
    const QString &text() const {return m_text;}
231
0
    bool isTspan() const {return m_isTspan;}
232
0
    void setWhitespaceMode(QSvgText::WhitespaceMode mode) {m_mode = mode;}
233
0
    QSvgText::WhitespaceMode whitespaceMode() const {return m_mode;}
234
private:
235
    QString m_text;
236
    QSvgText::WhitespaceMode m_mode;
237
    bool m_isTspan;
238
};
239
240
class QSvgUse : public QSvgNode
241
{
242
public:
243
    QSvgUse(const QPointF &start, QSvgNode *parent, QSvgNode *link);
244
    QSvgUse(const QPointF &start, QSvgNode *parent, const QString &linkId)
245
0
        : QSvgUse(start, parent, nullptr)
246
0
    { m_linkId = linkId; }
247
    void drawCommand(QPainter *p, QSvgExtraStates &states) override;
248
    Type type() const override;
249
    QRectF internalBounds(QPainter *p, QSvgExtraStates &states) const override;
250
    QRectF decoratedInternalBounds(QPainter *p, QSvgExtraStates &states) const override;
251
0
    bool isResolved() const { return m_link != nullptr; }
252
0
    const QString &linkId() const { return m_linkId; }
253
0
    void setLink(QSvgNode *link) { m_link = link; }
254
0
    QSvgNode *link() const { return m_link; }
255
0
    QPointF start() const { return m_start; }
256
0
    bool isRecursing() const { return m_recursing; }
257
258
private:
259
    QSvgNode *m_link;
260
    QPointF   m_start;
261
    QString   m_linkId;
262
    mutable bool m_recursing;
263
};
264
265
class QSvgVideo : public QSvgNode
266
{
267
public:
268
0
    void drawCommand(QPainter *, QSvgExtraStates &) override {};
269
    Type type() const override;
270
};
271
272
QT_END_NAMESPACE
273
274
#endif // QSVGGRAPHICS_P_H