diff options
author | Janne Anttila <janne.anttila@digia.com> | 2010-03-10 08:18:03 (GMT) |
---|---|---|
committer | Janne Anttila <janne.anttila@digia.com> | 2010-03-10 08:18:03 (GMT) |
commit | 7e78d2668e508f929243fe2169e1d9937b8d2b67 (patch) | |
tree | 50dd5769701c554e0faeb282cfed0f9ae3492cb3 /src/gui | |
parent | 065fdc4caba6305f45b53edf27391af29f496a1c (diff) | |
download | Qt-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
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/painting/qwindowsurface_s60.cpp | 25 |
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()); |