[vte/wip/egmont/bidi: 26/77] cleanups



commit 02fa0d29e2e970a48836dd98f85a32e8674f96ce
Author: Egmont Koblinger <egmont gmail com>
Date:   Thu Aug 23 20:54:55 2018 +0200

    cleanups

 src/bidi.cc | 108 +++++++++++++++++++++++++++++++++++++++++++++++-------------
 src/bidi.hh |  21 +++++++++---
 2 files changed, 103 insertions(+), 26 deletions(-)
---
diff --git a/src/bidi.cc b/src/bidi.cc
index 72023d2a..a11883a4 100644
--- a/src/bidi.cc
+++ b/src/bidi.cc
@@ -50,18 +50,17 @@ RingView::RingView()
         m_height_alloc = 32;
         m_width_alloc = 128;
 
-        m_bidimaps = (bidicellmap **) g_malloc (sizeof (*m_bidimaps) * m_height_alloc);
+        m_bidirows = (bidirow *) g_malloc (sizeof (bidirow) * m_height_alloc);
         for (int i = 0; i < m_height_alloc; i++) {
-                m_bidimaps[i] = (bidicellmap *) g_malloc (sizeof (**m_bidimaps) * m_width_alloc);
+                m_bidirows[i].map = (bidicellmap *) g_malloc (sizeof (bidicellmap) * m_width_alloc);
         }
 }
 
 RingView::~RingView()
 {
         for (int i = 0; i < m_height_alloc; i++)
-                g_free (m_bidimaps[i]);
-        g_free (m_bidimaps);
-        /* ... */
+                g_free (m_bidirows[i].map);
+        g_free (m_bidirows);
 }
 
 void RingView::set_ring(Ring *r)
@@ -76,7 +75,7 @@ void RingView::set_width(long w)
                         m_width_alloc *= 2;
                 }
                 for (int i = 0; i < m_height_alloc; i++) {
-                        m_bidimaps[i] = (bidicellmap *) g_realloc (m_bidimaps[i], sizeof (*m_bidimaps) * 
m_width_alloc);
+                        m_bidirows[i].map = (bidicellmap *) g_realloc (m_bidirows[i].map, sizeof 
(bidicellmap) * m_width_alloc);
                 }
         }
 
@@ -90,9 +89,9 @@ void RingView::set_rows(long s, long l)
                 while (l > m_height_alloc) {
                         m_height_alloc *= 2;
                 }
-                m_bidimaps = (bidicellmap **) g_realloc (m_bidimaps, sizeof (*m_bidimaps) * m_height_alloc);
+                m_bidirows = (bidirow *) g_realloc (m_bidirows, sizeof (bidirow) * m_height_alloc);
                 for (; i < m_height_alloc; i++) {
-                        m_bidimaps[i] = (bidicellmap *) g_malloc (sizeof (**m_bidimaps) * m_width_alloc);
+                        m_bidirows[i].map = (bidicellmap *) g_malloc (sizeof (bidicellmap) * m_width_alloc);
                 }
         }
 
@@ -108,15 +107,72 @@ void RingView::update()
         }
 }
 
