[vte/wip/egmont/bidi: 56/76] show char direction in i-beam cursor



commit 1178e55f87f718d577c283f674e3015a97a8c1b2
Author: Egmont Koblinger <egmont gmail com>
Date:   Thu Aug 30 00:58:46 2018 +0200

    show char direction in i-beam cursor

 src/bidi.cc | 23 +++++++++++++++++------
 src/bidi.hh |  2 ++
 src/vte.cc  | 13 ++++++++++++-
 3 files changed, 31 insertions(+), 7 deletions(-)
---
diff --git a/src/bidi.cc b/src/bidi.cc
index 6a8dfb9d..a882d738 100644
--- a/src/bidi.cc
+++ b/src/bidi.cc
@@ -116,6 +116,13 @@ bool BidiRow::base_is_rtl() const
         return m_base_rtl;
 }
 
+/* Whether the paragraph contains a foreign directionality character.
+ * This is used in the cursor, showing the character's directionality. */
+bool BidiRow::has_foreign() const
+{
+        return m_has_foreign;
+}
+
 
 RingView::RingView()
 {
@@ -205,12 +212,13 @@ void RingView::explicit_line(vte::grid::row_t row, bool rtl)
 
         BidiRow *bidirow = get_row_map_writable(row);
         bidirow->m_base_rtl = rtl;
+        bidirow->m_has_foreign = false;
 
         if (G_UNLIKELY (rtl)) {
                 bidirow->set_width(m_width);
                 for (i = 0; i < m_width; i++) {
                         bidirow->m_log2vis[i] = bidirow->m_vis2log[i] = m_width - 1 - i;
-                        bidirow->m_vis_rtl[i] = TRUE;
+                        bidirow->m_vis_rtl[i] = true;
                 }
         } else {
                 /* Shortcut: bidirow->m_width == 0 might denote a fully LTR line,
@@ -261,7 +269,7 @@ vte::grid::row_t RingView::paragraph(vte::grid::row_t row)
 {
         const VteRowData *row_data = m_ring->index(row);
         if (row_data == nullptr) {
-                return explicit_paragraph(row, FALSE);
+                return explicit_paragraph(row, false);
         }
 
 #ifndef WITH_FRIBIDI
@@ -377,6 +385,7 @@ vte::grid::row_t RingView::paragraph(vte::grid::row_t row)
         while (row < m_start + m_len) {
                 bidirow = get_row_map_writable(row);
                 bidirow->m_base_rtl = rtl;
+                bidirow->m_has_foreign = true;
                 bidirow->set_width(m_width);
 
                 row_data = m_ring->index(row);
@@ -413,12 +422,14 @@ vte::grid::row_t RingView::paragraph(vte::grid::row_t row)
                 if (level == 0) {
                         /* error, what should we do? */
                         explicit_line (row, rtl);
+                        bidirow->m_has_foreign = true;
                         goto next_line;
                 }
 
                 if (level == 1 || (rtl && level == 2)) {
                         /* Fast shortcut for LTR-only and RTL-only lines. */
                         explicit_line (row, rtl);
+                        bidirow->m_has_foreign = true;
                         goto next_line;
                 }
 
@@ -429,7 +440,7 @@ vte::grid::row_t RingView::paragraph(vte::grid::row_t row)
                         int unused = MAX(m_width - row_data->len, 0);
                         for (; tv < unused; tv++) {
                                 bidirow->m_vis2log[tv] = m_width - 1 - tv;
-                                bidirow->m_vis_rtl[tv] = TRUE;
+                                bidirow->m_vis_rtl[tv] = true;
                         }
                 }
                 for (fv = lines[line]; fv < lines[line + 1]; fv++) {
@@ -443,7 +454,7 @@ vte::grid::row_t RingView::paragraph(vte::grid::row_t row)
                                 /* RTL character directionality. Map fragments in reverse order. */
                                 for (col = 0; col < cell->attr.columns(); col++) {
                                         bidirow->m_vis2log[tv + col] = tl + cell->attr.columns() - 1 - col;
-                                        bidirow->m_vis_rtl[tv + col] = TRUE;
+                                        bidirow->m_vis_rtl[tv + col] = true;
                                 }
                                 tv += cell->attr.columns();
                                 tl += cell->attr.columns();
@@ -451,7 +462,7 @@ vte::grid::row_t RingView::paragraph(vte::grid::row_t row)
                                 /* LTR character directionality. */
                                 for (col = 0; col < cell->attr.columns(); col++) {
                                         bidirow->m_vis2log[tv] = tl;
-                                        bidirow->m_vis_rtl[tv] = FALSE;
+                                        bidirow->m_vis_rtl[tv] = false;
                                         tv++;
                                         tl++;
                                 }
@@ -462,7 +473,7 @@ vte::grid::row_t RingView::paragraph(vte::grid::row_t row)
                         g_assert_cmpint (tv, ==, MIN (row_data->len, m_width));
                         for (; tv < m_width; tv++) {
                                 bidirow->m_vis2log[tv] = tv;
-                                bidirow->m_vis_rtl[tv] = FALSE;
+                                bidirow->m_vis_rtl[tv] = false;
                         }
                 }
                 g_assert_cmpint (tv, ==, m_width);
diff --git a/src/bidi.hh b/src/bidi.hh
index 855108e0..7044af74 100644
--- a/src/bidi.hh
+++ b/src/bidi.hh
@@ -49,6 +49,7 @@ public:
         bool log_is_rtl(vte::grid::column_t col) const;
         bool vis_is_rtl(vte::grid::column_t col) const;
         bool base_is_rtl() const;
+        bool has_foreign() const;
 
 private:
         void set_width(vte::grid::column_t width);
@@ -61,6 +62,7 @@ private:
         guint8 *m_vis_rtl;
 
         guint8 m_base_rtl: 1;
+        guint8 m_has_foreign: 1;
 };
 
 
diff --git a/src/vte.cc b/src/vte.cc
index 2960998d..8668b8ff 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -9206,12 +9206,23 @@ Terminal::paint_cursor()
                         stem_width = (int) (((float) (m_char_ascent + m_char_descent)) * 
m_cursor_aspect_ratio + 0.5);
                         stem_width = CLAMP (stem_width, VTE_LINE_WIDTH, m_cell_width);
 
-                        if (row_data && bidirow->base_is_rtl())
+                        // FIXME make an exception when the cursor is just after the last character:
+                        // show it next to the last character (wherever it appears due to BiDi) rather than
+                        // beyond the end of the string, as KDE/Qt does. Maybe not just for I-beam.
+
+                        if (row_data && bidirow->vis_is_rtl(viscol))
                                 x += m_cell_width - stem_width;
 
                         _vte_draw_fill_rectangle(m_draw,
                                                  x, y + m_char_padding.top, stem_width, m_char_ascent + 
m_char_descent,
                                                  &bg, VTE_DRAW_OPAQUE);
+
+                        if (focus && row_data && bidirow->has_foreign())
+                                _vte_draw_fill_rectangle(m_draw,
+                                                         bidirow->vis_is_rtl(viscol) ? x - stem_width : x + 
stem_width, y + m_char_padding.top,
+                                                         stem_width, stem_width,
+                                                         &bg, VTE_DRAW_OPAQUE);
+
                        break;
                 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]