From 4056f0ddb150d0e5d60bc5941d51e365eed0ac86 Mon Sep 17 00:00:00 2001 From: Dov Feldstern Date: Sun, 24 Feb 2008 01:45:51 +0000 Subject: [PATCH] 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 --- src/Cursor.cpp | 31 +++++++++++++++---------------- src/Text2.cpp | 36 ++++++++++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/Cursor.cpp b/src/Cursor.cpp index b8e70680fd..ef62fea621 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -467,6 +467,21 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos) // known position around the cursor: 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 // on whether it is an RTL or LTR character... bool const cur_is_RTL = @@ -481,14 +496,6 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos) // determine the other one: 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; // *visual* position of 'left_pos': 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 - // 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; // *visual* position of 'right_pos' pos_type v_right_pos = bidi.log2vis(left_pos) + 1; diff --git a/src/Text2.cpp b/src/Text2.cpp index f34be2317a..b7dc9a13d6 100644 --- a/src/Text2.cpp +++ b/src/Text2.cpp @@ -711,10 +711,20 @@ bool Text::cursorVisLeft(Cursor & cur, bool skip_inset) // position 'left_pos' + 1. if (new_pos_is_RTL) { new_pos = left_pos + 1; - // if the position *after* left_pos is not RTL, set boundary to - // true (we want to be *after* left_pos, not before left_pos + 1!) - new_boundary = !cur.paragraph().getFontSettings( - cur.bv().buffer().params(), new_pos).isVisibleRightToLeft(); + // set the boundary to true in two situations: + if ( + // 1. if new_pos is now lastpos (which means that we're moving left + // 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 // 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. if (!new_pos_is_RTL) { new_pos = right_pos + 1; - // if the position *after* right_pos is RTL, set boundary to - // true (we want to be *after* right_pos, not before right_pos + 1!) - new_boundary = cur.paragraph().getFontSettings( - cur.bv().buffer().params(), new_pos).isVisibleRightToLeft(); + // set the boundary to true in two situations: + if ( + // 1. if new_pos is now lastpos (which means that we're moving + // 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 // moving to the right of it is as easy as setting the new position