-bidicellmap *RingView::get_row_map(long row)
+bidicellmap *RingView::get_row_map(long row)  // FIXME remove this?
 {
         g_assert_cmpint (row, >=, m_start);
         g_assert_cmpint (row, <, m_start + m_len);
-        return m_bidimaps[row - m_start];
+        return m_bidirows[row - m_start].map;
+}
+
+/* Converts from logical to visual column. Offscreen columns are mirrored
+ * for RTL lines, e.g. (assuming 80 columns) -1 <=> 80, -2 <=> 81 etc. */
+long RingView::log2vis(long row, long col)
+{
+        g_assert_cmpint (row, >=, m_start);
+        g_assert_cmpint (row, <, m_start + m_len);
+        bidirow *brow = &m_bidirows[row - m_start];
+        if (G_LIKELY (col >= 0 && col < m_width)) {
+                return brow->map[col].log2vis;
+        } else {
+                return brow->rtl ? m_width - 1 - col : col;
+        }
+}
+
+/* Converts from visual to logical column. Offscreen columns are mirrored
+ * for RTL lines, e.g. (assuming 80 columns) -1 <=> 80, -2 <=> 81 etc. */
+long RingView::vis2log(long row, long col)
+{
+        g_assert_cmpint (row, >=, m_start);
+        g_assert_cmpint (row, <, m_start + m_len);
+        bidirow *brow = &m_bidirows[row - m_start];
+        if (G_LIKELY (col >= 0 && col < m_width)) {
+                return brow->map[col].vis2log;
+        } else {
+                return brow->rtl ? m_width - 1 - col : col;
+        }
+}
+
+/* Whether the cell at the given visual position has RTL directionality.
+ * For offscreen columns the line's direction is returned. */
+bool RingView::vis_is_rtl(long row, long col)
+{
+        g_assert_cmpint (row, >=, m_start);
+        g_assert_cmpint (row, <, m_start + m_len);
+        bidirow *brow = &m_bidirows[row - m_start];
+        if (G_LIKELY (col >= 0 && col < m_width)) {
+                return brow->map[col].vis_rtl;
+        } else {
+                return brow->rtl;
+        }
+}
+
+/* Whether the cell at the given logical position has RTL directionality.
+ * For offscreen columns the line's direction is returned. */
+bool RingView::log_is_rtl(long row, long col)
+{
+        g_assert_cmpint (row, >=, m_start);
+        g_assert_cmpint (row, <, m_start + m_len);
+        bidirow *brow = &m_bidirows[row - m_start];
+        if (G_LIKELY (col >= 0 && col < m_width)) {
+                col = brow->map[col].log2vis;
+                return brow->map[col].vis_rtl;
+        } else {
+                return brow->rtl;
+        }
 }
 
 /* Set up the mapping according to explicit mode for a given line. */
