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