]> git.lyx.org Git - features.git/commitdiff
applied the hebrew patch
authorLars Gullik Bjønnes <larsbj@gullik.org>
Thu, 3 Feb 2000 19:51:27 +0000 (19:51 +0000)
committerLars Gullik Bjønnes <larsbj@gullik.org>
Thu, 3 Feb 2000 19:51:27 +0000 (19:51 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@528 a592a061-630c-0410-9148-cb99ea01b6c8

20 files changed:
ChangeLog
src/BufferView.C
src/BufferView.h
src/LyXAction.C
src/buffer.C
src/commandtags.h
src/intl.h
src/layout.h
src/lyx_cb.C
src/lyx_cb.h
src/lyxfont.C
src/lyxfont.h
src/lyxfunc.C
src/lyxrc.C
src/lyxrc.h
src/lyxtext.h
src/paragraph.C
src/tex-strings.C
src/text.C
src/text2.C

index 597439972dfdf01dd109f5f7287c95af028650ba..da616d7d6771ecdd62906aed2c404f4c11a1c42a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 2000-02-03  Lars Gullik Bjønnes  <larsbj@lyx.org>
 
+       * applied the hebrew patch.
+
        * src/lyxrow.h: make sure that all Row variables are initialized.
 
        * src/text2.C (TextHandleUndo): comment out a delete, this might
index 994e28c095d91357938768cca192d20b4d0965e5..b228294cfc4819272b1e8426829870d27dcde6a5 100644 (file)
@@ -44,6 +44,8 @@ using std::for_each;
 #include "lyx_cb.h"
 #include "gettext.h"
 #include "layout.h"
+#include "intl.h"
+#include "lyxrc.h"
 
 using std::find_if;
 
@@ -467,6 +469,7 @@ int BufferView::resizeCurrentBuffer()
        updateScrollbar();
        redraw();
        owner_->getMiniBuffer()->Init();
+       SetState();
        AllowInput();
 
        // Now if the title form still exist kill it
@@ -1231,6 +1234,8 @@ int BufferView::WorkAreaButtonRelease(FL_OBJECT * ob, Window ,
            (abs(last_click_y - y) >= 5)) {
                return 0;
        }
+       SetState();
+       owner_->getMiniBuffer()->Set(CurrentState());
 
        // Did we hit an editable inset?
        if (inset_hit != 0) {
@@ -1303,15 +1308,15 @@ int BufferView::WorkAreaButtonRelease(FL_OBJECT * ob, Window ,
        // Do we want to close a float? (click on the float-label)
        if (text->cursor.row->par->footnoteflag == 
            LyXParagraph::OPEN_FOOTNOTE
-           && text->cursor.pos == 0
+           //&& text->cursor.pos == 0
            && text->cursor.row->previous &&
            text->cursor.row->previous->par->
            footnoteflag != LyXParagraph::OPEN_FOOTNOTE){
                LyXFont font (LyXFont::ALL_SANE);
-               font.setSize(LyXFont::SIZE_SMALL);
+               font.setSize(LyXFont::SIZE_FOOTNOTE);
 
                int box_x = 20; // LYX_PAPER_MARGIN;
-               box_x += font.textWidth("Mwide-figM", 10);
+               box_x += font.textWidth(" wide-tab ", 10);
 
                int screen_first = screen->first;
 
@@ -1351,8 +1356,10 @@ Inset * BufferView::checkInsetHit(int & x, int & y)
   
        int y_tmp = y + getScreen()->first;
   
-       LyXCursor cursor = text->cursor;
-       if (cursor.pos < cursor.par->Last() 
+       LyXCursor & cursor = text->cursor;
+       LyXDirection direction = text->GetFontDirection(text->real_current_font);
+
+       if (cursor.pos < cursor.par->Last()
            && cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET
            && cursor.par->GetInset(cursor.pos)
            && cursor.par->GetInset(cursor.pos)->Editable()) {
@@ -1360,26 +1367,50 @@ Inset * BufferView::checkInsetHit(int & x, int & y)
                // Check whether the inset really was hit
                Inset * tmpinset = cursor.par->GetInset(cursor.pos);
                LyXFont font = text->GetFont(cursor.par, cursor.pos);
-               if (x > cursor.x
-                   && x < cursor.x + tmpinset->Width(font) 
+               int start_x, end_x;
+               if (direction == LYX_DIR_LEFT_TO_RIGHT) {
+                       start_x = cursor.x;
+                       end_x = cursor.x + tmpinset->Width(font);
+               } else {
+                       start_x = cursor.x - tmpinset->Width(font);
+                       end_x = cursor.x;
+               }
+
+               if (x > start_x && x < end_x
                    && y_tmp > cursor.y - tmpinset->Ascent(font)
                    && y_tmp < cursor.y + tmpinset->Descent(font)) {
-                       x = x - cursor.x;
+                       x = x - start_x;
                        // The origin of an inset is on the baseline
                        y = y_tmp - (cursor.y); 
                        return tmpinset;
                }
-       } else if (cursor.pos - 1 >= 0 
+       }
+
+       if (cursor.pos - 1 >= 0
                   && cursor.par->GetChar(cursor.pos - 1) == LyXParagraph::META_INSET
                   && cursor.par->GetInset(cursor.pos - 1)
                   && cursor.par->GetInset(cursor.pos - 1)->Editable()) {
                text->CursorLeft();
-               Inset * result = checkInsetHit(x, y);
-               if (result == 0) {
+               Inset * tmpinset = cursor.par->GetInset(cursor.pos);
+               LyXFont font = text->GetFont(cursor.par, cursor.pos);
+               int start_x, end_x;
+               if (direction == LYX_DIR_LEFT_TO_RIGHT) {
+                       start_x = cursor.x;
+                       end_x = cursor.x + tmpinset->Width(font);
+               } else {
+                       start_x = cursor.x - tmpinset->Width(font);
+                       end_x = cursor.x;
+               }
+               if (x > start_x && x < end_x
+                   && y_tmp > cursor.y - tmpinset->Ascent(font)
+                   && y_tmp < cursor.y + tmpinset->Descent(font)) {
+                       x = x - start_x;
+                       // The origin of an inset is on the baseline
+                       y = y_tmp - (cursor.y); 
+                       return tmpinset;
+               } else {
                        text->CursorRight();
                        return 0;
-               } else {
-                       return result;
                }
        }
        return 0;
@@ -1759,6 +1790,22 @@ void BufferView::smallUpdate(signed char f)
        }
 }
 
+extern LyXRC * lyxrc;
+void BufferView::SetState() {
+       bool primary;
+
+       if (!lyxrc->rtl_support)
+               return;
+
+       if (text->GetFontDirection(text->real_current_font)
+           == LYX_DIR_LEFT_TO_RIGHT) {
+               if (!owner_->getIntl()->primarykeymap)
+                       owner_->getIntl()->KeyMapPrim();
+       } else {
+               if (owner_->getIntl()->primarykeymap)
+                       owner_->getIntl()->KeyMapSec();
+       }
+}
 
 void BufferView::insetSleep()
 {
index 9248a676baf34b17958973d6803c6f5a2e43da79..bba675ec06853892d3591da903ad0ea43c1f9aad 100644 (file)
@@ -207,6 +207,10 @@ public:
         */
        static int work_area_handler(FL_OBJECT *, int event,
                                     FL_Coord, FL_Coord, int key, void *xev);
+
+       ///
+       void SetState();
+
 private:
        ///
        int WorkAreaMotionNotify(FL_OBJECT * ob,
index b0fa6c6a9c0bb6f59d7c616ebfb747d4de995b12..33f1230e0e1ca8885f88d99c94bfc2a1ec12941c 100644 (file)
@@ -196,6 +196,7 @@ void LyXAction::init()
                { LFUN_NOUN, "font-noun", N_("Toggle noun style"), Noop },
                { LFUN_ROMAN, "font-roman", N_("Toggle roman font style"),
                  Noop },
+               { LFUN_RTL, "font-rtl", N_("Toggle RTL"), Noop },
                { LFUN_SANS, "font-sans", N_("Toggle sans font style"), Noop },
                { LFUN_FONT_SIZE, "font-size", N_("Set font size"), Noop },
                { LFUN_FONT_STATE, "font-state", N_("Show font state"),
index ffdcc8408143b36a2a90f1e012dc63b544313548..e4b86df493f3e6a437ff1b312ac76fc7618e1edc 100644 (file)
@@ -677,6 +677,18 @@ bool Buffer::readLyXformat2(LyXLex & lex, LyXParagraph * par)
                        else
                                lex.printError("Unknown LaTeX font flag "
                                               "`$$Token'");
+               } else if (token == "\\direction") {
+                       lex.next();
+                       string tok = lex.GetString();
+                       if (tok == "ltr")
+                               font.setDirection(LyXFont::LTR_DIR);
+                       else if (tok == "rtl")
+                               font.setDirection(LyXFont::RTL_DIR);
+                       else if (tok == "default")
+                               font.setDirection(LyXFont::INHERIT_DIR);
+                       else
+                               lex.printError("Unknown font flag "
+                                              "`$$Token'");
                } else if (token == "\\emph") {
                        lex.next();
                        font.setEmph(font.setLyXMisc(lex.GetString()));
@@ -1681,11 +1693,16 @@ void Buffer::makeLaTeXFile(string const & fname,
                    && params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
                        options += "landscape,";
                
-               // language should be a parameter to \documentclass
+               // language should be a parameter to \documentclass             
                if (params.language != "default") {
+                       if (params.language == "hebrew")
+                               options += "english,";
+                       else if (lyxrc->rtl_support)
+                               options += "hebrew,";
                        options += params.language + ',';
-               }
-               
+               } else if (lyxrc->rtl_support)
+                       options += "hebrew,english,";
+
                // the user-defined options
                if (!params.options.empty()) {
                        options += params.options + ',';
@@ -1840,7 +1857,7 @@ void Buffer::makeLaTeXFile(string const & fname,
 
                // We try to load babel late, in case it interferes
                // with other packages.
-               if (params.language != "default") {
+               if (params.language != "default" || lyxrc->rtl_support ) {
                        LFile += "\\usepackage{babel}\n";
                        texrow.newline();
                }
index debdb5ad3d50345440b46e7b61d5097558b667a1..d7ec3bf1775f31cfa8cdf1e5b780f36770feded3 100644 (file)
@@ -243,6 +243,7 @@ enum kb_action {
        LFUN_SEQUENCE,                  // Andre' 991111
        LFUN_SAVEPREFERENCES,           // Lgb 991127
        LFUN_DATE_INSERT,               // jdblair 20000131
+       LFUN_RTL,                       // Dekel 20000203
        LFUN_LASTACTION  /* this marks the end of the table */
 };
 
index 8cf5bf36d5976c5340fb2687168fa010c926e407..919966dcad652d5dead65814c84de6ba4050f29b 100644 (file)
@@ -58,6 +58,8 @@ public:
        ///
        bool keymapon;
        ///
+       bool primarykeymap;
+       ///
        char * chsetcode;
        ///
        static void DispatchCallback(FL_OBJECT *, long);
@@ -71,8 +73,6 @@ private:
        ///
        void Keymap(long code);
        ///
-       bool primarykeymap;
-       ///
        int curkeymap;
        ///
        int otherkeymap;
index 58cb39ce3bd7a2c3cd3a02dee18aebe7da1f4fe7..cef49cad6e3b109e1373d1db18be91e81c2a8376 100644 (file)
@@ -65,6 +65,15 @@ enum LYX_MARGIN_TYPE {
        MARGIN_RIGHT_ADDRESS_BOX
 };
 
+
+///
+enum LyXDirection {
+       ///
+       LYX_DIR_LEFT_TO_RIGHT = 1,
+       ///
+       LYX_DIR_RIGHT_TO_LEFT = -1
+};
+  
 ///
 enum LyXAlignment {
        ///
index c3aade0dcb6f3c94dfe541359d84a6c8aceec6ee..d9f67679947d30d747dca0a1159f7a41b6587755 100644 (file)
@@ -2104,6 +2104,7 @@ void BufferView::openStuff()
                update(-2);
                text->OpenStuff();
                update(0);
+               current_view->SetState();
        }
 }
 
@@ -2117,6 +2118,7 @@ void BufferView::toggleFloat()
                update(-2);
                text->ToggleFootnote();
                update(0);
+               current_view->SetState();
        }
 }
 
@@ -2132,6 +2134,7 @@ void BufferView::menuUndo()
                        owner()->getMiniBuffer()->Set(_("No further undo information"));
                else
                        update(-1);
+               current_view->SetState();
        }
 }
 
@@ -2152,6 +2155,7 @@ void BufferView::menuRedo()
                        owner()->getMiniBuffer()->Set(_("No further redo information"));
                else
                        update(-1);
+               current_view->SetState();
        }
 }
 
@@ -2315,6 +2319,14 @@ void TexCB()
        ToggleAndShow(font);
 }
 
+void RTLCB()
+{
+       LyXFont font(LyXFont::ALL_IGNORE);
+       font.setDirection (LyXFont::TOGGLE_DIR);
+       ToggleAndShow(font);
+}
+
+
 
 void StyleResetCB()
 {
@@ -2929,6 +2941,13 @@ extern "C" void DocumentApplyCB(FL_OBJECT *, long)
        if (!current_view->available())
                return;
 
+       if (lyxrc->rtl_support) {
+               current_view->text->SetCursor(current_view->text->cursor.par,
+                                             current_view->text->cursor.pos);
+               current_view->SetState();
+               //minibuffer->Set(CurrentState());
+       }
+
        LyXTextClassList::ClassList::size_type new_class = fl_get_choice(fd_form_document->choice_class) - 1;
        if (params->textclass != new_class) {
                // try to load new_class
@@ -3270,6 +3289,7 @@ extern "C" void TableApplyCB(FL_OBJECT *, long)
      
        current_view->update(1);
        current_view->owner()->getMiniBuffer()->Set(_("Table inserted"));
+       current_view->SetState();
 }
 
 
@@ -3534,6 +3554,7 @@ extern "C" void FigureApplyCB(FL_OBJECT *, long)
        current_view->update(0);
        current_view->owner()->getMiniBuffer()->Set(_("Figure inserted"));
        current_view->text->UnFreezeUndo();
+       current_view->SetState();
 }
 
 
index 9619bdd979c3eadc9309ff29aaa462a600598ef8..13c2854f06f2fc544f7f01c772aa28fc6ebd8e37 100644 (file)
@@ -24,6 +24,8 @@ extern void BoldCB();
 ///
 extern void NounCB();
 ///
+extern void RTLCB();
+///
 extern "C" void MarginCB(FL_OBJECT *, long);
 ///
 extern "C" void FigureCB(FL_OBJECT *, long);
index c51edfc9079c2cb4aa6f8e51eb57bfb1eed5305e..d7231df75a453c7ad2600294a021cfa9f9293203 100644 (file)
@@ -59,6 +59,9 @@ string const lGUISizeNames[15] =
 string const GUIMiscNames[5] = 
 { N_("Off"), N_("On"), N_("Toggle"), N_("Inherit"), N_("Ignore") };
 
+string const GUIDirectionNames[5] = 
+{ N_("LTR"), N_("RTL"), N_("Toggle"), N_("Inherit"), N_("Ignore") };
+
 string const GUIColorNames[13] = 
 { N_("None"), N_("Black"), N_("White"), N_("Red"), N_("Green"), N_("Blue"),
   N_("Cyan"), N_("Magenta"), 
@@ -240,6 +243,19 @@ void LyXFont::update(LyXFont const & newfont, bool toggleall)
        setNoun(setMisc(newfont.noun(), noun()));
        setLatex(setMisc(newfont.latex(), latex()));
 
+       switch(newfont.direction()) {
+       case TOGGLE_DIR:
+               if (direction() == LTR_DIR)
+                       setDirection(RTL_DIR);
+               else
+                       setDirection(LTR_DIR);
+               break;
+       case IGNORE_DIR:
+               break;
+       default:
+               setDirection(newfont.direction());
+       }
+
        if(newfont.color() == color() && toggleall)
                setColor(INHERIT_COLOR); // toggle 'back'
        else if (newfont.color() != IGNORE_COLOR)
@@ -268,6 +284,8 @@ void LyXFont::reduce(LyXFont const & tmplt)
                setLatex(INHERIT);
        if (color() == tmplt.color())
                setColor(INHERIT_COLOR);
+       if (direction() == tmplt.direction())
+               setDirection(INHERIT_DIR);
 }
 
 
@@ -325,6 +343,12 @@ LyXFont & LyXFont::realize(LyXFont const & tmplt)
                        bits &= ~(Col_Mask << Col_Pos);
                        bits |= (tmplt.bits & Col_Mask << Col_Pos);
                }
+       if ((bits & (Dir_Mask << Dir_Pos)) == ui32(INHERIT_DIR) << Dir_Pos)
+               {
+                       bits &= ~(Dir_Mask << Dir_Pos);
+                       bits |= (tmplt.bits & Dir_Mask << Dir_Pos);
+               }
+
        return *this;
 }
 
@@ -336,7 +360,8 @@ bool LyXFont::resolved() const
                shape() != INHERIT_SHAPE && size() != INHERIT_SIZE &&
                emph() != INHERIT && underbar() != INHERIT && 
                noun() != INHERIT && latex() != INHERIT && 
-               color() != INHERIT_COLOR);
+               color() != INHERIT_COLOR &&
+               direction() != INHERIT_DIR);
 }
 
 
