From: Eskil Abrahamsen Blomfeldt Date: Thu, 5 May 2011 14:49:06 +0000 (+0200) Subject: Fix potential crash when displaying multiscripted text X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=27c5aabe9bd9d4881262312588ece7713de67ad4;p=konrad%2Fqtdeclarative.git Fix potential crash when displaying multiscripted text Shaping has to be done in the current thread, otherwise the font engines index for each glyph (referenced in the msb of the glyph index) might not be valid yet, because the font engines list is populated when shaping is done. So we need to make sure that the render thread relayouts. Geometry changes will already cause a relayout, which will in turn cause another relayout when the paint node is updated. There doesn't seem to be any convenient and safe way of avoiding this doubling of the layout step if we want to have rendering in a different thread than the QML graph. Reviewed-by: Gunnar --- diff --git a/src/declarative/items/qsgtext.cpp b/src/declarative/items/qsgtext.cpp index f2ec7b2..e7e655d 100644 --- a/src/declarative/items/qsgtext.cpp +++ b/src/declarative/items/qsgtext.cpp @@ -106,7 +106,7 @@ QSGTextPrivate::QSGTextPrivate() imageCacheDirty(true), updateOnComponentComplete(true), richText(false), singleline(false), cacheAllTextAsImage(true), internalWidthUpdate(false), requireImplicitWidth(false), truncated(false), hAlignImplicit(true), rightToLeftText(false), - layoutTextElided(false), naturalWidth(0), doc(0), nodeType(NodeIsNull) + layoutTextElided(false), naturalWidth(0), doc(0), layoutThread(0), nodeType(NodeIsNull) { cacheAllTextAsImage = enableImageCache(); } @@ -378,6 +378,8 @@ QRect QSGTextPrivate::setupTextLayout() bool elideText = false; bool truncate = false; + layoutThread = QThread::currentThread(); + QFontMetrics fm(layout.font()); elidePos = QPointF(); @@ -1070,6 +1072,10 @@ QSGNode *QSGText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) QRectF bounds = boundingRect(); + // We need to make sure the layout is done in the current thread + if (d->layoutThread != QThread::currentThread()) + d->updateLayout(); + // XXX todo - some styled text can be done by the QSGTextNode if (richTextAsImage || d->cacheAllTextAsImage || (!QSGDistanceFieldGlyphCache::distanceFieldEnabled() && d->style != Normal)) { bool wasDirty = d->imageCacheDirty; diff --git a/src/declarative/items/qsgtext_p_p.h b/src/declarative/items/qsgtext_p_p.h index 8d26394..a3836a1 100644 --- a/src/declarative/items/qsgtext_p_p.h +++ b/src/declarative/items/qsgtext_p_p.h @@ -134,6 +134,7 @@ public: QPixmap textLayoutImage(bool drawStyle); void drawTextLayout(QPainter *p, const QPointF &pos, bool drawStyle); QTextLayout layout; + QThread *layoutThread; static QPixmap drawOutline(const QPixmap &source, const QPixmap &styleSource); static QPixmap drawOutline(const QPixmap &source, const QPixmap &styleSource, int yOffset);