diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com> | 2014-10-16 16:57:08 +0200 |
---|---|---|
committer | Jani Heikkinen <jani.heikkinen@theqtcompany.com> | 2014-11-13 19:58:28 +0100 |
commit | dd08a22a4e8d7120341a1227e227de3f0628dd2f (patch) | |
tree | 6130ebf44600d5ec579752f617d9189875e7bb0b | |
parent | dd6e14a7df6e40ff8b9ffe22fe6124630a15bda0 (diff) |
-rw-r--r-- | src/quick/items/qquicktext.cpp | 45 | ||||
-rw-r--r-- | src/quick/items/qquicktext_p.h | 1 | ||||
-rw-r--r-- | src/quick/items/qquicktext_p_p.h | 1 | ||||
-rw-r--r-- | src/quick/items/qquicktextedit.cpp | 31 | ||||
-rw-r--r-- | src/quick/items/qquicktextedit_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquicktextinput.cpp | 27 | ||||
-rw-r--r-- | src/quick/items/qquicktextinput_p.h | 4 |
7 files changed, 108 insertions, 3 deletions
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index bfa2fccd67..87255f4bd9 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -79,6 +79,7 @@ QQuickTextPrivate::QQuickTextPrivate() , requireImplicitSize(false), implicitWidthValid(false), implicitHeightValid(false) , truncated(false), hAlignImplicit(true), rightToLeftText(false) , layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false), formatModifiesFontSize(false) + , polishSize(false) { implicitAntialiasing = true; } @@ -356,6 +357,8 @@ void QQuickTextPrivate::updateLayout() textHasChanged = true; updateLayout(); } + + q->polish(); } void QQuickText::imageDownloadFinished() @@ -2248,13 +2251,22 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data node->addImage(QRectF(img->pos.x() + dx, img->pos.y() + dy, pix->width(), pix->height()), pix->image()); } } + + // The font caches have now been initialized on the render thread, so they have to be + // invalidated before we can use them from the main thread again. + invalidateFontCaches(); + return node; } void QQuickText::updatePolish() { Q_D(QQuickText); - d->updateSize(); + if (d->polishSize) { + d->updateSize(); + d->polishSize = false; + } + invalidateFontCaches(); } /*! @@ -2381,6 +2393,7 @@ void QQuickText::setFontSizeMode(FontSizeMode mode) if (d->fontSizeMode() == mode) return; + d->polishSize = true; polish(); d->extra.value().fontSizeMode = mode; @@ -2409,8 +2422,10 @@ void QQuickText::setMinimumPixelSize(int size) if (d->minimumPixelSize() == size) return; - if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid())) + if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid())) { + d->polishSize = true; polish(); + } d->extra.value().minimumPixelSize = size; emit minimumPixelSizeChanged(); } @@ -2437,8 +2452,10 @@ void QQuickText::setMinimumPointSize(int size) if (d->minimumPointSize() == size) return; - if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid())) + if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid())) { + d->polishSize = true; polish(); + } d->extra.value().minimumPointSize = size; emit minimumPointSizeChanged(); } @@ -2699,4 +2716,26 @@ QString QQuickText::linkAt(qreal x, qreal y) const return d->anchorAt(QPointF(x, y)); } +/*! + * \internal + * + * Invalidates font caches owned by the text objects owned by the element + * to work around the fact that text objects cannot be used from multiple threads. + */ +void QQuickText::invalidateFontCaches() +{ + Q_D(QQuickText); + + if (d->richText && d->extra->doc != 0) { + QTextBlock block; + for (block = d->extra->doc->firstBlock(); block.isValid(); block = block.next()) { + if (block.layout() != 0 && block.layout()->engine() != 0) + block.layout()->engine()->resetFontEngineCache(); + } + } else { + if (d->layout.engine() != 0) + d->layout.engine()->resetFontEngineCache(); + } +} + QT_END_NAMESPACE diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h index c9f64d3fab..c3fa9e6935 100644 --- a/src/quick/items/qquicktext_p.h +++ b/src/quick/items/qquicktext_p.h @@ -245,6 +245,7 @@ protected: void hoverEnterEvent(QHoverEvent *event); void hoverMoveEvent(QHoverEvent *event); void hoverLeaveEvent(QHoverEvent *event); + void invalidateFontCaches(); private Q_SLOTS: void q_imagesLoaded(); diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h index 022c2ac9d5..d645ce5ed5 100644 --- a/src/quick/items/qquicktext_p_p.h +++ b/src/quick/items/qquicktext_p_p.h @@ -151,6 +151,7 @@ public: bool textHasChanged:1; bool needToUpdateLayout:1; bool formatModifiesFontSize:1; + bool polishSize:1; // Workaround for problem with polish called after updateSize (QTBUG-42636) static const QChar elideChar; diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index aca7150ca2..b950f96277 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -1739,6 +1739,7 @@ void QQuickTextEdit::triggerPreprocess() Q_D(QQuickTextEdit); if (d->updateType == QQuickTextEditPrivate::UpdateNone) d->updateType = QQuickTextEditPrivate::UpdateOnlyPreprocess; + polish(); update(); } @@ -1758,6 +1759,25 @@ static inline void updateNodeTransform(QQuickTextNode* node, const QPointF &topL node->setMatrix(transformMatrix); } +/*! + * \internal + * + * Invalidates font caches owned by the text objects owned by the element + * to work around the fact that text objects cannot be used from multiple threads. + */ +void QQuickTextEdit::invalidateFontCaches() +{ + Q_D(QQuickTextEdit); + if (d->document == 0) + return; + + QTextBlock block; + for (block = d->document->firstBlock(); block.isValid(); block = block.next()) { + if (block.layout() != 0 && block.layout()->engine() != 0) + block.layout()->engine()->resetFontEngineCache(); + } +} + QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) { Q_UNUSED(updatePaintNodeData); @@ -1911,9 +1931,16 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * rootNode->resetCursorNode(cursor); } + invalidateFontCaches(); + return rootNode; } +void QQuickTextEdit::updatePolish() +{ + invalidateFontCaches(); +} + /*! \qmlproperty bool QtQuick::TextEdit::canPaste @@ -2079,6 +2106,7 @@ void QQuickTextEdit::q_contentsChange(int pos, int charsRemoved, int charsAdded) markDirtyNodesForRange(pos, editRange, delta); + polish(); if (isComponentComplete()) { d->updateType = QQuickTextEditPrivate::UpdatePaintNode; update(); @@ -2106,6 +2134,7 @@ void QQuickTextEdit::updateSelection() // No need for node updates when we go from an empty selection to another empty selection if (d->control->textCursor().hasSelection() || d->hadSelection) { markDirtyNodesForRange(qMin(d->lastSelectionStart, d->control->textCursor().selectionStart()), qMax(d->control->textCursor().selectionEnd(), d->lastSelectionEnd), 0); + polish(); if (isComponentComplete()) { d->updateType = QQuickTextEditPrivate::UpdatePaintNode; update(); @@ -2246,6 +2275,7 @@ void QQuickTextEdit::updateWholeDocument() node->setDirty(); } + polish(); if (isComponentComplete()) { d->updateType = QQuickTextEditPrivate::UpdatePaintNode; update(); @@ -2260,6 +2290,7 @@ void QQuickTextEdit::invalidateBlock(const QTextBlock &block) void QQuickTextEdit::updateCursor() { Q_D(QQuickTextEdit); + polish(); if (isComponentComplete()) { d->updateType = QQuickTextEditPrivate::UpdatePaintNode; update(); diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h index 54e6dd229a..5d1c026c5c 100644 --- a/src/quick/items/qquicktextedit_p.h +++ b/src/quick/items/qquicktextedit_p.h @@ -330,6 +330,7 @@ private Q_SLOTS: private: void markDirtyNodesForRange(int start, int end, int charDelta); void updateTotalLines(); + void invalidateFontCaches(); protected: virtual void geometryChanged(const QRectF &newGeometry, @@ -354,6 +355,7 @@ protected: void inputMethodEvent(QInputMethodEvent *e); #endif QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData); + void updatePolish(); friend class QQuickTextUtil; friend class QQuickTextDocument; diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 1f03fb21e2..a9c60273d2 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -56,6 +56,8 @@ #include "qquickaccessibleattached_p.h" #endif +#include <QtGui/private/qtextengine_p.h> + QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) @@ -362,6 +364,7 @@ void QQuickTextInput::setColor(const QColor &c) d->color = c; d->textLayoutDirty = true; d->updateType = QQuickTextInputPrivate::UpdatePaintNode; + polish(); update(); emit colorChanged(); } @@ -389,6 +392,7 @@ void QQuickTextInput::setSelectionColor(const QColor &color) if (d->hasSelectedText()) { d->textLayoutDirty = true; d->updateType = QQuickTextInputPrivate::UpdatePaintNode; + polish(); update(); } emit selectionColorChanged(); @@ -414,6 +418,7 @@ void QQuickTextInput::setSelectedTextColor(const QColor &color) if (d->hasSelectedText()) { d->textLayoutDirty = true; d->updateType = QQuickTextInputPrivate::UpdatePaintNode; + polish(); update(); } emit selectedTextColorChanged(); @@ -723,6 +728,7 @@ void QQuickTextInput::setCursorVisible(bool on) if (!d->cursorItem) { d->setCursorBlinkPeriod(on ? qApp->styleHints()->cursorFlashTime() : 0); d->updateType = QQuickTextInputPrivate::UpdatePaintNode; + polish(); update(); } emit cursorVisibleChanged(d->cursorVisible); @@ -1830,9 +1836,23 @@ void QQuickTextInput::triggerPreprocess() Q_D(QQuickTextInput); if (d->updateType == QQuickTextInputPrivate::UpdateNone) d->updateType = QQuickTextInputPrivate::UpdateOnlyPreprocess; + polish(); update(); } +void QQuickTextInput::updatePolish() +{ + invalidateFontCaches(); +} + +void QQuickTextInput::invalidateFontCaches() +{ + Q_D(QQuickTextInput); + + if (d->m_textLayout.engine() != 0) + d->m_textLayout.engine()->resetFontEngineCache(); +} + QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) { Q_UNUSED(data); @@ -1891,6 +1911,8 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData d->textLayoutDirty = false; } + invalidateFontCaches(); + return node; } @@ -2651,6 +2673,7 @@ void QQuickTextInput::updateCursorRectangle(bool scroll) d->updateVerticalScroll(); } d->updateType = QQuickTextInputPrivate::UpdatePaintNode; + polish(); update(); emit cursorRectangleChanged(); if (d->cursorItem) { @@ -2668,6 +2691,7 @@ void QQuickTextInput::selectionChanged() Q_D(QQuickTextInput); d->textLayoutDirty = true; //TODO: Only update rect in selection d->updateType = QQuickTextInputPrivate::UpdatePaintNode; + polish(); update(); emit selectedTextChanged(); @@ -2879,6 +2903,7 @@ void QQuickTextInputPrivate::updateLayout() contentSize = QSizeF(width, height); updateType = UpdatePaintNode; + q->polish(); q->update(); if (!requireImplicitWidth && !q->widthValid()) @@ -4167,6 +4192,7 @@ void QQuickTextInputPrivate::setCursorBlinkPeriod(int msec) m_blinkTimer = 0; if (m_blinkStatus == 1) { updateType = UpdatePaintNode; + q->polish(); q->update(); } } @@ -4179,6 +4205,7 @@ void QQuickTextInput::timerEvent(QTimerEvent *event) if (event->timerId() == d->m_blinkTimer) { d->m_blinkStatus = !d->m_blinkStatus; d->updateType = QQuickTextInputPrivate::UpdatePaintNode; + polish(); update(); } else if (event->timerId() == d->m_passwordEchoTimer.timerId()) { d->m_passwordEchoTimer.stop(); diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h index 4b94530587..2386fc5642 100644 --- a/src/quick/items/qquicktextinput_p.h +++ b/src/quick/items/qquicktextinput_p.h @@ -314,6 +314,9 @@ Q_SIGNALS: #endif void renderTypeChanged(); +private: + void invalidateFontCaches(); + protected: virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); @@ -332,6 +335,7 @@ protected: void focusInEvent(QFocusEvent *event); void timerEvent(QTimerEvent *event); QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data); + void updatePolish(); public Q_SLOTS: void selectAll(); |