@@ -363,6 +388,8 @@ string LyXFont::stateText() const
                buf += string(_("Noun ")) + _(GUIMiscNames[noun()].c_str()) + ", ";
        if (latex() != INHERIT)
                buf += string(_("Latex ")) + _(GUIMiscNames[latex()].c_str()) + ", ";
+       if (direction() != INHERIT_DIR)
+               buf += string(_("Direction ")) + _(GUIDirectionNames[direction()].c_str()) + ", ";
        if (buf.empty())
                buf = _("Default");
        buf = strip(buf, ' ');
@@ -549,6 +576,17 @@ LyXFont & LyXFont::lyxRead(LyXLex & lex)
                        lex.next();
                        string tok = lex.GetString();
                        setLyXColor(tok);
+               } else if (tok == "direction") {
+                       lex.next();
+                       string tok = lowercase(lex.GetString());
+
+                       if (tok == "ltr") {
+                               setDirection(LTR_DIR);
+                       } else if (tok == "rtl") {
+                               setDirection(RTL_DIR);
+                       } else {
+                               lex.printError("Illegal type`$$Token'");
+                       }
                } else {
                        lex.printError("Unknown tag `$$Token'");
                        error = true;
@@ -615,12 +653,26 @@ void LyXFont::lyxWriteChanges(LyXFont const & orgfont, ostream & os) const
        if (orgfont.color() != color()) {
                os << "\\color " << LyXColorNames[color()] << "\n";
        }
+       if (orgfont.direction() != direction()) {
+               switch (direction()) {
+               case RTL_DIR:   os << "\\direction rtl \n"; break;
+               case LTR_DIR:   os << "\\direction ltr\n"; break;
+               case TOGGLE_DIR:   lyxerr << "LyXFont::lyxWriteFontChanges: "
+                                       "TOGGLE should not appear here!"
+                                      << endl;
+               case INHERIT_DIR:   os << "\\direction default \n"; break;
+               case IGNORE_DIR:    lyxerr << "LyXFont::lyxWriteFontChanges: "
+                                       "IGNORE should not appear here!"
+                                      << endl;
+               break;
+               }
+       }
 }
 
 
 /// Writes the head of the LaTeX needed to impose this font
 // Returns number of chars written.
-int LyXFont::latexWriteStartChanges(string & file, LyXFont const & base) const
+int LyXFont::latexWriteStartChanges(string & file, LyXFont const & base, LyXFont const & prev) const
 {
        LyXFont f = *this;
        f.reduce(base);
@@ -630,7 +682,21 @@ int LyXFont::latexWriteStartChanges(string & file, LyXFont const & base) const
        
        int count = 0;
        bool env = false;
-       
+
+       FONT_DIRECTION direction = f.direction();
+       if (direction != prev.direction()) {
+               if (direction == LTR_DIR) {
+                       file += "\\L{";
+                       count += 3;
+                       env = true; //We have opened a new environment
+               }
+               if (direction == RTL_DIR) {
+                       file += "\\R{";
+                       count += 3;
+                       env = true; //We have opened a new environment
+               }
+       }
+
        if (f.family() != INHERIT_FAMILY) {
                file += '\\';
                file += LaTeXFamilyNames[f.family()];
@@ -693,7 +759,7 @@ int LyXFont::latexWriteStartChanges(string & file, LyXFont const & base) const
 /// Writes ending block of LaTeX needed to close use of this font
 // Returns number of chars written
 // This one corresponds to latexWriteStartChanges(). (Asger)
-int LyXFont::latexWriteEndChanges(string & file, LyXFont const & base) const
+int LyXFont::latexWriteEndChanges(string & file, LyXFont const & base, LyXFont const & next) const
 {
        LyXFont f = *this; // why do you need this?
        f.reduce(base); // why isn't this just "reduce(base);" (Lgb)
@@ -706,6 +772,15 @@ int LyXFont::latexWriteEndChanges(string & file, LyXFont const & base) const
        
        int count = 0;
        bool env = false;
+
+       FONT_DIRECTION direction = f.direction();
+       if ( direction != next.direction()
+           && (direction == RTL_DIR || direction == LTR_DIR) ) {
+               file += '}';
+               ++count;
+               env = true; // Size change need not bother about closing env.
+       }
+
        if (f.family() != INHERIT_FAMILY) {
                file += '}';
                ++count;
index 668cdde652f5fd2332a3bd874ae9278101290934..c8d003835d0e113cfaafa1e5ecd41383426d92d4 100644 (file)
@@ -119,6 +119,19 @@ public:
                IGNORE_SIZE
        };
  
+       enum FONT_DIRECTION {
+               ///
+               LTR_DIR,
+               ///
+               RTL_DIR,
+               ///
+               TOGGLE_DIR,
+               ///
+               INHERIT_DIR,
+               ///
+               IGNORE_DIR
+       };
+
        /// Used for emph, underbar, noun and latex toggles
        enum FONT_MISC_STATE {
                ///
@@ -227,7 +240,10 @@ public:
  
        ///
        FONT_COLOR color() const;
+
+       ///
+       FONT_DIRECTION direction() const;
+
        ///
        LyXFont & setFamily(LyXFont::FONT_FAMILY f);
        ///
@@ -246,7 +262,9 @@ public:
        LyXFont & setLatex(LyXFont::FONT_MISC_STATE l);
        ///
        LyXFont & setColor(LyXFont::FONT_COLOR c);
+       ///
+       LyXFont & setDirection(LyXFont::FONT_DIRECTION d);
+
        /// Set family after LyX text format
        LyXFont & setLyXFamily(string const &);
  
@@ -304,13 +322,15 @@ public:
            to this font. Returns number of chars written. Base is the
            font state active now.
        */
-       int latexWriteStartChanges(string &, LyXFont const & base) const;
+       int latexWriteStartChanges(string &, LyXFont const & base,
+                                  LyXFont const & prev) const;
 
        /** Writes tha tail of the LaTeX needed to chagne to this font.
            Returns number of chars written. Base is the font state we want
            to achieve.
        */
-       int latexWriteEndChanges(string &, LyXFont const & base) const;
+       int latexWriteEndChanges(string &, LyXFont const & base,
+                                LyXFont const & next) const;
  
        /// Build GUI description of font state
        string stateText() const;
@@ -405,7 +425,9 @@ private:
                ///
                Nou_Pos = 22,
                ///
-               Lat_Pos = 25
+               Lat_Pos = 25,
+               ///
+               Dir_Pos = 28
        };
 
        ///
@@ -421,6 +443,8 @@ private:
                ///
                Col_Mask = 0x0f,
                ///
+               Dir_Mask = 0x07,
+               ///
                Misc_Mask = 0x07
        };
  
@@ -433,7 +457,8 @@ private:
                | ui32(OFF) << Emp_Pos
                | ui32(OFF) << Und_Pos
                | ui32(OFF) << Nou_Pos
-               | ui32(OFF) << Lat_Pos};
+               | ui32(OFF) << Lat_Pos
+               | ui32(LTR_DIR) << Dir_Pos};
  
        /// All inherit font
        enum{ inherit = ui32(INHERIT_FAMILY) << Fam_Pos
@@ -444,7 +469,8 @@ private:
                      | ui32(INHERIT) << Emp_Pos
                      | ui32(INHERIT) << Und_Pos
                      | ui32(INHERIT) << Nou_Pos
-                     | ui32(INHERIT) << Lat_Pos};
+                     | ui32(INHERIT) << Lat_Pos
+                     | ui32(INHERIT_DIR) << Dir_Pos};
  
        /// All ignore font
        enum{ ignore = ui32(IGNORE_FAMILY) << Fam_Pos
@@ -455,7 +481,8 @@ private:
                      | ui32(IGNORE) << Emp_Pos
                      | ui32(IGNORE) << Und_Pos
                      | ui32(IGNORE) << Nou_Pos
-                     | ui32(IGNORE) << Lat_Pos};
+                     | ui32(IGNORE) << Lat_Pos
+                     | ui32(IGNORE_DIR) << Dir_Pos};
  
        /// Updates a misc setting according to request
        LyXFont::FONT_MISC_STATE setMisc(LyXFont::FONT_MISC_STATE newfont,
@@ -562,6 +589,10 @@ inline LyXFont::FONT_COLOR LyXFont::color() const
        return LyXFont::FONT_COLOR((bits >> Col_Pos) & Col_Mask);
 }
 
