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