From: Eskil Abrahamsen Blomfeldt Date: Thu, 15 Sep 2011 09:49:12 +0000 (+0200) Subject: Support preedit text in QSGTextInput X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=77bb02ff9095db0e7b2012e7bcc8411528d8319d;p=konrad%2Fqtdeclarative.git 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 --- 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; };