+inline LyXFont::FONT_DIRECTION LyXFont::direction() const 
+{
+       return LyXFont::FONT_DIRECTION((bits >> Dir_Pos) & Dir_Mask);
+}
 
 inline LyXFont & LyXFont::setFamily(LyXFont::FONT_FAMILY f)
 {
@@ -632,4 +663,12 @@ inline LyXFont & LyXFont::setColor(LyXFont::FONT_COLOR c)
        bits |= ui32(c) << Col_Pos;
        return *this;
 }
+
+inline LyXFont & LyXFont::setDirection(LyXFont::FONT_DIRECTION d)
+{
+       bits &= ~(Dir_Mask << Dir_Pos);
+       bits |= ui32(d) << Dir_Pos;
+       return *this;
+}
+
 #endif
index 996b3285430b815cf8933b70cccc92645af670f1..051edd32ca14ca9c4f817cf9396dbc7e6f98b672 100644 (file)
@@ -164,6 +164,7 @@ void LyXFunc::moveCursorUpdate(bool selecting)
        /* ---> Everytime the cursor is moved, show the current font state. */
        // should this too me moved out of this func?
        //owner->getMiniBuffer()->Set(CurrentState());
+       owner->view()->SetState();
 }
 
 
@@ -202,6 +203,8 @@ int LyXFunc::processKeyEvent(XEvent * ev)
            keysym_return == XK_Escape) {
                owner->view()->unlockInset(owner->view()->the_locking_inset);
                owner->view()->text->CursorRight();
+               moveCursorUpdate(false);
+               owner->getMiniBuffer()->Set(CurrentState());
                return 0;
        }
 
@@ -404,6 +407,10 @@ LyXFunc::func_status LyXFunc::getStatus(int ac) const
                        if (font.latex() == LyXFont::ON)
                                box = LyXFunc::ToggleOn;
                        break;
+               case LFUN_RTL:
+                       if (font.direction() == LyXFont::RTL_DIR)
+                               box = LyXFunc::ToggleOn;
+                       break;
                default:
                        box = LyXFunc::OK;
                        break;
