diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2011-09-15 11:49:12 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-09-15 13:37:51 +0200 |
commit | 77bb02ff9095db0e7b2012e7bcc8411528d8319d (patch) | |
tree | b9c07d9357e69c8742f40ab22c5d352924fe0db2 | |
parent | dff8ec47d958be4d0861344c546b84218f41bc1e (diff) |
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 <qt_sanity_bot@ovi.com>
Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
-rw-r--r-- | src/declarative/items/qsgtextnode.cpp | 124 | ||||
-rw-r--r-- | 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 8e31903c66..5ff8395022 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<QTextLayout::FormatRange> *mergedFormats) +{ + Q_ASSERT(mergedFormats != 0); + if (textLayout == 0) + return; + + QList<QTextLayout::FormatRange> additionalFormats = textLayout->additionalFormats(); + for (int i=0; i<additionalFormats.size(); ++i) { + QTextLayout::FormatRange additionalFormat = additionalFormats.at(i); + if (additionalFormat.format.hasProperty(QTextFormat::ForegroundBrush) + || additionalFormat.format.hasProperty(QTextFormat::BackgroundBrush)) { + // Merge overlapping formats + if (!mergedFormats->isEmpty()) { + 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<QTextLayout::FormatRange> additionalFormats; - if (textLayout != 0) - additionalFormats = textLayout->additionalFormats(); QVarLengthArray<QTextLayout::FormatRange> colorChanges; - for (int i=0; i<additionalFormats.size(); ++i) { - QTextLayout::FormatRange additionalFormat = additionalFormats.at(i); - if (additionalFormat.format.hasProperty(QTextFormat::ForegroundBrush) - || additionalFormat.format.hasProperty(QTextFormat::BackgroundBrush)) { - // Merge overlapping formats - if (!colorChanges.isEmpty()) { - QTextLayout::FormatRange *lastFormat = colorChanges.data() + colorChanges.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; - - 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<QTextLayout::FormatRange> additionalFormats = textLayout->additionalFormats(); + int preeditLength = textLayout->preeditAreaText().length(); + int preeditPosition = textLayout->preeditAreaPosition(); + QVarLengthArray<QTextLayout::FormatRange> colorChanges; - for (int i=0; i<additionalFormats.size(); ++i) { - if (additionalFormats.at(i).format.hasProperty(QTextFormat::ForegroundBrush)) - colorChanges.append(additionalFormats.at(i)); - } + mergeFormats(textLayout, &colorChanges); for (int i=0; i<textLayout->lineCount(); ++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 6d68fd1df6..b8e8cd6e4b 100644 --- a/src/declarative/items/qsgtextnode_p.h +++ b/src/declarative/items/qsgtextnode_p.h @@ -47,10 +47,11 @@ #include <qglyphrun.h> #include <QtGui/qcolor.h> +#include <QtGui/qtextlayout.h> +#include <QtCore/qvarlengtharray.h> 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<QTextLayout::FormatRange> *mergedFormats); + QSGContext *m_context; QSGSimpleRectNode *m_cursorNode; }; |