Attached find a series of RTL patches which we need OKs for in order to commit.

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);


Attachment: rtlboundary.patch
Description: Binary data

Attachment: rtlcursorx.patch
Description: Binary data

Attachment: rtlselection.patch
Description: Binary data

Attachment: PGP.sig
Description: Signierter Teil der Nachricht

Reply via email to