in src/terminal/display.c [691:823]
void __guac_terminal_display_flush_clear(guac_terminal_display* display) {
guac_terminal_operation* current = display->operations;
int row, col;
/* For each operation */
for (row=0; row<display->height; row++) {
for (col=0; col<display->width; col++) {
/* If operation is a clear operation (set to space) */
if (current->type == GUAC_CHAR_SET &&
!guac_terminal_has_glyph(current->character.value)) {
/* The determined bounds of the rectangle of contiguous
* operations */
int detected_right = -1;
int detected_bottom = row;
/* The current row or column within a rectangle */
int rect_row, rect_col;
/* The dimensions of the rectangle as determined */
int rect_width, rect_height;
/* Color of the rectangle to draw */
guac_terminal_color color;
if (current->character.attributes.reverse != current->character.attributes.cursor)
color = current->character.attributes.foreground;
else
color = current->character.attributes.background;
/* Rely only on palette index if defined */
guac_terminal_display_lookup_color(display,
color.palette_index, &color);
/* Current row within a subrect */
guac_terminal_operation* rect_current_row;
/* Determine bounds of rectangle */
rect_current_row = current;
for (rect_row=row; rect_row<display->height; rect_row++) {
guac_terminal_operation* rect_current = rect_current_row;
/* Find width */
for (rect_col=col; rect_col<display->width; rect_col++) {
const guac_terminal_color* joining_color;
if (rect_current->character.attributes.reverse != rect_current->character.attributes.cursor)
joining_color = &rect_current->character.attributes.foreground;
else
joining_color = &rect_current->character.attributes.background;
/* If not identical operation, stop */
if (rect_current->type != GUAC_CHAR_SET
|| guac_terminal_has_glyph(rect_current->character.value)
|| guac_terminal_colorcmp(joining_color, &color) != 0)
break;
/* Next column */
rect_current++;
}
/* If too small, cannot append row */
if (rect_col-1 < detected_right)
break;
/* As row has been accepted, update rect_row of rect */
detected_bottom = rect_row;
/* For now, only set rect_col bound if uninitialized */
if (detected_right == -1)
detected_right = rect_col - 1;
/* Next row */
rect_current_row += display->width;
}
/* Calculate dimensions */
rect_width = detected_right - col + 1;
rect_height = detected_bottom - row + 1;
/* Mark rect as NOP (as it has been handled) */
rect_current_row = current;
for (rect_row=0; rect_row<rect_height; rect_row++) {
guac_terminal_operation* rect_current = rect_current_row;
for (rect_col=0; rect_col<rect_width; rect_col++) {
const guac_terminal_color* joining_color;
if (rect_current->character.attributes.reverse != rect_current->character.attributes.cursor)
joining_color = &rect_current->character.attributes.foreground;
else
joining_color = &rect_current->character.attributes.background;
/* Mark clear operations as NOP */
if (rect_current->type == GUAC_CHAR_SET
&& !guac_terminal_has_glyph(rect_current->character.value)
&& guac_terminal_colorcmp(joining_color, &color) == 0)
rect_current->type = GUAC_CHAR_NOP;
/* Next column */
rect_current++;
}
/* Next row */
rect_current_row += display->width;
}
/* Send rect */
guac_common_surface_set(
display->display_surface,
col * display->char_width,
row * display->char_height,
rect_width * display->char_width,
rect_height * display->char_height,
color.red, color.green, color.blue,
0xFF);
} /* end if clear operation */
/* Next operation */
current++;
}
}
}