[vte/wip/egmont/bidi: 103/104] etap14



commit 266e9dfd497712e26042da22cb54f58b4f7aadf0
Author: Egmont Koblinger <egmont gmail com>
Date:   Mon May 27 12:25:17 2019 +0200

    etap14

 src/ringview.cc | 25 ++++++++++++++++++++-----
 src/vte.cc      | 19 ++++++++++---------
 2 files changed, 30 insertions(+), 14 deletions(-)
---
diff --git a/src/ringview.cc b/src/ringview.cc
index f875ab40..7cb69687 100644
--- a/src/ringview.cc
+++ b/src/ringview.cc
@@ -83,14 +83,21 @@ void RingView::resume()
 {
         g_assert_cmpint (m_len, >=, 1);
 
-        m_rows_alloc_len = m_len + 16;  /* a bit of random heuristics for context lines */
+        /* +16: A bit of arbitrary heuristics to likely prevent a quickly following
+         * realloc for the required context lines. */
+        m_rows_alloc_len = m_len + 16;
         m_rows = (VteRowData **) g_malloc (sizeof (VteRowData *) * m_rows_alloc_len);
         for (int i = 0; i < m_rows_alloc_len; i++) {
                 m_rows[i] = (VteRowData *) g_malloc (sizeof (VteRowData));
                 _vte_row_data_init (m_rows[i]);
         }
 
-        m_bidirows_alloc_len = m_len;
+        /* +2: Likely prevent a quickly following realloc.
+         * The number of lines of interest keeps jumping up and down by one
+         * due to per-pixel scrolling, and by another one due sometimes having
+         * to reshuffle another line below the bottom for the overflowing bits
+         * of the outline rectangle cursor. */
+        m_bidirows_alloc_len = m_len + 2;
         m_bidirows = (BidiRow **) g_malloc (sizeof (BidiRow *) * m_bidirows_alloc_len);
         for (int i = 0; i < m_bidirows_alloc_len; i++) {
                 m_bidirows[i] = new BidiRow();
@@ -125,15 +132,22 @@ void RingView::set_rows(vte::grid::row_t start, vte::grid::row_t len)
         if (start == m_start && len == m_len)
                 return;
 
+        /* With per-pixel scrolling, the desired viewport often shrinks by
+         * one row at one end, and remains the same at the other end.
+         * Save work by just keeping the current valid data in this case. */
+        if (!m_invalid && start >= m_start && start + len <= m_start + m_len)
+                return;
+
         g_assert_cmpint (len, >=, 1);
 
         /* m_rows is expanded on demand in update() */
 
-        /* m_bidirows needs exactly these many lines */
+        /* m_bidirows needs exactly this many lines */
         if (G_UNLIKELY (!m_paused && len > m_bidirows_alloc_len)) {
                 int i = m_bidirows_alloc_len;
                 while (len > m_bidirows_alloc_len) {
-                        m_bidirows_alloc_len *= 1.25 /* whatever */;
+                        /* Don't realloc too aggressively. */
+                        m_bidirows_alloc_len = MAX (m_bidirows_alloc_len + 1, m_bidirows_alloc_len * 1.25 /* 
whatever */);
                 }
                 _vte_debug_print (VTE_DEBUG_RINGVIEW, "Ringview: reallocate to %d bidirows\n",
                                                       m_bidirows_alloc_len);
@@ -197,7 +211,8 @@ void RingView::update()
         m_rows_len = 0;
         while (row < m_start + m_len + VTE_RINGVIEW_PARAGRAPH_LENGTH_MAX) {
                 if (m_rows_len == m_rows_alloc_len) {
-                        m_rows_alloc_len *= 1.25 /* whatever */;
+                        /* Don't realloc too aggressively. */
+                        m_rows_alloc_len = MAX (m_rows_alloc_len + 1, m_rows_alloc_len * 1.25 /* whatever 
*/);
                         _vte_debug_print (VTE_DEBUG_RINGVIEW, "Ringview: reallocate to %d rows\n",
                                                               m_rows_alloc_len);
                         m_rows = (VteRowData **) g_realloc (m_rows, sizeof (VteRowData *) * 
m_rows_alloc_len);
diff --git a/src/vte.cc b/src/vte.cc
index 56cb03d6..f105f268 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -9016,19 +9016,16 @@ Terminal::draw_cells_with_attributes(struct _vte_draw_text_request *items,
        g_free(cells);
 }
 
-
 void
 Terminal::ringview_update()
 {
+        auto first_row = first_displayed_row();
+        auto last_row = last_displayed_row();
+        if (cursor_might_be_displayed())
+                last_row = MAX(last_row, m_screen->cursor.row);
+
         m_ringview.set_ring (m_screen->row_data);
-        /* Due to possibly unaligned height and per-pixel scrolling, up to 2 more lines than the
-         * logical height can be partially visible.
-         * If a row is just underneath the current viewport, we still need to run BiDi on it
-         * because the top an outlined rectangle cursor shape peeks in into the viewport, and we need
-         * to know where the BiDi algorithm maps that cursor. However, +2 is still enough for this
-         * as long as the outline cursor is 1px thin. If we ever make it wider, we'll need +3.
-         */
-        m_ringview.set_rows ((long) m_screen->scroll_delta, m_row_count + 2);
+        m_ringview.set_rows (first_row, last_row - first_row + 1);
         m_ringview.set_width (m_column_count);
         m_ringview.update ();
 }
@@ -9227,6 +9224,9 @@ Terminal::draw_rows(VteScreen *screen_,
                          * the second (left) character with the desired presentational form.
                          * Detect if we're about to render this glyph, and shift by half a cell
                          * to the right. */
+                        // FIXME Get FriBidi devs document this behavior.
+                        // FIXME Check what Arabic monospace fonts do. Is there any where these
+                        // ligated glyphs are wide, thus we now break its positioning?
                         vteunistr c_shaped = bidirow->vis_get_shaped_char(vcol, c);
                         int xoff = 0;
                         if (G_UNLIKELY (c_shaped != c && lcol > 0 && vcol < column_count - 1)) {
@@ -9319,6 +9319,7 @@ Terminal::paint_area(GdkRectangle const* area)
          * to the bottom visible pixel, hence the - 1 + 1 magic. */
         row_stop = pixel_to_row(MIN(area->height + area->y,
                                     get_allocated_height() - m_padding.top - m_padding.bottom) - 1) + 1;
+       row_stop = MIN(row_stop, last_displayed_row() + 1);
        if (row_stop <= row) {
                return;
        }


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