mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-24 13:49:50 +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>
This commit is contained in:
parent
4c58ac2416
commit
7bf5f13ce6
@ -7,6 +7,7 @@
|
||||
|
||||
R_API void r_cons_canvas_free (RConsCanvas *c) {
|
||||
free (c->b);
|
||||
free (c->attrs);
|
||||
free (c);
|
||||
}
|
||||
|
||||
@ -17,6 +18,10 @@ R_API void r_cons_canvas_clear (RConsCanvas *c) {
|
||||
c->b[c->blen] = 0;
|
||||
for (y = 0; y<c->h; y++)
|
||||
c->b[ y * c->w ] = '\n';
|
||||
if(c->attrs){
|
||||
c->attrslen=0;
|
||||
memset (c->attrs, 0, sizeof(*c->attrs)*c->blen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,6 +39,14 @@ R_API RConsCanvas* r_cons_canvas_new (int w, int h) {
|
||||
free (c);
|
||||
return NULL;
|
||||
}
|
||||
c->attrslen = 0;
|
||||
c->attrs = calloc(sizeof(*c->attrs),c->blen+1);
|
||||
if (!c->attrs) {
|
||||
free (c->b);
|
||||
free (c);
|
||||
return NULL;
|
||||
}
|
||||
c->attr=Color_RESET;
|
||||
c->w = w;
|
||||
c->h = h;
|
||||
c->x = c->y = 0;
|
||||
@ -100,6 +113,51 @@ static char *prefixline(RConsCanvas *c, int *left) {
|
||||
return p+x;
|
||||
}
|
||||
|
||||
static char ** attr_at(RConsCanvas *c,int loc){
|
||||
if(c->attrslen==0) return NULL;
|
||||
int i;
|
||||
for(i=0;i<(c->attrslen);i++){
|
||||
if(c->attrs[i].loc == loc)
|
||||
return &c->attrs[i].a;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void sort_attrs(RConsCanvas *c){
|
||||
int i,j;
|
||||
RConsCanvasAttr value;
|
||||
for(i = 1; i < c->attrslen; i++){
|
||||
value = c->attrs[i];
|
||||
for (j = i-1; j>=0 && c->attrs[j].loc>value.loc; j--){
|
||||
c->attrs[j+1] = c->attrs[j];
|
||||
}
|
||||
c->attrs[j+1] = value;
|
||||
}
|
||||
}
|
||||
|
||||
static void stamp_attr(RConsCanvas *c,int length){
|
||||
int i;
|
||||
char ** s;
|
||||
int loc = c->x + (c->y*c->w);
|
||||
s = attr_at(c,loc);
|
||||
|
||||
if(s){
|
||||
//If theres already an attr there, just replace it.
|
||||
*s = c->attr;
|
||||
}else{
|
||||
c->attrs[c->attrslen].loc = loc;
|
||||
c->attrs[c->attrslen].a = c->attr;
|
||||
c->attrslen++;
|
||||
sort_attrs(c);
|
||||
}
|
||||
|
||||
for(i=0;i<length;i++){
|
||||
s = attr_at(c,loc+i);
|
||||
if(s)
|
||||
*s = c->attr;
|
||||
}
|
||||
}
|
||||
|
||||
R_API void r_cons_canvas_write(RConsCanvas *c, const char *_s) {
|
||||
int left, slen, i, linenum = 0;
|
||||
char *p, *s, *str;
|
||||
@ -131,34 +189,45 @@ R_API void r_cons_canvas_write(RConsCanvas *c, const char *_s) {
|
||||
// if (x<0) x = 0;
|
||||
if (!G (x, c->y - c->sy))
|
||||
continue;
|
||||
stamp_attr(c,slen);
|
||||
memcpy (p, line+delta, slen-delta);
|
||||
if (!n) break;
|
||||
s = n;
|
||||
if (!G (c->x-c->sx, c->y+1-c->sy)) {
|
||||
if (!G (c->x-c->sx, c->y+1 - c->sy))
|
||||
break;
|
||||
}
|
||||
linenum ++;
|
||||
}
|
||||
free (str);
|
||||
}
|
||||
|
||||
R_API void r_cons_canvas_goto_write(RConsCanvas *c,int x,int y, char * s){
|
||||
if(r_cons_canvas_gotoxy(c,x,y))
|
||||
r_cons_canvas_write(c,s);
|
||||
}
|
||||
|
||||
R_API char *r_cons_canvas_to_string(RConsCanvas *c) {
|
||||
int x, y, olen = 0;
|
||||
char *o, *b;
|
||||
char *o, *b, **atr;
|
||||
if (!c) return NULL;
|
||||
b = c->b;
|
||||
o = malloc (c->w*(c->h+1));
|
||||
o = calloc (sizeof(char),
|
||||
(c->w*(c->h+1))*(CONS_MAX_ATTR_SZ));
|
||||
if (!o) return NULL;
|
||||
for (y = 0; y<c->h; y++) {
|
||||
for (x = 0; x<c->w; x++) {
|
||||
int p = x + (y*c->w);
|
||||
atr=attr_at(c,p);
|
||||
if(atr) {
|
||||
strcat(o,*atr);
|
||||
olen+=strlen(*atr);
|
||||
}
|
||||
if (!b[p] || b[p]=='\n')
|
||||
break;
|
||||
o[olen++] = b[p];
|
||||
}
|
||||
o[olen++] = '\n';
|
||||
}
|
||||
o[olen] = 0;
|
||||
o[olen] = '\0';
|
||||
return o;
|
||||
}
|
||||
|
||||
@ -176,6 +245,8 @@ R_API int r_cons_canvas_resize(RConsCanvas *c, int w, int h) {
|
||||
if (!c || w < 0) return R_FALSE;
|
||||
b = realloc (c->b, blen+1);
|
||||
if (!b) return R_FALSE;
|
||||
c->attrs = realloc(c->attrs,sizeof(*c->attrs)*blen+1);
|
||||
if (!c->attrs) return R_FALSE;
|
||||
c->blen = blen;
|
||||
c->b = b;
|
||||
c->w = w;
|
||||
@ -199,7 +270,9 @@ R_API void r_cons_canvas_box(RConsCanvas *c, int x, int y, int w, int h) {
|
||||
memset (row+1, '-', w-2);
|
||||
row[w-1] = roundcorners?'.':corner;
|
||||
row[w] = 0;
|
||||
if (G(x, y)) W(row);
|
||||
if (G(x, y)) {
|
||||
W(row);
|
||||
}
|
||||
if (G(x, y+h-1)) {
|
||||
row[0] = roundcorners?'\'':corner;
|
||||
row[w-1] = roundcorners?'\'':corner;
|
||||
@ -231,131 +304,65 @@ R_API void r_cons_canvas_fill(RConsCanvas *c, int x, int y, int w, int h, char c
|
||||
}
|
||||
|
||||
R_API void r_cons_canvas_line (RConsCanvas *c, int x, int y, int x2, int y2, int style) {
|
||||
int i, onscreen;
|
||||
char *c1="v", *c2="V";
|
||||
switch (style) {
|
||||
case 0:
|
||||
if (G (x, y))
|
||||
W ("v");
|
||||
if (G (x2, y2))
|
||||
W ("V");
|
||||
c->attr=Color_BLUE;
|
||||
c1="v";
|
||||
c2="V";
|
||||
break;
|
||||
case 1:
|
||||
if (G (x, y))
|
||||
W ("t"); //\\");
|
||||
if (G (x2, y2))
|
||||
W ("\\");
|
||||
c->attr=Color_GREEN;
|
||||
c1="t";
|
||||
c2="\\";
|
||||
break;
|
||||
case 2:
|
||||
if (G (x, y))
|
||||
W ("f");
|
||||
if (G (x2, y2))
|
||||
W ("/");
|
||||
c->attr=Color_RED;
|
||||
c1="f";
|
||||
c2="/";
|
||||
break;
|
||||
}
|
||||
if (x==x2) {
|
||||
int min = R_MIN (y,y2)+1;
|
||||
int max = R_MAX (y,y2);
|
||||
for (i=min; i<max; i++) {
|
||||
if (G (x,i))
|
||||
W ("|");
|
||||
}
|
||||
} else {
|
||||
// --
|
||||
// TODO: find if there's any collision in this line
|
||||
int hl = R_ABS (y-y2) / 2;
|
||||
int hl2 = R_ABS (y-y2)-hl;
|
||||
hl--;
|
||||
if (y2 > (y+1)) {
|
||||
for (i=0;i<hl;i++) {
|
||||
if (G (x,y+i+1))
|
||||
W ("|");
|
||||
}
|
||||
for (i=0;i<hl2;i++) {
|
||||
if (G (x2, y+hl+i+1))
|
||||
W ("|");
|
||||
}
|
||||
int w = R_ABS (x-x2);
|
||||
char *row = malloc (w+2);
|
||||
if (x>x2) {
|
||||
w++;
|
||||
row[0] = '.';
|
||||
if (w>2)
|
||||
memset (row+1, '-', w-2);
|
||||
row[w-1] = '\'';
|
||||
row[w] = 0;
|
||||
onscreen = G (x2+w,y+hl+1);
|
||||
i = G (x2, y+hl+1);
|
||||
if (!onscreen)
|
||||
onscreen = i;
|
||||
} else {
|
||||
row[0] = '`';
|
||||
row[0] = '\'';
|
||||
if (w>1)
|
||||
memset (row+1, '-', w-1);
|
||||
row[w] = '.';
|
||||
row[w+1] = 0;
|
||||
onscreen = G (x+w,y+1+hl);
|
||||
i = G (x,y+1+hl);
|
||||
if (!onscreen)
|
||||
onscreen = i;
|
||||
}
|
||||
if (onscreen)
|
||||
W (row);
|
||||
free (row);
|
||||
} else {
|
||||
int minx = R_MIN (x, x2);
|
||||
//if (y >= y2)
|
||||
int rl = R_ABS (x-x2)/2;
|
||||
int rl2 = R_ABS (x-x2)-rl+1;
|
||||
int vl = (R_ABS(y-y2))+1;
|
||||
if (y+1==y2)
|
||||
vl--;
|
||||
|
||||
for (i=0;i<vl; i++) {
|
||||
if (G (minx+rl,y2+i))
|
||||
W ("|");
|
||||
}
|
||||
|
||||
int w = rl;
|
||||
char *row = malloc (w+1);
|
||||
if (x>x2) {
|
||||
row[0] = '.';
|
||||
if (w>2)
|
||||
memset (row+1, '-', w-2);
|
||||
if (w>0)
|
||||
row[w-1] = '.';
|
||||
row[w] = 0;
|
||||
onscreen = G (x2,y2-1);
|
||||
} else {
|
||||
row[0] = '`';
|
||||
if (w>2)
|
||||
memset (row+1, '-', w-2);
|
||||
if (w>0)
|
||||
row[w-1] = '\'';
|
||||
row[w] = 0;
|
||||
onscreen = G (x+1,y+1);
|
||||
}
|
||||
if (onscreen)
|
||||
W (row);
|
||||
w = rl2;
|
||||
free (row);
|
||||
row = malloc (rl2+1);
|
||||
if (x>x2) {
|
||||
row[0] = '`';
|
||||
memset (row+1, '-', w-2);
|
||||
row[w-1] = '\'';
|
||||
row[w] = 0;
|
||||
onscreen = G (x2+rl, y+1);
|
||||
} else {
|
||||
row[0] = '.';
|
||||
memset (row+1, '-', w-2);
|
||||
row[w-1] = '.';
|
||||
row[w] = 0;
|
||||
onscreen = G (x+rl, y2-1);
|
||||
}
|
||||
if (onscreen)
|
||||
W (row);
|
||||
free (row);
|
||||
r_cons_canvas_goto_write(c,x,y,c1);
|
||||
r_cons_canvas_goto_write(c,x2,y2,c2);
|
||||
if(y2<y){
|
||||
int tmp = y2;
|
||||
y2=y;
|
||||
y=tmp;
|
||||
tmp=x2;
|
||||
x2=x;
|
||||
x=tmp;
|
||||
}
|
||||
char chizzle;//my nizzle
|
||||
int dx = abs(x2-x);
|
||||
int dy = abs(y2-y);
|
||||
int sx = x<x2 ? 1 : -1;
|
||||
int sy = y<y2 ? 1 : -1;
|
||||
int err = (dx>dy?dx:-dy)/2;
|
||||
int e2;
|
||||
// TODO: find if there's any collision in this line
|
||||
loop:
|
||||
e2 = err;
|
||||
if(e2>-dx){
|
||||
chizzle='_';
|
||||
err-=dy;
|
||||
x+=sx;
|
||||
}
|
||||
if(e2<dy){
|
||||
chizzle='|';
|
||||
err+=dx;
|
||||
y+=sy;
|
||||
}
|
||||
if((e2<dy) && (e2>-dx)){
|
||||
if(sy>0){
|
||||
chizzle=(sx>0)?'\\':'/';
|
||||
}else{
|
||||
chizzle=(sx>0)?'/':'\\';
|
||||
}
|
||||
}
|
||||
if(!(x==x2&&y==y2)){
|
||||
int i = (chizzle=='_'&&sy<0) ? 1 : 0;
|
||||
r_cons_canvas_goto_write(c,x,y-i,&chizzle);
|
||||
goto loop;
|
||||
}
|
||||
c->attr=Color_RESET;
|
||||
}
|
||||
|
@ -109,6 +109,13 @@ typedef struct r_cons_palette_t {
|
||||
|
||||
typedef void (*RConsEvent)(void *);
|
||||
|
||||
#define CONS_MAX_ATTR_SZ 15
|
||||
typedef struct r_cons_canvas_attr_t {
|
||||
//TODO add support for 256 colors.
|
||||
int loc;
|
||||
char * a;
|
||||
} RConsCanvasAttr;
|
||||
|
||||
typedef struct r_cons_canvas_t {
|
||||
int w;
|
||||
int h;
|
||||
@ -116,6 +123,9 @@ typedef struct r_cons_canvas_t {
|
||||
int y;
|
||||
char *b;
|
||||
int blen;
|
||||
char * attr;//The current attr (inserted on each write)
|
||||
RConsCanvasAttr * attrs;// all the different attributes
|
||||
int attrslen;
|
||||
int sx; // scrollx
|
||||
int sy; // scrolly
|
||||
} RConsCanvas;
|
||||
@ -284,8 +294,10 @@ R_API void r_cons_canvas_free (RConsCanvas *c);
|
||||
R_API void r_cons_canvas_clear (RConsCanvas *c);
|
||||
R_API void r_cons_canvas_print(RConsCanvas *c);
|
||||
R_API char *r_cons_canvas_to_string(RConsCanvas *c);
|
||||
R_API void r_cons_canvas_attr(RConsCanvas *c,const char * attr);
|
||||
R_API void r_cons_canvas_write(RConsCanvas *c, const char *_s);
|
||||
R_API int r_cons_canvas_gotoxy(RConsCanvas *c, int x, int y);
|
||||
R_API void r_cons_canvas_goto_write(RConsCanvas *c,int x,int y, char * s);
|
||||
R_API void r_cons_canvas_box(RConsCanvas *c, int x, int y, int w, int h);
|
||||
R_API void r_cons_canvas_line (RConsCanvas *c, int x, int y, int x2, int y2, int style);
|
||||
R_API int r_cons_canvas_resize(RConsCanvas *c, int w, int h);
|
||||
|
Loading…
Reference in New Issue
Block a user