draw.c - gramscii - A simple editor for ASCII box-and-arrow charts | |
Log | |
Files | |
Refs | |
Tags | |
README | |
LICENSE | |
--- | |
draw.c (14191B) | |
--- | |
1 #define _POSIX_C_SOURCE 200112L | |
2 | |
3 #include <stdlib.h> | |
4 #include <string.h> | |
5 | |
6 #include "gramscii.h" | |
7 #include "config.h" | |
8 | |
9 /** Extern declarations **/ | |
10 | |
11 extern int WIDTH, HEIGHT; | |
12 extern lineset_t screen; /* what is visualised */ | |
13 extern lineset_t cutbuf; /* cut/paste buffer */ | |
14 extern lineset_t *undo; /* undo list */ | |
15 | |
16 extern int undo_cur;/* undo position */ | |
17 extern int undo_lst;/* last valid undo position */ | |
18 | |
19 | |
20 extern int mode;/* mode */ | |
21 extern int dir;/* line direction */ | |
22 extern int step;/* current step */ | |
23 extern int x; | |
24 extern int y; | |
25 extern char corner; | |
26 extern char modified; /* set to 1 if screen modified since last save */ | |
27 | |
28 /* line and arrow markers */ | |
29 extern int cur_hl, cur_vl, cur_corn, cur_start, cur_end; | |
30 extern char line_h; | |
31 extern char line_v; | |
32 extern char mark_st; | |
33 extern char mark_end; | |
34 | |
35 /* number of available markers for each type */ | |
36 extern int hlines_sz; | |
37 extern int vlines_sz; | |
38 extern int corners_sz; | |
39 extern int stmarks_sz; | |
40 extern int endmarks_sz; | |
41 | |
42 | |
43 extern char autoend; /* set to 1 in auto-arrow mode */ | |
44 | |
45 /* Used by draw_arrow to identify the bounding box */ | |
46 extern int a_miny; | |
47 extern int a_maxy; | |
48 | |
49 /*** drawing-related functions ***/ | |
50 | |
51 /*** Lines and markers ***/ | |
52 | |
53 void toggle_hline(){ | |
54 | |
55 cur_hl = (cur_hl + 1) % hlines_sz; | |
56 line_h = hlines[cur_hl]; | |
57 | |
58 } | |
59 | |
60 void toggle_corner(){ | |
61 | |
62 cur_corn = (cur_corn + 1 ) % corners_sz; | |
63 corner = corners[cur_corn]; | |
64 | |
65 } | |
66 | |
67 void toggle_vline(){ | |
68 | |
69 cur_vl = (cur_vl + 1) % vlines_sz; | |
70 line_v = vlines[cur_vl]; | |
71 | |
72 } | |
73 | |
74 void toggle_st_mark(){ | |
75 | |
76 cur_start = (cur_start + 1 ) % stmarks_sz; | |
77 mark_st = st_marks[cur_start]; | |
78 } | |
79 | |
80 void toggle_end_mark(){ | |
81 | |
82 cur_end = (cur_end+ 1 ) % endmarks_sz; | |
83 mark_end = end_marks[cur_end]; | |
84 } | |
85 | |
86 int change_style(char c){ | |
87 switch(c){ | |
88 case '-': | |
89 toggle_hline(); | |
90 break; | |
91 case '|': | |
92 toggle_vline(); | |
93 break; | |
94 case '+': | |
95 toggle_corner(); | |
96 break; | |
97 case '<': | |
98 toggle_st_mark(); | |
99 break; | |
100 case '>': | |
101 toggle_end_mark(); | |
102 break; | |
103 case '.': | |
104 reset_styles(); | |
105 break; | |
106 default: | |
107 return 0; | |
108 } | |
109 return c; | |
110 } | |
111 | |
112 | |
113 | |
114 | |
115 /***** text, box, arrows *****/ | |
116 | |
117 void get_text(FILE *fc){ | |
118 char c; | |
119 int orig_x = x; | |
120 | |
121 redraw(); | |
122 copy_lines_to_ring(y, y, PRV_STATE); | |
123 while((c=fgetc(fc))!=EOF && c != 27){ | |
124 if(c=='\n'){ | |
125 set_cur(BG); | |
126 copy_lines_to_ring(y,y, NEW_STATE); | |
127 y += 1; | |
128 copy_lines_to_ring(y, y, PRV_STATE); | |
129 x = orig_x; | |
130 } | |
131 else { | |
132 set_cur(c); | |
133 update_current(); | |
134 modified = 1; | |
135 x += 1; | |
136 if (x >= WIDTH) | |
137 x = orig_x; | |
138 } | |
139 check_bound(&x, &y); | |
140 status_bar(); | |
141 show_cursor(); | |
142 } | |
143 if (modified) | |
144 copy_lines_to_ring(y, y, NEW_STATE); | |
145 mode=MOVE; | |
146 } | |
147 | |
148 void draw_box(int x1, int y1, int fix){ | |
149 | |
150 int xmin, ymin, xmax, ymax; | |
151 int i; | |
152 void (*f)(int, int, char); | |
153 | |
154 | |
155 xmin = MIN(x, x1); | |
156 xmax = MAX(x, x1); | |
157 ymin = MIN(y, y1); | |
158 ymax = MAX(y, y1); | |
159 | |
160 if (fix == FIX){ | |
161 f = set_xy; | |
162 copy_lines_to_ring(ymin, ymax, PRV_STATE); | |
163 } | |
164 else | |
165 f = draw_xy; | |
166 | |
167 for(i=xmin+1; i<=xmax; i++){ | |
168 f(i, ymin, line_h); | |
169 f(i, ymax, line_h); | |
170 } | |
171 for(i=ymin+1; i<=ymax; i++){ | |
172 f(xmin, i, line_v); | |
173 f(xmax, i, line_v); | |
174 } | |
175 f(xmin, ymin, corner); | |
176 f(xmin, ymax, corner); | |
177 f(xmax, ymin, corner); | |
178 f(xmax, ymax, corner); | |
179 if (fix == FIX) | |
180 copy_lines_to_ring(ymin, ymax, NEW_STATE); | |
181 show_cursor(); | |
182 } | |
183 | |
184 void draw_parallelogram(int x1, int y1, char st, char fix){ | |
185 int xmin, ymin, xmax, ymax; | |
186 int dy, minoff, maxoff, xoff, xincr; | |
187 int i; | |
188 char lean; | |
189 void (*f)(int, int, char); | |
190 | |
191 | |
192 xmin = MIN(x, x1); | |
193 xmax = MAX(x, x1); | |
194 ymin = MIN(y, y1); | |
195 ymax = MAX(y, y1); | |
196 dy = ymax - ymin; | |
197 | |
198 if (fix == FIX){ | |
199 f = set_xy; | |
200 copy_lines_to_ring(ymin, ymax, PRV_STATE); | |
201 } | |
202 else | |
203 f = draw_xy; | |
204 if (st == BOX_PARR){ | |
205 minoff = dy; | |
206 maxoff = 0; | |
207 lean = '/'; | |
208 xincr = -1; | |
209 } | |
210 else { | |
211 minoff = 0; | |
212 maxoff = dy; | |
213 lean = '\\'; | |
214 xincr = +1; | |
215 } | |
216 for(i=xmin+1; i<=xmax-dy; i++){ | |
217 f(i+minoff, ymin, line_h); | |
218 f(i+maxoff, ymax, line_h); | |
219 } | |
220 | |
221 for(i=ymin+1, xoff=minoff; i<=ymax; i++, xoff += xincr){ | |
222 f(xmin+(xoff+xincr), i, lean); | |
223 if (minoff) | |
224 f(xmax - (minoff - xoff - xincr), i, lean); | |
225 else | |
226 f(xmax - (maxoff - xoff - xincr), i, lean); | |
227 } | |
228 f(xmin+minoff, ymin, corner); | |
229 f(xmin+maxoff, ymax, corner); | |
230 f(xmax-maxoff, ymin, corner); | |
231 f(xmax-minoff, ymax, corner); | |
232 if (fix == FIX) | |
233 copy_lines_to_ring(ymin, ymax, NEW_STATE); | |
234 show_cursor(); | |
235 | |
236 } | |
237 | |
238 char flip_par_lean(char st){ | |
239 if (st == BOX_PARR) | |
240 return BOX_PARL; | |
241 else if (st == BOX_PARL) | |
242 return BOX_PARR; | |
243 return st; | |
244 } | |
245 | |
246 void draw_trapezium(int x1, int y1, char st, char fix){ | |
247 int xmin, ymin, xmax, ymax; | |
248 int dx, dy, ylong, yshort, xoff; | |
249 int xincr; | |
250 int i; | |
251 void (*f)(int, int, char); | |
252 char left_c, right_c; | |
253 | |
254 xmin = MIN(x, x1); | |
255 xmax = MAX(x, x1); | |
256 ymin = MIN(y, y1); | |
257 ymax = MAX(y, y1); | |
258 dx = (xmax - xmin); | |
259 dy = ymax - ymin; | |
260 /* dy = MAX(dx2, dy); */ | |
261 #ifdef DEBUG | |
262 fprintf(stderr, "dy: %d dx: %d\n", dy, dx); | |
263 #endif | |
264 if (fix == FIX){ | |
265 f = set_xy; | |
266 copy_lines_to_ring(ymin, ymax, PRV_STATE); | |
267 } | |
268 else | |
269 f = draw_xy; | |
270 | |
271 /* This is valid only for "upper" trapezoids */ | |
272 if (STYLE_IS(st, BOX_TRAP_U)){ | |
273 #ifdef DEBUG | |
274 fprintf(stderr, "This is an 'upward' trapezium\n"); | |
275 #endif | |
276 ylong = ymax; | |
277 yshort = ymin; | |
278 xoff = dy; | |
279 xincr = -1; | |
280 left_c = '/'; | |
281 right_c = '\\'; | |
282 } | |
283 else if (STYLE_IS(st, BOX_TRAP_D)){ | |
284 #ifdef DEBUG | |
285 fprintf(stderr, "This is a 'downward' trapezium\n"); | |
286 #endif | |
287 ylong = ymin; | |
288 yshort = ymax; | |
289 xoff = dy; | |
290 xincr = +1; | |
291 right_c = '/'; | |
292 left_c = '\\'; | |
293 } | |
294 /* Long side */ | |
295 for(i=xmin+1; i<=xmax; i++){ | |
296 f(i, ylong, line_h); | |
297 } | |
298 | |
299 if (STYLE_IS(st, BOX_TRAP_L)){ | |
300 /* short side */ | |
301 left_c = '/'; | |
302 right_c = line_v; | |
303 for(i=xmin+xoff;i<xmax; i++){ | |
304 f(i, yshort, line_h); | |
305 } | |
306 xoff = dy; | |
307 if (STYLE_IS(st, BOX_TRAP_D)){ | |
308 xoff = 0; | |
309 left_c = '\\'; | |
310 } | |
311 for(i=ymin; i<ymax; i++, xoff += xincr){ | |
312 f(xmin+xoff, i, left_c); | |
313 f(xmax, i, right_c); | |
314 } | |
315 f(xmin+dy, yshort, corner); | |
316 f(xmax, yshort, corner); | |
317 } | |
318 else if (STYLE_IS(st, BOX_TRAP_R)){ | |
319 right_c = '\\'; | |
320 left_c = line_v; | |
321 for(i=xmin; i<xmax-xoff; i++){ | |
322 f(i, yshort, line_h); | |
323 } | |
324 xoff = dy-1; | |
325 if (STYLE_IS(st, BOX_TRAP_D)){ | |
326 xoff = 1; | |
327 right_c = '/'; | |
328 } | |
329 for(i=ymin+1; i<ymax; i++, xoff += xincr){ | |
330 f(xmin, i, left_c); | |
331 f(xmax-xoff, i, right_c); | |
332 } | |
333 f(xmin, yshort, corner); | |
334 f(xmax-dy, yshort, corner); | |
335 } | |
336 else if (STYLE_IS(st, BOX_TRAP_C)){ | |
337 xoff = dy; | |
338 for (i=xmin+xoff; i<=xmax-xoff; i++){ | |
339 f(i, yshort, line_h); | |
340 } | |
341 xoff = dy - 1; | |
342 if (STYLE_IS(st, BOX_TRAP_D)) | |
343 xoff = 1; | |
344 for(i=ymin+1; i<ymax; i++, xoff += xincr){ | |
345 f(xmin + xoff, i, left_c); | |
346 f(xmax - xoff, i, right_c); | |
347 } | |
348 f(xmin+dy, yshort, corner); | |
349 f(xmax-dy, yshort, corner); | |
350 } | |
351 | |
352 | |
353 f(xmin, ylong, corner); | |
354 f(xmax, ylong, corner); | |
355 | |
356 | |
357 if (fix == FIX) | |
358 copy_lines_to_ring(ymin, ymax, NEW_STATE); | |
359 show_cursor(); | |
360 | |
361 } | |
362 | |
363 /* | |
364 * draw the current box, being it an actual box, a parallelogram, or a | |
365 * trapezium | |
366 */ | |
367 void update_box(int x1, int y1, char st, char fix){ | |
368 | |
369 if (st == BOX_RECT) | |
370 draw_box(x1, y1, fix); | |
371 else if (st & BOX_PAR) | |
372 draw_parallelogram(x1, y1, st, fix); | |
373 else if (st & BOX_TRAP) | |
374 draw_trapezium(x1, y1, st, fix); | |
375 status_bar(); | |
376 show_cursor(); | |
377 } | |
378 | |
379 char toggle_trap_type(char st){ | |
380 if (st & BOX_TRAP){ | |
381 if (st != BOX_TRAP_DR) | |
382 st += 1; | |
383 else | |
384 st = BOX_TRAP_UR; | |
385 } | |
386 if (st == BOX_TRAP_D) | |
387 st += 1; | |
388 return st; | |
389 } | |
390 | |
391 int box_end(char c, char st){ | |
392 if (c == '\n' || | |
393 c == 27 || | |
394 ((st == BOX_RECT) && c == 'b') || | |
395 ((st & BOX_PAR) && c == 'z') || | |
396 ((st & BOX_TRAP) && c == 't')) | |
397 return 1; | |
398 return 0; | |
399 } | |
400 | |
401 /* draw boxes, parallelograms, and trapezia */ | |
402 void get_box(FILE *fc, char st){ | |
403 char c; | |
404 int orig_x=x, orig_y=y; | |
405 redraw(); | |
406 step = 1; | |
407 #ifdef DEBUG | |
408 fprintf(stderr, "box style: %d\n", st); | |
409 #endif | |
410 draw_box(x,y,NOFIX); | |
411 while((c=fgetc(fc))!=EOF && !box_end(c, st)){ | |
412 if (c == 'Z' && (st & BOX_PAR)){ | |
413 st = flip_par_lean(st); | |
414 redraw(); | |
415 #ifdef DEBUG | |
416 fprintf(stderr, "new parallelogram style: %d\n",… | |
417 #endif | |
418 update_box(orig_x, orig_y, st, NOFIX); | |
419 continue; | |
420 } | |
421 else if (c == 'T' && (st & BOX_TRAP)){ | |
422 st = toggle_trap_type(st); | |
423 #ifdef DEBUG | |
424 fprintf(stderr, "new trapezium style: %d\n", st); | |
425 #endif | |
426 redraw(); | |
427 update_box(orig_x, orig_y, st, NOFIX); | |
428 continue; | |
429 } | |
430 if (change_style(c)){ | |
431 update_box(orig_x, orig_y, st, NOFIX); | |
432 continue; | |
433 } | |
434 if (!move_around(c, fc, 1)) | |
435 continue; | |
436 check_bound(&x, &y); | |
437 redraw(); | |
438 step = 1; | |
439 update_box(orig_x, orig_y, st, NOFIX); | |
440 } | |
441 if (((st == BOX_RECT ) && (c == 'b' || c == '\n')) || | |
442 ( (st & BOX_PAR ) && (c == 'z' || c == '\n')) || | |
443 ( (st & BOX_TRAP ) && (c == 't' || c == '\n'))){ | |
444 update_box(orig_x, orig_y, st, FIX); | |
445 modified = 1; | |
446 } | |
447 redraw(); | |
448 mode = MOVE; | |
449 } | |
450 | |
451 void draw_arrow(int xl, int yl, short *a, int a_len, int fix){ | |
452 | |
453 int i, j, cur_dir; | |
454 char line; | |
455 void (*f)(int, int, char); | |
456 | |
457 a_miny = a_maxy = yl; | |
458 if (fix == FIX) | |
459 f = set_xy; | |
460 else | |
461 f = draw_xy; | |
462 | |
463 f(xl, yl, mark_st); | |
464 if (!a_len){ | |
465 show_cursor(); | |
466 return; | |
467 } | |
468 cur_dir=DIR_N; | |
469 for (i=0; i<a_len; i+=2){ | |
470 if (i>0) { | |
471 /* If we are switching between horizontal and ve… | |
472 if (((cur_dir & DIR_HOR) && (a[i] & DIR_VER)) || | |
473 ((cur_dir & DIR_VER) && (a[i] & DIR_HOR))){ | |
474 f(xl, yl, corner); | |
475 show_cursor(); | |
476 } | |
477 } | |
478 for(j=0; j<a[i+1]; j++){ | |
479 line = (a[i] & DIR_L) || (a[i] & DIR_R) ? line_h… | |
480 xl += progr_x(a[i]); | |
481 yl += progr_y(a[i]); | |
482 check_bound(&xl, &yl); | |
483 if (yl < a_miny) a_miny = yl; | |
484 if (yl > a_maxy) a_maxy = yl; | |
485 f(xl, yl, line); | |
486 } | |
487 /* f(x,y,mark_end);*/ | |
488 cur_dir = a[i]; | |
489 } | |
490 if (autoend){ | |
491 if (cur_dir != DIR_N) | |
492 f(xl,yl, get_mark(cur_dir)); | |
493 } | |
494 else | |
495 f(xl,yl,mark_end); | |
496 show_cursor(); | |
497 } | |
498 | |
499 void get_arrow(FILE *fc){ | |
500 | |
501 char c; | |
502 int orig_x=x, orig_y=y, arrow_len; | |
503 static short *arrow = NULL; | |
504 short *tmp = NULL; | |
505 static int arrow_sz; | |
506 | |
507 if (!arrow){ | |
508 arrow_sz = 100; | |
509 arrow = malloc(arrow_sz * sizeof(short)); | |
510 if (arrow == NULL){ | |
511 fprintf(stderr, "Unable to allocate arrow"); | |
512 cleanup(1); | |
513 } | |
514 } | |
515 arrow_len = 0; | |
516 dir = DIR_N; | |
517 | |
518 redraw(); | |
519 step = 1; | |
520 draw_arrow(x,y, arrow, 0, NOFIX); | |
521 while((c=fgetc(fc))!=EOF && c != 27 && c!= 'a' && c != '\n'){ | |
522 if (change_style(c)) | |
523 goto update_arrow; | |
524 if (!move_around(c, fc, 0)) | |
525 continue; | |
526 check_bound(&x, &y); | |
527 /* FIXME: if we are out of bound, do nothing? */ | |
528 if (arrow_len == arrow_sz){ | |
529 arrow_sz *=2; | |
530 tmp = realloc(arrow, arrow_sz * sizeof(short)); | |
531 if (tmp == NULL){ | |
532 fprintf(stderr, "Unable to reallocate ar… | |
533 cleanup(1); | |
534 } | |
535 arrow = tmp; | |
536 } | |
537 if (dir != DIR_N){ | |
538 arrow[arrow_len++] = dir; | |
539 arrow[arrow_len++] = step; | |
540 } | |
541 redraw(); | |
542 step = 1; | |
543 update_arrow: | |
544 draw_arrow(orig_x, orig_y, arrow, arrow_len, NOFIX); | |
545 status_bar(); | |
546 show_cursor(); | |
547 } | |
548 if (c == 'a' || c == '\n'){ | |
549 copy_lines_to_ring(a_miny, a_maxy, PRV_STATE); | |
550 draw_arrow(orig_x, orig_y, arrow, arrow_len, FIX); | |
551 copy_lines_to_ring(a_miny, a_maxy, NEW_STATE); | |
552 modified = 1; | |
553 } | |
554 redraw(); | |
555 mode = MOVE; | |
556 } | |
557 | |
558 | |
559 void do_erase(int x1, int y1){ | |
560 int i; | |
561 switch(dir){ | |
562 case DIR_R: | |
563 for(i=x1; i<=x; i++) set_xy(i,y,BG); | |
564 break; | |
565 case DIR_L: | |
566 for(i=x1; i>=x; i--) set_xy(i,y,BG); | |
567 break; | |
568 case DIR_U: | |
569 for(i=y1; i>=y; i--) set_xy(x,i,BG); | |
570 break; | |
571 case DIR_D: | |
572 for(i=y1; i<=y; i++) set_xy(x,i,BG); | |
573 break; | |
574 } | |
575 } | |
576 | |
577 | |
578 void erase(FILE *fc){ | |
579 /*FIXME: add affected lines to undo */ | |
580 char c; | |
581 int orig_x = x, orig_y = y; | |
582 char first = 1, opened = 0; | |
583 status_bar(); | |
584 show_cursor(); | |
585 while((c=fgetc(fc))!=EOF && c!=27 && c!= 'x' && c != '\n'){ | |
586 if (!move_around(c, fc, 0)) continue; | |
587 check_bound(&x, &y); | |
588 if (first || | |
589 (y != orig_y && ! opened) || | |
590 (y == orig_y && x != orig_x && !opened) ){ | |
591 copy_lines_to_ring(MIN(y, orig_y), MAX(y, orig_y… | |
592 first = 0; | |
593 opened = 1; | |
594 } | |
595 do_erase(orig_x, orig_y); | |
596 if (y != orig_y && opened){ | |
597 copy_lines_to_ring(MIN(y, orig_y), MAX(y, orig_y… | |
598 opened = 0; | |
599 } | |
600 step = 1; | |
601 modified = 1; | |
602 orig_x = x; | |
603 orig_y = y; | |
604 redraw(); | |
605 status_bar(); | |
606 show_cursor(); | |
607 } | |
608 if (opened) | |
609 copy_lines_to_ring(y, y, NEW_STATE); | |
610 mode = MOVE; | |
611 } | |
612 | |
613 | |
614 | |
615 | |
616 | |
617 /*** Visual ***/ | |
618 | |
619 | |
620 void visual_box(FILE *fc){ | |
621 int orig_x =x, orig_y = y; | |
622 char c, f = BG; | |
623 | |
624 redraw(); | |
625 step = 1; | |
626 set_video(VIDEO_REV); | |
627 draw_box(x,y,NOFIX); | |
628 while((c=fgetc(fc))!=EOF && c != 27 && c!= 'v' && c != '\n'){ | |
629 if (!move_around(c, fc, 1)) switch(c){ | |
630 case 'y': /* yank (copy) */ | |
631 yank_region(MIN(orig_x,x), MIN(orig_y,y)… | |
632 goto vis_exit; | |
633 break; | |
634 case 'f':/* fill */ | |
635 f = get_key(fc, "fill char: "); /** FALL… | |
636 case 'x':/* erase */ | |
637 if (c == 'x') | |
638 yank_region(MIN(orig_x,x), MIN(o… | |
639 copy_lines_to_ring(MIN(orig_y, y), MAX(o… | |
640 erase_box(orig_x, orig_y, f); | |
641 erase_blank_lines(MIN(y,orig_y), MAX(y, … | |
642 copy_lines_to_ring(MIN(orig_y, y), MAX(o… | |
643 | |
644 modified = 1; | |
645 goto vis_exit; | |
646 break; | |
647 case 'C':/* crop-to-region */ | |
648 copy_lines_to_ring(0, HEIGHT-1, PRV_STAT… | |
649 crop_to_rect(MIN(x, orig_x), MIN(y, orig… | |
650 copy_lines_to_ring(0, HEIGHT-1, NEW_STAT… | |
651 modified = 1; | |
652 goto vis_exit; | |
653 break; | |
654 } | |
655 check_bound(&x, &y); | |
656 set_video(VIDEO_NRM); | |
657 redraw(); | |
658 step = 1; | |
659 f = BG; | |
660 set_video(VIDEO_REV); | |
661 draw_box(orig_x, orig_y, NOFIX); | |
662 status_bar(); | |
663 show_cursor(); | |
664 } | |
665 vis_exit: | |
666 set_video(VIDEO_NRM); | |
667 redraw(); | |
668 mode = MOVE; | |
669 } | |
670 | |
671 /*** yank/paste/undo ***/ | |
672 | |
673 void paste(){ | |
674 int y2; | |
675 | |
676 y2 = y + cutbuf.num - 1; | |
677 copy_lines_to_ring(y, y2, PRV_STATE); | |
678 paste_region(x, y); | |
679 copy_lines_to_ring(y, y2, NEW_STATE); | |
680 redraw(); | |
681 } | |
682 | |
683 void put_lines(lineset_t *u){ | |
684 int i, n; | |
685 | |
686 for (i=0; i< u->num; i++){ | |
687 n = u->l[i].n; | |
688 ensure_line_length(&(screen.l[i]), strlen(u->l[i].s)); | |
689 strcpy(screen.l[n].s, u->l[i].s); | |
690 screen.l[n].lst = strlen(u->l[i].s)-1; | |
691 } | |
692 } | |
693 | |
694 | |
695 void undo_change(){ | |
696 if (undo_cur >= 0){ | |
697 if (undo_cur > undo_lst) | |
698 undo_cur = undo_lst; | |
699 put_lines(& (undo[undo_cur])); | |
700 undo_cur -= 2; | |
701 modified = 1; | |
702 } | |
703 redraw(); | |
704 } | |
705 | |
706 void redo_change(){ | |
707 if (undo_cur <= undo_lst-2){ | |
708 if (undo_cur > 0) | |
709 put_lines(& (undo[undo_cur+1])); | |
710 undo_cur +=2; | |
711 put_lines(& (undo[undo_cur+1])); | |
712 modified = 1; | |
713 } | |
714 redraw(); | |
715 } | |
716 | |
717 | |
718 /** Comments **/ | |
719 | |
720 void get_comment(FILE *fc){ | |
721 char c; | |
722 redraw(); | |
723 while((c = fgetc(fc)) != EOF && c != '\n'); | |
724 mode = MOVE; | |
725 } | |
726 |