X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=terminal.c;h=960b2129e688eefb419cd88a7dcfcab175373a6b;hb=f4246872c4d904470ec7965a34ec08d8f5077609;hp=54f86f8630a80cee77305d8bf99d755f34d43fb9;hpb=a2e01a5604abc80d49e433c7faa91fab052ce755;p=PuTTY.git diff --git a/terminal.c b/terminal.c index 54f86f86..960b2129 100644 --- a/terminal.c +++ b/terminal.c @@ -2882,6 +2882,7 @@ static void term_out(Terminal *term) else if (term->curs.y < term->rows - 1) term->curs.y++; term->curs.x = 0; + cline = scrlineptr(term->curs.y); /* Now we must check_boundary again, of course. */ check_boundary(term, term->curs.x, term->curs.y); check_boundary(term, term->curs.x+2, term->curs.y); @@ -4542,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: @@ -4647,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) { @@ -4660,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; @@ -4744,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; @@ -4907,6 +4943,7 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise) unlineptr(ldata); } + sfree(newline); sfree(ch); } @@ -4919,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); } @@ -4939,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) {