1) rtlboundary.patch --- fixes bug 3754: Cursor movement at RTL-LTR boundary (http://bugzilla.lyx.org/show_bug.cgi?id=3754)
2) rtlcursorx.patch --- fixes issue (3) of bug 3551: Cursor movement in and around insets in RTL paragraphs (http://bugzilla.lyx.org/ show_bug.cgi?id=3551)
3) rtlselection.patch --- fixes bug 3550: Selection in mixed RTL-LTR paragraphs is broken (http://bugzilla.lyx.org/show_bug.cgi?id=3550)
You find the patches attached and the two short ones also inlined below. Stefan 1) rtlboundary.patch Index: src/Text2.cpp =================================================================== --- src/Text2.cpp (Revision 18644) +++ src/Text2.cpp (Arbeitskopie) @@ -1030,14 +1030,16 @@ // not at paragraph end? if (cur.pos() != cur.lastpos()) { - // if left of boundary -> just jump to right side - if (cur.boundary()) - return setCursor(cur, cur.pit(), cur.pos(), true, false); - // in front of editable inset, i.e. jump into it? if (checkAndActivateInset(cur, true)) return false; - + + // if left of boundary -> just jump to right side+ // but for RTL boundaries don't, because: abc|DDEEFFghi -> abcDDEEF|Fghi
+ if (cur.boundary() && + !bidi.isBoundary(cur.buffer(), cur.paragraph(), cur.pos())) + return setCursor(cur, cur.pit(), cur.pos(), true, false); + // next position is left of boundary, // but go to next line for special cases like space, newline, linesep #if 0 @@ -1062,6 +1064,11 @@ return setCursor(cur, cur.pit(), cur.pos() + 1, true, true); }+ // in front of RTL boundary? Stay on this side of the boundary because:
+ // ab|cDDEEFFghi -> abc|DDEEFFghi + if (bidi.isBoundary(cur.buffer(), cur.paragraph(), cur.pos() + 1)) + return setCursor(cur, cur.pit(), cur.pos() + 1, true, true); + // move right return setCursor(cur, cur.pit(), cur.pos() + 1, true, false); } 2) rtlcursorx.patch Index: src/Text.cpp =================================================================== --- src/Text.cpp (Revision 18626) +++ src/Text.cpp (Arbeitskopie) @@ -1687,20 +1755,13 @@ } // see correction above - if (boundary_correction) - if (getFont(buffer, par, ppos).isVisibleRightToLeft()) + if (boundary_correction) { + if (isRTL(buffer, sl, boundary)) x -= singleWidth(buffer, par, ppos); else x += singleWidth(buffer, par, ppos); + } - // Make sure inside an inset we always count from the left - // edge (bidi!) -- MV - if (sl.pos() < par.size()) { - font = getFont(buffer, par, sl.pos()); - if (!boundary && font.isVisibleRightToLeft() - && par.isInset(sl.pos())) - x -= par.getInset(sl.pos())->width(); - } return int(x); } Index: src/Text3.cpp =================================================================== --- src/Text3.cpp (Revision 18626) +++ src/Text3.cpp (Arbeitskopie) @@ -299,6 +299,20 @@ }+bool Text::isRTL(Buffer const & buffer, CursorSlice const & sl, bool boundary) const
+{ + if (!sl.text()) + return false; + + int correction = 0; + if (boundary && sl.pos() > 0) + correction = -1; + + Paragraph const & par = getPar(sl.pit());+ return getFont(buffer, par, sl.pos() + correction).isVisibleRightToLeft();
+} + + void Text::dispatch(Cursor & cur, FuncRequest & cmd) { LYXERR(Debug::ACTION) << "Text::dispatch: cmd: " << cmd << endl; Index: src/bufferview_funcs.cpp =================================================================== --- src/bufferview_funcs.cpp (Revision 18626) +++ src/bufferview_funcs.cpp (Arbeitskopie) @@ -161,15 +161,34 @@ { int x = 0; int y = 0; + int lastw = 0; - // Contribution of nested insets - for (size_t i = 1; i != dit.depth(); ++i) { + // Addup ontribution of nested insets, from inside to outside, + // keeping the outer paragraph for a special handling below + for (size_t i = dit.depth() - 1; i >= 1; --i) { CursorSlice const & sl = dit[i]; int xx = 0; int yy = 0; + + // get relative position inside sl.inset()sl.inset().cursorPos(bv, sl, boundary && ((i+1) == dit.depth()), xx, yy);
++ // Make relative position inside of the edited inset relative to sl.inset()
x += xx; y += yy; ++ // In case of an RTL inset, the edited inset will be positioned to the left
+ // of xx:yy + if (sl.text()) { + bool boundary_i = boundary && i + 1 == dit.depth(); + bool rtl = sl.text()->isRTL(*bv.buffer(), sl, boundary_i); + if (rtl) + x -= lastw; + } ++ // remember width for the case that sl.inset() is positioned in an RTL inset
+ lastw = sl.inset().width(); + //lyxerr << "Cursor::getPos, i: " // << i << " x: " << xx << " y: " << y << endl; } @@ -180,6 +199,7 @@ BOOST_ASSERT(!pm.rows().empty()); y -= pm.rows()[0].ascent(); #if 1 + // FIXME: document this mess size_t rend; if (sl.pos() > 0 && dit.depth() == 1) { int pos = sl.pos(); @@ -195,8 +215,18 @@ for (size_t rit = 0; rit != rend; ++rit) y += pm.rows()[rit].height(); y += pm.rows()[rend].ascent();- x += dit.bottom().text()->cursorX(bv, dit.bottom(), boundary && dit.depth() == 1);
- ++ // Make relative position from the nested inset now bufferview absolute. + int xx = dit.bottom().text()->cursorX(bv, dit.bottom(), boundary && dit.depth() == 1);
+ x += xx; + + // In the RTL case place the nested inset at the left of the cursor in + // the outer paragraph + bool boundary_1 = boundary && 1 == dit.depth();+ bool rtl = dit.bottom().text()->isRTL(*bv.buffer(), dit.bottom(), boundary_1);
+ if (rtl) + x -= lastw; + return Point(x, y); } Index: src/Text.h =================================================================== --- src/Text.h (Revision 18626) +++ src/Text.h (Arbeitskopie) @@ -333,6 +333,8 @@ docstring getPossibleLabel(Cursor & cur) const; /// is this paragraph right-to-left? bool isRTL(Buffer const &, Paragraph const & par) const; + /// is this position in the paragraph right-to-left?+ bool isRTL(Buffer const & buffer, CursorSlice const & sl, bool boundary) const;
/// bool checkAndActivateInset(Cursor & cur, bool front);
rtlboundary.patch
Description: Binary data
rtlcursorx.patch
Description: Binary data
rtlselection.patch
Description: Binary data
PGP.sig
Description: Signierter Teil der Nachricht