diff options
Diffstat (limited to 'src/gui/image')
-rw-r--r-- | src/gui/image/qicon.cpp | 10 | ||||
-rw-r--r-- | src/gui/image/qiconloader.cpp | 94 | ||||
-rw-r--r-- | src/gui/image/qimage.cpp | 3 | ||||
-rw-r--r-- | src/gui/image/qpixmap.cpp | 28 | ||||
-rw-r--r-- | src/gui/image/qpixmap_mac.cpp | 5 | ||||
-rw-r--r-- | src/gui/image/qpixmap_mac_p.h | 2 | ||||
-rw-r--r-- | src/gui/image/qpixmap_raster.cpp | 28 | ||||
-rw-r--r-- | src/gui/image/qpixmap_raster_p.h | 2 | ||||
-rw-r--r-- | src/gui/image/qpixmap_s60.cpp | 47 | ||||
-rw-r--r-- | src/gui/image/qpixmap_s60_p.h | 4 | ||||
-rw-r--r-- | src/gui/image/qpixmap_x11.cpp | 5 | ||||
-rw-r--r-- | src/gui/image/qpixmap_x11_p.h | 2 | ||||
-rw-r--r-- | src/gui/image/qpixmapcache.cpp | 1 | ||||
-rw-r--r-- | src/gui/image/qpixmapdata.cpp | 13 | ||||
-rw-r--r-- | src/gui/image/qpixmapdata_p.h | 4 | ||||
-rw-r--r-- | src/gui/image/qpixmapfilter.cpp | 51 |
16 files changed, 148 insertions, 151 deletions
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index fce4508..e0779a0 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -54,6 +54,7 @@ #include "qvariant.h" #include "qcache.h" #include "qdebug.h" +#include "private/qguiplatformplugin_p.h" #ifdef Q_WS_MAC #include <private/qt_mac_p.h> @@ -961,19 +962,10 @@ QString QIcon::themeName() */ QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback) { - static QCache <QString, QIcon> iconCache; QIcon icon; -#ifdef Q_WS_X11 - if (X11->desktopEnvironment == DE_KDE) { - icon = QKde::kdeIcon(name); - if (!icon.isNull()) - return icon; - } -#endif - if (iconCache.contains(name)) { icon = *iconCache.object(name); } else { diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index adc2967..46c5431 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -43,7 +43,7 @@ #include <private/qapplication_p.h> #include <private/qicon_p.h> -#include <private/qkde_p.h> +#include <private/qguiplatformplugin_p.h> #include <QtGui/QIconEnginePlugin> #include <QtGui/QPixmapCache> @@ -68,47 +68,29 @@ 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() { - QString defaultTheme; -#ifdef Q_WS_X11 - if (X11->desktopEnvironment == DE_GNOME) - defaultTheme = QLatin1String("gnome"); - else if (X11->desktopEnvironment == DE_KDE) - defaultTheme = X11->desktopVersion >= 4 ? - QString::fromLatin1("oxygen") : - QString::fromLatin1("crystalsvg"); -#endif - return defaultTheme; -} - -static QString systemThemeName() -{ - QString result = fallbackTheme(); #ifdef Q_WS_X11 if (X11->desktopEnvironment == DE_GNOME) { -#ifndef QT_NO_STYLE_GTK - result = QGtk::getGConfString(QLatin1String("/desktop/gnome/interface/icon_theme"), - result); -#endif + return QLatin1String("gnome"); } else if (X11->desktopEnvironment == DE_KDE) { - QSettings settings(QKde::kdeHome() + - QLatin1String("/share/config/kdeglobals"), - QSettings::IniFormat); - - settings.beginGroup(QLatin1String("Icons")); - - result = settings.value(QLatin1String("Theme"), result).toString(); + return X11->desktopVersion >= 4 + ? QString::fromLatin1("oxygen") + : QString::fromLatin1("crystalsvg"); + } else { + return QLatin1String("hicolor"); } #endif - return result; + return QString(); } - QIconLoader::QIconLoader() : m_themeKey(1), m_supportsSvg(false) { - m_systemTheme = systemThemeName(); + m_systemTheme = qt_guiPlatformPlugin()->systemIconThemeName(); + if (m_systemTheme.isEmpty()) + m_systemTheme = fallbackTheme(); QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterfaceV2_iid, QLatin1String("/iconengines"), @@ -128,7 +110,9 @@ void QIconLoader::updateSystemTheme() { // Only change if this is not explicitly set by the user if (m_userTheme.isEmpty()) { - QString theme = systemThemeName(); + QString theme = qt_guiPlatformPlugin()->systemIconThemeName(); + if (theme.isEmpty()) + theme = fallbackTheme(); if (theme != m_systemTheme) { m_systemTheme = theme; invalidateKey(); @@ -152,51 +136,7 @@ void QIconLoader::setThemeSearchPath(const QStringList &searchPaths) QStringList QIconLoader::themeSearchPaths() const { if (m_iconDirs.isEmpty()) { - -#if defined(Q_WS_X11) - - QString xdgDirString = QFile::decodeName(getenv("XDG_DATA_DIRS")); - if (xdgDirString.isEmpty()) - xdgDirString = QLatin1String("/usr/local/share/:/usr/share/"); - - QStringList xdgDirs = xdgDirString.split(QLatin1Char(':')); - - for (int i = 0 ; i < xdgDirs.size() ; ++i) { - QDir dir(xdgDirs[i]); - if (dir.exists()) - m_iconDirs.append(dir.path() + - QLatin1String("/icons")); - } - - if (X11->desktopEnvironment == DE_KDE) { - - m_iconDirs << QLatin1Char(':') + - QKde::kdeHome() + - QLatin1String("/share/icons"); - QStringList kdeDirs = - QFile::decodeName(getenv("KDEDIRS")).split(QLatin1Char(':')); - - for (int i = 0 ; i< kdeDirs.count() ; ++i) { - QDir dir(QLatin1Char(':') + kdeDirs.at(i) + - QLatin1String("/share/icons")); - if (dir.exists()) - m_iconDirs.append(dir.path()); - } - } - - // Add home directory first in search path - QDir homeDir(QDir::homePath() + QLatin1String("/.icons")); - if (homeDir.exists()) - m_iconDirs.prepend(homeDir.path()); -#endif - -#if defined(Q_WS_WIN) - m_iconDirs.append(qApp->applicationDirPath() + - QLatin1String("/icons")); -#elif defined(Q_WS_MAC) - m_iconDirs.append(qApp->applicationDirPath() + - QLatin1String("/../Resources/icons")); -#endif + m_iconDirs = qt_guiPlatformPlugin()->iconThemeSearchPaths(); // Allways add resource directory as search path m_iconDirs.append(QLatin1String(":/icons")); } @@ -291,7 +231,7 @@ QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, if (!theme.isValid()) { theme = QIconTheme(themeName); if (!theme.isValid()) - theme = fallbackTheme(); + theme = QIconTheme(fallbackTheme()); themeList.insert(themeName, theme); } diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 9048387..21ab40c 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -377,6 +377,9 @@ bool QImageData::checkForAlphaPixels() const \note If you would like to load QImage objects in a static build of Qt, refer to the \l{How To Create Qt Plugins#Static Plugins}{Plugin HowTo}. + \warning Painting on a QImage with the format + QImage::Format_Indexed8 is not supported. + \tableofcontents \section1 Reading and Writing Image Files diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 558ae54..c03a364 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -361,13 +361,7 @@ QPixmap QPixmap::copy(const QRect &rect) const const QRect r = rect.isEmpty() ? QRect(0, 0, width(), height()) : rect; - QPixmapData *d; - QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem(); - if (gs) - d = gs->createPixmapData(data->pixelType()); - else - d = QGraphicsSystem::createDefaultPixmapData(data->pixelType()); - + QPixmapData *d = data->createCompatiblePixmapData(); d->copy(data.data(), r); return QPixmap(d); } @@ -947,6 +941,9 @@ bool QPixmap::doImageIO(QImageWriter *writer, int quality) const /*! Fills the pixmap with the given \a color. + The effect of this function is undefined when the pixmap is + being painted on. + \sa {QPixmap#Pixmap Transformations}{Pixmap Transformations} */ @@ -955,6 +952,13 @@ void QPixmap::fill(const QColor &color) if (isNull()) return; + // Some people are probably already calling fill while a painter is active, so to not break + // their programs, only print a warning and return when the fill operation could cause a crash. + if (paintingActive() && (color.alpha() != 255) && !hasAlphaChannel()) { + qWarning("QPixmap::fill: Cannot fill while pixmap is being painted on"); + return; + } + detach(); data->fill(color); } @@ -1663,10 +1667,10 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) identifies the contents of the QPixmap object. The x11Info() function returns information about the configuration - of the X display used to display the widget. The - x11PictureHandle() function returns the X11 Picture handle of the - pixmap for XRender support. Note that the two latter functions are - only available on x11. + of the X display used by the screen to which the pixmap currently + belongs. The x11PictureHandle() function returns the X11 Picture + handle of the pixmap for XRender support. Note that the two latter + functions are only available on x11. \endtable @@ -2084,7 +2088,7 @@ QPixmapData* QPixmap::pixmapData() const /*! \fn const QX11Info &QPixmap::x11Info() const \bold{X11 only:} Returns information about the configuration of - the X display used to display the widget. + the X display used by the screen to which the pixmap currently belongs. \warning This function is only available on X11. diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp index de532fd..afa6f83 100644 --- a/src/gui/image/qpixmap_mac.cpp +++ b/src/gui/image/qpixmap_mac.cpp @@ -166,6 +166,11 @@ QMacPixmapData::QMacPixmapData(PixelType type) { } +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)) diff --git a/src/gui/image/qpixmap_mac_p.h b/src/gui/image/qpixmap_mac_p.h index 528dd1f..a3fb95f 100644 --- a/src/gui/image/qpixmap_mac_p.h +++ b/src/gui/image/qpixmap_mac_p.h @@ -65,6 +65,8 @@ 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); diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index ad68b07..fc76dc3 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -55,6 +55,29 @@ 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); + + data->fromImage(image, Qt::AutoColor); + + return QPixmap(data); +} + +QPixmap qt_toRasterPixmap(const QPixmap &pixmap) +{ + if (pixmap.isNull()) + return QPixmap(); + + if (QPixmap(pixmap).data_ptr()->classId() == QPixmapData::RasterClass) + return pixmap; + + return qt_toRasterPixmap(pixmap.toImage()); +} + QRasterPixmapData::QRasterPixmapData(PixelType type) : QPixmapData(type, RasterClass) { @@ -64,6 +87,11 @@ QRasterPixmapData::~QRasterPixmapData() { } +QPixmapData *QRasterPixmapData::createCompatiblePixmapData() const +{ + return new QRasterPixmapData(pixelType()); +} + void QRasterPixmapData::resize(int width, int height) { QImage::Format format; diff --git a/src/gui/image/qpixmap_raster_p.h b/src/gui/image/qpixmap_raster_p.h index da0405e..1553940 100644 --- a/src/gui/image/qpixmap_raster_p.h +++ b/src/gui/image/qpixmap_raster_p.h @@ -68,6 +68,8 @@ public: QRasterPixmapData(PixelType type); ~QRasterPixmapData(); + QPixmapData *createCompatiblePixmapData() const; + void resize(int width, int height); void fromFile(const QString &filename, Qt::ImageConversionFlags flags); void fromImage(const QImage &image, Qt::ImageConversionFlags flags); diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 37b6438..9ae8d72 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -229,24 +229,15 @@ static CFbsBitmap* uncompress(CFbsBitmap* bitmap) lock.relock(); - CBitmapContext *bitmapContext = 0; CFbsBitmapDevice* bitmapDevice = 0; + CFbsBitGc *bitmapGc = 0; QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(uncompressed)); - TInt err = bitmapDevice->CreateBitmapContext(bitmapContext); - if (err != KErrNone) { - delete bitmap; - delete bitmapDevice; - bitmap = 0; - bitmapDevice = 0; - - lock.relock(); - - return bitmap; - } + QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL()); + bitmapGc->Activate(bitmapDevice); - bitmapContext->DrawBitmap(TPoint(), bitmap); + bitmapGc->DrawBitmap(TPoint(), bitmap); - delete bitmapContext; + delete bitmapGc; delete bitmapDevice; return uncompressed; @@ -355,7 +346,7 @@ QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type), symbianBitmapDataAccess(new QSymbianBitmapDataAccess), cfbsBitmap(0), bitmapDevice(0), - bitmapContext(0), + bitmapGc(0), pengine(0), bytes(0) { @@ -365,6 +356,7 @@ QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type), QS60PixmapData::~QS60PixmapData() { release(); + delete symbianBitmapDataAccess; } void QS60PixmapData::resize(int width, int height) @@ -391,6 +383,8 @@ void QS60PixmapData::resize(int width, int height) if(cfbsBitmap->SizeInPixels() != newSize) { cfbsBitmap->Resize(TSize(width, height)); + bitmapDevice->Resize(TSize(width, height)); + bitmapGc->Resized(); if(pengine) { delete pengine; pengine = 0; @@ -404,12 +398,9 @@ void QS60PixmapData::resize(int width, int height) bool QS60PixmapData::initSymbianBitmapContext() { QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(cfbsBitmap)); - TInt err = bitmapDevice->CreateBitmapContext(bitmapContext); - if (err != KErrNone) { - delete bitmapDevice; - bitmapDevice = 0; - return false; - } + QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL()); + bitmapGc->Activate(bitmapDevice); + return true; } @@ -417,7 +408,7 @@ void QS60PixmapData::release() { if (cfbsBitmap) { QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); - delete bitmapContext; + delete bitmapGc; delete bitmapDevice; delete cfbsBitmap; lock.relock(); @@ -426,7 +417,7 @@ void QS60PixmapData::release() delete pengine; image = QImage(); cfbsBitmap = 0; - bitmapContext = 0; + bitmapGc = 0; bitmapDevice = 0; pengine = 0; bytes = 0; @@ -559,13 +550,15 @@ void QS60PixmapData::copy(const QPixmapData *data, const QRect &rect) resize(rect.width(), rect.height()); cfbsBitmap->SetDisplayMode(s60Data->cfbsBitmap->DisplayMode()); - bitmapContext->BitBlt(TPoint(0, 0), s60Data->cfbsBitmap, qt_QRect2TRect(rect)); + bitmapGc->BitBlt(TPoint(0, 0), s60Data->cfbsBitmap, qt_QRect2TRect(rect)); } bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect) { - bitmapContext->CopyRect(TPoint(dx, dy), qt_QRect2TRect(rect)); - return true; + beginDataAccess(); + bool res = QRasterPixmapData::scroll(dx, dy, rect); + endDataAccess(); + return res; } int QS60PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const @@ -723,6 +716,8 @@ void QS60PixmapData::beginDataAccess() void QS60PixmapData::endDataAccess(bool readOnly) const { + Q_UNUSED(readOnly); + if(!cfbsBitmap) return; diff --git a/src/gui/image/qpixmap_s60_p.h b/src/gui/image/qpixmap_s60_p.h index 4498c05..b23961a 100644 --- a/src/gui/image/qpixmap_s60_p.h +++ b/src/gui/image/qpixmap_s60_p.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE class CFbsBitmap; class CFbsBitmapDevice; -class CBitmapContext; +class CFbsBitGc; class QSymbianBitmapDataAccess; @@ -114,7 +114,7 @@ private: CFbsBitmap *cfbsBitmap; CFbsBitmapDevice *bitmapDevice; - CBitmapContext *bitmapContext; + CFbsBitGc *bitmapGc; QPaintEngine *pengine; uchar* bytes; diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index 74543a0..ea9eff9 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -319,6 +319,11 @@ QX11PixmapData::QX11PixmapData(PixelType type) { } +QPixmapData *QX11PixmapData::createCompatiblePixmapData() const +{ + return new QX11PixmapData(pixelType()); +} + void QX11PixmapData::resize(int width, int height) { setSerialNumber(++qt_pixmap_serial); diff --git a/src/gui/image/qpixmap_x11_p.h b/src/gui/image/qpixmap_x11_p.h index e34e690..2d6672d 100644 --- a/src/gui/image/qpixmap_x11_p.h +++ b/src/gui/image/qpixmap_x11_p.h @@ -71,6 +71,8 @@ public: // 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); diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index f12d397..b0b7d72 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -221,6 +221,7 @@ QPMCache::QPMCache() } QPMCache::~QPMCache() { + clear(); free(keyArray); } diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp index 93fc2eb..1ad1f02 100644 --- a/src/gui/image/qpixmapdata.cpp +++ b/src/gui/image/qpixmapdata.cpp @@ -43,6 +43,8 @@ #include <QtCore/qbuffer.h> #include <QtGui/qbitmap.h> #include <QtGui/qimagereader.h> +#include <private/qgraphicssystem_p.h> +#include <private/qapplication_p.h> QT_BEGIN_NAMESPACE @@ -67,6 +69,17 @@ QPixmapData::~QPixmapData() { } +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) { diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h index c26fba3..2f4f201 100644 --- a/src/gui/image/qpixmapdata_p.h +++ b/src/gui/image/qpixmapdata_p.h @@ -75,9 +75,11 @@ public: enum ClassId { RasterClass, X11Class, MacClass, DirectFBClass, OpenGLClass, OpenVGClass, CustomClass = 1024 }; - QPixmapData(PixelType pixelpType, int classId); + QPixmapData(PixelType pixelType, int classId); virtual ~QPixmapData(); + virtual QPixmapData *createCompatiblePixmapData() const; + virtual void resize(int width, int height) = 0; virtual void fromImage(const QImage &image, Qt::ImageConversionFlags flags) = 0; diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index df445db..9fcf776 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -591,7 +591,7 @@ QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const // Blur the image according to the blur radius // Based on exponential blur algorithm by Jani Huhtanen // (maximum radius is set to 16) -static QImage blurred(const QImage& image, const QRect& rect, int radius) +static QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false) { int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 }; int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1]; @@ -606,47 +606,53 @@ static QImage blurred(const QImage& image, const QRect& rect, int radius) int rgba[4]; unsigned char* p; + int i1 = 0; + int i2 = 3; + + if (alphaOnly) + i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3); + for (int col = c1; col <= c2; col++) { p = result.scanLine(r1) + col * 4; - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) rgba[i] = p[i] << 4; p += bpl; for (int j = r1; j < r2; j++, p += bpl) - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; } for (int row = r1; row <= r2; row++) { p = result.scanLine(row) + c1 * 4; - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) rgba[i] = p[i] << 4; p += 4; for (int j = c1; j < c2; j++, p += 4) - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; } for (int col = c1; col <= c2; col++) { p = result.scanLine(r2) + col * 4; - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) rgba[i] = p[i] << 4; p -= bpl; for (int j = r1; j < r2; j++, p -= bpl) - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; } for (int row = r1; row <= r2; row++) { p = result.scanLine(row) + c2 * 4; - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) rgba[i] = p[i] << 4; p -= 4; for (int j = c1; j < c2; j++, p -= 4) - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; } @@ -892,11 +898,11 @@ class QPixmapDropShadowFilterPrivate : public QPixmapFilterPrivate { public: QPixmapDropShadowFilterPrivate() - : offset(8, 8), color(63, 63, 63, 180), blurFilter(new QPixmapBlurFilter) {} + : offset(8, 8), color(63, 63, 63, 180), radius(1) {} QPointF offset; QColor color; - QPixmapBlurFilter *blurFilter; + int radius; }; /*! @@ -940,8 +946,6 @@ public: QPixmapDropShadowFilter::QPixmapDropShadowFilter(QObject *parent) : QPixmapFilter(*new QPixmapDropShadowFilterPrivate, DropShadowFilter, parent) { - Q_D(QPixmapDropShadowFilter); - d->blurFilter->setRadius(1); } /*! @@ -951,8 +955,6 @@ QPixmapDropShadowFilter::QPixmapDropShadowFilter(QObject *parent) */ QPixmapDropShadowFilter::~QPixmapDropShadowFilter() { - Q_D(QPixmapDropShadowFilter); - delete d->blurFilter; } /*! @@ -967,7 +969,7 @@ QPixmapDropShadowFilter::~QPixmapDropShadowFilter() int QPixmapDropShadowFilter::blurRadius() const { Q_D(const QPixmapDropShadowFilter); - return d->blurFilter->radius(); + return d->radius; } /*! @@ -982,7 +984,7 @@ int QPixmapDropShadowFilter::blurRadius() const void QPixmapDropShadowFilter::setBlurRadius(int radius) { Q_D(QPixmapDropShadowFilter); - d->blurFilter->setRadius(radius); + d->radius = radius; } /*! @@ -1056,7 +1058,7 @@ QRectF QPixmapDropShadowFilter::boundingRectFor(const QRectF &rect) const { Q_D(const QPixmapDropShadowFilter); - const qreal delta = qreal(d->blurFilter->radius() * 2); + const qreal delta = qreal(d->radius * 2); qreal x1 = qMin(rect.left(), rect.left() + d->offset.x() - delta); qreal y1 = qMin(rect.top(), rect.top() + d->offset.y() - delta); qreal x2 = qMax(rect.right(), rect.right() + d->offset.x() + delta); @@ -1079,24 +1081,25 @@ void QPixmapDropShadowFilter::draw(QPainter *p, QPixmapDropShadowFilter *dropShadowFilter = static_cast<QPixmapDropShadowFilter*>(filter); if (dropShadowFilter) { dropShadowFilter->setColor(d->color); - dropShadowFilter->setBlurRadius(d->blurFilter->radius()); + dropShadowFilter->setBlurRadius(d->radius); dropShadowFilter->setOffset(d->offset); dropShadowFilter->draw(p, pos, px, src); return; } - QImage tmp = src.isNull() ? px.toImage() : px.copy(src.toRect()).toImage(); - QPainter tmpPainter(&tmp); + QImage tmp = src.isNull() ? px.toImage() : px.copy(src.toAlignedRect()).toImage(); + + // blur the alpha channel + tmp = blurred(tmp, tmp.rect(), d->radius, true); // blacken the image... + QPainter tmpPainter(&tmp); tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); tmpPainter.fillRect(0, 0, tmp.width(), tmp.height(), d->color); tmpPainter.end(); - const QPixmap pixTmp = QPixmap::fromImage(tmp); - // draw the blurred drop shadow... - d->blurFilter->draw(p, pos + d->offset, pixTmp); + p->drawImage(pos + d->offset, tmp); // Draw the actual pixmap... p->drawPixmap(pos, px, src); |