From 77bb02ff9095db0e7b2012e7bcc8411528d8319d Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 15 Sep 2011 11:49:12 +0200 Subject: [PATCH] Support preedit text in QSGTextInput We need to support merged additional formats with backgrounds in the QSGTextInput as well, so that code has been separated into its own function. We also need to account for the position in the bounding rect, so that the decorations are painted at the correct location when there text input is scrolled. Task-number: QTBUG-21261 Change-Id: I0799a62bf26e6a7a2c1a6eef9bbdf889c1c8e870 Reviewed-on: http://codereview.qt-project.org/4964 Reviewed-by: Qt Sanity Bot Reviewed-by: Jiang Jiang --- src/declarative/items/qsgtextnode.cpp | 124 ++++++++++++++++++-------------- src/declarative/items/qsgtextnode_p.h | 5 +- 2 files changed, 74 insertions(+), 55 deletions(-) diff --git a/src/declarative/items/qsgtextnode.cpp b/src/declarative/items/qsgtextnode.cpp index 8e31903..5ff8395 100644 --- a/src/declarative/items/qsgtextnode.cpp +++ b/src/declarative/items/qsgtextnode.cpp @@ -213,6 +213,7 @@ namespace { { int newIndex = binaryTree->size(); QRectF searchRect = glyphRun.boundingRect(); + searchRect.translate(position); if (qFuzzyIsNull(searchRect.width()) || qFuzzyIsNull(searchRect.height())) return; @@ -786,6 +787,59 @@ namespace { } } +void QSGTextNode::mergeFormats(QTextLayout *textLayout, + QVarLengthArray *mergedFormats) +{ + Q_ASSERT(mergedFormats != 0); + if (textLayout == 0) + return; + + QList additionalFormats = textLayout->additionalFormats(); + for (int i=0; iisEmpty()) { + QTextLayout::FormatRange *lastFormat = mergedFormats->data() + mergedFormats->size() - 1; + + if (additionalFormat.start < lastFormat->start + lastFormat->length) { + QTextLayout::FormatRange *mergedRange = 0; + + int length = additionalFormat.length; + if (additionalFormat.start > lastFormat->start) { + lastFormat->length = additionalFormat.start - lastFormat->start; + length -= lastFormat->length; + + mergedFormats->append(QTextLayout::FormatRange()); + mergedRange = mergedFormats->data() + mergedFormats->size() - 1; + lastFormat = mergedFormats->data() + mergedFormats->size() - 2; + } else { + mergedRange = lastFormat; + } + + mergedRange->format = lastFormat->format; + mergedRange->format.merge(additionalFormat.format); + mergedRange->start = additionalFormat.start; + + int end = qMin(additionalFormat.start + additionalFormat.length, + lastFormat->start + lastFormat->length); + + mergedRange->length = end - mergedRange->start; + length -= mergedRange->length; + + additionalFormat.start = end; + additionalFormat.length = length; + } + } + + if (additionalFormat.length > 0) + mergedFormats->append(additionalFormat); + } + } + +} + void QSGTextNode::addTextDocument(const QPointF &, QTextDocument *textDocument, const QColor &textColor, QSGText::TextStyle style, const QColor &styleColor, @@ -808,53 +862,8 @@ void QSGTextNode::addTextDocument(const QPointF &, QTextDocument *textDocument, int preeditLength = block.isValid() ? block.layout()->preeditAreaText().length() : 0; int preeditPosition = block.isValid() ? block.layout()->preeditAreaPosition() : -1; - QTextLayout *textLayout = block.layout(); - QList additionalFormats; - if (textLayout != 0) - additionalFormats = textLayout->additionalFormats(); QVarLengthArray colorChanges; - for (int i=0; istart + lastFormat->length) { - QTextLayout::FormatRange *mergedRange = 0; - - int length = additionalFormat.length; - if (additionalFormat.start > lastFormat->start) { - lastFormat->length = additionalFormat.start - lastFormat->start; - length -= lastFormat->length; - - colorChanges.append(QTextLayout::FormatRange()); - mergedRange = colorChanges.data() + colorChanges.size() - 1; - lastFormat = colorChanges.data() + colorChanges.size() - 2; - } else { - mergedRange = lastFormat; - } - - mergedRange->format = lastFormat->format; - mergedRange->format.merge(additionalFormat.format); - mergedRange->start = additionalFormat.start; - - int end = qMin(additionalFormat.start + additionalFormat.length, - lastFormat->start + lastFormat->length); - - mergedRange->length = end - mergedRange->start; - length -= mergedRange->length; - - additionalFormat.start = end; - additionalFormat.length = length; - } - } - - if (additionalFormat.length > 0) - colorChanges.append(additionalFormat); - } - } + mergeFormats(block.layout(), &colorChanges); QTextBlock::iterator blockIterator = block.begin(); int textPos = block.position(); @@ -918,20 +927,27 @@ void QSGTextNode::addTextLayout(const QPointF &position, QTextLayout *textLayout engine.setSelectionColor(selectionColor); engine.setPosition(position); - QList additionalFormats = textLayout->additionalFormats(); + int preeditLength = textLayout->preeditAreaText().length(); + int preeditPosition = textLayout->preeditAreaPosition(); + QVarLengthArray colorChanges; - for (int i=0; ilineCount(); ++i) { QTextLine line = textLayout->lineAt(i); + int start = line.textStart(); + int length = line.textLength(); + int end = start + length; + + if (preeditPosition >= 0 + && preeditPosition >= start + && preeditPosition < end) { + end += preeditLength; + } + engine.setCurrentLine(line); - engine.addGlyphsForRanges(colorChanges, - line.textStart(), line.textStart() + line.textLength(), - selectionStart, selectionEnd); + engine.addGlyphsForRanges(colorChanges, start, end, selectionStart, selectionEnd); } engine.addToSceneGraph(this, style, styleColor); diff --git a/src/declarative/items/qsgtextnode_p.h b/src/declarative/items/qsgtextnode_p.h index 6d68fd1..b8e8cd6 100644 --- a/src/declarative/items/qsgtextnode_p.h +++ b/src/declarative/items/qsgtextnode_p.h @@ -47,10 +47,11 @@ #include #include +#include +#include QT_BEGIN_NAMESPACE -class QTextLayout; class QSGGlyphNode; class QTextBlock; class QColor; @@ -95,6 +96,8 @@ public: QSGNode *parentNode = 0); private: + void mergeFormats(QTextLayout *textLayout, QVarLengthArray *mergedFormats); + QSGContext *m_context; QSGSimpleRectNode *m_cursorNode; }; -- 1.7.2.5