aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/CMakeLists.txt1
-rw-r--r--src/quick/items/qquicktext.cpp7
-rw-r--r--src/quick/items/qquicktext_p.h6
-rw-r--r--src/quick/items/qquicktextedit.cpp23
-rw-r--r--src/quick/items/qquicktextedit_p.h6
-rw-r--r--src/quick/items/qquicktextedit_p_p.h3
-rw-r--r--src/quick/items/qquicktextinput.cpp7
-rw-r--r--src/quick/items/qquicktextinput_p.h6
-rw-r--r--src/quick/items/qquicktextinterface_p.h67
-rw-r--r--src/quick/items/qquickwindow.cpp34
-rw-r--r--src/quick/items/qquickwindow.h1
-rw-r--r--src/quick/items/qquickwindow_p.h2
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp5
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h1
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp4
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h1
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp13
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h1
-rw-r--r--src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp5
-rw-r--r--src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h1
20 files changed, 187 insertions, 7 deletions
diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt
index a757ec9afa..e02698f639 100644
--- a/src/quick/CMakeLists.txt
+++ b/src/quick/CMakeLists.txt
@@ -78,6 +78,7 @@ qt_internal_add_qml_module(Quick
items/qquickstateoperations.cpp items/qquickstateoperations_p.h
items/qquicktext.cpp items/qquicktext_p.h
items/qquicktext_p_p.h
+ items/qquicktextinterface_p.h
items/qquicktextcontrol.cpp items/qquicktextcontrol_p.h
items/qquicktextcontrol_p_p.h
items/qquicktextdocument.cpp items/qquicktextdocument.h items/qquicktextdocument_p.h
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 66baa7ed7c..fd65028a16 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -3008,6 +3008,13 @@ void QQuickText::hoverLeaveEvent(QHoverEvent *event)
d->processHoverEvent(event);
}
+void QQuickText::invalidate()
+{
+ Q_D(QQuickText);
+ d->textHasChanged = true;
+ d->updateLayout();
+}
+
bool QQuickTextPrivate::transformChanged(QQuickItem *transformedItem)
{
// If there's a lot of text, we may need QQuickText::updatePaintNode() to call
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index 13d8579017..aa48467b72 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -52,6 +52,7 @@
//
#include "qquickimplicitsizeitem_p.h"
+#include "qquicktextinterface_p.h"
#include <private/qtquickglobal_p.h>
#include <QtGui/qtextoption.h>
@@ -59,9 +60,10 @@ QT_BEGIN_NAMESPACE
class QQuickTextPrivate;
class QQuickTextLine;
-class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
+class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem, public QQuickTextInterface
{
Q_OBJECT
+ Q_INTERFACES(QQuickTextInterface)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
@@ -274,6 +276,8 @@ public:
QJSValue fontInfo() const;
QSizeF advance() const;
+ void invalidate() override;
+
Q_SIGNALS:
void textChanged(const QString &text);
void linkActivated(const QString &link);
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index f739474908..814522394e 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -435,6 +435,18 @@ void QQuickTextEdit::setText(const QString &text)
setFlag(QQuickItem::ItemObservesViewport, text.size() > QQuickTextEditPrivate::largeTextSizeThreshold);
}
+void QQuickTextEdit::invalidate()
+{
+ Q_D(QQuickTextEdit);
+ if (isComponentComplete()) {
+ if (d->document != nullptr)
+ d->document->markContentsDirty(0, d->document->characterCount());
+ invalidateFontCaches();
+ d->updateType = QQuickTextEditPrivate::UpdateAll;
+ update();
+ }
+}
+
/*!
\qmlproperty string QtQuick::TextEdit::preeditText
\readonly
@@ -2078,20 +2090,25 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
Q_UNUSED(updatePaintNodeData);
Q_D(QQuickTextEdit);
- if (d->updateType != QQuickTextEditPrivate::UpdatePaintNode && oldNode != nullptr) {
+ if (d->updateType != QQuickTextEditPrivate::UpdatePaintNode
+ && d->updateType != QQuickTextEditPrivate::UpdateAll
+ && oldNode != nullptr) {
// Update done in preprocess() in the nodes
d->updateType = QQuickTextEditPrivate::UpdateNone;
return oldNode;
}
- d->updateType = QQuickTextEditPrivate::UpdateNone;
+ if (!oldNode || d->updateType == QQuickTextEditPrivate::UpdateAll) {
+ delete oldNode;
+ oldNode = nullptr;
- if (!oldNode) {
// If we had any QQuickTextNode node references, they were deleted along with the root node
// But here we must delete the Node structures in textNodeMap
d->textNodeMap.clear();
}
+ d->updateType = QQuickTextEditPrivate::UpdateNone;
+
RootNode *rootNode = static_cast<RootNode *>(oldNode);
TextNodeIterator nodeIterator = d->textNodeMap.begin();
while (nodeIterator != d->textNodeMap.end() && !nodeIterator->dirty())
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index 7b43a847c1..77f19c1cfa 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -52,6 +52,7 @@
//
#include "qquickimplicitsizeitem_p.h"
+#include "qquicktextinterface_p.h"
#include <QtGui/qtextoption.h>
@@ -61,9 +62,10 @@ class QQuickTextDocument;
class QQuickTextEditPrivate;
class QTextBlock;
-class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
+class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem, public QQuickTextInterface
{
Q_OBJECT
+ Q_INTERFACES(QQuickTextInterface)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
@@ -303,6 +305,8 @@ public:
int tabStopDistance() const;
void setTabStopDistance(qreal distance);
+ void invalidate() override;
+
Q_SIGNALS:
void textChanged();
Q_REVISION(2, 7) void preeditTextChanged();
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index 2381b46a05..da62fe8c99 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -197,7 +197,8 @@ public:
enum UpdateType {
UpdateNone,
UpdateOnlyPreprocess,
- UpdatePaintNode
+ UpdatePaintNode,
+ UpdateAll
};
QQuickTextEdit::HAlignment hAlign;
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 2a136bf8d4..b209fabf14 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -136,6 +136,13 @@ QString QQuickTextInput::text() const
return (res.isNull() ? QString::fromLatin1("") : res);
}
+void QQuickTextInput::invalidate()
+{
+ Q_D(QQuickTextInput);
+ d->updateLayout();
+ invalidateFontCaches();
+}
+
void QQuickTextInput::setText(const QString &s)
{
Q_D(QQuickTextInput);
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index 031b4780db..24c27868de 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -52,6 +52,7 @@
//
#include "qquickimplicitsizeitem_p.h"
+#include "qquicktextinterface_p.h"
#include <QtGui/qtextoption.h>
#include <QtGui/qvalidator.h>
@@ -59,9 +60,10 @@ QT_BEGIN_NAMESPACE
class QQuickTextInputPrivate;
class QValidator;
-class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
+class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem, public QQuickTextInterface
{
Q_OBJECT
+ Q_INTERFACES(QQuickTextInterface)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(int length READ length NOTIFY textChanged)
@@ -311,6 +313,8 @@ public:
void setBottomPadding(qreal padding);
void resetBottomPadding();
+ void invalidate() override;
+
Q_SIGNALS:
void textChanged();
void cursorPositionChanged();
diff --git a/src/quick/items/qquicktextinterface_p.h b/src/quick/items/qquicktextinterface_p.h
new file mode 100644
index 0000000000..da2c123abf
--- /dev/null
+++ b/src/quick/items/qquicktextinterface_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKTEXTINTERFACE_P_H
+#define QQUICKTEXTINTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class Q_QUICK_PRIVATE_EXPORT QQuickTextInterface
+{
+public:
+ virtual void invalidate() = 0;
+};
+
+#define QQuickTextInterface_iid "org.qt-project.Qt.QQuickTextInterface"
+Q_DECLARE_INTERFACE(QQuickTextInterface, QQuickTextInterface_iid)
+
+QT_END_NAMESPACE
+
+#endif // QQUICKTEXTINTERFACE_P_H
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 6e9c258fd7..c172f0ec53 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -53,6 +53,7 @@
#include <private/qquickrendercontrol_p.h>
#include <private/qquickanimatorcontroller_p.h>
#include <private/qquickprofiler_p.h>
+#include <private/qquicktextinterface_p.h>
#include <private/qguiapplication_p.h>
@@ -436,6 +437,12 @@ void QQuickWindow::physicalDpiChanged()
updatePixelRatioHelper(d->contentItem, newPixelRatio);
}
+void QQuickWindow::handleFontDatabaseChanged()
+{
+ Q_D(QQuickWindow);
+ d->pendingFontUpdate = true;
+}
+
void QQuickWindow::handleScreenChanged(QScreen *screen)
{
Q_D(QQuickWindow);
@@ -504,6 +511,17 @@ void QQuickWindowRenderTarget::reset(QRhi *rhi)
owns = false;
}
+void QQuickWindowPrivate::invalidateFontData(QQuickItem *item)
+{
+ QQuickTextInterface *textItem = qobject_cast<QQuickTextInterface *>(item);
+ if (textItem != nullptr)
+ textItem->invalidate();
+
+ QList<QQuickItem *> children = item->childItems();
+ for (QQuickItem *child : children)
+ invalidateFontData(child);
+}
+
void QQuickWindowPrivate::ensureCustomRenderTarget()
{
// resolve() can be expensive when importing an existing native texture, so
@@ -547,6 +565,12 @@ void QQuickWindowPrivate::syncSceneGraph()
emit q->beforeSynchronizing();
runAndClearJobs(&beforeSynchronizingJobs);
+
+ if (pendingFontUpdate) {
+ QFont::cleanup();
+ invalidateFontData(contentItem);
+ }
+
if (!renderer) {
forceUpdate(contentItem);
@@ -573,6 +597,11 @@ void QQuickWindowPrivate::syncSceneGraph()
renderer->setVisualizationMode(visualizationMode);
+ if (pendingFontUpdate) {
+ context->invalidateGlyphCaches();
+ pendingFontUpdate = false;
+ }
+
emit q->afterSynchronizing();
runAndClearJobs(&afterSynchronizingJobs);
}
@@ -748,6 +777,11 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
Q_ASSERT(windowManager || renderControl);
+ QObject::connect(static_cast<QGuiApplication *>(QGuiApplication::instance()),
+ &QGuiApplication::fontDatabaseChanged,
+ q,
+ &QQuickWindow::handleFontDatabaseChanged);
+
if (QScreen *screen = q->screen()) {
lastReportedItemDevicePixelRatio = q->effectiveDevicePixelRatio();
// if the screen changes, then QQuickWindow::handleScreenChanged disconnects
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index 48878b057d..2d5b18dbcf 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -259,6 +259,7 @@ private Q_SLOTS:
void setTransientParent_helper(QQuickWindow *window);
void runJobsAfterSwap();
void handleApplicationStateChanged(Qt::ApplicationState state);
+ void handleFontDatabaseChanged();
private:
#ifndef QT_NO_DEBUG_STREAM
inline friend QQmlInfo operator<<(QQmlInfo info, const QQuickWindow *window)
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 0fd09a1e33..20f4743481 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -168,6 +168,7 @@ public:
void polishItems();
void forcePolish();
+ void invalidateFontData(QQuickItem *item);
void syncSceneGraph();
void renderSceneGraph(const QSize &size, const QSize &surfaceSize = QSize());
@@ -295,6 +296,7 @@ public:
uint hasActiveSwapchain : 1;
uint hasRenderableSwapchain : 1;
uint swapchainJustBecameRenderable : 1;
+ bool pendingFontUpdate = false;
bool windowEventDispatch = false;
private:
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index 9d18868c58..a35c1dc5a6 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -170,6 +170,11 @@ void QSGDistanceFieldGlyphCache::release(const QVector<glyph_t> &glyphs)
releaseGlyphs(unusedGlyphs);
}
+bool QSGDistanceFieldGlyphCache::isActive() const
+{
+ return true;
+}
+
void QSGDistanceFieldGlyphCache::update()
{
m_populatingGlyphs.clear();
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index 03b3889322..d7c5bebbf7 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -495,6 +495,7 @@ public:
virtual bool eightBitFormatIsAlphaSwizzled() const = 0;
virtual bool screenSpaceDerivativesSupported() const = 0;
+ virtual bool isActive() const;
protected:
struct GlyphPosition {
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 695af6b127..a5e0e5e035 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -432,6 +432,10 @@ QSGDistanceFieldGlyphCache *QSGRenderContext::distanceFieldGlyphCache(const QRaw
return nullptr;
}
+void QSGRenderContext::invalidateGlyphCaches()
+{
+
+}
void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine)
{
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 1c6b5c3205..39a3051fe2 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -198,6 +198,7 @@ public:
virtual void endSync();
virtual void preprocess();
+ virtual void invalidateGlyphCaches();
virtual QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality);
QSGTexture *textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window);
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index a4337a58ca..508870fbd5 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -94,6 +94,19 @@ void QSGDefaultRenderContext::initialize(const QSGRenderContext::InitParams *par
emit initialized();
}
+void QSGDefaultRenderContext::invalidateGlyphCaches()
+{
+ auto it = m_glyphCaches.begin();
+ while (it != m_glyphCaches.end()) {
+ if (!(*it)->isActive()) {
+ delete *it;
+ it = m_glyphCaches.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
void QSGDefaultRenderContext::invalidate()
{
if (!m_rhi)
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index a97347eaf0..e233c4c3bd 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -111,6 +111,7 @@ public:
void endNextRhiFrame(QSGRenderer *renderer) override;
void preprocess() override;
+ void invalidateGlyphCaches() override;
QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality) override;
QSGTexture *createTexture(const QImage &image, uint flags) const override;
diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
index b139c3428a..50a3091c55 100644
--- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
@@ -147,6 +147,11 @@ void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs)
markGlyphsToRender(glyphsToRender);
}
+bool QSGRhiDistanceFieldGlyphCache::isActive() const
+{
+ return m_unusedGlyphs.size() != m_glyphsTexture.size();
+}
+
void QSGRhiDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &glyphs)
{
typedef QHash<TextureInfo *, QVector<glyph_t> > GlyphTextureHash;
diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h
index 965b496e48..47bf59e3d7 100644
--- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h
@@ -72,6 +72,7 @@ public:
bool useTextureResizeWorkaround() const;
bool createFullSizeTextures() const;
+ bool isActive() const override;
int maxTextureSize() const;
void setMaxTextureCount(int max) { m_maxTextureCount = max; }