diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-06-10 12:31:20 (GMT) |
---|---|---|
committer | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-06-10 14:15:41 (GMT) |
commit | 32f32ee3e752a6cc03505ddaa48d2849eaedc2a6 (patch) | |
tree | ab6529edcfd0cc41a4d998504e768129c2e19dfd /src/gui/painting/qpainter.cpp | |
parent | f01efd0b49be074d9bc5a963b6d353b9eddf365a (diff) | |
download | Qt-32f32ee3e752a6cc03505ddaa48d2849eaedc2a6.zip Qt-32f32ee3e752a6cc03505ddaa48d2849eaedc2a6.tar.gz Qt-32f32ee3e752a6cc03505ddaa48d2849eaedc2a6.tar.bz2 |
QPainter::worldTransform() does not return identity matrix.
QPainter::worldTransform() does not return identity matrix when created
on a redirected widget. It should always be identity by default, and
should only change as a result of QPainter::setWorldTransform. The
reason it didn't return identity for redirected widgets, was that we
translated the shared painter's world matrix directly.
Since we cannot modify the world matrix directly, we have to store
the shared painter's current world transform in a separate matrix
(redirectedMatrix), reset the world transform to identity, and later
combine the redirectedMatrix with world transforms set on the painter.
Note that redirection_offset was in negative coordinates before,
and that redirectionMatrix now is in positive coordinates, hence opposite
signs around.
Auto-test included.
Reviewed-by: lars
Reviewed-by: Samuel
Diffstat (limited to 'src/gui/painting/qpainter.cpp')
-rw-r--r-- | src/gui/painting/qpainter.cpp | 47 |
1 files changed, 19 insertions, 28 deletions
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 4744f14..0ece498 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -281,10 +281,14 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev) q->d_ptr->state->wh = q->d_ptr->state->vh = widget->height(); // Update matrix. - if (q->d_ptr->state->WxF) - q->d_ptr->state->worldMatrix.translate(-offset.x(), -offset.y()); - else - q->d_ptr->state->redirection_offset = offset; + if (q->d_ptr->state->WxF) { + q->d_ptr->state->redirectionMatrix *= q->d_ptr->state->worldMatrix; + q->d_ptr->state->redirectionMatrix.translate(-offset.x(), -offset.y()); + q->d_ptr->state->worldMatrix = QTransform(); + q->d_ptr->state->WxF = false; + } else { + q->d_ptr->state->redirectionMatrix = QTransform::fromTranslate(-offset.x(), -offset.y()); + } q->d_ptr->updateMatrix(); QPaintEnginePrivate *enginePrivate = q->d_ptr->engine->d_func(); @@ -410,7 +414,7 @@ void QPainterPrivate::draw_helper(const QPainterPath &originalPath, DrawOperatio bool old_txinv = txinv; QTransform old_invMatrix = invMatrix; txinv = true; - invMatrix = QTransform().translate(-state->redirection_offset.x(), -state->redirection_offset.y()); + invMatrix = state->redirectionMatrix; QPainterPath clipPath = q->clipPath(); QRectF r = clipPath.boundingRect().intersected(absPathRect); absPathRect = r.toAlignedRect(); @@ -634,20 +638,7 @@ void QPainterPrivate::updateMatrix() state->matrix *= viewTransform(); txinv = false; // no inverted matrix - if (!state->redirection_offset.isNull()) { - // We want to translate in dev space so we do the adding of the redirection - // offset manually. - if (state->matrix.isAffine()) { - state->matrix = QTransform(state->matrix.m11(), state->matrix.m12(), - state->matrix.m21(), state->matrix.m22(), - state->matrix.dx()-state->redirection_offset.x(), - state->matrix.dy()-state->redirection_offset.y()); - } else { - QTransform temp; - temp.translate(-state->redirection_offset.x(), -state->redirection_offset.y()); - state->matrix *= temp; - } - } + state->matrix *= state->redirectionMatrix; if (extended) extended->transformChanged(); else @@ -1572,10 +1563,8 @@ void QPainter::restore() // replay the list of clip states, for (int i=0; i<d->state->clipInfo.size(); ++i) { const QPainterClipInfo &info = d->state->clipInfo.at(i); - tmp->matrix.setMatrix(info.matrix.m11(), info.matrix.m12(), info.matrix.m13(), - info.matrix.m21(), info.matrix.m22(), info.matrix.m23(), - info.matrix.dx() - d->state->redirection_offset.x(), - info.matrix.dy() - d->state->redirection_offset.y(), info.matrix.m33()); + tmp->matrix = info.matrix; + tmp->matrix *= d->state->redirectionMatrix; tmp->clipOperation = info.operation; if (info.clipType == QPainterClipInfo::RectClip) { tmp->dirtyFlags = QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyTransform; @@ -1689,7 +1678,7 @@ bool QPainter::begin(QPaintDevice *pd) d->state->painter = this; d->states.push_back(d->state); - d->state->redirection_offset = redirectionOffset; + d->state->redirectionMatrix.translate(-redirectionOffset.x(), -redirectionOffset.y()); d->state->brushOrigin = QPointF(); if (!d->engine) { @@ -1723,7 +1712,8 @@ bool QPainter::begin(QPaintDevice *pd) // Adjust offset for alien widgets painting outside the paint event. if (!inPaintEvent && paintOutsidePaintEvent && !widget->internalWinId() && widget->testAttribute(Qt::WA_WState_Created)) { - d->state->redirection_offset -= widget->mapTo(widget->nativeParentWidget(), QPoint()); + const QPoint offset = widget->mapTo(widget->nativeParentWidget(), QPoint()); + d->state->redirectionMatrix.translate(offset.x(), offset.y()); } break; } @@ -1805,11 +1795,12 @@ bool QPainter::begin(QPaintDevice *pd) d->state->wh = d->state->vh = pd->metric(QPaintDevice::PdmHeight); } - d->state->redirection_offset += d->engine->coordinateOffset(); + const QPoint coordinateOffset = d->engine->coordinateOffset(); + d->state->redirectionMatrix.translate(-coordinateOffset.x(), -coordinateOffset.y()); Q_ASSERT(d->engine->isActive()); - if (!d->state->redirection_offset.isNull()) + if (!d->state->redirectionMatrix.isIdentity()) d->updateMatrix(); Q_ASSERT(d->engine->isActive()); @@ -7704,7 +7695,7 @@ QPainterState::QPainterState(const QPainterState *s) clipRegion(s->clipRegion), clipPath(s->clipPath), clipOperation(s->clipOperation), renderHints(s->renderHints), clipInfo(s->clipInfo), - worldMatrix(s->worldMatrix), matrix(s->matrix), redirection_offset(s->redirection_offset), + worldMatrix(s->worldMatrix), matrix(s->matrix), redirectionMatrix(s->redirectionMatrix), wx(s->wx), wy(s->wy), ww(s->ww), wh(s->wh), vx(s->vx), vy(s->vy), vw(s->vw), vh(s->vh), opacity(s->opacity), WxF(s->WxF), VxF(s->VxF), |