mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-02 09:01:39 -05:00
Batch up drawing glyphs
This commit is contained in:
parent
7ae6b1a27d
commit
1d3e93922d
1 changed files with 81 additions and 24 deletions
|
|
@ -461,16 +461,19 @@ terminal_get_attr_row(struct terminal *terminal, int row)
|
||||||
return &terminal->data_attr[index * terminal->width];
|
return &terminal->data_attr[index * terminal->width];
|
||||||
}
|
}
|
||||||
|
|
||||||
struct decoded_attr {
|
union decoded_attr {
|
||||||
int foreground;
|
struct {
|
||||||
int background;
|
unsigned char foreground;
|
||||||
int bold;
|
unsigned char background;
|
||||||
int underline;
|
unsigned char bold;
|
||||||
|
unsigned char underline;
|
||||||
|
};
|
||||||
|
uint32_t key;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_decode_attr(struct terminal *terminal, int row, int col,
|
terminal_decode_attr(struct terminal *terminal, int row, int col,
|
||||||
struct decoded_attr *decoded)
|
union decoded_attr *decoded)
|
||||||
{
|
{
|
||||||
struct attr attr;
|
struct attr attr;
|
||||||
int foreground, background, tmp;
|
int foreground, background, tmp;
|
||||||
|
|
@ -744,6 +747,69 @@ terminal_set_color(struct terminal *terminal, cairo_t *cr, int index)
|
||||||
terminal->color_table[index].a);
|
terminal->color_table[index].a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct glyph_run {
|
||||||
|
struct terminal *terminal;
|
||||||
|
cairo_t *cr;
|
||||||
|
int count;
|
||||||
|
union decoded_attr attr;
|
||||||
|
cairo_glyph_t glyphs[256], *g;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
glyph_run_init(struct glyph_run *run, struct terminal *terminal, cairo_t *cr)
|
||||||
|
{
|
||||||
|
run->terminal = terminal;
|
||||||
|
run->cr = cr;
|
||||||
|
run->g = run->glyphs;
|
||||||
|
run->count = 0;
|
||||||
|
run->attr.key = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
glyph_run_flush(struct glyph_run *run, union decoded_attr attr)
|
||||||
|
{
|
||||||
|
cairo_scaled_font_t *font;
|
||||||
|
|
||||||
|
if (run->count == 0)
|
||||||
|
run->attr = attr;
|
||||||
|
if (run->count > ARRAY_LENGTH(run->glyphs) - 10 ||
|
||||||
|
(attr.key != run->attr.key)) {
|
||||||
|
if (run->attr.bold)
|
||||||
|
font = run->terminal->font_bold;
|
||||||
|
else
|
||||||
|
font = run->terminal->font_normal;
|
||||||
|
cairo_set_scaled_font(run->cr, font);
|
||||||
|
terminal_set_color(run->terminal, run->cr,
|
||||||
|
run->attr.foreground);
|
||||||
|
|
||||||
|
cairo_show_glyphs (run->cr, run->glyphs, run->count);
|
||||||
|
run->g = run->glyphs;
|
||||||
|
run->count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
glyph_run_add(struct glyph_run *run, int x, int y, union utf8_char *c)
|
||||||
|
{
|
||||||
|
int num_glyphs;
|
||||||
|
cairo_scaled_font_t *font;
|
||||||
|
|
||||||
|
num_glyphs = ARRAY_LENGTH(run->glyphs) - run->count;
|
||||||
|
|
||||||
|
if (run->attr.bold)
|
||||||
|
font = run->terminal->font_bold;
|
||||||
|
else
|
||||||
|
font = run->terminal->font_normal;
|
||||||
|
|
||||||
|
cairo_move_to(run->cr, x, y);
|
||||||
|
cairo_scaled_font_text_to_glyphs (font, x, y,
|
||||||
|
(char *) c->byte, 4,
|
||||||
|
&run->g, &num_glyphs,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
run->g += num_glyphs;
|
||||||
|
run->count += num_glyphs;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_draw_contents(struct terminal *terminal)
|
terminal_draw_contents(struct terminal *terminal)
|
||||||
{
|
{
|
||||||
|
|
@ -753,13 +819,11 @@ terminal_draw_contents(struct terminal *terminal)
|
||||||
int top_margin, side_margin;
|
int top_margin, side_margin;
|
||||||
int row, col;
|
int row, col;
|
||||||
union utf8_char *p_row;
|
union utf8_char *p_row;
|
||||||
struct decoded_attr attr;
|
union decoded_attr attr;
|
||||||
int text_x, text_y;
|
int text_x, text_y;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
double d;
|
double d;
|
||||||
int num_glyphs;
|
struct glyph_run run;
|
||||||
cairo_scaled_font_t *font;
|
|
||||||
cairo_glyph_t glyphs[256], *g;
|
|
||||||
|
|
||||||
window_get_child_allocation(terminal->window, &allocation);
|
window_get_child_allocation(terminal->window, &allocation);
|
||||||
|
|
||||||
|
|
@ -801,18 +865,15 @@ terminal_draw_contents(struct terminal *terminal)
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
||||||
|
|
||||||
/* paint the foreground */
|
/* paint the foreground */
|
||||||
|
glyph_run_init(&run, terminal, cr);
|
||||||
for (row = 0; row < terminal->height; row++) {
|
for (row = 0; row < terminal->height; row++) {
|
||||||
p_row = terminal_get_row(terminal, row);
|
p_row = terminal_get_row(terminal, row);
|
||||||
for (col = 0; col < terminal->width; col++) {
|
for (col = 0; col < terminal->width; col++) {
|
||||||
/* get the attributes for this character cell */
|
/* get the attributes for this character cell */
|
||||||
terminal_decode_attr(terminal, row, col, &attr);
|
terminal_decode_attr(terminal, row, col, &attr);
|
||||||
|
|
||||||
if (attr.bold)
|
glyph_run_flush(&run, attr);
|
||||||
font = terminal->font_bold;
|
|
||||||
else
|
|
||||||
font = terminal->font_normal;
|
|
||||||
cairo_set_scaled_font(cr, font);
|
|
||||||
terminal_set_color(terminal, cr, attr.foreground);
|
|
||||||
text_x = side_margin + col * extents.max_x_advance;
|
text_x = side_margin + col * extents.max_x_advance;
|
||||||
text_y = top_margin + extents.ascent + row * extents.height;
|
text_y = top_margin + extents.ascent + row * extents.height;
|
||||||
if (attr.underline) {
|
if (attr.underline) {
|
||||||
|
|
@ -820,18 +881,14 @@ terminal_draw_contents(struct terminal *terminal)
|
||||||
cairo_line_to(cr, text_x + extents.max_x_advance, (double) text_y + 1.5);
|
cairo_line_to(cr, text_x + extents.max_x_advance, (double) text_y + 1.5);
|
||||||
cairo_stroke(cr);
|
cairo_stroke(cr);
|
||||||
}
|
}
|
||||||
cairo_move_to(cr, text_x, text_y);
|
|
||||||
|
|
||||||
g = glyphs;
|
glyph_run_add(&run, text_x, text_y, &p_row[col]);
|
||||||
num_glyphs = ARRAY_LENGTH(glyphs);
|
|
||||||
cairo_scaled_font_text_to_glyphs (font, text_x, text_y,
|
|
||||||
(char *) p_row[col].byte, 4,
|
|
||||||
&g, &num_glyphs,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
cairo_show_glyphs (cr, g, num_glyphs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attr.key = ~0;
|
||||||
|
glyph_run_flush(&run, attr);
|
||||||
|
|
||||||
if ((terminal->mode & MODE_SHOW_CURSOR) && !terminal->focused) {
|
if ((terminal->mode & MODE_SHOW_CURSOR) && !terminal->focused) {
|
||||||
d = 0.5;
|
d = 0.5;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue