"Fossies" - the Fresh Open Source Software Archive

Member "td.c" (10 Jan 1988, 17942 Bytes) of package /linux/privat/old/td_0_2.tar.gz:


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