From a8c3ed1dbe209488866e687d1a63c6143a04cfe0 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 23 Dec 2009 10:38:56 +0100 Subject: Fix text rendering on GL2 paint engine If you draw with a brush, then draw a pixmap, then draw with the same brush, the GL2 engine wouldn't update the fragment shader to use the brush. This is because it detected the brush hadn't changed and so didn't need updating. To fix this, we now set the current brush to noBrush when drawing an image/pixmap so the engine knows it needs to update the GL state for the brush. Reviewed-By: Kim --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 15 ++++++++++----- src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index f52ed92..32fa3dc 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -388,21 +388,24 @@ inline QColor qt_premultiplyColor(QColor c, GLfloat opacity) void QGL2PaintEngineExPrivate::setBrush(const QBrush& brush) { - Q_ASSERT(brush.style() != Qt::NoBrush); - if (qbrush_fast_equals(currentBrush, brush)) return; + const Qt::BrushStyle newStyle = qbrush_style(brush); + Q_ASSERT(newStyle != Qt::NoBrush); + currentBrush = brush; + brushUniformsDirty = true; // All brushes have at least one uniform + + if (newStyle > Qt::SolidPattern) + brushTextureDirty = true; - brushTextureDirty = true; - brushUniformsDirty = true; if (currentBrush.style() == Qt::TexturePattern && qHasPixmapTexture(brush) && brush.texture().isQBitmap()) { shaderManager->setSrcPixelType(QGLEngineShaderManager::TextureSrcWithPattern); } else { - shaderManager->setSrcPixelType(currentBrush.style()); + shaderManager->setSrcPixelType(newStyle); } shaderManager->optimiseForBrushTransform(currentBrush.transform()); } @@ -700,6 +703,7 @@ static inline void setCoords(GLfloat *coords, const QGLRect &rect) void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern) { // Setup for texture drawing + currentBrush = noBrush; shaderManager->setSrcPixelType(pattern ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc); if (prepareForDraw(opaque)) shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT); @@ -1782,6 +1786,7 @@ void QGL2PaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int d state()->renderHints & QPainter::SmoothPixmapTransform, texture->id); // Setup for texture drawing + d->currentBrush = d->noBrush; d->shaderManager->setSrcPixelType(isBitmap ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc); if (d->prepareForDraw(isOpaque)) d->shaderManager->currentProgram()->setUniformValue(d->location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index f1ec6e6..8de4a82 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -244,6 +244,7 @@ public: uint maxClip; QBrush currentBrush; // May not be the state's brush! + const QBrush noBrush; GLfloat inverseScale; -- cgit v0.12 From d2f10dae860cea0de33b4cb9005ba8d2203ce1d1 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 12 Oct 2009 15:34:36 +0200 Subject: QImageReader: Avoid errorString creation in the normal case Deploy the same idiom found in QIODevice::errorString(). Return "Unknown Error" in case of am empty string. This is a tiny improvement for QtWebKit. Reviewed-by: Andreas --- src/gui/image/qimagereader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 074f3eb..4fb07fb 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -471,7 +471,6 @@ QImageReaderPrivate::QImageReaderPrivate(QImageReader *qq) handler = 0; quality = -1; imageReaderError = QImageReader::UnknownError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unknown error")); q = qq; } @@ -1302,6 +1301,8 @@ QImageReader::ImageReaderError QImageReader::error() const */ QString QImageReader::errorString() const { + if (d->errorString.isEmpty()) + return QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unknown error")); return d->errorString; } -- cgit v0.12 From 5c0a117f62607ed439cdfa3d94aaef627c47ce8a Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 15 Oct 2009 05:21:30 +0200 Subject: png: Avoid calling QImage::scanLine(int) from within a loop Reviewed-by: Andreas --- src/gui/image/qpnghandler.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 14c863b..1de0f32 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -67,6 +67,9 @@ QT_BEGIN_NAMESPACE # define Q_INTERNAL_WIN_NO_THROW #endif +// avoid going through QImage::scanLine() which calls detach +#define FAST_SCAN_LINE(data, bpl, y) (data + (y) * bpl) + /* All PNG files load to the minimal QImage equivalent. @@ -510,7 +513,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngImage(QImage *outImage) && outImage->format() == QImage::Format_Indexed8) { int color_table_size = outImage->colorCount(); for (int y=0; y<(int)height; ++y) { - uchar *p = outImage->scanLine(y); + uchar *p = FAST_SCAN_LINE(data, bpl, y); uchar *end = p + width; while (p < end) { if (*p >= color_table_size) -- cgit v0.12 From 3de151493f75dc52e693f84ef66ff1a86c79d8e3 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 13 Oct 2009 02:59:32 +0200 Subject: gif: 10% speedup on microbenchmark on QImageReader On the microbenchmark of what is executed during pure pageloading in regarding to QImageReader this is an improvement. Do not use the non const QImage::scanLine as this will go through the QImage::detach all the time making QImage::scanLine show up in the profile. Introduce a FAST_SCAN_LINE that is doing the scanLine calculation on local variables. Reviewed-by: Andreas --- src/plugins/imageformats/gif/qgifhandler.cpp | 40 ++++++++++++++++++---------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/plugins/imageformats/gif/qgifhandler.cpp b/src/plugins/imageformats/gif/qgifhandler.cpp index c95b63c..dee0e52 100644 --- a/src/plugins/imageformats/gif/qgifhandler.cpp +++ b/src/plugins/imageformats/gif/qgifhandler.cpp @@ -54,6 +54,10 @@ QT_BEGIN_NAMESPACE #define Q_TRANSPARENT 0x00ffffff +// avoid going through QImage::scanLine() which calls detach +#define FAST_SCAN_LINE(bits, bpl, y) (bits + (y) * bpl) + + /* Incremental image decoder for GIF image format. @@ -135,7 +139,7 @@ private: int frame; bool out_of_bounds; bool digress; - void nextY(QImage *image); + void nextY(unsigned char *bits, int bpl); void disposePrevious(QImage *image); }; @@ -232,6 +236,10 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, // CompuServe Incorporated. GIF(sm) is a Service Mark property of // CompuServe Incorporated." + image->detach(); + int bpl = image->bytesPerLine(); + unsigned char *bits = image->bits(); + #define LM(l, m) (((m)<<8)|l) digress = false; const int initial = length; @@ -335,7 +343,9 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, QImage::Format format = trans_index >= 0 ? QImage::Format_ARGB32 : QImage::Format_RGB32; if (image->isNull()) { (*image) = QImage(swidth, sheight, format); - memset(image->bits(), 0, image->byteCount()); + bpl = image->bytesPerLine(); + bits = image->bits(); + memset(bits, 0, image->byteCount()); // ### size of the upcoming frame, should rather // be known before decoding it. @@ -393,11 +403,13 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, backingstore = QImage(qMax(backingstore.width(), w), qMax(backingstore.height(), h), QImage::Format_RGB32); - memset(image->bits(), 0, image->byteCount()); + memset(bits, 0, image->byteCount()); } + const int dest_bpl = backingstore.bytesPerLine(); + unsigned char *dest_data = backingstore.bits(); for (int ln=0; lnscanLine(t+ln)+l, w*sizeof(QRgb)); + memcpy(FAST_SCAN_LINE(dest_data, dest_bpl, ln), + FAST_SCAN_LINE(bits, bpl, t+ln) + l, w*sizeof(QRgb)); } } @@ -470,14 +482,14 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, if (needfirst) { firstcode=oldcode=code; if (!out_of_bounds && image->height() > y && firstcode!=trans_index) - ((QRgb*)image->scanLine(y))[x] = color(firstcode); + ((QRgb*)FAST_SCAN_LINE(bits, bpl, y))[x] = color(firstcode); x++; if (x>=swidth) out_of_bounds = true; needfirst=false; if (x>=left+width) { x=left; out_of_bounds = left>=swidth || y>=sheight; - nextY(image); + nextY(bits, bpl); } } else { incode=code; @@ -515,7 +527,7 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, const QRgb *map = lcmap ? localcmap : globalcmap; QRgb *line = 0; if (!out_of_bounds && h > y) - line = (QRgb*)image->scanLine(y); + line = (QRgb*)FAST_SCAN_LINE(bits, bpl, y); while (sp>stack) { const uchar index = *(--sp); if (!out_of_bounds && h > y && index!=trans_index) { @@ -529,9 +541,9 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, if (x>=left+width) { x=left; out_of_bounds = left>=swidth || y>=sheight; - nextY(image); + nextY(bits, bpl); if (!out_of_bounds && h > y) - line = (QRgb*)image->scanLine(y); + line = (QRgb*)FAST_SCAN_LINE(bits, bpl, y); } } } @@ -644,7 +656,7 @@ void QGIFFormat::fillRect(QImage *image, int col, int row, int w, int h, QRgb co } } -void QGIFFormat::nextY(QImage *image) +void QGIFFormat::nextY(unsigned char *bits, int bpl) { int my; switch (interlace) { @@ -660,7 +672,7 @@ void QGIFFormat::nextY(QImage *image) // Don't dup with transparency if (trans_index < 0) { for (i=1; i<=my; i++) { - memcpy(image->scanLine(y+i)+left*sizeof(QRgb), image->scanLine(y)+left*sizeof(QRgb), + memcpy(FAST_SCAN_LINE(bits, bpl, y+i)+left*sizeof(QRgb), FAST_SCAN_LINE(bits, bpl, y)+left*sizeof(QRgb), (right-left+1)*sizeof(QRgb)); } } @@ -689,7 +701,7 @@ void QGIFFormat::nextY(QImage *image) // Don't dup with transparency if (trans_index < 0) { for (i=1; i<=my; i++) { - memcpy(image->scanLine(y+i)+left*sizeof(QRgb), image->scanLine(y)+left*sizeof(QRgb), + memcpy(FAST_SCAN_LINE(bits, bpl, y+i)+left*sizeof(QRgb), FAST_SCAN_LINE(bits, bpl, y)+left*sizeof(QRgb), (right-left+1)*sizeof(QRgb)); } } @@ -713,7 +725,7 @@ void QGIFFormat::nextY(QImage *image) // Don't dup with transparency if (trans_index < 0) { for (i=1; i<=my; i++) { - memcpy(image->scanLine(y+i)+left*sizeof(QRgb), image->scanLine(y)+left*sizeof(QRgb), + memcpy(FAST_SCAN_LINE(bits, bpl, y+i)+left*sizeof(QRgb), FAST_SCAN_LINE(bits, bpl, y)+left*sizeof(QRgb), (right-left+1)*sizeof(QRgb)); } } -- cgit v0.12 From b7d95c36f432f65d54343bf51e39e0b8b1d2d656 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 14 Dec 2009 09:05:37 +0100 Subject: gif: Add unit test for QImageReader::size calls Verify that QImageReader::size is not consuming a frame and can be called before each frame and that the last frame will return a QSize of (-1x-1). Task-number: QTBUG-6696 Reviewed-by: Andreas --- tests/auto/qimagereader/images/four-frames.gif | Bin 0 -> 427 bytes tests/auto/qimagereader/qimagereader.qrc | 2 + tests/auto/qimagereader/tst_qimagereader.cpp | 131 +++++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 tests/auto/qimagereader/images/four-frames.gif diff --git a/tests/auto/qimagereader/images/four-frames.gif b/tests/auto/qimagereader/images/four-frames.gif new file mode 100644 index 0000000..6aff2e0 Binary files /dev/null and b/tests/auto/qimagereader/images/four-frames.gif differ diff --git a/tests/auto/qimagereader/qimagereader.qrc b/tests/auto/qimagereader/qimagereader.qrc index 11b9406..58f2f74 100644 --- a/tests/auto/qimagereader/qimagereader.qrc +++ b/tests/auto/qimagereader/qimagereader.qrc @@ -57,5 +57,7 @@ images/qt6.gif images/qt7.gif images/qt8.gif + images/endless-anim.gif + images/four-frames.gif diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp index 630cc03..3f9d005 100644 --- a/tests/auto/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/qimagereader/tst_qimagereader.cpp @@ -141,6 +141,7 @@ private slots: #if defined QTEST_HAVE_GIF void gifHandlerBugs(); void animatedGif(); + void gifImageCount(); #endif void readCorruptImage_data(); @@ -739,6 +740,136 @@ void tst_QImageReader::animatedGif() image = io.read(); } } + +// http://bugreports.qt.nokia.com/browse/QTBUG-6696 +// Check the count of images in various call orders... +void tst_QImageReader::gifImageCount() +{ + // just read every frame... and see how much we got.. + { + QImageReader io(":images/four-frames.gif"); + + QVERIFY(io.canRead()); + QImage blackFrame = io.read(); + + QVERIFY(io.canRead()); + QImage whiteFrame = io.read(); + + QVERIFY(io.canRead()); + QImage greenFrame = io.read(); + + QVERIFY(io.canRead()); + QImage blueFrame = io.read(); + + QVERIFY(!io.canRead()); + QImage emptyFrame = io.read(); + + QVERIFY(!io.canRead()); + QCOMPARE(blackFrame.pixel(0,0), qRgb(0, 0, 0)); + QCOMPARE(blackFrame.size(), QSize(64,64)); + + QCOMPARE(whiteFrame.pixel(0,0), qRgb(0xff, 0xff, 0xff)); + QCOMPARE(whiteFrame.size(), QSize(64,64)); + + QCOMPARE(greenFrame.pixel(0,0), qRgb(0x0, 0xff, 0x0)); + QCOMPARE(greenFrame.size(), QSize(64,64)); + + QCOMPARE(blueFrame.pixel(0,0), qRgb(0x0, 0x0, 0xff)); + QCOMPARE(blueFrame.size(), QSize(64,64)); + QVERIFY(emptyFrame.isNull()); + } + + // Read and get the size + { + QImageReader io(":images/four-frames.gif"); + + QVERIFY(io.canRead()); + QCOMPARE(io.size(), QSize(64,64)); + + QVERIFY(io.canRead()); + QCOMPARE(io.size(), QSize(64,64)); + QCOMPARE(io.size(), QSize(64,64)); + QVERIFY(io.canRead()); + QImage blackFrame = io.read(); + + QVERIFY(io.canRead()); + QCOMPARE(io.size(), QSize(64,64)); + QCOMPARE(io.size(), QSize(64,64)); + QVERIFY(io.canRead()); + QImage whiteFrame = io.read(); + + QVERIFY(io.canRead()); + QCOMPARE(io.size(), QSize(64,64)); + QCOMPARE(io.size(), QSize(64,64)); + QVERIFY(io.canRead()); + QImage greenFrame = io.read(); + + QVERIFY(io.canRead()); + QCOMPARE(io.size(), QSize(64,64)); + QCOMPARE(io.size(), QSize(64,64)); + QVERIFY(io.canRead()); + QImage blueFrame = io.read(); + + QVERIFY(!io.canRead()); + QCOMPARE(io.size(), QSize()); + QCOMPARE(io.size(), QSize()); + QVERIFY(!io.canRead()); + QImage emptyFrame = io.read(); + + QVERIFY(!io.canRead()); + QCOMPARE(blackFrame.pixel(0,0), qRgb(0, 0, 0)); + QCOMPARE(blackFrame.size(), QSize(64,64)); + + QCOMPARE(whiteFrame.pixel(0,0), qRgb(0xff, 0xff, 0xff)); + QCOMPARE(whiteFrame.size(), QSize(64,64)); + + QCOMPARE(greenFrame.pixel(0,0), qRgb(0x0, 0xff, 0x0)); + QCOMPARE(greenFrame.size(), QSize(64,64)); + + QCOMPARE(blueFrame.pixel(0,0), qRgb(0x0, 0x0, 0xff)); + QCOMPARE(blueFrame.size(), QSize(64,64)); + QVERIFY(emptyFrame.isNull()); + } + + // Do a Size query as substitute for canRead + { + QImageReader io(":images/four-frames.gif"); + + QCOMPARE(io.size(), QSize(64,64)); + QCOMPARE(io.size(), QSize(64,64)); + QImage blackFrame = io.read(); + + QCOMPARE(io.size(), QSize(64,64)); + QCOMPARE(io.size(), QSize(64,64)); + QImage whiteFrame = io.read(); + + QCOMPARE(io.size(), QSize(64,64)); + QCOMPARE(io.size(), QSize(64,64)); + QImage greenFrame = io.read(); + + QCOMPARE(io.size(), QSize(64,64)); + QCOMPARE(io.size(), QSize(64,64)); + QImage blueFrame = io.read(); + + QCOMPARE(io.size(), QSize()); + QVERIFY(!io.canRead()); + QImage emptyFrame = io.read(); + + QVERIFY(!io.canRead()); + QCOMPARE(blackFrame.pixel(0,0), qRgb(0, 0, 0)); + QCOMPARE(blackFrame.size(), QSize(64,64)); + + QCOMPARE(whiteFrame.pixel(0,0), qRgb(0xff, 0xff, 0xff)); + QCOMPARE(whiteFrame.size(), QSize(64,64)); + + QCOMPARE(greenFrame.pixel(0,0), qRgb(0x0, 0xff, 0x0)); + QCOMPARE(greenFrame.size(), QSize(64,64)); + + QCOMPARE(blueFrame.pixel(0,0), qRgb(0x0, 0x0, 0xff)); + QCOMPARE(blueFrame.size(), QSize(64,64)); + QVERIFY(emptyFrame.isNull()); + } +} #endif class Server : public QObject -- cgit v0.12 From 6d9d6bf4b66127f7f24d22efa2fe6c24d05b3724 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 11 Oct 2009 04:12:47 +0200 Subject: images: Document QImageReader::loopCount behaviour for infinite loops The gif and mng reader will return -1 as QImageReader::loopCount() for infinite images. Document that this -1 is clashing with the error handling of this method. The documentation was mixing the default and error cases. In some cases "Otherwise -1" and "Otherwise 0" was used. Change this to mention the default coming from QImageIOHandler in the "Otherwise" clause and document the error case with -1. Add a test case to check that loopCount() returns -1 for infinite animations. Reviewed-by: Andreas --- src/gui/image/qimagereader.cpp | 22 ++++++++++++++-------- tests/auto/qimagereader/images/endless-anim.gif | Bin 0 -> 819 bytes tests/auto/qimagereader/tst_qimagereader.cpp | 7 +++++++ 3 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 tests/auto/qimagereader/images/endless-anim.gif diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 4fb07fb..c5aa28b 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -1214,10 +1214,12 @@ bool QImageReader::jumpToImage(int imageNumber) /*! For image formats that support animation, this function returns - the number of times the animation should loop. Otherwise, it - returns -1. + the number of times the animation should loop. In case of an + infinite animation or an error -1 is returned. To differentiate + an infinite animation from an error, canRead() should be called + before this function. - \sa supportsAnimation(), QImageIOHandler::loopCount() + \sa supportsAnimation(), QImageIOHandler::loopCount(), canRead() */ int QImageReader::loopCount() const { @@ -1231,9 +1233,9 @@ int QImageReader::loopCount() const the total number of images in the animation. Certain animation formats do not support this feature, in which - case 0 is returned. + case 0 is returned. In case of an error -1 is returned. - \sa supportsAnimation(), QImageIOHandler::imageCount() + \sa supportsAnimation(), QImageIOHandler::imageCount(), canRead() */ int QImageReader::imageCount() const { @@ -1247,7 +1249,9 @@ int QImageReader::imageCount() const the number of milliseconds to wait until displaying the next frame in the animation. Otherwise, 0 is returned. - \sa supportsAnimation(), QImageIOHandler::nextImageDelay() + In case of an error -1 is returned. + + \sa supportsAnimation(), QImageIOHandler::nextImageDelay(), canRead() */ int QImageReader::nextImageDelay() const { @@ -1258,10 +1262,12 @@ int QImageReader::nextImageDelay() const /*! For image formats that support animation, this function returns - the sequence number of the current frame. Otherwise, -1 is + the sequence number of the current frame. Otherwise, 0 is returned. - \sa supportsAnimation(), QImageIOHandler::currentImageNumber() + In case of an error -1 is returned. + + \sa supportsAnimation(), QImageIOHandler::currentImageNumber(), canRead() */ int QImageReader::currentImageNumber() const { diff --git a/tests/auto/qimagereader/images/endless-anim.gif b/tests/auto/qimagereader/images/endless-anim.gif new file mode 100644 index 0000000..00df8da Binary files /dev/null and b/tests/auto/qimagereader/images/endless-anim.gif differ diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp index 3f9d005..8cfaac5 100644 --- a/tests/auto/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/qimagereader/tst_qimagereader.cpp @@ -726,6 +726,13 @@ void tst_QImageReader::gifHandlerBugs() QVERIFY(!im1.isNull()); QVERIFY(!im2.isNull()); QCOMPARE(im1.convertToFormat(QImage::Format_ARGB32), im2.convertToFormat(QImage::Format_ARGB32)); } + + // Check the undocumented feature. + { + QImageReader io(prefix + "endless-anim.gif"); + QVERIFY(io.canRead()); + QCOMPARE(io.loopCount(), -1); + } } void tst_QImageReader::animatedGif() -- cgit v0.12 From 51b042f821f593808290e049e49f2f8bcd611fb0 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 23 Dec 2009 10:33:29 +0100 Subject: Docs: Amendments to latest changes to QImageReader docs. Reviewed-by: Holger Hans Peter Freyther --- src/gui/image/qimagereader.cpp | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index c5aa28b..7580446 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -1213,11 +1213,10 @@ bool QImageReader::jumpToImage(int imageNumber) } /*! - For image formats that support animation, this function returns - the number of times the animation should loop. In case of an - infinite animation or an error -1 is returned. To differentiate - an infinite animation from an error, canRead() should be called - before this function. + For image formats that support animation, this function returns the number + of times the animation should loop. If this function returns -1, it can + either mean the animation should loop forever, or that an error occurred. + If an error occurred, canRead() will return false. \sa supportsAnimation(), QImageIOHandler::loopCount(), canRead() */ @@ -1229,11 +1228,11 @@ int QImageReader::loopCount() const } /*! - For image formats that support animation, this function returns - the total number of images in the animation. + For image formats that support animation, this function returns the total + number of images in the animation. If the format does not support + animation, 0 is returned. - Certain animation formats do not support this feature, in which - case 0 is returned. In case of an error -1 is returned. + This function returns -1 if an error occurred. \sa supportsAnimation(), QImageIOHandler::imageCount(), canRead() */ @@ -1245,11 +1244,11 @@ int QImageReader::imageCount() const } /*! - For image formats that support animation, this function returns - the number of milliseconds to wait until displaying the next frame - in the animation. Otherwise, 0 is returned. + For image formats that support animation, this function returns the number + of milliseconds to wait until displaying the next frame in the animation. + If the image format doesn't support animation, 0 is returned. - In case of an error -1 is returned. + This function returns -1 if an error occurred. \sa supportsAnimation(), QImageIOHandler::nextImageDelay(), canRead() */ @@ -1261,11 +1260,11 @@ int QImageReader::nextImageDelay() const } /*! - For image formats that support animation, this function returns - the sequence number of the current frame. Otherwise, 0 is - returned. + For image formats that support animation, this function returns the + sequence number of the current frame. If the image format doesn't support + animation, 0 is returned. - In case of an error -1 is returned. + This function returns -1 if an error occurred. \sa supportsAnimation(), QImageIOHandler::currentImageNumber(), canRead() */ -- cgit v0.12 From 0e03f6bbfd003d354c603a1a89b961e5f0d3769c Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Fri, 18 Dec 2009 10:08:45 -0800 Subject: Get rid of no_cast_from_ascii warning --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 4744eb6..8126fca 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1063,7 +1063,7 @@ static inline bool setIntOption(const QStringList &arguments, const QString &var static inline QColor colorFromName(const QString &name) { - QRegExp rx("#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])"); + QRegExp rx(QLatin1String("#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])")); rx.setCaseSensitivity(Qt::CaseInsensitive); if (rx.exactMatch(name)) { Q_ASSERT(rx.captureCount() == 4); -- cgit v0.12 From d27006b2a853924a11aa2bc45590c2c5c5fcfafa Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Fri, 18 Dec 2009 10:06:48 -0800 Subject: Read QWS_SIZE from layer rather than screen When running the X11 emulator of DirectFB IDirectFBScreen->GetSize returns the size of the entire X11 Display, not the actual DirectFB window. We can read this from the primary layer instead and this value is correct both on devices and on the desktop. Reviewed-by: Donald Carr --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 8126fca..bb26d29 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1278,7 +1278,14 @@ bool QDirectFBScreen::connect(const QString &displaySpec) #ifdef QT_NO_DIRECTFB_WM result = d_ptr->primarySurface->GetSize(d_ptr->primarySurface, &w, &h); #elif (Q_DIRECTFB_VERSION >= 0x010000) - result = d_ptr->dfbScreen->GetSize(d_ptr->dfbScreen, &w, &h); + IDirectFBSurface *layerSurface; + if (d_ptr->dfbLayer->GetSurface(d_ptr->dfbLayer, &layerSurface) != DFB_OK) { + result = layerSurface->GetSize(layerSurface, &w, &h); + layerSurface->Release(layerSurface); + } + if (w <= 0 || h <= 0) { + result = d_ptr->dfbScreen->GetSize(d_ptr->dfbScreen, &w, &h); + } #else qWarning("QDirectFBScreen::connect: DirectFB versions prior to 1.0 do not offer a way\n" "query the size of the primary surface in windowed mode. You have to specify\n" -- cgit v0.12 From e416e8b439c7949faeeda5fda6edae2211e63eb2 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Wed, 23 Dec 2009 14:56:34 +0100 Subject: revert f36fb8b2b63b3734cc2bd66b329ca4fef1204845 as discussed at #qt-labs special dirs should be hidden on unix to preserve qt3-like behavior unhiding those dirs was not a good idea and now i do revert of my changes Merge-request: 1894 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_unix.cpp | 5 ++--- src/corelib/io/qfsfileengine_win.cpp | 9 +++------ tests/auto/qfileinfo/tst_qfileinfo.cpp | 8 ++------ 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 71414ce..ea262bf 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -825,10 +825,9 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const ret |= RootFlag; } else { QString baseName = fileName(BaseName); - if ((baseName.size() > 1 - && baseName.at(0) == QLatin1Char('.') && baseName.at(1) != QLatin1Char('.')) + if ((baseName.size() > 0 && baseName.at(0) == QLatin1Char('.')) # if !defined(QWS) && defined(Q_OS_MAC) - || _q_isMacHidden(d->filePath) + || _q_isMacHidden(d->filePath) # endif ) { ret |= HiddenFlag; diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index a6cb5a9..a7719a8 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1595,13 +1595,10 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil ret |= LocalDiskFlag; if (d->doStat()) { ret |= ExistsFlag; - if (d->filePath == QLatin1String("/") || isDriveRoot(d->filePath) || isUncRoot(d->filePath)) { + if (d->filePath == QLatin1String("/") || isDriveRoot(d->filePath) || isUncRoot(d->filePath)) ret |= RootFlag; - } else if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN) { - QString baseName = fileName(BaseName); - if (baseName != QLatin1String(".") && baseName != QLatin1String("..")) - ret |= HiddenFlag; - } + else if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN) + ret |= HiddenFlag; } } return ret; diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 1445f5b..84ea52b 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -1083,13 +1083,9 @@ void tst_QFileInfo::isHidden_data() && !QDir().mkdir("./.hidden-directory")) qWarning("Unable to create directory './.hidden-directory'. Some tests will fail."); - QTest::newRow("./.hidden-directory") << QString("./.hidden-directory") << true; - QTest::newRow("./.hidden-directory/.") << QString("./.hidden-directory/.") << false; - QTest::newRow("./.hidden-directory/..") << QString("./.hidden-directory/..") << false; - QTest::newRow("/path/to/.hidden-directory") << QDir::currentPath() + QString("/.hidden-directory") << true; - QTest::newRow("/path/to/.hidden-directory/.") << QDir::currentPath() + QString("/.hidden-directory/.") << false; - QTest::newRow("/path/to/.hidden-directory/..") << QDir::currentPath() + QString("/.hidden-directory/..") << false; + QTest::newRow("/path/to/.hidden-directory/.") << QDir::currentPath() + QString("/.hidden-directory/.") << true; + QTest::newRow("/path/to/.hidden-directory/..") << QDir::currentPath() + QString("/.hidden-directory/..") << true; #endif #if defined(Q_OS_MAC) -- cgit v0.12