[vte/wip/egmont/bidi: 9/84] vte-26-draw_rows-v5a.patch



commit 22633a43b45f6b1b3ed5f099007d6c34c34dd354
Author: Egmont Koblinger <egmont gmail com>
Date:   Thu Oct 4 12:15:48 2018 +0200

    vte-26-draw_rows-v5a.patch

 src/vte.cc     | 412 ++++++++++++++++++++-------------------------------------
 src/vtedraw.cc |   3 -
 src/vtedraw.hh |   1 -
 3 files changed, 140 insertions(+), 276 deletions(-)
---
diff --git a/src/vte.cc b/src/vte.cc
index 6c9dd1a4..f04bc1e8 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -8533,7 +8533,8 @@ Terminal::draw_cells(struct _vte_draw_text_request *items,
                columns = 0;
                x = items[i].x;
                y = items[i].y;
-               for (; i < n && items[i].y == y; i++) {
+                /* Items are not necessarily contiguous. */
+                for (; i < n && items[i].x == x + columns * column_width && items[i].y == y; i++) {
                        columns += items[i].columns;
                }
                if (clear && (draw_default_bg || back != VTE_DEFAULT_BG)) {
@@ -8573,7 +8574,8 @@ Terminal::draw_cells(struct _vte_draw_text_request *items,
                do {
                        x = items[i].x;
                        y = items[i].y;
-                       for (columns = 0; i < n && items[i].y == y; i++) {
+                        /* Items are not necessarily contiguous. */
+                        for (columns = 0; i < n && items[i].x == x + columns * column_width && items[i].y == 
y; i++) {
                                columns += items[i].columns;
                        }
                         switch (vte_attr_get_value(attr, VTE_ATTR_UNDERLINE_VALUE_MASK, 
VTE_ATTR_UNDERLINE_SHIFT)) {
@@ -8940,295 +8942,161 @@ Terminal::draw_rows(VteScreen *screen_,
                               gint column_width,
                               gint row_height)
 {
-       struct _vte_draw_text_request items[4*VTE_DRAW_MAX_LENGTH];
-        vte::grid::row_t row, rows;
-        vte::grid::column_t i, j;
-        long x, y;
+        struct _vte_draw_text_request *items;
+        vte::grid::row_t row;
+        vte::grid::column_t i, j, col;
+        long y;
         guint fore, nfore, back, nback, deco, ndeco;
-        gboolean hyperlink, nhyperlink, hilite, nhilite,
-                selected, nselected;
+        gboolean hyperlink = FALSE, nhyperlink, hilite = FALSE, nhilite;
+        gboolean selected;
+        uint32_t attr = 0, nattr;
        guint item_count;
        const VteCell *cell;
        VteRowData const* row_data;
 
         uint32_t const attr_mask = m_allow_bold ? ~0 : ~VTE_ATTR_BOLD_MASK;
 
-       /* adjust for the absolute start of row */
+        items = g_newa (struct _vte_draw_text_request, m_column_count);
+
+        /* Adjust for the absolute start of row. */
        start_x -= start_column * column_width;
 
-       /* clear the background */
-       x = start_x;
-       y = start_y;
-       row = start_row;
-       rows = end_row - start_row;
-       do {
+        /* 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 won't be chopped off by another cell's background.
+         * Process each row independently. */
+        for (row = start_row, y = start_y; row < end_row; row++, y += row_height) {
                row_data = find_row_data(row);
-               /* Back up in case this is a multicolumn character,
-                * making the drawing area a little wider. */
-               i = start_column;
-               if (row_data != NULL) {
-                       cell = _vte_row_data_get (row_data, i);
-                       if (cell != NULL) {
-                               while (cell->attr.fragment() && i > 0) {
-                                       cell = _vte_row_data_get (row_data, --i);
-                               }
-                       }
-                       /* Walk the line. */
-                       do {
-                               /* Get the character cell's contents. */
-                               cell = _vte_row_data_get (row_data, i);
-                               /* Find the colors for this cell. */
-                               selected = cell_is_selected(i, row);
-                                determine_colors(cell, selected, &fore, &back, &deco);
-
-                               j = i + (cell ? cell->attr.columns() : 1);
-
-                               while (j < end_column){
-                                       /* Retrieve the cell. */
-                                       cell = _vte_row_data_get (row_data, j);
-                                       /* Don't render fragments of multicolumn characters
-                                        * which have the same attributes as the initial
-                                        * portions. */
-                                       if (cell != NULL && cell->attr.fragment()) {
-                                               j++;
-                                               continue;
-                                       }
-                                       /* Resolve attributes to colors where possible and
-                                        * compare visual attributes to the first character
-                                        * in this chunk. */
-                                       selected = cell_is_selected(j, row);
-                                        determine_colors(cell, selected, &nfore, &nback, &ndeco);
-                                       if (nback != back) {
-                                               break;
-                                       }
-                                       j += cell ? cell->attr.columns() : 1;
-                               }
-                               if (back != VTE_DEFAULT_BG) {
-                                       vte::color::rgb bg;
-                                        rgb_from_index<8, 8, 8>(back, bg);
-                                       _vte_draw_fill_rectangle (
-                                                       m_draw,
-                                                       x + i * column_width,
-                                                       y,
-                                                        (j - i) * column_width,
-                                                       row_height,
-                                                       &bg, VTE_DRAW_OPAQUE);
-                               }
-                               /* We'll need to continue at the first cell which didn't
-                                * match the first one in this set. */
-                               i = j;
-                       } while (i < end_column);
-               } else {
-                       do {
-                               selected = cell_is_selected(i, row);
-                               j = i + 1;
-                               while (j < end_column){
-                                       nselected = cell_is_selected(j, row);
-                                       if (nselected != selected) {
-                                               break;
-                                       }
-                                       j++;
-                               }
-                                determine_colors(nullptr, selected, &fore, &back, &deco);
-                               if (back != VTE_DEFAULT_BG) {
-                                       vte::color::rgb bg;
-                                        rgb_from_index<8, 8, 8>(back, bg);
-                                       _vte_draw_fill_rectangle (m_draw,
-                                                                 x + i *column_width,
-                                                                 y,
-                                                                 (j - i)  * column_width,
-                                                                 row_height,
-                                                                 &bg, VTE_DRAW_OPAQUE);
-                               }
-                               i = j;
-                       } while (i < end_column);
-               }
-               row++;
-               y += row_height;
-       } while (--rows);
+                i = j = start_column;
+                /* 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 (row_data, i) : nullptr;
+                        /* Find the colors for this cell. */
+                        selected = cell_is_selected(i, row);
+                        determine_colors(cell, selected, &fore, &back, &deco);
 
+                        while (++j < end_column) {
+                                /* Retrieve the next cell. */
+                                cell = row_data ? _vte_row_data_get (row_data, j) : nullptr;
+                                /* Resolve attributes to colors where possible and
+                                 * compare visual attributes to the first character
+                                 * in this chunk. */
+                                selected = cell_is_selected(j, row);
+                                determine_colors(cell, selected, &nfore, &nback, &ndeco);
+                                if (nback != back) {
+                                        break;
+                                }
+                        }
+                        if (back != VTE_DEFAULT_BG) {
+                                vte::color::rgb bg;
+                                rgb_from_index<8, 8, 8>(back, bg);
+                                _vte_draw_fill_rectangle (m_draw,
+                                                          start_x + i * column_width,
+                                                          y,
+                                                          (j - i) * column_width,
+                                                          row_height,
+                                                          &bg, VTE_DRAW_OPAQUE);
+                        }
+                        /* We'll need to continue at the first cell which didn't
+                         * match the first one in this set. */
+                        i = j;
+                } while (i < end_column);
+        }
 
-       /* render the text */
-       y = start_y;
-       row = start_row;
-       rows = end_row - start_row;
-       item_count = 1;
-       do {
-               row_data = find_row_data(row);
-               if (row_data == NULL) {
-                       goto fg_skip_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 (row_data, i);
-               if (cell == NULL) {
-                       goto fg_skip_row;
-               }
-               while (cell->attr.fragment() && i > 0)
-                       cell = _vte_row_data_get (row_data, --i);
 
-               /* Walk the line. */
-               do {
-                       /* Get the character cell's contents. */
-                       cell = _vte_row_data_get (row_data, i);
-                       if (cell == NULL) {
-                               goto fg_skip_row;
-                       }
-                       while (cell->c == 0 || cell->attr.invisible() ||
-                                       (cell->c == ' ' &&
-                                         cell->attr.has_none(VTE_ATTR_UNDERLINE_MASK |
-                                                             VTE_ATTR_STRIKETHROUGH_MASK |
-                                                             VTE_ATTR_OVERLINE_MASK) &&
-                                         (!m_allow_hyperlink || cell->attr.hyperlink_idx == 0)) ||
-                               cell->attr.fragment()) {
-                               if (++i >= end_column) {
-                                       goto fg_skip_row;
-                               }
-                               cell = _vte_row_data_get (row_data, i);
-                               if (cell == NULL) {
-                                       goto fg_skip_row;
-                               }
-                       }
-                       /* Find the colors for this cell. */
-                       selected = cell_is_selected(i, row);
-                        determine_colors(cell, selected, &fore, &back, &deco);
+        /* Render one more column to the left and right, to make sure CJKs are drawn correctly. */
+        start_column = MAX(start_column - 1, 0);
+        end_column = MIN(end_column + 1, m_column_count);
 
-                        uint32_t const attr = cell->attr.attr;
+        /* Render the text. */
+        for (row = start_row, y = start_y; row < end_row; row++, y += row_height) {
+                row_data = find_row_data(row);
+                if (row_data == NULL) {
+                        /* Skip row. */
+                        continue;
+                }
 
-                        hyperlink = (m_allow_hyperlink && cell->attr.hyperlink_idx != 0);
-                        hilite = (cell->attr.hyperlink_idx != 0 && cell->attr.hyperlink_idx == 
m_hyperlink_hover_idx) ||
-                                 (m_hyperlink_hover_idx == 0 && m_match != nullptr && 
m_match_span.contains(row, i));
+                /* 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 = start_column; col < end_column; col++) {
+                        /* Get the character cell's contents. */
+                        cell = _vte_row_data_get (row_data, col);
+                        if (cell == NULL) {
+                                /* There'll be no more real cells in this row. */
+                                break;
+                        }
 
-                       items[0].c = cell->c;
-                       items[0].columns = cell->attr.columns();
-                       items[0].x = start_x + i * column_width;
-                       items[0].y = y;
-                       j = i + items[0].columns;
+                        nhyperlink = (m_allow_hyperlink && cell->attr.hyperlink_idx != 0);
+                        if (cell->c == 0 ||
+                                ((cell->c == ' ' || cell->c == '\t') &&  // FIXME '\t' is newly added now, 
double check
+                                 cell->attr.has_none(VTE_ATTR_UNDERLINE_MASK |
+                                                     VTE_ATTR_STRIKETHROUGH_MASK |
+                                                     VTE_ATTR_OVERLINE_MASK) &&
+                                 !nhyperlink) ||
+                            cell->attr.fragment() ||
+                            cell->attr.invisible()) {
+                                /* Skip empty or fragment cell. */
+                                continue;
+                        }
 
-                       /* Now find out how many cells have the same attributes. */
-                       do {
-                               while (j < end_column &&
-                                               item_count < G_N_ELEMENTS(items)) {
-                                       /* Retrieve the cell. */
-                                       cell = _vte_row_data_get (row_data, j);
-                                       if (cell == NULL) {
-                                               goto fg_next_row;
-                                       }
-                                        /* Ignore the attributes on a fragment, the attributes
-                                         * of the preceding character cell should apply. */
-                                        if (cell->attr.fragment()) {
-                                               j++;
-                                               continue;
-                                       }
-                                       if (cell->c == 0){
-                                               /* only break the run if we
-                                                * are drawing attributes
-                                                */
-                                                if ((attr & (VTE_ATTR_UNDERLINE_MASK |
-                                                             VTE_ATTR_STRIKETHROUGH_MASK |
-                                                             VTE_ATTR_OVERLINE_MASK)) |
-                                                    hyperlink | hilite) {
-                                                       break;
-                                               } else {
-                                                       j++;
-                                                       continue;
-                                               }
-                                       }
-                                       /* Resolve attributes to colors where possible and
-                                        * compare visual attributes to the first character
-                                        * in this chunk. */
-                                       selected = cell_is_selected(j, row);
-                                        determine_colors(cell, selected, &nfore, &nback, &ndeco);
-                                       if (nfore != fore) {
-                                               break;
-                                       }
-                                        if (ndeco != deco) {
-                                                break;
-                                        }
+                        /* Find the colors for this cell. */
+                        nattr = cell->attr.attr;
+                        selected = cell_is_selected(col, row);
+                        determine_colors(cell, selected, &nfore, &nback, &ndeco);
+
+                        nhilite = (nhyperlink && cell->attr.hyperlink_idx == m_hyperlink_hover_idx) ||
+                                  (!nhyperlink && m_match != nullptr && m_match_span.contains(row, col));
+
+                        /* See if it no longer fits the run. */
+                        if (item_count > 0 &&
+                                   (((attr ^ nattr) & (VTE_ATTR_BOLD_MASK |
+                                                       VTE_ATTR_ITALIC_MASK |
+                                                       VTE_ATTR_UNDERLINE_MASK |
+                                                       VTE_ATTR_STRIKETHROUGH_MASK |
+                                                       VTE_ATTR_OVERLINE_MASK |
+                                                       VTE_ATTR_BLINK_MASK |
+                                                       VTE_ATTR_INVISIBLE_MASK)) ||  // FIXME or just simply 
"attr != nattr"?
+                                    fore != nfore ||
+                                    back != nback ||
+                                    deco != ndeco ||
+                                    hyperlink != nhyperlink ||
+                                    hilite != nhilite)) {
+                                /* Draw the completed run of cells and start a new one. */
+                                draw_cells(items, item_count,
+                                           fore, back, deco, FALSE, FALSE,
+                                           attr & attr_mask,
+                                           hyperlink, hilite,
+                                           column_width, row_height);
+                                item_count = 0;
+                        }
 
-                                        /* Bold, italic, underline, strikethrough,
-                                         * overline, blink, or invisible differ;
-                                         * break the run.
-                                         */
-                                        if ((cell->attr.attr ^ attr) & (VTE_ATTR_BOLD_MASK |
-                                                                        VTE_ATTR_ITALIC_MASK |
-                                                                        VTE_ATTR_UNDERLINE_MASK |
-                                                                        VTE_ATTR_STRIKETHROUGH_MASK |
-                                                                        VTE_ATTR_OVERLINE_MASK |
-                                                                        VTE_ATTR_BLINK_MASK |
-                                                                        VTE_ATTR_INVISIBLE_MASK))
-                                                break;
+                        attr = nattr;
+                        fore = nfore;
+                        back = nback;
+                        deco = ndeco;
+                        hyperlink = nhyperlink;
+                        hilite = nhilite;
+
+                        g_assert_cmpint (item_count, <, m_column_count);
+                        items[item_count].c = cell->c;
+                        items[item_count].columns = cell->attr.columns();
+                        items[item_count].x = start_x + col * column_width;
+                        items[item_count].y = y;
+                        item_count++;
+                }
 
-                                        nhyperlink = (m_allow_hyperlink && cell->attr.hyperlink_idx != 0);
-                                        if (nhyperlink != hyperlink) {
-                                                break;
-                                        }
-                                       /* Break up matched/not-matched text. */
-                                        nhilite = (cell->attr.hyperlink_idx != 0 && cell->attr.hyperlink_idx 
== m_hyperlink_hover_idx) ||
-                                                  (m_hyperlink_hover_idx == 0 && m_match != nullptr && 
m_match_span.contains(row, j));
-                                       if (nhilite != hilite) {
-                                               break;
-                                       }
-                                       /* Add this cell to the draw list. */
-                                       items[item_count].c = cell->c;
-                                       items[item_count].columns = cell->attr.columns();
-                                       items[item_count].x = start_x + j * column_width;
-                                       items[item_count].y = y;
-                                       j +=  items[item_count].columns;
-                                       item_count++;
-                               }
-                               /* have we encountered a state change? */
-                               if (j < end_column) {
-                                       break;
-                               }
-fg_next_row:
-                               /* is this the last column, on the last row? */
-                               do {
-                                       do {
-                                               if (!--rows) {
-                                                       goto fg_draw;
-                                               }
-
-                                               /* restart on the next row */
-                                               row++;
-                                               y += row_height;
-                                               row_data = find_row_data(row);
-                                       } while (row_data == NULL);
-
-                                       /* Back up in case this is a
-                                        * multicolumn character, making the drawing
-                                        * area a little wider. */
-                                       j = start_column;
-                                       cell = _vte_row_data_get (row_data, j);
-                               } while (cell == NULL);
-                               while (cell->attr.fragment() && j > 0) {
-                                       cell = _vte_row_data_get (row_data, --j);
-                               }
-                       } while (TRUE);
-fg_draw:
-                       /* Draw the cells. */
-                       draw_cells(
-                                       items,
-                                       item_count,
-                                        fore, back, deco, FALSE, FALSE,
-                                        attr & attr_mask,
-                                        hyperlink, hilite,
-                                       column_width, row_height);
-                       item_count = 1;
-                       /* We'll need to continue at the first cell which didn't
-                        * match the first one in this set. */
-                       i = j;
-                       if (!rows) {
-                               goto fg_out;
-                       }
-               } while (i < end_column);
-fg_skip_row:
-               row++;
-               y += row_height;
-       } while (--rows);
-fg_out:
-       return;
+                /* Draw the last run of cells in the row. */
+                if (item_count > 0) {
+                        draw_cells(items, item_count,
+                                   fore, back, deco, FALSE, FALSE,
+                                   attr & attr_mask,
+                                   hyperlink, hilite,
+                                   column_width, row_height);
+                }
+        }
 }
 
 void
diff --git a/src/vtedraw.cc b/src/vtedraw.cc
index 7fceef72..4f56f611 100644
--- a/src/vtedraw.cc
+++ b/src/vtedraw.cc
@@ -148,9 +148,6 @@ _vte_double_equal(double a,
  *
  * Setting this to a large value can cause dramatic slow-downs for some
  * xservers (notably fglrx), see bug #410534.
- *
- * Moreover, setting it larger than %VTE_DRAW_MAX_LENGTH is nonsensical,
- * as the higher layers will not submit runs longer than that value.
  */
 #define MAX_RUN_LENGTH 100
 
diff --git a/src/vtedraw.hh b/src/vtedraw.hh
index c3ede799..f10af608 100644
--- a/src/vtedraw.hh
+++ b/src/vtedraw.hh
@@ -30,7 +30,6 @@
 G_BEGIN_DECLS
 
 #define VTE_DRAW_OPAQUE (1.0)
-#define VTE_DRAW_MAX_LENGTH 1024
 
 #define VTE_DRAW_NORMAL 0
 #define VTE_DRAW_BOLD   1


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