From 4cff91c66207b870e12365421e63cd978e162e64 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 8 Oct 2010 10:55:54 +0200 Subject: Fix infinite loop when justifying undisplayable Arabic text If the Arabic text is for some reason undisplayable, e.g. because of QTBUG-13132, the font engine will be unable to find the tatweel character and the kashida width may be returned as 0. This would potentially cause an infinite loop, as "need" would remain >= minKashida forever because x - 0 is still >= 0. Task-number: QTBUG-13130 Reviewed-by: Lars --- src/gui/text/qtextengine.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 05de8f5..3bd6122 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1949,9 +1949,11 @@ void QTextEngine::justify(const QScriptLine &line) if (kashida_pos >= 0) { // qDebug("kashida position at %d in word", kashida_pos); set(&justificationPoints[nPoints], kashida_type, g.mid(kashida_pos), fontEngine(si)); - minKashida = qMin(minKashida, justificationPoints[nPoints].kashidaWidth); - maxJustify = qMax(maxJustify, justificationPoints[nPoints].type); - ++nPoints; + if (justificationPoints[nPoints].kashidaWidth > 0) { + minKashida = qMin(minKashida, justificationPoints[nPoints].kashidaWidth); + maxJustify = qMax(maxJustify, justificationPoints[nPoints].type); + ++nPoints; + } } kashida_pos = -1; kashida_type = HB_Arabic_Normal; @@ -1975,9 +1977,11 @@ void QTextEngine::justify(const QScriptLine &line) } if (kashida_pos >= 0) { set(&justificationPoints[nPoints], kashida_type, g.mid(kashida_pos), fontEngine(si)); - minKashida = qMin(minKashida, justificationPoints[nPoints].kashidaWidth); - maxJustify = qMax(maxJustify, justificationPoints[nPoints].type); - ++nPoints; + if (justificationPoints[nPoints].kashidaWidth > 0) { + minKashida = qMin(minKashida, justificationPoints[nPoints].kashidaWidth); + maxJustify = qMax(maxJustify, justificationPoints[nPoints].type); + ++nPoints; + } } } -- cgit v0.12 From 4d974ff0a748b22e668a4cb7ef38101122c85b3b Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Fri, 8 Oct 2010 14:21:10 +0200 Subject: Avoid in-place convertion of images with multiple references The decoding from image reader was assuming the image reader do not keep the image internally. This is not true for the GIF plugins because the previous image can be used to compose the current image. This was causing crash on ARM because the 16 bits color depth causes the image memory to be reduce by half. When the plugin was accessing the memory, it assumes the images has not changed and is on 32 bits. This patch disable the in-place conversion if a detach is required. Regular conversion is the correct solution in this case, and it can also be made faster by converting while copying. Reviewed-by: Andreas Kling --- src/gui/image/qimage.cpp | 4 ++++ tests/auto/qpixmap/tst_qpixmap.cpp | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index ac148ee..1157b93 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -6607,6 +6607,10 @@ bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFla if (format == newFormat) return true; + // No in-place conversion if we have to detach + if (ref > 1) + return false; + const InPlace_Image_Converter *const converterPtr = &inplace_converter_map[format][newFormat]; InPlace_Image_Converter converter = *converterPtr; if (converter) diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 8005ec5..24cbb21 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -179,6 +179,7 @@ private slots: void fromImageReader_data(); void fromImageReader(); + void fromImageReaderAnimatedGif_data(); void fromImageReaderAnimatedGif(); void preserveDepth(); @@ -1605,6 +1606,8 @@ void tst_QPixmap::fromImageReader_data() 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"; + QTest::newRow("designer_indexed8_with_alpha_animated") << prefix + "/designer_indexed8_with_alpha_animated.gif"; + QTest::newRow("designer_indexed8_with_alpha_animated") << prefix + "/designer_indexed8_no_alpha_animated.gif"; } void tst_QPixmap::fromImageReader() @@ -1621,14 +1624,22 @@ void tst_QPixmap::fromImageReader() QVERIFY(pixmapsAreEqual(&pixmapWithCopy, &directLoadingPixmap)); } +void tst_QPixmap::fromImageReaderAnimatedGif_data() +{ + QTest::addColumn("imagePath"); + QTest::newRow("gif with alpha") << QString::fromLatin1("/designer_indexed8_with_alpha_animated.gif"); + QTest::newRow("gif without alpha") << QString::fromLatin1("/designer_indexed8_no_alpha_animated.gif"); +} + void tst_QPixmap::fromImageReaderAnimatedGif() { + QFETCH(QString, imagePath); #ifdef Q_OS_SYMBIAN const QString prefix = QLatin1String(SRCDIR) + "loadFromData"; #else const QString prefix = QLatin1String(SRCDIR) + "/loadFromData"; #endif - const QString path = prefix + QString::fromLatin1("/designer_indexed8_with_alpha_animated.gif"); + const QString path = prefix + imagePath; QImageReader referenceReader(path); QImageReader pixmapReader(path); -- cgit v0.12