diff --git a/src/Bidi.cpp b/src/Bidi.cpp deleted file mode 100644 index c06b08a269..0000000000 --- a/src/Bidi.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/** - * \file Bidi.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Dekel Tsur - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "Bidi.h" -#include "Buffer.h" -#include "BufferView.h" -#include "Cursor.h" -#include "Font.h" -#include "Row.h" -#include "LyXRC.h" -#include "Paragraph.h" - - -namespace lyx { - - -pos_type Bidi::log2vis(pos_type pos) const -{ - return (start_ == -1) ? pos : log2vis_list_[pos - start_]; -} - - -pos_type Bidi::vis2log(pos_type pos) const -{ - return (start_ == -1) ? pos : vis2log_list_[pos - start_]; -} - - -pos_type Bidi::level(pos_type pos) const -{ - return (start_ == -1) ? 0 : levels_[pos - start_]; -} - - -bool Bidi::inRange(pos_type pos) const -{ - return start_ == -1 || (start_ <= pos && pos <= end_); -} - - -bool Bidi::same_direction() const -{ - return same_direction_; -} - - -void Bidi::computeTables(Paragraph const & par, - Buffer const & buf, Row const & row) -{ - same_direction_ = true; - - if (par.inInset().forceLTR()) { - start_ = -1; - return; - } - - start_ = row.pos(); - end_ = row.endpos() - 1; - - if (start_ > end_) { - start_ = -1; - return; - } - - if (end_ + 2 - start_ > - static_cast(log2vis_list_.size())) { - pos_type new_size = - (end_ + 2 - start_ < 500) ? - 500 : 2 * (end_ + 2 - start_); - log2vis_list_.resize(new_size); - vis2log_list_.resize(new_size); - levels_.resize(new_size); - } - - vis2log_list_[end_ + 1 - start_] = -1; - log2vis_list_[end_ + 1 - start_] = -1; - - BufferParams const & bufparams = buf.params(); - pos_type stack[2]; - bool const rtl_par = par.isRTL(bufparams); - int lev = 0; - bool rtl = false; - bool rtl0 = false; - pos_type const body_pos = par.beginOfBody(); - - for (pos_type lpos = start_; lpos <= end_; ++lpos) { - bool is_space = false; - // We do not handle spaces around an RTL segment in a special way anymore. - // Neither do we do so when generating the LaTeX, so setting is_space - // to false makes the view in the GUI consistent with the output of LaTeX - // later. The old setting was: - //bool is_space = par.isLineSeparator(lpos); - // FIXME: once we're sure that this is what we really want, we should just - // get rid of this variable... - pos_type const pos = - (is_space && lpos + 1 <= end_ && - !par.isLineSeparator(lpos + 1) && - !par.isEnvSeparator(lpos + 1) && - !par.isNewline(lpos + 1)) - ? lpos + 1 : lpos; - - Font const * font = &(par.getFontSettings(bufparams, pos)); - if (pos != lpos && 0 < lpos && rtl0 && font->isRightToLeft() && - font->fontInfo().number() == FONT_ON && - par.getFontSettings(bufparams, lpos - 1).fontInfo().number() - == FONT_ON) { - font = &(par.getFontSettings(bufparams, lpos)); - is_space = false; - } - bool new_rtl = font->isVisibleRightToLeft(); - bool new_rtl0 = font->isRightToLeft(); - - int new_level; - - if (lpos == body_pos - 1 - && row.pos() < body_pos - 1 - && is_space) { - new_level = rtl_par ? 1 : 0; - new_rtl0 = rtl_par; - new_rtl = rtl_par; - } else if (new_rtl0) { - new_level = new_rtl ? 1 : 2; - } else { - new_level = rtl_par ? 2 : 0; - } - - if (is_space && new_level >= lev) { - new_level = lev; - new_rtl = rtl; - new_rtl0 = rtl0; - } - - int new_level2 = new_level; - - if (lev == new_level && rtl0 != new_rtl0) { - --new_level2; - log2vis_list_[lpos - start_] = rtl ? 1 : -1; - } else if (lev < new_level) { - log2vis_list_[lpos - start_] = rtl ? -1 : 1; - if (new_level > 0 && !rtl_par) - same_direction_ = false; - } else { - log2vis_list_[lpos - start_] = new_rtl ? -1 : 1; - } - rtl = new_rtl; - rtl0 = new_rtl0; - levels_[lpos - start_] = new_level; - - while (lev > new_level2) { - pos_type old_lpos = stack[--lev]; - int delta = lpos - old_lpos - 1; - if (lev % 2) - delta = -delta; - log2vis_list_[lpos - start_] += delta; - log2vis_list_[old_lpos - start_] += delta; - } - while (lev < new_level) - stack[lev++] = lpos; - } - - while (lev > 0) { - pos_type const old_lpos = stack[--lev]; - int delta = end_ - old_lpos; - if (lev % 2) - delta = -delta; - log2vis_list_[old_lpos - start_] += delta; - } - - pos_type vpos = start_ - 1; - for (pos_type lpos = start_; lpos <= end_; ++lpos) { - vpos += log2vis_list_[lpos - start_]; - vis2log_list_[vpos - start_] = lpos; - log2vis_list_[lpos - start_] = vpos; - } -} - - -// This method requires a previous call to computeTables() -bool Bidi::isBoundary(Buffer const & buf, Paragraph const & par, - pos_type pos) const -{ - if (pos == 0) - return false; - - if (!inRange(pos - 1)) { - // This can happen if pos is the first char of a row. - // Returning false in this case is incorrect! - return false; - } - - bool const rtl = level(pos - 1) % 2; - bool const rtl2 = inRange(pos) - ? level(pos) % 2 - : par.isRTL(buf.params()); - return rtl != rtl2; -} - - -bool Bidi::isBoundary(Buffer const & buf, Paragraph const & par, - pos_type pos, Font const & font) const -{ - bool const rtl = font.isVisibleRightToLeft(); - bool const rtl2 = inRange(pos) - ? level(pos) % 2 - : par.isRTL(buf.params()); - return rtl != rtl2; -} - -} // namespace lyx diff --git a/src/Bidi.h b/src/Bidi.h deleted file mode 100644 index 1b7e4f3122..0000000000 --- a/src/Bidi.h +++ /dev/null @@ -1,80 +0,0 @@ -// -*- C++ -*- -/** - * \file Bidi.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Dekel Tsur - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef BIDI_H -#define BIDI_H - -#include "support/types.h" - -#include - - -namespace lyx { - -class Buffer; -class Cursor; -class Paragraph; -class Row; -class Font; - - -/// bidi stuff -class Bidi { -public: - /// - bool isBoundary(Buffer const &, Paragraph const & par, - pos_type pos) const; - /// - bool isBoundary(Buffer const &, Paragraph const & par, - pos_type pos, Font const & font) const; - /** Maps positions in the visual string to positions - * in logical string. - */ - pos_type log2vis(pos_type pos) const; - /** Maps positions in the logical string to positions - * in visual string. - */ - pos_type vis2log(pos_type pos) const; - /* - * The text direction at logical position \param pos. - * Possible values are - * 0: left-to-right text - * 1: right-to-left text - * 2: left-to-right text in right-to-left language (aka numbers) - */ - pos_type level(pos_type pos) const; - /// Is logical position covered by this row? - bool inRange(pos_type pos) const; - /// Is the whole row in the same direction as the paragraph? - bool same_direction() const; - /// Compute the data for visual positions. - void computeTables(Paragraph const & par, - Buffer const &, Row const & row); -private: - /// - bool same_direction_; - /// - std::vector log2vis_list_; - /** Maps positions in the visual string to positions - * in logical string. - */ - std::vector vis2log_list_; - /// - std::vector levels_; - /// - pos_type start_; - /// - pos_type end_; -}; - -} // namespace lyx - -#endif // BIDI_H diff --git a/src/Cursor.cpp b/src/Cursor.cpp index f4e9ce8019..6c8844ce31 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -14,7 +14,6 @@ #include -#include "Bidi.h" #include "Buffer.h" #include "BufferView.h" #include "CoordCache.h" @@ -865,7 +864,7 @@ bool findNonVirtual(Row const & row, Row::const_iterator & cit, bool onleft) } -void Cursor::getSurroundingPosNew(pos_type & left_pos, pos_type & right_pos) const +void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos) const { // by default, we know nothing. left_pos = -1; @@ -942,147 +941,8 @@ void Cursor::getSurroundingPosNew(pos_type & left_pos, pos_type & right_pos) con left_pos = pos() - (cit->isRTL() ? 0 : 1); right_pos = pos() - (cit->isRTL() ? 1 : 0); } -} - -void Cursor::getSurroundingPosOrig(pos_type & left_pos, pos_type & right_pos) const -{ - // preparing bidi tables - Paragraph const & par = paragraph(); - Buffer const & buf = *buffer(); - Row const & row = textRow(); - Bidi bidi; - bidi.computeTables(par, buf, row); - - LYXERR(Debug::RTL, "bidi: " << row.pos() << "--" << row.endpos()); - - // The cursor is painted *before* the character at pos(), or, - // if 'boundary' is true, *after* the character at (pos() - - // 1). So we already have one known position around the - // cursor: - pos_type const known_pos = boundary() && pos() > 0 ? pos() - 1 : pos(); - - // edge case: if we're at the end of the paragraph, things are - // a little different (because lastpos is a position which - // does not really "exist" --- there's no character there - // yet). - if (known_pos == lastpos()) { - if (par.isRTL(buf.params())) { - left_pos = -1; - right_pos = bidi.vis2log(row.pos()); - } else { - // LTR paragraph - right_pos = -1; - left_pos = bidi.vis2log(row.endpos() - 1); - } - return; - } - - // Whether 'known_pos' is to the left or to the right of the - // cursor depends on whether it is an RTL or LTR character... - bool const cur_is_RTL = - par.getFontSettings(buf.params(), known_pos).isVisibleRightToLeft(); - // ... in the following manner: - // For an RTL character, "before" - // means "to the right" and "after" means "to the left"; and - // for LTR, it's the reverse. So, 'known_pos' is to the right - // of the cursor if (RTL && boundary) or (!RTL && !boundary): - bool const known_pos_on_right = cur_is_RTL == boundary(); - - // So we now know one of the positions surrounding the cursor. - // Let's determine the other one: - if (known_pos_on_right) { - right_pos = known_pos; - // *visual* position of 'left_pos': - pos_type v_left_pos = bidi.log2vis(right_pos) - 1; - // If the position we just identified as 'left_pos' is - // a "skipped separator" (a separator which is at the - // logical end of a row, except for the last row in a - // paragraph; such separators are not painted, so they - // "are not really there"; note that in bidi text, - // such a separator could appear visually in the - // middle of a row), set 'left_pos' to the *next* - // position to the left. - if (bidi.inRange(v_left_pos) - && bidi.vis2log(v_left_pos) + 1 == row.endpos() - && row.endpos() < lastpos() - && par.isSeparator(bidi.vis2log(v_left_pos))) - --v_left_pos; - - // calculate the logical position of 'left_pos', if in row - if (!bidi.inRange(v_left_pos)) - left_pos = -1; - else - left_pos = bidi.vis2log(v_left_pos); - // If the position we identified as 'right_pos' is a - // "skipped separator", set 'right_pos' to the *next* - // position to the right. - if (right_pos + 1 == row.endpos() && row.endpos() < lastpos() - && par.isSeparator(right_pos)) { - pos_type const v_right_pos = bidi.log2vis(right_pos) + 1; - if (!bidi.inRange(v_right_pos)) - right_pos = -1; - else - right_pos = bidi.vis2log(v_right_pos); - } - } else { - // known_pos is on the left - left_pos = known_pos; - // *visual* position of 'right_pos' - pos_type v_right_pos = bidi.log2vis(left_pos) + 1; - // If the position we just identified as 'right_pos' - // is a "skipped separator", set 'right_pos' to the - // *next* position to the right. - if (bidi.inRange(v_right_pos) - && bidi.vis2log(v_right_pos) + 1 == row.endpos() - && row.endpos() < lastpos() - && par.isSeparator(bidi.vis2log(v_right_pos))) - ++v_right_pos; - - // calculate the logical position of 'right_pos', if in row - if (!bidi.inRange(v_right_pos)) - right_pos = -1; - else - right_pos = bidi.vis2log(v_right_pos); - // If the position we identified as 'left_pos' is a - // "skipped separator", set 'left_pos' to the *next* - // position to the left. - if (left_pos + 1 == row.endpos() && row.endpos() < lastpos() - && par.isSeparator(left_pos)) { - pos_type const v_left_pos = bidi.log2vis(left_pos) - 1; - if (!bidi.inRange(v_left_pos)) - left_pos = -1; - else - left_pos = bidi.vis2log(v_left_pos); - } - } - return; -} - - -void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos) const -{ - // Check result wrt old implementation - // FIXME: remove after correct testing. - pos_type lp, rp; - getSurroundingPosNew(lp, rp); - getSurroundingPosOrig(left_pos, right_pos); - if (lp != left_pos || rp != right_pos) { - Row const & row = textRow(); - TextMetrics const & tm = bv_->textMetrics(text()); - double dummy = 0; - Row::const_iterator cit = tm.findRowElement(row, pos(), boundary(), dummy); - if (cit != row.end()) - LYXERR0("Wrong surroundingpos: old=(" << left_pos << ", " << right_pos - << "), new=(" << lp << ", " << rp - << ") *cit= " << *cit - << "\ncur = " << *this << "\nrow =" << row); - else - LYXERR0("Wrong surroundingpos: old=(" << left_pos << ", " << right_pos - << "), new=(" << lp << ", " << rp - << ") in empty row" - << "\ncur = " << *this << "\nrow =" << row); - } + // Note that debug message does not catch all early returns above LYXERR(Debug::RTL,"getSurroundingPos(" << pos() << (boundary() ? "b" : "") << ") => (" << left_pos << ", " << right_pos <<")"); } diff --git a/src/Cursor.h b/src/Cursor.h index 94d8f1a310..25771d3783 100644 --- a/src/Cursor.h +++ b/src/Cursor.h @@ -226,8 +226,6 @@ public: * edge" will be returned as -1. */ void getSurroundingPos(pos_type & left_pos, pos_type & right_pos) const; - void getSurroundingPosNew(pos_type & left_pos, pos_type & right_pos) const; - void getSurroundingPosOrig(pos_type & left_pos, pos_type & right_pos) const; /// the row in the paragraph we're in Row const & textRow() const; diff --git a/src/Makefile.am b/src/Makefile.am index 1ebf6c21e9..c10b8e51cb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -101,7 +101,6 @@ endif SOURCEFILESCORE = \ Author.cpp \ - Bidi.cpp \ boost.cpp \ BranchList.cpp \ Buffer.cpp \ @@ -196,7 +195,6 @@ SOURCEFILESCORE = \ HEADERFILESCORE = \ Author.h \ - Bidi.h \ BranchList.h \ buffer_funcs.h \ Buffer.h \