diff options
Diffstat (limited to 'src/gui/image')
52 files changed, 628 insertions, 12724 deletions
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index 72738c9fa8..3ccfb04fcc 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -5,11 +5,6 @@ HEADERS += \ image/qbitmap.h \ - image/qicon.h \ - image/qicon_p.h \ - image/qiconloader_p.h \ - image/qiconengine.h \ - image/qiconengineplugin.h \ image/qimage.h \ image/qimage_p.h \ image/qimageiohandler.h \ @@ -26,18 +21,13 @@ HEADERS += \ image/qpixmap_blitter_p.h \ image/qpixmapcache.h \ image/qpixmapcache_p.h \ - image/qpixmapdata_p.h \ - image/qpixmapdatafactory_p.h \ - image/qpixmapfilter_p.h \ + image/qplatformpixmap_qpa.h \ image/qimagepixmapcleanuphooks_p.h \ image/qvolatileimage_p.h \ - image/qvolatileimagedata_p.h \ - image/qnativeimagehandleprovider_p.h + image/qvolatileimagedata_p.h SOURCES += \ image/qbitmap.cpp \ - image/qicon.cpp \ - image/qiconloader.cpp \ image/qimage.cpp \ image/qimageiohandler.cpp \ image/qimagereader.cpp \ @@ -47,11 +37,7 @@ SOURCES += \ image/qpictureformatplugin.cpp \ image/qpixmap.cpp \ image/qpixmapcache.cpp \ - image/qpixmapdata.cpp \ - image/qpixmapdatafactory.cpp \ - image/qpixmapfilter.cpp \ - image/qiconengine.cpp \ - image/qiconengineplugin.cpp \ + image/qplatformpixmap.cpp \ image/qmovie.cpp \ image/qpixmap_raster.cpp \ image/qpixmap_blitter.cpp \ @@ -59,15 +45,12 @@ SOURCES += \ image/qimagepixmapcleanuphooks.cpp \ image/qvolatileimage.cpp -win32 { - SOURCES += image/qpixmap_win.cpp -} -else:embedded { - SOURCES += image/qpixmap_qws.cpp -} -else:qpa { +qpa: { SOURCES += image/qpixmap_qpa.cpp } +else:win32 { + SOURCES += image/qpixmap_win.cpp +} else:x11 { HEADERS += image/qpixmap_x11_p.h SOURCES += image/qpixmap_x11.cpp diff --git a/src/gui/image/qbitmap.cpp b/src/gui/image/qbitmap.cpp index c0cab83926..f32c517f17 100644 --- a/src/gui/image/qbitmap.cpp +++ b/src/gui/image/qbitmap.cpp @@ -40,12 +40,12 @@ ****************************************************************************/ #include "qbitmap.h" -#include "qpixmapdata_p.h" +#include "qplatformpixmap_qpa.h" #include "qimage.h" +#include "qscreen.h" #include "qvariant.h" #include <qpainter.h> -#include <private/qgraphicssystem_p.h> -#include <private/qapplication_p.h> +#include <private/qguiapplication_p.h> QT_BEGIN_NAMESPACE @@ -102,7 +102,7 @@ QT_BEGIN_NAMESPACE \sa QPixmap::isNull() */ QBitmap::QBitmap() - : QPixmap(QSize(0, 0), QPixmapData::BitmapType) + : QPixmap(QSize(0, 0), QPlatformPixmap::BitmapType) { } @@ -116,7 +116,7 @@ QBitmap::QBitmap() */ QBitmap::QBitmap(int w, int h) - : QPixmap(QSize(w, h), QPixmapData::BitmapType) + : QPixmap(QSize(w, h), QPlatformPixmap::BitmapType) { } @@ -128,7 +128,7 @@ QBitmap::QBitmap(int w, int h) */ QBitmap::QBitmap(const QSize &size) - : QPixmap(size, QPixmapData::BitmapType) + : QPixmap(size, QPlatformPixmap::BitmapType) { } @@ -173,7 +173,7 @@ QBitmap::QBitmap(const QPixmap &pixmap) */ QBitmap::QBitmap(const QString& fileName, const char *format) - : QPixmap(QSize(0, 0), QPixmapData::BitmapType) + : QPixmap(QSize(0, 0), QPlatformPixmap::BitmapType) { load(fileName, format, Qt::MonoOnly); } @@ -205,20 +205,6 @@ QBitmap &QBitmap::operator=(const QPixmap &pixmap) return *this; } - -#ifdef QT3_SUPPORT -QBitmap::QBitmap(int w, int h, const uchar *bits, bool isXbitmap) -{ - *this = fromData(QSize(w, h), bits, isXbitmap ? QImage::Format_MonoLSB : QImage::Format_Mono); -} - - -QBitmap::QBitmap(const QSize &size, const uchar *bits, bool isXbitmap) -{ - *this = fromData(size, bits, isXbitmap ? QImage::Format_MonoLSB : QImage::Format_Mono); -} -#endif - /*! Destroys the bitmap. */ @@ -275,9 +261,7 @@ QBitmap QBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags) img.setColor(1, c0); } - QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem(); - QScopedPointer<QPixmapData> data(gs ? gs->createPixmapData(QPixmapData::BitmapType) - : QGraphicsSystem::createDefaultPixmapData(QPixmapData::BitmapType)); + QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::BitmapType)); data->fromImage(img, flags | Qt::MonoOnly); return QPixmap(data.take()); @@ -335,77 +319,4 @@ QBitmap QBitmap::transformed(const QMatrix &matrix) const return transformed(QTransform(matrix)); } -#ifdef QT3_SUPPORT -/*! - \fn QBitmap QBitmap::xForm(const QMatrix &matrix) const - - Returns a copy of this bitmap, transformed according to the given - \a matrix. - - Use transformed() instead. -*/ - -/*! - \fn QBitmap::QBitmap(const QSize &size, bool clear) - - Constructs a bitmap with the given \a size. If \a clear is true, - the bits are initialized to Qt::color0. - - Use the corresponding QBitmap() constructor instead, and then call - the clear() function if the \a clear parameter is true. -*/ - -/*! - \fn QBitmap::QBitmap(int width, int height, bool clear) - - Constructs a bitmap with the given \a width and \a height. If \a - clear is true, the bits are initialized to Qt::color0. - - Use the corresponding QBitmap() constructor instead, and then call - the clear() function if the \a clear parameter is true. -*/ - -/*! - \fn QBitmap::QBitmap(int width, int height, const uchar *bits, bool isXbitmap) - - Constructs a bitmap with the given \a width and \a height, and - sets the contents to the \a bits supplied. The \a isXbitmap flag - should be true if \a bits was generated by the X11 bitmap - program. - - Use the static fromData() function instead. If \a isXbitmap is - true, use the default bit order(QImage_FormatMonoLSB) otherwise - use QImage::Format_Mono. - - \omit - The X bitmap bit order is little endian. The QImage - documentation discusses bit order of monochrome images. Opposed to - QImage, the data has to be byte aligned. - - Example (creates an arrow bitmap): - \snippet doc/src/snippets/code/src_gui_image_qbitmap.cpp 0 - \endomit -*/ - - -/*! - \fn QBitmap::QBitmap(const QSize &size, const uchar *bits, bool isXbitmap) - - \overload - - Constructs a bitmap with the given \a size, and sets the contents - to the \a bits supplied. The \a isXbitmap flag should be true if - \a bits was generated by the X11 bitmap program. - - \omit - The X bitmap bit order is little endian. The QImage documentation - discusses bit order of monochrome images. - \endomit - - Use the static fromData() function instead. If \a isXbitmap is - true, use the default bit order(QImage_FormatMonoLSB) otherwise - use QImage::Format_Mono. -*/ -#endif - QT_END_NAMESPACE diff --git a/src/gui/image/qbitmap.h b/src/gui/image/qbitmap.h index b37eed212d..a3104f5083 100644 --- a/src/gui/image/qbitmap.h +++ b/src/gui/image/qbitmap.h @@ -74,34 +74,11 @@ public: QBitmap transformed(const QMatrix &) const; QBitmap transformed(const QTransform &matrix) const; -#ifdef QT3_SUPPORT - inline QT3_SUPPORT_CONSTRUCTOR QBitmap(int w, int h, bool clear); - inline QT3_SUPPORT_CONSTRUCTOR QBitmap(const QSize &, bool clear); - QT3_SUPPORT_CONSTRUCTOR QBitmap(int w, int h, const uchar *bits, bool isXbitmap=false); - QT3_SUPPORT_CONSTRUCTOR QBitmap(const QSize &, const uchar *bits, bool isXbitmap=false); - inline QT3_SUPPORT QBitmap xForm(const QMatrix &matrix) const { return transformed(QTransform(matrix)); } - QT3_SUPPORT_CONSTRUCTOR QBitmap(const QImage &image) { *this = fromImage(image); } - QT3_SUPPORT QBitmap &operator=(const QImage &image) { *this = fromImage(image); return *this; } -#endif - typedef QExplicitlySharedDataPointer<QPixmapData> DataPtr; + typedef QExplicitlySharedDataPointer<QPlatformPixmap> DataPtr; }; Q_DECLARE_SHARED(QBitmap) -#ifdef QT3_SUPPORT -inline QBitmap::QBitmap(int w, int h, bool clear) - : QPixmap(QSize(w, h), 1) -{ - if (clear) this->clear(); -} - -inline QBitmap::QBitmap(const QSize &size, bool clear) - : QPixmap(size, 1) -{ - if (clear) this->clear(); -} -#endif - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 8840a83ff0..d854b1765b 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -692,11 +692,16 @@ bool qt_read_dib(QDataStream &s, QImage &image) return read_dib_body(s, bi, -1, -BMP_FILEHDR_SIZE, image); } -QBmpHandler::QBmpHandler() - : state(Ready) +QBmpHandler::QBmpHandler(InternalFormat fmt) : + m_format(fmt), state(Ready) { } +QByteArray QBmpHandler::formatName() const +{ + return m_format == BmpFormat ? "bmp" : "dib"; +} + bool QBmpHandler::readHeader() { state = Error; @@ -709,7 +714,7 @@ bool QBmpHandler::readHeader() s.setByteOrder(QDataStream::LittleEndian); // read BMP file header - if (!read_dib_fileheader(s, fileHeader)) + if (m_format == BmpFormat && !read_dib_fileheader(s, fileHeader)) return false; // read BMP info header @@ -722,11 +727,11 @@ bool QBmpHandler::readHeader() bool QBmpHandler::canRead() const { - if (state == Ready && !canRead(device())) + if (m_format == BmpFormat && state == Ready && !canRead(device())) return false; if (state != Error) { - setFormat("bmp"); + setFormat(formatName()); return true; } @@ -778,6 +783,12 @@ bool QBmpHandler::read(QImage *image) bool QBmpHandler::write(const QImage &img) { + if (m_format == DibFormat) { + QDataStream dibStream(device()); + dibStream.setByteOrder(QDataStream::LittleEndian); // Intel byte order + return qt_write_dib(dibStream, img); + } + QImage image; switch (img.format()) { case QImage::Format_ARGB8565_Premultiplied: @@ -875,7 +886,7 @@ void QBmpHandler::setOption(ImageOption option, const QVariant &value) QByteArray QBmpHandler::name() const { - return "bmp"; + return formatName(); } QT_END_NAMESPACE diff --git a/src/gui/image/qbmphandler_p.h b/src/gui/image/qbmphandler_p.h index 070d904b77..373f8fbaaf 100644 --- a/src/gui/image/qbmphandler_p.h +++ b/src/gui/image/qbmphandler_p.h @@ -81,10 +81,20 @@ struct BMP_INFOHDR { // BMP information header qint32 biClrImportant; // number of important colors }; +// BMP-Handler, which is also able to read and write the DIB +// (Device-Independent-Bitmap) format used internally in the Windows operating +// system for OLE/clipboard operations. DIB is a subset of BMP (without file +// header). The Windows-Lighthouse plugin accesses the DIB-functionality. + class QBmpHandler : public QImageIOHandler { public: - QBmpHandler(); + enum InternalFormat { + DibFormat, + BmpFormat + }; + + explicit QBmpHandler(InternalFormat fmt = BmpFormat); bool canRead() const; bool read(QImage *image); bool write(const QImage &image); @@ -99,11 +109,16 @@ public: private: bool readHeader(); + inline QByteArray formatName() const; + enum State { Ready, ReadHeader, Error }; + + const InternalFormat m_format; + State state; BMP_FILEHDR fileHeader; BMP_INFOHDR infoHeader; diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp deleted file mode 100644 index 724205f2fc..0000000000 --- a/src/gui/image/qicon.cpp +++ /dev/null @@ -1,1256 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qicon.h" -#include "qicon_p.h" -#include "qiconengine.h" -#include "qiconengineplugin.h" -#include "private/qfactoryloader_p.h" -#include "private/qiconloader_p.h" -#include "qapplication.h" -#include "qstyleoption.h" -#include "qpainter.h" -#include "qfileinfo.h" -#include "qstyle.h" -#include "qpixmapcache.h" -#include "qvariant.h" -#include "qcache.h" -#include "qdebug.h" -#include "private/qguiplatformplugin_p.h" - -#ifdef Q_WS_MAC -#include <private/qt_mac_p.h> -#include <private/qt_cocoa_helpers_mac_p.h> -#endif - -#ifdef Q_WS_X11 -#include "private/qt_x11_p.h" -#include "private/qkde_p.h" -#endif - -#include "private/qstylehelper_p.h" - -#ifndef QT_NO_ICON -QT_BEGIN_NAMESPACE - -/*! - \enum QIcon::Mode - - This enum type describes the mode for which a pixmap is intended - to be used. The currently defined modes are: - - \value Normal - Display the pixmap when the user is - not interacting with the icon, but the - functionality represented by the icon is available. - \value Disabled - Display the pixmap when the - functionality represented by the icon is not available. - \value Active - Display the pixmap when the - functionality represented by the icon is available and - the user is interacting with the icon, for example, moving the - mouse over it or clicking it. - \value Selected - Display the pixmap when the item represented by the icon is - selected. -*/ - -/*! - \enum QIcon::State - - This enum describes the state for which a pixmap is intended to be - used. The \e state can be: - - \value Off Display the pixmap when the widget is in an "off" state - \value On Display the pixmap when the widget is in an "on" state -*/ - -static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1); - -static void qt_cleanup_icon_cache(); -namespace { - class IconCache: public QCache<QString, QIcon> - { - public: - IconCache() - { - // ### FIXME: needs to be re-added if qApp is re-created - qAddPostRoutine(qt_cleanup_icon_cache); - } - }; -} -Q_GLOBAL_STATIC(IconCache, qtIconCache) - -static void qt_cleanup_icon_cache() -{ - qtIconCache()->clear(); -} - -QIconPrivate::QIconPrivate() - : engine(0), - serialNum(serialNumCounter.fetchAndAddRelaxed(1)), - detach_no(0), - engine_version(2), - v1RefCount(0) -{ -} - -QPixmapIconEngine::QPixmapIconEngine() -{ -} - -QPixmapIconEngine::QPixmapIconEngine(const QPixmapIconEngine &other) - : QIconEngineV2(other), pixmaps(other.pixmaps) -{ -} - -QPixmapIconEngine::~QPixmapIconEngine() -{ -} - -void QPixmapIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) -{ - QSize pixmapSize = rect.size(); -#if defined(Q_WS_MAC) - pixmapSize *= qt_mac_get_scalefactor(); -#endif - painter->drawPixmap(rect, pixmap(pixmapSize, mode, state)); -} - -static inline int area(const QSize &s) { return s.width() * s.height(); } - -// returns the smallest of the two that is still larger than or equal to size. -static QPixmapIconEngineEntry *bestSizeMatch( const QSize &size, QPixmapIconEngineEntry *pa, QPixmapIconEngineEntry *pb) -{ - int s = area(size); - if (pa->size == QSize() && pa->pixmap.isNull()) { - pa->pixmap = QPixmap(pa->fileName); - pa->size = pa->pixmap.size(); - } - int a = area(pa->size); - if (pb->size == QSize() && pb->pixmap.isNull()) { - pb->pixmap = QPixmap(pb->fileName); - pb->size = pb->pixmap.size(); - } - int b = area(pb->size); - int res = a; - if (qMin(a,b) >= s) - res = qMin(a,b); - else - res = qMax(a,b); - if (res == a) - return pa; - return pb; -} - -QPixmapIconEngineEntry *QPixmapIconEngine::tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state) -{ - QPixmapIconEngineEntry *pe = 0; - for (int i = 0; i < pixmaps.count(); ++i) - if (pixmaps.at(i).mode == mode && pixmaps.at(i).state == state) { - if (pe) - pe = bestSizeMatch(size, &pixmaps[i], pe); - else - pe = &pixmaps[i]; - } - return pe; -} - - -QPixmapIconEngineEntry *QPixmapIconEngine::bestMatch(const QSize &size, QIcon::Mode mode, QIcon::State state, bool sizeOnly) -{ - QPixmapIconEngineEntry *pe = tryMatch(size, mode, state); - while (!pe){ - QIcon::State oppositeState = (state == QIcon::On) ? QIcon::Off : QIcon::On; - if (mode == QIcon::Disabled || mode == QIcon::Selected) { - QIcon::Mode oppositeMode = (mode == QIcon::Disabled) ? QIcon::Selected : QIcon::Disabled; - if ((pe = tryMatch(size, QIcon::Normal, state))) - break; - if ((pe = tryMatch(size, QIcon::Active, state))) - break; - if ((pe = tryMatch(size, mode, oppositeState))) - break; - if ((pe = tryMatch(size, QIcon::Normal, oppositeState))) - break; - if ((pe = tryMatch(size, QIcon::Active, oppositeState))) - break; - if ((pe = tryMatch(size, oppositeMode, state))) - break; - if ((pe = tryMatch(size, oppositeMode, oppositeState))) - break; - } else { - QIcon::Mode oppositeMode = (mode == QIcon::Normal) ? QIcon::Active : QIcon::Normal; - if ((pe = tryMatch(size, oppositeMode, state))) - break; - if ((pe = tryMatch(size, mode, oppositeState))) - break; - if ((pe = tryMatch(size, oppositeMode, oppositeState))) - break; - if ((pe = tryMatch(size, QIcon::Disabled, state))) - break; - if ((pe = tryMatch(size, QIcon::Selected, state))) - break; - if ((pe = tryMatch(size, QIcon::Disabled, oppositeState))) - break; - if ((pe = tryMatch(size, QIcon::Selected, oppositeState))) - break; - } - - if (!pe) - return pe; - } - - if (sizeOnly ? (pe->size.isNull() || !pe->size.isValid()) : pe->pixmap.isNull()) { - pe->pixmap = QPixmap(pe->fileName); - if (!pe->pixmap.isNull()) - pe->size = pe->pixmap.size(); - } - - return pe; -} - -QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) -{ - QPixmap pm; - QPixmapIconEngineEntry *pe = bestMatch(size, mode, state, false); - if (pe) - pm = pe->pixmap; - - if (pm.isNull()) { - int idx = pixmaps.count(); - while (--idx >= 0) { - if (pe == &pixmaps[idx]) { - pixmaps.remove(idx); - break; - } - } - if (pixmaps.isEmpty()) - return pm; - else - return pixmap(size, mode, state); - } - - QSize actualSize = pm.size(); - if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height())) - actualSize.scale(size, Qt::KeepAspectRatio); - - QString key = QLatin1Literal("qt_") - % HexString<quint64>(pm.cacheKey()) - % HexString<uint>(pe->mode) - % HexString<quint64>(QApplication::palette().cacheKey()) - % HexString<uint>(actualSize.width()) - % HexString<uint>(actualSize.height()); - - if (mode == QIcon::Active) { - if (QPixmapCache::find(key % HexString<uint>(mode), pm)) - return pm; // horray - if (QPixmapCache::find(key % HexString<uint>(QIcon::Normal), pm)) { - QStyleOption opt(0); - opt.palette = QApplication::palette(); - QPixmap active = QApplication::style()->generatedIconPixmap(QIcon::Active, pm, &opt); - if (pm.cacheKey() == active.cacheKey()) - return pm; - } - } - - if (!QPixmapCache::find(key % HexString<uint>(mode), pm)) { - if (pm.size() != actualSize) - pm = pm.scaled(actualSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - if (pe->mode != mode && mode != QIcon::Normal) { - QStyleOption opt(0); - opt.palette = QApplication::palette(); - QPixmap generated = QApplication::style()->generatedIconPixmap(mode, pm, &opt); - if (!generated.isNull()) - pm = generated; - } - QPixmapCache::insert(key % HexString<uint>(mode), pm); - } - return pm; -} - -QSize QPixmapIconEngine::actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) -{ - QSize actualSize; - if (QPixmapIconEngineEntry *pe = bestMatch(size, mode, state, true)) - actualSize = pe->size; - - if (actualSize.isNull()) - return actualSize; - - if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height())) - actualSize.scale(size, Qt::KeepAspectRatio); - return actualSize; -} - -void QPixmapIconEngine::addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state) -{ - if (!pixmap.isNull()) { - QPixmapIconEngineEntry *pe = tryMatch(pixmap.size(), mode, state); - if(pe && pe->size == pixmap.size()) { - pe->pixmap = pixmap; - pe->fileName.clear(); - } else { - pixmaps += QPixmapIconEngineEntry(pixmap, mode, state); - } - } -} - -void QPixmapIconEngine::addFile(const QString &fileName, const QSize &_size, QIcon::Mode mode, QIcon::State state) -{ - if (!fileName.isEmpty()) { - QSize size = _size; - QPixmap pixmap; - - QString abs = fileName; - if (fileName.at(0) != QLatin1Char(':')) - abs = QFileInfo(fileName).absoluteFilePath(); - - for (int i = 0; i < pixmaps.count(); ++i) { - if (pixmaps.at(i).mode == mode && pixmaps.at(i).state == state) { - QPixmapIconEngineEntry *pe = &pixmaps[i]; - if(size == QSize()) { - pixmap = QPixmap(abs); - size = pixmap.size(); - } - if (pe->size == QSize() && pe->pixmap.isNull()) { - pe->pixmap = QPixmap(pe->fileName); - pe->size = pe->pixmap.size(); - } - if(pe->size == size) { - pe->pixmap = pixmap; - pe->fileName = abs; - return; - } - } - } - QPixmapIconEngineEntry e(abs, size, mode, state); - e.pixmap = pixmap; - pixmaps += e; - } -} - -QString QPixmapIconEngine::key() const -{ - return QLatin1String("QPixmapIconEngine"); -} - -QIconEngineV2 *QPixmapIconEngine::clone() const -{ - return new QPixmapIconEngine(*this); -} - -bool QPixmapIconEngine::read(QDataStream &in) -{ - int num_entries; - QPixmap pm; - QString fileName; - QSize sz; - uint mode; - uint state; - - in >> num_entries; - for (int i=0; i < num_entries; ++i) { - if (in.atEnd()) { - pixmaps.clear(); - return false; - } - in >> pm; - in >> fileName; - in >> sz; - in >> mode; - in >> state; - if (pm.isNull()) { - addFile(fileName, sz, QIcon::Mode(mode), QIcon::State(state)); - } else { - QPixmapIconEngineEntry pe(fileName, sz, QIcon::Mode(mode), QIcon::State(state)); - pe.pixmap = pm; - pixmaps += pe; - } - } - return true; -} - -bool QPixmapIconEngine::write(QDataStream &out) const -{ - int num_entries = pixmaps.size(); - out << num_entries; - for (int i=0; i < num_entries; ++i) { - if (pixmaps.at(i).pixmap.isNull()) - out << QPixmap(pixmaps.at(i).fileName); - else - out << pixmaps.at(i).pixmap; - out << pixmaps.at(i).fileName; - out << pixmaps.at(i).size; - out << (uint) pixmaps.at(i).mode; - out << (uint) pixmaps.at(i).state; - } - return true; -} - -void QPixmapIconEngine::virtual_hook(int id, void *data) -{ - switch (id) { - case QIconEngineV2::AvailableSizesHook: { - QIconEngineV2::AvailableSizesArgument &arg = - *reinterpret_cast<QIconEngineV2::AvailableSizesArgument*>(data); - arg.sizes.clear(); - for (int i = 0; i < pixmaps.size(); ++i) { - QPixmapIconEngineEntry &pe = pixmaps[i]; - if (pe.size == QSize() && pe.pixmap.isNull()) { - pe.pixmap = QPixmap(pe.fileName); - pe.size = pe.pixmap.size(); - } - if (pe.mode == arg.mode && pe.state == arg.state && !pe.size.isEmpty()) - arg.sizes.push_back(pe.size); - } - break; - } - default: - QIconEngineV2::virtual_hook(id, data); - } -} - -#ifndef QT_NO_LIBRARY -Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, - (QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive)) -Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loaderV2, - (QIconEngineFactoryInterfaceV2_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive)) -#endif - - - -/*! - \class QIcon - - \brief The QIcon class provides scalable icons in different modes - and states. - - \ingroup painting - \ingroup shared - - - A QIcon can generate smaller, larger, active, and disabled pixmaps - from the set of pixmaps it is given. Such pixmaps are used by Qt - widgets to show an icon representing a particular action. - - The simplest use of QIcon is to create one from a QPixmap file or - resource, and then use it, allowing Qt to work out all the required - icon styles and sizes. For example: - - \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 0 - - To undo a QIcon, simply set a null icon in its place: - - \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 1 - - Use the QImageReader::supportedImageFormats() and - QImageWriter::supportedImageFormats() functions to retrieve a - complete list of the supported file formats. - - When you retrieve a pixmap using pixmap(QSize, Mode, State), and no - pixmap for this given size, mode and state has been added with - addFile() or addPixmap(), then QIcon will generate one on the - fly. This pixmap generation happens in a QIconEngineV2. The default - engine scales pixmaps down if required, but never up, and it uses - the current style to calculate a disabled appearance. By using - custom icon engines, you can customize every aspect of generated - icons. With QIconEnginePluginV2 it is possible to register different - icon engines for different file suffixes, making it possible for - third parties to provide additional icon engines to those included - with Qt. - - \note Since Qt 4.2, an icon engine that supports SVG is included. - - \section1 Making Classes that Use QIcon - - If you write your own widgets that have an option to set a small - pixmap, consider allowing a QIcon to be set for that pixmap. The - Qt class QToolButton is an example of such a widget. - - Provide a method to set a QIcon, and when you draw the icon, choose - whichever pixmap is appropriate for the current state of your widget. - For example: - \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 2 - - You might also make use of the \c Active mode, perhaps making your - widget \c Active when the mouse is over the widget (see \l - QWidget::enterEvent()), while the mouse is pressed pending the - release that will activate the function, or when it is the currently - selected item. If the widget can be toggled, the "On" mode might be - used to draw a different icon. - - \img icon.png QIcon - - \sa {fowler}{GUI Design Handbook: Iconic Label}, {Icons Example} -*/ - - -/*! - Constructs a null icon. -*/ -QIcon::QIcon() - : d(0) -{ -} - -/*! - Constructs an icon from a \a pixmap. - */ -QIcon::QIcon(const QPixmap &pixmap) - :d(0) -{ - addPixmap(pixmap); -} - -/*! - Constructs a copy of \a other. This is very fast. -*/ -QIcon::QIcon(const QIcon &other) - :d(other.d) -{} - -/*! - Constructs an icon from the file with the given \a fileName. The - file will be loaded on demand. - - If \a fileName contains a relative path (e.g. the filename only) - the relevant file must be found relative to the runtime working - directory. - - The file name can be either refer to an actual file on disk or to - one of the application's embedded resources. See the - \l{resources.html}{Resource System} overview for details on how to - embed images and other resource files in the application's - executable. - - Use the QImageReader::supportedImageFormats() and - QImageWriter::supportedImageFormats() functions to retrieve a - complete list of the supported file formats. -*/ -QIcon::QIcon(const QString &fileName) - : d(0) -{ - addFile(fileName); -} - - -/*! - Creates an icon with a specific icon \a engine. The icon takes - ownership of the engine. -*/ -QIcon::QIcon(QIconEngine *engine) - :d(new QIconPrivate) -{ - d->engine_version = 1; - d->engine = engine; - d->v1RefCount = new QAtomicInt(1); -} - -/*! - Creates an icon with a specific icon \a engine. The icon takes - ownership of the engine. -*/ -QIcon::QIcon(QIconEngineV2 *engine) - :d(new QIconPrivate) -{ - d->engine_version = 2; - d->engine = engine; -} - -/*! - Destroys the icon. -*/ -QIcon::~QIcon() -{} - -/*! - Assigns the \a other icon to this icon and returns a reference to - this icon. -*/ -QIcon &QIcon::operator=(const QIcon &other) -{ - d = other.d; - return *this; -} - -/*! - \fn void QIcon::swap(QIcon &other) - \since 4.8 - - Swaps icon \a other with this icon. This operation is very - fast and never fails. -*/ - -/*! - Returns the icon as a QVariant. -*/ -QIcon::operator QVariant() const -{ - return QVariant(QVariant::Icon, this); -} - -/*! \obsolete - - Returns a number that identifies the contents of this - QIcon object. Distinct QIcon objects can have - the same serial number if they refer to the same contents - (but they don't have to). Also, the serial number of - a QIcon object may change during its lifetime. - - Use cacheKey() instead. - - A null icon always has a serial number of 0. - - Serial numbers are mostly useful in conjunction with caching. - - \sa QPixmap::serialNumber() -*/ - -int QIcon::serialNumber() const -{ - return d ? d->serialNum : 0; -} - -/*! - Returns a number that identifies the contents of this QIcon - object. Distinct QIcon objects can have the same key if - they refer to the same contents. - \since 4.3 - - The cacheKey() will change when the icon is altered via - addPixmap() or addFile(). - - Cache keys are mostly useful in conjunction with caching. - - \sa QPixmap::cacheKey() -*/ -qint64 QIcon::cacheKey() const -{ - if (!d) - return 0; - return (((qint64) d->serialNum) << 32) | ((qint64) (d->detach_no)); -} - -/*! - Returns a pixmap with the requested \a size, \a mode, and \a - state, generating one if necessary. The pixmap might be smaller than - requested, but never larger. - - \sa actualSize(), paint() -*/ -QPixmap QIcon::pixmap(const QSize &size, Mode mode, State state) const -{ - if (!d) - return QPixmap(); - return d->engine->pixmap(size, mode, state); -} - -/*! - \fn QPixmap QIcon::pixmap(int w, int h, Mode mode = Normal, State state = Off) const - - \overload - - Returns a pixmap of size QSize(\a w, \a h). The pixmap might be smaller than - requested, but never larger. -*/ - -/*! - \fn QPixmap QIcon::pixmap(int extent, Mode mode = Normal, State state = Off) const - - \overload - - Returns a pixmap of size QSize(\a extent, \a extent). The pixmap might be smaller - than requested, but never larger. -*/ - -/*! Returns the actual size of the icon for the requested \a size, \a - mode, and \a state. The result might be smaller than requested, but - never larger. - - \sa pixmap(), paint() -*/ -QSize QIcon::actualSize(const QSize &size, Mode mode, State state) const -{ - if (!d) - return QSize(); - return d->engine->actualSize(size, mode, state); -} - - -/*! - Uses the \a painter to paint the icon with specified \a alignment, - required \a mode, and \a state into the rectangle \a rect. - - \sa actualSize(), pixmap() -*/ -void QIcon::paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment, Mode mode, State state) const -{ - if (!d || !painter) - return; - QRect alignedRect = QStyle::alignedRect(painter->layoutDirection(), alignment, d->engine->actualSize(rect.size(), mode, state), rect); - d->engine->paint(painter, alignedRect, mode, state); -} - -/*! - \fn void QIcon::paint(QPainter *painter, int x, int y, int w, int h, Qt::Alignment alignment, - Mode mode, State state) const - - \overload - - Paints the icon into the rectangle QRect(\a x, \a y, \a w, \a h). -*/ - -/*! - Returns true if the icon is empty; otherwise returns false. - - An icon is empty if it has neither a pixmap nor a filename. - - Note: Even a non-null icon might not be able to create valid - pixmaps, eg. if the file does not exist or cannot be read. -*/ -bool QIcon::isNull() const -{ - return !d; -} - -/*!\internal - */ -bool QIcon::isDetached() const -{ - return !d || d->ref == 1; -} - -/*! \internal - */ -void QIcon::detach() -{ - if (d) { - if (d->ref != 1) { - QIconPrivate *x = new QIconPrivate; - if (d->engine_version > 1) { - QIconEngineV2 *engine = static_cast<QIconEngineV2 *>(d->engine); - x->engine = engine->clone(); - } else { - x->engine = d->engine; - x->v1RefCount = d->v1RefCount; - x->v1RefCount->ref(); - } - x->engine_version = d->engine_version; - d = x; - } - ++d->detach_no; - } -} - -/*! - Adds \a pixmap to the icon, as a specialization for \a mode and - \a state. - - Custom icon engines are free to ignore additionally added - pixmaps. - - \sa addFile() -*/ -void QIcon::addPixmap(const QPixmap &pixmap, Mode mode, State state) -{ - if (pixmap.isNull()) - return; - if (!d) { - d = new QIconPrivate; - d->engine = new QPixmapIconEngine; - } else { - detach(); - } - d->engine->addPixmap(pixmap, mode, state); -} - - -/*! Adds an image from the file with the given \a fileName to the - icon, as a specialization for \a size, \a mode and \a state. The - file will be loaded on demand. Note: custom icon engines are free - to ignore additionally added pixmaps. - - If \a fileName contains a relative path (e.g. the filename only) - the relevant file must be found relative to the runtime working - directory. - - The file name can be either refer to an actual file on disk or to - one of the application's embedded resources. See the - \l{resources.html}{Resource System} overview for details on how to - embed images and other resource files in the application's - executable. - - Use the QImageReader::supportedImageFormats() and - QImageWriter::supportedImageFormats() functions to retrieve a - complete list of the supported file formats. - - Note: When you add a non-empty filename to a QIcon, the icon becomes - non-null, even if the file doesn't exist or points to a corrupt file. - - \sa addPixmap() - */ -void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State state) -{ - if (fileName.isEmpty()) - return; - if (!d) { -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) - QFileInfo info(fileName); - QString suffix = info.suffix(); - if (!suffix.isEmpty()) { - // first try version 2 engines.. - if (QIconEngineFactoryInterfaceV2 *factory = qobject_cast<QIconEngineFactoryInterfaceV2*>(loaderV2()->instance(suffix))) { - if (QIconEngine *engine = factory->create(fileName)) { - d = new QIconPrivate; - d->engine = engine; - } - } - // ..then fall back and try to load version 1 engines - if (!d) { - if (QIconEngineFactoryInterface *factory = qobject_cast<QIconEngineFactoryInterface*>(loader()->instance(suffix))) { - if (QIconEngine *engine = factory->create(fileName)) { - d = new QIconPrivate; - d->engine = engine; - d->engine_version = 1; - d->v1RefCount = new QAtomicInt(1); - } - } - } - } -#endif - // ...then fall back to the default engine - if (!d) { - d = new QIconPrivate; - d->engine = new QPixmapIconEngine; - } - } else { - detach(); - } - d->engine->addFile(fileName, size, mode, state); -} - -/*! - \since 4.5 - - Returns a list of available icon sizes for the specified \a mode and - \a state. -*/ -QList<QSize> QIcon::availableSizes(Mode mode, State state) const -{ - if (!d || !d->engine || d->engine_version < 2) - return QList<QSize>(); - QIconEngineV2 *engine = static_cast<QIconEngineV2*>(d->engine); - return engine->availableSizes(mode, state); -} - -/*! - \since 4.7 - - Returns the name used to create the icon, if available. - - Depending on the way the icon was created, it may have an associated - name. This is the case for icons created with fromTheme() or icons - using a QIconEngine which supports the QIconEngineV2::IconNameHook. - - \sa fromTheme(), QIconEngine -*/ -QString QIcon::name() const -{ - if (!d || !d->engine || d->engine_version < 2) - return QString(); - QIconEngineV2 *engine = static_cast<QIconEngineV2*>(d->engine); - return engine->iconName(); -} - -/*! - \since 4.6 - - Sets the search paths for icon themes to \a paths. - \sa themeSearchPaths(), fromTheme(), setThemeName() -*/ -void QIcon::setThemeSearchPaths(const QStringList &paths) -{ - QIconLoader::instance()->setThemeSearchPath(paths); -} - -/*! - \since 4.6 - - Returns the search paths for icon themes. - - The default value will depend on the platform: - - On X11, the search path will use the XDG_DATA_DIRS environment - variable if available. - - By default all platforms will have the resource directory - \c{:\icons} as a fallback. You can use "rcc -project" to generate a - resource file from your icon theme. - - \sa setThemeSearchPaths(), fromTheme(), setThemeName() -*/ -QStringList QIcon::themeSearchPaths() -{ - return QIconLoader::instance()->themeSearchPaths(); -} - -/*! - \since 4.6 - - Sets the current icon theme to \a name. - - The \a name should correspond to a directory name in the - themeSearchPath() containing an index.theme - file describing it's contents. - - \sa themeSearchPaths(), themeName() -*/ -void QIcon::setThemeName(const QString &name) -{ - QIconLoader::instance()->setThemeName(name); -} - -/*! - \since 4.6 - - Returns the name of the current icon theme. - - On X11, the current icon theme depends on your desktop - settings. On other platforms it is not set by default. - - \sa setThemeName(), themeSearchPaths(), fromTheme(), - hasThemeIcon() -*/ -QString QIcon::themeName() -{ - return QIconLoader::instance()->themeName(); -} - -/*! - \since 4.6 - - Returns the QIcon corresponding to \a name in the current - icon theme. If no such icon is found in the current theme - \a fallback is returned instead. - - The latest version of the freedesktop icon specification and naming - specification can be obtained here: - - \list - \o \l{http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html} - \o \l{http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html} - \endlist - - To fetch an icon from the current icon theme: - - \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 3 - - Or if you want to provide a guaranteed fallback for platforms that - do not support theme icons, you can use the second argument: - - \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 4 - - \note By default, only X11 will support themed icons. In order to - use themed icons on Mac and Windows, you will have to bundle a - compliant theme in one of your themeSearchPaths() and set the - appropriate themeName(). - - \sa themeName(), setThemeName(), themeSearchPaths() -*/ -QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback) -{ - QIcon icon; - - if (qtIconCache()->contains(name)) { - icon = *qtIconCache()->object(name); - } else { - QIcon *cachedIcon = new QIcon(new QIconLoaderEngine(name)); - qtIconCache()->insert(name, cachedIcon); - icon = *cachedIcon; - } - - // Note the qapp check is to allow lazy loading of static icons - // Supporting fallbacks will not work for this case. - if (qApp && icon.availableSizes().isEmpty()) - return fallback; - - return icon; -} - -/*! - \since 4.6 - - Returns true if there is an icon available for \a name in the - current icon theme, otherwise returns false. - - \sa themeSearchPaths(), fromTheme(), setThemeName() -*/ -bool QIcon::hasThemeIcon(const QString &name) -{ - QIcon icon = fromTheme(name); - - return !icon.isNull(); -} - - -/***************************************************************************** - QIcon stream functions - *****************************************************************************/ -#if !defined(QT_NO_DATASTREAM) -/*! - \fn QDataStream &operator<<(QDataStream &stream, const QIcon &icon) - \relates QIcon - \since 4.2 - - Writes the given \a icon to the given \a stream as a PNG - image. If the icon contains more than one image, all images will - be written to the stream. Note that writing the stream to a file - will not produce a valid image file. -*/ - -QDataStream &operator<<(QDataStream &s, const QIcon &icon) -{ - if (s.version() >= QDataStream::Qt_4_3) { - if (icon.isNull()) { - s << QString(); - } else { - if (icon.d->engine_version > 1) { - QIconEngineV2 *engine = static_cast<QIconEngineV2 *>(icon.d->engine); - s << engine->key(); - engine->write(s); - } else { - // not really supported - qWarning("QIcon: Cannot stream QIconEngine. Use QIconEngineV2 instead."); - } - } - } else if (s.version() == QDataStream::Qt_4_2) { - if (icon.isNull()) { - s << 0; - } else { - QPixmapIconEngine *engine = static_cast<QPixmapIconEngine *>(icon.d->engine); - int num_entries = engine->pixmaps.size(); - s << num_entries; - for (int i=0; i < num_entries; ++i) { - s << engine->pixmaps.at(i).pixmap; - s << engine->pixmaps.at(i).fileName; - s << engine->pixmaps.at(i).size; - s << (uint) engine->pixmaps.at(i).mode; - s << (uint) engine->pixmaps.at(i).state; - } - } - } else { - s << QPixmap(icon.pixmap(22,22)); - } - return s; -} - -/*! - \fn QDataStream &operator>>(QDataStream &stream, QIcon &icon) - \relates QIcon - \since 4.2 - - Reads an image, or a set of images, from the given \a stream into - the given \a icon. -*/ - -QDataStream &operator>>(QDataStream &s, QIcon &icon) -{ - if (s.version() >= QDataStream::Qt_4_3) { - icon = QIcon(); - QString key; - s >> key; - if (key == QLatin1String("QPixmapIconEngine")) { - icon.d = new QIconPrivate; - QIconEngineV2 *engine = new QPixmapIconEngine; - icon.d->engine = engine; - engine->read(s); - } else if (key == QLatin1String("QIconLoaderEngine")) { - icon.d = new QIconPrivate; - QIconEngineV2 *engine = new QIconLoaderEngine(); - icon.d->engine = engine; - engine->read(s); -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) - } else if (QIconEngineFactoryInterfaceV2 *factory = qobject_cast<QIconEngineFactoryInterfaceV2*>(loaderV2()->instance(key))) { - if (QIconEngineV2 *engine= factory->create()) { - icon.d = new QIconPrivate; - icon.d->engine = engine; - engine->read(s); - } -#endif - } - } else if (s.version() == QDataStream::Qt_4_2) { - icon = QIcon(); - int num_entries; - QPixmap pm; - QString fileName; - QSize sz; - uint mode; - uint state; - - s >> num_entries; - for (int i=0; i < num_entries; ++i) { - s >> pm; - s >> fileName; - s >> sz; - s >> mode; - s >> state; - if (pm.isNull()) - icon.addFile(fileName, sz, QIcon::Mode(mode), QIcon::State(state)); - else - icon.addPixmap(pm, QIcon::Mode(mode), QIcon::State(state)); - } - } else { - QPixmap pm; - s >> pm; - icon.addPixmap(pm); - } - return s; -} - -#endif //QT_NO_DATASTREAM - - -#ifdef QT3_SUPPORT - -static int widths[2] = { 22, 32 }; -static int heights[2] = { 22, 32 }; - -static QSize pixmapSizeHelper(QIcon::Size which) -{ - int i = 0; - if (which == QIcon::Large) - i = 1; - return QSize(widths[i], heights[i]); -} - -/*! - \enum QIcon::Size - \compat - - \value Small Use QStyle::pixelMetric(QStyle::PM_SmallIconSize) instead. - \value Large Use QStyle::pixelMetric(QStyle::PM_LargeIconSize) instead. - \value Automatic N/A. -*/ - -/*! - Use pixmap(QSize(...), \a mode, \a state), where the first - argument is an appropriate QSize instead of a \l Size value. - - \sa pixmapSize() -*/ -QPixmap QIcon::pixmap(Size size, Mode mode, State state) const -{ return pixmap(pixmapSizeHelper(size), mode, state); } - -/*! - Use pixmap(QSize(...), mode, \a state), where the first argument - is an appropriate QSize instead of a \l Size value, and the - second argument is QIcon::Normal or QIcon::Disabled, depending on - the value of \a enabled. - - \sa pixmapSize() -*/ -QPixmap QIcon::pixmap(Size size, bool enabled, State state) const -{ return pixmap(pixmapSizeHelper(size), enabled ? Normal : Disabled, state); } - -/*! - Use one of the other pixmap() overloads. -*/ -QPixmap QIcon::pixmap() const -{ return pixmap(pixmapSizeHelper(Small), Normal, Off); } - -/*! - The pixmap() function now takes a QSize instead of a QIcon::Size, - so there is no need for this function in new code. -*/ -void QIcon::setPixmapSize(Size which, const QSize &size) -{ - int i = 0; - if (which == Large) - i = 1; - widths[i] = size.width(); - heights[i] = size.height(); -} - -/*! - Use QStyle::pixelMetric() with QStyle::PM_SmallIconSize or - QStyle::PM_LargeIconSize as the first argument, depending on \a - which. -*/ -QSize QIcon::pixmapSize(Size which) -{ - return pixmapSizeHelper(which); -} - -/*! - \fn void QIcon::reset(const QPixmap &pixmap, Size size) - - Use the constructor that takes a QPixmap and operator=(). -*/ - -/*! - \fn void QIcon::setPixmap(const QPixmap &pixmap, Size size, Mode mode, State state) - - Use addPixmap(\a pixmap, \a mode, \a state) instead. The \a size - parameter is ignored. -*/ - -/*! - \fn void QIcon::setPixmap(const QString &fileName, Size size, Mode mode, State state) - - Use addFile(\a fileName, \a mode, \a state) instead. The \a size - parameter is ignored. -*/ - -#endif // QT3_SUPPORT - -/*! - \fn DataPtr &QIcon::data_ptr() - \internal -*/ - -/*! - \typedef QIcon::DataPtr - \internal -*/ - -QT_END_NAMESPACE -#endif //QT_NO_ICON diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h deleted file mode 100644 index eb14384f78..0000000000 --- a/src/gui/image/qicon.h +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QICON_H -#define QICON_H - -#include <QtCore/qglobal.h> -#include <QtCore/qsize.h> -#include <QtCore/qlist.h> -#include <QtGui/qpixmap.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QIconPrivate; -class QIconEngine; -class QIconEngineV2; - -class Q_GUI_EXPORT QIcon -{ -public: - enum Mode { Normal, Disabled, Active, Selected }; - enum State { On, Off }; - - QIcon(); - QIcon(const QPixmap &pixmap); - QIcon(const QIcon &other); - explicit QIcon(const QString &fileName); // file or resource name - explicit QIcon(QIconEngine *engine); - explicit QIcon(QIconEngineV2 *engine); - ~QIcon(); - QIcon &operator=(const QIcon &other); -#ifdef Q_COMPILER_RVALUE_REFS - inline QIcon &operator=(QIcon &&other) - { qSwap(d, other.d); return *this; } -#endif - inline void swap(QIcon &other) { qSwap(d, other.d); } - - operator QVariant() const; - - QPixmap pixmap(const QSize &size, Mode mode = Normal, State state = Off) const; - inline QPixmap pixmap(int w, int h, Mode mode = Normal, State state = Off) const - { return pixmap(QSize(w, h), mode, state); } - inline QPixmap pixmap(int extent, Mode mode = Normal, State state = Off) const - { return pixmap(QSize(extent, extent), mode, state); } - - QSize actualSize(const QSize &size, Mode mode = Normal, State state = Off) const; - - QString name() const; - - void paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment = Qt::AlignCenter, Mode mode = Normal, State state = Off) const; - inline void paint(QPainter *painter, int x, int y, int w, int h, Qt::Alignment alignment = Qt::AlignCenter, Mode mode = Normal, State state = Off) const - { paint(painter, QRect(x, y, w, h), alignment, mode, state); } - - bool isNull() const; - bool isDetached() const; - void detach(); - - int serialNumber() const; - qint64 cacheKey() const; - - void addPixmap(const QPixmap &pixmap, Mode mode = Normal, State state = Off); - void addFile(const QString &fileName, const QSize &size = QSize(), Mode mode = Normal, State state = Off); - - QList<QSize> availableSizes(Mode mode = Normal, State state = Off) const; - - static QIcon fromTheme(const QString &name, const QIcon &fallback = QIcon()); - static bool hasThemeIcon(const QString &name); - - static QStringList themeSearchPaths(); - static void setThemeSearchPaths(const QStringList &searchpath); - - static QString themeName(); - static void setThemeName(const QString &path); - - -#ifdef QT3_SUPPORT - enum Size { Small, Large, Automatic = Small }; - static QT3_SUPPORT void setPixmapSize(Size which, const QSize &size); - static QT3_SUPPORT QSize pixmapSize(Size which); - inline QT3_SUPPORT void reset(const QPixmap &pixmap, Size /*size*/) { *this = QIcon(pixmap); } - inline QT3_SUPPORT void setPixmap(const QPixmap &pixmap, Size, Mode mode = Normal, State state = Off) - { addPixmap(pixmap, mode, state); } - inline QT3_SUPPORT void setPixmap(const QString &fileName, Size, Mode mode = Normal, State state = Off) - { addPixmap(QPixmap(fileName), mode, state); } - QT3_SUPPORT QPixmap pixmap(Size size, Mode mode, State state = Off) const; - QT3_SUPPORT QPixmap pixmap(Size size, bool enabled, State state = Off) const; - QT3_SUPPORT QPixmap pixmap() const; -#endif - - Q_DUMMY_COMPARISON_OPERATOR(QIcon) - -private: - QExplicitlySharedDataPointer<QIconPrivate> d; -#if !defined(QT_NO_DATASTREAM) - friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QIcon &); - friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QIcon &); -#endif - -public: - typedef QExplicitlySharedDataPointer<QIconPrivate> DataPtr; - inline DataPtr &data_ptr() { return d; } -}; - -Q_DECLARE_SHARED(QIcon) -Q_DECLARE_TYPEINFO(QIcon, Q_MOVABLE_TYPE); - -#if !defined(QT_NO_DATASTREAM) -Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QIcon &); -Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QIcon &); -#endif - -#ifdef QT3_SUPPORT -typedef QIcon QIconSet; -#endif - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QICON_H diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h deleted file mode 100644 index c5b4bb0ba7..0000000000 --- a/src/gui/image/qicon_p.h +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QICON_P_H -#define QICON_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <QtCore/qsize.h> -#include <QtCore/qlist.h> -#include <QtGui/qpixmap.h> -#include <QtGui/qicon.h> -#include <QtGui/qiconengine.h> - -#ifndef QT_NO_ICON -QT_BEGIN_NAMESPACE - -class QIconPrivate : public QSharedData -{ -public: - QIconPrivate(); - - ~QIconPrivate() { - if (engine_version == 1) { - if (!v1RefCount->deref()) { - delete engine; - delete v1RefCount; - } - } else if (engine_version == 2) { - delete engine; - } - } - - QIconEngine *engine; - - int serialNum; - int detach_no; - int engine_version; - - QAtomicInt *v1RefCount; -}; - - -struct QPixmapIconEngineEntry -{ - QPixmapIconEngineEntry():mode(QIcon::Normal), state(QIcon::Off){} - QPixmapIconEngineEntry(const QPixmap &pm, QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off) - :pixmap(pm), size(pm.size()), mode(m), state(s){} - QPixmapIconEngineEntry(const QString &file, const QSize &sz = QSize(), QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off) - :fileName(file), size(sz), mode(m), state(s){} - QPixmap pixmap; - QString fileName; - QSize size; - QIcon::Mode mode; - QIcon::State state; - bool isNull() const {return (fileName.isEmpty() && pixmap.isNull()); } -}; - - - -class QPixmapIconEngine : public QIconEngineV2 { -public: - QPixmapIconEngine(); - QPixmapIconEngine(const QPixmapIconEngine &); - ~QPixmapIconEngine(); - void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state); - QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); - QPixmapIconEngineEntry *bestMatch(const QSize &size, QIcon::Mode mode, QIcon::State state, bool sizeOnly); - QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state); - void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state); - void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state); - - // v2 functions - QString key() const; - QIconEngineV2 *clone() const; - bool read(QDataStream &in); - bool write(QDataStream &out) const; - void virtual_hook(int id, void *data); - -private: - QPixmapIconEngineEntry *tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state); - QVector<QPixmapIconEngineEntry> pixmaps; - - friend QDataStream &operator<<(QDataStream &s, const QIcon &icon); - friend class QIconThemeEngine; -}; - -QT_END_NAMESPACE -#endif //QT_NO_ICON -#endif // QICON_P_H diff --git a/src/gui/image/qiconengine.cpp b/src/gui/image/qiconengine.cpp deleted file mode 100644 index 8d71e4055a..0000000000 --- a/src/gui/image/qiconengine.cpp +++ /dev/null @@ -1,324 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qiconengine.h" -#include "qpainter.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QIconEngine - - \brief The QIconEngine class provides an abstract base class for QIcon renderers. - - \ingroup painting - - \bold {Use QIconEngineV2 instead.} - - An icon engine provides the rendering functions for a QIcon. Each icon has a - corresponding icon engine that is responsible for drawing the icon with a - requested size, mode and state. - - The icon is rendered by the paint() function, and the icon can additionally be - obtained as a pixmap with the pixmap() function (the default implementation - simply uses paint() to achieve this). The addPixmap() function can be used to - add new pixmaps to the icon engine, and is used by QIcon to add specialized - custom pixmaps. - - The paint(), pixmap(), and addPixmap() functions are all virtual, and can - therefore be reimplemented in subclasses of QIconEngine. - - \sa QIconEngineV2, QIconEnginePlugin - -*/ - -/*! - \fn virtual void QIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) = 0; - - Uses the given \a painter to paint the icon with the required \a mode and - \a state into the rectangle \a rect. -*/ - -/*! Returns the actual size of the icon the engine provides for the - requested \a size, \a mode and \a state. The default implementation - returns the given \a size. - */ -QSize QIconEngine::actualSize(const QSize &size, QIcon::Mode /*mode*/, QIcon::State /*state*/) -{ - return size; -} - - -/*! - Destroys the icon engine. - */ -QIconEngine::~QIconEngine() -{ -} - - -/*! - Returns the icon as a pixmap with the required \a size, \a mode, - and \a state. The default implementation creates a new pixmap and - calls paint() to fill it. -*/ -QPixmap QIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) -{ - QPixmap pm(size); - { - QPainter p(&pm); - paint(&p, QRect(QPoint(0,0),size), mode, state); - } - return pm; -} - -/*! - Called by QIcon::addPixmap(). Adds a specialized \a pixmap for the given - \a mode and \a state. The default pixmap-based engine stores any supplied - pixmaps, and it uses them instead of scaled pixmaps if the size of a pixmap - matches the size of icon requested. Custom icon engines that implement - scalable vector formats are free to ignores any extra pixmaps. - */ -void QIconEngine::addPixmap(const QPixmap &/*pixmap*/, QIcon::Mode /*mode*/, QIcon::State /*state*/) -{ -} - - -/*! Called by QIcon::addFile(). Adds a specialized pixmap from the - file with the given \a fileName, \a size, \a mode and \a state. The - default pixmap-based engine stores any supplied file names, and it - loads the pixmaps on demand instead of using scaled pixmaps if the - size of a pixmap matches the size of icon requested. Custom icon - engines that implement scalable vector formats are free to ignores - any extra files. - */ -void QIconEngine::addFile(const QString &/*fileName*/, const QSize &/*size*/, QIcon::Mode /*mode*/, QIcon::State /*state*/) -{ -} - - - -// version 2 functions - - -/*! - \class QIconEngineV2 - - \brief The QIconEngineV2 class provides an abstract base class for QIcon renderers. - - \ingroup painting - \since 4.3 - - An icon engine renders \l{QIcon}s. With icon engines, you can - customize icons. Qt provides a default engine that makes icons - adhere to the current style by scaling the icons and providing a - disabled appearance. - - An engine is installed on an icon either through a QIcon - constructor or through a QIconEnginePluginV2. The plugins are used - by Qt if a specific engine is not given when the icon is created. - See the QIconEngineV2 class description to learn how to create - icon engine plugins. - - An icon engine provides the rendering functions for a QIcon. Each - icon has a corresponding icon engine that is responsible for drawing - the icon with a requested size, mode and state. - - QIconEngineV2 extends the API of QIconEngine to allow streaming of - the icon engine contents, and should be used instead of QIconEngine - for implementing new icon engines. - - \sa QIconEnginePluginV2 - -*/ - -/*! - \enum QIconEngineV2::IconEngineHook - \since 4.5 - - These enum values are used for virtual_hook() to allow additional - queries to icon engine without breaking binary compatibility. - - \value AvailableSizesHook Allows to query the sizes of the - contained pixmaps for pixmap-based engines. The \a data argument - of the virtual_hook() function is a AvailableSizesArgument pointer - that should be filled with icon sizes. Engines that work in terms - of a scalable, vectorial format normally return an empty list. - - \value IconNameHook Allows to query the name used to create the - icon, for example when instantiating an icon using - QIcon::fromTheme(). - - \sa virtual_hook() - */ - -/*! - \class QIconEngineV2::AvailableSizesArgument - \since 4.5 - - This struct represents arguments to virtual_hook() function when - \a id parameter is QIconEngineV2::AvailableSizesHook. - - \sa virtual_hook(), QIconEngineV2::IconEngineHook - */ - -/*! - \variable QIconEngineV2::AvailableSizesArgument::mode - \brief the requested mode of an image. - - \sa QIcon::Mode -*/ - -/*! - \variable QIconEngineV2::AvailableSizesArgument::state - \brief the requested state of an image. - - \sa QIcon::State -*/ - -/*! - \variable QIconEngineV2::AvailableSizesArgument::sizes - - \brief image sizes that are available with specified \a mode and - \a state. This is an output parameter and is filled after call to - virtual_hook(). Engines that work in terms of a scalable, - vectorial format normally return an empty list. -*/ - - -/*! - Returns a key that identifies this icon engine. - */ -QString QIconEngineV2::key() const -{ - return QString(); -} - -/*! - Returns a clone of this icon engine. - */ -QIconEngineV2 *QIconEngineV2::clone() const -{ - return 0; -} - -/*! - Reads icon engine contents from the QDataStream \a in. Returns - true if the contents were read; otherwise returns false. - - QIconEngineV2's default implementation always return false. - */ -bool QIconEngineV2::read(QDataStream &) -{ - return false; -} - -/*! - Writes the contents of this engine to the QDataStream \a out. - Returns true if the contents were written; otherwise returns false. - - QIconEngineV2's default implementation always return false. - */ -bool QIconEngineV2::write(QDataStream &) const -{ - return false; -} - -/*! - \since 4.5 - - Additional method to allow extending QIconEngineV2 without - adding new virtual methods (and without breaking binary compatibility). - The actual action and format of \a data depends on \a id argument - which is in fact a constant from IconEngineHook enum. - - \sa IconEngineHook -*/ -void QIconEngineV2::virtual_hook(int id, void *data) -{ - switch (id) { - case QIconEngineV2::AvailableSizesHook: { - QIconEngineV2::AvailableSizesArgument &arg = - *reinterpret_cast<QIconEngineV2::AvailableSizesArgument*>(data); - arg.sizes.clear(); - break; - } - default: - break; - } -} - -/*! - \since 4.5 - - Returns sizes of all images that are contained in the engine for the - specific \a mode and \a state. - - \note This is a helper method and the actual work is done by - virtual_hook() method, hence this method depends on icon engine support - and may not work with all icon engines. - */ -QList<QSize> QIconEngineV2::availableSizes(QIcon::Mode mode, QIcon::State state) -{ - AvailableSizesArgument arg; - arg.mode = mode; - arg.state = state; - virtual_hook(QIconEngineV2::AvailableSizesHook, reinterpret_cast<void*>(&arg)); - return arg.sizes; -} - -/*! - \since 4.7 - - Returns the name used to create the engine, if available. - - \note This is a helper method and the actual work is done by - virtual_hook() method, hence this method depends on icon engine support - and may not work with all icon engines. - */ -QString QIconEngineV2::iconName() -{ - QString name; - virtual_hook(QIconEngineV2::IconNameHook, reinterpret_cast<void*>(&name)); - return name; -} - -QT_END_NAMESPACE diff --git a/src/gui/image/qiconengine.h b/src/gui/image/qiconengine.h deleted file mode 100644 index bfdce557ff..0000000000 --- a/src/gui/image/qiconengine.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QICONENGINE_H -#define QICONENGINE_H - -#include <QtCore/qglobal.h> -#include <QtCore/qlist.h> -#include <QtGui/qicon.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class Q_GUI_EXPORT QIconEngine -{ -public: - virtual ~QIconEngine(); - virtual void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) = 0; - virtual QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state); - virtual QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); - - virtual void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state); - virtual void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state); - -#if 0 - virtual int frameCount(QIcon::Mode fromMode, QIcon::State fromState, QIcon::Mode toMode, QIcon::State toState); - virtual void paintFrame(QPainter *painter, const QRect &rect, int frameNumber, QIcon::Mode fromMode, QIcon::State fromState, QIcon::Mode toMode, QIcon::State toState); -#endif -}; - -// ### Qt 5: move the below into QIconEngine -class Q_GUI_EXPORT QIconEngineV2 : public QIconEngine -{ -public: - virtual QString key() const; - virtual QIconEngineV2 *clone() const; - virtual bool read(QDataStream &in); - virtual bool write(QDataStream &out) const; - virtual void virtual_hook(int id, void *data); - -public: - enum IconEngineHook { AvailableSizesHook = 1, IconNameHook }; - - struct AvailableSizesArgument - { - QIcon::Mode mode; - QIcon::State state; - QList<QSize> sizes; - }; - - // ### Qt 5: make this function const and virtual. - QList<QSize> availableSizes(QIcon::Mode mode = QIcon::Normal, - QIcon::State state = QIcon::Off); - - // ### Qt 5: make this function const and virtual. - QString iconName(); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QICONENGINE_H diff --git a/src/gui/image/qiconengineplugin.cpp b/src/gui/image/qiconengineplugin.cpp deleted file mode 100644 index e1389ae726..0000000000 --- a/src/gui/image/qiconengineplugin.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qiconengineplugin.h" -#include "qiconengine.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QIconEnginePlugin - \brief The QIconEnginePlugin class provides an abstract base for custom QIconEngine plugins. - - \ingroup plugins - - \bold {Use QIconEnginePluginV2 instead.} - - The icon engine plugin is a simple plugin interface that makes it easy to - create custom icon engines that can be loaded dynamically into applications - through QIcon. QIcon uses the file or resource name's suffix to determine - what icon engine to use. - - Writing a icon engine plugin is achieved by subclassing this base class, - reimplementing the pure virtual functions keys() and create(), and - exporting the class with the Q_EXPORT_PLUGIN2() macro. - - \sa {How to Create Qt Plugins} -*/ - -/*! - \fn QStringList QIconEnginePlugin::keys() const - - Returns a list of icon engine keys that this plugin supports. The keys correspond - to the suffix of the file or resource name used when the plugin was created. - Keys are case insensitive. - - \sa create() -*/ - -/*! - \fn QIconEngine* QIconEnginePlugin::create(const QString& filename) - - Creates and returns a QIconEngine object for the icon with the given - \a filename. - - \sa keys() -*/ - -/*! - Constructs a icon engine plugin with the given \a parent. This is invoked - automatically by the Q_EXPORT_PLUGIN2() macro. -*/ -QIconEnginePlugin::QIconEnginePlugin(QObject *parent) - : QObject(parent) -{ -} - -/*! - Destroys the icon engine plugin. - - You never have to call this explicitly. Qt destroys a plugin - automatically when it is no longer used. -*/ -QIconEnginePlugin::~QIconEnginePlugin() -{ -} - -// version 2 - -/*! - \class QIconEnginePluginV2 - \brief The QIconEnginePluginV2 class provides an abstract base for custom QIconEngineV2 plugins. - - \ingroup plugins - \since 4.3 - - Icon engine plugins produces \l{QIconEngine}s for \l{QIcon}s; an - icon engine is used to render the icon. The keys that identifies - the engines the plugin can create are suffixes of - icon filenames; they are returned by keys(). The create() function - receives the icon filename to return an engine for; it should - return 0 if it cannot produce an engine for the file. - - Writing an icon engine plugin is achieved by inheriting - QIconEnginePluginV2, reimplementing keys() and create(), and - adding the Q_EXPORT_PLUGIN2() macro. - - You should ensure that you do not duplicate keys. Qt will query - the plugins for icon engines in the order in which the plugins are - found during plugin search (see the plugins \l{How to Create Qt - Plugins}{overview document}). - - \sa {How to Create Qt Plugins} -*/ - -/*! - \fn QStringList QIconEnginePluginV2::keys() const - - Returns a list of icon engine keys that this plugin supports. The keys correspond - to the suffix of the file or resource name used when the plugin was created. - Keys are case insensitive. - - \sa create() -*/ - -/*! - \fn QIconEngineV2* QIconEnginePluginV2::create(const QString& filename = QString()) - - Creates and returns a QIconEngine object for the icon with the given - \a filename. - - \sa keys() -*/ - -/*! - Constructs a icon engine plugin with the given \a parent. This is invoked - automatically by the Q_EXPORT_PLUGIN2() macro. -*/ -QIconEnginePluginV2::QIconEnginePluginV2(QObject *parent) - : QObject(parent) -{ -} - -/*! - Destroys the icon engine plugin. - - You never have to call this explicitly. Qt destroys a plugin - automatically when it is no longer used. -*/ -QIconEnginePluginV2::~QIconEnginePluginV2() -{ -} - -QT_END_NAMESPACE diff --git a/src/gui/image/qiconengineplugin.h b/src/gui/image/qiconengineplugin.h deleted file mode 100644 index 8e744b4e9c..0000000000 --- a/src/gui/image/qiconengineplugin.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QICONENGINEPLUGIN_H -#define QICONENGINEPLUGIN_H - -#include <QtCore/qplugin.h> -#include <QtCore/qfactoryinterface.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QIconEngine; -class QIconEngineV2; - -struct Q_GUI_EXPORT QIconEngineFactoryInterface : public QFactoryInterface -{ - virtual QIconEngine *create(const QString &filename) = 0; -}; - -#define QIconEngineFactoryInterface_iid \ - "com.trolltech.Qt.QIconEngineFactoryInterface" -Q_DECLARE_INTERFACE(QIconEngineFactoryInterface, QIconEngineFactoryInterface_iid) - -class Q_GUI_EXPORT QIconEnginePlugin : public QObject, public QIconEngineFactoryInterface -{ - Q_OBJECT - Q_INTERFACES(QIconEngineFactoryInterface:QFactoryInterface) -public: - QIconEnginePlugin(QObject *parent = 0); - ~QIconEnginePlugin(); - - virtual QStringList keys() const = 0; - virtual QIconEngine *create(const QString &filename) = 0; -}; - -// ### Qt 5: remove version 2 -struct Q_GUI_EXPORT QIconEngineFactoryInterfaceV2 : public QFactoryInterface -{ - virtual QIconEngineV2 *create(const QString &filename = QString()) = 0; -}; - -#define QIconEngineFactoryInterfaceV2_iid \ - "com.trolltech.Qt.QIconEngineFactoryInterfaceV2" -Q_DECLARE_INTERFACE(QIconEngineFactoryInterfaceV2, QIconEngineFactoryInterfaceV2_iid) - -class Q_GUI_EXPORT QIconEnginePluginV2 : public QObject, public QIconEngineFactoryInterfaceV2 -{ - Q_OBJECT - Q_INTERFACES(QIconEngineFactoryInterfaceV2:QFactoryInterface) -public: - QIconEnginePluginV2(QObject *parent = 0); - ~QIconEnginePluginV2(); - - virtual QStringList keys() const = 0; - virtual QIconEngineV2 *create(const QString &filename = QString()) = 0; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QICONENGINEPLUGIN_H diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp deleted file mode 100644 index e63043bf09..0000000000 --- a/src/gui/image/qiconloader.cpp +++ /dev/null @@ -1,570 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QT_NO_ICON -#include <private/qiconloader_p.h> - -#include <private/qapplication_p.h> -#include <private/qicon_p.h> -#include <private/qguiplatformplugin_p.h> - -#include <QtGui/QIconEnginePlugin> -#include <QtGui/QPixmapCache> -#include <QtGui/QIconEngine> -#include <QtGui/QStyleOption> -#include <QtCore/QList> -#include <QtCore/QHash> -#include <QtCore/QDir> -#include <QtCore/QSettings> -#include <QtGui/QPainter> - -#ifdef Q_WS_MAC -#include <private/qt_cocoa_helpers_mac_p.h> -#endif - -#ifdef Q_WS_X11 -#include <private/qt_x11_p.h> -#endif - -#include <private/qstylehelper_p.h> - -QT_BEGIN_NAMESPACE - -Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance) - -/* Theme to use in last resort, if the theme does not have the icon, neither the parents */ -static QString fallbackTheme() -{ -#ifdef Q_WS_X11 - if (X11->desktopEnvironment == DE_GNOME) { - return QLatin1String("gnome"); - } else if (X11->desktopEnvironment == DE_KDE) { - return X11->desktopVersion >= 4 - ? QString::fromLatin1("oxygen") - : QString::fromLatin1("crystalsvg"); - } else { - return QLatin1String("hicolor"); - } -#endif - return QString(); -} - -QIconLoader::QIconLoader() : - m_themeKey(1), m_supportsSvg(false), m_initialized(false) -{ -} - -// We lazily initialize the loader to make static icons -// work. Though we do not officially support this. -void QIconLoader::ensureInitialized() -{ - if (!m_initialized) { - m_initialized = true; - - Q_ASSERT(qApp); - - m_systemTheme = qt_guiPlatformPlugin()->systemIconThemeName(); - if (m_systemTheme.isEmpty()) - m_systemTheme = fallbackTheme(); -#ifndef QT_NO_LIBRARY - QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterfaceV2_iid, - QLatin1String("/iconengines"), - Qt::CaseInsensitive); - if (iconFactoryLoader.keys().contains(QLatin1String("svg"))) - m_supportsSvg = true; -#endif //QT_NO_LIBRARY - } -} - -QIconLoader *QIconLoader::instance() -{ - return iconLoaderInstance(); -} - -// Queries the system theme and invalidates existing -// icons if the theme has changed. -void QIconLoader::updateSystemTheme() -{ - // Only change if this is not explicitly set by the user - if (m_userTheme.isEmpty()) { - QString theme = qt_guiPlatformPlugin()->systemIconThemeName(); - if (theme.isEmpty()) - theme = fallbackTheme(); - if (theme != m_systemTheme) { - m_systemTheme = theme; - invalidateKey(); - } - } -} - -void QIconLoader::setThemeName(const QString &themeName) -{ - m_userTheme = themeName; - invalidateKey(); -} - -void QIconLoader::setThemeSearchPath(const QStringList &searchPaths) -{ - m_iconDirs = searchPaths; - themeList.clear(); - invalidateKey(); -} - -QStringList QIconLoader::themeSearchPaths() const -{ - if (m_iconDirs.isEmpty()) { - m_iconDirs = qt_guiPlatformPlugin()->iconThemeSearchPaths(); - // Always add resource directory as search path - m_iconDirs.append(QLatin1String(":/icons")); - } - return m_iconDirs; -} - -QIconTheme::QIconTheme(const QString &themeName) - : m_valid(false) -{ - QFile themeIndex; - - QList <QIconDirInfo> keyList; - QStringList iconDirs = QIcon::themeSearchPaths(); - for ( int i = 0 ; i < iconDirs.size() ; ++i) { - QDir iconDir(iconDirs[i]); - QString themeDir = iconDir.path() + QLatin1Char('/') + themeName; - themeIndex.setFileName(themeDir + QLatin1String("/index.theme")); - if (themeIndex.exists()) { - m_contentDir = themeDir; - m_valid = true; - break; - } - } -#ifndef QT_NO_SETTINGS - if (themeIndex.exists()) { - const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat); - QStringListIterator keyIterator(indexReader.allKeys()); - while (keyIterator.hasNext()) { - - const QString key = keyIterator.next(); - if (key.endsWith(QLatin1String("/Size"))) { - // Note the QSettings ini-format does not accept - // slashes in key names, hence we have to cheat - if (int size = indexReader.value(key).toInt()) { - QString directoryKey = key.left(key.size() - 5); - QIconDirInfo dirInfo(directoryKey); - dirInfo.size = size; - QString type = indexReader.value(directoryKey + - QLatin1String("/Type") - ).toString(); - - if (type == QLatin1String("Fixed")) - dirInfo.type = QIconDirInfo::Fixed; - else if (type == QLatin1String("Scalable")) - dirInfo.type = QIconDirInfo::Scalable; - else - dirInfo.type = QIconDirInfo::Threshold; - - dirInfo.threshold = indexReader.value(directoryKey + - QLatin1String("/Threshold"), - 2).toInt(); - - dirInfo.minSize = indexReader.value(directoryKey + - QLatin1String("/MinSize"), - size).toInt(); - - dirInfo.maxSize = indexReader.value(directoryKey + - QLatin1String("/MaxSize"), - size).toInt(); - m_keyList.append(dirInfo); - } - } - } - - // Parent themes provide fallbacks for missing icons - m_parents = indexReader.value( - QLatin1String("Icon Theme/Inherits")).toStringList(); - - // Ensure a default platform fallback for all themes - if (m_parents.isEmpty()) - m_parents.append(fallbackTheme()); - - // Ensure that all themes fall back to hicolor - if (!m_parents.contains(QLatin1String("hicolor"))) - m_parents.append(QLatin1String("hicolor")); - } -#endif //QT_NO_SETTINGS -} - -QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, - const QString &iconName, - QStringList &visited) const -{ - QThemeIconEntries entries; - Q_ASSERT(!themeName.isEmpty()); - - QPixmap pixmap; - - // Used to protect against potential recursions - visited << themeName; - - QIconTheme theme = themeList.value(themeName); - if (!theme.isValid()) { - theme = QIconTheme(themeName); - if (!theme.isValid()) - theme = QIconTheme(fallbackTheme()); - - themeList.insert(themeName, theme); - } - - QString contentDir = theme.contentDir() + QLatin1Char('/'); - QList<QIconDirInfo> subDirs = theme.keyList(); - - const QString svgext(QLatin1String(".svg")); - const QString pngext(QLatin1String(".png")); - - // Add all relevant files - for (int i = 0; i < subDirs.size() ; ++i) { - const QIconDirInfo &dirInfo = subDirs.at(i); - QString subdir = dirInfo.path; - QDir currentDir(contentDir + subdir); - if (currentDir.exists(iconName + pngext)) { - PixmapEntry *iconEntry = new PixmapEntry; - iconEntry->dir = dirInfo; - iconEntry->filename = currentDir.filePath(iconName + pngext); - // Notice we ensure that pixmap entries always come before - // scalable to preserve search order afterwards - entries.prepend(iconEntry); - } else if (m_supportsSvg && - currentDir.exists(iconName + svgext)) { - ScalableEntry *iconEntry = new ScalableEntry; - iconEntry->dir = dirInfo; - iconEntry->filename = currentDir.filePath(iconName + svgext); - entries.append(iconEntry); - } - } - - if (entries.isEmpty()) { - const QStringList parents = theme.parents(); - // Search recursively through inherited themes - for (int i = 0 ; i < parents.size() ; ++i) { - - const QString parentTheme = parents.at(i).trimmed(); - - if (!visited.contains(parentTheme)) // guard against recursion - entries = findIconHelper(parentTheme, iconName, visited); - - if (!entries.isEmpty()) // success - break; - } - } - return entries; -} - -QThemeIconEntries QIconLoader::loadIcon(const QString &name) const -{ - if (!themeName().isEmpty()) { - QStringList visited; - return findIconHelper(themeName(), name, visited); - } - - return QThemeIconEntries(); -} - - -// -------- Icon Loader Engine -------- // - - -QIconLoaderEngine::QIconLoaderEngine(const QString& iconName) - : m_iconName(iconName), m_key(0) -{ -} - -QIconLoaderEngine::~QIconLoaderEngine() -{ - while (!m_entries.isEmpty()) - delete m_entries.takeLast(); - Q_ASSERT(m_entries.size() == 0); -} - -QIconLoaderEngine::QIconLoaderEngine(const QIconLoaderEngine &other) - : QIconEngineV2(other), - m_iconName(other.m_iconName), - m_key(0) -{ -} - -QIconEngineV2 *QIconLoaderEngine::clone() const -{ - return new QIconLoaderEngine(*this); -} - -bool QIconLoaderEngine::read(QDataStream &in) { - in >> m_iconName; - return true; -} - -bool QIconLoaderEngine::write(QDataStream &out) const -{ - out << m_iconName; - return true; -} - -bool QIconLoaderEngine::hasIcon() const -{ - return !(m_entries.isEmpty()); -} - -// Lazily load the icon -void QIconLoaderEngine::ensureLoaded() -{ - - iconLoaderInstance()->ensureInitialized(); - - if (!(iconLoaderInstance()->themeKey() == m_key)) { - - while (!m_entries.isEmpty()) - delete m_entries.takeLast(); - - Q_ASSERT(m_entries.size() == 0); - m_entries = iconLoaderInstance()->loadIcon(m_iconName); - m_key = iconLoaderInstance()->themeKey(); - } -} - -void QIconLoaderEngine::paint(QPainter *painter, const QRect &rect, - QIcon::Mode mode, QIcon::State state) -{ - QSize pixmapSize = rect.size(); -#if defined(Q_WS_MAC) - pixmapSize *= qt_mac_get_scalefactor(); -#endif - painter->drawPixmap(rect, pixmap(pixmapSize, mode, state)); -} - -/* - * This algorithm is defined by the freedesktop spec: - * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html - */ -static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize) -{ - if (dir.type == QIconDirInfo::Fixed) { - return dir.size == iconsize; - - } else if (dir.type == QIconDirInfo::Scalable) { - return dir.size <= dir.maxSize && - iconsize >= dir.minSize; - - } else if (dir.type == QIconDirInfo::Threshold) { - return iconsize >= dir.size - dir.threshold && - iconsize <= dir.size + dir.threshold; - } - - Q_ASSERT(1); // Not a valid value - return false; -} - -/* - * This algorithm is defined by the freedesktop spec: - * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html - */ -static int directorySizeDistance(const QIconDirInfo &dir, int iconsize) -{ - if (dir.type == QIconDirInfo::Fixed) { - return qAbs(dir.size - iconsize); - - } else if (dir.type == QIconDirInfo::Scalable) { - if (iconsize < dir.minSize) - return dir.minSize - iconsize; - else if (iconsize > dir.maxSize) - return iconsize - dir.maxSize; - else - return 0; - - } else if (dir.type == QIconDirInfo::Threshold) { - if (iconsize < dir.size - dir.threshold) - return dir.minSize - iconsize; - else if (iconsize > dir.size + dir.threshold) - return iconsize - dir.maxSize; - else return 0; - } - - Q_ASSERT(1); // Not a valid value - return INT_MAX; -} - -QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size) -{ - int iconsize = qMin(size.width(), size.height()); - - // Note that m_entries are sorted so that png-files - // come first - - // Search for exact matches first - for (int i = 0; i < m_entries.count(); ++i) { - QIconLoaderEngineEntry *entry = m_entries.at(i); - if (directoryMatchesSize(entry->dir, iconsize)) { - return entry; - } - } - - // Find the minimum distance icon - int minimalSize = INT_MAX; - QIconLoaderEngineEntry *closestMatch = 0; - for (int i = 0; i < m_entries.count(); ++i) { - QIconLoaderEngineEntry *entry = m_entries.at(i); - int distance = directorySizeDistance(entry->dir, iconsize); - if (distance < minimalSize) { - minimalSize = distance; - closestMatch = entry; - } - } - return closestMatch; -} - -/* - * Returns the actual icon size. For scalable svg's this is equivalent - * to the requested size. Otherwise the closest match is returned but - * we can never return a bigger size than the requested size. - * - */ -QSize QIconLoaderEngine::actualSize(const QSize &size, QIcon::Mode mode, - QIcon::State state) -{ - ensureLoaded(); - - QIconLoaderEngineEntry *entry = entryForSize(size); - if (entry) { - const QIconDirInfo &dir = entry->dir; - if (dir.type == QIconDirInfo::Scalable) - return size; - else { - int result = qMin<int>(dir.size, qMin(size.width(), size.height())); - return QSize(result, result); - } - } - return QIconEngineV2::actualSize(size, mode, state); -} - -QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) -{ - Q_UNUSED(state); - - // Ensure that basePixmap is lazily initialized before generating the - // key, otherwise the cache key is not unique - if (basePixmap.isNull()) - basePixmap.load(filename); - - int actualSize = qMin(size.width(), size.height()); - - QString key = QLatin1Literal("$qt_theme_") - % HexString<qint64>(basePixmap.cacheKey()) - % HexString<int>(mode) - % HexString<qint64>(qApp->palette().cacheKey()) - % HexString<int>(actualSize); - - QPixmap cachedPixmap; - if (QPixmapCache::find(key, &cachedPixmap)) { - return cachedPixmap; - } else { - QStyleOption opt(0); - opt.palette = qApp->palette(); - cachedPixmap = qApp->style()->generatedIconPixmap(mode, basePixmap, &opt); - QPixmapCache::insert(key, cachedPixmap); - } - return cachedPixmap; -} - -QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) -{ - if (svgIcon.isNull()) - svgIcon = QIcon(filename); - - // Simply reuse svg icon engine - return svgIcon.pixmap(size, mode, state); -} - -QPixmap QIconLoaderEngine::pixmap(const QSize &size, QIcon::Mode mode, - QIcon::State state) -{ - ensureLoaded(); - - QIconLoaderEngineEntry *entry = entryForSize(size); - if (entry) - return entry->pixmap(size, mode, state); - - return QPixmap(); -} - -QString QIconLoaderEngine::key() const -{ - return QLatin1String("QIconLoaderEngine"); -} - -void QIconLoaderEngine::virtual_hook(int id, void *data) -{ - ensureLoaded(); - - switch (id) { - case QIconEngineV2::AvailableSizesHook: - { - QIconEngineV2::AvailableSizesArgument &arg - = *reinterpret_cast<QIconEngineV2::AvailableSizesArgument*>(data); - const QList<QIconDirInfo> directoryKey = iconLoaderInstance()->theme().keyList(); - arg.sizes.clear(); - - // Gets all sizes from the DirectoryInfo entries - for (int i = 0 ; i < m_entries.size() ; ++i) { - int size = m_entries.at(i)->dir.size; - arg.sizes.append(QSize(size, size)); - } - } - break; - case QIconEngineV2::IconNameHook: - { - QString &name = *reinterpret_cast<QString*>(data); - name = m_iconName; - } - break; - default: - QIconEngineV2::virtual_hook(id, data); - } -} - -QT_END_NAMESPACE - -#endif //QT_NO_ICON diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h deleted file mode 100644 index caa0158628..0000000000 --- a/src/gui/image/qiconloader_p.h +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDESKTOPICON_P_H -#define QDESKTOPICON_P_H - -#ifndef QT_NO_ICON -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtGui/QIcon> -#include <QtGui/QIconEngine> -#include <QtGui/QPixmapCache> -#include <private/qicon_p.h> -#include <private/qfactoryloader_p.h> -#include <QtCore/QHash> - -QT_BEGIN_NAMESPACE - -class QIconLoader; - -struct QIconDirInfo -{ - enum Type { Fixed, Scalable, Threshold }; - QIconDirInfo(const QString &_path = QString()) : - path(_path), - size(0), - maxSize(0), - minSize(0), - threshold(0), - type(Threshold) {} - QString path; - short size; - short maxSize; - short minSize; - short threshold; - Type type : 4; -}; - -class QIconLoaderEngineEntry - { -public: - virtual ~QIconLoaderEngineEntry() {} - virtual QPixmap pixmap(const QSize &size, - QIcon::Mode mode, - QIcon::State state) = 0; - QString filename; - QIconDirInfo dir; - static int count; -}; - -struct ScalableEntry : public QIconLoaderEngineEntry -{ - QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); - QIcon svgIcon; -}; - -struct PixmapEntry : public QIconLoaderEngineEntry -{ - QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); - QPixmap basePixmap; -}; - -typedef QList<QIconLoaderEngineEntry*> QThemeIconEntries; - -class QIconLoaderEngine : public QIconEngineV2 -{ -public: - QIconLoaderEngine(const QString& iconName = QString()); - ~QIconLoaderEngine(); - - void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state); - QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); - QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state); - QIconEngineV2 *clone() const; - bool read(QDataStream &in); - bool write(QDataStream &out) const; - -private: - QString key() const; - bool hasIcon() const; - void ensureLoaded(); - void virtual_hook(int id, void *data); - QIconLoaderEngineEntry *entryForSize(const QSize &size); - QIconLoaderEngine(const QIconLoaderEngine &other); - QThemeIconEntries m_entries; - QString m_iconName; - uint m_key; - - friend class QIconLoader; -}; - -class QIconTheme -{ -public: - QIconTheme(const QString &name); - QIconTheme() : m_valid(false) {} - QStringList parents() { return m_parents; } - QList <QIconDirInfo> keyList() { return m_keyList; } - QString contentDir() { return m_contentDir; } - bool isValid() { return m_valid; } - -private: - QString m_contentDir; - QList <QIconDirInfo> m_keyList; - QStringList m_parents; - bool m_valid; -}; - -class QIconLoader : public QObject -{ -public: - QIconLoader(); - QThemeIconEntries loadIcon(const QString &iconName) const; - uint themeKey() const { return m_themeKey; } - - QString themeName() const { return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme; } - void setThemeName(const QString &themeName); - QIconTheme theme() { return themeList.value(themeName()); } - void setThemeSearchPath(const QStringList &searchPaths); - QStringList themeSearchPaths() const; - QIconDirInfo dirInfo(int dirindex); - static QIconLoader *instance(); - void updateSystemTheme(); - void invalidateKey() { m_themeKey++; } - void ensureInitialized(); - -private: - QThemeIconEntries findIconHelper(const QString &themeName, - const QString &iconName, - QStringList &visited) const; - uint m_themeKey; - bool m_supportsSvg; - bool m_initialized; - - mutable QString m_userTheme; - mutable QString m_systemTheme; - mutable QStringList m_iconDirs; - mutable QHash <QString, QIconTheme> themeList; -}; - -QT_END_NAMESPACE - -#endif // QDESKTOPICON_P_H - -#endif //QT_NO_ICON diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 14322dc929..2dbb2f4b52 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -54,9 +54,9 @@ #include <stdlib.h> #include <limits.h> #include <math.h> +#include <qplatformpixmap_qpa.h> #include <private/qdrawhelper_p.h> #include <private/qmemrotate_p.h> -#include <private/qpixmapdata_p.h> #include <private/qimagescale_p.h> #include <private/qsimd_p.h> @@ -124,9 +124,6 @@ QBasicAtomicInt qimage_serial_number = Q_BASIC_ATOMIC_INITIALIZER(1); QImageData::QImageData() : ref(0), width(0), height(0), depth(0), nbytes(0), data(0), -#ifdef QT3_SUPPORT - jumptable(0), -#endif format(QImage::Format_ARGB32), bytes_per_line(0), ser_no(qimage_serial_number.fetchAndAddRelaxed(1)), detach_no(0), @@ -220,11 +217,6 @@ QImageData::~QImageData() delete paintEngine; if (data && own_data) free(data); -#ifdef QT3_SUPPORT - if (jumptable) - free(jumptable); - jumptable = 0; -#endif data = 0; } @@ -757,27 +749,6 @@ const uchar *qt_get_bitflip_array() // called from QPixma return bitflip; } -#if defined(QT3_SUPPORT) -static QImage::Format formatFor(int depth, QImage::Endian bitOrder) -{ - QImage::Format format; - if (depth == 1) { - format = bitOrder == QImage::BigEndian ? QImage::Format_Mono : QImage::Format_MonoLSB; - } else if (depth == 8) { - format = QImage::Format_Indexed8; - } else if (depth == 32) { - format = QImage::Format_RGB32; - } else if (depth == 24) { - format = QImage::Format_RGB888; - } else if (depth == 16) { - format = QImage::Format_RGB16; - } else { - qWarning("QImage: Depth %d not supported", depth); - format = QImage::Format_Invalid; - } - return format; -} -#endif /*! Constructs a null image. @@ -991,42 +962,6 @@ QImage::QImage(const QString &fileName, const char *format) load(fileName, format); } -/*! - Constructs an image and tries to load the image from the file with - the given \a fileName. - - The loader attempts to read the image using the specified \a - format. If the \a format is not specified (which is the default), - the loader probes the file for a header to guess the file format. - - If the loading of the image failed, this object is a null image. - - The file name can either refer to an actual file on disk or to one - of the application's embedded resources. See the - \l{resources.html}{Resource System} overview for details on how to - embed images and other resource files in the application's - executable. - - You can disable this constructor by defining \c - QT_NO_CAST_FROM_ASCII when you compile your applications. This can - be useful, for example, if you want to ensure that all - user-visible strings go through QObject::tr(). - - \sa QString::fromAscii(), isNull(), {QImage#Reading and Writing - Image Files}{Reading and Writing Image Files} -*/ -#ifndef QT_NO_CAST_FROM_ASCII -QImage::QImage(const char *fileName, const char *format) - : QPaintDevice() -{ - // ### Qt 5: if you remove the QImage(const QByteArray &) QT3_SUPPORT - // constructor, remove this constructor as well. The constructor here - // exists so that QImage("foo.png") compiles without ambiguity. - d = 0; - load(QString::fromAscii(fileName), format); -} -#endif - #ifndef QT_NO_IMAGEFORMAT_XPM extern bool qt_read_xpm_image_or_array(QIODevice *device, const char * const *source, QImage &image); @@ -1097,178 +1032,6 @@ QImage::QImage(const QImage &image) } } -#ifdef QT3_SUPPORT -/*! - \fn QImage::QImage(int width, int height, int depth, int numColors, Endian bitOrder) - - Constructs an image with the given \a width, \a height, \a depth, - \a numColors colors and \a bitOrder. - - Use the constructor that accepts a width, a height and a format - (i.e. specifying the depth and bit order), in combination with the - setColorCount() function, instead. - - \oldcode - QImage image(width, height, depth, numColors); - \newcode - QImage image(width, height, format); - - // For 8 bit images the default number of colors is 256. If - // another number of colors is required it can be specified - // using the setColorCount() function. - image.setColorCount(numColors); - \endcode -*/ - -QImage::QImage(int w, int h, int depth, int colorCount, Endian bitOrder) - : QPaintDevice() -{ - d = QImageData::create(QSize(w, h), formatFor(depth, bitOrder), colorCount); -} - -/*! - Constructs an image with the given \a size, \a depth, \a numColors - and \a bitOrder. - - Use the constructor that accepts a size and a format - (i.e. specifying the depth and bit order), in combination with the - setColorCount() function, instead. - - \oldcode - QSize mySize(width, height); - QImage image(mySize, depth, numColors); - \newcode - QSize mySize(width, height); - QImage image(mySize, format); - - // For 8 bit images the default number of colors is 256. If - // another number of colors is required it can be specified - // using the setColorCount() function. - image.setColorCount(numColors); - \endcode -*/ -QImage::QImage(const QSize& size, int depth, int numColors, Endian bitOrder) - : QPaintDevice() -{ - d = QImageData::create(size, formatFor(depth, bitOrder), numColors); -} - -/*! - \fn QImage::QImage(uchar* data, int width, int height, int depth, const QRgb* colortable, int numColors, Endian bitOrder) - - Constructs an image with the given \a width, \a height, depth, \a - colortable, \a numColors and \a bitOrder, that uses an existing - memory buffer, \a data. - - Use the constructor that accepts a uchar pointer, a width, a - height and a format (i.e. specifying the depth and bit order), in - combination with the setColorTable() function, instead. - - \oldcode - uchar *myData; - QRgb *myColorTable; - - QImage image(myData, width, height, depth, - myColorTable, numColors, IgnoreEndian); - \newcode - uchar *myData; - QVector<QRgb> myColorTable; - - QImage image(myData, width, height, format); - image.setColorTable(myColorTable); - \endcode -*/ -QImage::QImage(uchar* data, int w, int h, int depth, const QRgb* colortable, int numColors, Endian bitOrder) - : QPaintDevice() -{ - d = 0; - Format f = formatFor(depth, bitOrder); - if (f == Format_Invalid) - return; - - const int bytes_per_line = ((w*depth+31)/32)*4; // bytes per scanline - if (w <= 0 || h <= 0 || numColors < 0 || !data - || INT_MAX/sizeof(uchar *) < uint(h) - || INT_MAX/uint(depth) < uint(w) - || bytes_per_line <= 0 - || INT_MAX/uint(bytes_per_line) < uint(h)) - return; // invalid parameter(s) - d = new QImageData; - d->ref.ref(); - - d->own_data = false; - d->data = data; - d->width = w; - d->height = h; - d->depth = depth; - d->format = f; - if (depth == 32) - numColors = 0; - - d->bytes_per_line = bytes_per_line; - d->nbytes = d->bytes_per_line * h; - if (colortable) { - d->colortable.resize(numColors); - for (int i = 0; i < numColors; ++i) - d->colortable[i] = colortable[i]; - } else if (numColors) { - setColorCount(numColors); - } -} - -#ifdef Q_WS_QWS - -/*! - \fn QImage::QImage(uchar* data, int width, int height, int depth, int bytesPerLine, const QRgb* colortable, int numColors, Endian bitOrder) - - Constructs an image with the given \a width, \a height, \a depth, - \a bytesPerLine, \a colortable, \a numColors and \a bitOrder, that - uses an existing memory buffer, \a data. The image does not delete - the buffer at destruction. - - \warning This constructor is only available in Qt for Embedded Linux. - - The data has to be 32-bit aligned, and each scanline of data in the image - must also be 32-bit aligned, so it's no longer possible to specify a custom - \a bytesPerLine value. -*/ -QImage::QImage(uchar* data, int w, int h, int depth, int bpl, const QRgb* colortable, int numColors, Endian bitOrder) - : QPaintDevice() -{ - d = 0; - Format f = formatFor(depth, bitOrder); - if (f == Format_Invalid) - return; - if (!data || w <= 0 || h <= 0 || depth <= 0 || numColors < 0 - || INT_MAX/sizeof(uchar *) < uint(h) - || INT_MAX/uint(depth) < uint(w) - || bpl <= 0 - || INT_MAX/uint(bpl) < uint(h)) - return; // invalid parameter(s) - - d = new QImageData; - d->ref.ref(); - d->own_data = false; - d->data = data; - d->width = w; - d->height = h; - d->depth = depth; - d->format = f; - if (depth == 32) - numColors = 0; - d->bytes_per_line = bpl; - d->nbytes = d->bytes_per_line * h; - if (colortable) { - d->colortable.resize(numColors); - for (int i = 0; i < numColors; ++i) - d->colortable[i] = colortable[i]; - } else if (numColors) { - setColorCount(numColors); - } -} -#endif // Q_WS_QWS -#endif // QT3_SUPPORT - /*! Destroys the image and cleans up. */ @@ -1591,10 +1354,6 @@ int QImage::depth() const \sa setColorCount() */ -int QImage::numColors() const -{ - return d ? d->colortable.size() : 0; -} /*! \since 4.6 @@ -1613,75 +1372,6 @@ int QImage::colorCount() const return d ? d->colortable.size() : 0; } - -#ifdef QT3_SUPPORT -/*! - \fn QImage::Endian QImage::bitOrder() const - - Returns the bit order for the image. If it is a 1-bpp image, this - function returns either QImage::BigEndian or - QImage::LittleEndian. Otherwise, this function returns - QImage::IgnoreEndian. - - Use the format() function instead for the monochrome formats. For - non-monochrome formats the bit order is irrelevant. -*/ - -/*! - 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. -*/ -uchar **QImage::jumpTable() -{ - if (!d) - return 0; - detach(); - - // in case detach() ran out of memory.. - if (!d) - 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; - while (height--) { - *p++ = data; - data += d->bytes_per_line; - } - } - return d->jumptable; -} - -/*! - \overload -*/ -const uchar * const *QImage::jumpTable() const -{ - if (!d) - 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; - while (height--) { - *p++ = data; - data += d->bytes_per_line; - } - } - return d->jumptable; -} -#endif - /*! Sets the color table used to translate color indexes to QRgb values, to the specified \a colors. @@ -1731,10 +1421,6 @@ QVector<QRgb> QImage::colorTable() const \sa byteCount() */ -int QImage::numBytes() const -{ - return d ? d->nbytes : 0; -} /*! \since 4.6 @@ -2168,10 +1854,6 @@ void QImage::invertPixels(InvertMode mode) \sa setColorCount() */ -void QImage::setNumColors(int numColors) -{ - setColorCount(numColors); -} /*! \since 4.6 @@ -2224,116 +1906,6 @@ QImage::Format QImage::format() const } -#ifdef QT3_SUPPORT -/*! - Returns true if alpha buffer mode is enabled; otherwise returns - false. - - Use the hasAlphaChannel() function instead. - -*/ -bool QImage::hasAlphaBuffer() const -{ - if (!d) - return false; - - switch (d->format) { - case Format_ARGB32: - case Format_ARGB32_Premultiplied: - case Format_ARGB8565_Premultiplied: - case Format_ARGB8555_Premultiplied: - case Format_ARGB6666_Premultiplied: - case Format_ARGB4444_Premultiplied: - return true; - default: - return false; - } -} - -/*! - Enables alpha buffer mode if \a enable is true, otherwise disables - it. The alpha buffer is used to set a mask when a QImage is - translated to a QPixmap. - - If a monochrome or indexed 8-bit image has alpha channels in their - color tables they will automatically detect that they have an - alpha channel, so this function is not required. To force alpha - channels on 32-bit images, use the convertToFormat() function. -*/ - -void QImage::setAlphaBuffer(bool enable) -{ - if (!d - || d->format == Format_Mono - || d->format == Format_MonoLSB - || d->format == Format_Indexed8) - return; - if (enable && (d->format == Format_ARGB32 || - d->format == Format_ARGB32_Premultiplied || - d->format == Format_ARGB8565_Premultiplied || - d->format == Format_ARGB6666_Premultiplied || - d->format == Format_ARGB8555_Premultiplied || - d->format == Format_ARGB4444_Premultiplied)) - { - return; - } - if (!enable && (d->format == Format_RGB32 || - d->format == Format_RGB555 || - d->format == Format_RGB666 || - d->format == Format_RGB888 || - d->format == Format_RGB444)) - { - return; - } - detach(); - d->format = (enable ? Format_ARGB32 : Format_RGB32); -} - - -/*! - \fn bool QImage::create(int width, int height, int depth, int numColors, Endian bitOrder) - - Sets the image \a width, \a height, \a depth, its number of colors - (in \a numColors), and bit order. Returns true if successful, or - false if the parameters are incorrect or if memory cannot be - allocated. - - The \a width and \a height is limited to 32767. \a depth must be - 1, 8, or 32. If \a depth is 1, \a bitOrder must be set to - either QImage::LittleEndian or QImage::BigEndian. For other depths - \a bitOrder must be QImage::IgnoreEndian. - - This function allocates a color table and a buffer for the image - data. The image data is not initialized. The image buffer is - allocated as a single block that consists of a table of scanLine() - pointers (jumpTable()) and the image data (bits()). - - Use a QImage constructor instead. -*/ -bool QImage::create(int width, int height, int depth, int numColors, Endian bitOrder) -{ - if (d && !d->ref.deref()) - delete d; - d = QImageData::create(QSize(width, height), formatFor(depth, bitOrder), numColors); - return true; -} - -/*! - \fn bool QImage::create(const QSize& size, int depth, int numColors, Endian bitOrder) - \overload - - The width and height are specified in the \a size argument. - - Use a QImage constructor instead. -*/ -bool QImage::create(const QSize& size, int depth, int numColors, QImage::Endian bitOrder) -{ - if (d && !d->ref.deref()) - delete d; - d = QImageData::create(size, formatFor(depth, bitOrder), numColors); - return true; -} -#endif // QT3_SUPPORT /***************************************************************************** Internal routines for converting image depth. @@ -4023,30 +3595,6 @@ QImage QImage::convertToFormat(Format format, const QVector<QRgb> &colorTable, Q return image; } -#ifdef QT3_SUPPORT -/*! - Converts the depth (bpp) of the image to the given \a depth and - returns the converted image. The original image is not changed. - Returns this image if \a depth is equal to the image depth, or a - null image if this image cannot be converted. The \a depth - argument must be 1, 8 or 32. If the image needs to be modified to - fit in a lower-resolution result (e.g. converting from 32-bit to - 8-bit), use the \a flags to specify how you'd prefer this to - happen. - - Use the convertToFormat() function instead. -*/ - -QImage QImage::convertDepth(int depth, Qt::ImageConversionFlags flags) const -{ - if (!d || d->depth == depth) - return *this; - - Format format = formatFor (depth, QImage::LittleEndian); - return convertToFormat(format, flags); -} -#endif - /*! \fn bool QImage::valid(const QPoint &pos) const @@ -4265,41 +3813,6 @@ void QImage::setPixel(int x, int y, uint index_or_rgb) } } -#ifdef QT3_SUPPORT -/*! - Converts the bit order of the image to the given \a bitOrder and - returns the converted image. The original image is not changed. - Returns this image if the given \a bitOrder is equal to the image - current bit order, or a null image if this image cannot be - converted. - - Use convertToFormat() instead. -*/ - -QImage QImage::convertBitOrder(Endian bitOrder) const -{ - if (!d || isNull() || d->depth != 1 || !(bitOrder == BigEndian || bitOrder == LittleEndian)) - return QImage(); - - if ((d->format == Format_Mono && bitOrder == BigEndian) - || (d->format == Format_MonoLSB && bitOrder == LittleEndian)) - return *this; - - QImage image(d->width, d->height, d->format == Format_Mono ? Format_MonoLSB : Format_Mono); - - const uchar *data = d->data; - const uchar *end = data + d->nbytes; - uchar *ndata = image.d->data; - while (data < end) - *ndata++ = bitflip[*data++]; - - image.setDotsPerMeterX(dotsPerMeterX()); - image.setDotsPerMeterY(dotsPerMeterY()); - - image.d->colortable = d->colortable; - return image; -} -#endif /*! Returns true if all the colors in the image are shades of gray (i.e. their red, green and blue components are equal); otherwise @@ -5286,66 +4799,6 @@ QDataStream &operator>>(QDataStream &s, QImage &image) #endif // QT_NO_DATASTREAM -#ifdef QT3_SUPPORT -/*! - \fn QImage QImage::convertDepthWithPalette(int depth, QRgb* palette, int palette_count, Qt::ImageConversionFlags flags) const - - Returns an image with the given \a depth, using the \a - palette_count colors pointed to by \a palette. If \a depth is 1 or - 8, the returned image will have its color table ordered in the - same way as \a palette. - - If the image needs to be modified to fit in a lower-resolution - result (e.g. converting from 32-bit to 8-bit), use the \a flags to - specify how you'd prefer this to happen. - - Note: currently no closest-color search is made. If colors are - found that are not in the palette, the palette may not be used at - all. This result should not be considered valid because it may - change in future implementations. - - Currently inefficient for non-32-bit images. - - Use the convertToFormat() function in combination with the - setColorTable() function instead. -*/ -QImage QImage::convertDepthWithPalette(int d, QRgb* palette, int palette_count, Qt::ImageConversionFlags flags) const -{ - Format f = formatFor(d, QImage::LittleEndian); - QVector<QRgb> colortable; - for (int i = 0; i < palette_count; ++i) - colortable.append(palette[i]); - return convertToFormat(f, colortable, flags); -} - -/*! - \relates QImage - - Copies a block of pixels from \a src to \a dst. The pixels - copied from source (src) are converted according to - \a flags if it is incompatible with the destination - (\a dst). - - \a sx, \a sy is the top-left pixel in \a src, \a dx, \a dy is the - top-left position in \a dst and \a sw, \a sh is the size of the - copied block. The copying is clipped if areas outside \a src or \a - dst are specified. If \a sw is -1, it is adjusted to - src->width(). Similarly, if \a sh is -1, it is adjusted to - src->height(). - - Currently inefficient for non 32-bit images. - - Use copy() or QPainter::drawImage() instead. -*/ -void bitBlt(QImage *dst, int dx, int dy, const QImage *src, int sx, int sy, int sw, int sh, - Qt::ImageConversionFlags flags) -{ - if (dst->isNull() || src->isNull()) - return; - QPainter p(dst); - p.drawImage(QPoint(dx, dy), *src, QRect(sx, sy, sw, sh), flags); -} -#endif /*! \fn bool QImage::operator==(const QImage & image) const @@ -5619,15 +5072,6 @@ void QImage::setText(const QString &key, const QString &value) The language the text is recorded in is no longer relevant since the text is always set using QString and UTF-8 representation. */ -QString QImage::text(const char* key, const char* lang) const -{ - if (!d) - return QString(); - QString k = QString::fromAscii(key); - if (lang && *lang) - k += QLatin1Char('/') + QString::fromAscii(lang); - return d->text.value(k); -} /*! \fn QString QImage::text(const QImageTextKeyLang& keywordAndLanguage) const @@ -5641,15 +5085,6 @@ QString QImage::text(const char* key, const char* lang) const The language the text is recorded in is no longer relevant since the text is always set using QString and UTF-8 representation. */ -QString QImage::text(const QImageTextKeyLang& kl) const -{ - if (!d) - return QString(); - QString k = QString::fromAscii(kl.key); - if (!kl.lang.isEmpty()) - k += QLatin1Char('/') + QString::fromAscii(kl.lang); - return d->text.value(k); -} /*! \obsolete @@ -5661,20 +5096,6 @@ QString QImage::text(const QImageTextKeyLang& kl) const The language the text is recorded in is no longer relevant since the text is always set using QString and UTF-8 representation. */ -QStringList QImage::textLanguages() const -{ - if (!d) - return QStringList(); - QStringList keys = textKeys(); - QStringList languages; - for (int i = 0; i < keys.size(); ++i) { - int index = keys.at(i).indexOf(QLatin1Char('/')); - if (index > 0) - languages += keys.at(i).mid(index+1); - } - - return languages; -} /*! \obsolete @@ -5687,24 +5108,6 @@ QStringList QImage::textLanguages() const The language the text is recorded in is no longer relevant since the text is always set using QString and UTF-8 representation. */ -QList<QImageTextKeyLang> QImage::textList() const -{ - QList<QImageTextKeyLang> imageTextKeys; - if (!d) - return imageTextKeys; - QStringList keys = textKeys(); - for (int i = 0; i < keys.size(); ++i) { - int index = keys.at(i).indexOf(QLatin1Char('/')); - if (index > 0) { - QImageTextKeyLang tkl; - tkl.key = keys.at(i).left(index).toAscii(); - tkl.lang = keys.at(i).mid(index+1).toAscii(); - imageTextKeys += tkl; - } - } - - return imageTextKeys; -} /*! \fn void QImage::setText(const char* key, const char* language, const QString& text) @@ -5729,21 +5132,6 @@ QList<QImageTextKeyLang> QImage::textList() const \l{http://www.rfc-editor.org/rfc/rfc1766.txt}{RFC 1766}) or 0. \endomit */ -void QImage::setText(const char* key, const char* lang, const QString& s) -{ - if (!d) - return; - detach(); - - // In case detach() ran out of memory - if (!d) - return; - - QString k = QString::fromAscii(key); - if (lang && *lang) - k += QLatin1Char('/') + QString::fromAscii(lang); - d->text.insert(k, s); -} #endif // QT_NO_IMAGE_TEXT @@ -6325,24 +5713,6 @@ int QImage::bitPlaneCount() const return bpc; } - -#ifdef QT3_SUPPORT -#if defined(Q_WS_X11) -QT_BEGIN_INCLUDE_NAMESPACE -#include <private/qt_x11_p.h> -QT_END_INCLUDE_NAMESPACE -#endif - -QImage::Endian QImage::systemBitOrder() -{ -#if defined(Q_WS_X11) - return BitmapBitOrder(X11->display) == MSBFirst ? BigEndian : LittleEndian; -#else - return BigEndian; -#endif -} -#endif - /*! \fn QImage QImage::copy(const QRect &rect, Qt::ImageConversionFlags flags) const \compat diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 57d7169789..7e8a0a28e8 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -66,8 +66,8 @@ template <class T> class QVector; struct QImageData; class QImageDataMisc; // internal #ifndef QT_NO_IMAGE_TEXT -#ifdef QT_DEPRECATED -class Q_GUI_EXPORT QT_DEPRECATED QImageTextKeyLang { +#if QT_DEPRECATED_SINCE(5, 0) +class Q_GUI_EXPORT QImageTextKeyLang { public: QImageTextKeyLang(const char* k, const char* l) : key(k), lang(l) { } QImageTextKeyLang() { } @@ -134,9 +134,6 @@ public: explicit QImage(const char * const xpm[]); #endif explicit QImage(const QString &fileName, const char *format = 0); -#ifndef QT_NO_CAST_FROM_ASCII - explicit QImage(const char *fileName, const char *format = 0); -#endif QImage(const QImage &); ~QImage(); @@ -173,17 +170,11 @@ public: QRect rect() const; int depth() const; -#ifdef QT_DEPRECATED - QT_DEPRECATED int numColors() const; -#endif int colorCount() const; int bitPlaneCount() const; QRgb color(int i) const; void setColor(int i, QRgb c); -#ifdef QT_DEPRECATED - QT_DEPRECATED void setNumColors(int); -#endif void setColorCount(int); bool allGray() const; @@ -192,9 +183,7 @@ public: uchar *bits(); const uchar *bits() const; const uchar *constBits() const; -#ifdef QT_DEPRECATED - QT_DEPRECATED int numBytes() const; -#endif + int byteCount() const; uchar *scanLine(int); @@ -277,57 +266,19 @@ public: QString text(const QString &key = QString()) const; void setText(const QString &key, const QString &value); -#ifdef QT_DEPRECATED - QT_DEPRECATED QString text(const char* key, const char* lang=0) const; - QT_DEPRECATED QList<QImageTextKeyLang> textList() const; - QT_DEPRECATED QStringList textLanguages() const; - QT_DEPRECATED QString text(const QImageTextKeyLang&) const; - QT_DEPRECATED void setText(const char* key, const char* lang, const QString&); +#if QT_DEPRECATED_SINCE(5, 0) + inline QString text(const char* key, const char* lang=0) const; + inline QList<QImageTextKeyLang> textList() const; + inline QStringList textLanguages() const; + inline QString text(const QImageTextKeyLang&) const; + inline void setText(const char* key, const char* lang, const QString&); #endif #endif -#ifdef QT3_SUPPORT - enum Endian { BigEndian, LittleEndian, IgnoreEndian }; - QT3_SUPPORT_CONSTRUCTOR QImage(int width, int height, int depth, int numColors=0, Endian bitOrder=IgnoreEndian); - QT3_SUPPORT_CONSTRUCTOR QImage(const QSize&, int depth, int numColors=0, Endian bitOrder=IgnoreEndian); - QT3_SUPPORT_CONSTRUCTOR QImage(uchar *data, int w, int h, int depth, const QRgb *colortable, int numColors, Endian bitOrder); -#ifdef Q_WS_QWS - QT3_SUPPORT_CONSTRUCTOR QImage(uchar *data, int w, int h, int depth, int pbl, const QRgb *colortable, int numColors, Endian bitOrder); -#endif - inline QT3_SUPPORT Endian bitOrder() const { - Format f = format(); - return f == Format_Mono ? BigEndian : (f == Format_MonoLSB ? LittleEndian : IgnoreEndian); - } - QT3_SUPPORT QImage convertDepth(int, Qt::ImageConversionFlags flags = Qt::AutoColor) const; - QT3_SUPPORT QImage convertDepthWithPalette(int, QRgb* p, int pc, Qt::ImageConversionFlags flags = Qt::AutoColor) const; - QT3_SUPPORT QImage convertBitOrder(Endian) const; - QT3_SUPPORT bool hasAlphaBuffer() const; - QT3_SUPPORT void setAlphaBuffer(bool); - QT3_SUPPORT uchar **jumpTable(); - QT3_SUPPORT const uchar * const *jumpTable() const; - inline QT3_SUPPORT void reset() { *this = QImage(); } - static inline QT3_SUPPORT Endian systemByteOrder() - { return QSysInfo::ByteOrder == QSysInfo::BigEndian ? BigEndian : LittleEndian; } - inline QT3_SUPPORT QImage swapRGB() const { return rgbSwapped(); } - inline QT3_SUPPORT QImage mirror(bool horizontally = false, bool vertically = true) const - { return mirrored(horizontally, vertically); } - QT3_SUPPORT bool create(const QSize&, int depth, int numColors=0, Endian bitOrder=IgnoreEndian); - QT3_SUPPORT bool create(int width, int height, int depth, int numColors=0, Endian bitOrder=IgnoreEndian); - inline QT3_SUPPORT QImage xForm(const QMatrix &matrix) const { return transformed(QTransform(matrix)); } - inline QT3_SUPPORT QImage smoothScale(int w, int h, Qt::AspectRatioMode mode = Qt::IgnoreAspectRatio) const - { return scaled(QSize(w, h), mode, Qt::SmoothTransformation); } - inline QImage QT3_SUPPORT smoothScale(const QSize &s, Qt::AspectRatioMode mode = Qt::IgnoreAspectRatio) const - { return scaled(s, mode, Qt::SmoothTransformation); } - inline QT3_SUPPORT QImage scaleWidth(int w) const { return scaledToWidth(w); } - inline QT3_SUPPORT QImage scaleHeight(int h) const { return scaledToHeight(h); } - inline QT3_SUPPORT void invertPixels(bool invertAlpha) { invertAlpha ? invertPixels(InvertRgba) : invertPixels(InvertRgb); } - inline QT3_SUPPORT QImage copy(int x, int y, int w, int h, Qt::ImageConversionFlags) const - { return copy(QRect(x, y, w, h)); } - inline QT3_SUPPORT QImage copy(const QRect &rect, Qt::ImageConversionFlags) const - { return copy(rect); } - static QT3_SUPPORT Endian systemBitOrder(); - inline QT3_SUPPORT_CONSTRUCTOR QImage(const QByteArray &data) - { d = 0; *this = QImage::fromData(data); } +#if QT_DEPRECATED_SINCE(5, 0) + QT_DEPRECATED inline int numColors() const; + QT_DEPRECATED inline void setNumColors(int); + QT_DEPRECATED inline int numBytes() const; #endif protected: @@ -337,8 +288,8 @@ private: friend class QWSOnScreenSurface; QImageData *d; - friend class QRasterPixmapData; - friend class QBlittablePixmapData; + friend class QRasterPlatformPixmap; + friend class QBlittablePlatformPixmap; friend class QPixmapCacheEntry; friend Q_GUI_EXPORT qint64 qt_image_id(const QImage &image); friend const QVector<QRgb> *qt_image_colortable(const QImage &image); @@ -358,6 +309,94 @@ Q_GUI_EXPORT_INLINE int QImage::pixelIndex(const QPoint &pt) const { return pixe Q_GUI_EXPORT_INLINE QRgb QImage::pixel(const QPoint &pt) const { return pixel(pt.x(), pt.y()); } Q_GUI_EXPORT_INLINE void QImage::setPixel(const QPoint &pt, uint index_or_rgb) { setPixel(pt.x(), pt.y(), index_or_rgb); } +#if QT_DEPRECATED_SINCE(5, 0) +#ifndef QT_NO_IMAGE_TEXT +inline QString QImage::text(const char* key, const char* lang) const +{ + if (!d) + return QString(); + QString k = QString::fromAscii(key); + if (lang && *lang) + k += QLatin1Char('/') + QString::fromAscii(lang); + return d->text.value(k); +} + +inline QList<QImageTextKeyLang> QImage::textList() const +{ + QList<QImageTextKeyLang> imageTextKeys; + if (!d) + return imageTextKeys; + QStringList keys = textKeys(); + for (int i = 0; i < keys.size(); ++i) { + int index = keys.at(i).indexOf(QLatin1Char('/')); + if (index > 0) { + QImageTextKeyLang tkl; + tkl.key = keys.at(i).left(index).toAscii(); + tkl.lang = keys.at(i).mid(index+1).toAscii(); + imageTextKeys += tkl; + } + } + + return imageTextKeys; +} + +inline QStringList QImage::textLanguages() const +{ + if (!d) + return QStringList(); + QStringList keys = textKeys(); + QStringList languages; + for (int i = 0; i < keys.size(); ++i) { + int index = keys.at(i).indexOf(QLatin1Char('/')); + if (index > 0) + languages += keys.at(i).mid(index+1); + } + + return languages; +} + +inline QString QImage::text(const QImageTextKeyLang&) const +{ + if (!d) + return QString(); + QString k = QString::fromAscii(kl.key); + if (!kl.lang.isEmpty()) + k += QLatin1Char('/') + QString::fromAscii(kl.lang); + return d->text.value(k); +} + +inline void QImage::setText(const char* key, const char* lang, const QString&) +{ + if (!d) + return; + detach(); + + // In case detach() ran out of memory + if (!d) + return; + + QString k = QString::fromAscii(key); + if (lang && *lang) + k += QLatin1Char('/') + QString::fromAscii(lang); + d->text.insert(k, s); +} +#endif +inline int QImage::numColors() const +{ + return d ? d->colortable.size() : 0; +} + +inline void QImage::setNumColors(int) +{ + setColorCount(numColors); +} + +inline int QImage::numBytes() const +{ + return d ? d->nbytes : 0; +} +#endif + // QImage stream functions #if !defined(QT_NO_DATASTREAM) @@ -365,11 +404,6 @@ Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QImage &); Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QImage &); #endif -#ifdef QT3_SUPPORT -Q_GUI_EXPORT QT3_SUPPORT void bitBlt(QImage* dst, int dx, int dy, const QImage* src, - int sx=0, int sy=0, int sw=-1, int sh=-1, Qt::ImageConversionFlags flags = Qt::AutoColor); -#endif - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 7f243770fa..bc24778415 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -79,9 +79,6 @@ struct Q_GUI_EXPORT QImageData { // internal image data int nbytes; // number of bytes data QVector<QRgb> colortable; uchar *data; -#ifdef QT3_SUPPORT - uchar **jumptable; -#endif QImage::Format format; int bytes_per_line; int ser_no; // serial number diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp index aa1bf8059e..7901045593 100644 --- a/src/gui/image/qimagepixmapcleanuphooks.cpp +++ b/src/gui/image/qimagepixmapcleanuphooks.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include "qimagepixmapcleanuphooks_p.h" -#include "private/qpixmapdata_p.h" +#include "qplatformpixmap_qpa.h" #include "private/qimage_p.h" @@ -62,12 +62,12 @@ QImagePixmapCleanupHooks *QImagePixmapCleanupHooks::instance() return qt_image_and_pixmap_cleanup_hooks(); } -void QImagePixmapCleanupHooks::addPixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd hook) +void QImagePixmapCleanupHooks::addPlatformPixmapModificationHook(_qt_pixmap_cleanup_hook_pmd hook) { pixmapModificationHooks.append(hook); } -void QImagePixmapCleanupHooks::addPixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd hook) +void QImagePixmapCleanupHooks::addPlatformPixmapDestructionHook(_qt_pixmap_cleanup_hook_pmd hook) { pixmapDestructionHooks.append(hook); } @@ -78,12 +78,12 @@ void QImagePixmapCleanupHooks::addImageHook(_qt_image_cleanup_hook_64 hook) imageHooks.append(hook); } -void QImagePixmapCleanupHooks::removePixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd hook) +void QImagePixmapCleanupHooks::removePlatformPixmapModificationHook(_qt_pixmap_cleanup_hook_pmd hook) { pixmapModificationHooks.removeAll(hook); } -void QImagePixmapCleanupHooks::removePixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd hook) +void QImagePixmapCleanupHooks::removePlatformPixmapDestructionHook(_qt_pixmap_cleanup_hook_pmd hook) { pixmapDestructionHooks.removeAll(hook); } @@ -93,7 +93,7 @@ void QImagePixmapCleanupHooks::removeImageHook(_qt_image_cleanup_hook_64 hook) imageHooks.removeAll(hook); } -void QImagePixmapCleanupHooks::executePixmapDataModificationHooks(QPixmapData* pmd) +void QImagePixmapCleanupHooks::executePlatformPixmapModificationHooks(QPlatformPixmap* pmd) { QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks(); // the global destructor for the pixmap and image hooks might have @@ -108,7 +108,7 @@ void QImagePixmapCleanupHooks::executePixmapDataModificationHooks(QPixmapData* p qt_pixmap_cleanup_hook_64(pmd->cacheKey()); } -void QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(QPixmapData* pmd) +void QImagePixmapCleanupHooks::executePlatformPixmapDestructionHooks(QPlatformPixmap* pmd) { QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks(); // the global destructor for the pixmap and image hooks might have @@ -133,9 +133,9 @@ void QImagePixmapCleanupHooks::executeImageHooks(qint64 key) } -void QImagePixmapCleanupHooks::enableCleanupHooks(QPixmapData *pixmapData) +void QImagePixmapCleanupHooks::enableCleanupHooks(QPlatformPixmap *handle) { - pixmapData->is_cached = true; + handle->is_cached = true; } void QImagePixmapCleanupHooks::enableCleanupHooks(const QPixmap &pixmap) diff --git a/src/gui/image/qimagepixmapcleanuphooks_p.h b/src/gui/image/qimagepixmapcleanuphooks_p.h index fe49ea0c5e..c98da6110a 100644 --- a/src/gui/image/qimagepixmapcleanuphooks_p.h +++ b/src/gui/image/qimagepixmapcleanuphooks_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE typedef void (*_qt_image_cleanup_hook_64)(qint64); -typedef void (*_qt_pixmap_cleanup_hook_pmd)(QPixmapData*); +typedef void (*_qt_pixmap_cleanup_hook_pmd)(QPlatformPixmap*); class QImagePixmapCleanupHooks; @@ -70,26 +70,26 @@ public: static void enableCleanupHooks(const QImage &image); static void enableCleanupHooks(const QPixmap &pixmap); - static void enableCleanupHooks(QPixmapData *pixmapData); + static void enableCleanupHooks(QPlatformPixmap *handle); static bool isImageCached(const QImage &image); static bool isPixmapCached(const QPixmap &pixmap); // Gets called when a pixmap data is about to be modified: - void addPixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd); + void addPlatformPixmapModificationHook(_qt_pixmap_cleanup_hook_pmd); // Gets called when a pixmap data is about to be destroyed: - void addPixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd); + void addPlatformPixmapDestructionHook(_qt_pixmap_cleanup_hook_pmd); // Gets called when an image is about to be modified or destroyed: void addImageHook(_qt_image_cleanup_hook_64); - void removePixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd); - void removePixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd); + void removePlatformPixmapModificationHook(_qt_pixmap_cleanup_hook_pmd); + void removePlatformPixmapDestructionHook(_qt_pixmap_cleanup_hook_pmd); void removeImageHook(_qt_image_cleanup_hook_64); - static void executePixmapDataModificationHooks(QPixmapData*); - static void executePixmapDataDestructionHooks(QPixmapData*); + static void executePlatformPixmapModificationHooks(QPlatformPixmap*); + static void executePlatformPixmapDestructionHooks(QPlatformPixmap*); static void executeImageHooks(qint64 key); private: diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 411e5e9260..4bf4b08349 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -359,6 +359,8 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, #ifndef QT_NO_IMAGEFORMAT_BMP } else if (testFormat == "bmp") { handler = new QBmpHandler; + } else if (testFormat == "dib") { + handler = new QBmpHandler(QBmpHandler::DibFormat); #endif #ifndef QT_NO_IMAGEFORMAT_XPM } else if (testFormat == "xpm") { diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index 0c465a0a02..82ae64593a 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -201,6 +201,8 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device, #ifndef QT_NO_IMAGEFORMAT_BMP } else if (testFormat == "bmp") { handler = new QBmpHandler; + } else if (testFormat == "dib") { + handler = new QBmpHandler(QBmpHandler::DibFormat); #endif #ifndef QT_NO_IMAGEFORMAT_XPM } else if (testFormat == "xpm") { diff --git a/src/gui/image/qmovie.h b/src/gui/image/qmovie.h index f971e11b13..0278957091 100644 --- a/src/gui/image/qmovie.h +++ b/src/gui/image/qmovie.h @@ -51,11 +51,6 @@ #include <QtCore/qobject.h> #include <QtGui/qimagereader.h> -#ifdef QT3_SUPPORT -#include <QtGui/qimage.h> -#include <QtGui/qpixmap.h> -#endif - QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -151,21 +146,6 @@ public Q_SLOTS: private: Q_DISABLE_COPY(QMovie) Q_PRIVATE_SLOT(d_func(), void _q_loadNextFrame()) - -#ifdef QT3_SUPPORT -public: - inline QT3_SUPPORT bool isNull() const { return isValid(); } - inline QT3_SUPPORT int frameNumber() const { return currentFrameNumber(); } - inline QT3_SUPPORT bool running() const { return state() == Running; } - inline QT3_SUPPORT bool paused() const { return state() == Paused; } - inline QT3_SUPPORT bool finished() const { return state() == NotRunning; } - inline QT3_SUPPORT void restart() { stop(); start(); } - inline QT3_SUPPORT QImage frameImage() const { return currentImage(); } - inline QT3_SUPPORT QPixmap framePixmap() const { return currentPixmap(); } - inline QT3_SUPPORT void step() { jumpToNextFrame(); } - inline QT3_SUPPORT void pause() { setPaused(true); } - inline QT3_SUPPORT void unpause() { setPaused(false); } -#endif }; QT_END_NAMESPACE diff --git a/src/gui/image/qnativeimage.cpp b/src/gui/image/qnativeimage.cpp index aebcbafd29..35bca4431d 100644 --- a/src/gui/image/qnativeimage.cpp +++ b/src/gui/image/qnativeimage.cpp @@ -41,18 +41,17 @@ #include <qdebug.h> #include "qnativeimage_p.h" -#include "qcolormap.h" +#include "private/qguiapplication_p.h" +#include "qscreen.h" #include "private/qpaintengine_raster_p.h" -#include "private/qapplication_p.h" -#include "private/qgraphicssystem_p.h" +#include "private/qguiapplication_p.h" #if defined(Q_WS_X11) && !defined(QT_NO_MITSHM) #include <qx11info_x11.h> #include <sys/ipc.h> #include <sys/shm.h> -#include <qwidget.h> #endif #ifdef Q_WS_MAC @@ -70,7 +69,7 @@ typedef struct { } BITMAPINFO_MASK; -QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool isTextBuffer, QWidget *) +QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool isTextBuffer, QWindow *) { #ifndef Q_WS_WINCE Q_UNUSED(isTextBuffer); @@ -142,107 +141,14 @@ QNativeImage::~QNativeImage() QImage::Format QNativeImage::systemFormat() { - if (QColormap::instance().depth() == 16) - return QImage::Format_RGB16; - return QImage::Format_RGB32; -} - - -#elif defined(Q_WS_X11) && !defined(QT_NO_MITSHM) - -QNativeImage::QNativeImage(int width, int height, QImage::Format format,bool /* isTextBuffer */, QWidget *widget) - : xshmimg(0), xshmpm(0) -{ - if (!X11->use_mitshm) { - image = QImage(width, height, format); - // follow good coding practice and set xshminfo attributes, though values not used in this case - xshminfo.readOnly = true; - xshminfo.shmaddr = 0; - xshminfo.shmid = 0; - xshminfo.shmseg = 0; - return; - } - - QX11Info info = widget->x11Info(); - - int dd = info.depth(); - Visual *vis = (Visual*) info.visual(); - - xshmimg = XShmCreateImage(X11->display, vis, dd, ZPixmap, 0, &xshminfo, width, height); - if (!xshmimg) { - qWarning("QNativeImage: Unable to create shared XImage."); - return; - } - - bool ok; - xshminfo.shmid = shmget(IPC_PRIVATE, xshmimg->bytes_per_line * xshmimg->height, - IPC_CREAT | 0777); - ok = xshminfo.shmid != -1; - if (ok) { - xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0); - xshminfo.shmaddr = xshmimg->data; - ok = (xshminfo.shmaddr != (char*)-1); - if (ok) - image = QImage((uchar *)xshmimg->data, width, height, format); - } - xshminfo.readOnly = false; - if (ok) { - ok = XShmAttach(X11->display, &xshminfo); - XSync(X11->display, False); - if (shmctl(xshminfo.shmid, IPC_RMID, 0) == -1) - qWarning() << "Error while marking the shared memory segment to be destroyed"; - } - if (!ok) { - qWarning() << "QNativeImage: Unable to attach to shared memory segment."; - if (xshmimg->data) { - free(xshmimg->data); - xshmimg->data = 0; - } - XDestroyImage(xshmimg); - xshmimg = 0; - if (xshminfo.shmaddr) - shmdt(xshminfo.shmaddr); - if (xshminfo.shmid != -1) - shmctl(xshminfo.shmid, IPC_RMID, 0); - return; - } - if (X11->use_mitshm_pixmaps) { - xshmpm = XShmCreatePixmap(X11->display, DefaultRootWindow(X11->display), xshmimg->data, - &xshminfo, width, height, dd); - if (!xshmpm) { - qWarning() << "QNativeImage: Unable to create shared Pixmap."; - } - } -} - - -QNativeImage::~QNativeImage() -{ - if (!xshmimg) - return; - - if (xshmpm) { - XFreePixmap(X11->display, xshmpm); - xshmpm = 0; - } - XShmDetach(X11->display, &xshminfo); - xshmimg->data = 0; - XDestroyImage(xshmimg); - xshmimg = 0; - shmdt(xshminfo.shmaddr); - shmctl(xshminfo.shmid, IPC_RMID, 0); -} - -QImage::Format QNativeImage::systemFormat() -{ - if (QX11Info::appDepth() == 16) + if (QGuiApplication::primaryScreen()->depth() == 16) return QImage::Format_RGB16; return QImage::Format_RGB32; } #elif defined(Q_WS_MAC) -QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /* isTextBuffer */, QWidget *widget) +QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /* isTextBuffer */, QWindow *) : image(width, height, format) { @@ -267,7 +173,7 @@ QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /* #endif cg = CGBitmapContextCreate(image.bits(), width, height, 8, image.bytesPerLine(), - QCoreGraphicsPaintEngine::macDisplayColorSpace(widget), cgflags); + QCoreGraphicsPaintEngine::macDisplayColorSpace(0), cgflags); CGContextTranslateCTM(cg, 0, height); CGContextScaleCTM(cg, 1, -1); @@ -289,7 +195,7 @@ QImage::Format QNativeImage::systemFormat() #else // other platforms... -QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /* isTextBuffer */, QWidget *) +QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /* isTextBuffer */, QWindow *) : image(width, height, format) { @@ -302,11 +208,7 @@ QNativeImage::~QNativeImage() QImage::Format QNativeImage::systemFormat() { -#ifdef Q_WS_QPA - return QApplicationPrivate::platformIntegration()->screens().at(0)->format(); -#else - return QImage::Format_RGB32; -#endif + return QGuiApplication::primaryScreen()->handle()->format(); } #endif // platforms diff --git a/src/gui/image/qnativeimage_p.h b/src/gui/image/qnativeimage_p.h index e468917a67..f9132de69e 100644 --- a/src/gui/image/qnativeimage_p.h +++ b/src/gui/image/qnativeimage_p.h @@ -58,9 +58,6 @@ #ifdef Q_WS_WIN #include "qt_windows.h" -#elif defined(Q_WS_X11) -#include <private/qt_x11_p.h> - #elif defined(Q_WS_MAC) #include <private/qt_mac_p.h> @@ -68,12 +65,12 @@ QT_BEGIN_NAMESPACE -class QWidget; +class QWindow; class QNativeImage { public: - QNativeImage(int width, int height, QImage::Format format, bool isTextBuffer = false, QWidget *widget = 0); + QNativeImage(int width, int height, QImage::Format format, bool isTextBuffer = false, QWindow *window = 0); ~QNativeImage(); inline int width() const; @@ -88,11 +85,6 @@ public: HBITMAP bitmap; HBITMAP null_bitmap; -#elif defined(Q_WS_X11) && !defined(QT_NO_MITSHM) - XImage *xshmimg; - Pixmap xshmpm; - XShmSegmentInfo xshminfo; - #elif defined(Q_WS_MAC) CGContextRef cg; #endif diff --git a/src/gui/image/qnativeimagehandleprovider_p.h b/src/gui/image/qnativeimagehandleprovider_p.h deleted file mode 100644 index b3b3e487d1..0000000000 --- a/src/gui/image/qnativeimagehandleprovider_p.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QNATIVEIMAGEHANDLEPROVIDER_P_H -#define QNATIVEIMAGEHANDLEPROVIDER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qstring.h> - -QT_BEGIN_NAMESPACE - -class QNativeImageHandleProvider -{ -public: - virtual void get(void **handle, QString *type) = 0; - virtual void release(void *handle, const QString &type) = 0; -}; - -QT_END_NAMESPACE - -#endif // QNATIVEIMAGEHANDLEPROVIDER_P_H diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 5df469ace7..418393a1b8 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -47,6 +47,7 @@ #include <private/qfactoryloader_p.h> #include <private/qpaintengine_pic_p.h> #include <private/qfont_p.h> +#include <qguiapplication.h> #include "qdatastream.h" #include "qfile.h" @@ -1217,7 +1218,6 @@ QDataStream &operator>>(QDataStream &s, QPicture &r) QT_BEGIN_INCLUDE_NAMESPACE #include "qregexp.h" -#include "qapplication.h" #include "qpictureformatplugin.h" QT_END_INCLUDE_NAMESPACE diff --git a/src/gui/image/qpicture.h b/src/gui/image/qpicture.h index 848a6f5083..1c5d3a9c8f 100644 --- a/src/gui/image/qpicture.h +++ b/src/gui/image/qpicture.h @@ -104,9 +104,6 @@ protected: QPicture(QPicturePrivate &data); int metric(PaintDeviceMetric m) const; -#ifdef QT3_SUPPORT - inline QT3_SUPPORT QPicture copy() const { QPicture p(*this); p.detach(); return p; } -#endif private: bool exec(QPainter *p, QDataStream &ds, int i); diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 70715793a7..c2b9c6a1b9 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -42,20 +42,15 @@ #include <qglobal.h> #include "qpixmap.h" -#include "qpixmapdata_p.h" +#include "qplatformpixmap_qpa.h" #include "qimagepixmapcleanuphooks_p.h" #include "qbitmap.h" -#include "qcolormap.h" #include "qimage.h" -#include "qwidget.h" #include "qpainter.h" #include "qdatastream.h" #include "qbuffer.h" -#include "qapplication.h" -#include <private/qapplication_p.h> -#include <private/qgraphicssystem_p.h> -#include <private/qwidget_p.h> +#include <private/qguiapplication_p.h> #include "qevent.h" #include "qfile.h" #include "qfileinfo.h" @@ -65,58 +60,30 @@ #include "qimagewriter.h" #include "qpaintengine.h" #include "qthread.h" - -#ifdef Q_WS_MAC -# include "private/qt_mac_p.h" -# include "private/qpixmap_mac_p.h" -#endif +#include "qdebug.h" #ifdef Q_WS_QPA # include "qplatformintegration_qpa.h" #endif -#if defined(Q_WS_X11) -# include "qx11info_x11.h" -# include <private/qt_x11_p.h> -# include <private/qpixmap_x11_p.h> -#endif - -#if defined(Q_OS_SYMBIAN) -# include <private/qt_s60_p.h> -#endif - #include "qpixmap_raster_p.h" -#include "private/qstylehelper_p.h" +#include "private/qhexstring_p.h" QT_BEGIN_NAMESPACE -// ### Qt 5: remove -Q_GUI_EXPORT qint64 qt_pixmap_id(const QPixmap &pixmap) -{ - return pixmap.cacheKey(); -} - static bool qt_pixmap_thread_test() { - if (!qApp) { + if (!QCoreApplication::instance()) { qFatal("QPixmap: Must construct a QApplication before a QPaintDevice"); return false; } if (qApp->thread() != QThread::currentThread()) { bool fail = false; -#if defined (Q_WS_X11) - if (!QApplication::testAttribute(Qt::AA_X11InitThreads)) - fail = true; -#elif defined (Q_WS_QPA) - if (!QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps)) { + if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps)) { printf("Lighthouse plugin does not support threaded pixmaps!\n"); fail = true; } -#else - if (QApplicationPrivate::graphics_system_name != QLatin1String("raster")) - fail = true; -#endif if (fail) { qWarning("QPixmap: It is not safe to use pixmaps outside the GUI thread"); return false; @@ -125,23 +92,10 @@ static bool qt_pixmap_thread_test() return true; } -void QPixmap::init(int w, int h, Type type) -{ - init(w, h, int(type)); -} - -extern QApplication::Type qt_appType; - -void QPixmap::init(int w, int h, int type) +void QPixmap::doInit(int w, int h, int type) { - if (qt_appType == QApplication::Tty) { - qWarning("QPixmap: Cannot create a QPixmap when no GUI is being used"); - data = 0; - return; - } - - if ((w > 0 && h > 0) || type == QPixmapData::BitmapType) - data = QPixmapData::create(w, h, (QPixmapData::PixelType) type); + if ((w > 0 && h > 0) || type == QPlatformPixmap::BitmapType) + data = QPlatformPixmap::create(w, h, (QPlatformPixmap::PixelType) type); else data = 0; } @@ -172,7 +126,7 @@ QPixmap::QPixmap() : QPaintDevice() { (void) qt_pixmap_thread_test(); - init(0, 0, QPixmapData::PixmapType); + doInit(0, 0, QPlatformPixmap::PixmapType); } /*! @@ -193,9 +147,9 @@ QPixmap::QPixmap(int w, int h) : QPaintDevice() { if (!qt_pixmap_thread_test()) - init(0, 0, QPixmapData::PixmapType); + doInit(0, 0, QPlatformPixmap::PixmapType); else - init(w, h, QPixmapData::PixmapType); + doInit(w, h, QPlatformPixmap::PixmapType); } /*! @@ -212,20 +166,9 @@ QPixmap::QPixmap(const QSize &size) : QPaintDevice() { if (!qt_pixmap_thread_test()) - init(0, 0, QPixmapData::PixmapType); - else - init(size.width(), size.height(), QPixmapData::PixmapType); -} - -/*! - \internal -*/ -QPixmap::QPixmap(const QSize &s, Type type) -{ - if (!qt_pixmap_thread_test()) - init(0, 0, type); + doInit(0, 0, QPlatformPixmap::PixmapType); else - init(s.width(), s.height(), type); + doInit(size.width(), size.height(), QPlatformPixmap::PixmapType); } /*! @@ -234,15 +177,15 @@ QPixmap::QPixmap(const QSize &s, Type type) QPixmap::QPixmap(const QSize &s, int type) { if (!qt_pixmap_thread_test()) - init(0, 0, static_cast<QPixmapData::PixelType>(type)); + doInit(0, 0, static_cast<QPlatformPixmap::PixelType>(type)); else - init(s.width(), s.height(), static_cast<QPixmapData::PixelType>(type)); + doInit(s.width(), s.height(), static_cast<QPlatformPixmap::PixelType>(type)); } /*! \internal */ -QPixmap::QPixmap(QPixmapData *d) +QPixmap::QPixmap(QPlatformPixmap *d) : QPaintDevice(), data(d) { } @@ -279,7 +222,7 @@ QPixmap::QPixmap(QPixmapData *d) QPixmap::QPixmap(const QString& fileName, const char *format, Qt::ImageConversionFlags flags) : QPaintDevice() { - init(0, 0, QPixmapData::PixmapType); + doInit(0, 0, QPlatformPixmap::PixmapType); if (!qt_pixmap_thread_test()) return; @@ -296,7 +239,7 @@ QPixmap::QPixmap(const QPixmap &pixmap) : QPaintDevice() { if (!qt_pixmap_thread_test()) { - init(0, 0, QPixmapData::PixmapType); + doInit(0, 0, QPlatformPixmap::PixmapType); return; } if (pixmap.paintingActive()) { // make a deep copy @@ -325,13 +268,13 @@ QPixmap::QPixmap(const QPixmap &pixmap) QPixmap::QPixmap(const char * const xpm[]) : QPaintDevice() { - init(0, 0, QPixmapData::PixmapType); + doInit(0, 0, QPlatformPixmap::PixmapType); if (!xpm) return; QImage image(xpm); if (!image.isNull()) { - if (data && data->pixelType() == QPixmapData::BitmapType) + if (data && data->pixelType() == QPlatformPixmap::BitmapType) *this = QBitmap::fromImage(image); else *this = fromImage(image); @@ -386,7 +329,7 @@ QPixmap QPixmap::copy(const QRect &rect) const if (!rect.isEmpty()) r = r.intersected(rect); - QPixmapData *d = data->createCompatiblePixmapData(); + QPlatformPixmap *d = data->createCompatiblePlatformPixmap(); d->copy(data.data(), r); return QPixmap(d); } @@ -563,7 +506,7 @@ QMatrix QPixmap::trueMatrix(const QMatrix &m, int w, int h) bool QPixmap::isQBitmap() const { - return data->type == QPixmapData::BitmapType; + return data->type == QPlatformPixmap::BitmapType; } /*! @@ -657,65 +600,6 @@ int QPixmap::depth() const pixmap = pixmap.copy(QRect(QPoint(0, 0), size)); \endcode */ -#ifdef QT3_SUPPORT -void QPixmap::resize_helper(const QSize &s) -{ - int w = s.width(); - int h = s.height(); - if (w < 1 || h < 1) { - *this = QPixmap(); - return; - } - - if (size() == s) - return; - - // QPixmap.data member may be QRuntimePixmapData so use pixmapData() function to get - // the actual underlaying runtime pixmap data. - QPixmapData *pd = pixmapData(); - - // Create new pixmap - QPixmap pm(QSize(w, h), pd ? pd->type : QPixmapData::PixmapType); - bool uninit = false; -#if defined(Q_WS_X11) - QX11PixmapData *x11Data = pd && pd->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(pd) : 0; - if (x11Data) { - pm.x11SetScreen(x11Data->xinfo.screen()); - uninit = x11Data->flags & QX11PixmapData::Uninitialized; - } -#elif defined(Q_WS_MAC) - QMacPixmapData *macData = pd && pd->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(pd) : 0; - if (macData) - uninit = macData->uninit; -#endif - if (!uninit && !isNull()) { - // Copy old pixmap - if (hasAlphaChannel()) - pm.fill(Qt::transparent); - QPainter p(&pm); - p.drawPixmap(0, 0, *this, 0, 0, qMin(width(), w), qMin(height(), h)); - } - -#if defined(Q_WS_X11) - if (x11Data && x11Data->x11_mask) { - QPixmapData *newPd = pm.pixmapData(); - QX11PixmapData *pmData = (newPd && newPd->classId() == QPixmapData::X11Class) - ? static_cast<QX11PixmapData*>(newPd) : 0; - if (pmData) { - pmData->x11_mask = (Qt::HANDLE)XCreatePixmap(X11->display, - RootWindow(x11Data->xinfo.display(), - x11Data->xinfo.screen()), - w, h, 1); - GC gc = XCreateGC(X11->display, pmData->x11_mask, 0, 0); - XCopyArea(X11->display, x11Data->x11_mask, pmData->x11_mask, gc, 0, 0, - qMin(width(), w), qMin(height(), h), 0, 0); - XFreeGC(X11->display, gc); - } - } -#endif - *this = pm; -} -#endif /*! \fn void QPixmap::resize(int width, int height) @@ -776,7 +660,44 @@ void QPixmap::setMask(const QBitmap &mask) return; detach(); - data->setMask(mask); + + QImage image = data->toImage(); + if (mask.size().isEmpty()) { + if (image.depth() != 1) { // hw: ???? + image = image.convertToFormat(QImage::Format_RGB32); + } + } else { + const int w = image.width(); + const int h = image.height(); + + switch (image.depth()) { + case 1: { + const QImage imageMask = mask.toImage().convertToFormat(image.format()); + for (int y = 0; y < h; ++y) { + const uchar *mscan = imageMask.scanLine(y); + uchar *tscan = image.scanLine(y); + int bytesPerLine = image.bytesPerLine(); + for (int i = 0; i < bytesPerLine; ++i) + tscan[i] &= mscan[i]; + } + break; + } + default: { + const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB); + image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + for (int y = 0; y < h; ++y) { + const uchar *mscan = imageMask.scanLine(y); + QRgb *tscan = (QRgb *)image.scanLine(y); + for (int x = 0; x < w; ++x) { + if (!(mscan[x>>3] & (1 << (x&7)))) + tscan[x] = 0; + } + } + break; + } + } + } + data->fromImage(image, Qt::AutoColor); } #ifndef QT_NO_IMAGE_HEURISTIC_MASK @@ -823,19 +744,6 @@ QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) return QBitmap::fromImage(image.createMaskFromColor(maskColor.rgba(), mode)); } -/*! \overload - - Creates and returns a mask for this pixmap based on the given \a - maskColor. Same as calling createMaskFromColor(maskColor, - Qt::MaskInColor) - - \sa createHeuristicMask(), QImage::createMaskFromColor() -*/ -QBitmap QPixmap::createMaskFromColor(const QColor &maskColor) const -{ - return createMaskFromColor(maskColor, Qt::MaskInColor); -} - /*! Loads a pixmap from the file with the given \a fileName. Returns true if the pixmap was successfully loaded; otherwise returns @@ -873,7 +781,7 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers % info.absoluteFilePath() % HexString<uint>(info.lastModified().toTime_t()) % HexString<quint64>(info.size()) - % HexString<uint>(data ? data->pixelType() : QPixmapData::PixmapType); + % HexString<uint>(data ? data->pixelType() : QPlatformPixmap::PixmapType); // Note: If no extension is provided, we try to match the // file against known plugin extensions @@ -883,7 +791,7 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers if (QPixmapCache::find(key, *this)) return true; - QScopedPointer<QPixmapData> tmp(QPixmapData::create(0, 0, data ? data->type : QPixmapData::PixmapType)); + QScopedPointer<QPlatformPixmap> tmp(QPlatformPixmap::create(0, 0, data ? data->type : QPlatformPixmap::PixmapType)); if (tmp->fromFile(fileName, format, flags)) { data = tmp.take(); QPixmapCache::insert(key, *this); @@ -918,7 +826,7 @@ bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::I return false; if (!data) - data = QPixmapData::create(0, 0, QPixmapData::PixmapType); + data = QPlatformPixmap::create(0, 0, QPlatformPixmap::PixmapType); return data->fromData(buf, len, format, flags); } @@ -986,21 +894,24 @@ bool QPixmap::doImageIO(QImageWriter *writer, int quality) const return writer->write(toImage()); } - -// The implementation (and documentation) of -// QPixmap::fill(const QWidget *, const QPoint &) -// is in qwidget.cpp - /*! - \fn void QPixmap::fill(const QWidget *widget, int x, int y) + \fn void QPixmap::fill(const QPaintDevice *device, int x, int y) \overload - Fills the pixmap with the \a widget's background color or pixmap. + \obsolete + + Fills the pixmap with the \a device's background color or pixmap. The given point, (\a x, \a y), defines an offset in widget coordinates to which the pixmap's top-left pixel will be mapped to. */ +void QPixmap::fill(const QPaintDevice *, const QPoint &) +{ + qWarning() << "QPixmap::fill(const QPaintDevice *device, const QPoint &offset) is deprecated, ignored"; +} + + /*! Fills the pixmap with the given \a color. @@ -1029,7 +940,7 @@ void QPixmap::fill(const QColor &color) } else { // Don't bother to make a copy of the data object, since // it will be filled with new pixel data anyway. - QPixmapData *d = data->createCompatiblePixmapData(); + QPlatformPixmap *d = data->createCompatiblePlatformPixmap(); d->resize(data->width(), data->height()); data = d; } @@ -1072,6 +983,7 @@ qint64 QPixmap::cacheKey() const return data->cacheKey(); } +#if 0 static void sendResizeEvents(QWidget *target) { QResizeEvent e(target->size(), QSize()); @@ -1084,9 +996,10 @@ static void sendResizeEvents(QWidget *target) sendResizeEvents(child); } } +#endif /*! - \fn QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rectangle) + \fn QPixmap QPixmap::grabWidget(QPaintDevice * widget, const QRect &rectangle) Creates a pixmap and paints the given \a widget, restricted by the given \a rectangle, in it. If the \a widget has any children, then @@ -1115,33 +1028,18 @@ static void sendResizeEvents(QWidget *target) \sa grabWindow() */ -QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rect) +QPixmap QPixmap::grabWidget(QObject *widget, const QRect &rectangle) { + QPixmap pixmap; + // ### Qt5: should we keep or remove this method? + // SC solution would be to install a callback form QtWidgets, but ugly. + qWarning("QPixmap::grabWidget is deprecated, use QWidget::grab() instead"); if (!widget) - return QPixmap(); - - if (widget->testAttribute(Qt::WA_PendingResizeEvent) || !widget->testAttribute(Qt::WA_WState_Created)) - sendResizeEvents(widget); - - widget->d_func()->prepareToRender(QRegion(), - QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask); - - QRect r(rect); - if (r.width() < 0) - r.setWidth(widget->width() - rect.x()); - if (r.height() < 0) - r.setHeight(widget->height() - rect.y()); - - if (!r.intersects(widget->rect())) - return QPixmap(); - - QPixmap res(r.size()); - if (!qt_widget_private(widget)->isOpaque) - res.fill(Qt::transparent); - - widget->d_func()->render(&res, QPoint(), r, QWidget::DrawWindowBackground - | QWidget::DrawChildren | QWidget::IgnoreMask, true); - return res; + return pixmap; + QMetaObject::invokeMethod(widget, "grab", Qt::DirectConnection, + Q_RETURN_ARG(QPixmap, pixmap), + Q_ARG(QRect, rectangle)); + return pixmap; } /*! @@ -1200,137 +1098,6 @@ QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rect) */ -#if defined(Q_WS_X11) || defined(Q_WS_QWS) - -/*! - Returns the pixmap's handle to the device context. - - Note that, since QPixmap make use of \l {Implicit Data - Sharing}{implicit data sharing}, the detach() function must be - called explicitly to ensure that only \e this pixmap's data is - modified if the pixmap data is shared. - - \warning This function is X11 specific; using it is non-portable. - - \warning Since 4.8, pixmaps do not have an X11 handle unless - created with \l {QPixmap::}{fromX11Pixmap()}, or if the native - graphics system is explicitly enabled. - - \sa detach() - \sa QApplication::setGraphicsSystem() -*/ - -Qt::HANDLE QPixmap::handle() const -{ -#if defined(Q_WS_X11) - const QPixmapData *pd = pixmapData(); - if (pd && pd->classId() == QPixmapData::X11Class) - return static_cast<const QX11PixmapData*>(pd)->handle(); -#endif - return 0; -} -#endif - - -#ifdef QT3_SUPPORT -static Qt::ImageConversionFlags colorModeToFlags(QPixmap::ColorMode mode) -{ - Qt::ImageConversionFlags flags = Qt::AutoColor; - switch (mode) { - case QPixmap::Color: - flags |= Qt::ColorOnly; - break; - case QPixmap::Mono: - flags |= Qt::MonoOnly; - break; - default: - break;// Nothing. - } - return flags; -} - -/*! - Use the constructor that takes a Qt::ImageConversionFlag instead. -*/ - -QPixmap::QPixmap(const QString& fileName, const char *format, ColorMode mode) - : QPaintDevice() -{ - init(0, 0, QPixmapData::PixmapType); - if (!qt_pixmap_thread_test()) - return; - - load(fileName, format, colorModeToFlags(mode)); -} - -/*! - Constructs a pixmap from the QImage \a image. - - Use the static fromImage() function instead. -*/ -QPixmap::QPixmap(const QImage& image) - : QPaintDevice() -{ - init(0, 0, QPixmapData::PixmapType); - if (!qt_pixmap_thread_test()) - return; - - if (data && data->pixelType() == QPixmapData::BitmapType) - *this = QBitmap::fromImage(image); - else - *this = fromImage(image); -} - -/*! - \overload - - Converts the given \a image to a pixmap that is assigned to this - pixmap. - - Use the static fromImage() function instead. -*/ - -QPixmap &QPixmap::operator=(const QImage &image) -{ - if (data && data->pixelType() == QPixmapData::BitmapType) - *this = QBitmap::fromImage(image); - else - *this = fromImage(image); - return *this; -} - -/*! - Use the load() function that takes a Qt::ImageConversionFlag instead. -*/ - -bool QPixmap::load(const QString &fileName, const char *format, ColorMode mode) -{ - return load(fileName, format, colorModeToFlags(mode)); -} - -/*! - Use the loadFromData() function that takes a Qt::ImageConversionFlag instead. -*/ - -bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, ColorMode mode) -{ - return loadFromData(buf, len, format, colorModeToFlags(mode)); -} - -/*! - Use the static fromImage() function instead. -*/ -bool QPixmap::convertFromImage(const QImage &image, ColorMode mode) -{ - if (data && data->pixelType() == QPixmapData::BitmapType) - *this = QBitmap::fromImage(image, colorModeToFlags(mode)); - else - *this = fromImage(image, colorModeToFlags(mode)); - return !isNull(); -} - -#endif - /***************************************************************************** QPixmap stream functions *****************************************************************************/ @@ -1375,34 +1142,6 @@ QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap) #endif // QT_NO_DATASTREAM -#ifdef QT3_SUPPORT -Q_GUI_EXPORT void copyBlt(QPixmap *dst, int dx, int dy, - const QPixmap *src, int sx, int sy, int sw, int sh) -{ - Q_ASSERT_X(dst, "::copyBlt", "Destination pixmap must be non-null"); - Q_ASSERT_X(src, "::copyBlt", "Source pixmap must be non-null"); - - if (src->hasAlphaChannel()) { - if (dst->paintEngine()->hasFeature(QPaintEngine::PorterDuff)) { - QPainter p(dst); - p.setCompositionMode(QPainter::CompositionMode_Source); - p.drawPixmap(dx, dy, *src, sx, sy, sw, sh); - } else { - QImage image = dst->toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied); - QPainter p(&image); - p.setCompositionMode(QPainter::CompositionMode_Source); - p.drawPixmap(dx, dy, *src, sx, sy, sw, sh); - p.end(); - *dst = QPixmap::fromImage(image); - } - } else { - QPainter p(dst); - p.drawPixmap(dx, dy, *src, sx, sy, sw, sh); - } - -} -#endif - /*! \internal */ @@ -1832,23 +1571,7 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) */ bool QPixmap::hasAlpha() const { -#if defined(Q_WS_X11) - if (data && data->hasAlphaChannel()) - return true; - QPixmapData *pd = pixmapData(); - if (pd && pd->classId() == QPixmapData::X11Class) { - QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(pd); -#ifndef QT_NO_XRENDER - if (x11Data->picture && x11Data->d == 32) - return true; -#endif - if (x11Data->d == 1 || x11Data->x11_mask) - return true; - } - return false; -#else return data && data->hasAlphaChannel(); -#endif } /*! @@ -1871,78 +1594,6 @@ int QPixmap::metric(PaintDeviceMetric metric) const } /*! - \fn void QPixmap::setAlphaChannel(const QPixmap &alphaChannel) - \obsolete - - Sets the alpha channel of this pixmap to the given \a alphaChannel - by converting the \a alphaChannel into 32 bit and using the - intensity of the RGB pixel values. - - The effect of this function is undefined when the pixmap is being - painted on. - - \warning This is potentially an expensive operation. Most usecases - for this function are covered by QPainter and compositionModes - which will normally execute faster. - - \sa alphaChannel(), {QPixmap#Pixmap Transformations}{Pixmap - Transformations} - */ -void QPixmap::setAlphaChannel(const QPixmap &alphaChannel) -{ - if (alphaChannel.isNull()) - return; - - if (paintingActive()) { - qWarning("QPixmap::setAlphaChannel: " - "Cannot set alpha channel while pixmap is being painted on"); - return; - } - - if (width() != alphaChannel.width() && height() != alphaChannel.height()) { - qWarning("QPixmap::setAlphaChannel: " - "The pixmap and the alpha channel pixmap must have the same size"); - return; - } - - detach(); - data->setAlphaChannel(alphaChannel); -} - -/*! - \obsolete - - Returns the alpha channel of the pixmap as a new grayscale QPixmap in which - each pixel's red, green, and blue values are given the alpha value of the - original pixmap. The color depth of the returned pixmap is the system depth - on X11 and 8-bit on Windows and Mac OS X. - - You can use this function while debugging - to get a visible image of the alpha channel. If the pixmap doesn't have an - alpha channel, i.e., the alpha channel's value for all pixels equals - 0xff), a null pixmap is returned. You can check this with the \c isNull() - function. - - We show an example: - - \snippet doc/src/snippets/alphachannel.cpp 0 - - \image alphachannelimage.png The pixmap and channelImage QPixmaps - - \warning This is an expensive operation. The alpha channel of the - pixmap is extracted dynamically from the pixeldata. Most usecases of this - function are covered by QPainter and compositionModes which will normally - execute faster. - - \sa setAlphaChannel(), {QPixmap#Pixmap Information}{Pixmap - Information} -*/ -QPixmap QPixmap::alphaChannel() const -{ - return data ? data->alphaChannel() : QPixmap(); -} - -/*! \internal */ QPaintEngine *QPixmap::paintEngine() const @@ -1962,7 +1613,36 @@ QPaintEngine *QPixmap::paintEngine() const */ QBitmap QPixmap::mask() const { - return data ? data->mask() : QBitmap(); + if (!data || !hasAlphaChannel()) + return QBitmap(); + + const QImage img = toImage(); + const QImage image = (img.depth() < 32 ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) : img); + const int w = image.width(); + const int h = image.height(); + + QImage mask(w, h, QImage::Format_MonoLSB); + if (mask.isNull()) // allocation failed + return QBitmap(); + + mask.setColorCount(2); + mask.setColor(0, QColor(Qt::color0).rgba()); + mask.setColor(1, QColor(Qt::color1).rgba()); + + const int bpl = mask.bytesPerLine(); + + for (int y = 0; y < h; ++y) { + const QRgb *src = reinterpret_cast<const QRgb*>(image.scanLine(y)); + uchar *dest = mask.scanLine(y); + memset(dest, 0, bpl); + for (int x = 0; x < w; ++x) { + if (qAlpha(*src) > 0) + dest[x >> 3] |= (1 << (x & 7)); + ++src; + } + } + + return QBitmap::fromImage(mask); } /*! @@ -1977,21 +1657,7 @@ QBitmap QPixmap::mask() const */ int QPixmap::defaultDepth() { -#if defined(Q_WS_QWS) - return QScreen::instance()->depth(); -#elif defined(Q_WS_X11) - return QX11Info::appDepth(); -#elif defined(Q_WS_WINCE) - return QColormap::instance().depth(); -#elif defined(Q_WS_WIN) - return 32; // XXX -#elif defined(Q_WS_MAC) - return 32; -#elif defined(Q_OS_SYMBIAN) - return S60->screenDepth; -#elif defined(Q_WS_QPA) - return 32; //LITE: use graphicssystem (we should do that in general) -#endif + return 32; // LITE: ### use QPlatformScreen (we should do that in general) } /*! @@ -2016,50 +1682,22 @@ void QPixmap::detach() if (!data) return; - // QPixmap.data member may be QRuntimePixmapData so use pixmapData() function to get + // QPixmap.data member may be QRuntimePlatformPixmap so use handle() function to get // the actual underlaying runtime pixmap data. - QPixmapData *pd = pixmapData(); - QPixmapData::ClassId id = pd->classId(); - if (id == QPixmapData::RasterClass) { - QRasterPixmapData *rasterData = static_cast<QRasterPixmapData*>(pd); + QPlatformPixmap *pd = handle(); + QPlatformPixmap::ClassId id = pd->classId(); + if (id == QPlatformPixmap::RasterClass) { + QRasterPlatformPixmap *rasterData = static_cast<QRasterPlatformPixmap*>(pd); rasterData->image.detach(); } if (data->is_cached && data->ref == 1) - QImagePixmapCleanupHooks::executePixmapDataModificationHooks(data.data()); - -#if defined(Q_WS_MAC) - QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(pd) : 0; - if (macData) { - if (macData->cg_mask) { - CGImageRelease(macData->cg_mask); - macData->cg_mask = 0; - } - } -#endif + QImagePixmapCleanupHooks::executePlatformPixmapModificationHooks(data.data()); if (data->ref != 1) { *this = copy(); } ++data->detach_no; - -#if defined(Q_WS_X11) - if (pd->classId() == QPixmapData::X11Class) { - QX11PixmapData *d = static_cast<QX11PixmapData*>(pd); - d->flags &= ~QX11PixmapData::Uninitialized; - - // reset the cache data - if (d->hd2) { - XFreePixmap(X11->display, d->hd2); - d->hd2 = 0; - } - } -#elif defined(Q_WS_MAC) - if (macData) { - macData->macReleaseCGImageRef(); - macData->uninit = false; - } -#endif } /*! @@ -2082,9 +1720,7 @@ QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags) if (image.isNull()) return QPixmap(); - QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem(); - QScopedPointer<QPixmapData> data(gs ? gs->createPixmapData(QPixmapData::PixmapType) - : QGraphicsSystem::createDefaultPixmapData(QPixmapData::PixmapType)); + QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType)); data->fromImage(image, flags); return QPixmap(data.take()); } @@ -2103,9 +1739,7 @@ QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags) */ QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags) { - QGraphicsSystem *gs = QApplicationPrivate::graphicsSystem(); - QScopedPointer<QPixmapData> data(gs ? gs->createPixmapData(QPixmapData::PixmapType) - : QGraphicsSystem::createDefaultPixmapData(QPixmapData::PixmapType)); + QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType)); data->fromImageReader(imageReader, flags); return QPixmap(data.take()); } @@ -2154,14 +1788,9 @@ QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionF /*! \internal */ -QPixmapData* QPixmap::pixmapData() const +QPlatformPixmap* QPixmap::handle() const { - if (data) { - QPixmapData* pm = data.data(); - return pm->runtimeData() ? pm->runtimeData() : pm; - } - - return 0; + return data.data(); } diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index 3012080abb..5d300d1f76 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -52,11 +52,6 @@ QT_BEGIN_HEADER -#if defined(Q_OS_SYMBIAN) -class CFbsBitmap; -class RSgImage; -#endif - QT_BEGIN_NAMESPACE QT_MODULE(Gui) @@ -66,13 +61,13 @@ class QImageReader; class QColor; class QVariant; class QX11Info; -class QPixmapData; +class QPlatformPixmap; class Q_GUI_EXPORT QPixmap : public QPaintDevice { public: QPixmap(); - explicit QPixmap(QPixmapData *data); + explicit QPixmap(QPlatformPixmap *data); QPixmap(int w, int h); QPixmap(const QSize &); QPixmap(const QString& fileName, const char *format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor); @@ -103,32 +98,25 @@ public: static int defaultDepth(); void fill(const QColor &fillColor = Qt::white); - void fill(const QWidget *widget, const QPoint &ofs); - inline void fill(const QWidget *widget, int xofs, int yofs) { fill(widget, QPoint(xofs, yofs)); } + void fill(const QPaintDevice *device, const QPoint &ofs); + inline void fill(const QPaintDevice *device, int xofs, int yofs) { fill(device, QPoint(xofs, yofs)); } QBitmap mask() const; void setMask(const QBitmap &); -#ifdef QT_DEPRECATED - QT_DEPRECATED QPixmap alphaChannel() const; - QT_DEPRECATED void setAlphaChannel(const QPixmap &); -#endif - bool hasAlpha() const; bool hasAlphaChannel() const; #ifndef QT_NO_IMAGE_HEURISTIC_MASK QBitmap createHeuristicMask(bool clipTight = true) const; #endif - QBitmap createMaskFromColor(const QColor &maskColor) const; // ### Qt 5: remove - QBitmap createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const; + QBitmap createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode = Qt::MaskInColor) const; static QPixmap grabWindow(WId, int x=0, int y=0, int w=-1, int h=-1); - static QPixmap grabWidget(QWidget *widget, const QRect &rect); - static inline QPixmap grabWidget(QWidget *widget, int x=0, int y=0, int w=-1, int h=-1) + static QPixmap grabWidget(QObject *widget, const QRect &rect); + static inline QPixmap grabWidget(QObject *widget, int x=0, int y=0, int w=-1, int h=-1) { return grabWidget(widget, QRect(x, y, w, h)); } - inline QPixmap scaled(int w, int h, Qt::AspectRatioMode aspectMode = Qt::IgnoreAspectRatio, Qt::TransformationMode mode = Qt::FastTransformation) const { return scaled(QSize(w, h), aspectMode, mode); } @@ -153,32 +141,6 @@ public: bool convertFromImage(const QImage &img, Qt::ImageConversionFlags flags = Qt::AutoColor); -#if defined(Q_WS_WIN) - enum HBitmapFormat { - NoAlpha, - PremultipliedAlpha, - Alpha - }; - - HBITMAP toWinHBITMAP(HBitmapFormat format = NoAlpha) const; - HICON toWinHICON() const; - - static QPixmap fromWinHBITMAP(HBITMAP hbitmap, HBitmapFormat format = NoAlpha); - static QPixmap fromWinHICON(HICON hicon); -#endif - -#if defined(Q_WS_MAC) - CGImageRef toMacCGImageRef() const; - static QPixmap fromMacCGImageRef(CGImageRef image); -#endif - -#if defined(Q_OS_SYMBIAN) - CFbsBitmap *toSymbianCFbsBitmap() const; - static QPixmap fromSymbianCFbsBitmap(CFbsBitmap *bitmap); - RSgImage* toSymbianRSgImage() const; - static QPixmap fromSymbianRSgImage(RSgImage *sgImage); -#endif - inline QPixmap copy(int x, int y, int width, int height) const; QPixmap copy(const QRect &rect = QRect()) const; @@ -195,105 +157,43 @@ public: bool isQBitmap() const; -#if defined(Q_WS_QWS) - const uchar *qwsBits() const; - int qwsBytesPerLine() const; - QRgb *clut() const; -#ifdef QT_DEPRECATED - QT_DEPRECATED int numCols() const; -#endif - int colorCount() const; -#elif defined(Q_WS_MAC) - Qt::HANDLE macQDHandle() const; - Qt::HANDLE macQDAlphaHandle() const; - Qt::HANDLE macCGHandle() const; -#elif defined(Q_WS_X11) - enum ShareMode { ImplicitlyShared, ExplicitlyShared }; - - static QPixmap fromX11Pixmap(Qt::HANDLE pixmap, ShareMode mode = ImplicitlyShared); - static int x11SetDefaultScreen(int screen); - void x11SetScreen(int screen); - const QX11Info &x11Info() const; - Qt::HANDLE x11PictureHandle() const; -#endif - -#if defined(Q_WS_X11) || defined(Q_WS_QWS) - Qt::HANDLE handle() const; -#endif - QPaintEngine *paintEngine() const; inline bool operator!() const { return isNull(); } +#if QT_DEPRECATED_SINCE(5, 0) + QT_DEPRECATED inline QPixmap alphaChannel() const; + QT_DEPRECATED inline void setAlphaChannel(const QPixmap &); +#endif + protected: int metric(PaintDeviceMetric) const; -#ifdef QT3_SUPPORT -public: - enum ColorMode { Auto, Color, Mono }; - QT3_SUPPORT_CONSTRUCTOR QPixmap(const QString& fileName, const char *format, ColorMode mode); - QT3_SUPPORT bool load(const QString& fileName, const char *format, ColorMode mode); - QT3_SUPPORT bool loadFromData(const uchar *buf, uint len, const char* format, ColorMode mode); - QT3_SUPPORT_CONSTRUCTOR QPixmap(const QImage& image); - QT3_SUPPORT QPixmap &operator=(const QImage &); - inline QT3_SUPPORT QImage convertToImage() const { return toImage(); } - QT3_SUPPORT bool convertFromImage(const QImage &, ColorMode mode); - inline QT3_SUPPORT operator QImage() const { return toImage(); } - inline QT3_SUPPORT QPixmap xForm(const QMatrix &matrix) const { return transformed(QTransform(matrix)); } - inline QT3_SUPPORT bool selfMask() const { return false; } -private: - void resize_helper(const QSize &s); -public: - inline QT3_SUPPORT void resize(const QSize &s) { resize_helper(s); } - inline QT3_SUPPORT void resize(int width, int height) { resize_helper(QSize(width, height)); } -#endif - private: - QExplicitlySharedDataPointer<QPixmapData> data; + QExplicitlySharedDataPointer<QPlatformPixmap> data; bool doImageIO(QImageWriter *io, int quality) const; - // ### Qt5: remove the following three lines - enum Type { PixmapType, BitmapType }; // must match QPixmapData::PixelType - QPixmap(const QSize &s, Type); - void init(int, int, Type = PixmapType); - QPixmap(const QSize &s, int type); - void init(int, int, int); + void doInit(int, int, int); void deref(); -#if defined(Q_WS_WIN) - void initAlphaPixmap(uchar *bytes, int length, struct tagBITMAPINFO *bmi); -#endif Q_DUMMY_COMPARISON_OPERATOR(QPixmap) -#ifdef Q_WS_MAC - friend CGContextRef qt_mac_cg_context(const QPaintDevice*); - friend CGImageRef qt_mac_create_imagemask(const QPixmap&, const QRectF&); - friend IconRef qt_mac_create_iconref(const QPixmap&); - friend quint32 *qt_mac_pixmap_get_base(const QPixmap*); - friend int qt_mac_pixmap_get_bytes_per_line(const QPixmap*); -#endif - friend class QPixmapData; - friend class QX11PixmapData; - friend class QMacPixmapData; - friend class QS60PixmapData; + friend class QPlatformPixmap; friend class QBitmap; friend class QPaintDevice; friend class QPainter; - friend class QGLWidget; - friend class QX11PaintEngine; - friend class QCoreGraphicsPaintEngine; + friend class QOpenGLWidget; friend class QWidgetPrivate; friend class QRasterBuffer; #if !defined(QT_NO_DATASTREAM) friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QPixmap &); #endif - friend Q_GUI_EXPORT qint64 qt_pixmap_id(const QPixmap &pixmap); public: - QPixmapData* pixmapData() const; + QPlatformPixmap* handle() const; public: - typedef QExplicitlySharedDataPointer<QPixmapData> DataPtr; + typedef QExplicitlySharedDataPointer<QPlatformPixmap> DataPtr; inline DataPtr &data_ptr() { return data; } }; @@ -315,6 +215,22 @@ inline bool QPixmap::loadFromData(const QByteArray &buf, const char *format, return loadFromData(reinterpret_cast<const uchar *>(buf.constData()), buf.size(), format, flags); } +#if QT_DEPRECATED_SINCE(5, 0) +inline QPixmap QPixmap::alphaChannel() const +{ + return toImage().alphaChannel(); +} + +inline void QPixmap::setAlphaChannel(const QPixmap &p) +{ + detach(); + QImage image = data->toImage(); + image.setAlphaChannel(p.toImage()); + data->fromImage(image); + +} +#endif + /***************************************************************************** QPixmap stream functions *****************************************************************************/ @@ -324,14 +240,6 @@ Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QPixmap &); Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QPixmap &); #endif -/***************************************************************************** - QPixmap (and QImage) helper functions -*****************************************************************************/ -#ifdef QT3_SUPPORT -QT3_SUPPORT Q_GUI_EXPORT void copyBlt(QPixmap *dst, int dx, int dy, const QPixmap *src, - int sx=0, int sy=0, int sw=-1, int sh=-1); -#endif // QT3_SUPPORT - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp index f3a4318032..dc0f03abdc 100644 --- a/src/gui/image/qpixmap_blitter.cpp +++ b/src/gui/image/qpixmap_blitter.cpp @@ -43,9 +43,9 @@ #include <qpainter.h> #include <qimage.h> +#include <qscreen.h> -#include <private/qapplication_p.h> -#include <private/qgraphicssystem_p.h> +#include <private/qguiapplication_p.h> #include <private/qblittable_p.h> #include <private/qdrawhelper_p.h> @@ -56,8 +56,8 @@ QT_BEGIN_NAMESPACE static int global_ser_no = 0; -QBlittablePixmapData::QBlittablePixmapData() - : QPixmapData(QPixmapData::PixmapType,BlitterClass), m_engine(0), m_blittable(0) +QBlittablePlatformPixmap::QBlittablePlatformPixmap() + : QPlatformPixmap(QPlatformPixmap::PixmapType,BlitterClass), m_engine(0), m_blittable(0) #ifdef QT_BLITTER_RASTEROVERLAY ,m_rasterOverlay(0), m_unmergedCopy(0) #endif //QT_BLITTER_RASTEROVERLAY @@ -65,7 +65,7 @@ QBlittablePixmapData::QBlittablePixmapData() setSerialNumber(++global_ser_no); } -QBlittablePixmapData::~QBlittablePixmapData() +QBlittablePlatformPixmap::~QBlittablePlatformPixmap() { delete m_blittable; delete m_engine; @@ -75,23 +75,23 @@ QBlittablePixmapData::~QBlittablePixmapData() #endif //QT_BLITTER_RASTEROVERLAY } -QBlittable *QBlittablePixmapData::blittable() const +QBlittable *QBlittablePlatformPixmap::blittable() const { if (!m_blittable) { - QBlittablePixmapData *that = const_cast<QBlittablePixmapData *>(this); + QBlittablePlatformPixmap *that = const_cast<QBlittablePlatformPixmap *>(this); that->m_blittable = this->createBlittable(QSize(w,h)); } return m_blittable; } -void QBlittablePixmapData::setBlittable(QBlittable *blittable) +void QBlittablePlatformPixmap::setBlittable(QBlittable *blittable) { resize(blittable->size().width(),blittable->size().height()); m_blittable = blittable; } -void QBlittablePixmapData::resize(int width, int height) +void QBlittablePlatformPixmap::resize(int width, int height) { delete m_blittable; @@ -99,14 +99,14 @@ void QBlittablePixmapData::resize(int width, int height) delete m_engine; m_engine = 0; #ifdef Q_WS_QPA - d = QApplicationPrivate::platformIntegration()->screens().at(0)->depth(); + d = QGuiApplication::primaryScreen()->depth(); #endif w = width; h = height; is_null = (w <= 0 || h <= 0); } -int QBlittablePixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const +int QBlittablePlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const { switch (metric) { case QPaintDevice::PdmWidth: @@ -126,14 +126,14 @@ int QBlittablePixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const case QPaintDevice::PdmPhysicalDpiY: return qt_defaultDpiY(); default: - qWarning("QRasterPixmapData::metric(): Unhandled metric type %d", metric); + qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric); break; } return 0; } -void QBlittablePixmapData::fill(const QColor &color) +void QBlittablePlatformPixmap::fill(const QColor &color) { //jlind: todo: change when blittables can support non opaque fillRects if (color.alpha() == 255 && blittable()->capabilities() & QBlittable::SolidRectCapability) { @@ -167,22 +167,22 @@ void QBlittablePixmapData::fill(const QColor &color) } -QImage *QBlittablePixmapData::buffer() +QImage *QBlittablePlatformPixmap::buffer() { return blittable()->lock(); } -QImage QBlittablePixmapData::toImage() const +QImage QBlittablePlatformPixmap::toImage() const { return blittable()->lock()->copy(); } -bool QBlittablePixmapData::hasAlphaChannel() const +bool QBlittablePlatformPixmap::hasAlphaChannel() const { return blittable()->lock()->hasAlphaChannel(); } -void QBlittablePixmapData::fromImage(const QImage &image, +void QBlittablePlatformPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags) { resize(image.width(),image.height()); @@ -204,10 +204,10 @@ void QBlittablePixmapData::fromImage(const QImage &image, } } -QPaintEngine *QBlittablePixmapData::paintEngine() const +QPaintEngine *QBlittablePlatformPixmap::paintEngine() const { if (!m_engine) { - QBlittablePixmapData *that = const_cast<QBlittablePixmapData *>(this); + QBlittablePlatformPixmap *that = const_cast<QBlittablePlatformPixmap *>(this); that->m_engine = new QBlitterPaintEngine(that); } return m_engine; @@ -217,7 +217,7 @@ QPaintEngine *QBlittablePixmapData::paintEngine() const static bool showRasterOverlay = !qgetenv("QT_BLITTER_RASTEROVERLAY").isEmpty(); -void QBlittablePixmapData::mergeOverlay() +void QBlittablePlatformPixmap::mergeOverlay() { if (m_unmergedCopy || !showRasterOverlay) return; @@ -228,7 +228,7 @@ void QBlittablePixmapData::mergeOverlay() p.end(); } -void QBlittablePixmapData::unmergeOverlay() +void QBlittablePlatformPixmap::unmergeOverlay() { if (!m_unmergedCopy || !showRasterOverlay) return; @@ -241,7 +241,7 @@ void QBlittablePixmapData::unmergeOverlay() m_unmergedCopy = 0; } -QImage *QBlittablePixmapData::overlay() +QImage *QBlittablePlatformPixmap::overlay() { if (!m_rasterOverlay|| m_rasterOverlay->size() != QSize(w,h)){ @@ -255,7 +255,7 @@ QImage *QBlittablePixmapData::overlay() return m_rasterOverlay; } -void QBlittablePixmapData::markRasterOverlayImpl(const QRectF &rect) +void QBlittablePlatformPixmap::markRasterOverlayImpl(const QRectF &rect) { if (!showRasterOverlay) return; @@ -268,7 +268,7 @@ void QBlittablePixmapData::markRasterOverlayImpl(const QRectF &rect) } } -void QBlittablePixmapData::unmarkRasterOverlayImpl(const QRectF &rect) +void QBlittablePlatformPixmap::unmarkRasterOverlayImpl(const QRectF &rect) { if (!showRasterOverlay) return; @@ -282,7 +282,7 @@ void QBlittablePixmapData::unmarkRasterOverlayImpl(const QRectF &rect) } } -QRectF QBlittablePixmapData::clipAndTransformRect(const QRectF &rect) const +QRectF QBlittablePlatformPixmap::clipAndTransformRect(const QRectF &rect) const { QRectF transformationRect = rect; paintEngine(); diff --git a/src/gui/image/qpixmap_blitter_p.h b/src/gui/image/qpixmap_blitter_p.h index 07791e548b..3ab5cb3da3 100644 --- a/src/gui/image/qpixmap_blitter_p.h +++ b/src/gui/image/qpixmap_blitter_p.h @@ -42,18 +42,18 @@ #ifndef QPIXMAP_BLITTER_P_H #define QPIXMAP_BLITTER_P_H -#include <private/qpixmapdata_p.h> +#include <qplatformpixmap_qpa.h> #include <private/qpaintengine_blitter_p.h> #ifndef QT_NO_BLITTABLE QT_BEGIN_NAMESPACE -class Q_GUI_EXPORT QBlittablePixmapData : public QPixmapData +class Q_GUI_EXPORT QBlittablePlatformPixmap : public QPlatformPixmap { -// Q_DECLARE_PRIVATE(QBlittablePixmapData); +// Q_DECLARE_PRIVATE(QBlittablePlatformPixmap); public: - QBlittablePixmapData(); - ~QBlittablePixmapData(); + QBlittablePlatformPixmap(); + ~QBlittablePlatformPixmap(); virtual QBlittable *createBlittable(const QSize &size) const = 0; QBlittable *blittable() const; @@ -98,7 +98,7 @@ protected: }; -inline void QBlittablePixmapData::markRasterOverlay(const QRectF &rect) +inline void QBlittablePlatformPixmap::markRasterOverlay(const QRectF &rect) { #ifdef QT_BLITTER_RASTEROVERLAY markRasterOverlayImpl(rect); @@ -107,7 +107,7 @@ inline void QBlittablePixmapData::markRasterOverlay(const QRectF &rect) #endif } -inline void QBlittablePixmapData::markRasterOverlay(const QVectorPath &path) +inline void QBlittablePlatformPixmap::markRasterOverlay(const QVectorPath &path) { #ifdef QT_BLITTER_RASTEROVERLAY markRasterOverlayImpl(path.convertToPainterPath().boundingRect()); @@ -116,7 +116,7 @@ inline void QBlittablePixmapData::markRasterOverlay(const QVectorPath &path) #endif } -inline void QBlittablePixmapData::markRasterOverlay(const QPointF &pos, const QTextItem &ti) +inline void QBlittablePlatformPixmap::markRasterOverlay(const QPointF &pos, const QTextItem &ti) { #ifdef QT_BLITTER_RASTEROVERLAY QFontMetricsF fm(ti.font()); @@ -129,7 +129,7 @@ inline void QBlittablePixmapData::markRasterOverlay(const QPointF &pos, const QT #endif } -inline void QBlittablePixmapData::markRasterOverlay(const QRect *rects, int rectCount) +inline void QBlittablePlatformPixmap::markRasterOverlay(const QRect *rects, int rectCount) { #ifdef QT_BLITTER_RASTEROVERLAY for (int i = 0; i < rectCount; i++) { @@ -140,7 +140,7 @@ inline void QBlittablePixmapData::markRasterOverlay(const QRect *rects, int rect Q_UNUSED(rectCount) #endif } -inline void QBlittablePixmapData::markRasterOverlay(const QRectF *rects, int rectCount) +inline void QBlittablePlatformPixmap::markRasterOverlay(const QRectF *rects, int rectCount) { #ifdef QT_BLITTER_RASTEROVERLAY for (int i = 0; i < rectCount; i++) { @@ -152,7 +152,7 @@ inline void QBlittablePixmapData::markRasterOverlay(const QRectF *rects, int rec #endif } -inline void QBlittablePixmapData::unmarkRasterOverlay(const QRectF &rect) +inline void QBlittablePlatformPixmap::unmarkRasterOverlay(const QRectF &rect) { #ifdef QT_BLITTER_RASTEROVERLAY unmarkRasterOverlayImpl(rect); diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp deleted file mode 100644 index 47b6eef761..0000000000 --- a/src/gui/image/qpixmap_mac.cpp +++ /dev/null @@ -1,1233 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpixmap.h" -#include "qimage.h" -#include "qapplication.h" -#include "qbitmap.h" -#include "qmatrix.h" -#include "qtransform.h" -#include "qlibrary.h" -#include "qvarlengtharray.h" -#include "qdebug.h" -#include <private/qdrawhelper_p.h> -#include <private/qpixmap_mac_p.h> -#include <private/qpixmap_raster_p.h> -#include <private/qpaintengine_mac_p.h> -#include <private/qt_mac_p.h> -#include <private/qt_cocoa_helpers_mac_p.h> -#include <private/qapplication_p.h> - -#include <limits.h> -#include <string.h> - -QT_BEGIN_NAMESPACE - -/***************************************************************************** - Externals - *****************************************************************************/ -extern const uchar *qt_get_bitflip_array(); //qimage.cpp -extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev); //qpaintdevice_mac.cpp -extern RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp -extern void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp -extern QRegion qt_mac_convert_mac_region(RgnHandle rgn); //qregion_mac.cpp - -static int qt_pixmap_serial = 0; - -Q_GUI_EXPORT quint32 *qt_mac_pixmap_get_base(const QPixmap *pix) -{ - if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) - return reinterpret_cast<quint32 *>(static_cast<QRasterPixmapData*>(pix->data.data())->buffer()->bits()); - else - return static_cast<QMacPixmapData*>(pix->data.data())->pixels; -} - -Q_GUI_EXPORT int qt_mac_pixmap_get_bytes_per_line(const QPixmap *pix) -{ - if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) - return static_cast<QRasterPixmapData*>(pix->data.data())->buffer()->bytesPerLine(); - else - return static_cast<QMacPixmapData*>(pix->data.data())->bytesPerRow; -} - -void qt_mac_cgimage_data_free(void *info, const void *memoryToFree, size_t) -{ - QMacPixmapData *pmdata = static_cast<QMacPixmapData *>(info); - if (!pmdata) { - free(const_cast<void *>(memoryToFree)); - } else { - if (QMacPixmapData::validDataPointers.contains(pmdata) == false) { - free(const_cast<void *>(memoryToFree)); - return; - } - if (pmdata->pixels == pmdata->pixelsToFree) { - // something we aren't expecting, just free it. - Q_ASSERT(memoryToFree != pmdata->pixelsToFree); - free(const_cast<void *>(memoryToFree)); - } else { - free(pmdata->pixelsToFree); - pmdata->pixelsToFree = static_cast<quint32 *>(const_cast<void *>(memoryToFree)); - } - pmdata->cg_dataBeingReleased = 0; - } -} - -CGImageRef qt_mac_image_to_cgimage(const QImage &image) -{ - int bitsPerColor = 8; - int bitsPerPixel = 32; - if (image.depth() == 1) { - bitsPerColor = 1; - bitsPerPixel = 1; - } - QCFType<CGDataProviderRef> provider = - CGDataProviderCreateWithData(0, image.bits(), image.bytesPerLine() * image.height(), - 0); - - uint cgflags = kCGImageAlphaPremultipliedFirst; -#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - cgflags |= kCGBitmapByteOrder32Host; -#endif - - CGImageRef cgImage = CGImageCreate(image.width(), image.height(), bitsPerColor, bitsPerPixel, - image.bytesPerLine(), - QCoreGraphicsPaintEngine::macGenericColorSpace(), - cgflags, provider, - 0, - 0, - kCGRenderingIntentDefault); - - return cgImage; -} - -/***************************************************************************** - QPixmap member functions - *****************************************************************************/ - -static inline QRgb qt_conv16ToRgb(ushort c) { - static const int qt_rbits = (565/100); - static const int qt_gbits = (565/10%10); - static const int qt_bbits = (565%10); - static const int qt_red_shift = qt_bbits+qt_gbits-(8-qt_rbits); - static const int qt_green_shift = qt_bbits-(8-qt_gbits); - static const int qt_neg_blue_shift = 8-qt_bbits; - static const int qt_blue_mask = (1<<qt_bbits)-1; - static const int qt_green_mask = (1<<(qt_gbits+qt_bbits))-((1<<qt_bbits)-1); - static const int qt_red_mask = (1<<(qt_rbits+qt_gbits+qt_bbits))-(1<<(qt_gbits+qt_bbits)); - - const int r=(c & qt_red_mask); - const int g=(c & qt_green_mask); - const int b=(c & qt_blue_mask); - const int tr = r >> qt_red_shift; - const int tg = g >> qt_green_shift; - const int tb = b << qt_neg_blue_shift; - - return qRgb(tr,tg,tb); -} - -QSet<QMacPixmapData*> QMacPixmapData::validDataPointers; - -QMacPixmapData::QMacPixmapData(PixelType type) - : QPixmapData(type, MacClass), has_alpha(0), has_mask(0), - uninit(true), pixels(0), pixelsSize(0), pixelsToFree(0), - bytesPerRow(0), cg_data(0), cg_dataBeingReleased(0), cg_mask(0), - pengine(0) -{ -} - -QPixmapData *QMacPixmapData::createCompatiblePixmapData() const -{ - return new QMacPixmapData(pixelType()); -} - -#define BEST_BYTE_ALIGNMENT 16 -#define COMPTUE_BEST_BYTES_PER_ROW(bpr) \ - (((bpr) + (BEST_BYTE_ALIGNMENT - 1)) & ~(BEST_BYTE_ALIGNMENT - 1)) - -void QMacPixmapData::resize(int width, int height) -{ - setSerialNumber(++qt_pixmap_serial); - - w = width; - h = height; - is_null = (w <= 0 || h <= 0); - d = (pixelType() == BitmapType ? 1 : 32); - bool make_null = w <= 0 || h <= 0; // create null pixmap - if (make_null || d == 0) { - w = 0; - h = 0; - is_null = true; - d = 0; - if (!make_null) - qWarning("Qt: QPixmap: Invalid pixmap parameters"); - return; - } - - if (w < 1 || h < 1) - return; - - //create the pixels - bytesPerRow = w * sizeof(quint32); // Minimum bytes per row. - - // Quartz2D likes things as a multple of 16 (for now). - bytesPerRow = COMPTUE_BEST_BYTES_PER_ROW(bytesPerRow); - macCreatePixels(); -} - -#undef COMPUTE_BEST_BYTES_PER_ROW - -void QMacPixmapData::fromImage(const QImage &img, - Qt::ImageConversionFlags flags) -{ - setSerialNumber(++qt_pixmap_serial); - - // the conversion code only handles format >= - // Format_ARGB32_Premultiplied at the moment.. - if (img.format() > QImage::Format_ARGB32_Premultiplied) { - QImage image; - if (img.hasAlphaChannel()) - image = img.convertToFormat(QImage::Format_ARGB32_Premultiplied); - else - image = img.convertToFormat(QImage::Format_RGB32); - fromImage(image, flags); - return; - } - - w = img.width(); - h = img.height(); - is_null = (w <= 0 || h <= 0); - d = (pixelType() == BitmapType ? 1 : img.depth()); - - QImage image = img; - int dd = QPixmap::defaultDepth(); - bool force_mono = (dd == 1 || - (flags & Qt::ColorMode_Mask)==Qt::MonoOnly); - if (force_mono) { // must be monochrome - if (d != 1) { - image = image.convertToFormat(QImage::Format_MonoLSB, flags); // dither - d = 1; - } - } else { // can be both - bool conv8 = false; - if(d > 8 && dd <= 8) { // convert to 8 bit - if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither) - flags = (flags & ~Qt::DitherMode_Mask) - | Qt::PreferDither; - conv8 = true; - } else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) { - conv8 = d == 1; // native depth wanted - } else if (d == 1) { - if (image.colorCount() == 2) { - QRgb c0 = image.color(0); // Auto: convert to best - QRgb c1 = image.color(1); - conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255); - } else { - // eg. 1-color monochrome images (they do exist). - conv8 = true; - } - } - if (conv8) { - image = image.convertToFormat(QImage::Format_Indexed8, flags); - d = 8; - } - } - - if (image.depth()==1) { - image.setColor(0, QColor(Qt::color0).rgba()); - image.setColor(1, QColor(Qt::color1).rgba()); - } - - if (d == 16 || d == 24) { - image = image.convertToFormat(QImage::Format_RGB32, flags); - fromImage(image, flags); - return; - } - - // different size or depth, make a new pixmap - resize(w, h); - - quint32 *dptr = pixels, *drow; - const uint dbpr = bytesPerRow; - - const QImage::Format sfmt = image.format(); - const unsigned short sbpr = image.bytesPerLine(); - - // use const_cast to prevent a detach - const uchar *sptr = const_cast<const QImage &>(image).bits(), *srow; - - for (int y = 0; y < h; ++y) { - drow = dptr + (y * (dbpr / 4)); - srow = sptr + (y * sbpr); - switch(sfmt) { - case QImage::Format_MonoLSB: - case QImage::Format_Mono:{ - for (int x = 0; x < w; ++x) { - char one_bit = *(srow + (x / 8)); - if (sfmt == QImage::Format_Mono) - one_bit = one_bit >> (7 - (x % 8)); - else - one_bit = one_bit >> (x % 8); - if ((one_bit & 0x01)) - *(drow+x) = 0xFF000000; - else - *(drow+x) = 0xFFFFFFFF; - } - break; - } - case QImage::Format_Indexed8: { - int numColors = image.numColors(); - if (numColors > 0) { - for (int x = 0; x < w; ++x) { - int index = *(srow + x); - *(drow+x) = PREMUL(image.color(qMin(index, numColors))); - } - } - } break; - case QImage::Format_RGB32: - for (int x = 0; x < w; ++x) - *(drow+x) = *(((quint32*)srow) + x) | 0xFF000000; - break; - case QImage::Format_ARGB32: - case QImage::Format_ARGB32_Premultiplied: - for (int x = 0; x < w; ++x) { - if(sfmt == QImage::Format_RGB32) - *(drow+x) = 0xFF000000 | (*(((quint32*)srow) + x) & 0x00FFFFFF); - else if(sfmt == QImage::Format_ARGB32_Premultiplied) - *(drow+x) = *(((quint32*)srow) + x); - else - *(drow+x) = PREMUL(*(((quint32*)srow) + x)); - } - break; - default: - qWarning("Qt: internal: Oops: Forgot a format [%d] %s:%d", sfmt, - __FILE__, __LINE__); - break; - } - } - if (sfmt != QImage::Format_RGB32) { //setup the alpha - bool alphamap = image.depth() == 32; - if (sfmt == QImage::Format_Indexed8) { - const QVector<QRgb> rgb = image.colorTable(); - for (int i = 0, count = image.colorCount(); i < count; ++i) { - const int alpha = qAlpha(rgb[i]); - if (alpha != 0xff) { - alphamap = true; - break; - } - } - } - macSetHasAlpha(alphamap); - } - uninit = false; -} - -int get_index(QImage * qi,QRgb mycol) -{ - int loopc; - for(loopc=0;loopc<qi->colorCount();loopc++) { - if(qi->color(loopc)==mycol) - return loopc; - } - qi->setColorCount(qi->colorCount()+1); - qi->setColor(qi->colorCount(),mycol); - return qi->colorCount(); -} - -QImage QMacPixmapData::toImage() const -{ - QImage::Format format = QImage::Format_MonoLSB; - if (d != 1) //Doesn't support index color modes - format = (has_alpha ? QImage::Format_ARGB32_Premultiplied : - QImage::Format_RGB32); - - QImage image(w, h, format); - quint32 *sptr = pixels, *srow; - const uint sbpr = bytesPerRow; - if (format == QImage::Format_MonoLSB) { - image.fill(0); - image.setColorCount(2); - image.setColor(0, QColor(Qt::color0).rgba()); - image.setColor(1, QColor(Qt::color1).rgba()); - for (int y = 0; y < h; ++y) { - uchar *scanLine = image.scanLine(y); - srow = sptr + (y * (sbpr/4)); - for (int x = 0; x < w; ++x) { - if (!(*(srow + x) & RGB_MASK)) - scanLine[x >> 3] |= (1 << (x & 7)); - } - } - } else { - for (int y = 0; y < h; ++y) { - srow = sptr + (y * (sbpr / 4)); - memcpy(image.scanLine(y), srow, w * 4); - } - - } - - return image; -} - -void QMacPixmapData::fill(const QColor &fillColor) - -{ - { //we don't know what backend to use so we cannot paint here - quint32 *dptr = pixels; - Q_ASSERT_X(dptr, "QPixmap::fill", "No dptr"); - const quint32 colr = PREMUL(fillColor.rgba()); - const int nbytes = bytesPerRow * h; - if (!colr) { - memset(dptr, 0, nbytes); - } else { - for (uint i = 0; i < nbytes / sizeof(quint32); ++i) - *(dptr + i) = colr; - } - } - - // If we had an alpha channel from before, don't - // switch it off. Only go from no alpha to alpha: - if (fillColor.alpha() != 255) - macSetHasAlpha(true); -} - -QPixmap QMacPixmapData::alphaChannel() const -{ - if (!has_alpha) - return QPixmap(); - - QMacPixmapData *alpha = new QMacPixmapData(PixmapType); - alpha->resize(w, h); - macGetAlphaChannel(alpha, false); - return QPixmap(alpha); -} - -void QMacPixmapData::setAlphaChannel(const QPixmap &alpha) -{ - has_mask = true; - QMacPixmapData *alphaData = static_cast<QMacPixmapData*>(alpha.data.data()); - macSetAlphaChannel(alphaData, false); -} - -QBitmap QMacPixmapData::mask() const -{ - if (!has_mask && !has_alpha) - return QBitmap(); - - QMacPixmapData *mask = new QMacPixmapData(BitmapType); - mask->resize(w, h); - macGetAlphaChannel(mask, true); - return QPixmap(mask); -} - -void QMacPixmapData::setMask(const QBitmap &mask) -{ - if (mask.isNull()) { - QMacPixmapData opaque(PixmapType); - opaque.resize(w, h); - opaque.fill(QColor(255, 255, 255, 255)); - macSetAlphaChannel(&opaque, true); - has_alpha = has_mask = false; - return; - } - - has_alpha = false; - has_mask = true; - QMacPixmapData *maskData = static_cast<QMacPixmapData*>(mask.data.data()); - macSetAlphaChannel(maskData, true); -} - -int QMacPixmapData::metric(QPaintDevice::PaintDeviceMetric theMetric) const -{ - switch (theMetric) { - case QPaintDevice::PdmWidth: - return w; - case QPaintDevice::PdmHeight: - return h; - case QPaintDevice::PdmWidthMM: - return qRound(metric(QPaintDevice::PdmWidth) * 25.4 / qreal(metric(QPaintDevice::PdmDpiX))); - case QPaintDevice::PdmHeightMM: - return qRound(metric(QPaintDevice::PdmHeight) * 25.4 / qreal(metric(QPaintDevice::PdmDpiY))); - case QPaintDevice::PdmNumColors: - return 1 << d; - case QPaintDevice::PdmDpiX: - case QPaintDevice::PdmPhysicalDpiX: { - extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp - return int(qt_mac_defaultDpi_x()); - } - case QPaintDevice::PdmDpiY: - case QPaintDevice::PdmPhysicalDpiY: { - extern float qt_mac_defaultDpi_y(); //qpaintdevice_mac.cpp - return int(qt_mac_defaultDpi_y()); - } - case QPaintDevice::PdmDepth: - return d; - default: - qWarning("QPixmap::metric: Invalid metric command"); - } - return 0; -} - -QMacPixmapData::~QMacPixmapData() -{ - validDataPointers.remove(this); - if (cg_mask) { - CGImageRelease(cg_mask); - cg_mask = 0; - } - - delete pengine; // Make sure we aren't drawing on the context anymore. - if (cg_data) { - CGImageRelease(cg_data); - } else if (!cg_dataBeingReleased && pixels != pixelsToFree) { - free(pixels); - } - free(pixelsToFree); -} - -void QMacPixmapData::macSetAlphaChannel(const QMacPixmapData *pix, bool asMask) -{ - if (!pixels || !h || !w || pix->w != w || pix->h != h) - return; - - quint32 *dptr = pixels, *drow; - const uint dbpr = bytesPerRow; - const unsigned short sbpr = pix->bytesPerRow; - quint32 *sptr = pix->pixels, *srow; - for (int y=0; y < h; ++y) { - drow = dptr + (y * (dbpr/4)); - srow = sptr + (y * (sbpr/4)); - if(d == 1) { - for (int x=0; x < w; ++x) { - if((*(srow+x) & RGB_MASK)) - *(drow+x) = 0xFFFFFFFF; - } - } else if(d == 8) { - for (int x=0; x < w; ++x) - *(drow+x) = (*(drow+x) & RGB_MASK) | (*(srow+x) << 24); - } else if(asMask) { - for (int x=0; x < w; ++x) { - if(*(srow+x) & RGB_MASK) - *(drow+x) = (*(drow+x) & RGB_MASK); - else - *(drow+x) = (*(drow+x) & RGB_MASK) | 0xFF000000; - *(drow+x) = PREMUL(*(drow+x)); - } - } else { - for (int x=0; x < w; ++x) { - const uchar alpha = qGray(qRed(*(srow+x)), qGreen(*(srow+x)), qBlue(*(srow+x))); - const uchar destAlpha = qt_div_255(alpha * qAlpha(*(drow+x))); -#if 1 - *(drow+x) = (*(drow+x) & RGB_MASK) | (destAlpha << 24); -#else - *(drow+x) = qRgba(qt_div_255(qRed(*(drow+x) * alpha)), - qt_div_255(qGreen(*(drow+x) * alpha)), - qt_div_255(qBlue(*(drow+x) * alpha)), destAlpha); -#endif - *(drow+x) = PREMUL(*(drow+x)); - } - } - } - macSetHasAlpha(true); -} - -void QMacPixmapData::macGetAlphaChannel(QMacPixmapData *pix, bool asMask) const -{ - quint32 *dptr = pix->pixels, *drow; - const uint dbpr = pix->bytesPerRow; - const unsigned short sbpr = bytesPerRow; - quint32 *sptr = pixels, *srow; - for(int y=0; y < h; ++y) { - drow = dptr + (y * (dbpr/4)); - srow = sptr + (y * (sbpr/4)); - if(asMask) { - for (int x = 0; x < w; ++x) { - if (*(srow + x) & qRgba(0, 0, 0, 255)) - *(drow + x) = 0x00000000; - else - *(drow + x) = 0xFFFFFFFF; - } - } else { - for (int x = 0; x < w; ++x) { - const int alpha = qAlpha(*(srow + x)); - *(drow + x) = qRgb(alpha, alpha, alpha); - } - } - } -} - -void QMacPixmapData::macSetHasAlpha(bool b) -{ - has_alpha = b; - macReleaseCGImageRef(); -} - -void QMacPixmapData::macCreateCGImageRef() -{ - Q_ASSERT(cg_data == 0); - //create the cg data - CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macDisplayColorSpace(); - QCFType<CGDataProviderRef> provider = CGDataProviderCreateWithData(this, - pixels, bytesPerRow * h, - qt_mac_cgimage_data_free); - validDataPointers.insert(this); - uint cgflags = kCGImageAlphaPremultipliedFirst; -#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - cgflags |= kCGBitmapByteOrder32Host; -#endif - cg_data = CGImageCreate(w, h, 8, 32, bytesPerRow, colorspace, - cgflags, provider, 0, 0, kCGRenderingIntentDefault); -} - -void QMacPixmapData::macReleaseCGImageRef() -{ - if (!cg_data) - return; // There's nothing we need to do - - cg_dataBeingReleased = cg_data; - CGImageRelease(cg_data); - cg_data = 0; - - if (pixels != pixelsToFree) { - macCreatePixels(); - } else { - pixelsToFree = 0; - } -} - - -// We create our space in memory to paint on here. If we already have existing pixels -// copy them over. This is to preserve the fact that CGImageRef's are immutable. -void QMacPixmapData::macCreatePixels() -{ - const int numBytes = bytesPerRow * h; - quint32 *base_pixels; - if (pixelsToFree && pixelsToFree != pixels) { - // Reuse unused block of memory lying around from a previous callback. - base_pixels = pixelsToFree; - pixelsToFree = 0; - } else { - // We need a block of memory to do stuff with. - base_pixels = static_cast<quint32 *>(malloc(numBytes)); - } - - if (pixels) - memcpy(base_pixels, pixels, qMin(pixelsSize, (uint) numBytes)); - pixels = base_pixels; - pixelsSize = numBytes; -} - -#if 0 -QPixmap QMacPixmapData::transformed(const QTransform &transform, - Qt::TransformationMode mode) const -{ - int w, h; // size of target pixmap - const int ws = width(); - const int hs = height(); - - QTransform mat(transform.m11(), transform.m12(), - transform.m21(), transform.m22(), 0., 0.); - if (transform.m12() == 0.0F && transform.m21() == 0.0F && - transform.m11() >= 0.0F && transform.m22() >= 0.0F) - { - h = int(qAbs(mat.m22()) * hs + 0.9999); - w = int(qAbs(mat.m11()) * ws + 0.9999); - h = qAbs(h); - w = qAbs(w); - } else { // rotation or shearing - QPolygonF a(QRectF(0,0,ws+1,hs+1)); - a = mat.map(a); - QRectF r = a.boundingRect().normalized(); - w = int(r.width() + 0.9999); - h = int(r.height() + 0.9999); - } - mat = QPixmap::trueMatrix(mat, ws, hs); - if (!h || !w) - return QPixmap(); - - // create destination - QMacPixmapData *pm = new QMacPixmapData(pixelType(), w, h); - const quint32 *sptr = pixels; - quint32 *dptr = pm->pixels; - memset(dptr, 0, (pm->bytesPerRow * pm->h)); - - // do the transform - if (mode == Qt::SmoothTransformation) { -#warning QMacPixmapData::transformed not properly implemented - qWarning("QMacPixmapData::transformed not properly implemented"); -#if 0 - QPainter p(&pm); - p.setRenderHint(QPainter::Antialiasing); - p.setRenderHint(QPainter::SmoothPixmapTransform); - p.setTransform(mat); - p.drawPixmap(0, 0, *this); -#endif - } else { - bool invertible; - mat = mat.inverted(&invertible); - if (!invertible) - return QPixmap(); - - const int bpp = 32; - const int xbpl = (w * bpp) / 8; - if (!qt_xForm_helper(mat, 0, QT_XFORM_TYPE_MSBFIRST, bpp, - (uchar*)dptr, xbpl, (pm->bytesPerRow) - xbpl, - h, (uchar*)sptr, (bytesPerRow), ws, hs)) { - qWarning("QMacPixmapData::transform(): failure"); - return QPixmap(); - } - } - - // update the alpha - pm->macSetHasAlpha(true); - return QPixmap(pm); -} -#endif - -QT_BEGIN_INCLUDE_NAMESPACE -#include <OpenGL/OpenGL.h> -#include <OpenGL/gl.h> -QT_END_INCLUDE_NAMESPACE - -// Load and resolve the symbols we need from OpenGL manually so QtGui doesn't have to link against the OpenGL framework. -typedef CGLError (*PtrCGLChoosePixelFormat)(const CGLPixelFormatAttribute *, CGLPixelFormatObj *, long *); -typedef CGLError (*PtrCGLClearDrawable)(CGLContextObj); -typedef CGLError (*PtrCGLCreateContext)(CGLPixelFormatObj, CGLContextObj, CGLContextObj *); -typedef CGLError (*PtrCGLDestroyContext)(CGLContextObj); -typedef CGLError (*PtrCGLDestroyPixelFormat)(CGLPixelFormatObj); -typedef CGLError (*PtrCGLSetCurrentContext)(CGLContextObj); -typedef CGLError (*PtrCGLSetFullScreen)(CGLContextObj); -typedef void (*PtrglFinish)(); -typedef void (*PtrglPixelStorei)(GLenum, GLint); -typedef void (*PtrglReadBuffer)(GLenum); -typedef void (*PtrglReadPixels)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *); - -static PtrCGLChoosePixelFormat ptrCGLChoosePixelFormat = 0; -static PtrCGLClearDrawable ptrCGLClearDrawable = 0; -static PtrCGLCreateContext ptrCGLCreateContext = 0; -static PtrCGLDestroyContext ptrCGLDestroyContext = 0; -static PtrCGLDestroyPixelFormat ptrCGLDestroyPixelFormat = 0; -static PtrCGLSetCurrentContext ptrCGLSetCurrentContext = 0; -static PtrCGLSetFullScreen ptrCGLSetFullScreen = 0; -static PtrglFinish ptrglFinish = 0; -static PtrglPixelStorei ptrglPixelStorei = 0; -static PtrglReadBuffer ptrglReadBuffer = 0; -static PtrglReadPixels ptrglReadPixels = 0; - -static bool resolveOpenGLSymbols() -{ - if (ptrCGLChoosePixelFormat == 0) { - QLibrary library(QLatin1String("/System/Library/Frameworks/OpenGL.framework/OpenGL")); - ptrCGLChoosePixelFormat = (PtrCGLChoosePixelFormat)(library.resolve("CGLChoosePixelFormat")); - ptrCGLClearDrawable = (PtrCGLClearDrawable)(library.resolve("CGLClearDrawable")); - ptrCGLCreateContext = (PtrCGLCreateContext)(library.resolve("CGLCreateContext")); - ptrCGLDestroyContext = (PtrCGLDestroyContext)(library.resolve("CGLDestroyContext")); - ptrCGLDestroyPixelFormat = (PtrCGLDestroyPixelFormat)(library.resolve("CGLDestroyPixelFormat")); - ptrCGLSetCurrentContext = (PtrCGLSetCurrentContext)(library.resolve("CGLSetCurrentContext")); - ptrCGLSetFullScreen = (PtrCGLSetFullScreen)(library.resolve("CGLSetFullScreen")); - ptrglFinish = (PtrglFinish)(library.resolve("glFinish")); - ptrglPixelStorei = (PtrglPixelStorei)(library.resolve("glPixelStorei")); - ptrglReadBuffer = (PtrglReadBuffer)(library.resolve("glReadBuffer")); - ptrglReadPixels = (PtrglReadPixels)(library.resolve("glReadPixels")); - } - return ptrCGLChoosePixelFormat && ptrCGLClearDrawable && ptrCGLCreateContext - && ptrCGLDestroyContext && ptrCGLDestroyPixelFormat && ptrCGLSetCurrentContext - && ptrCGLSetFullScreen && ptrglFinish && ptrglPixelStorei - && ptrglReadBuffer && ptrglReadPixels; -} - -// Inverts the given pixmap in the y direction. -static void qt_mac_flipPixmap(void *data, int rowBytes, int height) -{ - int bottom = height - 1; - void *base = data; - void *buffer = malloc(rowBytes); - - int top = 0; - while ( top < bottom ) - { - void *topP = (void *)((top * rowBytes) + (intptr_t)base); - void *bottomP = (void *)((bottom * rowBytes) + (intptr_t)base); - - bcopy( topP, buffer, rowBytes ); - bcopy( bottomP, topP, rowBytes ); - bcopy( buffer, bottomP, rowBytes ); - - ++top; - --bottom; - } - free(buffer); -} - -// Grabs displayRect from display and places it into buffer. -static void qt_mac_grabDisplayRect(CGDirectDisplayID display, const QRect &displayRect, void *buffer) -{ - if (display == kCGNullDirectDisplay) - return; - - CGLPixelFormatAttribute attribs[] = { - kCGLPFAFullScreen, - kCGLPFADisplayMask, - (CGLPixelFormatAttribute)0, /* Display mask bit goes here */ - (CGLPixelFormatAttribute)0 - }; - - attribs[2] = (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(display); - - // Build a full-screen GL context - CGLPixelFormatObj pixelFormatObj; - long numPixelFormats; - - ptrCGLChoosePixelFormat( attribs, &pixelFormatObj, &numPixelFormats ); - - if (!pixelFormatObj) // No full screen context support - return; - - CGLContextObj glContextObj; - ptrCGLCreateContext(pixelFormatObj, 0, &glContextObj); - ptrCGLDestroyPixelFormat(pixelFormatObj) ; - if (!glContextObj) - return; - - ptrCGLSetCurrentContext(glContextObj); - ptrCGLSetFullScreen(glContextObj) ; - - ptrglReadBuffer(GL_FRONT); - - ptrglFinish(); // Finish all OpenGL commands - ptrglPixelStorei(GL_PACK_ALIGNMENT, 4); // Force 4-byte alignment - ptrglPixelStorei(GL_PACK_ROW_LENGTH, 0); - ptrglPixelStorei(GL_PACK_SKIP_ROWS, 0); - ptrglPixelStorei(GL_PACK_SKIP_PIXELS, 0); - - // Fetch the data in XRGB format, matching the bitmap context. - ptrglReadPixels(GLint(displayRect.x()), GLint(displayRect.y()), - GLint(displayRect.width()), GLint(displayRect.height()), -#ifdef __BIG_ENDIAN__ - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer -#else - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, buffer -#endif - ); - - ptrCGLSetCurrentContext(0); - ptrCGLClearDrawable(glContextObj); // disassociate from full screen - ptrCGLDestroyContext(glContextObj); // and destroy the context -} - -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) -// Returns a pixmap containing the screen contents at rect. -static QPixmap qt_mac_grabScreenRect_10_6(const QRect &rect) -{ - const int maxDisplays = 128; // 128 displays should be enough for everyone. - CGDirectDisplayID displays[maxDisplays]; - CGDisplayCount displayCount; - const CGRect cgRect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); - const CGDisplayErr err = CGGetDisplaysWithRect(cgRect, maxDisplays, displays, &displayCount); - - if (err && displayCount == 0) - return QPixmap(); - QPixmap windowPixmap(rect.size()); - for (uint i = 0; i < displayCount; ++i) { - const CGRect bounds = CGDisplayBounds(displays[i]); - // Translate to display-local coordinates - QRect displayRect = rect.translated(qRound(-bounds.origin.x), qRound(-bounds.origin.y)); - QCFType<CGImageRef> image = CGDisplayCreateImageForRect(displays[i], - CGRectMake(displayRect.x(), displayRect.y(), displayRect.width(), displayRect.height())); - QPixmap pix = QPixmap::fromMacCGImageRef(image); - QPainter painter(&windowPixmap); - painter.drawPixmap(-bounds.origin.x, -bounds.origin.y, pix); - } - return windowPixmap; -} -#endif - -static QPixmap qt_mac_grabScreenRect(const QRect &rect) -{ - if (!resolveOpenGLSymbols()) - return QPixmap(); - - const int maxDisplays = 128; // 128 displays should be enough for everyone. - CGDirectDisplayID displays[maxDisplays]; - CGDisplayCount displayCount; - const CGRect cgRect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); - const CGDisplayErr err = CGGetDisplaysWithRect(cgRect, maxDisplays, displays, &displayCount); - - if (err && displayCount == 0) - return QPixmap(); - - long bytewidth = rect.width() * 4; // Assume 4 bytes/pixel for now - bytewidth = (bytewidth + 3) & ~3; // Align to 4 bytes - QVarLengthArray<char> buffer(rect.height() * bytewidth); - - for (uint i = 0; i < displayCount; ++i) { - const CGRect bounds = CGDisplayBounds(displays[i]); - // Translate to display-local coordinates - QRect displayRect = rect.translated(qRound(-bounds.origin.x), qRound(-bounds.origin.y)); - // Adjust for inverted y axis. - displayRect.moveTop(qRound(bounds.size.height) - displayRect.y() - rect.height()); - qt_mac_grabDisplayRect(displays[i], displayRect, buffer.data()); - } - - qt_mac_flipPixmap(buffer.data(), bytewidth, rect.height()); - QCFType<CGContextRef> bitmap = CGBitmapContextCreate(buffer.data(), rect.width(), - rect.height(), 8, bytewidth, - QCoreGraphicsPaintEngine::macGenericColorSpace(), - kCGImageAlphaNoneSkipFirst); - QCFType<CGImageRef> image = CGBitmapContextCreateImage(bitmap); - return QPixmap::fromMacCGImageRef(image); -} - -#ifndef QT_MAC_USE_COCOA // no QuickDraw in 64-bit mode -static QPixmap qt_mac_grabScreenRect_10_3(int x, int y, int w, int h, QWidget *widget) -{ - QPixmap pm = QPixmap(w, h); - extern WindowPtr qt_mac_window_for(const QWidget *); // qwidget_mac.cpp - const BitMap *windowPort = 0; - if((widget->windowType() == Qt::Desktop)) { - GDHandle gdh; - if(!(gdh=GetMainDevice())) - qDebug("Qt: internal: Unexpected condition reached: %s:%d", __FILE__, __LINE__); - windowPort = (BitMap*)(*(*gdh)->gdPMap); - } else { - windowPort = GetPortBitMapForCopyBits(GetWindowPort(qt_mac_window_for(widget))); - } - const BitMap *pixmapPort = GetPortBitMapForCopyBits(static_cast<GWorldPtr>(pm.macQDHandle())); - Rect macSrcRect, macDstRect; - SetRect(&macSrcRect, x, y, x + w, y + h); - SetRect(&macDstRect, 0, 0, w, h); - CopyBits(windowPort, pixmapPort, &macSrcRect, &macDstRect, srcCopy, 0); - return pm; -} -#endif - -QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h) -{ - QWidget *widget = QWidget::find(window); - if (widget == 0) - return QPixmap(); - - if(w == -1) - w = widget->width() - x; - if(h == -1) - h = widget->height() - y; - - QPoint globalCoord(0, 0); - globalCoord = widget->mapToGlobal(globalCoord); - QRect rect(globalCoord.x() + x, globalCoord.y() + y, w, h); - -#ifdef QT_MAC_USE_COCOA -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) - return qt_mac_grabScreenRect_10_6(rect); - else -#endif - return qt_mac_grabScreenRect(rect); -#else -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - return qt_mac_grabScreenRect(rect); - } else -#endif - { - return qt_mac_grabScreenRect_10_3(x, y, w, h, widget); - } -#endif // ifdef Q_WS_MAC64 -} - -/*! \internal - - Returns the QuickDraw CGrafPtr of the pixmap. 0 is returned if it can't - be obtained. Do not hold the pointer around for long as it can be - relocated. - - \warning This function is only available on Mac OS X. - \warning As of Qt 4.6, this function \e{always} returns zero. -*/ - -Qt::HANDLE QPixmap::macQDHandle() const -{ - return 0; -} - -/*! \internal - - Returns the QuickDraw CGrafPtr of the pixmap's alpha channel. 0 is - returned if it can't be obtained. Do not hold the pointer around for - long as it can be relocated. - - \warning This function is only available on Mac OS X. - \warning As of Qt 4.6, this function \e{always} returns zero. -*/ - -Qt::HANDLE QPixmap::macQDAlphaHandle() const -{ - return 0; -} - -/*! \internal - - Returns the CoreGraphics CGContextRef of the pixmap. 0 is returned if - it can't be obtained. It is the caller's responsiblity to - CGContextRelease the context when finished using it. - - \warning This function is only available on Mac OS X. -*/ - -Qt::HANDLE QPixmap::macCGHandle() const -{ - if (isNull()) - return 0; - - if (data->classId() == QPixmapData::MacClass) { - QMacPixmapData *d = static_cast<QMacPixmapData *>(data.data()); - if (!d->cg_data) - d->macCreateCGImageRef(); - CGImageRef ret = d->cg_data; - CGImageRetain(ret); - return ret; - } else if (data->classId() == QPixmapData::RasterClass) { - return qt_mac_image_to_cgimage(static_cast<QRasterPixmapData *>(data.data())->image); - } - return 0; -} - -bool QMacPixmapData::hasAlphaChannel() const -{ - return has_alpha; -} - -CGImageRef qt_mac_create_imagemask(const QPixmap &pixmap, const QRectF &sr) -{ - QMacPixmapData *px = static_cast<QMacPixmapData*>(pixmap.data.data()); - if (px->cg_mask) { - if (px->cg_mask_rect == sr) { - CGImageRetain(px->cg_mask); //reference for the caller - return px->cg_mask; - } - CGImageRelease(px->cg_mask); - px->cg_mask = 0; - } - - const int sx = qRound(sr.x()), sy = qRound(sr.y()), sw = qRound(sr.width()), sh = qRound(sr.height()); - const int sbpr = px->bytesPerRow; - const uint nbytes = sw * sh; - // alpha is always 255 for bitmaps, ignore it in this case. - const quint32 mask = px->depth() == 1 ? 0x00ffffff : 0xffffffff; - quint8 *dptr = static_cast<quint8 *>(malloc(nbytes)); - quint32 *sptr = px->pixels, *srow; - for(int y = sy, offset=0; y < sh; ++y) { - srow = sptr + (y * (sbpr / 4)); - for(int x = sx; x < sw; ++x) - *(dptr+(offset++)) = (*(srow+x) & mask) ? 255 : 0; - } - QCFType<CGDataProviderRef> provider = CGDataProviderCreateWithData(0, dptr, nbytes, qt_mac_cgimage_data_free); - px->cg_mask = CGImageMaskCreate(sw, sh, 8, 8, nbytes / sh, provider, 0, 0); - px->cg_mask_rect = sr; - CGImageRetain(px->cg_mask); //reference for the caller - return px->cg_mask; -} - -#ifndef QT_MAC_USE_COCOA -IconRef qt_mac_create_iconref(const QPixmap &px) -{ - if (px.isNull()) - return 0; - - //create icon - IconFamilyHandle iconFamily = reinterpret_cast<IconFamilyHandle>(NewHandle(0)); - //create data - { - struct { - OSType mac_type; - int width, height, depth; - bool mask; - } images[] = { - { kThumbnail32BitData, 128, 128, 32, false }, - { kThumbnail8BitMask, 128, 128, 8, true }, - { 0, 0, 0, 0, false } //end marker - }; - for(int i = 0; images[i].mac_type; i++) { - //get QPixmap data - QImage scaled_px = px.toImage().scaled(images[i].width, images[i].height); - - quint32 *sptr = (quint32 *) scaled_px.bits(); - quint32 *srow; - uint sbpr = scaled_px.bytesPerLine(); - - //get Handle data - const int dbpr = images[i].width * (images[i].depth/8); - Handle hdl = NewHandle(dbpr*images[i].height); - if(!sptr) { //handle null pixmap - memset((*hdl), '\0', dbpr*images[i].height); - } else if(images[i].mask) { - if(images[i].mac_type == kThumbnail8BitMask) { - for(int y = 0, hindex = 0; y < images[i].height; ++y) { - srow = sptr + (y * (sbpr/4)); - for(int x = 0; x < images[i].width; ++x) - *((*hdl)+(hindex++)) = qAlpha(*(srow+x)); - } - } - } else { - char *dest = (*hdl); -#if defined(__i386__) - if(images[i].depth == 32) { - for(int y = 0; y < images[i].height; ++y) { - uint *source = (uint*)((const uchar*)sptr+(sbpr*y)); - for(int x = 0; x < images[i].width; ++x, dest += 4) - *((uint*)dest) = CFSwapInt32(*(source + x)); - } - } else -#endif - { - for(int y = 0; y < images[i].height; ++y) - memcpy(dest+(y*dbpr), ((const uchar*)sptr+(sbpr*y)), dbpr); - } - } - - //set the family data to the Handle - OSStatus set = SetIconFamilyData(iconFamily, images[i].mac_type, hdl); - if(set != noErr) - qWarning("%s: %d -- Unable to create icon data[%d]!! %ld", - __FILE__, __LINE__, i, long(set)); - DisposeHandle(hdl); - } - } - - //acquire and cleanup - IconRef ret; - static int counter = 0; - const OSType kQtCreator = 'CUTE'; - RegisterIconRefFromIconFamily(kQtCreator, (OSType)counter, iconFamily, &ret); - AcquireIconRef(ret); - UnregisterIconRef(kQtCreator, (OSType)counter); - DisposeHandle(reinterpret_cast<Handle>(iconFamily)); - counter++; - return ret; - -} -#endif - -/*! \internal */ -QPaintEngine* QMacPixmapData::paintEngine() const -{ - if (!pengine) { - QMacPixmapData *that = const_cast<QMacPixmapData*>(this); - that->pengine = new QCoreGraphicsPaintEngine(); - } - return pengine; -} - -void QMacPixmapData::copy(const QPixmapData *data, const QRect &rect) -{ - if (data->pixelType() == BitmapType) { - QBitmap::fromImage(toImage().copy(rect)); - return; - } - - const QMacPixmapData *macData = static_cast<const QMacPixmapData*>(data); - - resize(rect.width(), rect.height()); - - has_alpha = macData->has_alpha; - has_mask = macData->has_mask; - uninit = false; - - const int x = rect.x(); - const int y = rect.y(); - char *dest = reinterpret_cast<char*>(pixels); - const char *src = reinterpret_cast<const char*>(macData->pixels + x) + y * macData->bytesPerRow; - for (int i = 0; i < h; ++i) { - memcpy(dest, src, w * 4); - dest += bytesPerRow; - src += macData->bytesPerRow; - } - - has_alpha = macData->has_alpha; - has_mask = macData->has_mask; -} - -bool QMacPixmapData::scroll(int dx, int dy, const QRect &rect) -{ - Q_UNUSED(dx); - Q_UNUSED(dy); - Q_UNUSED(rect); - return false; -} - -/*! - \since 4.2 - - Creates a \c CGImageRef equivalent to the QPixmap. Returns the \c CGImageRef handle. - - It is the caller's responsibility to release the \c CGImageRef data - after use. - - \warning This function is only available on Mac OS X. - - \sa fromMacCGImageRef() -*/ -CGImageRef QPixmap::toMacCGImageRef() const -{ - return (CGImageRef)macCGHandle(); -} - -/*! - \since 4.2 - - Returns a QPixmap that is equivalent to the given \a image. - - \warning This function is only available on Mac OS X. - - \sa toMacCGImageRef(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} -*/ -QPixmap QPixmap::fromMacCGImageRef(CGImageRef image) -{ - const size_t w = CGImageGetWidth(image), - h = CGImageGetHeight(image); - QPixmap ret(w, h); - ret.fill(Qt::transparent); - CGRect rect = CGRectMake(0, 0, w, h); - CGContextRef ctx = qt_mac_cg_context(&ret); - qt_mac_drawCGImage(ctx, &rect, image); - CGContextRelease(ctx); - return ret; -} - -QT_END_NAMESPACE diff --git a/src/gui/image/qpixmap_mac_p.h b/src/gui/image/qpixmap_mac_p.h deleted file mode 100644 index 3a5d97dc4a..0000000000 --- a/src/gui/image/qpixmap_mac_p.h +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPIXMAP_MAC_P_H -#define QPIXMAP_MAC_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtGui/private/qpixmapdata_p.h> -#include <QtGui/private/qpixmapdatafactory_p.h> -#include <QtGui/private/qt_mac_p.h> - -QT_BEGIN_NAMESPACE - -class QMacPixmapData : public QPixmapData -{ -public: - QMacPixmapData(PixelType type); - ~QMacPixmapData(); - - QPixmapData *createCompatiblePixmapData() const; - - void resize(int width, int height); - void fromImage(const QImage &image, Qt::ImageConversionFlags flags); - void copy(const QPixmapData *data, const QRect &rect); - bool scroll(int dx, int dy, const QRect &rect); - - int metric(QPaintDevice::PaintDeviceMetric metric) const; - void fill(const QColor &color); - QBitmap mask() const; - void setMask(const QBitmap &mask); - bool hasAlphaChannel() const; -// QPixmap transformed(const QTransform &matrix, -// Qt::TransformationMode mode) const; - void setAlphaChannel(const QPixmap &alphaChannel); - QPixmap alphaChannel() const; - QImage toImage() const; - QPaintEngine* paintEngine() const; - -private: - - uint has_alpha : 1, has_mask : 1, uninit : 1; - - void macSetHasAlpha(bool b); - void macGetAlphaChannel(QMacPixmapData *, bool asMask) const; - void macSetAlphaChannel(const QMacPixmapData *, bool asMask); - void macCreateCGImageRef(); - void macCreatePixels(); - void macReleaseCGImageRef(); - /* - pixels stores the pixmap data. pixelsToFree is either 0 or some memory - block that was bound to a CGImageRef and released, and for which the - release callback has been called. There are two uses to pixelsToFree: - - 1. If pixels == pixelsToFree, then we know that the CGImageRef is done\ - with the data and we can modify pixels without breaking CGImageRef's - mutability invariant. - - 2. If pixels != pixelsToFree and pixelsToFree != 0, then we can reuse - pixelsToFree later on instead of malloc'ing memory. - */ - quint32 *pixels; - uint pixelsSize; - quint32 *pixelsToFree; - uint bytesPerRow; - QRectF cg_mask_rect; - CGImageRef cg_data, cg_dataBeingReleased, cg_mask; - static QSet<QMacPixmapData*> validDataPointers; - - QPaintEngine *pengine; - - friend class QPixmap; - friend class QRasterBuffer; - friend class QRasterPaintEngine; - friend class QCoreGraphicsPaintEngine; - friend CGImageRef qt_mac_create_imagemask(const QPixmap&, const QRectF&); - friend quint32 *qt_mac_pixmap_get_base(const QPixmap*); - friend int qt_mac_pixmap_get_bytes_per_line(const QPixmap*); - friend void qt_mac_cgimage_data_free(void *, const void*, size_t); - friend IconRef qt_mac_create_iconref(const QPixmap&); - friend CGContextRef qt_mac_cg_context(const QPaintDevice*); - friend QColor qcolorForThemeTextColor(ThemeTextColor themeColor); -}; - -QT_END_NAMESPACE - -#endif // QPIXMAP_MAC_P_H diff --git a/src/gui/image/qpixmap_qpa.cpp b/src/gui/image/qpixmap_qpa.cpp index 095dd3ae76..9c69ddef7e 100644 --- a/src/gui/image/qpixmap_qpa.cpp +++ b/src/gui/image/qpixmap_qpa.cpp @@ -40,10 +40,10 @@ ****************************************************************************/ #include <qpixmap.h> -#include <private/qgraphicssystem_p.h> -#include <private/qapplication_p.h> +#include <qscreen.h> +#include <private/qguiapplication_p.h> QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h) { - return QApplicationPrivate::platformIntegration()->grabWindow(window, x, y, w, h); + return QGuiApplication::primaryScreen()->handle()->grabWindow(window, x, y, w, h); } diff --git a/src/gui/image/qpixmap_qws.cpp b/src/gui/image/qpixmap_qws.cpp deleted file mode 100644 index 804483898c..0000000000 --- a/src/gui/image/qpixmap_qws.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qpixmap.h> -#include <qapplication.h> -#include <qwidget.h> -#include <qdesktopwidget.h> -#include <qscreen_qws.h> -#include <qwsdisplay_qws.h> -#include <private/qdrawhelper_p.h> -#include <private/qpixmap_raster_p.h> - - -QT_BEGIN_NAMESPACE - -QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h) -{ - QWidget *widget = QWidget::find(window); - if (!widget) - return QPixmap(); - - QRect grabRect = widget->frameGeometry(); - if (!widget->isWindow()) - grabRect.translate(widget->parentWidget()->mapToGlobal(QPoint())); - if (w < 0) - w = widget->width() - x; - if (h < 0) - h = widget->height() - y; - grabRect &= QRect(x, y, w, h).translated(widget->mapToGlobal(QPoint())); - - QScreen *screen = qt_screen; - QDesktopWidget *desktop = QApplication::desktop(); - if (!desktop) - return QPixmap(); - if (desktop->numScreens() > 1) { - const int screenNo = desktop->screenNumber(widget); - if (screenNo != -1) - screen = qt_screen->subScreens().at(screenNo); - grabRect = grabRect.translated(-screen->region().boundingRect().topLeft()); - } - - if (screen->pixelFormat() == QImage::Format_Invalid) { - qWarning("QPixmap::grabWindow(): Unable to copy pixels from framebuffer"); - return QPixmap(); - } - - if (screen->isTransformed()) { - const QSize screenSize(screen->width(), screen->height()); - grabRect = screen->mapToDevice(grabRect, screenSize); - } - - QWSDisplay::grab(false); - QPixmap pixmap; - QImage img(screen->base(), - screen->deviceWidth(), screen->deviceHeight(), - screen->linestep(), screen->pixelFormat()); - img = img.copy(grabRect); - QWSDisplay::ungrab(); - - if (screen->isTransformed()) { - QMatrix matrix; - switch (screen->transformOrientation()) { - case 1: matrix.rotate(90); break; - case 2: matrix.rotate(180); break; - case 3: matrix.rotate(270); break; - default: break; - } - img = img.transformed(matrix); - } - - if (screen->pixelType() == QScreen::BGRPixel) - img = img.rgbSwapped(); - - return QPixmap::fromImage(img); -} - -QRgb* QPixmap::clut() const -{ - if (data && data->classId() == QPixmapData::RasterClass) { - const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data()); - return d->image.colorTable().data(); - } - - return 0; -} - -int QPixmap::numCols() const -{ - return colorCount(); -} - -int QPixmap::colorCount() const -{ - if (data && data->classId() == QPixmapData::RasterClass) { - const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data()); - return d->image.colorCount(); - } - - return 0; -} - -const uchar* QPixmap::qwsBits() const -{ - if (data && data->classId() == QPixmapData::RasterClass) { - const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data()); - return d->image.bits(); - } - - return 0; -} - -int QPixmap::qwsBytesPerLine() const -{ - if (data && data->classId() == QPixmapData::RasterClass) { - const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data()); - return d->image.bytesPerLine(); - } - - return 0; -} - -QT_END_NAMESPACE diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 6355222da1..ce7d66043c 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -54,20 +54,16 @@ #include <QImageReader> #include <private/qimage_p.h> #include <private/qsimd_p.h> -#include <private/qwidget_p.h> #include <private/qdrawhelper_p.h> QT_BEGIN_NAMESPACE -const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08, - 0x10, 0x20, 0x40, 0x80 }; - QPixmap qt_toRasterPixmap(const QImage &image) { - QPixmapData *data = - new QRasterPixmapData(image.depth() == 1 - ? QPixmapData::BitmapType - : QPixmapData::PixmapType); + QPlatformPixmap *data = + new QRasterPlatformPixmap(image.depth() == 1 + ? QPlatformPixmap::BitmapType + : QPlatformPixmap::PixmapType); data->fromImage(image, Qt::AutoColor); @@ -79,27 +75,27 @@ QPixmap qt_toRasterPixmap(const QPixmap &pixmap) if (pixmap.isNull()) return QPixmap(); - if (QPixmap(pixmap).data_ptr()->classId() == QPixmapData::RasterClass) + if (QPixmap(pixmap).data_ptr()->classId() == QPlatformPixmap::RasterClass) return pixmap; return qt_toRasterPixmap(pixmap.toImage()); } -QRasterPixmapData::QRasterPixmapData(PixelType type) - : QPixmapData(type, RasterClass) +QRasterPlatformPixmap::QRasterPlatformPixmap(PixelType type) + : QPlatformPixmap(type, RasterClass) { } -QRasterPixmapData::~QRasterPixmapData() +QRasterPlatformPixmap::~QRasterPlatformPixmap() { } -QPixmapData *QRasterPixmapData::createCompatiblePixmapData() const +QPlatformPixmap *QRasterPlatformPixmap::createCompatiblePlatformPixmap() const { - return new QRasterPixmapData(pixelType()); + return new QRasterPlatformPixmap(pixelType()); } -void QRasterPixmapData::resize(int width, int height) +void QRasterPlatformPixmap::resize(int width, int height) { QImage::Format format; #ifdef Q_WS_QWS @@ -134,7 +130,7 @@ void QRasterPixmapData::resize(int width, int height) setSerialNumber(image.serialNumber()); } -bool QRasterPixmapData::fromData(const uchar *buffer, uint len, const char *format, +bool QRasterPlatformPixmap::fromData(const uchar *buffer, uint len, const char *format, Qt::ImageConversionFlags flags) { QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len); @@ -148,7 +144,7 @@ bool QRasterPixmapData::fromData(const uchar *buffer, uint len, const char *form return !isNull(); } -void QRasterPixmapData::fromImage(const QImage &sourceImage, +void QRasterPlatformPixmap::fromImage(const QImage &sourceImage, Qt::ImageConversionFlags flags) { Q_UNUSED(flags); @@ -156,7 +152,7 @@ void QRasterPixmapData::fromImage(const QImage &sourceImage, createPixmapForImage(image, flags, /* inplace = */false); } -void QRasterPixmapData::fromImageReader(QImageReader *imageReader, +void QRasterPlatformPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags) { Q_UNUSED(flags); @@ -170,19 +166,19 @@ void QRasterPixmapData::fromImageReader(QImageReader *imageReader, // from qwindowsurface.cpp extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); -void QRasterPixmapData::copy(const QPixmapData *data, const QRect &rect) +void QRasterPlatformPixmap::copy(const QPlatformPixmap *data, const QRect &rect) { fromImage(data->toImage(rect).copy(), Qt::NoOpaqueDetection); } -bool QRasterPixmapData::scroll(int dx, int dy, const QRect &rect) +bool QRasterPlatformPixmap::scroll(int dx, int dy, const QRect &rect) { if (!image.isNull()) qt_scrollRectInImage(image, rect, QPoint(dx, dy)); return true; } -void QRasterPixmapData::fill(const QColor &color) +void QRasterPlatformPixmap::fill(const QColor &color) { uint pixel; @@ -266,51 +262,12 @@ void QRasterPixmapData::fill(const QColor &color) image.fill(pixel); } -void QRasterPixmapData::setMask(const QBitmap &mask) -{ - if (mask.size().isEmpty()) { - if (image.depth() != 1) { // hw: ???? - image = image.convertToFormat(QImage::Format_RGB32); - } - } else { - const int w = image.width(); - const int h = image.height(); - - switch (image.depth()) { - case 1: { - const QImage imageMask = mask.toImage().convertToFormat(image.format()); - for (int y = 0; y < h; ++y) { - const uchar *mscan = imageMask.scanLine(y); - uchar *tscan = image.scanLine(y); - int bytesPerLine = image.bytesPerLine(); - for (int i = 0; i < bytesPerLine; ++i) - tscan[i] &= mscan[i]; - } - break; - } - default: { - const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB); - image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); - for (int y = 0; y < h; ++y) { - const uchar *mscan = imageMask.scanLine(y); - QRgb *tscan = (QRgb *)image.scanLine(y); - for (int x = 0; x < w; ++x) { - if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7])) - tscan[x] = 0; - } - } - break; - } - } - } -} - -bool QRasterPixmapData::hasAlphaChannel() const +bool QRasterPlatformPixmap::hasAlphaChannel() const { return image.hasAlphaChannel(); } -QImage QRasterPixmapData::toImage() const +QImage QRasterPlatformPixmap::toImage() const { if (!image.isNull()) { QImageData *data = const_cast<QImage &>(image).data_ptr(); @@ -324,7 +281,7 @@ QImage QRasterPixmapData::toImage() const return image; } -QImage QRasterPixmapData::toImage(const QRect &rect) const +QImage QRasterPlatformPixmap::toImage(const QRect &rect) const { if (rect.isNull()) return image; @@ -338,17 +295,12 @@ QImage QRasterPixmapData::toImage(const QRect &rect) const return image.copy(clipped); } -void QRasterPixmapData::setAlphaChannel(const QPixmap &alphaChannel) -{ - image.setAlphaChannel(alphaChannel.toImage()); -} - -QPaintEngine* QRasterPixmapData::paintEngine() const +QPaintEngine* QRasterPlatformPixmap::paintEngine() const { return image.paintEngine(); } -int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const +int QRasterPlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const { QImageData *d = image.d; if (!d) @@ -375,14 +327,14 @@ int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const case QPaintDevice::PdmPhysicalDpiY: return qt_defaultDpiY(); default: - qWarning("QRasterPixmapData::metric(): Unhandled metric type %d", metric); + qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric); break; } return 0; } -void QRasterPixmapData::createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace) +void QRasterPlatformPixmap::createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace) { QImage::Format format; if (flags & Qt::NoFormatConversion) @@ -484,7 +436,7 @@ void QRasterPixmapData::createPixmapForImage(QImage &sourceImage, Qt::ImageConve setSerialNumber(image.serialNumber()); } -QImage* QRasterPixmapData::buffer() +QImage* QRasterPlatformPixmap::buffer() { return ℑ } diff --git a/src/gui/image/qpixmap_raster_p.h b/src/gui/image/qpixmap_raster_p.h index decbd10b5f..c451a94858 100644 --- a/src/gui/image/qpixmap_raster_p.h +++ b/src/gui/image/qpixmap_raster_p.h @@ -53,8 +53,7 @@ // We mean it. // -#include <QtGui/private/qpixmapdata_p.h> -#include <QtGui/private/qpixmapdatafactory_p.h> +#include <QtGui/qplatformpixmap_qpa.h> #ifdef Q_WS_WIN # include "qt_windows.h" @@ -62,13 +61,13 @@ QT_BEGIN_NAMESPACE -class Q_GUI_EXPORT QRasterPixmapData : public QPixmapData +class Q_GUI_EXPORT QRasterPlatformPixmap : public QPlatformPixmap { public: - QRasterPixmapData(PixelType type); - ~QRasterPixmapData(); + QRasterPlatformPixmap(PixelType type); + ~QRasterPlatformPixmap(); - QPixmapData *createCompatiblePixmapData() const; + QPlatformPixmap *createCompatiblePlatformPixmap() const; void resize(int width, int height); void fromFile(const QString &filename, Qt::ImageConversionFlags flags); @@ -76,12 +75,10 @@ public: void fromImage(const QImage &image, Qt::ImageConversionFlags flags); void fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags); - void copy(const QPixmapData *data, const QRect &rect); + void copy(const QPlatformPixmap *data, const QRect &rect); bool scroll(int dx, int dy, const QRect &rect); void fill(const QColor &color); - void setMask(const QBitmap &mask); bool hasAlphaChannel() const; - void setAlphaChannel(const QPixmap &alphaChannel); QImage toImage() const; QImage toImage(const QRect &rect) const; QPaintEngine* paintEngine() const; diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp deleted file mode 100644 index ac29f5dea4..0000000000 --- a/src/gui/image/qpixmap_s60.cpp +++ /dev/null @@ -1,1040 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include <exception> -#include <w32std.h> -#include <fbs.h> - -#include <private/qapplication_p.h> -#include <private/qgraphicssystem_p.h> -#include <private/qt_s60_p.h> -#include <private/qpaintengine_s60_p.h> -#include <private/qfont_p.h> - -#include "qpixmap.h" -#include "qpixmap_raster_p.h" -#include <qwidget.h> -#include "qpixmap_s60_p.h" -#include "qnativeimage_p.h" -#include "qbitmap.h" -#include "qimage.h" -#include "qimage_p.h" - -#include <fbs.h> - -QT_BEGIN_NAMESPACE - -const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08, - 0x10, 0x20, 0x40, 0x80 }; - -static bool cleanup_function_registered = false; -static QS60PixmapData *firstPixmap = 0; - -// static -void QS60PixmapData::qt_symbian_register_pixmap(QS60PixmapData *pd) -{ - if (!cleanup_function_registered) { - qAddPostRoutine(qt_symbian_release_pixmaps); - cleanup_function_registered = true; - } - - pd->next = firstPixmap; - pd->prev = 0; - if (firstPixmap) - firstPixmap->prev = pd; - firstPixmap = pd; -} - -// static -void QS60PixmapData::qt_symbian_unregister_pixmap(QS60PixmapData *pd) -{ - if (pd->next) - pd->next->prev = pd->prev; - if (pd->prev) - pd->prev->next = pd->next; - else - firstPixmap = pd->next; -} - -// static -void QS60PixmapData::qt_symbian_release_pixmaps() -{ - // Scan all QS60PixmapData objects in the system and destroy them. - QS60PixmapData *pd = firstPixmap; - while (pd != 0) { - pd->release(); - pd = pd->next; - } -} - -/* - \class QSymbianFbsClient - \since 4.6 - \internal - - Symbian Font And Bitmap server client that is - used to lock the global bitmap heap. Only used in - S60 v3.1 and S60 v3.2. -*/ -_LIT(KFBSERVLargeBitmapAccessName,"FbsLargeBitmapAccess"); -class QSymbianFbsClient -{ -public: - - QSymbianFbsClient() : heapLocked(false) - { - heapLock.OpenGlobal(KFBSERVLargeBitmapAccessName); - } - - ~QSymbianFbsClient() - { - heapLock.Close(); - } - - bool lockHeap() - { - bool wasLocked = heapLocked; - - if (heapLock.Handle() && !heapLocked) { - heapLock.Wait(); - heapLocked = true; - } - - return wasLocked; - } - - bool unlockHeap() - { - bool wasLocked = heapLocked; - - if (heapLock.Handle() && heapLocked) { - heapLock.Signal(); - heapLocked = false; - } - - return wasLocked; - } - - -private: - - RMutex heapLock; - bool heapLocked; -}; - -Q_GLOBAL_STATIC(QSymbianFbsClient, qt_symbianFbsClient); - - - -// QSymbianFbsHeapLock - -QSymbianFbsHeapLock::QSymbianFbsHeapLock(LockAction a) -: action(a), wasLocked(false) -{ - QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); - if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) - wasLocked = qt_symbianFbsClient()->unlockHeap(); -} - -QSymbianFbsHeapLock::~QSymbianFbsHeapLock() -{ - // Do nothing -} - -void QSymbianFbsHeapLock::relock() -{ - QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); - if (wasLocked && (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3)) - qt_symbianFbsClient()->lockHeap(); -} - -/* - \class QSymbianBitmapDataAccess - \since 4.6 - \internal - - Data access class that is used to locks/unlocks pixel data - when drawing or modifying CFbsBitmap pixel data. -*/ -class QSymbianBitmapDataAccess -{ -public: - - static int heapRefCount; - QSysInfo::SymbianVersion symbianVersion; - - explicit QSymbianBitmapDataAccess() - { - symbianVersion = QSysInfo::symbianVersion(); - }; - - ~QSymbianBitmapDataAccess() {}; - - inline void beginDataAccess(CFbsBitmap *bitmap) - { - if (symbianVersion == QSysInfo::SV_9_2) { - if (heapRefCount == 0) - qt_symbianFbsClient()->lockHeap(); - } else { - bitmap->LockHeap(ETrue); - } - - heapRefCount++; - } - - inline void endDataAccess(CFbsBitmap *bitmap) - { - heapRefCount--; - - if (symbianVersion == QSysInfo::SV_9_2) { - if (heapRefCount == 0) - qt_symbianFbsClient()->unlockHeap(); - } else { - bitmap->UnlockHeap(ETrue); - } - } -}; - -int QSymbianBitmapDataAccess::heapRefCount = 0; - - -#define UPDATE_BUFFER() \ - { \ - beginDataAccess(); \ - endDataAccess(); \ -} - - -static CFbsBitmap* createSymbianCFbsBitmap(const TSize& size, TDisplayMode mode) -{ - QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); - - CFbsBitmap* bitmap = 0; - QT_TRAP_THROWING(bitmap = new (ELeave) CFbsBitmap); - - if (bitmap->Create(size, mode) != KErrNone) { - delete bitmap; - bitmap = 0; - } - - lock.relock(); - - return bitmap; -} - -static CFbsBitmap* uncompress(CFbsBitmap* bitmap) -{ - if(bitmap->IsCompressedInRAM()) { - QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); - - CFbsBitmap *uncompressed = 0; - QT_TRAP_THROWING(uncompressed = new (ELeave) CFbsBitmap); - - if (uncompressed->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) { - delete bitmap; - bitmap = 0; - lock.relock(); - - return bitmap; - } - - lock.relock(); - - CFbsBitmapDevice* bitmapDevice = 0; - CFbsBitGc *bitmapGc = 0; - QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(uncompressed)); - QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL()); - bitmapGc->Activate(bitmapDevice); - - bitmapGc->BitBlt(TPoint(), bitmap); - - delete bitmapGc; - delete bitmapDevice; - - return uncompressed; - } else { - return bitmap; - } -} - -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(); - - CFbsBitmap* temporary = createSymbianCFbsBitmap(srcRect.Size(), screenDevice->DisplayMode()); - - QPixmap pix; - - if (temporary && screenDevice->CopyScreenToBitmap(temporary, srcRect) == KErrNone) { - pix = QPixmap::fromSymbianCFbsBitmap(temporary); - } - - delete temporary; - return pix; -} - -/*! - \fn CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const - \since 4.6 - - Creates a \c CFbsBitmap that is equivalent to the QPixmap. Internally this - function will try to duplicate the handle instead of copying the data, - however in scenarios where this is not possible the data will be copied. - If the creation fails or the pixmap is null, then this function returns 0. - - It is the caller's responsibility to release the \c CFbsBitmap data - after use either by deleting the bitmap or calling \c Reset(). - - \warning On S60 3.1 and S60 3.2, semi-transparent pixmaps are always copied - and not duplicated. - \warning This function is only available on Symbian OS. - - \sa fromSymbianCFbsBitmap() -*/ -CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const -{ - QPixmapData *data = pixmapData(); - if (!data || data->isNull()) - return 0; - - return reinterpret_cast<CFbsBitmap*>(data->toNativeType(QPixmapData::FbsBitmap)); -} - -/*! - \fn QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap) - \since 4.6 - - Creates a QPixmap from a \c CFbsBitmap \a bitmap. Internally this function - will try to duplicate the bitmap handle instead of copying the data, however - in scenarios where this is not possible the data will be copied. - To be sure that QPixmap does not modify your original instance, you should - make a copy of your \c CFbsBitmap before calling this function. - If the CFbsBitmap is not valid this function will return a null QPixmap. - For performance reasons it is recommended to use a \a bitmap with a display - mode of EColor16MAP or EColor16MU whenever possible. - - \warning This function is only available on Symbian OS. - - \sa toSymbianCFbsBitmap(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} -*/ -QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap) -{ - if (!bitmap) - return QPixmap(); - - QScopedPointer<QPixmapData> data(QPixmapData::create(0,0, QPixmapData::PixmapType)); - data->fromNativeType(reinterpret_cast<void*>(bitmap), QPixmapData::FbsBitmap); - QPixmap pixmap(data.take()); - return pixmap; -} - -QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type), - symbianBitmapDataAccess(new QSymbianBitmapDataAccess), - cfbsBitmap(0), - pengine(0), - bytes(0), - formatLocked(false), - next(0), - prev(0) -{ - qt_symbian_register_pixmap(this); -} - -QS60PixmapData::~QS60PixmapData() -{ - release(); - delete symbianBitmapDataAccess; - qt_symbian_unregister_pixmap(this); -} - -void QS60PixmapData::resize(int width, int height) -{ - if (width <= 0 || height <= 0) { - w = width; - h = height; - is_null = true; - - release(); - return; - } else if (!cfbsBitmap) { - TDisplayMode mode; - if (pixelType() == BitmapType) - mode = EGray2; - else - mode = EColor16MU; - - CFbsBitmap* bitmap = createSymbianCFbsBitmap(TSize(width, height), mode); - fromSymbianBitmap(bitmap); - } else { - - TSize newSize(width, height); - - if(cfbsBitmap->SizeInPixels() != newSize) { - cfbsBitmap->Resize(TSize(width, height)); - if(pengine) { - delete pengine; - pengine = 0; - } - } - - UPDATE_BUFFER(); - } -} - -void QS60PixmapData::release() -{ - if (cfbsBitmap) { - QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); - delete cfbsBitmap; - lock.relock(); - } - - delete pengine; - image = QImage(); - cfbsBitmap = 0; - pengine = 0; - bytes = 0; -} - -/*! - * Takes ownership of bitmap. Used by window surface - */ -void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat) -{ - Q_ASSERT(bitmap); - - release(); - - cfbsBitmap = bitmap; - formatLocked = lockFormat; - - setSerialNumber(cfbsBitmap->Handle()); - - UPDATE_BUFFER(); - - // Create default palette if needed - if (cfbsBitmap->DisplayMode() == EGray2) { - image.setColorCount(2); - image.setColor(0, QColor(Qt::color0).rgba()); - image.setColor(1, QColor(Qt::color1).rgba()); - - //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid - //So invert mono bitmaps so that masks work correctly. - image.invertPixels(); - } else if (cfbsBitmap->DisplayMode() == EGray256) { - for (int i=0; i < 256; ++i) - image.setColor(i, qRgb(i, i, i)); - } else if (cfbsBitmap->DisplayMode() == EColor256) { - const TColor256Util *palette = TColor256Util::Default(); - for (int i=0; i < 256; ++i) - image.setColor(i, (QRgb)(palette->Color256(i).Value())); - } -} - -QImage QS60PixmapData::toImage(const QRect &r) const -{ - QS60PixmapData *that = const_cast<QS60PixmapData*>(this); - that->beginDataAccess(); - QImage copy = that->image.copy(r); - that->endDataAccess(); - - return copy; -} - -void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags) -{ - release(); - - QImage sourceImage; - - if (pixelType() == BitmapType) { - sourceImage = img.convertToFormat(QImage::Format_MonoLSB); - } else { - if (img.depth() == 1) { - sourceImage = img.hasAlphaChannel() - ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) - : img.convertToFormat(QImage::Format_RGB32); - } else { - - QImage::Format opaqueFormat = QNativeImage::systemFormat(); - QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; - - if (!img.hasAlphaChannel() - || ((flags & Qt::NoOpaqueDetection) == 0 - && !const_cast<QImage &>(img).data_ptr()->checkForAlphaPixels())) { - sourceImage = img.convertToFormat(opaqueFormat); - } else { - sourceImage = img.convertToFormat(alphaFormat); - } - } - } - - - QImage::Format destFormat = sourceImage.format(); - TDisplayMode mode; - switch (destFormat) { - case QImage::Format_MonoLSB: - mode = EGray2; - break; - case QImage::Format_RGB32: - mode = EColor16MU; - break; - case QImage::Format_ARGB32_Premultiplied: - if (S60->supportsPremultipliedAlpha) { - mode = Q_SYMBIAN_ECOLOR16MAP; - break; - } else { - destFormat = QImage::Format_ARGB32; - } - // Fall through intended - case QImage::Format_ARGB32: - mode = EColor16MA; - break; - case QImage::Format_Invalid: - return; - default: - qWarning("Image format not supported: %d", image.format()); - return; - } - - cfbsBitmap = createSymbianCFbsBitmap(TSize(sourceImage.width(), sourceImage.height()), mode); - if (!cfbsBitmap) { - qWarning("Could not create CFbsBitmap"); - release(); - return; - } - - setSerialNumber(cfbsBitmap->Handle()); - - const uchar *sptr = const_cast<const QImage &>(sourceImage).bits(); - symbianBitmapDataAccess->beginDataAccess(cfbsBitmap); - uchar *dptr = (uchar*)cfbsBitmap->DataAddress(); - Mem::Copy(dptr, sptr, sourceImage.byteCount()); - symbianBitmapDataAccess->endDataAccess(cfbsBitmap); - - UPDATE_BUFFER(); - - if (destFormat == QImage::Format_MonoLSB) { - image.setColorCount(2); - image.setColor(0, QColor(Qt::color0).rgba()); - image.setColor(1, QColor(Qt::color1).rgba()); - } else { - image.setColorTable(sourceImage.colorTable()); - } -} - -void QS60PixmapData::copy(const QPixmapData *data, const QRect &rect) -{ - const QS60PixmapData *s60Data = static_cast<const QS60PixmapData*>(data); - fromImage(s60Data->toImage(rect), Qt::AutoColor | Qt::OrderedAlphaDither); -} - -bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect) -{ - beginDataAccess(); - bool res = QRasterPixmapData::scroll(dx, dy, rect); - endDataAccess(); - return res; -} - -int QS60PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const -{ - if (!cfbsBitmap) - return 0; - - switch (metric) { - case QPaintDevice::PdmWidth: - return cfbsBitmap->SizeInPixels().iWidth; - case QPaintDevice::PdmHeight: - return cfbsBitmap->SizeInPixels().iHeight; - case QPaintDevice::PdmWidthMM: - return qRound(cfbsBitmap->SizeInPixels().iWidth * 25.4 / qt_defaultDpiX()); - case QPaintDevice::PdmHeightMM: - return qRound(cfbsBitmap->SizeInPixels().iHeight * 25.4 / qt_defaultDpiY()); - case QPaintDevice::PdmNumColors: - return TDisplayModeUtils::NumDisplayModeColors(cfbsBitmap->DisplayMode()); - case QPaintDevice::PdmDpiX: - case QPaintDevice::PdmPhysicalDpiX: - return qt_defaultDpiX(); - case QPaintDevice::PdmDpiY: - case QPaintDevice::PdmPhysicalDpiY: - return qt_defaultDpiY(); - case QPaintDevice::PdmDepth: - return TDisplayModeUtils::NumDisplayModeBitsPerPixel(cfbsBitmap->DisplayMode()); - default: - qWarning("QPixmap::metric: Invalid metric command"); - } - return 0; - -} - -void QS60PixmapData::fill(const QColor &color) -{ - if (color.alpha() != 255) { - QImage im(width(), height(), QImage::Format_ARGB32_Premultiplied); - im.fill(PREMUL(color.rgba())); - release(); - fromImage(im, Qt::AutoColor | Qt::OrderedAlphaDither); - } else { - beginDataAccess(); - QRasterPixmapData::fill(color); - endDataAccess(); - } -} - -void QS60PixmapData::setMask(const QBitmap &mask) -{ - if (mask.size().isEmpty()) { - if (image.depth() != 1) { - QImage newImage = image.convertToFormat(QImage::Format_RGB32); - release(); - fromImage(newImage, Qt::AutoColor | Qt::OrderedAlphaDither); - } - } else if (image.depth() == 1) { - beginDataAccess(); - QRasterPixmapData::setMask(mask); - endDataAccess(); - } else { - const int w = image.width(); - const int h = image.height(); - - const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB); - QImage newImage = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); - for (int y = 0; y < h; ++y) { - const uchar *mscan = imageMask.scanLine(y); - QRgb *tscan = (QRgb *)newImage.scanLine(y); - for (int x = 0; x < w; ++x) { - if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7])) - tscan[x] = 0; - } - } - release(); - fromImage(newImage, Qt::AutoColor | Qt::OrderedAlphaDither); - } -} - -void QS60PixmapData::setAlphaChannel(const QPixmap &alphaChannel) -{ - QImage img(toImage()); - img.setAlphaChannel(alphaChannel.toImage()); - release(); - fromImage(img, Qt::OrderedDither | Qt::OrderedAlphaDither); -} - -QImage QS60PixmapData::toImage() const -{ - return toImage(QRect()); -} - -QPaintEngine* QS60PixmapData::paintEngine() const -{ - if (!pengine) { - QS60PixmapData *that = const_cast<QS60PixmapData*>(this); - that->pengine = new QS60PaintEngine(&that->image, that); - } - return pengine; -} - -void QS60PixmapData::beginDataAccess() -{ - if(!cfbsBitmap) - return; - - symbianBitmapDataAccess->beginDataAccess(cfbsBitmap); - - uchar* newBytes = (uchar*)cfbsBitmap->DataAddress(); - - TSize size = cfbsBitmap->SizeInPixels(); - - if (newBytes == bytes && image.width() == size.iWidth && image.height() == size.iHeight) - return; - - bytes = newBytes; - TDisplayMode mode = cfbsBitmap->DisplayMode(); - QImage::Format format = qt_TDisplayMode2Format(mode); - // On S60 3.1, premultiplied alpha pixels are stored in a bitmap with 16MA type. - // S60 window surface needs backing store pixmap for transparent window in ARGB32 format. - // In that case formatLocked is true. - if (!formatLocked && format == QImage::Format_ARGB32) - format = QImage::Format_ARGB32_Premultiplied; // pixel data is actually in premultiplied format - - QVector<QRgb> savedColorTable; - if (!image.isNull()) - savedColorTable = image.colorTable(); - - image = QImage(bytes, size.iWidth, size.iHeight, format); - - // Restore the palette or create a default - if (!savedColorTable.isEmpty()) { - image.setColorTable(savedColorTable); - } - - w = size.iWidth; - h = size.iHeight; - d = image.depth(); - is_null = (w <= 0 || h <= 0); - - if (pengine) { - QS60PaintEngine *engine = static_cast<QS60PaintEngine *>(pengine); - engine->prepare(&image); - } -} - -void QS60PixmapData::endDataAccess(bool readOnly) const -{ - Q_UNUSED(readOnly); - - if(!cfbsBitmap) - return; - - symbianBitmapDataAccess->endDataAccess(cfbsBitmap); -} - -/*! - \since 4.6 - - Returns a QPixmap that wraps given \a sgImage graphics resource. - The data should be valid even when original RSgImage handle has been - closed. - - \warning This function is only available on Symbian OS. - - \sa toSymbianRSgImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} -*/ - -QPixmap QPixmap::fromSymbianRSgImage(RSgImage *sgImage) -{ - // It is expected that RSgImage will - // CURRENTLY be used in conjuction with - // OpenVG graphics system - // - // Surely things might change in future - - if (!sgImage) - return QPixmap(); - - QScopedPointer<QPixmapData> data(QPixmapData::create(0,0, QPixmapData::PixmapType)); - data->fromNativeType(reinterpret_cast<void*>(sgImage), QPixmapData::SgImage); - QPixmap pixmap(data.take()); - return pixmap; -} - -/*! -\since 4.6 - -Returns a \c RSgImage that is equivalent to the QPixmap by copying the data. - -It is the caller's responsibility to close/delete the \c RSgImage after use. - -\warning This function is only available on Symbian OS. - -\sa fromSymbianRSgImage() -*/ - -RSgImage *QPixmap::toSymbianRSgImage() const -{ - // It is expected that RSgImage will - // CURRENTLY be used in conjuction with - // OpenVG graphics system - // - // Surely things might change in future - - if (isNull()) - return 0; - - RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmapData()->toNativeType(QPixmapData::SgImage)); - - return sgImage; -} - -void* QS60PixmapData::toNativeType(NativeType type) -{ - if (type == QPixmapData::SgImage) { - return 0; - } else if (type == QPixmapData::FbsBitmap) { - - if (isNull() || !cfbsBitmap) - return 0; - - bool convertToArgb32 = false; - bool needsCopy = false; - - if (!(S60->supportsPremultipliedAlpha)) { - // Convert argb32_premultiplied to argb32 since Symbian 9.2 does - // not support premultipied format. - - if (image.format() == QImage::Format_ARGB32_Premultiplied) { - needsCopy = true; - convertToArgb32 = true; - } - } - - CFbsBitmap *bitmap = 0; - - TDisplayMode displayMode = cfbsBitmap->DisplayMode(); - - if(displayMode == EGray2) { - //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid - //So invert mono bitmaps so that masks work correctly. - beginDataAccess(); - image.invertPixels(); - endDataAccess(); - needsCopy = true; - } - - if (needsCopy) { - QImage source; - - if (convertToArgb32) { - beginDataAccess(); - source = image.convertToFormat(QImage::Format_ARGB32); - endDataAccess(); - displayMode = EColor16MA; - } else { - source = image; - } - - CFbsBitmap *newBitmap = createSymbianCFbsBitmap(TSize(source.width(), source.height()), displayMode); - const uchar *sptr = source.bits(); - symbianBitmapDataAccess->beginDataAccess(newBitmap); - - uchar *dptr = (uchar*)newBitmap->DataAddress(); - Mem::Copy(dptr, sptr, source.byteCount()); - - symbianBitmapDataAccess->endDataAccess(newBitmap); - - bitmap = newBitmap; - } else { - - QT_TRAP_THROWING(bitmap = new (ELeave) CFbsBitmap); - - TInt err = bitmap->Duplicate(cfbsBitmap->Handle()); - if (err != KErrNone) { - qWarning("Could not duplicate CFbsBitmap"); - delete bitmap; - bitmap = 0; - } - } - - if(displayMode == EGray2) { - // restore pixels - beginDataAccess(); - image.invertPixels(); - endDataAccess(); - } - - return reinterpret_cast<void*>(bitmap); - - } - - return 0; -} - -void QS60PixmapData::fromNativeType(void* pixmap, NativeType nativeType) -{ - if (nativeType == QPixmapData::SgImage) { - return; - } else if (nativeType == QPixmapData::FbsBitmap && pixmap) { - - CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap); - - bool deleteSourceBitmap = false; - bool needsCopy = false; - -#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE - - // Rasterize extended bitmaps - - TUid extendedBitmapType = bitmap->ExtendedBitmapType(); - if (extendedBitmapType != KNullUid) { - CFbsBitmap *rasterBitmap = createSymbianCFbsBitmap(bitmap->SizeInPixels(), EColor16MA); - - CFbsBitmapDevice *rasterBitmapDev = 0; - QT_TRAP_THROWING(rasterBitmapDev = CFbsBitmapDevice::NewL(rasterBitmap)); - - CFbsBitGc *rasterBitmapGc = 0; - TInt err = rasterBitmapDev->CreateContext(rasterBitmapGc); - if (err != KErrNone) { - delete rasterBitmap; - delete rasterBitmapDev; - rasterBitmapDev = 0; - return; - } - - rasterBitmapGc->BitBlt(TPoint( 0, 0), bitmap); - - bitmap = rasterBitmap; - - delete rasterBitmapDev; - delete rasterBitmapGc; - - rasterBitmapDev = 0; - rasterBitmapGc = 0; - - deleteSourceBitmap = true; - } -#endif - - - deleteSourceBitmap = bitmap->IsCompressedInRAM(); - CFbsBitmap *sourceBitmap = uncompress(bitmap); - - TDisplayMode displayMode = sourceBitmap->DisplayMode(); - QImage::Format format = qt_TDisplayMode2Format(displayMode); - - QImage::Format opaqueFormat = QNativeImage::systemFormat(); - QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; - - if (format != opaqueFormat && format != alphaFormat && format != QImage::Format_MonoLSB) - needsCopy = true; - - - type = (format != QImage::Format_MonoLSB) - ? QPixmapData::PixmapType - : QPixmapData::BitmapType; - - if (needsCopy) { - - TSize size = sourceBitmap->SizeInPixels(); - int bytesPerLine = sourceBitmap->ScanLineLength(size.iWidth, displayMode); - - QSymbianBitmapDataAccess da; - da.beginDataAccess(sourceBitmap); - uchar *bytes = (uchar*)sourceBitmap->DataAddress(); - QImage img = QImage(bytes, size.iWidth, size.iHeight, bytesPerLine, format); - img = img.copy(); - da.endDataAccess(sourceBitmap); - - if(displayMode == EGray2) { - //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid - //So invert mono bitmaps so that masks work correctly. - img.invertPixels(); - } else if(displayMode == EColor16M) { - img = img.rgbSwapped(); // EColor16M is BGR - } - - fromImage(img, Qt::AutoColor); - - if(deleteSourceBitmap) - delete sourceBitmap; - } else { - CFbsBitmap* duplicate = 0; - QT_TRAP_THROWING(duplicate = new (ELeave) CFbsBitmap); - - TInt err = duplicate->Duplicate(sourceBitmap->Handle()); - if (err != KErrNone) { - qWarning("Could not duplicate CFbsBitmap"); - - if(deleteSourceBitmap) - delete sourceBitmap; - - delete duplicate; - return; - } - - fromSymbianBitmap(duplicate); - - if(deleteSourceBitmap) - delete sourceBitmap; - } - } -} - -void QS60PixmapData::convertToDisplayMode(int mode) -{ - const TDisplayMode displayMode = static_cast<TDisplayMode>(mode); - if (!cfbsBitmap || cfbsBitmap->DisplayMode() == displayMode) - return; - if (image.depth() != TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode)) { - qWarning("Cannot convert display mode due to depth mismatch"); - return; - } - - const TSize size = cfbsBitmap->SizeInPixels(); - QScopedPointer<CFbsBitmap> newBitmap(createSymbianCFbsBitmap(size, displayMode)); - - const uchar *sptr = const_cast<const QImage &>(image).bits(); - symbianBitmapDataAccess->beginDataAccess(newBitmap.data()); - uchar *dptr = (uchar*)newBitmap->DataAddress(); - Mem::Copy(dptr, sptr, image.byteCount()); - symbianBitmapDataAccess->endDataAccess(newBitmap.data()); - - QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); - delete cfbsBitmap; - lock.relock(); - cfbsBitmap = newBitmap.take(); - setSerialNumber(cfbsBitmap->Handle()); - UPDATE_BUFFER(); -} - -QPixmapData *QS60PixmapData::createCompatiblePixmapData() const -{ - return new QS60PixmapData(pixelType()); -} - -QT_END_NAMESPACE diff --git a/src/gui/image/qpixmap_s60_p.h b/src/gui/image/qpixmap_s60_p.h deleted file mode 100644 index e48154963b..0000000000 --- a/src/gui/image/qpixmap_s60_p.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPIXMAPDATA_S60_P_H -#define QPIXMAPDATA_S60_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtGui/private/qpixmap_raster_p.h> - -QT_BEGIN_NAMESPACE - -class CFbsBitmap; -class CFbsBitmapDevice; -class CFbsBitGc; - -class QSymbianBitmapDataAccess; - -class QSymbianFbsHeapLock -{ -public: - - enum LockAction { - Unlock - }; - - explicit QSymbianFbsHeapLock(LockAction a); - ~QSymbianFbsHeapLock(); - void relock(); - -private: - - LockAction action; - bool wasLocked; -}; - -class QS60PixmapData : public QRasterPixmapData -{ -public: - QS60PixmapData(PixelType type); - ~QS60PixmapData(); - - QPixmapData *createCompatiblePixmapData() const; - - void resize(int width, int height); - void fromImage(const QImage &image, Qt::ImageConversionFlags flags); - void copy(const QPixmapData *data, const QRect &rect); - bool scroll(int dx, int dy, const QRect &rect); - - int metric(QPaintDevice::PaintDeviceMetric metric) const; - void fill(const QColor &color); - void setMask(const QBitmap &mask); - void setAlphaChannel(const QPixmap &alphaChannel); - QImage toImage() const; - QPaintEngine* paintEngine() const; - - void beginDataAccess(); - void endDataAccess(bool readOnly=false) const; - - void* toNativeType(NativeType type); - void fromNativeType(void* pixmap, NativeType type); - - void convertToDisplayMode(int mode); - -private: - void release(); - void fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat=false); - QImage toImage(const QRect &r) const; - - QSymbianBitmapDataAccess *symbianBitmapDataAccess; - - CFbsBitmap *cfbsBitmap; - QPaintEngine *pengine; - uchar* bytes; - - bool formatLocked; - - QS60PixmapData *next; - QS60PixmapData *prev; - - static void qt_symbian_register_pixmap(QS60PixmapData *pd); - static void qt_symbian_unregister_pixmap(QS60PixmapData *pd); - static void qt_symbian_release_pixmaps(); - - friend class QPixmap; - friend class QS60WindowSurface; - friend class QS60PaintEngine; - friend class QS60Data; -}; - -QT_END_NAMESPACE - -#endif // QPIXMAPDATA_S60_P_H - diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp deleted file mode 100644 index 0aaf30b8fd..0000000000 --- a/src/gui/image/qpixmap_win.cpp +++ /dev/null @@ -1,477 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpixmap.h" -#include "qpixmap_raster_p.h" - -#include "qbitmap.h" -#include "qimage.h" -#include "qwidget.h" -#include "qpainter.h" -#include "qdatastream.h" -#include "qbuffer.h" -#include "qapplication.h" -#include "qevent.h" -#include "qfile.h" -#include "qfileinfo.h" -#include "qdatetime.h" -#include "qpixmapcache.h" -#include "qimagereader.h" -#include "qimagewriter.h" -#include "qdebug.h" -#include "qt_windows.h" - -#if defined(Q_WS_WINCE) -#include <winbase.h> -#include "qguifunctions_wince.h" -extern bool qt_wince_is_high_dpi(); -extern bool qt_wince_is_pocket_pc(); -#endif - -#ifndef CAPTUREBLT -#define CAPTUREBLT ((DWORD)0x40000000) -#endif - -QT_BEGIN_NAMESPACE - -QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h ) -{ - RECT r; - GetClientRect(winId, &r); - - if (w < 0) w = r.right - r.left; - if (h < 0) h = r.bottom - r.top; - -#ifdef Q_WS_WINCE_WM - if (qt_wince_is_pocket_pc()) { - QWidget *widget = QWidget::find(winId); - if (qobject_cast<QDesktopWidget *>(widget)) { - RECT rect = {0,0,0,0}; - AdjustWindowRectEx(&rect, WS_BORDER | WS_CAPTION, FALSE, 0); - int magicNumber = qt_wince_is_high_dpi() ? 4 : 2; - y += rect.top - magicNumber; - } - } -#endif - - // Create and setup bitmap - HDC display_dc = GetDC(0); - HDC bitmap_dc = CreateCompatibleDC(display_dc); - HBITMAP bitmap = CreateCompatibleBitmap(display_dc, w, h); - HGDIOBJ null_bitmap = SelectObject(bitmap_dc, bitmap); - - // copy data - HDC window_dc = GetDC(winId); - BitBlt(bitmap_dc, 0, 0, w, h, window_dc, x, y, SRCCOPY -#ifndef Q_WS_WINCE - | CAPTUREBLT -#endif - ); - - // clean up all but bitmap - ReleaseDC(winId, window_dc); - SelectObject(bitmap_dc, null_bitmap); - DeleteDC(bitmap_dc); - - QPixmap pixmap = QPixmap::fromWinHBITMAP(bitmap); - - DeleteObject(bitmap); - ReleaseDC(0, display_dc); - - return pixmap; -} - -HBITMAP QPixmap::toWinHBITMAP(HBitmapFormat format) const -{ - if (isNull()) - return 0; - - HBITMAP bitmap = 0; - if (data->classId() == QPixmapData::RasterClass) { - QRasterPixmapData* d = static_cast<QRasterPixmapData*>(data.data()); - int w = d->image.width(); - int h = d->image.height(); - - HDC display_dc = GetDC(0); - - // Define the header - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = w * h * 4; - - // Create the pixmap - uchar *pixels = 0; - bitmap = CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, (void **) &pixels, 0, 0); - ReleaseDC(0, display_dc); - if (!bitmap) { - qErrnoWarning("QPixmap::toWinHBITMAP(), failed to create dibsection"); - return 0; - } - if (!pixels) { - qErrnoWarning("QPixmap::toWinHBITMAP(), did not allocate pixel data"); - return 0; - } - - // Copy over the data - QImage::Format imageFormat = QImage::Format_ARGB32; - if (format == NoAlpha) - imageFormat = QImage::Format_RGB32; - else if (format == PremultipliedAlpha) - imageFormat = QImage::Format_ARGB32_Premultiplied; - const QImage image = d->image.convertToFormat(imageFormat); - int bytes_per_line = w * 4; - for (int y=0; y<h; ++y) - memcpy(pixels + y * bytes_per_line, image.scanLine(y), bytes_per_line); - - } else { - QPixmapData *data = new QRasterPixmapData(depth() == 1 ? - QPixmapData::BitmapType : QPixmapData::PixmapType); - data->fromImage(toImage(), Qt::AutoColor); - return QPixmap(data).toWinHBITMAP(format); - } - return bitmap; -} - -QPixmap QPixmap::fromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format) -{ - // Verify size - BITMAP bitmap_info; - memset(&bitmap_info, 0, sizeof(BITMAP)); - - int res = GetObject(bitmap, sizeof(BITMAP), &bitmap_info); - if (!res) { - qErrnoWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap info"); - return QPixmap(); - } - int w = bitmap_info.bmWidth; - int h = bitmap_info.bmHeight; - - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = w * h * 4; - - QImage result; - // Get bitmap bits - uchar *data = (uchar *) qMalloc(bmi.bmiHeader.biSizeImage); - - HDC display_dc = GetDC(0); - if (GetDIBits(display_dc, bitmap, 0, h, data, &bmi, DIB_RGB_COLORS)) { - - QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied; - uint mask = 0; - if (format == NoAlpha) { - imageFormat = QImage::Format_RGB32; - mask = 0xff000000; - } - - // Create image and copy data into image. - QImage image(w, h, imageFormat); - if (!image.isNull()) { // failed to alloc? - int bytes_per_line = w * sizeof(QRgb); - for (int y=0; y<h; ++y) { - QRgb *dest = (QRgb *) image.scanLine(y); - const QRgb *src = (const QRgb *) (data + y * bytes_per_line); - for (int x=0; x<w; ++x) { - const uint pixel = src[x]; - if ((pixel & 0xff000000) == 0 && (pixel & 0x00ffffff) != 0) - dest[x] = pixel | 0xff000000; - else - dest[x] = pixel | mask; - } - } - } - result = image; - } else { - qWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap bits"); - } - ReleaseDC(0, display_dc); - qFree(data); - return fromImage(result); -} - -HBITMAP qt_createIconMask(const QBitmap &bitmap) -{ - QImage bm = bitmap.toImage().convertToFormat(QImage::Format_Mono); - int w = bm.width(); - int h = bm.height(); - int bpl = ((w+15)/16)*2; // bpl, 16 bit alignment - uchar *bits = new uchar[bpl*h]; - bm.invertPixels(); - for (int y=0; y<h; y++) - memcpy(bits+y*bpl, bm.scanLine(y), bpl); - HBITMAP hbm = CreateBitmap(w, h, 1, 1, bits); - delete [] bits; - return hbm; -} - -HICON QPixmap::toWinHICON() const -{ - QBitmap maskBitmap = mask(); - if (maskBitmap.isNull()) { - maskBitmap= QBitmap(size()); - maskBitmap.fill(Qt::color1); - } - - ICONINFO ii; - ii.fIcon = true; - ii.hbmMask = qt_createIconMask(maskBitmap); - ii.hbmColor = toWinHBITMAP(QPixmap::Alpha); - ii.xHotspot = 0; - ii.yHotspot = 0; - - HICON hIcon = CreateIconIndirect(&ii); - - DeleteObject(ii.hbmColor); - DeleteObject(ii.hbmMask); - - return hIcon; -} - -#ifdef Q_WS_WIN -#ifndef Q_WS_WINCE - -static QImage qt_fromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h) -{ - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = w * h * 4; - - QImage image(w, h, QImage::Format_ARGB32_Premultiplied); - if (image.isNull()) - return image; - - // Get bitmap bits - uchar *data = (uchar *) qMalloc(bmi.bmiHeader.biSizeImage); - - if (GetDIBits(hdc, bitmap, 0, h, data, &bmi, DIB_RGB_COLORS)) { - // Create image and copy data into image. - for (int y=0; y<h; ++y) { - void *dest = (void *) image.scanLine(y); - void *src = data + y * image.bytesPerLine(); - memcpy(dest, src, image.bytesPerLine()); - } - } else { - qWarning("qt_fromWinHBITMAP(), failed to get bitmap bits"); - } - qFree(data); - - return image; -} - -QPixmap QPixmap::fromWinHICON(HICON icon) -{ - bool foundAlpha = false; - HDC screenDevice = GetDC(0); - HDC hdc = CreateCompatibleDC(screenDevice); - ReleaseDC(0, screenDevice); - - ICONINFO iconinfo; - bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center - if (!result) - qWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()"); - - int w = iconinfo.xHotspot * 2; - int h = iconinfo.yHotspot * 2; - - BITMAPINFOHEADER bitmapInfo; - bitmapInfo.biSize = sizeof(BITMAPINFOHEADER); - bitmapInfo.biWidth = w; - bitmapInfo.biHeight = h; - bitmapInfo.biPlanes = 1; - bitmapInfo.biBitCount = 32; - bitmapInfo.biCompression = BI_RGB; - bitmapInfo.biSizeImage = 0; - bitmapInfo.biXPelsPerMeter = 0; - bitmapInfo.biYPelsPerMeter = 0; - bitmapInfo.biClrUsed = 0; - bitmapInfo.biClrImportant = 0; - DWORD* bits; - - HBITMAP winBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bitmapInfo, DIB_RGB_COLORS, (VOID**)&bits, NULL, 0); - HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap); - DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL); - QImage image = qt_fromWinHBITMAP(hdc, winBitmap, w, h); - - for (int y = 0 ; y < h && !foundAlpha ; y++) { - QRgb *scanLine= reinterpret_cast<QRgb *>(image.scanLine(y)); - for (int x = 0; x < w ; x++) { - if (qAlpha(scanLine[x]) != 0) { - foundAlpha = true; - break; - } - } - } - if (!foundAlpha) { - //If no alpha was found, we use the mask to set alpha values - DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK); - QImage mask = qt_fromWinHBITMAP(hdc, winBitmap, w, h); - - for (int y = 0 ; y < h ; y++){ - QRgb *scanlineImage = reinterpret_cast<QRgb *>(image.scanLine(y)); - QRgb *scanlineMask = mask.isNull() ? 0 : reinterpret_cast<QRgb *>(mask.scanLine(y)); - for (int x = 0; x < w ; x++){ - if (scanlineMask && qRed(scanlineMask[x]) != 0) - scanlineImage[x] = 0; //mask out this pixel - else - scanlineImage[x] |= 0xff000000; // set the alpha channel to 255 - } - } - } - //dispose resources created by iconinfo call - DeleteObject(iconinfo.hbmMask); - DeleteObject(iconinfo.hbmColor); - - SelectObject(hdc, oldhdc); //restore state - DeleteObject(winBitmap); - DeleteDC(hdc); - return QPixmap::fromImage(image); -} -#else //ifndef Q_WS_WINCE -QPixmap QPixmap::fromWinHICON(HICON icon) -{ - HDC screenDevice = GetDC(0); - HDC hdc = CreateCompatibleDC(screenDevice); - ReleaseDC(0, screenDevice); - - ICONINFO iconinfo; - bool result = GetIconInfo(icon, &iconinfo); - if (!result) - qWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()"); - - int w = 0; - int h = 0; - if (!iconinfo.xHotspot || !iconinfo.yHotspot) { - // We could not retrieve the icon size via GetIconInfo, - // so we try again using the icon bitmap. - BITMAP bm; - int result = GetObject(iconinfo.hbmColor, sizeof(BITMAP), &bm); - if (!result) result = GetObject(iconinfo.hbmMask, sizeof(BITMAP), &bm); - if (!result) { - qWarning("QPixmap::fromWinHICON(), failed to retrieve icon size"); - return QPixmap(); - } - w = bm.bmWidth; - h = bm.bmHeight; - } else { - // x and y Hotspot describes the icon center - w = iconinfo.xHotspot * 2; - h = iconinfo.yHotspot * 2; - } - const DWORD dwImageSize = w * h * 4; - - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFO); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = dwImageSize; - - uchar* bits; - - HBITMAP winBitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &bits, 0, 0); - if (winBitmap ) - memset(bits, 0xff, dwImageSize); - if (!winBitmap) { - qWarning("QPixmap::fromWinHICON(), failed to CreateDIBSection()"); - return QPixmap(); - } - - HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap); - if (!DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_NORMAL)) - qWarning("QPixmap::fromWinHICON(), failed to DrawIcon()"); - - uint mask = 0xff000000; - // Create image and copy data into image. - QImage image(w, h, QImage::Format_ARGB32); - - if (!image.isNull()) { // failed to alloc? - int bytes_per_line = w * sizeof(QRgb); - for (int y=0; y < h; ++y) { - QRgb *dest = (QRgb *) image.scanLine(y); - const QRgb *src = (const QRgb *) (bits + y * bytes_per_line); - for (int x=0; x < w; ++x) { - dest[x] = src[x]; - } - } - } - if (!DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK)) - qWarning("QPixmap::fromWinHICON(), failed to DrawIcon()"); - if (!image.isNull()) { // failed to alloc? - int bytes_per_line = w * sizeof(QRgb); - for (int y=0; y < h; ++y) { - QRgb *dest = (QRgb *) image.scanLine(y); - const QRgb *src = (const QRgb *) (bits + y * bytes_per_line); - for (int x=0; x < w; ++x) { - if (!src[x]) - dest[x] = dest[x] | mask; - } - } - } - SelectObject(hdc, oldhdc); //restore state - DeleteObject(winBitmap); - DeleteDC(hdc); - return QPixmap::fromImage(image); -} -#endif //ifndef Q_WS_WINCE -#endif //ifdef Q_WS_WIN - -QT_END_NAMESPACE diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp deleted file mode 100644 index 77c2a2a9d9..0000000000 --- a/src/gui/image/qpixmap_x11.cpp +++ /dev/null @@ -1,2419 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// Uncomment the next line to enable the MIT Shared Memory extension -// -// WARNING: This has some problems: -// -// 1. Consumes a 800x600 pixmap -// 2. Qt does not handle the ShmCompletion message, so you will -// get strange effects if you xForm() repeatedly. -// -// #define QT_MITSHM - -#if defined(Q_OS_WIN32) && defined(QT_MITSHM) -#undef QT_MITSHM -#endif - -#include "qplatformdefs.h" - -#include "qdebug.h" -#include "qiodevice.h" -#include "qpixmap_x11_p.h" -#include "qbitmap.h" -#include "qcolormap.h" -#include "qimage.h" -#include "qmatrix.h" -#include "qapplication.h" -#include <private/qpaintengine_x11_p.h> -#include <private/qt_x11_p.h> -#include "qx11info_x11.h" -#include <private/qdrawhelper_p.h> -#include <private/qimage_p.h> -#include <private/qimagepixmapcleanuphooks_p.h> - -#include <stdlib.h> - -#if defined(Q_CC_MIPS) -# define for if(0){}else for -#endif - -QT_BEGIN_NAMESPACE - -QPixmap qt_toX11Pixmap(const QImage &image) -{ - QPixmapData *data = - new QX11PixmapData(image.depth() == 1 - ? QPixmapData::BitmapType - : QPixmapData::PixmapType); - - data->fromImage(image, Qt::AutoColor); - - return QPixmap(data); -} - -QPixmap qt_toX11Pixmap(const QPixmap &pixmap) -{ - if (pixmap.isNull()) - return QPixmap(); - - if (QPixmap(pixmap).data_ptr()->classId() == QPixmapData::X11Class) - return pixmap; - - return qt_toX11Pixmap(pixmap.toImage()); -} - -// For thread-safety: -// image->data does not belong to X11, so we must free it ourselves. - -inline static void qSafeXDestroyImage(XImage *x) -{ - if (x->data) { - free(x->data); - x->data = 0; - } - XDestroyImage(x); -} - -QBitmap QX11PixmapData::mask_to_bitmap(int screen) const -{ - if (!x11_mask) - return QBitmap(); - QPixmap::x11SetDefaultScreen(screen); - QBitmap bm(w, h); - GC gc = XCreateGC(X11->display, bm.handle(), 0, 0); - XCopyArea(X11->display, x11_mask, bm.handle(), gc, 0, 0, - bm.data->width(), bm.data->height(), 0, 0); - XFreeGC(X11->display, gc); - return bm; -} - -Qt::HANDLE QX11PixmapData::bitmap_to_mask(const QBitmap &bitmap, int screen) -{ - if (bitmap.isNull()) - return 0; - QBitmap bm = bitmap; - bm.x11SetScreen(screen); - - Pixmap mask = XCreatePixmap(X11->display, RootWindow(X11->display, screen), - bm.data->width(), bm.data->height(), 1); - GC gc = XCreateGC(X11->display, mask, 0, 0); - XCopyArea(X11->display, bm.handle(), mask, gc, 0, 0, - bm.data->width(), bm.data->height(), 0, 0); - XFreeGC(X11->display, gc); - return mask; -} - - -/***************************************************************************** - MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster. - *****************************************************************************/ - -#if defined(QT_MITSHM) - -static bool xshminit = false; -static XShmSegmentInfo xshminfo; -static XImage *xshmimg = 0; -static Pixmap xshmpm = 0; - -static void qt_cleanup_mitshm() -{ - if (xshmimg == 0) - return; - Display *dpy = QX11Info::appDisplay(); - if (xshmpm) { - XFreePixmap(dpy, xshmpm); - xshmpm = 0; - } - XShmDetach(dpy, &xshminfo); xshmimg->data = 0; - qSafeXDestroyImage(xshmimg); xshmimg = 0; - shmdt(xshminfo.shmaddr); - shmctl(xshminfo.shmid, IPC_RMID, 0); -} - -static bool qt_create_mitshm_buffer(const QPaintDevice* dev, int w, int h) -{ - static int major, minor; - static Bool pixmaps_ok; - Display *dpy = dev->data->xinfo->display(); - int dd = dev->x11Depth(); - Visual *vis = (Visual*)dev->x11Visual(); - - if (xshminit) { - qt_cleanup_mitshm(); - } else { - if (!XShmQueryVersion(dpy, &major, &minor, &pixmaps_ok)) - return false; // MIT Shm not supported - qAddPostRoutine(qt_cleanup_mitshm); - xshminit = true; - } - - xshmimg = XShmCreateImage(dpy, vis, dd, ZPixmap, 0, &xshminfo, w, h); - if (!xshmimg) - return false; - - bool ok; - xshminfo.shmid = shmget(IPC_PRIVATE, - xshmimg->bytes_per_line * xshmimg->height, - IPC_CREAT | 0777); - ok = xshminfo.shmid != -1; - if (ok) { - xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0); - xshminfo.shmaddr = xshmimg->data; - ok = (xshminfo.shmaddr != (char*)-1); - } - xshminfo.readOnly = false; - if (ok) - ok = XShmAttach(dpy, &xshminfo); - if (!ok) { - qSafeXDestroyImage(xshmimg); - xshmimg = 0; - if (xshminfo.shmaddr) - shmdt(xshminfo.shmaddr); - if (xshminfo.shmid != -1) - shmctl(xshminfo.shmid, IPC_RMID, 0); - return false; - } - if (pixmaps_ok) - xshmpm = XShmCreatePixmap(dpy, DefaultRootWindow(dpy), xshmimg->data, - &xshminfo, w, h, dd); - - return true; -} - -#else - -// If extern, need a dummy. -// -// static bool qt_create_mitshm_buffer(QPaintDevice*, int, int) -// { -// return false; -// } - -#endif // QT_MITSHM - - -/***************************************************************************** - Internal functions - *****************************************************************************/ - -extern const uchar *qt_get_bitflip_array(); // defined in qimage.cpp - -// Returns position of highest bit set or -1 if none -static int highest_bit(uint v) -{ - int i; - uint b = (uint)1 << 31; - for (i=31; ((b & v) == 0) && i>=0; i--) - b >>= 1; - return i; -} - -// Returns position of lowest set bit in 'v' as an integer (0-31), or -1 -static int lowest_bit(uint v) -{ - int i; - ulong lb; - lb = 1; - for (i=0; ((v & lb) == 0) && i<32; i++, lb<<=1) {} - return i==32 ? -1 : i; -} - -// Counts the number of bits set in 'v' -static uint n_bits(uint v) -{ - int i = 0; - while (v) { - v = v & (v - 1); - i++; - } - return i; -} - -static uint *red_scale_table = 0; -static uint *green_scale_table = 0; -static uint *blue_scale_table = 0; - -static void cleanup_scale_tables() -{ - delete[] red_scale_table; - delete[] green_scale_table; - delete[] blue_scale_table; -} - -/* - Could do smart bitshifting, but the "obvious" algorithm only works for - nBits >= 4. This is more robust. -*/ -static void build_scale_table(uint **table, uint nBits) -{ - if (nBits > 7) { - qWarning("build_scale_table: internal error, nBits = %i", nBits); - return; - } - if (!*table) { - static bool firstTable = true; - if (firstTable) { - qAddPostRoutine(cleanup_scale_tables); - firstTable = false; - } - *table = new uint[256]; - } - int maxVal = (1 << nBits) - 1; - int valShift = 8 - nBits; - int i; - for(i = 0 ; i < maxVal + 1 ; i++) - (*table)[i << valShift] = i*255/maxVal; -} - -static int defaultScreen = -1; - -/***************************************************************************** - QPixmap member functions - *****************************************************************************/ - -QBasicAtomicInt qt_pixmap_serial = Q_BASIC_ATOMIC_INITIALIZER(0); -int Q_GUI_EXPORT qt_x11_preferred_pixmap_depth = 0; - -QX11PixmapData::QX11PixmapData(PixelType type) - : QPixmapData(type, X11Class), gl_surface(0), hd(0), - flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0), - share_mode(QPixmap::ImplicitlyShared), pengine(0) -{ -} - -QPixmapData *QX11PixmapData::createCompatiblePixmapData() const -{ - return new QX11PixmapData(pixelType()); -} - -void QX11PixmapData::resize(int width, int height) -{ - setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1)); - - w = width; - h = height; - is_null = (w <= 0 || h <= 0); - - if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) { - QX11InfoData* xd = xinfo.getX11Data(true); - xd->screen = defaultScreen; - xd->depth = QX11Info::appDepth(xd->screen); - xd->cells = QX11Info::appCells(xd->screen); - xd->colormap = QX11Info::appColormap(xd->screen); - xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen); - xd->visual = (Visual *)QX11Info::appVisual(xd->screen); - xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen); - xinfo.setX11Data(xd); - } - - int dd = xinfo.depth(); - - if (qt_x11_preferred_pixmap_depth) - dd = qt_x11_preferred_pixmap_depth; - - bool make_null = w <= 0 || h <= 0; // create null pixmap - d = (pixelType() == BitmapType ? 1 : dd); - if (make_null || d == 0) { - w = 0; - h = 0; - is_null = true; - hd = 0; - picture = 0; - d = 0; - if (!make_null) - qWarning("QPixmap: Invalid pixmap parameters"); - return; - } - hd = (Qt::HANDLE)XCreatePixmap(X11->display, - RootWindow(X11->display, xinfo.screen()), - w, h, d); -#ifndef QT_NO_XRENDER - if (X11->use_xrender) { - XRenderPictFormat *format = d == 1 - ? XRenderFindStandardFormat(X11->display, PictStandardA1) - : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual()); - picture = XRenderCreatePicture(X11->display, hd, format, 0, 0); - } -#endif // QT_NO_XRENDER -} - -struct QX11AlphaDetector -{ - bool hasAlpha() const { - if (checked) - return has; - // Will implicitly also check format and return quickly for opaque types... - checked = true; - has = image->isNull() ? false : const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels(); - return has; - } - - bool hasXRenderAndAlpha() const { - if (!X11->use_xrender) - return false; - return hasAlpha(); - } - - QX11AlphaDetector(const QImage *i, Qt::ImageConversionFlags flags) - : image(i), checked(false), has(false) - { - if (flags & Qt::NoOpaqueDetection) { - checked = true; - has = image->hasAlphaChannel(); - } - } - - const QImage *image; - mutable bool checked; - mutable bool has; -}; - -void QX11PixmapData::fromImage(const QImage &img, - Qt::ImageConversionFlags flags) -{ - setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1)); - - w = img.width(); - h = img.height(); - d = img.depth(); - is_null = (w <= 0 || h <= 0); - - if (is_null) { - w = h = 0; - return; - } - - if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) { - QX11InfoData* xd = xinfo.getX11Data(true); - xd->screen = defaultScreen; - xd->depth = QX11Info::appDepth(xd->screen); - xd->cells = QX11Info::appCells(xd->screen); - xd->colormap = QX11Info::appColormap(xd->screen); - xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen); - xd->visual = (Visual *)QX11Info::appVisual(xd->screen); - xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen); - xinfo.setX11Data(xd); - } - - if (pixelType() == BitmapType) { - bitmapFromImage(img); - return; - } - - if (uint(w) >= 32768 || uint(h) >= 32768) { - w = h = 0; - is_null = true; - return; - } - - QX11AlphaDetector alphaCheck(&img, flags); - int dd = alphaCheck.hasXRenderAndAlpha() ? 32 : xinfo.depth(); - - if (qt_x11_preferred_pixmap_depth) - dd = qt_x11_preferred_pixmap_depth; - - QImage image = img; - - // must be monochrome - if (dd == 1 || (flags & Qt::ColorMode_Mask) == Qt::MonoOnly) { - if (d != 1) { - // dither - image = image.convertToFormat(QImage::Format_MonoLSB, flags); - d = 1; - } - } else { // can be both - bool conv8 = false; - if (d > 8 && dd <= 8) { // convert to 8 bit - if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither) - flags = (flags & ~Qt::DitherMode_Mask) - | Qt::PreferDither; - conv8 = true; - } else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) { - conv8 = (d == 1); // native depth wanted - } else if (d == 1) { - if (image.colorCount() == 2) { - QRgb c0 = image.color(0); // Auto: convert to best - QRgb c1 = image.color(1); - conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255); - } else { - // eg. 1-color monochrome images (they do exist). - conv8 = true; - } - } - if (conv8) { - image = image.convertToFormat(QImage::Format_Indexed8, flags); - d = 8; - } - } - - if (d == 1 || d == 16 || d == 24) { - image = image.convertToFormat(QImage::Format_RGB32, flags); - fromImage(image, Qt::AutoColor); - return; - } - - Display *dpy = X11->display; - Visual *visual = (Visual *)xinfo.visual(); - XImage *xi = 0; - bool trucol = (visual->c_class >= TrueColor); - int nbytes = image.byteCount(); - uchar *newbits= 0; - -#ifndef QT_NO_XRENDER - if (alphaCheck.hasXRenderAndAlpha()) { - const QImage &cimage = image; - - d = 32; - - if (QX11Info::appDepth() != d) { - if (xinfo.x11data) { - xinfo.x11data->depth = d; - } else { - QX11InfoData *xd = xinfo.getX11Data(true); - xd->screen = QX11Info::appScreen(); - xd->depth = d; - xd->cells = QX11Info::appCells(); - xd->colormap = QX11Info::appColormap(); - xd->defaultColormap = QX11Info::appDefaultColormap(); - xd->visual = (Visual *)QX11Info::appVisual(); - xd->defaultVisual = QX11Info::appDefaultVisual(); - xinfo.setX11Data(xd); - } - } - - hd = (Qt::HANDLE)XCreatePixmap(dpy, RootWindow(dpy, xinfo.screen()), - w, h, d); - picture = XRenderCreatePicture(X11->display, hd, - XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0); - - xi = XCreateImage(dpy, visual, d, ZPixmap, 0, 0, w, h, 32, 0); - Q_CHECK_PTR(xi); - newbits = (uchar *)malloc(xi->bytes_per_line*h); - Q_CHECK_PTR(newbits); - xi->data = (char *)newbits; - - switch(cimage.format()) { - case QImage::Format_Indexed8: { - QVector<QRgb> colorTable = cimage.colorTable(); - uint *xidata = (uint *)xi->data; - for (int y = 0; y < h; ++y) { - const uchar *p = cimage.scanLine(y); - for (int x = 0; x < w; ++x) { - const QRgb rgb = colorTable[p[x]]; - const int a = qAlpha(rgb); - if (a == 0xff) - *xidata = rgb; - else - // RENDER expects premultiplied alpha - *xidata = qRgba(qt_div_255(qRed(rgb) * a), - qt_div_255(qGreen(rgb) * a), - qt_div_255(qBlue(rgb) * a), - a); - ++xidata; - } - } - } - break; - case QImage::Format_RGB32: { - uint *xidata = (uint *)xi->data; - for (int y = 0; y < h; ++y) { - const QRgb *p = (const QRgb *) cimage.scanLine(y); - for (int x = 0; x < w; ++x) - *xidata++ = p[x] | 0xff000000; - } - } - break; - case QImage::Format_ARGB32: { - uint *xidata = (uint *)xi->data; - for (int y = 0; y < h; ++y) { - const QRgb *p = (const QRgb *) cimage.scanLine(y); - for (int x = 0; x < w; ++x) { - const QRgb rgb = p[x]; - const int a = qAlpha(rgb); - if (a == 0xff) - *xidata = rgb; - else - // RENDER expects premultiplied alpha - *xidata = qRgba(qt_div_255(qRed(rgb) * a), - qt_div_255(qGreen(rgb) * a), - qt_div_255(qBlue(rgb) * a), - a); - ++xidata; - } - } - - } - break; - case QImage::Format_ARGB32_Premultiplied: { - uint *xidata = (uint *)xi->data; - for (int y = 0; y < h; ++y) { - const QRgb *p = (const QRgb *) cimage.scanLine(y); - memcpy(xidata, p, w*sizeof(QRgb)); - xidata += w; - } - } - break; - default: - Q_ASSERT(false); - } - - if ((xi->byte_order == MSBFirst) != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) { - uint *xidata = (uint *)xi->data; - uint *xiend = xidata + w*h; - while (xidata < xiend) { - *xidata = (*xidata >> 24) - | ((*xidata >> 8) & 0xff00) - | ((*xidata << 8) & 0xff0000) - | (*xidata << 24); - ++xidata; - } - } - - GC gc = XCreateGC(dpy, hd, 0, 0); - XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h); - XFreeGC(dpy, gc); - - qSafeXDestroyImage(xi); - - return; - } -#endif // QT_NO_XRENDER - - if (trucol) { // truecolor display - if (image.format() == QImage::Format_ARGB32_Premultiplied) - image = image.convertToFormat(QImage::Format_ARGB32); - - const QImage &cimage = image; - QRgb pix[256]; // pixel translation table - const bool d8 = (d == 8); - const uint red_mask = (uint)visual->red_mask; - const uint green_mask = (uint)visual->green_mask; - const uint blue_mask = (uint)visual->blue_mask; - const int red_shift = highest_bit(red_mask) - 7; - const int green_shift = highest_bit(green_mask) - 7; - const int blue_shift = highest_bit(blue_mask) - 7; - const uint rbits = highest_bit(red_mask) - lowest_bit(red_mask) + 1; - const uint gbits = highest_bit(green_mask) - lowest_bit(green_mask) + 1; - const uint bbits = highest_bit(blue_mask) - lowest_bit(blue_mask) + 1; - - if (d8) { // setup pixel translation - QVector<QRgb> ctable = cimage.colorTable(); - for (int i=0; i < cimage.colorCount(); i++) { - int r = qRed (ctable[i]); - int g = qGreen(ctable[i]); - int b = qBlue (ctable[i]); - r = red_shift > 0 ? r << red_shift : r >> -red_shift; - g = green_shift > 0 ? g << green_shift : g >> -green_shift; - b = blue_shift > 0 ? b << blue_shift : b >> -blue_shift; - pix[i] = (b & blue_mask) | (g & green_mask) | (r & red_mask) - | ~(blue_mask | green_mask | red_mask); - } - } - - xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0); - Q_CHECK_PTR(xi); - newbits = (uchar *)malloc(xi->bytes_per_line*h); - Q_CHECK_PTR(newbits); - if (!newbits) // no memory - return; - int bppc = xi->bits_per_pixel; - - bool contig_bits = n_bits(red_mask) == rbits && - n_bits(green_mask) == gbits && - n_bits(blue_mask) == bbits; - bool dither_tc = - // Want it? - (flags & Qt::Dither_Mask) != Qt::ThresholdDither && - (flags & Qt::DitherMode_Mask) != Qt::AvoidDither && - // Need it? - bppc < 24 && !d8 && - // Can do it? (Contiguous bits?) - contig_bits; - - static bool init=false; - static int D[16][16]; - if (dither_tc && !init) { - // I also contributed this code to XV - WWA. - /* - The dither matrix, D, is obtained with this formula: - - D2 = [0 2] - [3 1] - - - D2*n = [4*Dn 4*Dn+2*Un] - [4*Dn+3*Un 4*Dn+1*Un] - */ - int n,i,j; - init=1; - - /* Set D2 */ - D[0][0]=0; - D[1][0]=2; - D[0][1]=3; - D[1][1]=1; - - /* Expand using recursive definition given above */ - for (n=2; n<16; n*=2) { - for (i=0; i<n; i++) { - for (j=0; j<n; j++) { - D[i][j]*=4; - D[i+n][j]=D[i][j]+2; - D[i][j+n]=D[i][j]+3; - D[i+n][j+n]=D[i][j]+1; - } - } - } - init=true; - } - - enum { BPP8, - BPP16_565, BPP16_555, - BPP16_MSB, BPP16_LSB, - BPP24_888, - BPP24_MSB, BPP24_LSB, - BPP32_8888, - BPP32_MSB, BPP32_LSB - } mode = BPP8; - - bool same_msb_lsb = (xi->byte_order == MSBFirst) == (QSysInfo::ByteOrder == QSysInfo::BigEndian); - - if(bppc == 8) // 8 bit - mode = BPP8; - else if(bppc == 16) { // 16 bit MSB/LSB - if(red_shift == 8 && green_shift == 3 && blue_shift == -3 && !d8 && same_msb_lsb) - mode = BPP16_565; - else if(red_shift == 7 && green_shift == 2 && blue_shift == -3 && !d8 && same_msb_lsb) - mode = BPP16_555; - else - mode = (xi->byte_order == LSBFirst) ? BPP16_LSB : BPP16_MSB; - } else if(bppc == 24) { // 24 bit MSB/LSB - if (red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb) - mode = BPP24_888; - else - mode = (xi->byte_order == LSBFirst) ? BPP24_LSB : BPP24_MSB; - } else if(bppc == 32) { // 32 bit MSB/LSB - if(red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb) - mode = BPP32_8888; - else - mode = (xi->byte_order == LSBFirst) ? BPP32_LSB : BPP32_MSB; - } else - qFatal("Logic error 3"); - -#define GET_PIXEL \ - uint pixel; \ - if (d8) pixel = pix[*src++]; \ - else { \ - int r = qRed (*p); \ - int g = qGreen(*p); \ - int b = qBlue (*p++); \ - r = red_shift > 0 \ - ? r << red_shift : r >> -red_shift; \ - g = green_shift > 0 \ - ? g << green_shift : g >> -green_shift; \ - b = blue_shift > 0 \ - ? b << blue_shift : b >> -blue_shift; \ - pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask) \ - | ~(blue_mask | green_mask | red_mask); \ - } - -#define GET_PIXEL_DITHER_TC \ - int r = qRed (*p); \ - int g = qGreen(*p); \ - int b = qBlue (*p++); \ - const int thres = D[x%16][y%16]; \ - if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \ - > thres) \ - r += (1<<(8-rbits)); \ - if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \ - > thres) \ - g += (1<<(8-gbits)); \ - if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \ - > thres) \ - b += (1<<(8-bbits)); \ - r = red_shift > 0 \ - ? r << red_shift : r >> -red_shift; \ - g = green_shift > 0 \ - ? g << green_shift : g >> -green_shift; \ - b = blue_shift > 0 \ - ? b << blue_shift : b >> -blue_shift; \ - uint pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask); - -// again, optimized case -// can't be optimized that much :( -#define GET_PIXEL_DITHER_TC_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask, \ - rbits,gbits,bbits) \ - const int thres = D[x%16][y%16]; \ - int r = qRed (*p); \ - if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \ - > thres) \ - r += (1<<(8-rbits)); \ - int g = qGreen(*p); \ - if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \ - > thres) \ - g += (1<<(8-gbits)); \ - int b = qBlue (*p++); \ - if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \ - > thres) \ - b += (1<<(8-bbits)); \ - uint pixel = ((r red_shift) & red_mask) \ - | ((g green_shift) & green_mask) \ - | ((b blue_shift) & blue_mask); - -#define CYCLE(body) \ - for (int y=0; y<h; y++) { \ - const uchar* src = cimage.scanLine(y); \ - uchar* dst = newbits + xi->bytes_per_line*y; \ - const QRgb* p = (const QRgb *)src; \ - body \ - } - - if (dither_tc) { - switch (mode) { - case BPP16_565: - CYCLE( - quint16* dst16 = (quint16*)dst; - for (int x=0; x<w; x++) { - GET_PIXEL_DITHER_TC_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f,5,6,5) - *dst16++ = pixel; - } - ) - break; - case BPP16_555: - CYCLE( - quint16* dst16 = (quint16*)dst; - for (int x=0; x<w; x++) { - GET_PIXEL_DITHER_TC_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f,5,5,5) - *dst16++ = pixel; - } - ) - break; - case BPP16_MSB: // 16 bit MSB - CYCLE( - for (int x=0; x<w; x++) { - GET_PIXEL_DITHER_TC - *dst++ = (pixel >> 8); - *dst++ = pixel; - } - ) - break; - case BPP16_LSB: // 16 bit LSB - CYCLE( - for (int x=0; x<w; x++) { - GET_PIXEL_DITHER_TC - *dst++ = pixel; - *dst++ = pixel >> 8; - } - ) - break; - default: - qFatal("Logic error"); - } - } else { - switch (mode) { - case BPP8: // 8 bit - CYCLE( - Q_UNUSED(p); - for (int x=0; x<w; x++) - *dst++ = pix[*src++]; - ) - break; - case BPP16_565: - CYCLE( - quint16* dst16 = (quint16*)dst; - for (int x = 0; x < w; x++) { - *dst16++ = ((*p >> 8) & 0xf800) - | ((*p >> 5) & 0x7e0) - | ((*p >> 3) & 0x1f); - ++p; - } - ) - break; - case BPP16_555: - CYCLE( - quint16* dst16 = (quint16*)dst; - for (int x=0; x<w; x++) { - *dst16++ = ((*p >> 9) & 0x7c00) - | ((*p >> 6) & 0x3e0) - | ((*p >> 3) & 0x1f); - ++p; - } - ) - break; - case BPP16_MSB: // 16 bit MSB - CYCLE( - for (int x=0; x<w; x++) { - GET_PIXEL - *dst++ = (pixel >> 8); - *dst++ = pixel; - } - ) - break; - case BPP16_LSB: // 16 bit LSB - CYCLE( - for (int x=0; x<w; x++) { - GET_PIXEL - *dst++ = pixel; - *dst++ = pixel >> 8; - } - ) - break; - case BPP24_888: // 24 bit MSB - CYCLE( - for (int x=0; x<w; x++) { - *dst++ = qRed (*p); - *dst++ = qGreen(*p); - *dst++ = qBlue (*p++); - } - ) - break; - case BPP24_MSB: // 24 bit MSB - CYCLE( - for (int x=0; x<w; x++) { - GET_PIXEL - *dst++ = pixel >> 16; - *dst++ = pixel >> 8; - *dst++ = pixel; - } - ) - break; - case BPP24_LSB: // 24 bit LSB - CYCLE( - for (int x=0; x<w; x++) { - GET_PIXEL - *dst++ = pixel; - *dst++ = pixel >> 8; - *dst++ = pixel >> 16; - } - ) - break; - case BPP32_8888: - CYCLE( - memcpy(dst, p, w * 4); - ) - break; - case BPP32_MSB: // 32 bit MSB - CYCLE( - for (int x=0; x<w; x++) { - GET_PIXEL - *dst++ = pixel >> 24; - *dst++ = pixel >> 16; - *dst++ = pixel >> 8; - *dst++ = pixel; - } - ) - break; - case BPP32_LSB: // 32 bit LSB - CYCLE( - for (int x=0; x<w; x++) { - GET_PIXEL - *dst++ = pixel; - *dst++ = pixel >> 8; - *dst++ = pixel >> 16; - *dst++ = pixel >> 24; - } - ) - break; - default: - qFatal("Logic error 2"); - } - } - xi->data = (char *)newbits; - } - - if (d == 8 && !trucol) { // 8 bit pixmap - int pop[256]; // pixel popularity - - if (image.colorCount() == 0) - image.setColorCount(1); - - const QImage &cimage = image; - memset(pop, 0, sizeof(int)*256); // reset popularity array - for (int i = 0; i < h; i++) { // for each scanline... - const uchar* p = cimage.scanLine(i); - const uchar *end = p + w; - while (p < end) // compute popularity - pop[*p++]++; - } - - newbits = (uchar *)malloc(nbytes); // copy image into newbits - Q_CHECK_PTR(newbits); - if (!newbits) // no memory - return; - uchar* p = newbits; - memcpy(p, cimage.bits(), nbytes); // copy image data into newbits - - /* - * The code below picks the most important colors. It is based on the - * diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley. - */ - - struct PIX { // pixel sort element - uchar r,g,b,n; // color + pad - int use; // popularity - int index; // index in colormap - int mindist; - }; - int ncols = 0; - for (int i=0; i< cimage.colorCount(); i++) { // compute number of colors - if (pop[i] > 0) - ncols++; - } - for (int i = cimage.colorCount(); i < 256; i++) // ignore out-of-range pixels - pop[i] = 0; - - // works since we make sure above to have at least - // one color in the image - if (ncols == 0) - ncols = 1; - - PIX pixarr[256]; // pixel array - PIX pixarr_sorted[256]; // pixel array (sorted) - memset(pixarr, 0, ncols*sizeof(PIX)); - PIX *px = &pixarr[0]; - int maxpop = 0; - int maxpix = 0; - uint j = 0; - QVector<QRgb> ctable = cimage.colorTable(); - for (int i = 0; i < 256; i++) { // init pixel array - if (pop[i] > 0) { - px->r = qRed (ctable[i]); - px->g = qGreen(ctable[i]); - px->b = qBlue (ctable[i]); - px->n = 0; - px->use = pop[i]; - if (pop[i] > maxpop) { // select most popular entry - maxpop = pop[i]; - maxpix = j; - } - px->index = i; - px->mindist = 1000000; - px++; - j++; - } - } - pixarr_sorted[0] = pixarr[maxpix]; - pixarr[maxpix].use = 0; - - for (int i = 1; i < ncols; i++) { // sort pixels - int minpix = -1, mindist = -1; - px = &pixarr_sorted[i-1]; - int r = px->r; - int g = px->g; - int b = px->b; - int dist; - if ((i & 1) || i<10) { // sort on max distance - for (int j=0; j<ncols; j++) { - px = &pixarr[j]; - if (px->use) { - dist = (px->r - r)*(px->r - r) + - (px->g - g)*(px->g - g) + - (px->b - b)*(px->b - b); - if (px->mindist > dist) - px->mindist = dist; - if (px->mindist > mindist) { - mindist = px->mindist; - minpix = j; - } - } - } - } else { // sort on max popularity - for (int j=0; j<ncols; j++) { - px = &pixarr[j]; - if (px->use) { - dist = (px->r - r)*(px->r - r) + - (px->g - g)*(px->g - g) + - (px->b - b)*(px->b - b); - if (px->mindist > dist) - px->mindist = dist; - if (px->use > mindist) { - mindist = px->use; - minpix = j; - } - } - } - } - pixarr_sorted[i] = pixarr[minpix]; - pixarr[minpix].use = 0; - } - - QColormap cmap = QColormap::instance(xinfo.screen()); - uint pix[256]; // pixel translation table - px = &pixarr_sorted[0]; - for (int i = 0; i < ncols; i++) { // allocate colors - QColor c(px->r, px->g, px->b); - pix[px->index] = cmap.pixel(c); - px++; - } - - p = newbits; - for (int i = 0; i < nbytes; i++) { // translate pixels - *p = pix[*p]; - p++; - } - } - - if (!xi) { // X image not created - xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0); - if (xi->bits_per_pixel == 16) { // convert 8 bpp ==> 16 bpp - ushort *p2; - int p2inc = xi->bytes_per_line/sizeof(ushort); - ushort *newerbits = (ushort *)malloc(xi->bytes_per_line * h); - Q_CHECK_PTR(newerbits); - if (!newerbits) // no memory - return; - uchar* p = newbits; - for (int y = 0; y < h; y++) { // OOPS: Do right byte order!! - p2 = newerbits + p2inc*y; - for (int x = 0; x < w; x++) - *p2++ = *p++; - } - free(newbits); - newbits = (uchar *)newerbits; - } else if (xi->bits_per_pixel != 8) { - qWarning("QPixmap::fromImage: Display not supported " - "(bpp=%d)", xi->bits_per_pixel); - } - xi->data = (char *)newbits; - } - - hd = (Qt::HANDLE)XCreatePixmap(X11->display, - RootWindow(X11->display, xinfo.screen()), - w, h, dd); - - GC gc = XCreateGC(dpy, hd, 0, 0); - XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h); - XFreeGC(dpy, gc); - - qSafeXDestroyImage(xi); - d = dd; - -#ifndef QT_NO_XRENDER - if (X11->use_xrender) { - XRenderPictFormat *format = d == 1 - ? XRenderFindStandardFormat(X11->display, PictStandardA1) - : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual()); - picture = XRenderCreatePicture(X11->display, hd, format, 0, 0); - } -#endif - - if (alphaCheck.hasAlpha()) { - QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags)); - setMask(m); - } -} - -Qt::HANDLE QX11PixmapData::createBitmapFromImage(const QImage &image) -{ - QImage img = image.convertToFormat(QImage::Format_MonoLSB); - const QRgb c0 = QColor(Qt::black).rgb(); - const QRgb c1 = QColor(Qt::white).rgb(); - if (img.color(0) == c0 && img.color(1) == c1) { - img.invertPixels(); - img.setColor(0, c1); - img.setColor(1, c0); - } - - char *bits; - uchar *tmp_bits; - int w = img.width(); - int h = img.height(); - int bpl = (w + 7) / 8; - int ibpl = img.bytesPerLine(); - if (bpl != ibpl) { - tmp_bits = new uchar[bpl*h]; - bits = (char *)tmp_bits; - uchar *p, *b; - int y; - b = tmp_bits; - p = img.scanLine(0); - for (y = 0; y < h; y++) { - memcpy(b, p, bpl); - b += bpl; - p += ibpl; - } - } else { - bits = (char *)img.bits(); - tmp_bits = 0; - } - Qt::HANDLE hd = (Qt::HANDLE)XCreateBitmapFromData(X11->display, - QX11Info::appRootWindow(), - bits, w, h); - if (tmp_bits) // Avoid purify complaint - delete [] tmp_bits; - return hd; -} - -void QX11PixmapData::bitmapFromImage(const QImage &image) -{ - w = image.width(); - h = image.height(); - d = 1; - is_null = (w <= 0 || h <= 0); - hd = createBitmapFromImage(image); -#ifndef QT_NO_XRENDER - if (X11->use_xrender) - picture = XRenderCreatePicture(X11->display, hd, - XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0); -#endif // QT_NO_XRENDER -} - -void QX11PixmapData::fill(const QColor &fillColor) -{ - if (fillColor.alpha() != 255) { -#ifndef QT_NO_XRENDER - if (X11->use_xrender) { - if (!picture || d != 32) - convertToARGB32(/*preserveContents = */false); - - ::Picture src = X11->getSolidFill(xinfo.screen(), fillColor); - XRenderComposite(X11->display, PictOpSrc, src, 0, picture, - 0, 0, width(), height(), - 0, 0, width(), height()); - } else -#endif - { - QImage im(width(), height(), QImage::Format_ARGB32_Premultiplied); - im.fill(PREMUL(fillColor.rgba())); - release(); - fromImage(im, Qt::AutoColor | Qt::OrderedAlphaDither); - } - return; - } - - GC gc = XCreateGC(X11->display, hd, 0, 0); - if (depth() == 1) { - XSetForeground(X11->display, gc, qGray(fillColor.rgb()) > 127 ? 0 : 1); - } else if (X11->use_xrender && d >= 24) { - XSetForeground(X11->display, gc, fillColor.rgba()); - } else { - XSetForeground(X11->display, gc, - QColormap::instance(xinfo.screen()).pixel(fillColor)); - } - XFillRectangle(X11->display, hd, gc, 0, 0, width(), height()); - XFreeGC(X11->display, gc); -} - -QX11PixmapData::~QX11PixmapData() -{ - // Cleanup hooks have to be called before the handles are freed - if (is_cached) { - QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(this); - is_cached = false; - } - - release(); -} - -void QX11PixmapData::release() -{ - delete pengine; - pengine = 0; - - if (!X11) { - // At this point, the X server will already have freed our resources, - // so there is nothing to do. - return; - } - - if (x11_mask) { -#ifndef QT_NO_XRENDER - if (mask_picture) - XRenderFreePicture(X11->display, mask_picture); - mask_picture = 0; -#endif - XFreePixmap(X11->display, x11_mask); - x11_mask = 0; - } - - if (hd) { -#ifndef QT_NO_XRENDER - if (picture) { - XRenderFreePicture(X11->display, picture); - picture = 0; - } -#endif // QT_NO_XRENDER - - if (hd2) { - XFreePixmap(xinfo.display(), hd2); - hd2 = 0; - } - if (!(flags & Readonly)) - XFreePixmap(xinfo.display(), hd); - hd = 0; - } -} - -QPixmap QX11PixmapData::alphaChannel() const -{ - if (!hasAlphaChannel()) { - QPixmap pm(w, h); - pm.fill(Qt::white); - return pm; - } - QImage im(toImage()); - return QPixmap::fromImage(im.alphaChannel(), Qt::OrderedDither); -} - -void QX11PixmapData::setAlphaChannel(const QPixmap &alpha) -{ - QImage image(toImage()); - image.setAlphaChannel(alpha.toImage()); - release(); - fromImage(image, Qt::OrderedDither | Qt::OrderedAlphaDither); -} - - -QBitmap QX11PixmapData::mask() const -{ - QBitmap mask; -#ifndef QT_NO_XRENDER - if (picture && d == 32) { - // #### slow - there must be a better way.. - mask = QBitmap::fromImage(toImage().createAlphaMask()); - } else -#endif - if (d == 1) { - QX11PixmapData *that = const_cast<QX11PixmapData*>(this); - mask = QPixmap(that); - } else { - mask = mask_to_bitmap(xinfo.screen()); - } - return mask; -} - -/*! - Sets a mask bitmap. - - The \a newmask bitmap defines the clip mask for this pixmap. Every - pixel in \a newmask corresponds to a pixel in this pixmap. Pixel - value 1 means opaque and pixel value 0 means transparent. The mask - must have the same size as this pixmap. - - \warning Setting the mask on a pixmap will cause any alpha channel - data to be cleared. For example: - \snippet doc/src/snippets/image/image.cpp 2 - Now, alpha and alphacopy are visually different. - - Setting a null mask resets the mask. - - The effect of this function is undefined when the pixmap is being - painted on. - - \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap - Transformations}, QBitmap -*/ -void QX11PixmapData::setMask(const QBitmap &newmask) -{ - if (newmask.isNull()) { // clear mask -#ifndef QT_NO_XRENDER - if (picture && d == 32) { - QX11PixmapData newData(pixelType()); - newData.resize(w, h); - newData.fill(Qt::black); - XRenderComposite(X11->display, PictOpOver, - picture, 0, newData.picture, - 0, 0, 0, 0, 0, 0, w, h); - release(); - *this = newData; - // the new QX11PixmapData object isn't referenced yet, so - // ref it - ref.ref(); - - // the below is to make sure the QX11PixmapData destructor - // doesn't delete our newly created render picture - newData.hd = 0; - newData.x11_mask = 0; - newData.picture = 0; - newData.mask_picture = 0; - newData.hd2 = 0; - } else -#endif - if (x11_mask) { -#ifndef QT_NO_XRENDER - if (picture) { - XRenderPictureAttributes attrs; - attrs.alpha_map = 0; - XRenderChangePicture(X11->display, picture, CPAlphaMap, - &attrs); - } - if (mask_picture) - XRenderFreePicture(X11->display, mask_picture); - mask_picture = 0; -#endif - XFreePixmap(X11->display, x11_mask); - x11_mask = 0; - } - return; - } - -#ifndef QT_NO_XRENDER - if (picture && d == 32) { - XRenderComposite(X11->display, PictOpSrc, - picture, newmask.x11PictureHandle(), - picture, 0, 0, 0, 0, 0, 0, w, h); - } else -#endif - if (depth() == 1) { - XGCValues vals; - vals.function = GXand; - GC gc = XCreateGC(X11->display, hd, GCFunction, &vals); - XCopyArea(X11->display, newmask.handle(), hd, gc, 0, 0, - width(), height(), 0, 0); - XFreeGC(X11->display, gc); - } else { - // ##### should or the masks together - if (x11_mask) { - XFreePixmap(X11->display, x11_mask); -#ifndef QT_NO_XRENDER - if (mask_picture) - XRenderFreePicture(X11->display, mask_picture); -#endif - } - x11_mask = QX11PixmapData::bitmap_to_mask(newmask, xinfo.screen()); -#ifndef QT_NO_XRENDER - if (picture) { - mask_picture = XRenderCreatePicture(X11->display, x11_mask, - XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0); - XRenderPictureAttributes attrs; - attrs.alpha_map = mask_picture; - XRenderChangePicture(X11->display, picture, CPAlphaMap, &attrs); - } -#endif - } -} - -int QX11PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const -{ - switch (metric) { - case QPaintDevice::PdmWidth: - return w; - case QPaintDevice::PdmHeight: - return h; - case QPaintDevice::PdmNumColors: - return 1 << d; - case QPaintDevice::PdmDepth: - return d; - case QPaintDevice::PdmWidthMM: { - const int screen = xinfo.screen(); - const int mm = DisplayWidthMM(X11->display, screen) * w - / DisplayWidth(X11->display, screen); - return mm; - } - case QPaintDevice::PdmHeightMM: { - const int screen = xinfo.screen(); - const int mm = (DisplayHeightMM(X11->display, screen) * h) - / DisplayHeight(X11->display, screen); - return mm; - } - case QPaintDevice::PdmDpiX: - case QPaintDevice::PdmPhysicalDpiX: - return QX11Info::appDpiX(xinfo.screen()); - case QPaintDevice::PdmDpiY: - case QPaintDevice::PdmPhysicalDpiY: - return QX11Info::appDpiY(xinfo.screen()); - default: - qWarning("QX11PixmapData::metric(): Invalid metric"); - return 0; - } -} - -struct QXImageWrapper -{ - XImage *xi; -}; - -bool QX11PixmapData::canTakeQImageFromXImage(const QXImageWrapper &xiWrapper) const -{ - XImage *xi = xiWrapper.xi; - - // ARGB32_Premultiplied - if (picture && depth() == 32) - return true; - - Visual *visual = (Visual *)xinfo.visual(); - - // RGB32 - if (depth() == 24 && xi->bits_per_pixel == 32 && visual->red_mask == 0xff0000 - && visual->green_mask == 0xff00 && visual->blue_mask == 0xff) - return true; - - // RGB16 - if (depth() == 16 && xi->bits_per_pixel == 16 && visual->red_mask == 0xf800 - && visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f) - return true; - - return false; -} - -QImage QX11PixmapData::takeQImageFromXImage(const QXImageWrapper &xiWrapper) const -{ - XImage *xi = xiWrapper.xi; - - QImage::Format format = QImage::Format_ARGB32_Premultiplied; - if (depth() == 24) - format = QImage::Format_RGB32; - else if (depth() == 16) - format = QImage::Format_RGB16; - - QImage image((uchar *)xi->data, xi->width, xi->height, xi->bytes_per_line, format); - // take ownership - image.data_ptr()->own_data = true; - xi->data = 0; - - // we may have to swap the byte order - if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst) - || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst)) - { - for (int i=0; i < image.height(); i++) { - if (depth() == 16) { - ushort *p = (ushort*)image.scanLine(i); - ushort *end = p + image.width(); - while (p < end) { - *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff); - p++; - } - } else { - uint *p = (uint*)image.scanLine(i); - uint *end = p + image.width(); - while (p < end) { - *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000) - | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff); - p++; - } - } - } - } - - // fix-up alpha channel - if (format == QImage::Format_RGB32) { - QRgb *p = (QRgb *)image.bits(); - for (int y = 0; y < xi->height; ++y) { - for (int x = 0; x < xi->width; ++x) - p[x] |= 0xff000000; - p += xi->bytes_per_line / 4; - } - } - - XDestroyImage(xi); - return image; -} - -QImage QX11PixmapData::toImage(const QRect &rect) const -{ - QXImageWrapper xiWrapper; - xiWrapper.xi = XGetImage(X11->display, hd, rect.x(), rect.y(), rect.width(), rect.height(), - AllPlanes, (depth() == 1) ? XYPixmap : ZPixmap); - - Q_CHECK_PTR(xiWrapper.xi); - if (!xiWrapper.xi) - return QImage(); - - if (!x11_mask && canTakeQImageFromXImage(xiWrapper)) - return takeQImageFromXImage(xiWrapper); - - QImage image = toImage(xiWrapper, rect); - qSafeXDestroyImage(xiWrapper.xi); - return image; -} - -/*! - Converts the pixmap to a QImage. Returns a null image if the - conversion fails. - - If the pixmap has 1-bit depth, the returned image will also be 1 - bit deep. If the pixmap has 2- to 8-bit depth, the returned image - has 8-bit depth. If the pixmap has greater than 8-bit depth, the - returned image has 32-bit depth. - - Note that for the moment, alpha masks on monochrome images are - ignored. - - \sa fromImage(), {QImage#Image Formats}{Image Formats} -*/ - -QImage QX11PixmapData::toImage() const -{ - return toImage(QRect(0, 0, w, h)); -} - -QImage QX11PixmapData::toImage(const QXImageWrapper &xiWrapper, const QRect &rect) const -{ - XImage *xi = xiWrapper.xi; - - int d = depth(); - Visual *visual = (Visual *)xinfo.visual(); - bool trucol = (visual->c_class >= TrueColor) && d > 1; - - QImage::Format format = QImage::Format_Mono; - if (d > 1 && d <= 8) { - d = 8; - format = QImage::Format_Indexed8; - } - // we could run into the situation where d == 8 AND trucol is true, which can - // cause problems when converting to and from images. in this case, always treat - // the depth as 32... - if (d > 8 || trucol) { - d = 32; - format = QImage::Format_RGB32; - } - - if (d == 1 && xi->bitmap_bit_order == LSBFirst) - format = QImage::Format_MonoLSB; - if (x11_mask && format == QImage::Format_RGB32) - format = QImage::Format_ARGB32; - - QImage image(xi->width, xi->height, format); - if (image.isNull()) // could not create image - return image; - - QImage alpha; - if (x11_mask) { - if (rect.contains(QRect(0, 0, w, h))) - alpha = mask().toImage(); - else - alpha = mask().toImage().copy(rect); - } - bool ale = alpha.format() == QImage::Format_MonoLSB; - - if (trucol) { // truecolor - const uint red_mask = (uint)visual->red_mask; - const uint green_mask = (uint)visual->green_mask; - const uint blue_mask = (uint)visual->blue_mask; - const int red_shift = highest_bit(red_mask) - 7; - const int green_shift = highest_bit(green_mask) - 7; - const int blue_shift = highest_bit(blue_mask) - 7; - - const uint red_bits = n_bits(red_mask); - const uint green_bits = n_bits(green_mask); - const uint blue_bits = n_bits(blue_mask); - - static uint red_table_bits = 0; - static uint green_table_bits = 0; - static uint blue_table_bits = 0; - - if (red_bits < 8 && red_table_bits != red_bits) { - build_scale_table(&red_scale_table, red_bits); - red_table_bits = red_bits; - } - if (blue_bits < 8 && blue_table_bits != blue_bits) { - build_scale_table(&blue_scale_table, blue_bits); - blue_table_bits = blue_bits; - } - if (green_bits < 8 && green_table_bits != green_bits) { - build_scale_table(&green_scale_table, green_bits); - green_table_bits = green_bits; - } - - int r, g, b; - - QRgb *dst; - uchar *src; - uint pixel; - int bppc = xi->bits_per_pixel; - - if (bppc > 8 && xi->byte_order == LSBFirst) - bppc++; - - for (int y = 0; y < xi->height; ++y) { - uchar* asrc = x11_mask ? alpha.scanLine(y) : 0; - dst = (QRgb *)image.scanLine(y); - src = (uchar *)xi->data + xi->bytes_per_line*y; - for (int x = 0; x < xi->width; x++) { - switch (bppc) { - case 8: - pixel = *src++; - break; - case 16: // 16 bit MSB - pixel = src[1] | (uint)src[0] << 8; - src += 2; - break; - case 17: // 16 bit LSB - pixel = src[0] | (uint)src[1] << 8; - src += 2; - break; - case 24: // 24 bit MSB - pixel = src[2] | (uint)src[1] << 8 | (uint)src[0] << 16; - src += 3; - break; - case 25: // 24 bit LSB - pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16; - src += 3; - break; - case 32: // 32 bit MSB - pixel = src[3] | (uint)src[2] << 8 | (uint)src[1] << 16 | (uint)src[0] << 24; - src += 4; - break; - case 33: // 32 bit LSB - pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16 | (uint)src[3] << 24; - src += 4; - break; - default: // should not really happen - x = xi->width; // leave loop - y = xi->height; - pixel = 0; // eliminate compiler warning - qWarning("QPixmap::convertToImage: Invalid depth %d", bppc); - } - if (red_shift > 0) - r = (pixel & red_mask) >> red_shift; - else - r = (pixel & red_mask) << -red_shift; - if (green_shift > 0) - g = (pixel & green_mask) >> green_shift; - else - g = (pixel & green_mask) << -green_shift; - if (blue_shift > 0) - b = (pixel & blue_mask) >> blue_shift; - else - b = (pixel & blue_mask) << -blue_shift; - - if (red_bits < 8) - r = red_scale_table[r]; - if (green_bits < 8) - g = green_scale_table[g]; - if (blue_bits < 8) - b = blue_scale_table[b]; - - if (x11_mask) { - if (ale) { - *dst++ = (asrc[x >> 3] & (1 << (x & 7))) ? qRgba(r, g, b, 0xff) : 0; - } else { - *dst++ = (asrc[x >> 3] & (0x80 >> (x & 7))) ? qRgba(r, g, b, 0xff) : 0; - } - } else { - *dst++ = qRgb(r, g, b); - } - } - } - } else if (xi->bits_per_pixel == d) { // compatible depth - char *xidata = xi->data; // copy each scanline - int bpl = qMin(image.bytesPerLine(),xi->bytes_per_line); - for (int y=0; y<xi->height; y++) { - memcpy(image.scanLine(y), xidata, bpl); - xidata += xi->bytes_per_line; - } - } else { - /* Typically 2 or 4 bits display depth */ - qWarning("QPixmap::convertToImage: Display not supported (bpp=%d)", - xi->bits_per_pixel); - return QImage(); - } - - if (d == 1) { // bitmap - image.setColorCount(2); - image.setColor(0, qRgb(255,255,255)); - image.setColor(1, qRgb(0,0,0)); - } else if (!trucol) { // pixmap with colormap - register uchar *p; - uchar *end; - uchar use[256]; // pixel-in-use table - uchar pix[256]; // pixel translation table - int ncols, bpl; - memset(use, 0, 256); - memset(pix, 0, 256); - bpl = image.bytesPerLine(); - - if (x11_mask) { // which pixels are used? - for (int i = 0; i < xi->height; i++) { - uchar* asrc = alpha.scanLine(i); - p = image.scanLine(i); - if (ale) { - for (int x = 0; x < xi->width; x++) { - if (asrc[x >> 3] & (1 << (x & 7))) - use[*p] = 1; - ++p; - } - } else { - for (int x = 0; x < xi->width; x++) { - if (asrc[x >> 3] & (0x80 >> (x & 7))) - use[*p] = 1; - ++p; - } - } - } - } else { - for (int i = 0; i < xi->height; i++) { - p = image.scanLine(i); - end = p + bpl; - while (p < end) - use[*p++] = 1; - } - } - ncols = 0; - for (int i = 0; i < 256; i++) { // build translation table - if (use[i]) - pix[i] = ncols++; - } - for (int i = 0; i < xi->height; i++) { // translate pixels - p = image.scanLine(i); - end = p + bpl; - while (p < end) { - *p = pix[*p]; - p++; - } - } - if (x11_mask) { - int trans; - if (ncols < 256) { - trans = ncols++; - image.setColorCount(ncols); // create color table - image.setColor(trans, 0x00000000); - } else { - image.setColorCount(ncols); // create color table - // oh dear... no spare "transparent" pixel. - // use first pixel in image (as good as any). - trans = image.scanLine(0)[0]; - } - for (int i = 0; i < xi->height; i++) { - uchar* asrc = alpha.scanLine(i); - p = image.scanLine(i); - if (ale) { - for (int x = 0; x < xi->width; x++) { - if (!(asrc[x >> 3] & (1 << (x & 7)))) - *p = trans; - ++p; - } - } else { - for (int x = 0; x < xi->width; x++) { - if (!(asrc[x >> 3] & (1 << (7 -(x & 7))))) - *p = trans; - ++p; - } - } - } - } else { - image.setColorCount(ncols); // create color table - } - QVector<QColor> colors = QColormap::instance(xinfo.screen()).colormap(); - int j = 0; - for (int i=0; i<colors.size(); i++) { // translate pixels - if (use[i]) - image.setColor(j++, 0xff000000 | colors.at(i).rgb()); - } - } - - return image; -} - -/*! - Returns a copy of the pixmap that is transformed using the given - transformation \a matrix and transformation \a mode. The original - pixmap is not changed. - - The transformation \a matrix is internally adjusted to compensate - for unwanted translation; i.e. the pixmap produced is the smallest - pixmap that contains all the transformed points of the original - pixmap. Use the trueMatrix() function to retrieve the actual - matrix used for transforming the pixmap. - - This function is slow because it involves transformation to a - QImage, non-trivial computations and a transformation back to a - QPixmap. - - \sa trueMatrix(), {QPixmap#Pixmap Transformations}{Pixmap - Transformations} -*/ -QPixmap QX11PixmapData::transformed(const QTransform &transform, - Qt::TransformationMode mode ) const -{ - if (mode == Qt::SmoothTransformation || transform.type() >= QTransform::TxProject) { - QImage image = toImage(); - return QPixmap::fromImage(image.transformed(transform, mode)); - } - - uint w = 0; - uint h = 0; // size of target pixmap - uint ws, hs; // size of source pixmap - uchar *dptr; // data in target pixmap - uint dbpl, dbytes; // bytes per line/bytes total - uchar *sptr; // data in original pixmap - int sbpl; // bytes per line in original - int bpp; // bits per pixel - bool depth1 = depth() == 1; - Display *dpy = X11->display; - - ws = width(); - hs = height(); - - QTransform mat(transform.m11(), transform.m12(), transform.m13(), - transform.m21(), transform.m22(), transform.m23(), - 0., 0., 1); - bool complex_xform = false; - qreal scaledWidth; - qreal scaledHeight; - - if (mat.type() <= QTransform::TxScale) { - scaledHeight = qAbs(mat.m22()) * hs + 0.9999; - scaledWidth = qAbs(mat.m11()) * ws + 0.9999; - h = qAbs(int(scaledHeight)); - w = qAbs(int(scaledWidth)); - } else { // rotation or shearing - QPolygonF a(QRectF(0, 0, ws, hs)); - a = mat.map(a); - QRect r = a.boundingRect().toAlignedRect(); - w = r.width(); - h = r.height(); - scaledWidth = w; - scaledHeight = h; - complex_xform = true; - } - mat = QPixmap::trueMatrix(mat, ws, hs); // true matrix - - bool invertible; - mat = mat.inverted(&invertible); // invert matrix - - if (h == 0 || w == 0 || !invertible - || qAbs(scaledWidth) >= 32768 || qAbs(scaledHeight) >= 32768 ) - // error, return null pixmap - return QPixmap(); - -#if defined(QT_MITSHM) - static bool try_once = true; - if (try_once) { - try_once = false; - if (!xshminit) - qt_create_mitshm_buffer(this, 800, 600); - } - - bool use_mitshm = xshmimg && !depth1 && - xshmimg->width >= w && xshmimg->height >= h; -#endif - XImage *xi = XGetImage(X11->display, handle(), 0, 0, ws, hs, AllPlanes, - depth1 ? XYPixmap : ZPixmap); - - if (!xi) - return QPixmap(); - - sbpl = xi->bytes_per_line; - sptr = (uchar *)xi->data; - bpp = xi->bits_per_pixel; - - if (depth1) - dbpl = (w+7)/8; - else - dbpl = ((w*bpp+31)/32)*4; - dbytes = dbpl*h; - -#if defined(QT_MITSHM) - if (use_mitshm) { - dptr = (uchar *)xshmimg->data; - uchar fillbyte = bpp == 8 ? white.pixel() : 0xff; - for (int y=0; y<h; y++) - memset(dptr + y*xshmimg->bytes_per_line, fillbyte, dbpl); - } else { -#endif - dptr = (uchar *)malloc(dbytes); // create buffer for bits - Q_CHECK_PTR(dptr); - if (depth1) // fill with zeros - memset(dptr, 0, dbytes); - else if (bpp == 8) // fill with background color - memset(dptr, WhitePixel(X11->display, xinfo.screen()), dbytes); - else - memset(dptr, 0, dbytes); -#if defined(QT_MITSHM) - } -#endif - - // #define QT_DEBUG_XIMAGE -#if defined(QT_DEBUG_XIMAGE) - qDebug("----IMAGE--INFO--------------"); - qDebug("width............. %d", xi->width); - qDebug("height............ %d", xi->height); - qDebug("xoffset........... %d", xi->xoffset); - qDebug("format............ %d", xi->format); - qDebug("byte order........ %d", xi->byte_order); - qDebug("bitmap unit....... %d", xi->bitmap_unit); - qDebug("bitmap bit order.. %d", xi->bitmap_bit_order); - qDebug("depth............. %d", xi->depth); - qDebug("bytes per line.... %d", xi->bytes_per_line); - qDebug("bits per pixel.... %d", xi->bits_per_pixel); -#endif - - int type; - if (xi->bitmap_bit_order == MSBFirst) - type = QT_XFORM_TYPE_MSBFIRST; - else - type = QT_XFORM_TYPE_LSBFIRST; - int xbpl, p_inc; - if (depth1) { - xbpl = (w+7)/8; - p_inc = dbpl - xbpl; - } else { - xbpl = (w*bpp)/8; - p_inc = dbpl - xbpl; -#if defined(QT_MITSHM) - if (use_mitshm) - p_inc = xshmimg->bytes_per_line - xbpl; -#endif - } - - if (!qt_xForm_helper(mat, xi->xoffset, type, bpp, dptr, xbpl, p_inc, h, sptr, sbpl, ws, hs)){ - qWarning("QPixmap::transform: display not supported (bpp=%d)",bpp); - QPixmap pm; - return pm; - } - - qSafeXDestroyImage(xi); - - if (depth1) { // mono bitmap - QBitmap bm = QBitmap::fromData(QSize(w, h), dptr, - BitmapBitOrder(X11->display) == MSBFirst - ? QImage::Format_Mono - : QImage::Format_MonoLSB); - free(dptr); - return bm; - } else { // color pixmap - QX11PixmapData *x11Data = new QX11PixmapData(QPixmapData::PixmapType); - QPixmap pm(x11Data); - x11Data->flags &= ~QX11PixmapData::Uninitialized; - x11Data->xinfo = xinfo; - x11Data->d = d; - x11Data->w = w; - x11Data->h = h; - x11Data->is_null = (w <= 0 || h <= 0); - x11Data->hd = (Qt::HANDLE)XCreatePixmap(X11->display, - RootWindow(X11->display, xinfo.screen()), - w, h, d); - x11Data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1)); - -#ifndef QT_NO_XRENDER - if (X11->use_xrender) { - XRenderPictFormat *format = x11Data->d == 32 - ? XRenderFindStandardFormat(X11->display, PictStandardARGB32) - : XRenderFindVisualFormat(X11->display, (Visual *) x11Data->xinfo.visual()); - x11Data->picture = XRenderCreatePicture(X11->display, x11Data->hd, format, 0, 0); - } -#endif // QT_NO_XRENDER - - GC gc = XCreateGC(X11->display, x11Data->hd, 0, 0); -#if defined(QT_MITSHM) - if (use_mitshm) { - XCopyArea(dpy, xshmpm, x11Data->hd, gc, 0, 0, w, h, 0, 0); - } else -#endif - { - xi = XCreateImage(dpy, (Visual*)x11Data->xinfo.visual(), - x11Data->d, - ZPixmap, 0, (char *)dptr, w, h, 32, 0); - XPutImage(dpy, pm.handle(), gc, xi, 0, 0, 0, 0, w, h); - qSafeXDestroyImage(xi); - } - XFreeGC(X11->display, gc); - - if (x11_mask) { // xform mask, too - pm.setMask(mask_to_bitmap(xinfo.screen()).transformed(transform)); - } else if (d != 32 && complex_xform) { // need a mask! - QBitmap mask(ws, hs); - mask.fill(Qt::color1); - pm.setMask(mask.transformed(transform)); - } - return pm; - } -} - -int QPixmap::x11SetDefaultScreen(int screen) -{ - int old = defaultScreen; - defaultScreen = screen; - return old; -} - -void QPixmap::x11SetScreen(int screen) -{ - if (paintingActive()) { - qWarning("QPixmap::x11SetScreen(): Cannot change screens during painting"); - return; - } - - if (isNull()) - return; - - if (data->classId() != QPixmapData::X11Class) - return; - - if (screen < 0) - screen = QX11Info::appScreen(); - - QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(data.data()); - if (screen == x11Data->xinfo.screen()) - return; // nothing to do - - if (isNull()) { - QX11InfoData* xd = x11Data->xinfo.getX11Data(true); - xd->screen = screen; - xd->depth = QX11Info::appDepth(screen); - xd->cells = QX11Info::appCells(screen); - xd->colormap = QX11Info::appColormap(screen); - xd->defaultColormap = QX11Info::appDefaultColormap(screen); - xd->visual = (Visual *)QX11Info::appVisual(screen); - xd->defaultVisual = QX11Info::appDefaultVisual(screen); - x11Data->xinfo.setX11Data(xd); - return; - } -#if 0 - qDebug("QPixmap::x11SetScreen for %p from %d to %d. Size is %d/%d", x11Data, x11Data->xinfo.screen(), screen, width(), height()); -#endif - - x11SetDefaultScreen(screen); - *this = qt_toX11Pixmap(toImage()); -} - -QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h) -{ - if (w == 0 || h == 0) - return QPixmap(); - - Display *dpy = X11->display; - XWindowAttributes window_attr; - if (!XGetWindowAttributes(dpy, window, &window_attr)) - return QPixmap(); - - if (w < 0) - w = window_attr.width - x; - if (h < 0) - h = window_attr.height - y; - - // determine the screen - int scr; - for (scr = 0; scr < ScreenCount(dpy); ++scr) { - if (window_attr.root == RootWindow(dpy, scr)) // found it - break; - } - if (scr >= ScreenCount(dpy)) // sanity check - return QPixmap(); - - - // get the depth of the root window - XWindowAttributes root_attr; - if (!XGetWindowAttributes(dpy, window_attr.root, &root_attr)) - return QPixmap(); - - if (window_attr.depth == root_attr.depth) { - // if the depth of the specified window and the root window are the - // same, grab pixels from the root window (so that we get the any - // overlapping windows and window manager frames) - - // map x and y to the root window - WId unused; - if (!XTranslateCoordinates(dpy, window, window_attr.root, x, y, - &x, &y, &unused)) - return QPixmap(); - - window = window_attr.root; - window_attr = root_attr; - } - - QX11PixmapData *data = new QX11PixmapData(QPixmapData::PixmapType); - - void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const XWindowAttributes &a); - qt_x11_getX11InfoForWindow(&data->xinfo,window_attr); - - data->resize(w, h); - - QPixmap pm(data); - - data->flags &= ~QX11PixmapData::Uninitialized; - pm.x11SetScreen(scr); - - GC gc = XCreateGC(dpy, pm.handle(), 0, 0); - XSetSubwindowMode(dpy, gc, IncludeInferiors); - XCopyArea(dpy, window, pm.handle(), gc, x, y, w, h, 0, 0); - XFreeGC(dpy, gc); - - return pm; -} - -bool QX11PixmapData::hasAlphaChannel() const -{ - return d == 32; -} - -const QX11Info &QPixmap::x11Info() const -{ - if (data && data->classId() == QPixmapData::X11Class) - return static_cast<QX11PixmapData*>(data.data())->xinfo; - else { - static QX11Info nullX11Info; - return nullX11Info; - } -} - -#if !defined(QT_NO_XRENDER) -static XRenderPictFormat *qt_renderformat_for_depth(const QX11Info &xinfo, int depth) -{ - if (depth == 1) - return XRenderFindStandardFormat(X11->display, PictStandardA1); - else if (depth == 32) - return XRenderFindStandardFormat(X11->display, PictStandardARGB32); - else - return XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual()); -} -#endif - -QPaintEngine* QX11PixmapData::paintEngine() const -{ - QX11PixmapData *that = const_cast<QX11PixmapData*>(this); - - if ((flags & Readonly) && share_mode == QPixmap::ImplicitlyShared) { - // if someone wants to draw onto us, copy the shared contents - // and turn it into a fully fledged QPixmap - ::Pixmap hd_copy = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()), - w, h, d); -#if !defined(QT_NO_XRENDER) - XRenderPictFormat *format = qt_renderformat_for_depth(xinfo, d); - ::Picture picture_copy = XRenderCreatePicture(X11->display, hd_copy, format, 0, 0); - - if (picture && d == 32) { - XRenderComposite(X11->display, PictOpSrc, picture, 0, picture_copy, - 0, 0, 0, 0, 0, 0, w, h); - XRenderFreePicture(X11->display, picture); - that->picture = picture_copy; - } else -#endif - { - GC gc = XCreateGC(X11->display, hd_copy, 0, 0); - XCopyArea(X11->display, hd, hd_copy, gc, 0, 0, w, h, 0, 0); - XFreeGC(X11->display, gc); - } - that->hd = hd_copy; - that->flags &= ~QX11PixmapData::Readonly; - } - - if (!that->pengine) - that->pengine = new QX11PaintEngine; - return that->pengine; -} - -Qt::HANDLE QPixmap::x11PictureHandle() const -{ -#ifndef QT_NO_XRENDER - if (data && data->classId() == QPixmapData::X11Class) - return static_cast<const QX11PixmapData*>(data.data())->picture; - else - return 0; -#else - return 0; -#endif // QT_NO_XRENDER -} - -Qt::HANDLE QX11PixmapData::x11ConvertToDefaultDepth() -{ -#ifndef QT_NO_XRENDER - if (d == QX11Info::appDepth() || !X11->use_xrender) - return hd; - if (!hd2) { - hd2 = XCreatePixmap(xinfo.display(), hd, w, h, QX11Info::appDepth()); - XRenderPictFormat *format = XRenderFindVisualFormat(xinfo.display(), - (Visual*) xinfo.visual()); - Picture pic = XRenderCreatePicture(xinfo.display(), hd2, format, 0, 0); - XRenderComposite(xinfo.display(), PictOpSrc, picture, - XNone, pic, 0, 0, 0, 0, 0, 0, w, h); - XRenderFreePicture(xinfo.display(), pic); - } - return hd2; -#else - return hd; -#endif -} - -void QX11PixmapData::copy(const QPixmapData *data, const QRect &rect) -{ - if (data->pixelType() == BitmapType) { - fromImage(data->toImage().copy(rect), Qt::AutoColor); - return; - } - - const QX11PixmapData *x11Data = static_cast<const QX11PixmapData*>(data); - - setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1)); - - flags &= ~Uninitialized; - xinfo = x11Data->xinfo; - d = x11Data->d; - w = rect.width(); - h = rect.height(); - is_null = (w <= 0 || h <= 0); - hd = (Qt::HANDLE)XCreatePixmap(X11->display, - RootWindow(X11->display, x11Data->xinfo.screen()), - w, h, d); -#ifndef QT_NO_XRENDER - if (X11->use_xrender) { - XRenderPictFormat *format = d == 32 - ? XRenderFindStandardFormat(X11->display, PictStandardARGB32) - : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual()); - picture = XRenderCreatePicture(X11->display, hd, format, 0, 0); - } -#endif // QT_NO_XRENDER - if (x11Data->x11_mask) { - x11_mask = XCreatePixmap(X11->display, hd, w, h, 1); -#ifndef QT_NO_XRENDER - if (X11->use_xrender) { - mask_picture = XRenderCreatePicture(X11->display, x11_mask, - XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0); - XRenderPictureAttributes attrs; - attrs.alpha_map = x11Data->mask_picture; - XRenderChangePicture(X11->display, x11Data->picture, CPAlphaMap, &attrs); - } -#endif - } - -#if !defined(QT_NO_XRENDER) - if (x11Data->picture && x11Data->d == 32) { - XRenderComposite(X11->display, PictOpSrc, - x11Data->picture, 0, picture, - rect.x(), rect.y(), 0, 0, 0, 0, w, h); - } else -#endif - { - GC gc = XCreateGC(X11->display, hd, 0, 0); - XCopyArea(X11->display, x11Data->hd, hd, gc, - rect.x(), rect.y(), w, h, 0, 0); - if (x11Data->x11_mask) { - GC monogc = XCreateGC(X11->display, x11_mask, 0, 0); - XCopyArea(X11->display, x11Data->x11_mask, x11_mask, monogc, - rect.x(), rect.y(), w, h, 0, 0); - XFreeGC(X11->display, monogc); - } - XFreeGC(X11->display, gc); - } -} - -bool QX11PixmapData::scroll(int dx, int dy, const QRect &rect) -{ - GC gc = XCreateGC(X11->display, hd, 0, 0); - XCopyArea(X11->display, hd, hd, gc, - rect.left(), rect.top(), rect.width(), rect.height(), - rect.left() + dx, rect.top() + dy); - XFreeGC(X11->display, gc); - return true; -} - -#if !defined(QT_NO_XRENDER) -void QX11PixmapData::convertToARGB32(bool preserveContents) -{ - if (!X11->use_xrender) - return; - - // Q_ASSERT(count == 1); - if ((flags & Readonly) && share_mode == QPixmap::ExplicitlyShared) - return; - - Pixmap pm = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()), - w, h, 32); - Picture p = XRenderCreatePicture(X11->display, pm, - XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0); - if (picture) { - if (preserveContents) - XRenderComposite(X11->display, PictOpSrc, picture, 0, p, 0, 0, 0, 0, 0, 0, w, h); - if (!(flags & Readonly)) - XRenderFreePicture(X11->display, picture); - } - if (hd && !(flags & Readonly)) - XFreePixmap(X11->display, hd); - if (x11_mask) { - XFreePixmap(X11->display, x11_mask); - if (mask_picture) - XRenderFreePicture(X11->display, mask_picture); - x11_mask = 0; - mask_picture = 0; - } - hd = pm; - picture = p; - d = 32; -} -#endif - -QPixmap QPixmap::fromX11Pixmap(Qt::HANDLE pixmap, QPixmap::ShareMode mode) -{ - Window root; - int x; - int y; - uint width; - uint height; - uint border_width; - uint depth; - XWindowAttributes win_attribs; - int num_screens = ScreenCount(X11->display); - int screen = 0; - - XGetGeometry(X11->display, pixmap, &root, &x, &y, &width, &height, &border_width, &depth); - XGetWindowAttributes(X11->display, root, &win_attribs); - - for (; screen < num_screens; ++screen) { - if (win_attribs.screen == ScreenOfDisplay(X11->display, screen)) - break; - } - - QX11PixmapData *data = new QX11PixmapData(depth == 1 ? QPixmapData::BitmapType : QPixmapData::PixmapType); - data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1)); - data->flags = QX11PixmapData::Readonly; - data->share_mode = mode; - data->w = width; - data->h = height; - data->is_null = (width <= 0 || height <= 0); - data->d = depth; - data->hd = pixmap; - - if (defaultScreen >= 0 && defaultScreen != screen) { - QX11InfoData* xd = data->xinfo.getX11Data(true); - xd->screen = defaultScreen; - xd->depth = QX11Info::appDepth(xd->screen); - xd->cells = QX11Info::appCells(xd->screen); - xd->colormap = QX11Info::appColormap(xd->screen); - xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen); - xd->visual = (Visual *)QX11Info::appVisual(xd->screen); - xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen); - data->xinfo.setX11Data(xd); - } - -#ifndef QT_NO_XRENDER - if (X11->use_xrender) { - XRenderPictFormat *format = qt_renderformat_for_depth(data->xinfo, depth); - data->picture = XRenderCreatePicture(X11->display, data->hd, format, 0, 0); - } -#endif // QT_NO_XRENDER - - return QPixmap(data); -} - - -QT_END_NAMESPACE diff --git a/src/gui/image/qpixmap_x11_p.h b/src/gui/image/qpixmap_x11_p.h deleted file mode 100644 index 7cd80e62f9..0000000000 --- a/src/gui/image/qpixmap_x11_p.h +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPIXMAPDATA_X11_P_H -#define QPIXMAPDATA_X11_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtGui/private/qpixmapdata_p.h> -#include <QtGui/private/qpixmapdatafactory_p.h> - -#include "QtGui/qx11info_x11.h" - -QT_BEGIN_NAMESPACE - -class QX11PaintEngine; - -struct QXImageWrapper; - -class Q_GUI_EXPORT QX11PixmapData : public QPixmapData -{ -public: - QX11PixmapData(PixelType type); -// QX11PixmapData(PixelType type, int width, int height); -// QX11PixmapData(PixelType type, const QImage &image, -// Qt::ImageConversionFlags flags); - ~QX11PixmapData(); - - QPixmapData *createCompatiblePixmapData() const; - - void resize(int width, int height); - void fromImage(const QImage &image, Qt::ImageConversionFlags flags); - void copy(const QPixmapData *data, const QRect &rect); - bool scroll(int dx, int dy, const QRect &rect); - - void fill(const QColor &color); - QBitmap mask() const; - void setMask(const QBitmap &mask); - bool hasAlphaChannel() const; - void setAlphaChannel(const QPixmap &alphaChannel); - QPixmap alphaChannel() const; - QPixmap transformed(const QTransform &transform, - Qt::TransformationMode mode) const; - QImage toImage() const; - QImage toImage(const QRect &rect) const; - QPaintEngine* paintEngine() const; - - Qt::HANDLE handle() const { return hd; } - Qt::HANDLE x11ConvertToDefaultDepth(); - - static Qt::HANDLE createBitmapFromImage(const QImage &image); - - void* gl_surface; -#ifndef QT_NO_XRENDER - void convertToARGB32(bool preserveContents = true); -#endif - -protected: - int metric(QPaintDevice::PaintDeviceMetric metric) const; - -private: - friend class QPixmap; - friend class QBitmap; - friend class QX11PaintEngine; - friend class QX11WindowSurface; - friend class QRasterWindowSurface; - friend class QGLContextPrivate; // Needs to access xinfo, gl_surface & flags - friend class QEglContext; // Needs gl_surface - friend class QGLContext; // Needs gl_surface - friend class QX11GLPixmapData; // Needs gl_surface - friend class QMeeGoLivePixmapData; // Needs gl_surface and flags - friend bool qt_createEGLSurfaceForPixmap(QPixmapData*, bool); // Needs gl_surface - - void release(); - - QImage toImage(const QXImageWrapper &xi, const QRect &rect) const; - - QBitmap mask_to_bitmap(int screen) const; - static Qt::HANDLE bitmap_to_mask(const QBitmap &, int screen); - void bitmapFromImage(const QImage &image); - - bool canTakeQImageFromXImage(const QXImageWrapper &xi) const; - QImage takeQImageFromXImage(const QXImageWrapper &xi) const; - - Qt::HANDLE hd; - - enum Flag { - NoFlags = 0x0, - Uninitialized = 0x1, - Readonly = 0x2, - InvertedWhenBoundToTexture = 0x4, - GlSurfaceCreatedWithAlpha = 0x8 - }; - uint flags; - - QX11Info xinfo; - Qt::HANDLE x11_mask; - Qt::HANDLE picture; - Qt::HANDLE mask_picture; - Qt::HANDLE hd2; // sorted in the default display depth - QPixmap::ShareMode share_mode; - - QX11PaintEngine *pengine; -}; - -QT_END_NAMESPACE - -#endif // QPIXMAPDATA_X11_P_H - diff --git a/src/gui/image/qpixmapcache_p.h b/src/gui/image/qpixmapcache_p.h index 336c0f01d4..7b96f5a2cf 100644 --- a/src/gui/image/qpixmapcache_p.h +++ b/src/gui/image/qpixmapcache_p.h @@ -81,9 +81,9 @@ class QPixmapCacheEntry : public QPixmap public: QPixmapCacheEntry(const QPixmapCache::Key &key, const QPixmap &pix) : QPixmap(pix), key(key) { - QPixmapData *pd = pixmapData(); - if (pd && pd->classId() == QPixmapData::RasterClass) { - QRasterPixmapData *d = static_cast<QRasterPixmapData*>(pd); + QPlatformPixmap *pd = handle(); + if (pd && pd->classId() == QPlatformPixmap::RasterClass) { + QRasterPlatformPixmap *d = static_cast<QRasterPlatformPixmap*>(pd); if (!d->image.isNull() && d->image.d->paintEngine && !d->image.d->paintEngine->isActive()) { diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp deleted file mode 100644 index c46429cf40..0000000000 --- a/src/gui/image/qpixmapdata.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpixmapdata_p.h" -#include <QtCore/qbuffer.h> -#include <QtGui/qbitmap.h> -#include <QtGui/qimagereader.h> -#include <private/qgraphicssystem_p.h> -#include <private/qapplication_p.h> -#include <private/qimagepixmapcleanuphooks_p.h> - -QT_BEGIN_NAMESPACE - -const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08, - 0x10, 0x20, 0x40, 0x80 }; - -QPixmapData *QPixmapData::create(int w, int h, PixelType type) -{ - QPixmapData *data; - QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem(); - if (gs) - data = gs->createPixmapData(static_cast<QPixmapData::PixelType>(type)); - else - data = QGraphicsSystem::createDefaultPixmapData(static_cast<QPixmapData::PixelType>(type)); - data->resize(w, h); - return data; -} - - -QPixmapData::QPixmapData(PixelType pixelType, int objectId) - : w(0), - h(0), - d(0), - is_null(true), - ref(0), - detach_no(0), - type(pixelType), - id(objectId), - ser_no(0), - is_cached(false) -{ -} - -QPixmapData::~QPixmapData() -{ - // Sometimes the pixmap cleanup hooks will be called from derrived classes, which will - // then set is_cached to false. For example, on X11 QtOpenGL needs to delete the GLXPixmap - // or EGL Pixmap Surface for a given pixmap _before_ the native X11 pixmap is deleted, - // otherwise some drivers will leak the GL surface. In this case, QX11PixmapData will - // call the cleanup hooks itself before deleting the native pixmap and set is_cached to - // false. - if (is_cached) { - QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(this); - is_cached = false; - } -} - -QPixmapData *QPixmapData::createCompatiblePixmapData() const -{ - QPixmapData *d; - QGraphicsSystem *gs = QApplicationPrivate::graphicsSystem(); - if (gs) - d = gs->createPixmapData(pixelType()); - else - d = QGraphicsSystem::createDefaultPixmapData(pixelType()); - return d; -} - -static QImage makeBitmapCompliantIfNeeded(QPixmapData *d, const QImage &image, Qt::ImageConversionFlags flags) -{ - if (d->pixelType() == QPixmapData::BitmapType) { - QImage img = image.convertToFormat(QImage::Format_MonoLSB, flags); - - // make sure image.color(0) == Qt::color0 (white) - // and image.color(1) == Qt::color1 (black) - const QRgb c0 = QColor(Qt::black).rgb(); - const QRgb c1 = QColor(Qt::white).rgb(); - if (img.color(0) == c0 && img.color(1) == c1) { - img.invertPixels(); - img.setColor(0, c1); - img.setColor(1, c0); - } - return img; - } - - return image; -} - -void QPixmapData::fromImageReader(QImageReader *imageReader, - Qt::ImageConversionFlags flags) -{ - const QImage image = imageReader->read(); - fromImage(image, flags); -} - -bool QPixmapData::fromFile(const QString &fileName, const char *format, - Qt::ImageConversionFlags flags) -{ - QImage image = QImageReader(fileName, format).read(); - if (image.isNull()) - return false; - fromImage(makeBitmapCompliantIfNeeded(this, image, flags), flags); - return !isNull(); -} - -bool QPixmapData::fromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags) -{ - QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buf), len); - QBuffer b(&a); - b.open(QIODevice::ReadOnly); - QImage image = QImageReader(&b, format).read(); - fromImage(makeBitmapCompliantIfNeeded(this, image, flags), flags); - return !isNull(); -} - -void QPixmapData::copy(const QPixmapData *data, const QRect &rect) -{ - fromImage(data->toImage(rect), Qt::NoOpaqueDetection); -} - -bool QPixmapData::scroll(int dx, int dy, const QRect &rect) -{ - Q_UNUSED(dx); - Q_UNUSED(dy); - Q_UNUSED(rect); - return false; -} - -void QPixmapData::setMask(const QBitmap &mask) -{ - if (mask.size().isEmpty()) { - if (depth() != 1) - fromImage(toImage().convertToFormat(QImage::Format_RGB32), - Qt::AutoColor); - } else { - QImage image = toImage(); - const int w = image.width(); - const int h = image.height(); - - switch (image.depth()) { - case 1: { - const QImage imageMask = mask.toImage().convertToFormat(image.format()); - for (int y = 0; y < h; ++y) { - const uchar *mscan = imageMask.scanLine(y); - uchar *tscan = image.scanLine(y); - int bytesPerLine = image.bytesPerLine(); - for (int i = 0; i < bytesPerLine; ++i) - tscan[i] &= mscan[i]; - } - break; - } - default: { - const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB); - image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); - for (int y = 0; y < h; ++y) { - const uchar *mscan = imageMask.scanLine(y); - QRgb *tscan = (QRgb *)image.scanLine(y); - for (int x = 0; x < w; ++x) { - if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7])) - tscan[x] = 0; - } - } - break; - } - } - fromImage(image, Qt::AutoColor); - } -} - -QBitmap QPixmapData::mask() const -{ - if (!hasAlphaChannel()) - return QBitmap(); - - const QImage img = toImage(); - const QImage image = (img.depth() < 32 ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) : img); - const int w = image.width(); - const int h = image.height(); - - QImage mask(w, h, QImage::Format_MonoLSB); - if (mask.isNull()) // allocation failed - return QBitmap(); - - mask.setColorCount(2); - mask.setColor(0, QColor(Qt::color0).rgba()); - mask.setColor(1, QColor(Qt::color1).rgba()); - - const int bpl = mask.bytesPerLine(); - - for (int y = 0; y < h; ++y) { - const QRgb *src = reinterpret_cast<const QRgb*>(image.scanLine(y)); - uchar *dest = mask.scanLine(y); - memset(dest, 0, bpl); - for (int x = 0; x < w; ++x) { - if (qAlpha(*src) > 0) - dest[x >> 3] |= qt_pixmap_bit_mask[x & 7]; - ++src; - } - } - - return QBitmap::fromImage(mask); -} - -QPixmap QPixmapData::transformed(const QTransform &matrix, - Qt::TransformationMode mode) const -{ - return QPixmap::fromImage(toImage().transformed(matrix, mode)); -} - -void QPixmapData::setAlphaChannel(const QPixmap &alphaChannel) -{ - QImage image = toImage(); - image.setAlphaChannel(alphaChannel.toImage()); - fromImage(image, Qt::AutoColor); -} - -QPixmap QPixmapData::alphaChannel() const -{ - return QPixmap::fromImage(toImage().alphaChannel()); -} - -void QPixmapData::setSerialNumber(int serNo) -{ - ser_no = serNo; -} - -QImage QPixmapData::toImage(const QRect &rect) const -{ - if (rect.contains(QRect(0, 0, w, h))) - return toImage(); - else - return toImage().copy(rect); -} - -QImage* QPixmapData::buffer() -{ - return 0; -} - -#if defined(Q_OS_SYMBIAN) -void* QPixmapData::toNativeType(NativeType /* type */) -{ - return 0; -} - -void QPixmapData::fromNativeType(void* /* pixmap */, NativeType /* typre */) -{ - return; -} -#endif - -QT_END_NAMESPACE diff --git a/src/gui/image/qpixmapdatafactory.cpp b/src/gui/image/qpixmapdatafactory.cpp deleted file mode 100644 index f7c79880ca..0000000000 --- a/src/gui/image/qpixmapdatafactory.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpixmapdatafactory_p.h" - -#ifdef Q_WS_QWS -# include <QtGui/qscreen_qws.h> -#endif -#ifdef Q_WS_X11 -# include <private/qpixmap_x11_p.h> -#endif -#if defined(Q_WS_WIN) -# include <private/qpixmap_raster_p.h> -#endif -#ifdef Q_WS_MAC -# include <private/qpixmap_mac_p.h> -#endif -#ifdef Q_WS_QPA -# include <private/qpixmap_raster_p.h> -#endif -#ifdef Q_OS_SYMBIAN -# include <private/qpixmap_s60_p.h> -#endif - -#include "private/qapplication_p.h" -#include "private/qgraphicssystem_p.h" - -QT_BEGIN_NAMESPACE - -#if !defined(Q_WS_QWS) - -class QSimplePixmapDataFactory : public QPixmapDataFactory -{ -public: - ~QSimplePixmapDataFactory() {} - QPixmapData* create(QPixmapData::PixelType type); -}; - -QPixmapData* QSimplePixmapDataFactory::create(QPixmapData::PixelType type) -{ - if (QApplicationPrivate::graphicsSystem()) - return QApplicationPrivate::graphicsSystem()->createPixmapData(type); - -#if defined(Q_WS_X11) - return new QX11PixmapData(type); -#elif defined(Q_WS_WIN) - return new QRasterPixmapData(type); -#elif defined(Q_WS_MAC) - return new QMacPixmapData(type); -#elif defined(Q_WS_QPA) - return new QRasterPixmapData(type); -#elif defined(Q_OS_SYMBIAN) - return new QS60PixmapData(type); -#else -#error QSimplePixmapDataFactory::create() not implemented -#endif -} - -Q_GLOBAL_STATIC(QSimplePixmapDataFactory, factory) - -#endif // !defined(Q_WS_QWS) - -QPixmapDataFactory::~QPixmapDataFactory() -{ -} - -QPixmapDataFactory* QPixmapDataFactory::instance(int screen) -{ - Q_UNUSED(screen); -#ifdef Q_WS_QWS - return QScreen::instance()->pixmapDataFactory(); -#else - return factory(); -#endif -} - -QT_END_NAMESPACE diff --git a/src/gui/image/qpixmapdatafactory_p.h b/src/gui/image/qpixmapdatafactory_p.h deleted file mode 100644 index a539d672c3..0000000000 --- a/src/gui/image/qpixmapdatafactory_p.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPIXMAPDATAFACTORY_P_H -#define QPIXMAPDATAFACTORY_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qstring.h> -#include <QtGui/qimage.h> -#include <QtGui/private/qpixmapdata_p.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QPixmapData; - -class QPixmapDataFactory -{ -public: - static QPixmapDataFactory* instance(int screen = 0); - virtual ~QPixmapDataFactory(); - - virtual QPixmapData* create(QPixmapData::PixelType type) = 0; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QPIXMAPDATAFACTORY_P_H diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp deleted file mode 100644 index a33e173f70..0000000000 --- a/src/gui/image/qpixmapfilter.cpp +++ /dev/null @@ -1,1382 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qglobal.h> - -#include <QDebug> - -#include "qpainter.h" -#include "qpixmap.h" -#include "qpixmapfilter_p.h" -#include "qvarlengtharray.h" - -#include "private/qapplication_p.h" -#include "private/qgraphicssystem_p.h" -#include "private/qpaintengineex_p.h" -#include "private/qpaintengine_raster_p.h" -#include "qmath.h" -#include "private/qmath_p.h" -#include "private/qmemrotate_p.h" -#include "private/qdrawhelper_p.h" - -#ifndef QT_NO_GRAPHICSEFFECT -QT_BEGIN_NAMESPACE - -class QPixmapFilterPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QPixmapFilter) -public: - QPixmapFilter::FilterType type; -}; - -/*! - \class QPixmapFilter - \since 4.5 - \ingroup painting - - \brief The QPixmapFilter class provides the basic functionality for - pixmap filter classes. Pixmap filter can be for example colorize or blur. - - QPixmapFilter is the base class for every pixmap filter. QPixmapFilter is - an abstract class and cannot itself be instantiated. It provides a standard - interface for filter processing. - - \internal -*/ - -/*! - \enum QPixmapFilter::FilterType - - \internal - - This enum describes the types of filter that can be applied to pixmaps. - - \value ConvolutionFilter A filter that is used to calculate the convolution - of the image with a kernel. See - QPixmapConvolutionFilter for more information. - \value ColorizeFilter A filter that is used to change the overall color - of an image. See QPixmapColorizeFilter for more - information. - \value DropShadowFilter A filter that is used to add a drop shadow to an - image. See QPixmapDropShadowFilter for more - information. - \value BlurFilter A filter that is used to blur an image using - a simple blur radius. See QPixmapBlurFilter - for more information. - - \value UserFilter The first filter type that can be used for - application-specific purposes. -*/ - - -/*! - Constructs a default QPixmapFilter with the given \a type. - - This constructor should be used when subclassing QPixmapFilter to - create custom user filters. - - \internal -*/ -QPixmapFilter::QPixmapFilter(FilterType type, QObject *parent) - : QObject(*new QPixmapFilterPrivate, parent) -{ - d_func()->type = type; -} - - - -/*! - \internal -*/ -QPixmapFilter::QPixmapFilter(QPixmapFilterPrivate&d, QPixmapFilter::FilterType type, QObject *parent) - : QObject(d, parent) -{ - d_func()->type = type; -} - - -/*! - Destroys the pixmap filter. - - \internal -*/ -QPixmapFilter::~QPixmapFilter() -{ -} - -/*! - Returns the type of the filter. All standard pixmap filter classes - are associated with a unique value. - - \internal -*/ -QPixmapFilter::FilterType QPixmapFilter::type() const -{ - Q_D(const QPixmapFilter); - return d->type; -} - -/*! - Returns the bounding rectangle that is affected by the pixmap - filter if the filter is applied to the specified \a rect. - - \internal -*/ -QRectF QPixmapFilter::boundingRectFor(const QRectF &rect) const -{ - return rect; -} - -/*! - \fn void QPixmapFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF& srcRect) const - - Uses \a painter to draw filtered result of \a src at the point - specified by \a p. If \a srcRect is specified the it will - be used as a source rectangle to only draw a part of the source. - - draw() will affect the area which boundingRectFor() returns. - - \internal -*/ - -/*! - \class QPixmapConvolutionFilter - \since 4.5 - \ingroup painting - - \brief The QPixmapConvolutionFilter class provides convolution - filtering for pixmaps. - - QPixmapConvolutionFilter implements a convolution pixmap filter, - which is applied when \l{QPixmapFilter::}{draw()} is called. A - convolution filter lets you distort an image by setting the values - of a matrix of qreal values called its - \l{setConvolutionKernel()}{kernel}. The matrix's values are - usually between -1.0 and 1.0. - - \omit - In convolution filtering, the pixel value is calculated from the - neighboring pixels based on the weighting convolution kernel. - This needs explaining to be useful. - \endomit - - Example: - \snippet doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp 1 - - \sa {Pixmap Filters Example}, QPixmapColorizeFilter, QPixmapDropShadowFilter - - - \internal -*/ - -class QPixmapConvolutionFilterPrivate : public QPixmapFilterPrivate -{ -public: - QPixmapConvolutionFilterPrivate(): convolutionKernel(0), kernelWidth(0), kernelHeight(0), convoluteAlpha(false) {} - ~QPixmapConvolutionFilterPrivate() { - delete[] convolutionKernel; - } - - qreal *convolutionKernel; - int kernelWidth; - int kernelHeight; - bool convoluteAlpha; -}; - - -/*! - Constructs a pixmap convolution filter. - - By default there is no convolution kernel. - - \internal -*/ -QPixmapConvolutionFilter::QPixmapConvolutionFilter(QObject *parent) - : QPixmapFilter(*new QPixmapConvolutionFilterPrivate, ConvolutionFilter, parent) -{ - Q_D(QPixmapConvolutionFilter); - d->convoluteAlpha = true; -} - -/*! - Destructor of pixmap convolution filter. - - \internal -*/ -QPixmapConvolutionFilter::~QPixmapConvolutionFilter() -{ -} - -/*! - Sets convolution kernel with the given number of \a rows and \a columns. - Values from \a kernel are copied to internal data structure. - - To preserve the intensity of the pixmap, the sum of all the - values in the convolution kernel should add up to 1.0. A sum - greater than 1.0 produces a lighter result and a sum less than 1.0 - produces a darker and transparent result. - - \internal -*/ -void QPixmapConvolutionFilter::setConvolutionKernel(const qreal *kernel, int rows, int columns) -{ - Q_D(QPixmapConvolutionFilter); - delete [] d->convolutionKernel; - d->convolutionKernel = new qreal[rows * columns]; - memcpy(d->convolutionKernel, kernel, sizeof(qreal) * rows * columns); - d->kernelWidth = columns; - d->kernelHeight = rows; -} - -/*! - Gets the convolution kernel data. - - \internal -*/ -const qreal *QPixmapConvolutionFilter::convolutionKernel() const -{ - Q_D(const QPixmapConvolutionFilter); - return d->convolutionKernel; -} - -/*! - Gets the number of rows in the convolution kernel. - - \internal -*/ -int QPixmapConvolutionFilter::rows() const -{ - Q_D(const QPixmapConvolutionFilter); - return d->kernelHeight; -} - -/*! - Gets the number of columns in the convolution kernel. - - \internal -*/ -int QPixmapConvolutionFilter::columns() const -{ - Q_D(const QPixmapConvolutionFilter); - return d->kernelWidth; -} - - -/*! - \internal -*/ -QRectF QPixmapConvolutionFilter::boundingRectFor(const QRectF &rect) const -{ - Q_D(const QPixmapConvolutionFilter); - return rect.adjusted(-d->kernelWidth / 2, -d->kernelHeight / 2, (d->kernelWidth - 1) / 2, (d->kernelHeight - 1) / 2); -} - -// Convolutes the image -static void convolute( - QImage *destImage, - const QPointF &pos, - const QImage &srcImage, - const QRectF &srcRect, - QPainter::CompositionMode mode, - qreal *kernel, - int kernelWidth, - int kernelHeight ) -{ - const QImage processImage = (srcImage.format() != QImage::Format_ARGB32_Premultiplied ) ? srcImage.convertToFormat(QImage::Format_ARGB32_Premultiplied) : srcImage; - // TODO: support also other formats directly without copying - - int *fixedKernel = new int[kernelWidth*kernelHeight]; - for(int i = 0; i < kernelWidth*kernelHeight; i++) - { - fixedKernel[i] = (int)(65536 * kernel[i]); - } - QRectF trect = srcRect.isNull() ? processImage.rect() : srcRect; - trect.moveTo(pos); - QRectF bounded = trect.adjusted(-kernelWidth / 2, -kernelHeight / 2, (kernelWidth - 1) / 2, (kernelHeight - 1) / 2); - QRect rect = bounded.toAlignedRect(); - QRect targetRect = rect.intersected(destImage->rect()); - - QRectF srect = srcRect.isNull() ? processImage.rect() : srcRect; - QRectF sbounded = srect.adjusted(-kernelWidth / 2, -kernelHeight / 2, (kernelWidth - 1) / 2, (kernelHeight - 1) / 2); - QPoint srcStartPoint = sbounded.toAlignedRect().topLeft()+(targetRect.topLeft()-rect.topLeft()); - - const uint *sourceStart = (uint*)processImage.scanLine(0); - uint *outputStart = (uint*)destImage->scanLine(0); - - int yk = srcStartPoint.y(); - for (int y = targetRect.top(); y <= targetRect.bottom(); y++) { - uint* output = outputStart + (destImage->bytesPerLine()/sizeof(uint))*y+targetRect.left(); - int xk = srcStartPoint.x(); - for(int x = targetRect.left(); x <= targetRect.right(); x++) { - int r = 0; - int g = 0; - int b = 0; - int a = 0; - - // some out of bounds pre-checking to avoid inner-loop ifs - int kernely = -kernelHeight/2; - int starty = 0; - int endy = kernelHeight; - if(yk+kernely+endy >= srcImage.height()) - endy = kernelHeight-((yk+kernely+endy)-srcImage.height())-1; - if(yk+kernely < 0) - starty = -(yk+kernely); - - int kernelx = -kernelWidth/2; - int startx = 0; - int endx = kernelWidth; - if(xk+kernelx+endx >= srcImage.width()) - endx = kernelWidth-((xk+kernelx+endx)-srcImage.width())-1; - if(xk+kernelx < 0) - startx = -(xk+kernelx); - - for (int ys = starty; ys < endy; ys ++) { - const uint *pix = sourceStart + (processImage.bytesPerLine()/sizeof(uint))*(yk+kernely+ys) + ((xk+kernelx+startx)); - const uint *endPix = pix+endx-startx; - int kernelPos = ys*kernelWidth+startx; - while (pix < endPix) { - int factor = fixedKernel[kernelPos++]; - a += (((*pix) & 0xff000000)>>24) * factor; - r += (((*pix) & 0x00ff0000)>>16) * factor; - g += (((*pix) & 0x0000ff00)>>8 ) * factor; - b += (((*pix) & 0x000000ff) ) * factor; - pix++; - } - } - - r = qBound((int)0, r >> 16, (int)255); - g = qBound((int)0, g >> 16, (int)255); - b = qBound((int)0, b >> 16, (int)255); - a = qBound((int)0, a >> 16, (int)255); - // composition mode checking could be moved outside of loop - if(mode == QPainter::CompositionMode_Source) { - uint color = (a<<24)+(r<<16)+(g<<8)+b; - *output++ = color; - } else { - uint current = *output; - uchar ca = (current&0xff000000)>>24; - uchar cr = (current&0x00ff0000)>>16; - uchar cg = (current&0x0000ff00)>>8; - uchar cb = (current&0x000000ff); - uint color = - (((ca*(255-a) >> 8)+a) << 24)+ - (((cr*(255-a) >> 8)+r) << 16)+ - (((cg*(255-a) >> 8)+g) << 8)+ - (((cb*(255-a) >> 8)+b)); - *output++ = color;; - } - xk++; - } - yk++; - } - delete[] fixedKernel; -} - -/*! - \internal -*/ -void QPixmapConvolutionFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF& srcRect) const -{ - Q_D(const QPixmapConvolutionFilter); - if (!painter->isActive()) - return; - - if(d->kernelWidth<=0 || d->kernelHeight <= 0) - return; - - if (src.isNull()) - return; - - QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ? - static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0; - QPixmapConvolutionFilter *convolutionFilter = static_cast<QPixmapConvolutionFilter*>(filter); - if (convolutionFilter) { - convolutionFilter->setConvolutionKernel(d->convolutionKernel, d->kernelWidth, d->kernelHeight); - convolutionFilter->d_func()->convoluteAlpha = d->convoluteAlpha; - convolutionFilter->draw(painter, p, src, srcRect); - return; - } - - // falling back to raster implementation - - QImage *target = 0; - if (painter->paintEngine()->paintDevice()->devType() == QInternal::Image) { - target = static_cast<QImage *>(painter->paintEngine()->paintDevice()); - - QTransform mat = painter->combinedTransform(); - - if (mat.type() > QTransform::TxTranslate) { - // Disabled because of transformation... - target = 0; - } else { - QRasterPaintEngine *pe = static_cast<QRasterPaintEngine *>(painter->paintEngine()); - if (pe->clipType() == QRasterPaintEngine::ComplexClip) - // disabled because of complex clipping... - target = 0; - else { - QRectF clip = pe->clipBoundingRect(); - QRectF rect = boundingRectFor(srcRect.isEmpty() ? src.rect() : srcRect); - QTransform x = painter->deviceTransform(); - if (!clip.contains(rect.translated(x.dx() + p.x(), x.dy() + p.y()))) { - target = 0; - } - - } - } - } - - if (target) { - QTransform x = painter->deviceTransform(); - QPointF offset(x.dx(), x.dy()); - - convolute(target, p+offset, src.toImage(), srcRect, QPainter::CompositionMode_SourceOver, d->convolutionKernel, d->kernelWidth, d->kernelHeight); - } else { - QRect srect = srcRect.isNull() ? src.rect() : srcRect.toRect(); - QRect rect = boundingRectFor(srect).toRect(); - QImage result = QImage(rect.size(), QImage::Format_ARGB32_Premultiplied); - QPoint offset = srect.topLeft() - rect.topLeft(); - convolute(&result, - offset, - src.toImage(), - srect, - QPainter::CompositionMode_Source, - d->convolutionKernel, - d->kernelWidth, - d->kernelHeight); - painter->drawImage(p - offset, result); - } -} - -/*! - \class QPixmapBlurFilter - \since 4.6 - \ingroup multimedia - - \brief The QPixmapBlurFilter class provides blur filtering - for pixmaps. - - QPixmapBlurFilter implements a blur pixmap filter, - which is applied when \l{QPixmapFilter::}{draw()} is called. - - The filter lets you specialize the radius of the blur as well - as hints as to whether to prefer performance or quality. - - By default, the blur effect is produced by applying an exponential - filter generated from the specified blurRadius(). Paint engines - may override this with a custom blur that is faster on the - underlying hardware. - - \sa {Pixmap Filters Example}, QPixmapConvolutionFilter, QPixmapDropShadowFilter - - \internal -*/ - -class QPixmapBlurFilterPrivate : public QPixmapFilterPrivate -{ -public: - QPixmapBlurFilterPrivate() : radius(5), hints(QGraphicsBlurEffect::PerformanceHint) {} - - qreal radius; - QGraphicsBlurEffect::BlurHints hints; -}; - - -/*! - Constructs a pixmap blur filter. - - \internal -*/ -QPixmapBlurFilter::QPixmapBlurFilter(QObject *parent) - : QPixmapFilter(*new QPixmapBlurFilterPrivate, BlurFilter, parent) -{ -} - -/*! - Destructor of pixmap blur filter. - - \internal -*/ -QPixmapBlurFilter::~QPixmapBlurFilter() -{ -} - -/*! - Sets the radius of the blur filter. Higher radius produces increased blurriness. - - \internal -*/ -void QPixmapBlurFilter::setRadius(qreal radius) -{ - Q_D(QPixmapBlurFilter); - d->radius = radius; -} - -/*! - Gets the radius of the blur filter. - - \internal -*/ -qreal QPixmapBlurFilter::radius() const -{ - Q_D(const QPixmapBlurFilter); - return d->radius; -} - -/*! - Setting the blur hints to PerformanceHint causes the implementation - to trade off visual quality to blur the image faster. Setting the - blur hints to QualityHint causes the implementation to improve - visual quality at the expense of speed. - - AnimationHint causes the implementation to optimize for animating - the blur radius, possibly by caching blurred versions of the source - pixmap. - - The implementation is free to ignore this value if it only has a single - blur algorithm. - - \internal -*/ -void QPixmapBlurFilter::setBlurHints(QGraphicsBlurEffect::BlurHints hints) -{ - Q_D(QPixmapBlurFilter); - d->hints = hints; -} - -/*! - Gets the blur hints of the blur filter. - - \internal -*/ -QGraphicsBlurEffect::BlurHints QPixmapBlurFilter::blurHints() const -{ - Q_D(const QPixmapBlurFilter); - return d->hints; -} - -const qreal radiusScale = qreal(2.5); - -/*! - \internal -*/ -QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const -{ - Q_D(const QPixmapBlurFilter); - const qreal delta = radiusScale * d->radius + 1; - return rect.adjusted(-delta, -delta, delta, delta); -} - -template <int shift> -inline int qt_static_shift(int value) -{ - if (shift == 0) - return value; - else if (shift > 0) - return value << (uint(shift) & 0x1f); - else - return value >> (uint(-shift) & 0x1f); -} - -template<int aprec, int zprec> -inline void qt_blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha) -{ - QRgb *pixel = (QRgb *)bptr; - -#define Z_MASK (0xff << zprec) - const int A_zprec = qt_static_shift<zprec - 24>(*pixel) & Z_MASK; - const int R_zprec = qt_static_shift<zprec - 16>(*pixel) & Z_MASK; - const int G_zprec = qt_static_shift<zprec - 8>(*pixel) & Z_MASK; - const int B_zprec = qt_static_shift<zprec>(*pixel) & Z_MASK; -#undef Z_MASK - - const int zR_zprec = zR >> aprec; - const int zG_zprec = zG >> aprec; - const int zB_zprec = zB >> aprec; - const int zA_zprec = zA >> aprec; - - zR += alpha * (R_zprec - zR_zprec); - zG += alpha * (G_zprec - zG_zprec); - zB += alpha * (B_zprec - zB_zprec); - zA += alpha * (A_zprec - zA_zprec); - -#define ZA_MASK (0xff << (zprec + aprec)) - *pixel = - qt_static_shift<24 - zprec - aprec>(zA & ZA_MASK) - | qt_static_shift<16 - zprec - aprec>(zR & ZA_MASK) - | qt_static_shift<8 - zprec - aprec>(zG & ZA_MASK) - | qt_static_shift<-zprec - aprec>(zB & ZA_MASK); -#undef ZA_MASK -} - -const int alphaIndex = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3); - -template<int aprec, int zprec> -inline void qt_blurinner_alphaOnly(uchar *bptr, int &z, int alpha) -{ - const int A_zprec = int(*(bptr)) << zprec; - const int z_zprec = z >> aprec; - z += alpha * (A_zprec - z_zprec); - *(bptr) = z >> (zprec + aprec); -} - -template<int aprec, int zprec, bool alphaOnly> -inline void qt_blurrow(QImage & im, int line, int alpha) -{ - uchar *bptr = im.scanLine(line); - - int zR = 0, zG = 0, zB = 0, zA = 0; - - if (alphaOnly && im.format() != QImage::Format_Indexed8) - bptr += alphaIndex; - - const int stride = im.depth() >> 3; - const int im_width = im.width(); - for (int index = 0; index < im_width; ++index) { - if (alphaOnly) - qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha); - else - qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha); - bptr += stride; - } - - bptr -= stride; - - for (int index = im_width - 2; index >= 0; --index) { - bptr -= stride; - if (alphaOnly) - qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha); - else - qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha); - } -} - -/* -* expblur(QImage &img, int radius) -* -* Based on exponential blur algorithm by Jani Huhtanen -* -* In-place blur of image 'img' with kernel -* of approximate radius 'radius'. -* -* Blurs with two sided exponential impulse -* response. -* -* aprec = precision of alpha parameter -* in fixed-point format 0.aprec -* -* zprec = precision of state parameters -* zR,zG,zB and zA in fp format 8.zprec -*/ -template <int aprec, int zprec, bool alphaOnly> -void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transposed = 0) -{ - // halve the radius if we're using two passes - if (improvedQuality) - radius *= qreal(0.5); - - Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied - || img.format() == QImage::Format_RGB32 - || img.format() == QImage::Format_Indexed8); - - // choose the alpha such that pixels at radius distance from a fully - // saturated pixel will have an alpha component of no greater than - // the cutOffIntensity - const qreal cutOffIntensity = 2; - int alpha = radius <= qreal(1e-5) - ? ((1 << aprec)-1) - : qRound((1<<aprec)*(1 - qPow(cutOffIntensity * (1 / qreal(255)), 1 / radius))); - - int img_height = img.height(); - for (int row = 0; row < img_height; ++row) { - for (int i = 0; i <= int(improvedQuality); ++i) - qt_blurrow<aprec, zprec, alphaOnly>(img, row, alpha); - } - - QImage temp(img.height(), img.width(), img.format()); - if (transposed >= 0) { - if (img.depth() == 8) { - qt_memrotate270(reinterpret_cast<const quint8*>(img.bits()), - img.width(), img.height(), img.bytesPerLine(), - reinterpret_cast<quint8*>(temp.bits()), - temp.bytesPerLine()); - } else { - qt_memrotate270(reinterpret_cast<const quint32*>(img.bits()), - img.width(), img.height(), img.bytesPerLine(), - reinterpret_cast<quint32*>(temp.bits()), - temp.bytesPerLine()); - } - } else { - if (img.depth() == 8) { - qt_memrotate90(reinterpret_cast<const quint8*>(img.bits()), - img.width(), img.height(), img.bytesPerLine(), - reinterpret_cast<quint8*>(temp.bits()), - temp.bytesPerLine()); - } else { - qt_memrotate90(reinterpret_cast<const quint32*>(img.bits()), - img.width(), img.height(), img.bytesPerLine(), - reinterpret_cast<quint32*>(temp.bits()), - temp.bytesPerLine()); - } - } - - img_height = temp.height(); - for (int row = 0; row < img_height; ++row) { - for (int i = 0; i <= int(improvedQuality); ++i) - qt_blurrow<aprec, zprec, alphaOnly>(temp, row, alpha); - } - - if (transposed == 0) { - if (img.depth() == 8) { - qt_memrotate90(reinterpret_cast<const quint8*>(temp.bits()), - temp.width(), temp.height(), temp.bytesPerLine(), - reinterpret_cast<quint8*>(img.bits()), - img.bytesPerLine()); - } else { - qt_memrotate90(reinterpret_cast<const quint32*>(temp.bits()), - temp.width(), temp.height(), temp.bytesPerLine(), - reinterpret_cast<quint32*>(img.bits()), - img.bytesPerLine()); - } - } else { - img = temp; - } -} -#define AVG(a,b) ( ((((a)^(b)) & 0xfefefefeUL) >> 1) + ((a)&(b)) ) -#define AVG16(a,b) ( ((((a)^(b)) & 0xf7deUL) >> 1) + ((a)&(b)) ) - -Q_GUI_EXPORT QImage qt_halfScaled(const QImage &source) -{ - if (source.width() < 2 || source.height() < 2) - return QImage(); - - QImage srcImage = source; - - if (source.format() == QImage::Format_Indexed8) { - // assumes grayscale - QImage dest(source.width() / 2, source.height() / 2, srcImage.format()); - - const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits()); - int sx = srcImage.bytesPerLine(); - int sx2 = sx << 1; - - uchar *dst = reinterpret_cast<uchar*>(dest.bits()); - int dx = dest.bytesPerLine(); - int ww = dest.width(); - int hh = dest.height(); - - for (int y = hh; y; --y, dst += dx, src += sx2) { - const uchar *p1 = src; - const uchar *p2 = src + sx; - uchar *q = dst; - for (int x = ww; x; --x, ++q, p1 += 2, p2 += 2) - *q = ((int(p1[0]) + int(p1[1]) + int(p2[0]) + int(p2[1])) + 2) >> 2; - } - - return dest; - } else if (source.format() == QImage::Format_ARGB8565_Premultiplied) { - QImage dest(source.width() / 2, source.height() / 2, srcImage.format()); - - const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits()); - int sx = srcImage.bytesPerLine(); - int sx2 = sx << 1; - - uchar *dst = reinterpret_cast<uchar*>(dest.bits()); - int dx = dest.bytesPerLine(); - int ww = dest.width(); - int hh = dest.height(); - - for (int y = hh; y; --y, dst += dx, src += sx2) { - const uchar *p1 = src; - const uchar *p2 = src + sx; - uchar *q = dst; - for (int x = ww; x; --x, q += 3, p1 += 6, p2 += 6) { - // alpha - q[0] = AVG(AVG(p1[0], p1[3]), AVG(p2[0], p2[3])); - // rgb - const quint16 p16_1 = (p1[2] << 8) | p1[1]; - const quint16 p16_2 = (p1[5] << 8) | p1[4]; - const quint16 p16_3 = (p2[2] << 8) | p2[1]; - const quint16 p16_4 = (p2[5] << 8) | p2[4]; - const quint16 result = AVG16(AVG16(p16_1, p16_2), AVG16(p16_3, p16_4)); - q[1] = result & 0xff; - q[2] = result >> 8; - } - } - - return dest; - } else if (source.format() != QImage::Format_ARGB32_Premultiplied - && source.format() != QImage::Format_RGB32) - { - srcImage = source.convertToFormat(QImage::Format_ARGB32_Premultiplied); - } - - QImage dest(source.width() / 2, source.height() / 2, srcImage.format()); - - const quint32 *src = reinterpret_cast<const quint32*>(const_cast<const QImage &>(srcImage).bits()); - int sx = srcImage.bytesPerLine() >> 2; - int sx2 = sx << 1; - - quint32 *dst = reinterpret_cast<quint32*>(dest.bits()); - int dx = dest.bytesPerLine() >> 2; - int ww = dest.width(); - int hh = dest.height(); - - for (int y = hh; y; --y, dst += dx, src += sx2) { - const quint32 *p1 = src; - const quint32 *p2 = src + sx; - quint32 *q = dst; - for (int x = ww; x; --x, q++, p1 += 2, p2 += 2) - *q = AVG(AVG(p1[0], p1[1]), AVG(p2[0], p2[1])); - } - - return dest; -} - -Q_GUI_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0) -{ - if (blurImage.format() != QImage::Format_ARGB32_Premultiplied - && blurImage.format() != QImage::Format_RGB32) - { - blurImage = blurImage.convertToFormat(QImage::Format_ARGB32_Premultiplied); - } - - qreal scale = 1; - if (radius >= 4 && blurImage.width() >= 2 && blurImage.height() >= 2) { - blurImage = qt_halfScaled(blurImage); - scale = 2; - radius *= qreal(0.5); - } - - if (alphaOnly) - expblur<12, 10, true>(blurImage, radius, quality, transposed); - else - expblur<12, 10, false>(blurImage, radius, quality, transposed); - - if (p) { - p->scale(scale, scale); - p->setRenderHint(QPainter::SmoothPixmapTransform); - p->drawImage(QRect(0, 0, blurImage.width(), blurImage.height()), blurImage); - } -} - -Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0) -{ - if (blurImage.format() == QImage::Format_Indexed8) - expblur<12, 10, true>(blurImage, radius, quality, transposed); - else - expblur<12, 10, false>(blurImage, radius, quality, transposed); -} - -Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); - -/*! - \internal -*/ -void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &rect) const -{ - Q_D(const QPixmapBlurFilter); - if (!painter->isActive()) - return; - - if (src.isNull()) - return; - - QRectF srcRect = rect; - if (srcRect.isNull()) - srcRect = src.rect(); - - if (d->radius <= 1) { - painter->drawPixmap(srcRect.translated(p), src, srcRect); - return; - } - - qreal scaledRadius = radiusScale * d->radius; - qreal scale; - if (qt_scaleForTransform(painter->transform(), &scale)) - scaledRadius /= scale; - - QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ? - static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0; - QPixmapBlurFilter *blurFilter = static_cast<QPixmapBlurFilter*>(filter); - if (blurFilter) { - blurFilter->setRadius(scaledRadius); - blurFilter->setBlurHints(d->hints); - blurFilter->draw(painter, p, src, srcRect); - return; - } - - QImage srcImage; - QImage destImage; - - if (srcRect == src.rect()) { - srcImage = src.toImage(); - } else { - QRect rect = srcRect.toAlignedRect().intersected(src.rect()); - srcImage = src.copy(rect).toImage(); - } - - QTransform transform = painter->worldTransform(); - painter->translate(p); - qt_blurImage(painter, srcImage, scaledRadius, (d->hints & QGraphicsBlurEffect::QualityHint), false); - painter->setWorldTransform(transform); -} - -// grayscales the image to dest (could be same). If rect isn't defined -// destination image size is used to determine the dimension of grayscaling -// process. -static void grayscale(const QImage &image, QImage &dest, const QRect& rect = QRect()) -{ - QRect destRect = rect; - QRect srcRect = rect; - if (rect.isNull()) { - srcRect = dest.rect(); - destRect = dest.rect(); - } - if (&image != &dest) { - destRect.moveTo(QPoint(0, 0)); - } - - unsigned int *data = (unsigned int *)image.bits(); - unsigned int *outData = (unsigned int *)dest.bits(); - - if (dest.size() == image.size() && image.rect() == srcRect) { - // a bit faster loop for grayscaling everything - int pixels = dest.width() * dest.height(); - for (int i = 0; i < pixels; ++i) { - int val = qGray(data[i]); - outData[i] = qRgba(val, val, val, qAlpha(data[i])); - } - } else { - int yd = destRect.top(); - for (int y = srcRect.top(); y <= srcRect.bottom() && y < image.height(); y++) { - data = (unsigned int*)image.scanLine(y); - outData = (unsigned int*)dest.scanLine(yd++); - int xd = destRect.left(); - for (int x = srcRect.left(); x <= srcRect.right() && x < image.width(); x++) { - int val = qGray(data[x]); - outData[xd++] = qRgba(val, val, val, qAlpha(data[x])); - } - } - } -} - -/*! - \class QPixmapColorizeFilter - \since 4.5 - \ingroup painting - - \brief The QPixmapColorizeFilter class provides colorizing - filtering for pixmaps. - - A colorize filter gives the pixmap a tint of its color(). The - filter first grayscales the pixmap and then converts those to - colorized values using QPainter::CompositionMode_Screen with the - chosen color. The alpha-channel is not changed. - - Example: - \snippet doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp 0 - - \sa QPainter::CompositionMode - - \internal -*/ -class QPixmapColorizeFilterPrivate : public QPixmapFilterPrivate -{ - Q_DECLARE_PUBLIC(QPixmapColorizeFilter) -public: - QColor color; - qreal strength; - quint32 opaque : 1; - quint32 alphaBlend : 1; - quint32 padding : 30; -}; - -/*! - Constructs an pixmap colorize filter. - - Default color value for colorizing is QColor(0, 0, 192). - - \internal -*/ -QPixmapColorizeFilter::QPixmapColorizeFilter(QObject *parent) - : QPixmapFilter(*new QPixmapColorizeFilterPrivate, ColorizeFilter, parent) -{ - Q_D(QPixmapColorizeFilter); - d->color = QColor(0, 0, 192); - d->strength = qreal(1); - d->opaque = true; - d->alphaBlend = false; -} - -/*! - Gets the color of the colorize filter. - - \internal -*/ -QColor QPixmapColorizeFilter::color() const -{ - Q_D(const QPixmapColorizeFilter); - return d->color; -} - -/*! - Sets the color of the colorize filter to the \a color specified. - - \internal -*/ -void QPixmapColorizeFilter::setColor(const QColor &color) -{ - Q_D(QPixmapColorizeFilter); - d->color = color; -} - -/*! - Gets the strength of the colorize filter, 1.0 means full colorized while - 0.0 equals to no filtering at all. - - \internal -*/ -qreal QPixmapColorizeFilter::strength() const -{ - Q_D(const QPixmapColorizeFilter); - return d->strength; -} - -/*! - Sets the strength of the colorize filter to \a strength. - - \internal -*/ -void QPixmapColorizeFilter::setStrength(qreal strength) -{ - Q_D(QPixmapColorizeFilter); - d->strength = qBound(qreal(0), strength, qreal(1)); - d->opaque = !qFuzzyIsNull(d->strength); - d->alphaBlend = !qFuzzyIsNull(d->strength - 1); -} - -/*! - \internal -*/ -void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const -{ - Q_D(const QPixmapColorizeFilter); - - if (src.isNull()) - return; - - QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ? - static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0; - QPixmapColorizeFilter *colorizeFilter = static_cast<QPixmapColorizeFilter*>(filter); - if (colorizeFilter) { - colorizeFilter->setColor(d->color); - colorizeFilter->setStrength(d->strength); - colorizeFilter->draw(painter, dest, src, srcRect); - return; - } - - // falling back to raster implementation - - if (!d->opaque) { - painter->drawPixmap(dest, src, srcRect); - return; - } - - QImage srcImage; - QImage destImage; - - if (srcRect.isNull()) { - srcImage = src.toImage(); - srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); - destImage = QImage(srcImage.size(), srcImage.format()); - } else { - QRect rect = srcRect.toAlignedRect().intersected(src.rect()); - - srcImage = src.copy(rect).toImage(); - srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); - destImage = QImage(rect.size(), srcImage.format()); - } - - // do colorizing - QPainter destPainter(&destImage); - grayscale(srcImage, destImage, srcImage.rect()); - destPainter.setCompositionMode(QPainter::CompositionMode_Screen); - destPainter.fillRect(srcImage.rect(), d->color); - destPainter.end(); - - if (d->alphaBlend) { - // alpha blending srcImage and destImage - QImage buffer = srcImage; - QPainter bufPainter(&buffer); - bufPainter.setOpacity(d->strength); - bufPainter.drawImage(0, 0, destImage); - bufPainter.end(); - destImage = buffer; - } - - if (srcImage.hasAlphaChannel()) - destImage.setAlphaChannel(srcImage.alphaChannel()); - - painter->drawImage(dest, destImage); -} - -class QPixmapDropShadowFilterPrivate : public QPixmapFilterPrivate -{ -public: - QPixmapDropShadowFilterPrivate() - : offset(8, 8), color(63, 63, 63, 180), radius(1) {} - - QPointF offset; - QColor color; - qreal radius; -}; - -/*! - \class QPixmapDropShadowFilter - \since 4.5 - \ingroup painting - - \brief The QPixmapDropShadowFilter class is a convenience class - for drawing pixmaps with drop shadows. - - The drop shadow is produced by taking a copy of the source pixmap - and applying a color to the copy using a - QPainter::CompositionMode_DestinationIn operation. This produces a - homogeneously-colored pixmap which is then drawn using a - QPixmapConvolutionFilter at an offset. The original pixmap is - drawn on top. - - The QPixmapDropShadowFilter class provides some customization - options to specify how the drop shadow should appear. The color of - the drop shadow can be modified using the setColor() function, the - drop shadow offset can be modified using the setOffset() function, - and the blur radius of the drop shadow can be changed through the - setBlurRadius() function. - - By default, the drop shadow is a dark gray shadow, blurred with a - radius of 1 at an offset of 8 pixels towards the lower right. - - Example: - \snippet doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp 2 - - \sa QPixmapColorizeFilter, QPixmapConvolutionFilter - - \internal - */ - -/*! - Constructs drop shadow filter. - - \internal -*/ -QPixmapDropShadowFilter::QPixmapDropShadowFilter(QObject *parent) - : QPixmapFilter(*new QPixmapDropShadowFilterPrivate, DropShadowFilter, parent) -{ -} - -/*! - Destroys drop shadow filter. - - \internal -*/ -QPixmapDropShadowFilter::~QPixmapDropShadowFilter() -{ -} - -/*! - Returns the radius in pixels of the blur on the drop shadow. - - A smaller radius results in a sharper shadow. - - \sa color(), offset() - - \internal -*/ -qreal QPixmapDropShadowFilter::blurRadius() const -{ - Q_D(const QPixmapDropShadowFilter); - return d->radius; -} - -/*! - Sets the radius in pixels of the blur on the drop shadow to the \a radius specified. - - Using a smaller radius results in a sharper shadow. - - \sa setColor(), setOffset() - - \internal -*/ -void QPixmapDropShadowFilter::setBlurRadius(qreal radius) -{ - Q_D(QPixmapDropShadowFilter); - d->radius = radius; -} - -/*! - Returns the color of the drop shadow. - - \sa blurRadius(), offset() - - \internal -*/ -QColor QPixmapDropShadowFilter::color() const -{ - Q_D(const QPixmapDropShadowFilter); - return d->color; -} - -/*! - Sets the color of the drop shadow to the \a color specified. - - \sa setBlurRadius(), setOffset() - - \internal -*/ -void QPixmapDropShadowFilter::setColor(const QColor &color) -{ - Q_D(QPixmapDropShadowFilter); - d->color = color; -} - -/*! - Returns the shadow offset in pixels. - - \sa blurRadius(), color() - - \internal -*/ -QPointF QPixmapDropShadowFilter::offset() const -{ - Q_D(const QPixmapDropShadowFilter); - return d->offset; -} - -/*! - Sets the shadow offset in pixels to the \a offset specified. - - \sa setBlurRadius(), setColor() - - \internal -*/ -void QPixmapDropShadowFilter::setOffset(const QPointF &offset) -{ - Q_D(QPixmapDropShadowFilter); - d->offset = offset; -} - -/*! - \fn void QPixmapDropShadowFilter::setOffset(qreal dx, qreal dy) - \overload - - Sets the shadow offset in pixels to be the displacement specified by the - horizontal \a dx and vertical \a dy coordinates. - - \sa setBlurRadius(), setColor() - - \internal -*/ - -/*! - \internal - */ -QRectF QPixmapDropShadowFilter::boundingRectFor(const QRectF &rect) const -{ - Q_D(const QPixmapDropShadowFilter); - return rect.united(rect.translated(d->offset).adjusted(-d->radius, -d->radius, d->radius, d->radius)); -} - -/*! - \internal - */ -void QPixmapDropShadowFilter::draw(QPainter *p, - const QPointF &pos, - const QPixmap &px, - const QRectF &src) const -{ - Q_D(const QPixmapDropShadowFilter); - - if (px.isNull()) - return; - - QPixmapFilter *filter = p->paintEngine() && p->paintEngine()->isExtended() ? - static_cast<QPaintEngineEx *>(p->paintEngine())->pixmapFilter(type(), this) : 0; - QPixmapDropShadowFilter *dropShadowFilter = static_cast<QPixmapDropShadowFilter*>(filter); - if (dropShadowFilter) { - dropShadowFilter->setColor(d->color); - dropShadowFilter->setBlurRadius(d->radius); - dropShadowFilter->setOffset(d->offset); - dropShadowFilter->draw(p, pos, px, src); - return; - } - - QImage tmp(px.size(), QImage::Format_ARGB32_Premultiplied); - tmp.fill(0); - QPainter tmpPainter(&tmp); - tmpPainter.setCompositionMode(QPainter::CompositionMode_Source); - tmpPainter.drawPixmap(d->offset, px); - tmpPainter.end(); - - // blur the alpha channel - QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied); - blurred.fill(0); - QPainter blurPainter(&blurred); - qt_blurImage(&blurPainter, tmp, d->radius, false, true); - blurPainter.end(); - - tmp = blurred; - - // blacken the image... - tmpPainter.begin(&tmp); - tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); - tmpPainter.fillRect(tmp.rect(), d->color); - tmpPainter.end(); - - // draw the blurred drop shadow... - p->drawImage(pos, tmp); - - // Draw the actual pixmap... - p->drawPixmap(pos, px, src); -} - -QT_END_NAMESPACE - -#endif //QT_NO_GRAPHICSEFFECT diff --git a/src/gui/image/qpixmapfilter_p.h b/src/gui/image/qpixmapfilter_p.h deleted file mode 100644 index 4ece5876bd..0000000000 --- a/src/gui/image/qpixmapfilter_p.h +++ /dev/null @@ -1,196 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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.1, 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPIXMAPFILTER_H -#define QPIXMAPFILTER_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qnamespace.h> -#include <QtGui/qpixmap.h> -#include <QtGui/qgraphicseffect.h> - -#ifndef QT_NO_GRAPHICSEFFECT -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QPainter; -class QPixmapData; - -class QPixmapFilterPrivate; - -class Q_GUI_EXPORT QPixmapFilter : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QPixmapFilter) -public: - virtual ~QPixmapFilter() = 0; - - enum FilterType { - ConvolutionFilter, - ColorizeFilter, - DropShadowFilter, - BlurFilter, - - UserFilter = 1024 - }; - - FilterType type() const; - - virtual QRectF boundingRectFor(const QRectF &rect) const; - - virtual void draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &srcRect = QRectF()) const = 0; - -protected: - QPixmapFilter(QPixmapFilterPrivate &d, FilterType type, QObject *parent); - QPixmapFilter(FilterType type, QObject *parent); -}; - -class QPixmapConvolutionFilterPrivate; - -class Q_GUI_EXPORT QPixmapConvolutionFilter : public QPixmapFilter -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QPixmapConvolutionFilter) - -public: - QPixmapConvolutionFilter(QObject *parent = 0); - ~QPixmapConvolutionFilter(); - - void setConvolutionKernel(const qreal *matrix, int rows, int columns); - - QRectF boundingRectFor(const QRectF &rect) const; - void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const; - -private: - friend class QGLPixmapConvolutionFilter; - friend class QVGPixmapConvolutionFilter; - const qreal *convolutionKernel() const; - int rows() const; - int columns() const; -}; - -class QPixmapBlurFilterPrivate; - -class Q_GUI_EXPORT QPixmapBlurFilter : public QPixmapFilter -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QPixmapBlurFilter) - -public: - QPixmapBlurFilter(QObject *parent = 0); - ~QPixmapBlurFilter(); - - void setRadius(qreal radius); - void setBlurHints(QGraphicsBlurEffect::BlurHints hints); - - qreal radius() const; - QGraphicsBlurEffect::BlurHints blurHints() const; - - QRectF boundingRectFor(const QRectF &rect) const; - void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const; - -private: - friend class QGLPixmapBlurFilter; -}; - -class QPixmapColorizeFilterPrivate; - -class Q_GUI_EXPORT QPixmapColorizeFilter : public QPixmapFilter -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QPixmapColorizeFilter) - -public: - QPixmapColorizeFilter(QObject *parent = 0); - - void setColor(const QColor& color); - QColor color() const; - - void setStrength(qreal strength); - qreal strength() const; - - void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const; -}; - -class QPixmapDropShadowFilterPrivate; - -class Q_GUI_EXPORT QPixmapDropShadowFilter : public QPixmapFilter -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QPixmapDropShadowFilter) - -public: - QPixmapDropShadowFilter(QObject *parent = 0); - ~QPixmapDropShadowFilter(); - - QRectF boundingRectFor(const QRectF &rect) const; - void draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src = QRectF()) const; - - qreal blurRadius() const; - void setBlurRadius(qreal radius); - - QColor color() const; - void setColor(const QColor &color); - - QPointF offset() const; - void setOffset(const QPointF &offset); - inline void setOffset(qreal dx, qreal dy) { setOffset(QPointF(dx, dy)); } -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif //QT_NO_GRAPHICSEFFECT -#endif // QPIXMAPFILTER_H diff --git a/src/gui/image/qplatformpixmap.cpp b/src/gui/image/qplatformpixmap.cpp new file mode 100644 index 0000000000..a214f397ed --- /dev/null +++ b/src/gui/image/qplatformpixmap.cpp @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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.1, 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qplatformpixmap_qpa.h" +#include <QtCore/qbuffer.h> +#include <QtGui/qbitmap.h> +#include <QtGui/qimagereader.h> +#include <private/qguiapplication_p.h> +#include <private/qimagepixmapcleanuphooks_p.h> + +QT_BEGIN_NAMESPACE + +QPlatformPixmap *QPlatformPixmap::create(int w, int h, PixelType type) +{ + QPlatformPixmap *data = QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(static_cast<QPlatformPixmap::PixelType>(type)); + data->resize(w, h); + return data; +} + + +QPlatformPixmap::QPlatformPixmap(PixelType pixelType, int objectId) + : w(0), + h(0), + d(0), + is_null(true), + ref(0), + detach_no(0), + type(pixelType), + id(objectId), + ser_no(0), + is_cached(false) +{ +} + +QPlatformPixmap::~QPlatformPixmap() +{ + // Sometimes the pixmap cleanup hooks will be called from derrived classes, which will + // then set is_cached to false. For example, on X11 QtGui needs to delete the GLXPixmap + // or EGL Pixmap Surface for a given pixmap _before_ the native X11 pixmap is deleted, + // otherwise some drivers will leak the GL surface. In this case, QX11PlatformPixmap will + // call the cleanup hooks itself before deleting the native pixmap and set is_cached to + // false. + if (is_cached) { + QImagePixmapCleanupHooks::executePlatformPixmapDestructionHooks(this); + is_cached = false; + } +} + +QPlatformPixmap *QPlatformPixmap::createCompatiblePlatformPixmap() const +{ + QPlatformPixmap *d = QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(pixelType()); + return d; +} + +static QImage makeBitmapCompliantIfNeeded(QPlatformPixmap *d, const QImage &image, Qt::ImageConversionFlags flags) +{ + if (d->pixelType() == QPlatformPixmap::BitmapType) { + QImage img = image.convertToFormat(QImage::Format_MonoLSB, flags); + + // make sure image.color(0) == Qt::color0 (white) + // and image.color(1) == Qt::color1 (black) + const QRgb c0 = QColor(Qt::black).rgb(); + const QRgb c1 = QColor(Qt::white).rgb(); + if (img.color(0) == c0 && img.color(1) == c1) { + img.invertPixels(); + img.setColor(0, c1); + img.setColor(1, c0); + } + return img; + } + + return image; +} + +void QPlatformPixmap::fromImageReader(QImageReader *imageReader, + Qt::ImageConversionFlags flags) +{ + const QImage image = imageReader->read(); + fromImage(image, flags); +} + +bool QPlatformPixmap::fromFile(const QString &fileName, const char *format, + Qt::ImageConversionFlags flags) +{ + QImage image = QImageReader(fileName, format).read(); + if (image.isNull()) + return false; + fromImage(makeBitmapCompliantIfNeeded(this, image, flags), flags); + return !isNull(); +} + +bool QPlatformPixmap::fromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags) +{ + QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buf), len); + QBuffer b(&a); + b.open(QIODevice::ReadOnly); + QImage image = QImageReader(&b, format).read(); + fromImage(makeBitmapCompliantIfNeeded(this, image, flags), flags); + return !isNull(); +} + +void QPlatformPixmap::copy(const QPlatformPixmap *data, const QRect &rect) +{ + fromImage(data->toImage(rect), Qt::NoOpaqueDetection); +} + +bool QPlatformPixmap::scroll(int dx, int dy, const QRect &rect) +{ + Q_UNUSED(dx); + Q_UNUSED(dy); + Q_UNUSED(rect); + return false; +} + +QPixmap QPlatformPixmap::transformed(const QTransform &matrix, + Qt::TransformationMode mode) const +{ + return QPixmap::fromImage(toImage().transformed(matrix, mode)); +} + +void QPlatformPixmap::setSerialNumber(int serNo) +{ + ser_no = serNo; +} + +QImage QPlatformPixmap::toImage(const QRect &rect) const +{ + if (rect.contains(QRect(0, 0, w, h))) + return toImage(); + else + return toImage().copy(rect); +} + +QImage* QPlatformPixmap::buffer() +{ + return 0; +} + +#if defined(Q_OS_SYMBIAN) +void* QPlatformPixmap::toNativeType(NativeType /* type */) +{ + return 0; +} + +void QPlatformPixmap::fromNativeType(void* /* pixmap */, NativeType /* typre */) +{ + return; +} +#endif + +QT_END_NAMESPACE diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qplatformpixmap_qpa.h index 5b75aa102b..d528f4138f 100644 --- a/src/gui/image/qpixmapdata_p.h +++ b/src/gui/image/qplatformpixmap_qpa.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE class QImageReader; -class Q_GUI_EXPORT QPixmapData +class Q_GUI_EXPORT QPlatformPixmap { public: enum PixelType { @@ -68,22 +68,14 @@ public: // Must match QPixmap::Type PixmapType, BitmapType }; -#if defined(Q_OS_SYMBIAN) - enum NativeType { - FbsBitmap, - SgImage, - VolatileImage, - NativeImageHandleProvider - }; -#endif - enum ClassId { RasterClass, X11Class, MacClass, DirectFBClass, - OpenGLClass, OpenVGClass, RuntimeClass, BlitterClass, - CustomClass = 1024 }; - QPixmapData(PixelType pixelType, int classId); - virtual ~QPixmapData(); + enum ClassId { RasterClass, DirectFBClass, + BlitterClass, CustomClass = 1024 }; + + QPlatformPixmap(PixelType pixelType, int classId); + virtual ~QPlatformPixmap(); - virtual QPixmapData *createCompatiblePixmapData() const; + virtual QPlatformPixmap *createCompatiblePlatformPixmap() const; virtual void resize(int width, int height) = 0; virtual void fromImage(const QImage &image, @@ -96,18 +88,16 @@ public: virtual bool fromData(const uchar *buffer, uint len, const char *format, Qt::ImageConversionFlags flags); - virtual void copy(const QPixmapData *data, const QRect &rect); + virtual void copy(const QPlatformPixmap *data, const QRect &rect); virtual bool scroll(int dx, int dy, const QRect &rect); virtual int metric(QPaintDevice::PaintDeviceMetric metric) const = 0; virtual void fill(const QColor &color) = 0; - virtual QBitmap mask() const; - virtual void setMask(const QBitmap &mask); + virtual bool hasAlphaChannel() const = 0; virtual QPixmap transformed(const QTransform &matrix, Qt::TransformationMode mode) const; - virtual void setAlphaChannel(const QPixmap &alphaChannel); - virtual QPixmap alphaChannel() const; + virtual QImage toImage() const = 0; virtual QImage toImage(const QRect &rect) const; virtual QPaintEngine* paintEngine() const = 0; @@ -121,7 +111,6 @@ public: inline int width() const { return w; } inline int height() const { return h; } - QT_DEPRECATED inline int numColors() const { return metric(QPaintDevice::PdmNumColors); } inline int colorCount() const { return metric(QPaintDevice::PdmNumColors); } inline int depth() const { return d; } inline bool isNull() const { return is_null; } @@ -134,14 +123,7 @@ public: | ((qint64) detach_no)); } -#if defined(Q_OS_SYMBIAN) - virtual void* toNativeType(NativeType type); - virtual void fromNativeType(void* pixmap, NativeType type); -#endif - - static QPixmapData *create(int w, int h, PixelType type); - - virtual QPixmapData *runtimeData() const { return 0; } + static QPlatformPixmap *create(int w, int h, PixelType type); protected: @@ -153,11 +135,9 @@ protected: private: friend class QPixmap; - friend class QX11PixmapData; - friend class QS60PixmapData; friend class QImagePixmapCleanupHooks; // Needs to set is_cached - friend class QGLTextureCache; //Needs to check the reference count - friend class QExplicitlySharedDataPointer<QPixmapData>; + friend class QOpenGLTextureCache; //Needs to check the reference count + friend class QExplicitlySharedDataPointer<QPlatformPixmap>; QAtomicInt ref; int detach_no; diff --git a/src/gui/image/qvolatileimage.cpp b/src/gui/image/qvolatileimage.cpp index aa3759a9ec..f7fe70c496 100644 --- a/src/gui/image/qvolatileimage.cpp +++ b/src/gui/image/qvolatileimage.cpp @@ -42,7 +42,7 @@ #include "qvolatileimage_p.h" #include "qvolatileimagedata_p.h" #include <QtGui/private/qpaintengine_raster_p.h> -#include <QtGui/private/qpixmapdata_p.h> +#include <QtGui/qplatformpixmap_qpa.h> QT_BEGIN_NAMESPACE @@ -200,15 +200,6 @@ void *QVolatileImage::duplicateNativeImage() const return d->duplicateNativeImage(); } -void QVolatileImage::setAlphaChannel(const QPixmap &alphaChannel) -{ - ensureFormat(QImage::Format_ARGB32_Premultiplied); - beginDataAccess(); - imageRef().setAlphaChannel(alphaChannel.toImage()); - endDataAccess(); - d->ensureImage(); -} - void QVolatileImage::fill(uint pixelValue) { beginDataAccess(); @@ -245,7 +236,7 @@ void QVolatileImage::copyFrom(QVolatileImage *source, const QRect &rect) } /*! - To be called from the PixmapData's paintEngine(). + To be called from the PlatformPixmap's paintEngine(). */ QPaintEngine *QVolatileImage::paintEngine() { @@ -284,7 +275,7 @@ bool QVolatileImagePaintEngine::end() void QVolatileImagePaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm) { #ifdef Q_OS_SYMBIAN - void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage); + void *nativeData = pm.handle()->toNativeType(QPlatformPixmap::VolatileImage); if (nativeData) { QVolatileImage *img = static_cast<QVolatileImage *>(nativeData); img->beginDataAccess(); @@ -301,7 +292,7 @@ void QVolatileImagePaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm) void QVolatileImagePaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) { #ifdef Q_OS_SYMBIAN - void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage); + void *nativeData = pm.handle()->toNativeType(QPlatformPixmap::VolatileImage); if (nativeData) { QVolatileImage *img = static_cast<QVolatileImage *>(nativeData); img->beginDataAccess(); diff --git a/src/gui/image/qvolatileimage_p.h b/src/gui/image/qvolatileimage_p.h index 911b61224d..91f8ce3598 100644 --- a/src/gui/image/qvolatileimage_p.h +++ b/src/gui/image/qvolatileimage_p.h @@ -87,7 +87,6 @@ public: QImage toImage() const; QImage &imageRef(); QPaintEngine *paintEngine(); - void setAlphaChannel(const QPixmap &alphaChannel); void fill(uint pixelValue); void *duplicateNativeImage() const; void copyFrom(QVolatileImage *source, const QRect &rect); |