diff options
Diffstat (limited to 'atascii.c')
-rw-r--r-- | atascii.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/atascii.c b/atascii.c new file mode 100644 index 0000000..d1d1243 --- /dev/null +++ b/atascii.c @@ -0,0 +1,115 @@ +#include "atascii.h" + +const char *atascii_inverse_on = "\x1b[7m"; +const char *atascii_inverse_off = "\x1b[27m"; + +int atascii_context_init(atascii_ctx *ctx, int mode, int flags) { + memset(ctx, 0, sizeof(atascii_ctx)); + + switch(mode) { + case ATA_MODE_UTF8: + if(flags & ATA_FLAG_ICS) + ctx->table = ics2utf; + else + ctx->table = ata2utf; + break; + case ATA_MODE_MAGAZINE: + ctx->flags &= ~ATA_FLAG_UNDERLINE; + ctx->table = ata2mag; + break; + default: + return 0; + } + + ctx->mode = mode; + ctx->flags = flags; + + return 1; +} + +char *atascii_a2utf(atascii_ctx *ctx, int src, char *dest) { + dest[0] = 0; + + if(src == ATA_CHR_FINISH) { + if(ctx->inv) + strcpy(dest, atascii_inverse_off); + return dest; + } + + if(src == 0x9b) { + strcpy(dest, "\n"); + ctx->lines++; + return dest; + } + + if(ctx->flags & ATA_FLAG_TEXTMODE) { + switch(src) { + case 0x7f: /* tab */ + strcpy(dest, "\t"); + return dest; + case 0xfd: /* bell */ + strcpy(dest, "\a"); + return dest; + case 0x7e: /* backspace */ + strcpy(dest, "\b"); + return dest; + default: break; + } + } + + if(ctx->flags & ATA_FLAG_STRIP_INVERSE) src &= 0x7f; + + if(!(ctx->flags & ATA_FLAG_UNDERLINE)) { + /* strings of inverse chars only get one "inverse on" ANSI + sequence, and one "inverse off" afterwards. */ + if(src & 0x80) { + if(!ctx->inv) { + ctx->inv = 1; + if(ctx->mode == ATA_MODE_MAGAZINE) { + strcpy(dest, "{inv}"); + } else { + strcpy(dest, atascii_inverse_on); + } + } + } else { + if(ctx->inv) { + ctx->inv = 0; + if(ctx->mode == ATA_MODE_MAGAZINE) { + strcpy(dest, "{norm}"); + } else { + strcpy(dest, atascii_inverse_off); + } + } + } + } + + if(ctx->mode == ATA_MODE_MAGAZINE) { + /* special cases: control codes with bit 7 set can't go + in the table since it's only got 128 entries. */ + switch(src) { + case 0x9c: + strcat(dest, "{del-line}"); return dest; + case 0x9d: + strcat(dest, "{ins-line}"); return dest; + case 0x9e: + strcat(dest, "{clr-tab}"); return dest; + case 0x9f: + strcat(dest, "{set-tab}"); return dest; + case 0xfd: + strcat(dest, "{bell}"); return dest; + case 0xfe: + strcat(dest, "{del-char}"); return dest; + case 0xff: + strcat(dest, "{ins-char}"); return dest; + default: break; + } + } + + strcat(dest, ctx->table[src & 0x7f]); + + if((ctx->flags & ATA_FLAG_UNDERLINE) && (src & 0x80)) { + strcat(dest, "\b_"); + } + + return dest; +} |