fix a visual cursor edge-case:

Only when an LTR paragraph *ends with* an RTL chunk of text, movement was 
incorrect in two ways:

1. After moving into the pargraph from the end, and then trying to move towards
the beginning of the paragraph, the cursor would immediately jump to the 
previous pargraph.

2. If the cursor were placed inside the RTL text, and then we would move left
towards the beginning of the paragraph, upon reaching the end (beginning?) of
the RTL chunk, cursor would jump to the end of the paragraph, and then continue
as in (1).

(Same thing, of course, with the reverse situation, i.e., RTL paragraph ending
with LTR text).

We now deal with both of these cases correctly.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23173 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Dov Feldstern 2008-02-24 01:45:51 +00:00
parent b313333c1a
commit 4056f0ddb1
2 changed files with 43 additions and 24 deletions

View File

@ -467,6 +467,21 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos)
// known position around the cursor: // known position around the cursor:
pos_type known_pos = boundary() ? pos() - 1 : pos(); pos_type known_pos = boundary() ? pos() - 1 : pos();
// edge case: if we're at the end of the paragraph, things are a little
// different (because lastpos is a position which does not really "exist"
// --- there's no character there yet).
if (known_pos == lastpos()) {
if (par.isRTL(buf.params())) {
left_pos = -1;
right_pos = bidi.vis2log(row.pos());
}
else { // LTR paragraph
right_pos = -1;
left_pos = bidi.vis2log(row.endpos() - 1);
}
return;
}
// Whether 'known_pos' is to the left or to the right of the cursor depends // Whether 'known_pos' is to the left or to the right of the cursor depends
// on whether it is an RTL or LTR character... // on whether it is an RTL or LTR character...
bool const cur_is_RTL = bool const cur_is_RTL =
@ -481,14 +496,6 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos)
// determine the other one: // determine the other one:
if (known_pos_on_right) { if (known_pos_on_right) {
// edge-case: we're at the end of the paragraph, there isn't really any
// position any further to the right
if (known_pos == lastpos()) {
right_pos = -1;
left_pos = row.endpos() - 1;
return;
}
// the normal case
right_pos = known_pos; right_pos = known_pos;
// *visual* position of 'left_pos': // *visual* position of 'left_pos':
pos_type v_left_pos = bidi.log2vis(right_pos) - 1; pos_type v_left_pos = bidi.log2vis(right_pos) - 1;
@ -521,14 +528,6 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos)
} }
} }
else { // known_pos is on the left else { // known_pos is on the left
// edge-case: we're at the end of the paragraph, there isn't really any
// position any further to the left
if (known_pos == lastpos()) {
left_pos = -1;
right_pos = row.endpos() - 1;
return;
}
// the normal case
left_pos = known_pos; left_pos = known_pos;
// *visual* position of 'right_pos' // *visual* position of 'right_pos'
pos_type v_right_pos = bidi.log2vis(left_pos) + 1; pos_type v_right_pos = bidi.log2vis(left_pos) + 1;

View File

@ -711,10 +711,20 @@ bool Text::cursorVisLeft(Cursor & cur, bool skip_inset)
// position 'left_pos' + 1. // position 'left_pos' + 1.
if (new_pos_is_RTL) { if (new_pos_is_RTL) {
new_pos = left_pos + 1; new_pos = left_pos + 1;
// if the position *after* left_pos is not RTL, set boundary to // set the boundary to true in two situations:
// true (we want to be *after* left_pos, not before left_pos + 1!) if (
new_boundary = !cur.paragraph().getFontSettings( // 1. if new_pos is now lastpos (which means that we're moving left
cur.bv().buffer().params(), new_pos).isVisibleRightToLeft(); // to the end of an RTL chunk which is at the end of an LTR
// paragraph);
new_pos == cur.lastpos()
// 2. if the position *after* left_pos is not RTL (we want to be
// *after* left_pos, not before left_pos + 1!)
|| !cur.paragraph().getFontSettings(cur.bv().buffer().params(),
new_pos).isVisibleRightToLeft()
)
new_boundary = true;
else // set the boundary to false
new_boundary = false;
} }
// Otherwise (if the character at position 'left_pos' is LTR), then // Otherwise (if the character at position 'left_pos' is LTR), then
// moving to the left of it is as easy as setting the new position // moving to the left of it is as easy as setting the new position
@ -791,10 +801,20 @@ bool Text::cursorVisRight(Cursor & cur, bool skip_inset)
// position 'right_pos' + 1. // position 'right_pos' + 1.
if (!new_pos_is_RTL) { if (!new_pos_is_RTL) {
new_pos = right_pos + 1; new_pos = right_pos + 1;
// if the position *after* right_pos is RTL, set boundary to // set the boundary to true in two situations:
// true (we want to be *after* right_pos, not before right_pos + 1!) if (
new_boundary = cur.paragraph().getFontSettings( // 1. if new_pos is now lastpos (which means that we're moving
cur.bv().buffer().params(), new_pos).isVisibleRightToLeft(); // right to the end of an LTR chunk which is at the end of an
// RTL paragraph);
new_pos == cur.lastpos()
// 2. if the position *after* right_pos is RTL (we want to be
// *after* right_pos, not before right_pos + 1!)
|| cur.paragraph().getFontSettings(cur.bv().buffer().params(),
new_pos).isVisibleRightToLeft()
)
new_boundary = true;
else // set the boundary to false
new_boundary = false;
} }
// Otherwise (if the character at position 'right_pos' is RTL), then // Otherwise (if the character at position 'right_pos' is RTL), then
// moving to the right of it is as easy as setting the new position // moving to the right of it is as easy as setting the new position