@@ -547,8 +554,20 @@ string LyXFunc::Dispatch(int ac,
                                                return string();
                                        else {
                                                setMessage(N_("Text mode"));
-                                               if (action == LFUN_RIGHT || action == -1)
+                                               LyXDirection direction = owner->view()->text->GetParDirection(owner->view()->text->cursor.par);
+                                               if ( action == -1 ||
+                                                    (action == LFUN_RIGHT
+                                                     && direction == LYX_DIR_LEFT_TO_RIGHT)) {
                                                        owner->view()->text->CursorRight();
+                                                       moveCursorUpdate(false);
+                                                       owner->getMiniBuffer()->Set(CurrentState());
+                                               }
+                                               if ( action == LFUN_LEFT 
+                                                    && direction == LYX_DIR_RIGHT_TO_LEFT) {
+                                                       owner->view()->text->CursorRight();
+                                                       moveCursorUpdate(false);
+                                                       owner->getMiniBuffer()->Set(CurrentState());
+                                               }
                                                if (action == LFUN_LEFT || action == LFUN_RIGHT)
                                                        return string();
                                        }
@@ -918,6 +937,8 @@ string LyXFunc::Dispatch(int ac,
                
        case LFUN_TEX:
                TexCB();
+               owner->view()->SetState();
+               owner->getMiniBuffer()->Set(CurrentState());
                break;
                
        case LFUN_MELT:
@@ -938,7 +959,8 @@ string LyXFunc::Dispatch(int ac,
                                        MeltCB(ob, 0);
                        }
                else
-                       FootCB(ob, 0); 
+                       FootCB(ob, 0);
+               owner->view()->SetState();
                break;
 
        case LFUN_MARGINMELT:
@@ -952,6 +974,7 @@ string LyXFunc::Dispatch(int ac,
                }
                else
                        MarginCB(ob, 0); 
+               owner->view()->SetState();
                break;
                
                // --- version control -------------------------------
@@ -1140,6 +1163,14 @@ string LyXFunc::Dispatch(int ac,
                owner->getToolbar()->combox->Show();
                break;
 
+       case LFUN_RTL:
+       {
+               RTLCB();
+               owner->view()->SetState();
+               owner->getMiniBuffer()->Set(CurrentState());
+       }
+               break;
+
        case LFUN_EMPH:
                EmphCB();
                break;
@@ -1264,9 +1295,12 @@ string LyXFunc::Dispatch(int ac,
        case LFUN_RIGHT:
        {
                LyXText * tmptext = owner->view()->text;
+               LyXDirection direction = tmptext->GetParDirection(tmptext->cursor.par);
                if(!tmptext->mark_set)
                        owner->view()->beforeChange();
                owner->view()->update(-2);
+               if (direction == LYX_DIR_RIGHT_TO_LEFT)
+                       tmptext->CursorLeft();
                if (tmptext->cursor.pos < tmptext->cursor.par->Last()
                    && tmptext->cursor.par->GetChar(tmptext->cursor.pos)
                    == LyXParagraph::META_INSET
@@ -1277,7 +1311,8 @@ string LyXFunc::Dispatch(int ac,
                        tmpinset->Edit(0, 0);
                        break;
                }
-               tmptext->CursorRight();
+               if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                       tmptext->CursorRight();
                owner->view()->text->FinishUndo();
                moveCursorUpdate(false);
                owner->getMiniBuffer()->Set(CurrentState());
@@ -1289,9 +1324,11 @@ string LyXFunc::Dispatch(int ac,
                // This is soooo ugly. Isn`t it possible to make
                // it simpler? (Lgb)
                LyXText * txt = owner->view()->text;
+               LyXDirection direction = txt->GetParDirection(txt->cursor.par);
                if(!txt->mark_set) owner->view()->beforeChange();
                owner->view()->update(-2);
-               txt->CursorLeft();
+               if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                       txt->CursorLeft();
                if (txt->cursor.pos < txt->cursor.par->Last()
                    && txt->cursor.par->GetChar(txt->cursor.pos)
                    == LyXParagraph::META_INSET
@@ -1303,6 +1340,9 @@ string LyXFunc::Dispatch(int ac,
                                                                    txt->cursor.pos)), 0);
                        break;
                }
+               if  (direction == LYX_DIR_RIGHT_TO_LEFT)
+                       txt->CursorRight();
+
                owner->view()->text->FinishUndo();
                moveCursorUpdate(false);
                owner->getMiniBuffer()->Set(CurrentState());
@@ -1402,7 +1442,11 @@ string LyXFunc::Dispatch(int ac,
                if(!owner->view()->text->mark_set)
                        owner->view()->beforeChange();
                owner->view()->update(-2);
-               owner->view()->text->CursorRightOneWord();
+               if (owner->view()->text->GetParDirection(owner->view()->text->cursor.par) 
+                   == LYX_DIR_LEFT_TO_RIGHT)
+                       owner->view()->text->CursorRightOneWord();
+               else
+                       owner->view()->text->CursorLeftOneWord();
                owner->view()->text->FinishUndo();
                moveCursorUpdate(false);
                owner->getMiniBuffer()->Set(CurrentState());
@@ -1412,7 +1456,11 @@ string LyXFunc::Dispatch(int ac,
                if(!owner->view()->text->mark_set)
                        owner->view()->beforeChange();
                owner->view()->update(-2);
-               owner->view()->text->CursorLeftOneWord();
+               if (owner->view()->text->GetParDirection(owner->view()->text->cursor.par) 
+                   == LYX_DIR_LEFT_TO_RIGHT)
+                       owner->view()->text->CursorLeftOneWord();
+               else
+                       owner->view()->text->CursorRightOneWord();
                owner->view()->text->FinishUndo();
                moveCursorUpdate(false);
                owner->getMiniBuffer()->Set(CurrentState());
@@ -1442,7 +1490,11 @@ string LyXFunc::Dispatch(int ac,
                /* cursor selection ---------------------------- */
        case LFUN_RIGHTSEL:
                owner->view()->update(-2);
-               owner->view()->text->CursorRight();
+               if (owner->view()->text->GetParDirection(owner->view()->text->cursor.par)
+                   == LYX_DIR_LEFT_TO_RIGHT)
+                       owner->view()->text->CursorRight();
+               else
+                       owner->view()->text->CursorLeft();
                owner->view()->text->FinishUndo();
                moveCursorUpdate(true);
                owner->getMiniBuffer()->Set(CurrentState());
@@ -1450,7 +1502,11 @@ string LyXFunc::Dispatch(int ac,
                
        case LFUN_LEFTSEL:
                owner->view()->update(-2);
-               owner->view()->text->CursorLeft();
+               if (owner->view()->text->GetParDirection(owner->view()->text->cursor.par)
+                   == LYX_DIR_LEFT_TO_RIGHT)
+                       owner->view()->text->CursorLeft();
+               else
+                       owner->view()->text->CursorRight();
                owner->view()->text->FinishUndo();
                moveCursorUpdate(true);
                owner->getMiniBuffer()->Set(CurrentState());
@@ -1522,7 +1578,11 @@ string LyXFunc::Dispatch(int ac,
                
        case LFUN_WORDRIGHTSEL:
                owner->view()->update(-2);
-               owner->view()->text->CursorRightOneWord();
+               if (owner->view()->text->GetParDirection(owner->view()->text->cursor.par)
+                   == LYX_DIR_LEFT_TO_RIGHT)
+                       owner->view()->text->CursorRightOneWord();
+               else
+                       owner->view()->text->CursorLeftOneWord();
                owner->view()->text->FinishUndo();
                moveCursorUpdate(true);
                owner->getMiniBuffer()->Set(CurrentState());
@@ -1530,7 +1590,11 @@ string LyXFunc::Dispatch(int ac,
                
        case LFUN_WORDLEFTSEL:
                owner->view()->update(-2);
-               owner->view()->text->CursorLeftOneWord();
+               if (owner->view()->text->GetParDirection(owner->view()->text->cursor.par) 
+                   == LYX_DIR_LEFT_TO_RIGHT)
+                       owner->view()->text->CursorLeftOneWord();
+               else
+                       owner->view()->text->CursorRightOneWord();
                owner->view()->text->FinishUndo();
                moveCursorUpdate(true);
                owner->getMiniBuffer()->Set(CurrentState());
@@ -1599,6 +1663,9 @@ string LyXFunc::Dispatch(int ac,
                        owner->view()->cut();
                }
                SetUpdateTimer();
+               moveCursorUpdate(false);
+               owner->getMiniBuffer()->Set(CurrentState());
+               owner->view()->SetState();
                break;
 
        case LFUN_DELETE_SKIP:
@@ -1654,6 +1721,7 @@ string LyXFunc::Dispatch(int ac,
                owner->view()->update( 1 );
                SetUpdateTimer();
                moveCursorUpdate(false);
+               owner->getMiniBuffer()->Set(CurrentState());
                break;
 
                /* -------> Delete word backward. */
@@ -1664,6 +1732,7 @@ string LyXFunc::Dispatch(int ac,
                owner->view()->update( 1 );
                SetUpdateTimer();
                moveCursorUpdate(false);
+               owner->getMiniBuffer()->Set(CurrentState());
                break;
                
                /* -------> Kill to end of line. */
@@ -1712,6 +1781,8 @@ string LyXFunc::Dispatch(int ac,
                        owner->view()->cut();
                }
                SetUpdateTimer();
+               owner->getMiniBuffer()->Set(CurrentState());
+               owner->view()->SetState();
        }
        break;
 
@@ -1755,6 +1826,8 @@ string LyXFunc::Dispatch(int ac,
                SetUpdateTimer(0.01);
                owner->view()->text->sel_cursor = 
                        owner->view()->text->cursor;
+               owner->view()->SetState();
+               owner->getMiniBuffer()->Set(CurrentState());
                break;
        }
 
@@ -1766,6 +1839,8 @@ string LyXFunc::Dispatch(int ac,
                SetUpdateTimer(0.01);
                owner->view()->text->sel_cursor = 
                        owner->view()->text->cursor;
+               owner->view()->SetState();
+               owner->getMiniBuffer()->Set(CurrentState());
                break;
        }
        
@@ -1797,6 +1872,8 @@ string LyXFunc::Dispatch(int ac,
                }
                SetUpdateTimer(0.01);
                owner->view()->text->sel_cursor = cursor;
+               owner->view()->SetState();
+               owner->getMiniBuffer()->Set(CurrentState());
        }
        break;
        
@@ -2297,6 +2374,7 @@ string LyXFunc::Dispatch(int ac,
                }
                owner->view()->text->InsertFootnoteEnvironment(kind);
                owner->view()->update(1);
+               owner->view()->SetState();
        }
        break;
        
index b30469c415fb7da2036f2942862b2f4e05b96d60..11bf1382ddf00b88d4678b2596c7f09dbf933284 100644 (file)
@@ -128,6 +128,7 @@ enum LyXRCTags {
        RC_RELYX_COMMAND,
        RC_HTML_COMMAND,
        RC_MAKE_BACKUP,
+       RC_RTL_SUPPORT,
        RC_PDFLATEX_COMMAND,
        RC_PDF_MODE,
        RC_VIEWPDF_COMMAND,
@@ -204,6 +205,7 @@ static keyword_item lyxrcTags[] = {
        { "\\printer", RC_PRINTER },
        { "\\ps_command", RC_PS_COMMAND },
        { "\\relyx_command", RC_RELYX_COMMAND },
+       { "\\rtl", RC_RTL_SUPPORT },
        { "\\screen_dpi", RC_SCREEN_DPI },
        { "\\screen_font_encoding", RC_SCREEN_FONT_ENCODING },
        { "\\screen_font_menu", RC_SCREEN_FONT_MENU },
@@ -323,6 +325,7 @@ LyXRC::LyXRC()
        isp_use_esc_chars = false;
        use_kbmap = false;
        hasBindFile = false;
+       rtl_support = false;
        defaultKeyBindings();
        ///
        date_insert_format = "%A, %e. %B %Y";
@@ -911,6 +914,10 @@ int LyXRC::read(string const & filename)
                        if (lexrc.next())
                                date_insert_format = lexrc.GetString();
                        break;
+               case RC_RTL_SUPPORT:
+                       if (lexrc.next())
+                               rtl_support = lexrc.GetBool();
+                       break;
                case RC_LAST: break; // this is just a dummy
                }
        }
@@ -1199,6 +1206,8 @@ void LyXRC::output(ostream & os) const
                os << "\\personal_dictionary \"" << isp_pers_dict << "\"\n";
        case RC_ESC_CHARS:
                os << "\\escape_chars \"" << isp_esc_chars << "\"\n";
+       case RC_RTL_SUPPORT:
+               os << "\\rtl " << tostr(rtl_support) << "\n";
        case RC_MAKE_BACKUP:
                os << "\\make_backup " << tostr(make_backup) << "\n";
        case RC_DATE_INSERT_FORMAT:
index d1d30fbcda7f7a01a7ab91fb7d5ef9d6ce0e99bd..6b30d0a6db795d924c542e2a4a482fd71d95e5f8 100644 (file)
@@ -199,7 +199,8 @@ public:
        string lyxpipes;
        ///
        string date_insert_format;
-
+       ///
+       bool rtl_support;
 private:
        ///
        void defaultKeyBindings();
index e0f1ceb0cfe54a8d0792628025b9427cacf2aff6..4b3bd8190ddf519755993707c23dbddbe76d55c8 100644 (file)
@@ -21,6 +21,7 @@
 #include "undo.h"
 #include "lyxcursor.h"
 #include "lyxparagraph.h"
+#include "layout.h"
 
 class Buffer;
 class BufferParams;
@@ -226,10 +227,12 @@ public:
        void SelectSelectedWord();
        ///
        void SetCursor(LyXParagraph * par,
-                      LyXParagraph::size_type pos) const;
+                      LyXParagraph::size_type pos,
+                      bool setfont = true) const;
        ///
        void SetCursorIntern(LyXParagraph * par,
-                            LyXParagraph::size_type pos) const;
+                            LyXParagraph::size_type pos,
+                            bool setfont = true) const;
        ///
        void SetCursorFromCoordinates(int x, long y) const;
        ///
@@ -474,6 +477,18 @@ public:
         void toggleAppendix();
        ///
        unsigned short paperWidth() const { return paperwidth; }
+
+       ///
+       LyXDirection GetDocumentDirection() const;
+       ///
+       LyXDirection GetParDirection(LyXParagraph * par) const;
+
+       ///
+       LyXDirection GetFontDirection(LyXFont const &font) const;
+
+       ///
+       LyXDirection GetLetterDirection(LyXParagraph * par, LyXParagraph::size_type pos) const;
+
 private:
        /// width of the paper
        unsigned short  paperwidth;
@@ -523,7 +538,8 @@ private:
        void PrepareToPrint(Row * row, float & x,
                            float & fill_separator, 
                            float & fill_hfill,
-                           float & fill_label_hfill) const;
+                           float & fill_label_hfill,
+                           bool bidi = true) const;
        ///
        void DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const;
 
@@ -590,6 +606,41 @@ private:
          */
        bool HfillExpansion(Row const * row_ptr,
                            LyXParagraph::size_type pos) const;
+
+       ///
+       mutable vector<LyXParagraph::size_type> log2vis_list;
+
+       ///
+       mutable vector<LyXParagraph::size_type> vis2log_list;
+
+       ///
+       mutable LyXParagraph::size_type bidi_start;
+
+       ///
+       void ComputeBidiTables(Row *row) const;
+
+       ///
+       void ComputeBidiTablesFromTo(Row *row,
+                                    LyXParagraph::size_type from,
+                                    LyXParagraph::size_type to,
+                                    LyXParagraph::size_type offset) const;
+
+       /// Maps positions in the visual string to positions in logical string.
+       inline LyXParagraph::size_type log2vis(LyXParagraph::size_type pos) const {
+               if (bidi_start == -1)
+                       return pos;
+               else
+                       return log2vis_list[pos-bidi_start];
+       }
+
+       /// Maps positions in the logical string to positions in visual string.
+       inline LyXParagraph::size_type vis2log(LyXParagraph::size_type pos) const {
+               if (bidi_start == -1)
+                       return pos;
+               else
+                       return vis2log_list[pos-bidi_start];
+       }
+
        /** returns the paragraph position of the last character in the 
          specified row
          */
index b54f9b0f23c6d91244f4c224abb67794753985bf..c641f54f6d4923811dda233766b48418b1536b59 100644 (file)
@@ -985,6 +985,8 @@ LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos) const
                        tmpfont = layout.font;
                else
                        tmpfont = layout.labelfont;
+               if (current_view->text->GetParDirection((LyXParagraph *)this) == LYX_DIR_RIGHT_TO_LEFT)
+                       tmpfont.setDirection(LyXFont::RTL_DIR);
        }
 
        // check for environment font information
@@ -2314,6 +2316,17 @@ LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow,
                texrow.newline();
        }
 
+       LyXDirection direction = current_view->text->GetParDirection((LyXParagraph *)this);
+       LyXDirection global_direction = current_view->text->GetDocumentDirection();
+       if (direction != global_direction) {
+               if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                       file += "{\\unsethebrew\n";
+               else
+                       file += "{\\sethebrew\n";
+               texrow.newline();
+       }
+       
+
        switch (style.latextype) {
        case LATEX_COMMAND:
                file += '\\';
@@ -2368,6 +2381,9 @@ LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow,
        } else if (style.resfont.size() != font.size()){
                file += "{\\" + font.latexSize() + " \\par}";
        }
+
+       if (direction != global_direction)
+               file += "\\par}";
        
        switch (style.latextype) {
        case LATEX_ITEM_ENVIRONMENT:
@@ -2447,7 +2463,7 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
        bool return_value = false;
 
        LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass, GetLayout());
-       LyXFont basefont;
+       LyXFont basefont, last_font;
 
        // Maybe we have to create a optional argument.
        if (style.labeltype != LABEL_MANUAL)
@@ -2490,7 +2506,7 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
                if (i == main_body && !IsDummy()) {
                        if (main_body > 0) {
                                if (open_font) {
-                                       column += running_font.latexWriteEndChanges(file, basefont);
+                                       column += running_font.latexWriteEndChanges(file, basefont, basefont);
                                        open_font = false;
                                }
                                basefont = getFont(-1); // Now use the layout font
@@ -2535,6 +2551,7 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
 
                // Fully instantiated font
                LyXFont font = getFont(i);
+               last_font = running_font;
 
                // Spaces at end of font change are simulated to be
                // outside font change, i.e. we write "\textXX{text} "
@@ -2547,7 +2564,8 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
                // We end font definition before blanks
                if (!font.equalExceptLatex(running_font) && open_font) {
                        column += running_font.latexWriteEndChanges(file,
-                                                                   basefont);
+                                                                   basefont,
+                                                                   (i == main_body-1) ? basefont : font);
                        running_font = basefont;
                        open_font = false;
                }
@@ -2564,7 +2582,7 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
                // Do we need to change font?
                if (!font.equalExceptLatex(running_font)
                    && i != main_body-1) {
-                       column += font.latexWriteStartChanges(file, basefont);
+                       column += font.latexWriteStartChanges(file, basefont, last_font);
                        running_font = font;
                        open_font = true;
                }
@@ -2577,7 +2595,7 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
                                file += '\n';
                        } else {
                                if (open_font) {
-                                       column += running_font.latexWriteEndChanges(file, basefont);
+                                       column += running_font.latexWriteEndChanges(file, basefont, basefont);
                                        open_font = false;
                                }
                                basefont = getFont(-1);
@@ -2600,7 +2618,7 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
 
        // If we have an open font definition, we have to close it
        if (open_font) {
-               running_font.latexWriteEndChanges(file, basefont);
+               running_font.latexWriteEndChanges(file, basefont, basefont);
        }
 
        // Needed if there is an optional argument but no contents.
@@ -2662,6 +2680,7 @@ bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
        LyXFont basefont = getFont(-1); // Get layout font
        // Which font is currently active?
        LyXFont running_font = basefont;
+       LyXFont last_font;
        // Do we have an open font change?
        bool open_font = false;
        int current_cell_number = -1;
@@ -2682,6 +2701,7 @@ bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
                
                // Fully instantiated font
                LyXFont font = getFont(i);
+               last_font = running_font;
 
                // Spaces at end of font change are simulated to be
                // outside font change.
@@ -2695,7 +2715,7 @@ bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
                // We end font definition before blanks
                if (font != running_font && open_font) {
                        column += running_font.latexWriteEndChanges(file,
-                                                                   basefont);
+                                                                   basefont, font);
                        running_font = basefont;
                        open_font = false;
                }
@@ -2705,7 +2725,7 @@ bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
                }
                // Do we need to change font?
                if (font != running_font) {
-                       column += font.latexWriteStartChanges(file, basefont);
+                       column += font.latexWriteStartChanges(file, basefont, last_font);
                        running_font = font;
                        open_font = true;
                }
@@ -2723,7 +2743,7 @@ bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
                        // SimpleTeXSpecialChars()
                        if (open_font) {
                                column += running_font
-                                       .latexWriteEndChanges(file, basefont);
+                                       .latexWriteEndChanges(file, basefont, basefont);
                                open_font = false;
                        }
                        basefont = getFont(-1);
@@ -2761,7 +2781,7 @@ bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
 
        // If we have an open font definition, we have to close it
        if (open_font) {
-               running_font.latexWriteEndChanges(file, basefont);
+               running_font.latexWriteEndChanges(file, basefont, basefont);
        }
        ++current_cell_number;
        tmp = table->TexEndOfCell(file, current_cell_number);
@@ -2789,6 +2809,7 @@ bool LyXParagraph::TeXContTableRows(string & file,
                textclasslist.Style(current_view->buffer()->params.textclass,
                                    GetLayout());
        LyXFont basefont = getFont(-1); // Get layout font
+       LyXFont last_font;
        // Which font is currently active?
        LyXFont running_font = basefont;
        // Do we have an open font change?
@@ -2822,6 +2843,7 @@ bool LyXParagraph::TeXContTableRows(string & file,
 
                        // Fully instantiated font
                        LyXFont font = getFont(i);
+                       last_font = running_font;
 
                        // Spaces at end of font change are simulated to
                        // be outside font change. i.e. we write
@@ -2835,7 +2857,7 @@ bool LyXParagraph::TeXContTableRows(string & file,
 
                        // We end font definition before blanks
                        if (font != running_font && open_font) {
-                               column += running_font.latexWriteEndChanges(file, basefont);
+                               column += running_font.latexWriteEndChanges(file, basefont, font);
                                running_font = basefont;
                                open_font = false;
                        }
@@ -2848,7 +2870,7 @@ bool LyXParagraph::TeXContTableRows(string & file,
                        if (font != running_font) {
                                column +=
                                        font.latexWriteStartChanges(file,
-                                                                   basefont);
+                                                                   basefont, last_font);
                                running_font = font;
                                open_font = true;
                        }
@@ -2867,7 +2889,7 @@ bool LyXParagraph::TeXContTableRows(string & file,
                }
                // If we have an open font definition, we have to close it
                if (open_font) {
-                       running_font.latexWriteEndChanges(file, basefont);
+                       running_font.latexWriteEndChanges(file, basefont, basefont);
                        open_font = false;
                }
                basefont = getFont(-1);
@@ -3308,8 +3330,18 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
        case LyXParagraph::META_INSET: {
                Inset * inset = GetInset(i);
                if (inset) {
+                       bool close = false;
                        int len = file.length();
+                       if ( (inset->LyxCode() == Inset::GRAPHICS_CODE
+                             || inset->LyxCode() == Inset::MATH_CODE)
+                            && current_view->text->GetFontDirection(running_font)
+                            == LYX_DIR_RIGHT_TO_LEFT) {
+                               file += "\\L{";
+                               close = true;
+                       }
                        int tmp = inset->Latex(file, style.isCommand());
+                       if (close)
+                               file += "}";
                        
                        if (tmp) {
                                column = 0;
@@ -3326,7 +3358,7 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
        case LyXParagraph::META_NEWLINE:
                if (open_font) {
                        column += running_font.latexWriteEndChanges(file,
-                                                                   basefont);
+                                                                   basefont, basefont);
                        open_font = false;
                }
                basefont = getFont(-1);
index 11eb4ae9c6fbc7aa79f6a561ba883f1309f67659..75106e08366deefb37c9665ea1eeac3e01958405 100644 (file)
@@ -56,7 +56,7 @@ char const * tex_babel[] = {"default", "afrikaans", "american",
                           "english", "esperanto", "estonian",
                           "finnish", "francais", "french", "frenchb",
                           "galician",
-                          "german", "greek", "hungarian", "irish",
+                          "german", "greek", "hebrew", "hungarian", "irish",
                           "italian", "lsorbian", "magyar", "norsk",
                           "polish", "portuges", "romanian",
                           "russian", "scottish",
index 5c61b1cc2e37fb126504d9e19da95cecb161689b..49d1f0371497ddcd149972e1277db2dd290b3cda 100644 (file)
@@ -28,6 +28,7 @@
 #include "lyxscreen.h"
 #include "minibuffer.h"
 #include "debug.h"
+#include "lyxrc.h"
 #include "LyXView.h"
 
 using std::max;
@@ -39,6 +40,7 @@ extern int mono_video;
 extern int reverse_video;
 extern int fast_selection;
 extern BufferView * current_view;
+extern LyXRC * lyxrc;
 
 // ale070405
 extern int bibitemMaxWidth(LyXFont const &);
@@ -129,14 +131,152 @@ LyXParagraph::size_type LyXText::RowLast(Row const * row) const
                return row->next->pos - 1;
 }
 
+LyXDirection LyXText::GetDocumentDirection() const {
+       return (lyxrc->rtl_support && parameters->language == "hebrew")
+               ? LYX_DIR_RIGHT_TO_LEFT : LYX_DIR_LEFT_TO_RIGHT;
+}
+
+LyXDirection LyXText::GetParDirection(LyXParagraph * par) const {
+       if (!lyxrc->rtl_support || par->table)
+               return LYX_DIR_LEFT_TO_RIGHT;
+
+       if (par->size() > 0)
+               return (GetFont(par, 0).direction() ==  LyXFont::RTL_DIR)
+                       ? LYX_DIR_RIGHT_TO_LEFT : LYX_DIR_LEFT_TO_RIGHT;
+       else
+               return GetDocumentDirection();
+}
+
+LyXDirection LyXText::GetFontDirection(LyXFont const &font) const {
+       if (lyxrc->rtl_support 
+           && font.direction() == LyXFont::RTL_DIR
+           && font.latex() != LyXFont::ON)
+               return LYX_DIR_RIGHT_TO_LEFT;
+       else
+               return LYX_DIR_LEFT_TO_RIGHT;
+}
+
+LyXDirection LyXText::GetLetterDirection(LyXParagraph * par,
+                                        LyXParagraph::size_type pos) const {
+       if (!lyxrc->rtl_support)
+               return LYX_DIR_LEFT_TO_RIGHT;
+
+       LyXDirection direction = GetFontDirection(GetFont(par, pos));
+       if (par->IsLineSeparator(pos) && 0 < pos && pos < par->Last()-1
+           && !par->IsLineSeparator(pos+1)
+           && !(par->table && par->IsNewline(pos+1))
+           && ( GetFontDirection(GetFont(par, pos-1)) != direction ||
+                GetFontDirection(GetFont(par, pos+1)) != direction) )
+               return GetParDirection(par);
+       else
+               return direction;
+}
+
+void LyXText::ComputeBidiTables(Row *row) const {
+
+       if (!lyxrc->rtl_support) {
+               bidi_start = -1;
+               return;
+       }
+       LyXParagraph::size_type last = RowLast(row);
+       bidi_start = row->pos;
+
+       if (bidi_start > last) {
+               bidi_start = -1;
+               return;
+       }
+
+       if (last+2-bidi_start >
+           static_cast<LyXParagraph::size_type>(log2vis_list.size()) ) {
+               LyXParagraph::size_type new_size = 
+                       (last+2-bidi_start < 500) ? 500 : 2*(last+2-bidi_start);
+               log2vis_list.resize(new_size);
+               vis2log_list.resize(new_size);
+       }
+
+       vis2log_list[last+1-bidi_start] = -1;
+       log2vis_list[last+1-bidi_start] = -1;
+
+       LyXParagraph::size_type main_body = BeginningOfMainBody(row->par);
+       if (main_body > 0 && row->pos < main_body-1 && main_body-1 <= last
+           && row->par->IsLineSeparator(main_body-1)) {
+               // This is needed in case there is a direction change in
+               // the label which is continued into the main body
+               if (GetParDirection(row->par) == LYX_DIR_LEFT_TO_RIGHT) {
+                       ComputeBidiTablesFromTo(row,bidi_start,main_body-2,0);
+                       log2vis_list[main_body-1-bidi_start] = main_body-1;
+                       vis2log_list[main_body-1-bidi_start] = main_body-1;
+                       if (main_body <= last)
+                               ComputeBidiTablesFromTo(row,main_body,last,0);
+               } else {
+                       ComputeBidiTablesFromTo(row,bidi_start,main_body-2,last-main_body+2);
+                       log2vis_list[main_body-1-bidi_start] = last-main_body+1+bidi_start;
+                       vis2log_list[last-main_body+1-bidi_start] = main_body-1;
+                       if (main_body <= last)
+                               ComputeBidiTablesFromTo(row,main_body,last,-main_body);
+               }
+       } else
+               ComputeBidiTablesFromTo(row,bidi_start,last,0);
+}
+
+
+void LyXText::ComputeBidiTablesFromTo(Row *row,
+                                     LyXParagraph::size_type from,
+                                     LyXParagraph::size_type to,
+                                     LyXParagraph::size_type offset) const {
+
+       LyXParagraph::size_type vpos, old_lpos, stack[2];
+       LyXDirection par_direction = GetParDirection(row->par);
+       LyXDirection direction = par_direction;
+       LyXParagraph::size_type lpos = from;
+       int level = 0;
+
+       while (lpos <= to) {
+               if (GetLetterDirection(row->par, lpos) == direction) {
+                       log2vis_list[lpos-bidi_start] = direction;
+                       lpos++;
+               } else {
+                       if (level == 0 ||
+                           (level == 1 && direction == LYX_DIR_RIGHT_TO_LEFT
+                            && GetFont(row->par, lpos).direction() == LyXFont::RTL_DIR
+                            && GetFont(row->par, lpos).latex() == LyXFont::ON ) ) {
+                               // The last check is needed when the char is a space
+                               stack[level++] = lpos;
+                       } else {
+                               old_lpos = stack[--level];
+                               log2vis_list[old_lpos-bidi_start] = 
+                                       log2vis_list[lpos-bidi_start] =
+                                       (old_lpos-lpos)*direction;
+                               lpos++;
+                       }
+                       direction = static_cast<LyXDirection>(-direction);
+               }
+       }
+
+       while (level > 0) {
+               old_lpos = stack[--level];
+               log2vis_list[old_lpos-bidi_start] = (old_lpos-(to+1))*direction; 
+               direction = static_cast<LyXDirection>(-direction);
+       }
 
-void LyXText::Draw(Row const * row, LyXParagraph::size_type & pos,
+       vpos = (par_direction == LYX_DIR_LEFT_TO_RIGHT)
+               ? from-1 : to+1;
+       vpos += offset;
+       for (lpos = from; lpos <= to; lpos++) {
+               vpos += log2vis_list[lpos-bidi_start];
+               vis2log_list[vpos-bidi_start] = lpos;
+               log2vis_list[lpos-bidi_start] = vpos;
+       }
+}
+
+void LyXText::Draw(Row const * row, LyXParagraph::size_type & vpos,
                   LyXScreen & scr, int offset, float & x)
 {
+       LyXParagraph::size_type pos = vis2log(vpos);
        char c = row->par->GetChar(pos);
 
        if (IsNewlineChar(c)) {
-               ++pos;
+               ++vpos;
                // Draw end-of-line marker
 
                LyXFont font = GetFont(row->par, pos);
@@ -144,15 +284,28 @@ void LyXText::Draw(Row const * row, LyXParagraph::size_type & pos,
                int wid = font.width('n');
                int y = (offset + row->baseline);
                XPoint p[3];
-               p[0].x = int(x + wid*0.375); p[0].y = int(y - 0.875*asc*0.75);
-               p[1].x = int(x);             p[1].y = int(y - 0.500*asc*0.75);
-               p[2].x = int(x + wid*0.375); p[2].y = int(y - 0.125*asc*0.75);
-               scr.drawLines(::getGC(gc_new_line), p, 3);
+               if (GetLetterDirection(row->par, pos) == LYX_DIR_LEFT_TO_RIGHT) {
+                       p[0].x = int(x + wid*0.375); p[0].y = int(y - 0.875*asc*0.75);
+                       p[1].x = int(x);             p[1].y = int(y - 0.500*asc*0.75);
+                       p[2].x = int(x + wid*0.375); p[2].y = int(y - 0.125*asc*0.75);
+                       scr.drawLines(::getGC(gc_new_line), p, 3);
+               
+                       p[0].x = int(x);             p[0].y = int(y - 0.500*asc*0.75);
+                       p[1].x = int(x + wid);       p[1].y = int(y - 0.500*asc*0.75);
+                       p[2].x = int(x + wid);       p[2].y = int(y - asc*0.75);
+                       scr.drawLines(::getGC(gc_new_line), p, 3);
+               } else {
+                       p[0].x = int(x + wid*0.625); p[0].y = int(y - 0.875*asc*0.75);
+                       p[1].x = int(x + wid);       p[1].y = int(y - 0.500*asc*0.75);
+                       p[2].x = int(x + wid*0.625); p[2].y = int(y - 0.125*asc*0.75);
+                       scr.drawLines(::getGC(gc_new_line), p, 3);
                
-               p[0].x = int(x);             p[0].y = int(y - 0.500*asc*0.75);
-               p[1].x = int(x + wid);       p[1].y = int(y - 0.500*asc*0.75);
-               p[2].x = int(x + wid);       p[2].y = int(y - asc*0.75);
-               scr.drawLines(::getGC(gc_new_line), p, 3);
+                       p[0].x = int(x + wid);       p[0].y = int(y - 0.500*asc*0.75);
+                       p[1].x = int(x);             p[1].y = int(y - 0.500*asc*0.75);
+                       p[2].x = int(x);             p[2].y = int(y - asc*0.75);
+                       scr.drawLines(::getGC(gc_new_line), p, 3);
+               }
+               x += wid;
                return;
        }
 
@@ -210,13 +363,13 @@ void LyXText::Draw(Row const * row, LyXParagraph::size_type & pos,
                scr.drawLine(gc_foot, offset + row->baseline,
                             int(tmpx), int(x - tmpx));
          
-               ++pos;
+               ++vpos;
                return;
        } else if (c == LyXParagraph::META_INSET) {
                Inset * tmpinset = row->par->GetInset(pos);
                if (tmpinset) 
                        tmpinset->Draw(font, scr, offset + row->baseline, x);
-               ++pos;
+               ++vpos;
                return;
        }
 
@@ -235,15 +388,16 @@ void LyXText::Draw(Row const * row, LyXParagraph::size_type & pos,
        // will only overflow if the machine is out of memory...
        static string textstring;
        textstring = c;
-       ++pos;
+       ++vpos;
 
        LyXParagraph::size_type last = RowLast(row);
        
-       while (pos <= last
-              && static_cast<char>(c = row->par->GetChar(pos)) > ' '
+       while (vpos <= last &&
+              (pos = vis2log(vpos)) >= 0
+              && static_cast<unsigned char>(c = row->par->GetChar(pos)) > ' '
               && font2 == GetFont(row->par, pos)) {
                textstring += c;
-               ++pos;
+               ++vpos;
        }
        float tmpx = x;
 
@@ -604,7 +758,7 @@ bool LyXText::HitInTable(Row * row, int x) const
        if (!row->par->table)
                return false;
        PrepareToPrint(row, tmpx, fill_separator,
-                      fill_hfill, fill_label_hfill);
+                      fill_hfill, fill_label_hfill, false);
        return (x > tmpx && x < tmpx + row->par->table->WidthOfTable());
 }
 
@@ -767,8 +921,8 @@ int LyXText::Fill(Row const * row, int paper_width) const
        int left_margin = LabelEnd(row);
        
        // if the row ends with newline, this newline will not be relevant
-       if (last >= 0 && row->par->IsNewline(last))
-               --last;
+       //if (last >= 0 && row->par->IsNewline(last))
+       //      --last;
        
        // if the row ends with a space, this space will not be relevant
        if (last >= 0 && row->par->IsLineSeparator(last))
@@ -790,17 +944,25 @@ int LyXText::Fill(Row const * row, int paper_width) const
        LyXParagraph::size_type main_body = 
                BeginningOfMainBody(row->par);
        LyXParagraph::size_type i = row->pos;
+
        while (i <= last) {
-               w += SingleWidth(row->par, i);
-               ++i;
-               if (i == main_body) {
-                       w += GetFont(row->par, -2)
-                               .stringWidth(layout.labelsep);
+               if (main_body > 0 && i == main_body) {
+                       w += GetFont(row->par, -2).
+                               stringWidth(layout.labelsep);
                        if (row->par->IsLineSeparator(i - 1))
                                w -= SingleWidth(row->par, i - 1);
                        if (w < left_margin)
                                w = left_margin;
                }
+               w += SingleWidth(row->par, i);
+               ++i;
+       }
+       if (main_body > 0 && main_body > last) {
+               w += GetFont(row->par, -2).stringWidth(layout.labelsep);
+               if (last >= 0 && row->par->IsLineSeparator(last))
+                       w -= SingleWidth(row->par, last);
+               if (w < left_margin)
+                       w = left_margin;
        }
        
        fill = paper_width - w - RightMargin(row);
@@ -2380,16 +2542,16 @@ void  LyXText::InsertChar(char c)
                        status = LyXText::NEED_MORE_REFRESH;
             
                        BreakAgainOneRow(row);
-                       SetCursor(cursor.par, cursor.pos + 1);
+
+                       current_font = rawtmpfont;
+                       real_current_font = realtmpfont;
+                       SetCursor(cursor.par, cursor.pos + 1, false);
                        /* cursor MUST be in row now */
             
                        if (row->next && row->next->par == row->par)
                                need_break_row = row->next;
                        else
                                need_break_row = 0;
-
-                       current_font = rawtmpfont;
-                       real_current_font = realtmpfont;
             
                        // check, wether the last characters font has changed. 
                        if (cursor.pos && cursor.pos == cursor.par->Last()
@@ -2421,14 +2583,13 @@ void  LyXText::InsertChar(char c)
                                row = row->next;
                        BreakAgainOneRow(row);
                }
-               SetCursor(cursor.par, cursor.pos + 1);
+               current_font = rawtmpfont;
+               real_current_font = realtmpfont;
+               SetCursor(cursor.par, cursor.pos + 1, false);
                if (row->next && row->next->par == row->par)
                        need_break_row = row->next;
                else
-                       need_break_row = 0;
-               
-               current_font = rawtmpfont;
-               real_current_font = realtmpfont;
+                       need_break_row = 0;             
        } else {
                refresh_y = y;
                refresh_x = cursor.x;
@@ -2442,9 +2603,9 @@ void  LyXText::InsertChar(char c)
                else
                        status = LyXText::NEED_MORE_REFRESH;
             
-               SetCursor(cursor.par, cursor.pos + 1);
                current_font = rawtmpfont;
                real_current_font = realtmpfont;
+               SetCursor(cursor.par, cursor.pos + 1, false);
        }
 
        /* check, wether the last characters font has changed. */ 
@@ -2477,11 +2638,11 @@ void LyXText::charInserted()
        }
 }
 
-
 void LyXText::PrepareToPrint(Row * row, float & x,
                             float & fill_separator, 
                             float & fill_hfill,
-                            float & fill_label_hfill) const
+                            float & fill_label_hfill,
+                            bool bidi) const
 {
        float nh, nlh, ns;
        
@@ -2490,8 +2651,19 @@ void LyXText::PrepareToPrint(Row * row, float & x,
        fill_label_hfill = 0;
        fill_separator = 0;
        fill_label_hfill = 0;
-       
-       x = LeftMargin(row);
+
+       LyXDirection direction = GetParDirection(row->par);
+
+       if (direction == LYX_DIR_RIGHT_TO_LEFT) {
+               x = RightMargin(row);
+               if (row->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
+                       LyXFont font(LyXFont::ALL_SANE);
+                       font.setSize(LyXFont::SIZE_SMALL);
+                       x += font.textWidth("Mwide-figM", 10);
+               }
+       }
+       else
+               x = LeftMargin(row);
        
        /* is there a manual margin with a manual label */ 
        if (textclasslist.Style(parameters->textclass,
@@ -2522,11 +2694,11 @@ void LyXText::PrepareToPrint(Row * row, float & x,
        else  {
           /* is it block, flushleft or flushright? 
            * set x how you need it */
-          int align;
-          if (row->par->FirstPhysicalPar()->align == LYX_ALIGN_LAYOUT)
-            align = textclasslist.Style(parameters->textclass, row->par->GetLayout()).align;
-          else
-            align = row->par->FirstPhysicalPar()->align;
+       int align;
+       if (row->par->FirstPhysicalPar()->align == LYX_ALIGN_LAYOUT)
+         align = textclasslist.Style(parameters->textclass, row->par->GetLayout()).align;
+       else
+         align = row->par->FirstPhysicalPar()->align;
           
           /* center displayed insets */ 
           if (row->par->GetChar(row->pos) == LyXParagraph::META_INSET
@@ -2544,6 +2716,8 @@ void LyXText::PrepareToPrint(Row * row, float & x,
                       && row->next->par->GetInset(row->next->pos)->display())
                  )
                fill_separator = w / ns;
+             else if (direction == LYX_DIR_RIGHT_TO_LEFT)
+               x += w;
              break;
            case LYX_ALIGN_RIGHT:
              x += w;
@@ -2553,8 +2727,32 @@ void LyXText::PrepareToPrint(Row * row, float & x,
              break;
           }
        }
-     }
+       if (!bidi)
+               return;
 
+       ComputeBidiTables(row);
+       if (direction == LYX_DIR_RIGHT_TO_LEFT) {
+               LyXParagraph::size_type main_body = 
+                       BeginningOfMainBody(row->par);
+               LyXParagraph::size_type last = RowLast(row);
+
+               if (row->pos <= last
+                   && !row->par->table
+                   && last != vis2log(last)
+                   && row->par->IsLineSeparator(last)) {
+                       if (!(main_body > 0 && main_body-1 == last))
+                               x -= fill_separator+SingleWidth(row->par,last);
+               } else if (main_body > 0 &&
+                          (main_body-1 > last || 
+                           !row->par->IsLineSeparator(main_body-1))) {
+                       LyXLayout const & layout = textclasslist.Style(parameters->textclass,
+                                                                      row->par->GetLayout());
+                       x += GetFont(row->par, -2).stringWidth(layout.labelsep);
+                       if (main_body-1 <= last)
+                               x += fill_label_hfill;
+               }
+       }
+}
       
 /* important for the screen */
 
@@ -3203,9 +3401,9 @@ void  LyXText::Backspace()
                                refresh_y = y;
                                refresh_row = tmprow;
                                status = LyXText::NEED_MORE_REFRESH;
-                               SetCursor(cursor.par, cursor.pos);
                                current_font = rawtmpfont;
                                real_current_font = realtmpfont;
+                               SetCursor(cursor.par, cursor.pos, false);
                                // check, whether the last character's font has changed.
                                rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1);
                                if (rawparfont != rawtmpfont)
@@ -3234,8 +3432,9 @@ void  LyXText::Backspace()
                        status = LyXText::NEED_MORE_REFRESH;
                        
                        BreakAgainOneRow(row);
-                       
-                       SetCursor(cursor.par, cursor.pos);
+                       current_font = rawtmpfont; 
+                       real_current_font = realtmpfont;
+                       SetCursor(cursor.par, cursor.pos, false);
                        // cursor MUST be in row now
                        
                        if (row->next && row->next->par == row->par)
@@ -3253,7 +3452,9 @@ void  LyXText::Backspace()
                                status = LyXText::NEED_MORE_REFRESH;
                        refresh_y = y;
                        refresh_row = row;
-                       SetCursor(cursor.par, cursor.pos);
+                       current_font = rawtmpfont; 
+                       real_current_font = realtmpfont;
+                       SetCursor(cursor.par, cursor.pos, false);
                }
        }
    
@@ -3280,24 +3481,21 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
                            Row * row_ptr, long y)
 {
        /* returns a printed row */
-       LyXParagraph::size_type pos, pos_end;
+       LyXDirection direction = GetParDirection(row_ptr->par);
+       LyXParagraph::size_type vpos, pos, pos_end;
        float x, tmpx;
        int y_top, y_bottom;
        float fill_separator, fill_hfill, fill_label_hfill;
        LyXParagraph * par, * firstpar;
-       int left_margin;
        LyXFont font;
        int maxdesc;
        if (row_ptr->height <= 0) {
                lyxerr << "LYX_ERROR: row.height: " << row_ptr->height << endl;
                return;
        }
-       left_margin = LabelEnd(row_ptr);
        PrepareToPrint(row_ptr, x, fill_separator,
                       fill_hfill, fill_label_hfill);
 
-       LyXParagraph::size_type main_body = 
-               BeginningOfMainBody(row_ptr->par);
        /* initialize the pixmap */
        
        scr.fillRectangle(gc_clear,
@@ -3307,20 +3505,35 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
                /* selection code */ 
                if (sel_start_cursor.row == row_ptr &&
                    sel_end_cursor.row == row_ptr) {
-                       scr.fillRectangle(gc_selection, sel_start_cursor.x,
+                       if (sel_start_cursor.x < sel_end_cursor.x)
+                         scr.fillRectangle(gc_selection, sel_start_cursor.x,
                                          offset,
-                                         sel_end_cursor.x -
-                                         sel_start_cursor.x,
+                                         sel_end_cursor.x - sel_start_cursor.x,
+                                         row_ptr->height);
+                       else
+                         scr.fillRectangle(gc_selection, sel_end_cursor.x,
+                                         offset,
+                                         sel_start_cursor.x - sel_end_cursor.x,
                                          row_ptr->height);
                }
                else if (sel_start_cursor.row == row_ptr) {
+                    if (direction == LYX_DIR_LEFT_TO_RIGHT)
                        scr.fillRectangle(gc_selection, sel_start_cursor.x,
                                          offset,
                                          paperwidth - sel_start_cursor.x,
                                          row_ptr->height);
+                    else
+                       scr.fillRectangle(gc_selection, 0, offset,
+                                         sel_start_cursor.x, row_ptr->height);
                } else if (sel_end_cursor.row == row_ptr) {
+                    if (direction == LYX_DIR_LEFT_TO_RIGHT)
                        scr.fillRectangle(gc_selection, 0, offset,
                                          sel_end_cursor.x, row_ptr->height);
+                    else
+                       scr.fillRectangle(gc_selection, sel_end_cursor.x,
+                                         offset,
+                                         paperwidth - sel_end_cursor.x,
+                                         row_ptr->height);
                } else if (y > sel_start_cursor.y && y < sel_end_cursor.y) {
                        scr.fillRectangle(gc_selection, 0, offset,
                                          paperwidth, row_ptr->height);
@@ -3418,14 +3631,13 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
                                     paperwidth - LYX_PAPER_MARGIN,
                                     offset,
                                     offset + row_ptr->height);
-                       
-               
+                                       
        } else  {
                if (row_ptr->previous &&
                    row_ptr->previous->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
                        LyXFont font(LyXFont::ALL_SANE);
                        font.setSize(LyXFont::SIZE_FOOTNOTE);
-                       
+
                        int box_x = LYX_PAPER_MARGIN;
                        box_x += font.textWidth(" wide-tab ", 10);
                        
@@ -3522,19 +3734,31 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
                                                 * an extra row and has a pagebreak at the top. */
                                                maxdesc = int(font.maxDescent() * layout.spacing.getValue() * parameters->spacing.getValue())
                                                        + int(layout.parsep) * DefaultHeight();
+                                               if (direction == LYX_DIR_RIGHT_TO_LEFT)
+                                                       tmpx = paperwidth - LeftMargin(row_ptr) - 
+                                                               font.stringWidth(tmpstring);
                                                scr.drawString(font, tmpstring,
                                                               offset + row_ptr->baseline
                                                               - row_ptr->ascent_of_text - maxdesc,
-                                                              int(x));
+                                                              int(tmpx));
                                        }
                                } else {
-                                       x -= font.stringWidth( layout.labelsep);
-                                       x -= font.stringWidth( tmpstring);
+                                       if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                                               tmpx = x - font.stringWidth(layout.labelsep)
+                                                       - font.stringWidth(tmpstring);
+                                       else {
+                                               tmpx = paperwidth - LeftMargin(row_ptr)
+                                                       + font.stringWidth(layout.labelsep);
+                                               if (row_ptr->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)  {
+                                                       LyXFont font(LyXFont::ALL_SANE);
+                                                       font.setSize(LyXFont::SIZE_SMALL);
+                                                       tmpx += font.textWidth("Mwide-figM", 10);
+                                               }
+                                       }
                                        /* draw it! */
                                        scr.drawString(font, tmpstring,
-                                                      offset + row_ptr->baseline, int(x));
+                                                      offset + row_ptr->baseline, int(tmpx));
                                }
-                               x = tmpx;
                        }
                        /* the labels at the top of an environment. More or less for bibliography */ 
                } else if (layout.labeltype == LABEL_TOP_ENVIRONMENT ||
@@ -3548,29 +3772,35 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
                                        maxdesc = int(font.maxDescent() * layout.spacing.getValue() * parameters->spacing.getValue()
                                                         + (layout.labelbottomsep * DefaultHeight()));
                                        
-                                       int top_label_x = int(x);
+                                       tmpx = x;
                                        if (layout.labeltype == LABEL_CENTERED_TOP_ENVIRONMENT){
-                                               top_label_x = int(x + (paperwidth - RightMargin(row_ptr) - x) / 2); 
-                                               top_label_x -= (font.stringWidth( tmpstring)/2);
-                                       }
-                                       
+                                               tmpx = ( ((direction == LYX_DIR_LEFT_TO_RIGHT)
+                                                         ? x : LeftMargin(row_ptr) )
+                                                        + paperwidth - RightMargin(row_ptr) ) / 2; 
+                                               tmpx -= (font.stringWidth(tmpstring)/2);
+                                       } else if (direction == LYX_DIR_RIGHT_TO_LEFT)
+                                               tmpx = paperwidth - LeftMargin(row_ptr) - 
+                                                       font.stringWidth(tmpstring);
+
                                        scr.drawString(font, tmpstring,
                                                       offset + row_ptr->baseline
                                                       - row_ptr->ascent_of_text - maxdesc,  
-                                                      top_label_x);                
+                                                      int(tmpx));                  
                                }
                        }
                }
                if (layout.labeltype == LABEL_BIBLIO) { // ale970302
                        if (row_ptr->par->bibkey) {
-                               tmpx = x;
-                               x -= font.stringWidth(layout.labelsep);
                                font = GetFont(row_ptr->par, -1);
-                               x -= row_ptr->par->bibkey->Width(font);
+                               if (direction == LYX_DIR_LEFT_TO_RIGHT)
+                                       tmpx = x - font.stringWidth(layout.labelsep)
+                                               - row_ptr->par->bibkey->Width(font);
+                               else
+                                       tmpx = paperwidth - LeftMargin(row_ptr)
+                                               + font.stringWidth(layout.labelsep);
                                row_ptr->par->bibkey->Draw(font, scr,
                                                           offset + row_ptr->baseline, 
-                                                          x);
-                               x = tmpx;
+                                                          tmpx);
                        }
                } 
        }
