@@ -149,9 +149,13 @@ static void emit_ch(struct Clayterm *ct, int x, int y, uint32_t ch) {
149149 buf_char (& ct -> out , ch );
150150}
151151
152- /* ── Double-buffer diff (from termbox2 tb_present) ────────────────── */
153-
154- static void present (struct Clayterm * ct ) {
152+ /**
153+ * Diff back buffer against front buffer and emit only changed cells
154+ * using absolute CUP positioning (\x1b[row;colH). Unchanged cells are
155+ * skipped, making this efficient for subsequent frames where most of
156+ * the screen is static. Derived from termbox2 tb_present.
157+ */
158+ static void present_cups (struct Clayterm * ct ) {
155159 ct -> lastx = -1 ;
156160 ct -> lasty = -1 ;
157161
@@ -191,6 +195,13 @@ static void present(struct Clayterm *ct) {
191195 }
192196}
193197
198+ /**
199+ * Emit back buffer as newline-separated rows without CUP positioning.
200+ * Every cell is written (no diffing), and the front buffer is primed
201+ * so that a subsequent present() call can diff efficiently. This is
202+ * used for inline "region" rendering where the caller manages cursor
203+ * positioning externally and the output must work in pipes.
204+ */
194205static void present_lines (struct Clayterm * ct ) {
195206 for (int y = 0 ; y < ct -> h ; y ++ ) {
196207 if (y > 0 )
@@ -416,8 +427,11 @@ struct Clayterm *init(void *mem, int w, int h, int row) {
416427 .lasty = -1 ,
417428 };
418429
419- cells_clear (ct -> front , w , h );
420- cells_clear (ct -> back , w , h );
430+ // initialize back buffer with spaces and default fg/bg
431+ cells_fill (ct -> back , w , h , ' ' , ATTR_DEFAULT , ATTR_DEFAULT );
432+
433+ // initialize front buffer with zeros. Every cell will be
434+ cells_fill (ct -> front , w , h , 0 , 0 , 0 );
421435 return ct ;
422436}
423437
@@ -551,7 +565,7 @@ void reduce(struct Clayterm *ct, uint32_t *buf, int len, int mode) {
551565 ct -> lastfg = ct -> lastbg = 0xffffffff ;
552566 ct -> lastx = ct -> lasty = -1 ;
553567
554- cells_clear (ct -> back , ct -> w , ct -> h );
568+ cells_fill (ct -> back , ct -> w , ct -> h , ' ' , ATTR_DEFAULT , ATTR_DEFAULT );
555569
556570 /* walk Clay render commands into back buffer */
557571 for (int32_t j = 0 ; j < cmds .length ; j ++ ) {
@@ -590,7 +604,7 @@ void reduce(struct Clayterm *ct, uint32_t *buf, int len, int mode) {
590604 if (mode == 1 ) {
591605 present_lines (ct );
592606 } else {
593- present (ct );
607+ present_cups (ct );
594608 }
595609}
596610
0 commit comments