diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-07-01 10:03:53 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-07-01 16:25:19 +0200 |
commit | a09a8d509a69ed16d8afbe15296b8332cacd6c66 (patch) | |
tree | 28645b437fd0390d903f753a44ba79626eecb8ac /src/gui | |
parent | 4b28152da64f7f23a1bbb810d8cdb7626a5f0b8e (diff) | |
parent | 83f06da1c6bffff61af78cbe75a0691d53742b53 (diff) |
Merge remote-tracking branch 'origin/5.3' into dev
Conflicts:
mkspecs/qnx-x86-qcc/qplatformdefs.h
src/corelib/global/qglobal.h
src/network/socket/qnativesocketengine_winrt.cpp
src/plugins/platforms/android/androidjniaccessibility.cpp
src/plugins/platforms/windows/qwindowswindow.cpp
Manually adjusted:
mkspecs/qnx-armle-v7-qcc/qplatformdefs.h
to include 9ce697f2d54be6d94381c72af28dda79cbc027d4
Thanks goes to Sergio for the qnx mkspecs adjustments.
Change-Id: I53b1fd6bc5bc884e5ee2c2b84975f58171a1cb8e
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/accessible/qaccessible.cpp | 4 | ||||
-rw-r--r-- | src/gui/animation/qguivariantanimation.cpp | 2 | ||||
-rw-r--r-- | src/gui/image/qgifhandler.cpp | 2 | ||||
-rw-r--r-- | src/gui/image/qicon.cpp | 119 | ||||
-rw-r--r-- | src/gui/image/qicon_p.h | 10 | ||||
-rw-r--r-- | src/gui/image/qimage.cpp | 274 | ||||
-rw-r--r-- | src/gui/image/qpixmap.cpp | 1 | ||||
-rw-r--r-- | src/gui/image/qpixmap_raster.cpp | 6 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 10 | ||||
-rw-r--r-- | src/gui/kernel/qplatformclipboard.cpp | 3 | ||||
-rw-r--r-- | src/gui/opengl/qopenglframebufferobject.cpp | 11 | ||||
-rw-r--r-- | src/gui/opengl/qopenglframebufferobject_p.h | 1 | ||||
-rw-r--r-- | src/gui/opengl/qopenglfunctions.cpp | 78 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 67 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qpaintengineex.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qfontengine.cpp | 27 | ||||
-rw-r--r-- | src/gui/text/qfontmetrics.cpp | 6 |
18 files changed, 326 insertions, 301 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index c715c5c7e0..3d1807ec05 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -1713,10 +1713,6 @@ Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface) /*! \internal */ QDebug operator<<(QDebug d, const QAccessibleEvent &ev) { - if (!&ev) { - d << "QAccessibleEvent(null)"; - return d; - } d.nospace() << "QAccessibleEvent("; if (ev.object()) { d.nospace() << "object=" << hex << ev.object() << dec; diff --git a/src/gui/animation/qguivariantanimation.cpp b/src/gui/animation/qguivariantanimation.cpp index 34abbca282..2cd31696ba 100644 --- a/src/gui/animation/qguivariantanimation.cpp +++ b/src/gui/animation/qguivariantanimation.cpp @@ -64,7 +64,7 @@ template<> Q_INLINE_TEMPLATE QQuaternion _q_interpolate(const QQuaternion &f,con return QQuaternion::slerp(f, t, progress); } -static void qRegisterGuiGetInterpolator() +void qRegisterGuiGetInterpolator() { qRegisterAnimationInterpolator<QColor>(_q_interpolateVariant<QColor>); qRegisterAnimationInterpolator<QVector2D>(_q_interpolateVariant<QVector2D>); diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp index 19b838240f..91588edd50 100644 --- a/src/gui/image/qgifhandler.cpp +++ b/src/gui/image/qgifhandler.cpp @@ -674,7 +674,7 @@ void QGIFFormat::scan(QIODevice *device, QVector<QSize> *imageSizes, int *loopCo return; qint64 oldPos = device->pos(); - if (!device->seek(0)) + if (device->isSequential() || !device->seek(0)) return; int colorCount = 0; diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 0a4b50bbea..8172ecbb48 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -363,44 +363,93 @@ void QPixmapIconEngine::addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon } } -void QPixmapIconEngine::addFile(const QString &fileName, const QSize &_size, QIcon::Mode mode, QIcon::State state) +// Read out original image depth as set by ICOReader +static inline int origIcoDepth(const QImage &image) { - if (!fileName.isEmpty()) { - QString abs = fileName; - if (fileName.at(0) != QLatin1Char(':')) - abs = QFileInfo(fileName).absoluteFilePath(); - QImageReader reader(abs); - - do { - QSize size = _size; - QPixmap pixmap; - - 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.convertFromImage(reader.read()); - size = pixmap.size(); - } - if (pe->size == QSize() && pe->pixmap.isNull()) { - pe->pixmap = QPixmap(pe->fileName); - // Reset the devicePixelRatio. The pixmap may be loaded from a @2x file, - // but be used as a 1x pixmap by QIcon. - pe->pixmap.setDevicePixelRatio(1.0); - pe->size = pe->pixmap.size(); - } - if (pe->size == size) { - pe->pixmap = pixmap; - pe->fileName = abs; - return; - } - } + const QString s = image.text(QStringLiteral("_q_icoOrigDepth")); + return s.isEmpty() ? 32 : s.toInt(); +} + +static inline int findBySize(const QList<QImage> &images, const QSize &size) +{ + for (int i = 0; i < images.size(); ++i) { + if (images.at(i).size() == size) + return i; + } + return -1; +} + +// Convenience class providing a bool read() function. +namespace { +class ImageReader +{ +public: + ImageReader(const QString &fileName) : m_reader(fileName), m_atEnd(false) {} + + QByteArray format() const { return m_reader.format(); } + + bool read(QImage *image) + { + if (m_atEnd) + return false; + *image = m_reader.read(); + if (!image->size().isValid()) { + m_atEnd = true; + return false; + } + m_atEnd = !m_reader.jumpToNextImage(); + return true; + } + +private: + QImageReader m_reader; + bool m_atEnd; +}; +} // namespace + +void QPixmapIconEngine::addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state) +{ + if (fileName.isEmpty()) + return; + const QString abs = fileName.startsWith(QLatin1Char(':')) ? fileName : QFileInfo(fileName).absoluteFilePath(); + const bool ignoreSize = !size.isValid(); + ImageReader imageReader(abs); + const QByteArray format = imageReader.format(); + if (format.isEmpty()) // Device failed to open or unsupported format. + return; + QImage image; + if (format != "ico") { + if (ignoreSize) { // No size specified: Add all images. + while (imageReader.read(&image)) + pixmaps += QPixmapIconEngineEntry(abs, image, mode, state); + } else { + // Try to match size. If that fails, add a placeholder with the filename and empty pixmap for the size. + while (imageReader.read(&image) && image.size() != size) {} + pixmaps += image.size() == size ? + QPixmapIconEngineEntry(abs, image, mode, state) : QPixmapIconEngineEntry(abs, size, mode, state); + } + return; + } + // Special case for reading Windows ".ico" files. Historically (QTBUG-39287), + // these files may contain low-resolution images. As this information is lost, + // ICOReader sets the original format as an image text key value. Read all matching + // images into a list trying to find the highest quality per size. + QList<QImage> icoImages; + while (imageReader.read(&image)) { + if (ignoreSize || image.size() == size) { + const int position = findBySize(icoImages, image.size()); + if (position >= 0) { // Higher quality available? -> replace. + if (origIcoDepth(image) > origIcoDepth(icoImages.at(position))) + icoImages[position] = image; + } else { + icoImages.append(image); } - QPixmapIconEngineEntry e(abs, size, mode, state); - e.pixmap = pixmap; - pixmaps += e; - } while (reader.jumpToNextImage()); + } } + foreach (const QImage &i, icoImages) + pixmaps += QPixmapIconEngineEntry(abs, i, mode, state); + if (icoImages.isEmpty() && !ignoreSize) // Add placeholder with the filename and empty pixmap for the size. + pixmaps += QPixmapIconEngineEntry(abs, size, mode, state); } QString QPixmapIconEngine::key() const diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h index 7351ad489a..eb94457f48 100644 --- a/src/gui/image/qicon_p.h +++ b/src/gui/image/qicon_p.h @@ -89,6 +89,7 @@ struct QPixmapIconEngineEntry :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){} + QPixmapIconEngineEntry(const QString &file, const QImage &image, QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off); QPixmap pixmap; QString fileName; QSize size; @@ -97,7 +98,14 @@ struct QPixmapIconEngineEntry bool isNull() const {return (fileName.isEmpty() && pixmap.isNull()); } }; - +inline QPixmapIconEngineEntry::QPixmapIconEngineEntry(const QString &file, const QImage &image, QIcon::Mode m, QIcon::State s) + : fileName(file), size(image.size()), mode(m), state(s) +{ + pixmap.convertFromImage(image); + // Reset the devicePixelRatio. The pixmap may be loaded from a @2x file, + // but be used as a 1x pixmap by QIcon. + pixmap.setDevicePixelRatio(1.0); +} class QPixmapIconEngine : public QIconEngine { public: diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index dda8894722..b0b6b27b71 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1662,11 +1662,14 @@ void QImage::fill(uint pixel) return; } - if (d->format == Format_RGB32 || d->format == Format_RGBX8888) + if (d->format == Format_RGB32) pixel |= 0xff000000; - - if (d->format == Format_RGBX8888 || d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied) - pixel = ARGB2RGBA(pixel); + if (d->format == Format_RGBX8888) +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + pixel |= 0xff000000; +#else + pixel |= 0x000000ff; +#endif qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel, 0, 0, d->width, d->height, d->bytes_per_line); @@ -1716,22 +1719,27 @@ void QImage::fill(const QColor &color) if (!d) return; - if (d->depth == 32) { - uint pixel = color.rgba(); - if (d->format == QImage::Format_ARGB32_Premultiplied || d->format == QImage::Format_RGBA8888_Premultiplied) - pixel = qPremultiply(pixel); - fill((uint) pixel); - - } else if (d->format == QImage::Format_RGB16) { + switch (d->format) { + case QImage::Format_RGB32: + case QImage::Format_ARGB32: + fill(color.rgba()); + break; + case QImage::Format_ARGB32_Premultiplied: + fill(qPremultiply(color.rgba())); + break; + case QImage::Format_RGBX8888: + fill(ARGB2RGBA(color.rgba() | 0xff000000)); + break; + case QImage::Format_RGBA8888: + fill(ARGB2RGBA(color.rgba())); + break; + case QImage::Format_RGBA8888_Premultiplied: + fill(ARGB2RGBA(qPremultiply(color.rgba()))); + break; + case QImage::Format_RGB16: fill((uint) qConvertRgb32To16(color.rgba())); - - } else if (d->depth == 1) { - if (color == Qt::color1) - fill((uint) 1); - else - fill((uint) 0); - - } else if (d->depth == 8) { + break; + case QImage::Format_Indexed8: { uint pixel = 0; for (int i=0; i<d->colortable.size(); ++i) { if (color.rgba() == d->colortable.at(i)) { @@ -1740,20 +1748,24 @@ void QImage::fill(const QColor &color) } } fill(pixel); - - } else { + break; + } + case QImage::Format_Mono: + case QImage::Format_MonoLSB: + if (color == Qt::color1) + fill((uint) 1); + else + fill((uint) 0); + break; + default: { QPainter p(this); p.setCompositionMode(QPainter::CompositionMode_Source); p.fillRect(rect(), color); - } - + }} } - - - /*! Inverts all pixel values in the image. @@ -2685,13 +2697,6 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const return maskImage; } - -/* - This code is contributed by Philipp Lang, - GeneriCom Software Germany (www.generi.com) - under the terms of the QPL, Version 1.0 -*/ - /*! \fn QImage QImage::mirrored(bool horizontal = false, bool vertical = true) const Returns a mirror of the image, mirrored in the horizontal and/or @@ -2703,61 +2708,108 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const \sa {QImage#Image Transformations}{Image Transformations} */ -template<typename T> -inline void mirrored_helper_loop(int w, int h, int dxi, int dxs, int dyi, int dy, const uchar* sdata, uchar* ddata, int sbpl, int dbpl) +template<class T> inline void do_mirror_data(QImageData *dst, QImageData *src, + int dstX0, int dstY0, + int dstXIncr, int dstYIncr, + int w, int h) { - for (int sy = 0; sy < h; sy++, dy += dyi) { - const T* ssl = (T*)(sdata + sy*sbpl); - T* dsl = (T*)(ddata + dy*dbpl); - int dx = dxs; - for (int sx = 0; sx < w; sx++, dx += dxi) - dsl[dx] = ssl[sx]; + if (dst == src) { + // When mirroring in-place, stop in the middle for one of the directions, since we + // are swapping the bytes instead of merely copying. + const int srcXEnd = dstX0 ? w / 2 : w; + const int srcYEnd = !dstX0 && dstY0 ? h / 2 : h; + for (int srcY = 0, dstY = dstY0; srcY < srcYEnd; ++srcY, dstY += dstYIncr) { + T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line); + T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line); + for (int srcX = 0, dstX = dstX0; srcX < srcXEnd; ++srcX, dstX += dstXIncr) + std::swap(srcPtr[srcX], dstPtr[dstX]); + } + } else { + for (int srcY = 0, dstY = dstY0; srcY < h; ++srcY, dstY += dstYIncr) { + T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line); + T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line); + for (int srcX = 0, dstX = dstX0; srcX < w; ++srcX, dstX += dstXIncr) + dstPtr[dstX] = srcPtr[srcX]; + } } } -template<typename T> -inline void mirrored_helper_loop_inplace(int w, int h, int dxi, int dxs, int dyi, int dy, uchar* sdata, int sbpl) +inline void do_mirror(QImageData *dst, QImageData *src, bool horizontal, bool vertical) { - for (int sy = 0; sy < h; sy++, dy += dyi) { - T* ssl = (T*)(sdata + sy*sbpl); - T* dsl = (T*)(sdata + dy*sbpl); - int dx = dxs; - for (int sx = 0; sx < w; sx++, dx += dxi) - std::swap(dsl[dx], ssl[sx]); + Q_ASSERT(src->width == dst->width && src->height == dst->height && src->depth == dst->depth); + int w = src->width; + int h = src->height; + int depth = src->depth; + + if (src->depth == 1) { + w = (w + 7) / 8; // byte aligned width + depth = 8; } -} -inline void mirror_horizonal_bitmap(int w, int h, int dxs, uchar* data, int bpl, bool monolsb) -{ - int shift = w % 8; - const uchar* bitflip = qt_get_bitflip_array(); - for (int y = h-1; y >= 0; y--) { - quint8* a0 = (quint8*)(data + y*bpl); - // Swap bytes - quint8* a = a0+dxs; - while (a >= a0) { - *a = bitflip[*a]; - a--; - } - // Shift bits if unaligned - if (shift != 0) { - a = a0+dxs; - quint8 c = 0; - if (monolsb) { - while (a >= a0) { - quint8 nc = *a << shift; - *a = (*a >> (8-shift)) | c; - --a; - c = nc; - } - } else { - while (a >= a0) { - quint8 nc = *a >> shift; - *a = (*a << (8-shift)) | c; - --a; - c = nc; + int dstX0 = 0, dstXIncr = 1; + int dstY0 = 0, dstYIncr = 1; + if (horizontal) { + // 0 -> w-1, 1 -> w-2, 2 -> w-3, ... + dstX0 = w - 1; + dstXIncr = -1; + } + if (vertical) { + // 0 -> h-1, 1 -> h-2, 2 -> h-3, ... + dstY0 = h - 1; + dstYIncr = -1; + } + + switch (depth) { + case 32: + do_mirror_data<quint32>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h); + break; + case 24: + do_mirror_data<quint24>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h); + break; + case 16: + do_mirror_data<quint16>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h); + break; + case 8: + do_mirror_data<quint8>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h); + break; + default: + Q_ASSERT(false); + break; + } + + // The bytes are now all in the correct place. In addition, the bits in the individual + // bytes have to be flipped too when horizontally mirroring a 1 bit-per-pixel image. + if (horizontal && dst->depth == 1) { + Q_ASSERT(dst->format == QImage::Format_Mono || dst->format == QImage::Format_MonoLSB); + const int shift = 8 - (dst->width % 8); + const uchar *bitflip = qt_get_bitflip_array(); + for (int y = 0; y < h; ++y) { + uchar *begin = dst->data + y * dst->bytes_per_line; + uchar *end = begin + dst->bytes_per_line; + for (uchar *p = begin; p < end; ++p) { + *p = bitflip[*p]; + // When the data is non-byte aligned, an extra bit shift (of the number of + // unused bits at the end) is needed for the entire scanline. + if (shift != 8 && p != begin) { + if (dst->format == QImage::Format_Mono) { + for (int i = 0; i < shift; ++i) { + p[-1] <<= 1; + p[-1] |= (*p & (128 >> i)) >> (7 - i); + } + } else { + for (int i = 0; i < shift; ++i) { + p[-1] >>= 1; + p[-1] |= (*p & (1 << i)) << (7 - i); + } + } } } + if (shift != 8) { + if (dst->format == QImage::Format_Mono) + end[-1] <<= shift; + else + end[-1] >>= shift; + } } } } @@ -2773,8 +2825,6 @@ QImage QImage::mirrored_helper(bool horizontal, bool vertical) const if ((d->width <= 1 && d->height <= 1) || (!horizontal && !vertical)) return *this; - int w = d->width; - int h = d->height; // Create result image, copy colormap QImage result(d->width, d->height, d->format); QIMAGE_SANITYCHECK_MEMORY(result); @@ -2787,29 +2837,8 @@ QImage QImage::mirrored_helper(bool horizontal, bool vertical) const result.d->has_alpha_clut = d->has_alpha_clut; result.d->devicePixelRatio = d->devicePixelRatio; - if (d->depth == 1) - w = (w+7)/8; - int dxi = horizontal ? -1 : 1; - int dxs = horizontal ? w-1 : 0; - int dyi = vertical ? -1 : 1; - int dys = vertical ? h-1 : 0; - - // 1 bit, 8 bit - if (d->depth == 1 || d->depth == 8) - mirrored_helper_loop<quint8>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line); - // 16 bit - else if (d->depth == 16) - mirrored_helper_loop<quint16>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line); - // 24 bit - else if (d->depth == 24) - mirrored_helper_loop<quint24>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line); - // 32 bit - else if (d->depth == 32) - mirrored_helper_loop<quint32>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line); - - // special handling of 1 bit images for horizontal mirroring - if (horizontal && d->depth == 1) - mirror_horizonal_bitmap(d->width, d->height, dxs, result.d->data, result.d->bytes_per_line, d->format == Format_MonoLSB); + do_mirror(result.d, d, horizontal, vertical); + return result; } @@ -2818,45 +2847,12 @@ QImage QImage::mirrored_helper(bool horizontal, bool vertical) const */ void QImage::mirrored_inplace(bool horizontal, bool vertical) { - if (!d) - return; - - if ((d->width <= 1 && d->height <= 1) || (!horizontal && !vertical)) + if (!d || (d->width <= 1 && d->height <= 1) || (!horizontal && !vertical)) return; detach(); - int w = d->width; - int h = d->height; - - if (d->depth == 1) - w = (w+7)/8; - int dxi = horizontal ? -1 : 1; - int dxs = horizontal ? w-1 : 0; - int dyi = vertical ? -1 : 1; - int dys = vertical ? h-1 : 0; - - if (vertical) - h = h/2; - else if (horizontal) - w = w/2; - - // 1 bit, 8 bit - if (d->depth == 1 || d->depth == 8) - mirrored_helper_loop_inplace<quint8>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line); - // 16 bit - else if (d->depth == 16) - mirrored_helper_loop_inplace<quint16>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line); - // 24 bit - else if (d->depth == 24) - mirrored_helper_loop_inplace<quint24>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line); - // 32 bit - else if (d->depth == 32) - mirrored_helper_loop_inplace<quint32>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line); - - // special handling of 1 bit images for horizontal mirroring - if (horizontal && d->depth == 1) - mirror_horizonal_bitmap(d->width, d->height, dxs, d->data, d->bytes_per_line, d->format == Format_MonoLSB); + do_mirror(d, d, horizontal, vertical); } /*! diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 86c4dfbdca..c6d8d19bb1 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1098,6 +1098,7 @@ bool QPixmap::isDetached() const */ bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags flags) { + detach(); if (image.isNull() || !data) *this = QPixmap::fromImage(image, flags); else diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 1465fea8b9..d879a5cb61 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -363,10 +363,12 @@ void QRasterPlatformPixmap::createPixmapForImage(QImage &sourceImage, Qt::ImageC } is_null = (w <= 0 || h <= 0); - image.d->devicePixelRatio = sourceImage.devicePixelRatio(); + if (image.d) + image.d->devicePixelRatio = sourceImage.devicePixelRatio(); //ensure the pixmap and the image resulting from toImage() have the same cacheKey(); setSerialNumber(image.cacheKey() >> 32); - setDetachNumber(image.d->detach_no); + if (image.d) + setDetachNumber(image.d->detach_no); } QImage* QRasterPlatformPixmap::buffer() diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 29ab7daca0..c155512e9d 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -171,6 +171,7 @@ bool QGuiApplicationPrivate::noGrab = false; static qreal fontSmoothingGamma = 1.7; extern void qRegisterGuiVariant(); +extern void qRegisterGuiGetInterpolator(); extern void qInitDrawhelperAsm(); extern void qInitImageConversions(); @@ -489,6 +490,12 @@ static QWindowGeometrySpecification windowGeometrySpecification; \li \c{-platformtheme} \e platformTheme, specifies the platform theme. Overridden by the \c QT_QPA_PLATFORMTHEME environment variable. + + \li \c{-plugin} \e plugin, specifies additional plugins to load. The argument + may appear multiple times. + + Overridden by the \c QT_QPA_GENERIC_PLUGINS environment variable. + \li \c{-qmljsdebugger=}, activates the QML/JS debugger with a specified port. The value must be of format \c{port:1234}\e{[,block]}, where \e block is optional @@ -1281,6 +1288,9 @@ void QGuiApplicationPrivate::init() // trigger registering of QVariant's GUI types qRegisterGuiVariant(); + // trigger registering of animation interpolators + qRegisterGuiGetInterpolator(); + QWindowSystemInterfacePrivate::eventTime.start(); is_app_running = true; diff --git a/src/gui/kernel/qplatformclipboard.cpp b/src/gui/kernel/qplatformclipboard.cpp index 5c25054260..d93268c9f2 100644 --- a/src/gui/kernel/qplatformclipboard.cpp +++ b/src/gui/kernel/qplatformclipboard.cpp @@ -123,7 +123,8 @@ bool QPlatformClipboard::ownsMode(QClipboard::Mode mode) const void QPlatformClipboard::emitChanged(QClipboard::Mode mode) { - QGuiApplication::clipboard()->emitChanged(mode); + if (!QGuiApplicationPrivate::is_app_closing) // QTBUG-39317, prevent emission when closing down. + QGuiApplication::clipboard()->emitChanged(mode); } QT_END_NAMESPACE diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 2651c23665..97b006b4fc 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -443,9 +443,10 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi samples = qBound(0, int(samples), int(maxSamples)); } + samples = qMax(0, samples); + requestedSamples = samples; size = sz; target = texture_target; - // texture dimensions QT_RESET_GLERROR(); // reset error state GLuint fbo = 0; @@ -477,6 +478,9 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi valid = checkFramebufferStatus(ctx); if (valid) { + // Query the actual number of samples. This can be greater than the requested + // value since the typically supported values are 0, 4, 8, ..., and the + // requests are mapped to the next supported value. funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc); } @@ -546,7 +550,10 @@ void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment) { - int samples = format.samples(); + // Use the same sample count for all attachments. format.samples() already contains + // the actual number of samples for the color attachment and is not suitable. Use + // requestedSamples instead. + const int samples = requestedSamples; // free existing attachments if (depth_buffer_guard) { diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h index 7a653bc16d..75348d1481 100644 --- a/src/gui/opengl/qopenglframebufferobject_p.h +++ b/src/gui/opengl/qopenglframebufferobject_p.h @@ -131,6 +131,7 @@ public: GLenum target; QSize size; QOpenGLFramebufferObjectFormat format; + int requestedSamples; uint valid : 1; QOpenGLFramebufferObject::Attachment fbo_attachment; QOpenGLExtensions funcs; diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index 57590cfece..db88fbb68c 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -283,46 +283,48 @@ static int qt_gl_resolve_features() QSurfaceFormat format = QOpenGLContext::currentContext()->format(); QOpenGLExtensionMatcher extensions; - // Recognize features by extension name. - if (extensions.match("GL_ARB_multitexture")) - features |= QOpenGLFunctions::Multitexture; - if (extensions.match("GL_ARB_shader_objects")) - features |= QOpenGLFunctions::Shaders; - if (extensions.match("GL_EXT_framebuffer_object") || - extensions.match("GL_ARB_framebuffer_object")) - features |= QOpenGLFunctions::Framebuffers; - if (extensions.match("GL_EXT_blend_color")) - features |= QOpenGLFunctions::BlendColor; - if (extensions.match("GL_EXT_blend_equation_separate")) - features |= QOpenGLFunctions::BlendEquationSeparate; - if (extensions.match("GL_EXT_blend_func_separate")) - features |= QOpenGLFunctions::BlendFuncSeparate; - if (extensions.match("GL_EXT_blend_subtract")) - features |= QOpenGLFunctions::BlendSubtract; - if (extensions.match("GL_ARB_texture_compression")) - features |= QOpenGLFunctions::CompressedTextures; - if (extensions.match("GL_ARB_multisample")) - features |= QOpenGLFunctions::Multisample; - if (extensions.match("GL_ARB_texture_non_power_of_two")) - features |= QOpenGLFunctions::NPOTTextures | - QOpenGLFunctions::NPOTTextureRepeat; - - // assume version 2.0 or higher - features |= QOpenGLFunctions::BlendColor | - QOpenGLFunctions::BlendEquation | - QOpenGLFunctions::Multitexture | - QOpenGLFunctions::CompressedTextures | - QOpenGLFunctions::Multisample | - QOpenGLFunctions::BlendFuncSeparate | - QOpenGLFunctions::Buffers | - QOpenGLFunctions::Shaders | - QOpenGLFunctions::StencilSeparate | - QOpenGLFunctions::BlendEquationSeparate | - QOpenGLFunctions::NPOTTextures | - QOpenGLFunctions::NPOTTextureRepeat; - if (format.majorVersion() >= 3) features |= QOpenGLFunctions::Framebuffers; + else if (extensions.match("GL_EXT_framebuffer_object") || + extensions.match("GL_ARB_framebuffer_object")) + features |= QOpenGLFunctions::Framebuffers; + + if (format.majorVersion() >= 2) { + features |= QOpenGLFunctions::BlendColor | + QOpenGLFunctions::BlendEquation | + QOpenGLFunctions::BlendSubtract | + QOpenGLFunctions::Multitexture | + QOpenGLFunctions::CompressedTextures | + QOpenGLFunctions::Multisample | + QOpenGLFunctions::BlendFuncSeparate | + QOpenGLFunctions::Buffers | + QOpenGLFunctions::Shaders | + QOpenGLFunctions::StencilSeparate | + QOpenGLFunctions::BlendEquationSeparate | + QOpenGLFunctions::NPOTTextures | + QOpenGLFunctions::NPOTTextureRepeat; + } else { + // Recognize features by extension name. + if (extensions.match("GL_ARB_multitexture")) + features |= QOpenGLFunctions::Multitexture; + if (extensions.match("GL_ARB_shader_objects")) + features |= QOpenGLFunctions::Shaders; + if (extensions.match("GL_EXT_blend_color")) + features |= QOpenGLFunctions::BlendColor; + if (extensions.match("GL_EXT_blend_equation_separate")) + features |= QOpenGLFunctions::BlendEquationSeparate; + if (extensions.match("GL_EXT_blend_subtract")) + features |= QOpenGLFunctions::BlendSubtract; + if (extensions.match("GL_EXT_blend_func_separate")) + features |= QOpenGLFunctions::BlendFuncSeparate; + if (extensions.match("GL_ARB_texture_compression")) + features |= QOpenGLFunctions::CompressedTextures; + if (extensions.match("GL_ARB_multisample")) + features |= QOpenGLFunctions::Multisample; + if (extensions.match("GL_ARB_texture_non_power_of_two")) + features |= QOpenGLFunctions::NPOTTextures | + QOpenGLFunctions::NPOTTextureRepeat; + } const QPair<int, int> version = format.version(); if (version < qMakePair(3, 0) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 2b40bf37e1..44b38dcf1c 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1798,71 +1798,6 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c } fx = v_fx.i[0]; fy = v_fy.i[0]; -#elif defined(__ARM_NEON__) - BILINEAR_ROTATE_BOUNDS_PROLOG - - const int16x8_t colorMask = vdupq_n_s16(0x00ff); - const int16x8_t invColorMask = vmvnq_s16(colorMask); - const int16x8_t v_256 = vdupq_n_s16(256); - int32x4_t v_fdx = vdupq_n_s32(fdx*4); - int32x4_t v_fdy = vdupq_n_s32(fdy*4); - - const uchar *textureData = data->texture.imageData; - const int bytesPerLine = data->texture.bytesPerLine; - - union Vect_buffer { int32x4_t vect; quint32 i[4]; }; - Vect_buffer v_fx, v_fy; - - for (int i = 0; i < 4; i++) { - v_fx.i[i] = fx; - v_fy.i[i] = fy; - fx += fdx; - fy += fdy; - } - - const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff); - - while (b < boundedEnd) { - if (fdx > 0 && (v_fx.i[3] >> 16) >= image_x2) - break; - if (fdx < 0 && (v_fx.i[3] >> 16) < image_x1) - break; - if (fdy > 0 && (v_fy.i[3] >> 16) >= image_y2) - break; - if (fdy < 0 && (v_fy.i[3] >> 16) < image_y1) - break; - - Vect_buffer tl, tr, bl, br; - - Vect_buffer v_fx_shifted, v_fy_shifted; - v_fx_shifted.vect = vshrq_n_s32(v_fx.vect, 16); - v_fy_shifted.vect = vshrq_n_s32(v_fy.vect, 16); - - for (int i = 0; i < 4; i++) { - const int x1 = v_fx_shifted.i[i]; - const int y1 = v_fy_shifted.i[i]; - const uchar *sl = textureData + bytesPerLine * y1; - const uint *s1 = (const uint *)sl; - const uint *s2 = (const uint *)(sl + bytesPerLine); - tl.i[i] = s1[x1]; - tr.i[i] = s1[x1+1]; - bl.i[i] = s2[x1]; - br.i[i] = s2[x1+1]; - } - - int32x4_t v_distx = vshrq_n_s32(vandq_s32(v_fx.vect, v_ffff_mask), 12); - int32x4_t v_disty = vshrq_n_s32(vandq_s32(v_fy.vect, v_ffff_mask), 12); - v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16)); - v_disty = vorrq_s32(v_disty, vshlq_n_s32(v_disty, 16)); - int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4); - - interpolate_4_pixels_16_neon(vreinterpretq_s16_s32(tl.vect), vreinterpretq_s16_s32(tr.vect), vreinterpretq_s16_s32(bl.vect), vreinterpretq_s16_s32(br.vect), vreinterpretq_s16_s32(v_distx), v_disty, v_disty_, colorMask, invColorMask, v_256, b); - b+=4; - v_fx.vect = vaddq_s32(v_fx.vect, v_fdx); - v_fy.vect = vaddq_s32(v_fy.vect, v_fdy); - } - fx = v_fx.i[0]; - fy = v_fy.i[0]; #endif } @@ -6318,6 +6253,7 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer, } } +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN static void qt_alphamapblit_rgba8888(QRasterBuffer *rasterBuffer, int x, int y, quint32 color, const uchar *map, @@ -6326,6 +6262,7 @@ static void qt_alphamapblit_rgba8888(QRasterBuffer *rasterBuffer, { qt_alphamapblit_argb32(rasterBuffer, x, y, ARGB2RGBA(color), map, mapWidth, mapHeight, mapStride, clip); } +#endif static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer, int x, int y, quint32 color, diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index acab08e794..ba20186d00 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -761,7 +761,7 @@ void QPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) bool((painter()->renderHints() & QPainter::TextAntialiasing) && !(painter()->font().styleStrategy() & QFont::NoAntialias))); painter()->translate(p.x(), p.y()); - painter()->fillPath(path, state->pen().brush()); + painter()->fillPath(path, painter()->pen().brush()); painter()->restore(); } } diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index e75a59cc91..8487cf2394 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -830,6 +830,8 @@ void QPaintEngineEx::drawEllipse(const QRectF &r) int point_count = 0; x.points[0] = qt_curves_for_arc(r, 0, -360, x.points + 1, &point_count); + if (point_count == 0) + return; QVectorPath vp((qreal *) pts, point_count + 1, qpaintengineex_ellipse_types, QVectorPath::EllipseHint); draw(vp); } diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index a165330913..3ce4ae67ae 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -181,9 +181,13 @@ static const HB_FontClass hb_fontClass = { static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB_UInt *length) { - QFontEngine *fe = (QFontEngine *)font; - Q_ASSERT(fe->faceData.get_font_table); - if (!fe->faceData.get_font_table(fe->faceData.user_data, tableTag, buffer, length)) + QFontEngine::FaceData *data = (QFontEngine::FaceData *)font; + Q_ASSERT(data); + + qt_get_font_table_func_t get_font_table = data->get_font_table; + Q_ASSERT(get_font_table); + + if (!get_font_table(data->user_data, tableTag, buffer, length)) return HB_Err_Invalid_Argument; return HB_Err_Ok; } @@ -291,8 +295,11 @@ void *QFontEngine::harfbuzzFont() const #endif if (!font_) { HB_Face hbFace = (HB_Face)harfbuzzFace(); - if (hbFace->font_for_init != 0) + if (hbFace->font_for_init) { + void *data = hbFace->font_for_init; q_check_ptr(qHBLoadFace(hbFace)); + free(data); + } HB_FontRec *hbFont = (HB_FontRec *) malloc(sizeof(HB_FontRec)); Q_CHECK_PTR(hbFont); @@ -323,7 +330,12 @@ void *QFontEngine::harfbuzzFace() const return hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this)); #endif if (!face_) { - HB_Face hbFace = qHBNewFace(const_cast<QFontEngine *>(this), hb_getSFntTable); + QFontEngine::FaceData *data = (QFontEngine::FaceData *)malloc(sizeof(QFontEngine::FaceData)); + Q_CHECK_PTR(data); + data->user_data = faceData.user_data; + data->get_font_table = faceData.get_font_table; + + HB_Face hbFace = qHBNewFace(data, hb_getSFntTable); Q_CHECK_PTR(hbFace); hbFace->isSymbolFont = symbol; @@ -376,8 +388,11 @@ bool QFontEngine::supportsScript(QChar::Script script) const } #endif HB_Face hbFace = (HB_Face)harfbuzzFace(); - if (hbFace->font_for_init != 0) + if (hbFace->font_for_init) { + void *data = hbFace->font_for_init; q_check_ptr(qHBLoadFace(hbFace)); + free(data); + } return hbFace->supported_scripts[script_to_hbscript(script)]; } diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 7868fd23d1..f6ab123739 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -295,8 +295,7 @@ int QFontMetrics::descent() const /*! Returns the height of the font. - This is always equal to ascent()+descent()+1 (the 1 is for the - base line). + This is always equal to ascent()+descent(). \sa leading(), lineSpacing() */ @@ -1159,8 +1158,7 @@ qreal QFontMetricsF::descent() const /*! Returns the height of the font. - This is always equal to ascent()+descent()+1 (the 1 is for the - base line). + This is always equal to ascent()+descent(). \sa leading(), lineSpacing() */ |