-void RingView::explicit_line(long row, gboolean rtl)
+void RingView::explicit_line(long row, bool rtl)
 {
         int i;
         bidicellmap *map;
@@ -124,7 +180,8 @@ void RingView::explicit_line(long row, gboolean rtl)
         if (G_UNLIKELY (row < m_start || row >= m_start + m_len))
                 return;
 
-        map = m_bidimaps[row - m_start];
+        m_bidirows[row - m_start].rtl = rtl;
+        map = m_bidirows[row - m_start].map;
 
         if (G_UNLIKELY (rtl)) {
                 for (i = 0; i < m_width; i++) {
@@ -142,7 +199,7 @@ void RingView::explicit_line(long row, gboolean rtl)
 /* Set up the mapping according to explicit mode, for all the lines
  * of a paragraph beginning at the given line.
  * Returns the row number after the paragraph or viewport (whichever ends first). */
-long RingView::explicit_paragraph(long row, gboolean rtl)
+long RingView::explicit_paragraph(long row, bool rtl)
 {
         const VteRowData *row_data;
 
@@ -164,8 +221,8 @@ long RingView::paragraph(long row)
 
 #ifdef WITH_FRIBIDI
         const VteCell *cell;
-        gboolean rtl;
-        gboolean autodir;
+        bool rtl;
+        bool autodir;
         FriBidiParType pbase_dir;
         FriBidiLevel level;
         bidicellmap *map;
@@ -248,10 +305,11 @@ long RingView::paragraph(long row)
         }
 
         /* For convenience, from now on this variable contains the resolved (i.e. possibly autodetected) 
value. */
+        g_assert_cmpint (pbase_dir, !=, FRIBIDI_PAR_ON);
         rtl = (pbase_dir == FRIBIDI_PAR_RTL || pbase_dir == FRIBIDI_PAR_WRTL);
 
         if (level == 1 || (rtl && level == 2)) {
-                /* Fast shortcut for LTR-only and RTL-only. */
+                /* Fast shortcut for LTR-only and RTL-only paragraphs. */
                 return explicit_paragraph (row_orig, rtl);
         }
 
@@ -265,14 +323,15 @@ long RingView::paragraph(long row)
                         continue;
                 }
 
-                map = m_bidimaps[row - m_start];
+                m_bidirows[row - m_start].rtl = rtl;
+                map = m_bidirows[row - m_start].map;
 
                 row_data = m_ring->index(row++);
                 if (row_data == nullptr)
                         break;
 
                 /* fribidi_reorder_line() conveniently reorders arbitrary numbers we pass as the map.
-                 * Use the logical position to save us from headaches when encountering fragments . */
+                 * Use the logical position to save us from headaches when encountering fragments. */
                 k = lines[line];
                 for (j = 0; j < m_width && j < row_data->len; j++) {
                         cell = _vte_row_data_get (row_data, j);
@@ -299,10 +358,14 @@ long RingView::paragraph(long row)
                 if (level == 0) {
                         /* error, what should we do? */
                         explicit_line (row, rtl);
-                        goto cont;
+                        goto next_line;
                 }
 
-                // FIXME can we do LTR-only and RTL-only shortcuts, just like with 
fribidi_get_par_embedding_levels_ex() ?
+                if (level == 1 || (rtl && level == 2)) {
+                        /* Fast shortcut for LTR-only and RTL-only lines. */
+                        explicit_line (row, rtl);
+                        goto next_line;
+                }
 
                 /* Copy to our realm. Proceed in visual order.*/
                 v = 0;
@@ -348,7 +411,8 @@ long RingView::paragraph(long row)
                 }
                 g_assert_cmpint (v, ==, m_width);
 
-                /* From vis2log create the log2vis mapping too */
+                /* From vis2log create the log2vis mapping too.
+                 * In debug mode assert that we have a bijective mapping. */
                 if (_vte_debug_on (VTE_DEBUG_BIDI)) {
                         for (l = 0; l < m_width; l++) {
                                 map[l].log2vis = -1;
@@ -365,7 +429,7 @@ long RingView::paragraph(long row)
                         }
                 }
 
-cont:
+next_line:
                 line++;
 
                 if (!row_data->attr.soft_wrapped)
diff --git a/src/bidi.hh b/src/bidi.hh
index 6291f662..09dfd079 100644
--- a/src/bidi.hh
+++ b/src/bidi.hh
@@ -23,6 +23,7 @@
 #include "ring.hh"
 #include "vterowdata.hh"
 
+// FIXME these names are ugly. Also, make these declarations private if possible.
 struct _bidicellmap {
         int log2vis;
         int vis2log;
@@ -31,6 +32,13 @@ struct _bidicellmap {
 
 typedef struct _bidicellmap bidicellmap;
 
+struct _bidirow {
+        guint8 rtl: 1;
+        bidicellmap *map;
+};
+
+typedef struct _bidirow bidirow;
+
 namespace vte {
 
 namespace base {  // FIXME ???
@@ -46,12 +54,17 @@ public:
 
         void update();
 
-        bidicellmap *get_row_map(long row);
+        bidicellmap *get_row_map(long row);  // FIXME remove?
+
+        long log2vis(long row, long col);
+        long vis2log(long row, long col);
+        bool log_is_rtl(long row, long col);
+        bool vis_is_rtl(long row, long col);
 
 private:
         Ring *m_ring;
 
-        bidicellmap **m_bidimaps;
+        bidirow *m_bidirows;
 
         long m_start;
         long m_len;
@@ -60,8 +73,8 @@ private:
         long m_height_alloc;
         long m_width_alloc;
 
-        void explicit_line(long row, gboolean rtl);
-        long explicit_paragraph(long row, gboolean rtl);
+        void explicit_line(long row, bool rtl);
+        long explicit_paragraph(long row, bool rtl);
         long paragraph(long row);
 };
 


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