Coverage Report

Created: 2025-07-16 07:53

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