summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/aspects/qaspectengine.cpp2
-rw-r--r--src/core/nodes/qnode_p.h2
-rw-r--r--src/core/qscene.cpp14
-rw-r--r--src/core/qscene_p.h5
-rw-r--r--src/extras/text/distancefieldtextrenderer_p_p.h1
-rw-r--r--src/extras/text/qdistancefieldglyphcache.cpp100
-rw-r--r--src/extras/text/qdistancefieldglyphcache.h90
-rw-r--r--src/extras/text/qdistancefieldglyphcache_p.h87
-rw-r--r--src/extras/text/qdistancefieldtext.cpp82
-rw-r--r--src/extras/text/qdistancefieldtext.h5
-rw-r--r--src/extras/text/qdistancefieldtext_p.h19
-rw-r--r--src/extras/text/qtextureatlas.cpp2
-rw-r--r--src/extras/text/qtextureatlas.h84
-rw-r--r--src/extras/text/qtextureatlas_p.h82
-rw-r--r--src/extras/text/qtextureatlas_p_p.h139
-rw-r--r--src/extras/text/text.pri9
-rw-r--r--src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp3
-rw-r--r--tests/manual/distancefieldtext/TextScene.qml5
18 files changed, 361 insertions, 370 deletions
diff --git a/src/core/aspects/qaspectengine.cpp b/src/core/aspects/qaspectengine.cpp
index 15f975332..c1ec1b4ac 100644
--- a/src/core/aspects/qaspectengine.cpp
+++ b/src/core/aspects/qaspectengine.cpp
@@ -218,6 +218,8 @@ QAspectEngine::~QAspectEngine()
void QAspectEnginePrivate::initNodeTree(QNode *node)
{
+ // Set the root entity on the scene
+ m_scene->setRootNode(node);
QNodeVisitor visitor;
visitor.traverse(node, this, &QAspectEnginePrivate::initNode, &QAspectEnginePrivate::initEntity);
}
diff --git a/src/core/nodes/qnode_p.h b/src/core/nodes/qnode_p.h
index 5d6329e62..d4a48aa1e 100644
--- a/src/core/nodes/qnode_p.h
+++ b/src/core/nodes/qnode_p.h
@@ -74,7 +74,7 @@ public:
void init(QNode *parent);
- void setScene(QScene *scene);
+ virtual void setScene(QScene *scene);
QScene *scene() const;
void setArbiter(QLockableObserverInterface *arbiter) Q_DECL_OVERRIDE;
diff --git a/src/core/qscene.cpp b/src/core/qscene.cpp
index 972659131..1fcfeaac7 100644
--- a/src/core/qscene.cpp
+++ b/src/core/qscene.cpp
@@ -55,6 +55,7 @@ public:
QScenePrivate(QAspectEngine *engine)
: m_engine(engine)
, m_arbiter(nullptr)
+ , m_rootNode(nullptr)
{
}
@@ -67,6 +68,7 @@ public:
QLockableObserverInterface *m_arbiter;
mutable QReadWriteLock m_lock;
mutable QReadWriteLock m_nodePropertyTrackModeLock;
+ QNode *m_rootNode;
};
@@ -171,6 +173,12 @@ QNodeId QScene::nodeIdFromObservable(QObservableInterface *observable) const
return d->m_observableToUuid.value(observable);
}
+QNode *QScene::rootNode() const
+{
+ Q_D(const QScene);
+ return d->m_rootNode;
+}
+
void QScene::setArbiter(QLockableObserverInterface *arbiter)
{
Q_D(QScene);
@@ -236,6 +244,12 @@ void QScene::removePropertyTrackDataForNode(QNodeId nodeId)
d->m_nodePropertyTrackModeLookupTable.remove(nodeId);
}
+void QScene::setRootNode(QNode *root)
+{
+ Q_D(QScene);
+ d->m_rootNode = root;
+}
+
} // Qt3D
QT_END_NAMESPACE
diff --git a/src/core/qscene_p.h b/src/core/qscene_p.h
index 1a313c249..fdcb23edb 100644
--- a/src/core/qscene_p.h
+++ b/src/core/qscene_p.h
@@ -83,6 +83,8 @@ public:
QVector<QNode *> lookupNodes(const QVector<QNodeId> &ids) const;
QNodeId nodeIdFromObservable(QObservableInterface *observable) const;
+ QNode *rootNode() const;
+
void setArbiter(Qt3DCore::QLockableObserverInterface *arbiter);
Qt3DCore::QLockableObserverInterface *arbiter() const;
@@ -105,6 +107,9 @@ public:
private:
Q_DECLARE_PRIVATE(QScene)
QScopedPointer<QScenePrivate> d_ptr;
+
+ void setRootNode(QNode *root);
+ friend class QAspectEnginePrivate;
};
} // Qt3D
diff --git a/src/extras/text/distancefieldtextrenderer_p_p.h b/src/extras/text/distancefieldtextrenderer_p_p.h
index fd2e76167..06c377a35 100644
--- a/src/extras/text/distancefieldtextrenderer_p_p.h
+++ b/src/extras/text/distancefieldtextrenderer_p_p.h
@@ -52,7 +52,6 @@
//
#include <Qt3DCore/private/qentity_p.h>
-#include <Qt3DExtras/qdistancefieldglyphcache.h>
#include <Qt3DExtras/private/distancefieldtextrenderer_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/extras/text/qdistancefieldglyphcache.cpp b/src/extras/text/qdistancefieldglyphcache.cpp
index dfe59883c..aacccc7dc 100644
--- a/src/extras/text/qdistancefieldglyphcache.cpp
+++ b/src/extras/text/qdistancefieldglyphcache.cpp
@@ -41,9 +41,13 @@
#include <QtGui/qglyphrun.h>
#include <QtGui/private/qrawfont_p.h>
-#include "qdistancefieldglyphcache.h"
#include "qdistancefieldglyphcache_p.h"
-#include "qtextureatlas.h"
+#include "qtextureatlas_p.h"
+
+#include <QtGui/qfont.h>
+#include <QtGui/private/qdistancefield_p.h>
+#include <Qt3DCore/private/qnode_p.h>
+#include <Qt3DExtras/private/qtextureatlas_p.h>
QT_BEGIN_NAMESPACE
@@ -53,6 +57,59 @@ using namespace Qt3DCore;
namespace Qt3DExtras {
+// ref-count glyphs and keep track of where they are stored
+class StoredGlyph {
+public:
+ StoredGlyph() = default;
+ StoredGlyph(const StoredGlyph &other) = default;
+ StoredGlyph(const QRawFont &font, quint32 glyph, bool doubleResolution);
+
+ int refCount() const { return m_ref; }
+ void ref() { ++m_ref; }
+ int deref() { return m_ref = std::max(m_ref - 1, (quint32) 0); }
+
+ bool addToTextureAtlas(QTextureAtlas *atlas);
+ void removeFromTextureAtlas();
+
+ QTextureAtlas *atlas() const { return m_atlas; }
+ QRectF glyphPathBoundingRect() const { return m_glyphPathBoundingRect; }
+ QRectF texCoords() const;
+
+private:
+ quint32 m_glyph = (quint32) -1;
+ quint32 m_ref = 0;
+ QTextureAtlas *m_atlas = nullptr;
+ QTextureAtlas::TextureId m_atlasEntry = QTextureAtlas::InvalidTexture;
+ QRectF m_glyphPathBoundingRect;
+ QImage m_distanceFieldImage; // only used until added to texture atlas
+};
+
+// A DistanceFieldFont stores all glyphs for a given QRawFont.
+// it will use multiple QTextureAtlasess to store the distance
+// fields and uses ref-counting for each glyph to ensure that
+// unused glyphs are removed from the texture atlasses.
+class DistanceFieldFont
+{
+public:
+ DistanceFieldFont(const QRawFont &font, bool doubleRes, Qt3DCore::QNode *parent);
+ ~DistanceFieldFont();
+
+ StoredGlyph findGlyph(quint32 glyph) const;
+ StoredGlyph refGlyph(quint32 glyph);
+ void derefGlyph(quint32 glyph);
+
+ bool doubleGlyphResolution() const { return m_doubleGlyphResolution; }
+
+private:
+ QRawFont m_font;
+ bool m_doubleGlyphResolution;
+ Qt3DCore::QNode *m_parentNode; // parent node for the QTextureAtlasses
+
+ QHash<quint32, StoredGlyph> m_glyphs;
+
+ QVector<QTextureAtlas*> m_atlasses;
+};
+
StoredGlyph::StoredGlyph(const QRawFont &font, quint32 glyph, bool doubleResolution)
: m_glyph(glyph)
, m_ref(1)
@@ -190,7 +247,7 @@ void DistanceFieldFont::derefGlyph(quint32 glyph)
// copied from QSGDistanceFieldGlyphCacheManager::fontKey
// we use this function to compare QRawFonts, as QRawFont doesn't
// implement a stable comparison function
-QString QDistanceFieldGlyphCachePrivate::fontKey(const QRawFont &font)
+QString QDistanceFieldGlyphCache::fontKey(const QRawFont &font)
{
QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
if (!fe->faceId().filename.isEmpty()) {
@@ -210,7 +267,7 @@ QString QDistanceFieldGlyphCachePrivate::fontKey(const QRawFont &font)
}
}
-DistanceFieldFont* QDistanceFieldGlyphCachePrivate::getOrCreateDistanceFieldFont(const QRawFont &font)
+DistanceFieldFont* QDistanceFieldGlyphCache::getOrCreateDistanceFieldFont(const QRawFont &font)
{
// return, if font already exists (make sure to only create one DistanceFieldFont for
// each unique QRawFont, by building a hash on the QRawFont that ignores the font size)
@@ -229,13 +286,13 @@ DistanceFieldFont* QDistanceFieldGlyphCachePrivate::getOrCreateDistanceFieldFont
actualFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE(useDoubleRes) * QT_DISTANCEFIELD_SCALE(useDoubleRes));
// create new font cache
- DistanceFieldFont *dff = new DistanceFieldFont(actualFont, useDoubleRes, q_func());
+ DistanceFieldFont *dff = new DistanceFieldFont(actualFont, useDoubleRes, m_rootNode);
m_fonts.insert(key, dff);
return dff;
}
-QDistanceFieldGlyphCache::QDistanceFieldGlyphCache(QNode *parent)
- : QNode(*new QDistanceFieldGlyphCachePrivate(), parent)
+QDistanceFieldGlyphCache::QDistanceFieldGlyphCache()
+ : m_rootNode(nullptr)
{
}
@@ -243,10 +300,19 @@ QDistanceFieldGlyphCache::~QDistanceFieldGlyphCache()
{
}
+void QDistanceFieldGlyphCache::setRootNode(QNode *rootNode)
+{
+ m_rootNode = rootNode;
+}
+
+QNode *QDistanceFieldGlyphCache::rootNode() const
+{
+ return m_rootNode;
+}
+
bool QDistanceFieldGlyphCache::doubleGlyphResolution(const QRawFont &font)
{
- Q_D(QDistanceFieldGlyphCache);
- return d->getOrCreateDistanceFieldFont(font)->doubleGlyphResolution();
+ return getOrCreateDistanceFieldFont(font)->doubleGlyphResolution();
}
namespace {
@@ -266,13 +332,11 @@ QDistanceFieldGlyphCache::Glyph refAndGetGlyph(DistanceFieldFont *dff, quint32 g
return ret;
}
-}
+} // anonymous
QVector<QDistanceFieldGlyphCache::Glyph> QDistanceFieldGlyphCache::refGlyphs(const QGlyphRun &run)
{
- Q_D(QDistanceFieldGlyphCache);
-
- DistanceFieldFont *dff = d->getOrCreateDistanceFieldFont(run.rawFont());
+ DistanceFieldFont *dff = getOrCreateDistanceFieldFont(run.rawFont());
QVector<QDistanceFieldGlyphCache::Glyph> ret;
const QVector<quint32> glyphs = run.glyphIndexes();
@@ -284,15 +348,12 @@ QVector<QDistanceFieldGlyphCache::Glyph> QDistanceFieldGlyphCache::refGlyphs(con
QDistanceFieldGlyphCache::Glyph QDistanceFieldGlyphCache::refGlyph(const QRawFont &font, quint32 glyph)
{
- Q_D(QDistanceFieldGlyphCache);
- return refAndGetGlyph(d->getOrCreateDistanceFieldFont(font), glyph);
+ return refAndGetGlyph(getOrCreateDistanceFieldFont(font), glyph);
}
void QDistanceFieldGlyphCache::derefGlyphs(const QGlyphRun &run)
{
- Q_D(QDistanceFieldGlyphCache);
-
- DistanceFieldFont *dff = d->getOrCreateDistanceFieldFont(run.rawFont());
+ DistanceFieldFont *dff = getOrCreateDistanceFieldFont(run.rawFont());
const QVector<quint32> glyphs = run.glyphIndexes();
for (quint32 glyph : glyphs)
@@ -301,8 +362,7 @@ void QDistanceFieldGlyphCache::derefGlyphs(const QGlyphRun &run)
void QDistanceFieldGlyphCache::derefGlyph(const QRawFont &font, quint32 glyph)
{
- Q_D(QDistanceFieldGlyphCache);
- d->getOrCreateDistanceFieldFont(font)->derefGlyph(glyph);
+ getOrCreateDistanceFieldFont(font)->derefGlyph(glyph);
}
} // namespace Qt3DExtras
diff --git a/src/extras/text/qdistancefieldglyphcache.h b/src/extras/text/qdistancefieldglyphcache.h
deleted file mode 100644
index b02625b47..000000000
--- a/src/extras/text/qdistancefieldglyphcache.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt3D 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 QT3DEXTRAS_QDISTANCEFIELDGLYPHCACHE_H
-#define QT3DEXTRAS_QDISTANCEFIELDGLYPHCACHE_H
-
-#include <QtCore/QRectF>
-#include <Qt3DCore/qnode.h>
-#include <Qt3DExtras/qt3dextras_global.h>
-
-QT_BEGIN_NAMESPACE
-
-class QRawFont;
-class QGlyphRun;
-
-namespace Qt3DRender {
-class QAbstractTexture;
-}
-
-namespace Qt3DExtras {
-
-class QDistanceFieldGlyphCachePrivate;
-
-class QT3DEXTRASSHARED_EXPORT QDistanceFieldGlyphCache : public Qt3DCore::QNode
-{
- Q_OBJECT
-
-public:
- QDistanceFieldGlyphCache(Qt3DCore::QNode *parent = nullptr);
- ~QDistanceFieldGlyphCache();
-
- struct Glyph {
- Qt3DRender::QAbstractTexture *texture = nullptr;
- QRectF glyphPathBoundingRect; // bounding rect of the QPainterPath used to draw the glyph
- QRectF texCoords; // texture coordinates within texture
- };
-
- bool doubleGlyphResolution(const QRawFont &font);
-
- QVector<Glyph> refGlyphs(const QGlyphRun &run);
- Glyph refGlyph(const QRawFont &font, quint32 glyph);
-
- void derefGlyphs(const QGlyphRun &run);
- void derefGlyph(const QRawFont &font, quint32 glyph);
-
-private:
- Q_DECLARE_PRIVATE(QDistanceFieldGlyphCache)
-};
-
-} // namespace Qt3DExtras
-
-QT_END_NAMESPACE
-
-#endif // QT3DEXTRAS_QDISTANCEFIELDGLYPHCACHE_H
diff --git a/src/extras/text/qdistancefieldglyphcache_p.h b/src/extras/text/qdistancefieldglyphcache_p.h
index 90164cd39..6ca011c76 100644
--- a/src/extras/text/qdistancefieldglyphcache_p.h
+++ b/src/extras/text/qdistancefieldglyphcache_p.h
@@ -51,82 +51,57 @@
// We mean it.
//
-#include <QtCore/qscopedpointer.h>
-#include <QtGui/qglyphrun.h>
-#include <QtGui/qfont.h>
-#include <QtGui/private/qdistancefield_p.h>
-#include <Qt3DCore/private/qnode_p.h>
-#include <Qt3DExtras/qdistancefieldglyphcache.h>
-#include <Qt3DExtras/qtextureatlas.h>
+#include <QtCore/QRectF>
+#include <Qt3DCore/qnode.h>
+#include <Qt3DExtras/qt3dextras_global.h>
QT_BEGIN_NAMESPACE
-namespace Qt3DExtras {
+class QRawFont;
+class QGlyphRun;
-// ref-count glyphs and keep track of where they are stored
-class StoredGlyph {
-public:
- StoredGlyph() = default;
- StoredGlyph(const StoredGlyph &other) = default;
- StoredGlyph(const QRawFont &font, quint32 glyph, bool doubleResolution);
+namespace Qt3DCore {
+class QNode;
+}
- int refCount() const { return m_ref; }
- void ref() { ++m_ref; }
- int deref() { return m_ref = std::max(m_ref - 1, (quint32) 0); }
+namespace Qt3DRender {
+class QAbstractTexture;
+}
- bool addToTextureAtlas(QTextureAtlas *atlas);
- void removeFromTextureAtlas();
+namespace Qt3DExtras {
- QTextureAtlas *atlas() const { return m_atlas; }
- QRectF glyphPathBoundingRect() const { return m_glyphPathBoundingRect; }
- QRectF texCoords() const;
+class DistanceFieldFont;
+class QDistanceFieldGlyphCachePrivate;
-private:
- quint32 m_glyph = (quint32) -1;
- quint32 m_ref = 0;
- QTextureAtlas *m_atlas = nullptr;
- QTextureAtlas::TextureId m_atlasEntry = QTextureAtlas::InvalidTexture;
- QRectF m_glyphPathBoundingRect;
- QImage m_distanceFieldImage; // only used until added to texture atlas
-};
-
-// A DistanceFieldFont stores all glyphs for a given QRawFont.
-// it will use multiple QTextureAtlasess to store the distance
-// fields and uses ref-counting for each glyph to ensure that
-// unused glyphs are removed from the texture atlasses.
-class DistanceFieldFont
+class QDistanceFieldGlyphCache
{
public:
- DistanceFieldFont(const QRawFont &font, bool doubleRes, Qt3DCore::QNode *parent);
- ~DistanceFieldFont();
-
- StoredGlyph findGlyph(quint32 glyph) const;
- StoredGlyph refGlyph(quint32 glyph);
- void derefGlyph(quint32 glyph);
+ QDistanceFieldGlyphCache();
+ ~QDistanceFieldGlyphCache();
- bool doubleGlyphResolution() const { return m_doubleGlyphResolution; }
+ void setRootNode(Qt3DCore::QNode *rootNode);
+ Qt3DCore::QNode *rootNode() const;
-private:
- QRawFont m_font;
- bool m_doubleGlyphResolution;
- Qt3DCore::QNode *m_parentNode; // parent node for the QTextureAtlasses
+ struct Glyph {
+ Qt3DRender::QAbstractTexture *texture = nullptr;
+ QRectF glyphPathBoundingRect; // bounding rect of the QPainterPath used to draw the glyph
+ QRectF texCoords; // texture coordinates within texture
+ };
- QHash<quint32, StoredGlyph> m_glyphs;
+ bool doubleGlyphResolution(const QRawFont &font);
- QVector<QTextureAtlas*> m_atlasses;
-};
+ QVector<Glyph> refGlyphs(const QGlyphRun &run);
+ Glyph refGlyph(const QRawFont &font, quint32 glyph);
-class QDistanceFieldGlyphCachePrivate : public Qt3DCore::QNodePrivate
-{
-public:
- Q_DECLARE_PUBLIC(QDistanceFieldGlyphCache)
-
- DistanceFieldFont* getOrCreateDistanceFieldFont(const QRawFont &font);
+ void derefGlyphs(const QGlyphRun &run);
+ void derefGlyph(const QRawFont &font, quint32 glyph);
private:
+ DistanceFieldFont* getOrCreateDistanceFieldFont(const QRawFont &font);
static QString fontKey(const QRawFont &font);
QHash<QString, DistanceFieldFont*> m_fonts;
+ Qt3DCore::QNode *m_rootNode;
};
} // namespace Qt3DExtras
diff --git a/src/extras/text/qdistancefieldtext.cpp b/src/extras/text/qdistancefieldtext.cpp
index fdd40fc5a..88e6e9be5 100644
--- a/src/extras/text/qdistancefieldtext.cpp
+++ b/src/extras/text/qdistancefieldtext.cpp
@@ -54,6 +54,8 @@
#include <Qt3DRender/qgeometry.h>
#include <Qt3DRender/qgeometryrenderer.h>
+#include <Qt3DCore/private/qscene_p.h>
+
QT_BEGIN_NAMESPACE
namespace {
@@ -67,8 +69,11 @@ inline Q_DECL_CONSTEXPR QRectF scaleRectF(const QRectF &rect, float scale)
namespace Qt3DExtras {
+QHash<Qt3DCore::QScene *, QDistanceFieldTextPrivate::CacheEntry> QDistanceFieldTextPrivate::m_glyphCacheInstances;
+
QDistanceFieldTextPrivate::QDistanceFieldTextPrivate()
- : m_font(QLatin1String("Times"), 10)
+ : m_glyphCache(nullptr)
+ , m_font(QLatin1String("Times"), 10)
, m_scaledFont(QLatin1String("Times"), 10)
, m_color(QColor(255, 255, 255, 255))
{
@@ -78,6 +83,38 @@ QDistanceFieldTextPrivate::~QDistanceFieldTextPrivate()
{
}
+void QDistanceFieldTextPrivate::setScene(Qt3DCore::QScene *scene)
+{
+ if (scene == m_scene)
+ return;
+
+ // Unref old glyph cache if it exists
+ if (m_scene != nullptr) {
+ m_glyphCache = nullptr;
+ QDistanceFieldTextPrivate::CacheEntry &entry = QDistanceFieldTextPrivate::m_glyphCacheInstances[m_scene];
+ --entry.count;
+ if (entry.count == 0 && entry.glyphCache != nullptr) {
+ delete entry.glyphCache;
+ entry.glyphCache = nullptr;
+ }
+ }
+
+ QEntityPrivate::setScene(scene);
+
+ // Ref new glyph cache is scene is valid
+ if (scene != nullptr) {
+ QDistanceFieldTextPrivate::CacheEntry &entry = QDistanceFieldTextPrivate::m_glyphCacheInstances[scene];
+ if (entry.glyphCache == nullptr) {
+ entry.glyphCache = new QDistanceFieldGlyphCache();
+ entry.glyphCache->setRootNode(scene->rootNode());
+ }
+ m_glyphCache = entry.glyphCache;
+ ++entry.count;
+ // Update to populate glyphCache if needed
+ update();
+ }
+}
+
QDistanceFieldText::QDistanceFieldText(QNode *parent)
: Qt3DCore::QEntity(*new QDistanceFieldTextPrivate(), parent)
{
@@ -104,7 +141,8 @@ struct RenderData {
void QDistanceFieldTextPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs)
{
- Q_ASSERT(m_glyphCache || runs.isEmpty());
+ if (runs.isEmpty())
+ return;
// For each distinct texture, we need a separate DistanceFieldTextRenderer,
// for which we need vertex and index data
@@ -198,19 +236,20 @@ void QDistanceFieldTextPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &ru
}
// de-ref all glyphs for previous QGlyphRuns
- if (m_glyphCache) {
- for (int i = 0; i < m_currentGlyphRuns.size(); i++)
- m_glyphCache->derefGlyphs(m_currentGlyphRuns[i]);
- }
+ for (int i = 0; i < m_currentGlyphRuns.size(); i++)
+ m_glyphCache->derefGlyphs(m_currentGlyphRuns[i]);
m_currentGlyphRuns = runs;
}
void QDistanceFieldTextPrivate::update()
{
+ if (m_glyphCache == nullptr)
+ return;
+
QVector<QGlyphRun> glyphRuns;
// collect all GlyphRuns generated by the QTextLayout
- if (m_glyphCache && !m_position.isEmpty() && !m_text.isEmpty() && m_fontScale > 0.f) {
+ if (!m_position.isEmpty() && !m_text.isEmpty() && m_fontScale > 0.f) {
QTextLayout layout(m_text, m_scaledFont);
const float lineWidth = m_position.width() / computeActualScale();
float height = 0;
@@ -257,7 +296,7 @@ void QDistanceFieldText::setFont(const QFont &font)
emit fontChanged(font);
- if (!d->m_text.isEmpty() && d->m_glyphCache)
+ if (!d->m_text.isEmpty())
d->update();
}
}
@@ -294,8 +333,7 @@ void QDistanceFieldText::setText(const QString &text)
d->m_text = text;
emit textChanged(text);
- if (d->m_glyphCache)
- d->update();
+ d->update();
}
}
@@ -312,7 +350,7 @@ void QDistanceFieldText::setPosition(const QRectF &pos)
d->m_position = pos;
emit positionChanged(pos);
- if (!d->m_text.isEmpty() && d->m_glyphCache)
+ if (!d->m_text.isEmpty())
d->update();
}
}
@@ -330,28 +368,6 @@ void QDistanceFieldText::setFontScale(float scale)
d->m_fontScale = scale;
emit fontScaleChanged(scale);
- if (!d->m_text.isEmpty() && d->m_glyphCache)
- d->update();
- }
-}
-
-QDistanceFieldGlyphCache *QDistanceFieldText::glyphCache() const
-{
- Q_D(const QDistanceFieldText);
- return d->m_glyphCache;
-}
-
-void QDistanceFieldText::setGlyphCache(QDistanceFieldGlyphCache *glyphCache)
-{
- Q_D(QDistanceFieldText);
- if (d->m_glyphCache != glyphCache) {
- // make sure all glyphs that we still reference in our old glyph cache
- // will be de-reffed
- d->setCurrentGlyphRuns(QVector<QGlyphRun>());
-
- d->m_glyphCache = glyphCache;
- emit glyphCacheChanged(glyphCache);
-
if (!d->m_text.isEmpty())
d->update();
}
diff --git a/src/extras/text/qdistancefieldtext.h b/src/extras/text/qdistancefieldtext.h
index 2eaafda63..a1bfc9d9e 100644
--- a/src/extras/text/qdistancefieldtext.h
+++ b/src/extras/text/qdistancefieldtext.h
@@ -61,7 +61,6 @@ class QT3DEXTRASSHARED_EXPORT QDistanceFieldText : public Qt3DCore::QEntity
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(QRectF position READ position WRITE setPosition NOTIFY positionChanged)
Q_PROPERTY(float fontScale READ fontScale WRITE setFontScale NOTIFY fontScaleChanged)
- Q_PROPERTY(Qt3DExtras::QDistanceFieldGlyphCache* glyphCache READ glyphCache WRITE setGlyphCache NOTIFY glyphCacheChanged)
public:
explicit QDistanceFieldText(Qt3DCore::QNode *parent = nullptr);
@@ -82,16 +81,12 @@ public:
float fontScale() const;
void setFontScale(float scale);
- QDistanceFieldGlyphCache *glyphCache() const;
- void setGlyphCache(QDistanceFieldGlyphCache *glyphCache);
-
Q_SIGNALS:
void fontChanged(const QFont &font);
void colorChanged(const QColor &color);
void textChanged(const QString &text);
void positionChanged(const QRectF &position);
void fontScaleChanged(float scale);
- void glyphCacheChanged(QDistanceFieldGlyphCache *glyphCache);
private:
Q_DECLARE_PRIVATE(QDistanceFieldText)
diff --git a/src/extras/text/qdistancefieldtext_p.h b/src/extras/text/qdistancefieldtext_p.h
index 578ed7f98..d30f226d6 100644
--- a/src/extras/text/qdistancefieldtext_p.h
+++ b/src/extras/text/qdistancefieldtext_p.h
@@ -52,12 +52,16 @@
//
#include <Qt3DCore/private/qentity_p.h>
-#include <Qt3DExtras/qdistancefieldglyphcache.h>
#include <Qt3DExtras/private/distancefieldtextrenderer_p.h>
+#include <Qt3DExtras/private/qdistancefieldglyphcache_p.h>
#include <QFont>
QT_BEGIN_NAMESPACE
+namespace Qt3DCore {
+class QScene;
+}
+
namespace Qt3DRender {
class QGeometryRenderer;
class QGeometry;
@@ -79,12 +83,13 @@ public:
Q_DECLARE_PUBLIC(QDistanceFieldText)
- QDistanceFieldGlyphCache *m_glyphCache = nullptr;
-
// keep track of the glyphs currently being displayed,
// to guarantee proper glyph ref-counting in the
// QDistanceFieldGlyphCache
QVector<QGlyphRun> m_currentGlyphRuns;
+ QDistanceFieldGlyphCache *m_glyphCache;
+
+ void setScene(Qt3DCore::QScene *scene) Q_DECL_OVERRIDE;
QFont m_font;
QFont m_scaledFont; // ignore point or pixel size, set to default value
@@ -100,6 +105,14 @@ public:
void setCurrentGlyphRuns(const QVector<QGlyphRun> &runs);
void update();
+
+ struct CacheEntry
+ {
+ QDistanceFieldGlyphCache *glyphCache = nullptr;
+ int count = 0;
+ };
+
+ static QHash<Qt3DCore::QScene *, CacheEntry> m_glyphCacheInstances;
};
} // namespace Qt3DExtras
diff --git a/src/extras/text/qtextureatlas.cpp b/src/extras/text/qtextureatlas.cpp
index 1a076a3ab..49c6397d6 100644
--- a/src/extras/text/qtextureatlas.cpp
+++ b/src/extras/text/qtextureatlas.cpp
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#include "qtextureatlas.h"
#include "qtextureatlas_p.h"
+#include "qtextureatlas_p_p.h"
#include <Qt3DRender/qtexturedata.h>
#include <Qt3DRender/qabstracttextureimage.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
diff --git a/src/extras/text/qtextureatlas.h b/src/extras/text/qtextureatlas.h
deleted file mode 100644
index c70f9dfd3..000000000
--- a/src/extras/text/qtextureatlas.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt3D 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 QT3DEXTRAS_QTEXTUREATLAS_H
-#define QT3DEXTRAS_QTEXTUREATLAS_H
-
-#include <Qt3DExtras/qt3dextras_global.h>
-#include <Qt3DRender/qabstracttexture.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DExtras {
-
-class QTextureAtlasPrivate;
-
-class QT3DEXTRASSHARED_EXPORT QTextureAtlas : public Qt3DRender::QAbstractTexture
-{
- Q_OBJECT
-
-public:
- typedef int TextureId;
- static Q_CONSTEXPR TextureId InvalidTexture = -1;
-
- QTextureAtlas(Qt3DCore::QNode *parent = nullptr);
- ~QTextureAtlas();
-
- QOpenGLTexture::PixelFormat pixelFormat() const;
- void setPixelFormat(QOpenGLTexture::PixelFormat fmt);
-
- TextureId addImage(const QImage &image, int padding);
- void removeImage(TextureId id);
-
- int imageCount() const;
-
- bool hasImage(TextureId id) const;
- QRect imagePosition(TextureId id) const;
- QRectF imageTexCoords(TextureId id) const;
- int imagePadding(TextureId id) const;
-
-private:
- Q_DECLARE_PRIVATE(QTextureAtlas)
-};
-
-} // namespace Qt3DExtras
-
-QT_END_NAMESPACE
-
-#endif // QT3DEXTRAS_QTEXTUREATLAS_H
diff --git a/src/extras/text/qtextureatlas_p.h b/src/extras/text/qtextureatlas_p.h
index 34386a87a..8dc9e19b3 100644
--- a/src/extras/text/qtextureatlas_p.h
+++ b/src/extras/text/qtextureatlas_p.h
@@ -51,86 +51,42 @@
// We mean it.
//
-#include <QtCore/qscopedpointer.h>
-#include <Qt3DRender/private/qabstracttexture_p.h>
-#include <Qt3DRender/qtexturegenerator.h>
-#include <Qt3DExtras/private/areaallocator_p.h>
-#include <Qt3DExtras/qtextureatlas.h>
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qabstracttexture.h>
QT_BEGIN_NAMESPACE
namespace Qt3DExtras {
-// Used to store texture info within atlas
-struct AtlasTexture
-{
- QRect position;
- int padding = 0;
-};
+class QTextureAtlasPrivate;
-// data shared between QTextureAtlasPrivate and the QTextureGenerators
-// we use this extra indirection so we can lazily copy the sub-images
-// into the actual texture image in the backend texture loader thread.
-class QTextureAtlasData
+class QTextureAtlas : public Qt3DRender::QAbstractTexture
{
-public:
- QTextureAtlasData(int w, int h, QImage::Format fmt);
- ~QTextureAtlasData();
-
- int width() const { return m_image.width(); }
- int height() const { return m_image.height(); }
+ Q_OBJECT
- void addImage(const AtlasTexture &texture, const QImage &image);
- QByteArray createUpdatedImageData();
-
-private:
- struct Update {
- AtlasTexture textureInfo;
- QImage image;
- };
-
- QMutex m_mutex;
- QImage m_image;
- QVector<Update> m_updates;
-};
-
-typedef QSharedPointer<QTextureAtlasData> QTextureAtlasDataPtr;
-
-class QTextureAtlasPrivate : public Qt3DRender::QAbstractTexturePrivate
-{
public:
- QTextureAtlasPrivate();
- ~QTextureAtlasPrivate();
+ typedef int TextureId;
+ static Q_CONSTEXPR TextureId InvalidTexture = -1;
- Q_DECLARE_PUBLIC(QTextureAtlas)
+ QTextureAtlas(Qt3DCore::QNode *parent = nullptr);
+ ~QTextureAtlas();
- QTextureAtlas::TextureId m_currId = 1; // IDs for new sub-textures
- int m_currGen = 0;
+ QOpenGLTexture::PixelFormat pixelFormat() const;
+ void setPixelFormat(QOpenGLTexture::PixelFormat fmt);
- QTextureAtlasDataPtr m_data;
- QScopedPointer<AreaAllocator> m_allocator;
- QOpenGLTexture::PixelFormat m_pixelFormat;
- QHash<QTextureAtlas::TextureId, AtlasTexture> m_textures;
-};
+ TextureId addImage(const QImage &image, int padding);
+ void removeImage(TextureId id);
-class QTextureAtlasGenerator : public Qt3DRender::QTextureGenerator
-{
-public:
- QTextureAtlasGenerator(const QTextureAtlasPrivate *texAtlas);
- ~QTextureAtlasGenerator();
- Qt3DRender::QTextureDataPtr operator()() Q_DECL_OVERRIDE;
- bool operator==(const QTextureGenerator &other) const Q_DECL_OVERRIDE;
+ int imageCount() const;
- QT3D_FUNCTOR(QTextureAtlasGenerator)
+ bool hasImage(TextureId id) const;
+ QRect imagePosition(TextureId id) const;
+ QRectF imageTexCoords(TextureId id) const;
+ int imagePadding(TextureId id) const;
private:
- QTextureAtlasDataPtr m_data;
- Qt3DRender::QAbstractTexture::TextureFormat m_format;
- QOpenGLTexture::PixelFormat m_pixelFormat;
- int m_generation;
- Qt3DCore::QNodeId m_atlasId;
+ Q_DECLARE_PRIVATE(QTextureAtlas)
};
-typedef QSharedPointer<QTextureAtlasGenerator> QTextureAtlasGeneratorPtr;
} // namespace Qt3DExtras
diff --git a/src/extras/text/qtextureatlas_p_p.h b/src/extras/text/qtextureatlas_p_p.h
new file mode 100644
index 000000000..ca18a263a
--- /dev/null
+++ b/src/extras/text/qtextureatlas_p_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D 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 QT3DEXTRAS_QTEXTUREATLAS_P_P_H
+#define QT3DEXTRAS_QTEXTUREATLAS_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qscopedpointer.h>
+#include <Qt3DRender/private/qabstracttexture_p.h>
+#include <Qt3DRender/qtexturegenerator.h>
+#include <Qt3DExtras/private/areaallocator_p.h>
+#include <Qt3DExtras/private/qtextureatlas_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+// Used to store texture info within atlas
+struct AtlasTexture
+{
+ QRect position;
+ int padding = 0;
+};
+
+// data shared between QTextureAtlasPrivate and the QTextureGenerators
+// we use this extra indirection so we can lazily copy the sub-images
+// into the actual texture image in the backend texture loader thread.
+class QTextureAtlasData
+{
+public:
+ QTextureAtlasData(int w, int h, QImage::Format fmt);
+ ~QTextureAtlasData();
+
+ int width() const { return m_image.width(); }
+ int height() const { return m_image.height(); }
+
+ void addImage(const AtlasTexture &texture, const QImage &image);
+ QByteArray createUpdatedImageData();
+
+private:
+ struct Update {
+ AtlasTexture textureInfo;
+ QImage image;
+ };
+
+ QMutex m_mutex;
+ QImage m_image;
+ QVector<Update> m_updates;
+};
+
+typedef QSharedPointer<QTextureAtlasData> QTextureAtlasDataPtr;
+
+class QTextureAtlasPrivate : public Qt3DRender::QAbstractTexturePrivate
+{
+public:
+ QTextureAtlasPrivate();
+ ~QTextureAtlasPrivate();
+
+ Q_DECLARE_PUBLIC(QTextureAtlas)
+
+ QTextureAtlas::TextureId m_currId = 1; // IDs for new sub-textures
+ int m_currGen = 0;
+
+ QTextureAtlasDataPtr m_data;
+ QScopedPointer<AreaAllocator> m_allocator;
+ QOpenGLTexture::PixelFormat m_pixelFormat;
+ QHash<QTextureAtlas::TextureId, AtlasTexture> m_textures;
+};
+
+class QTextureAtlasGenerator : public Qt3DRender::QTextureGenerator
+{
+public:
+ QTextureAtlasGenerator(const QTextureAtlasPrivate *texAtlas);
+ ~QTextureAtlasGenerator();
+ Qt3DRender::QTextureDataPtr operator()() Q_DECL_OVERRIDE;
+ bool operator==(const QTextureGenerator &other) const Q_DECL_OVERRIDE;
+
+ QT3D_FUNCTOR(QTextureAtlasGenerator)
+
+private:
+ QTextureAtlasDataPtr m_data;
+ Qt3DRender::QAbstractTexture::TextureFormat m_format;
+ QOpenGLTexture::PixelFormat m_pixelFormat;
+ int m_generation;
+ Qt3DCore::QNodeId m_atlasId;
+};
+typedef QSharedPointer<QTextureAtlasGenerator> QTextureAtlasGeneratorPtr;
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QTEXTUREATLAS_P_P_H
diff --git a/src/extras/text/text.pri b/src/extras/text/text.pri
index 24ab40cc2..583d91de6 100644
--- a/src/extras/text/text.pri
+++ b/src/extras/text/text.pri
@@ -1,15 +1,14 @@
HEADERS += \
- $$PWD/qtextureatlas.h \
- $$PWD/qtextureatlas_p.h \
- $$PWD/qdistancefieldglyphcache.h \
- $$PWD/qdistancefieldglyphcache_p.h \
$$PWD/qdistancefieldmaterial.h \
$$PWD/qdistancefieldmaterial_p.h \
$$PWD/distancefieldtextrenderer_p.h \
$$PWD/distancefieldtextrenderer_p_p.h \
$$PWD/qdistancefieldtext.h \
$$PWD/qdistancefieldtext_p.h \
- $$PWD/areaallocator_p.h
+ $$PWD/areaallocator_p.h \
+ $$PWD/qdistancefieldglyphcache_p.h \
+ $$PWD/qtextureatlas_p_p.h \
+ $$PWD/qtextureatlas_p.h
SOURCES += \
$$PWD/qtextureatlas.cpp \
diff --git a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
index 8aad63178..29a5d9883 100644
--- a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
+++ b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
@@ -68,8 +68,6 @@
#include <Qt3DExtras/qcylindergeometry.h>
#include <Qt3DExtras/qextrudedtextgeometry.h>
#include <Qt3DExtras/qextrudedtextmesh.h>
-#include <Qt3DExtras/qtextureatlas.h>
-#include <Qt3DExtras/qdistancefieldglyphcache.h>
#include <Qt3DExtras/qdistancefieldtext.h>
#include <Qt3DExtras/qmorphphongmaterial.h>
#include <Qt3DQuickExtras/private/quick3dlevelofdetailloader_p.h>
@@ -126,7 +124,6 @@ void Qt3DQuick3DExtrasPlugin::registerTypes(const char *uri)
qmlRegisterType<Qt3DExtras::QExtrudedTextGeometry>(uri, 2, 9, "ExtrudedTextGeometry");
qmlRegisterType<Qt3DExtras::QExtrudedTextMesh>(uri, 2, 9, "ExtrudedTextMesh");
- qmlRegisterType<Qt3DExtras::QDistanceFieldGlyphCache>(uri, 2, 9, "DistanceFieldGlyphCache");
qmlRegisterType<Qt3DExtras::QDistanceFieldText>(uri, 2, 9, "DistanceFieldText");
}
diff --git a/tests/manual/distancefieldtext/TextScene.qml b/tests/manual/distancefieldtext/TextScene.qml
index 2d60a1c67..54757b400 100644
--- a/tests/manual/distancefieldtext/TextScene.qml
+++ b/tests/manual/distancefieldtext/TextScene.qml
@@ -91,10 +91,6 @@ Entity {
}
]
- DistanceFieldGlyphCache {
- id: glyphCache
- }
-
function getChars(n) {
var s = "";
for (var i = 0; i < n; i++) {
@@ -148,7 +144,6 @@ Entity {
font.pointSize: 10
text: getChars(strLen)
- glyphCache: glyphCache
position: Qt.rect(-10, -5, 20, 10)
fontScale: 0.1
}