@@ -3622,7 +3852,7 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
        /* draw the text in the pixmap */  
        pos_end = RowLast(row_ptr);
        
-       pos = row_ptr->pos;
+       vpos = row_ptr->pos;
        /* table stuff -- begin*/
        if (row_ptr->par->table) {
                bool on_off;
@@ -3630,7 +3860,8 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
                float x_old = x;
                x += row_ptr->par->table->GetBeginningOfTextInCell(cell);
                
-               while (pos <= pos_end)  {
+               while (vpos <= pos_end)  {
+                       pos = vis2log(vpos);
                        if (row_ptr->par->IsNewline(pos)) {
                                
                                x = x_old + row_ptr->par->table->WidthOfColumn(cell);
@@ -3668,7 +3899,7 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
                                x += row_ptr->par->table->GetBeginningOfTextInCell(cell);
                                if (row_ptr->par->table->IsFirstCell(cell))
                                        --cell; // little hack, sorry
-                               ++pos;
+                               ++vpos;
                        } else if (row_ptr->par->IsHfill(pos)) {
                                x += 1;
                                
@@ -3676,7 +3907,7 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
                                                     offset + row_ptr->baseline - DefaultHeight()/2, 
                                                     offset + row_ptr->baseline);               
                                x += 2;
-                               ++pos;
+                               ++vpos;
                        } else {
                                if (row_ptr->par->IsSeparator(pos)) {
                                        tmpx = x;
@@ -3705,9 +3936,9 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
                                                                     int(x - tmpx));                        
                                                }
                                        }
-                                       ++pos;
+                                       ++vpos;
                                } else
