source: libcaca/trunk/cucul/export.c @ 571

Last change on this file since 571 was 571, checked in by Jean-Yves Lamoureux, 16 years ago
  • Updated README for network driver, fixed remaining exporters
  • Property svn:keywords set to Id
File size: 10.0 KB
Line 
1/*
2 *  libcucul      Unicode canvas library
3 *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  This library is free software; you can redistribute it and/or
7 *  modify it under the terms of the Do What The Fuck You Want To
8 *  Public License, Version 2, as published by Sam Hocevar. See
9 *  http://sam.zoy.org/wtfpl/COPYING for more details.
10 */
11
12/** \file export.c
13 *  \version \$Id: export.c 571 2006-03-09 13:08:41Z jylam $
14 *  \author Sam Hocevar <sam@zoy.org>
15 *  \author Jean-Yves Lamoureux <jylam@lnxscene.org>
16 *  \brief Export function
17 *
18 *  This file contains export functions for various file formats such
19 *  as HTML or IRC.
20 */
21
22#include "config.h"
23
24#if !defined(__KERNEL__)
25#   include <stdlib.h>
26#   include <stdio.h>
27#   include <string.h>
28#endif
29
30#include "cucul.h"
31#include "cucul_internals.h"
32
33/* HTML */
34
35/** \brief Generate HTML representation of current image.
36 *
37 *  This function generates and returns the HTML representation of
38 *  the current image.
39 */
40char* cucul_get_html(cucul_t *qq, int *size)
41{
42    static int const palette[] =
43    {
44        0x000, 0x008, 0x080, 0x088, 0x800, 0x808, 0x880, 0x888,
45        0x444, 0x44f, 0x4f4, 0x4ff, 0xf44, 0xf4f, 0xff4, 0xfff,
46    };
47    char *cur;
48    unsigned int x, y, len;
49
50    /* 13000 -> css palette
51     * 40 -> max size used for a pixel (plus 10, never know)*/
52    /* FIXME: Check this value */
53    if(qq->html_buffer)
54        free(qq->html_buffer);
55
56    qq->html_buffer = malloc((13000 + ((qq->width*qq->height) * 40)) * sizeof(char));
57    cur = qq->html_buffer;
58
59    /* HTML header */
60    cur += sprintf(cur, "<html>\n<head>\n<title>Generated by libcaca %s</title>\n", VERSION);
61
62    /* CSS */
63    cur += sprintf(cur, "<style>\n");
64    cur += sprintf(cur, ".caca { font-family: monospace, fixed; font-weight: bold; }");
65    for(x = 0; x < 0x100; x++)
66    {
67        cur += sprintf(cur, ".b%02x { color:#%03x; background-color:#%03x; }\n",
68                       x, palette[x & 0xf ], palette[x >> 4]);
69    }
70    cur += sprintf(cur, "</style>\n</head>\n<body>\n");
71
72    cur += sprintf(cur, "<div cellpadding='0' cellspacing='0' style='%s'>\n",
73                        "font-family: monospace, fixed; font-weight: bold;");
74
75    for(y = 0; y < qq->height; y++)
76    {
77        uint8_t *lineattr = qq->attr + y * qq->width;
78        uint32_t *linechar = qq->chars + y * qq->width;
79
80        for(x = 0; x < qq->width; x += len)
81        {
82            cur += sprintf(cur, "<span class='b%02x'>", lineattr[x]);
83
84            for(len = 0;
85                x + len < qq->width && lineattr[x + len] == lineattr[x];
86                len++)
87            {
88                if(linechar[x + len] == (uint32_t)' ')
89                    cur += sprintf(cur, "&nbsp;");
90                else
91                    cur += sprintf(cur, "%c", linechar[x + len] & 0x7f);
92            }
93            cur += sprintf(cur, "</span>");
94        }
95        /* New line */
96        cur += sprintf(cur, "<br />\n");
97    }
98
99    cur += sprintf(cur, "</div></body></html>\n");
100
101    /* Crop to really used size */
102    *size = (strlen(qq->html_buffer) + 1) * sizeof(char);
103    qq->html_buffer = realloc(qq->html_buffer, *size);
104
105    return qq->html_buffer;
106}
107
108/** \brief Generate HTML3 representation of current image.
109 *
110 *  This function generates and returns the HTML3 representation of
111 *  the current image. It is way bigger than cucul_get_html(), but
112 *  permits viewing in old browsers (or limited ones such as links)
113 *  Won't work under gecko (mozilla rendering engine) unless you set
114 *  a correct header.
115 */
116char* cucul_get_html3(cucul_t *qq, int *size)
117{
118    static int const palette[] =
119    {
120        0x000000, 0x000088, 0x008800, 0x008888,
121        0x880000, 0x880088, 0x888800, 0x888888,
122        0x444444, 0x4444ff, 0x44ff44, 0x44ffff,
123        0xff4444, 0xff44ff, 0xffff44, 0xffffff,
124    };
125    char *cur;
126    unsigned int x, y, len;
127
128    /* 13000 -> css palette
129     * 40 -> max size used for a pixel (plus 10, never know) */
130
131    if(qq->html3_buffer)
132        free(qq->html3_buffer);
133
134    qq->html3_buffer = malloc((13000 + ((qq->width*qq->height)*40))*sizeof(char));
135    cur = qq->html3_buffer;
136
137    /* Table */
138    cur += sprintf(cur, "<table cols='%d' cellpadding='0' cellspacing='0'>\n",
139                        qq->height);
140
141    for(y = 0; y < qq->height; y++)
142    {
143        uint8_t *lineattr = qq->attr + y * qq->width;
144        uint32_t *linechar = qq->chars + y * qq->width;
145
146        cur += sprintf(cur, "<tr>");
147
148        for(x = 0; x < qq->width; x += len)
149        {
150            unsigned int i;
151
152            /* Use colspan option to factorize cells with same attributes
153             * (see below) */
154            len = 1;
155            while(x + len < qq->width && lineattr[x + len] == lineattr[x])
156                len++;
157
158            cur += sprintf(cur, "<td bgcolor=#%06x", palette[lineattr[x] >> 4]);
159
160            if(len > 1)
161                cur += sprintf(cur, " colspan=%d", len);
162
163            cur += sprintf(cur, "><font color=#%06x>",
164                                palette[lineattr[x] & 0x0f]);
165
166            for(i = 0; i < len; i++)
167            {
168                if(linechar[x + i] == (uint32_t)' ')
169                    cur += sprintf(cur, "&nbsp;");
170                else
171                    cur += sprintf(cur, "%c", linechar[x + i] & 0x7f);
172            }
173
174            cur += sprintf(cur, "</font></td>");
175        }
176        cur += sprintf(cur, "</tr>\n");
177    }
178
179    /* Footer */
180    cur += sprintf(cur, "</table>\n");
181
182    /* Crop to really used size */
183    *size = (strlen(qq->html3_buffer) + 1) * sizeof(char);
184    qq->html3_buffer = realloc(qq->html3_buffer, *size);
185   
186    return qq->html3_buffer;
187}
188
189/** \brief Generate IRC representation of current image.
190 *
191 *  This function generates and returns an IRC representation of
192 *  the current image.
193 */
194char* cucul_get_irc(cucul_t *qq, int *size)
195{
196    static int const palette[] =
197    {
198        1, 2, 3, 10, 5, 6, 7, 15, /* Dark */
199        14, 12, 9, 11, 4, 13, 8, 0, /* Light */
200    };
201
202    char *cur;
203    unsigned int x, y;
204
205    /* 11 bytes assumed for max length per pixel. Worst case scenario:
206     * ^Cxx,yy   6 bytes
207     * ^B^B      2 bytes
208     * c         1 byte
209     * \r\n      2 bytes
210     * In real life, the average bytes per pixel value will be around 5.
211     */
212
213    if(qq->irc_buffer)
214        free(qq->irc_buffer);
215
216    qq->irc_buffer = malloc((2 + (qq->width * qq->height * 11)) * sizeof(char));
217    cur = qq->irc_buffer;
218
219    *cur++ = '\x0f';
220
221    for(y = 0; y < qq->height; y++)
222    {
223        uint8_t *lineattr = qq->attr + y * qq->width;
224        uint32_t *linechar = qq->chars + y * qq->width;
225
226        uint8_t prevfg = -1;
227        uint8_t prevbg = -1;
228
229        for(x = 0; x < qq->width; x++)
230        {
231            uint8_t fg = palette[lineattr[x] & 0x0f];
232            uint8_t bg = palette[lineattr[x] >> 4];
233            uint32_t c = linechar[x];
234
235            if(bg == prevbg)
236            {
237                if(fg == prevfg)
238                    ; /* Same fg/bg, do nothing */
239                else if(c == (uint32_t)' ')
240                    fg = prevfg; /* Hackety hack */
241                else
242                {
243                    cur += sprintf(cur, "\x03%d", fg);
244                    if(c >= (uint32_t)'0' && c <= (uint32_t)'9')
245                        cur += sprintf(cur, "\x02\x02");
246                }
247            }
248            else
249            {
250                if(fg == prevfg)
251                    cur += sprintf(cur, "\x03,%d", bg);
252                else
253                    cur += sprintf(cur, "\x03%d,%d", fg, bg);
254
255                if(c >= (uint32_t)'0' && c <= (uint32_t)'9')
256                    cur += sprintf(cur, "\x02\x02");
257            }
258            *cur++ = c & 0x7f;
259            prevfg = fg;
260            prevbg = bg;
261        }
262        *cur++ = '\r';
263        *cur++ = '\n';
264    }
265
266    *cur++ = '\x0f';
267
268    /* Crop to really used size */
269    *size = (strlen(qq->irc_buffer) + 1) * sizeof(char);
270    qq->irc_buffer = realloc(qq->irc_buffer, *size);
271
272    return qq->irc_buffer;
273}
274
275/** \brief Generate ANSI representation of current image.
276 *
277 *  This function generates and returns an ANSI representation of
278 *  the current image.
279 *  \param trailing if 0, raw ANSI will be generated. Otherwise, you'll be
280 *                  able to cut/paste the result to a function like printf
281 *  \return buffer containing generated ANSI codes as a big string
282 */
283char * cucul_get_ansi(cucul_t *qq, int trailing, int *size)
284{
285    static int const palette[] =
286    {
287        30, 34, 32, 36, 31, 35, 33, 37, /* Both lines (light and dark) are the same, */
288        30, 34, 32, 36, 31, 35, 33, 37, /* light colors handling is done later */
289    };
290
291    char *cur;
292    unsigned int x, y;
293
294    /* 20 bytes assumed for max length per pixel.
295     * Add height*9 to that (zeroes color at the end and jump to next line) */
296    if(qq->ansi_buffer)
297        free(qq->ansi_buffer);
298    qq->ansi_buffer = malloc(((qq->height*9) + (qq->width * qq->height * 20)) * sizeof(char));
299    cur = qq->ansi_buffer;
300
301    // *cur++ = '';
302
303    for(y = 0; y < qq->height; y++)
304    {
305        uint8_t *lineattr = qq->attr + y * qq->width;
306        uint32_t *linechar = qq->chars + y * qq->width;
307
308        uint8_t prevfg = -1;
309        uint8_t prevbg = -1;
310
311        for(x = 0; x < qq->width; x++)
312        {
313            uint8_t fg = palette[lineattr[x] & 0x0f];
314            uint8_t bg = (palette[lineattr[x] >> 4])+10;
315            uint32_t c = linechar[x];
316
317            if(!trailing)
318                cur += sprintf(cur, "\033[");
319            else
320                cur += sprintf(cur, "\\033[");
321
322            if(fg > 7)
323                cur += sprintf(cur, "1;%d;%dm",fg,bg);
324            else
325                cur += sprintf(cur, "0;%d;%dm",fg,bg);
326            *cur++ = c & 0x7f;
327            if((c == '%') && trailing)
328                *cur++ = c & 0x7f;
329            prevfg = fg;
330            prevbg = bg;
331        }
332        if(!trailing)
333            cur += sprintf(cur, "\033[0m\n\r");
334        else
335            cur += sprintf(cur, "\\033[0m\\n\n");
336    }
337
338    /* Crop to really used size */
339    *size = (strlen(qq->ansi_buffer) + 1)* sizeof(char);
340    qq->ansi_buffer = realloc(qq->ansi_buffer, *size);
341
342    return qq->ansi_buffer;
343}
344
Note: See TracBrowser for help on using the repository browser.