AnalogTerm2: improve the smooth scrolling implementation.
authorMatthew Mondor <mmondor@pulsar-zone.net>
Tue, 25 Apr 2023 19:34:45 +0000 (19:34 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Tue, 25 Apr 2023 19:34:45 +0000 (19:34 +0000)
mmsoftware/analogterm2/TODO.txt
mmsoftware/analogterm2/src/draw.c
mmsoftware/analogterm2/src/screen.c
mmsoftware/analogterm2/src/screen.h

index de8c363..cd102ac 100644 (file)
@@ -35,7 +35,7 @@
   https://en.wikipedia.org/wiki/Box-drawing_character
 - Overwrite/clear selections before freeing them
 - ≣ † ☆ ツ ⌘›🍺∴ ( ͡° ͜ʖ ͡°)   ƒ   ︵  ₂   😈  θ  ƒ  ›  ʼ  ƒ ∂  ʻ  μ  ›  ∫   ◇ ♪
-  ► ə β ə ſ ρ ə ∴ ♪ 😱 † 😳 › ▛ ᵗ
+  ► ə β ə ſ ρ ə ∴ ♪ 😱 † 😳 › ▛ ᵗ *
 - Verify if dead key support is incomplete for ISO-8859-4 and ISO-8859-10.
   There were special characters that were unicode since the start but also
   could have punctuation.  And others that used two at a time...  It might
 - Smooth scrolling could theoretically work with scroll regions instead of
   only working when scrolling from the bottom of the screen.  The current
   implementation could also be improved and more configurable.  Notably, the
-  top line is not scrolled and an extra memory buffer is allocated for
-  simplicity.  Also look at tcflow(3).  Currently, for smooth scrolling to
-  work with screen(1)/tmux(1), the status bar must be disabled or configured
-  to be at the top.
+  top line is not scrolled.  Also look at tcflow(3).  Currently, for smooth
+  scrolling to work with screen(1)/tmux(1), the status bar must be disabled or
+  configured to be at the top.
   An early test used input flow control by temporarily stopping to read.  This
   was not kept, but it may be necessary in some circumstances to avoid sudden
-  jumps.  Was restored in a different way, may need improvement.
+  jumps.  Was restored in a different way, may need improvement.  It could
+  still be improved to more accurately detect when extra scrolling would
+  occur.  Long jump may also be considered.
 - Check termios(4) IMAXBEL and queue size, also reported by stty(1).
   This may allow to tweak interactive performance when a lot of application
   output happens.
index 6ba8517..7ba78d8 100644 (file)
@@ -298,13 +298,11 @@ draw_lines(state_t *st, screen_t *sc, int low, int high)
 
        /*
         * XXX
-        * Smooth scrolling version.  Instead of stopping at the required
-        * scanline, this implementation expects an extra line in bitmap
-        * memory that extends the visible window.  Not ideal but easy without
-        * affecting performance.  It also does not handle properly the top
-        * line that is to be discarded, which gets overwritten bottom-up
+        * Smooth scrolling version.  Currently does not handle properly the
+        * top line that is to be discarded, which gets overwritten bottom-up
         * rather than scrolled.  It is not very noticeable but still
-        * considered to be a bug.  It will be visible at low refresh rates.
+        * considered to be a bug of the implementation.  It is visible at low
+        * refresh rates.
         */
        sc->update_y = ((low * (FONT_HEIGHT + cfg_leading)) +
            st->smoothscroll_offset) * 2;
@@ -512,6 +510,13 @@ draw_lines(state_t *st, screen_t *sc, int low, int high)
                }
 
                /*
+                * Stop if we reach the bottom of the pixels memory, possible
+                * with a smooth scrolling offset.
+                */
+               if (scanptr2 >= sc->pixels_boundary)
+                       break;
+
+               /*
                 * Draw pixel or background.
                 * p serves as a boolean as well as an intensity level from 1
                 * to INTENSITY_MAX.  If 0/false, the background will be drawn.
index 04627ff..8b960c1 100644 (file)
@@ -145,23 +145,16 @@ screen_init(void)
        s->visual = s->vinfo.visual;
        depth = s->vinfo.depth;
 
-       /*
-        * XXX
-        * We allocate an extra line for use by the optional smooth scrolling
-        * feature, that exists in the underlaying ZPixmap although the X
-        * window size is kept smaller.  See draw.c for more related notes.
-        */
-
        /* Font rendered with 2x/1.5x software zoom */
        if (cfg_condensed)
                width = ((int)((cfg_text_width * FONT_WIDTH) * 1.5)) + 1;
        else
                width = ((cfg_text_width * FONT_WIDTH) * 2) + 1;
 #ifdef EXPAND_Y
-       height = ((int)(((cfg_text_height + 1) * (FONT_HEIGHT + cfg_leading))
-           * 2.5) + 1);
+       height = ((int)((cfg_text_height * (FONT_HEIGHT + cfg_leading)) * 2.5)
+           + 1);
 #else
-       height = ((cfg_text_height + 1) * (FONT_HEIGHT + cfg_leading)) * 2;
+       height = (cfg_text_height * (FONT_HEIGHT + cfg_leading)) * 2;
 #endif
 
        s->pixels_width = width;
@@ -171,9 +164,9 @@ screen_init(void)
        if ((s->pixels = malloc((width * height) * sizeof(uint32_t)))
            == NULL)
                goto err;
+       s->pixels_boundary = &s->pixels[width * height];
 
-       s->win = XCreateWindow(s->dpy, s->parentwin, 0, 22, width,
-           height - ((FONT_HEIGHT + cfg_leading) * 2), 0,
+       s->win = XCreateWindow(s->dpy, s->parentwin, 0, 22, width, height, 0,
            depth, InputOutput, s->visual,
            /*CWBackPixel | CWColormap | CWBorderPixel*/0, &s->attr);
 
@@ -205,6 +198,7 @@ screen_init(void)
                if (s->image->bytes_per_line == width * 4) {
                        free(s->pixels);
                        s->pixels = (uint32_t *)s->image->data;
+                       s->pixels_boundary = &s->pixels[width * height];
                        s->shm = true;
                } else
                        destroy_xshm_image(s->dpy, s->image, &s->shm_info);
index e5d2098..7c2bbfd 100644 (file)
@@ -37,7 +37,7 @@ struct screen_s {
 #endif
        bool                    shm;
        /* What we work with */
-       uint32_t                *pixels;
+       uint32_t                *pixels, *pixels_boundary;
        int                     pixels_width, pixels_height;
        int                     update_x, update_y, update_w, update_h;
        int                     fd;