summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@trolltech.com>2009-07-13 19:43:12 (GMT)
committerOlivier Goffart <ogoffart@trolltech.com>2009-07-15 09:28:30 (GMT)
commita72c30020bdadbe0d82e583e17acd25715604f7b (patch)
treece82e9ace289d9cb22a09d847497b01222ad1a1c /src/gui
parente9ded3b600256686e4a735e365988f317a51db03 (diff)
downloadQt-a72c30020bdadbe0d82e583e17acd25715604f7b.zip
Qt-a72c30020bdadbe0d82e583e17acd25715604f7b.tar.gz
Qt-a72c30020bdadbe0d82e583e17acd25715604f7b.tar.bz2
Bad drawing of styled viewports within QAbstractScrollArea
This patch includes lots of refactoring, but the real problem was that in QWidgetPrivate::paintBackground we call drawPrimitive(PE_Widget) with a potentialy translated painter, but the opt.rect is not translated. When having a scroll area the calling function used to translated the painter and then pass the offset around to rectify. but drawPrimitive cannot rectify it. The solution is not to translate the painter but use other way to rectify the brush Task-number: 257517 Reviewed-by: bnilsen
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm10
-rw-r--r--src/gui/kernel/qwidget.cpp58
-rw-r--r--src/gui/kernel/qwidget_mac.mm11
-rw-r--r--src/gui/kernel/qwidget_p.h2
-rw-r--r--src/gui/styles/qmacstyle_mac.mm11
5 files changed, 40 insertions, 52 deletions
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 52685ca..3e5bfb6 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -550,15 +550,7 @@ extern "C" {
qwidget->objectName().local8Bit().data());
#endif
QPainter p(qwidget);
- QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(qwidget->parent());
- QPoint scrollAreaOffset;
- if (scrollArea && scrollArea->viewport() == qwidget) {
- QAbstractScrollAreaPrivate *priv
- = static_cast<QAbstractScrollAreaPrivate *>(qt_widget_private(scrollArea));
- scrollAreaOffset = priv->contentsOffset();
- p.translate(-scrollAreaOffset);
- }
- qwidgetprivate->paintBackground(&p, qrgn, scrollAreaOffset,
+ qwidgetprivate->paintBackground(&p, qrgn,
qwidget->isWindow() ? QWidgetPrivate::DrawAsRoot : 0);
p.end();
}
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 5f076ff..7026525 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -1966,10 +1966,9 @@ void QPixmap::fill( const QWidget *widget, const QPoint &off )
QPainter p(this);
p.translate(-off);
widget->d_func()->paintBackground(&p, QRect(off, size()));
-
}
-static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QPoint &offset, const QBrush &brush)
+static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrush &brush)
{
Q_ASSERT(painter);
@@ -1978,26 +1977,39 @@ static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QPoin
// Optimize pattern filling on mac by using HITheme directly
// when filling with the standard widget background.
// Defined in qmacstyle_mac.cpp
- extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QPoint &offset, const QBrush &brush);
- qt_mac_fill_background(painter, rgn, offset, brush);
+ extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush);
+ qt_mac_fill_background(painter, rgn, brush);
#else
- const QRegion translated = rgn.translated(offset);
- const QRect rect(translated.boundingRect());
- painter->setClipRegion(translated);
+ const QRect rect(rgn.boundingRect());
+ painter->setClipRegion(rgn);
painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
#endif
} else {
const QVector<QRect> &rects = rgn.rects();
for (int i = 0; i < rects.size(); ++i)
- painter->fillRect(rects.at(i).translated(offset), brush);
+ painter->fillRect(rects.at(i), brush);
}
}
-
-void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, const QPoint &offset, int flags) const
+void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const
{
Q_Q(const QWidget);
+#ifndef QT_NO_SCROLLAREA
+ bool resetBrushOrigin = false;
+ QPointF oldBrushOrigin;
+ //If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture
+ QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent);
+ if (scrollArea && scrollArea->viewport() == q) {
+ QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr;
+ QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
+ oldBrushOrigin = painter->brushOrigin();
+ resetBrushOrigin = true;
+ painter->setBrushOrigin(-priv->contentsOffset());
+
+ }
+#endif // QT_NO_SCROLLAREA
+
const QBrush autoFillBrush = q->palette().brush(q->backgroundRole());
if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) {
@@ -2006,18 +2018,24 @@ void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, cons
if (!(flags & DontSetCompositionMode) && painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff))
painter->setCompositionMode(QPainter::CompositionMode_Source); //copy alpha straight in
#endif
- fillRegion(painter, rgn, offset, bg);
+ fillRegion(painter, rgn, bg);
}
if (q->autoFillBackground())
- fillRegion(painter, rgn, offset, autoFillBrush);
+ fillRegion(painter, rgn, autoFillBrush);
+
if (q->testAttribute(Qt::WA_StyledBackground)) {
- painter->setClipRegion(rgn.translated(offset));
+ painter->setClipRegion(rgn);
QStyleOption opt;
opt.initFrom(q);
q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q);
}
+
+#ifndef QT_NO_SCROLLAREA
+ if (resetBrushOrigin)
+ painter->setBrushOrigin(oldBrushOrigin);
+#endif // QT_NO_SCROLLAREA
}
/*
@@ -4998,19 +5016,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
&& !q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) {
QPainter p(q);
- QPoint scrollAreaOffset;
-
-#ifndef QT_NO_SCROLLAREA
- QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent);
- if (scrollArea && scrollArea->viewport() == q) {
- QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr;
- QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
- scrollAreaOffset = priv->contentsOffset();
- p.translate(-scrollAreaOffset);
- }
-#endif // QT_NO_SCROLLAREA
-
- paintBackground(&p, toBePainted, scrollAreaOffset, (asRoot || onScreen) ? flags | DrawAsRoot : 0);
+ paintBackground(&p, toBePainted, (asRoot || onScreen) ? flags | DrawAsRoot : 0);
}
if (!sharedPainter)
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 5577224..84c3def 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -1198,16 +1198,7 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event,
p.setClipping(false);
if(was_unclipped)
widget->setAttribute(Qt::WA_PaintUnclipped);
-
- QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(widget->parent());
- QPoint scrollAreaOffset;
- if (scrollArea && scrollArea->viewport() == widget) {
- QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(static_cast<QWidget *>(scrollArea)->d_ptr);
- scrollAreaOffset = priv->contentsOffset();
- p.translate(-scrollAreaOffset);
- }
-
- widget->d_func()->paintBackground(&p, qrgn, scrollAreaOffset, widget->isWindow() ? DrawAsRoot : 0);
+ widget->d_func()->paintBackground(&p, qrgn, widget->isWindow() ? DrawAsRoot : 0);
if (widget->testAttribute(Qt::WA_TintedBackground)) {
QColor tint = widget->palette().window().color();
tint.setAlphaF(.6);
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 626950e..998181e 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -295,7 +295,7 @@ public:
void setUpdatesEnabled_helper(bool );
- void paintBackground(QPainter *, const QRegion &, const QPoint & = QPoint(), int flags = DrawAsRoot) const;
+ void paintBackground(QPainter *, const QRegion &, int flags = DrawAsRoot) const;
bool isAboutToShow() const;
QRegion prepareToRender(const QRegion &region, QWidget::RenderFlags renderFlags);
void render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &sourceRegion,
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index c08009b..5d75392 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -1871,24 +1871,23 @@ QPixmap QMacStylePrivate::generateBackgroundPattern() const
Fills the given \a rect with the pattern stored in \a brush. As an optimization,
HIThemeSetFill us used directly if we are filling with the standard background.
*/
-void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QPoint &offset, const QBrush &brush)
+void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush)
{
QPoint dummy;
const QPaintDevice *target = painter->device();
const QPaintDevice *redirected = QPainter::redirected(target, &dummy);
const bool usePainter = redirected && redirected != target;
- const QRegion translated = rgn.translated(offset);
if (!usePainter && qt_mac_backgroundPattern
&& qt_mac_backgroundPattern->cacheKey() == brush.texture().cacheKey()) {
- painter->setClipRegion(translated);
+ painter->setClipRegion(rgn);
CGContextRef cg = qt_mac_cg_context(target);
CGContextSaveGState(cg);
HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationInverted);
- const QVector<QRect> &rects = translated.rects();
+ const QVector<QRect> &rects = rgn.rects();
for (int i = 0; i < rects.size(); ++i) {
const QRect rect(rects.at(i));
// Anchor the pattern to the top so it stays put when the window is resized.
@@ -1899,8 +1898,8 @@ void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QPoint
CGContextRestoreGState(cg);
} else {
- const QRect rect(translated.boundingRect());
- painter->setClipRegion(translated);
+ const QRect rect(rgn.boundingRect());
+ painter->setClipRegion(rgn);
painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
}
}