aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/items
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2011-08-31 12:47:20 +0200
committerJiang Jiang <jiang.jiang@nokia.com>2011-08-31 18:13:38 +0200
commit565a7827bb2a7c7af23eade8f3c8809c72f81251 (patch)
tree2ebfc3cd90152b7b93489f034b52a78b0f945943 /src/declarative/items
parent01335edc94d2961bd4061ed2cb81ebd1151797bf (diff)
Support font color with Text.StyledText in SceneGraph
When Text.StyledText is set as format, QML will use a QTextLayout back-end with additional formats to render styled text, supporting a few HTML tags. To support color changes using this format, we need to process the additional formats in the text node. The code that fetches glyph runs is now separated into its own function and is called once per color-changing format if any such exist. Task-number: QTBUG-21199 Change-Id: Ib9b0cbec8d23de2dfafae9f641a2e3f7819c6a7a Reviewed-on: http://codereview.qt.nokia.com/3982 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
Diffstat (limited to 'src/declarative/items')
-rw-r--r--src/declarative/items/qsgtextnode.cpp94
1 files changed, 72 insertions, 22 deletions
diff --git a/src/declarative/items/qsgtextnode.cpp b/src/declarative/items/qsgtextnode.cpp
index 1ae457b6fa..a8a29bad24 100644
--- a/src/declarative/items/qsgtextnode.cpp
+++ b/src/declarative/items/qsgtextnode.cpp
@@ -281,6 +281,8 @@ namespace {
void addSelectedGlyphs(const QGlyphRun &glyphRun);
void addUnselectedGlyphs(const QGlyphRun &glyphRun);
+ void addGlyphsInRange(int rangeStart, int rangeEnd, const QColor &color,
+ int selectionStart, int selectionEnd);
void addToSceneGraph(QSGTextNode *parent,
QSGText::TextStyle style = QSGText::Normal,
@@ -568,6 +570,45 @@ namespace {
m_hasSelection = m_hasSelection || m_currentLineTree.size() > currentSize;
}
+ void SelectionEngine::addGlyphsInRange(int rangeStart, int rangeLength,
+ const QColor &color,
+ int selectionStart, int selectionEnd)
+ {
+ QColor oldColor = m_textColor;
+ m_textColor = color;
+
+ QTextLine &line = m_currentLine;
+ int rangeEnd = rangeStart + rangeLength;
+ if (selectionStart > rangeEnd || selectionEnd < rangeStart) {
+ QList<QGlyphRun> glyphRuns = line.glyphRuns(rangeStart, rangeLength);
+ for (int j=0; j<glyphRuns.size(); ++j)
+ addUnselectedGlyphs(glyphRuns.at(j));
+ } else {
+ if (rangeStart < selectionStart) {
+ QList<QGlyphRun> glyphRuns = line.glyphRuns(rangeStart,
+ qMin(selectionStart - rangeStart,
+ rangeLength));
+
+ for (int j=0; j<glyphRuns.size(); ++j)
+ addUnselectedGlyphs(glyphRuns.at(j));
+ }
+
+ if (rangeEnd >= selectionStart && selectionStart >= rangeStart) {
+ QList<QGlyphRun> glyphRuns = line.glyphRuns(selectionStart, selectionEnd - selectionStart + 1);
+
+ for (int j=0; j<glyphRuns.size(); ++j)
+ addSelectedGlyphs(glyphRuns.at(j));
+ }
+
+ if (selectionEnd >= rangeStart && selectionEnd < rangeEnd) {
+ QList<QGlyphRun> glyphRuns = line.glyphRuns(selectionEnd + 1, rangeEnd - selectionEnd);
+ for (int j=0; j<glyphRuns.size(); ++j)
+ addUnselectedGlyphs(glyphRuns.at(j));
+ }
+ }
+ m_textColor = oldColor;
+ }
+
void SelectionEngine::addToSceneGraph(QSGTextNode *parentNode,
QSGText::TextStyle style,
const QColor &styleColor)
@@ -761,39 +802,48 @@ void QSGTextNode::addTextLayout(const QPointF &position, QTextLayout *textLayout
engine.setSelectionColor(selectionColor);
engine.setPosition(position);
+ QList<QTextLayout::FormatRange> additionalFormats = textLayout->additionalFormats();
+ 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));
+ }
+
for (int i=0; i<textLayout->lineCount(); ++i) {
QTextLine line = textLayout->lineAt(i);
engine.setCurrentLine(line);
- int lineEnd = line.textStart() + line.textLength();
- if (selectionStart > lineEnd || selectionEnd < line.textStart()) {
- QList<QGlyphRun> glyphRuns = line.glyphRuns();
- for (int j=0; j<glyphRuns.size(); ++j)
- engine.addUnselectedGlyphs(glyphRuns.at(j));
- } else {
- if (line.textStart() < selectionStart) {
- QList<QGlyphRun> glyphRuns = line.glyphRuns(line.textStart(),
- qMin(selectionStart - line.textStart(),
- line.textLength()));
+ int currentPosition = line.textStart();
+ int remainingLength = line.textLength();
+ for (int j=0; j<colorChanges.size(); ++j) {
+ const QTextLayout::FormatRange &range = colorChanges.at(j);
+ if (range.start + range.length >= currentPosition
+ && range.start < currentPosition + remainingLength) {
- for (int j=0; j<glyphRuns.size(); ++j)
- engine.addUnselectedGlyphs(glyphRuns.at(j));
- }
+ if (range.start > currentPosition) {
+ engine.addGlyphsInRange(currentPosition, range.start - currentPosition,
+ color, selectionStart, selectionEnd);
+ }
- if (lineEnd >= selectionStart && selectionStart >= line.textStart()) {
- QList<QGlyphRun> glyphRuns = line.glyphRuns(selectionStart, selectionEnd - selectionStart + 1);
+ int rangeEnd = qMin(range.start + range.length, currentPosition + remainingLength);
+ QColor rangeColor = range.format.foreground().color();
- for (int j=0; j<glyphRuns.size(); ++j)
- engine.addSelectedGlyphs(glyphRuns.at(j));
- }
+ engine.addGlyphsInRange(range.start, rangeEnd - range.start, rangeColor,
+ selectionStart, selectionEnd);
- if (selectionEnd >= line.textStart() && selectionEnd < lineEnd) {
- QList<QGlyphRun> glyphRuns = line.glyphRuns(selectionEnd + 1, lineEnd - selectionEnd);
- for (int j=0; j<glyphRuns.size(); ++j)
- engine.addUnselectedGlyphs(glyphRuns.at(j));
+ currentPosition = range.start + range.length;
+ remainingLength = line.textStart() + line.textLength() - currentPosition;
+
+ } else if (range.start > currentPosition + remainingLength || remainingLength <= 0) {
+ break;
}
}
+
+ if (remainingLength > 0) {
+ engine.addGlyphsInRange(currentPosition, remainingLength, color,
+ selectionStart, selectionEnd);
+ }
}
engine.addToSceneGraph(this, style, styleColor);