diff options
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 2 | ||||
-rw-r--r-- | src/gui/image/qimage.cpp | 4 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 25 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 5 | ||||
-rw-r--r-- | tests/auto/qpointer/tst_qpointer.cpp | 32 | ||||
-rw-r--r-- | tests/auto/qtextlayout/tst_qtextlayout.cpp | 19 |
6 files changed, 78 insertions, 9 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 7fe9c52..c3102ea 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -408,6 +408,8 @@ void QMetaObject::removeGuard(QObject **ptr) if (!hash || hash->isEmpty()) return; QMutexLocker locker(guardHashLock()); + if (!*ptr) //check again, under the lock + return; GuardHash::iterator it = hash->find(*ptr); const GuardHash::iterator end = hash->end(); bool more = false; //if the QObject has more pointer attached to it. diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index bb94788c..897cb64 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -2018,11 +2018,11 @@ void QImage::fill(Qt::GlobalColor color) Fills the entire image with the given \a color. If the depth of the image is 1, the image will be filled with 1 if - \a color equals Qt::color0; it will otherwise be filled with 0. + \a color equals Qt::color1; it will otherwise be filled with 0. If the depth of the image is 8, the image will be filled with the index corresponding the \a color in the color table if present; it - will otherwise be filled with 0.| + will otherwise be filled with 0. \since 4.8 */ diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 546861a..e8db049 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -151,6 +151,13 @@ static inline uint line_emulation(uint emulation) | QPaintEngine_OpaqueBackground); } +static bool qt_paintengine_supports_transformations(QPaintEngine::Type type) +{ + return type == QPaintEngine::OpenGL2 + || type == QPaintEngine::OpenVG + || type == QPaintEngine::OpenGL; +} + #ifndef QT_NO_DEBUG static bool qt_painter_thread_test(int devType, const char *what, bool extraCondition = false) { @@ -5795,8 +5802,17 @@ void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs) int count = qMin(glyphIndexes.size(), glyphPositions.size()); QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count); - for (int i=0; i<count; ++i) - fixedPointPositions[i] = QFixedPoint::fromPointF(position + glyphPositions.at(i)); + + bool paintEngineSupportsTransformations = + d->extended != 0 + ? qt_paintengine_supports_transformations(d->extended->type()) + : false; + for (int i=0; i<count; ++i) { + QPointF processedPosition = position + glyphPositions.at(i); + if (!paintEngineSupportsTransformations) + processedPosition = d->state->transform().map(processedPosition); + fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition); + } d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count); @@ -5988,10 +6004,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText return; } - bool paintEngineSupportsTransformations = d->extended->type() == QPaintEngine::OpenGL2 - || d->extended->type() == QPaintEngine::OpenVG - || d->extended->type() == QPaintEngine::OpenGL; - + bool paintEngineSupportsTransformations = qt_paintengine_supports_transformations(d->extended->type()); if (paintEngineSupportsTransformations && !staticText_d->untransformedCoordinates) { staticText_d->untransformedCoordinates = true; staticText_d->needsRelayout = true; diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 06eed55..96379e6 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1233,6 +1233,8 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const shaper_item.num_glyphs -= itemBoundaries[k + 1]; } shaper_item.initialGlyphCount = shaper_item.num_glyphs; + if (shaper_item.num_glyphs < shaper_item.item.length) + shaper_item.num_glyphs = shaper_item.item.length; QFontEngine *actualFontEngine = font; uint engineIdx = 0; @@ -1257,7 +1259,8 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const } const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos); - moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); + if (shaper_item.num_glyphs > shaper_item.item.length) + moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); shaper_item.glyphs = g.glyphs; shaper_item.attributes = g.attributes; diff --git a/tests/auto/qpointer/tst_qpointer.cpp b/tests/auto/qpointer/tst_qpointer.cpp index 5a07e41..ce23764 100644 --- a/tests/auto/qpointer/tst_qpointer.cpp +++ b/tests/auto/qpointer/tst_qpointer.cpp @@ -73,6 +73,7 @@ private slots: void castDuringDestruction(); void data() const; void dataSignature() const; + void threadSafety(); }; tst_QPointer::tst_QPointer() @@ -345,5 +346,36 @@ void tst_QPointer::dataSignature() const } } +class TestRunnable : public QObject, public QRunnable { + void run() { + QPointer<QObject> obj1 = new QObject; + QPointer<QObject> obj2 = new QObject; + obj1->moveToThread(thread()); // this is the owner thread + obj1->deleteLater(); // the delete will happen in the owner thread + obj2->moveToThread(thread()); // this is the owner thread + obj2->deleteLater(); // the delete will happen in the owner thread + } +}; + +void tst_QPointer::threadSafety() +{ + + QThread owner; + owner.start(); + + QThreadPool pool; + for (int i = 0; i < 300; i++) { + QPointer<TestRunnable> task = new TestRunnable; + task->setAutoDelete(true); + task->moveToThread(&owner); + pool.start(task); + } + pool.waitForDone(); + + owner.quit(); + owner.wait(); +} + + QTEST_MAIN(tst_QPointer) #include "tst_qpointer.moc" diff --git a/tests/auto/qtextlayout/tst_qtextlayout.cpp b/tests/auto/qtextlayout/tst_qtextlayout.cpp index dcc43d0..4f4413f 100644 --- a/tests/auto/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/qtextlayout/tst_qtextlayout.cpp @@ -125,6 +125,7 @@ private slots: void lineWidthFromBOM(); void textWidthVsWIdth(); + void textWithSurrogates_qtbug15679(); private: QFont testFont; @@ -1412,6 +1413,24 @@ void tst_QTextLayout::textWidthVsWIdth() } } +void tst_QTextLayout::textWithSurrogates_qtbug15679() +{ + QString str = QString::fromUtf8("🀀a🀀"); + QTextLayout layout(str); + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + + qreal x[6]; + for (int i = 0; i < 6; i++) + x[i] = line.cursorToX(i); + + // If the first and third character are using the same + // font, they must have the same advance (since they + // are surrogate pairs, we need to add two for each + // character) + QCOMPARE(x[2] - x[0], x[5] - x[3]); +} QTEST_MAIN(tst_QTextLayout) #include "tst_qtextlayout.moc" |