On 01/07/2011 02:47 PM, Callum Lowcay wrote:
> Includes the 3 vt100 character sets.  Some of the graphic symbols don't
> display because they are not included in the default font.  Apparantly
> the cairo toy font API doesn't do font substitution.
> 
> Signed-off-by: Callum Lowcay <[email protected]>
> ---
>  clients/terminal.c |  117 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 117 insertions(+), 0 deletions(-)
> 
> diff --git a/clients/terminal.c b/clients/terminal.c
> index 88864c3..a56f29b 100644
> --- a/clients/terminal.c
> +++ b/clients/terminal.c
> @@ -166,6 +166,69 @@ utf8_next_char(struct utf8_state_machine *machine, char 
> c)
>       return machine->state;
>  }
>  
> +struct char_sub {
> +     union utf8_char match;
> +     union utf8_char replace;
> +};
> +/* Set last char_sub match to NULL char */
> +typedef struct char_sub *character_set;
> +
> +struct char_sub CS_US[] = {
> +     {{{0, }}, {{0, }}}
> +};
> +static struct char_sub CS_UK[] = {
> +     {{{'#', 0, }}, {{0xC2, 0xA3, 0, }}},
> +     {{{0, }}, {{0, }}}
> +};
> +static struct char_sub CS_SPECIAL[] = {
> +     {{{'`', 0, }}, {{0xE2, 0x99, 0xA6, 0}}}, /* diamond */
> +     {{{'a', 0, }}, {{0xE2, 0x96, 0x92, 0}}}, /* 50% cell */
> +     {{{'b', 0, }}, {{0xE2, 0x90, 0x89, 0}}}, /* HT */
> +     {{{'c', 0, }}, {{0xE2, 0x90, 0x8C, 0}}}, /* FF */
> +     {{{'d', 0, }}, {{0xE2, 0x90, 0x8D, 0}}}, /* CR */
> +     {{{'e', 0, }}, {{0xE2, 0x90, 0x8A, 0}}}, /* LF */
> +     {{{'f', 0, }}, {{0xC2, 0xB0, 0, }}}, /* Degree */
> +     {{{'g', 0, }}, {{0xC2, 0xB1, 0, }}}, /* Plus/Minus */
> +     {{{'h', 0, }}, {{0xE2, 0x90, 0xA4, 0}}}, /* NL */
> +     {{{'i', 0, }}, {{0xE2, 0x90, 0x8B, 0}}}, /* VT */
> +     {{{'j', 0, }}, {{0xE2, 0x94, 0x98, 0}}}, /* CN_RB */
> +     {{{'k', 0, }}, {{0xE2, 0x94, 0x90, 0}}}, /* CN_RT */
> +     {{{'l', 0, }}, {{0xE2, 0x94, 0x8C, 0}}}, /* CN_LT */
> +     {{{'m', 0, }}, {{0xE2, 0x94, 0x94, 0}}}, /* CN_RB */
> +     {{{'n', 0, }}, {{0xE2, 0x94, 0xBC, 0}}}, /* CROSS */
> +     {{{'o', 0, }}, {{0xE2, 0x94, 0x80, 0}}}, /* H */
> +     {{{'p', 0, }}, {{0xE2, 0x94, 0x80, 0}}}, /* H */
> +     {{{'q', 0, }}, {{0xE2, 0x94, 0x80, 0}}}, /* H */
> +     {{{'r', 0, }}, {{0xE2, 0x94, 0x80, 0}}}, /* H */
> +     {{{'s', 0, }}, {{0xE2, 0x94, 0x80, 0}}}, /* H */
> +     {{{'t', 0, }}, {{0xE2, 0x94, 0x9C, 0}}}, /* TR */
> +     {{{'u', 0, }}, {{0xE2, 0x94, 0xA4, 0}}}, /* TL */
> +     {{{'v', 0, }}, {{0xE2, 0x94, 0xB4, 0}}}, /* TU */
> +     {{{'w', 0, }}, {{0xE2, 0x94, 0xAC, 0}}}, /* TD */
> +     {{{'x', 0, }}, {{0xE2, 0x94, 0x82, 0}}}, /* V */
> +     {{{'y', 0, }}, {{0xE2, 0x89, 0xA4, 0}}}, /* LE */
> +     {{{'z', 0, }}, {{0xE2, 0x89, 0xA5, 0}}}, /* GE */
> +     {{{'{', 0, }}, {{0xCF, 0x80, 0, }}}, /* PI */
> +     {{{'|', 0, }}, {{0xE2, 0x89, 0xA0, 0}}}, /* NEQ */
> +     {{{'}', 0, }}, {{0xC2, 0xA3, 0, }}}, /* POUND */
> +     {{{'~', 0, }}, {{0xE2, 0x8B, 0x85, 0}}}, /* DOT */
> +     {{{0, }}, {{0, }}}
> +};
> +
> +static void
> +apply_char_set(character_set cs, union utf8_char *utf8)
> +{
> +     int i = 0;
> +     
> +     while (cs[i].match.byte[0]) {
> +             if ((*utf8).ch == cs[i].match.ch) {
> +                     *utf8 = cs[i].replace;
> +                     break;
> +             }
> +             i++;
> +     }
> +}
> +
>  struct terminal_color { double r, g, b, a; };
>  struct attr {
>       unsigned char fg, bg;
> @@ -202,6 +265,8 @@ struct terminal {
>       struct attr saved_attr;
>       union utf8_char last_char;
>       int margin_top, margin_bottom;
> +     character_set cs, g0, g1;
> +     character_set saved_cs, saved_g0, saved_g1;
>       int data_pitch, attr_pitch;  /* The width in bytes of a line */
>       int width, height, start, row, column;
>       int saved_row, saved_column;
> @@ -249,6 +314,14 @@ terminal_init(struct terminal *terminal)
>       terminal->row = 0;
>       terminal->column = 0;
>  
> +     terminal->g0 = CS_US;
> +     terminal->g1 = CS_US;
> +     terminal->cs = terminal->g0;
> +
> +     terminal->saved_g0 = terminal->g0;
> +     terminal->saved_g1 = terminal->g1;
> +     terminal->saved_cs = terminal->cs;
> +
>       terminal->saved_attr = terminal->curr_attr;
>       terminal->saved_origin_mode = terminal->origin_mode;
>       terminal->saved_row = terminal->row;
> @@ -714,6 +787,12 @@ handle_term_parameter(struct terminal *terminal, int 
> code, int sr)
>  
>       if (terminal->qmark_flag) {
>               switch(code) {
> +             case 2:  /* DECANM */
> +                     /* No VT52 support yet */
> +                     terminal->g0 = CS_US;
> +                     terminal->g1 = CS_US;
> +                     terminal->cs = terminal->g0;
> +                     break;
>               case 3:  /* DECCOLM */
>                       if (sr)
>                               terminal_resize(terminal, 132, 24);
> @@ -1147,12 +1226,18 @@ handle_non_csi_escape(struct terminal *terminal, char 
> code)
>               terminal->saved_column = terminal->column;
>               terminal->saved_attr = terminal->curr_attr;
>               terminal->saved_origin_mode = terminal->origin_mode;
> +             terminal->saved_cs = terminal->cs;
> +             terminal->saved_g0 = terminal->g0;
> +             terminal->saved_g1 = terminal->g1;
>               break;
>       case '8':    /* DECRC */
>               terminal->row = terminal->saved_row;
>               terminal->column = terminal->saved_column;
>               terminal->curr_attr = terminal->saved_attr;
>               terminal->origin_mode = terminal->saved_origin_mode;
> +             terminal->cs = terminal->saved_cs;
> +             terminal->g0 = terminal->saved_g0;
> +             terminal->g1 = terminal->saved_g1;
>               break;
>       default:
>               fprintf(stderr, "Unknown escape code: %c\n", code);
> @@ -1179,6 +1264,30 @@ handle_special_escape(struct terminal *terminal, char 
> special, char code)
>                       fprintf(stderr, "Unknown HASH escape #%c\n", code);
>                       break;
>               }
> +     } else if (special == '(' || special == ')') {
> +             switch(code) {
> +             case '0':
> +                     if (special == '(')
> +                             terminal->g0 = CS_SPECIAL;
> +                     else
> +                             terminal->g1 = CS_SPECIAL;
> +                     break;
> +             case 'A':
> +                     if (special == '(')
> +                             terminal->g0 = CS_UK;
> +                     else
> +                             terminal->g1 = CS_UK;
> +                     break;
> +             case 'B':
> +                     if (special == '(')
> +                             terminal->g0 = CS_US;
> +                     else
> +                             terminal->g1 = CS_US;
> +                     break;
> +             default:
> +                     fprintf(stderr, "Unknown character set %c\n", code);
> +                     break;
> +             }
>       } else {
>               fprintf(stderr, "Unknown special escape %c%c\n", special, code);
>       }
> @@ -1307,6 +1416,12 @@ handle_special_char(struct terminal *terminal, char c)
>       case '\a':
>               /* Bell */
>               break;
> +     case '\x0E': /* SO */
> +             terminal->cs = terminal->g1;
> +             break;
> +     case '\x0F': /* SI */
> +             terminal->cs = terminal->g0;
> +             break;
>       default:
>               return 0;
>       }
> @@ -1321,6 +1436,8 @@ handle_char(struct terminal *terminal, union utf8_char 
> utf8)
>       struct attr *attr_row;
>       
>       if (handle_special_char(terminal, utf8.byte[0])) return;
> +
> +     apply_char_set(terminal->cs, &utf8);
>       
>       /* There are a whole lot of non-characters, control codes,
>        * and formatting codes that should probably be ignored,

In looking at this I decided the way to go was to draw the line drawing 
characters by hand as lines and the visible controls by hand positioning them 
in the character cell with a smaller font.  (It turns out the font coverage for 
the visible controls is poor.)  The one glyph I didn't find and didn't make a 
decision on is the checkerboard symbol.

Do not forget to test with combining Unicode characters including cases where 
you have several combining characters in a row that are supposed to overlay the 
non-combining character.
_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to