1 static void k8t_DrawLine (K8Term
*term
, int x1
, int x2
, int scry
, int lineno
, int dontcopy
) {
2 //fprintf(stderr, "%d: k8t_DrawLine: x1=%d; x2=%d; scry=%d; row:%d; lineno=%d\n", mclock_ticks(), x1, x2, scry, term->row, lineno);
3 if (term
== NULL
|| scry
< 0 || scry
>= term
->row
) return;
4 if (scry
== term
->row
-1 && term
->cmdline
.cmdMode
!= K8T_CMDMODE_NONE
) { xdrawcmdline(term
, &term
->cmdline
, scry
); return; }
5 if (lineno
< 0 || lineno
>= term
->linecount
) {
6 k8t_DrawClear(term
, 0, scry
, term
->col
-1, scry
);
7 k8t_DrawCopy(term
, 0, scry
, term
->col
, 1);
12 K8TLine l
= term
->line
[lineno
];
14 if (lineno
< term
->row
&& term
->topline
== 0) {
15 if (!term
->dirty
[lineno
]) return;
17 // fix 'dirty' flag for line
18 if (term
->dirty
[lineno
]&0x02) {
19 // mark full line as dirty
22 term
->dirty
[lineno
] = 0;
24 term
->dirty
[lineno
] = 0;
25 if (x1
> 0) for (int x
= 0; x
< x1
; ++x
) if (l
[x
].state
&K8T_GLYPH_DIRTY
) { term
->dirty
[lineno
] = 1; break; }
26 if (!term
->dirty
[lineno
] && x2
< term
->col
) for (int x
= x2
; x
< term
->col
; ++x
) if (l
[x
].state
&K8T_GLYPH_DIRTY
) { term
->dirty
[lineno
] = 1; break; }
29 for (stx
= x1
; stx
< x2
; ++stx
) if (l
[stx
].state
&K8T_GLYPH_DIRTY
) break;
30 for (ex
= x2
; ex
> stx
; --ex
) if (l
[ex
-1].state
&K8T_GLYPH_DIRTY
) break;
31 if (stx
>= x2
|| ex
<= stx
) return; // nothing to do
34 // 'dontcopy' means that the whole screen is dirty
37 term
->dirty
[lineno
] = 0;
40 //if (lineno < term->row) term->dirty[lineno] = 0;
46 if (term
->sel
.bx
!= -1 && k8t_isSelected(term
, stx
, lineno
)) base
.attr
^= K8T_ATTR_REVERSE
;
49 //k8t_DrawClear(term, stx, scry, ex-1, scry); //k8: actually, we don't need this for good monospace fonts, so...
50 for (int x
= stx
; x
< ex
; ++x
) {
52 l
[x
].state
&= ~K8T_GLYPH_DIRTY
; //!
53 if (term
->sel
.bx
!= -1 && k8t_isSelected(term
, x
, lineno
)) new.attr
^= K8T_ATTR_REVERSE
;
54 if (ib
> 0 && (K8T_ATTRCMP(base
, new) || ib
>= DRAW_BUF_SIZ
-UTF_SIZ
)) {
55 // flush k8t_Draw buffer
56 k8t_DrawString(term
, term
->drawbuf
, &base
, ox
, scry
, ic
, ib
);
59 if (ib
== 0) { ox
= x
; base
= new; }
60 sl
= k8t_UTF8Size(new.c
);
61 memcpy(term
->drawbuf
+ib
, new.c
, sl
);
65 if (ib
> 0) k8t_DrawString(term
, term
->drawbuf
, &base
, ox
, scry
, ic
, ib
);
66 //k8t_DrawCopy(term, 0, scry, term->col, 1);
67 //if (term->c.y == lineno && term->c.x >= stx && term->c.x < ex) k8t_DrawCursor();
68 if (!dontcopy
) k8t_DrawCopy(term
, stx
, scry
, ex
-stx
, 1);
73 static void k8t_DrawRegion (K8Term
*term
, int x1
, int y1
, int x2
, int y2
, int forced
) {
77 term
->justSwapped
= 0;
79 if (!forced
&& (xw
.state
&K8T_WIN_VISIBLE
) == 0) {
81 lastDrawTime
= term
->lastDrawTime
= 1;
86 if (y1
== 0 && y2
== term
->row
) {
88 for (int y
= 0; y
< y2
; ++y
) if (!(term
->dirty
[y
]&0x02)) { fulldirty
= 0; break; }
91 if (term
->topline
< term
->row
) {
92 for (int y
= y1
; y
< y2
; ++y
) k8t_DrawLine(term
, x1
, x2
, y
+term
->topline
, y
, fulldirty
);
94 if (term
->topline
> 0) {
95 int scry
= K8T_MIN(term
->topline
, term
->row
), y
= term
->row
;
98 if (term
->topline
>= term
->row
) y
+= term
->topline
-term
->row
;
100 k8t_DrawLine(term
, 0, term
->col
, scry
, y
, 0);
104 if (fulldirty
) k8t_DrawCopy(term
, 0, 0, term
->col
, term
->row
);
105 k8t_DrawCursor(term
);
108 lastDrawTime
= term
->lastDrawTime
= mclock_ticks();
109 term
->wantRedraw
= 0;
114 static void k8t_Draw (K8Term
*term
, int forced
) {
116 //fprintf(stderr, "k8t_Draw(%d) (%d)\n", forced, mclock_ticks());
117 k8t_DrawRegion(term
, 0, 0, term
->col
, term
->row
, forced
);