Divide the do_paint() loop into several subloops. The activity of
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 17 Dec 2004 11:37:16 +0000 (11:37 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 17 Dec 2004 11:37:16 +0000 (11:37 +0000)
going through the line and working out which bits need to be redrawn
is now in a separate loop from the subsequent activity of actually
going through and doing the redraws. This _should_ enable me to
tinker with the which-bits-to-redraw data in between the two, thus
fixing `font-overflow'. However, I thought it would be sensible to
break the work up into two commits so we can track bugs in the
restructuring separately from bugs introduced by the new feature.

Also added a couple more terminal test files.

git-svn-id: svn://svn.tartarus.org/sgt/putty@5001 cda61777-01e9-0310-a592-d414129be87e

terminal.c
testdata/lattrs.txt [new file with mode: 0644]
testdata/vt100.txt [new file with mode: 0644]

index b167f3b..960b212 100644 (file)
@@ -4543,12 +4543,15 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
 #ifdef OPTIMISE_SCROLL
     struct scrollregion *sr;
 #endif /* OPTIMISE_SCROLL */
+    termchar *newline;
 
     cursor_background = term->basic_erase_char;
 
     chlen = 1024;
     ch = snewn(chlen, wchar_t);
 
+    newline = snewn(term->cols, termchar);
+
     rv = (!term->rvideo ^ !term->in_vbell ? ATTR_REVERSE : 0);
 
     /* Depends on:
@@ -4648,10 +4651,6 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
        scrpos.y = i + term->disptop;
        ldata = lineptr(scrpos.y);
 
-       dirty_run = dirty_line = (ldata->lattr !=
-                                 term->disptext[i]->lattr);
-       term->disptext[i]->lattr = ldata->lattr;
-
        /* Do Arabic shaping and bidi. */
        lchars = term_bidi_line(term, ldata, i);
        if (lchars) {
@@ -4661,10 +4660,13 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
            backward = NULL;
        }
 
+       /*
+        * First loop: work along the line deciding what we want
+        * each character cell to look like.
+        */
        for (j = 0; j < term->cols; j++) {
            unsigned long tattr, tchar;
            termchar *d = lchars + j;
-           int break_run, do_copy;
            scrpos.x = backward ? backward[j] : j;
 
            tchar = d->chr;
@@ -4745,6 +4747,39 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
                term->dispcursy = i;
            }
 
+           /* FULL-TERMCHAR */
+           newline[j].attr = tattr;
+           newline[j].chr = tchar;
+           /* Combining characters are still read from lchars */
+           newline[j].cc_next = 0;
+       }
+
+       /*
+        * Now loop over the line again, noting where things have
+        * changed.
+        */
+       for (j = 0; j < term->cols; j++) {
+           if (term->disptext[i]->chars[j].chr != newline[j].chr ||
+               term->disptext[i]->chars[j].attr != newline[j].attr) {
+               term->disptext[i]->chars[j].attr |= ATTR_INVALID;
+           }
+       }
+
+       /*
+        * Finally, loop once more and actually do the drawing.
+        */
+       dirty_run = dirty_line = (ldata->lattr !=
+                                 term->disptext[i]->lattr);
+       term->disptext[i]->lattr = ldata->lattr;
+
+       for (j = 0; j < term->cols; j++) {
+           unsigned long tattr, tchar;
+           int break_run, do_copy;
+           termchar *d = lchars + j;
+
+           tattr = newline[j].attr;
+           tchar = newline[j].chr;
+
            if ((term->disptext[i]->chars[j].attr ^ tattr) & ATTR_WIDE)
                dirty_line = TRUE;
 
@@ -4908,6 +4943,7 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
        unlineptr(ldata);
     }
 
+    sfree(newline);
     sfree(ch);
 }
 
@@ -4920,7 +4956,7 @@ void term_invalidate(Terminal *term)
 
     for (i = 0; i < term->rows; i++)
        for (j = 0; j < term->cols; j++)
-           term->disptext[i]->chars[j].attr = ATTR_INVALID;
+           term->disptext[i]->chars[j].attr |= ATTR_INVALID;
 
     term_schedule_update(term);
 }
@@ -4940,10 +4976,10 @@ void term_paint(Terminal *term, Context ctx,
     for (i = top; i <= bottom && i < term->rows; i++) {
        if ((term->disptext[i]->lattr & LATTR_MODE) == LATTR_NORM)
            for (j = left; j <= right && j < term->cols; j++)
-               term->disptext[i]->chars[j].attr = ATTR_INVALID;
+               term->disptext[i]->chars[j].attr |= ATTR_INVALID;
        else
            for (j = left / 2; j <= right / 2 + 1 && j < term->cols; j++)
-               term->disptext[i]->chars[j].attr = ATTR_INVALID;
+               term->disptext[i]->chars[j].attr |= ATTR_INVALID;
     }
 
     if (immediately) {
diff --git a/testdata/lattrs.txt b/testdata/lattrs.txt
new file mode 100644 (file)
index 0000000..5cafc95
--- /dev/null
@@ -0,0 +1,6 @@
+Test of line attributes:
+
+\e#3Double-height top
+\e#4Double-height bottom
+\e#5Normal text (#5)
+\e#6Double-width only
diff --git a/testdata/vt100.txt b/testdata/vt100.txt
new file mode 100644 (file)
index 0000000..b206770
--- /dev/null
@@ -0,0 +1,12 @@
+VT100 line drawing characters, actually using the VT100 escapes
+\e(B\e)0\ eooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\ f
+
+\ elqqqqqqqqqqpoopqrssrqqqqqqqqqqwqqqqqqqqqqpoopqrssrqqqqqqqqqqk\ f
+\ ex\ f                             \ ex\ f                             \ ex\ f
+\ ex\ f      ooh, swirly!           \ ex\ f       top right corner      \ ex\ f
+\ ex\ f                             \ ex\ f                             \ ex\ f
+\ etqqqqqqqqqqpoopqrssrqqqqqqqqqqnqqqqqqqqqqpoopqrssrqqqqqqqqqqu\ f
+\ ex\ f                             \ ex\ f                             \ ex\ f
+\ ex\ f     stuff down here         \ ex\ f       is quite inane        \ ex\ f
+\ ex\ f                             \ ex\ f                             \ ex\ f
+\ emqqqqqqqqqqpoopqrssrqqqqqqqqqqvqqqqqqqqqqpoopqrssrqqqqqqqqqqj\ f