diff options
Diffstat (limited to 'src/gui/image')
-rw-r--r-- | src/gui/image/image.pri | 5 | ||||
-rw-r--r-- | src/gui/image/qbitmap.cpp | 8 | ||||
-rw-r--r-- | src/gui/image/qbitmap.h | 1 | ||||
-rw-r--r-- | src/gui/image/qicon.cpp | 8 | ||||
-rw-r--r-- | src/gui/image/qicon.h | 2 | ||||
-rw-r--r-- | src/gui/image/qimage.cpp | 12 | ||||
-rw-r--r-- | src/gui/image/qimage.h | 2 | ||||
-rw-r--r-- | src/gui/image/qimage_ssse3.cpp | 2 | ||||
-rw-r--r-- | src/gui/image/qnativeimage.cpp | 20 | ||||
-rw-r--r-- | src/gui/image/qpicture.cpp | 8 | ||||
-rw-r--r-- | src/gui/image/qpicture.h | 1 | ||||
-rw-r--r-- | src/gui/image/qpixmap.cpp | 13 | ||||
-rw-r--r-- | src/gui/image/qpixmap.h | 2 | ||||
-rw-r--r-- | src/gui/image/qpixmap_blitter.cpp | 311 | ||||
-rw-r--r-- | src/gui/image/qpixmap_blitter_p.h | 166 | ||||
-rw-r--r-- | src/gui/image/qpixmap_qpa.cpp | 49 | ||||
-rw-r--r-- | src/gui/image/qpixmap_s60.cpp | 3 | ||||
-rw-r--r-- | src/gui/image/qpixmap_x11_p.h | 2 | ||||
-rw-r--r-- | src/gui/image/qpixmapdata_p.h | 3 | ||||
-rw-r--r-- | src/gui/image/qpixmapdatafactory.cpp | 7 | ||||
-rw-r--r-- | src/gui/image/qpnghandler.cpp | 82 | ||||
-rw-r--r-- | src/gui/image/qtiffhandler.cpp | 1 | ||||
-rw-r--r-- | src/gui/image/qxbmhandler.cpp | 25 | ||||
-rw-r--r-- | src/gui/image/qxpmhandler.cpp | 2 |
24 files changed, 674 insertions, 61 deletions
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index f89706c..92ea397 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -23,6 +23,7 @@ HEADERS += \ image/qpictureformatplugin.h \ image/qpixmap.h \ image/qpixmap_raster_p.h \ + image/qpixmap_blitter_p.h \ image/qpixmapcache.h \ image/qpixmapcache_p.h \ image/qpixmapdata_p.h \ @@ -50,6 +51,7 @@ SOURCES += \ image/qiconengineplugin.cpp \ image/qmovie.cpp \ image/qpixmap_raster.cpp \ + image/qpixmap_blitter.cpp \ image/qnativeimage.cpp \ image/qimagepixmapcleanuphooks.cpp @@ -59,6 +61,9 @@ win32 { else:embedded { SOURCES += image/qpixmap_qws.cpp } +else:qpa { + SOURCES += image/qpixmap_qpa.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 91622f3..9d90b3f 100644 --- a/src/gui/image/qbitmap.cpp +++ b/src/gui/image/qbitmap.cpp @@ -227,6 +227,14 @@ QBitmap::~QBitmap() } /*! + \fn void QBitmap::swap(QBitmap &other) + \since 4.8 + + Swaps bitmap \a other with this bitmap. This operation is very + fast and never fails. +*/ + +/*! Returns the bitmap as a QVariant. */ QBitmap::operator QVariant() const diff --git a/src/gui/image/qbitmap.h b/src/gui/image/qbitmap.h index 1bbe1cf..93be951 100644 --- a/src/gui/image/qbitmap.h +++ b/src/gui/image/qbitmap.h @@ -63,6 +63,7 @@ public: ~QBitmap(); QBitmap &operator=(const QPixmap &); + inline void swap(QBitmap &other) { QPixmap::swap(other); } // prevent QBitmap<->QPixmap swaps operator QVariant() const; inline void clear() { fill(Qt::color0); } diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index a2f429a..e54bb5f 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -613,6 +613,14 @@ QIcon &QIcon::operator=(const QIcon &other) } /*! + \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 diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h index fd591e6..5091d03 100644 --- a/src/gui/image/qicon.h +++ b/src/gui/image/qicon.h @@ -75,6 +75,8 @@ public: 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; diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 300e04b..d86021cb9 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1329,6 +1329,14 @@ QImage &QImage::operator=(const QImage &image) } /*! + \fn void QImage::swap(QImage &other) + \since 4.8 + + Swaps image \a other with this image. This operation is very + fast and never fails. +*/ + +/*! \internal */ int QImage::devType() const @@ -6689,6 +6697,10 @@ bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFla if (format == newFormat) return true; + // No in-place conversion if we have to detach + if (ref > 1) + return false; + const InPlace_Image_Converter *const converterPtr = &inplace_converter_map[format][newFormat]; InPlace_Image_Converter converter = *converterPtr; if (converter) diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 4fe7da2..c6a947e 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -144,6 +144,7 @@ public: inline QImage &operator=(QImage &&other) { qSwap(d, other.d); return *this; } #endif + inline void swap(QImage &other) { qSwap(d, other.d); } bool isNull() const; @@ -334,6 +335,7 @@ private: QImageData *d; friend class QRasterPixmapData; + friend class QBlittablePixmapData; friend class QPixmapCacheEntry; friend Q_GUI_EXPORT qint64 qt_image_id(const QImage &image); friend const QVector<QRgb> *qt_image_colortable(const QImage &image); diff --git a/src/gui/image/qimage_ssse3.cpp b/src/gui/image/qimage_ssse3.cpp index 9aed011..836d7b0 100644 --- a/src/gui/image/qimage_ssse3.cpp +++ b/src/gui/image/qimage_ssse3.cpp @@ -54,7 +54,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, con { quint32 *const end = dst + len; - // Prologue, align dst to 16 bytes. The alignement is done on dst because it has 4 store() + // Prologue, align dst to 16 bytes. The alignment is done on dst because it has 4 store() // for each 3 load() of src. const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3; const int prologLength = qMin(len, offsetToAlignOn16Bytes); diff --git a/src/gui/image/qnativeimage.cpp b/src/gui/image/qnativeimage.cpp index 8446387..0f7872e 100644 --- a/src/gui/image/qnativeimage.cpp +++ b/src/gui/image/qnativeimage.cpp @@ -45,6 +45,9 @@ #include "private/qpaintengine_raster_p.h" +#include "private/qapplication_p.h" +#include "private/qgraphicssystem_p.h" + #if defined(Q_WS_X11) && !defined(QT_NO_MITSHM) #include <qx11info_x11.h> #include <sys/ipc.h> @@ -241,8 +244,19 @@ QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /* : image(width, height, format) { - uint cgflags = kCGImageAlphaNoneSkipFirst; + switch (format) { + case QImage::Format_ARGB32: + cgflags = kCGImageAlphaFirst; + break; + case QImage::Format_ARGB32_Premultiplied: + case QImage::Format_ARGB8565_Premultiplied: + case QImage::Format_ARGB6666_Premultiplied: + case QImage::Format_ARGB8555_Premultiplied: + case QImage::Format_ARGB4444_Premultiplied: + cgflags = kCGImageAlphaPremultipliedFirst; + break; + } #ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version cgflags |= kCGBitmapByteOrder32Host; @@ -284,7 +298,11 @@ QNativeImage::~QNativeImage() QImage::Format QNativeImage::systemFormat() { +#ifdef Q_WS_QPA + return QApplicationPrivate::platformIntegration()->screens().at(0)->format(); +#else return QImage::Format_RGB32; +#endif } #endif // platforms diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 48d2de3..fc81d23 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -1030,6 +1030,14 @@ QPicture& QPicture::operator=(const QPicture &p) } /*! + \fn void QPicture::swap(QPicture &other) + \since 4.8 + + Swaps picture \a other with this picture. This operation is very + fast and never fails. +*/ + +/*! \internal Constructs a QPicturePrivate diff --git a/src/gui/image/qpicture.h b/src/gui/image/qpicture.h index 49b0fd6..d24f23a 100644 --- a/src/gui/image/qpicture.h +++ b/src/gui/image/qpicture.h @@ -85,6 +85,7 @@ public: inline QPicture &operator=(QPicture &&other) { qSwap(d_ptr, other.d_ptr); return *this; } #endif + inline void swap(QPicture &other) { d_ptr.swap(other.d_ptr); } void detach(); bool isDetached() const; diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index ad07fbd..9fd10ae 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -440,6 +440,14 @@ QPixmap &QPixmap::operator=(const QPixmap &pixmap) } /*! + \fn void QPixmap::swap(QPixmap &other) + \since 4.8 + + Swaps pixmap \a other with this pixmap. This operation is very + fast and never fails. +*/ + +/*! Returns the pixmap as a QVariant. */ QPixmap::operator QVariant() const @@ -1102,6 +1110,9 @@ QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &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; @@ -1964,6 +1975,8 @@ int QPixmap::defaultDepth() 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 } diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index e9f9365..15fe5fa 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -87,6 +87,8 @@ public: inline QPixmap &operator=(QPixmap &&other) { qSwap(data, other.data); return *this; } #endif + inline void swap(QPixmap &other) { qSwap(data, other.data); } + operator QVariant() const; bool isNull() const; // ### Qt 5: make inline diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp new file mode 100644 index 0000000..e8a7b89 --- /dev/null +++ b/src/gui/image/qpixmap_blitter.cpp @@ -0,0 +1,311 @@ +/**************************************************************************** +** +** Copyright (C) 2010 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpixmap_blitter_p.h" + +#include <qpainter.h> +#include <qimage.h> + +#include <private/qapplication_p.h> +#include <private/qgraphicssystem_p.h> +#include <private/qblittable_p.h> + +#include <private/qdrawhelper_p.h> + +#ifndef QT_NO_BLITTABLE +QT_BEGIN_NAMESPACE + +static int global_ser_no = 0; + +QBlittablePixmapData::QBlittablePixmapData() + : QPixmapData(QPixmapData::PixmapType,BlitterClass), m_engine(0), m_blittable(0) +#ifdef QT_BLITTER_RASTEROVERLAY + ,m_rasterOverlay(0), m_unmergedCopy(0) +#endif //QT_BLITTER_RASTEROVERLAY +{ + setSerialNumber(++global_ser_no); +} + +QBlittablePixmapData::~QBlittablePixmapData() +{ + delete m_blittable; + delete m_engine; +#ifdef QT_BLITTER_RASTEROVERLAY + delete m_rasterOverlay; + delete m_unmergedCopy; +#endif //QT_BLITTER_RASTEROVERLAY +} + +QBlittable *QBlittablePixmapData::blittable() const +{ + if (!m_blittable) { + QBlittablePixmapData *that = const_cast<QBlittablePixmapData *>(this); + that->m_blittable = this->createBlittable(QSize(w,h)); + } + + return m_blittable; +} + +void QBlittablePixmapData::setBlittable(QBlittable *blittable) +{ + resize(blittable->size().width(),blittable->size().height()); + m_blittable = blittable; +} + +void QBlittablePixmapData::resize(int width, int height) +{ + + delete m_blittable; + m_blittable = 0; + delete m_engine; + m_engine = 0; +#ifdef Q_WS_QPA + d = QApplicationPrivate::platformIntegration()->screens().at(0)->depth(); +#endif + w = width; + h = height; + is_null = (w <= 0 || h <= 0); +} +Q_GUI_EXPORT extern int qt_defaultDpiX(); +Q_GUI_EXPORT extern int qt_defaultDpiY(); + +int QBlittablePixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const +{ + switch (metric) { + case QPaintDevice::PdmWidth: + return w; + case QPaintDevice::PdmHeight: + return h; + case QPaintDevice::PdmWidthMM: + return qRound(w * 25.4 / qt_defaultDpiX()); + case QPaintDevice::PdmHeightMM: + return qRound(h * 25.4 / qt_defaultDpiY()); + case QPaintDevice::PdmDepth: + return 32; + case QPaintDevice::PdmDpiX: // fall-through + case QPaintDevice::PdmPhysicalDpiX: + return qt_defaultDpiX(); + case QPaintDevice::PdmDpiY: // fall-through + case QPaintDevice::PdmPhysicalDpiY: + return qt_defaultDpiY(); + default: + qWarning("QRasterPixmapData::metric(): Unhandled metric type %d", metric); + break; + } + + return 0; +} + +void QBlittablePixmapData::fill(const QColor &color) +{ + //jlind: todo: change when blittables can support non opaque fillRects + if (color.alpha() == 255 && blittable()->capabilities() & QBlittable::SolidRectCapability) { + blittable()->unlock(); + blittable()->fillRect(QRectF(0,0,w,h),color); + }else { + uint pixel; + switch (blittable()->lock()->format()) { + case QImage::Format_ARGB32_Premultiplied: + pixel = PREMUL(color.rgba()); + break; + case QImage::Format_ARGB8565_Premultiplied: + pixel = qargb8565(color.rgba()).rawValue(); + break; + case QImage::Format_ARGB8555_Premultiplied: + pixel = qargb8555(color.rgba()).rawValue(); + break; + case QImage::Format_ARGB6666_Premultiplied: + pixel = qargb6666(color.rgba()).rawValue(); + break; + case QImage::Format_ARGB4444_Premultiplied: + pixel = qargb4444(color.rgba()).rawValue(); + break; + default: + pixel = color.rgba(); + break; + } + //so premultiplied formats are supported and ARGB32 and RGB32 + blittable()->lock()->fill(pixel); + } + +} + +QImage *QBlittablePixmapData::buffer() +{ + return blittable()->lock(); +} + +QImage QBlittablePixmapData::toImage() const +{ + return blittable()->lock()->copy(); +} + +bool QBlittablePixmapData::hasAlphaChannel() const +{ + return blittable()->lock()->hasAlphaChannel(); +} + +void QBlittablePixmapData::fromImage(const QImage &image, + Qt::ImageConversionFlags flags) +{ + resize(image.width(),image.height()); + markRasterOverlay(QRect(0,0,w,h)); + QImage *thisImg = buffer(); + + QImage correctFormatPic = image; + if (correctFormatPic.format() != thisImg->format()) + correctFormatPic = correctFormatPic.convertToFormat(thisImg->format(), flags); + + uchar *mem = thisImg->bits(); + const uchar *bits = correctFormatPic.bits(); + int bytesCopied = 0; + while (bytesCopied < correctFormatPic.byteCount()) { + memcpy(mem,bits,correctFormatPic.bytesPerLine()); + mem += thisImg->bytesPerLine(); + bits += correctFormatPic.bytesPerLine(); + bytesCopied+=correctFormatPic.bytesPerLine(); + } +} + +QPaintEngine *QBlittablePixmapData::paintEngine() const +{ + if (!m_engine) { + QBlittablePixmapData *that = const_cast<QBlittablePixmapData *>(this); + that->m_engine = new QBlitterPaintEngine(that); + } + return m_engine; +} + +#ifdef QT_BLITTER_RASTEROVERLAY + +static bool showRasterOverlay = !qgetenv("QT_BLITTER_RASTEROVERLAY").isEmpty(); + +void QBlittablePixmapData::mergeOverlay() +{ + if (m_unmergedCopy || !showRasterOverlay) + return; + m_unmergedCopy = new QImage(buffer()->copy()); + QPainter p(buffer()); + p.setCompositionMode(QPainter::CompositionMode_SourceOver); + p.drawImage(0,0,*overlay()); + p.end(); +} + +void QBlittablePixmapData::unmergeOverlay() +{ + if (!m_unmergedCopy || !showRasterOverlay) + return; + QPainter p(buffer()); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.drawImage(0,0,*m_unmergedCopy); + p.end(); + + delete m_unmergedCopy; + m_unmergedCopy = 0; +} + +QImage *QBlittablePixmapData::overlay() +{ + if (!m_rasterOverlay|| + m_rasterOverlay->size() != QSize(w,h)){ + m_rasterOverlay = new QImage(w,h,QImage::Format_ARGB32_Premultiplied); + m_rasterOverlay->fill(0x00000000); + uint color = (qrand() % 11)+7; + m_overlayColor = QColor(Qt::GlobalColor(color)); + m_overlayColor.setAlpha(0x88); + + } + return m_rasterOverlay; +} + +void QBlittablePixmapData::markRasterOverlayImpl(const QRectF &rect) +{ + if (!showRasterOverlay) + return; + QRectF transformationRect = clipAndTransformRect(rect); + if(!transformationRect.isEmpty()) { + QPainter p(overlay()); + p.setBrush(m_overlayColor); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.fillRect(transformationRect,QBrush(m_overlayColor)); + } +} + +void QBlittablePixmapData::unmarkRasterOverlayImpl(const QRectF &rect) +{ + if (!showRasterOverlay) + return; + QRectF transformationRect = clipAndTransformRect(rect); + if (!transformationRect.isEmpty()) { + QPainter p(overlay()); + QColor color(0x00,0x00,0x00,0x00); + p.setBrush(color); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.fillRect(transformationRect,QBrush(color)); + } +} + +QRectF QBlittablePixmapData::clipAndTransformRect(const QRectF &rect) const +{ + QRectF transformationRect = rect; + paintEngine(); + if (m_engine->state()) { + transformationRect = m_engine->state()->matrix.mapRect(rect); + const QClipData *clipData = m_engine->clip(); + if (clipData) { + if (clipData->hasRectClip) { + transformationRect &= clipData->clipRect; + } else if (clipData->hasRegionClip) { + const QVector<QRect> rects = clipData->clipRegion.rects(); + for (int i = 0; i < rects.size(); i++) { + transformationRect &= rects.at(i); + } + } + } + } + return transformationRect; +} + +#endif //QT_BLITTER_RASTEROVERLAY + +QT_END_NAMESPACE + +#endif //QT_NO_BLITTABLE diff --git a/src/gui/image/qpixmap_blitter_p.h b/src/gui/image/qpixmap_blitter_p.h new file mode 100644 index 0000000..55b5618 --- /dev/null +++ b/src/gui/image/qpixmap_blitter_p.h @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2010 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPIXMAP_BLITTER_P_H +#define QPIXMAP_BLITTER_P_H + +#include <private/qpixmapdata_p.h> +#include <private/qpaintengine_blitter_p.h> + +#ifndef QT_NO_BLITTABLE +QT_BEGIN_NAMESPACE + +class Q_GUI_EXPORT QBlittablePixmapData : public QPixmapData +{ +// Q_DECLARE_PRIVATE(QBlittablePixmapData); +public: + QBlittablePixmapData(); + ~QBlittablePixmapData(); + + virtual QBlittable *createBlittable(const QSize &size) const = 0; + QBlittable *blittable() const; + void setBlittable(QBlittable *blittable); + + void resize(int width, int height); + int metric(QPaintDevice::PaintDeviceMetric metric) const; + void fill(const QColor &color); + QImage *buffer(); + QImage toImage() const; + bool hasAlphaChannel() const; + void fromImage(const QImage &image, Qt::ImageConversionFlags flags); + + QPaintEngine *paintEngine() const; + + void markRasterOverlay(const QRectF &); + void markRasterOverlay(const QPointF &, const QTextItem &); + void markRasterOverlay(const QVectorPath &); + void markRasterOverlay(const QRect *rects, int rectCount); + void markRasterOverlay(const QRectF *rects, int rectCount); + void unmarkRasterOverlay(const QRectF &); + +#ifdef QT_BLITTER_RASTEROVERLAY + void mergeOverlay(); + void unmergeOverlay(); + QImage *overlay(); + +#endif //QT_BLITTER_RASTEROVERLAY +protected: + QBlitterPaintEngine *m_engine; + QBlittable *m_blittable; + +#ifdef QT_BLITTER_RASTEROVERLAY + QImage *m_rasterOverlay; + QImage *m_unmergedCopy; + QColor m_overlayColor; + + void markRasterOverlayImpl(const QRectF &); + void unmarkRasterOverlayImpl(const QRectF &); + QRectF clipAndTransformRect(const QRectF &) const; +#endif //QT_BLITTER_RASTEROVERLAY + +}; + +inline void QBlittablePixmapData::markRasterOverlay(const QRectF &rect) +{ +#ifdef QT_BLITTER_RASTEROVERLAY + markRasterOverlayImpl(rect); +#else + Q_UNUSED(rect) +#endif +} + +inline void QBlittablePixmapData::markRasterOverlay(const QVectorPath &path) +{ +#ifdef QT_BLITTER_RASTEROVERLAY + markRasterOverlayImpl(path.convertToPainterPath().boundingRect()); +#else + Q_UNUSED(path) +#endif +} + +inline void QBlittablePixmapData::markRasterOverlay(const QPointF &pos, const QTextItem &ti) +{ +#ifdef QT_BLITTER_RASTEROVERLAY + QFontMetricsF fm(ti.font()); + QRectF rect = fm.tightBoundingRect(ti.text()); + rect.moveBottomLeft(pos); + markRasterOverlay(rect); +#else + Q_UNUSED(pos) + Q_UNUSED(ti) +#endif +} + +inline void QBlittablePixmapData::markRasterOverlay(const QRect *rects, int rectCount) +{ +#ifdef QT_BLITTER_RASTEROVERLAY + for (int i = 0; i < rectCount; i++) { + markRasterOverlay(rects[i]); + } +#else + Q_UNUSED(rects) + Q_UNUSED(rectCount) +#endif +} +inline void QBlittablePixmapData::markRasterOverlay(const QRectF *rects, int rectCount) +{ +#ifdef QT_BLITTER_RASTEROVERLAY + for (int i = 0; i < rectCount; i++) { + markRasterOverlay(rects[i]); + } +#else + Q_UNUSED(rects) + Q_UNUSED(rectCount) +#endif +} + +inline void QBlittablePixmapData::unmarkRasterOverlay(const QRectF &rect) +{ +#ifdef QT_BLITTER_RASTEROVERLAY + unmarkRasterOverlayImpl(rect); +#else + Q_UNUSED(rect) +#endif +} + +QT_END_NAMESPACE +#endif // QT_NO_BLITTABLE +#endif // QPIXMAP_BLITTER_P_H diff --git a/src/gui/image/qpixmap_qpa.cpp b/src/gui/image/qpixmap_qpa.cpp new file mode 100644 index 0000000..61be216 --- /dev/null +++ b/src/gui/image/qpixmap_qpa.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2009 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qpixmap.h> +#include <private/qgraphicssystem_p.h> +#include <private/qapplication_p.h> + +QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h) +{ + return QApplicationPrivate::platformIntegration()->grabWindow(window, x, y, w, h); +} diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 47249d9..b7c8acb 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -968,11 +968,12 @@ void QS60PixmapData::fromNativeType(void* pixmap, NativeType nativeType) 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, format); + QImage img = QImage(bytes, size.iWidth, size.iHeight, bytesPerLine, format); img = img.copy(); da.endDataAccess(sourceBitmap); diff --git a/src/gui/image/qpixmap_x11_p.h b/src/gui/image/qpixmap_x11_p.h index f171281..7eab64c 100644 --- a/src/gui/image/qpixmap_x11_p.h +++ b/src/gui/image/qpixmap_x11_p.h @@ -115,7 +115,7 @@ private: friend class QEglContext; // Needs gl_surface friend class QGLContext; // Needs gl_surface friend class QX11GLPixmapData; // Needs gl_surface - friend class QMeeGoGraphicsSystem; // Needs gl_surface and flags + friend class QMeeGoLivePixmapData; // Needs gl_surface and flags friend bool qt_createEGLSurfaceForPixmap(QPixmapData*, bool); // Needs gl_surface void release(); diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h index ec62b0b..f69eb3d 100644 --- a/src/gui/image/qpixmapdata_p.h +++ b/src/gui/image/qpixmapdata_p.h @@ -75,7 +75,8 @@ public: }; #endif enum ClassId { RasterClass, X11Class, MacClass, DirectFBClass, - OpenGLClass, OpenVGClass, RuntimeClass, CustomClass = 1024 }; + OpenGLClass, OpenVGClass, RuntimeClass, BlitterClass, + CustomClass = 1024 }; QPixmapData(PixelType pixelType, int classId); virtual ~QPixmapData(); diff --git a/src/gui/image/qpixmapdatafactory.cpp b/src/gui/image/qpixmapdatafactory.cpp index 7498a7c..50dad38 100644 --- a/src/gui/image/qpixmapdatafactory.cpp +++ b/src/gui/image/qpixmapdatafactory.cpp @@ -53,6 +53,9 @@ #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 @@ -82,8 +85,10 @@ QPixmapData* QSimplePixmapDataFactory::create(QPixmapData::PixelType type) 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); + return new QS60PixmapData(type); #else #error QSimplePixmapDataFactory::create() not implemented #endif diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 935aba0..ea62cf8 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -331,6 +331,7 @@ public: float gamma; int quality; QString description; + QStringList readTexts; png_struct *png_ptr; png_info *info_ptr; @@ -389,25 +390,20 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngHeader() while (num_text--) { QString key, value; -#if defined(PNG_iTXt_SUPPORTED) && !defined(QT_NO_TEXTCODEC) - if (text_ptr->lang) { - QTextCodec *codec = QTextCodec::codecForName(text_ptr->lang); - if (codec) { - key = codec->toUnicode(text_ptr->lang_key); - value = codec->toUnicode(QByteArray(text_ptr->text, text_ptr->itxt_length)); - } else { - key = QString::fromLatin1(text_ptr->key); - value = QString::fromLatin1(QByteArray(text_ptr->text, int(text_ptr->text_length))); - } + key = QString::fromLatin1(text_ptr->key); +#if defined(PNG_iTXt_SUPPORTED) + if (text_ptr->itxt_length) { + value = QString::fromUtf8(text_ptr->text, int(text_ptr->itxt_length)); } else #endif { - key = QString::fromLatin1(text_ptr->key); value = QString::fromLatin1(QByteArray(text_ptr->text, int(text_ptr->text_length))); } if (!description.isEmpty()) description += QLatin1String("\n\n"); description += key + QLatin1String(": ") + value.simplified(); + readTexts.append(key); + readTexts.append(value); text_ptr++; } #endif @@ -485,25 +481,8 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngImage(QImage *outImage) outImage->setDotsPerMeterX(png_get_x_pixels_per_meter(png_ptr,info_ptr)); outImage->setDotsPerMeterY(png_get_y_pixels_per_meter(png_ptr,info_ptr)); -#ifndef QT_NO_IMAGE_TEXT - png_textp text_ptr; - int num_text=0; - png_get_text(png_ptr,info_ptr,&text_ptr,&num_text); - while (num_text--) { - outImage->setText(text_ptr->key,0,QString::fromAscii(text_ptr->text)); - text_ptr++; - } - - foreach (const QString &pair, description.split(QLatin1String("\n\n"))) { - int index = pair.indexOf(QLatin1Char(':')); - if (index >= 0 && pair.indexOf(QLatin1Char(' ')) < index) { - outImage->setText(QLatin1String("Description"), pair.simplified()); - } else { - QString key = pair.left(index); - outImage->setText(key, pair.mid(index + 2).simplified()); - } - } -#endif + for (int i = 0; i < readTexts.size()-1; i+=2) + outImage->setText(readTexts.at(i), readTexts.at(i+1)); png_read_end(png_ptr, end_info); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); @@ -634,29 +613,40 @@ static void set_text(const QImage &image, png_structp png_ptr, png_infop info_pt return; png_textp text_ptr = new png_text[text.size()]; + qMemSet(text_ptr, 0, text.size() * sizeof(png_text)); QMap<QString, QString>::ConstIterator it = text.constBegin(); int i = 0; while (it != text.constEnd()) { - QString t = it.value(); - if (t.length() < 40) - text_ptr[i].compression = PNG_TEXT_COMPRESSION_NONE; - else - text_ptr[i].compression = PNG_TEXT_COMPRESSION_zTXt; text_ptr[i].key = qstrdup(it.key().left(79).toLatin1().constData()); + bool noCompress = (it.value().length() < 40); -#ifndef PNG_iTXt_SUPPORTED - QByteArray value = it.value().toLatin1(); - text_ptr[i].text = qstrdup(value.constData()); - text_ptr[i].text_length = value.size(); -#else - QByteArray value = it.value().toUtf8(); - text_ptr[i].text = qstrdup(value.constData()); - text_ptr[i].text_length = 0; - text_ptr[i].itxt_length = value.size(); - text_ptr[i].lang = const_cast<char*>("UTF-8"); - text_ptr[i].lang_key = qstrdup(it.key().toUtf8().constData()); +#ifdef PNG_iTXt_SUPPORTED + bool needsItxt = false; + foreach(const QChar c, it.value()) { + uchar ch = c.cell(); + if (c.row() || (ch < 0x20 && ch != '\n') || (ch > 0x7e && ch < 0xa0)) { + needsItxt = true; + break; + } + } + + if (needsItxt) { + text_ptr[i].compression = noCompress ? PNG_ITXT_COMPRESSION_NONE : PNG_ITXT_COMPRESSION_zTXt; + QByteArray value = it.value().toUtf8(); + text_ptr[i].text = qstrdup(value.constData()); + text_ptr[i].itxt_length = value.size(); + text_ptr[i].lang = const_cast<char*>("UTF-8"); + text_ptr[i].lang_key = qstrdup(it.key().toUtf8().constData()); + } + else #endif + { + text_ptr[i].compression = noCompress ? PNG_TEXT_COMPRESSION_NONE : PNG_TEXT_COMPRESSION_zTXt; + QByteArray value = it.value().toLatin1(); + text_ptr[i].text = qstrdup(value.constData()); + text_ptr[i].text_length = value.size(); + } ++i; ++it; } diff --git a/src/gui/image/qtiffhandler.cpp b/src/gui/image/qtiffhandler.cpp index 2e8b998..dd2bd10 100644 --- a/src/gui/image/qtiffhandler.cpp +++ b/src/gui/image/qtiffhandler.cpp @@ -611,6 +611,7 @@ QVariant QTiffHandler::option(ImageOption option) const TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height); imageSize = QSize(width, height); + TIFFClose(tiff); } device()->seek(pos); if (imageSize.isValid()) diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp index 0dd4e99..f9c2e0c 100644 --- a/src/gui/image/qxbmhandler.cpp +++ b/src/gui/image/qxbmhandler.cpp @@ -66,27 +66,36 @@ static inline int hex2byte(register char *p) static bool read_xbm_header(QIODevice *device, int& w, int& h) { const int buflen = 300; + const int maxlen = 4096; char buf[buflen + 1]; QRegExp r1(QLatin1String("^#define[ \t]+[a-zA-Z0-9._]+[ \t]+")); QRegExp r2(QLatin1String("[0-9]+")); qint64 readBytes = 0; + qint64 totalReadBytes = 0; - // "#define .._width <num>" - readBytes = device->readLine(buf, buflen); - if (readBytes <= 0) - return false; - buf[readBytes - 1] = '\0'; + buf[0] = '\0'; // skip initial comment, if any - while (buf[0] != '#' && (readBytes = device->readLine( buf, buflen )) > 0) {} + while (buf[0] != '#') { + readBytes = device->readLine(buf, buflen); + + // if readBytes >= buflen, it's very probably not a C file + if (readBytes <= 0 || readBytes >= buflen -1) + return false; + + // limit xbm headers to the first 4k in the file to prevent + // excessive reads on non-xbm files + totalReadBytes += readBytes; + if (totalReadBytes >= maxlen) + return false; + } - if (readBytes <= 0) - return false; buf[readBytes - 1] = '\0'; QString sbuf; sbuf = QString::fromLatin1(buf); + // "#define .._width <num>" if (r1.indexIn(sbuf) == 0 && r2.indexIn(sbuf, r1.matchedLength()) == r1.matchedLength()) w = QByteArray(&buf[r1.matchedLength()]).trimmed().toInt(); diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp index b97afd3..453100c 100644 --- a/src/gui/image/qxpmhandler.cpp +++ b/src/gui/image/qxpmhandler.cpp @@ -766,7 +766,7 @@ static bool qt_get_named_xpm_rgb(const char *name_no_space, QRgb *rgb) { XPMRGBData x; x.name = name_no_space; - // Funtion bsearch() is supposed to be + // Function bsearch() is supposed to be // void *bsearch(const void *key, const void *base, ... // So why (char*)? Are there broken bsearch() declarations out there? XPMRGBData *r = (XPMRGBData *)bsearch((char *)&x, (char *)xpmRgbTbl, xpmRgbTblSize, |