-                                       Draw(row_ptr, pos, scr, offset, x);
+                                       Draw(row_ptr, vpos, scr, offset, x);
                        }
                }
                
@@ -3747,9 +3978,21 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
                }
        } else {
                /* table stuff -- end*/
-               
-               while (pos <= pos_end)  {
-                       
+               LyXParagraph::size_type main_body = 
+                       BeginningOfMainBody(row_ptr->par);
+               if (main_body > 0 &&
+                   (main_body-1 > pos_end || 
+                    !row_ptr->par->IsLineSeparator(main_body-1)))
+                       main_body = 0;
+
+               while (vpos <= pos_end)  {
+                       pos = vis2log(vpos);
+                       if (main_body > 0 && pos == main_body-1) {
+                               x += fill_label_hfill
+                                       + GetFont(row_ptr->par, -2).stringWidth(layout.labelsep)
+                                       - SingleWidth(row_ptr->par, main_body-1);
+                       }
+
                        if (row_ptr->par->IsHfill(pos)) {
                                x += 1;
                                scr.drawVerticalLine(gc_fill, int(x),  
@@ -3775,7 +4018,7 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
                                                             offset + row_ptr->baseline);
                                }
                                x += 2;
-                               ++pos;
+                               ++vpos;
                        } else {
                                if (row_ptr->par->IsSeparator(pos)) {
                                        tmpx = x;
@@ -3806,17 +4049,9 @@ void LyXText::GetVisibleRow(LyXScreen & scr, int offset,
                                                                     int(x - tmpx));
                                                }
                                        }
-                                       ++pos;
+                                       ++vpos;
                                } else
-                                       Draw(row_ptr, pos, scr, offset, x);
-                       }
-                       if (pos == main_body) {
-                               x += GetFont(row_ptr->par, -2).stringWidth(
-                                       layout.labelsep);
-                               if (row_ptr->par->IsLineSeparator(pos - 1))
-                                       x-= SingleWidth(row_ptr->par, pos - 1);
-                               if (x < left_margin)
-                                       x = left_margin;
+                                       Draw(row_ptr, vpos, scr, offset, x);
                        }
                }
        }
