diff options
28 files changed, 606 insertions, 143 deletions
diff --git a/src/3rdparty/phonon/ds9/videorenderer_evr.cpp b/src/3rdparty/phonon/ds9/videorenderer_evr.cpp index d23d9ce..de3f46f 100644 --- a/src/3rdparty/phonon/ds9/videorenderer_evr.cpp +++ b/src/3rdparty/phonon/ds9/videorenderer_evr.cpp @@ -43,14 +43,12 @@ namespace Phonon { //normally we should use IID_IMFGetService but this introduces another dependency //so here we simply define our own IId with the same value + ComPointer<T> ret; ComPointer<IMFGetService> getService(filter, IID_IMFGetService); - Q_ASSERT(getService); - T *ptr = 0; - HRESULT hr = getService->GetService(guidService, riid, reinterpret_cast<void **>(&ptr)); - if (!SUCCEEDED(hr) || ptr == 0) - Q_ASSERT(!SUCCEEDED(hr) && ptr != 0); - ComPointer<T> service(ptr); - return service; + if (getService) { + getService->GetService(guidService, riid, reinterpret_cast<void**>(ret.pparam())); + } + return ret; } VideoRendererEVR::~VideoRendererEVR() @@ -70,6 +68,10 @@ namespace Phonon } ComPointer<IMFVideoDisplayControl> filterControl = getService<IMFVideoDisplayControl>(m_filter, MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl); + if (!filterControl) { + m_filter = Filter(); //will release the interface + return; + } filterControl->SetVideoWindow(reinterpret_cast<HWND>(target->winId())); filterControl->SetAspectRatioMode(MFVideoARMode_None); // We're in control of the size diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index ee3c4f2..bcf4477 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -393,6 +393,27 @@ void QAbstractEventDispatcher::closingDown() \snippet doc/src/snippets/code/src_corelib_kernel_qabstracteventdispatcher.cpp 0 + Note that the type of the \a message is platform dependent. The + following table shows the \a {message}'s type on Windows, Mac, and + X11. You can do a static cast to these types. + + \table + \header + \o Platform + \o type + \row + \o Windows + \o MSG + \row + \o X11 + \o XEvent + \row + \o Mac + \o NSEvent + \endtable + + + \sa setEventFilter(), filterEvent() */ @@ -434,6 +455,9 @@ QAbstractEventDispatcher::EventFilter QAbstractEventDispatcher::setEventFilter(E compatibility with any extensions that may be used in the application. + Note that the type of \a message is platform dependent. See + QAbstractEventDispatcher::EventFilter for details. + \sa setEventFilter() */ bool QAbstractEventDispatcher::filterEvent(void *message) diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 8541c7d..9332bbc 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -546,13 +546,13 @@ bool QUuid::operator>(const QUuid &other) const \fn QUuid QUuid::createUuid() On any platform other than Windows, this function returns a new - UUID with variant QUuid::DCE and version QUuid::Random. The random - numbers used to construct the UUID are obtained from the local - pseudo-random generator, qrand(), which is usually not a cryptographic - quality random number generator. Therefore, a UUID generated by - this function can't be guaranteed to be unique. If the pseudo-random - number generator for the calling thread has not yet been seeded, this - function will seed the pseudo-random number generator by calling qsrand(). + UUID with variant QUuid::DCE and version QUuid::Random. If + the /dev/urandom device exists, then the numbers used to construct + the UUID will be of cryptographic quality, which will make the UUID + unique. Otherwise, the numbers of the UUID will be obtained from + the local pseudo-random number generator (qrand(), which is seeded + by qsrand()) which is usually not of cryptograhic quality, which + means that the UUID can't be guaranteed to be unique. On a Windows platform, a GUID is generated, which almost certainly \e{will} be unique, on this or any other system, networked or not. @@ -577,6 +577,7 @@ QUuid QUuid::createUuid() QT_BEGIN_INCLUDE_NAMESPACE #include "qdatetime.h" +#include "qfile.h" #include "stdlib.h" // For srand/rand QT_END_INCLUDE_NAMESPACE @@ -584,24 +585,35 @@ extern void qsrand(); // in qglobal.cpp QUuid QUuid::createUuid() { - static const int intbits = sizeof(int)*8; - static int randbits = 0; - if (!randbits) { - int max = RAND_MAX; - do { ++randbits; } while ((max=max>>1)); - } - - // reseed, but only if not already seeded - qsrand(); - QUuid result; uint *data = &(result.data1); - int chunks = 16 / sizeof(uint); - while (chunks--) { - uint randNumber = 0; - for (int filled = 0; filled < intbits; filled += randbits) - randNumber |= qrand()<<filled; - *(data+chunks) = randNumber; + +#ifdef Q_OS_UNIX + QFile devUrandom; + devUrandom.setFileName(QLatin1String("/dev/urandom")); + if (devUrandom.open(QIODevice::ReadOnly)) { + qint64 numToRead = 4 * sizeof(uint); + devUrandom.read((char *) data, numToRead); // should read 128-bits of data + } else +#endif + { + static const int intbits = sizeof(int)*8; + static int randbits = 0; + if (!randbits) { + int max = RAND_MAX; + do { ++randbits; } while ((max=max>>1)); + } + + // reseed, but only if not already seeded + qsrand(); + + int chunks = 16 / sizeof(uint); + while (chunks--) { + uint randNumber = 0; + for (int filled = 0; filled < intbits; filled += randbits) + randNumber |= qrand()<<filled; + *(data+chunks) = randNumber; + } } result.data4[0] = (result.data4[0] & 0x3F) | 0x80; // UV_DCE diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index adc2632..bb8a994 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -2274,6 +2274,8 @@ bool QImage::create(const QSize& size, int depth, int numColors, QImage::Endian typedef void (*Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); +typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFlags); + static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { Q_ASSERT(src->format == QImage::Format_ARGB32); @@ -2298,6 +2300,169 @@ static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt: } } +static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_ARGB32); + + const int pad = (data->bytes_per_line >> 2) - data->width; + QRgb *rgb_data = (QRgb *) data->data; + + for (int i = 0; i < data->height; ++i) { + const QRgb *end = rgb_data + data->width; + while (rgb_data < end) { + *rgb_data = PREMUL(*rgb_data); + ++rgb_data; + } + rgb_data += pad; + } + data->format = QImage::Format_ARGB32_Premultiplied; + return true; +} + +static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_Indexed8); + const int depth = 32; + + const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; + const int nbytes = dst_bytes_per_line * data->height; + uchar *const newData = (uchar *)realloc(data->data, nbytes); + if (!newData) + return false; + + data->data = newData; + + // start converting from the end because the end image is bigger than the source + uchar *src_data = newData + data->nbytes; // end of src + quint32 *dest_data = (quint32 *) (newData + nbytes); // end of dest > end of src + const int width = data->width; + const int src_pad = data->bytes_per_line - width; + const int dest_pad = (dst_bytes_per_line >> 2) - width; + + for (int i = 0; i < data->height; ++i) { + src_data -= src_pad; + dest_data -= dest_pad; + for (int pixI = 0; pixI < width; ++pixI) { + --src_data; + --dest_data; + const uint pixel = data->colortable[*src_data]; + *dest_data = (quint32) PREMUL(pixel); + } + } + + data->format = QImage::Format_ARGB32_Premultiplied; + data->bytes_per_line = dst_bytes_per_line; + data->depth = depth; + data->nbytes = nbytes; + + return true; +} + +static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_Indexed8); + const int depth = 32; + + const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; + const int nbytes = dst_bytes_per_line * data->height; + uchar *const newData = (uchar *)realloc(data->data, nbytes); + if (!newData) + return false; + + data->data = newData; + + // start converting from the end because the end image is bigger than the source + uchar *src_data = newData + data->nbytes; + quint32 *dest_data = (quint32 *) (newData + nbytes); + const int width = data->width; + const int src_pad = data->bytes_per_line - width; + const int dest_pad = (dst_bytes_per_line >> 2) - width; + + for (int i = 0; i < data->height; ++i) { + src_data -= src_pad; + dest_data -= dest_pad; + for (int pixI = 0; pixI < width; ++pixI) { + --src_data; + --dest_data; + *dest_data = (quint32) data->colortable[*src_data]; + } + } + + data->format = QImage::Format_RGB32; + data->bytes_per_line = dst_bytes_per_line; + data->depth = depth; + data->nbytes = nbytes; + + return true; +} + +static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_Indexed8); + const int depth = 16; + + const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; + const int nbytes = dst_bytes_per_line * data->height; + uchar *const newData = (uchar *)realloc(data->data, nbytes); + if (!newData) + return false; + + data->data = newData; + + // start converting from the end because the end image is bigger than the source + uchar *src_data = newData + data->nbytes; + quint16 *dest_data = (quint16 *) (newData + nbytes); + const int width = data->width; + const int src_pad = data->bytes_per_line - width; + const int dest_pad = (dst_bytes_per_line >> 1) - width; + + for (int i = 0; i < data->height; ++i) { + src_data -= src_pad; + dest_data -= dest_pad; + for (int pixI = 0; pixI < width; ++pixI) { + --src_data; + --dest_data; + const uint pixel = data->colortable[*src_data]; + *dest_data = qt_colorConvert<quint16, quint32>(pixel, 0); + } + } + + data->format = QImage::Format_RGB16; + data->bytes_per_line = dst_bytes_per_line; + data->depth = depth; + data->nbytes = nbytes; + + return true; +} + +static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_RGB32); + const int depth = 16; + + const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; + const int src_bytes_per_line = data->bytes_per_line; + quint32 *src_data = (quint32 *) data->data; + quint16 *dst_data = (quint16 *) data->data; + + for (int i = 0; i < data->height; ++i) { + qt_memconvert(dst_data, src_data, data->width); + src_data = (quint32 *) (((char*)src_data) + src_bytes_per_line); + dst_data = (quint16 *) (((char*)dst_data) + dst_bytes_per_line); + } + data->format = QImage::Format_RGB16; + data->bytes_per_line = dst_bytes_per_line; + data->depth = depth; + data->nbytes = dst_bytes_per_line * data->height; + uchar *const newData = (uchar *)realloc(data->data, data->nbytes); + if (newData) { + data->data = newData; + return true; + } else { + return false; + } +} + static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied); @@ -3447,6 +3612,103 @@ static const Image_Converter converter_map[QImage::NImageFormats][QImage::NImage } // Format_ARGB4444_Premultiplied }; +static const InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] = +{ + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_Mono + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_MonoLSB + { + 0, + 0, + 0, + 0, + 0, + convert_indexed8_to_RGB_inplace, + convert_indexed8_to_ARGB_PM_inplace, + convert_indexed8_to_RGB16_inplace, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + }, // Format_Indexed8 + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_RGB_to_RGB16_inplace, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + }, // Format_ARGB32 + { + 0, + 0, + 0, + 0, + 0, + 0, + convert_ARGB_to_ARGB_PM_inplace, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + }, // Format_ARGB32 + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_ARGB32_Premultiplied + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_RGB16 + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_ARGB8565_Premultiplied + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_RGB666 + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_ARGB6666_Premultiplied + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_RGB555 + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_ARGB8555_Premultiplied + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_RGB888 + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_RGB444 + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } // Format_ARGB4444_Premultiplied +}; + /*! Returns a copy of the image in the given \a format. @@ -6276,6 +6538,18 @@ QTransform QImage::trueMatrix(const QTransform &matrix, int w, int h) return matrix * QTransform().translate(-delta.x(), -delta.y()); } +bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags flags) +{ + if (format == newFormat) + return true; + + const InPlace_Image_Converter *const converterPtr = &inplace_converter_map[format][newFormat]; + InPlace_Image_Converter converter = *converterPtr; + if (converter) + return converter(this, flags); + else + return false; +} /*! \typedef QImage::DataPtr diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 0c19647..f1a0c47 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -96,6 +96,9 @@ struct Q_GUI_EXPORT QImageData { // internal image data bool checkForAlphaPixels() const; + // Convert the image in-place, minimizing memory reallocation + // Return false if the conversion cannot be done in-place. + bool convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags); #ifndef QT_NO_IMAGE_TEXT QMap<QString, QString> text; diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 9dc15fc..13c03a1 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -47,6 +47,9 @@ #include "qbitmap.h" #include "qimage.h" +#include <QBuffer> +#include <QImageReader> +#include <private/qsimd_p.h> #include <private/qwidget_p.h> #include <private/qdrawhelper_p.h> @@ -127,91 +130,26 @@ void QRasterPixmapData::resize(int width, int height) setSerialNumber(image.serialNumber()); } +bool QRasterPixmapData::fromData(const uchar *buffer, uint len, const char *format, + Qt::ImageConversionFlags flags) +{ + QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len); + QBuffer b(&a); + b.open(QIODevice::ReadOnly); + QImage image = QImageReader(&b, format).read(); + if (image.isNull()) + return false; + + createPixmapForImage(image, flags, /* inplace = */true); + return !isNull(); +} + void QRasterPixmapData::fromImage(const QImage &sourceImage, Qt::ImageConversionFlags flags) { Q_UNUSED(flags); - -#ifdef Q_WS_QWS - QImage::Format format; - if (pixelType() == BitmapType) { - format = QImage::Format_Mono; - } else { - format = QScreen::instance()->pixelFormat(); - if (format == QImage::Format_Invalid) - format = QImage::Format_ARGB32_Premultiplied; - else if (format == QImage::Format_Indexed8) // currently not supported - format = QImage::Format_RGB444; - } - - if (sourceImage.hasAlphaChannel() - && ((flags & Qt::NoOpaqueDetection) - || const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels())) { - switch (format) { - case QImage::Format_RGB16: - format = QImage::Format_ARGB8565_Premultiplied; - break; - case QImage::Format_RGB666: - format = QImage::Format_ARGB6666_Premultiplied; - break; - case QImage::Format_RGB555: - format = QImage::Format_ARGB8555_Premultiplied; - break; - case QImage::Format_RGB444: - format = QImage::Format_ARGB4444_Premultiplied; - break; - default: - format = QImage::Format_ARGB32_Premultiplied; - break; - } - } else if (format == QImage::Format_Invalid) { - format = QImage::Format_ARGB32_Premultiplied; - } - - image = sourceImage.convertToFormat(format); -#else - if (pixelType() == BitmapType) { - image = sourceImage.convertToFormat(QImage::Format_MonoLSB); - } else { - if (sourceImage.depth() == 1) { - image = sourceImage.hasAlphaChannel() - ? sourceImage.convertToFormat(QImage::Format_ARGB32_Premultiplied) - : sourceImage.convertToFormat(QImage::Format_RGB32); - } else { - - QImage::Format opaqueFormat = QNativeImage::systemFormat(); - QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; - -#ifndef QT_HAVE_NEON - switch (opaqueFormat) { - case QImage::Format_RGB16: - alphaFormat = QImage::Format_ARGB8565_Premultiplied; - break; - default: // We don't care about the others... - break; - } -#endif - - if (!sourceImage.hasAlphaChannel() - || ((flags & Qt::NoOpaqueDetection) == 0 - && !const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels())) { - image = sourceImage.convertToFormat(opaqueFormat); - } else { - image = sourceImage.convertToFormat(alphaFormat); - } - } - } -#endif - if (image.d) { - w = image.d->width; - h = image.d->height; - d = image.d->depth; - } else { - w = h = d = 0; - } - is_null = (w <= 0 || h <= 0); - - setSerialNumber(image.serialNumber()); + QImage image = sourceImage; + createPixmapForImage(image, flags, /* inplace = */false); } // from qwindowsurface.cpp @@ -240,7 +178,7 @@ void QRasterPixmapData::fill(const QColor &color) if (alpha != 255) { if (!image.hasAlphaChannel()) { QImage::Format toFormat; -#ifndef QT_HAVE_NEON +#if !(defined(QT_HAVE_NEON) || defined(QT_ALWAYS_HAVE_SSE2)) if (image.format() == QImage::Format_RGB16) toFormat = QImage::Format_ARGB8565_Premultiplied; else if (image.format() == QImage::Format_RGB666) @@ -398,6 +336,105 @@ int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const return 0; } +void QRasterPixmapData::createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace) +{ + QImage::Format format; +#ifdef Q_WS_QWS + if (pixelType() == BitmapType) { + format = QImage::Format_Mono; + } else { + format = QScreen::instance()->pixelFormat(); + if (format == QImage::Format_Invalid) + format = QImage::Format_ARGB32_Premultiplied; + else if (format == QImage::Format_Indexed8) // currently not supported + format = QImage::Format_RGB444; + } + + if (sourceImage.hasAlphaChannel() + && ((flags & Qt::NoOpaqueDetection) + || const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels())) { + switch (format) { + case QImage::Format_RGB16: + format = QImage::Format_ARGB8565_Premultiplied; + break; + case QImage::Format_RGB666: + format = QImage::Format_ARGB6666_Premultiplied; + break; + case QImage::Format_RGB555: + format = QImage::Format_ARGB8555_Premultiplied; + break; + case QImage::Format_RGB444: + format = QImage::Format_ARGB4444_Premultiplied; + break; + default: + format = QImage::Format_ARGB32_Premultiplied; + break; + } + } else if (format == QImage::Format_Invalid) { + format = QImage::Format_ARGB32_Premultiplied; + } +#else + if (pixelType() == BitmapType) { + format = QImage::Format_MonoLSB; + } else { + if (sourceImage.depth() == 1) { + format = sourceImage.hasAlphaChannel() + ? QImage::Format_ARGB32_Premultiplied + : QImage::Format_RGB32; + } else { + QImage::Format opaqueFormat = QNativeImage::systemFormat(); + QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; + +#if !defined(QT_HAVE_NEON) && !defined(QT_ALWAYS_HAVE_SSE2) + switch (opaqueFormat) { + case QImage::Format_RGB16: + alphaFormat = QImage::Format_ARGB8565_Premultiplied; + break; + default: // We don't care about the others... + break; + } +#endif + + if (!sourceImage.hasAlphaChannel()) { + format = opaqueFormat; + } else if ((flags & Qt::NoOpaqueDetection) == 0 + && !const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels()) + { + // image has alpha format but is really opaque, so try to do a + // more efficient conversion + if (sourceImage.format() == QImage::Format_ARGB32 + || sourceImage.format() == QImage::Format_ARGB32_Premultiplied) + { + if (!inPlace) + sourceImage.detach(); + sourceImage.d->format = QImage::Format_RGB32; + } + format = opaqueFormat; + } else { + format = alphaFormat; + } + } + } +#endif + + if (inPlace && sourceImage.d->convertInPlace(format, flags)) { + image = sourceImage; + } else { + image = sourceImage.convertToFormat(format); + } + + if (image.d) { + w = image.d->width; + h = image.d->height; + d = image.d->depth; + } else { + w = h = d = 0; + } + is_null = (w <= 0 || h <= 0); + + setSerialNumber(image.serialNumber()); +} + QImage* QRasterPixmapData::buffer() { return ℑ diff --git a/src/gui/image/qpixmap_raster_p.h b/src/gui/image/qpixmap_raster_p.h index 6cdd3d7..d7e3f85 100644 --- a/src/gui/image/qpixmap_raster_p.h +++ b/src/gui/image/qpixmap_raster_p.h @@ -72,6 +72,7 @@ public: void resize(int width, int height); void fromFile(const QString &filename, Qt::ImageConversionFlags flags); + bool fromData(const uchar *buffer, uint len, const char *format, Qt::ImageConversionFlags flags); void fromImage(const QImage &image, Qt::ImageConversionFlags flags); bool scroll(int dx, int dy, const QRect &rect); @@ -85,6 +86,8 @@ public: protected: int metric(QPaintDevice::PaintDeviceMetric metric) const; + void createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace); + void setImage(const QImage &image); QImage image; private: diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp index ea4fe6b..31ca909 100644 --- a/src/gui/image/qpixmapdata.cpp +++ b/src/gui/image/qpixmapdata.cpp @@ -146,7 +146,7 @@ bool QPixmapData::fromData(const uchar *buf, uint len, const char *format, Qt::I void QPixmapData::copy(const QPixmapData *data, const QRect &rect) { - fromImage(data->toImage().copy(rect), Qt::AutoColor); + fromImage(data->toImage().copy(rect), Qt::NoOpaqueDetection); } bool QPixmapData::scroll(int dx, int dy, const QRect &rect) diff --git a/src/gui/itemviews/qabstractitemdelegate.cpp b/src/gui/itemviews/qabstractitemdelegate.cpp index 775bf7d..0ea6d67 100644 --- a/src/gui/itemviews/qabstractitemdelegate.cpp +++ b/src/gui/itemviews/qabstractitemdelegate.cpp @@ -291,8 +291,14 @@ void QAbstractItemDelegate::updateEditorGeometry(QWidget *, } /*! - Whenever an event occurs, this function is called with the \a event - \a model \a option and the \a index that corresponds to the item being edited. + When editing of an item starts, this function is called with the + \a event that triggered the editing, the \a model, the \a index of + the item, and the \a option used for rendering the item. + + Mouse events are sent to editorEvent() even if they don't start + editing of the item. This can, for instance, be useful if you wish + to open a context menu when the right mouse button is pressed on + an item. The base implementation returns false (indicating that it has not handled the event). diff --git a/src/gui/painting/qoutlinemapper_p.h b/src/gui/painting/qoutlinemapper_p.h index f64d03b..d534f76 100644 --- a/src/gui/painting/qoutlinemapper_p.h +++ b/src/gui/painting/qoutlinemapper_p.h @@ -95,8 +95,8 @@ public: m_tags(0), m_contours(0), m_polygon_dev(0), - m_round_coords(false), - m_in_clip_elements(false) + m_in_clip_elements(false), + m_round_coords(false) { } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index d17c711..71bc990 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -2391,6 +2391,8 @@ void QPainter::setCompositionMode(CompositionMode mode) qWarning("QPainter::setCompositionMode: Painter not active"); return; } + if (d->state->composition_mode == mode) + return; if (d->extended) { d->state->composition_mode = mode; d->extended->compositionModeChanged(); diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index 883f511..ada5293 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -884,7 +884,7 @@ void QCleanlooksStyle::drawPrimitive(PrimitiveElement elem, } painter->restore(); break; -#ifndef QT_NO_LINEDIT +#ifndef QT_NO_LINEEDIT case PE_FrameLineEdit: // fall through #endif // QT_NO_LINEEDIT diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index c742455..91a6612 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -421,7 +421,7 @@ namespace { class DrawTextItemRecorder: public QPaintEngine { public: - DrawTextItemRecorder(bool untransformedCoordinates, bool useBackendOptimizations, int numChars) + DrawTextItemRecorder(bool untransformedCoordinates, bool useBackendOptimizations) : m_dirtyPen(false), m_useBackendOptimizations(useBackendOptimizations), m_untransformedCoordinates(untransformedCoordinates) { @@ -518,11 +518,10 @@ namespace { class DrawTextItemDevice: public QPaintDevice { public: - DrawTextItemDevice(bool untransformedCoordinates, bool useBackendOptimizations, - int numChars) + DrawTextItemDevice(bool untransformedCoordinates, bool useBackendOptimizations) { m_paintEngine = new DrawTextItemRecorder(untransformedCoordinates, - useBackendOptimizations, numChars); + useBackendOptimizations); } ~DrawTextItemDevice() @@ -664,7 +663,7 @@ void QStaticTextPrivate::init() position = QPointF(0, 0); - DrawTextItemDevice device(untransformedCoordinates, useBackendOptimizations, text.size()); + DrawTextItemDevice device(untransformedCoordinates, useBackendOptimizations); { QPainter painter(&device); painter.setFont(font); diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 48aee8f..e0386f1 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -127,6 +127,8 @@ bool Qt::mightBeRichText(const QString& text) tag += text[i]; else if (!tag.isEmpty() && text[i].isSpace()) break; + else if (!tag.isEmpty() && text[i] == QLatin1Char('/') && i + 1 == close) + break; else if (!text[i].isSpace() && (!tag.isEmpty() || text[i] != QLatin1Char('!'))) return false; // that's not a tag } diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index ac1fffd..60195a8 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -2670,7 +2670,7 @@ QTextItemInt::QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFo QTextItemInt::QTextItemInt(const QGlyphLayout &g, QFont *font, QFontEngine *fe) : flags(0), justified(false), underlineStyle(QTextCharFormat::NoUnderline), - num_chars(0), chars(0), logClusters(0), f(font), fontEngine(fe), glyphs(g) + num_chars(0), chars(0), logClusters(0), f(font), glyphs(g), fontEngine(fe) { } diff --git a/tests/auto/qpixmap/loadFromData/designer_argb32.png b/tests/auto/qpixmap/loadFromData/designer_argb32.png Binary files differnew file mode 100644 index 0000000..55d8247 --- /dev/null +++ b/tests/auto/qpixmap/loadFromData/designer_argb32.png diff --git a/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.gif b/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.gif Binary files differnew file mode 100644 index 0000000..26a6da3 --- /dev/null +++ b/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.gif diff --git a/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.png b/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.png Binary files differnew file mode 100644 index 0000000..28cd2f0 --- /dev/null +++ b/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.png diff --git a/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.gif b/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.gif Binary files differnew file mode 100644 index 0000000..49ec77b --- /dev/null +++ b/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.gif diff --git a/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.png b/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.png Binary files differnew file mode 100644 index 0000000..09735a9 --- /dev/null +++ b/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.png diff --git a/tests/auto/qpixmap/loadFromData/designer_rgb32.jpg b/tests/auto/qpixmap/loadFromData/designer_rgb32.jpg Binary files differnew file mode 100644 index 0000000..70f39c2 --- /dev/null +++ b/tests/auto/qpixmap/loadFromData/designer_rgb32.jpg diff --git a/tests/auto/qpixmap/loadFromData/designer_rgb32.png b/tests/auto/qpixmap/loadFromData/designer_rgb32.png Binary files differnew file mode 100644 index 0000000..bca471d --- /dev/null +++ b/tests/auto/qpixmap/loadFromData/designer_rgb32.png diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 49b1e52..179f068 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -172,6 +172,9 @@ private slots: void fromData(); void loadFromDataNullValues(); + void loadFromDataImage_data(); + void loadFromDataImage(); + void preserveDepth(); void splash_crash(); @@ -1540,6 +1543,40 @@ void tst_QPixmap::loadFromDataNullValues() } } +void tst_QPixmap::loadFromDataImage_data() +{ + QTest::addColumn<QString>("imagePath"); +#ifdef Q_OS_SYMBIAN + const QString prefix = QLatin1String(SRCDIR) + "loadFromData"; +#else + const QString prefix = QLatin1String(SRCDIR) + "/loadFromData"; +#endif + QTest::newRow("designer_argb32.png") << prefix + "/designer_argb32.png"; + QTest::newRow("designer_indexed8_no_alpha.png") << prefix + "/designer_indexed8_no_alpha.png"; + QTest::newRow("designer_indexed8_with_alpha.png") << prefix + "/designer_indexed8_with_alpha.png"; + QTest::newRow("designer_rgb32.png") << prefix + "/designer_rgb32.png"; + QTest::newRow("designer_indexed8_no_alpha.gif") << prefix + "/designer_indexed8_no_alpha.gif"; + QTest::newRow("designer_indexed8_with_alpha.gif") << prefix + "/designer_indexed8_with_alpha.gif"; + QTest::newRow("designer_rgb32.jpg") << prefix + "/designer_rgb32.jpg"; +} + +void tst_QPixmap::loadFromDataImage() +{ + QFETCH(QString, imagePath); + + QImage imageRef(imagePath); + QPixmap pixmapWithCopy = QPixmap::fromImage(imageRef); + + QFile file(imagePath); + file.open(QIODevice::ReadOnly); + QByteArray rawData = file.readAll(); + + QPixmap directLoadingPixmap; + directLoadingPixmap.loadFromData(rawData); + + QVERIFY(pixmapsAreEqual(&pixmapWithCopy, &directLoadingPixmap)); +} + void tst_QPixmap::task_246446() { // This crashed without the bugfix in 246446 diff --git a/tests/auto/qtextdocument/tst_qtextdocument.cpp b/tests/auto/qtextdocument/tst_qtextdocument.cpp index 51aee74..808299b 100644 --- a/tests/auto/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/qtextdocument/tst_qtextdocument.cpp @@ -98,6 +98,7 @@ private slots: void noundo_isModified2(); void noundo_isModified3(); void mightBeRichText(); + void mightBeRichText_data(); void task240325(); @@ -679,13 +680,32 @@ void tst_QTextDocument::noundo_isModified3() QVERIFY(doc->isModified()); } -void tst_QTextDocument::mightBeRichText() +void tst_QTextDocument::mightBeRichText_data() { const char qtDocuHeader[] = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" "<!DOCTYPE html\n" " PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n" "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">"; QVERIFY(Qt::mightBeRichText(QString::fromLatin1(qtDocuHeader))); + QTest::addColumn<QString>("input"); + QTest::addColumn<bool>("result"); + + QTest::newRow("documentation-header") << QString("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" + "<!DOCTYPE html\n" + " PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n" + "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">") + << true; + QTest::newRow("br-nospace") << QString("Test <br/> new line") << true; + QTest::newRow("br-space") << QString("Test <br /> new line") << true; + QTest::newRow("br-invalidspace") << QString("Test <br/ > new line") << false; + QTest::newRow("invalid closing tag") << QString("Test <br/ line") << false; +} + +void tst_QTextDocument::mightBeRichText() +{ + QFETCH(QString, input); + QFETCH(bool, result); + QVERIFY(result == Qt::mightBeRichText(input)); } Q_DECLARE_METATYPE(QTextDocumentFragment) diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp index e80f948..96eb772 100644 --- a/tools/qdoc3/ditaxmlgenerator.cpp +++ b/tools/qdoc3/ditaxmlgenerator.cpp @@ -1402,20 +1402,20 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark QList<Section> sections; QList<Section>::ConstIterator s; - const ClassNode* cn = 0; - const NamespaceNode *namespasse = 0; + ClassNode* cn = 0; + NamespaceNode* namespasse = 0; QString title; QString rawTitle; QString fullTitle; if (inner->type() == Node::Namespace) { - namespasse = static_cast<const NamespaceNode *>(inner); + namespasse = static_cast<const NamespaceNode*>(inner); rawTitle = marker->plainName(inner); fullTitle = marker->plainFullName(inner); title = rawTitle + " Namespace"; } else if (inner->type() == Node::Class) { - cn = static_cast<const ClassNode *>(inner); + cn = static_cast<const ClassNode*>(inner); rawTitle = marker->plainName(inner); fullTitle = marker->plainFullName(inner); title = rawTitle + " Class Reference"; @@ -4583,12 +4583,11 @@ void DitaXmlGenerator::writeFunctions(const Section& s, NodeList::ConstIterator m = s.members.begin(); while (m != s.members.end()) { if ((*m)->type() == Node::Function) { - const FunctionNode* fn = reinterpret_cast<const FunctionNode*>(*m); - QString name = fn->name(); + FunctionNode* fn = static_cast<const FunctionNode*>(*m); writer.writeStartElement(CXXFUNCTION); - writeGuidAttribute(name); + writer.writeAttribute("id",fn->guid()); writer.writeStartElement(APINAME); - writer.writeCharacters(name); + writer.writeCharacters(fn->name()); writer.writeEndElement(); // </apiName> generateBrief(fn,marker); writer.writeStartElement(CXXFUNCTIONDETAIL); @@ -4662,11 +4661,14 @@ void DitaXmlGenerator::writeFunctions(const Section& s, writer.writeCharacters(fnl); writer.writeEndElement(); // <cxxFunctionNameLookup> - //writer.writeStartElement(CXXFUNCTIONREIMPLEMENTED); - //writer.writeAttribute("href", zzz); - //writer.writeCharacters(); - //writer.writeEndElement(); // </cxxFunctionReimplemented> - + if (fn->isReimp() && fn->reimplementedFrom() != 0) { + FunctionNode* rfn = (FunctionNode*)fn->reimplementedFrom(); + writer.writeStartElement(CXXFUNCTIONREIMPLEMENTED); + writer.writeAttribute("href",rfn->ditaXmlHref()); + writer.writeCharacters(marker->plainFullName(rfn)); + writer.writeEndElement(); // </cxxFunctionReimplemented> + } + writeParameters(fn,marker); writeLocation(fn, marker); writer.writeEndElement(); // <cxxFunctionDefinition> writer.writeStartElement(APIDESC); @@ -4689,6 +4691,32 @@ void DitaXmlGenerator::writeFunctions(const Section& s, } } +void DitaXmlGenerator::writeParameters(FunctionNode* fn, CodeMarker* marker) +{ + const QList<Parameter>& parameters = fn->parameters(); + if (!parameters.isEmpty()) { + writer.writeStartElement(CXXFUNCTIONPARAMETERS); + QList<Parameter>::ConstIterator p = parameters.begin(); + while (p != parameters.end()) { + writer.writeStartElement(CXXFUNCTIONPARAMETER); + writer.writeStartElement(CXXFUNCTIONPARAMETERDECLAREDTYPE); + writer.writeCharacters((*p).leftType()); + writer.writeEndElement(); // <cxxFunctionParameterDeclaredType> + writer.writeStartElement(CXXFUNCTIONPARAMETERDECLARATIONNAME); + writer.writeCharacters((*p).name()); + writer.writeEndElement(); // <cxxFunctionParameterDeclarationName> + if (!(*p).defaultValue().isEmpty()) { + writer.writeStartElement(CXXFUNCTIONPARAMETERDEFAULTVALUE); + writer.writeCharacters((*p).defaultValue()); + writer.writeEndElement(); // <cxxFunctionParameterDefaultValue> + } + writer.writeEndElement(); // <cxxFunctionParameter> + ++p; + } + writer.writeEndElement(); // <cxxFunctionParameters> + } +} + void DitaXmlGenerator::writeNestedClasses(const Section& s, const ClassNode* cn, CodeMarker* marker) diff --git a/tools/qdoc3/ditaxmlgenerator.h b/tools/qdoc3/ditaxmlgenerator.h index 71304b3..e8ad8ba 100644 --- a/tools/qdoc3/ditaxmlgenerator.h +++ b/tools/qdoc3/ditaxmlgenerator.h @@ -117,6 +117,7 @@ class DitaXmlGenerator : public PageGenerator void writeFunctions(const Section& s, const ClassNode* cn, CodeMarker* marker); + void writeParameters(FunctionNode* fn, CodeMarker* marker); void writeNestedClasses(const Section& s, const ClassNode* cn, CodeMarker* marker); diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index 2a03fd2..06681cb 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -101,7 +101,7 @@ Node::Node(Type type, InnerNode *parent, const QString& name) { if (par) par->addChild(this); - uuid = QUuid::createUuid(); + //uuid = QUuid::createUuid(); } /*! @@ -241,20 +241,32 @@ QString Node::fileBase() const return base.toLower(); } -/*! \fnQUuid Node::guid() const +/*! Returns this node's Universally Unique IDentifier. If its UUID has not yet been created, it is created first. */ +QUuid Node::guid() +{ + if (uuid.isNull()) + uuid = QUuid::createUuid(); + return uuid; +} /*! Composes a string to be used as an href attribute in DITA XML. It is composed of the file name and the UUID separated - by a '#' + by a '#'. If this node is a class node, the file name is + taken from this node; if this node is a function node, the + file name is taken from the parent node of this node. */ QString Node::ditaXmlHref() { - QString href = fileBase(); + QString href; + if (type() == Function) + href = parent()->fileBase(); + else + href = fileBase(); if (!href.endsWith(".xml")) href += ".xml"; return href + "#" + guid(); diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h index 44cdac2..4d1e757 100644 --- a/tools/qdoc3/node.h +++ b/tools/qdoc3/node.h @@ -191,7 +191,8 @@ class Node void clearRelated() { rel = 0; } virtual QString fileBase() const; - QUuid guid() const { return uuid; } + //QUuid guid() const { return uuid; } + QUuid guid(); QString ditaXmlHref(); protected: |