[vte/wip/egmont/bidi: 44/75] vte-26-draw_rows-v3.patch



commit e1639aa00f2628a0e51bcc620f76c0ec094d11af
Author: Egmont Koblinger <egmont gmail com>
Date:   Sat Aug 25 15:06:33 2018 +0200

    vte-26-draw_rows-v3.patch

 src/vte.cc | 415 +++++++++++++++++++++++--------------------------------------
 1 file changed, 155 insertions(+), 260 deletions(-)
---
diff --git a/src/vte.cc b/src/vte.cc
index 74ed47b1..54e1cb6e 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -8588,7 +8588,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 continuous. */
+                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)) {
@@ -8628,7 +8629,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 continuous. */
+                        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)) {
@@ -9000,23 +9002,24 @@ Terminal::draw_rows(VteScreen *screen_,
                               gint column_width,
                               gint row_height)
 {
-       struct _vte_draw_text_request items[4*VTE_DRAW_MAX_LENGTH];
+        struct _vte_draw_text_request items[VTE_DRAW_MAX_LENGTH];
         vte::grid::row_t row, rows;
-        vte::grid::column_t i, j;
+        vte::grid::column_t i, j, col;
         long x, 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 */
+        /* Adjust for the absolute start of row. */
        start_x -= start_column * column_width;
 
-       /* clear the background */
+        /* Clear the background. */
        x = start_x;
        y = start_y;
        row = start_row;
@@ -9025,270 +9028,162 @@ Terminal::draw_rows(VteScreen *screen_,
                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);
-               }
+                i = j = start_column;
+                /* Walk the line. */
+                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,
+                                                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);
                row++;
                y += row_height;
        } while (--rows);
 
 
-       /* 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);
+        /* Render the text. */
+        row = start_row;
+        y = start_y;
+        col = start_column;
 
-               /* 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);
-
-                        uint32_t const attr = cell->attr.attr;
-
-                        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));
-
-                       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;
+        do {
+                item_count = 0;
+                while (item_count < G_N_ELEMENTS(items)) {
+                        /* Find next cell that we care about. */
+                        cell = NULL;
+                        while (row < end_row) {
+                                row_data = find_row_data(row);
+                                if (row_data == NULL) {
+                                        /* Skip row. */
+                                        row++;
+                                        y += row_height;
+                                        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) {
+                                /* Walk the line. */
+                                while (col < end_column) {  // FIXME gcc warning: missed loop optimization
+                                        cell = _vte_row_data_get (row_data, col);
+                                        if (cell == NULL) {
+                                                /* There'll be no more real cells in this row, go to next 
row. */
                                                 break;
                                         }
 
-                                        /* 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;
-
+                                        /* Get the character cell's contents. */
+                                        cell = _vte_row_data_get (row_data, col);
                                         nhyperlink = (m_allow_hyperlink && cell->attr.hyperlink_idx != 0);
-                                        if (nhyperlink != hyperlink) {
-                                                break;
+                                        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. */
+                                                col++;
+                                                continue;
                                         }
-                                       /* 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;
+
+                                        /* Real cell found, "break 2". */
+                                        break;
+                                }
+
+                                if (cell == NULL) {
+                                        /* Next row. */
+                                        row++;
+                                        y += row_height;
+                                        col = start_column;
+                                        continue;
+                                }
+
+                                /* Real cell found. */
+                                break;
+                        }
+
+                        if (cell == NULL) {
+                                /* No more cells to paint, flush what we've collected so far. */
+                                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));
+
+                        if (item_count == 0) {
+                                /* First cell in run, remember its attributes. */
+                                attr = nattr;
+                                fore = nfore;
+                                back = nback;
+                                deco = ndeco;
+                                hyperlink = nhyperlink;
+                                hilite = nhilite;
+                        } else {
+                                /* Subsequent cell, see if it fits in the run. */
+                                if (((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) {
+                                        break;
+                                }
+                        }
+
+                        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;
+                        col += items[item_count++].columns;
+                }
+
+                /* Draw the cells. */
+                if (item_count > 0) {
+                        draw_cells(items, item_count,
+                                   fore, back, deco, FALSE, FALSE,
+                                   attr & attr_mask,
+                                   hyperlink, hilite,
+                                   column_width, row_height);
+                        item_count = 0;
+                }
+        } while (cell != NULL);
 }
 
 void


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