aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2011-06-23 10:40:39 +0200
committerGunnar Sletta <gunnar.sletta@nokia.com>2011-06-23 10:40:39 +0200
commit098b7fb0ac84dbe65a8861cce76e036f0b9198d6 (patch)
treeeaa86479874a61f8d201dc861e5b3cfd6d1a7d58
parentb35d6b475333fc2fabd0e91f1bfcf2f65aa4d4f4 (diff)
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
-rw-r--r--src/declarative/items/qsgtextnode.cpp30
-rw-r--r--src/declarative/items/qsgtextnode_p.h3
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp58
3 files changed, 72 insertions, 19 deletions
diff --git a/src/declarative/items/qsgtextnode.cpp b/src/declarative/items/qsgtextnode.cpp
index 6909d8cfca..b8dee689d5 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<QSGDistanceFieldGlyphNode *>(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<QSGDistanceFieldGlyphNode *>(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<QGlyphRun> glyphsList(textLayout->glyphRuns());
+
+ QSGGlyphNode *prevNode = 0;
+
for (int i=0; i<glyphsList.size(); ++i) {
QGlyphRun glyphs = glyphsList.at(i);
QRawFont font = glyphs.rawFont();
- addGlyphs(position + QPointF(0, font.ascent()), glyphs, color, style, styleColor);
+ prevNode = addGlyphs(position + QPointF(0, font.ascent()), glyphs, color, style, styleColor, prevNode);
}
}
diff --git a/src/declarative/items/qsgtextnode_p.h b/src/declarative/items/qsgtextnode_p.h
index 7a49f51dbe..e442b4cff2 100644
--- a/src/declarative/items/qsgtextnode_p.h
+++ b/src/declarative/items/qsgtextnode_p.h
@@ -73,7 +73,8 @@ private:
void addTextBlock(const QPointF &position, QTextDocument *textDocument, const QTextBlock &block,
const QColor &overrideColor, QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor());
QSGGlyphNode *addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color,
- QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor());
+ QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor(),
+ QSGGlyphNode *node = 0);
void addTextDecorations(const QPointF &position, const QRawFont &font, const QColor &color,
qreal width, bool hasOverline, bool hasStrikeOut, bool hasUnderline);
QSGContext *m_context;
diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp
index d826f7f1e7..4686067bd7 100644
--- a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp
+++ b/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp
@@ -124,9 +124,32 @@ void QSGDistanceFieldGlyphNode::updateGeometry()
m_glyph_cache->populate(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; v<g->vertexCount(); ++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; i<g->indexCount();) {
+
+// 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);
}