2018-03-01 09:53:53 +00:00
|
|
|
/* radare - LGPL - Copyright 2013-2018 - pancake */
|
2013-08-25 22:51:36 +00:00
|
|
|
|
|
|
|
#include <r_cons.h>
|
|
|
|
|
2018-05-02 13:36:08 +00:00
|
|
|
#define useUtf8 (r_cons_singleton ()->use_utf8)
|
|
|
|
#define useUtf8Curvy (r_cons_singleton ()->use_utf8_curvy)
|
2016-10-20 23:24:40 +00:00
|
|
|
|
2015-12-08 11:55:29 +00:00
|
|
|
#define W(y) r_cons_canvas_write (c, y)
|
|
|
|
#define G(x, y) r_cons_canvas_gotoxy (c, x, y)
|
2014-04-29 01:53:48 +00:00
|
|
|
|
2015-12-08 11:55:29 +00:00
|
|
|
R_API void r_cons_canvas_free(RConsCanvas *c) {
|
2018-03-07 11:47:39 +00:00
|
|
|
if (c) {
|
2018-06-12 11:05:47 +00:00
|
|
|
if (c->b) {
|
|
|
|
int y;
|
|
|
|
for (y = 0; y < c->h; y++) {
|
|
|
|
free (c->b[y]);
|
|
|
|
}
|
|
|
|
free (c->b);
|
|
|
|
}
|
|
|
|
free (c->bsize);
|
|
|
|
free (c->blen);
|
2018-03-07 11:47:39 +00:00
|
|
|
free (c->attrs);
|
|
|
|
free (c);
|
|
|
|
}
|
2013-08-25 22:51:36 +00:00
|
|
|
}
|
|
|
|
|
2015-12-08 11:55:29 +00:00
|
|
|
R_API void r_cons_canvas_clear(RConsCanvas *c) {
|
2014-09-24 01:17:43 +00:00
|
|
|
if (c && c->b) {
|
2018-06-12 11:05:47 +00:00
|
|
|
int y;
|
2016-10-20 23:24:40 +00:00
|
|
|
for (y = 0; y < c->h; y++) {
|
2018-06-12 11:05:47 +00:00
|
|
|
memset (c->b[y], '\n', c->bsize[y]);
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
|
|
|
|
/*//XXX tofix*/
|
2015-12-08 11:55:29 +00:00
|
|
|
if (c->attrs) {
|
|
|
|
c->attrslen = 0;
|
2018-06-12 11:05:47 +00:00
|
|
|
memset (c->attrs, 0, sizeof (*c->attrs) * (c->w + 1) * c->h);
|
Initial support for colors in RConsCanvas
started on cons_canvas color support. Still a bit buggy, working out the kinks.
Yanked my old line drawing algo from ward, still working on colors.
Still incomplete, Changed the way that attributes work, still lots of strange behavior, It appears that most attributes aren't where they belong.
still not finished. Ok now the lines and colors are working, but the colors are overwriting other sections. Working on preventing that.
colors are now working, but they are _so. slow._
woops, removed the debugging printf
Figured out the big evil function that has to be optimized, attr_at takes aprox 91% of the cpu, so he needs to be fixed
Signed-off-by: r0nk <r00nk@simplecpu.com>
Signed-off-by: r0nk <r00nk@simplecpu.com>
2015-02-10 22:06:27 +00:00
|
|
|
}
|
2014-09-08 15:10:53 +00:00
|
|
|
}
|
2013-08-25 22:51:36 +00:00
|
|
|
}
|
|
|
|
|
2018-06-12 11:05:47 +00:00
|
|
|
static bool _is_ansi_seq(const char *s) {
|
2018-03-01 09:53:53 +00:00
|
|
|
return s && s[0] == 033 && s[1] == '[';
|
2013-08-25 22:51:36 +00:00
|
|
|
}
|
|
|
|
|
2018-06-12 11:05:47 +00:00
|
|
|
static int _get_piece(const char *p, char *chr) {
|
2015-07-29 22:50:37 +00:00
|
|
|
const char *q = p;
|
2016-10-20 23:24:40 +00:00
|
|
|
if (!p) {
|
|
|
|
return 0;
|
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
while (p && *p && *p != '\n' && ! _is_ansi_seq (p)) {
|
2016-10-20 23:24:40 +00:00
|
|
|
p++;
|
|
|
|
}
|
|
|
|
if (chr) {
|
|
|
|
*chr = *p;
|
|
|
|
}
|
2015-07-29 22:50:37 +00:00
|
|
|
return p - q;
|
2013-08-25 22:51:36 +00:00
|
|
|
}
|
|
|
|
|
2017-09-16 23:26:02 +00:00
|
|
|
static const char **attr_at(RConsCanvas *c, int loc) {
|
2015-02-19 03:04:36 +00:00
|
|
|
int i, j, delta;
|
2016-10-20 23:24:40 +00:00
|
|
|
if (!c->color || c->attrslen == 0) {
|
2015-02-14 03:50:29 +00:00
|
|
|
return NULL;
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
2015-02-15 20:48:46 +00:00
|
|
|
j = c->attrslen / 2;
|
2015-02-19 03:04:36 +00:00
|
|
|
delta = c->attrslen / 2;
|
2015-12-08 11:55:29 +00:00
|
|
|
for (i = 0; i < (c->attrslen); i++) {
|
|
|
|
delta /= 2;
|
2016-10-20 23:24:40 +00:00
|
|
|
if (delta == 0) {
|
2015-12-08 11:55:29 +00:00
|
|
|
delta = 1;
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
|
|
|
if (c->attrs[j].loc == loc) {
|
2017-09-16 23:26:02 +00:00
|
|
|
return &c->attrs[j].a;
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
2015-12-08 11:55:29 +00:00
|
|
|
if (c->attrs[j].loc < loc) {
|
|
|
|
j += delta;
|
2016-10-20 23:24:40 +00:00
|
|
|
if (j >= c->attrslen) {
|
2015-02-15 02:21:32 +00:00
|
|
|
break;
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
|
|
|
if (c->attrs[j].loc > loc && delta == 1) {
|
2015-02-15 02:21:32 +00:00
|
|
|
break;
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
2015-12-08 11:55:29 +00:00
|
|
|
} else if (c->attrs[j].loc > loc) {
|
|
|
|
j -= delta;
|
2016-10-20 23:24:40 +00:00
|
|
|
if (j <= 0) {
|
2015-02-15 02:21:32 +00:00
|
|
|
break;
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
|
|
|
if (c->attrs[j].loc < loc && delta == 1) {
|
2015-02-15 02:21:32 +00:00
|
|
|
break;
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
2015-02-15 02:21:32 +00:00
|
|
|
}
|
Initial support for colors in RConsCanvas
started on cons_canvas color support. Still a bit buggy, working out the kinks.
Yanked my old line drawing algo from ward, still working on colors.
Still incomplete, Changed the way that attributes work, still lots of strange behavior, It appears that most attributes aren't where they belong.
still not finished. Ok now the lines and colors are working, but the colors are overwriting other sections. Working on preventing that.
colors are now working, but they are _so. slow._
woops, removed the debugging printf
Figured out the big evil function that has to be optimized, attr_at takes aprox 91% of the cpu, so he needs to be fixed
Signed-off-by: r0nk <r00nk@simplecpu.com>
Signed-off-by: r0nk <r00nk@simplecpu.com>
2015-02-10 22:06:27 +00:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-06-12 11:05:47 +00:00
|
|
|
static void stamp_attr(RConsCanvas *c, int loc, int length) {
|
2018-06-16 13:25:00 +00:00
|
|
|
if (!c->color) {
|
|
|
|
return;
|
|
|
|
}
|
Initial support for colors in RConsCanvas
started on cons_canvas color support. Still a bit buggy, working out the kinks.
Yanked my old line drawing algo from ward, still working on colors.
Still incomplete, Changed the way that attributes work, still lots of strange behavior, It appears that most attributes aren't where they belong.
still not finished. Ok now the lines and colors are working, but the colors are overwriting other sections. Working on preventing that.
colors are now working, but they are _so. slow._
woops, removed the debugging printf
Figured out the big evil function that has to be optimized, attr_at takes aprox 91% of the cpu, so he needs to be fixed
Signed-off-by: r0nk <r00nk@simplecpu.com>
Signed-off-by: r0nk <r00nk@simplecpu.com>
2015-02-10 22:06:27 +00:00
|
|
|
int i;
|
2017-09-16 23:26:02 +00:00
|
|
|
const char **s;
|
2015-12-08 11:55:29 +00:00
|
|
|
s = attr_at (c, loc);
|
Initial support for colors in RConsCanvas
started on cons_canvas color support. Still a bit buggy, working out the kinks.
Yanked my old line drawing algo from ward, still working on colors.
Still incomplete, Changed the way that attributes work, still lots of strange behavior, It appears that most attributes aren't where they belong.
still not finished. Ok now the lines and colors are working, but the colors are overwriting other sections. Working on preventing that.
colors are now working, but they are _so. slow._
woops, removed the debugging printf
Figured out the big evil function that has to be optimized, attr_at takes aprox 91% of the cpu, so he needs to be fixed
Signed-off-by: r0nk <r00nk@simplecpu.com>
Signed-off-by: r0nk <r00nk@simplecpu.com>
2015-02-10 22:06:27 +00:00
|
|
|
|
2017-09-16 23:26:02 +00:00
|
|
|
if (s) {
|
2018-06-18 20:40:58 +00:00
|
|
|
if (*s != 0 && strlen (*s) > 2 && *(*s + 2) == '0') {
|
2018-06-16 13:25:00 +00:00
|
|
|
if (strlen (c->attr) == 5 && *(c->attr + 2) != '0') {
|
|
|
|
char tmp[9];
|
|
|
|
memcpy (tmp, c->attr, 2);
|
|
|
|
strcpy (tmp + 2, "0;");
|
|
|
|
memcpy (tmp + 4, c->attr + 2, 3);
|
|
|
|
tmp[8] = 0;
|
|
|
|
c->attr = r_str_const (tmp);
|
|
|
|
}
|
|
|
|
}
|
2017-09-16 23:26:02 +00:00
|
|
|
*s = c->attr;
|
2015-02-17 16:01:00 +00:00
|
|
|
} else {
|
2018-08-22 23:35:18 +00:00
|
|
|
for (i = c->attrslen; i > 0 && loc < c->attrs[i - 1].loc; i--) {
|
|
|
|
c->attrs[i] = c->attrs[i - 1];
|
|
|
|
}
|
|
|
|
c->attrs[i].loc = loc;
|
|
|
|
c->attrs[i].a = c->attr;
|
Initial support for colors in RConsCanvas
started on cons_canvas color support. Still a bit buggy, working out the kinks.
Yanked my old line drawing algo from ward, still working on colors.
Still incomplete, Changed the way that attributes work, still lots of strange behavior, It appears that most attributes aren't where they belong.
still not finished. Ok now the lines and colors are working, but the colors are overwriting other sections. Working on preventing that.
colors are now working, but they are _so. slow._
woops, removed the debugging printf
Figured out the big evil function that has to be optimized, attr_at takes aprox 91% of the cpu, so he needs to be fixed
Signed-off-by: r0nk <r00nk@simplecpu.com>
Signed-off-by: r0nk <r00nk@simplecpu.com>
2015-02-10 22:06:27 +00:00
|
|
|
c->attrslen++;
|
|
|
|
}
|
|
|
|
|
2018-06-16 13:25:00 +00:00
|
|
|
for (i = 1; i < length; i++) {
|
2015-12-08 11:55:29 +00:00
|
|
|
s = attr_at (c, loc + i);
|
2017-09-16 23:26:02 +00:00
|
|
|
if (s) {
|
2018-06-18 20:40:58 +00:00
|
|
|
*s = 0;
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
Initial support for colors in RConsCanvas
started on cons_canvas color support. Still a bit buggy, working out the kinks.
Yanked my old line drawing algo from ward, still working on colors.
Still incomplete, Changed the way that attributes work, still lots of strange behavior, It appears that most attributes aren't where they belong.
still not finished. Ok now the lines and colors are working, but the colors are overwriting other sections. Working on preventing that.
colors are now working, but they are _so. slow._
woops, removed the debugging printf
Figured out the big evil function that has to be optimized, attr_at takes aprox 91% of the cpu, so he needs to be fixed
Signed-off-by: r0nk <r00nk@simplecpu.com>
Signed-off-by: r0nk <r00nk@simplecpu.com>
2015-02-10 22:06:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-09 17:36:00 +00:00
|
|
|
/* check for ANSI sequences and use them as attr */
|
2015-07-29 22:50:37 +00:00
|
|
|
static const char *set_attr(RConsCanvas *c, const char *s) {
|
2018-04-11 08:25:22 +00:00
|
|
|
if (!c || !s) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2015-08-09 17:36:00 +00:00
|
|
|
const char *p = s;
|
2015-05-30 15:55:11 +00:00
|
|
|
|
2018-06-12 11:05:47 +00:00
|
|
|
while (_is_ansi_seq (p)) {
|
2015-08-09 17:36:00 +00:00
|
|
|
p += 2;
|
|
|
|
while (*p && *p != 'J' && *p != 'm' && *p != 'H') {
|
|
|
|
p++;
|
|
|
|
}
|
2015-07-29 22:50:37 +00:00
|
|
|
p++;
|
2015-08-09 17:36:00 +00:00
|
|
|
}
|
2015-05-30 15:55:11 +00:00
|
|
|
|
2015-08-09 17:36:00 +00:00
|
|
|
if (p != s) {
|
2017-09-22 07:12:01 +00:00
|
|
|
char tmp[256];
|
2017-09-16 23:40:26 +00:00
|
|
|
const int slen = R_MIN (p - s, sizeof (tmp) - 1);
|
|
|
|
if (slen > 0) {
|
|
|
|
memcpy (tmp, s, slen);
|
|
|
|
tmp[slen] = 0;
|
|
|
|
// could be faster
|
|
|
|
c->attr = r_str_const (tmp);
|
|
|
|
}
|
2015-07-29 22:50:37 +00:00
|
|
|
}
|
2015-08-09 17:36:00 +00:00
|
|
|
return p;
|
2015-07-29 22:50:37 +00:00
|
|
|
}
|
2015-05-30 15:55:11 +00:00
|
|
|
|
2018-06-12 11:05:47 +00:00
|
|
|
R_API bool r_cons_canvas_gotoxy(RConsCanvas *c, int x, int y) {
|
|
|
|
bool ret = true;
|
|
|
|
if (!c) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
y += c->sy;
|
|
|
|
x += c->sx;
|
|
|
|
|
|
|
|
if (y > c->h * 2) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-06-13 10:55:36 +00:00
|
|
|
if (y >= c->h) {
|
|
|
|
y = c->h - 1;
|
2018-06-12 11:05:47 +00:00
|
|
|
ret = false;
|
|
|
|
}
|
2018-06-13 10:55:36 +00:00
|
|
|
if (y < 0) {
|
|
|
|
y = 0;
|
2018-06-12 11:05:47 +00:00
|
|
|
ret = false;
|
|
|
|
}
|
|
|
|
if (x < 0) {
|
|
|
|
//c->x = 0;
|
|
|
|
ret = false;
|
|
|
|
}
|
2018-06-13 10:55:36 +00:00
|
|
|
if (x > c->blen[y] * 2) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (x >= c->blen[y]) {
|
|
|
|
c->x = c->blen[y];
|
2018-06-12 11:05:47 +00:00
|
|
|
ret = false;
|
|
|
|
}
|
|
|
|
if (x < c->blen[y] && x >= 0) {
|
|
|
|
c->x = x;
|
|
|
|
}
|
|
|
|
if (y < c->h && y >= 0) {
|
|
|
|
c->y = y;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
2015-05-30 15:55:11 +00:00
|
|
|
|
2018-06-12 11:05:47 +00:00
|
|
|
R_API RConsCanvas *r_cons_canvas_new(int w, int h) {
|
|
|
|
if (w < 1 || h < 1) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
RConsCanvas *c = R_NEW0 (RConsCanvas);
|
|
|
|
if (!c) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
c->bsize = NULL;
|
|
|
|
c->blen = NULL;
|
|
|
|
int i = 0;
|
|
|
|
c->color = 0;
|
|
|
|
c->sx = 0;
|
|
|
|
c->sy = 0;
|
|
|
|
c->b = malloc (sizeof *c->b * h);
|
|
|
|
if (!c->b) {
|
|
|
|
goto beach;
|
|
|
|
}
|
|
|
|
c->blen = malloc (sizeof *c->blen * h);
|
|
|
|
if (!c->blen) {
|
|
|
|
goto beach;
|
|
|
|
}
|
|
|
|
c->bsize = malloc (sizeof *c->bsize * h);
|
|
|
|
if (!c->bsize) {
|
|
|
|
goto beach;
|
|
|
|
}
|
|
|
|
for (i = 0; i < h; i++) {
|
|
|
|
c->b[i] = malloc (w + 1);
|
|
|
|
c->blen[i] = w;
|
|
|
|
c->bsize[i] = w + 1;
|
|
|
|
if (!c->b[i]) {
|
|
|
|
goto beach;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c->w = w;
|
|
|
|
c->h = h;
|
|
|
|
c->x = c->y = 0;
|
|
|
|
c->attrslen = 0;
|
|
|
|
c->attrs = calloc (sizeof (*c->attrs), (c->w + 1) * c->h);
|
|
|
|
if (!c->attrs) {
|
|
|
|
goto beach;
|
|
|
|
}
|
|
|
|
c->attr = Color_RESET;
|
|
|
|
r_cons_canvas_clear (c);
|
|
|
|
return c;
|
|
|
|
beach: {
|
|
|
|
int j;
|
|
|
|
for (j = 0; j < i; j++) {
|
|
|
|
free (c->b[j]);
|
|
|
|
}
|
|
|
|
free (c->bsize);
|
|
|
|
free (c->blen);
|
|
|
|
free (c->b);
|
|
|
|
free (c);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int utf8len_fixed(const char *s, int n) {
|
2018-07-02 16:54:46 +00:00
|
|
|
int i = 0, j = 0, fullwidths = 0;
|
2018-06-12 11:05:47 +00:00
|
|
|
while (s[i] && n > 0) {
|
|
|
|
if ((s[i] & 0xc0) != 0x80) {
|
|
|
|
j++;
|
2018-07-02 16:54:46 +00:00
|
|
|
if (r_str_char_fullwidth (s + i, n)) {
|
|
|
|
fullwidths++;
|
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
}
|
|
|
|
n--;
|
|
|
|
i++;
|
|
|
|
}
|
2018-07-02 16:54:46 +00:00
|
|
|
return j + fullwidths;
|
2018-06-12 11:05:47 +00:00
|
|
|
}
|
|
|
|
|
2018-06-13 10:55:36 +00:00
|
|
|
static int bytes_utf8len(const char *s, int n, int left) {
|
2018-07-02 16:54:46 +00:00
|
|
|
int i = 0, fullwidths = 0;
|
2018-07-24 15:53:46 +00:00
|
|
|
while (n > -1 && i < left && s[i]) {
|
|
|
|
if (r_str_char_fullwidth (s + i, left - i)) {
|
2018-07-02 16:54:46 +00:00
|
|
|
fullwidths++;
|
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
if ((s[i] & 0xc0) != 0x80) {
|
|
|
|
n--;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
2018-07-02 16:54:46 +00:00
|
|
|
i -= fullwidths;
|
2018-06-18 20:40:58 +00:00
|
|
|
return n == -1 ? i - 1 : i;
|
2018-06-12 11:05:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int expand_line (RConsCanvas *c, int real_len, int utf8_len) {
|
2018-06-18 20:40:58 +00:00
|
|
|
if (real_len == 0) {
|
|
|
|
return true;
|
|
|
|
}
|
2018-06-13 10:55:36 +00:00
|
|
|
int buf_utf8_len = bytes_utf8len (c->b[c->y] + c->x, utf8_len, c->blen[c->y] - c->x);
|
2018-07-24 15:53:46 +00:00
|
|
|
int goback = R_MAX (0, (buf_utf8_len - utf8_len));
|
2018-06-12 11:05:47 +00:00
|
|
|
int padding = (real_len - utf8_len) - goback;
|
|
|
|
|
|
|
|
if (padding) {
|
|
|
|
if (padding > 0 && c->blen[c->y] + padding > c->bsize[c->y]) {
|
|
|
|
int newsize = R_MAX (c->bsize[c->y] * 1.5, c->blen[c->y] + padding);
|
|
|
|
char * newline = realloc (c->b[c->y], sizeof (*c->b[c->y])*(newsize));
|
|
|
|
if (!newline) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
memset (newline + c->bsize[c->y], 0, newsize - c->bsize[c->y]);
|
|
|
|
c->b[c->y] = newline;
|
|
|
|
c->bsize[c->y] = newsize;
|
|
|
|
}
|
2018-07-24 15:53:46 +00:00
|
|
|
int size = R_MAX (c->blen[c->y] - c->x - goback, 0);
|
|
|
|
char *start = c->b[c->y] + c->x + goback;
|
2018-06-12 11:05:47 +00:00
|
|
|
char *tmp = malloc (size);
|
|
|
|
if (!tmp) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
memcpy (tmp, start, size);
|
2018-06-18 20:40:58 +00:00
|
|
|
if (padding < 0) {
|
|
|
|
int lap = R_MAX (0, c->b[c->y] - (start + padding));
|
2018-06-20 07:27:54 +00:00
|
|
|
memcpy (start + padding + lap, tmp + lap, size - lap);
|
2018-06-18 20:40:58 +00:00
|
|
|
free (tmp);
|
|
|
|
c->blen[c->y] += padding;
|
|
|
|
return true;
|
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
memcpy (start + padding, tmp, size);
|
|
|
|
free (tmp);
|
|
|
|
c->blen[c->y] += padding;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API void r_cons_canvas_write(RConsCanvas *c, const char *s) {
|
2018-06-24 18:09:14 +00:00
|
|
|
if (!c || !s || !*s || !R_BETWEEN (0, c->y, c->h - 1) || !R_BETWEEN (0, c->x, c->w - 1)) {
|
2016-10-20 23:24:40 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
|
|
|
|
char ch;
|
|
|
|
int left, slen, attr_len, piece_len;
|
|
|
|
int orig_x = c->x, attr_x = c->x;
|
|
|
|
|
2018-06-13 10:55:36 +00:00
|
|
|
c->x = bytes_utf8len (c->b[c->y], c->x, c->blen[c->y]);
|
2018-06-12 11:05:47 +00:00
|
|
|
|
2015-07-29 22:50:37 +00:00
|
|
|
/* split the string into pieces of non-ANSI chars and print them normally,
|
2015-12-08 12:24:21 +00:00
|
|
|
** using the ANSI chars to set the attr of the canvas */
|
2017-01-28 12:28:31 +00:00
|
|
|
r_cons_break_push (NULL, NULL);
|
2015-07-29 22:50:37 +00:00
|
|
|
do {
|
2015-08-09 17:36:00 +00:00
|
|
|
const char *s_part = set_attr (c, s);
|
2015-11-08 22:38:42 +00:00
|
|
|
ch = 0;
|
2018-06-12 11:05:47 +00:00
|
|
|
piece_len = _get_piece (s_part, &ch);
|
2016-10-20 23:24:40 +00:00
|
|
|
if (piece_len == 0 && ch == '\0' && s_part == s) {
|
|
|
|
break;
|
|
|
|
}
|
2018-06-18 20:40:58 +00:00
|
|
|
left = c->blen[c->y] - c->x;
|
|
|
|
slen = piece_len;
|
|
|
|
|
|
|
|
if (piece_len > left) {
|
2018-06-20 07:27:54 +00:00
|
|
|
int utf8_piece_len = utf8len_fixed (s_part, piece_len);
|
2018-07-24 15:53:46 +00:00
|
|
|
if (utf8_piece_len > c->w - attr_x) {
|
2018-06-18 20:40:58 +00:00
|
|
|
slen = left;
|
|
|
|
}
|
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
|
|
|
|
int real_len = r_str_nlen (s_part, slen);
|
|
|
|
int utf8_len = utf8len_fixed (s_part, slen);
|
|
|
|
|
|
|
|
if (!expand_line (c, real_len, utf8_len)) {
|
2018-06-14 14:42:51 +00:00
|
|
|
break;
|
2015-08-09 17:36:00 +00:00
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
|
|
|
|
if (G (c->x - c->sx, c->y - c->sy)) {
|
|
|
|
memcpy (c->b[c->y] + c->x, s_part, slen);
|
2015-07-29 22:50:37 +00:00
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
|
2018-06-16 13:25:00 +00:00
|
|
|
attr_len = slen <= 0 && s_part != s? 1: utf8_len;
|
|
|
|
if (attr_len > 0 && attr_x < c->blen[c->y]) {
|
|
|
|
stamp_attr (c, c->y*c->w + attr_x, attr_len);
|
|
|
|
}
|
|
|
|
|
2015-08-09 17:36:00 +00:00
|
|
|
s = s_part;
|
2015-07-29 22:50:37 +00:00
|
|
|
if (ch == '\n') {
|
2018-06-20 08:47:53 +00:00
|
|
|
c->attr = Color_RESET;
|
2018-06-20 15:49:25 +00:00
|
|
|
stamp_attr (c, c->y*c->w + attr_x, 0);
|
2015-07-29 22:50:37 +00:00
|
|
|
c->y++;
|
|
|
|
s++;
|
2018-06-12 11:05:47 +00:00
|
|
|
if (*s == '\0' || c->y >= c->h) {
|
2016-10-20 23:24:40 +00:00
|
|
|
break;
|
|
|
|
}
|
2018-06-13 10:55:36 +00:00
|
|
|
c->x = bytes_utf8len (c->b[c->y], orig_x, c->blen[c->y]);
|
2018-06-12 11:05:47 +00:00
|
|
|
attr_x = orig_x;
|
2015-07-29 22:50:37 +00:00
|
|
|
} else {
|
|
|
|
c->x += slen;
|
2018-06-12 11:05:47 +00:00
|
|
|
attr_x += utf8_len;
|
2015-07-29 22:50:37 +00:00
|
|
|
}
|
|
|
|
s += piece_len;
|
2017-01-28 12:28:31 +00:00
|
|
|
} while (*s && !r_cons_is_breaked ());
|
|
|
|
r_cons_break_pop ();
|
2015-08-09 17:36:00 +00:00
|
|
|
c->x = orig_x;
|
2013-08-25 22:51:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
R_API char *r_cons_canvas_to_string(RConsCanvas *c) {
|
2018-06-12 11:05:47 +00:00
|
|
|
int x, y, olen = 0, attr_x = 0;
|
2015-02-17 16:01:00 +00:00
|
|
|
char *o;
|
2017-09-16 23:26:02 +00:00
|
|
|
const char **atr;
|
2015-09-14 00:08:31 +00:00
|
|
|
int is_first = true;
|
2015-06-03 23:30:33 +00:00
|
|
|
|
2016-11-07 17:38:45 +00:00
|
|
|
if (!c) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
|
|
|
|
for (y = 0; y < c->h; y++) {
|
|
|
|
olen += c->blen[y] + 1;
|
|
|
|
}
|
|
|
|
o = calloc (1, olen * (CONS_MAX_ATTR_SZ));
|
2016-11-07 17:38:45 +00:00
|
|
|
if (!o) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
|
|
|
|
olen = 0;
|
2015-02-17 16:01:00 +00:00
|
|
|
for (y = 0; y < c->h; y++) {
|
2015-06-03 23:30:33 +00:00
|
|
|
if (!is_first) {
|
|
|
|
o[olen++] = '\n';
|
|
|
|
}
|
2015-09-14 00:08:31 +00:00
|
|
|
is_first = false;
|
2018-06-12 11:05:47 +00:00
|
|
|
attr_x = 0;
|
|
|
|
for (x = 0; x < c->blen[y]; x++) {
|
|
|
|
if ((c->b[y][x] & 0xc0) != 0x80) {
|
|
|
|
atr = attr_at (c, y*c->w + attr_x);
|
|
|
|
if (atr && *atr) {
|
|
|
|
int len = strlen (*atr);
|
|
|
|
memcpy (o + olen, *atr, len);
|
|
|
|
olen += len;
|
|
|
|
}
|
|
|
|
attr_x++;
|
2018-07-24 15:53:46 +00:00
|
|
|
if (r_str_char_fullwidth (c->b[y] + x, c->blen[y] - x)) {
|
2018-07-02 16:54:46 +00:00
|
|
|
attr_x++;
|
|
|
|
}
|
Initial support for colors in RConsCanvas
started on cons_canvas color support. Still a bit buggy, working out the kinks.
Yanked my old line drawing algo from ward, still working on colors.
Still incomplete, Changed the way that attributes work, still lots of strange behavior, It appears that most attributes aren't where they belong.
still not finished. Ok now the lines and colors are working, but the colors are overwriting other sections. Working on preventing that.
colors are now working, but they are _so. slow._
woops, removed the debugging printf
Figured out the big evil function that has to be optimized, attr_at takes aprox 91% of the cpu, so he needs to be fixed
Signed-off-by: r0nk <r00nk@simplecpu.com>
Signed-off-by: r0nk <r00nk@simplecpu.com>
2015-02-10 22:06:27 +00:00
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
if (!c->b[y][x] || c->b[y][x] == '\n') {
|
|
|
|
o[olen++] = ' ';
|
|
|
|
continue;
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
const char *rune = r_cons_get_rune ((const ut8)c->b[y][x]);
|
2016-10-20 23:24:40 +00:00
|
|
|
if (rune) {
|
|
|
|
strcpy (o + olen, rune);
|
|
|
|
olen += strlen (rune);
|
|
|
|
} else {
|
2018-06-12 11:05:47 +00:00
|
|
|
o[olen++] = c->b[y][x];
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
2013-08-25 22:51:36 +00:00
|
|
|
}
|
2018-06-18 23:05:25 +00:00
|
|
|
while (olen > 0 && o[olen - 1] == ' ') {
|
2018-06-12 11:05:47 +00:00
|
|
|
o[--olen] = '\0';
|
|
|
|
}
|
2013-08-25 22:51:36 +00:00
|
|
|
}
|
Initial support for colors in RConsCanvas
started on cons_canvas color support. Still a bit buggy, working out the kinks.
Yanked my old line drawing algo from ward, still working on colors.
Still incomplete, Changed the way that attributes work, still lots of strange behavior, It appears that most attributes aren't where they belong.
still not finished. Ok now the lines and colors are working, but the colors are overwriting other sections. Working on preventing that.
colors are now working, but they are _so. slow._
woops, removed the debugging printf
Figured out the big evil function that has to be optimized, attr_at takes aprox 91% of the cpu, so he needs to be fixed
Signed-off-by: r0nk <r00nk@simplecpu.com>
Signed-off-by: r0nk <r00nk@simplecpu.com>
2015-02-10 22:06:27 +00:00
|
|
|
o[olen] = '\0';
|
2013-08-25 22:51:36 +00:00
|
|
|
return o;
|
|
|
|
}
|
|
|
|
|
2015-06-11 01:55:15 +00:00
|
|
|
R_API void r_cons_canvas_print_region(RConsCanvas *c) {
|
|
|
|
char *o = r_cons_canvas_to_string (c);
|
|
|
|
if (o) {
|
2017-11-26 01:25:57 +00:00
|
|
|
r_str_trim_tail (o);
|
|
|
|
if (*o) {
|
|
|
|
r_cons_strcat (o);
|
|
|
|
}
|
2017-11-26 00:32:52 +00:00
|
|
|
free (o);
|
2015-06-11 01:55:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-25 22:51:36 +00:00
|
|
|
R_API void r_cons_canvas_print(RConsCanvas *c) {
|
|
|
|
char *o = r_cons_canvas_to_string (c);
|
2014-09-08 15:10:53 +00:00
|
|
|
if (o) {
|
|
|
|
r_cons_strcat (o);
|
|
|
|
free (o);
|
|
|
|
}
|
2013-08-25 22:51:36 +00:00
|
|
|
}
|
2014-04-28 23:55:10 +00:00
|
|
|
|
2014-05-05 01:15:28 +00:00
|
|
|
R_API int r_cons_canvas_resize(RConsCanvas *c, int w, int h) {
|
2016-10-20 23:24:40 +00:00
|
|
|
if (!c || w < 0) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
void *newattrs = NULL;
|
|
|
|
int *newblen = realloc (c->blen, sizeof *c->blen * h);
|
|
|
|
if (!newblen) {
|
|
|
|
r_cons_canvas_free (c);
|
2016-10-20 23:24:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
c->blen = newblen;
|
|
|
|
int *newbsize = realloc (c->bsize, sizeof *c->bsize * h);
|
|
|
|
if (!newbsize) {
|
|
|
|
r_cons_canvas_free (c);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
c->bsize = newbsize;
|
|
|
|
char **newb = realloc (c->b, sizeof *c->b * h);
|
|
|
|
if (!newb) {
|
|
|
|
r_cons_canvas_free (c);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
c->b = newb;
|
|
|
|
int i;
|
|
|
|
char *newline = NULL;
|
|
|
|
for (i = 0; i < h; i++) {
|
|
|
|
if (i < c->h) {
|
|
|
|
newline = realloc (c->b[i], sizeof *c->b[i] * (w + 1));
|
|
|
|
} else {
|
|
|
|
newline = malloc ((w + 1));
|
|
|
|
}
|
|
|
|
c->blen[i] = w;
|
|
|
|
c->bsize[i] = w + 1;
|
|
|
|
if (!newline) {
|
|
|
|
int j;
|
|
|
|
for (j = 0; j <= i; j++) {
|
|
|
|
free (c->b[i]);
|
|
|
|
}
|
|
|
|
free (c->attrs);
|
|
|
|
free (c->blen);
|
|
|
|
free (c->bsize);
|
|
|
|
free (c->b);
|
|
|
|
free (c);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
c->b[i] = newline;
|
|
|
|
}
|
|
|
|
newattrs = realloc (c->attrs, sizeof (*c->attrs) * (w + 1) * h);
|
|
|
|
if (!newattrs) {
|
|
|
|
r_cons_canvas_free (c);
|
2015-09-14 00:08:31 +00:00
|
|
|
return false;
|
2015-03-21 00:27:54 +00:00
|
|
|
}
|
2018-06-12 11:05:47 +00:00
|
|
|
c->attrs = newattrs;
|
2014-05-05 01:15:28 +00:00
|
|
|
c->w = w;
|
|
|
|
c->h = h;
|
|
|
|
c->x = 0;
|
|
|
|
c->y = 0;
|
|
|
|
r_cons_canvas_clear (c);
|
2015-09-14 00:08:31 +00:00
|
|
|
return true;
|
2014-04-28 23:55:10 +00:00
|
|
|
}
|
|
|
|
|
2015-02-15 20:48:46 +00:00
|
|
|
R_API void r_cons_canvas_box(RConsCanvas *c, int x, int y, int w, int h, const char *color) {
|
2016-10-20 23:24:40 +00:00
|
|
|
const char *hline = useUtf8? RUNECODESTR_LINE_HORIZ : "-";
|
|
|
|
const char *vline = useUtf8? RUNECODESTR_LINE_VERT : "|";
|
2017-10-08 11:09:27 +00:00
|
|
|
const char *tl_corner = useUtf8 ? (useUtf8Curvy ? RUNECODESTR_CURVE_CORNER_TL : RUNECODESTR_CORNER_TL) : ".";
|
|
|
|
const char *tr_corner = useUtf8 ? (useUtf8Curvy ? RUNECODESTR_CURVE_CORNER_TR : RUNECODESTR_CORNER_TR) : ".";
|
|
|
|
const char *bl_corner = useUtf8 ? (useUtf8Curvy ? RUNECODESTR_CURVE_CORNER_BL : RUNECODESTR_CORNER_BL) : "`";
|
|
|
|
const char *br_corner = useUtf8 ? (useUtf8Curvy ? RUNECODESTR_CURVE_CORNER_BR : RUNECODESTR_CORNER_BR) : "'";
|
2015-05-31 18:05:41 +00:00
|
|
|
int i, x_mod;
|
2014-04-29 01:53:48 +00:00
|
|
|
int roundcorners = 0;
|
2015-05-31 18:05:41 +00:00
|
|
|
char *row = NULL, *row_ptr;
|
2014-04-29 01:53:48 +00:00
|
|
|
|
2016-10-20 23:24:40 +00:00
|
|
|
if (w < 1 || h < 1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (color) {
|
2017-09-16 23:26:02 +00:00
|
|
|
c->attr = color;
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
2018-03-01 09:53:53 +00:00
|
|
|
if (!c->color) {
|
|
|
|
c->attr = Color_RESET;
|
|
|
|
}
|
2015-12-08 11:55:29 +00:00
|
|
|
row = malloc (w + 1);
|
2018-03-01 09:53:53 +00:00
|
|
|
if (!row) {
|
2015-03-05 01:07:53 +00:00
|
|
|
return;
|
2018-03-01 09:53:53 +00:00
|
|
|
}
|
2016-10-20 23:24:40 +00:00
|
|
|
row[0] = roundcorners? '.': tl_corner[0];
|
|
|
|
if (w > 2) {
|
|
|
|
memset (row + 1, hline[0], w - 2);
|
|
|
|
}
|
|
|
|
if (w > 1) {
|
|
|
|
row[w - 1] = roundcorners? '.': tr_corner[0];
|
|
|
|
}
|
2015-05-31 18:04:55 +00:00
|
|
|
row[w] = 0;
|
2015-05-31 18:05:41 +00:00
|
|
|
|
|
|
|
row_ptr = row;
|
|
|
|
x_mod = x;
|
|
|
|
if (x < -c->sx) {
|
2015-12-08 11:55:29 +00:00
|
|
|
x_mod = R_MIN (-c->sx, x_mod + w);
|
2015-05-31 18:05:41 +00:00
|
|
|
row_ptr += x_mod - x;
|
|
|
|
}
|
2015-12-08 11:55:29 +00:00
|
|
|
if (G (x_mod, y)) {
|
|
|
|
W (row_ptr);
|
Initial support for colors in RConsCanvas
started on cons_canvas color support. Still a bit buggy, working out the kinks.
Yanked my old line drawing algo from ward, still working on colors.
Still incomplete, Changed the way that attributes work, still lots of strange behavior, It appears that most attributes aren't where they belong.
still not finished. Ok now the lines and colors are working, but the colors are overwriting other sections. Working on preventing that.
colors are now working, but they are _so. slow._
woops, removed the debugging printf
Figured out the big evil function that has to be optimized, attr_at takes aprox 91% of the cpu, so he needs to be fixed
Signed-off-by: r0nk <r00nk@simplecpu.com>
Signed-off-by: r0nk <r00nk@simplecpu.com>
2015-02-10 22:06:27 +00:00
|
|
|
}
|
2015-12-08 11:55:29 +00:00
|
|
|
if (G (x_mod, y + h - 1)) {
|
2016-10-20 23:24:40 +00:00
|
|
|
row[0] = roundcorners? '\'': bl_corner[0];
|
|
|
|
row[w - 1] = roundcorners? '\'': br_corner[0];
|
2015-12-08 11:55:29 +00:00
|
|
|
W (row_ptr);
|
2014-05-05 01:15:28 +00:00
|
|
|
}
|
2015-12-08 11:55:29 +00:00
|
|
|
for (i = 1; i < h - 1; i++) {
|
2018-03-05 22:32:27 +00:00
|
|
|
if (G (x, y + i)) {
|
|
|
|
W (vline);
|
|
|
|
}
|
|
|
|
if (G (x + w - 1, y + i)) {
|
|
|
|
W (vline);
|
|
|
|
}
|
2014-04-28 23:55:10 +00:00
|
|
|
}
|
2014-05-05 21:28:57 +00:00
|
|
|
free (row);
|
2018-03-01 09:53:53 +00:00
|
|
|
if (color) {
|
|
|
|
c->attr = Color_RESET;
|
|
|
|
}
|
2014-04-28 23:55:10 +00:00
|
|
|
}
|
|
|
|
|
2018-06-10 01:27:29 +00:00
|
|
|
R_API void r_cons_canvas_fill(RConsCanvas *c, int x, int y, int w, int h, char ch) {
|
2014-04-28 23:55:10 +00:00
|
|
|
int i;
|
2016-10-20 23:24:40 +00:00
|
|
|
if (w < 0) {
|
|
|
|
return;
|
|
|
|
}
|
2017-12-29 10:22:22 +00:00
|
|
|
char *row = malloc (w + 1);
|
2016-10-20 23:24:40 +00:00
|
|
|
if (!row) {
|
|
|
|
return;
|
|
|
|
}
|
2014-04-29 01:53:48 +00:00
|
|
|
memset (row, ch, w);
|
2014-04-28 23:55:10 +00:00
|
|
|
row[w] = 0;
|
2015-12-08 11:55:29 +00:00
|
|
|
for (i = 0; i < h; i++) {
|
2016-10-20 23:24:40 +00:00
|
|
|
if (G (x, y + i)) {
|
2015-12-08 11:55:29 +00:00
|
|
|
W (row);
|
2016-10-20 23:24:40 +00:00
|
|
|
}
|
2014-04-28 23:55:10 +00:00
|
|
|
}
|
2014-05-05 21:28:57 +00:00
|
|
|
free (row);
|
2014-04-28 23:55:10 +00:00
|
|
|
}
|
|
|
|
|
2015-12-08 11:55:29 +00:00
|
|
|
R_API void r_cons_canvas_line(RConsCanvas *c, int x, int y, int x2, int y2, RCanvasLineStyle *style) {
|
2015-02-15 20:34:12 +00:00
|
|
|
if (c->linemode) {
|
|
|
|
r_cons_canvas_line_square (c, x, y, x2, y2, style);
|
|
|
|
} else {
|
|
|
|
r_cons_canvas_line_diagonal (c, x, y, x2, y2, style);
|
Initial support for colors in RConsCanvas
started on cons_canvas color support. Still a bit buggy, working out the kinks.
Yanked my old line drawing algo from ward, still working on colors.
Still incomplete, Changed the way that attributes work, still lots of strange behavior, It appears that most attributes aren't where they belong.
still not finished. Ok now the lines and colors are working, but the colors are overwriting other sections. Working on preventing that.
colors are now working, but they are _so. slow._
woops, removed the debugging printf
Figured out the big evil function that has to be optimized, attr_at takes aprox 91% of the cpu, so he needs to be fixed
Signed-off-by: r0nk <r00nk@simplecpu.com>
Signed-off-by: r0nk <r00nk@simplecpu.com>
2015-02-10 22:06:27 +00:00
|
|
|
}
|
2014-04-28 23:55:10 +00:00
|
|
|
}
|