diff options
author | Přemysl Janouch <p.janouch@gmail.com> | 2014-10-24 08:27:13 +0200 |
---|---|---|
committer | Přemysl Janouch <p.janouch@gmail.com> | 2014-10-24 08:27:13 +0200 |
commit | 52e8c7ac090bbeab857514a1c9bff7e842b416c7 (patch) | |
tree | 475cef7652fdd68b26e1f91c6205a4155ee8418f | |
parent | de3c8b89bbc4e728df93552267099106966d3651 (diff) | |
download | neetdraw-52e8c7ac090bbeab857514a1c9bff7e842b416c7.tar.gz neetdraw-52e8c7ac090bbeab857514a1c9bff7e842b416c7.tar.xz neetdraw-52e8c7ac090bbeab857514a1c9bff7e842b416c7.zip |
Add IRC and ANSI SGR exports
-rw-r--r-- | autistdraw.c | 209 |
1 files changed, 207 insertions, 2 deletions
diff --git a/autistdraw.c b/autistdraw.c index 90b5ed8..44fb252 100644 --- a/autistdraw.c +++ b/autistdraw.c @@ -240,11 +240,204 @@ draw_point (app_context_t *app, int x, int y, uint8_t color) } } +// --- Exports ----------------------------------------------------------------- + +static bool +is_data_row_empty (app_context_t *app, int y) +{ + for (size_t x = 0; x < app->bitmap_w; x++) + if (app->bitmap[y * app->bitmap_w + x]) + return false; + return true; +} + +static bool +is_data_column_empty (app_context_t *app, int x) +{ + for (size_t y = 0; y < app->bitmap_h; y++) + if (app->bitmap[y * app->bitmap_w + x]) + return false; + return true; +} + +static void +find_data_bounding_rect (app_context_t *app, + size_t *x, size_t *y, size_t *w, size_t *h) +{ + size_t my_x = 0, my_y = 0; + size_t my_w = app->bitmap_w, my_h = app->bitmap_h; + size_t i; + + i = 0; + while (i < app->bitmap_h && is_data_row_empty (app, i++)) + my_y++; + + // Special case: the whole canvas is empty + if (my_y == my_h) + { + my_x = my_w; + goto end; + } + + i = app->bitmap_h; + while (i-- && is_data_row_empty (app, i)) + my_h--; + + i = 0; + while (i < app->bitmap_w && is_data_column_empty (app, i++)) + my_x++; + + i = app->bitmap_w; + while (i-- && is_data_column_empty (app, i)) + my_w--; + +end: + *x = my_x; + *y = my_y; + *w = my_w - my_x; + *h = my_h - my_y; +} + +static const char * +color_to_ansi (uint8_t color) +{ + static const char *table[2 * PALETTE_WIDTH] = + { + "\033[0m", + "\033[0;40m", + "\033[0;41m", + "\033[0;42m", + "\033[0;43m", + "\033[0;44m", + "\033[0;45m", + "\033[0;46m", + "\033[0;47m", + "\033[0;1;7m", + "\033[0;1;7;30m", + "\033[0;1;7;31m", + "\033[0;1;7;32m", + "\033[0;1;7;33m", + "\033[0;1;7;34m", + "\033[0;1;7;35m", + "\033[0;1;7;36m", + "\033[0;1;7;37m", + }; + + if (color > sizeof table / sizeof table[0]) + return NULL; + return table[color]; +} + +static void +export_ansi (app_context_t *app) +{ + FILE *fp = fopen ("export-ansi.asc", "wb"); + if (!fp) + { + display ("Error opening file for writing."); + return; + } + + size_t x, y, w, h; + find_data_bounding_rect (app, &x, &y, &w, &h); + + for (size_t row = 0; row < h; row++) + { + const char *color = NULL; + for (size_t column = 0; column < w; column++) + { + const char *new_color = color_to_ansi (app->bitmap[ + (y + row) * app->bitmap_w + (x + column)]); + if (color != new_color) + fputs (new_color, fp); + color = new_color; + fputc (' ', fp); + } + fputc ('\n', fp); + } + + fclose (fp); +} + +enum +{ + MIRC_NONE = -1, + + MIRC_WHITE = 0, + MIRC_BLACK = 1, + MIRC_BLUE = 2, + MIRC_GREEN = 3, + MIRC_L_RED = 4, + MIRC_RED = 5, + MIRC_PURPLE = 6, + MIRC_ORANGE = 7, + MIRC_YELLOW = 8, + MIRC_L_GREEN = 9, + MIRC_CYAN = 10, + MIRC_L_CYAN = 11, + MIRC_L_BLUE = 12, + MIRC_L_PURPLE = 13, + MIRC_GRAY = 14, + MIRC_L_GRAY = 15, + + MIRC_TRANSPARENT = 99 +}; + +static int +color_to_mirc (uint8_t color) +{ + static const int table[2 * PALETTE_WIDTH] = + { + // XXX: not sure what to map the default color pair to; + // the mIRC code for reverse colours seems to not be well supported + MIRC_TRANSPARENT, MIRC_BLACK, MIRC_RED, MIRC_GREEN, MIRC_YELLOW, + MIRC_BLUE, MIRC_PURPLE, MIRC_CYAN, MIRC_L_GRAY, + MIRC_BLACK, MIRC_GRAY, MIRC_L_RED, MIRC_L_GREEN, MIRC_YELLOW, + MIRC_L_BLUE, MIRC_L_PURPLE, MIRC_L_CYAN, MIRC_WHITE + }; + + if (color > sizeof table / sizeof table[0]) + return MIRC_NONE; + return table[color]; +} + +static void +export_irc (app_context_t *app) +{ + FILE *fp = fopen ("export-irc.asc", "wb"); + if (!fp) + { + display ("Error opening file for writing."); + return; + } + + size_t x, y, w, h; + find_data_bounding_rect (app, &x, &y, &w, &h); + + for (size_t row = 0; row < h; row++) + { + int color = MIRC_NONE; + for (size_t column = 0; column < w; column++) + { + int new_color = color_to_mirc (app->bitmap[ + (y + row) * app->bitmap_w + (x + column)]); + if (color != new_color) + fprintf (fp, "\x03%02d,%02d", new_color, new_color); + color = new_color; + fputc ('_', fp); + } + fputc ('\n', fp); + } + + fclose (fp); +} + +// ----------------------------------------------------------------------------- + static bool on_key (app_context_t *app, termo_key_t *key) { - if (key->type == TERMO_TYPE_KEYSYM - && key->code.sym == TERMO_SYM_ESCAPE) + if (key->type == TERMO_TYPE_KEYSYM && key->code.sym == TERMO_SYM_ESCAPE) return false; if (key->type == TERMO_TYPE_KEY @@ -252,6 +445,18 @@ on_key (app_context_t *app, termo_key_t *key) && (key->code.codepoint == 'C' || key->code.codepoint == 'c')) return false; + if (key->type == TERMO_TYPE_KEY && key->code.codepoint == 'e') + { + export_ansi (app); + return true; + } + + if (key->type == TERMO_TYPE_KEY && key->code.codepoint == 'E') + { + export_irc (app); + return true; + } + if (key->type != TERMO_TYPE_MOUSE) return true; |