2009-06-08 18:17:06 -04:00
|
|
|
/* Fully specialized functions for dumping to a file.
|
|
|
|
*
|
|
|
|
* This include file defines a function that dumps the document to a
|
|
|
|
* file. The function is specialized to one color mode and one kind
|
|
|
|
* of charset. This is supposedly faster than runtime checks. The
|
|
|
|
* file that includes this file must define several macros to select
|
|
|
|
* the specialization.
|
|
|
|
*
|
|
|
|
* The following macro must be defined:
|
|
|
|
*
|
|
|
|
* - DUMP_FUNCTION_SPECIALIZED: The name of the function that this
|
|
|
|
* file should define.
|
|
|
|
*
|
2009-06-21 12:05:26 -04:00
|
|
|
* One of the following macros must be defined:
|
2009-06-08 18:17:06 -04:00
|
|
|
*
|
2009-06-21 12:05:26 -04:00
|
|
|
* - DUMP_COLOR_MODE_NONE
|
2009-06-08 18:17:06 -04:00
|
|
|
* - DUMP_COLOR_MODE_16
|
|
|
|
* - DUMP_COLOR_MODE_256
|
|
|
|
* - DUMP_COLOR_MODE_TRUE
|
|
|
|
*
|
|
|
|
* The following macro may be defined:
|
|
|
|
*
|
|
|
|
* - DUMP_CHARSET_UTF8
|
|
|
|
*/
|
|
|
|
|
2020-10-05 14:14:55 -04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2009-06-08 18:17:06 -04:00
|
|
|
static int
|
2009-06-19 07:34:51 -04:00
|
|
|
DUMP_FUNCTION_SPECIALIZED(struct document *document, struct dump_output *out)
|
2009-06-08 18:17:06 -04:00
|
|
|
{
|
|
|
|
int y;
|
|
|
|
#ifdef DUMP_COLOR_MODE_16
|
|
|
|
unsigned char color = 0;
|
2009-06-12 16:18:21 -04:00
|
|
|
const int width = get_opt_int("document.dump.width", NULL);
|
2009-06-08 18:17:06 -04:00
|
|
|
#elif defined(DUMP_COLOR_MODE_256)
|
|
|
|
unsigned char foreground = 0;
|
|
|
|
unsigned char background = 0;
|
2009-06-12 16:18:21 -04:00
|
|
|
const int width = get_opt_int("document.dump.width", NULL);
|
2009-06-08 18:17:06 -04:00
|
|
|
#elif defined(DUMP_COLOR_MODE_TRUE)
|
2009-06-08 20:48:40 -04:00
|
|
|
static const unsigned char color[6] = {255, 255, 255, 0, 0, 0};
|
|
|
|
const unsigned char *foreground = &color[0];
|
|
|
|
const unsigned char *background = &color[3];
|
2009-06-12 16:18:21 -04:00
|
|
|
const int width = get_opt_int("document.dump.width", NULL);
|
2009-06-08 18:17:06 -04:00
|
|
|
#endif /* DUMP_COLOR_MODE_TRUE */
|
|
|
|
|
|
|
|
for (y = 0; y < document->height; y++) {
|
2009-06-21 12:29:14 -04:00
|
|
|
#ifdef DUMP_COLOR_MODE_NONE
|
2009-06-08 18:17:06 -04:00
|
|
|
int white = 0;
|
2009-06-21 12:29:14 -04:00
|
|
|
#endif
|
2009-06-08 18:17:06 -04:00
|
|
|
int x;
|
|
|
|
|
|
|
|
#ifdef DUMP_COLOR_MODE_16
|
2009-06-19 07:34:51 -04:00
|
|
|
write_color_16(color, out);
|
2009-06-08 18:17:06 -04:00
|
|
|
#elif defined(DUMP_COLOR_MODE_256)
|
2009-06-19 07:34:51 -04:00
|
|
|
write_color_256("38", foreground, out);
|
|
|
|
write_color_256("48", background, out);
|
2009-06-08 18:17:06 -04:00
|
|
|
#elif defined(DUMP_COLOR_MODE_TRUE)
|
2009-06-19 07:34:51 -04:00
|
|
|
write_true_color("38", foreground, out);
|
|
|
|
write_true_color("48", background, out);
|
2009-06-08 18:17:06 -04:00
|
|
|
#endif /* DUMP_COLOR_MODE_TRUE */
|
|
|
|
|
|
|
|
for (x = 0; x < document->data[y].length; x++) {
|
|
|
|
#ifdef DUMP_CHARSET_UTF8
|
|
|
|
unicode_val_T c;
|
2021-01-02 10:20:27 -05:00
|
|
|
const char *utf8_buf;
|
2009-06-08 20:38:22 -04:00
|
|
|
#else /* !DUMP_CHARSET_UTF8 */
|
2009-06-08 18:17:06 -04:00
|
|
|
unsigned char c;
|
2009-06-08 20:38:22 -04:00
|
|
|
#endif /* !DUMP_CHARSET_UTF8 */
|
2009-06-08 20:48:40 -04:00
|
|
|
const unsigned char attr
|
|
|
|
= document->data[y].chars[x].attr;
|
2009-06-08 18:17:06 -04:00
|
|
|
#ifdef DUMP_COLOR_MODE_16
|
2009-06-08 20:48:40 -04:00
|
|
|
const unsigned char color1
|
2012-03-03 05:27:58 -05:00
|
|
|
= document->data[y].chars[x].c.color[0];
|
2009-06-08 18:17:06 -04:00
|
|
|
#elif defined(DUMP_COLOR_MODE_256)
|
2009-06-08 20:48:40 -04:00
|
|
|
const unsigned char color1
|
2012-03-03 05:27:58 -05:00
|
|
|
= document->data[y].chars[x].c.color[0];
|
2009-06-08 20:48:40 -04:00
|
|
|
const unsigned char color2
|
2012-03-03 05:27:58 -05:00
|
|
|
= document->data[y].chars[x].c.color[1];
|
2009-06-19 08:11:12 -04:00
|
|
|
#elif defined(DUMP_COLOR_MODE_TRUE)
|
|
|
|
const unsigned char *const new_foreground
|
2012-03-03 05:27:58 -05:00
|
|
|
= &document->data[y].chars[x].c.color[0];
|
2009-06-19 08:11:12 -04:00
|
|
|
const unsigned char *const new_background
|
2012-03-03 05:27:58 -05:00
|
|
|
= &document->data[y].chars[x].c.color[3];
|
2009-06-19 08:11:12 -04:00
|
|
|
#endif /* DUMP_COLOR_MODE_TRUE */
|
2009-06-08 18:17:06 -04:00
|
|
|
|
2009-06-19 07:05:51 -04:00
|
|
|
c = document->data[y].chars[x].data;
|
|
|
|
|
|
|
|
#ifdef DUMP_CHARSET_UTF8
|
|
|
|
if (c == UCS_NO_CHAR) {
|
|
|
|
/* This is the second cell of
|
|
|
|
* a double-cell character. */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
#endif /* DUMP_CHARSET_UTF8 */
|
2009-06-08 18:17:06 -04:00
|
|
|
|
2009-06-19 08:11:12 -04:00
|
|
|
#ifdef DUMP_COLOR_MODE_16
|
2009-06-08 18:17:06 -04:00
|
|
|
if (color != color1) {
|
|
|
|
color = color1;
|
2009-06-19 07:34:51 -04:00
|
|
|
if (write_color_16(color, out))
|
2009-06-08 18:17:06 -04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-06-19 08:11:12 -04:00
|
|
|
#elif defined(DUMP_COLOR_MODE_256)
|
2009-06-08 18:17:06 -04:00
|
|
|
if (foreground != color1) {
|
|
|
|
foreground = color1;
|
2009-06-19 07:34:51 -04:00
|
|
|
if (write_color_256("38", foreground, out))
|
2009-06-08 18:17:06 -04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (background != color2) {
|
|
|
|
background = color2;
|
2009-06-19 07:34:51 -04:00
|
|
|
if (write_color_256("48", background, out))
|
2009-06-08 18:17:06 -04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-06-19 08:11:12 -04:00
|
|
|
#elif defined(DUMP_COLOR_MODE_TRUE)
|
2009-06-08 18:17:06 -04:00
|
|
|
if (memcmp(foreground, new_foreground, 3)) {
|
|
|
|
foreground = new_foreground;
|
2009-06-19 07:34:51 -04:00
|
|
|
if (write_true_color("38", foreground, out))
|
2009-06-08 18:17:06 -04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (memcmp(background, new_background, 3)) {
|
|
|
|
background = new_background;
|
2009-06-19 07:34:51 -04:00
|
|
|
if (write_true_color("48", background, out))
|
2009-06-08 18:17:06 -04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif /* DUMP_COLOR_MODE_TRUE */
|
|
|
|
|
|
|
|
if ((attr & SCREEN_ATTR_FRAME)
|
2009-06-21 11:30:36 -04:00
|
|
|
&& c >= FRAME_CHARS_BEGIN && c < FRAME_CHARS_END)
|
|
|
|
c = out->frame[c - FRAME_CHARS_BEGIN];
|
2009-06-08 18:17:06 -04:00
|
|
|
|
2009-06-19 07:10:50 -04:00
|
|
|
#ifdef DUMP_CHARSET_UTF8
|
2009-06-21 12:29:14 -04:00
|
|
|
if (!isscreensafe_ucs(c)) c = ' ';
|
2009-06-19 07:10:50 -04:00
|
|
|
#else
|
2009-06-21 12:29:14 -04:00
|
|
|
if (!isscreensafe(c)) c = ' ';
|
2009-06-19 07:10:50 -04:00
|
|
|
#endif
|
2009-06-21 12:29:14 -04:00
|
|
|
|
|
|
|
#ifdef DUMP_COLOR_MODE_NONE
|
|
|
|
if (c == ' ') {
|
2009-06-08 18:17:06 -04:00
|
|
|
/* Count spaces. */
|
|
|
|
white++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Print spaces if any. */
|
|
|
|
while (white) {
|
2009-06-19 07:34:51 -04:00
|
|
|
if (write_char(' ', out))
|
2009-06-08 18:17:06 -04:00
|
|
|
return -1;
|
|
|
|
white--;
|
|
|
|
}
|
2009-06-21 12:29:14 -04:00
|
|
|
#endif /* DUMP_COLOR_MODE_NONE */
|
2009-06-08 18:17:06 -04:00
|
|
|
|
|
|
|
/* Print normal char. */
|
2009-06-08 20:36:25 -04:00
|
|
|
#ifdef DUMP_CHARSET_UTF8
|
2009-06-08 20:38:22 -04:00
|
|
|
utf8_buf = encode_utf8(c);
|
|
|
|
while (*utf8_buf) {
|
2009-06-19 07:34:51 -04:00
|
|
|
if (write_char(*utf8_buf++, out)) return -1;
|
2009-06-08 20:36:25 -04:00
|
|
|
}
|
2009-06-08 20:38:22 -04:00
|
|
|
|
2009-06-08 20:36:25 -04:00
|
|
|
#else /* !DUMP_CHARSET_UTF8 */
|
2009-06-19 07:34:51 -04:00
|
|
|
if (write_char(c, out))
|
2009-06-08 18:17:06 -04:00
|
|
|
return -1;
|
2009-06-08 20:36:25 -04:00
|
|
|
#endif /* !DUMP_CHARSET_UTF8 */
|
2009-06-08 18:17:06 -04:00
|
|
|
}
|
2009-06-08 20:36:25 -04:00
|
|
|
|
2009-06-21 12:05:26 -04:00
|
|
|
#ifndef DUMP_COLOR_MODE_NONE
|
2009-06-08 18:17:06 -04:00
|
|
|
for (;x < width; x++) {
|
2009-06-19 07:34:51 -04:00
|
|
|
if (write_char(' ', out))
|
2009-06-08 18:17:06 -04:00
|
|
|
return -1;
|
|
|
|
}
|
2009-06-21 12:05:26 -04:00
|
|
|
#endif /* !DUMP_COLOR_MODE_NONE */
|
2009-06-08 18:17:06 -04:00
|
|
|
|
|
|
|
/* Print end of line. */
|
2009-06-19 07:34:51 -04:00
|
|
|
if (write_char('\n', out))
|
2009-06-08 18:17:06 -04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-06-19 07:34:51 -04:00
|
|
|
if (dump_output_flush(out))
|
2009-06-08 18:17:06 -04:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2020-10-05 14:14:55 -04:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|