diff options
Diffstat (limited to 'draw.c')
-rw-r--r-- | draw.c | 324 |
1 files changed, 324 insertions, 0 deletions
@@ -0,0 +1,324 @@ +#include <stdlib.h> + +#include "gramscii.h" +#include "config.h" + +/*** drawing-related functions ***/ + +/*** Lines and markers ***/ + +void toggle_hline(){ + + cur_hl = (cur_hl + 1) % hlines_sz; + line_h = hlines[cur_hl]; + +} + +void toggle_corner(){ + + cur_corn = (cur_corn + 1 ) % corners_sz; + corner = corners[cur_corn]; + +} + +void toggle_vline(){ + + cur_vl = (cur_vl + 1) % vlines_sz; + line_v = vlines[cur_vl]; + +} + +void toggle_st_mark(){ + + cur_start = (cur_start + 1 ) % stmarks_sz; + mark_st = st_marks[cur_start]; +} + +void toggle_end_mark(){ + + cur_end = (cur_end+ 1 ) % endmarks_sz; + mark_end = end_marks[cur_end]; +} + +int change_style(char c){ + switch(c){ + case '-': + toggle_hline(); + break; + case '|': + toggle_vline(); + break; + case '+': + toggle_corner(); + break; + case '<': + toggle_st_mark(); + break; + case '>': + toggle_end_mark(); + break; + case '.': + reset_styles(); + break; + default: + return 0; + } + return c; +} + + + + +/***** text, box, arrows *****/ + +void get_text(FILE *fc){ + char c; + int orig_x = x; + + redraw(); + while((c=fgetc(fc))!=EOF && c != 27){ + if(c=='\n'){ + set_cur(BG); + y += 1; + x = orig_x; + } + else { + set_cur(c); + update_current(); + modified = 1; + x += 1; + if (x >= WIDTH) + x = orig_x; + } + check_bound(); + status_bar(); + show_cursor(); + } + mode=MOVE; +} + +void draw_box(int x1, int y1, int fix){ + + int xmin, ymin, xmax, ymax; + int i; + void (*f)(int, int, char); + + if (fix == FIX) + f = set_xy; + else + f = draw_xy; + + xmin = MIN(x, x1); + xmax = MAX(x, x1); + ymin = MIN(y, y1); + ymax = MAX(y, y1); + + for(i=xmin+1; i<=xmax; i++){ + f(i, ymin, line_h); + f(i, ymax, line_h); + } + for(i=ymin+1; i<=ymax; i++){ + f(xmin, i, line_v); + f(xmax, i, line_v); + } + f(xmin, ymin, corner); + f(xmin, ymax, corner); + f(xmax, ymin, corner); + f(xmax, ymax, corner); + show_cursor(); +} + +void get_box(FILE *fc){ + char c; + int orig_x=x, orig_y=y; + redraw(); + step = 1; + draw_box(x,y,NOFIX); + while((c=fgetc(fc))!=EOF && c != 27 && c!= 'b' && c != '\n'){ + if (change_style(c)) + goto update_box; + if (!move_around(c, fc)) + continue; + check_bound(); + redraw(); + step = 1; +update_box: + draw_box(orig_x, orig_y, NOFIX); + status_bar(); + show_cursor(); + } + if (c == 'b' || c == '\n'){ + draw_box(orig_x, orig_y, FIX); + modified = 1; + } + redraw(); + mode = MOVE; +} + +void draw_arrow(int x, int y, char *a, int a_len, int fix){ + + int i, j, cur_dir; + char line; + void (*f)(int, int, char); + + + if (fix == FIX) + f = set_xy; + else + f = draw_xy; + + f(x,y,mark_st); + if (!a_len){ + show_cursor(); + return; + } + cur_dir=DIR_N; + for (i=0; i<a_len; i+=2){ + if (i>0) { + /* If we are switching between horizontal and vertical, put a "corner" */ + if (((cur_dir & DIR_HOR) && (a[i] & DIR_VER)) || + ((cur_dir & DIR_VER) && (a[i] & DIR_HOR))){ + f(x,y,corner); + show_cursor(); + } + } + for(j=0; j<a[i+1]; j++){ + line = (a[i] & DIR_L) || (a[i] & DIR_R) ? line_h : line_v; + x += progr_x(a[i]); + y += progr_y(a[i]); + f(x, y, line); + } + /* f(x,y,mark_end);*/ + cur_dir = a[i]; + } + if (autoend){ + if (cur_dir != DIR_N) + f(x,y, get_mark(cur_dir)); + } + else + f(x,y,mark_end); + show_cursor(); +} + +void get_arrow(FILE *fc){ + + char c; + int orig_x=x, orig_y=y, arrow_len; + static char *arrow = NULL; + static int arrow_sz; + + if (!arrow){ + arrow_sz = 100; + arrow = malloc(arrow_sz * sizeof(char)); + } + arrow_len = 0; + dir = DIR_N; + + redraw(); + step = 1; + draw_arrow(x,y, arrow, 0, NOFIX); + while((c=fgetc(fc))!=EOF && c != 27 && c!= 'a' && c != '\n'){ + if (change_style(c)) + goto update_arrow; + if (!move_around(c, fc)) + continue; + check_bound(); + /* FIXME: if we are out of bound, do nothing? */ + if (arrow_len == arrow_sz){ + arrow_sz *=2; + arrow = realloc(arrow, arrow_sz * sizeof(char)); + } + arrow[arrow_len++] = dir; + arrow[arrow_len++] = step; + redraw(); + step = 1; +update_arrow: + draw_arrow(orig_x, orig_y, arrow, arrow_len, NOFIX); + status_bar(); + show_cursor(); + } + if (c == 'a' || c == '\n'){ + draw_arrow(orig_x, orig_y, arrow, arrow_len, FIX); + modified = 1; + } + redraw(); + mode = MOVE; +} + + +void do_erase(int x1, int y1){ + int i; + switch(dir){ + case DIR_R: + for(i=x1; i<=x; i++) set_xy(i,y,BG); + break; + case DIR_L: + for(i=x1; i>=x; i--) set_xy(i,y,BG); + break; + case DIR_U: + for(i=y1; i>=y; i--) set_xy(x,i,BG); + break; + case DIR_D: + for(i=y1; i<=y; i++) set_xy(x,i,BG); + break; + } +} + + +void erase(FILE *fc){ + char c; + int orig_x = x, orig_y = y; + status_bar(); + show_cursor(); + while((c=fgetc(fc))!=EOF && c!=27 && c!= 'x' && c != '\n'){ + if (!move_around(c, fc)) continue; + check_bound(); + do_erase(orig_x, orig_y); + step = 1; + modified = 1; + orig_x = x; + orig_y = y; + redraw(); + status_bar(); + show_cursor(); + } + mode = MOVE; +} + + +/*** Visual ***/ + + +void visual_box(FILE *fc){ + int orig_x =x, orig_y = y; + char c, f = BG; + + redraw(); + step = 1; + set_video(VIDEO_REV); + draw_box(x,y,NOFIX); + while((c=fgetc(fc))!=EOF && c != 27 && c!= 'v' && c != '\n'){ + if (!move_around(c, fc)) switch(c){ + case 'f':/* fill */ + f = get_key(fc, "fill char: "); /** FALLTHROUGH **/ + case 'x':/* erase */ + erase_box(orig_x, orig_y, f); + modified = 1; + goto vis_exit; + break; + } + check_bound(); + set_video(VIDEO_NRM); + redraw(); + step = 1; + f = BG; + set_video(VIDEO_REV); + draw_box(orig_x, orig_y, NOFIX); + status_bar(); + show_cursor(); + } +vis_exit: + set_video(VIDEO_NRM); + redraw(); + mode = MOVE; +} |