From 72535633e3d4f9a42c22561029e34a6b8d0b0bba Mon Sep 17 00:00:00 2001 From: Dov Feldstern Date: Mon, 9 Jul 2007 17:18:35 +0000 Subject: [PATCH] Fix bug 3889 (justification of Bidi text in the GUI) git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19016 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/Text.cpp | 14 ++++++++++++++ src/rowpainter.cpp | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/Text.cpp b/src/Text.cpp index 50311608a0..336239c26e 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -1718,6 +1718,12 @@ int Text::cursorX(BufferView const & bv, CursorSlice const & sl, pos_type const row_pos = row.pos(); pos_type const end = row.endpos(); + // Spaces at logical line breaks in bidi text must be skipped during + // cursor positioning. However, they may appear visually in the middle + // of a row; they must be skipped, wherever they are... + // * logically "abc_[HEBREW_\nHEBREW]" + // * visually "abc_[_WERBEH\nWERBEH]" + pos_type skipped_sep_vpos = -1; if (end <= row_pos) cursor_vpos = row_pos; @@ -1743,7 +1749,15 @@ int Text::cursorX(BufferView const & bv, CursorSlice const & sl, FontMetrics const & labelfm = theFontMetrics( getLabelFont(buffer, par)); + // If the last logical character is a separator, skip it, unless + // it's in the last row of a paragraph; see skipped_sep_vpos declaration + if (end > 0 && end < par.size() && par.isSeparator(end - 1)) + skipped_sep_vpos = bidi.log2vis(end - 1); + for (pos_type vpos = row_pos; vpos < cursor_vpos; ++vpos) { + // Skip the separator which is at the logical end of the row + if (vpos == skipped_sep_vpos) + continue; pos_type pos = bidi.vis2log(vpos); if (body_pos > 0 && pos == body_pos - 1) { // FIXME UNICODE diff --git a/src/rowpainter.cpp b/src/rowpainter.cpp index e3dfefba8f..9844e2d146 100644 --- a/src/rowpainter.cpp +++ b/src/rowpainter.cpp @@ -734,6 +734,12 @@ void RowPainter::paintLast() void RowPainter::paintText() { pos_type const end = row_.endpos(); + // Spaces at logical line breaks in bidi text must be skipped during + // painting. However, they may appear visually in the middle + // of a row; they must be skipped, wherever they are... + // * logically "abc_[HEBREW_\nHEBREW]" + // * visually "abc_[_WERBEH\nWERBEH]" + pos_type skipped_sep_vpos = -1; pos_type body_pos = par_.beginOfBody(); if (body_pos > 0 && (body_pos > end || !par_.isLineSeparator(body_pos - 1))) { @@ -751,10 +757,21 @@ void RowPainter::paintText() Font font; Buffer const & buffer = *bv_.buffer(); + // If the last logical character is a separator, don't paint it, unless + // it's in the last row of a paragraph; see skipped_sep_vpos declaration + if (end > 0 && end < par_.size() && par_.isSeparator(end - 1)) + skipped_sep_vpos = bidi_.log2vis(end - 1); + for (pos_type vpos = row_.pos(); vpos < end; ) { if (x_ > bv_.workWidth()) break; + // Skip the separator at the logical end of the row + if (vpos == skipped_sep_vpos) { + ++vpos; + continue; + } + pos_type const pos = bidi_.vis2log(vpos); if (pos >= par_.size()) {