QTextLayout: Fix cursor movement from invalid position
Actually guarantee cursor doesn't move in this case for both logical and visual modes (just what the documentation says we already do ;) Change-Id: Iabdca7aa1d205672386a0095e3487e585611cdb5 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
47056e78d3
commit
330f6e3598
@ -3138,11 +3138,12 @@ int QTextEngine::positionInLigature(const QScriptItem *si, int end,
|
|||||||
int QTextEngine::previousLogicalPosition(int oldPos) const
|
int QTextEngine::previousLogicalPosition(int oldPos) const
|
||||||
{
|
{
|
||||||
const QCharAttributes *attrs = attributes();
|
const QCharAttributes *attrs = attributes();
|
||||||
if (!attrs || oldPos < 0)
|
int len = block.isValid() ? block.length() - 1
|
||||||
|
: layoutData->string.length();
|
||||||
|
Q_ASSERT(len <= layoutData->string.length());
|
||||||
|
if (!attrs || oldPos <= 0 || oldPos > len)
|
||||||
return oldPos;
|
return oldPos;
|
||||||
|
|
||||||
if (oldPos <= 0)
|
|
||||||
return 0;
|
|
||||||
oldPos--;
|
oldPos--;
|
||||||
while (oldPos && !attrs[oldPos].graphemeBoundary)
|
while (oldPos && !attrs[oldPos].graphemeBoundary)
|
||||||
oldPos--;
|
oldPos--;
|
||||||
@ -3224,7 +3225,6 @@ int QTextEngine::beginningOfLine(int lineNum)
|
|||||||
|
|
||||||
int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation op)
|
int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation op)
|
||||||
{
|
{
|
||||||
if (!layoutData)
|
|
||||||
itemize();
|
itemize();
|
||||||
|
|
||||||
bool moveRight = (op == QTextCursor::Right);
|
bool moveRight = (op == QTextCursor::Right);
|
||||||
@ -3233,7 +3233,8 @@ int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation
|
|||||||
return moveRight ^ alignRight ? nextLogicalPosition(pos) : previousLogicalPosition(pos);
|
return moveRight ^ alignRight ? nextLogicalPosition(pos) : previousLogicalPosition(pos);
|
||||||
|
|
||||||
int lineNum = lineNumberForTextPosition(pos);
|
int lineNum = lineNumberForTextPosition(pos);
|
||||||
Q_ASSERT(lineNum >= 0);
|
if (lineNum < 0)
|
||||||
|
return pos;
|
||||||
|
|
||||||
QVector<int> insertionPoints;
|
QVector<int> insertionPoints;
|
||||||
insertionPointsForLine(lineNum, insertionPoints);
|
insertionPointsForLine(lineNum, insertionPoints);
|
||||||
@ -3256,6 +3257,8 @@ int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation
|
|||||||
if (lineNum > 0)
|
if (lineNum > 0)
|
||||||
return alignRight ? beginningOfLine(lineNum - 1) : endOfLine(lineNum - 1);
|
return alignRight ? beginningOfLine(lineNum - 1) : endOfLine(lineNum - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
|
@ -674,7 +674,10 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
|
|||||||
int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const
|
int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const
|
||||||
{
|
{
|
||||||
const QCharAttributes *attributes = d->attributes();
|
const QCharAttributes *attributes = d->attributes();
|
||||||
if (!attributes || oldPos <= 0 || oldPos > d->layoutData->string.length())
|
int len = d->block.isValid() ? d->block.length() - 1
|
||||||
|
: d->layoutData->string.length();
|
||||||
|
Q_ASSERT(len <= d->layoutData->string.length());
|
||||||
|
if (!attributes || oldPos <= 0 || oldPos > len)
|
||||||
return oldPos;
|
return oldPos;
|
||||||
|
|
||||||
if (mode == SkipCharacters) {
|
if (mode == SkipCharacters) {
|
||||||
|
@ -71,6 +71,8 @@ private slots:
|
|||||||
void bidiCursorMovement();
|
void bidiCursorMovement();
|
||||||
void bidiCursorLogicalMovement_data();
|
void bidiCursorLogicalMovement_data();
|
||||||
void bidiCursorLogicalMovement();
|
void bidiCursorLogicalMovement();
|
||||||
|
void bidiInvalidCursorNoMovement_data();
|
||||||
|
void bidiInvalidCursorNoMovement();
|
||||||
};
|
};
|
||||||
|
|
||||||
tst_QComplexText::tst_QComplexText()
|
tst_QComplexText::tst_QComplexText()
|
||||||
@ -272,6 +274,37 @@ void tst_QComplexText::bidiCursorLogicalMovement()
|
|||||||
} while (moved);
|
} while (moved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QComplexText::bidiInvalidCursorNoMovement_data()
|
||||||
|
{
|
||||||
|
bidiCursorMovement_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QComplexText::bidiInvalidCursorNoMovement()
|
||||||
|
{
|
||||||
|
QFETCH(QString, logical);
|
||||||
|
QFETCH(int, basicDir);
|
||||||
|
|
||||||
|
QTextLayout layout(logical);
|
||||||
|
|
||||||
|
QTextOption option = layout.textOption();
|
||||||
|
option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft);
|
||||||
|
layout.setTextOption(option);
|
||||||
|
|
||||||
|
// visual
|
||||||
|
QCOMPARE(layout.rightCursorPosition(-1000), -1000);
|
||||||
|
QCOMPARE(layout.rightCursorPosition(1000), 1000);
|
||||||
|
|
||||||
|
QCOMPARE(layout.leftCursorPosition(-1000), -1000);
|
||||||
|
QCOMPARE(layout.leftCursorPosition(1000), 1000);
|
||||||
|
|
||||||
|
// logical
|
||||||
|
QCOMPARE(layout.nextCursorPosition(-1000), -1000);
|
||||||
|
QCOMPARE(layout.nextCursorPosition(1000), 1000);
|
||||||
|
|
||||||
|
QCOMPARE(layout.previousCursorPosition(-1000), -1000);
|
||||||
|
QCOMPARE(layout.previousCursorPosition(1000), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QComplexText::bidiCursor_PDF()
|
void tst_QComplexText::bidiCursor_PDF()
|
||||||
{
|
{
|
||||||
QString str = QString::fromUtf8("\342\200\252hello\342\200\254");
|
QString str = QString::fromUtf8("\342\200\252hello\342\200\254");
|
||||||
|
Loading…
Reference in New Issue
Block a user