summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qobject.cpp2
-rw-r--r--src/gui/image/qimage.cpp4
-rw-r--r--src/gui/painting/qpainter.cpp25
-rw-r--r--src/gui/text/qtextengine.cpp5
-rw-r--r--tests/auto/qpointer/tst_qpointer.cpp32
-rw-r--r--tests/auto/qtextlayout/tst_qtextlayout.cpp19
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"