Make QWidget::render() work correctly with all paint devices

Make sure QWidget::render takes correct code paths with all
kinds of paint devices.

Correctly restore the inRenderWithPainter flag. The old code
would not correctly restore the flag, likely leading to
inconsistencies. Remove the unused last parameter in
QWidgetPrivate::render. Remove the special handling
for QPrinter in the same method.

Task-number: QTBUG-26564
Change-Id: Iba43269b090abd8dd88c5225b75e1ee9239d58f9
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
This commit is contained in:
Lars Knoll 2014-03-21 09:36:05 +01:00 committed by The Qt Project
parent 5279134935
commit 071098b08b
2 changed files with 8 additions and 23 deletions

View File

@ -4677,7 +4677,8 @@ void QWidget::unsetCursor()
void QWidget::render(QPaintDevice *target, const QPoint &targetOffset, void QWidget::render(QPaintDevice *target, const QPoint &targetOffset,
const QRegion &sourceRegion, RenderFlags renderFlags) const QRegion &sourceRegion, RenderFlags renderFlags)
{ {
d_func()->render(target, targetOffset, sourceRegion, renderFlags, false); QPainter p(target);
render(&p, targetOffset, sourceRegion, renderFlags);
} }
/*! /*!
@ -4721,9 +4722,6 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
d->createExtra(); d->createExtra();
d->extra->inRenderWithPainter = true; d->extra->inRenderWithPainter = true;
#ifdef Q_WS_MAC
d->render_helper(painter, targetOffset, toBePainted, renderFlags);
#else
QPaintEngine *engine = painter->paintEngine(); QPaintEngine *engine = painter->paintEngine();
Q_ASSERT(engine); Q_ASSERT(engine);
QPaintEnginePrivate *enginePriv = engine->d_func(); QPaintEnginePrivate *enginePriv = engine->d_func();
@ -4734,7 +4732,7 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
// Render via a pixmap when dealing with non-opaque painters or printers. // Render via a pixmap when dealing with non-opaque painters or printers.
if (!inRenderWithPainter && (opacity < 1.0 || (target->devType() == QInternal::Printer))) { if (!inRenderWithPainter && (opacity < 1.0 || (target->devType() == QInternal::Printer))) {
d->render_helper(painter, targetOffset, toBePainted, renderFlags); d->render_helper(painter, targetOffset, toBePainted, renderFlags);
d->extra->inRenderWithPainter = false; d->extra->inRenderWithPainter = inRenderWithPainter;
return; return;
} }
@ -4755,7 +4753,7 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
enginePriv->setSystemViewport(oldSystemClip); enginePriv->setSystemViewport(oldSystemClip);
} }
render(target, targetOffset, toBePainted, renderFlags); d->render(target, targetOffset, toBePainted, renderFlags);
// Restore system clip, viewport and transform. // Restore system clip, viewport and transform.
enginePriv->systemClip = oldSystemClip; enginePriv->systemClip = oldSystemClip;
@ -4764,9 +4762,8 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
// Restore shared painter. // Restore shared painter.
d->setSharedPainter(oldPainter); d->setSharedPainter(oldPainter);
#endif
d->extra->inRenderWithPainter = false; d->extra->inRenderWithPainter = inRenderWithPainter;
} }
static void sendResizeEvents(QWidget *target) static void sendResizeEvents(QWidget *target)
@ -5204,8 +5201,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
} }
void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset, void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
const QRegion &sourceRegion, QWidget::RenderFlags renderFlags, const QRegion &sourceRegion, QWidget::RenderFlags renderFlags)
bool readyToRender)
{ {
if (!target) { if (!target) {
qWarning("QWidget::render: null pointer to paint device"); qWarning("QWidget::render: null pointer to paint device");
@ -5213,7 +5209,7 @@ void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
} }
const bool inRenderWithPainter = extra && extra->inRenderWithPainter; const bool inRenderWithPainter = extra && extra->inRenderWithPainter;
QRegion paintRegion = !inRenderWithPainter && !readyToRender QRegion paintRegion = !inRenderWithPainter
? prepareToRender(sourceRegion, renderFlags) ? prepareToRender(sourceRegion, renderFlags)
: sourceRegion; : sourceRegion;
if (paintRegion.isEmpty()) if (paintRegion.isEmpty())
@ -5272,23 +5268,12 @@ void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
flags |= DontSetCompositionMode; flags |= DontSetCompositionMode;
if (target->devType() == QInternal::Printer) {
QPainter p(target);
render_helper(&p, targetOffset, paintRegion, renderFlags);
return;
}
#ifndef Q_WS_MAC
// Render via backingstore. // Render via backingstore.
drawWidget(target, paintRegion, offset, flags, sharedPainter()); drawWidget(target, paintRegion, offset, flags, sharedPainter());
// Restore shared painter. // Restore shared painter.
if (oldSharedPainter) if (oldSharedPainter)
setSharedPainter(oldSharedPainter); setSharedPainter(oldSharedPainter);
#else
// Render via backingstore (no shared painter).
drawWidget(target, paintRegion, offset, flags, 0);
#endif
} }
void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& siblings, int index, const QRegion &rgn, void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& siblings, int index, const QRegion &rgn,

View File

@ -389,7 +389,7 @@ public:
void render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &sourceRegion, void render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &sourceRegion,
QWidget::RenderFlags renderFlags); QWidget::RenderFlags renderFlags);
void render(QPaintDevice *target, const QPoint &targetOffset, const QRegion &sourceRegion, void render(QPaintDevice *target, const QPoint &targetOffset, const QRegion &sourceRegion,
QWidget::RenderFlags renderFlags, bool readyToRender); QWidget::RenderFlags renderFlags);
void drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags, void drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags,
QPainter *sharedPainter = 0, QWidgetBackingStore *backingStore = 0); QPainter *sharedPainter = 0, QWidgetBackingStore *backingStore = 0);