From 098b7fb0ac84dbe65a8861cce76e036f0b9198d6 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 23 Jun 2011 10:40:39 +0200 Subject: [PATCH] Merge multiple lines of text into a single geometry node Long term, we might want to have this kind of logic in the QSGGeometry class through a grow() function or in the QSGRenderer, but we only have this one usecase where it actually makes sense right now, so I'm keeping it local. Change-Id: Ibbb0dd4a6e4b587154e26ffc2a34375fbb4a571d --- src/declarative/items/qsgtextnode.cpp | 30 +++++++---- src/declarative/items/qsgtextnode_p.h | 3 +- .../scenegraph/qsgdistancefieldglyphnode.cpp | 58 +++++++++++++++++++--- 3 files changed, 72 insertions(+), 19 deletions(-) diff --git a/src/declarative/items/qsgtextnode.cpp b/src/declarative/items/qsgtextnode.cpp index 6909d8c..b8dee68 100644 --- a/src/declarative/items/qsgtextnode.cpp +++ b/src/declarative/items/qsgtextnode.cpp @@ -152,18 +152,25 @@ void QSGTextNode::addTextDecorations(const QPointF &position, const QRawFont &fo } QSGGlyphNode *QSGTextNode::addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color, - QSGText::TextStyle style, const QColor &styleColor) + QSGText::TextStyle style, const QColor &styleColor, QSGGlyphNode *prevNode) { - QSGGlyphNode *node = m_context->createGlyphNode(); - if (QSGDistanceFieldGlyphCache::distanceFieldEnabled()) { - QSGDistanceFieldGlyphNode *dfNode = static_cast(node); - dfNode->setStyle(style); - dfNode->setStyleColor(styleColor); - } + QSGGlyphNode *node = prevNode; + + if (!node) + node = m_context->createGlyphNode(); + node->setGlyphs(position, glyphs); - node->setColor(color); - appendChildNode(node); + if (node != prevNode) { + if (QSGDistanceFieldGlyphCache::distanceFieldEnabled()) { + QSGDistanceFieldGlyphNode *dfNode = static_cast(node); + dfNode->setStyle(style); + dfNode->setStyleColor(styleColor); + } + node->setColor(color); + appendChildNode(node); + } + if (glyphs.overline() || glyphs.strikeOut() || glyphs.underline()) { QPointF baseLine = node->baseLine(); @@ -193,10 +200,13 @@ void QSGTextNode::addTextLayout(const QPointF &position, QTextLayout *textLayout QSGText::TextStyle style, const QColor &styleColor) { QList glyphsList(textLayout->glyphRuns()); + + QSGGlyphNode *prevNode = 0; + for (int i=0; ipopulate(glyphIndexes.count(), glyphIndexes.constData()); Q_ASSERT(g->indexType() == GL_UNSIGNED_SHORT); - g->allocate(glyphIndexes.size() * 4, glyphIndexes.size() * 6); - QVector4D *vp = (QVector4D *)g->vertexData(); - ushort *ip = g->indexDataAsUShort(); + + int oldVertexCount = g->vertexCount(); + int oldIndexCount = g->indexCount(); + + // We could potentially move the realloc part into the QSGGeometry object as a + // grow() function... + + void *data = 0; + if (oldVertexCount && oldIndexCount) { + int byteSize = oldVertexCount * sizeof(QSGGeometry::TexturedPoint2D) + + oldIndexCount * sizeof(quint16); + data = qMalloc(byteSize); + memcpy(data, g->vertexData(), byteSize); + } + + g->allocate(oldVertexCount + glyphIndexes.size() * 4, oldIndexCount + glyphIndexes.size() * 6); + + if (data) { + memcpy(g->vertexData(), data, oldVertexCount * sizeof(QSGGeometry::TexturedPoint2D)); + memcpy(g->indexData(), ((char *) data) + oldVertexCount * sizeof(QSGGeometry::TexturedPoint2D), + oldIndexCount * sizeof(quint16)); + qFree(data); + } + + QSGGeometry::TexturedPoint2D *vp = g->vertexDataAsTexturedPoint2D() + oldVertexCount; + ushort *ip = g->indexDataAsUShort() + oldIndexCount; QPointF margins(2, 2); QPointF texMargins = margins / m_glyph_cache->fontScale(); @@ -167,12 +190,12 @@ void QSGDistanceFieldGlyphNode::updateGeometry() m_baseLine = glyphPosition; int vi = i & 1 ? (glyphIndexes.size() + 1) / 2 + i / 2 : i / 2; - vp[4 * vi + 0] = QVector4D(cx1, cy1, tx1, ty1); - vp[4 * vi + 1] = QVector4D(cx2, cy1, tx2, ty1); - vp[4 * vi + 2] = QVector4D(cx1, cy2, tx1, ty2); - vp[4 * vi + 3] = QVector4D(cx2, cy2, tx2, ty2); + vp[4 * vi + 0].set(cx1, cy1, tx1, ty1); + vp[4 * vi + 1].set(cx2, cy1, tx2, ty1); + vp[4 * vi + 2].set(cx1, cy2, tx1, ty2); + vp[4 * vi + 3].set(cx2, cy2, tx2, ty2); - int o = i * 4; + int o = i * 4 + oldVertexCount; ip[6 * i + 0] = o + 0; ip[6 * i + 1] = o + 2; ip[6 * i + 2] = o + 3; @@ -181,6 +204,25 @@ void QSGDistanceFieldGlyphNode::updateGeometry() ip[6 * i + 5] = o + 0; } +// printf("Vertices:\n"); +// for (int v=0; vvertexCount(); ++v) { +// QSGGeometry::TexturedPoint2D *t = g->vertexDataAsTexturedPoint2D() + v; +// printf(" - %d -- %f %f -- %.3f %.3f\n", v, t->x, t->y, t->tx, t->ty); +// } + +// printf("Indices:\n"); +// for (int i=0; iindexCount();) { + +// printf(" - %[ ", i); +// printf("%d, ", g->indexDataAsUShort()[i++]); +// printf("%d, ", g->indexDataAsUShort()[i++]); +// printf("%d, ", g->indexDataAsUShort()[i++]); +// printf("%d, ", g->indexDataAsUShort()[i++]); +// printf("%d, ", g->indexDataAsUShort()[i++]); +// printf("%d", g->indexDataAsUShort()[i++]); +// printf(" ]\n"); +// } + setBoundingRect(boundingRect); markDirty(DirtyGeometry); } -- 2.7.4