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