From fac227f609e544f8f55aca8447b4328d6534407a Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 17 Jun 2010 07:43:41 +0200 Subject: Speed up calls to QPainter::setCompositionMode when the mode is unchanged Avoid marking the composition mode as dirty and calling into the extended engine if the composition mode that the application wants to set is the same that's currently used. Reviewed-by: Gunnar --- src/gui/painting/qpainter.cpp | 2 ++ 1 file changed, 2 insertions(+) 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(); -- cgit v0.12 From 594900e68f8e264facbe8c75eaf2b857240bc072 Mon Sep 17 00:00:00 2001 From: Geir Vattekar Date: Thu, 17 Jun 2010 09:11:18 +0200 Subject: Doc: Specified QAbstractEventDispatcher::filterEvent()'s argument types. Task-number: QTBUG-10904 Reviewed-by: Morten Engvoldsen --- src/corelib/kernel/qabstracteventdispatcher.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) 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) -- cgit v0.12 From e4fbdd4fde9b8d2acc13268b44caa57405c3db1a Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 17 Jun 2010 10:24:49 +0200 Subject: Typo in qcleanlooksstyle.cpp Task-number: QTBUG-11506 --- src/gui/styles/qcleanlooksstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 -- cgit v0.12 From cf74e83d8b79c4840c073bb7dc387045b1210df8 Mon Sep 17 00:00:00 2001 From: Geir Vattekar Date: Thu, 17 Jun 2010 11:14:59 +0200 Subject: Doc: Small change to QAbstractItemDelegate::editorEvent() Task-number: QTBUG-2446 Reviewed-by: Marius Bugge Monsen --- src/gui/itemviews/qabstractitemdelegate.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) 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). -- cgit v0.12 From 4cdeac4d4780e163eee3a1916683766f16747f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 17 Jun 2010 10:38:06 +0200 Subject: Optimized QPixmap::fromImage for raster pixmaps. If we know that the QImage is ARGB32 or ARGB32_Premultiplied and doesn't contain any alpha pixels we can treat it as RGB32 when doing the conversion. Reviewed-by: Gunnar Sletta --- src/gui/image/qpixmap_raster.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 9dc15fc..4f32d2f 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -192,10 +192,23 @@ void QRasterPixmapData::fromImage(const QImage &sourceImage, } #endif - if (!sourceImage.hasAlphaChannel() - || ((flags & Qt::NoOpaqueDetection) == 0 - && !const_cast(sourceImage).data_ptr()->checkForAlphaPixels())) { + if (!sourceImage.hasAlphaChannel()) { image = sourceImage.convertToFormat(opaqueFormat); + } else if ((flags & Qt::NoOpaqueDetection) == 0 + && !const_cast(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) + { + QImage rgbImage(sourceImage.bits(), sourceImage.width(), sourceImage.height(), + QImage::Format_RGB32); + image = rgbImage.convertToFormat(opaqueFormat); + image.detach(); + } else { + image = sourceImage.convertToFormat(opaqueFormat); + } } else { image = sourceImage.convertToFormat(alphaFormat); } -- cgit v0.12 From 21f5de51e0c49006f5be75ef64675145b9d8b5c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 17 Jun 2010 10:59:31 +0200 Subject: Don't do opaque detection when copying a sub-rect of a QPixmap. If the pixmap is non-opaque in the first place most likely a reasonably sized sub-rect is also non-opaque, so this check is a waste in 90 % of the cases. Reviewed-by: Gunnar Sletta --- src/gui/image/qpixmapdata.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) -- cgit v0.12 From cf5971503ee1f7a5ce96758e33796dfdf48375bf Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 18 Jun 2010 16:01:54 +0200 Subject: Fix a possible crash with the EVR video renderer in windows This can happn when the component can be instanciated but not all the services are available on it. The code is now more robust. Reviewed-By: gabi --- src/3rdparty/phonon/ds9/videorenderer_evr.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 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 ret; ComPointer getService(filter, IID_IMFGetService); - Q_ASSERT(getService); - T *ptr = 0; - HRESULT hr = getService->GetService(guidService, riid, reinterpret_cast(&ptr)); - if (!SUCCEEDED(hr) || ptr == 0) - Q_ASSERT(!SUCCEEDED(hr) && ptr != 0); - ComPointer service(ptr); - return service; + if (getService) { + getService->GetService(guidService, riid, reinterpret_cast(ret.pparam())); + } + return ret; } VideoRendererEVR::~VideoRendererEVR() @@ -70,6 +68,10 @@ namespace Phonon } ComPointer filterControl = getService(m_filter, MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl); + if (!filterControl) { + m_filter = Filter(); //will release the interface + return; + } filterControl->SetVideoWindow(reinterpret_cast(target->winId())); filterControl->SetAspectRatioMode(MFVideoARMode_None); // We're in control of the size -- cgit v0.12 From 0a96503e84b418708712af61497df4a493ed9072 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Sat, 19 Jun 2010 21:56:29 +0200 Subject: Start the implementation of in-place recoding for images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, with the graphics system raster, converting from images to QPixmap often needs to allocate a new image to convert the right format. For example, for an image in ARGB32 of 10 mbytes, we need to allocate a second image of 10 mbytes in ARGB32_PM to convert the source image in the right format for pixmap. This can create a hight peak of memory, and is a bit slower than it should. This patch introduce in-place conversion of images when they are loaded with QPixmap::loadFromData(). The images are loaded in their default format by QImageReader, and are then converted in-place, trying to reduce memory allocations. Reviewed-by: Samuel Rødal --- src/gui/image/qimage.cpp | 274 +++++++++++++++++++++ src/gui/image/qimage_p.h | 3 + src/gui/image/qpixmap_raster.cpp | 214 +++++++++------- src/gui/image/qpixmap_raster_p.h | 3 + .../auto/qpixmap/loadFromData/designer_argb32.png | Bin 0 -> 4189 bytes .../loadFromData/designer_indexed8_no_alpha.gif | Bin 0 -> 3317 bytes .../loadFromData/designer_indexed8_no_alpha.png | Bin 0 -> 2431 bytes .../loadFromData/designer_indexed8_with_alpha.gif | Bin 0 -> 2086 bytes .../loadFromData/designer_indexed8_with_alpha.png | Bin 0 -> 1405 bytes tests/auto/qpixmap/loadFromData/designer_rgb32.jpg | Bin 0 -> 11810 bytes tests/auto/qpixmap/loadFromData/designer_rgb32.png | Bin 0 -> 4282 bytes tests/auto/qpixmap/tst_qpixmap.cpp | 37 +++ 12 files changed, 436 insertions(+), 95 deletions(-) create mode 100644 tests/auto/qpixmap/loadFromData/designer_argb32.png create mode 100644 tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.gif create mode 100644 tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.png create mode 100644 tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.gif create mode 100644 tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.png create mode 100644 tests/auto/qpixmap/loadFromData/designer_rgb32.jpg create mode 100644 tests/auto/qpixmap/loadFromData/designer_rgb32.png 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(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 text; diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 4f32d2f..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 +#include +#include #include #include @@ -127,104 +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(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(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()) { - image = sourceImage.convertToFormat(opaqueFormat); - } else if ((flags & Qt::NoOpaqueDetection) == 0 - && !const_cast(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) - { - QImage rgbImage(sourceImage.bits(), sourceImage.width(), sourceImage.height(), - QImage::Format_RGB32); - image = rgbImage.convertToFormat(opaqueFormat); - image.detach(); - } else { - 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 @@ -253,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) @@ -411,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(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(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/tests/auto/qpixmap/loadFromData/designer_argb32.png b/tests/auto/qpixmap/loadFromData/designer_argb32.png new file mode 100644 index 0000000..55d8247 Binary files /dev/null and b/tests/auto/qpixmap/loadFromData/designer_argb32.png differ diff --git a/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.gif b/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.gif new file mode 100644 index 0000000..26a6da3 Binary files /dev/null and b/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.gif differ diff --git a/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.png b/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.png new file mode 100644 index 0000000..28cd2f0 Binary files /dev/null and b/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.png differ diff --git a/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.gif b/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.gif new file mode 100644 index 0000000..49ec77b Binary files /dev/null and b/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.gif differ diff --git a/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.png b/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.png new file mode 100644 index 0000000..09735a9 Binary files /dev/null and b/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.png differ diff --git a/tests/auto/qpixmap/loadFromData/designer_rgb32.jpg b/tests/auto/qpixmap/loadFromData/designer_rgb32.jpg new file mode 100644 index 0000000..70f39c2 Binary files /dev/null and b/tests/auto/qpixmap/loadFromData/designer_rgb32.jpg differ diff --git a/tests/auto/qpixmap/loadFromData/designer_rgb32.png b/tests/auto/qpixmap/loadFromData/designer_rgb32.png new file mode 100644 index 0000000..bca471d Binary files /dev/null and b/tests/auto/qpixmap/loadFromData/designer_rgb32.png differ 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("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 -- cgit v0.12 From 4363d4eebce4afd2ce3b3d6da205f8037357099a Mon Sep 17 00:00:00 2001 From: Darin Broady Date: Mon, 21 Jun 2010 11:41:04 +0200 Subject: Allow Unix to generate unique UUIDs if /dev/urandom exists. Merge-request: 629 Reviewed-by: Bradley T. Hughes --- src/corelib/plugin/quuid.cpp | 58 ++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 23 deletions(-) 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()<>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()< Date: Mon, 21 Jun 2010 12:03:49 +0200 Subject: Fix compiler warnings in QtGui (text,painting). Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/painting/qoutlinemapper_p.h | 4 ++-- src/gui/text/qstatictext.cpp | 9 ++++----- src/gui/text/qtextengine.cpp | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) 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/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/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) { } -- cgit v0.12 From 1fb24d6852e34bd58f35172dea4bfd4c41236689 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 21 Jun 2010 12:07:20 +0200 Subject: Make sure that
is seen as a valid tag in Qt::mightBeRichText() The W3C online markup validation test verifies that
is indeed valid XHTML and
is also valid so this ensures that this case is accounted for. The existing test was expanded to accout for each of these cases. Task-number: QTBUG-1786 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextdocument.cpp | 2 ++ tests/auto/qtextdocument/tst_qtextdocument.cpp | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index c7a9756..65e88ab 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/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[] = "\n" "\n" ""; QVERIFY(Qt::mightBeRichText(QString::fromLatin1(qtDocuHeader))); + QTest::addColumn("input"); + QTest::addColumn("result"); + + QTest::newRow("documentation-header") << QString("\n" + "\n" + "") + << true; + QTest::newRow("br-nospace") << QString("Test
new line") << true; + QTest::newRow("br-space") << QString("Test
new line") << true; + QTest::newRow("br-invalidspace") << QString("Test
new line") << false; + QTest::newRow("invalid closing tag") << QString("Test
Date: Mon, 21 Jun 2010 12:15:11 +0200 Subject: doc: Added more DITA output to the XML generator More cxxFunction stuff for member functions. Function parameters and other stuff. Task-number: QTBUG-11391 --- tools/qdoc3/ditaxmlgenerator.cpp | 54 ++++++++++++++++++++++++++++++---------- tools/qdoc3/ditaxmlgenerator.h | 1 + tools/qdoc3/node.cpp | 20 ++++++++++++--- tools/qdoc3/node.h | 3 ++- 4 files changed, 60 insertions(+), 18 deletions(-) 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
sections; QList
::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(inner); + namespasse = static_cast(inner); rawTitle = marker->plainName(inner); fullTitle = marker->plainFullName(inner); title = rawTitle + " Namespace"; } else if (inner->type() == Node::Class) { - cn = static_cast(inner); + cn = static_cast(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(*m); - QString name = fn->name(); + FunctionNode* fn = static_cast(*m); writer.writeStartElement(CXXFUNCTION); - writeGuidAttribute(name); + writer.writeAttribute("id",fn->guid()); writer.writeStartElement(APINAME); - writer.writeCharacters(name); + writer.writeCharacters(fn->name()); writer.writeEndElement(); // generateBrief(fn,marker); writer.writeStartElement(CXXFUNCTIONDETAIL); @@ -4662,11 +4661,14 @@ void DitaXmlGenerator::writeFunctions(const Section& s, writer.writeCharacters(fnl); writer.writeEndElement(); // - //writer.writeStartElement(CXXFUNCTIONREIMPLEMENTED); - //writer.writeAttribute("href", zzz); - //writer.writeCharacters(); - //writer.writeEndElement(); // - + 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(); // + } + writeParameters(fn,marker); writeLocation(fn, marker); writer.writeEndElement(); // writer.writeStartElement(APIDESC); @@ -4689,6 +4691,32 @@ void DitaXmlGenerator::writeFunctions(const Section& s, } } +void DitaXmlGenerator::writeParameters(FunctionNode* fn, CodeMarker* marker) +{ + const QList& parameters = fn->parameters(); + if (!parameters.isEmpty()) { + writer.writeStartElement(CXXFUNCTIONPARAMETERS); + QList::ConstIterator p = parameters.begin(); + while (p != parameters.end()) { + writer.writeStartElement(CXXFUNCTIONPARAMETER); + writer.writeStartElement(CXXFUNCTIONPARAMETERDECLAREDTYPE); + writer.writeCharacters((*p).leftType()); + writer.writeEndElement(); // + writer.writeStartElement(CXXFUNCTIONPARAMETERDECLARATIONNAME); + writer.writeCharacters((*p).name()); + writer.writeEndElement(); // + if (!(*p).defaultValue().isEmpty()) { + writer.writeStartElement(CXXFUNCTIONPARAMETERDEFAULTVALUE); + writer.writeCharacters((*p).defaultValue()); + writer.writeEndElement(); // + } + writer.writeEndElement(); // + ++p; + } + writer.writeEndElement(); // + } +} + 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: -- cgit v0.12