diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com> | 2015-03-20 14:21:46 +0100 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com> | 2015-03-24 11:37:03 +0000 |
commit | 7a874de4db87bfb3fd40e47bb488850a8a4047d4 (patch) | |
tree | 2b2280b576ee44cde89c1d54bfb050a9c9e19d2f /src/quick/items/qquicktextnodeengine.cpp | |
parent | a501ea6401430d79737a18d807446d223777bb8e (diff) |
Fix disappearing text in selections
Change 11a595e30615943cd6c63f08cc44cde7861112eb introduced a
regression where selected text might disappear randomly because
we changed the order the nodes were added to the list. The
order is significant in cases where there is overlap, such as
for painting selections.
Instead of iterating over the hash and thus getting the regular
nodes in random order, we make the first node with any given
key the primary node, add this to the list immediately, and then
just do a look up in the hash for the nodes that should be
merged with it.
Change-Id: Id2208ab672294aa3dd2bc9741e6c6697c2c66746
Task-number: QTBUG-45133
Reviewed-by: aavit <eirik.aavitsland@theqtcompany.com>
Diffstat (limited to 'src/quick/items/qquicktextnodeengine.cpp')
-rw-r--r-- | src/quick/items/qquicktextnodeengine.cpp | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp index 14d305ad50..7903f79e89 100644 --- a/src/quick/items/qquicktextnodeengine.cpp +++ b/src/quick/items/qquicktextnodeengine.cpp @@ -50,6 +50,14 @@ QT_BEGIN_NAMESPACE +QQuickTextNodeEngine::BinaryTreeNodeKey::BinaryTreeNodeKey(BinaryTreeNode *node) + : fontEngine(QRawFontPrivate::get(node->glyphRun.rawFont())->fontEngine) + , clipNode(node->clipNode) + , color(node->color.rgba()) + , selectionState(node->selectionState) +{ +} + QQuickTextNodeEngine::BinaryTreeNode::BinaryTreeNode(const QGlyphRun &g, SelectionState selState, const QRectF &brect, @@ -680,35 +688,34 @@ uint qHash(const QQuickTextNodeEngine::BinaryTreeNodeKey &key) void QQuickTextNodeEngine::mergeProcessedNodes(QList<BinaryTreeNode *> *regularNodes, QList<BinaryTreeNode *> *imageNodes) { - QMultiHash<BinaryTreeNodeKey, BinaryTreeNode *> map; + QHash<BinaryTreeNodeKey, QList<BinaryTreeNode *> > map; for (int i = 0; i < m_processedNodes.size(); ++i) { BinaryTreeNode *node = m_processedNodes.data() + i; if (node->image.isNull()) { - QRawFont rawFont = node->glyphRun.rawFont(); - QRawFontPrivate *rawFontD = QRawFontPrivate::get(rawFont); - QFontEngine *fontEngine = rawFontD->fontEngine; - - BinaryTreeNodeKey key(fontEngine, - node->clipNode, - node->color.rgba(), - int(node->selectionState)); - map.insertMulti(key, node); + BinaryTreeNodeKey key(node); + + QList<BinaryTreeNode *> &nodes = map[key]; + if (nodes.isEmpty()) + regularNodes->append(node); + + nodes.append(node); } else { imageNodes->append(node); } } - QMultiHash<BinaryTreeNodeKey, BinaryTreeNode *>::const_iterator it = map.constBegin(); - while (it != map.constEnd()) { - BinaryTreeNode *primaryNode = it.value(); - regularNodes->append(primaryNode); + for (int i = 0; i < regularNodes->size(); ++i) { + BinaryTreeNode *primaryNode = regularNodes->at(i); + BinaryTreeNodeKey key(primaryNode); + + const QList<BinaryTreeNode *> &nodes = map.value(key); + Q_ASSERT(nodes.first() == primaryNode); int count = 0; - QMultiHash<BinaryTreeNodeKey, BinaryTreeNode *>::const_iterator jt; - for (jt = it; jt != map.constEnd() && jt.key() == it.key(); ++jt) - count += jt.value()->glyphRun.glyphIndexes().size(); + for (int j = 0; j < nodes.size(); ++j) + count += nodes.at(j)->glyphRun.glyphIndexes().size(); if (count != primaryNode->glyphRun.glyphIndexes().size()) { QGlyphRun &glyphRun = primaryNode->glyphRun; @@ -718,24 +725,21 @@ void QQuickTextNodeEngine::mergeProcessedNodes(QList<BinaryTreeNode *> *regularN QVector<QPointF> glyphPositions = glyphRun.positions(); glyphPositions.reserve(count); - for (jt = it + 1; jt != map.constEnd() && jt.key() == it.key(); ++jt) { - BinaryTreeNode *otherNode = jt.value(); + for (int j = 1; j < nodes.size(); ++j) { + BinaryTreeNode *otherNode = nodes.at(j); glyphIndexes += otherNode->glyphRun.glyphIndexes(); primaryNode->ranges += otherNode->ranges; QVector<QPointF> otherPositions = otherNode->glyphRun.positions(); - for (int j = 0; j < otherPositions.size(); ++j) - glyphPositions += otherPositions.at(j) + (otherNode->position - primaryNode->position); + for (int k = 0; k < otherPositions.size(); ++k) + glyphPositions += otherPositions.at(k) + (otherNode->position - primaryNode->position); } - it = jt; Q_ASSERT(glyphPositions.size() == count); Q_ASSERT(glyphIndexes.size() == count); glyphRun.setGlyphIndexes(glyphIndexes); glyphRun.setPositions(glyphPositions); - } else { - ++it; } } } |