]> git.lyx.org Git - features.git/commitdiff
two patches from Dekel
authorLars Gullik Bjønnes <larsbj@gullik.org>
Tue, 30 May 2000 19:31:11 +0000 (19:31 +0000)
committerLars Gullik Bjønnes <larsbj@gullik.org>
Tue, 30 May 2000 19:31:11 +0000 (19:31 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@780 a592a061-630c-0410-9148-cb99ea01b6c8

13 files changed:
ChangeLog
lib/lyxrc.example
src/LColor.C
src/LColor.h
src/bufferview_funcs.C
src/lyx_cb.C
src/lyxcursor.h
src/lyxfunc.C
src/lyxrc.C
src/lyxrc.h
src/lyxtext.h
src/text.C
src/text2.C

index 094b2679770f9b204e11a97f36e7b06c1ca10bb8..59c59af405840deb3b2e9e09aeb91063ce71ce34 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2000-05-27  Dekel Tsur  <dekel@math.tau.ac.il>
+
+       * src/text.C (draw): draw bars under foreign language words.
+       
+       * src/LColor.[Ch]: add LColor::language
+                            
+2000-05-27 Dekel Tsur  <dekel@math.tau.ac.il>
+
+       * src/lyxcursor.h (boundary): New member variable
+
+       * src/text.C (IsBoundary): New methods
+
+       * src/text.C: Use the above for currect cursor movement when there
+       is both RTL & LTR text.
+       
+       * src/text2.C: ditto
+       
+       * src/bufferview_funcs.C (ToggleAndShow): ditto
+
 2000-05-30  Jean-Marc Lasgouttes  <Jean-Marc.Lasgouttes@inria.fr>
 
        * src/text.C (DeleteLineForward): set selection to true to avoid
index 19c68350cfefd36a3bd2d9f04e1c582c9cdc7e9e..b37ba8c5a32ec00e3f8f273610dc4dbcbce96b74 100644 (file)
 # the document. Default is true.
 #\language_auto_end false
 
+# Set mark_foreign_language to "false" to disable the highlighting of words
+# with a foreign language to the language of the documet.
+# Default is "true"
+#\mark_foreign_language false
+
 #
 # HEBREW SUPPORT SECTION ####################################################
 #
 # For example,
 #\bind "F12" "language hebrew"
 
+# You might want ot disable the foreign language marking:
+#\mark_foreign_language false
+
 # Finally, you need to select iso8859-8 font encoding, and select screen fonts
 # (below are the default fonts. You need to replace them by Hebrew fonts)
 #\screen_font_encoding iso8859-8
index 9fec78cbcaaccc399945072cb607ffced2b0b5b2..c4763d8f72fc69624171fc477a1e2974f01205ee 100644 (file)
@@ -66,6 +66,7 @@ LColor::LColor()
        { notebg, N_("note background"), "notebg", "yellow", "notebg" },
        { noteframe, N_("note frame"), "noteframe", "black", "noteframe" },
        { depthbar, N_("depth bar"), "depthbar", "IndianRed", "depthbar" },
+       { language, N_("language"), "language", "Blue", "language" },
        { command, N_("command-inset"), "command", "black", "command" },
        { commandbg, N_("command-inset background"), "commandbg", "grey80", "commandbg" },
        { commandframe, N_("inset frame"), "commandframe", "black", "commandframe" },
index 57e29fc8e418b82e3d787b29a3c037dea8924c40..4fc25de94d6eb884ebfd41b74ecaaf8c351615e0 100644 (file)
@@ -78,6 +78,8 @@ public:
 
                /// Color for the depth bars in the margin
                depthbar,
+               /// Color for marking foreign language words
+               language,
 
                /// Text color for command insets
                command,
index bc99b1eca528e4cc5f564b8d312054a67b633596..f4765b42055ca45f169348d82a1e95acf46bc772 100644 (file)
@@ -293,5 +293,17 @@ void ToggleAndShow(BufferView * bv, LyXFont const & font)
                else
                        bv->text->ToggleFree(font, toggleall);
                bv->update(1);
+
+               if (font.language() != ignore_language ||
+                   font.latex() != LyXFont::IGNORE) {
+                       LyXText * text = bv->text;
+                       LyXCursor & cursor = text->cursor;
+                       text->ComputeBidiTables(cursor.row);
+                       if (cursor.boundary != 
+                           text->IsBoundary(cursor.par, cursor.pos,
+                                            text->real_current_font) )
+                               text->SetCursor(cursor.par, cursor.pos,
+                                               false, !cursor.boundary);
+               }
        }
 }
index 54210ed8efeb2fd644931a21784a34770e4920ec..ace787145d5966c3a8ecd9b616430fdf1aacde65 100644 (file)
@@ -2377,10 +2377,12 @@ extern "C" void DocumentApplyCB(FL_OBJECT *, long)
        if (current_view->available()) {
                if (old_language != new_language &&
                    old_language->RightToLeft == new_language->RightToLeft && 
-                   ! current_view->buffer()->isMultiLingual() ) {
+                   ! current_view->buffer()->isMultiLingual() )
                        current_view->buffer()->ChangeLanguage(old_language,
                                                               new_language);
-                       current_view->buffer()->redraw();
+               if (old_language != new_language) {
+                       //current_view->buffer()->redraw();
+                       redo = true;
                }
        }
        params->language_info = new_language;
