[vte/wip/egmont/bidi: 39/82] RingView architecture first steps
- From: Egmont Koblinger <egmontkob src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/wip/egmont/bidi: 39/82] RingView architecture first steps
- Date: Wed, 12 Sep 2018 11:54:46 +0000 (UTC)
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]