@@ -3863,28 +4098,27 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
        float tmpx = 0.0;
        float fill_separator, fill_hfill, fill_label_hfill;
    
-       int left_margin = LabelEnd(row);
        PrepareToPrint(row, tmpx, fill_separator,
                       fill_hfill, fill_label_hfill);
-       int main_body = BeginningOfMainBody(row->par);
-       
-       int c = row->pos;
 
-       int last = RowLast(row);
-       if (row->par->IsNewline(last))
-               --last;
-   
+       LyXDirection direction = GetParDirection(row->par);
+       LyXParagraph::size_type vc = row->pos;
+       LyXParagraph::size_type last = RowLast(row);
+       LyXParagraph::size_type c;
+
        LyXLayout const & layout = textclasslist.Style(parameters->textclass,
                                           row->par->GetLayout());
        /* table stuff -- begin */
        if (row->par->table) {
-               if (!row->next || row->next->par != row->par)
-                       last = RowLast(row); /* the last row doesn't need a newline at the end*/
+               if (row->next && row->next->par == row->par //the last row doesn't need a newline at the end
+                   && row->par->IsNewline(last))
+                       last--;
                int cell = NumberOfCell(row->par, row->pos);
                float x_old = tmpx;
                bool ready = false;
                tmpx += row->par->table->GetBeginningOfTextInCell(cell);
-               while (c <= last
+               while (vc <= last
+                      && (c = vis2log(vc)) >= 0
                       && tmpx + (SingleWidth(row->par, c)/2) <= x
                       && !ready){
                        if (row->par->IsNewline(c)) {
@@ -3893,26 +4127,32 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
                                        x_old = tmpx;
                                        ++cell;
                                        tmpx += row->par->table->GetBeginningOfTextInCell(cell);
-                                       ++c;
+                                       ++vc;
                                } else
                                        ready = true;
                        } else {
                                tmpx += SingleWidth(row->par, c);
-                               ++c;
+                               ++vc;
                        }
                }
-       } else
+       } else {
                /* table stuff -- end*/
-
-               while (c <= last
-                      && tmpx + (SingleWidth(row->par, c)/2)  <= x) {
-                       
-                       if (c && c == main_body
-                           && !row->par->IsLineSeparator(c - 1)) {
-                               tmpx += GetFont(row->par, -2)
-                                       .stringWidth(layout.labelsep);
-                               if (tmpx < left_margin)
-                                       tmpx = left_margin;
+               LyXParagraph::size_type main_body = BeginningOfMainBody(row->par);
+               float last_tmpx = tmpx;
+
+               if (main_body > 0 &&
+                   (main_body-1 > last || 
+                    !row->par->IsLineSeparator(main_body-1)))
+                       main_body = 0;
+
+               while (vc <= last && tmpx <= x) {
+                       c = vis2log(vc);
+                       last_tmpx = tmpx;
+                       if (main_body > 0 && c == main_body-1) {
+                               tmpx += fill_label_hfill +
+                                       GetFont(row->par, -2).stringWidth(layout.labelsep);
+                               if (row->par->IsLineSeparator(main_body-1))
+                                       tmpx -= SingleWidth(row->par, main_body-1);
                        }
             
                        tmpx += SingleWidth(row->par, c);
@@ -3926,25 +4166,54 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
                                 && row->par->IsSeparator(c)) {
                                tmpx+= fill_separator;  
                        }
-                       ++c;
-                       if (c == main_body
-                           && row->par->IsLineSeparator(c - 1)) {
-                               tmpx += GetFont(row->par, -2)
-                                       .stringWidth(layout.labelsep);
-                               tmpx-= SingleWidth(row->par, c - 1);
-                               if (tmpx < left_margin)
-                                       tmpx = left_margin;
-                       }
+                       ++vc;
                }
+
+               if (vc > row->pos && (tmpx+last_tmpx)/2 > x) {
+                       vc--;
+                       tmpx = last_tmpx;
+               }
+       }
        /* make sure that a last space in a row doesnt count */
-       if (c > 0 && c >= last
-           && row->par->IsLineSeparator(c - 1)
-           && !(!row->next || row->next->par != row->par)) {
-               tmpx -= SingleWidth(row->par, c - 1);
-               tmpx -= fill_separator;
+       if (row->pos <= last
+           && !(!row->next || row->next->par != row->par))
+               if (direction == LYX_DIR_LEFT_TO_RIGHT && vc > last
+                   && row->par->IsLineSeparator(vis2log(last)) ) {
+                       vc = last;
+                       tmpx -= fill_separator+SingleWidth(row->par, vis2log(last));
+               } else if (direction == LYX_DIR_RIGHT_TO_LEFT 
+                          && vc == row->pos
+                          && row->par->IsLineSeparator(vis2log(row->pos)) ) {
+                       vc = row->pos+1;
+                       tmpx += fill_separator+SingleWidth(row->par, vis2log(row->pos));
+               }
+
+       if (row->pos > last)  // Row is empty?
+               c = row->pos;
+       else if (vc <= last) {
+               c = vis2log(vc);
+               LyXDirection direction = GetLetterDirection(row->par , c);
+               if (vc > row->pos && row->par->IsLineSeparator(c)
+                   && GetLetterDirection(row->par , vis2log(vc-1)) != direction)
+                       c = vis2log(vc-1);
+               if (direction == LYX_DIR_RIGHT_TO_LEFT)
+                       ++c;
+       } else {
+               c = vis2log(last)+1;
+               if (GetLetterDirection(row->par, c-1) == LYX_DIR_RIGHT_TO_LEFT)
+                       --c;            
        }
-       c-= row->pos;
-       
+
+       if (!row->par->table && row->pos <= last && c > last
+           && row->par->IsNewline(last)) {
+               if (GetLetterDirection(row->par,last) == LYX_DIR_LEFT_TO_RIGHT)
+                       tmpx -= SingleWidth(row->par, last);
+               else
+                       tmpx += SingleWidth(row->par, last);
+               c = last;
+       }
+
+       c-= row->pos;   
        x = int(tmpx);
        return c;
 }
index 8903d40b852348bfd375361a9e1de8ec90c2f00f..bfcc2827e970d183d7c01ac3792d5446089624fa 100644 (file)
@@ -936,8 +936,16 @@ void LyXText::SetSelection()
        last_sel_cursor = cursor;
    
        // and now the whole selection
-   
-       if (sel_cursor.y < cursor.y ||
+
+       if (sel_cursor.par == cursor.par)
+          if (sel_cursor.pos < cursor.pos) {
+               sel_end_cursor = cursor;
+               sel_start_cursor = sel_cursor;
+       } else {
+               sel_end_cursor = sel_cursor; 
+               sel_start_cursor = cursor;
+       }
+       else if (sel_cursor.y < cursor.y ||
            (sel_cursor.y == cursor.y && sel_cursor.x < cursor.x)) {
                sel_end_cursor = cursor;
                sel_start_cursor = sel_cursor;
@@ -1596,35 +1604,43 @@ void LyXText::SetCounter(LyXParagraph * par) const
                        par->incCounter(i + par->enumdepth);
                        char * s = new char[25];
                        int number = par->getCounter(i + par->enumdepth);
+
+                       static const char *roman[20] = {
+                               "i",   "ii",  "iii", "iv", "v",
+                               "vi",  "vii", "viii", "ix", "x",
+                               "xi",  "xii", "xiii", "xiv", "xv",
+                               "xvi", "xvii", "xviii", "xix", "xx"
+                       };
+                       static const char hebrew[22] = {
+                               'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è',
+                               'é', 'ë', 'ì', 'î', 'ð', 'ñ', 'ò', 'ô', 'ö', 
+                               '÷', 'ø', 'ù', 'ú'
+                       };
+
                        switch (par->enumdepth) {
                        case 1:
-                               sprintf(s, "(%c)", (number % 27) + 'a' - 1);
+                               if (GetParDirection(par) == LYX_DIR_LEFT_TO_RIGHT)
+                                       sprintf(s, "(%c)", ((number-1) % 26) + 'a');
+                               else
+                                       sprintf(s, "(%c)", hebrew[(number-1) % 22]);
                                break;
                        case 2:
-                               switch (number) {
-                               case 1: sprintf(s, "i."); break;
-                               case 2: sprintf(s, "ii."); break;
-                               case 3: sprintf(s, "iii."); break;
-                               case 4: sprintf(s, "iv."); break;
-                               case 5: sprintf(s, "v."); break;
-                               case 6: sprintf(s, "vi."); break;
-                               case 7: sprintf(s, "vii."); break;
-                               case 8: sprintf(s, "viii."); break;
-                               case 9: sprintf(s, "ix."); break;
-                               case 10: sprintf(s, "x."); break;
-                               case 11: sprintf(s, "xi."); break;
-                               case 12: sprintf(s, "xii."); break;
-                               case 13: sprintf(s, "xiii."); break;
-                               default:
-                                       sprintf(s, "\\roman{%d}.", number);
-                                       break;
-                               }
+                               if (GetParDirection(par) == LYX_DIR_LEFT_TO_RIGHT)
+                                       sprintf(s, "%s.", roman[(number-1) % 20]);
+                               else
+                                       sprintf(s, ".%s", roman[(number-1) % 20]);
                                break;
                        case 3:
-                               sprintf(s, "%c.", (number % 27) + 'A' - 1);
+                               if (GetParDirection(par) == LYX_DIR_LEFT_TO_RIGHT)
+                                       sprintf(s, "%c.", ((number-1) % 26) + 'A');
+                               else
+                                       sprintf(s, ".%c", ((number-1) % 26) + 'A');
                                break;
                        default:
-                               sprintf(s, "%d.", number);
+                               if (GetParDirection(par) == LYX_DIR_LEFT_TO_RIGHT)
+                                       sprintf(s, "%d.", number);
+                               else
+                                       sprintf(s, ".%d", number);      
                                break;
                        }
                        par->labelstring = s;
@@ -1653,18 +1669,31 @@ void LyXText::SetCounter(LyXParagraph * par) const
                        if (par->footnoteflag != LyXParagraph::NO_FOOTNOTE
                            && (par->footnotekind == LyXParagraph::FIG
                                || par->footnotekind == LyXParagraph::WIDE_FIG))
-                               s = "Figure:";
+                               if (GetParDirection(par) == LYX_DIR_LEFT_TO_RIGHT)
+                                       s = "Figure:";
+                               else
+                                       s = ":øåéà";
                        else if (par->footnoteflag != LyXParagraph::NO_FOOTNOTE
                                 && (par->footnotekind == LyXParagraph::TAB
                                     || par->footnotekind == LyXParagraph::WIDE_TAB))
-                               s = "Table:";
+                               if (GetParDirection(par) == LYX_DIR_LEFT_TO_RIGHT)
+                                       s = "Table:";
+                               else
+                                       s = ":äìáè";
                        else if (par->footnoteflag != LyXParagraph::NO_FOOTNOTE
                                 && par->footnotekind == LyXParagraph::ALGORITHM)
-                               s = "Algorithm:";
+                               if (GetParDirection(par) == LYX_DIR_LEFT_TO_RIGHT)
+                                       s = "Algorithm:";
+                               else
+                                       s = ":íúéøåâìà";
                        else {
                                /* par->SetLayout(0); 
                                   s = layout->labelstring;  */
-                               s = "Senseless: "; 
+                               if (GetParDirection(par) == LYX_DIR_LEFT_TO_RIGHT)
+                                       s = "Senseless: ";
+                               else
+                                       s = " :úåòîùî øñç";
+          
                        }
                }
                par->labelstring = s;
@@ -2882,22 +2911,22 @@ int LyXText::UpdateInset(Inset * inset)
 
 
 void LyXText::SetCursor(LyXParagraph * par,
-                       LyXParagraph::size_type pos) const
+                       LyXParagraph::size_type pos, bool setfont) const
 {
        LyXCursor old_cursor = cursor;
-       SetCursorIntern(par, pos);
+       SetCursorIntern(par, pos, setfont);
        DeleteEmptyParagraphMechanism(old_cursor);
 }
 
 
 void LyXText::SetCursorIntern(LyXParagraph * par,
-                             LyXParagraph::size_type pos) const
+                             LyXParagraph::size_type pos, bool setfont) const
 {
        long y;
        Row * row;
-       int left_margin;
        LyXParagraph * tmppar;
-   
+       LyXParagraph::size_type vpos,cursor_vpos;
+
        // correct the cursor position if impossible
        if (pos > par->Last()){
                tmppar = par->ParFromPos(pos);
@@ -2923,6 +2952,25 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
        cursor.par = par;
        cursor.pos = pos;
 
+       if (setfont)
+               if (cursor.pos && 
+                   (cursor.pos == cursor.par->Last() || cursor.par->IsSeparator(cursor.pos)
+                    || (cursor.pos && cursor.pos == BeginningOfMainBody(cursor.par)
+                        && !cursor.par->IsSeparator(cursor.pos))
+                    || (cursor.par->table && cursor.par->IsNewline(cursor.pos))
+                    )) {
+                       current_font = cursor.par->GetFontSettings(cursor.pos - 1);
+                       real_current_font = GetFont(cursor.par, cursor.pos - 1);
+               } else {
+                       current_font = cursor.par->GetFontSettings(cursor.pos);
+                       real_current_font = GetFont(cursor.par, cursor.pos);
+                       if (pos == 0 && par->size() == 0 
+                           && GetDocumentDirection() == LYX_DIR_RIGHT_TO_LEFT) {
+                               current_font.setDirection(LyXFont::RTL_DIR);
+                               real_current_font.setDirection(LyXFont::RTL_DIR);
+                       }
+               }
+
        /* get the cursor y position in text  */
        row = GetRow(par, pos, y);
        /* y is now the beginning of the cursor row */ 
@@ -2931,19 +2979,33 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
        cursor.y = y;
    
        /* now get the cursors x position */
-   
        float x;
        float fill_separator, fill_hfill, fill_label_hfill;
-       left_margin = LabelEnd(row);
        PrepareToPrint(row, x, fill_separator, fill_hfill, fill_label_hfill);
-       LyXParagraph::size_type main_body =
-               BeginningOfMainBody(row->par);
+
+       LyXParagraph::size_type last = RowLast(row);
+       if (row->pos > last)
+               cursor_vpos = 0;
+       else if (pos <= last ) {
+               LyXDirection letter_direction = GetLetterDirection(row->par, pos);
+               LyXDirection font_direction = GetFontDirection(real_current_font);
+               if (letter_direction == font_direction || pos == 0)
+                       cursor_vpos = (letter_direction == LYX_DIR_LEFT_TO_RIGHT)
+                               ? log2vis(pos) : log2vis(pos)+1;
+               else
+                       cursor_vpos = (font_direction == LYX_DIR_LEFT_TO_RIGHT)
+                               ? log2vis(pos-1)+1 : log2vis(pos-1);
+       } else
+               cursor_vpos = (GetLetterDirection(row->par, last) == LYX_DIR_LEFT_TO_RIGHT)
+                       ? log2vis(last)+1 : log2vis(last);
+
        /* table stuff -- begin*/
        if (row->par->table) {
                int cell = NumberOfCell(row->par, row->pos);
                float x_old = x;
                x += row->par->table->GetBeginningOfTextInCell(cell);
-               for (pos = row->pos; pos < cursor.pos; ++pos)  {
+               for (vpos = row->pos; vpos < cursor_vpos; ++vpos)  {
+                       pos = vis2log(vpos);
                        if (row->par->IsNewline(pos)) {
                                x = x_old + row->par->table->WidthOfColumn(cell);
                                x_old = x;
@@ -2953,16 +3015,23 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
                                x += SingleWidth(row->par, pos);
                        }
                }
-       } else
+       } else {
                /* table stuff -- end*/
-
-               for (pos = row->pos; pos < cursor.pos; ++pos)  {
-                       if (pos && pos == main_body
-                           && !row->par->IsLineSeparator(pos - 1)) {
-                               x += GetFont(row->par, -2).stringWidth(
+               LyXParagraph::size_type main_body =
+                       BeginningOfMainBody(row->par);
+               if (main_body > 0 &&
+                   (main_body-1 > last || 
+                    !row->par->IsLineSeparator(main_body-1)))
+                       main_body = 0;
+
+               for (vpos = row->pos; vpos < cursor_vpos; ++vpos)  {
+                       pos = vis2log(vpos);
+                       if (main_body > 0 && pos == main_body-1) {
+                               x += fill_label_hfill +
+                                       GetFont(row->par, -2).stringWidth(
                                                    textclasslist.Style(parameters->textclass, row->par->GetLayout()).labelsep);
-                               if (x < left_margin)
-                                       x = left_margin;
+                               if (row->par->IsLineSeparator(main_body-1))
+                                       x -= SingleWidth(row->par, main_body-1);
                        }
       
                        x += SingleWidth(row->par, pos);
@@ -2975,34 +3044,13 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
                        else if (pos >= main_body && row->par->IsSeparator(pos)) {
                                x+= fill_separator;
                        }
-      
-                       if (pos + 1 == main_body
-                           && row->par->IsLineSeparator(pos)) {
-                               x += GetFont(row->par, -2).stringWidth(
-                                                   textclasslist.Style(parameters->textclass, row->par->GetLayout()).labelsep);
-                               if (row->par->IsLineSeparator(pos))
-                                       x -= SingleWidth(row->par, pos);
-                               if (x < left_margin)
-                                       x = left_margin;
-                       }
                }
+       }
    
        cursor.x = int(x);
    
        cursor.x_fix = cursor.x;
        cursor.row = row;
-   
-       if (cursor.pos && 
-           (cursor.pos == cursor.par->Last() || cursor.par->IsSeparator(cursor.pos)
-            || (cursor.pos && cursor.pos == BeginningOfMainBody(cursor.par)
-                && !cursor.par->IsSeparator(cursor.pos))
-                   )) {
-               current_font = cursor.par->GetFontSettings(cursor.pos - 1);
-               real_current_font = GetFont(cursor.par, cursor.pos - 1);
-       } else {
-               current_font = cursor.par->GetFontSettings(cursor.pos);
-               real_current_font = GetFont(cursor.par, cursor.pos);
-       }
 }
 
 
@@ -3028,6 +3076,7 @@ void LyXText::SetCursorFromCoordinates(int x, long y) const
             || cursor.par->IsSeparator(cursor.pos)
             || (cursor.pos && cursor.pos == BeginningOfMainBody(cursor.par)
                 && !cursor.par->IsSeparator(cursor.pos))
+            || (cursor.par->table && cursor.par->IsNewline(cursor.pos))
                    )) {
                current_font = cursor.par->GetFontSettings(cursor.pos - 1);
                real_current_font = GetFont(cursor.par, cursor.pos - 1);