index 0a2af4cba0ce01d766bea41e55b7c9fcc976d9f9..e1a8a64ef5eb9e1d97eb7046c39562ba7ea2e291 100644 (file)
@@ -24,6 +24,8 @@ struct LyXCursor {
        ///
        LyXParagraph::size_type pos;
        ///
+       bool boundary;
+       ///
        int x;
        ///
        int x_fix;
@@ -33,9 +35,9 @@ struct LyXCursor {
        Row * row;
        ///
        inline bool operator==(const LyXCursor &a) const
-               { return (a.par == par) && (a.pos == pos); }
+               { return a.par == par && a.pos == pos && a.boundary == boundary ; }
        inline bool operator!=(const LyXCursor &a) const
-               { return (a.par != par) || (a.pos != pos); }
+               { return a.par != par || a.pos != pos || a.boundary != boundary; }
 };
 
 #endif
index 1eb58c30a2ccd1b3098f0b2a4259035544b422f4..e5c5fa8a6fcf6a119ea8dc0d4a0d5d81034fbe46 100644 (file)
@@ -1222,18 +1222,16 @@ string LyXFunc::Dispatch(int ac,
                break;
 
        case LFUN_LANGUAGE:
-       {
                Lang(owner->view(), argument);
                owner->view()->setState();
                owner->getMiniBuffer()->Set(CurrentState(owner->view()));
-       }
                break;
 
        case LFUN_EMPH:
                Emph(owner->view());
                owner->getMiniBuffer()->Set(CurrentState(owner->view()));
                break;
-               
+
        case LFUN_BOLD:
                Bold(owner->view());
                owner->getMiniBuffer()->Set(CurrentState(owner->view()));
@@ -1367,7 +1365,7 @@ string LyXFunc::Dispatch(int ac,
                        owner->view()->beforeChange();
                owner->view()->update(-2);
                if (is_rtl)
-                       tmptext->CursorLeft();
+                       tmptext->CursorLeft(false);
                if (tmptext->cursor.pos < tmptext->cursor.par->Last()
                    && tmptext->cursor.par->GetChar(tmptext->cursor.pos)
                    == LyXParagraph::META_INSET
@@ -1379,7 +1377,7 @@ string LyXFunc::Dispatch(int ac,
                        break;
                }
                if (!is_rtl)
-                       tmptext->CursorRight();
+                       tmptext->CursorRight(false);
                owner->view()->text->FinishUndo();
                moveCursorUpdate(false);
                owner->getMiniBuffer()->Set(CurrentState(owner->view()));
@@ -1395,7 +1393,7 @@ string LyXFunc::Dispatch(int ac,
                if(!txt->mark_set) owner->view()->beforeChange();
                owner->view()->update(-2);
                if (!is_rtl)
-                       txt->CursorLeft();
+                       txt->CursorLeft(false);
                if (txt->cursor.pos < txt->cursor.par->Last()
                    && txt->cursor.par->GetChar(txt->cursor.pos)
                    == LyXParagraph::META_INSET
@@ -1412,7 +1410,7 @@ string LyXFunc::Dispatch(int ac,
                        break;
                }
                if  (is_rtl)
-                       txt->CursorRight();
+                       txt->CursorRight(false);
 
                owner->view()->text->FinishUndo();
                moveCursorUpdate(false);
index 1f1661d377257ed3cc5530ae38bd7debbb1a38f3..28a2bdb7003db3e73a1eb33a5be203cc50bcddc0 100644 (file)
@@ -137,6 +137,7 @@ enum LyXRCTags {
        RC_BACKUPDIR_PATH,
        RC_RTL_SUPPORT,
        RC_AUTO_NUMBER,
+       RC_MARK_FOREIGN_LANGUAGE,
        RC_LANGUAGE_PACKAGE,
        RC_LANGUAGE_AUTO_BEGIN,
        RC_LANGUAGE_AUTO_END,
@@ -213,6 +214,7 @@ keyword_item lyxrcTags[] = {
         { "\\literate_error_filter", RC_LITERATE_ERROR_FILTER },
         { "\\literate_extension", RC_LITERATE_EXTENSION },
        { "\\make_backup", RC_MAKE_BACKUP },
+       { "\\mark_foreign_language", RC_MARK_FOREIGN_LANGUAGE },
        { "\\num_lastfiles", RC_NUMLASTFILES },
        { "\\override_x_deadkeys", RC_OVERRIDE_X_DEADKEYS },
        { "\\pdf_mode", RC_PDF_MODE },
@@ -367,6 +369,7 @@ void LyXRC::setDefaults() {
        hasBindFile = false;
        rtl_support = false;
        auto_number = true;
+       mark_foreign_language = true;
        language_package = "\\usepackage{babel}";
        language_auto_begin = true;
        language_auto_end = true;
@@ -1011,6 +1014,9 @@ int LyXRC::read(string const & filename)
                        if (lexrc.next())
                                auto_number = lexrc.GetBool();
                        break;
+               case RC_MARK_FOREIGN_LANGUAGE:
+                       if (lexrc.next())
+                               mark_foreign_language = lexrc.GetBool();
                case RC_SHOW_BANNER:
                        if (lexrc.next())
                                show_banner = lexrc.GetBool();
@@ -1337,6 +1343,9 @@ void LyXRC::output(ostream & os) const
                os << "\\rtl " << tostr(rtl_support) << "\n";
        case RC_AUTO_NUMBER:
                os << "\\auto_number" << tostr(auto_number) << "\n";
+       case RC_MARK_FOREIGN_LANGUAGE:
+               os << "\\mark_foreign_language " << 
+                       tostr(mark_foreign_language) << "\n";
        case RC_LANGUAGE_AUTO_BEGIN:
                os << "\\language_auto_begin " 
                   << tostr(language_auto_begin) << "\n";
index d560d329305176086423c9087b1df9ac84c1788f..b931af0111d5daa39eef20e5008195d738859ad4 100644 (file)
@@ -221,6 +221,8 @@ public:
        ///
        bool auto_number;
        ///
+       bool mark_foreign_language;
+       ///
        bool show_banner;
        /// Do we have to use a GUI?
        bool use_gui;
index 1f56ba635baf54e5e5945ec0b4ef455237427038..21b2adab072eade22061db8544e52ef647156cdf 100644 (file)
@@ -182,7 +182,7 @@ public:
        /** returns the column near the specified x-coordinate of the row 
         x is set to the real beginning of this column
         */ 
-       int GetColumnNearX(Row * row, int & x) const;
+       int GetColumnNearX(Row * row, int & x, bool & boundary) const;
        
        /** returns a pointer to a specified row. y is set to the beginning
         of the row
@@ -244,13 +244,28 @@ public:
        ///
        void SetCursor(LyXParagraph * par,
                       LyXParagraph::size_type pos,
-                      bool setfont = true) const;
+                      bool setfont = true,
+                      bool boundary = false) const;
+
        void SetCursor(LyXCursor &, LyXParagraph * par,
-                      LyXParagraph::size_type pos) const;
+                      LyXParagraph::size_type pos,
+                      bool boundary = false) const;
        ///
        void SetCursorIntern(LyXParagraph * par,
                             LyXParagraph::size_type pos,
-                            bool setfont = true) const;
+                            bool setfont = true,
+                            bool boundary = false) const;
+       ///
+       void SetCurrentFont() const;
+
+       ///
+       bool IsBoundary(LyXParagraph * par,
+                       LyXParagraph::size_type pos) const;
+       ///
+       bool IsBoundary(LyXParagraph * par,
+                        LyXParagraph::size_type pos,
+                        LyXFont const & font) const;
+
        ///
        void SetCursorFromCoordinates(int x, long y) const;
        void SetCursorFromCoordinates(LyXCursor &, int x, long y) const;
@@ -259,9 +274,13 @@ public:
        ///
        void CursorDown() const;
        ///
-       void CursorLeft() const;
+       void CursorLeft(bool internal = true) const;
        ///
-       void CursorRight() const;
+       void CursorRight(bool internal = true) const;
+       ///
+       void CursorLeftIntern(bool internal = true) const;
+       ///
+       void CursorRightIntern(bool internal = true) const;
        ///
        void CursorLeftOneWord() const;
        ///
@@ -469,10 +488,6 @@ public:
        /// for external use in lyx_cb.C
        void SetCursorParUndo();
        ///
-       void CursorLeftIntern() const;
-       ///
-       void CursorRightIntern() const;
-       ///
        void RemoveTableRow(LyXCursor * cursor) const;
        ///
        bool IsEmptyTableCell() const;
@@ -480,6 +495,41 @@ public:
        void toggleAppendix();
        ///
        unsigned short paperWidth() const { return paperwidth; }
+
+       ///
+       void ComputeBidiTables(Row *row) 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];
+       }
+
+       inline
+       int bidi_level(LyXParagraph::size_type pos) const {
+               if (bidi_start == -1)
+                       return 0;
+               else
+                       return bidi_levels[pos-bidi_start];
+       }       
+
+       inline
+       bool bidi_InRange(LyXParagraph::size_type pos) const {
+               return bidi_start == -1 ||
+                       (bidi_start <= pos && pos <= bidi_end);
+       }
 private:
        ///
        BufferView * owner_;
@@ -612,36 +662,10 @@ private:
        mutable LyXParagraph::size_type bidi_start;
 
        ///
-       mutable bool bidi_same_direction;
+       mutable LyXParagraph::size_type bidi_end;
 
        ///
-       void ComputeBidiTables(Row *row) 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];
-       }
-
-       inline
-       int bidi_level(LyXParagraph::size_type pos) const {
-               if (bidi_start == -1)
-                       return 0;
-               else
-                       return bidi_levels[pos-bidi_start];
-       }       
+       mutable bool bidi_same_direction;
 
        ///
        unsigned char TransformChar(unsigned char c, Letter_Form form) const;
index 7d85629a10106151688daa775a03c8ad3fa8dd16..fdcff33627b4be4797984305c9fe6e566568a660 100644 (file)
@@ -280,26 +280,26 @@ void LyXText::ComputeBidiTables(Row * row) const
                bidi_start = -1;
                return;
        }
-       LyXParagraph::size_type last = RowLastPrintable(row);
        bidi_start = row->pos;
+       bidi_end = RowLastPrintable(row);
 
-       if (bidi_start > last) {
+       if (bidi_start > bidi_end) {
                bidi_start = -1;
                return;
        }
 
-       if (last + 2 - bidi_start >
+       if (bidi_end + 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);
+                       (bidi_end + 2 - bidi_start < 500) ?
+                       500 : 2 * (bidi_end + 2 - bidi_start);
                log2vis_list.resize(new_size);
                vis2log_list.resize(new_size);
                bidi_levels.resize(new_size);
        }
 
-       vis2log_list[last + 1 - bidi_start] = -1;
-       log2vis_list[last + 1 - bidi_start] = -1;
+       vis2log_list[bidi_end + 1 - bidi_start] = -1;
+       log2vis_list[bidi_end + 1 - bidi_start] = -1;
 
        LyXParagraph::size_type stack[2];
        bool rtl_par = row->par->getParLanguage()->RightToLeft;
@@ -308,10 +308,11 @@ void LyXText::ComputeBidiTables(Row * row) const
        bool rtl0 = false;
        LyXParagraph::size_type main_body = BeginningOfMainBody(row->par);
 
-       for (LyXParagraph::size_type lpos = bidi_start; lpos <= last; ++lpos) {
+       for (LyXParagraph::size_type lpos = bidi_start; lpos <= bidi_end; ++lpos) {
                bool is_space = row->par->IsLineSeparator(lpos);
                LyXParagraph::size_type pos =
-                       (is_space && lpos+1 <= last &&
+                       (is_space && lpos+1 <= bidi_end &&
+                        !row->par->IsLineSeparator(lpos+1) &&
                         (!row->par->table || !row->par->IsNewline(lpos+1)) )
                        ? lpos + 1 : lpos;
                LyXFont font = row->par->GetFontSettings(pos);
@@ -367,14 +368,14 @@ void LyXText::ComputeBidiTables(Row * row) const
 
        while (level > 0) {
                LyXParagraph::size_type old_lpos = stack[--level];
-               int delta = last - old_lpos;
+               int delta = bidi_end - old_lpos;
                if (level % 2)
                        delta = -delta;
                log2vis_list[old_lpos - bidi_start] += delta;
        }
 
        LyXParagraph::size_type vpos = bidi_start - 1;
-       for (LyXParagraph::size_type lpos = bidi_start; lpos <= last; ++lpos) {
+       for (LyXParagraph::size_type lpos = bidi_start; lpos <= bidi_end; ++lpos) {
                vpos += log2vis_list[lpos - bidi_start];
                vis2log_list[vpos - bidi_start] = lpos;
                log2vis_list[lpos - bidi_start] = vpos;
@@ -382,6 +383,43 @@ void LyXText::ComputeBidiTables(Row * row) const
 }
 
 
+// This method requires a previous call to ComputeBidiTables()
+bool LyXText::IsBoundary(LyXParagraph * par, LyXParagraph::size_type pos) const
+{
+       if (!lyxrc.rtl_support)
+               return false;    // This is just for speedup
+
+       if (!bidi_InRange(pos - 1) ||
+           (par->table && par->IsNewline(pos-1)) )
+               return false;
+
+       bool rtl = bidi_level(pos - 1) % 2;
+       bool rtl2 = rtl;
+       if (pos == par->Last() ||
+           (par->table && par->IsNewline(pos)))
+               rtl2 = par->isRightToLeftPar();
+       else if (bidi_InRange(pos))
+               rtl2 = bidi_level(pos) % 2;
+       return rtl != rtl2;
+}
+
+bool LyXText::IsBoundary(LyXParagraph * par, LyXParagraph::size_type pos,
+                LyXFont const & font) const
+{
+       if (!lyxrc.rtl_support)
+               return false;    // This is just for speedup
+
+       bool rtl = font.isVisibleRightToLeft();
+       bool rtl2 = rtl;
+       if (pos == par->Last() ||
+           (par->table && par->IsNewline(pos)))
+               rtl2 = par->isRightToLeftPar();
+       else if (bidi_InRange(pos))
+               rtl2 =  bidi_level(pos) % 2;
+       return rtl != rtl2;
+}
+
+
 void LyXText::draw(Row const * row,
                   LyXParagraph::size_type & vpos,
                   int offset, float & x)
@@ -390,6 +428,7 @@ void LyXText::draw(Row const * row,
        
        LyXParagraph::size_type pos = vis2log(vpos);
        char c = row->par->GetChar(pos);
+       float tmpx = x;
 
        if (IsNewlineChar(c)) {
                ++vpos;
@@ -492,8 +531,6 @@ void LyXText::draw(Row const * row,
          
                font.setColor(LColor::footnote);
 
-               float tmpx = x;
-
                // draw it and set new x position
                
                pain.text(int(x), offset + y, fs, font);
@@ -511,6 +548,14 @@ void LyXText::draw(Row const * row,
                                       offset + row->baseline, x);
                }
                ++vpos;
+
+               if (lyxrc.mark_foreign_language &&
+                   font.language() != buffer->params.language_info) {
+                       int y = offset + row->baseline + 2;
+                       pain.line(int(tmpx), y, int(x), y,
+                                 LColor::language);
+               }
+
                return;
        }
 
@@ -532,7 +577,6 @@ void LyXText::draw(Row const * row,
        ++vpos;
 
        LyXParagraph::size_type last = RowLastPrintable(row);
-       float tmpx = x;
 
        if (font.language()->lang == "hebrew") {
                if (is_nikud(c)) {
@@ -597,6 +641,11 @@ void LyXText::draw(Row const * row,
                pain.line(int(tmpx), offset + row->baseline + 2,
                          int(x), offset + row->baseline + 2);
                
+       } else if (lyxrc.mark_foreign_language &&
+           font.language() != buffer->params.language_info) {
+               int y = offset + row->baseline + 2;
+               pain.line(int(tmpx), y, int(x), y,
+                         LColor::language);
        }
 
        // If we want ulem.sty support, drawing
@@ -2403,7 +2452,7 @@ void LyXText::InsertCharInTable(char c)
                }
        }
 
-       cursor.pos++;
+       ++cursor.pos;
 
        CheckParagraphInTable(cursor.par, cursor.pos);
        
@@ -2439,7 +2488,7 @@ void LyXText::CheckParagraphInTable(LyXParagraph * par,
        if (par->table->SetWidthOfCell(NumberOfCell(par, pos),
                                       WidthOfCell(par, tmp_pos))) {
                LyXCursor tmpcursor = cursor;
-               SetCursorIntern(par, pos);
+               SetCursorIntern(par, pos, false);
                /* make a complete redraw */
                RedoDrawingOfParagraph(cursor);
                cursor = tmpcursor;
@@ -2460,7 +2509,7 @@ void LyXText::CheckParagraphInTable(LyXParagraph * par,
                else
                        status = LyXText::NEED_MORE_REFRESH;
        }
-        SetCursorIntern(cursor.par, cursor.pos);
+        SetCursorIntern(cursor.par, cursor.pos, false, cursor.boundary);
 }
 
 
@@ -2525,7 +2574,9 @@ void LyXText::BackspaceInTable()
                current_font = rawtmpfont;
                real_current_font = realtmpfont;
        }
-       SetCursorIntern(cursor.par, cursor.pos);
+       SetCursorIntern(cursor.par, cursor.pos, true, cursor.boundary);
+       if (IsBoundary(cursor.par, cursor.pos) != cursor.boundary)
+               SetCursor(cursor.par, cursor.pos, false, !cursor.boundary);
 }
 
 /* table stuff -- end*/
@@ -2666,7 +2717,7 @@ void LyXText::InsertChar(char c)
 
                        current_font = rawtmpfont;
                        real_current_font = realtmpfont;
-                       SetCursor(cursor.par, cursor.pos + 1, false);
+                       SetCursor(cursor.par, cursor.pos + 1, false, cursor.boundary);
                        /* cursor MUST be in row now */
             
                        if (row->next && row->next->par == row->par)
@@ -2706,7 +2757,7 @@ void LyXText::InsertChar(char c)
                }
                current_font = rawtmpfont;
                real_current_font = realtmpfont;
-               SetCursor(cursor.par, cursor.pos + 1, false);
+               SetCursor(cursor.par, cursor.pos + 1, false, cursor.boundary);
                if (row->next && row->next->par == row->par)
                        need_break_row = row->next;
                else
@@ -2726,7 +2777,7 @@ void LyXText::InsertChar(char c)
             
                current_font = rawtmpfont;
                real_current_font = realtmpfont;
-               SetCursor(cursor.par, cursor.pos + 1, false);
+               SetCursor(cursor.par, cursor.pos + 1, false, cursor.boundary);
        }
 
        /* check, wether the last characters font has changed. */ 
@@ -3298,12 +3349,14 @@ void LyXText::Backspace()
                return;
        }
        /* table stuff -- end */
+
+       // LyXFont rawtmpfont = current_font;
+       // LyXFont realtmpfont = real_current_font;
+       //    We don't need the above variables as calling to SetCursor() with third
+       //    argument eqaul to false, will not change current_font & real_current_font
        
-       LyXFont rawtmpfont = current_font;
-       LyXFont realtmpfont = real_current_font;
-   
        // Get the font that is used to calculate the baselineskip
-       int const lastpos = cursor.par->Last();
+       LyXParagraph::size_type lastpos = cursor.par->Last();
        LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1);
 
        if (cursor.pos == 0) {
@@ -3365,7 +3418,7 @@ void LyXText::Backspace()
                if (cursor.par->Previous()) { 
                        // steps into the above paragraph.
                        SetCursorIntern(cursor.par->Previous(), 
-                                       cursor.par->Previous()->Last());
+                                       cursor.par->Previous()->Last(), false);
                }
 
                /* Pasting is not allowed, if the paragraphs have different
@@ -3416,7 +3469,7 @@ void LyXText::Backspace()
                        UpdateCounters(cursor.row);
                        
                        // the row may have changed, block, hfills etc.
-                       SetCursor(cursor.par, cursor.pos);
+                       SetCursor(cursor.par, cursor.pos, false);
                }
        } else {
                /* this is the code for a normal backspace, not pasting
@@ -3428,7 +3481,7 @@ void LyXText::Backspace()
                // not a good idea since it triggers the auto-delete
                // mechanism. So we do a CursorLeftIntern()-lite,
                // without the dreaded mechanism. (JMarc)
-               SetCursorIntern(cursor.par, cursor.pos - 1);
+               SetCursorIntern(cursor.par, cursor.pos - 1, false, cursor.boundary);
                
                // some insets are undeletable here
                if (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET) {
@@ -3529,12 +3582,12 @@ void LyXText::Backspace()
                                refresh_y = y;
                                refresh_row = tmprow;
                                status = LyXText::NEED_MORE_REFRESH;
-                               current_font = rawtmpfont;
-                               real_current_font = realtmpfont;
-                               SetCursor(cursor.par, cursor.pos, false);
+                               SetCursor(cursor.par, cursor.pos, false, cursor.boundary);
+                               //current_font = rawtmpfont;
+                               //real_current_font = realtmpfont;
                                // check, whether the last character's font has changed.
-                               rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1);
-                               if (rawparfont != rawtmpfont)
+                               if (rawparfont !=
+                                   cursor.par->GetFontSettings(cursor.par->Last() - 1))
                                        RedoHeightOfParagraph(cursor);
                                return;
                        }
@@ -3560,9 +3613,7 @@ void LyXText::Backspace()
                        status = LyXText::NEED_MORE_REFRESH;
                        
                        BreakAgainOneRow(row);
-                       current_font = rawtmpfont; 
-                       real_current_font = realtmpfont;
-                       SetCursor(cursor.par, cursor.pos, false);
+                       SetCursor(cursor.par, cursor.pos, false, cursor.boundary);
                        // cursor MUST be in row now
                        
                        if (row->next && row->next->par == row->par)
@@ -3580,19 +3631,23 @@ void LyXText::Backspace()
                                status = LyXText::NEED_MORE_REFRESH;
                        refresh_y = y;
                        refresh_row = row;
-                       current_font = rawtmpfont; 
-                       real_current_font = realtmpfont;
-                       SetCursor(cursor.par, cursor.pos, false);
+                       SetCursor(cursor.par, cursor.pos, false, cursor.boundary);
                }
        }
-       // restore the current font
-       // That is what a user expects!
-       current_font = rawtmpfont; 
-       real_current_font = realtmpfont;
+
+       // current_font = rawtmpfont;
+       // real_current_font = realtmpfont;
+
+       lastpos = cursor.par->Last();
+       if (cursor.pos == lastpos) {
+               SetCurrentFont();
+               if (IsBoundary(cursor.par, cursor.pos) != cursor.boundary)
+                       SetCursor(cursor.par, cursor.pos, false, !cursor.boundary);
+       }
        
        // check, wether the last characters font has changed.
-       rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1);
-       if (rawparfont != rawtmpfont) {
+       if (rawparfont != 
+           cursor.par->GetFontSettings(lastpos - 1)) {
                RedoHeightOfParagraph(cursor);
        } else {
                // now the special right address boxes
@@ -4444,7 +4499,7 @@ int LyXText::DefaultHeight() const
    
 /* returns the column near the specified x-coordinate of the row 
 * x is set to the real beginning of this column  */ 
-int LyXText::GetColumnNearX(Row * row, int & x) const
+int LyXText::GetColumnNearX(Row * row, int & x, bool & boundary) const
 {
        float tmpx = 0.0;
        float fill_separator, fill_hfill, fill_label_hfill;
@@ -4457,6 +4512,8 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
        LyXParagraph::size_type c = 0;
        LyXLayout const & layout = textclasslist.Style(buffer->params.textclass,
                                                       row->par->GetLayout());
+       bool left_side = false;
+
        /* table stuff -- begin */
        if (row->par->table) {
                //the last row doesn't need a newline at the end
@@ -4464,26 +4521,29 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
                    && row->par->IsNewline(last))
                        last--;
                int cell = NumberOfCell(row->par, row->pos);
-               float x_old = tmpx;
-               bool ready = false;
+               float cell_x = tmpx + row->par->table->WidthOfColumn(cell);
                tmpx += row->par->table->GetBeginningOfTextInCell(cell);
-               while (vc <= last
-                      && (c = vis2log(vc)) >= 0
-                      && tmpx + (SingleWidth(row->par, c)/2) <= x
-                      && !ready){
-                       if (row->par->IsNewline(c)) {
-                               if (x_old + row->par->table->WidthOfColumn(cell) <= x){
-                                       tmpx = x_old + row->par->table->WidthOfColumn(cell);
-                                       x_old = tmpx;
-                                       ++cell;
-                                       tmpx += row->par->table->GetBeginningOfTextInCell(cell);
-                                       ++vc;
-                               } else
-                                       ready = true;
-                       } else {
-                               tmpx += SingleWidth(row->par, c);
-                               ++vc;
-                       }
+               float last_tmpx = tmpx;
+               while (vc <= last && tmpx <= x) {
+                      c = vis2log(vc);
+                      last_tmpx = tmpx;
+                      if (row->par->IsNewline(c)) {
+                              if (cell_x <= x){
+                                      ++cell;
+                                      tmpx = cell_x + row->par->table->GetBeginningOfTextInCell(cell);
+                                      cell_x += row->par->table->WidthOfColumn(cell);
+                                      ++vc;
+                              } else
+                                      break;
+                      } else {
+                              tmpx += SingleWidth(row->par, c);
+                              ++vc;
+                      }
+               }
+               if (vc > row->pos && !row->par->IsNewline(c) &&
+                   (tmpx+last_tmpx)/2 > x) {
+                       tmpx = last_tmpx;
+                       left_side = true;
                }
        } else {
                /* table stuff -- end*/
@@ -4523,28 +4583,31 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
                }
 
                if (vc > row->pos && (tmpx+last_tmpx)/2 > x) {
-                       vc--;
                        tmpx = last_tmpx;
+                       left_side = true;
                }
        }
 
+
        if (vc > last + 1)  // This shouldn't happen.
                vc = last+1;
 
+       boundary = false;
+
        if (row->pos > last)  // Row is empty?
                c = row->pos;
-       else if (vc > last ||
-                (vc - 1 >= row->pos &&
-                 ( (row->par->IsSeparator(vis2log(vc)) && vis2log(vc) != last)
-                   || (row->par->table && row->par->IsNewline(vc) )
-                  ))) {
-               c = vis2log(vc - 1);
-               if (bidi_level(c) % 2 == 0)
-                       ++c;
-       } else {
+       else if (vc == row->pos ||
+                (row->par->table && vc <= last && row->par->IsNewline(vc-1)) ) {
                c = vis2log(vc);
                if (bidi_level(c) % 2 == 1)
                        ++c;
+       } else {
+               c = vis2log(vc - 1);
+               bool rtl = (bidi_level(c) % 2 == 1);
+               if (left_side == rtl) {
+                       ++c;
+                       boundary = IsBoundary(row->par, c);
+               }
        }
 
        if (!row->par->table && row->pos <= last && c > last
index 445fb211e12d9f5c460eb26416d3b421bd609f6c..e0ed5616ba5da9006e640489aa70ee806e7159f2 100644 (file)
@@ -846,7 +846,7 @@ void LyXText::SetFont(LyXFont const & font, bool toggleall)
        SetCursor(sel_end_cursor.par, sel_end_cursor.pos);
        ClearSelection();
        SetSelection();
-       SetCursor(tmpcursor.par, tmpcursor.pos);
+       SetCursor(tmpcursor.par, tmpcursor.pos, true, tmpcursor.boundary);
 }
 
 
@@ -875,7 +875,7 @@ void LyXText::RedoHeightOfParagraph(LyXCursor const & cur)
        status = LyXText::NEED_MORE_REFRESH;
        refresh_y = y;
        refresh_row = tmprow;
-       SetCursor(cur.par, cur.pos);
+       SetCursor(cur.par, cur.pos, false, cursor.boundary);
 }
 
 
@@ -1054,8 +1054,8 @@ void LyXText::SetSelection()
        }
    
        // a selection with no contents is not a selection
-       if (sel_start_cursor.x == sel_end_cursor.x && 
-           sel_start_cursor.y == sel_end_cursor.y)
+       if (sel_start_cursor.par == sel_end_cursor.par && 
+           sel_start_cursor.pos == sel_end_cursor.pos)
                selection = false;
 
        // Stuff what we got on the clipboard. Even if there is no selection.
@@ -3115,16 +3115,17 @@ int LyXText::UpdateInset(Inset * inset)
 
 
 void LyXText::SetCursor(LyXParagraph * par,
-                       LyXParagraph::size_type pos, bool setfont) const
+                       LyXParagraph::size_type pos, 
+                       bool setfont, bool boundary) const
 {
        LyXCursor old_cursor = cursor;
-       SetCursorIntern(par, pos, setfont);
+       SetCursorIntern(par, pos, setfont, boundary);
        DeleteEmptyParagraphMechanism(old_cursor);
 }
 
 
 void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
