[vte/wip/egmont/bidi: 19/78] RingView architecture first steps



commit 2a5bd7a16568367eed4bd72fe172a0c4e0feed83
Author: Egmont Koblinger <egmont gmail com>
Date:   Wed Aug 22 11:54:15 2018 +0200

    RingView architecture first steps

 src/bidi.cc        | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/bidi.hh        | 52 ++++++++++++++++++++++++++++++++++++
 src/vte.cc         | 30 ++++++++++++++-------
 src/vteinternal.hh |  2 ++
 4 files changed, 153 insertions(+), 9 deletions(-)
---
diff --git a/src/bidi.cc b/src/bidi.cc
index 5505cf76..0207399d 100644
--- a/src/bidi.cc
+++ b/src/bidi.cc
@@ -26,6 +26,84 @@
 #include "debug.h"
 #include "vteinternal.hh"
 
+using namespace vte::base;
+
+RingView::RingView()
+{
+        m_ring = nullptr;
+
+        m_start = m_len = m_width = 0;
+
+        m_height_alloc = 32;
+        m_width_alloc = 128;
+
+        m_bidimaps = (bidicellmap **) g_malloc (sizeof (*m_bidimaps) * m_height_alloc);
+        for (int i = 0; i < m_height_alloc; i++) {
+                m_bidimaps[i] = (bidicellmap *) g_malloc (sizeof (**m_bidimaps) * m_width_alloc);
+        }
+}
+
+RingView::~RingView()
+{
+        for (int i = 0; i < m_height_alloc; i++)
+                g_free (m_bidimaps[i]);
+       g_free (m_bidimaps);
+        /* ... */
+}
+
+void RingView::set_ring(Ring *r)
+{
+        m_ring = r;
+}
+
+void RingView::set_width(long w)
+{
+        if (G_UNLIKELY (w > m_width_alloc)) {
+                while (w > m_width_alloc) {
+                        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_width = w;
+}
+
+void RingView::set_rows(long s, long l)
+{
+        if (G_UNLIKELY (l > m_height_alloc)) {
+                int i = m_height_alloc;
+                while (l > m_height_alloc) {
+                        m_height_alloc *= 2;
+                }
+                m_bidimaps = (bidicellmap **) g_realloc (m_bidimaps, sizeof (*m_bidimaps) * m_height_alloc);
+                for (; i < m_height_alloc; i++) {
+                        m_bidimaps[i] = (bidicellmap *) g_malloc (sizeof (**m_bidimaps) * m_width_alloc);
+                }
+        }
+
+        m_start = s;
+        m_len = l;
+}
+
+void RingView::update()
+{
+        for (int i = 0; i < m_len; i++) {
+                for (int j = 0; j < m_width; j++) {
+                        m_bidimaps[i][j].log2vis = j;
+                        m_bidimaps[i][j].vis2log = j;
+                        m_bidimaps[i][j].rtl = 0;
+                }
+        }
+}
+
+bidicellmap *RingView::get_row_map(long row)
+{
+        g_assert (row >= m_start && row < m_start + m_len);
+        return m_bidimaps[row - m_start];
+}
+
 #ifdef WITH_FRIBIDI
 
 FriBidiChar str[1000];
diff --git a/src/bidi.hh b/src/bidi.hh
index b712caef..58fddf04 100644
--- a/src/bidi.hh
+++ b/src/bidi.hh
@@ -20,12 +20,64 @@
 
 #include <glib.h>
 
+#include "ring.hh"
 #include "vterowdata.hh"
 
+struct _bidicellmap {
+        int log2vis;
+        int vis2log;
+        guint8 rtl: 1;
+};
+
+typedef struct _bidicellmap bidicellmap;
+
+namespace vte {
+
+namespace base {  // FIXME ???
+
+class RingView {
+public:
+        RingView();
+        ~RingView();
+
+        void set_ring(Ring *ring);
+        void set_rows(long start, long len);
+        void set_width(long width);
+
+        void update();
+
+        bidicellmap *get_row_map(long row);
+
+private:
+        Ring *m_ring;
+
+        bidicellmap **m_bidimaps;
+
+        long m_start;
+        long m_len;
+        long m_width;
+
+        long m_height_alloc;
+        long m_width_alloc;
+};
+
+
+}; /* namespace base */
+
+}; /* namespace vte */
+
 G_BEGIN_DECLS
 
 void bidi_shuffle (const VteRowData *rowdata, int width);
 int log2vis (int log);
 int vis2log (int vis);
 
+struct _bidimap {
+        vte::base::Ring *ring;
+};
+
+typedef struct _bidimap bidimap;
+
+
+
 G_END_DECLS
diff --git a/src/vte.cc b/src/vte.cc
index 1b67d2b6..609464df 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -8835,8 +8835,8 @@ Terminal::draw_cells_with_attributes(struct _vte_draw_text_request *items,
 
 
 /* XXX tmp hack */
-#define _vte_row_data_get_visual(row_data_p, col) \
-        _vte_row_data_get(row_data_p, vis2log(col))
+#define _vte_row_data_get_visual(row_data_p, bidimap, col) \
+        _vte_row_data_get(row_data_p, bidimap[col].vis2log)
 
 
 /* Paint the contents of a given row at the given location.  Take advantage
@@ -8861,12 +8861,23 @@ Terminal::draw_rows(VteScreen *screen_,
        guint item_count;
        const VteCell *cell;
        VteRowData const* row_data;
+       bidicellmap const* bidimap;
 
         auto const column_count = m_column_count;
         uint32_t const attr_mask = m_allow_bold ? ~0 : ~VTE_ATTR_BOLD_MASK;
 
         items = g_newa (struct _vte_draw_text_request, column_count);
 
+
+
+        // FIXME find a nicer place for these
+        m_ringview.set_ring (m_screen->row_data);
+        m_ringview.set_rows ((long) m_screen->scroll_delta, m_row_count + 2);
+        m_ringview.set_width (m_column_count);
+        m_ringview.update ();
+
+
+
         /* Paint the background.
          * Do it first for all the cells we're about to paint, before drawing the glyphs,
          * so that overflowing bits of a glyph (to the right or downwards) won't be
@@ -8875,20 +8886,20 @@ Terminal::draw_rows(VteScreen *screen_,
          * Process each row independently. */
         for (row = start_row, y = start_y; row < end_row; row++, y += row_height) {
                row_data = find_row_data(row);
-               bidi_shuffle (row_data, m_column_count);
+                bidimap = m_ringview.get_row_map(row);
                 i = j = 0;
                 /* Walk the line.
                  * Locate runs of identical bg colors within a row, and paint each run as a single 
rectangle. */
                 do {
                         /* Get the first cell's contents. */
-                        cell = row_data ? _vte_row_data_get_visual (row_data, i) : nullptr;
+                        cell = row_data ? _vte_row_data_get_visual (row_data, bidimap, i) : nullptr;
                         /* Find the colors for this cell. */
                         selected = cell_is_selected(i, row);
                         determine_colors(cell, selected, &fore, &back, &deco);
 
                         while (++j < column_count) {
                                 /* Retrieve the next cell. */
-                                cell = row_data ? _vte_row_data_get_visual (row_data, j) : nullptr;
+                                cell = row_data ? _vte_row_data_get_visual (row_data, bidimap, j) : nullptr;
                                 /* Resolve attributes to colors where possible and
                                  * compare visual attributes to the first character
                                  * in this chunk. */
@@ -8922,14 +8933,14 @@ Terminal::draw_rows(VteScreen *screen_,
                         /* Skip row. */
                         continue;
                 }
-                bidi_shuffle (row_data, m_column_count);
+                bidimap = m_ringview.get_row_map(row);
 
                 /* Walk the line.
                  * Locate runs of identical attributes within a row, and draw each run using a single 
draw_cells() call. */
                 item_count = 0;
                 for (col = 0; col < column_count; col++) {
                         /* Get the character cell's contents. */
-                        cell = _vte_row_data_get_visual (row_data, col);
+                        cell = _vte_row_data_get_visual (row_data, bidimap, col);
                         if (cell == NULL) {
                                 /* We're rendering BiDi text in visual order, so an unused cell can be 
followed by a used one. */
                                 continue;
@@ -9117,7 +9128,8 @@ Terminal::paint_cursor()
         /* Find the first cell of the character "under" the cursor.
          * This is for CJK.  For TAB, paint the cursor where it really is. */
         VteRowData const *row_data = find_row_data(drow);
-        bidi_shuffle (row_data, m_column_count);
+        m_ringview.update();
+        bidicellmap const *bidimap = m_ringview.get_row_map(drow);
 
        auto cell = find_charcell(col, drow);
         while (cell != NULL && cell->attr.fragment() && cell->c != '\t' && col > 0) {
@@ -9128,7 +9140,7 @@ Terminal::paint_cursor()
        /* Draw the cursor. */
        item.c = (cell && cell->c) ? cell->c : ' ';
        item.columns = item.c == '\t' ? 1 : cell ? cell->attr.columns() : 1;
-       item.x = log2vis(col) * width;
+       item.x = bidimap[col].log2vis * width;
        item.y = row_to_pixel(drow);
        if (cell && cell->c != 0) {
                style = _vte_draw_get_style(cell->attr.bold(), cell->attr.italic());
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index eef61651..f9367e2c 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -24,6 +24,7 @@
 #include "vtetypes.hh"
 #include "vtedraw.hh"
 #include "reaper.hh"
+#include "bidi.hh"
 #include "ring.hh"
 #include "buffer.h"
 #include "parser.hh"
@@ -601,6 +602,7 @@ public:
 
         /* BiDi parameters outside of ECMA and DEC private modes */
         guint m_bidi_rtl  : 1;
+        vte::base::RingView m_ringview;
 
 public:
 


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