aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2014-10-24 08:27:13 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2014-10-24 08:27:13 +0200
commit52e8c7ac090bbeab857514a1c9bff7e842b416c7 (patch)
tree475cef7652fdd68b26e1f91c6205a4155ee8418f
parentde3c8b89bbc4e728df93552267099106966d3651 (diff)
downloadneetdraw-52e8c7ac090bbeab857514a1c9bff7e842b416c7.tar.gz
neetdraw-52e8c7ac090bbeab857514a1c9bff7e842b416c7.tar.xz
neetdraw-52e8c7ac090bbeab857514a1c9bff7e842b416c7.zip
Add IRC and ANSI SGR exports
-rw-r--r--autistdraw.c209
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;