-                       LyXParagraph::size_type pos) const
+                       LyXParagraph::size_type pos, bool boundary) const
 {
        // correct the cursor position if impossible
        if (pos > par->Last()){
@@ -3154,6 +3155,7 @@ void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
 
        cur.par = par;
        cur.pos = pos;
+       cur.boundary = boundary;
 
        /* get the cursor y position in text  */
        long y = 0;
@@ -3175,16 +3177,18 @@ void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
 
        if (last < row->pos)
                 cursor_vpos = 0;
-       else if ((pos > last) ||
-                ((pos - 1 >= row->pos) &&
-                 (row->par->IsSeparator(pos) ||
-                  (row->par->table && row->par->IsNewline(pos)))))
+       else if (pos > last && !boundary)
+               cursor_vpos = (row->par->isRightToLeftPar())
+                       ? row->pos : last+1; 
+       else if (pos > row->pos &&
+                (pos > last || boundary || 
+                 (row->par->table && row->par->IsNewline(pos))))
                /// Place cursor after char at (logical) position pos-1
-               cursor_vpos = !(bidi_level(pos-1) % 2)
+               cursor_vpos = (bidi_level(pos-1) % 2 == 0)
                        ? log2vis(pos-1) + 1 : log2vis(pos-1);
        else
                /// Place cursor before char at (logical) position pos
-               cursor_vpos = !(bidi_level(pos) % 2)
+               cursor_vpos = (bidi_level(pos) % 2 == 0)
                        ? log2vis(pos) : log2vis(pos) + 1;
 
        /* table stuff -- begin*/
@@ -3248,9 +3252,10 @@ void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
 
 
 void LyXText::SetCursorIntern(LyXParagraph * par,
-                             LyXParagraph::size_type pos, bool setfont) const
+                             LyXParagraph::size_type pos,
+                             bool setfont, bool boundary) const
 {
-       SetCursor(cursor, par, pos);
+       SetCursor(cursor, par, pos, boundary);
 // #warning Remove this when verified working (Jug 20000413)
 #if 0
        // correct the cursor position if impossible
@@ -3369,18 +3374,32 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
        cursor.x_fix = cursor.x;
        cursor.row = row;
 #endif
-       if (setfont) {
-               if (cursor.pos && 
-                   (cursor.pos == cursor.par->Last() || 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 (setfont)
+               SetCurrentFont();
+}
+
+void LyXText::SetCurrentFont() const
+{
+       LyXParagraph::size_type pos = cursor.pos;
+       if (cursor.boundary && pos > 0)
+               --pos;
+
+       if (pos > 0) {
+               if (pos == cursor.par->Last() ||
+                   (cursor.par->table && cursor.par->IsNewline(pos)))
+                       --pos;
+               else if (cursor.par->IsSeparator(pos)) {
+                       if (pos > cursor.row->pos &&
+                           bidi_level(pos) % 2 == 
+                           bidi_level(pos - 1) % 2)
+                               --pos;
+                       else if (pos + 1 < cursor.par->Last())
+                               ++pos;
                }
        }
+
+       current_font = cursor.par->GetFontSettings(pos);
+       real_current_font = GetFont(cursor.par, pos);
 }
 
 
@@ -3391,29 +3410,14 @@ void LyXText::SetCursorFromCoordinates(int x, long y) const
        /* get the row first */ 
    
        Row * row = GetRowNearY(y);
-   
        cursor.par = row->par;
-   
-       int column = GetColumnNearX(row, x);
+
+       int column = GetColumnNearX(row, x, cursor.boundary);
        cursor.pos = row->pos + column;
        cursor.x = x;
        cursor.y = y + row->baseline;
-   
        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))
-            || (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);
-       }
+       SetCurrentFont();
        DeleteEmptyParagraphMechanism(old_cursor);
 }
 
