export.c (libcaca-0.99.beta19) | : | export.c (libcaca-0.99.beta20.tar.bz2) | ||
---|---|---|---|---|
/* | /* | |||
* libcaca Colour ASCII-Art library | * libcaca Colour ASCII-Art library | |||
* Copyright (c) 2002-2012 Sam Hocevar <sam@hocevar.net> | * Copyright © 2002—2021 Sam Hocevar <sam@hocevar.net> | |||
* 2006 Jean-Yves Lamoureux <jylam@lnxscene.org> | * 2006 Jean-Yves Lamoureux <jylam@lnxscene.org> | |||
* All Rights Reserved | * All Rights Reserved | |||
* | * | |||
* This library is free software. It comes without any warranty, to | * This library is free software. It comes without any warranty, to | |||
* the extent permitted by applicable law. You can redistribute it | * the extent permitted by applicable law. You can redistribute it | |||
* and/or modify it under the terms of the Do What the Fuck You Want | * 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 | * to Public License, Version 2, as published by Sam Hocevar. See | |||
* http://www.wtfpl.net/ for more details. | * http://www.wtfpl.net/ for more details. | |||
*/ | */ | |||
/* | /* | |||
* This file contains various export functions | * This file contains various export functions | |||
skipping to change at line 30 | skipping to change at line 30 | |||
#if !defined(__KERNEL__) | #if !defined(__KERNEL__) | |||
# include <stdlib.h> | # include <stdlib.h> | |||
# include <stdio.h> | # include <stdio.h> | |||
# include <string.h> | # include <string.h> | |||
#endif | #endif | |||
#include "caca.h" | #include "caca.h" | |||
#include "caca_internals.h" | #include "caca_internals.h" | |||
#include "codec.h" | #include "codec.h" | |||
/* Big endian */ | ||||
static inline int sprintu32(char *s, uint32_t x) | static inline int sprintu32(char *s, uint32_t x) | |||
{ | { | |||
s[0] = (uint8_t)(x >> 24); | s[0] = (uint8_t)(x >> 24); | |||
s[1] = (uint8_t)(x >> 16) & 0xff; | s[1] = (uint8_t)(x >> 16) & 0xff; | |||
s[2] = (uint8_t)(x >> 8) & 0xff; | s[2] = (uint8_t)(x >> 8) & 0xff; | |||
s[3] = (uint8_t)(x ) & 0xff; | s[3] = (uint8_t)(x ) & 0xff; | |||
return 4; | return 4; | |||
} | } | |||
/* Big endian */ | ||||
static inline int sprintu16(char *s, uint16_t x) | static inline int sprintu16(char *s, uint16_t x) | |||
{ | { | |||
s[0] = (uint8_t)(x >> 8) & 0xff; | s[0] = (uint8_t)(x >> 8) & 0xff; | |||
s[1] = (uint8_t)(x ) & 0xff; | s[1] = (uint8_t)(x ) & 0xff; | |||
return 2; | return 2; | |||
} | } | |||
static inline int write_u8(char *s, uint8_t x) | ||||
{ | ||||
s[0] = x; | ||||
return 1; | ||||
} | ||||
static inline int write_string(char *s, char const *d) | ||||
{ | ||||
int n = 0; | ||||
for (; d[n]; ++n) | ||||
s[n] = d[n]; | ||||
return n; | ||||
} | ||||
static void *export_caca(caca_canvas_t const *, size_t *); | static void *export_caca(caca_canvas_t const *, size_t *); | |||
static void *export_html(caca_canvas_t const *, size_t *); | static void *export_html(caca_canvas_t const *, size_t *); | |||
static void *export_html3(caca_canvas_t const *, size_t *); | static void *export_html3(caca_canvas_t const *, size_t *); | |||
static void *export_bbfr(caca_canvas_t const *, size_t *); | static void *export_bbfr(caca_canvas_t const *, size_t *); | |||
static void *export_ps(caca_canvas_t const *, size_t *); | static void *export_ps(caca_canvas_t const *, size_t *); | |||
static void *export_svg(caca_canvas_t const *, size_t *); | static void *export_svg(caca_canvas_t const *, size_t *); | |||
static void *export_tga(caca_canvas_t const *, size_t *); | static void *export_tga(caca_canvas_t const *, size_t *); | |||
static void *export_troff(caca_canvas_t const *, size_t *); | static void *export_troff(caca_canvas_t const *, size_t *); | |||
/** \brief Export a canvas into a foreign format. | /** \brief Export a canvas into a foreign format. | |||
skipping to change at line 341 | skipping to change at line 357 | |||
cur += sprintf(cur, "&"); | cur += sprintf(cur, "&"); | |||
else if(linechar[x + len] == '<') | else if(linechar[x + len] == '<') | |||
cur += sprintf(cur, "<"); | cur += sprintf(cur, "<"); | |||
else if(linechar[x + len] == '>') | else if(linechar[x + len] == '>') | |||
cur += sprintf(cur, ">"); | cur += sprintf(cur, ">"); | |||
else if(linechar[x + len] == '\"') | else if(linechar[x + len] == '\"') | |||
cur += sprintf(cur, """); | cur += sprintf(cur, """); | |||
else if(linechar[x + len] == '\'') | else if(linechar[x + len] == '\'') | |||
cur += sprintf(cur, "'"); | cur += sprintf(cur, "'"); | |||
else if(linechar[x + len] < 0x00000080) | else if(linechar[x + len] < 0x00000080) | |||
cur += sprintf(cur, "%c", (uint8_t)linechar[x + len]); | cur += write_u8(cur, (uint8_t)linechar[x + len]); | |||
else if((linechar[x + len] <= 0x0010fffd) | else if((linechar[x + len] <= 0x0010fffd) | |||
&& | && | |||
((linechar[x + len] & 0x0000fffe) != 0x0000fffe) | ((linechar[x + len] & 0x0000fffe) != 0x0000fffe) | |||
&& | && | |||
((linechar[x + len] < 0x0000d800) | ((linechar[x + len] < 0x0000d800) | |||
|| | || | |||
(linechar[x + len] > 0x0000dfff))) | (linechar[x + len] > 0x0000dfff))) | |||
cur += sprintf(cur, "&#%i;", (unsigned int)linechar[x + len] ); | cur += sprintf(cur, "&#%i;", (unsigned int)linechar[x + len] ); | |||
else | else | |||
/* non-character codepoints become U+FFFD | /* non-character codepoints become U+FFFD | |||
skipping to change at line 572 | skipping to change at line 588 | |||
cur += sprintf(cur, "&"); | cur += sprintf(cur, "&"); | |||
else if(linechar[x + i] == '<') | else if(linechar[x + i] == '<') | |||
cur += sprintf(cur, "<"); | cur += sprintf(cur, "<"); | |||
else if(linechar[x + i] == '>') | else if(linechar[x + i] == '>') | |||
cur += sprintf(cur, ">"); | cur += sprintf(cur, ">"); | |||
else if(linechar[x + i] == '\"') | else if(linechar[x + i] == '\"') | |||
cur += sprintf(cur, """); | cur += sprintf(cur, """); | |||
else if(linechar[x + i] == '\'') | else if(linechar[x + i] == '\'') | |||
cur += sprintf(cur, "'"); | cur += sprintf(cur, "'"); | |||
else if(linechar[x + i] < 0x00000080) | else if(linechar[x + i] < 0x00000080) | |||
cur += sprintf(cur, "%c", (uint8_t)linechar[x + i]); | cur += write_u8(cur, (uint8_t)linechar[x + i]); | |||
else if((linechar[x + i] <= 0x0010fffd) | else if((linechar[x + i] <= 0x0010fffd) | |||
&& | && | |||
((linechar[x + i] & 0x0000fffe) != 0x0000fffe) | ((linechar[x + i] & 0x0000fffe) != 0x0000fffe) | |||
&& | && | |||
((linechar[x + i] < 0x0000d800) | ((linechar[x + i] < 0x0000d800) | |||
|| | || | |||
(linechar[x + i] > 0x0000dfff))) | (linechar[x + i] > 0x0000dfff))) | |||
cur += sprintf(cur, "&#%i;", (unsigned int)linechar[x + i]); | cur += sprintf(cur, "&#%i;", (unsigned int)linechar[x + i]); | |||
else | else | |||
/* non-character codepoints become U+FFFD | /* non-character codepoints become U+FFFD | |||
skipping to change at line 850 | skipping to change at line 866 | |||
static char const svg_header[] = | static char const svg_header[] = | |||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | |||
"<svg width=\"%d\" height=\"%d\" viewBox=\"0 0 %d %d\"" | "<svg width=\"%d\" height=\"%d\" viewBox=\"0 0 %d %d\"" | |||
" xmlns=\"http://www.w3.org/2000/svg\"" | " xmlns=\"http://www.w3.org/2000/svg\"" | |||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"" | " xmlns:xlink=\"http://www.w3.org/1999/xlink\"" | |||
" xml:space=\"preserve\" version=\"1.1\" baseProfile=\"full\">\n"; | " xml:space=\"preserve\" version=\"1.1\" baseProfile=\"full\">\n"; | |||
char *data, *cur; | char *data, *cur; | |||
int x, y; | int x, y; | |||
/* 200 is arbitrary but should be ok */ | /* Use 200 as a safety value for character information size | |||
* | ||||
* Worst case for background, 68 chars: | ||||
* <rect style="fill:#fff" x="65535" y="65535" width="6" height="10"/>\n | ||||
* Worst case for foreground, 97 chars: | ||||
* <text style="fill:#fff" font-weight="bold" font-style="italic" x="65535 | ||||
" y="65535">xxxxxx</text>\n | ||||
*/ | ||||
*bytes = strlen(svg_header) + 128 + cv->width * cv->height * 200; | *bytes = strlen(svg_header) + 128 + cv->width * cv->height * 200; | |||
cur = data = malloc(*bytes); | cur = data = malloc(*bytes); | |||
/* Header */ | /* Header */ | |||
cur += sprintf(cur, svg_header, cv->width * 6, cv->height * 10, | cur += sprintf(cur, svg_header, cv->width * 6, cv->height * 10, | |||
cv->width * 6, cv->height * 10); | cv->width * 6, cv->height * 10); | |||
cur += sprintf(cur, " <g id=\"mainlayer\" font-size=\"10\"" | cur += sprintf(cur, " <g id=\"mainlayer\" font-size=\"10\"" | |||
" style=\"font-family: monospace\">\n"); | " style=\"font-family: monospace\">\n"); | |||
skipping to change at line 891 | skipping to change at line 913 | |||
for(x = 0; x < cv->width; x++) | for(x = 0; x < cv->width; x++) | |||
{ | { | |||
uint32_t ch = *linechar++; | uint32_t ch = *linechar++; | |||
if(ch == ' ' || ch == CACA_MAGIC_FULLWIDTH) | if(ch == ' ' || ch == CACA_MAGIC_FULLWIDTH) | |||
{ | { | |||
lineattr++; | lineattr++; | |||
continue; | continue; | |||
} | } | |||
cur += sprintf(cur, "<text style=\"fill:#%.03x\" " | cur += sprintf(cur, "<text style=\"fill:#%.03x\"%s%s " | |||
"x=\"%d\" y=\"%d\">", | "x=\"%d\" y=\"%d\">", | |||
caca_attr_to_rgb12_fg(*lineattr++), | caca_attr_to_rgb12_fg(*lineattr), | |||
(*lineattr & CACA_BOLD) ? " font-weight=\"bold\" | ||||
" : "", | ||||
(*lineattr & CACA_ITALICS) ? " font-style=\"ital | ||||
ic\"" : "", | ||||
x * 6, (y * 10) + 8); | x * 6, (y * 10) + 8); | |||
lineattr++; | ||||
if(ch < 0x00000020) | if(ch < 0x00000020) | |||
*cur++ = '?'; | *cur++ = '?'; | |||
else if(ch > 0x0000007f) | else if(ch > 0x0000007f) | |||
cur += caca_utf32_to_utf8(cur, ch); | cur += caca_utf32_to_utf8(cur, ch); | |||
else switch((uint8_t)ch) | else switch((uint8_t)ch) | |||
{ | { | |||
case '>': cur += sprintf(cur, ">"); break; | case '>': cur += sprintf(cur, ">"); break; | |||
case '<': cur += sprintf(cur, "<"); break; | case '<': cur += sprintf(cur, "<"); break; | |||
case '&': cur += sprintf(cur, "&"); break; | case '&': cur += sprintf(cur, "&"); break; | |||
skipping to change at line 947 | skipping to change at line 972 | |||
f = caca_load_font(fontlist[0], 0); | f = caca_load_font(fontlist[0], 0); | |||
w = caca_get_canvas_width(cv) * caca_get_font_width(f); | w = caca_get_canvas_width(cv) * caca_get_font_width(f); | |||
h = caca_get_canvas_height(cv) * caca_get_font_height(f); | h = caca_get_canvas_height(cv) * caca_get_font_height(f); | |||
*bytes = w * h * 4 + 18; /* 32 bpp + 18 bytes for the header */ | *bytes = w * h * 4 + 18; /* 32 bpp + 18 bytes for the header */ | |||
cur = data = malloc(*bytes); | cur = data = malloc(*bytes); | |||
/* ID Length */ | /* ID Length */ | |||
cur += sprintf(cur, "%c", 0); | cur += write_u8(cur, 0); | |||
/* Color Map Type: no colormap */ | /* Color Map Type: no colormap */ | |||
cur += sprintf(cur, "%c", 0); | cur += write_u8(cur, 0); | |||
/* Image Type: uncompressed truecolor */ | /* Image Type: uncompressed truecolor */ | |||
cur += sprintf(cur, "%c", 2); | cur += write_u8(cur, 2); | |||
/* Color Map Specification: no color map */ | /* Color Map Specification: no color map */ | |||
memset(cur, 0, 5); cur += 5; | memset(cur, 0, 5); cur += 5; | |||
/* Image Specification */ | /* Image Specification */ | |||
cur += sprintf(cur, "%c%c", 0, 0); /* X Origin */ | cur += sprintf(cur, "%c%c", 0, 0); /* X Origin */ | |||
cur += sprintf(cur, "%c%c", 0, 0); /* Y 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", w & 0xff, w >> 8); /* Width */ | |||
cur += sprintf(cur, "%c%c", h & 0xff, h >> 8); /* Height */ | cur += sprintf(cur, "%c%c", h & 0xff, h >> 8); /* Height */ | |||
cur += sprintf(cur, "%c", 32); /* Pixel Depth */ | cur += write_u8(cur, 32); /* Pixel Depth */ | |||
cur += sprintf(cur, "%c", 40); /* Image Descriptor */ | cur += write_u8(cur, 40); /* Image Descriptor */ | |||
/* Image ID: no ID */ | /* Image ID: no ID */ | |||
/* Color Map Data: no colormap */ | /* Color Map Data: no colormap */ | |||
/* Image Data */ | /* Image Data */ | |||
caca_render_canvas(cv, f, cur, w, h, 4 * w); | caca_render_canvas(cv, f, cur, w, h, 4 * w); | |||
/* Swap bytes. What a waste of time. */ | /* Swap bytes. What a waste of time. */ | |||
for(i = 0; i < w * h * 4; i += 4) | for(i = 0; i < w * h * 4; i += 4) | |||
{ | { | |||
skipping to change at line 1002 | skipping to change at line 1027 | |||
/* Each char is at most | /* Each char is at most | |||
* 2x\mM (2x10) | * 2x\mM (2x10) | |||
* + \fB + \fI + \fR (9) | * + \fB + \fI + \fR (9) | |||
* + 4 bytes = 33 | * + 4 bytes = 33 | |||
* Each line has a \n (1) and maybe 0xc2 0xa0 (2) | * Each line has a \n (1) and maybe 0xc2 0xa0 (2) | |||
* Header has .nf\n (3) | * Header has .nf\n (3) | |||
*/ | */ | |||
*bytes = 3 + cv->height * 3 + (cv->width * cv->height * 33); | *bytes = 3 + cv->height * 3 + (cv->width * cv->height * 33); | |||
cur = data = malloc(*bytes); | cur = data = malloc(*bytes); | |||
cur += sprintf(cur, ".nf\n"); | cur += write_string(cur, ".nf\n"); | |||
prevfg = 0; | prevfg = 0; | |||
prevbg = 0; | prevbg = 0; | |||
started = 0; | started = 0; | |||
for(y = 0; y < cv->height; y++) | for(y = 0; y < cv->height; y++) | |||
{ | { | |||
uint32_t *lineattr = cv->attrs + y * cv->width; | uint32_t *lineattr = cv->attrs + y * cv->width; | |||
uint32_t *linechar = cv->chars + y * cv->width; | uint32_t *linechar = cv->chars + y * cv->width; | |||
skipping to change at line 1057 | skipping to change at line 1082 | |||
else | else | |||
cur += caca_utf32_to_utf8(cur, ch); | cur += caca_utf32_to_utf8(cur, ch); | |||
if(lineattr[x] & (CACA_BOLD|CACA_ITALICS)) | if(lineattr[x] & (CACA_BOLD|CACA_ITALICS)) | |||
cur += sprintf(cur, "\\fR"); | cur += sprintf(cur, "\\fR"); | |||
prevfg = fg; | prevfg = fg; | |||
prevbg = bg; | prevbg = bg; | |||
started = 1; | started = 1; | |||
} | } | |||
cur += sprintf(cur, "\n"); | cur += write_u8(cur, '\n'); | |||
} | } | |||
/* Crop to really used size */ | /* Crop to really used size */ | |||
debug("troff export: alloc %lu bytes, realloc %lu", | debug("troff export: alloc %lu bytes, realloc %lu", | |||
(unsigned long int)*bytes, (unsigned long int)(cur - data)); | (unsigned long int)*bytes, (unsigned long int)(cur - data)); | |||
*bytes = (uintptr_t)(cur - data); | *bytes = (uintptr_t)(cur - data); | |||
data = realloc(data, *bytes); | data = realloc(data, *bytes); | |||
return data; | return data; | |||
} | } | |||
/* | /* | |||
* XXX: The following functions are aliases. | * XXX: The following functions are aliases. | |||
*/ | */ | |||
void *cucul_export_memory(cucul_canvas_t const *, char const *, | ||||
size_t *) CACA_ALIAS(caca_export_canvas_to_memory); | ||||
void *caca_export_memory(caca_canvas_t const *, char const *, | void *caca_export_memory(caca_canvas_t const *, char const *, | |||
size_t *) CACA_ALIAS(caca_export_canvas_to_memory); | size_t *) CACA_ALIAS(caca_export_canvas_to_memory); | |||
char const * const * cucul_get_export_list(void) | ||||
CACA_ALIAS(caca_get_export_list); | ||||
End of changes. 18 change blocks. | ||||
18 lines changed or deleted | 44 lines changed or added |