Qt Quick: Fix selection when mixing line breaks and line wraps

The enabler for finding selection ranges in Qt Quick had two bugs
which caused some selected text to disappear. Specifically, this
was the case for selected text where a line contained both an
explicit break and a break due to line wrapping.

First of all, the glyphsEnd that is passed into glyphRunsWithInfo()
is expected to be inclusive, since we are actually searching for
its index in the log cluster array. We would in certain cases
not find the glyph at all in the log clusters, thus the glyph
run would be set to overlap with any glyph run coming after it
in the same item.

Second of all, we need to start searching at the correct position
in the log clusters when searching for the correct rangeStart,
since rangeStart is initialized with textPosition. Otherwise, we
would in some cases never reach the start of the range, and
rangeStart would be set to textPosition + textLength, which is the
end of the range.

Task-number: QTBUG-49596
Change-Id: I436ba3f1c7414d4f5044d9b70aa04c60b01755e4
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
bb10
Eskil Abrahamsen Blomfeldt 2016-02-03 13:53:44 +01:00 committed by Friedemann Kleint
parent fef629cd91
commit 342c909b34
1 changed files with 10 additions and 9 deletions

View File

@ -2141,6 +2141,7 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine,
QGlyphRunPrivate *d = QGlyphRunPrivate::get(glyphRun);
int rangeStart = textPosition;
logClusters += textPosition;
while (*logClusters != glyphsStart && rangeStart < textPosition + textLength) {
++logClusters;
++rangeStart;
@ -2325,16 +2326,16 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
if (mainFontEngine->type() == QFontEngine::Multi) {
QFontEngineMulti *multiFontEngine = static_cast<QFontEngineMulti *>(mainFontEngine);
int end = rtl ? glyphLayout.numGlyphs : 0;
int start = rtl ? end : 0;
int which = glyphLayout.glyphs[rtl ? start - 1 : end] >> 24;
for (; (rtl && start > 0) || (!rtl && end < glyphLayout.numGlyphs);
int start = rtl ? glyphLayout.numGlyphs : 0;
int end = start - 1;
int which = glyphLayout.glyphs[rtl ? start - 1 : end + 1] >> 24;
for (; (rtl && start > 0) || (!rtl && end < glyphLayout.numGlyphs - 1);
rtl ? --start : ++end) {
const int e = glyphLayout.glyphs[rtl ? start - 1 : end] >> 24;
const int e = glyphLayout.glyphs[rtl ? start - 1 : end + 1] >> 24;
if (e == which)
continue;
QGlyphLayout subLayout = glyphLayout.mid(start, end - start);
QGlyphLayout subLayout = glyphLayout.mid(start, end - start + 1);
multiFontEngine->ensureEngineAt(which);
QGlyphRun::GlyphRunFlags subFlags = flags;
@ -2358,13 +2359,13 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
}
if (rtl)
end = start;
end = start - 1;
else
start = end;
start = end + 1;
which = e;
}
QGlyphLayout subLayout = glyphLayout.mid(start, end - start);
QGlyphLayout subLayout = glyphLayout.mid(start, end - start + 1);
multiFontEngine->ensureEngineAt(which);
QGlyphRun::GlyphRunFlags subFlags = flags;