Coverage Report

Created: 2026-10-28 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/painting/qpainter_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
#ifndef QPAINTER_P_H
6
#define QPAINTER_P_H
7
8
//
9
//  W A R N I N G
10
//  -------------
11
//
12
// This file is not part of the Qt API.  It exists purely as an
13
// implementation detail.  This header file may change from version to
14
// version without notice, or even be removed.
15
//
16
// We mean it.
17
//
18
19
#include <QtCore/qspan.h>
20
#include <QtCore/qvarlengtharray.h>
21
#include <QtGui/private/qtguiglobal_p.h>
22
#include "QtGui/qbrush.h"
23
#include "QtGui/qcolorspace.h"
24
#include "QtGui/qcolortransform.h"
25
#include "QtGui/qfont.h"
26
#include "QtGui/qpen.h"
27
#include "QtGui/qregion.h"
28
#include "QtGui/qpainter.h"
29
#include "QtGui/qpainterpath.h"
30
#include "QtGui/qpaintengine.h"
31
32
#include <private/qpen_p.h>
33
34
#include <memory>
35
#include <stack>
36
37
QT_BEGIN_NAMESPACE
38
39
class QPaintEngine;
40
class QEmulationPaintEngine;
41
class QPaintEngineEx;
42
struct QFixedPoint;
43
44
struct QTLWExtra;
45
46
struct DataPtrContainer {
47
    void *ptr;
48
};
49
50
0
inline const void *data_ptr(const QTransform &t) { return (const DataPtrContainer *) &t; }
51
0
inline bool qtransform_fast_equals(const QTransform &a, const QTransform &b) { return data_ptr(a) == data_ptr(b); }
52
53
// QPen inline functions...
54
2.80M
inline QPen::DataPtr &data_ptr(const QPen &p) { return const_cast<QPen &>(p).data_ptr(); }
55
584k
inline bool qpen_fast_equals(const QPen &a, const QPen &b) { return data_ptr(a) == data_ptr(b); }
56
722k
inline QBrush qpen_brush(const QPen &p) { return data_ptr(p)->brush; }
57
168k
inline qreal qpen_widthf(const QPen &p) { return data_ptr(p)->width; }
58
260k
inline Qt::PenStyle qpen_style(const QPen &p) { return data_ptr(p)->style; }
59
324k
inline Qt::PenCapStyle qpen_capStyle(const QPen &p) { return data_ptr(p)->capStyle; }
60
162k
inline Qt::PenJoinStyle qpen_joinStyle(const QPen &p) { return data_ptr(p)->joinStyle; }
61
62
// QBrush inline functions...
63
1.68M
inline QBrush::DataPtr &data_ptr(const QBrush &p) { return const_cast<QBrush &>(p).data_ptr(); }
64
94.1k
inline bool qbrush_fast_equals(const QBrush &a, const QBrush &b) { return data_ptr(a) == data_ptr(b); }
65
980k
inline Qt::BrushStyle qbrush_style(const QBrush &b) { return data_ptr(b)->style; }
66
512k
inline const QColor &qbrush_color(const QBrush &b) { return data_ptr(b)->color; }
67
0
inline bool qbrush_has_transform(const QBrush &b) { return data_ptr(b)->transform.type() > QTransform::TxNone; }
68
69
class QPainterClipInfo
70
{
71
public:
72
0
    QPainterClipInfo() { } // for QList, don't use
73
    enum ClipType { RegionClip, PathClip, RectClip, RectFClip };
74
75
    QPainterClipInfo(const QPainterPath &p, Qt::ClipOperation op, const QTransform &m) :
76
0
        clipType(PathClip), matrix(m), operation(op), path(p) { }
77
78
    QPainterClipInfo(const QRegion &r, Qt::ClipOperation op, const QTransform &m) :
79
0
        clipType(RegionClip), matrix(m), operation(op), region(r) { }
80
81
    QPainterClipInfo(const QRect &r, Qt::ClipOperation op, const QTransform &m) :
82
0
        clipType(RectClip), matrix(m), operation(op), rect(r) { }
83
84
    QPainterClipInfo(const QRectF &r, Qt::ClipOperation op, const QTransform &m) :
85
22.4k
        clipType(RectFClip), matrix(m), operation(op), rectf(r) { }
86
87
    ClipType clipType;
88
    QTransform matrix;
89
    Qt::ClipOperation operation;
90
    QPainterPath path;
91
    QRegion region;
92
    QRect rect;
93
    QRectF rectf;
94
95
    // ###
96
//     union {
97
//         QRegionData *d;
98
//         QPainterPathPrivate *pathData;
99
100
//         struct {
101
//             int x, y, w, h;
102
//         } rectData;
103
//         struct {
104
//             qreal x, y, w, h;
105
//         } rectFData;
106
//     };
107
108
};
109
110
Q_DECLARE_TYPEINFO(QPainterClipInfo, Q_RELOCATABLE_TYPE);
111
112
class Q_GUI_EXPORT QPainterState : public QPaintEngineState
113
{
114
public:
115
    QPainterState();
116
    QPainterState(const QPainterState *s);
117
    virtual ~QPainterState();
118
    void init(QPainter *p);
119
120
    QPointF brushOrigin;
121
    QFont font;
122
    QFont deviceFont;
123
    QPen pen;
124
    QBrush brush;
125
    QBrush bgBrush = Qt::white; // background brush
126
    QRegion clipRegion;
127
    QPainterPath clipPath;
128
    Qt::ClipOperation clipOperation = Qt::NoClip;
129
    QPainter::RenderHints renderHints;
130
    QList<QPainterClipInfo> clipInfo; // ### Make me smaller and faster to copy around...
131
    QTransform worldMatrix;       // World transformation matrix, not window and viewport
132
    QTransform matrix;            // Complete transformation matrix,
133
    QTransform redirectionMatrix;
134
    int wx = 0, wy = 0, ww = 0, wh = 0; // window rectangle
135
    int vx = 0, vy = 0, vw = 0, vh = 0; // viewport rectangle
136
    qreal opacity = 1;
137
138
    uint WxF:1;                 // World transformation
139
    uint VxF:1;                 // View transformation
140
    uint clipEnabled:1;
141
142
    Qt::BGMode bgMode = Qt::TransparentMode;
143
    QPainter *painter = nullptr;
144
    Qt::LayoutDirection layoutDirection;
145
    QPainter::CompositionMode composition_mode = QPainter::CompositionMode_SourceOver;
146
    uint emulationSpecifier = 0;
147
    uint changeFlags = 0;
148
};
149
150
struct QPainterDummyState
151
{
152
    QFont font;
153
    QPen pen;
154
    QBrush brush;
155
    QTransform transform;
156
};
157
158
class QRawFont;
159
class QPainterPrivate
160
{
161
0
    Q_DECLARE_PUBLIC(QPainter)
162
0
public:
163
0
    explicit QPainterPrivate(QPainter *painter);
164
0
    ~QPainterPrivate();
165
0
166
0
    QPainter *q_ptr;
167
0
    // Allocate space for 4 d-pointers (enough for up to 4 sub-sequent
168
0
    // redirections within the same paintEvent(), which should be enough
169
0
    // in 99% of all cases). E.g: A renders B which renders C which renders D.
170
0
    static constexpr qsizetype NDPtrs = 4;
171
0
    QVarLengthArray<std::unique_ptr<QPainterPrivate>, NDPtrs> d_ptrs;
172
0
173
0
    std::unique_ptr<QPainterState> state;
174
0
    template <typename T, std::size_t N = 8>
175
0
    struct SmallStack : std::stack<T, QVarLengthArray<T, N>> {
176
300k
        void clear() { this->c.clear(); }
177
    };
178
    SmallStack<std::unique_ptr<QPainterState>> savedStates;
179
180
    mutable std::unique_ptr<QPainterDummyState> dummyState;
181
182
    QTransform invMatrix;
183
    uint txinv:1;
184
    uint inDestructor : 1;
185
    uint refcount = 1;
186
187
    enum DrawOperation { StrokeDraw        = 0x1,
188
                         FillDraw          = 0x2,
189
                         StrokeAndFillDraw = 0x3
190
    };
191
192
0
    QPainterDummyState *fakeState() const {
193
0
        if (!dummyState)
194
0
            dummyState = std::make_unique<QPainterDummyState>();
195
0
        return dummyState.get();
196
0
    }
197
198
    void updateEmulationSpecifier(QPainterState *s);
199
    void updateStateImpl(QPainterState *state);
200
    void updateState(QPainterState *state);
201
0
    void updateState(std::unique_ptr<QPainterState> &state) { updateState(state.get()); }
202
203
    void draw_helper(const QPainterPath &path, DrawOperation operation = StrokeAndFillDraw);
204
    void drawStretchedGradient(const QPainterPath &path, DrawOperation operation);
205
    void drawOpaqueBackground(const QPainterPath &path, DrawOperation operation);
206
    void drawTextItem(const QPointF &p, const QTextItem &_ti, QTextEngine *textEngine);
207
208
#if !defined(QT_NO_RAWFONT)
209
    void drawGlyphs(const QPointF &decorationPosition, const quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount,
210
                    QFontEngine *fontEngine, bool overline = false, bool underline = false,
211
                    bool strikeOut = false);
212
#endif
213
214
    void updateMatrix();
215
    void updateInvMatrix();
216
217
    void checkEmulation();
218
219
    static QPainterPrivate *get(QPainter *painter)
220
545k
    {
221
545k
        return painter->d_ptr.get();
222
545k
    }
223
224
    QTransform viewTransform() const;
225
    qreal effectiveDevicePixelRatio() const;
226
    QTransform hidpiScaleTransform() const;
227
    static bool attachPainterPrivate(QPainter *q, QPaintDevice *pdev);
228
    void detachPainterPrivate(QPainter *q);
229
    void initFrom(const QPaintDevice *device);
230
231
    QPaintDevice *device = nullptr;
232
    QPaintDevice *original_device = nullptr;
233
    QPaintDevice *helper_device = nullptr;
234
235
    struct QPaintEngineDestructor {
236
        void operator()(QPaintEngine *pe) const noexcept
237
300k
        {
238
300k
            if (pe && pe->autoDestruct())
239
0
                delete pe;
240
300k
        }
241
    };
242
    std::unique_ptr<QPaintEngine, QPaintEngineDestructor> engine;
243
244
    std::unique_ptr<QEmulationPaintEngine> emulationEngine;
245
    QPaintEngineEx *extended = nullptr;
246
    QBrush colorBrush;          // for fill with solid color
247
248
    Q_GUI_EXPORT void setEngineDirtyFlags(QSpan<const QPaintEngine::DirtyFlags>);
249
};
250
251
Q_GUI_EXPORT void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation);
252
253
QString qt_generate_brush_key(const QBrush &brush);
254
255
256
QT_END_NAMESPACE
257
258
#endif // QPAINTER_P_H