From 2396423d03749a7ab4f7ffe35a156494da6edb52 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Mon, 28 May 2012 12:37:12 +0200 Subject: [PATCH] vte/font/console: support basic character attributes This adds support for colored and bold characters. This also adds the infrastrucure for background colors and underlined characters, however, these are not properly implemented, yet. The color codes are similar to xterm and optimized on black backgrounds. So they are not too bright or shiny. Signed-off-by: David Herrmann --- src/console.c | 15 +++++--- src/console.h | 3 +- src/font.h | 14 ++++++- src/font_pango.c | 22 ++++++++--- src/vte.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 137 insertions(+), 16 deletions(-) diff --git a/src/console.c b/src/console.c index 771473a..4c1c4a5 100644 --- a/src/console.c +++ b/src/console.c @@ -48,6 +48,7 @@ struct cell { kmscon_symbol_t ch; + struct font_char_attr attr; }; struct line { @@ -763,7 +764,8 @@ static void kmscon_buffer_draw(struct kmscon_buffer *buf, for (j = 0; j < num; ++j) { cell = &line->cells[j]; - font_screen_draw_char(fscr, cell->ch, j, i, 1, 1); + font_screen_draw_char(fscr, cell->ch, &cell->attr, + j, i, 1, 1); } } @@ -772,13 +774,14 @@ static void kmscon_buffer_draw(struct kmscon_buffer *buf, } static void kmscon_buffer_write(struct kmscon_buffer *buf, unsigned int x, - unsigned int y, kmscon_symbol_t ch) + unsigned int y, kmscon_symbol_t ch, + const struct font_char_attr *attr) { struct line *line, **slot; int ret; bool scroll = false; - if (!buf) + if (!buf || !attr) return; if (x >= buf->size_x || y >= buf->size_y) { @@ -822,6 +825,7 @@ static void kmscon_buffer_write(struct kmscon_buffer *buf, unsigned int x, } line->cells[x].ch = ch; + memcpy(&line->cells[x].attr, attr, sizeof(*attr)); } static kmscon_symbol_t kmscon_buffer_read(struct kmscon_buffer *buf, @@ -1039,7 +1043,8 @@ void kmscon_console_draw(struct kmscon_console *con, struct font_screen *fscr) kmscon_buffer_draw(con->cells, fscr); } -void kmscon_console_write(struct kmscon_console *con, kmscon_symbol_t ch) +void kmscon_console_write(struct kmscon_console *con, kmscon_symbol_t ch, + const struct font_char_attr *attr) { unsigned int last; @@ -1061,7 +1066,7 @@ void kmscon_console_write(struct kmscon_console *con, kmscon_symbol_t ch) } } - kmscon_buffer_write(con->cells, con->cursor_x, con->cursor_y, ch); + kmscon_buffer_write(con->cells, con->cursor_x, con->cursor_y, ch, attr); con->cursor_x++; } diff --git a/src/console.h b/src/console.h index 9ce8152..31c8934 100644 --- a/src/console.h +++ b/src/console.h @@ -55,7 +55,8 @@ int kmscon_console_resize(struct kmscon_console *con, unsigned int x, void kmscon_console_draw(struct kmscon_console *con, struct font_screen *fscr); -void kmscon_console_write(struct kmscon_console *con, kmscon_symbol_t ch); +void kmscon_console_write(struct kmscon_console *con, kmscon_symbol_t ch, + const struct font_char_attr *attr); void kmscon_console_newline(struct kmscon_console *con); void kmscon_console_backspace(struct kmscon_console *con); void kmscon_console_move_to(struct kmscon_console *con, unsigned int x, diff --git a/src/font.h b/src/font.h index a832f37..acc1aa7 100644 --- a/src/font.h +++ b/src/font.h @@ -91,7 +91,6 @@ int kmscon_font_draw(struct kmscon_font *font, kmscon_symbol_t ch, float *m, enum font_style { FONT_NORMAL, FONT_ITALIC, - FONT_OBLIQUE, }; struct font_attr { @@ -110,6 +109,18 @@ struct font_attr { .style = FONT_NORMAL, \ } +struct font_char_attr { + uint8_t fr; /* foreground red */ + uint8_t fg; /* foreground green */ + uint8_t fb; /* foreground blue */ + uint8_t br; /* background red */ + uint8_t bg; /* background green */ + uint8_t bb; /* background blue */ + unsigned int bold : 1; /* bold character */ + unsigned int underline : 1; /* underlined character */ + unsigned int inverse : 1; /* inverse colors */ +}; + /* font draw/assemble buffers */ struct font_buffer { @@ -144,6 +155,7 @@ unsigned int font_screen_height(struct font_screen *screen); int font_screen_draw_start(struct font_screen *screen); int font_screen_draw_char(struct font_screen *screen, kmscon_symbol_t ch, + const struct font_char_attr *attr, unsigned int cellx, unsigned int celly, unsigned int width, unsigned int height); int font_screen_draw_perform(struct font_screen *screen, float *m); diff --git a/src/font_pango.c b/src/font_pango.c index 10ea135..3a7616b 100644 --- a/src/font_pango.c +++ b/src/font_pango.c @@ -253,8 +253,6 @@ static int face__new(struct font_face **out, const struct font_attr *attr, if (face->attr.style == FONT_ITALIC) style = PANGO_STYLE_ITALIC; - else if (face->attr.style == FONT_OBLIQUE) - style = PANGO_STYLE_OBLIQUE; else style = PANGO_STYLE_NORMAL; @@ -699,18 +697,30 @@ int font_screen_draw_start(struct font_screen *screen) } int font_screen_draw_char(struct font_screen *screen, kmscon_symbol_t ch, + const struct font_char_attr *attr, unsigned int cellx, unsigned int celly, unsigned int width, unsigned int height) { struct font_glyph *glyph; int ret; - if (!screen || !width || !height) + if (!screen || !width || !height || !attr) return -EINVAL; - ret = face_lookup(screen->faces.normal, &glyph, ch); - if (ret) - return ret; + if (attr->bold) { + ret = face_lookup(screen->faces.bold, &glyph, ch); + if (ret) + return ret; + } else { + ret = face_lookup(screen->faces.normal, &glyph, ch); + if (ret) + return ret; + } + + if (attr->inverse) + cairo_set_source_rgb(screen->cr, attr->br, attr->bg, attr->bb); + else + cairo_set_source_rgb(screen->cr, attr->fr, attr->fg, attr->fb); if (glyph->type == GLYPH_STRING) { cairo_move_to(screen->cr, cellx * screen->advance_x, diff --git a/src/vte.c b/src/vte.c index 4932bd2..3177834 100644 --- a/src/vte.c +++ b/src/vte.c @@ -54,6 +54,7 @@ #include #include "console.h" +#include "font.h" #include "log.h" #include "unicode.h" #include "vte.h" @@ -113,6 +114,8 @@ struct kmscon_vte { unsigned int state; unsigned int csi_argc; int csi_argv[CSI_ARG_MAX]; + + struct font_char_attr cattr; }; int kmscon_vte_new(struct kmscon_vte **out, struct kmscon_console *con) @@ -132,6 +135,16 @@ int kmscon_vte_new(struct kmscon_vte **out, struct kmscon_console *con) vte->state = STATE_GROUND; vte->con = con; + vte->cattr.fr = 255; + vte->cattr.fg = 255; + vte->cattr.fb = 255; + vte->cattr.br = 0; + vte->cattr.bg = 0; + vte->cattr.bb = 0; + vte->cattr.bold = 0; + vte->cattr.underline = 0; + vte->cattr.inverse = 0; + ret = kmscon_utf8_mach_new(&vte->mach); if (ret) goto err_free; @@ -237,7 +250,7 @@ static void do_execute(struct kmscon_vte *vte, uint32_t ctrl) case 0x1a: /* SUB */ /* Discard current escape sequence and show err-sym */ /* TODO: show reversed question mark */ - kmscon_console_write(vte->con, '?'); + kmscon_console_write(vte->con, '?', &vte->cattr); break; case 0x1b: /* ESC */ /* Invokes an escape sequence */ @@ -362,7 +375,7 @@ static void do_esc(struct kmscon_vte *vte, uint32_t data) static void do_csi(struct kmscon_vte *vte, uint32_t data) { - int num; + int num, i; if (vte->csi_argc < CSI_ARG_MAX) vte->csi_argc++; @@ -414,6 +427,86 @@ static void do_csi(struct kmscon_vte *vte, uint32_t data) log_debug("unknown parameter to CSI-K: %d", vte->csi_argv[0]); break; + case 'm': + for (i = 0; i < CSI_ARG_MAX; ++i) { + switch (vte->csi_argv[i]) { + case -1: + break; + case 0: + vte->cattr.fr = 255; + vte->cattr.fg = 255; + vte->cattr.fb = 255; + vte->cattr.br = 0; + vte->cattr.bg = 0; + vte->cattr.bb = 0; + vte->cattr.bold = 0; + vte->cattr.underline = 0; + vte->cattr.inverse = 0; + break; + case 1: + vte->cattr.bold = 1; + break; + case 4: + vte->cattr.underline = 1; + break; + case 7: + vte->cattr.inverse = 1; + break; + case 22: + vte->cattr.bold = 0; + break; + case 24: + vte->cattr.underline = 0; + break; + case 27: + vte->cattr.inverse = 0; + break; + case 30: + vte->cattr.fr = 0; + vte->cattr.fg = 0; + vte->cattr.fb = 0; + break; + case 31: + vte->cattr.fr = 205; + vte->cattr.fg = 0; + vte->cattr.fb = 0; + break; + case 32: + vte->cattr.fr = 0; + vte->cattr.fg = 205; + vte->cattr.fb = 0; + break; + case 33: + vte->cattr.fr = 205; + vte->cattr.fg = 205; + vte->cattr.fb = 0; + break; + case 34: + vte->cattr.fr = 0; + vte->cattr.fg = 0; + vte->cattr.fb = 238; + break; + case 35: + vte->cattr.fr = 205; + vte->cattr.fg = 0; + vte->cattr.fb = 205; + break; + case 36: + vte->cattr.fr = 0; + vte->cattr.fg = 205; + vte->cattr.fb = 205; + break; + case 37: + vte->cattr.fr = 255; + vte->cattr.fg = 255; + vte->cattr.fb = 255; + break; + default: + log_debug("unhandled SGR attr %i", + vte->csi_argv[i]); + } + } + break; default: log_debug("unhandled CSI sequence %c", data); } @@ -433,7 +526,7 @@ static void do_action(struct kmscon_vte *vte, uint32_t data, int action) break; case ACTION_PRINT: sym = kmscon_symbol_make(data); - kmscon_console_write(vte->con, sym); + kmscon_console_write(vte->con, sym, &vte->cattr); break; case ACTION_EXECUTE: do_execute(vte, data);