diff options
Diffstat (limited to 'src/gui/image')
-rw-r--r-- | src/gui/image/image.pri | 3 | ||||
-rw-r--r-- | src/gui/image/qimage.cpp | 17 | ||||
-rw-r--r-- | src/gui/image/qimageiohandler.cpp | 1 | ||||
-rw-r--r-- | src/gui/image/qimageiohandler.h | 3 | ||||
-rw-r--r-- | src/gui/image/qpicture.cpp | 29 | ||||
-rw-r--r-- | src/gui/image/qpicture.h | 4 | ||||
-rw-r--r-- | src/gui/image/qpicture_p.h | 4 | ||||
-rw-r--r-- | src/gui/image/qpixmap.cpp | 30 | ||||
-rw-r--r-- | src/gui/image/qpixmap.h | 10 | ||||
-rw-r--r-- | src/gui/image/qpixmap_raster.cpp | 10 | ||||
-rw-r--r-- | src/gui/image/qpixmap_s60.cpp | 233 | ||||
-rw-r--r-- | src/gui/image/qpixmapcache.cpp | 14 | ||||
-rw-r--r-- | src/gui/image/qpixmapdatafactory.cpp | 4 |
13 files changed, 325 insertions, 37 deletions
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index b9c36dc..5e9bf8e 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -66,6 +66,9 @@ mac { HEADERS += image/qpixmap_mac_p.h SOURCES += image/qpixmap_mac.cpp } +symbian { + SOURCES += image/qpixmap_s60.cpp +} # Built-in image format support HEADERS += \ diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index bb77fb5..476fe52 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -178,6 +178,13 @@ static int depthForFormat(QImage::Format format) return depth; } +/*! \fn QImageData * QImageData::create(const QSize &size, QImage::Format format, int numColors) + + \internal + + Creates a new image data. + Returns 0 if invalid parameters are give or anything else failed. +*/ QImageData * QImageData::create(const QSize &size, QImage::Format format, int numColors) { if (!size.isValid() || numColors < 0 || format == QImage::Format_Invalid) @@ -216,7 +223,7 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format, int nu || INT_MAX/sizeof(uchar *) < uint(height)) return 0; - QImageData *d = new QImageData; + QScopedPointer<QImageData> d(new QImageData); d->colortable.resize(numColors); if (depth == 1) { d->colortable[0] = QColor(Qt::black).rgba(); @@ -239,12 +246,11 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format, int nu d->data = (uchar *)malloc(d->nbytes); if (!d->data) { - delete d; return 0; } d->ref.ref(); - return d; + return d.take(); } @@ -1610,6 +1616,7 @@ int QImage::numColors() const /*! Returns a pointer to the scanline pointer table. This is the beginning of the data block for the image. + Returns 0 in case of an error. Use the bits() or scanLine() function instead. */ @@ -1625,6 +1632,8 @@ uchar **QImage::jumpTable() if (!d->jumptable) { d->jumptable = (uchar **)malloc(d->height*sizeof(uchar *)); + if (!d->jumptable) + return 0; uchar *data = d->data; int height = d->height; uchar **p = d->jumptable; @@ -1645,6 +1654,8 @@ const uchar * const *QImage::jumpTable() const return 0; if (!d->jumptable) { d->jumptable = (uchar **)malloc(d->height*sizeof(uchar *)); + if (!d->jumptable) + return 0; uchar *data = d->data; int height = d->height; uchar **p = d->jumptable; diff --git a/src/gui/image/qimageiohandler.cpp b/src/gui/image/qimageiohandler.cpp index c64eef8..8248e42 100644 --- a/src/gui/image/qimageiohandler.cpp +++ b/src/gui/image/qimageiohandler.cpp @@ -272,7 +272,6 @@ QImageIOHandler::QImageIOHandler(QImageIOHandlerPrivate &dd) */ QImageIOHandler::~QImageIOHandler() { - delete d_ptr; } /*! diff --git a/src/gui/image/qimageiohandler.h b/src/gui/image/qimageiohandler.h index 94751f3..50508c0 100644 --- a/src/gui/image/qimageiohandler.h +++ b/src/gui/image/qimageiohandler.h @@ -44,6 +44,7 @@ #include <QtCore/qplugin.h> #include <QtCore/qfactoryinterface.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -109,7 +110,7 @@ public: protected: QImageIOHandler(QImageIOHandlerPrivate &dd); - QImageIOHandlerPrivate *d_ptr; + QScopedPointer<QImageIOHandlerPrivate> d_ptr; private: Q_DISABLE_COPY(QImageIOHandler) }; diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index ea1392b..ddb51d3 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -132,7 +132,6 @@ QPicture::QPicture(int formatVersion) { Q_D(QPicture); d_ptr->q_ptr = this; - d->paintEngine = 0; if (formatVersion == 0) qWarning("QPicture: invalid format version 0"); @@ -155,7 +154,7 @@ QPicture::QPicture(int formatVersion) */ QPicture::QPicture(const QPicture &pic) - : QPaintDevice(), d_ptr(pic.d_ptr) + : QPaintDevice(), d_ptr(pic.d_ptr.data()) { d_func()->ref.ref(); } @@ -173,10 +172,6 @@ QPicture::QPicture(QPicturePrivate &dptr) */ QPicture::~QPicture() { - if (!d_func()->ref.deref()) { - delete d_func()->paintEngine; - delete d_func(); - } } /*! @@ -1032,9 +1027,7 @@ void QPicture::detach_helper() x->formatMinor = d->formatMinor; x->brect = d->brect; x->override_rect = d->override_rect; - if (!d->ref.deref()) - delete d; - d_ptr = x; + d_ptr.reset(x); } /*! @@ -1043,13 +1036,25 @@ void QPicture::detach_helper() */ QPicture& QPicture::operator=(const QPicture &p) { - qAtomicAssign<QPicturePrivate>(d_ptr, p.d_ptr); + d_ptr.assign(p.d_ptr.data()); return *this; } /*! \internal + Constructs a QPicturePrivate +*/ +QPicturePrivate::QPicturePrivate() + : in_memory_only(false), + q_ptr(0) +{ + ref = 1; +} + +/*! + \internal + Sets formatOk to false and resets the format version numbers to default */ @@ -1137,8 +1142,8 @@ bool QPicturePrivate::checkFormat() QPaintEngine *QPicture::paintEngine() const { if (!d_func()->paintEngine) - const_cast<QPicture*>(this)->d_func()->paintEngine = new QPicturePaintEngine; - return d_func()->paintEngine; + const_cast<QPicture*>(this)->d_func()->paintEngine.reset(new QPicturePaintEngine); + return d_func()->paintEngine.data(); } /***************************************************************************** diff --git a/src/gui/image/qpicture.h b/src/gui/image/qpicture.h index 67e8db2..c323f0e 100644 --- a/src/gui/image/qpicture.h +++ b/src/gui/image/qpicture.h @@ -106,7 +106,7 @@ private: bool exec(QPainter *p, QDataStream &ds, int i); void detach_helper(); - QPicturePrivate *d_ptr; + QScopedSharedPointer<QPicturePrivate> d_ptr; friend class QPicturePaintEngine; friend class Q3Picture; friend class QAlphaPaintEngine; @@ -114,7 +114,7 @@ private: public: typedef QPicturePrivate* DataPtr; - inline DataPtr &data_ptr() { return d_ptr; } + inline DataPtr &data_ptr() { return d_ptr.data_ptr(); } }; Q_DECLARE_SHARED(QPicture) diff --git a/src/gui/image/qpicture_p.h b/src/gui/image/qpicture_p.h index 86b6365..6147019 100644 --- a/src/gui/image/qpicture_p.h +++ b/src/gui/image/qpicture_p.h @@ -143,7 +143,7 @@ public: PdcReservedStop = 199 // for Qt }; - inline QPicturePrivate() : in_memory_only(false), q_ptr(0) { ref = 1; } + QPicturePrivate(); QAtomicInt ref; bool checkFormat(); @@ -156,7 +156,7 @@ public: int formatMinor; QRect brect; QRect override_rect; - QPaintEngine *paintEngine; + QScopedPointer<QPaintEngine> paintEngine; bool in_memory_only; QList<QImage> image_list; QList<QPixmap> pixmap_list; diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 82835d5..1bcb846 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -77,6 +77,10 @@ # include <private/qpixmap_x11_p.h> #endif +#if defined(Q_OS_SYMBIAN) +# include <private/qt_s60_p.h> +#endif + #include "qpixmap_raster_p.h" QT_BEGIN_NAMESPACE @@ -257,7 +261,12 @@ QPixmap::QPixmap(const QString& fileName, const char *format, Qt::ImageConversio if (!qt_pixmap_thread_test()) return; - load(fileName, format, flags); + QT_TRY { + load(fileName, format, flags); + } QT_CATCH(...) { + deref(); + QT_RETHROW; + } } /*! @@ -305,12 +314,17 @@ QPixmap::QPixmap(const char * const xpm[]) if (!xpm) return; - QImage image(xpm); - if (!image.isNull()) { - if (data->pixelType() == QPixmapData::BitmapType) - *this = QBitmap::fromImage(image); - else - *this = fromImage(image); + QT_TRY { + QImage image(xpm); + if (!image.isNull()) { + if (data->pixelType() == QPixmapData::BitmapType) + *this = QBitmap::fromImage(image); + else + *this = fromImage(image); + } + } QT_CATCH(...) { + deref(); + QT_RETHROW; } } #endif @@ -1887,6 +1901,8 @@ int QPixmap::defaultDepth() return 32; // XXX #elif defined(Q_WS_MAC) return 32; +#elif defined(Q_OS_SYMBIAN) + return S60->screenDepth; #endif } diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index d1e2ecb..279e1ef 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -51,6 +51,10 @@ QT_BEGIN_HEADER +#if defined(Q_OS_SYMBIAN) +class CFbsBitmap; +#endif + QT_BEGIN_NAMESPACE QT_MODULE(Gui) @@ -59,7 +63,6 @@ class QImageWriter; class QColor; class QVariant; class QX11Info; - class QPixmapData; class Q_GUI_EXPORT QPixmap : public QPaintDevice @@ -152,6 +155,11 @@ public: static QPixmap fromMacCGImageRef(CGImageRef image); #endif +#if defined(Q_OS_SYMBIAN) + CFbsBitmap *toSymbianCFbsBitmap() const; + static QPixmap fromSymbianCFbsBitmap(CFbsBitmap *bitmap); +#endif + inline QPixmap copy(int x, int y, int width, int height) const; QPixmap copy(const QRect &rect = QRect()) const; diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 9cc896b..e0d952a 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -172,9 +172,13 @@ void QRasterPixmapData::fromImage(const QImage &sourceImage, } } #endif - w = image.d->width; - h = image.d->height; - d = image.d->depth; + if (image.d) { + w = image.d->width; + h = image.d->height; + d = image.d->depth; + } else { + w = h = d = 0; + } is_null = (w <= 0 || h <= 0); setSerialNumber(image.serialNumber()); diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp new file mode 100644 index 0000000..58b3ee4 --- /dev/null +++ b/src/gui/image/qpixmap_s60.cpp @@ -0,0 +1,233 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <exception> +#include <w32std.h> +#include <fbs.h> + +#include <private/qt_s60_p.h> +#include "qpixmap.h" +#include "qpixmap_raster_p.h" +#include <qwidget.h> + +QT_BEGIN_NAMESPACE + +QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h ) +{ + CWsScreenDevice* screenDevice = S60->screenDevice(); + TSize screenSize = screenDevice->SizeInPixels(); + + TSize srcSize; + // Find out if this is one of our windows. + QSymbianControl *sControl; + sControl = winId->MopGetObject(sControl); + if (sControl && sControl->widget()->windowType() == Qt::Desktop) { + // Grabbing desktop widget + srcSize = screenSize; + } else { + TPoint relativePos = winId->PositionRelativeToScreen(); + x += relativePos.iX; + y += relativePos.iY; + srcSize = winId->Size(); + } + + TRect srcRect(TPoint(x, y), srcSize); + // Clip to the screen + srcRect.Intersection(TRect(screenSize)); + + if (w > 0 && h > 0) { + TRect subRect(TPoint(x, y), TSize(w, h)); + // Clip to the subRect + srcRect.Intersection(subRect); + } + + if (srcRect.IsEmpty()) + return QPixmap(); + + TDisplayMode displayMode = screenDevice->DisplayMode(); + CFbsBitmap* temporary = q_check_ptr(new CFbsBitmap()); // CBase derived object needs check on new + TInt error = temporary->Create(srcRect.Size(), displayMode); + if (error == KErrNone) + error = screenDevice->CopyScreenToBitmap(temporary, srcRect); + + if (error != KErrNone) { + CBase::Delete(temporary); + return QPixmap(); + } + + QPixmap pixmap = QPixmap::fromSymbianCFbsBitmap(temporary); + CBase::Delete(temporary); + return pixmap; +} + +/*! +\since 4.6 + +Returns a \c CFbsBitmap that is equivalent to the QPixmap by copying the data. + +It is the caller's responsibility to delete the \c CFbsBitmap after use. + +\warning This function is only available on Symbian OS. + +\sa fromSymbianCFbsBitmap() +*/ + +CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const +{ + if (isNull()) + return 0; + + TDisplayMode mode; + const QImage img = toImage(); + QImage::Format destFormat = img.format(); + switch (img.format()) { + case QImage::Format_Mono: + destFormat = QImage::Format_MonoLSB; + // Fall through intended + case QImage::Format_MonoLSB: + mode = EGray2; + break; + case QImage::Format_Indexed8: + if (img.isGrayscale()) + mode = EGray256; + else + mode = EColor256; + break; + case QImage::Format_RGB32: + mode = EColor16MU; + break; + case QImage::Format_ARGB6666_Premultiplied: + case QImage::Format_ARGB8565_Premultiplied: + case QImage::Format_ARGB8555_Premultiplied: + destFormat = QImage::Format_ARGB32_Premultiplied; + // Fall through intended + case QImage::Format_ARGB32_Premultiplied: +#if !defined(__SERIES60_31__) && !defined(__S60_32__) + // ### TODO: Add runtime detection as well? + mode = EColor16MAP; + break; +#endif + destFormat = QImage::Format_ARGB32; + // Fall through intended + case QImage::Format_ARGB32: + mode = EColor16MA; + break; + case QImage::Format_RGB555: + destFormat = QImage::Format_RGB16; + // Fall through intended + case QImage::Format_RGB16: + mode = EColor64K; + break; + case QImage::Format_RGB666: + destFormat = QImage::Format_RGB888; + // Fall through intended + case QImage::Format_RGB888: + mode = EColor16M; + break; + case QImage::Format_RGB444: + mode = EColor4K; + break; + case QImage::Format_Invalid: + return 0; + default: + qWarning("Image format not supported: %d", img.format()); + return 0; + } + + CFbsBitmap* bitmap = q_check_ptr(new CFbsBitmap()); // CBase derived object needs check on new + TSize size(width(), height()); + if (bitmap->Create(size, mode) != KErrNone) { + CBase::Delete(bitmap); + return 0; + } + + const QImage converted = img.convertToFormat(destFormat); + + bitmap->LockHeap(); + const uchar *sptr = converted.bits(); + uchar *dptr = (uchar*)bitmap->DataAddress(); + Mem::Copy(dptr, sptr, converted.numBytes()); + bitmap->UnlockHeap(); + return bitmap; +} + +/*! +\since 4.6 + +Returns a QPixmap that is equivalent to the \c CFbsBitmap by copying the data. +If the CFbsBitmap is not valid or is compressed in memory, this function will +return a null QPixmap. + +\warning This function is only available on Symbian OS. + +\sa toSymbianCFbsBitmap(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} +*/ + +QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap) +{ + int width = bitmap->SizeInPixels().iWidth; + int height = bitmap->SizeInPixels().iHeight; + + if (!bitmap || width <= 0 || height <= 0 || bitmap->IsCompressedInRAM()) + return QPixmap(); + + TDisplayMode displayMode = bitmap->DisplayMode(); + QImage::Format format = qt_TDisplayMode2Format(displayMode); + int bytesPerLine = CFbsBitmap::ScanLineLength(width, displayMode); + bitmap->LockHeap(); + QImage image = QImage((const uchar*)bitmap->DataAddress(), width, height, bytesPerLine, format); + if (displayMode == EGray2) { + image.setNumColors(2); + image.setColor(0, QColor(Qt::color0).rgba()); + image.setColor(1, QColor(Qt::color1).rgba()); + } else if (displayMode == EGray256) { + for (int i=0; i < 256; ++i) + image.setColor(i, qRgb(i, i, i)); + }else if (displayMode == EColor256) { + const TColor256Util *palette = TColor256Util::Default(); + for (int i=0; i < 256; ++i) + image.setColor(i, (QRgb)(palette->Color256(i).Value())); + } + QPixmap pixmap = QPixmap::fromImage(image.copy()); + bitmap->UnlockHeap(); + return pixmap; +} + +QT_END_NAMESPACE diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index ecdcd8c..aedc90c 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -86,7 +86,9 @@ QT_BEGIN_NAMESPACE \sa QCache, QPixmap */ -#if defined(Q_WS_QWS) || defined(Q_WS_WINCE) +#if defined(Q_OS_SYMBIAN) +static int cache_limit = 1024; // 1048 KB cache limit for symbian +#elif defined(Q_WS_QWS) || defined(Q_WS_WINCE) static int cache_limit = 2048; // 2048 KB cache limit for embedded #else static int cache_limit = 10240; // 10 MB cache limit for desktop @@ -366,7 +368,8 @@ void QPMCache::resizeKeyArray(int size) { if (size <= keyArraySize || size == 0) return; - keyArray = reinterpret_cast<int *>(realloc(keyArray, size * sizeof(int))); + keyArray = q_check_ptr(reinterpret_cast<int *>(realloc(keyArray, + size * sizeof(int)))); for (int i = keyArraySize; i != size; ++i) keyArray[i] = i + 1; keyArraySize = size; @@ -608,7 +611,12 @@ void QPixmapCache::remove(const Key &key) void QPixmapCache::clear() { - pm_cache()->clear(); + QT_TRY { + pm_cache()->clear(); + } QT_CATCH(const std::bad_alloc &) { + // if we ran out of memory during pm_cache(), it's no leak, + // so just ignore it. + } } QT_END_NAMESPACE diff --git a/src/gui/image/qpixmapdatafactory.cpp b/src/gui/image/qpixmapdatafactory.cpp index e5bf414..852e875 100644 --- a/src/gui/image/qpixmapdatafactory.cpp +++ b/src/gui/image/qpixmapdatafactory.cpp @@ -47,7 +47,7 @@ #ifdef Q_WS_X11 # include <private/qpixmap_x11_p.h> #endif -#ifdef Q_WS_WIN +#if defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) # include <private/qpixmap_raster_p.h> #endif #ifdef Q_WS_MAC @@ -75,7 +75,7 @@ QPixmapData* QSimplePixmapDataFactory::create(QPixmapData::PixelType type) #if defined(Q_WS_X11) return new QX11PixmapData(type); -#elif defined(Q_WS_WIN) +#elif defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) return new QRasterPixmapData(type); #elif defined(Q_WS_MAC) return new QMacPixmapData(type); |