From 0e99f3c853aa10f60aa33804c122b187edb565ea Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Mon, 23 Nov 2015 14:04:57 +0400 Subject: QTextLine::cursorToX: Always return the nearest valid cursor position The documentation already states we're doing this, so stop lying and implement it properly :) Change-Id: Ic78980d76f61e8aa64e59ea058a8105d9c507774 Reviewed-by: Lars Knoll --- src/gui/text/qtextlayout.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/gui/text/qtextlayout.cpp') diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 9f046af47c..e69a591d59 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2624,26 +2624,26 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR */ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const { - if (!eng->layoutData) - eng->itemize(); - const QScriptLine &line = eng->lines[index]; bool lastLine = index >= eng->lines.size() - 1; QFixed x = line.x; - x += eng->alignLine(line) - eng->leadingSpaceWidth(line); - if (!index && !eng->layoutData->items.size()) { - *cursorPos = 0; + if (!eng->layoutData) + eng->itemize(); + if (!eng->layoutData->items.size()) { + *cursorPos = line.from; return x.toReal(); } + x += eng->alignLine(line) - eng->leadingSpaceWidth(line); + int lineEnd = line.from + line.length + line.trailingSpaces; - int pos = qBound(0, *cursorPos, lineEnd); + int pos = qBound(line.from, *cursorPos, lineEnd); int itm; const QCharAttributes *attributes = eng->attributes(); if (!attributes) { - *cursorPos = 0; + *cursorPos = line.from; return x.toReal(); } while (pos < lineEnd && !attributes[pos].graphemeBoundary) @@ -2655,7 +2655,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const else itm = eng->findItem(pos); if (itm < 0) { - *cursorPos = 0; + *cursorPos = line.from; return x.toReal(); } eng->shapeLine(line); -- cgit v1.2.3 From 073a16e50e5803fc92dc46bca704f8a7ef79e597 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 21 Nov 2015 00:34:43 +0400 Subject: QTextLine::cursorToX: Optimize by re-using the cached values (and move some code around) Change-Id: I2e26dcc7b769fdbcc750332845da11ec88e332dd Reviewed-by: Lars Knoll --- src/gui/text/qtextlayout.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'src/gui/text/qtextlayout.cpp') diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index e69a591d59..67af3d316b 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2663,18 +2663,14 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const const QScriptItem *si = &eng->layoutData->items[itm]; if (!si->num_glyphs) eng->shape(itm); - pos -= si->position; + + const int l = eng->length(itm); + pos = qBound(0, pos - si->position, l); QGlyphLayout glyphs = eng->shapedGlyphs(si); unsigned short *logClusters = eng->logClusters(si); Q_ASSERT(logClusters); - int l = eng->length(itm); - if (pos > l) - pos = l; - if (pos < 0) - pos = 0; - int glyph_pos = pos == l ? si->num_glyphs : logClusters[pos]; if (edge == Trailing && glyph_pos < si->num_glyphs) { // trailing edge is leading edge of next cluster @@ -2683,7 +2679,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const glyph_pos++; } - bool reverse = eng->layoutData->items[itm].analysis.bidiLevel % 2; + bool reverse = si->analysis.bidiLevel % 2; // add the items left of the cursor @@ -2710,13 +2706,15 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const x += si.width; continue; } + + const int itemLength = eng->length(item); int start = qMax(line.from, si.position); - int end = qMin(lineEnd, si.position + eng->length(item)); + int end = qMin(lineEnd, si.position + itemLength); logClusters = eng->logClusters(&si); int gs = logClusters[start-si.position]; - int ge = (end == si.position + eng->length(item)) ? si.num_glyphs-1 : logClusters[end-si.position-1]; + int ge = (end == si.position + itemLength) ? si.num_glyphs-1 : logClusters[end-si.position-1]; QGlyphLayout glyphs = eng->shapedGlyphs(&si); -- cgit v1.2.3 From fa00afe7d760d91cf9c91f57dd2f77625e758e28 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 21 Nov 2015 01:04:39 +0400 Subject: Optimize QTextEngine::findItem() usage cases Since the item positions are guaranteed to grow, we could safely re-use the obtained first item while looking for the last item in the chain. Change-Id: I5e42f5de820c62a51a109a4b227b031c697aa898 Reviewed-by: Lars Knoll --- src/gui/text/qtextlayout.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gui/text/qtextlayout.cpp') diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 67af3d316b..5f570fea82 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2685,7 +2685,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const // add the items left of the cursor int firstItem = eng->findItem(line.from); - int lastItem = eng->findItem(lineEnd - 1); + int lastItem = eng->findItem(lineEnd - 1, itm); int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0; QVarLengthArray visualOrder(nItems); @@ -2786,7 +2786,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const return line.from; int firstItem = eng->findItem(line.from); - int lastItem = eng->findItem(line.from + line_length - 1); + int lastItem = eng->findItem(line.from + line_length - 1, firstItem); int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0; if (!nItems) -- cgit v1.2.3 From d06d7413d5ac22e2c0d65e3144e80da6c716f9f5 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 25 Nov 2015 11:16:12 +0100 Subject: Fix QTextLine::cursorToX() 0e99f3c broke tst_qquicktextinput::horizontalAlignment_RightToLeft() and tst_qquicktextedit::hAlign_RightToLeft(). This fix was proposed by Konstantin. Change-Id: I602b7301d415f266224ae2c1ffd81244e9565862 Reviewed-by: Simon Hausmann Reviewed-by: Lars Knoll --- src/gui/text/qtextlayout.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/gui/text/qtextlayout.cpp') diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 5f570fea82..65650504ac 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2627,7 +2627,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const const QScriptLine &line = eng->lines[index]; bool lastLine = index >= eng->lines.size() - 1; - QFixed x = line.x; + QFixed x = line.x + eng->alignLine(line) - eng->leadingSpaceWidth(line); if (!eng->layoutData) eng->itemize(); @@ -2636,8 +2636,6 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const return x.toReal(); } - x += eng->alignLine(line) - eng->leadingSpaceWidth(line); - int lineEnd = line.from + line.length + line.trailingSpaces; int pos = qBound(line.from, *cursorPos, lineEnd); int itm; -- cgit v1.2.3