1 | /* |
---|
2 | * libcucul Canvas for ultrafast compositing of Unicode letters |
---|
3 | * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org> |
---|
4 | * 2006 Jean-Yves Lamoureux <jylam@lnxscene.org> |
---|
5 | * All Rights Reserved |
---|
6 | * |
---|
7 | * $Id: export_ansi.c 769 2006-04-14 07:30:53Z sam $ |
---|
8 | * |
---|
9 | * This library is free software; you can redistribute it and/or |
---|
10 | * modify it under the terms of the Do What The Fuck You Want To |
---|
11 | * Public License, Version 2, as published by Sam Hocevar. See |
---|
12 | * http://sam.zoy.org/wtfpl/COPYING for more details. |
---|
13 | */ |
---|
14 | |
---|
15 | /* |
---|
16 | * This file contains export functions for ANSI |
---|
17 | */ |
---|
18 | |
---|
19 | #include "config.h" |
---|
20 | |
---|
21 | #if !defined(__KERNEL__) |
---|
22 | # include <stdlib.h> |
---|
23 | # include <stdio.h> |
---|
24 | # include <string.h> |
---|
25 | #endif |
---|
26 | |
---|
27 | #include "cucul.h" |
---|
28 | #include "cucul_internals.h" |
---|
29 | |
---|
30 | /** \brief Generate ANSI representation of current image. |
---|
31 | * |
---|
32 | * This function generates and returns an ANSI representation of |
---|
33 | * the current image. |
---|
34 | * \param trailing if 0, raw ANSI will be generated. Otherwise, you'll be |
---|
35 | * able to cut/paste the result to a function like printf |
---|
36 | * \return buffer containing generated ANSI codes as a big string |
---|
37 | */ |
---|
38 | void _cucul_get_ansi(cucul_t *qq, struct cucul_buffer *ex) |
---|
39 | { |
---|
40 | static int const palette[] = |
---|
41 | { |
---|
42 | 0, 4, 2, 6, 1, 5, 3, 7, |
---|
43 | 8, 12, 10, 14, 9, 13, 11, 15 |
---|
44 | }; |
---|
45 | |
---|
46 | char *cur; |
---|
47 | unsigned int x, y; |
---|
48 | |
---|
49 | /* 23 bytes assumed for max length per pixel ('\e[5;1;3x;4y;9x;10ym' plus |
---|
50 | * 4 max bytes for a UTF-8 character). |
---|
51 | * Add height*9 to that (zeroes color at the end and jump to next line) */ |
---|
52 | ex->size = (qq->height * 9) + (qq->width * qq->height * 23); |
---|
53 | ex->data = malloc(ex->size); |
---|
54 | |
---|
55 | cur = ex->data; |
---|
56 | |
---|
57 | for(y = 0; y < qq->height; y++) |
---|
58 | { |
---|
59 | uint32_t *lineattr = qq->attr + y * qq->width; |
---|
60 | uint32_t *linechar = qq->chars + y * qq->width; |
---|
61 | |
---|
62 | uint8_t prevfg = -1; |
---|
63 | uint8_t prevbg = -1; |
---|
64 | |
---|
65 | for(x = 0; x < qq->width; x++) |
---|
66 | { |
---|
67 | uint8_t fg = palette[_cucul_argb32_to_ansi4fg(lineattr[x])]; |
---|
68 | uint8_t bg = palette[_cucul_argb32_to_ansi4bg(lineattr[x])]; |
---|
69 | uint32_t c = linechar[x]; |
---|
70 | |
---|
71 | if(fg != prevfg || bg != prevbg) |
---|
72 | { |
---|
73 | cur += sprintf(cur, "\033[0;"); |
---|
74 | |
---|
75 | if(fg < 8) |
---|
76 | if(bg < 8) |
---|
77 | cur += sprintf(cur, "3%d;4%dm", fg, bg); |
---|
78 | else |
---|
79 | cur += sprintf(cur, "5;3%d;4%d;10%dm", |
---|
80 | fg, bg - 8, bg - 8); |
---|
81 | else |
---|
82 | if(bg < 8) |
---|
83 | cur += sprintf(cur, "1;3%d;4%d;9%dm", |
---|
84 | fg - 8, bg, fg - 8); |
---|
85 | else |
---|
86 | cur += sprintf(cur, "5;1;3%d;4%d;9%d;10%dm", |
---|
87 | fg - 8, bg - 8, fg - 8, bg - 8); |
---|
88 | } |
---|
89 | |
---|
90 | *cur++ = c & 0x7f; |
---|
91 | |
---|
92 | prevfg = fg; |
---|
93 | prevbg = bg; |
---|
94 | } |
---|
95 | |
---|
96 | cur += sprintf(cur, "\033[0m\r\n"); |
---|
97 | } |
---|
98 | |
---|
99 | /* Crop to really used size */ |
---|
100 | ex->size = (uintptr_t)(cur - ex->data); |
---|
101 | ex->data = realloc(ex->data, ex->size); |
---|
102 | } |
---|
103 | |
---|