[vte/wip/egmont/bidi: 20/83] RingView architecture first steps
- From: Egmont Koblinger <egmontkob src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/wip/egmont/bidi: 20/83] RingView architecture first steps
- Date: Thu, 3 Jan 2019 12:55:05 +0000 (UTC)
commit 58217dde847b3179711a8aa9f1b8ad074cf1d25e
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 0e5f91ed..b4eb2460 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -8831,8 +8831,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
@@ -8857,12 +8857,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
@@ -8871,20 +8882,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. */
@@ -8918,14 +8929,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;
@@ -9113,7 +9124,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) {
@@ -9124,7 +9136,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]