Coverage Report

Created: 2026-03-31 07:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/painting/qemulationpaintengine.cpp
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
#include <private/qemulationpaintengine_p.h>
6
#include <private/qpainter_p.h>
7
#include <private/qtextengine_p.h>
8
#include <qdebug.h>
9
10
QT_BEGIN_NAMESPACE
11
12
QEmulationPaintEngine::QEmulationPaintEngine(QPaintEngineEx *engine)
13
0
    : real_engine(engine)
14
0
{
15
0
    QPaintEngine::state = real_engine->state();
16
0
}
17
18
19
QPaintEngine::Type QEmulationPaintEngine::type() const
20
0
{
21
0
    return real_engine->type();
22
0
}
23
24
bool QEmulationPaintEngine::begin(QPaintDevice *)
25
0
{
26
0
    return true;
27
0
}
28
29
bool QEmulationPaintEngine::end()
30
0
{
31
0
    return true;
32
0
}
33
34
35
QPainterState *QEmulationPaintEngine::createState(QPainterState *orig) const
36
0
{
37
0
    return real_engine->createState(orig);
38
0
}
39
40
static inline void combineXForm(QBrush *brush, const QRectF &r)
41
0
{
42
0
    QTransform t(r.width(), 0, 0, r.height(), r.x(), r.y());
43
0
    if (brush->gradient() && brush->gradient()->coordinateMode() != QGradient::ObjectMode)
44
0
        brush->setTransform(t * brush->transform()); // compat mode
45
0
    else
46
0
        brush->setTransform(brush->transform() * t);
47
0
}
48
49
void QEmulationPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
50
0
{
51
0
    QPainterState *s = state();
52
53
0
    if (s->bgMode == Qt::OpaqueMode) {
54
0
        Qt::BrushStyle style = brush.style();
55
0
        if ((style >= Qt::Dense1Pattern && style <= Qt::DiagCrossPattern) || (style == Qt::TexturePattern ))
56
0
            real_engine->fill(path, s->bgBrush);
57
0
    }
58
59
0
    Qt::BrushStyle style = qbrush_style(brush);
60
0
    if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
61
0
        QGradient::CoordinateMode coMode = brush.gradient()->coordinateMode();
62
0
        if (coMode > QGradient::LogicalMode) {
63
0
            QBrush copy = brush;
64
0
            const QPaintDevice *d = real_engine->painter()->device();
65
0
            QRectF r = (coMode == QGradient::StretchToDeviceMode) ? QRectF(0, 0, d->width(), d->height()) : path.controlPointRect();
66
0
            combineXForm(&copy, r);
67
0
            real_engine->fill(path, copy);
68
0
            return;
69
0
        }
70
0
    } else if (style == Qt::TexturePattern) {
71
0
        qreal dpr = qHasPixmapTexture(brush) ? brush.texture().devicePixelRatio() : brush.textureImage().devicePixelRatio();
72
0
        if (!qFuzzyCompare(dpr, qreal(1.0))) {
73
0
            QBrush copy = brush;
74
0
            combineXForm(&copy, QRectF(0, 0, 1.0/dpr, 1.0/dpr));
75
0
            real_engine->fill(path, copy);
76
0
            return;
77
0
        }
78
0
    }
79
80
0
    real_engine->fill(path, brush);
81
0
}
82
83
void QEmulationPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
84
0
{
85
0
    QPainterState *s = state();
86
87
0
    if (s->bgMode == Qt::OpaqueMode && pen.style() > Qt::SolidLine) {
88
0
        QPen bgPen = pen;
89
0
        bgPen.setBrush(s->bgBrush);
90
0
        bgPen.setStyle(Qt::SolidLine);
91
0
        real_engine->stroke(path, bgPen);
92
0
    }
93
94
0
    QBrush brush = pen.brush();
95
0
    QPen copy = pen;
96
0
    Qt::BrushStyle style = qbrush_style(brush);
97
0
    if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern ) {
98
0
        QGradient::CoordinateMode coMode = brush.gradient()->coordinateMode();
99
0
        if (coMode > QGradient::LogicalMode) {
100
0
            const QPaintDevice *d = real_engine->painter()->device();
101
0
            QRectF r = (coMode == QGradient::StretchToDeviceMode) ? QRectF(0, 0, d->width(), d->height()) : path.controlPointRect();
102
0
            combineXForm(&brush, r);
103
0
            copy.setBrush(brush);
104
0
            real_engine->stroke(path, copy);
105
0
            return;
106
0
        }
107
0
    }
108
109
0
    real_engine->stroke(path, pen);
