source: libcaca/trunk/cucul/export_svg.c @ 644

Last change on this file since 644 was 644, checked in by Sam Hocevar, 14 years ago
  • Renamed cucul_buffer to cucul_export. Vanilla rum rules.
  • Property svn:keywords set to Id
File size: 4.5 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_svg.c 644 2006-03-18 00:06:24Z sam $
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 SVG (Scalable Vector Graphics files
19 */
20
21#include "config.h"
22
23#if !defined(__KERNEL__)
24#   include <stdlib.h>
25#   include <stdio.h>
26#   include <string.h>
27#endif
28
29#include "cucul.h"
30#include "cucul_internals.h"
31
32static char const svg_header[] =
33    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
34    "<svg width=\"%d\" height=\"%d\" viewBox=\"0 0 %d %d\""
35    " xmlns=\"http://www.w3.org/2000/svg\""
36    " xmlns:xlink=\"http://www.w3.org/1999/xlink\""
37    " xml:space=\"preserve\" version=\"1.1\"  baseProfile=\"full\">\n"
38    " <defs>\n"
39    "  <style type=\"text/css\">\n"
40    "    <![CDATA[\n";
41
42/** \brief Generate SVG representation of current image.
43 *
44 *  This function generates and returns a SVG representation of
45 *  the current image.
46 */
47void _cucul_get_svg(cucul_t *qq, struct cucul_export *ex)
48{
49    static int const palette[] =
50    {
51        0x000000, 0x000088, 0x008800, 0x008888,
52        0x880000, 0x880088, 0x888800, 0x888888,
53        0x444444, 0x4444ff, 0x44ff44, 0x44ffff,
54        0xff4444, 0xff44ff, 0xffff44, 0xffffff,
55    };
56
57    char *cur;
58    unsigned int x, y;
59
60    /* 200 is arbitrary but should be ok */
61    ex->size = strlen(svg_header) + (qq->width * qq->height * 200);
62    ex->buffer = malloc(ex->size);
63
64    cur = ex->buffer;
65
66    /* Header */
67    cur += sprintf(cur, svg_header, qq->width * 6, qq->height * 10,
68                                    qq->width * 6, qq->height * 10);
69
70    /* Precalc of colors in CSS style  */
71    for(x = 0; x < 0x100; x++)
72    {
73        cur += sprintf(cur, ".b%02x {fill:#%06X}\n", x, palette[x >> 4]);
74        cur += sprintf(cur, ".f%02x {fill:#%06X}\n", x, palette[x & 0xf]);
75    }
76
77    cur += sprintf(cur, "]]>\n");
78    cur += sprintf(cur, "  </style>\n");
79    cur += sprintf(cur, " </defs>\n");
80    cur += sprintf(cur, " <g id=\"mainlayer\" font-size=\"12\">\n");
81
82    /* Background */
83    for(y = 0; y < qq->height; y++)
84    {
85        uint8_t *lineattr = qq->attr + y * qq->width;
86
87        for(x = 0; x < qq->width; x++)
88        {
89            cur += sprintf(cur, "<rect class=\"b%02x\" x=\"%d\" y=\"%d\""
90                                " width=\"6\" height=\"10\"/>\n",
91                                *lineattr++, x * 6, y * 10);
92        }
93    }
94
95    /* Text */
96    for(y = 0; y < qq->height; y++)
97    {
98        uint8_t *lineattr = qq->attr + y * qq->width;
99        uint32_t *linechar = qq->chars + y * qq->width;
100
101        for(x = 0; x < qq->width; x++)
102        {
103            uint32_t c = *linechar++;
104
105            cur += sprintf(cur, "<text class=\"f%02x\" x=\"%d\" y=\"%d\">",
106                                *lineattr++, x * 6, (y * 10) + 10);
107            if(c < 0x00000020)
108                cur += sprintf(cur, "?");
109            else if(c > 0x0000007f)
110            {
111                static const uint8_t mark[7] =
112                {
113                    0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
114                };
115
116                char buf[10], *parser;
117                int bytes = (c < 0x800) ? 2 : (c < 0x10000) ? 3 : 4;
118
119                buf[bytes] = '\0';
120                parser = buf + bytes;
121
122                switch(bytes)
123                {
124                    case 4: *--parser = (c | 0x80) & 0xbf; c >>= 6;
125                    case 3: *--parser = (c | 0x80) & 0xbf; c >>= 6;
126                    case 2: *--parser = (c | 0x80) & 0xbf; c >>= 6;
127                }
128                *--parser = c | mark[bytes];
129
130                cur += sprintf(cur, "%s", buf);
131            }
132            else switch((uint8_t)c)
133            {
134                case '>': cur += sprintf(cur, "&gt;"); break;
135                case '<': cur += sprintf(cur, "&lt;"); break;
136                case '&': cur += sprintf(cur, "&amp;"); break;
137                default: cur += sprintf(cur, "%c", c); break;
138            }
139            cur += sprintf(cur, "</text>\n");
140        }
141    }
142
143    cur += sprintf(cur, " </g>\n");
144    cur += sprintf(cur, "</svg>\n");
145
146    /* Crop to really used size */
147    ex->size = strlen(ex->buffer) + 1;
148    ex->buffer = realloc(ex->buffer, ex->size);
149}
150
Note: See TracBrowser for help on using the repository browser.