diff --git a/cucul/Makefile.am b/cucul/Makefile.am index ece1b4f..1ec107e 100644 --- a/cucul/Makefile.am +++ b/cucul/Makefile.am @@ -27,12 +27,7 @@ libcucul_la_SOURCES = \ font.c \ font_mono9.h \ font_monobold12.h \ - export_irc.c \ - export_ansi.c \ - export_html.c \ - export_ps.c \ - export_svg.c \ - export_bitmap.c \ + export.c \ $(NULL) libcucul_la_LDFLAGS = -no-undefined libcucul_la_LIBADD = @CUCUL_LIBS@ diff --git a/cucul/cucul.c b/cucul/cucul.c index 3d1242b..50f66b9 100644 --- a/cucul/cucul.c +++ b/cucul/cucul.c @@ -247,91 +247,6 @@ int cucul_rand(int min, int max) return min + (int)((1.0*(max-min+1)) * rand() / (RAND_MAX+1.0)); } -/** \brief Export a canvas into a foreign format. - * - * This function exports a libcucul canvas into various foreign formats such - * as ANSI art, HTML, IRC colours, etc. One should use cucul_get_buffer_data() - * and cucul_get_buffer_size() to access the buffer contents. The allocated - * data is valid until cucul_free_buffer() is called. - * - * Valid values for \e format are: - * - * \li \e "ansi": export ANSI art (CP437 charset with ANSI colour codes). - * - * \li \e "html": export an HTML page with CSS information. - * - * \li \e "html3": export an HTML table that should be compatible with - * most navigators, including textmode ones. - * - * \li \e "irc": export UTF-8 text with mIRC colour codes. - * - * \li \e "ps": export a PostScript document. - * - * \li \e "svg": export an SVG vector image. - * - * \li \e "tga": export a TGA image. - * - * \param qq A libcucul canvas - * \param format A string describing the requested output format. - */ -cucul_buffer_t * cucul_create_export(cucul_t *qq, char const *format) -{ - cucul_buffer_t *ex; - - ex = malloc(sizeof(cucul_buffer_t)); - ex->size = 0; - ex->data = NULL; - - if(!strcasecmp("ansi", format)) - _cucul_get_ansi(qq, ex); - else if(!strcasecmp("html", format)) - _cucul_get_html(qq, ex); - else if(!strcasecmp("html3", format)) - _cucul_get_html3(qq, ex); - else if(!strcasecmp("irc", format)) - _cucul_get_irc(qq, ex); - else if(!strcasecmp("ps", format)) - _cucul_get_ps(qq, ex); - else if(!strcasecmp("svg", format)) - _cucul_get_svg(qq, ex); - else if(!strcasecmp("tga", format)) - _cucul_get_tga(qq, ex); - - if(ex->size == 0) - { - free(ex); - return NULL; - } - - return ex; -} - -/** \brief Get available export formats - * - * Return a list of available export formats. The list is a NULL-terminated - * array of strings, interleaving a string containing the internal value for - * the export format, to be used with \e cucul_create_export(), and a string - * containing the natural language description for that export format. - * - * \return An array of strings. - */ -char const * const * cucul_get_export_list(void) -{ - static char const * const list[] = - { - "ansi", "ANSI", - "html", "HTML", - "html3", "backwards-compatible HTML", - "irc", "IRC with mIRC colours", - "ps", "PostScript document", - "svg", "SVG vector image", - "tga", "TGA image", - NULL, NULL - }; - - return list; -} - /** \brief Get the buffer size. * * This function returns the length (in bytes) of the memory area stored diff --git a/cucul/cucul_internals.h b/cucul/cucul_internals.h index b3fc2e7..3bfc9f0 100644 --- a/cucul/cucul_internals.h +++ b/cucul/cucul_internals.h @@ -71,13 +71,4 @@ uint32_t _cucul_argb32_to_rgb24fg(uint32_t); uint32_t _cucul_argb32_to_rgb24bg(uint32_t); void _cucul_argb32_to_argb4(uint32_t, uint8_t[8]); -/* Export functions */ -extern void _cucul_get_ansi(cucul_t *, cucul_buffer_t *); -extern void _cucul_get_html(cucul_t *, cucul_buffer_t *); -extern void _cucul_get_html3(cucul_t *, cucul_buffer_t *); -extern void _cucul_get_irc(cucul_t *, cucul_buffer_t *); -extern void _cucul_get_ps(cucul_t *, cucul_buffer_t *); -extern void _cucul_get_svg(cucul_t *, cucul_buffer_t *); -extern void _cucul_get_tga(cucul_t *, cucul_buffer_t *); - #endif /* __CUCUL_INTERNALS_H__ */ diff --git a/cucul/export.c b/cucul/export.c new file mode 100644 index 0000000..386f97f --- /dev/null +++ b/cucul/export.c @@ -0,0 +1,677 @@ +/* + * libcucul Canvas for ultrafast compositing of Unicode letters + * Copyright (c) 2002-2006 Sam Hocevar + * 2006 Jean-Yves Lamoureux + * All Rights Reserved + * + * $Id$ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Do What The Fuck You Want To + * Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + */ + +/* + * This file contains various export functions + */ + +#include "config.h" + +#if !defined(__KERNEL__) +# include +# include +# include +#endif + +#include "cucul.h" +#include "cucul_internals.h" + +static void export_ansi(cucul_t *, cucul_buffer_t *); +static void export_html(cucul_t *, cucul_buffer_t *); +static void export_html3(cucul_t *, cucul_buffer_t *); +static void export_irc(cucul_t *, cucul_buffer_t *); +static void export_ps(cucul_t *, cucul_buffer_t *); +static void export_svg(cucul_t *, cucul_buffer_t *); +static void export_tga(cucul_t *, cucul_buffer_t *); + +/** \brief Export a canvas into a foreign format. + * + * This function exports a libcucul canvas into various foreign formats such + * as ANSI art, HTML, IRC colours, etc. One should use cucul_get_buffer_data() + * and cucul_get_buffer_size() to access the buffer contents. The allocated + * data is valid until cucul_free_buffer() is called. + * + * Valid values for \e format are: + * + * \li \e "ansi": export ANSI art (CP437 charset with ANSI colour codes). + * + * \li \e "html": export an HTML page with CSS information. + * + * \li \e "html3": export an HTML table that should be compatible with + * most navigators, including textmode ones. + * + * \li \e "irc": export UTF-8 text with mIRC colour codes. + * + * \li \e "ps": export a PostScript document. + * + * \li \e "svg": export an SVG vector image. + * + * \li \e "tga": export a TGA image. + * + * \param qq A libcucul canvas + * \param format A string describing the requested output format. + */ +cucul_buffer_t * cucul_create_export(cucul_t *qq, char const *format) +{ + cucul_buffer_t *ex; + + ex = malloc(sizeof(cucul_buffer_t)); + ex->size = 0; + ex->data = NULL; + + if(!strcasecmp("ansi", format)) + export_ansi(qq, ex); + else if(!strcasecmp("html", format)) + export_html(qq, ex); + else if(!strcasecmp("html3", format)) + export_html3(qq, ex); + else if(!strcasecmp("irc", format)) + export_irc(qq, ex); + else if(!strcasecmp("ps", format)) + export_ps(qq, ex); + else if(!strcasecmp("svg", format)) + export_svg(qq, ex); + else if(!strcasecmp("tga", format)) + export_tga(qq, ex); + + if(ex->size == 0) + { + free(ex); + return NULL; + } + + return ex; +} + +/** \brief Get available export formats + * + * Return a list of available export formats. The list is a NULL-terminated + * array of strings, interleaving a string containing the internal value for + * the export format, to be used with \e cucul_create_export(), and a string + * containing the natural language description for that export format. + * + * \return An array of strings. + */ +char const * const * cucul_get_export_list(void) +{ + static char const * const list[] = + { + "ansi", "ANSI", + "html", "HTML", + "html3", "backwards-compatible HTML", + "irc", "IRC with mIRC colours", + "ps", "PostScript document", + "svg", "SVG vector image", + "tga", "TGA image", + NULL, NULL + }; + + return list; +} + +/* + * XXX: the following functions are local. + */ + +/* Generate ANSI representation of current canvas. */ +static void export_ansi(cucul_t *qq, cucul_buffer_t *ex) +{ + static int const palette[] = + { + 0, 4, 2, 6, 1, 5, 3, 7, + 8, 12, 10, 14, 9, 13, 11, 15 + }; + + char *cur; + unsigned int x, y; + + /* 23 bytes assumed for max length per pixel ('\e[5;1;3x;4y;9x;10ym' plus + * 4 max bytes for a UTF-8 character). + * Add height*9 to that (zeroes color at the end and jump to next line) */ + ex->size = (qq->height * 9) + (qq->width * qq->height * 23); + ex->data = malloc(ex->size); + + cur = ex->data; + + for(y = 0; y < qq->height; y++) + { + uint32_t *lineattr = qq->attr + y * qq->width; + uint32_t *linechar = qq->chars + y * qq->width; + + uint8_t prevfg = -1; + uint8_t prevbg = -1; + + for(x = 0; x < qq->width; x++) + { + uint8_t fg = palette[_cucul_argb32_to_ansi4fg(lineattr[x])]; + uint8_t bg = palette[_cucul_argb32_to_ansi4bg(lineattr[x])]; + uint32_t c = linechar[x]; + + if(fg != prevfg || bg != prevbg) + { + cur += sprintf(cur, "\033[0;"); + + if(fg < 8) + if(bg < 8) + cur += sprintf(cur, "3%d;4%dm", fg, bg); + else + cur += sprintf(cur, "5;3%d;4%d;10%dm", + fg, bg - 8, bg - 8); + else + if(bg < 8) + cur += sprintf(cur, "1;3%d;4%d;9%dm", + fg - 8, bg, fg - 8); + else + cur += sprintf(cur, "5;1;3%d;4%d;9%d;10%dm", + fg - 8, bg - 8, fg - 8, bg - 8); + } + + *cur++ = c & 0x7f; + + prevfg = fg; + prevbg = bg; + } + + cur += sprintf(cur, "\033[0m\r\n"); + } + + /* Crop to really used size */ + ex->size = (uintptr_t)(cur - ex->data); + ex->data = realloc(ex->data, ex->size); +} + +/* Generate HTML representation of current canvas. */ +static void export_html(cucul_t *qq, cucul_buffer_t *ex) +{ + static int const palette[] = + { + 0x000, 0x008, 0x080, 0x088, 0x800, 0x808, 0x880, 0x888, + 0x444, 0x44f, 0x4f4, 0x4ff, 0xf44, 0xf4f, 0xff4, 0xfff, + }; + char *cur; + unsigned int x, y, len; + + /* The CSS palette: roughly 13000 bytes + * A line: 7 chars for "
\n" + * A glyph: 18 chars for "" + * up to 9 chars for "&#xxxxxx;", far less for pure ASCII + * 7 chars for "" */ + ex->size = 13000 + qq->height * (7 + qq->width * (18 + 9 + 7)); + ex->data = malloc(ex->size); + + cur = ex->data; + + /* HTML header */ + cur += sprintf(cur, "\n\nGenerated by libcaca %s\n", VERSION); + + /* CSS */ + cur += sprintf(cur, "\n\n\n"); + + cur += sprintf(cur, "
\n", + "font-family: monospace, fixed; font-weight: bold;"); + + for(y = 0; y < qq->height; y++) + { + uint32_t *lineattr = qq->attr + y * qq->width; + uint32_t *linechar = qq->chars + y * qq->width; + + for(x = 0; x < qq->width; x += len) + { + cur += sprintf(cur, "", + _cucul_argb32_to_ansi8(lineattr[x])); + + for(len = 0; + x + len < qq->width && lineattr[x + len] == lineattr[x]; + len++) + { + if(linechar[x + len] <= 0x00000020) + cur += sprintf(cur, " "); + else if(linechar[x + len] < 0x00000080) + cur += sprintf(cur, "%c", linechar[x + len]); + else + cur += sprintf(cur, "&#%i;", linechar[x + len]); + } + cur += sprintf(cur, ""); + } + /* New line */ + cur += sprintf(cur, "
\n"); + } + + cur += sprintf(cur, "
\n"); + + /* Crop to really used size */ + ex->size = strlen(ex->data) + 1; + ex->data = realloc(ex->data, ex->size); +} + +/* Export an HTML3 document. This function is way bigger than export_html(), + * but permits viewing in old browsers (or limited ones such as links). It + * will not work under gecko (mozilla rendering engine) unless you set a + * correct header. */ +static void export_html3(cucul_t *qq, cucul_buffer_t *ex) +{ + static int const palette[] = + { + 0x000000, 0x000088, 0x008800, 0x008888, + 0x880000, 0x880088, 0x888800, 0x888888, + 0x444444, 0x4444ff, 0x44ff44, 0x44ffff, + 0xff4444, 0xff44ff, 0xffff44, 0xffffff, + }; + + char *cur; + unsigned int x, y, len; + + /* The CSS palette: roughly 13000 bytes + * A line: 10 chars for "\n" + * A glyph: 40 chars for "" + * up to 9 chars for "&#xxxxxx;", far less for pure ASCII + * 12 chars for "" */ + ex->size = 13000 + qq->height * (10 + qq->width * (40 + 9 + 12)); + ex->data = malloc(ex->size); + + cur = ex->data; + + /* Table */ + cur += sprintf(cur, "\n", + qq->height); + + for(y = 0; y < qq->height; y++) + { + uint32_t *lineattr = qq->attr + y * qq->width; + uint32_t *linechar = qq->chars + y * qq->width; + + cur += sprintf(cur, ""); + + for(x = 0; x < qq->width; x += len) + { + unsigned int i; + + /* Use colspan option to factorize cells with same attributes + * (see below) */ + len = 1; + while(x + len < qq->width && lineattr[x + len] == lineattr[x]) + len++; + + cur += sprintf(cur, ""); + } + cur += sprintf(cur, "\n"); + } + + /* Footer */ + cur += sprintf(cur, "
1) + cur += sprintf(cur, " colspan=%d", len); + + cur += sprintf(cur, ">", + palette[_cucul_argb32_to_ansi4fg(lineattr[x])]); + + for(i = 0; i < len; i++) + { + if(linechar[x + i] <= 0x00000020) + cur += sprintf(cur, " "); + else if(linechar[x + i] < 0x00000080) + cur += sprintf(cur, "%c", linechar[x + i]); + else + cur += sprintf(cur, "&#%i;", linechar[x + i]); + } + + cur += sprintf(cur, "
\n"); + + /* Crop to really used size */ + ex->size = (uintptr_t)(cur - ex->data); + ex->data = realloc(ex->data, ex->size); +} + +/* Export a text file with IRC colours */ +static void export_irc(cucul_t *qq, cucul_buffer_t *ex) +{ + static int const palette[] = + { + 1, 2, 3, 10, 5, 6, 7, 15, /* Dark */ + 14, 12, 9, 11, 4, 13, 8, 0, /* Light */ + }; + + char *cur; + unsigned int x, y; + + /* 11 bytes assumed for max length per pixel. Worst case scenario: + * ^Cxx,yy 6 bytes + * ^B^B 2 bytes + * c 1 byte + * \r\n 2 bytes + * In real life, the average bytes per pixel value will be around 5. + */ + + ex->size = 2 + (qq->width * qq->height * 11); + ex->data = malloc(ex->size); + + cur = ex->data; + + for(y = 0; y < qq->height; y++) + { + uint32_t *lineattr = qq->attr + y * qq->width; + uint32_t *linechar = qq->chars + y * qq->width; + + uint8_t prevfg = -1; + uint8_t prevbg = -1; + + for(x = 0; x < qq->width; x++) + { + uint8_t fg = palette[_cucul_argb32_to_ansi4fg(lineattr[x])]; + uint8_t bg = palette[_cucul_argb32_to_ansi4bg(lineattr[x])]; + uint32_t c = linechar[x]; + + if(bg == prevbg) + { + if(fg == prevfg) + ; /* Same fg/bg, do nothing */ + else if(c == (uint32_t)' ') + fg = prevfg; /* Hackety hack */ + else + { + cur += sprintf(cur, "\x03%d", fg); + if(c >= (uint32_t)'0' && c <= (uint32_t)'9') + cur += sprintf(cur, "\x02\x02"); + } + } + else + { + if(fg == prevfg) + cur += sprintf(cur, "\x03,%d", bg); + else + cur += sprintf(cur, "\x03%d,%d", fg, bg); + + if(c >= (uint32_t)'0' && c <= (uint32_t)'9') + cur += sprintf(cur, "\x02\x02"); + } + *cur++ = c & 0x7f; + prevfg = fg; + prevbg = bg; + } + *cur++ = '\r'; + *cur++ = '\n'; + } + + /* Crop to really used size */ + ex->size = (uintptr_t)(cur - ex->data); + ex->data = realloc(ex->data, ex->size); +} + +/* Export a PostScript document. */ +static void export_ps(cucul_t *qq, cucul_buffer_t *ex) +{ + static char const *ps_header = + "%!\n" + "%% libcaca PDF export\n" + "%%LanguageLevel: 2\n" + "%%Pages: 1\n" + "%%DocumentData: Clean7Bit\n" + "/csquare {\n" + " newpath\n" + " 0 0 moveto\n" + " 0 1 rlineto\n" + " 1 0 rlineto\n" + " 0 -1 rlineto\n" + " closepath\n" + " setrgbcolor\n" + " fill\n" + "} def\n" + "/S {\n" + " Show\n" + "} bind def\n" + "/Courier-Bold findfont\n" + "8 scalefont\n" + "setfont\n" + "gsave\n" + "6 10 scale\n"; + + char *cur; + unsigned int x, y; + + /* 200 is arbitrary but should be ok */ + ex->size = strlen(ps_header) + (qq->width * qq->height * 200); + ex->data = malloc(ex->size); + + cur = ex->data; + + /* Header */ + cur += sprintf(cur, "%s", ps_header); + + /* Background, drawn using csquare macro defined in header */ + for(y = qq->height; y--; ) + { + uint32_t *lineattr = qq->attr + y * qq->width; + + for(x = 0; x < qq->width; x++) + { + uint8_t argb[8]; + _cucul_argb32_to_argb4(*lineattr++, argb); + cur += sprintf(cur, "1 0 translate\n %f %f %f csquare\n", + (float)argb[1] * (1.0 / 0xf), + (float)argb[2] * (1.0 / 0xf), + (float)argb[3] * (1.0 / 0xf)); + } + + /* Return to beginning of the line, and jump to the next one */ + cur += sprintf(cur, "-%d 1 translate\n", qq->width); + } + + cur += sprintf(cur, "grestore\n"); /* Restore transformation matrix */ + + for(y = qq->height; y--; ) + { + uint32_t *lineattr = qq->attr + (qq->height - y - 1) * qq->width; + uint32_t *linechar = qq->chars + (qq->height - y - 1) * qq->width; + + for(x = 0; x < qq->width; x++) + { + uint8_t argb[8]; + uint32_t c = *linechar++; + + _cucul_argb32_to_argb4(*lineattr++, argb); + + cur += sprintf(cur, "newpath\n"); + cur += sprintf(cur, "%d %d moveto\n", (x + 1) * 6, y * 10 + 2); + cur += sprintf(cur, "%f %f %f setrgbcolor\n", + (float)argb[5] * (1.0 / 0xf), + (float)argb[6] * (1.0 / 0xf), + (float)argb[7] * (1.0 / 0xf)); + + if(c < 0x00000020) + cur += sprintf(cur, "(?) show\n"); + else if(c >= 0x00000080) + cur += sprintf(cur, "(?) show\n"); + else switch((uint8_t)(c & 0x7f)) + { + case '\\': + case '(': + case ')': + cur += sprintf(cur, "(\\%c) show\n", c); + break; + default: + cur += sprintf(cur, "(%c) show\n", c); + break; + } + } + } + + cur += sprintf(cur, "showpage\n"); + + /* Crop to really used size */ + ex->size = (uintptr_t)(cur - ex->data); + ex->data = realloc(ex->data, ex->size); +} + +/* Export an SVG vector image */ +static void export_svg(cucul_t *qq, cucul_buffer_t *ex) +{ + static char const svg_header[] = + "\n" + "\n"; + + char *cur; + unsigned int x, y; + + /* 200 is arbitrary but should be ok */ + ex->size = strlen(svg_header) + (qq->width * qq->height * 200); + ex->data = malloc(ex->size); + + cur = ex->data; + + /* Header */ + cur += sprintf(cur, svg_header, qq->width * 6, qq->height * 10, + qq->width * 6, qq->height * 10); + + cur += sprintf(cur, " \n"); + + /* Background */ + for(y = 0; y < qq->height; y++) + { + uint32_t *lineattr = qq->attr + y * qq->width; + + for(x = 0; x < qq->width; x++) + { + cur += sprintf(cur, "\n", + _cucul_argb32_to_rgb12bg(*lineattr++), + x * 6, y * 10); + } + } + + /* Text */ + for(y = 0; y < qq->height; y++) + { + uint32_t *lineattr = qq->attr + y * qq->width; + uint32_t *linechar = qq->chars + y * qq->width; + + for(x = 0; x < qq->width; x++) + { + uint32_t c = *linechar++; + + cur += sprintf(cur, "", + _cucul_argb32_to_rgb12fg(*lineattr++), + x * 6, (y * 10) + 10); + if(c < 0x00000020) + cur += sprintf(cur, "?"); + else if(c > 0x0000007f) + { + static const uint8_t mark[7] = + { + 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC + }; + + char buf[10], *parser; + int bytes = (c < 0x800) ? 2 : (c < 0x10000) ? 3 : 4; + + buf[bytes] = '\0'; + parser = buf + bytes; + + switch(bytes) + { + case 4: *--parser = (c | 0x80) & 0xbf; c >>= 6; + case 3: *--parser = (c | 0x80) & 0xbf; c >>= 6; + case 2: *--parser = (c | 0x80) & 0xbf; c >>= 6; + } + *--parser = c | mark[bytes]; + + cur += sprintf(cur, "%s", buf); + } + else switch((uint8_t)c) + { + case '>': cur += sprintf(cur, ">"); break; + case '<': cur += sprintf(cur, "<"); break; + case '&': cur += sprintf(cur, "&"); break; + default: cur += sprintf(cur, "%c", c); break; + } + cur += sprintf(cur, "\n"); + } + } + + cur += sprintf(cur, " \n"); + cur += sprintf(cur, "\n"); + + /* Crop to really used size */ + ex->size = (uintptr_t)(cur - ex->data); + ex->data = realloc(ex->data, ex->size); +} + +/* Export a TGA image */ +static void export_tga(cucul_t *qq, cucul_buffer_t *ex) +{ + char const * const * fonts; + char * cur; + cucul_font_t *f; + unsigned int i, w, h; + + fonts = cucul_get_font_list(); + if(!fonts[0]) + return; + + f = cucul_load_font(fonts[0], 0); + + w = cucul_get_width(qq) * cucul_get_font_width(f); + h = cucul_get_height(qq) * cucul_get_font_height(f); + + ex->size = w * h * 4 + 18; /* 32 bpp + 18 bytes for the header */ + ex->data = malloc(ex->size); + + cur = ex->data; + + /* ID Length */ + cur += sprintf(cur, "%c", 0); + /* Color Map Type: no colormap */ + cur += sprintf(cur, "%c", 0); + /* Image Type: uncompressed truecolor */ + cur += sprintf(cur, "%c", 2); + /* Color Map Specification: no color map */ + memset(cur, 0, 5); cur += 5; + + /* Image Specification */ + cur += sprintf(cur, "%c%c", 0, 0); /* X Origin */ + cur += sprintf(cur, "%c%c", 0, 0); /* Y Origin */ + cur += sprintf(cur, "%c%c", w & 0xff, w >> 8); /* Width */ + cur += sprintf(cur, "%c%c", h & 0xff, h >> 8); /* Height */ + cur += sprintf(cur, "%c", 32); /* Pixel Depth */ + cur += sprintf(cur, "%c", 40); /* Image Descriptor */ + + /* Image ID: no ID */ + /* Color Map Data: no colormap */ + + /* Image Data */ + cucul_render_canvas(qq, f, cur, w, h, 4 * w); + + /* Swap bytes. What a waste of time. */ + for(i = 0; i < w * h * 4; i += 4) + { + char w; + w = cur[i]; cur[i] = cur[i + 3]; cur[i + 3] = w; + w = cur[i + 1]; cur[i + 1] = cur[i + 2]; cur[i + 2] = w; + } + + cucul_free_font(f); +} + diff --git a/cucul/export_ansi.c b/cucul/export_ansi.c deleted file mode 100644 index 59645db..0000000 --- a/cucul/export_ansi.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * libcucul Canvas for ultrafast compositing of Unicode letters - * Copyright (c) 2002-2006 Sam Hocevar - * 2006 Jean-Yves Lamoureux - * All Rights Reserved - * - * $Id$ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the Do What The Fuck You Want To - * Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - */ - -/* - * This file contains export functions for ANSI - */ - -#include "config.h" - -#if !defined(__KERNEL__) -# include -# include -# include -#endif - -#include "cucul.h" -#include "cucul_internals.h" - -/** \brief Generate ANSI representation of current image. - * - * This function generates and returns an ANSI representation of - * the current image. - * \param trailing if 0, raw ANSI will be generated. Otherwise, you'll be - * able to cut/paste the result to a function like printf - * \return buffer containing generated ANSI codes as a big string - */ -void _cucul_get_ansi(cucul_t *qq, cucul_buffer_t *ex) -{ - static int const palette[] = - { - 0, 4, 2, 6, 1, 5, 3, 7, - 8, 12, 10, 14, 9, 13, 11, 15 - }; - - char *cur; - unsigned int x, y; - - /* 23 bytes assumed for max length per pixel ('\e[5;1;3x;4y;9x;10ym' plus - * 4 max bytes for a UTF-8 character). - * Add height*9 to that (zeroes color at the end and jump to next line) */ - ex->size = (qq->height * 9) + (qq->width * qq->height * 23); - ex->data = malloc(ex->size); - - cur = ex->data; - - for(y = 0; y < qq->height; y++) - { - uint32_t *lineattr = qq->attr + y * qq->width; - uint32_t *linechar = qq->chars + y * qq->width; - - uint8_t prevfg = -1; - uint8_t prevbg = -1; - - for(x = 0; x < qq->width; x++) - { - uint8_t fg = palette[_cucul_argb32_to_ansi4fg(lineattr[x])]; - uint8_t bg = palette[_cucul_argb32_to_ansi4bg(lineattr[x])]; - uint32_t c = linechar[x]; - - if(fg != prevfg || bg != prevbg) - { - cur += sprintf(cur, "\033[0;"); - - if(fg < 8) - if(bg < 8) - cur += sprintf(cur, "3%d;4%dm", fg, bg); - else - cur += sprintf(cur, "5;3%d;4%d;10%dm", - fg, bg - 8, bg - 8); - else - if(bg < 8) - cur += sprintf(cur, "1;3%d;4%d;9%dm", - fg - 8, bg, fg - 8); - else - cur += sprintf(cur, "5;1;3%d;4%d;9%d;10%dm", - fg - 8, bg - 8, fg - 8, bg - 8); - } - - *cur++ = c & 0x7f; - - prevfg = fg; - prevbg = bg; - } - - cur += sprintf(cur, "\033[0m\r\n"); - } - - /* Crop to really used size */ - ex->size = (uintptr_t)(cur - ex->data); - ex->data = realloc(ex->data, ex->size); -} - diff --git a/cucul/export_bitmap.c b/cucul/export_bitmap.c deleted file mode 100644 index 7022229..0000000 --- a/cucul/export_bitmap.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * libcucul Canvas for ultrafast compositing of Unicode letters - * Copyright (c) 2002-2006 Sam Hocevar - * All Rights Reserved - * - * $Id$ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the Do What The Fuck You Want To - * Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - */ - -/* - * This file contains export functions for bitmap formats - */ - -#include "config.h" - -#if !defined(__KERNEL__) -# include -# include -# include -#endif - -#include "cucul.h" -#include "cucul_internals.h" - -void _cucul_get_tga(cucul_t *qq, cucul_buffer_t *ex) -{ - char const * const * fonts; - char * cur; - cucul_font_t *f; - unsigned int i, w, h; - - fonts = cucul_get_font_list(); - if(!fonts[0]) - return; - - f = cucul_load_font(fonts[0], 0); - - w = cucul_get_width(qq) * cucul_get_font_width(f); - h = cucul_get_height(qq) * cucul_get_font_height(f); - - ex->size = w * h * 4 + 18; - ex->data = malloc(ex->size); - - cur = ex->data; - - /* ID Length */ - cur += sprintf(cur, "%c", 0); - /* Color Map Type: no colormap */ - cur += sprintf(cur, "%c", 0); - /* Image Type: uncompressed truecolor */ - cur += sprintf(cur, "%c", 2); - /* Color Map Specification: no color map */ - memset(cur, 0, 5); cur += 5; - - /* Image Specification */ - cur += sprintf(cur, "%c%c", 0, 0); /* X Origin */ - cur += sprintf(cur, "%c%c", 0, 0); /* Y Origin */ - cur += sprintf(cur, "%c%c", w & 0xff, w >> 8); /* Width */ - cur += sprintf(cur, "%c%c", h & 0xff, h >> 8); /* Height */ - cur += sprintf(cur, "%c", 32); /* Pixel Depth */ - cur += sprintf(cur, "%c", 40); /* Image Descriptor */ - - /* Image ID: no ID */ - /* Color Map Data: no colormap */ - - /* Image Data */ - cucul_render_canvas(qq, f, cur, w, h, 4 * w); - - /* Swap bytes. What a waste of time. */ - for(i = 0; i < w * h * 4; i += 4) - { - char w; - w = cur[i]; cur[i] = cur[i + 3]; cur[i + 3] = w; - w = cur[i + 1]; cur[i + 1] = cur[i + 2]; cur[i + 2] = w; - } - - cucul_free_font(f); -} - diff --git a/cucul/export_html.c b/cucul/export_html.c deleted file mode 100644 index c5be03c..0000000 --- a/cucul/export_html.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * libcucul Canvas for ultrafast compositing of Unicode letters - * Copyright (c) 2002-2006 Sam Hocevar - * 2006 Jean-Yves Lamoureux - * All Rights Reserved - * - * $Id$ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the Do What The Fuck You Want To - * Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - */ - -/* - * This file contains export functions for HTML and HTML3 - */ - -#include "config.h" - -#if !defined(__KERNEL__) -# include -# include -# include -#endif - -#include "cucul.h" -#include "cucul_internals.h" - -/** \brief Generate HTML representation of current image. - * - * This function generates and returns the HTML representation of - * the current image. - */ -void _cucul_get_html(cucul_t *qq, cucul_buffer_t *ex) -{ - static int const palette[] = - { - 0x000, 0x008, 0x080, 0x088, 0x800, 0x808, 0x880, 0x888, - 0x444, 0x44f, 0x4f4, 0x4ff, 0xf44, 0xf4f, 0xff4, 0xfff, - }; - char *cur; - unsigned int x, y, len; - - /* The CSS palette: roughly 13000 bytes - * A line: 7 chars for "
\n" - * A glyph: 18 chars for "" - * up to 9 chars for "&#xxxxxx;", far less for pure ASCII - * 7 chars for "" */ - ex->size = 13000 + qq->height * (7 + qq->width * (18 + 9 + 7)); - ex->data = malloc(ex->size); - - cur = ex->data; - - /* HTML header */ - cur += sprintf(cur, "\n\nGenerated by libcaca %s\n", VERSION); - - /* CSS */ - cur += sprintf(cur, "\n\n\n"); - - cur += sprintf(cur, "
\n", - "font-family: monospace, fixed; font-weight: bold;"); - - for(y = 0; y < qq->height; y++) - { - uint32_t *lineattr = qq->attr + y * qq->width; - uint32_t *linechar = qq->chars + y * qq->width; - - for(x = 0; x < qq->width; x += len) - { - cur += sprintf(cur, "", - _cucul_argb32_to_ansi8(lineattr[x])); - - for(len = 0; - x + len < qq->width && lineattr[x + len] == lineattr[x]; - len++) - { - if(linechar[x + len] <= 0x00000020) - cur += sprintf(cur, " "); - else if(linechar[x + len] < 0x00000080) - cur += sprintf(cur, "%c", linechar[x + len]); - else - cur += sprintf(cur, "&#%i;", linechar[x + len]); - } - cur += sprintf(cur, ""); - } - /* New line */ - cur += sprintf(cur, "
\n"); - } - - cur += sprintf(cur, "
\n"); - - /* Crop to really used size */ - ex->size = strlen(ex->data) + 1; - ex->data = realloc(ex->data, ex->size); -} - - -/** \brief Generate HTML3 representation of current image. - * - * This function generates and returns the HTML3 representation of - * the current image. It is way bigger than cucul_get_html(), but - * permits viewing in old browsers (or limited ones such as links) - * Won't work under gecko (mozilla rendering engine) unless you set - * a correct header. - */ -void _cucul_get_html3(cucul_t *qq, cucul_buffer_t *ex) -{ - static int const palette[] = - { - 0x000000, 0x000088, 0x008800, 0x008888, - 0x880000, 0x880088, 0x888800, 0x888888, - 0x444444, 0x4444ff, 0x44ff44, 0x44ffff, - 0xff4444, 0xff44ff, 0xffff44, 0xffffff, - }; - - char *cur; - unsigned int x, y, len; - - /* The CSS palette: roughly 13000 bytes - * A line: 10 chars for "\n" - * A glyph: 40 chars for "" - * up to 9 chars for "&#xxxxxx;", far less for pure ASCII - * 12 chars for "" */ - ex->size = 13000 + qq->height * (10 + qq->width * (40 + 9 + 12)); - ex->data = malloc(ex->size); - - cur = ex->data; - - /* Table */ - cur += sprintf(cur, "\n", - qq->height); - - for(y = 0; y < qq->height; y++) - { - uint32_t *lineattr = qq->attr + y * qq->width; - uint32_t *linechar = qq->chars + y * qq->width; - - cur += sprintf(cur, ""); - - for(x = 0; x < qq->width; x += len) - { - unsigned int i; - - /* Use colspan option to factorize cells with same attributes - * (see below) */ - len = 1; - while(x + len < qq->width && lineattr[x + len] == lineattr[x]) - len++; - - cur += sprintf(cur, ""); - } - cur += sprintf(cur, "\n"); - } - - /* Footer */ - cur += sprintf(cur, "
1) - cur += sprintf(cur, " colspan=%d", len); - - cur += sprintf(cur, ">", - palette[_cucul_argb32_to_ansi4fg(lineattr[x])]); - - for(i = 0; i < len; i++) - { - if(linechar[x + i] <= 0x00000020) - cur += sprintf(cur, " "); - else if(linechar[x + i] < 0x00000080) - cur += sprintf(cur, "%c", linechar[x + i]); - else - cur += sprintf(cur, "&#%i;", linechar[x + i]); - } - - cur += sprintf(cur, "
\n"); - - /* Crop to really used size */ - ex->size = (uintptr_t)(cur - ex->data); - ex->data = realloc(ex->data, ex->size); -} - - diff --git a/cucul/export_irc.c b/cucul/export_irc.c deleted file mode 100644 index b910ff7..0000000 --- a/cucul/export_irc.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * libcucul Canvas for ultrafast compositing of Unicode letters - * Copyright (c) 2002-2006 Sam Hocevar - * 2006 Jean-Yves Lamoureux - * All Rights Reserved - * - * $Id$ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the Do What The Fuck You Want To - * Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - */ - -/* - * This file contains export functions for IRC - */ - -#include "config.h" - -#if !defined(__KERNEL__) -# include -# include -# include -#endif - -#include "cucul.h" -#include "cucul_internals.h" - -/** \brief Generate IRC representation of current image. - * - * This function generates and returns an IRC representation of - * the current image. - */ -void _cucul_get_irc(cucul_t *qq, cucul_buffer_t *ex) -{ - static int const palette[] = - { - 1, 2, 3, 10, 5, 6, 7, 15, /* Dark */ - 14, 12, 9, 11, 4, 13, 8, 0, /* Light */ - }; - - char *cur; - unsigned int x, y; - - /* 11 bytes assumed for max length per pixel. Worst case scenario: - * ^Cxx,yy 6 bytes - * ^B^B 2 bytes - * c 1 byte - * \r\n 2 bytes - * In real life, the average bytes per pixel value will be around 5. - */ - - ex->size = 2 + (qq->width * qq->height * 11); - ex->data = malloc(ex->size); - - cur = ex->data; - - for(y = 0; y < qq->height; y++) - { - uint32_t *lineattr = qq->attr + y * qq->width; - uint32_t *linechar = qq->chars + y * qq->width; - - uint8_t prevfg = -1; - uint8_t prevbg = -1; - - for(x = 0; x < qq->width; x++) - { - uint8_t fg = palette[_cucul_argb32_to_ansi4fg(lineattr[x])]; - uint8_t bg = palette[_cucul_argb32_to_ansi4bg(lineattr[x])]; - uint32_t c = linechar[x]; - - if(bg == prevbg) - { - if(fg == prevfg) - ; /* Same fg/bg, do nothing */ - else if(c == (uint32_t)' ') - fg = prevfg; /* Hackety hack */ - else - { - cur += sprintf(cur, "\x03%d", fg); - if(c >= (uint32_t)'0' && c <= (uint32_t)'9') - cur += sprintf(cur, "\x02\x02"); - } - } - else - { - if(fg == prevfg) - cur += sprintf(cur, "\x03,%d", bg); - else - cur += sprintf(cur, "\x03%d,%d", fg, bg); - - if(c >= (uint32_t)'0' && c <= (uint32_t)'9') - cur += sprintf(cur, "\x02\x02"); - } - *cur++ = c & 0x7f; - prevfg = fg; - prevbg = bg; - } - *cur++ = '\r'; - *cur++ = '\n'; - } - - /* Crop to really used size */ - ex->size = (uintptr_t)(cur - ex->data); - ex->data = realloc(ex->data, ex->size); -} diff --git a/cucul/export_ps.c b/cucul/export_ps.c deleted file mode 100644 index 9709ccd..0000000 --- a/cucul/export_ps.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * libcucul Canvas for ultrafast compositing of Unicode letters - * Copyright (c) 2002-2006 Sam Hocevar - * 2006 Jean-Yves Lamoureux - * All Rights Reserved - * - * $Id$ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the Do What The Fuck You Want To - * Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - */ - -/* - * This file contains export functions for Postscript files - */ - -#include "config.h" - -#if !defined(__KERNEL__) -# include -# include -# include -#endif - -#include "cucul.h" -#include "cucul_internals.h" - -static char const *ps_header = - "%!\n" - "%% libcaca PDF export\n" - "%%LanguageLevel: 2\n" - "%%Pages: 1\n" - "%%DocumentData: Clean7Bit\n" - "/csquare {\n" - " newpath\n" - " 0 0 moveto\n" - " 0 1 rlineto\n" - " 1 0 rlineto\n" - " 0 -1 rlineto\n" - " closepath\n" - " setrgbcolor\n" - " fill\n" - "} def\n" - "/S {\n" - " Show\n" - "} bind def\n" - "/Courier-Bold findfont\n" - "8 scalefont\n" - "setfont\n" - "gsave\n" - "6 10 scale\n"; - -/** \brief Generate Postscript representation of current image. - * - * This function generates and returns a Postscript representation of - * the current image. - */ -void _cucul_get_ps(cucul_t *qq, cucul_buffer_t *ex) -{ - char *cur; - unsigned int x, y; - - /* 200 is arbitrary but should be ok */ - ex->size = strlen(ps_header) + (qq->width * qq->height * 200); - ex->data = malloc(ex->size); - - cur = ex->data; - - /* Header */ - cur += sprintf(cur, "%s", ps_header); - - /* Background, drawn using csquare macro defined in header */ - for(y = qq->height; y--; ) - { - uint32_t *lineattr = qq->attr + y * qq->width; - - for(x = 0; x < qq->width; x++) - { - uint8_t argb[8]; - _cucul_argb32_to_argb4(*lineattr++, argb); - cur += sprintf(cur, "1 0 translate\n %f %f %f csquare\n", - (float)argb[1] * (1.0 / 0xf), - (float)argb[2] * (1.0 / 0xf), - (float)argb[3] * (1.0 / 0xf)); - } - - /* Return to beginning of the line, and jump to the next one */ - cur += sprintf(cur, "-%d 1 translate\n", qq->width); - } - - cur += sprintf(cur, "grestore\n"); /* Restore transformation matrix */ - - for(y = qq->height; y--; ) - { - uint32_t *lineattr = qq->attr + (qq->height - y - 1) * qq->width; - uint32_t *linechar = qq->chars + (qq->height - y - 1) * qq->width; - - for(x = 0; x < qq->width; x++) - { - uint8_t argb[8]; - uint32_t c = *linechar++; - - _cucul_argb32_to_argb4(*lineattr++, argb); - - cur += sprintf(cur, "newpath\n"); - cur += sprintf(cur, "%d %d moveto\n", (x + 1) * 6, y * 10 + 2); - cur += sprintf(cur, "%f %f %f setrgbcolor\n", - (float)argb[5] * (1.0 / 0xf), - (float)argb[6] * (1.0 / 0xf), - (float)argb[7] * (1.0 / 0xf)); - - if(c < 0x00000020) - cur += sprintf(cur, "(?) show\n"); - else if(c >= 0x00000080) - cur += sprintf(cur, "(?) show\n"); - else switch((uint8_t)(c & 0x7f)) - { - case '\\': - case '(': - case ')': - cur += sprintf(cur, "(\\%c) show\n", c); - break; - default: - cur += sprintf(cur, "(%c) show\n", c); - break; - } - } - } - - cur += sprintf(cur, "showpage\n"); - - /* Crop to really used size */ - ex->size = (uintptr_t)(cur - ex->data); - ex->data = realloc(ex->data, ex->size); -} - diff --git a/cucul/export_svg.c b/cucul/export_svg.c deleted file mode 100644 index 8da4ad9..0000000 --- a/cucul/export_svg.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * libcucul Canvas for ultrafast compositing of Unicode letters - * Copyright (c) 2002-2006 Sam Hocevar - * 2006 Jean-Yves Lamoureux - * All Rights Reserved - * - * $Id$ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the Do What The Fuck You Want To - * Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - */ - -/* - * This file contains export functions for SVG (Scalable Vector Graphics files - */ - -#include "config.h" - -#if !defined(__KERNEL__) -# include -# include -# include -#endif - -#include "cucul.h" -#include "cucul_internals.h" - -static char const svg_header[] = - "\n" - "\n"; - -/* - * This function generates and returns an SVG representation of - * the current image. - */ -void _cucul_get_svg(cucul_t *qq, cucul_buffer_t *ex) -{ - char *cur; - unsigned int x, y; - - /* 200 is arbitrary but should be ok */ - ex->size = strlen(svg_header) + (qq->width * qq->height * 200); - ex->data = malloc(ex->size); - - cur = ex->data; - - /* Header */ - cur += sprintf(cur, svg_header, qq->width * 6, qq->height * 10, - qq->width * 6, qq->height * 10); - - cur += sprintf(cur, " \n"); - - /* Background */ - for(y = 0; y < qq->height; y++) - { - uint32_t *lineattr = qq->attr + y * qq->width; - - for(x = 0; x < qq->width; x++) - { - cur += sprintf(cur, "\n", - _cucul_argb32_to_rgb12bg(*lineattr++), - x * 6, y * 10); - } - } - - /* Text */ - for(y = 0; y < qq->height; y++) - { - uint32_t *lineattr = qq->attr + y * qq->width; - uint32_t *linechar = qq->chars + y * qq->width; - - for(x = 0; x < qq->width; x++) - { - uint32_t c = *linechar++; - - cur += sprintf(cur, "", - _cucul_argb32_to_rgb12fg(*lineattr++), - x * 6, (y * 10) + 10); - if(c < 0x00000020) - cur += sprintf(cur, "?"); - else if(c > 0x0000007f) - { - static const uint8_t mark[7] = - { - 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC - }; - - char buf[10], *parser; - int bytes = (c < 0x800) ? 2 : (c < 0x10000) ? 3 : 4; - - buf[bytes] = '\0'; - parser = buf + bytes; - - switch(bytes) - { - case 4: *--parser = (c | 0x80) & 0xbf; c >>= 6; - case 3: *--parser = (c | 0x80) & 0xbf; c >>= 6; - case 2: *--parser = (c | 0x80) & 0xbf; c >>= 6; - } - *--parser = c | mark[bytes]; - - cur += sprintf(cur, "%s", buf); - } - else switch((uint8_t)c) - { - case '>': cur += sprintf(cur, ">"); break; - case '<': cur += sprintf(cur, "<"); break; - case '&': cur += sprintf(cur, "&"); break; - default: cur += sprintf(cur, "%c", c); break; - } - cur += sprintf(cur, "\n"); - } - } - - cur += sprintf(cur, " \n"); - cur += sprintf(cur, "\n"); - - /* Crop to really used size */ - ex->size = (uintptr_t)(cur - ex->data); - ex->data = realloc(ex->data, ex->size); -} -