[vte/wip/egmont/bidi: 30/75] RingView architecture first steps
- From: Egmont Koblinger <egmontkob src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/wip/egmont/bidi: 30/75] RingView architecture first steps
- Date: Wed, 19 Sep 2018 08:15:45 +0000 (UTC)
commit 83e38142b9e064000854023562367e042fb0e418
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 ddaa219d..c927855f 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -8982,8 +8982,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
@@ -9010,9 +9010,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;
@@ -9027,15 +9038,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);
@@ -9044,7 +9055,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. */
@@ -9117,21 +9128,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++;
@@ -9147,7 +9158,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++;
@@ -9177,7 +9188,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++;
@@ -9265,16 +9276,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:
@@ -9418,7 +9429,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) {
@@ -9429,7 +9441,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 c63bc7ef..938f5154 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]