summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatolaZ <katolaz@freaknet.org>2019-07-27 08:06:27 +0100
committerKatolaZ <katolaz@freaknet.org>2019-07-27 08:06:27 +0100
commitb38ed132a7df231fc08ce384d8559e6648fdd0cc (patch)
treea71b99edbc5ce15acfc2abec5e7c5b60edded5cd
parentf678684b470f02d9fed4818eb92c2a925380c428 (diff)
first step towards crop + some fixes to erase
-rw-r--r--TODO3
-rw-r--r--files.c2
-rw-r--r--gramscii.h5
-rw-r--r--main.c3
-rw-r--r--screen.c138
5 files changed, 110 insertions, 41 deletions
diff --git a/TODO b/TODO
index d521256..59534ac 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,6 @@
+ optimize redraws (redraw only the modified rectangle)
++ add crop command (C)
+- fix bug with 'g' commands in arrow mode
- add screen geometry option (-g 25x80?)
- read file at point
- read output of command (!)
@@ -11,7 +13,6 @@
+ parse control characters
+ parse arrows (text-mode will allow movements as well)
- (?) implement CTRL+G as abort (aside ESC)
-- add crop command (C)
- (?) remove extra blanks until EOL when saving to file
+ visual selection
- crop-to
diff --git a/files.c b/files.c
index 811a9bc..c007eac 100644
--- a/files.c
+++ b/files.c
@@ -53,7 +53,7 @@ void load_file(FILE *fc){
while((fgets(screen[i].s, WIDTH+2, fin)) != NULL && i<HEIGHT)
screen[i++].s[WIDTH-1]='\0';
for(;i<HEIGHT; i++){
- erase_line(screen[i].s);
+ erase_line(i);
}
fclose(fin);
}
diff --git a/gramscii.h b/gramscii.h
index 0b2c81f..6666515 100644
--- a/gramscii.h
+++ b/gramscii.h
@@ -59,7 +59,7 @@ typedef struct{
#define progr_x(d) ((d) == DIR_L ? -1 : (d) == DIR_R ? 1 : 0)
#define progr_y(d) ((d) == DIR_U ? -1 : (d) == DIR_D ? 1 : 0)
-/* #define DEBUG 1 */
+#define DEBUG 1
/** global variables **/
@@ -116,9 +116,10 @@ void get_string(FILE *fc, char *msg, char *s, int sz);
void erase_box(int x1, int y1, char c);
int is_yes(char c);
void init_screen();
-void erase_line(char *s);
+void erase_line(int i);
void erase_screen();
void go_to(int where);
+void crop_to_nonblank();
/** drawing-related functions **/
int change_style(char c);
diff --git a/main.c b/main.c
index c0f4b6b..195d8af 100644
--- a/main.c
+++ b/main.c
@@ -122,6 +122,9 @@ void commands(FILE *fc){
mode = VIS;
visual_box(fc);
break;
+ case 'C':
+ crop_to_nonblank();
+ break;
case 'q':
check_modified(fc);/** FALLTHROUGH **/
case 'Q':
diff --git a/screen.c b/screen.c
index 2e61acf..0c5f2d8 100644
--- a/screen.c
+++ b/screen.c
@@ -109,39 +109,64 @@ int is_yes(char c){
/*** Screen management ***/
-void show_cursor(){
- if (silent)
- return;
- printf("\033[%d;%df", y+1, x+1);
- fflush(stdout);
+void ensure_line_length(int i, int len){
+ char *tmp;
+
+ if (screen[i].sz < len + 1){
+ tmp = realloc(screen[i].s, (len+1) * 2 * sizeof(char));
+ if (!tmp){
+ fprintf(stderr, "Unable to allocate string\n");
+ exit(1);
+ }
+ screen[i].s = tmp;
+ screen[i].sz = (len + 1) * 2;
+ }
}
-void set_xy(int _x, int _y, char c){
+void alloc_line(int i){
+ char *tmp;
+
+ screen[i].sz = WIDTH+1;
+ tmp = malloc((screen[i].sz) * sizeof(char));
+ if (tmp == NULL){
+ fprintf(stderr, "unable to allocate line %d\n", i+1);
+ exit(1);
+ }
+ screen[i].s = tmp;
+ memset(screen[i].s, BG, screen[i].sz);
+ screen[i].lst = -1;
+ screen[i].s[0]='\0';
+}
+
+void ensure_num_lines(int n){
line_t *tmp;
- if (_y >= num_lines){
- tmp = realloc(screen, (_y + LONG_STEP)* sizeof(line_t));
+
+ if (n > num_lines){
+ tmp = realloc(screen, (n + LONG_STEP) * sizeof(line_t));
if (tmp == NULL){
fprintf(stderr, "Unable to allocate memory for more lines");
exit(1);
}
- else while ( num_lines < _y + LONG_STEP){
- screen[num_lines].sz = WIDTH+1;
- screen[num_lines].s = malloc((screen[num_lines].sz) * sizeof(char));
- if (screen[num_lines].s == NULL){
- perror("allocating screen[num_lines].s");
- exit(1);
- }
- memset(screen[num_lines].s, BG, screen[num_lines].sz);
- screen[num_lines].lst = 0;
- screen[num_lines].s[screen[num_lines].lst+1]='\0';
+ else while ( num_lines < n + LONG_STEP){
+ alloc_line(num_lines);
num_lines ++;
}
}
- if (screen[_y].sz < _x + 2){
- screen[_y].sz = (_x +2) * 2;
- screen[_y].s = realloc(screen[_y].s, screen[_y].sz * sizeof(char));
- }
+}
+
+
+void show_cursor(){
+ if (silent)
+ return;
+ printf("\033[%d;%df", y+1, x+1);
+ fflush(stdout);
+}
+
+
+void set_xy(int _x, int _y, char c){
+ ensure_num_lines(_y + 1);
+ ensure_line_length(_y, _x + 1);
while (screen[_y].lst<_x){
screen[_y].lst ++;
screen[_y].s[screen[_y].lst] = BG;
@@ -172,11 +197,9 @@ void update_current(){
fflush(stdout);
}
-void erase_line(char *s){
- while(*s){
- *s = BG;
- s++;
- }
+void erase_line(int i){
+ screen[i].lst = -1;
+ screen[i].s[0] = '\0';
}
void erase_box(int x1, int y1, char c){
@@ -196,7 +219,7 @@ void erase_box(int x1, int y1, char c){
void erase_screen(){
int i;
for(i=0;i<HEIGHT; i++)
- erase_line(screen[i].s);
+ erase_line(i);
}
void check_bound(){
@@ -399,15 +422,7 @@ void init_screen(){
exit(1);
}
for (i=0; i<HEIGHT; i++){
- screen[i].sz = WIDTH+1;
- screen[i].s = malloc((screen[i].sz) * sizeof(char));
- if (screen[i].s == NULL){
- perror("allocating screen[i].s");
- exit(1);
- }
- memset(screen[i].s, BG, screen[i].sz);
- screen[i].lst = 0;
- screen[i].s[screen[i].lst+1]='\0';
+ alloc_line(i);
}
hlines_sz= sizeof(hlines) -1;
vlines_sz= sizeof(vlines) -1;
@@ -417,3 +432,52 @@ void init_screen(){
reset_styles();
}
+void find_nonblank_rect(int *x1, int *y1, int *x2, int *y2){
+
+ int i, j;
+ int first;
+ *x1= WIDTH; /** FIXME: replace with num_cols **/
+ *y1 = num_lines;
+ *x2 = *y2 = 0;
+
+ for (i=0; i<num_lines; i++){
+ if (screen[i].lst < 0)
+ continue;
+ *y2 = i;
+ if (i < *y1)
+ *y1 = i;
+ if (screen[i].lst > *x2)
+ *x2 = screen[i].lst;
+ j = 0;
+ while(j <= screen[i].lst && isblank(first=screen[i].s[j]))
+ j++;
+ if (j < *x1)
+ *x1 = j;
+ }
+}
+
+void crop_to_rect(int x1, int y1, int x2, int y2){
+ int i;
+
+ for (i=0; i<= y2-y1; i ++){
+ ensure_line_length(i, screen[i+y1].lst);
+ sprintf(screen[i].s, "%s", screen[i+y1].s + x1);
+ screen[i].lst = screen[i+y1].lst - x1;
+ }
+ while (i<=y2){
+ screen[i].lst = -1;
+ screen[i].s[0]= '\0';
+ i ++;
+ }
+}
+
+void crop_to_nonblank(){
+ int x1, x2, y1, y2;
+ find_nonblank_rect(&x1, &y1, &x2, &y2);
+#ifdef DEBUG
+ fprintf(stderr, "crop rectangle: (%d, %d)-(%d, %d)\n", x1, y1, x2, y2);
+#endif
+ crop_to_rect(x1, y1, x2, y2);
+ redraw();
+}
+