Much faster drawing method (complete).
This commit is contained in:
parent
e5619531a6
commit
7b09948842
@ -93,6 +93,26 @@ struct ssh_guac_terminal {
|
|||||||
*/
|
*/
|
||||||
PangoFontDescription* font_desc;
|
PangoFontDescription* font_desc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Index of next glyph to create
|
||||||
|
*/
|
||||||
|
int next_glyph;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Index of locations for each glyph in the stroke and fill layers.
|
||||||
|
*/
|
||||||
|
int glyphs[256];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color of glyphs in copy buffer
|
||||||
|
*/
|
||||||
|
int glyph_foreground;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color of glyphs in copy buffer
|
||||||
|
*/
|
||||||
|
int glyph_background;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A single wide layer holding each glyph, with each glyph only
|
* A single wide layer holding each glyph, with each glyph only
|
||||||
* colored with foreground color (background remains transparent).
|
* colored with foreground color (background remains transparent).
|
||||||
@ -184,8 +204,10 @@ int ssh_guac_terminal_write(ssh_guac_terminal* term, const char* c, int size);
|
|||||||
|
|
||||||
int ssh_guac_terminal_redraw_cursor(ssh_guac_terminal* term);
|
int ssh_guac_terminal_redraw_cursor(ssh_guac_terminal* term);
|
||||||
|
|
||||||
int ssh_guac_terminal_set(ssh_guac_terminal* term, int row, int col,
|
int ssh_guac_terminal_set_colors(ssh_guac_terminal* term,
|
||||||
char c, int foreground, int background);
|
int foreground, int background);
|
||||||
|
|
||||||
|
int ssh_guac_terminal_set(ssh_guac_terminal* term, int row, int col, char c);
|
||||||
|
|
||||||
int ssh_guac_terminal_copy(ssh_guac_terminal* term,
|
int ssh_guac_terminal_copy(ssh_guac_terminal* term,
|
||||||
int src_row, int src_col, int rows, int cols,
|
int src_row, int src_col, int rows, int cols,
|
||||||
|
@ -85,12 +85,16 @@ ssh_guac_terminal* ssh_guac_terminal_create(guac_client* client) {
|
|||||||
ssh_guac_terminal* term = malloc(sizeof(ssh_guac_terminal));
|
ssh_guac_terminal* term = malloc(sizeof(ssh_guac_terminal));
|
||||||
term->client = client;
|
term->client = client;
|
||||||
|
|
||||||
term->foreground = term->default_foreground = 7; /* White */
|
term->glyph_foreground = term->foreground = term->default_foreground = 7; /* White */
|
||||||
term->background = term->default_background = 0; /* Black */
|
term->glyph_background = term->background = term->default_background = 0; /* Black */
|
||||||
term->reverse = 0; /* Normal video */
|
term->reverse = 0; /* Normal video */
|
||||||
term->bold = 0; /* Normal intensity */
|
term->bold = 0; /* Normal intensity */
|
||||||
term->underscore = 0; /* No underline */
|
term->underscore = 0; /* No underline */
|
||||||
|
|
||||||
|
memset(term->glyphs, 0, sizeof(term->glyphs));
|
||||||
|
term->glyph_stroke = guac_client_alloc_buffer(client);
|
||||||
|
term->filled_glyphs = guac_client_alloc_buffer(client);
|
||||||
|
|
||||||
term->cursor_row = 0;
|
term->cursor_row = 0;
|
||||||
term->cursor_col = 0;
|
term->cursor_col = 0;
|
||||||
term->cursor_layer = guac_client_alloc_layer(client, 1);
|
term->cursor_layer = guac_client_alloc_layer(client, 1);
|
||||||
@ -165,14 +169,18 @@ void ssh_guac_terminal_free(ssh_guac_terminal* term) {
|
|||||||
/* STUB */
|
/* STUB */
|
||||||
}
|
}
|
||||||
|
|
||||||
guac_layer* __ssh_guac_terminal_get_glyph(ssh_guac_terminal* term, char c) {
|
int __ssh_guac_terminal_get_glyph(ssh_guac_terminal* term, char c) {
|
||||||
|
|
||||||
GUACIO* io = term->client->io;
|
GUACIO* io = term->client->io;
|
||||||
guac_layer* glyph;
|
int location;
|
||||||
|
|
||||||
/* Use default foreground color */
|
/* Use foreground color */
|
||||||
const ssh_guac_terminal_color* color =
|
const ssh_guac_terminal_color* color =
|
||||||
&ssh_guac_terminal_palette[term->default_foreground];
|
&ssh_guac_terminal_palette[term->glyph_foreground];
|
||||||
|
|
||||||
|
/* Use background color */
|
||||||
|
const ssh_guac_terminal_color* background =
|
||||||
|
&ssh_guac_terminal_palette[term->glyph_background];
|
||||||
|
|
||||||
cairo_surface_t* surface;
|
cairo_surface_t* surface;
|
||||||
cairo_t* cairo;
|
cairo_t* cairo;
|
||||||
@ -181,7 +189,9 @@ guac_layer* __ssh_guac_terminal_get_glyph(ssh_guac_terminal* term, char c) {
|
|||||||
|
|
||||||
/* Return glyph if exists */
|
/* Return glyph if exists */
|
||||||
if (term->glyphs[(int) c])
|
if (term->glyphs[(int) c])
|
||||||
return term->glyphs[(int) c];
|
return term->glyphs[(int) c] - 1;
|
||||||
|
|
||||||
|
location = term->next_glyph++;
|
||||||
|
|
||||||
/* Otherwise, draw glyph */
|
/* Otherwise, draw glyph */
|
||||||
surface = cairo_image_surface_create(
|
surface = cairo_image_surface_create(
|
||||||
@ -208,16 +218,27 @@ guac_layer* __ssh_guac_terminal_get_glyph(ssh_guac_terminal* term, char c) {
|
|||||||
g_object_unref(layout);
|
g_object_unref(layout);
|
||||||
cairo_destroy(cairo);
|
cairo_destroy(cairo);
|
||||||
|
|
||||||
/* Send glyph and save */
|
/* Send glyph and update filled flyphs */
|
||||||
glyph = guac_client_alloc_buffer(term->client);
|
guac_send_png(io, GUAC_COMP_OVER, term->glyph_stroke, location * term->char_width, 0, surface);
|
||||||
guac_send_png(io, GUAC_COMP_OVER, glyph, 0, 0, surface);
|
|
||||||
term->glyphs[(int) c] = glyph;
|
guac_send_rect(io, GUAC_COMP_SRC, term->filled_glyphs,
|
||||||
|
location * term->char_width, 0,
|
||||||
|
term->char_width, term->char_height,
|
||||||
|
background->red,
|
||||||
|
background->green,
|
||||||
|
background->blue,
|
||||||
|
0xFF);
|
||||||
|
|
||||||
|
guac_send_copy(io, term->glyph_stroke,
|
||||||
|
location * term->char_width, 0, term->char_width, term->char_height,
|
||||||
|
GUAC_COMP_OVER, term->filled_glyphs, location * term->char_width, 0);
|
||||||
|
|
||||||
|
term->glyphs[(int) c] = location+1;
|
||||||
|
|
||||||
guac_flush(io);
|
|
||||||
cairo_surface_destroy(surface);
|
cairo_surface_destroy(surface);
|
||||||
|
|
||||||
/* Return glyph */
|
/* Return glyph */
|
||||||
return glyph;
|
return location;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,24 +269,17 @@ int ssh_guac_terminal_redraw_cursor(ssh_guac_terminal* term) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssh_guac_terminal_set(ssh_guac_terminal* term, int row, int col,
|
int ssh_guac_terminal_set_colors(ssh_guac_terminal* term,
|
||||||
char c, int foreground, int background) {
|
int foreground, int background) {
|
||||||
|
|
||||||
GUACIO* io = term->client->io;
|
GUACIO* io = term->client->io;
|
||||||
guac_layer* glyph = __ssh_guac_terminal_get_glyph(term, c);
|
|
||||||
const ssh_guac_terminal_color* background_color;
|
const ssh_guac_terminal_color* background_color;
|
||||||
|
|
||||||
/* Get background color */
|
/* Get background color */
|
||||||
background_color = &ssh_guac_terminal_palette[background];
|
background_color = &ssh_guac_terminal_palette[background];
|
||||||
|
|
||||||
guac_send_copy(io,
|
/* If foreground different from current, colorize */
|
||||||
glyph, 0, 0, term->char_width, term->char_height,
|
if (foreground != term->glyph_foreground) {
|
||||||
GUAC_COMP_SRC, GUAC_DEFAULT_LAYER,
|
|
||||||
term->char_width * col,
|
|
||||||
term->char_height * row);
|
|
||||||
|
|
||||||
/* If foreground different from default, colorize */
|
|
||||||
if (foreground != term->default_foreground) {
|
|
||||||
|
|
||||||
/* Get color */
|
/* Get color */
|
||||||
const ssh_guac_terminal_color* color =
|
const ssh_guac_terminal_color* color =
|
||||||
@ -273,10 +287,10 @@ int ssh_guac_terminal_set(ssh_guac_terminal* term, int row, int col,
|
|||||||
|
|
||||||
/* Colorize letter */
|
/* Colorize letter */
|
||||||
guac_send_rect(io,
|
guac_send_rect(io,
|
||||||
GUAC_COMP_ATOP, GUAC_DEFAULT_LAYER,
|
GUAC_COMP_ATOP, term->glyph_stroke,
|
||||||
|
|
||||||
term->char_width * col, term->char_height * row,
|
0, 0,
|
||||||
term->char_width, term->char_height,
|
term->char_width * term->next_glyph, term->char_height,
|
||||||
|
|
||||||
color->red,
|
color->red,
|
||||||
color->green,
|
color->green,
|
||||||
@ -285,22 +299,53 @@ int ssh_guac_terminal_set(ssh_guac_terminal* term, int row, int col,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set background */
|
/* If any color change at all, update filled */
|
||||||
/*guac_send_rect(io,
|
if (foreground != term->glyph_foreground || background != term->glyph_background) {
|
||||||
GUAC_COMP_ROVER, GUAC_DEFAULT_LAYER,
|
|
||||||
|
|
||||||
term->char_width * col, term->char_height * row,
|
/* Set background */
|
||||||
term->char_width, term->char_height,
|
guac_send_rect(io,
|
||||||
|
GUAC_COMP_SRC, term->filled_glyphs,
|
||||||
|
|
||||||
background_color->red,
|
0, 0,
|
||||||
background_color->green,
|
term->char_width * term->next_glyph, term->char_height,
|
||||||
background_color->blue,
|
|
||||||
255);*/
|
background_color->red,
|
||||||
|
background_color->green,
|
||||||
|
background_color->blue,
|
||||||
|
255);
|
||||||
|
|
||||||
|
/* Copy stroke */
|
||||||
|
guac_send_copy(io, term->glyph_stroke,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
term->char_width * term->next_glyph, term->char_height,
|
||||||
|
|
||||||
|
GUAC_COMP_OVER, term->filled_glyphs,
|
||||||
|
0, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
term->glyph_foreground = foreground;
|
||||||
|
term->glyph_background = background;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ssh_guac_terminal_set(ssh_guac_terminal* term, int row, int col, char c) {
|
||||||
|
|
||||||
|
GUACIO* io = term->client->io;
|
||||||
|
int location = __ssh_guac_terminal_get_glyph(term, c);
|
||||||
|
|
||||||
|
return guac_send_copy(io,
|
||||||
|
term->filled_glyphs,
|
||||||
|
location * term->char_width, 0, term->char_width, term->char_height,
|
||||||
|
GUAC_COMP_SRC, GUAC_DEFAULT_LAYER,
|
||||||
|
term->char_width * col,
|
||||||
|
term->char_height * row);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int ssh_guac_terminal_write(ssh_guac_terminal* term, const char* c, int size) {
|
int ssh_guac_terminal_write(ssh_guac_terminal* term, const char* c, int size) {
|
||||||
|
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
|
@ -112,10 +112,13 @@ int ssh_guac_terminal_echo(ssh_guac_terminal* term, char c) {
|
|||||||
if (term->bold && foreground <= 7)
|
if (term->bold && foreground <= 7)
|
||||||
foreground += 8;
|
foreground += 8;
|
||||||
|
|
||||||
|
ssh_guac_terminal_set_colors(term,
|
||||||
|
foreground, background);
|
||||||
|
|
||||||
ssh_guac_terminal_set(term,
|
ssh_guac_terminal_set(term,
|
||||||
term->cursor_row,
|
term->cursor_row,
|
||||||
term->cursor_col,
|
term->cursor_col,
|
||||||
c, foreground, background);
|
c);
|
||||||
|
|
||||||
/* Advance cursor */
|
/* Advance cursor */
|
||||||
term->cursor_col++;
|
term->cursor_col++;
|
||||||
|
Loading…
Reference in New Issue
Block a user