void __guac_terminal_display_flush_clear()

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++;

        }
    }

}