Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qpaintengine_pic.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
4#include "private/qpaintengine_p.h"
5#include "private/qpainter_p.h"
6#include "private/qpicture_p.h"
7#include "private/qfont_p.h"
8
9#ifndef QT_NO_PICTURE
10
11#include "qbuffer.h"
12#include "qbytearray.h"
13#include "qdatastream.h"
14#include "qmath.h"
15#include "qpaintengine_pic_p.h"
16#include "qpicture.h"
17#include "qpolygon.h"
18#include "qrect.h"
19#include <private/qtextengine_p.h>
20
21//#define QT_PICTURE_DEBUG
22#include <qdebug.h>
23
24
26
35
37 : QPaintEngine(*(new QPicturePaintEnginePrivate), AllFeatures)
38{
40 d->pt = nullptr;
41}
42
44 : QPaintEngine(dptr, AllFeatures)
45{
47 d->pt = nullptr;
48}
49
53
55{
57#ifdef QT_PICTURE_DEBUG
58 qDebug("QPicturePaintEngine::begin()");
59#endif
60 Q_ASSERT(pd);
61 QPicture *pic = static_cast<QPicture *>(pd);
62
63 d->pdev = pd;
64 d->pic_d = pic->d_func();
65 Q_ASSERT(d->pic_d);
66
67 d->s.setDevice(&d->pic_d->pictb);
68 d->s.setVersion(d->pic_d->formatMajor);
69
70 d->pic_d->pictb.open(QIODevice::WriteOnly | QIODevice::Truncate);
71 d->s.writeRawData(qt_mfhdr_tag, 4);
72 d->s << (quint16) 0 << (quint16) d->pic_d->formatMajor << (quint16) d->pic_d->formatMinor;
73 d->s << (quint8) QPicturePrivate::PdcBegin << (quint8) sizeof(qint32);
74 d->pic_d->brect = QRect();
75 if (d->pic_d->formatMajor >= 4) {
76 QRect r = pic->boundingRect();
77 d->s << (qint32) r.left() << (qint32) r.top() << (qint32) r.width()
78 << (qint32) r.height();
79 }
80 d->pic_d->trecs = 0;
81 d->s << (quint32)d->pic_d->trecs; // total number of records
82 d->pic_d->formatOk = false;
83 setActive(true);
84 return true;
85}
86
88{
90#ifdef QT_PICTURE_DEBUG
91 qDebug("QPicturePaintEngine::end()");
92#endif
93 d->pic_d->trecs++;
95 int cs_start = sizeof(quint32); // pos of checksum word
96 int data_start = cs_start + sizeof(quint16);
97 int brect_start = data_start + 2*sizeof(qint16) + 2*sizeof(quint8);
98 int pos = d->pic_d->pictb.pos();
99 d->pic_d->pictb.seek(brect_start);
100 if (d->pic_d->formatMajor >= 4) { // bounding rectangle
101 QRect r = static_cast<QPicture *>(d->pdev)->boundingRect();
102 d->s << (qint32) r.left() << (qint32) r.top() << (qint32) r.width()
103 << (qint32) r.height();
104 }
105 d->s << (quint32) d->pic_d->trecs; // write number of records
106 d->pic_d->pictb.seek(cs_start);
107 const QByteArray buf = d->pic_d->pictb.buffer();
108 quint16 cs = (quint16) qChecksum(QByteArrayView(buf.constData() + data_start, pos - data_start));
109 d->s << cs; // write checksum
110 d->pic_d->pictb.close();
111 setActive(false);
112 return true;
113}
114
115#define SERIALIZE_CMD(c) \
116 d->pic_d->trecs++; \
117 d->s << (quint8) c; \
118 d->s << (quint8) 0; \
119 pos = d->pic_d->pictb.pos()
120
122{
124#ifdef QT_PICTURE_DEBUG
125 qDebug() << " -> updatePen(): width:" << pen.width() << "style:"
126 << pen.style() << "color:" << pen.color();
127#endif
128 int pos;
130 if (d->pic_d->in_memory_only) {
131 int index = d->pic_d->pen_list.size();
132 d->pic_d->pen_list.append(pen);
133 d->s << index;
134 } else {
135 d->s << pen;
136 }
137 writeCmdLength(pos, QRect(), false);
138}
139
141{
143#ifdef QT_PICTURE_DEBUG
144 qDebug() << " -> updateCompositionMode():" << cmode;
145#endif
146 int pos;
148 d->s << (qint32)cmode;
149 writeCmdLength(pos, QRectF(), false);
150}
151
153{
155#ifdef QT_PICTURE_DEBUG
156 qDebug() << " -> updateClipEnabled():" << enabled;
157#endif
158 int pos;
160 d->s << enabled;
161 writeCmdLength(pos, QRectF(), false);
162}
163
165{
167#ifdef QT_PICTURE_DEBUG
168 qDebug() << " -> updateOpacity():" << opacity;
169#endif
170 int pos;
172 d->s << double(opacity);
173 writeCmdLength(pos, QRectF(), false);
174}
175
177{
179#ifdef QT_PICTURE_DEBUG
180 qDebug() << " -> updateBrush(): style:" << brush.style();
181#endif
182 int pos;
184 if (d->pic_d->in_memory_only) {
185 int index = d->pic_d->brush_list.size();
186 d->pic_d->brush_list.append(brush);
187 d->s << index;
188 } else {
189 d->s << brush;
190 }
191 writeCmdLength(pos, QRect(), false);
192}
193
195{
197#ifdef QT_PICTURE_DEBUG
198 qDebug() << " -> updateBrushOrigin(): " << p;
199#endif
200 int pos;
202 d->s << p;
203 writeCmdLength(pos, QRect(), false);
204}
205
207{
209#ifdef QT_PICTURE_DEBUG
210 qDebug() << " -> updateFont(): pt sz:" << font.pointSize();
211#endif
212 int pos;
214 QFont fnt = font;
215 d->s << fnt;
216 writeCmdLength(pos, QRectF(), false);
217}
218
220{
222#ifdef QT_PICTURE_DEBUG
223 qDebug() << " -> updateBackground(): mode:" << bgMode << "style:" << bgBrush.style();
224#endif
225 int pos;
227 d->s << bgBrush.color();
228 writeCmdLength(pos, QRect(), false);
229
231 d->s << (qint8) bgMode;
232 writeCmdLength(pos, QRectF(), false);
233}
234
236{
238#ifdef QT_PICTURE_DEBUG
239 qDebug() << " -> updateMatrix():" << matrix;
240#endif
241 int pos;
243 d->s << matrix << (qint8) false;
244 writeCmdLength(pos, QRectF(), false);
245}
246
248{
250#ifdef QT_PICTURE_DEBUG
251 qDebug() << " -> updateClipRegion(): op:" << op
252 << "bounding rect:" << region.boundingRect();
253#endif
254 int pos;
256 d->s << region << qint8(op);
257 writeCmdLength(pos, QRectF(), false);
258}
259
261{
263#ifdef QT_PICTURE_DEBUG
264 qDebug() << " -> updateClipPath(): op:" << op
265 << "bounding rect:" << path.boundingRect();
266#endif
267 int pos;
268
270 d->s << path << qint8(op);
271 writeCmdLength(pos, QRectF(), false);
272}
273
274void QPicturePaintEngine::updateRenderHints(QPainter::RenderHints hints)
275{
277#ifdef QT_PICTURE_DEBUG
278 qDebug() << " -> updateRenderHints(): " << hints;
279#endif
280 int pos;
282 d->s << (quint32) hints;
283 writeCmdLength(pos, QRect(), false);
284}
285
286void QPicturePaintEngine::writeCmdLength(int pos, const QRectF &r, bool corr)
287{
289 int newpos = d->pic_d->pictb.pos(); // new position
290 int length = newpos - pos;
291 QRectF br(r);
292
293 if (length < 255) { // write 8-bit length
294 d->pic_d->pictb.seek(pos - 1); // position to right index
295 d->s << (quint8)length;
296 } else { // write 32-bit length
297 d->s << (quint32)0; // extend the buffer
298 d->pic_d->pictb.seek(pos - 1); // position to right index
299 d->s << (quint8)255; // indicate 32-bit length
300 char *p = d->pic_d->pictb.buffer().data();
301 memmove(p+pos+4, p+pos, length); // make room for 4 byte
302 d->s << (quint32)length;
303 newpos += 4;
304 }
305 d->pic_d->pictb.seek(newpos); // set to new position
306
307 if (br.width() > 0.0 || br.height() > 0.0) {
308 if (corr) { // widen bounding rect
309 int w2 = painter()->pen().width() / 2;
310 br.setCoords(br.left() - w2, br.top() - w2,
311 br.right() + w2, br.bottom() + w2);
312 }
313 br = painter()->transform().mapRect(br);
314 if (painter()->hasClipping()) {
316 br &= cr;
317 }
318
319 if (br.width() > 0.0 || br.height() > 0.0) {
320 int minx = qFloor(br.left());
321 int miny = qFloor(br.top());
322 int maxx = qCeil(br.right());
323 int maxy = qCeil(br.bottom());
324
325 if (d->pic_d->brect.width() > 0 || d->pic_d->brect.height() > 0) {
326 minx = qMin(minx, d->pic_d->brect.left());
327 miny = qMin(miny, d->pic_d->brect.top());
328 maxx = qMax(maxx, d->pic_d->brect.x() + d->pic_d->brect.width());
329 maxy = qMax(maxy, d->pic_d->brect.y() + d->pic_d->brect.height());
330 d->pic_d->brect = QRect(minx, miny, maxx - minx, maxy - miny);
331 } else {
332 d->pic_d->brect = QRect(minx, miny, maxx - minx, maxy - miny);
333 }
334 }
335 }
336}
337
339{
341#ifdef QT_PICTURE_DEBUG
342 qDebug() << " -> drawEllipse():" << rect;
343#endif
344 int pos;
346 d->s << rect;
347 writeCmdLength(pos, rect, true);
348}
349
351{
353#ifdef QT_PICTURE_DEBUG
354 qDebug() << " -> drawPath():" << path.boundingRect();
355#endif
356 int pos;
358 d->s << path;
359 writeCmdLength(pos, path.boundingRect(), true);
360}
361
363{
365#ifdef QT_PICTURE_DEBUG
366 qDebug() << " -> drawPolygon(): size=" << numPoints;
367#endif
368 int pos;
369
371 polygon.reserve(numPoints);
372 for (int i=0; i<numPoints; ++i)
373 polygon << points[i];
374
375 if (mode == PolylineMode) {
377 d->s << polygon;
378 } else {
380 d->s << polygon;
381 d->s << (qint8)(mode == OddEvenMode ? 0 : 1);
382 }
383
384 writeCmdLength(pos, polygon.boundingRect(), true);
385}
386
387void QPicturePaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
388{
390#ifdef QT_PICTURE_DEBUG
391 qDebug() << " -> drawPixmap():" << r;
392#endif
393 int pos;
395
396 if (d->pic_d->in_memory_only) {
397 int index = d->pic_d->pixmap_list.size();
398 d->pic_d->pixmap_list.append(pm);
399 d->s << r << index << sr;
400 } else {
401 d->s << r << pm << sr;
402 }
403 writeCmdLength(pos, r, false);
404}
405
407{
409#ifdef QT_PICTURE_DEBUG
410 qDebug() << " -> drawTiledPixmap():" << r << s;
411#endif
412 int pos;
414 if (d->pic_d->in_memory_only) {
415 int index = d->pic_d->pixmap_list.size();
416 d->pic_d->pixmap_list.append(pixmap);
417 d->s << r << index << s;
418 } else {
419 d->s << r << pixmap << s;
420 }
421 writeCmdLength(pos, r, false);
422}
423
425 Qt::ImageConversionFlags flags)
426{
428#ifdef QT_PICTURE_DEBUG
429 qDebug() << " -> drawImage():" << r << sr;
430#endif
431 int pos;
433 if (d->pic_d->in_memory_only) {
434 int index = d->pic_d->image_list.size();
435 d->pic_d->image_list.append(image);
436 d->s << r << index << sr << (quint32) flags;
437 } else {
438 d->s << r << image << sr << (quint32) flags;
439 }
440 writeCmdLength(pos, r, false);
441}
442
444{
446#ifdef QT_PICTURE_DEBUG
447 qDebug() << " -> drawTextItem():" << p << ti.text();
448#endif
449
450 const QTextItemInt &si = static_cast<const QTextItemInt &>(ti);
451 if (si.chars == nullptr)
452 QPaintEngine::drawTextItem(p, ti); // Draw as path
453
454 if (d->pic_d->formatMajor >= 9) {
455 int pos;
457 QFont fnt = ti.font();
458 fnt.setUnderline(false);
459 fnt.setStrikeOut(false);
460 fnt.setOverline(false);
461
462 qreal justificationWidth = 0;
463 if (si.justified)
464 justificationWidth = si.width.toReal();
465
466 d->s << p << ti.text() << fnt << ti.renderFlags() << double(fnt.d->dpi)/qt_defaultDpi() << justificationWidth;
467 writeCmdLength(pos, /*brect=*/QRectF(), /*corr=*/false);
468 } else if (d->pic_d->formatMajor >= 8) {
469 // old old (buggy) format
470 int pos;
472 d->s << QPointF(p.x(), p.y() - ti.ascent()) << ti.text() << ti.font() << ti.renderFlags();
473 writeCmdLength(pos, /*brect=*/QRectF(), /*corr=*/false);
474 } else {
475 // old (buggy) format
476 int pos;
478 d->s << p << ti.text();
479 writeCmdLength(pos, QRectF(p, QSizeF(1,1)), true);
480 }
481}
482
499
501
502#endif // QT_NO_PICTURE
\inmodule QtGui
Definition qbrush.h:30
const QColor & color() const
Returns the brush color.
Definition qbrush.h:121
Qt::BrushStyle style() const
Returns the brush style.
Definition qbrush.h:120
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore\reentrant
Definition qdatastream.h:46
\reentrant
Definition qfont.h:22
void setOverline(bool)
If enable is true, sets overline on; otherwise sets overline off.
Definition qfont.cpp:1288
void setStrikeOut(bool)
If enable is true, sets strikeout on; otherwise sets strikeout off.
Definition qfont.cpp:1315
int pointSize() const
Returns the point size of the font.
Definition qfont.cpp:884
void setUnderline(bool)
If enable is true, sets underline on; otherwise sets underline off.
Definition qfont.cpp:1262
\inmodule QtGui
Definition qimage.h:37
The QPaintEngineState class provides information about the active paint engine's current state....
QTransform transform() const
QBrush backgroundBrush() const
Returns the background brush in the current paint engine state.
QPainterPath clipPath() const
Returns the clip path in the current paint engine state.
Qt::ClipOperation clipOperation() const
Returns the clip operation in the current paint engine state.
QPointF brushOrigin() const
Returns the brush origin in the current paint engine state.
qreal opacity() const
bool isClipEnabled() const
Returns whether clipping is enabled or not in the current paint engine state.
QBrush brush() const
Returns the brush in the current paint engine state.
QRegion clipRegion() const
Returns the clip region in the current paint engine state.
QPainter::RenderHints renderHints() const
Returns the render hints in the current paint engine state.
QFont font() const
Returns the font in the current paint engine state.
QPen pen() const
Returns the pen in the current paint engine state.
QPaintEngine::DirtyFlags state() const
Returns a combination of flags identifying the set of properties that need to be updated when updatin...
Qt::BGMode backgroundMode() const
Returns the background mode in the current paint engine state.
QPainter::CompositionMode compositionMode() const
Returns the composition mode in the current paint engine state.
\inmodule QtGui
void setActive(bool newState)
Sets the active state of the paint engine to state.
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem)
This function draws the text item textItem at position p.
PolygonDrawMode
\value OddEvenMode The polygon should be drawn using OddEven fill rule.
QPainter * painter() const
Returns the paint engine's painter.
QPaintEngineState * state
\inmodule QtGui
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
const QPen & pen() const
Returns the painter's current pen.
const QTransform & transform() const
Alias for worldTransform().
CompositionMode
Defines the modes supported for digital image compositing.
Definition qpainter.h:97
QRectF clipBoundingRect() const
Returns the bounding rectangle of the current clip if there is a clip; otherwise returns an empty rec...
\inmodule QtGui
Definition qpen.h:28
QColor color() const
Returns the color of this pen's brush.
Definition qpen.cpp:692
int width() const
Returns the pen width with integer precision.
Definition qpen.cpp:560
Qt::PenStyle style() const
Returns the pen style.
Definition qpen.cpp:366
void updateOpacity(qreal opacity)
void drawImage(const QRectF &r, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags=Qt::AutoColor) override
Reimplement this function to draw the part of the image specified by the sr rectangle in the given re...
void updateMatrix(const QTransform &matrix)
void updatePen(const QPen &pen)
void drawPolygon(const QPointF *points, int numPoints, PolygonDrawMode mode) override
Reimplement this virtual function to draw the polygon defined by the pointCount first points in point...
void updateClipRegion(const QRegion &region, Qt::ClipOperation op)
void drawPath(const QPainterPath &path) override
The default implementation ignores the path and does nothing.
void drawTextItem(const QPointF &p, const QTextItem &ti) override
This function draws the text item textItem at position p.
void updateBrushOrigin(const QPointF &origin)
void updateFont(const QFont &font)
void updateCompositionMode(QPainter::CompositionMode cmode)
void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) override
Reimplement this function to draw the pixmap in the given rect, starting at the given p.
void updateClipEnabled(bool enabled)
void updateState(const QPaintEngineState &state) override
Reimplement this function to update the state of a paint engine.
bool end() override
Reimplement this function to finish painting on the current paint device.
void updateBrush(const QBrush &brush)
void drawEllipse(const QRectF &rect) override
Reimplement this function to draw the largest ellipse that can be contained within rectangle rect.
void updateClipPath(const QPainterPath &path, Qt::ClipOperation op)
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override
Reimplement this function to draw the part of the pm specified by the sr rectangle in the given r.
void updateRenderHints(QPainter::RenderHints hints)
void updateBackground(Qt::BGMode bgmode, const QBrush &bgBrush)
bool begin(QPaintDevice *pdev) override
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
The QPicture class is a paint device that records and replays QPainter commands.
Definition qpicture.h:19
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
\inmodule QtCore\reentrant
Definition qpoint.h:217
The QPolygonF class provides a list of points using floating point precision.
Definition qpolygon.h:96
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:173
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
QRect boundingRect() const noexcept
Returns the bounding rectangle of this region.
\inmodule QtCore
Definition qsize.h:208
Internal QTextItem.
const QChar * chars
\inmodule QtGui
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
QRect mapRect(const QRect &) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
rect
[4]
else opt state
[0]
Combined button and popup list for selecting options.
ClipOperation
Definition brush.cpp:5
Definition image.cpp:4
Q_CORE_EXPORT quint16 qChecksum(QByteArrayView data, Qt::ChecksumType standard=Qt::ChecksumIso3309)
Q_GUI_EXPORT int qt_defaultDpi()
Definition qfont.cpp:140
#define qDebug
[1]
Definition qlogging.h:164
int qFloor(T v)
Definition qmath.h:42
int qCeil(T v)
Definition qmath.h:36
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLenum mode
GLuint index
[2]
GLboolean r
[2]
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLenum GLuint GLenum GLsizei const GLchar * buf
GLbitfield flags
GLfixed GLfixed GLint GLint GLfixed points
GLdouble s
[6]
Definition qopenglext.h:235
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
GLuint GLenum matrix
GLsizei const GLchar *const * path
GLfloat GLfloat p
[1]
static const QRectF boundingRect(const QPointF *points, int pointCount)
#define SERIALIZE_CMD(c)
const char * qt_mfhdr_tag
Definition qpicture.cpp:83
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
unsigned int quint32
Definition qtypes.h:50
short qint16
Definition qtypes.h:47
unsigned short quint16
Definition qtypes.h:48
int qint32
Definition qtypes.h:49
QT_BEGIN_NAMESPACE typedef signed char qint8
Definition qtypes.h:45
double qreal
Definition qtypes.h:187
unsigned char quint8
Definition qtypes.h:46
#define enabled
widget render & pixmap
constexpr qreal toReal() const
Definition qfixed_p.h:42