"Fossies" - the Fresh Open Source Software Archive 
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*
2
3 Textdraw (td) is a small utility that allows do draw (ascii-based) line-,
4 rectangle-, ellipse- and text-objects with copy/paste/move features.
5
6 Homepage of Textdraw: http://web.uta4you.at/shop/td/index.htm
7 (c) July/2002 by Dieter Schoppitsch (shop@uta4you.at)
8
9 */
10
11 #include <ncurses.h>
12 #include <math.h>
13 #include <errno.h>
14 #include <string.h>
15
16 #define trunc(x) ((int)(x))
17
18 #define ESC 27 // escape key
19 #define ENTER 10 // enter key
20 #define DEL 330 // del key
21 #define MAXOBJECTS 100 // maximum of possible objects
22 #define MAXTXTLEN 200 // max string length
23
24 /* VARIABLES*/
25 int x=0, y=0;
26 int maxrow=23, maxcol=79, menrow=24;
27 int lastlin=0, lastrec=0, lasttxt=0, lastell=0;
28 char chart[MAXTXTLEN][MAXTXTLEN]; // max chart (console) dimensions
29 char string[MAXTXTLEN]="";
30 FILE *fil;
31 char *filename;
32
33 struct _line_
34 {int x1,y1,x2,y2; char a;};
35 struct _line_ lin[MAXOBJECTS];
36
37 struct _rect_
38 {int x1,y1,x2,y2;};
39 struct _rect_ rec[MAXOBJECTS];
40
41 struct _ell_
42 {int x1,y1,x2,y2;};
43 struct _ell_ ell[MAXOBJECTS];
44
45 struct _text_
46 {int x,y; char a; char t[MAXTXTLEN];};
47 struct _text_ txt[MAXOBJECTS];
48
49 struct _mark_
50 {char a; int nr;};
51 struct _mark_ mark;
52
53 struct _buf_
54 {int x1,y1,x2,y2; char c,a; char t[MAXTXTLEN];};
55 struct _buf_ buf;
56
57 /* SUBPROGRAMS */
58 int round(float x) // round function
59 { if(x>=0) return trunc(x+0.5);
60 else return trunc(x-0.5);
61 }
62
63 void clearcomment() // clears comment line
64 { int i;
65 char s[MAXTXTLEN];
66 for(i=0;i<=maxcol;i++) s[i]=' ';
67 mvprintw(menrow, 0,"%s",s);
68 }
69
70 void comment(char *txt) // print comment
71 { clearcomment(); mvprintw(menrow, 0,"%s", txt);}
72
73 void comment_error(char *where)
74 { char buf[128];
75 snprintf(buf, sizeof(buf), "%s: %s", where, strerror(errno));
76 comment(buf);
77 }
78
79 void curpos() //position cursor with printing coordinates
80 { mvprintw(menrow,maxcol-10," ");
81 mvprintw(menrow,maxcol-10,"x=%d y=%d",x,y);
82 mvprintw(y,x,"");
83 }
84
85 void cursor() // move cursor to a new position
86 { int c;
87 while((c=getch()) != ENTER)
88 { switch(c)
89 {
90 case KEY_UP:
91 y-=1; if(y<0) y=0;
92 curpos();
93 break;
94 case KEY_DOWN:
95 y+=1; if(y>maxrow) y=maxrow;
96 curpos();
97 break;
98 case KEY_LEFT:
99 x-=1; if(x<0) x=0;
100 curpos();
101 break;
102 case KEY_RIGHT:
103 x+=1; if(x>maxcol) x=maxcol;
104 curpos();
105 break;
106 case KEY_HOME:
107 x=0; curpos();
108 break;
109 case KEY_END:
110 x=maxcol; curpos();
111 break;
112 case KEY_PPAGE:
113 y=0; curpos();
114 break;
115 case KEY_NPAGE:
116 y=maxrow; curpos();
117 break;
118 }
119 }
120 }
121
122 void input() // reads (inputs) value for string
123 { clearcomment();
124 mvprintw(menrow,0,"%s ",string);
125 echo(); getstr(string); noecho();
126 }
127
128 void help() // print help screen
129 { int c; clear();
130 printw("\nTEXTDRAW 0.2 (c) by Dieter Schoppitsch\n\n");
131 printw("c copy copy marked object to buffer\n");
132 printw("d delete delete marked object\n");
133 printw("e ellipse draw ellipse-object\n");
134 printw("h help this help page\n");
135 printw("l line draw line-object\n");
136 printw("m move move marked object\n");
137 printw("p print print to ascii-file 'print'\n");
138 printw("q, ESC exit exit (without saving!)\n");
139 printw("r rectangle draw rectangle-object\n");
140 printw("s save save file\n");
141 printw("t text draw text-object\n");
142 printw("v paste paste buffer\n");
143 printw("\n");
144 printw("position cursor with cursor keys\n");
145 printw("mark object at 'hot spot'\n");
146 printw("to load existing file: <td filename>\n");
147 printw("try also: home, end, pgdn, pgup\n");
148 refresh(); c=getch();
149 }
150
151 /* INIT */
152 void init() // sets initial values
153 { int i,j;
154 for(i=0;i<=maxrow;i++) for(j=0;j<=maxcol;j++) chart[i][j]=' ';
155 }
156
157
158 /* DRAW */
159 void drawtxt() // draws textobjects to chart-array
160 { int i,j;
161 for(i=0;i<lasttxt;i++) for(j=0;j<=strlen(txt[i].t)-1;j++)
162 if(txt[i].a=='u')
163 { if(txt[i].y-j>=0 && txt[i].x+j<=maxcol)
164 chart[txt[i].y-j][txt[i].x+j]=txt[i].t[j];
165 }
166 else if(txt[i].a=='v')
167 { if(j+txt[i].y<=maxrow)
168 chart[txt[i].y+j][txt[i].x]=txt[i].t[j];
169 }
170 else if(txt[i].a=='d')
171 { if(j+txt[i].y<=maxrow && j+txt[i].x<=maxcol)
172 chart[txt[i].y+j][txt[i].x+j]=txt[i].t[j];
173 }
174 else
175 { if(j+txt[i].x<=maxcol)
176 chart[txt[i].y][txt[i].x+j]=txt[i].t[j];
177 }
178 }
179
180 void drawlin() // draws line in chart-array
181 { int i,j;
182 float k,d;
183
184 for(i=0;i<lastlin;i++)
185 if(lin[i].x1!=lin[i].x2 || lin[i].y1!=lin[i].y2)
186 { if(abs(lin[i].x1-lin[i].x2)>abs(lin[i].y1-lin[i].y2))
187 { k=(float)(lin[i].y1-lin[i].y2)/(lin[i].x1-lin[i].x2);
188 d=lin[i].y1-k*lin[i].x1;
189 if(lin[i].x1<lin[i].x2)
190 for(j=lin[i].x1;j<=lin[i].x2;j++)
191 chart[round(k*j+d)][j]=lin[i].a;
192 else
193 for(j=lin[i].x2;j<=lin[i].x1;j++)
194 chart[round(k*j+d)][j]=lin[i].a;
195 }
196 else
197 { k=(float)(lin[i].x1-lin[i].x2)/(lin[i].y1-lin[i].y2);
198 d=lin[i].x1-k*lin[i].y1;
199 if(lin[i].y1<lin[i].y2)
200 for(j=lin[i].y1;j<=lin[i].y2;j++)
201 chart[j][round(k*j+d)]=lin[i].a;
202 else
203 for(j=lin[i].y2;j<=lin[i].y1;j++)
204 chart[j][round(k*j+d)]=lin[i].a;
205 }
206 }
207 }
208
209 void drawrec() // draws rectangle in chart-array
210 { int i,j;
211
212 for(i=0;i<lastrec;i++)
213 if(rec[i].x1!=rec[i].x2 || rec[i].y1!=rec[i].y2)
214 { if(rec[i].x2>rec[i].x1 && rec[i].y2>rec[i].y1)
215 { for(j=rec[i].y1+1;j<=rec[i].y2;j++)
216 { chart[j][rec[i].x1]='|';
217 chart[j][rec[i].x2]='|';
218 }
219 for(j=rec[i].x1+1;j<=rec[i].x2-1;j++)
220 { chart[rec[i].y1][j]='_';
221 chart[rec[i].y2][j]='_';
222 }
223 }
224 else if(rec[i].x2>rec[i].x1 && rec[i].y1>rec[i].y2)
225 { for(j=rec[i].y2+1;j<=rec[i].y1;j++)
226 { chart[j][rec[i].x1]='|';
227 chart[j][rec[i].x2]='|';
228 }
229 for(j=rec[i].x1+1;j<=rec[i].x2-1;j++)
230 { chart[rec[i].y1][j]='_';
231 chart[rec[i].y2][j]='_';
232 }
233 }
234 else if(rec[i].x1>rec[i].x2 && rec[i].y2>rec[i].y1)
235 { for(j=rec[i].y1+1;j<=rec[i].y2;j++)
236 { chart[j][rec[i].x1]='|';
237 chart[j][rec[i].x2]='|';
238 }
239 for(j=rec[i].x2+1;j<=rec[i].x1-1;j++)
240 { chart[rec[i].y1][j]='_';
241 chart[rec[i].y2][j]='_';
242 }
243 }
244 else
245 { for(j=rec[i].y2+1;j<=rec[i].y1;j++)
246 { chart[j][rec[i].x1]='|';
247 chart[j][rec[i].x2]='|';
248 }
249 for(j=rec[i].x2+1;j<=rec[i].x1-1;j++)
250 { chart[rec[i].y1][j]='_';
251 chart[rec[i].y2][j]='_';
252 }
253 }
254 }
255 }
256
257 void drawell() // draws ellipse in chart-array
258 { int i,j;
259 float a,b,s;
260
261 for(i=0;i<lastell;i++)
262 if(ell[i].x1!=ell[i].x2 || ell[i].y1!=ell[i].y2)
263 { a=(float)abs(ell[i].x2-ell[i].x1)/2;
264 b=(float)abs(ell[i].y2-ell[i].y1)/2;
265 if(abs(ell[i].x1-ell[i].x2)>abs(ell[i].y1-ell[i].y2)) // y(x)
266 { if(ell[i].x1<ell[i].x2 && ell[i].y1<ell[i].y2)
267 for(j=ell[i].x1;j<=ell[i].x2;j++)
268 {
269 s=sqrt((1-(j-ell[i].x1-a)*(j-ell[i].x1-a)/a/a)*b*b);
270 chart[ell[i].y1+round(b-s)][j]='*';
271 chart[ell[i].y1+round(b+s)][j]='*';
272 }
273 else if(ell[i].x1<ell[i].x2 && ell[i].y1>ell[i].y2)
274 for(j=ell[i].x1;j<=ell[i].x2;j++)
275 {
276 s=sqrt((1-(j-ell[i].x1-a)*(j-ell[i].x1-a)/a/a)*b*b);
277 chart[ell[i].y1-round(b-s)][j]='*';
278 chart[ell[i].y1-round(b+s)][j]='*';
279 }
280 else if(ell[i].x1>ell[i].x2 && ell[i].y1<ell[i].y2)
281 for(j=ell[i].x2;j<=ell[i].x1;j++)
282 {
283 s=sqrt((1-(j-ell[i].x2-a)*(j-ell[i].x2-a)/a/a)*b*b);
284 chart[ell[i].y1+round(b-s)][j]='*';
285 chart[ell[i].y1+round(b+s)][j]='*';
286 }
287 else
288 for(j=ell[i].x2;j<=ell[i].x1;j++)
289 {
290 s=sqrt((1-(j-ell[i].x2-a)*(j-ell[i].x2-a)/a/a)*b*b);
291 chart[ell[i].y1-round(b-s)][j]='*';
292 chart[ell[i].y1-round(b+s)][j]='*';
293 }
294 }
295 else // x(y)
296 { if(ell[i].x1<ell[i].x2 && ell[i].y1<ell[i].y2)
297 for(j=ell[i].y1;j<=ell[i].y2;j++)
298 {
299 s=sqrt((1-(j-ell[i].y1-b)*(j-ell[i].y1-b)/b/b)*a*a);
300 chart[j][ell[i].x1+round(a-s)]='*';
301 chart[j][ell[i].x1+round(a+s)]='*';
302 }
303 else if(ell[i].x1<ell[i].x2 && ell[i].y1>ell[i].y2)
304 for(j=ell[i].y2;j<=ell[i].y1;j++)
305 {
306 s=sqrt((1-(j-ell[i].y2-b)*(j-ell[i].y2-b)/b/b)*a*a);
307 chart[j][ell[i].x1+round(a-s)]='*';
308 chart[j][ell[i].x1+round(a+s)]='*';
309 }
310 else if(ell[i].x1>ell[i].x2 && ell[i].y1<ell[i].y2)
311 for(j=ell[i].y1;j<=ell[i].y2;j++)
312 {
313 s=sqrt((1-(j-ell[i].y1-b)*(j-ell[i].y1-b)/b/b)*a*a);
314 chart[j][ell[i].x1-round(a-s)]='*';
315 chart[j][ell[i].x1-round(a+s)]='*';
316 }
317 else
318 for(j=ell[i].y2;j<=ell[i].y1;j++)
319 {
320 s=sqrt((1-(j-ell[i].y2-b)*(j-ell[i].y2-b)/b/b)*a*a);
321 chart[j][ell[i].x1-round(a-s)]='*';
322 chart[j][ell[i].x1-round(a+s)]='*';
323 }
324 }
325 }
326
327 }
328
329 void draw() // draws chart-array on screen
330 { int i,j;
331
332 for(i=0;i<=maxrow;i++) for(j=0;j<=maxcol;j++) chart[i][j]=' ';
333
334 drawlin();
335 drawrec();
336 drawell();
337 drawtxt();
338
339 mvprintw(0,0,"");
340 for(i=0;i<=maxrow;i++) printw("%s",chart[i]);
341 curpos();
342 refresh();
343 }
344
345 /* INPUTS */
346 void textinput() // input of text-object-parameter
347 { int c;
348 txt[lasttxt].x=x; txt[lasttxt].y=y;
349
350 string[0]='\0'; strcpy(string,"input text: ");
351 input();
352 strcpy(txt[lasttxt].t, string),
353
354 string[0]='\0';
355 strcpy(string,
356 "alignment - vertical/horizontal/upward/downward (v/h/u/d): ");
357 input(); txt[lasttxt].a=string[0];
358
359 c=string[0];
360 if(c!='v' && c!='V' && c!='u' && c!='U' && c!='d' && c!='D')
361 txt[lasttxt].a='h';
362
363 clearcomment(); curpos();
364
365 lasttxt+=1;
366 }
367
368 void lineinput() // inputs line-object-parameter
369 { lin[lastlin].x1=x; lin[lastlin].y1=y;
370 curpos();
371 comment("mark end of line");
372 mvprintw(y,x,"");
373
374 cursor();
375
376 lin[lastlin].x2=x; lin[lastlin].y2=y;
377 string[0]='\0'; strcpy(string,"line draw character: ");
378 input(); lin[lastlin].a=string[0];
379 clearcomment(); curpos();
380
381 lastlin+=1;
382 }
383
384 void recinput() // inputs rectangle-object-paramenter
385 { rec[lastrec].x1=x; rec[lastrec].y1=y;
386
387 comment("mark 2nd point of rectangle");
388 mvprintw(y,x,"");
389
390 cursor();
391
392 rec[lastrec].x2=x; rec[lastrec].y2=y;
393 clearcomment(); curpos();
394
395
396 lastrec+=1;
397 }
398
399 void ellinput() // inputs ellipse-object-parameter
400 { ell[lastell].x1=x; ell[lastell].y1=y;
401
402 comment("mark 2nd point of ellipse");
403 mvprintw(y,x,"");
404
405 cursor();
406
407 ell[lastell].x2=x; ell[lastell].y2=y;
408 clearcomment(); curpos();
409
410 lastell+=1;
411 }
412
413 /* MARK, MOVE/DELETE/COPY/PASTE */
414
415 void markobj() // mark objekt to move, delete, copy, paste
416 { int i;
417 mark.a=' '; mark.nr=0;
418
419 for(i=0;i<lastlin;i++) if(x==lin[i].x1 && y==lin[i].y1)
420 { mark.a='l'; mark.nr=i;
421 }
422 for(i=0;i<lastrec;i++) if(x==rec[i].x1 && y==rec[i].y1)
423 { mark.a='r'; mark.nr=i;
424 }
425 for(i=0;i<lastell;i++) if(x==ell[i].x1 && y==ell[i].y1)
426 { mark.a='e'; mark.nr=i;
427 }
428 for(i=0;i<lasttxt;i++) if(x==txt[i].x && y==txt[i].y)
429 { mark.a='t'; mark.nr=i;
430 }
431 }
432
433 void moving() // moves marked objekt to other position
434 { int dx,dy;
435
436 markobj();
437 if(mark.a=='t')
438 { mvprintw(txt[mark.nr].x,txt[mark.nr].y,"");
439 comment("move text to");
440 curpos(); cursor(); clearcomment();
441 dx=x-txt[mark.nr].x; dy=y-txt[mark.nr].y;
442 txt[mark.nr].x=txt[mark.nr].x+dx;
443 txt[mark.nr].y=txt[mark.nr].y+dy;
444 }
445 if(mark.a=='e')
446 { mvprintw(ell[mark.nr].x1,ell[mark.nr].y1,"");
447 comment("move ellipse to");
448 curpos(); cursor(); clearcomment();
449 dx=x-ell[mark.nr].x1; dy=y-ell[mark.nr].y1;
450 ell[mark.nr].x1=ell[mark.nr].x1+dx;
451 ell[mark.nr].y1=ell[mark.nr].y1+dy;
452 ell[mark.nr].x2=ell[mark.nr].x2+dx;
453 ell[mark.nr].y2=ell[mark.nr].y2+dy;
454 }
455 if(mark.a=='r')
456 { mvprintw(rec[mark.nr].x1,rec[mark.nr].y1,"");
457 comment("move rectangle to");
458 curpos(); cursor(); clearcomment();
459 dx=x-rec[mark.nr].x1; dy=y-rec[mark.nr].y1;
460 rec[mark.nr].x1=rec[mark.nr].x1+dx;
461 rec[mark.nr].y1=rec[mark.nr].y1+dy;
462 rec[mark.nr].x2=rec[mark.nr].x2+dx;
463 rec[mark.nr].y2=rec[mark.nr].y2+dy;
464 }
465 if(mark.a=='l')
466 { mvprintw(lin[mark.nr].x1,lin[mark.nr].y1,"");
467 comment("move line to");
468 curpos(); cursor(); clearcomment();
469 dx=x-lin[mark.nr].x1; dy=y-lin[mark.nr].y1;
470 lin[mark.nr].x1=lin[mark.nr].x1+dx;
471 lin[mark.nr].y1=lin[mark.nr].y1+dy;
472 lin[mark.nr].x2=lin[mark.nr].x2+dx;
473 lin[mark.nr].y2=lin[mark.nr].y2+dy;
474 }
475 }
476
477 void delete()
478 { int i;
479
480 markobj();
481 if(mark.a=='t')
482 { for(i=mark.nr+1;i<lasttxt;i++)
483 { txt[i-1].x=txt[i].x; txt[i-1].y=txt[i].y;
484 txt[i-1].a=txt[i].a;
485 txt[i-1].t[0]='\0'; strcpy(txt[i-1].t,txt[i].t);
486
487 }
488 lasttxt-=1;
489 }
490 if(mark.a=='e')
491 { for(i=mark.nr+1;i<lastell;i++)
492 { ell[i-1].x1=ell[i].x1; ell[i-1].y1=ell[i].y1;
493 ell[i-1].x2=ell[i].x2; ell[i-1].y2=ell[i].y2;
494 }
495 lastell-=1;
496 }
497 if(mark.a=='r')
498 { for(i=mark.nr+1;i<lastrec;i++)
499 { rec[i-1].x1=rec[i].x1; rec[i-1].y1=rec[i].y1;
500 rec[i-1].x2=rec[i].x2; rec[i-1].y2=rec[i].y2;
501 }
502 lastrec-=1;
503 }
504 if(mark.a=='l')
505 { for(i=mark.nr+1;i<lastlin;i++)
506 { lin[i-1].x1=lin[i].x1; lin[i-1].y1=lin[i].y1;
507 lin[i-1].x2=lin[i].x2; lin[i-1].y2=lin[i].y2;
508 lin[i-1].a=lin[i].a;
509 }
510 lastlin-=1;
511 }
512 }
513
514 void copy() // copy marked object to buffer-object
515 { buf.c=buf.a='0'; buf.x1=buf.x2=buf.y1=buf.y2=0; buf.t[0]='\0';
516
517 markobj();
518 if(mark.a=='t')
519 { buf.c='t';
520 buf.a=txt[mark.nr].a;
521 buf.x1=txt[mark.nr].x;
522 buf.y1=txt[mark.nr].y;
523 buf.t[0]='\0'; strcpy(buf.t,txt[mark.nr].t);
524 comment("text copied");
525 }
526 if(mark.a=='e')
527 { buf.c='e';
528 buf.x1=ell[mark.nr].x1;
529 buf.y1=ell[mark.nr].y1;
530 buf.x2=ell[mark.nr].x2;
531 buf.y2=ell[mark.nr].y2;
532 comment("ellipse copied");
533 }
534 if(mark.a=='r')
535 { buf.c='r';
536 buf.x1=rec[mark.nr].x1;
537 buf.y1=rec[mark.nr].y1;
538 buf.x2=rec[mark.nr].x2;
539 buf.y2=rec[mark.nr].y2;
540 comment("rectangle copied");
541 }
542 if(mark.a=='l')
543 { buf.c='l';
544 buf.x1=lin[mark.nr].x1;
545 buf.y1=lin[mark.nr].y1;
546 buf.x2=lin[mark.nr].x2;
547 buf.y2=lin[mark.nr].y2;
548 buf.a=lin[mark.nr].a;
549 comment("line copied");
550 }
551 }
552
553 void paste() // paste copied object at cursor position
554 {
555 if(buf.c=='t')
556 { txt[lasttxt].a=buf.a;
557 txt[lasttxt].x=x;
558 txt[lasttxt].y=y;
559 txt[lasttxt].t[0]='\0'; strcpy(txt[lasttxt].t,buf.t);
560 lasttxt+=1;
561 }
562 if(buf.c=='e')
563 { ell[lastell].x1=x;
564 ell[lastell].y1=y;
565 ell[lastell].x2=buf.x2+x-buf.x1;
566 ell[lastell].y2=buf.y2+y-buf.y1;
567 lastell+=1;
568 }
569 if(buf.c=='r')
570 { rec[lastrec].x1=x;
571 rec[lastrec].y1=y;
572 rec[lastrec].x2=buf.x2+x-buf.x1;
573 rec[lastrec].y2=buf.y2+y-buf.y1;
574 lastrec+=1;
575 }
576 if(buf.c=='l')
577 { lin[lastlin].x1=x;
578 lin[lastlin].y1=y;
579 lin[lastlin].x2=buf.x2+x-buf.x1;
580 lin[lastlin].y2=buf.y2+y-buf.y1;
581 lin[lastlin].a=buf.a;
582 lastlin+=1;
583 }
584 }
585
586 /* LOAD, SAVE, PRINT */
587 void load() // load from file
588 { int i,l;
589
590 fil=fopen(filename,"r");
591
592 if (!fil)
593 { comment_error("Could not load");
594 return;
595 }
596
597 fscanf(fil,"%d",&lastlin);
598 for(i=0;i<lastlin;i++)
599 { fscanf(fil,"%d %d %d %d %c\n",
600 &lin[i].x1,&lin[i].y1,&lin[i].x2,&lin[i].y2,&lin[i].a);
601 }
602 fscanf(fil,"%d\n",&lastrec);
603 for(i=0;i<lastrec;i++)
604 { fscanf(fil,"%d %d %d %d\n",
605 &rec[i].x1,&rec[i].y1,&rec[i].x2,&rec[i].y2);
606 }
607 fscanf(fil,"%d\n",&lastell);
608 for(i=0;i<lastell;i++)
609 { fscanf(fil,"%d %d %d %d\n",
610 &ell[i].x1,&ell[i].y1,&ell[i].x2,&ell[i].y2);
611 }
612 fscanf(fil,"%d\n",&lasttxt);
613 for(i=0;i<lasttxt;i++)
614 { fscanf(fil,"%d %d %c %d",&txt[i].x,&txt[i].y,&txt[i].a,&l);
615 fseek(fil, 1, SEEK_CUR);
616 fread(txt[i].t,1, l, fil);
617 txt[i].t[l]='\0';
618 }
619
620 comment("file loaded");
621 fclose(fil);
622 }
623
624 void save() // save to file
625 { int i;
626
627 fil=fopen(filename,"w+");
628
629 if (!fil)
630 { comment_error("Could not save");
631 return;
632 }
633
634 fprintf(fil,"%d\n",lastlin);
635 for(i=0;i<lastlin;i++)
636 { fprintf(fil,"%d %d %d %d %c\n",
637 lin[i].x1,lin[i].y1,lin[i].x2,lin[i].y2,lin[i].a);
638 }
639 fprintf(fil,"%d\n",lastrec);
640 for(i=0;i<lastrec;i++)
641 { fprintf(fil,"%d %d %d %d\n",
642 rec[i].x1,rec[i].y1,rec[i].x2,rec[i].y2);
643 }
644 fprintf(fil,"%d\n",lastell);
645 for(i=0;i<lastell;i++)
646 { fprintf(fil,"%d %d %d %d\n",
647 ell[i].x1,ell[i].y1,ell[i].x2,ell[i].y2);
648 }
649 fprintf(fil,"%d\n",lasttxt);
650 for(i=0;i<lasttxt;i++)
651 { fprintf(fil,"%d %d %c %d %s\n",
652 txt[i].x,txt[i].y,txt[i].a,strlen(txt[i].t),txt[i].t);
653 }
654
655 comment("file saved");
656 fclose(fil);
657 }
658
659 void print() // print chart to file 'print'
660 { int i,j;
661
662 FILE *prnt;
663 prnt=fopen("print","w");
664
665 if (!prnt)
666 { comment_error("Could not print");
667 return;
668 }
669
670 for(i=0;i<=maxrow;i++)
671 { j=strlen(chart[i])-1;
672 while(chart[i][j]==' ' && j>=0) j--;
673 chart[i][j+1]='\0';
674 }
675
676 for(i=0;i<=maxrow;i++) fprintf(prnt,"%s\n",chart[i]);
677 comment("file 'print' printed");
678
679 fclose(prnt);
680 }
681
682
683 int main(int argc, char *argv[]) /* MAIN */
684 { int c;
685
686 initscr(); raw(); keypad(stdscr, TRUE); noecho();
687 getmaxyx(stdscr,maxrow,maxcol);
688 maxrow-=2; maxcol-=1; menrow=maxrow+1;
689 init();
690
691 if(argv[1]=='\0') // new file
692 {
693 filename="new";
694 comment("file 'new' opened - to open existing file: <td filename>");
695 }
696 else // open file
697 {
698 filename=argv[1];
699 load();
700 }
701
702 draw();
703 curpos();
704
705 while((c = getch())!=ESC && c!='q' && c!='Q') // quit
706 { switch(c)
707 {
708 case KEY_UP: // up
709 y-=1; if(y<0) y=0;
710 curpos();
711 break;
712 case KEY_DOWN: // down
713 y+=1; if(y>maxrow) y=maxrow;
714 curpos();
715 break;
716 case KEY_LEFT: // left
717 x-=1; if(x<0) x=0;
718 curpos();
719 break;
720 case KEY_RIGHT: // right
721 x+=1; if(x>maxcol) x=maxcol;
722 curpos();
723 break;
724 case KEY_HOME: // home
725 x=0; curpos();
726 break;
727 case KEY_END: // end
728 x=maxcol; curpos();
729 break;
730 case KEY_PPAGE: // pgup
731 y=0; curpos();
732 break;
733 case KEY_NPAGE: // pgdn
734 y=maxrow; curpos();
735 break;
736 case 'c': case 'C': // copy
737 copy(); draw();
738 break;
739 case 'd': case 'D': case DEL: // delete
740 delete(); draw();
741 break;
742 case 'e': case 'E': // ellipse
743 ellinput(); draw();
744 break;
745 case 'h': case 'H': // help
746 help(); draw();
747 break;
748 case 'l': case 'L': // line
749 lineinput(); draw();
750 break;
751 case 'm': case 'M': // move
752 moving(); draw();
753 break;
754 case 'p': case 'P': // print
755 print(); draw();
756 break;
757 case 'r': case 'R': // rectangle
758 recinput(); draw();
759 break;
760 case 's': case 'S': // save
761 save(); draw();
762 break;
763 case 't': case 'T': // text
764 textinput(); draw();
765 break;
766 case 'v': case 'V': // paste
767 paste(); draw();
768 break;
769 }
770 }
771
772 endwin();
773 return 0;
774 }
775
776 /* IDEAS:
777
778 * user defineable keys
779 * colors
780 * white surface
781 * mouse support
782 * drop down menus
783 * rotate/mirror object
784 * group object
785 * put object infront/behind
786 * objects with/without frame/filled_color/pattern
787 * object polygon
788 * ascii-art-import (bitmap)
789 * multi windows
790 * presentation features (effects)
791 * save as html
792
793 */
794