@@ -3422,7 +3426,7 @@ void LyXText::SetCursorFromCoordinates(LyXCursor & cur, int x, long y) const
        /* get the row first */ 
    
        Row * row = GetRowNearY(y);
-       int column = GetColumnNearX(row, x);
+       int column = GetColumnNearX(row, x, cur.boundary);
    
        cur.par = row->par;
        cur.pos = row->pos + column;
@@ -3432,9 +3436,9 @@ void LyXText::SetCursorFromCoordinates(LyXCursor & cur, int x, long y) const
 }
 
 
-void LyXText::CursorLeft() const
+void LyXText::CursorLeft(bool internal) const
 {
-       CursorLeftIntern();
+       CursorLeftIntern(internal);
         if (cursor.par->table) {
                 int cell = NumberOfCell(cursor.par, cursor.pos);
                 if (cursor.par->table->IsContRow(cell) &&
@@ -3445,20 +3449,27 @@ void LyXText::CursorLeft() const
 }
 
 
-void LyXText::CursorLeftIntern() const
+void LyXText::CursorLeftIntern(bool internal) const
 {
        if (cursor.pos > 0) {
-               SetCursor(cursor.par, cursor.pos - 1);
-       }
-       else if (cursor.par->Previous()) { // steps into the above paragraph.
-               SetCursor(cursor.par->Previous(), cursor.par->Previous()->Last());
+               bool boundary = cursor.boundary;
+               SetCursor(cursor.par, cursor.pos - 1, true, false);
+               if (!internal && !boundary &&
+                   IsBoundary(cursor.par, cursor.pos + 1))
+                       SetCursor(cursor.par, cursor.pos + 1, true, true);
+       } else if (cursor.par->Previous()) { // steps into the above paragraph.
+               LyXParagraph * par = cursor.par->Previous();
+               LyXParagraph::size_type pos = par->Last();
+               SetCursor(par, pos);
+               if (IsBoundary(par, pos))
+                       SetCursor(par, pos, false, true);
        }
 }
 
 
-void LyXText::CursorRight() const
+void LyXText::CursorRight(bool internal) const
 {
-       CursorRightIntern();
+       CursorRightIntern(internal);
         if (cursor.par->table) {
                 int cell = NumberOfCell(cursor.par, cursor.pos);
                 if (cursor.par->table->IsContRow(cell) &&
@@ -3469,14 +3480,19 @@ void LyXText::CursorRight() const
 }
 
 
-void LyXText::CursorRightIntern() const
+void LyXText::CursorRightIntern(bool internal) const
 {
        if (cursor.pos < cursor.par->Last()) {
-               SetCursor(cursor.par, cursor.pos + 1);
-       }
-       else if (cursor.par->Next()) {
+               if (!internal && cursor.boundary &&
+                   (!cursor.par->table || !cursor.par->IsNewline(cursor.pos)))
+                       SetCursor(cursor.par, cursor.pos, true, false);
+               else {
+                       SetCursor(cursor.par, cursor.pos + 1, true, false);
+                       if (!internal && IsBoundary(cursor.par, cursor.pos))
+                               SetCursor(cursor.par, cursor.pos, true, true);
+               }
+       } else if (cursor.par->Next())
                SetCursor(cursor.par->Next(), 0);
-       }
 }