Add IRC and ANSI SGR exports

This commit is contained in:
Přemysl Eric Janouch 2014-10-24 08:27:13 +02:00
parent de3c8b89bb
commit 52e8c7ac09
1 changed files with 207 additions and 2 deletions

View File

@ -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;