[vte/wip/egmont/bidi: 39/82] RingView architecture first steps



commit 9a71c72c2238feab8637024bdf6f43a8728afd31
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         | 48 ++++++++++++++++++++-------------
 src/vteinternal.hh |  2 ++
 4 files changed, 162 insertions(+), 18 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 74d286a9..c531303b 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -9023,8 +9023,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
@@ -9051,9 +9051,20 @@ Terminal::draw_rows(VteScreen *screen_,
        guint item_count;
        const VteCell *cell;
        VteRowData const* row_data;
+       bidicellmap const* bidimap;
 
         uint32_t const attr_mask = m_allow_bold ? ~0 : ~VTE_ATTR_BOLD_MASK;
 
+
+
+        // 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 ();
+
+
+
        /* adjust for the absolute start of row */
        start_x -= start_column * column_width;
 
@@ -9068,15 +9079,15 @@ Terminal::draw_rows(VteScreen *screen_,
                 * making the drawing area a little wider. */
                i = start_column;
                if (row_data != NULL) {
-                        bidi_shuffle (row_data, m_column_count);
-                       cell = _vte_row_data_get_visual (row_data, i);
+                        bidimap = m_ringview.get_row_map(row);
+                       cell = _vte_row_data_get_visual (row_data, bidimap, i);
                        while (cell != NULL && cell->attr.fragment() && i > 0) {
-                               cell = _vte_row_data_get_visual (row_data, --i);
+                               cell = _vte_row_data_get_visual (row_data, bidimap, --i);
                        }
                        /* Walk the line. */
                        do {
                                /* Get the character cell's contents. */
-                               cell = _vte_row_data_get_visual (row_data, i);
+                               cell = _vte_row_data_get_visual (row_data, bidimap, i);
                                /* Find the colors for this cell. */
                                selected = cell_is_selected(i, row);
                                 determine_colors(cell, selected, &fore, &back, &deco);
@@ -9085,7 +9096,7 @@ Terminal::draw_rows(VteScreen *screen_,
 
                                while (j < end_column){
                                        /* Retrieve the cell. */
-                                       cell = _vte_row_data_get_visual (row_data, j);
+                                       cell = _vte_row_data_get_visual (row_data, bidimap, j);
                                        /* Don't render fragments of multicolumn characters
                                         * which have the same attributes as the initial
                                         * portions. */
@@ -9158,21 +9169,21 @@ Terminal::draw_rows(VteScreen *screen_,
                if (row_data == NULL) {
                        goto fg_skip_row;
                }
-                bidi_shuffle (row_data, m_column_count);
+               bidimap = m_ringview.get_row_map(row);
                /* Back up in case this is a multicolumn character,
                 * making the drawing area a little wider. */
                i = start_column;
-               cell = _vte_row_data_get_visual (row_data, i);
+               cell = _vte_row_data_get_visual (row_data, bidimap, i);
 //             if (cell == NULL) {
 //                     goto fg_skip_row;
 //             }
                while (cell != NULL && cell->attr.fragment() && i > 0)
-                       cell = _vte_row_data_get_visual (row_data, --i);
+                       cell = _vte_row_data_get_visual (row_data, bidimap, --i);
 
                /* Walk the line. */
                do {
                        /* Get the character cell's contents. */
-                       cell = _vte_row_data_get_visual (row_data, i);
+                       cell = _vte_row_data_get_visual (row_data, bidimap, i);
 //                     if (cell == NULL) {
 //                             // goto fg_skip_row;
 //                             i++;
@@ -9188,7 +9199,7 @@ Terminal::draw_rows(VteScreen *screen_,
                                if (++i >= end_column) {
                                        goto fg_skip_row;
                                }
-                               cell = _vte_row_data_get_visual (row_data, i);
+                               cell = _vte_row_data_get_visual (row_data, bidimap, i);
 //                             if (cell == NULL) {
 //                                     // goto fg_skip_row;
 //                                     i++;
@@ -9218,7 +9229,7 @@ Terminal::draw_rows(VteScreen *screen_,
                                while (j < end_column &&
                                                item_count < G_N_ELEMENTS(items)) {
                                        /* Retrieve the cell. */
-                                       cell = _vte_row_data_get_visual (row_data, j);
+                                       cell = _vte_row_data_get_visual (row_data, bidimap, j);
                                        if (cell == NULL) {
                                                // goto fg_next_row;
                                                j++;
@@ -9306,16 +9317,16 @@ fg_next_row:
                                                y += row_height;
                                                row_data = find_row_data(row);
                                        } while (row_data == NULL);
-                                        bidi_shuffle (row_data, m_column_count);
+                                        bidimap = m_ringview.get_row_map(row);
 
                                        /* Back up in case this is a
                                         * multicolumn character, making the drawing
                                         * area a little wider. */
                                        j = start_column;
-                                       cell = _vte_row_data_get_visual (row_data, j);
+                                       cell = _vte_row_data_get_visual (row_data, bidimap, j);
                                } while (FALSE);  // FIXME eliminate loop
                                while (cell != NULL && cell->attr.fragment() && j > 0) {
-                                       cell = _vte_row_data_get_visual (row_data, --j);
+                                       cell = _vte_row_data_get_visual (row_data, bidimap, --j);
                                }
                        } while (TRUE);
 fg_draw:
@@ -9459,7 +9470,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) {
@@ -9470,7 +9482,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 d10b90ae..b4502d40 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"
@@ -640,6 +641,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]