summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJanne Anttila <janne.anttila@digia.com>2010-03-10 08:18:03 (GMT)
committerJanne Anttila <janne.anttila@digia.com>2010-03-10 08:18:03 (GMT)
commit7e78d2668e508f929243fe2169e1d9937b8d2b67 (patch)
tree50dd5769701c554e0faeb282cfed0f9ae3492cb3
parent065fdc4caba6305f45b53edf27391af29f496a1c (diff)
downloadQt-7e78d2668e508f929243fe2169e1d9937b8d2b67.zip
Qt-7e78d2668e508f929243fe2169e1d9937b8d2b67.tar.gz
Qt-7e78d2668e508f929243fe2169e1d9937b8d2b67.tar.bz2
Fixed paint crash in Symbian for trasnclucent dialogs.
In Symbian Qt::WA_TrasnclucentBackground is set for QDialogs. In QTBUG-8706 there is setVisible(false) call for widget before orientation is switched from portrait to landscape with SW APIs. This setVisible call invalidates/marks the widget area, basically whole portrait screen (0,0, 360, 640 in 5800XM) dirty. The orientation switch changes backingstore/windowsurface size to 640, 360, and invalidates that area. As an consequnce the widget dirty area after these two operations is 0, 0, 640, 640. Now when the widget is made visible again, the dirty region is larger than a screen and causes a crash when trying to access windowsurface bitmap data outside its bounds. Fixed the issue by using QPainter instead of own implementation. QPainter handles intersecting with image automatically. Another benefit of QPainter is that it uses platform specific drawHelpers if available to speed-up drawing. Task-number: QTBUG-8706 Reviewed-by: Jani Hautakangas
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp25
1 files changed, 8 insertions, 17 deletions
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
index 028ec48..d05c7e4 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -70,13 +70,13 @@ QS60WindowSurface::QS60WindowSurface(QWidget* widget)
// We create empty CFbsBitmap here -> it will be resized in setGeometry
CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new
qt_symbian_throwIfError( bitmap->Create( TSize(0, 0), mode ) );
-
+
QS60PixmapData *data = new QS60PixmapData(QPixmapData::PixmapType);
if (data) {
data->fromSymbianBitmap(bitmap, true);
d_ptr->device = QPixmap(data);
}
-
+
setStaticContentsSupport(true);
}
QS60WindowSurface::~QS60WindowSurface()
@@ -89,24 +89,15 @@ void QS60WindowSurface::beginPaint(const QRegion &rgn)
if (!qt_widget_private(window())->isOpaque) {
QS60PixmapData *pixmapData = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data());
pixmapData->beginDataAccess();
- QImage &image = pixmapData->image;
- QRgb *data = reinterpret_cast<QRgb *>(image.bits());
- const int row_stride = image.bytesPerLine() / 4;
+ QPainter p(&pixmapData->image);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
const QVector<QRect> rects = rgn.rects();
+ const QColor blank = Qt::transparent;
for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
- const int x_start = it->x();
- const int width = it->width();
-
- const int y_start = it->y();
- const int height = it->height();
-
- QRgb *row = data + row_stride * y_start;
- for (int y = 0; y < height; ++y) {
- qt_memfill(row + x_start, 0U, width);
- row += row_stride;
- }
+ p.fillRect(*it, blank);
}
+
pixmapData->endDataAccess();
}
}
@@ -128,7 +119,7 @@ QImage* QS60WindowSurface::buffer(const QWidget *widget)
const QPoint off = offset(widget);
QImage *img = &(static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data())->image);
-
+
QRect rect(off, widget->size());
rect &= QRect(QPoint(), img->size());