1*e1e3d21dSopcode /* @(#)long2.c	1.4	10/10/84
2574ebed1Sslatteng  *
3574ebed1Sslatteng  * Copyright -C- 1982 Barry S. Roitblat
4574ebed1Sslatteng  *
5574ebed1Sslatteng  *
6574ebed1Sslatteng  *      This file contains routines to implement the long text commands
7574ebed1Sslatteng  * of the gremlin PICTURE editor.
8574ebed1Sslatteng  *
9574ebed1Sslatteng  */
10574ebed1Sslatteng 
11574ebed1Sslatteng #include "gremlin.h"
12574ebed1Sslatteng #include "grem2.h"
13574ebed1Sslatteng #include <ctype.h>
14574ebed1Sslatteng 
15574ebed1Sslatteng /* imports from graphics files */
16574ebed1Sslatteng 
17574ebed1Sslatteng extern GRVector(), GRArc(), GRPutText(), GRClose();
18574ebed1Sslatteng extern GRDisplayPoint(), GRDeletePoint(), GRBlankPoints();
19574ebed1Sslatteng extern charxsize, charysize, GrXMax, GrYMax;
20574ebed1Sslatteng 
21574ebed1Sslatteng /* import from path.c */
22574ebed1Sslatteng 
23574ebed1Sslatteng extern int PSetPath(), PConvertTilde();
24574ebed1Sslatteng extern char *PGetPath();
25574ebed1Sslatteng 
26574ebed1Sslatteng /* imports from display.c */
27574ebed1Sslatteng 
28574ebed1Sslatteng extern DISScreenAdd(), DISScreenErase();
29574ebed1Sslatteng extern DISDisplaySet(), DISEraseSet(), DISClearSetDisplay();
30574ebed1Sslatteng 
31574ebed1Sslatteng /* imports from database files */
32574ebed1Sslatteng 
33574ebed1Sslatteng extern ELT *DBInit(), *DBCreateElt(), *DBRead();
34574ebed1Sslatteng extern DBDelete(), DBGravitate(), DBClearElt();
35574ebed1Sslatteng extern ELT *DBCopy();
36574ebed1Sslatteng extern DBXform(), DBChangeBrush();
37574ebed1Sslatteng extern DBAddSet(), DBClearSet();
38574ebed1Sslatteng extern POINT *PTInit(), *PTMakePoint();
39574ebed1Sslatteng extern PTDeletePoint();
40574ebed1Sslatteng 
41574ebed1Sslatteng /* imports from undodb.c */
42574ebed1Sslatteng 
43574ebed1Sslatteng extern UNELT *unlist, *unback;
44574ebed1Sslatteng extern UNForget();
45574ebed1Sslatteng 
46574ebed1Sslatteng /* imports from short.c */
47574ebed1Sslatteng 
48574ebed1Sslatteng extern SHUpdate();
49574ebed1Sslatteng extern int adj[];
50574ebed1Sslatteng 
51574ebed1Sslatteng /* imports from textio.c */
52574ebed1Sslatteng 
53574ebed1Sslatteng extern TxPutString(), TxPutMsg(), TxMsgOK(), TxClose();
54574ebed1Sslatteng extern TXFIELD TAlign, TAdjust, TBrush, TFont, TGravity, TCSize;
55574ebed1Sslatteng extern TEdit, TJustmode;
56574ebed1Sslatteng 
57574ebed1Sslatteng /* imports from menu.c  */
58574ebed1Sslatteng 
59574ebed1Sslatteng extern MNHighLt(), MNUnHighLt();
60574ebed1Sslatteng extern HiMen[], HiFont[], HiBrush[], HiMode[];
61574ebed1Sslatteng 
62574ebed1Sslatteng /* imports from c */
63574ebed1Sslatteng 
64574ebed1Sslatteng extern char *malloc();
65574ebed1Sslatteng extern char *strcpy(), *sprintf();
66574ebed1Sslatteng 
67574ebed1Sslatteng /* imports from main.c */
68574ebed1Sslatteng 
69574ebed1Sslatteng extern ELT *PICTURE;                /* current PICTURE database      */
70574ebed1Sslatteng extern ELT *cset;                   /* current set database          */
71574ebed1Sslatteng extern CBRUSH, CSIZE, CFONT;        /* current brush, size, font     */
72574ebed1Sslatteng extern CJUST;                       /* current text justification    */
73574ebed1Sslatteng extern Gridon;                      /* grid mode flag                */
74574ebed1Sslatteng extern Orientation;                 /* orientation of workspace      */
75574ebed1Sslatteng extern SEARCH;                      /* flag for path search          */
76574ebed1Sslatteng extern Alignment;                   /* point alignment indicator     */
77574ebed1Sslatteng extern float PX, PY;                /* cursor coordinates            */
78574ebed1Sslatteng extern float Lastx, Lasty;          /* previous cursor coordinates   */
79574ebed1Sslatteng extern SEQ;                         /* point sequence number         */
80574ebed1Sslatteng extern POINT *POINTLIST, *BACKPOINT;/* accumulated point list        */
81574ebed1Sslatteng extern Gridsize;                    /* grid spacing                  */
82574ebed1Sslatteng extern Adjustment;                  /* point adjustment mode         */
83574ebed1Sslatteng extern GravityOn;                   /* gravity mode flag             */
84574ebed1Sslatteng extern Consume;                     /* point clear flag              */
85574ebed1Sslatteng extern CHANGED;                     /* PICTURE changed flag          */
86574ebed1Sslatteng extern ELT *MEN[];                  /* pointers for user symbols     */
87574ebed1Sslatteng extern POINT MENPOINT[];            /* pointers used fo user symbols */
88574ebed1Sslatteng extern cmdbuf[];                    /* line buffer for commands      */
89574ebed1Sslatteng extern char *textpos[], *dispmode[];/* text positioning modes        */
90574ebed1Sslatteng extern int textmode[];              /* text positioning              */
91574ebed1Sslatteng extern char *lines[], *fonts[];     /* line and character styles     */
92574ebed1Sslatteng extern int jmodes, lnum[], fnum[];
93574ebed1Sslatteng 
94574ebed1Sslatteng /*  imports from long1.c         */
95574ebed1Sslatteng extern bang;
96574ebed1Sslatteng extern GetNumParm();
97574ebed1Sslatteng extern LGLookup();
98574ebed1Sslatteng extern SetOrient();
99574ebed1Sslatteng 
100574ebed1Sslatteng char *Editfile;
101574ebed1Sslatteng 
102574ebed1Sslatteng #define BADNUM -1
103574ebed1Sslatteng #define NONUM -2
104574ebed1Sslatteng #define Delimiter(c) ((c == '\0') || (c == ' ') || (c == ','))
105574ebed1Sslatteng 
106574ebed1Sslatteng static char badarg[10] = "bad args";
107574ebed1Sslatteng 
1083a4b2214Sslatteng 
LGFont(line)109574ebed1Sslatteng LGFont(line)
110574ebed1Sslatteng char *line;
111574ebed1Sslatteng /*
112574ebed1Sslatteng  *      This routine looks at the command line for parameters to set
113574ebed1Sslatteng  * the current Font.
114574ebed1Sslatteng  */
115574ebed1Sslatteng 
116574ebed1Sslatteng {
117574ebed1Sslatteng     int new, index;
118574ebed1Sslatteng     char string[2];
119574ebed1Sslatteng 
120574ebed1Sslatteng     Consume = FALSE;
121574ebed1Sslatteng     index = 0;
122574ebed1Sslatteng     if (isalpha(*(++line)))
123574ebed1Sslatteng     {
124574ebed1Sslatteng         new = LGLookup(line, fonts, &index);
125574ebed1Sslatteng         if ( new >= 0) new = fnum[new];
126574ebed1Sslatteng         else new = BADNUM;
127574ebed1Sslatteng     }
128574ebed1Sslatteng     else new = GetNumParm(line, &index);
129574ebed1Sslatteng     if ( (new == BADNUM) || (new > NFONTS) )
130574ebed1Sslatteng     {
131574ebed1Sslatteng         error(badarg);
132574ebed1Sslatteng         return;
133574ebed1Sslatteng     }
134574ebed1Sslatteng     if (new != NONUM)
135574ebed1Sslatteng     {
136574ebed1Sslatteng         MNUnHighLt(HiFont[CFONT-1]);
137574ebed1Sslatteng         MNHighLt(HiFont[new-1], hicolor);
138574ebed1Sslatteng         CFONT = new;
139574ebed1Sslatteng         (void) sprintf(string, "%1d",new);
140574ebed1Sslatteng         TxPutString(&TFont,string);
141574ebed1Sslatteng     }
142574ebed1Sslatteng }  /* end LGFont */
143574ebed1Sslatteng 
1443a4b2214Sslatteng 
LGJust(line)145574ebed1Sslatteng LGJust(line)
146574ebed1Sslatteng char *line;
147574ebed1Sslatteng /*
148574ebed1Sslatteng  *      This routine looks at the command line for parameters to set
149574ebed1Sslatteng  * the current text justification mode.
150574ebed1Sslatteng  */
151574ebed1Sslatteng 
152574ebed1Sslatteng {
153574ebed1Sslatteng     int new, index;
154574ebed1Sslatteng 
155574ebed1Sslatteng     Consume = FALSE;
156574ebed1Sslatteng     index = 0;
157574ebed1Sslatteng     if (isalpha(*(++line)))
158574ebed1Sslatteng     {
159574ebed1Sslatteng       /* make sure mode is in lower case, and look up in table */
160574ebed1Sslatteng         if (isupper(*line))
161574ebed1Sslatteng         {
162574ebed1Sslatteng             *line = tolower(*line);
163574ebed1Sslatteng             *(line+1) = tolower(*(line+1));
164574ebed1Sslatteng         }
165574ebed1Sslatteng         for (new = 0; (strcmp(line, textpos[new]) != 0); ++new)
166574ebed1Sslatteng             if (new > jmodes)
167574ebed1Sslatteng             {
168574ebed1Sslatteng                error("no such mode");
169574ebed1Sslatteng                return;
170574ebed1Sslatteng             }
171574ebed1Sslatteng         if ( new < 0) new = BADNUM;
172574ebed1Sslatteng     }
173574ebed1Sslatteng     else new = GetNumParm(line, &index) - 1;
174574ebed1Sslatteng     if ( (new <= BADNUM) || (new > jmodes) )
175574ebed1Sslatteng     {
176574ebed1Sslatteng         error(badarg);
177574ebed1Sslatteng         return;
178574ebed1Sslatteng     }
179574ebed1Sslatteng     if (new != NONUM)
180574ebed1Sslatteng     {
181574ebed1Sslatteng         new = textmode[new];
182574ebed1Sslatteng         CJUST = new;
183574ebed1Sslatteng         TxPutString(&TJustmode,dispmode[new]);
184574ebed1Sslatteng     }
185574ebed1Sslatteng }  /* end LGJust */
186574ebed1Sslatteng 
1873a4b2214Sslatteng 
LGSize(line)188574ebed1Sslatteng LGSize(line)
189574ebed1Sslatteng char *line;
190574ebed1Sslatteng /*
191574ebed1Sslatteng  *      This routine changes the current character size.
192574ebed1Sslatteng  */
193574ebed1Sslatteng 
194574ebed1Sslatteng {
195574ebed1Sslatteng     int new, index;
196574ebed1Sslatteng     char string[2];
197574ebed1Sslatteng 
198574ebed1Sslatteng     index = 1;
199574ebed1Sslatteng     new = GetNumParm(line, &index);
200574ebed1Sslatteng     if ( (new == BADNUM) || (new > NSIZES) )
201574ebed1Sslatteng     {
202574ebed1Sslatteng         error(badarg);
203574ebed1Sslatteng         return;
204574ebed1Sslatteng     }
205574ebed1Sslatteng     if (new != NONUM)
206574ebed1Sslatteng     {
207574ebed1Sslatteng         CSIZE = new;
208574ebed1Sslatteng         (void) sprintf(string, "%1d",new);
209574ebed1Sslatteng         TxPutString(&TCSize,string);
210574ebed1Sslatteng     }
211574ebed1Sslatteng     Consume = FALSE;
212574ebed1Sslatteng }  /* end LGSize */
213574ebed1Sslatteng 
LGAlign(line)214574ebed1Sslatteng LGAlign(line)
215574ebed1Sslatteng char *line;
216574ebed1Sslatteng /*
217574ebed1Sslatteng  *      This routine sets the point alignment indicator
218574ebed1Sslatteng  */
219574ebed1Sslatteng 
220574ebed1Sslatteng {
221574ebed1Sslatteng     int newalign, index;
222574ebed1Sslatteng     char string[4];
223574ebed1Sslatteng 
224574ebed1Sslatteng     index = 1;
225574ebed1Sslatteng     newalign = GetNumParm(line, &index);
226574ebed1Sslatteng     if (newalign == NONUM)
227574ebed1Sslatteng         if (Alignment == 1) Alignment = Gridsize;
228574ebed1Sslatteng         else Alignment = 1;
229574ebed1Sslatteng     else
230574ebed1Sslatteng     {
231574ebed1Sslatteng         if ((newalign < 1) || (newalign > GrYMax/2) )
232574ebed1Sslatteng         {
233574ebed1Sslatteng             error(badarg);
234574ebed1Sslatteng             return;
235574ebed1Sslatteng         }
236574ebed1Sslatteng         Alignment = newalign;
237574ebed1Sslatteng     }
238574ebed1Sslatteng     (void) sprintf(string, "%3d",Alignment);
239574ebed1Sslatteng     TxPutString(&TAlign,string);
240574ebed1Sslatteng     Consume = FALSE;
241574ebed1Sslatteng }  /* end LGAlign */
242574ebed1Sslatteng 
2433a4b2214Sslatteng 
LGIncludeSet(line)244574ebed1Sslatteng LGIncludeSet(line)
245574ebed1Sslatteng char *line;
246574ebed1Sslatteng /*
247574ebed1Sslatteng  *      This routine adds all elements selected by points in POINTLIST
248574ebed1Sslatteng  * to the current set.  It does not remove previously selected elements.
249574ebed1Sslatteng  *
250574ebed1Sslatteng  */
251574ebed1Sslatteng 
252574ebed1Sslatteng {
253574ebed1Sslatteng     POINT *p1, *p2;
254574ebed1Sslatteng     ELT *e1;
255574ebed1Sslatteng     float n1, n2;
256574ebed1Sslatteng 
257574ebed1Sslatteng     if (DBNullelt(PICTURE)) return;
258574ebed1Sslatteng     if (SEQ == 0)    /* no points: entire picture becomes */
259574ebed1Sslatteng     {                /* current set                       */
260574ebed1Sslatteng         e1 = PICTURE;
261574ebed1Sslatteng         while ( !DBNullelt(e1) )
262574ebed1Sslatteng         {
263574ebed1Sslatteng             DBAddSet(e1);
264574ebed1Sslatteng             DISDisplaySet(e1);
265574ebed1Sslatteng             e1 = DBNextElt(e1);
266574ebed1Sslatteng         }
267574ebed1Sslatteng     }  /* end if */
268574ebed1Sslatteng     else
269574ebed1Sslatteng     {
270574ebed1Sslatteng         p1 = POINTLIST;
271574ebed1Sslatteng         while ( !Nullpoint(p1) )
272574ebed1Sslatteng         {
273574ebed1Sslatteng             DBGravitate(p1->x, p1->y, &n1, &n2, &p2, &e1, PICTURE);
274574ebed1Sslatteng             if ( !DBNullelt(e1) )
275574ebed1Sslatteng             {
276574ebed1Sslatteng                 DBAddSet(e1);
277574ebed1Sslatteng                 DISDisplaySet(e1);
278574ebed1Sslatteng             }
279574ebed1Sslatteng             p1 = PTNextPoint(p1);
280574ebed1Sslatteng         }  /* end while */;
281574ebed1Sslatteng     }  /* end else */
282574ebed1Sslatteng } /* end LGIncludeSet */
283574ebed1Sslatteng 
284574ebed1Sslatteng 
2853a4b2214Sslatteng 
LGMenu(line)286574ebed1Sslatteng LGMenu(line)
287574ebed1Sslatteng char *line;
288574ebed1Sslatteng /*
289574ebed1Sslatteng  *      This routine implements the menu command.  The contents of
290574ebed1Sslatteng  * the specified user menu item is copied into the PICTURE transformed
291574ebed1Sslatteng  * to the positioning point.
292574ebed1Sslatteng  */
293574ebed1Sslatteng 
294574ebed1Sslatteng {
295574ebed1Sslatteng 
296574ebed1Sslatteng     ELT *elist, *e1;
297574ebed1Sslatteng     POINT *plist;
298574ebed1Sslatteng     int symbol, index;
299574ebed1Sslatteng     float xmat[3][2];
300574ebed1Sslatteng 
301574ebed1Sslatteng     if (SEQ < 1)
302574ebed1Sslatteng     {
303574ebed1Sslatteng         error("no positioning point");
304574ebed1Sslatteng         return;
305574ebed1Sslatteng     }
306574ebed1Sslatteng     index = 1;
307574ebed1Sslatteng     symbol = GetNumParm(line, &index);
308574ebed1Sslatteng     if ( (symbol <= 0) || (symbol > NUSER) )
309574ebed1Sslatteng     {
310574ebed1Sslatteng         error(badarg);
311574ebed1Sslatteng         return;
312574ebed1Sslatteng     }
313574ebed1Sslatteng     symbol--;     /* users inputs number between 1 and N, actual
314574ebed1Sslatteng                      symbol number is between 0 and N-1          */
315574ebed1Sslatteng     xmat[0][0] = xmat[1][1] = 1;    /* create transformation matrix */
316574ebed1Sslatteng     xmat[0][1] = xmat[1][0] = 0;    /* for copy into PICTURE        */
317574ebed1Sslatteng     plist = POINTLIST;
318574ebed1Sslatteng     while ( !Nullpoint(plist) )
319574ebed1Sslatteng     {
320574ebed1Sslatteng         DISClearSetDisplay();   /* Clear old current set */
321574ebed1Sslatteng         DBClearSet();
322574ebed1Sslatteng         xmat[2][0] = plist->x - (MENPOINT[symbol]).x;
323574ebed1Sslatteng         xmat[2][1] = plist->y - (MENPOINT[symbol]).y;
324574ebed1Sslatteng         elist = MEN[symbol];
325574ebed1Sslatteng         while ( !DBNullelt(elist) )  /* copy buffer to picture */
326574ebed1Sslatteng         {
327574ebed1Sslatteng             e1 = DBCopy(elist, xmat, &PICTURE);
328574ebed1Sslatteng             DBAddSet(e1);
329574ebed1Sslatteng             DISScreenAdd(e1, (linemask | setmask));
330574ebed1Sslatteng             elist = DBNextElt(elist);
331574ebed1Sslatteng         }  /* end while */
332574ebed1Sslatteng         plist = PTNextPoint(plist);
333574ebed1Sslatteng     }  /* end while */
334574ebed1Sslatteng     CHANGED = TRUE;
335574ebed1Sslatteng }  /* end LGMenu */
336574ebed1Sslatteng 
3373a4b2214Sslatteng 
LGRead(line)338574ebed1Sslatteng LGRead(line)
339574ebed1Sslatteng char *line;
340574ebed1Sslatteng /*
341574ebed1Sslatteng  *      This routine reads in the specified filename (command line) to the
342574ebed1Sslatteng  * selected user symbol or current set if no user symbol is selected.  If
343574ebed1Sslatteng  * no filename is specified, the current set is copied to the user symbol;
344574ebed1Sslatteng  */
345574ebed1Sslatteng 
346574ebed1Sslatteng {
347574ebed1Sslatteng     POINT pos, ppos;
348574ebed1Sslatteng     ELT *elist, *e1;
349574ebed1Sslatteng     char tname[50], filename[100];
350574ebed1Sslatteng     float xmat[3][2];
351574ebed1Sslatteng     int i, orient;
352574ebed1Sslatteng 
353574ebed1Sslatteng     if ( *line == '\0' )     /* no arguments */
354574ebed1Sslatteng     {
355574ebed1Sslatteng         error(badarg);
356574ebed1Sslatteng         return;
357574ebed1Sslatteng     }
358574ebed1Sslatteng     ++line;
359574ebed1Sslatteng     (void) sscanf(line, "%s", tname);
360574ebed1Sslatteng     elist = DBRead(tname, &orient, &pos); /* read file */
361574ebed1Sslatteng     UNForget();     /* forget changes registered by DBRead */
362574ebed1Sslatteng     if (SEQ < 1)    /* no positioning point */
363574ebed1Sslatteng     {
364574ebed1Sslatteng         ppos.x = pos.x;
365574ebed1Sslatteng         ppos.y = pos.y;
366574ebed1Sslatteng     }
367574ebed1Sslatteng     else
368574ebed1Sslatteng     {
369574ebed1Sslatteng         ppos.x = POINTLIST->x;
370574ebed1Sslatteng         ppos.y = POINTLIST->y;
371574ebed1Sslatteng     }
372574ebed1Sslatteng     xmat[0][0] = xmat[1][1] = 1;   /* set up matrix to copy to */
373574ebed1Sslatteng     xmat[0][1] = xmat[1][0] = 0;   /* appropriate place in     */
374574ebed1Sslatteng     xmat[2][0] = ppos.x - pos.x;   /* picture as current set   */
375574ebed1Sslatteng     xmat[2][1] = ppos.y - pos.y;
376574ebed1Sslatteng     DBClearSet();
377574ebed1Sslatteng     DISClearSetDisplay();
378574ebed1Sslatteng     while ( !DBNullelt(elist) )
379574ebed1Sslatteng     {
380574ebed1Sslatteng         e1 = DBCopy(elist, xmat, &PICTURE);
381574ebed1Sslatteng         DISScreenAdd(e1, (linemask | setmask));
382574ebed1Sslatteng         DBAddSet(e1);
383574ebed1Sslatteng         e1 = DBNextElt(elist);
384574ebed1Sslatteng         DBClearElt(elist);
385574ebed1Sslatteng         elist = e1;
386574ebed1Sslatteng     }
387574ebed1Sslatteng     CHANGED = TRUE;
388574ebed1Sslatteng }  /* end LGRead */
389574ebed1Sslatteng 
3903a4b2214Sslatteng 
LGEdit(line)391574ebed1Sslatteng LGEdit(line)
392574ebed1Sslatteng char *line;
393574ebed1Sslatteng /*
394574ebed1Sslatteng  * This routine reads in a new PICTURE for editing
395574ebed1Sslatteng  */
396574ebed1Sslatteng 
397574ebed1Sslatteng {
398574ebed1Sslatteng     FILE *fp, *POpen();
399574ebed1Sslatteng     POINT pos;
400574ebed1Sslatteng     ELT *e1;
401574ebed1Sslatteng     char *tn, tname[50];
402574ebed1Sslatteng     int i;
403574ebed1Sslatteng 
404574ebed1Sslatteng     if (!bang)     /* no ! */
405574ebed1Sslatteng     {
406574ebed1Sslatteng         if (CHANGED)
407574ebed1Sslatteng         {
408574ebed1Sslatteng             error("no write");
409574ebed1Sslatteng             return;
410574ebed1Sslatteng         }
411574ebed1Sslatteng     }  /* end if !bang */;
412574ebed1Sslatteng     DBClearSet();
413574ebed1Sslatteng     while ( !DBNullelt(PICTURE) )   /* clear current PICTURE */
414574ebed1Sslatteng     {
415574ebed1Sslatteng         e1 = DBNextElt(PICTURE);
416574ebed1Sslatteng         DBClearElt(PICTURE);
417574ebed1Sslatteng         PICTURE = e1;
418574ebed1Sslatteng     };
419574ebed1Sslatteng     ++line;
420574ebed1Sslatteng     tn = tname;
421574ebed1Sslatteng     (void) sscanf(line, "%s", tname);
422574ebed1Sslatteng 
423574ebed1Sslatteng     POINTLIST = PTInit();   /* Initialize globals */
424574ebed1Sslatteng     SEQ = 0;
425574ebed1Sslatteng     CHANGED = FALSE;
426574ebed1Sslatteng 
427574ebed1Sslatteng     i = strlen(tname);
428574ebed1Sslatteng     if (i > 0)        /* filename present */
429574ebed1Sslatteng     {
430574ebed1Sslatteng         fp = POpen(tname, (char **) NULL, SEARCH);
431574ebed1Sslatteng         TxPutString(&TEdit, tname);
432574ebed1Sslatteng         if (fp == NULL)
433574ebed1Sslatteng         {
434574ebed1Sslatteng             PICTURE = DBInit();
435574ebed1Sslatteng             error(" (creating new file)");
436574ebed1Sslatteng         }
437574ebed1Sslatteng         else
438574ebed1Sslatteng         {
439*e1e3d21dSopcode 	    fclose(fp);		/* bug fix 10/10/84 mro */
440574ebed1Sslatteng             PICTURE = DBRead(tname, &Orientation, &pos);
441574ebed1Sslatteng             SetOrient(Orientation);    /* Set appropriate picture area
442574ebed1Sslatteng                                         * orientation                    */
443574ebed1Sslatteng         }
444574ebed1Sslatteng         (void) strcpy (Editfile, tname);
445574ebed1Sslatteng     }
446574ebed1Sslatteng     else
447574ebed1Sslatteng     {
448574ebed1Sslatteng         TxPutString(&TEdit, "");
449574ebed1Sslatteng         (void) strcpy(Editfile, "");
450574ebed1Sslatteng     }
451574ebed1Sslatteng     unlist = unback = nullun;
452574ebed1Sslatteng     CP();
453574ebed1Sslatteng     SHUpdate();      /* display new picture */
454574ebed1Sslatteng }  /* end LGEdit */
455574ebed1Sslatteng 
restorepoints()456574ebed1Sslatteng static restorepoints()
457574ebed1Sslatteng 
458574ebed1Sslatteng /* This routine (re) displays the points in the back-up pointlist
459574ebed1Sslatteng  */
460574ebed1Sslatteng {
461574ebed1Sslatteng 
462574ebed1Sslatteng     int i;
463574ebed1Sslatteng     POINT *plist, *pl1, *pl2;
464574ebed1Sslatteng 
465574ebed1Sslatteng     GRBlankPoints();
466574ebed1Sslatteng     plist = BACKPOINT;
467574ebed1Sslatteng     for (i=0; !Nullpoint(plist); ++i)
468574ebed1Sslatteng     {
469574ebed1Sslatteng         Lastx = plist->x;
470574ebed1Sslatteng         Lasty = plist->y;
471574ebed1Sslatteng         GRDisplayPoint( (int) plist->x, (int) plist->y, i, pointstyle );
472574ebed1Sslatteng         plist = PTNextPoint(plist);
473574ebed1Sslatteng     }
474574ebed1Sslatteng     pl1 = POINTLIST;
475574ebed1Sslatteng     POINTLIST = BACKPOINT;
476574ebed1Sslatteng     SEQ = i;
477574ebed1Sslatteng     BACKPOINT = pl1;
478574ebed1Sslatteng }  /* end restorepoints */
479574ebed1Sslatteng 
4803a4b2214Sslatteng 
LGUndo(line)481574ebed1Sslatteng LGUndo(line)
482574ebed1Sslatteng char *line;
483574ebed1Sslatteng /*
484574ebed1Sslatteng  *      This routine uses the information in the undo database to reconstruct
485574ebed1Sslatteng  * the PICTURE as it was before the last command.  The undo database is set
486574ebed1Sslatteng  * so that the next undo would nullify this one.
487574ebed1Sslatteng  * An undo of an Add is to delete the new element.
488574ebed1Sslatteng  * Add the old element back to undo a delete.
489574ebed1Sslatteng  * Modified elements are undone by copying the old element into the database
490574ebed1Sslatteng  * in place of the modified element.
491574ebed1Sslatteng  */
492574ebed1Sslatteng 
493574ebed1Sslatteng {
494574ebed1Sslatteng     UNELT *fix, *temp;
495574ebed1Sslatteng     ELT *(*e1);
496574ebed1Sslatteng 
497574ebed1Sslatteng     fix = unlist;       /* initialize unlist so that undo-ing can   */
498574ebed1Sslatteng     unlist = nullun;    /* add items to properly undo the undo      */
499574ebed1Sslatteng     if (fix == nullun)
500574ebed1Sslatteng     {
501574ebed1Sslatteng         fix = unback;
502574ebed1Sslatteng         unback = nullun;
503574ebed1Sslatteng     }
504574ebed1Sslatteng     DBClearSet();
505574ebed1Sslatteng     DISClearSetDisplay();
506574ebed1Sslatteng     GRBlankPoints();
507574ebed1Sslatteng     while (fix != nullun)
508574ebed1Sslatteng     {
509574ebed1Sslatteng         switch (fix->action)
510574ebed1Sslatteng         {
511574ebed1Sslatteng             case ADD: DISScreenErase(fix->newelt, linemask);
512574ebed1Sslatteng                       TxMsgOK();
513574ebed1Sslatteng                       restorepoints();
514574ebed1Sslatteng                       DBDelete(fix->newelt, fix->dbase);
515574ebed1Sslatteng                       temp = fix->nextun;
516574ebed1Sslatteng                       free((char *) fix);
517574ebed1Sslatteng                       fix = temp;
518574ebed1Sslatteng                       break;
519574ebed1Sslatteng 
520574ebed1Sslatteng          case DELETE: fix->action = ADD;   /* create undo unelt */
521574ebed1Sslatteng                       fix->newelt = fix->oldelt;
522574ebed1Sslatteng                       fix->oldelt = NULL;
523574ebed1Sslatteng                       fix->newelt->nextelt = PICTURE;
524574ebed1Sslatteng                       restorepoints();
525574ebed1Sslatteng                       DBAddSet(fix->newelt);
526574ebed1Sslatteng                       DISScreenAdd(fix->newelt,(linemask|setmask));
527574ebed1Sslatteng                       PICTURE = fix->newelt;    /* put in database */
528574ebed1Sslatteng                       temp = fix->nextun;
529574ebed1Sslatteng                       fix->nextun = unlist;     /* link into unlist */
530574ebed1Sslatteng                       unlist = fix;
531574ebed1Sslatteng                       fix = temp;
532574ebed1Sslatteng                       break;
533574ebed1Sslatteng 
534574ebed1Sslatteng             case MOD: DISScreenErase(fix->newelt, linemask);
535574ebed1Sslatteng                       TxMsgOK();
536574ebed1Sslatteng                       restorepoints();
537574ebed1Sslatteng                       DISScreenAdd(fix->oldelt, (setmask | linemask));
538574ebed1Sslatteng                       DBAddSet(fix->oldelt);
539574ebed1Sslatteng                       e1 = fix->dbase;
540574ebed1Sslatteng                       while ( *e1 != fix->newelt )
541574ebed1Sslatteng                       {                     /* find elt to replace */
542574ebed1Sslatteng                           e1 = &(DBNextElt((*e1)));
543574ebed1Sslatteng                       }
544574ebed1Sslatteng                       fix->oldelt->nextelt = DBNextElt((*e1));
545574ebed1Sslatteng                       *e1 = fix->oldelt;
546574ebed1Sslatteng                       fix->oldelt = fix->newelt;
547574ebed1Sslatteng                       fix->newelt = *e1;     /* create undo unelt */
548574ebed1Sslatteng                       temp = fix->nextun;
549574ebed1Sslatteng                       fix->nextun = unlist;
550574ebed1Sslatteng                       unlist = fix;     /* link into unlist */
551574ebed1Sslatteng                       fix = temp;
552574ebed1Sslatteng                       break;
553574ebed1Sslatteng 
554574ebed1Sslatteng         }  /* end switch */;
555574ebed1Sslatteng     }  /* end while */
556574ebed1Sslatteng     Consume = FALSE;
557574ebed1Sslatteng }  /* LGUndo */
558574ebed1Sslatteng 
5593a4b2214Sslatteng 
LGWrite(line)560574ebed1Sslatteng LGWrite(line)
561574ebed1Sslatteng char *line;
562574ebed1Sslatteng /*
563574ebed1Sslatteng  *      This routine writes the current PICTURE into the specified filename
564574ebed1Sslatteng  * or to the current Editfile
565574ebed1Sslatteng  */
566574ebed1Sslatteng 
567574ebed1Sslatteng {
568574ebed1Sslatteng     FILE *fp, *fopen();
569574ebed1Sslatteng     char tname[50], filename[100], string[100], *tn, *fn, *wfile;
570574ebed1Sslatteng     ELT *elist;
571574ebed1Sslatteng     POINT *plist, pos;
572574ebed1Sslatteng     int i, space, stat;
573574ebed1Sslatteng 
574574ebed1Sslatteng     space = 100;
575574ebed1Sslatteng     ++line;
576574ebed1Sslatteng     tn = tname;  fn = filename;
577574ebed1Sslatteng     (void) sscanf(line, "%s", tname);
578574ebed1Sslatteng     i = strlen(tname);
579574ebed1Sslatteng     if (i == 0)       /* no filename */
580574ebed1Sslatteng     {
581574ebed1Sslatteng         if ( *Editfile == '\0' )
582574ebed1Sslatteng         {
583574ebed1Sslatteng             error("write to where?");
584574ebed1Sslatteng             return;
585574ebed1Sslatteng         }
586574ebed1Sslatteng         fp = fopen(Editfile, "w");
587574ebed1Sslatteng         wfile = Editfile;
588574ebed1Sslatteng     }
589574ebed1Sslatteng     else
590574ebed1Sslatteng     {
591574ebed1Sslatteng     stat = PConvertTilde(&tn, &fn, &space);
592574ebed1Sslatteng     *fn = '\0';
593574ebed1Sslatteng     if (stat == FALSE)
594574ebed1Sslatteng     {
595574ebed1Sslatteng         sprintf(string, "unknown path %s", tname);
596574ebed1Sslatteng         error(string);
597574ebed1Sslatteng         return;
598574ebed1Sslatteng     }
599574ebed1Sslatteng         if ( !bang )  /* user doesn't insist */
600574ebed1Sslatteng         {
601574ebed1Sslatteng             fp = fopen(filename, "r");
602574ebed1Sslatteng             if ( fp != NULL )
603574ebed1Sslatteng             {
604574ebed1Sslatteng                  error("file already exists");
605574ebed1Sslatteng                  return;
606574ebed1Sslatteng             }
607574ebed1Sslatteng         }
608574ebed1Sslatteng         fp = fopen(filename, "w");
609574ebed1Sslatteng         wfile = filename;
610574ebed1Sslatteng     };
611574ebed1Sslatteng     if (fp == NULL)      /* file error */
612574ebed1Sslatteng     {
613574ebed1Sslatteng         (void) sprintf(string,"can't open %s", wfile);
614574ebed1Sslatteng         error(string);
615574ebed1Sslatteng         return;
616574ebed1Sslatteng     };
617574ebed1Sslatteng     TxPutMsg("writing file...");
618574ebed1Sslatteng     CHANGED = FALSE;
619574ebed1Sslatteng     if (SEQ > 0)       /* specified a positioning point */
620574ebed1Sslatteng     {
621574ebed1Sslatteng         pos.x = POINTLIST->x;
622574ebed1Sslatteng         pos.y = POINTLIST->y;
623574ebed1Sslatteng     }
624574ebed1Sslatteng     else
625574ebed1Sslatteng     {
626574ebed1Sslatteng         if ( !DBNullelt(PICTURE) )
627574ebed1Sslatteng         {
628574ebed1Sslatteng             pos.x = PICTURE->ptlist->x;
629574ebed1Sslatteng             pos.y = PICTURE->ptlist->y;
630574ebed1Sslatteng         }
631574ebed1Sslatteng         else
632574ebed1Sslatteng         {
633574ebed1Sslatteng             pos.x = pos.y = 0;
634574ebed1Sslatteng         };
635574ebed1Sslatteng     }
636574ebed1Sslatteng     fprintf(fp,"gremlinfile\n");    /* write header */
637574ebed1Sslatteng     fprintf(fp, "%d %1.2f %1.2f\n", Orientation, pos.x, pos.y);
638574ebed1Sslatteng     elist = PICTURE;
639574ebed1Sslatteng     while ( !DBNullelt(elist) )    /* write each element */
640574ebed1Sslatteng     {
641574ebed1Sslatteng         fprintf(fp, "%d\n", elist->type);
642574ebed1Sslatteng         plist = elist->ptlist;
643574ebed1Sslatteng         while ( !Nullpoint(plist) )  /* write each point */
644574ebed1Sslatteng         {
645574ebed1Sslatteng             fprintf(fp, "%1.2f %1.2f\n",plist->x, plist->y);
646574ebed1Sslatteng             plist = PTNextPoint(plist);
647574ebed1Sslatteng         }  /* end while plist */
648574ebed1Sslatteng         fprintf(fp, "%1.2f %1.2f\n", -1.0, -1.0);  /* end pointlist */
649574ebed1Sslatteng         fprintf(fp, "%d %d\n",elist->brushf, elist->size);
650574ebed1Sslatteng         fprintf(fp,"%d %s\n ", strlen(elist->textpt), elist->textpt);
651574ebed1Sslatteng         elist = DBNextElt(elist);
652574ebed1Sslatteng     }  /* end while */
653574ebed1Sslatteng     fprintf(fp,"%d\n",-1);   /* end of element list */
654574ebed1Sslatteng     TxMsgOK();
655574ebed1Sslatteng     (void) fclose(fp);
656574ebed1Sslatteng }  /* end LGWrite */;
657574ebed1Sslatteng 
6583a4b2214Sslatteng 
LGQuit(line)659574ebed1Sslatteng LGQuit(line)
660574ebed1Sslatteng char *line;
661574ebed1Sslatteng /*
662574ebed1Sslatteng  *      This routine terminates the editor.  The terminal states for the text
663574ebed1Sslatteng  * terminal and the graphics display are restored and an EXIT is performed.
664574ebed1Sslatteng  */
665574ebed1Sslatteng 
666574ebed1Sslatteng {
667574ebed1Sslatteng     if (!bang)
668574ebed1Sslatteng     {
669574ebed1Sslatteng         if (CHANGED)
670574ebed1Sslatteng         {
671574ebed1Sslatteng             error("no write");
672574ebed1Sslatteng             return;
673574ebed1Sslatteng         }
674574ebed1Sslatteng     }  /* end if */;
675574ebed1Sslatteng     GRClose();
676574ebed1Sslatteng     TxClose();
677574ebed1Sslatteng     exit(0);
678574ebed1Sslatteng }  /* end LGQuit */
679574ebed1Sslatteng 
LGHAdjust()680574ebed1Sslatteng LGHAdjust()
681574ebed1Sslatteng /*
682574ebed1Sslatteng  * Horizontal adjust -
683574ebed1Sslatteng  *      This routine toggles the adjustment mode.
684574ebed1Sslatteng  */
685574ebed1Sslatteng 
686574ebed1Sslatteng {
687574ebed1Sslatteng     if (Adjustment == HORZ)
688574ebed1Sslatteng     {
689574ebed1Sslatteng         MNUnHighLt(HiMode[adj[HORZ]]);
690574ebed1Sslatteng         Adjustment = NOADJ;
691574ebed1Sslatteng         TxPutString(&TAdjust, "NO ADJUSTMENT");
692574ebed1Sslatteng     }
693574ebed1Sslatteng     else
694574ebed1Sslatteng     {
695574ebed1Sslatteng         MNUnHighLt(HiMode[adj[Adjustment]]);
696574ebed1Sslatteng         MNHighLt(HiMode[adj[HORZ]], hicolor);
697574ebed1Sslatteng         Adjustment = HORZ;
698574ebed1Sslatteng         TxPutString(&TAdjust, " HORIZONTAL  ");
699574ebed1Sslatteng     }
700574ebed1Sslatteng     Consume = FALSE;
701574ebed1Sslatteng }
702574ebed1Sslatteng 
7033a4b2214Sslatteng 
LGVAdjust()704574ebed1Sslatteng LGVAdjust()
705574ebed1Sslatteng /*
706574ebed1Sslatteng  * Vertical adjust -
707574ebed1Sslatteng  *      This routine toggles the adjustment mode.
708574ebed1Sslatteng  */
709574ebed1Sslatteng 
710574ebed1Sslatteng {
711574ebed1Sslatteng     if (Adjustment == VERT)
712574ebed1Sslatteng     {
713574ebed1Sslatteng         MNUnHighLt(HiMode[adj[VERT]]);
714574ebed1Sslatteng         Adjustment = NOADJ;
715574ebed1Sslatteng         TxPutString(&TAdjust, "NO ADJUSTMENT");
716574ebed1Sslatteng     }
717574ebed1Sslatteng     else
718574ebed1Sslatteng     {
719574ebed1Sslatteng         MNUnHighLt(HiMode[adj[Adjustment]]);
720574ebed1Sslatteng         MNHighLt(HiMode[adj[VERT]], hicolor);
721574ebed1Sslatteng         Adjustment = VERT;
722574ebed1Sslatteng         TxPutString(&TAdjust, "  VERTICAL   ");
723574ebed1Sslatteng     }
724574ebed1Sslatteng     Consume = FALSE;
725574ebed1Sslatteng }
726574ebed1Sslatteng 
727574ebed1Sslatteng 
7283a4b2214Sslatteng 
sign(x)729574ebed1Sslatteng static sign(x)
730574ebed1Sslatteng float x;
731574ebed1Sslatteng /*
732574ebed1Sslatteng  *      This local routine returns 1 if x >= 0
733574ebed1Sslatteng  * otherwise returns 0;
734574ebed1Sslatteng  */
735574ebed1Sslatteng 
736574ebed1Sslatteng {
737574ebed1Sslatteng     if (x >= 0) return(1);
738574ebed1Sslatteng     else  return(0);
739574ebed1Sslatteng }
740574ebed1Sslatteng 
LGMirror(line)741574ebed1Sslatteng LGMirror(line)
742574ebed1Sslatteng char *line;
743574ebed1Sslatteng /*
744574ebed1Sslatteng  *      This routine mirrors the elements in the current set as defined
745574ebed1Sslatteng  * by points.  The mirroring is accomplished by defining a transformation
746574ebed1Sslatteng  * matrix and calling DBXform.
747574ebed1Sslatteng  */
748574ebed1Sslatteng 
749574ebed1Sslatteng {
750574ebed1Sslatteng     ELT *e1;
751574ebed1Sslatteng     POINT pt, pos, *p1, *p2;
752574ebed1Sslatteng     float xmat[3][2], scalex, scaley;
753574ebed1Sslatteng     int i, j;
754574ebed1Sslatteng 
755574ebed1Sslatteng     if (SEQ < 3)        /* not enough points */
756574ebed1Sslatteng     {
757574ebed1Sslatteng         error("not enough points");
758574ebed1Sslatteng         return;
759574ebed1Sslatteng     }
760574ebed1Sslatteng     if (DBNullelt(cset))
761574ebed1Sslatteng     {
762574ebed1Sslatteng         error("no current set");
763574ebed1Sslatteng         return;
764574ebed1Sslatteng     }
765574ebed1Sslatteng     p1 = PTNextPoint(POINTLIST);
766574ebed1Sslatteng     p2 = PTNextPoint(p1);
767574ebed1Sslatteng     scalex = scaley = 1;
768574ebed1Sslatteng     if (sign(p1->x - POINTLIST->x) != sign(p2->x - POINTLIST->x))
769574ebed1Sslatteng         scalex = -scalex;
770574ebed1Sslatteng     if (sign(p1->y - POINTLIST->y) != sign(p2->y - POINTLIST->y))
771574ebed1Sslatteng         scaley = -scaley;
772574ebed1Sslatteng 
773574ebed1Sslatteng     /* create transformation matrix to translate set to origin,
774574ebed1Sslatteng        performing the mirroring and translating back               */
775574ebed1Sslatteng 
776574ebed1Sslatteng     xmat[0][0] = scalex;
777574ebed1Sslatteng     xmat[1][1] = scaley;
778574ebed1Sslatteng     xmat[1][0] = xmat[0][1] = 0;
779574ebed1Sslatteng     xmat[2][0] = - POINTLIST->x * (scalex - 1.0);
780574ebed1Sslatteng     xmat[2][1] = - POINTLIST->y * (scaley - 1.0);
781574ebed1Sslatteng     e1 = cset;
782574ebed1Sslatteng     while ( !DBNullelt(e1) )
783574ebed1Sslatteng     {
784574ebed1Sslatteng         DISScreenErase(e1, (linemask | setmask));
785574ebed1Sslatteng         TxMsgOK();
786574ebed1Sslatteng         DBXform(e1, xmat, &PICTURE);
787574ebed1Sslatteng         if (TEXT(e1->type))
788574ebed1Sslatteng         {
789574ebed1Sslatteng             GRsetwmask(textmask | setmask);
790574ebed1Sslatteng             p1 = e1->ptlist;
791574ebed1Sslatteng             GRPutText(e1->type, p1, e1->brushf, e1->size,e1->textpt, &pos);
792574ebed1Sslatteng             i= strlen(e1->textpt);
793574ebed1Sslatteng             p2 = PTInit();
794574ebed1Sslatteng             (void) PTMakePoint(p1->x, p1->y, &p2);
795574ebed1Sslatteng                        /* add extra positioning points */
796574ebed1Sslatteng             (void) PTMakePoint(pos.x, pos.y, &p2);
797574ebed1Sslatteng             (void) PTMakePoint(pos.x + i * charxsize / 2, pos.y, &p2);
798574ebed1Sslatteng             (void) PTMakePoint(pos.x + i * charxsize, pos.y, &p2);
799574ebed1Sslatteng             e1->ptlist = p2;
800574ebed1Sslatteng         }  /* end if TEXT */
801574ebed1Sslatteng         else
802574ebed1Sslatteng         {
803574ebed1Sslatteng             if (e1->type == ARC)   /* arcs require special handling */
804574ebed1Sslatteng                 if (e1->size > 0)   /* circles are OK */
805574ebed1Sslatteng                     if (scalex * scaley < 0)  /* both directions OK */
806574ebed1Sslatteng                     {          /* swap starting and ending points of arc */
807574ebed1Sslatteng                         p1 = PTNextPoint(e1->ptlist);
808574ebed1Sslatteng                         p2 = PTNextPoint(p1);
809574ebed1Sslatteng                         pt.x = p1->x;
810574ebed1Sslatteng                         pt.y = p1->y;
811574ebed1Sslatteng                         p1->x = p2->x;
812574ebed1Sslatteng                         p1->y = p2->y;
813574ebed1Sslatteng                         p2->x = pt.x;
814574ebed1Sslatteng                         p2->y = pt.y;
815574ebed1Sslatteng                     }
816574ebed1Sslatteng             DISScreenAdd(e1, (linemask | setmask));
817574ebed1Sslatteng         }  /* end else */
818574ebed1Sslatteng         e1 = DBNextofSet(e1);
819574ebed1Sslatteng     }  /* end while */
820574ebed1Sslatteng     CHANGED = TRUE;
821574ebed1Sslatteng }  /* end LGMirror */
822574ebed1Sslatteng 
8233a4b2214Sslatteng 
LGPath(line)824574ebed1Sslatteng LGPath(line)
825574ebed1Sslatteng char *line;
826574ebed1Sslatteng /*
827574ebed1Sslatteng  *      This routine looks at the command line for parameters to set
828574ebed1Sslatteng  * the current search path.
829574ebed1Sslatteng  */
830574ebed1Sslatteng 
831574ebed1Sslatteng {
832574ebed1Sslatteng     char path[100];
833574ebed1Sslatteng 
834574ebed1Sslatteng     if ( *line == '\0' )  TxPutMsg(PGetPath());     /* no arguments */
835574ebed1Sslatteng     else
836574ebed1Sslatteng     {
837574ebed1Sslatteng         SEARCH = TRUE;
838574ebed1Sslatteng         (void) sscanf(line, "%s", path);
839574ebed1Sslatteng         PSetPath(path);
840574ebed1Sslatteng     }
841574ebed1Sslatteng     Consume = FALSE;
842574ebed1Sslatteng }  /* end LGFont */
843