From 12849e1767f3f881c9060368c3a14fae6e5a9ef1 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 31 Mar 2009 00:26:10 -0700 Subject: Prevent crash on resizing The crash was caused by out-of-bounds reading on the raster engine's clipping structures since our size had changed size last lock. This code makes sure the clipData structures are atleast as tall as the current height of the paint device. Reviewed-by: Tom Cooksey --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 90fc446..450c7f4 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -243,6 +243,7 @@ public: SurfaceCache *surfaceCache; QTransform transform; + int lastLockedHeight; private: // QRegion rectsToClippedRegion(const QRect *rects, int n) const; // QRegion rectsToClippedRegion(const QRectF *rects, int n) const; @@ -267,9 +268,9 @@ private: QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) : surface(0), antialiased(false), forceRasterPrimitives(false), simplePen(false), - simpleBrush(false), matrixRotShear(false), matrixScale(false), fbWidth(-1), fbHeight(-1), - opacity(255), drawFlags(0), blitFlags(0), duffFlags(0), dirtyFlags(false), dirtyClip(true), - dfbHandledClip(false), dfbDevice(0), q(p) + simpleBrush(false), matrixRotShear(false), matrixScale(false), lastLockedHeight(-1), + fbWidth(-1), fbHeight(-1), opacity(255), drawFlags(0), blitFlags(0), duffFlags(0), + dirtyFlags(false), dirtyClip(true), dfbHandledClip(false), dfbDevice(0), q(p) { fb = QDirectFBScreen::instance()->dfb(); surfaceCache = new SurfaceCache; @@ -311,6 +312,8 @@ void QDirectFBPaintEnginePrivate::lock() // We will potentially get a new pointer to the buffer after a // lock so we need to call the base implementation of prepare so // it updates its rasterBuffer to point to the new buffer address. + lastLockedHeight = dfbDevice->height(); + Q_ASSERT(dfbDevice); prepare(dfbDevice); } @@ -330,6 +333,7 @@ void QDirectFBPaintEnginePrivate::setTransform(const QTransform &m) void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) { + lastLockedHeight = -1; if (device->devType() == QInternal::CustomRaster) dfbDevice = static_cast(device); else if (device->devType() == QInternal::Pixmap) { @@ -927,6 +931,9 @@ void QDirectFBPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) { Q_D(QDirectFBPaintEngine); d->setClipDirty(); + const QPoint bottom = d->transform.map(QPoint(0, path.controlPointRect().y2)); + if (bottom.y() >= d->lastLockedHeight) + d->lock(); QRasterPaintEngine::clip(path, op); } @@ -934,10 +941,15 @@ void QDirectFBPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) { Q_D(QDirectFBPaintEngine); d->setClipDirty(); + if (!d->clip()->hasRectClip && d->clip()->enabled) { + const QPoint bottom = d->transform.map(QPoint(0, rect.bottom())); + if (bottom.y() >= d->lastLockedHeight) + d->lock(); + } + QRasterPaintEngine::clip(rect, op); } - void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) { Q_D(QDirectFBPaintEngine); -- cgit v0.12 From 810bbcd38e8f829ccc6702f5cdf2bb97bbca97cc Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 30 Mar 2009 21:51:33 -0700 Subject: No sense in detecting the format twice Use the format passed in to the function rather than detecting it again based on hasAlphaChannel(). Reviewed-by: Tom Cooksey --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 3a6b3a2..fd6f48a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -249,14 +249,10 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription } IDirectFBSurface *QDirectFBScreen::copyToDFBSurface(const QImage &img, - QImage::Format format, + QImage::Format pixmapFormat, SurfaceCreationOptions options) { QImage image = img; - const QImage::Format pixmapFormat = image.hasAlphaChannel() - ? QDirectFBScreen::alphaPixmapFormat() - : QDirectFBScreen::pixelFormat(); - if (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN #ifdef QT_NO_DIRECTFB_PREALLOCATED || image.format() != pixmapFormat @@ -266,7 +262,7 @@ IDirectFBSurface *QDirectFBScreen::copyToDFBSurface(const QImage &img, } - IDirectFBSurface *dfbSurface = createDFBSurface(img.size(), format, options); + IDirectFBSurface *dfbSurface = createDFBSurface(img.size(), pixmapFormat, options); if (!dfbSurface) { qWarning("QDirectFBPixmapData::fromImage() Couldn't create surface"); return 0; -- cgit v0.12 From c2417c61aeda9de8a8e4c876ea42d6076d4078b0 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 31 Mar 2009 10:27:59 -0700 Subject: Remove these convenience functions. They only make sense under the assumption that there most of the time is no transform. With Falcon this isn't really the case. Reviewed-by: Tom Cooksey --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 34 ++++++++-------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 450c7f4..b8354d9 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -61,17 +61,6 @@ static inline uint ALPHA_MUL(uint x, uint a) return t; } -static inline QRect mapRect(const QTransform &transform, const QRect &rect) -{ - return (transform.isIdentity() ? rect : transform.mapRect(rect)); -} - -static inline QRect mapRect(const QTransform &transform, const QRectF &rect) -{ - return (transform.isIdentity() ? rect : transform.mapRect(rect)). - toRect(); -} - class SurfaceCache { public: @@ -542,7 +531,7 @@ QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRect *rects, QRegion region; for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]); region += clip & r; } @@ -555,7 +544,7 @@ QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRectF *rects, QRegion region; for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]).toRect(); region += clip & r; } @@ -584,7 +573,7 @@ void QDirectFBPaintEnginePrivate::fillRects(const QRect *rects, int n) const { QVarLengthArray dfbRects(n); for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]); dfbRects[i].x = r.x(); dfbRects[i].y = r.y(); dfbRects[i].w = r.width(); @@ -597,7 +586,7 @@ void QDirectFBPaintEnginePrivate::fillRects(const QRectF *rects, int n) const { QVarLengthArray dfbRects(n); for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]).toRect(); dfbRects[i].x = r.x(); dfbRects[i].y = r.y(); dfbRects[i].w = r.width(); @@ -609,7 +598,7 @@ void QDirectFBPaintEnginePrivate::fillRects(const QRectF *rects, int n) const void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) const { for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]); surface->DrawRectangle(surface, r.x(), r.y(), r.width() + 1, r.height() + 1); } @@ -618,7 +607,7 @@ void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) const void QDirectFBPaintEnginePrivate::drawRects(const QRectF *rects, int n) const { for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]).toRect(); surface->DrawRectangle(surface, r.x(), r.y(), r.width() + 1, r.height() + 1); } @@ -642,7 +631,7 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest, QDirectFBPixmapData *dfbData = static_cast(data); IDirectFBSurface *s = dfbData->directFBSurface(); const QRect sr = src.toRect(); - const QRect dr = ::mapRect(transform, dest); + const QRect dr = transform.mapRect(dest).toRect(); const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; DFBResult result; @@ -674,6 +663,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast(data); IDirectFBSurface *s = dfbData->directFBSurface(); + const QRect dr = transform.mapRect(dest).toRect(); const QRect dr = ::mapRect(transform, dest); DFBResult result = DFB_OK; @@ -696,7 +686,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, result = surface->BatchBlit(surface, s, rects.constData(), points.constData(), points.size()); } else { - const QRect sr = ::mapRect(transform, QRect(0, 0, pixmap.width(), pixmap.height())); + const QRect sr = transform.mapRect(QRect(0, 0, pixmap.width(), pixmap.height())); const int dx = sr.width(); const int dy = sr.height(); const DFBRectangle sRect = { 0, 0, dx, dy }; @@ -769,7 +759,7 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, } const QRect sr = src.toRect(); - const QRect dr = ::mapRect(transform, dest); + const QRect dr = transform.mapRect(dest).toRect(); const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); @@ -1197,7 +1187,7 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) d->unlock(); d->updateFlags(); d->setDFBColor(brush.color()); - const QRect r = ::mapRect(d->transform, rect); + const QRect r = d->transform.mapRect(rect).toRect(); d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()); return; } @@ -1229,7 +1219,7 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) d->unlock(); d->updateFlags(); d->setDFBColor(color); - const QRect r = ::mapRect(d->transform, rect); + const QRect r = d->transform.mapRect(rect).toRect(); d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()); } -- cgit v0.12 From 4d878fe43bef5ff6387c3bb73587315efa21424d Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 31 Mar 2009 10:40:34 -0700 Subject: Compile I messed up the cherry-pick merge and left one of these in. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index b8354d9..3b6ea80 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -664,7 +664,6 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, QDirectFBPixmapData *dfbData = static_cast(data); IDirectFBSurface *s = dfbData->directFBSurface(); const QRect dr = transform.mapRect(dest).toRect(); - const QRect dr = ::mapRect(transform, dest); DFBResult result = DFB_OK; if (!matrixScale && dr == QRect(0, 0, fbWidth, fbHeight)) { -- cgit v0.12 From ac96e93728541897203a8d1bcbdf9e43c4af8758 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 31 Mar 2009 19:53:21 +0200 Subject: Doc: Fixed the screenshots and example description to match the code. Task-number: 242369 Reviewed-by: TrustMe --- doc/src/examples/extension.qdoc | 11 +++++------ doc/src/images/extension-example.png | Bin 7676 -> 9929 bytes doc/src/images/extension_more.png | Bin 9309 -> 13523 bytes 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/src/examples/extension.qdoc b/doc/src/examples/extension.qdoc index 8a0ca3a..02e0698 100644 --- a/doc/src/examples/extension.qdoc +++ b/doc/src/examples/extension.qdoc @@ -80,9 +80,9 @@ user type a word to search for, we need several \l {QCheckBox}{QCheckBox}es to facilitate the search options, and we need three \l {QPushButton}{QPushButton}s: the \gui Find button to - start a search, the \gui More button to enable an advanced search, - and the \gui Close button to exit the application. Finally, we - need a QWidget representing the application's extension part. + start a search and the \gui More button to enable an advanced search. + Finally, we need a QWidget representing the application's extension + part. \section1 FindDialog Class Implementation @@ -128,8 +128,7 @@ the connection makes sure that the extension widget is shown depending on the state of \gui More button. - We also connect the \gui Close button to the QWidget::close() - slot, and we put the checkboxes associated with the advanced + We also put the check boxes associated with the advanced search options into a layout we install on the extension widget. \snippet examples/dialogs/extension/finddialog.cpp 4 @@ -137,7 +136,7 @@ Before we create the main layout, we create several child layouts for the widgets: First we allign the QLabel ans its buddy, the QLineEdit, using a QHBoxLayout. Then we vertically allign the - QLabel and QLineEdit with the checkboxes associated with the + QLabel and QLineEdit with the check boxes associated with the simple search, using a QVBoxLayout. We also create a QVBoxLayout for the buttons. In the end we lay out the two latter layouts and the extension widget using a QGridLayout. diff --git a/doc/src/images/extension-example.png b/doc/src/images/extension-example.png index dfaacc0..18fab52 100644 Binary files a/doc/src/images/extension-example.png and b/doc/src/images/extension-example.png differ diff --git a/doc/src/images/extension_more.png b/doc/src/images/extension_more.png index 2b06809..407af27 100644 Binary files a/doc/src/images/extension_more.png and b/doc/src/images/extension_more.png differ -- cgit v0.12