110
0
}
111
112
void QEmulationPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
113
0
{
114
0
    real_engine->clip(path, op);
115
0
}
116
117
void QEmulationPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
118
0
{
119
0
    if (state()->bgMode == Qt::OpaqueMode && pm.isQBitmap())
120
0
        fillBGRect(r);
121
0
    real_engine->drawPixmap(r, pm, sr);
122
0
}
123
124
void QEmulationPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
125
0
{
126
0
    if (state()->bgMode == Qt::OpaqueMode) {
127
0
        const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
128
0
        QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent).toReal());
129
0
        fillBGRect(rect);
130
0
    }
131
132
0
    QPainterState *s = state();
133
0
    Qt::BrushStyle style = qbrush_style(s->pen.brush());
134
0
    if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern)
135
0
    {
136
0
        QPen savedPen = s->pen;
137
0
        QGradient g = *s->pen.brush().gradient();
138
139
0
        if (g.coordinateMode() > QGradient::LogicalMode) {
140
0
            QBrush copy = s->pen.brush();
141
0
            const QPaintDevice *d = real_engine->painter()->device();
142
0
            const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
143
0
            QRectF r = (g.coordinateMode() == QGradient::StretchToDeviceMode) ?
144
0
                        QRectF(0, 0, d->width(), d->height()) :
145
0
                        QRectF(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
146
0
            combineXForm(&copy, r);
147
0
            g.setCoordinateMode(QGradient::LogicalMode);
148
0
            QBrush brush(g);
149
0
            brush.setTransform(copy.transform());
150
0
            s->pen.setBrush(brush);
151
0
            penChanged();
152
0
            real_engine->drawTextItem(p, textItem);
153
0
            s->pen = savedPen;
154
0
            penChanged();
155
0
            return;
156
0
        }
157
0
    }
158
159
0
    real_engine->drawTextItem(p, textItem);
160
0
}
161
162
void QEmulationPaintEngine::drawStaticTextItem(QStaticTextItem *item)
163
0
{
164
0
    real_engine->drawStaticTextItem(item);
165
0
}
166
167
void QEmulationPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s)
168
0
{
169
0
    if (state()->bgMode == Qt::OpaqueMode && pixmap.isQBitmap())
170
0
        fillBGRect(r);
171
0
    real_engine->drawTiledPixmap(r, pixmap, s);
172
0
}
173
174
void QEmulationPaintEngine::drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags)
175
0
{
176
0
    real_engine->drawImage(r, pm, sr, flags);
177
0
}
178
179
void QEmulationPaintEngine::clipEnabledChanged()
180
0
{
181
0
    real_engine->clipEnabledChanged();
182
0
}
183
184
void QEmulationPaintEngine::penChanged()
185
0
{
186
0
    real_engine->penChanged();
187
0
}
188
189
void QEmulationPaintEngine::brushChanged()
190
0
{
191
0
    real_engine->brushChanged();
192
0
}
193
194
void QEmulationPaintEngine::brushOriginChanged()
195
0
{
196
0
    real_engine->brushOriginChanged();
197
0
}
198
199
void QEmulationPaintEngine::opacityChanged()
200
0
{
201
0
    real_engine->opacityChanged();
202
0
}
203
204
void QEmulationPaintEngine::compositionModeChanged()
205
0
{
206
0
    real_engine->compositionModeChanged();
207
0
}
208
209
void QEmulationPaintEngine::renderHintsChanged()
210
0
{
211
0
    real_engine->renderHintsChanged();
212
0
}
213
214
void QEmulationPaintEngine::transformChanged()
215
0
{
216
0
    real_engine->transformChanged();
217
0
}
218
219
void QEmulationPaintEngine::setState(QPainterState *s)
220
0
{
221
0
    QPaintEngine::state = s;
222
0
    real_engine->setState(s);
223
0
}
224
225
void QEmulationPaintEngine::beginNativePainting()
226
0
{
227
0
    real_engine->beginNativePainting();
228
0
}
229
230
void QEmulationPaintEngine::endNativePainting()
231
0
{
232
0
    real_engine->endNativePainting();
233
0
}
234
235
void QEmulationPaintEngine::fillBGRect(const QRectF &r)
236
0
{
237
0
    qreal pts[] = { r.x(), r.y(), r.x() + r.width(), r.y(),
238
0
                    r.x() + r.width(), r.y() + r.height(), r.x(), r.y() + r.height() };
239
0
    QVectorPath vp(pts, 4, nullptr, QVectorPath::RectangleHint);
240
0
    real_engine->fill(vp, state()->bgBrush);
241
0
}
242
243
QT_END_NAMESPACE