-lyx::pos_type LyXText::log2vis(lyx::pos_type pos) const
-{
- return (bidi_start == -1) ? pos : log2vis_list[pos - bidi_start];
-}
-
-
-lyx::pos_type LyXText::vis2log(lyx::pos_type pos) const
-{
- return (bidi_start == -1) ? pos : vis2log_list[pos - bidi_start];
-}
-
-
-lyx::pos_type LyXText::bidi_level(lyx::pos_type pos) const
-{
- return (bidi_start == -1) ? 0 : bidi_levels[pos - bidi_start];
-}
-
-
-bool LyXText::bidi_InRange(lyx::pos_type pos) const
-{
- return bidi_start == -1 || (bidi_start <= pos && pos <= bidi_end);
-}
-
-
-void LyXText::computeBidiTables(Paragraph const & par,
- Buffer const & buf, Row & row) const
-{
- bidi_same_direction = true;
- if (!lyxrc.rtl_support) {
- bidi_start = -1;
- return;
- }
-
- InsetOld * inset = par.inInset();
- if (inset && inset->owner() &&
- inset->owner()->lyxCode() == InsetOld::ERT_CODE) {
- bidi_start = -1;
- return;
- }
-
- bidi_start = row.pos();
- bidi_end = lastPos(par, row);
-
- if (bidi_start > bidi_end) {
- bidi_start = -1;
- return;
- }
-
- if (bidi_end + 2 - bidi_start >
- static_cast<pos_type>(log2vis_list.size())) {
- pos_type new_size =
- (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[bidi_end + 1 - bidi_start] = -1;
- log2vis_list[bidi_end + 1 - bidi_start] = -1;
-
- BufferParams const & bufparams = buf.params();
- pos_type stack[2];
- bool const rtl_par = par.isRightToLeftPar(bufparams);
- int level = 0;
- bool rtl = false;
- bool rtl0 = false;
- pos_type const body_pos = par.beginningOfBody();
-
- for (pos_type lpos = bidi_start; lpos <= bidi_end; ++lpos) {
- bool is_space = par.isLineSeparator(lpos);
- pos_type const pos =
- (is_space && lpos + 1 <= bidi_end &&
- !par.isLineSeparator(lpos + 1) &&
- !par.isNewline(lpos + 1))
- ? lpos + 1 : lpos;
- LyXFont font = par.getFontSettings(bufparams, pos);
- if (pos != lpos && 0 < lpos && rtl0 && font.isRightToLeft() &&
- font.number() == LyXFont::ON &&
- par.getFontSettings(bufparams, lpos - 1).number()
- == LyXFont::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 >= level) {
- new_level = level;
- new_rtl = rtl;
- new_rtl0 = rtl0;
- }
-
- int new_level2 = new_level;
-
- if (level == new_level && rtl0 != new_rtl0) {
- --new_level2;
- log2vis_list[lpos - bidi_start] = rtl ? 1 : -1;
- } else if (level < new_level) {
- log2vis_list[lpos - bidi_start] = rtl ? -1 : 1;
- if (new_level > rtl_par)
- bidi_same_direction = false;
- } else
- log2vis_list[lpos - bidi_start] = new_rtl ? -1 : 1;
- rtl = new_rtl;
- rtl0 = new_rtl0;
- bidi_levels[lpos - bidi_start] = new_level;
-
- while (level > new_level2) {
- pos_type old_lpos = stack[--level];
- int delta = lpos - old_lpos - 1;
- if (level % 2)
- delta = -delta;
- log2vis_list[lpos - bidi_start] += delta;
- log2vis_list[old_lpos - bidi_start] += delta;
- }
- while (level < new_level)
- stack[level++] = lpos;
- }
-
- while (level > 0) {
- pos_type const old_lpos = stack[--level];
- int delta = bidi_end - old_lpos;
- if (level % 2)
- delta = -delta;
- log2vis_list[old_lpos - bidi_start] += delta;
- }
-
- pos_type vpos = bidi_start - 1;
- for (pos_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;
- }
-}
-
-
-// This method requires a previous call to ComputeBidiTables()
-bool LyXText::isBoundary(Buffer const & buf, Paragraph const & par,
- pos_type pos) const
-{
- if (!lyxrc.rtl_support || pos == 0)
- return false;
-
- if (!bidi_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 = bidi_level(pos - 1) % 2;
- bool const rtl2 = bidi_InRange(pos)
- ? bidi_level(pos) % 2
- : par.isRightToLeftPar(buf.params());
- return rtl != rtl2;
-}
-
-
-bool LyXText::isBoundary(Buffer const & buf, Paragraph const & par,
- pos_type pos, LyXFont const & font) const
-{
- if (!lyxrc.rtl_support)
- return false; // This is just for speedup
-
- bool const rtl = font.isVisibleRightToLeft();
- bool const rtl2 = bidi_InRange(pos)
- ? bidi_level(pos) % 2
- : par.isRightToLeftPar(buf.params());
- return rtl != rtl2;
-}
-
-