19ac52343Sopcode /*
2*b3593ea1Sopcode * @(#)long2.c 1.2 01/03/85
39ac52343Sopcode *
49ac52343Sopcode * More routines to implement "long" commands for the SUN Gremlin
59ac52343Sopcode * picture editor.
69ac52343Sopcode *
79ac52343Sopcode * Mark Opperman (opcode@monet.BERKELEY)
89ac52343Sopcode *
99ac52343Sopcode */
109ac52343Sopcode
119ac52343Sopcode #include <suntool/tool_hs.h>
129ac52343Sopcode #include <suntool/menu.h>
139ac52343Sopcode #include <sys/file.h>
149ac52343Sopcode #include "gremlin.h"
159ac52343Sopcode #include <ctype.h>
169ac52343Sopcode
179ac52343Sopcode /* imports from graphics files */
189ac52343Sopcode
199ac52343Sopcode extern GRBlankPoints();
209ac52343Sopcode extern GRDisplayPoint();
219ac52343Sopcode extern GRSetTextPos();
229ac52343Sopcode
239ac52343Sopcode /* imports from path.c */
249ac52343Sopcode
259ac52343Sopcode extern PSetPath();
269ac52343Sopcode extern PConvertTilde();
279ac52343Sopcode extern char *PGetPath();
289ac52343Sopcode
299ac52343Sopcode /* imports from display.c */
309ac52343Sopcode
319ac52343Sopcode extern DISClearSetDisplay();
329ac52343Sopcode extern DISScreenAdd();
339ac52343Sopcode extern DISScreenErase();
349ac52343Sopcode
359ac52343Sopcode /* imports from database files */
369ac52343Sopcode
379ac52343Sopcode extern ELT *DBCopy();
389ac52343Sopcode extern ELT *DBRead();
399ac52343Sopcode extern ELT *DBCreateElt();
409ac52343Sopcode
419ac52343Sopcode extern POINT *PTMakeTextPoints();
429ac52343Sopcode extern POINT *PTMakePoint();
439ac52343Sopcode
449ac52343Sopcode extern DBAddSet();
459ac52343Sopcode extern DBChangeBrush();
469ac52343Sopcode extern DBChangeType();
479ac52343Sopcode extern DBChangeTypeStipple();
489ac52343Sopcode extern DBClearElt();
499ac52343Sopcode extern DBClearSet();
509ac52343Sopcode extern DBDelete();
519ac52343Sopcode extern DBGravitate();
529ac52343Sopcode extern DBXform();
539ac52343Sopcode
549ac52343Sopcode /* imports from undodb.c */
559ac52343Sopcode
569ac52343Sopcode extern UNELT *unlist;
579ac52343Sopcode extern UNELT *unback;
589ac52343Sopcode extern UNForget();
599ac52343Sopcode
609ac52343Sopcode /* imports from short.c */
619ac52343Sopcode
629ac52343Sopcode extern SHUpdate();
639ac52343Sopcode extern int adj[];
649ac52343Sopcode
659ac52343Sopcode /* imports from text.c */
669ac52343Sopcode
679ac52343Sopcode extern TxKillLine();
689ac52343Sopcode extern TxMsgOK();
699ac52343Sopcode extern TxPutMsg();
709ac52343Sopcode
719ac52343Sopcode /* imports from menu.c */
729ac52343Sopcode
739ac52343Sopcode extern MNHighLt();
749ac52343Sopcode extern MNUnHighLt();
759ac52343Sopcode extern HiMode[];
769ac52343Sopcode
779ac52343Sopcode /* imports from C */
789ac52343Sopcode
799ac52343Sopcode extern char *strcpy();
809ac52343Sopcode extern char *sprintf();
819ac52343Sopcode extern char *malloc();
829ac52343Sopcode extern FILE *fopen();
839ac52343Sopcode
849ac52343Sopcode /* imports from sun.c */
859ac52343Sopcode
869ac52343Sopcode extern flush_window_input();
879ac52343Sopcode extern prompt_ok();
889ac52343Sopcode
899ac52343Sopcode /* imports from main.c */
909ac52343Sopcode
919ac52343Sopcode extern char namestripe[];
929ac52343Sopcode extern char version[];
939ac52343Sopcode extern struct tool *tool;
949ac52343Sopcode extern struct pixfont *text_pf;
959ac52343Sopcode
969ac52343Sopcode extern tool_fd;
979ac52343Sopcode extern menu_fd;
989ac52343Sopcode
999ac52343Sopcode extern ELT *PICTURE; /* current PICTURE database */
1009ac52343Sopcode extern ELT *cset; /* current set database */
1019ac52343Sopcode extern Orientation; /* orientation of workspace */
1029ac52343Sopcode extern SEARCH; /* flag for path search */
1039ac52343Sopcode extern Alignment; /* point alignment indicator */
1049ac52343Sopcode extern CBRUSH; /* current brush */
1059ac52343Sopcode extern CSTIPPLE; /* current stipple */
1069ac52343Sopcode extern float PX, PY; /* cursor coordinates */
1079ac52343Sopcode extern float Lastx, Lasty; /* previous cursor coordinates */
1089ac52343Sopcode extern SEQ; /* point sequence number */
1099ac52343Sopcode extern POINT *POINTLIST, *BACKPOINT;/* accumulated point list */
1109ac52343Sopcode extern Gridsize; /* grid spacing */
1119ac52343Sopcode extern Adjustment; /* point adjustment mode */
1129ac52343Sopcode extern CHANGED; /* PICTURE changed flag */
1139ac52343Sopcode extern ELT *MEN[]; /* pointers for user symbols */
1149ac52343Sopcode extern POINT MENPOINT[]; /* pointers used fo user symbols */
1159ac52343Sopcode extern newfileformat; /* TRUE if using SUN file format */
1169ac52343Sopcode
1179ac52343Sopcode /* imports from long1.c */
1189ac52343Sopcode
1199ac52343Sopcode extern CSP();
1209ac52343Sopcode extern CP();
1219ac52343Sopcode
1229ac52343Sopcode char *Editfile;
1239ac52343Sopcode char *eltnames[] = {
1249ac52343Sopcode "BOTLEFT", "BOTRIGHT", "CENTCENT", "VECTOR", "ARC", "CURVE", "POLYGON",
1259ac52343Sopcode "", "", "",
1269ac52343Sopcode "TOPLEFT", "TOPCENT", "TOPRIGHT", "CENTLEFT", "CENTRIGHT", "BOTCENT"
1279ac52343Sopcode };
1289ac52343Sopcode
129*b3593ea1Sopcode char nowrite_msg[] = "NO WRITE SINCE LAST CHANGE! Press left button to \
130*b3593ea1Sopcode edit new file, middle or right button to cancel.";
131*b3593ea1Sopcode char filexists_msg[] = "FILE EXISTS! Press left button to overwrite, middle \
132*b3593ea1Sopcode or right button to cancel.";
133*b3593ea1Sopcode static char quit_msg[] = "NO WRITE SINCE LAST CHANGE! Press left button \
134*b3593ea1Sopcode to confirm quit, middle or right button to cancel.";
135*b3593ea1Sopcode static char quit2_msg[] = "Press left button to confirm quit, middle or right \
136*b3593ea1Sopcode button to cancel.";
1379ac52343Sopcode
1389ac52343Sopcode #define BADNUM -1
1399ac52343Sopcode #define NONUM -2
1409ac52343Sopcode
1419ac52343Sopcode static char badarg[] = "bad args";
1429ac52343Sopcode
1439ac52343Sopcode
1449ac52343Sopcode /*
1459ac52343Sopcode * This routine creates and displays a POLYGON element from the
1469ac52343Sopcode * points previously specified.
1479ac52343Sopcode */
1489ac52343Sopcode static
LGDrawPolygon(bordered)1499ac52343Sopcode LGDrawPolygon(bordered)
1509ac52343Sopcode int bordered;
1519ac52343Sopcode {
1529ac52343Sopcode register POINT *p1, *p2;
1539ac52343Sopcode POINT *p0, *plist;
1549ac52343Sopcode ELT *e1;
1559ac52343Sopcode char *txt;
1569ac52343Sopcode
1579ac52343Sopcode if (SEQ < 3) { /* not enough points */
1589ac52343Sopcode error("need at least 3 points");
1599ac52343Sopcode return;
1609ac52343Sopcode }
1619ac52343Sopcode
1629ac52343Sopcode UNForget();
1639ac52343Sopcode
1649ac52343Sopcode DISClearSetDisplay();
1659ac52343Sopcode DBClearSet();
1669ac52343Sopcode
1679ac52343Sopcode plist = PTInit();
1689ac52343Sopcode p0 = p1 = POINTLIST;
1699ac52343Sopcode (void) PTMakePoint(p1->x, p1->y, &plist);
1709ac52343Sopcode p2 = PTNextPoint(p1);
1719ac52343Sopcode
1729ac52343Sopcode while (!Nullpoint(p2)) {
1739ac52343Sopcode (void) PTMakePoint(p2->x, p2->y, &plist);
1749ac52343Sopcode p1 = p2;
1759ac52343Sopcode p2 = PTNextPoint(p1);
1769ac52343Sopcode }
1779ac52343Sopcode
1789ac52343Sopcode txt = malloc(1);
1799ac52343Sopcode *txt = '\0';
1809ac52343Sopcode e1 = DBCreateElt(POLYGON, plist, bordered ? CBRUSH : 0, CSTIPPLE,
1819ac52343Sopcode txt, &PICTURE);
1829ac52343Sopcode DISScreenAdd(e1, pixmask | csetmask);
1839ac52343Sopcode DBAddSet(e1);
1849ac52343Sopcode
1859ac52343Sopcode CP();
1869ac52343Sopcode CHANGED = TRUE;
1879ac52343Sopcode } /* end LGDrawPolygon */
1889ac52343Sopcode
1899ac52343Sopcode
LGBPolygon()1909ac52343Sopcode LGBPolygon()
1919ac52343Sopcode {
1929ac52343Sopcode LGDrawPolygon(TRUE);
1939ac52343Sopcode }
1949ac52343Sopcode
1959ac52343Sopcode
LGPolygon()1969ac52343Sopcode LGPolygon()
1979ac52343Sopcode {
1989ac52343Sopcode LGDrawPolygon(FALSE);
1999ac52343Sopcode }
2009ac52343Sopcode
2019ac52343Sopcode
2029ac52343Sopcode /*
2039ac52343Sopcode * Modify elements in current set to POLYGON type with the indicated
2049ac52343Sopcode * brush. POLYGONs, CURVEs and VECTORs can be modified to either
2059ac52343Sopcode * bordered or unbordered POLYGONs.
2069ac52343Sopcode */
LGModifyPolygon(brush)2079ac52343Sopcode LGModifyPolygon(brush)
2089ac52343Sopcode int brush; /* zero for unbordered */
2099ac52343Sopcode {
2109ac52343Sopcode register ELT *elt;
2119ac52343Sopcode
2129ac52343Sopcode if (DBNullelt(cset)) {
2139ac52343Sopcode error("no current set");
2149ac52343Sopcode return;
2159ac52343Sopcode }
2169ac52343Sopcode
2179ac52343Sopcode UNForget();
2189ac52343Sopcode CSP();
2199ac52343Sopcode
2209ac52343Sopcode elt = cset;
2219ac52343Sopcode while (!DBNullelt(elt)) {
2229ac52343Sopcode if (elt->type == POLYGON) {
2239ac52343Sopcode DISScreenErase(elt, pixmask | csetmask);
2249ac52343Sopcode DBChangeBrush(elt, brush, &PICTURE);
2259ac52343Sopcode DISScreenAdd(elt, pixmask | csetmask);
2269ac52343Sopcode }
2279ac52343Sopcode else if ((elt->type == VECTOR) || (elt->type == CURVE)) {
2289ac52343Sopcode DISScreenErase(elt, pixmask | csetmask);
2299ac52343Sopcode if (brush != 0) /* bordered polygon */
2309ac52343Sopcode DBChangeTypeStipple(elt, POLYGON, CSTIPPLE, &PICTURE);
2319ac52343Sopcode else /* unbordered polygon */
2329ac52343Sopcode DBChangeTypeBrushStipple(elt, POLYGON, 0, CSTIPPLE, &PICTURE);
2339ac52343Sopcode DISScreenAdd(elt, pixmask | csetmask);
2349ac52343Sopcode }
2359ac52343Sopcode
2369ac52343Sopcode elt = DBNextofSet(elt);
2379ac52343Sopcode }
2389ac52343Sopcode
2399ac52343Sopcode CP();
2409ac52343Sopcode CHANGED = TRUE;
2419ac52343Sopcode } /* end LGModifyPolygon */
2429ac52343Sopcode
2439ac52343Sopcode
2449ac52343Sopcode /*
2459ac52343Sopcode * Modify curves, vectors and polygons in the current set
2469ac52343Sopcode * to bordered polygons.
2479ac52343Sopcode */
LGMBPolygon()2489ac52343Sopcode LGMBPolygon()
2499ac52343Sopcode {
2509ac52343Sopcode LGModifyPolygon(CBRUSH);
2519ac52343Sopcode }
2529ac52343Sopcode
2539ac52343Sopcode
2549ac52343Sopcode /*
2559ac52343Sopcode * Modify curves, vectors and polygons in the current set
2569ac52343Sopcode * to unbordered polygons.
2579ac52343Sopcode */
LGMPolygon()2589ac52343Sopcode LGMPolygon()
2599ac52343Sopcode {
2609ac52343Sopcode LGModifyPolygon(0);
2619ac52343Sopcode }
2629ac52343Sopcode
2639ac52343Sopcode
2649ac52343Sopcode /*
2659ac52343Sopcode * Modify curves and polygons in the current set to vectors.
2669ac52343Sopcode */
LGMVector()2679ac52343Sopcode LGMVector()
2689ac52343Sopcode {
2699ac52343Sopcode register ELT *elt;
2709ac52343Sopcode
2719ac52343Sopcode if (DBNullelt(cset)) {
2729ac52343Sopcode error("no current set");
2739ac52343Sopcode return;
2749ac52343Sopcode }
2759ac52343Sopcode
2769ac52343Sopcode UNForget();
2779ac52343Sopcode CSP();
2789ac52343Sopcode
2799ac52343Sopcode elt = cset;
2809ac52343Sopcode while (!DBNullelt(elt)) {
2819ac52343Sopcode if (elt->type == POLYGON) {
2829ac52343Sopcode DISScreenErase(elt, pixmask | csetmask);
2839ac52343Sopcode if (elt->brushf != 0)
2849ac52343Sopcode DBChangeTypeStipple(elt, VECTOR, 0, &PICTURE);
2859ac52343Sopcode else
2869ac52343Sopcode DBChangeTypeBrushStipple(elt, VECTOR, CBRUSH, 0, &PICTURE);
2879ac52343Sopcode DISScreenAdd(elt, pixmask | csetmask);
2889ac52343Sopcode }
2899ac52343Sopcode else if (elt->type == CURVE) {
2909ac52343Sopcode DISScreenErase(elt, pixmask | csetmask);
2919ac52343Sopcode DBChangeType(elt, VECTOR, &PICTURE);
2929ac52343Sopcode DISScreenAdd(elt, pixmask | csetmask);
2939ac52343Sopcode }
2949ac52343Sopcode elt = DBNextofSet(elt);
2959ac52343Sopcode }
2969ac52343Sopcode
2979ac52343Sopcode CP();
2989ac52343Sopcode CHANGED = TRUE;
2999ac52343Sopcode }
3009ac52343Sopcode
3019ac52343Sopcode
3029ac52343Sopcode /*
3039ac52343Sopcode * Modify vectors and polygons in the current set to curves.
3049ac52343Sopcode */
LGMCurve()3059ac52343Sopcode LGMCurve()
3069ac52343Sopcode {
3079ac52343Sopcode register ELT *elt;
3089ac52343Sopcode
3099ac52343Sopcode if (DBNullelt(cset)) {
3109ac52343Sopcode error("no current set");
3119ac52343Sopcode return;
3129ac52343Sopcode }
3139ac52343Sopcode
3149ac52343Sopcode UNForget();
3159ac52343Sopcode CSP();
3169ac52343Sopcode
3179ac52343Sopcode elt = cset;
3189ac52343Sopcode while (!DBNullelt(elt)) {
3199ac52343Sopcode if (elt->type == VECTOR) {
3209ac52343Sopcode DISScreenErase(elt, pixmask | csetmask);
3219ac52343Sopcode DBChangeType(elt, CURVE, &PICTURE);
3229ac52343Sopcode DISScreenAdd(elt, pixmask | csetmask);
3239ac52343Sopcode }
3249ac52343Sopcode else if (elt->type == POLYGON) {
3259ac52343Sopcode DISScreenErase(elt, pixmask | csetmask);
3269ac52343Sopcode if (elt->brushf != 0) /* bordered polygon */
3279ac52343Sopcode DBChangeTypeStipple(elt, CURVE, 0, &PICTURE);
3289ac52343Sopcode else /* unbordered polygon */
3299ac52343Sopcode DBChangeTypeBrushStipple(elt, CURVE, CBRUSH, 0, &PICTURE);
3309ac52343Sopcode DISScreenAdd(elt, pixmask | csetmask);
3319ac52343Sopcode }
3329ac52343Sopcode elt = DBNextofSet(elt);
3339ac52343Sopcode }
3349ac52343Sopcode
3359ac52343Sopcode CP();
3369ac52343Sopcode CHANGED = TRUE;
3379ac52343Sopcode }
3389ac52343Sopcode
3399ac52343Sopcode
LGIncludeSet()3409ac52343Sopcode LGIncludeSet()
3419ac52343Sopcode /*
3429ac52343Sopcode * This routine adds all elements selected by points in POINTLIST
3439ac52343Sopcode * to the current set. It does not remove previously selected elements.
3449ac52343Sopcode */
3459ac52343Sopcode {
3469ac52343Sopcode POINT *p1, *p2;
3479ac52343Sopcode ELT *e1;
3489ac52343Sopcode float n1, n2;
3499ac52343Sopcode
3509ac52343Sopcode if (DBNullelt(PICTURE))
3519ac52343Sopcode return;
3529ac52343Sopcode
3539ac52343Sopcode if (SEQ == 0) { /* no points: entire picture becomes current set */
3549ac52343Sopcode e1 = PICTURE;
3559ac52343Sopcode while (!DBNullelt(e1)) {
3569ac52343Sopcode if (!DBInCset(e1)) { /* not now in current set */
3579ac52343Sopcode DBAddSet(e1); /* add it to current set */
3589ac52343Sopcode DISScreenAdd(e1, csetmask); /* and display it */
3599ac52343Sopcode }
3609ac52343Sopcode e1 = DBNextElt(e1);
3619ac52343Sopcode }
3629ac52343Sopcode }
3639ac52343Sopcode else {
3649ac52343Sopcode p1 = POINTLIST;
3659ac52343Sopcode
3669ac52343Sopcode /* for each user point */
3679ac52343Sopcode while (!Nullpoint(p1)) {
3689ac52343Sopcode
3699ac52343Sopcode /* find closest element */
3709ac52343Sopcode DBGravitate(p1->x, p1->y, &n1, &n2, &p2, &e1, PICTURE, FALSE);
3719ac52343Sopcode
3729ac52343Sopcode /* if something's close and its not already in the current set */
3739ac52343Sopcode if (!DBNullelt(e1) && !DBInCset(e1)) {
3749ac52343Sopcode DBAddSet(e1); /* add it */
3759ac52343Sopcode DISScreenAdd(e1, csetmask); /* and display it */
3769ac52343Sopcode }
3779ac52343Sopcode p1 = PTNextPoint(p1);
3789ac52343Sopcode }
3799ac52343Sopcode }
3809ac52343Sopcode
3819ac52343Sopcode CP();
3829ac52343Sopcode } /* end LGIncludeSet */
3839ac52343Sopcode
3849ac52343Sopcode
3859ac52343Sopcode /*
3869ac52343Sopcode * This routine implements the menu command. The contents of
3879ac52343Sopcode * the specified user menu item is copied into the PICTURE transformed
3889ac52343Sopcode * to the positioning point.
3899ac52343Sopcode */
LGGet(buffer)3909ac52343Sopcode LGGet(buffer)
3919ac52343Sopcode int buffer;
3929ac52343Sopcode {
3939ac52343Sopcode
3949ac52343Sopcode ELT *elist, *e1;
3959ac52343Sopcode POINT *plist;
3969ac52343Sopcode int symbol, index;
3979ac52343Sopcode float xmat[3][2];
3989ac52343Sopcode
3999ac52343Sopcode if (SEQ < 1) {
4009ac52343Sopcode error("no positioning point");
4019ac52343Sopcode return;
4029ac52343Sopcode }
4039ac52343Sopcode
4049ac52343Sopcode UNForget();
4059ac52343Sopcode buffer--; /* users inputs number between 1 and N, actual
4069ac52343Sopcode buffer number is between 0 and N-1 */
4079ac52343Sopcode
4089ac52343Sopcode xmat[0][0] = xmat[1][1] = 1; /* create transformation matrix */
4099ac52343Sopcode xmat[0][1] = xmat[1][0] = 0; /* for copy into PICTURE */
4109ac52343Sopcode plist = POINTLIST;
4119ac52343Sopcode
4129ac52343Sopcode while (!Nullpoint(plist)) {
4139ac52343Sopcode DISClearSetDisplay();
4149ac52343Sopcode DBClearSet();
4159ac52343Sopcode xmat[2][0] = plist->x - (MENPOINT[buffer]).x;
4169ac52343Sopcode xmat[2][1] = plist->y - (MENPOINT[buffer]).y;
4179ac52343Sopcode elist = MEN[buffer];
4189ac52343Sopcode
4199ac52343Sopcode while (!DBNullelt(elist)) { /* copy buffer to picture */
4209ac52343Sopcode e1 = DBCopy(elist, xmat, &PICTURE);
4219ac52343Sopcode DISScreenAdd(e1, pixmask | csetmask);
4229ac52343Sopcode DBAddSet(e1);
4239ac52343Sopcode elist = DBNextElt(elist);
4249ac52343Sopcode }
4259ac52343Sopcode
4269ac52343Sopcode plist = PTNextPoint(plist);
4279ac52343Sopcode }
4289ac52343Sopcode
4299ac52343Sopcode CP();
4309ac52343Sopcode CHANGED = TRUE;
4319ac52343Sopcode } /* end LGGet */
4329ac52343Sopcode
4339ac52343Sopcode
LGGet1()4349ac52343Sopcode LGGet1()
4359ac52343Sopcode {
4369ac52343Sopcode LGGet(1);
4379ac52343Sopcode }
4389ac52343Sopcode
4399ac52343Sopcode
LGGet2()4409ac52343Sopcode LGGet2()
4419ac52343Sopcode {
4429ac52343Sopcode LGGet(2);
4439ac52343Sopcode }
4449ac52343Sopcode
4459ac52343Sopcode
LGGet3()4469ac52343Sopcode LGGet3()
4479ac52343Sopcode {
4489ac52343Sopcode LGGet(3);
4499ac52343Sopcode }
4509ac52343Sopcode
4519ac52343Sopcode
LGGet4()4529ac52343Sopcode LGGet4()
4539ac52343Sopcode {
4549ac52343Sopcode LGGet(4);
4559ac52343Sopcode }
4569ac52343Sopcode
4579ac52343Sopcode
4589ac52343Sopcode /*
4599ac52343Sopcode * This routine reads in the specified filename (command line) to the
4609ac52343Sopcode * selected user symbol or current set if no user symbol is selected. If
4619ac52343Sopcode * no filename is specified, the current set is copied to the user symbol;
4629ac52343Sopcode */
LGRead()4639ac52343Sopcode LGRead()
4649ac52343Sopcode {
4659ac52343Sopcode POINT pos, ppos;
4669ac52343Sopcode ELT *elist, *e1;
4679ac52343Sopcode char tname[TEXT_BUFMAX];
4689ac52343Sopcode float xmat[3][2];
4699ac52343Sopcode int orient;
4709ac52343Sopcode
4719ac52343Sopcode text_getvalue(&tname[0]);
4729ac52343Sopcode if (*tname == '\0') {
4739ac52343Sopcode error("read from where?");
4749ac52343Sopcode return;
4759ac52343Sopcode }
4769ac52343Sopcode
4779ac52343Sopcode elist = DBRead(tname, &orient, &pos); /* read file */
4789ac52343Sopcode if (elist == (ELT *) NULL)
4799ac52343Sopcode return;
4809ac52343Sopcode
4819ac52343Sopcode UNForget(); /* forget changes registered */
4829ac52343Sopcode /* by DBRead */
4839ac52343Sopcode if (SEQ < 1) { /* no positioning point */
4849ac52343Sopcode ppos.x = pos.x;
4859ac52343Sopcode ppos.y = pos.y;
4869ac52343Sopcode }
4879ac52343Sopcode else {
4889ac52343Sopcode ppos.x = POINTLIST->x;
4899ac52343Sopcode ppos.y = POINTLIST->y;
4909ac52343Sopcode }
4919ac52343Sopcode
4929ac52343Sopcode xmat[0][0] = xmat[1][1] = 1; /* set up matrix to copy to */
4939ac52343Sopcode xmat[0][1] = xmat[1][0] = 0; /* appropriate place in */
4949ac52343Sopcode xmat[2][0] = ppos.x - pos.x; /* picture as current set */
4959ac52343Sopcode xmat[2][1] = ppos.y - pos.y;
4969ac52343Sopcode DISClearSetDisplay();
4979ac52343Sopcode DBClearSet();
4989ac52343Sopcode
4999ac52343Sopcode while (!DBNullelt(elist)) {
5009ac52343Sopcode e1 = DBCopy(elist, xmat, &PICTURE);
5019ac52343Sopcode DISScreenAdd(e1, pixmask | csetmask);
5029ac52343Sopcode DBAddSet(e1);
5039ac52343Sopcode e1 = DBNextElt(elist);
5049ac52343Sopcode DBClearElt(elist);
5059ac52343Sopcode elist = e1;
5069ac52343Sopcode }
5079ac52343Sopcode
5089ac52343Sopcode CHANGED = TRUE;
5099ac52343Sopcode TxKillLine();
5109ac52343Sopcode CP();
5119ac52343Sopcode } /* end LGRead */
5129ac52343Sopcode
5139ac52343Sopcode
5149ac52343Sopcode /*
5159ac52343Sopcode * This routine reads in a new PICTURE for editing
5169ac52343Sopcode */
LGEdit()5179ac52343Sopcode LGEdit()
5189ac52343Sopcode {
5199ac52343Sopcode FILE *fp, *POpen();
5209ac52343Sopcode POINT pos;
5219ac52343Sopcode ELT *e1;
5229ac52343Sopcode char *prealname, *tn, tname[TEXT_BUFMAX];
5239ac52343Sopcode int fd;
5249ac52343Sopcode
5259ac52343Sopcode text_getvalue(&tname[0]);
5269ac52343Sopcode
5279ac52343Sopcode if (CHANGED) {
5289ac52343Sopcode if (!prompt_ok(menu_fd, nowrite_msg)) {
5299ac52343Sopcode return;
5309ac52343Sopcode }
5319ac52343Sopcode }
5329ac52343Sopcode
5339ac52343Sopcode DISClearSetDisplay();
5349ac52343Sopcode DBClearSet();
5359ac52343Sopcode
5369ac52343Sopcode while (!DBNullelt(PICTURE)) { /* clear current PICTURE */
5379ac52343Sopcode e1 = DBNextElt(PICTURE);
5389ac52343Sopcode DBClearElt(PICTURE);
5399ac52343Sopcode PICTURE = e1;
5409ac52343Sopcode }
5419ac52343Sopcode
5429ac52343Sopcode tn = tname;
5439ac52343Sopcode
5449ac52343Sopcode POINTLIST = PTInit(); /* initialize globals */
5459ac52343Sopcode SEQ = 0;
5469ac52343Sopcode CHANGED = FALSE;
5479ac52343Sopcode (void) strcpy(namestripe, version);
5489ac52343Sopcode
5499ac52343Sopcode if (*tname != '\0') { /* filename present */
5509ac52343Sopcode fp = POpen(tname, &prealname, SEARCH);
5519ac52343Sopcode
5529ac52343Sopcode if (fp == NULL) {
5539ac52343Sopcode PICTURE = DBInit();
5549ac52343Sopcode strcpy(Editfile, tname);
5559ac52343Sopcode strcat(namestripe, tname);
5569ac52343Sopcode error("creating new file");
5579ac52343Sopcode }
5589ac52343Sopcode else {
5599ac52343Sopcode fclose(fp);
5609ac52343Sopcode strcpy(Editfile, prealname);
5619ac52343Sopcode strcat(namestripe, prealname);
5629ac52343Sopcode PICTURE = DBRead(tname, &Orientation, &pos);
5639ac52343Sopcode if ((fd = open(prealname, O_WRONLY | O_APPEND)) < 0)
5649ac52343Sopcode strcat(namestripe, " (read only)");
5659ac52343Sopcode else
5669ac52343Sopcode close(fd);
5679ac52343Sopcode }
5689ac52343Sopcode }
5699ac52343Sopcode else { /* create new file */
5709ac52343Sopcode PICTURE = DBInit();
5719ac52343Sopcode (void) strcat(namestripe, "new file");
5729ac52343Sopcode (void) strcpy(Editfile, "");
5739ac52343Sopcode }
5749ac52343Sopcode
5759ac52343Sopcode tool_display(tool);
5769ac52343Sopcode
5779ac52343Sopcode unlist = unback = NULL;
5789ac52343Sopcode CP();
5799ac52343Sopcode SHUpdate(); /* display new picture */
5809ac52343Sopcode TxKillLine();
5819ac52343Sopcode } /* end LGEdit */
5829ac52343Sopcode
5839ac52343Sopcode
5849ac52343Sopcode /*
5859ac52343Sopcode * This routine (re) displays the points in the back-up pointlist
5869ac52343Sopcode */
5879ac52343Sopcode static
restorepoints()5889ac52343Sopcode restorepoints()
5899ac52343Sopcode {
5909ac52343Sopcode
5919ac52343Sopcode register POINT *plist, *pl1;
5929ac52343Sopcode register i;
5939ac52343Sopcode
5949ac52343Sopcode GRBlankPoints(POINTLIST);
5959ac52343Sopcode plist = BACKPOINT;
5969ac52343Sopcode
5979ac52343Sopcode for (i=0; !Nullpoint(plist); ++i) {
5989ac52343Sopcode Lastx = plist->x;
5999ac52343Sopcode Lasty = plist->y;
6009ac52343Sopcode GRDisplayPoint(plist->x, plist->y, i);
6019ac52343Sopcode plist = PTNextPoint(plist);
6029ac52343Sopcode }
6039ac52343Sopcode
6049ac52343Sopcode pl1 = POINTLIST;
6059ac52343Sopcode POINTLIST = BACKPOINT;
6069ac52343Sopcode SEQ = i;
6079ac52343Sopcode BACKPOINT = pl1;
6089ac52343Sopcode } /* end restorepoints */
6099ac52343Sopcode
6109ac52343Sopcode
6119ac52343Sopcode /*
6129ac52343Sopcode * This routine uses the information in the undo database to reconstruct
6139ac52343Sopcode * the PICTURE as it was before the last command. The undo database is set
6149ac52343Sopcode * so that the next undo would nullify this one.
6159ac52343Sopcode * An undo of an Add is to delete the new element.
6169ac52343Sopcode * Add the old element back to undo a delete.
6179ac52343Sopcode * Modified elements are undone by copying the old element into the database
6189ac52343Sopcode * in place of the modified element.
6199ac52343Sopcode */
LGUndo()6209ac52343Sopcode LGUndo()
6219ac52343Sopcode {
6229ac52343Sopcode UNELT *fix, *temp;
6239ac52343Sopcode ELT *(*e1);
6249ac52343Sopcode
6259ac52343Sopcode fix = unlist; /* initialize unlist so that undo-ing can */
6269ac52343Sopcode unlist = NULL; /* add items to properly undo the undo */
6279ac52343Sopcode
6289ac52343Sopcode if (fix == NULL) {
6299ac52343Sopcode fix = unback;
6309ac52343Sopcode unback = NULL;
6319ac52343Sopcode }
6329ac52343Sopcode
6339ac52343Sopcode DISClearSetDisplay();
6349ac52343Sopcode DBClearSet();
6359ac52343Sopcode
6369ac52343Sopcode while (fix != NULL) {
6379ac52343Sopcode switch (fix->action) {
6389ac52343Sopcode case ADD:
6399ac52343Sopcode DISScreenErase(fix->newelt, pixmask);
6409ac52343Sopcode TxMsgOK();
6419ac52343Sopcode restorepoints();
6429ac52343Sopcode DBDelete(fix->newelt, fix->dbase);
6439ac52343Sopcode temp = fix->nextun;
6449ac52343Sopcode free((char *) fix);
6459ac52343Sopcode fix = temp;
6469ac52343Sopcode break;
6479ac52343Sopcode case DELETE:
6489ac52343Sopcode fix->action = ADD; /* create undo unelt */
6499ac52343Sopcode fix->newelt = fix->oldelt;
6509ac52343Sopcode fix->oldelt = NULL;
6519ac52343Sopcode fix->newelt->nextelt = PICTURE;
6529ac52343Sopcode restorepoints();
6539ac52343Sopcode DISScreenAdd(fix->newelt, pixmask | csetmask);
6549ac52343Sopcode DBAddSet(fix->newelt);
6559ac52343Sopcode PICTURE = fix->newelt; /* put in database */
6569ac52343Sopcode temp = fix->nextun;
6579ac52343Sopcode fix->nextun = unlist; /* link into unlist */
6589ac52343Sopcode unlist = fix;
6599ac52343Sopcode fix = temp;
6609ac52343Sopcode break;
6619ac52343Sopcode case MOD:
6629ac52343Sopcode DISScreenErase(fix->newelt, pixmask);
6639ac52343Sopcode TxMsgOK();
6649ac52343Sopcode restorepoints();
6659ac52343Sopcode DISScreenAdd(fix->oldelt, pixmask | csetmask);
6669ac52343Sopcode DBAddSet(fix->oldelt);
6679ac52343Sopcode e1 = fix->dbase;
6689ac52343Sopcode
6699ac52343Sopcode while (*e1 != fix->newelt) { /* find elt to replace */
6709ac52343Sopcode e1 = &(DBNextElt((*e1)));
6719ac52343Sopcode }
6729ac52343Sopcode
6739ac52343Sopcode fix->oldelt->nextelt = DBNextElt((*e1));
6749ac52343Sopcode *e1 = fix->oldelt;
6759ac52343Sopcode fix->oldelt = fix->newelt;
6769ac52343Sopcode fix->newelt = *e1; /* create undo unelt */
6779ac52343Sopcode temp = fix->nextun;
6789ac52343Sopcode fix->nextun = unlist;
6799ac52343Sopcode unlist = fix; /* link into unlist */
6809ac52343Sopcode fix = temp;
6819ac52343Sopcode break;
6829ac52343Sopcode }
6839ac52343Sopcode }
6849ac52343Sopcode } /* end LGUndo */
6859ac52343Sopcode
6869ac52343Sopcode
6879ac52343Sopcode /*
6889ac52343Sopcode * Write elements from elist to filename.
6899ac52343Sopcode * If setonly is true, elements are taken from the "setnext"
6909ac52343Sopcode * pointer; otherwise, elements are taken from "nextelt".
6919ac52343Sopcode * Ie., the current set is written with setonly = TRUE and
6929ac52343Sopcode * the complete picture is written with setonly = FALSE.
6939ac52343Sopcode */
6949ac52343Sopcode static
LGWriteSet(elist,filename,setonly)6959ac52343Sopcode LGWriteSet(elist, filename, setonly)
6969ac52343Sopcode ELT *elist;
6979ac52343Sopcode char *filename;
6989ac52343Sopcode int setonly;
6999ac52343Sopcode {
7009ac52343Sopcode FILE *fp;
7019ac52343Sopcode POINT *plist, pos;
7029ac52343Sopcode char string[256];
7039ac52343Sopcode
7049ac52343Sopcode fp = fopen(filename, "w");
7059ac52343Sopcode if (fp == NULL) {
7069ac52343Sopcode (void) sprintf(string, "can't open %s", filename);
7079ac52343Sopcode error(string);
7089ac52343Sopcode return;
7099ac52343Sopcode }
7109ac52343Sopcode
7119ac52343Sopcode TxPutMsg("writing file...");
7129ac52343Sopcode UNForget();
7139ac52343Sopcode CHANGED = FALSE;
7149ac52343Sopcode
7159ac52343Sopcode if (SEQ > 0) { /* specified a positioning point */
7169ac52343Sopcode pos.x = POINTLIST->x;
7179ac52343Sopcode pos.y = POINTLIST->y;
7189ac52343Sopcode }
7199ac52343Sopcode else {
7209ac52343Sopcode if (!DBNullelt(elist)) {
7219ac52343Sopcode pos.x = elist->ptlist->x;
7229ac52343Sopcode pos.y = elist->ptlist->y;
7239ac52343Sopcode }
7249ac52343Sopcode else {
7259ac52343Sopcode pos.x = pos.y = 0.0;
7269ac52343Sopcode }
7279ac52343Sopcode }
7289ac52343Sopcode
7299ac52343Sopcode if (newfileformat)
7309ac52343Sopcode fprintf(fp, "sungremlinfile\n"); /* write header */
7319ac52343Sopcode else
7329ac52343Sopcode fprintf(fp, "gremlinfile\n"); /* write header */
7339ac52343Sopcode fprintf(fp, "%d %1.2f %1.2f\n", Orientation, pos.x, pos.y);
7349ac52343Sopcode
7359ac52343Sopcode while (!DBNullelt(elist)) { /* write each element */
7369ac52343Sopcode if (newfileformat)
7379ac52343Sopcode fprintf(fp, "%s\n", eltnames[elist->type]);
7389ac52343Sopcode else
7399ac52343Sopcode fprintf(fp, "%d\n", elist->type);
7409ac52343Sopcode
7419ac52343Sopcode plist = elist->ptlist;
7429ac52343Sopcode
7439ac52343Sopcode while (!Nullpoint(plist)) { /* write each point */
7449ac52343Sopcode fprintf(fp, "%1.2f %1.2f\n", plist->x, plist->y);
7459ac52343Sopcode plist = PTNextPoint(plist);
7469ac52343Sopcode }
7479ac52343Sopcode
7489ac52343Sopcode if (newfileformat)
7499ac52343Sopcode fprintf(fp, "*\n"); /* end pointlist */
7509ac52343Sopcode else
7519ac52343Sopcode fprintf(fp, "-1.00 -1.00\n"); /* end pointlist */
7529ac52343Sopcode
7539ac52343Sopcode fprintf(fp, "%d %d\n", elist->brushf, elist->size);
7549ac52343Sopcode fprintf(fp,"%d %s\n", strlen(elist->textpt), elist->textpt);
7559ac52343Sopcode elist = setonly ? DBNextofSet(elist) : DBNextElt(elist);
7569ac52343Sopcode }
7579ac52343Sopcode fprintf(fp, "-1\n");
7589ac52343Sopcode
7599ac52343Sopcode (void) fclose(fp);
7609ac52343Sopcode TxMsgOK();
7619ac52343Sopcode TxKillLine();
7629ac52343Sopcode CP();
7639ac52343Sopcode } /* end LGWriteSet */
7649ac52343Sopcode
7659ac52343Sopcode
7669ac52343Sopcode /*
7679ac52343Sopcode * This routine writes the current set into the specified filename
7689ac52343Sopcode */
LGSave()7699ac52343Sopcode LGSave()
7709ac52343Sopcode {
7719ac52343Sopcode FILE *fp;
7729ac52343Sopcode char tname[TEXT_BUFMAX], filename[TEXT_BUFMAX], *tn, *fn;
7739ac52343Sopcode int space, stat;
7749ac52343Sopcode
7759ac52343Sopcode space = TEXT_BUFMAX;
7769ac52343Sopcode text_getvalue(&tname[0]);
7779ac52343Sopcode tn = tname;
7789ac52343Sopcode fn = filename;
7799ac52343Sopcode
7809ac52343Sopcode if (*tname == '\0') {
7819ac52343Sopcode error("write to where?");
7829ac52343Sopcode return;
7839ac52343Sopcode }
7849ac52343Sopcode
7859ac52343Sopcode stat = PConvertTilde(&tn, &fn, &space);
7869ac52343Sopcode *fn = '\0';
7879ac52343Sopcode
7889ac52343Sopcode if (stat == FALSE) {
7899ac52343Sopcode sprintf(filename, "unknown path %s", tname);
7909ac52343Sopcode error(filename);
7919ac52343Sopcode return;
7929ac52343Sopcode }
7939ac52343Sopcode
7949ac52343Sopcode fp = fopen(filename, "r");
7959ac52343Sopcode if (fp != NULL) {
7969ac52343Sopcode if (!prompt_ok(menu_fd, filexists_msg)) {
7979ac52343Sopcode fclose(fp);
7989ac52343Sopcode return;
7999ac52343Sopcode }
8009ac52343Sopcode else
8019ac52343Sopcode fclose(fp);
8029ac52343Sopcode }
8039ac52343Sopcode
8049ac52343Sopcode LGWriteSet(cset, filename, TRUE);
8059ac52343Sopcode } /* end LGSave */;
8069ac52343Sopcode
8079ac52343Sopcode
8089ac52343Sopcode /*
8099ac52343Sopcode * This routine writes the current PICTURE into the specified filename
8109ac52343Sopcode * or to the current Editfile
8119ac52343Sopcode */
LGWrite()8129ac52343Sopcode LGWrite()
8139ac52343Sopcode {
8149ac52343Sopcode FILE *fp;
8159ac52343Sopcode char tname[TEXT_BUFMAX], filename[TEXT_BUFMAX], *tn, *fn;
8169ac52343Sopcode int space, stat;
8179ac52343Sopcode
8189ac52343Sopcode space = TEXT_BUFMAX;
8199ac52343Sopcode text_getvalue(&tname[0]);
8209ac52343Sopcode tn = tname;
8219ac52343Sopcode fn = filename;
8229ac52343Sopcode
8239ac52343Sopcode if (tname[0] == '\0') {
8249ac52343Sopcode if (Editfile[0] == '\0') {
8259ac52343Sopcode error("write to where?");
8269ac52343Sopcode return;
8279ac52343Sopcode }
8289ac52343Sopcode strcpy(filename, Editfile);
8299ac52343Sopcode }
8309ac52343Sopcode else {
8319ac52343Sopcode stat = PConvertTilde(&tn, &fn, &space);
8329ac52343Sopcode *fn = '\0';
8339ac52343Sopcode if (stat == FALSE) {
8349ac52343Sopcode sprintf(filename, "unknown path %s", tname);
8359ac52343Sopcode error(filename);
8369ac52343Sopcode return;
8379ac52343Sopcode }
8389ac52343Sopcode fp = fopen(filename, "r");
8399ac52343Sopcode if (fp != NULL) {
8409ac52343Sopcode if (!prompt_ok(menu_fd, filexists_msg)) {
8419ac52343Sopcode fclose(fp);
8429ac52343Sopcode return;
8439ac52343Sopcode }
8449ac52343Sopcode else
8459ac52343Sopcode fclose(fp);
8469ac52343Sopcode }
8479ac52343Sopcode }
8489ac52343Sopcode
8499ac52343Sopcode LGWriteSet(PICTURE, filename, FALSE);
8509ac52343Sopcode } /* end LGWrite */;
8519ac52343Sopcode
8529ac52343Sopcode
8539ac52343Sopcode /*
8549ac52343Sopcode * This routine terminates the editor. The terminal states for the text
8559ac52343Sopcode * terminal and the graphics display are restored and an EXIT is performed.
8569ac52343Sopcode */
LGQuit()8579ac52343Sopcode LGQuit()
8589ac52343Sopcode {
8599ac52343Sopcode if (prompt_ok(tool_fd, CHANGED ? quit_msg : quit2_msg))
8609ac52343Sopcode exit(0);
8619ac52343Sopcode } /* end LGQuit */
8629ac52343Sopcode
8639ac52343Sopcode
8649ac52343Sopcode /*
8659ac52343Sopcode * Horizontal Adjust -
8669ac52343Sopcode * This routine toggles the adjustment mode.
8679ac52343Sopcode */
LGHAdjust()8689ac52343Sopcode LGHAdjust()
8699ac52343Sopcode {
8709ac52343Sopcode if (Adjustment == HORZ) {
8719ac52343Sopcode MNUnHighLt(HiMode[adj[HORZ]]);
8729ac52343Sopcode Adjustment = NOADJ;
8739ac52343Sopcode }
8749ac52343Sopcode else {
8759ac52343Sopcode if (Adjustment != NOADJ)
8769ac52343Sopcode MNUnHighLt(HiMode[adj[Adjustment]]);
8779ac52343Sopcode MNHighLt(HiMode[adj[HORZ]]);
8789ac52343Sopcode Adjustment = HORZ;
8799ac52343Sopcode }
8809ac52343Sopcode } /* end LGHAdjust */
8819ac52343Sopcode
8829ac52343Sopcode
8839ac52343Sopcode /*
8849ac52343Sopcode * Vertical Adjust -
8859ac52343Sopcode * This routine toggles the adjustment mode.
8869ac52343Sopcode */
LGVAdjust()8879ac52343Sopcode LGVAdjust()
8889ac52343Sopcode {
8899ac52343Sopcode if (Adjustment == VERT) {
8909ac52343Sopcode MNUnHighLt(HiMode[adj[VERT]]);
8919ac52343Sopcode Adjustment = NOADJ;
8929ac52343Sopcode }
8939ac52343Sopcode else {
8949ac52343Sopcode if (Adjustment != NOADJ)
8959ac52343Sopcode MNUnHighLt(HiMode[adj[Adjustment]]);
8969ac52343Sopcode MNHighLt(HiMode[adj[VERT]]);
8979ac52343Sopcode Adjustment = VERT;
8989ac52343Sopcode }
8999ac52343Sopcode } /* end LGVAdjust */
9009ac52343Sopcode
9019ac52343Sopcode
9029ac52343Sopcode /*
9039ac52343Sopcode * This local routine returns 1 if x >= 0
9049ac52343Sopcode * otherwise returns -1
9059ac52343Sopcode */
9069ac52343Sopcode static
sign(x)9079ac52343Sopcode sign(x)
9089ac52343Sopcode float x;
9099ac52343Sopcode {
9109ac52343Sopcode return((x >= 0) ? 1 : -1);
9119ac52343Sopcode }
9129ac52343Sopcode
9139ac52343Sopcode
9149ac52343Sopcode /*
9159ac52343Sopcode * This routine is called by all mirroring routines to effect the
9169ac52343Sopcode * transformation specified by xmat.
9179ac52343Sopcode */
9189ac52343Sopcode static
mirror(xmat)9199ac52343Sopcode mirror(xmat)
9209ac52343Sopcode float xmat[3][2];
9219ac52343Sopcode {
9229ac52343Sopcode register ELT *elt;
9239ac52343Sopcode POINT pt, pos, *p1, *p2;
9249ac52343Sopcode int i, j;
9259ac52343Sopcode
9269ac52343Sopcode UNForget();
9279ac52343Sopcode elt = cset;
9289ac52343Sopcode CSP();
9299ac52343Sopcode
9309ac52343Sopcode while (!DBNullelt(elt)) {
9319ac52343Sopcode DISScreenErase(elt, pixmask | csetmask);
9329ac52343Sopcode TxMsgOK();
9339ac52343Sopcode DBXform(elt, xmat, &PICTURE);
9349ac52343Sopcode if (TEXT(elt->type)) {
9359ac52343Sopcode GRSetTextPos(elt->textpt, elt->type, elt->brushf, elt->size,
9369ac52343Sopcode elt->ptlist, &pos);
9379ac52343Sopcode elt->ptlist = PTMakeTextPoints(elt->textpt, elt->brushf, elt->size,
9389ac52343Sopcode elt->ptlist, &pos);
9399ac52343Sopcode DISScreenAdd(elt, pixmask | csetmask);
9409ac52343Sopcode }
9419ac52343Sopcode else {
9429ac52343Sopcode if ((elt->type == ARC) && (elt->size > 0) &&
9439ac52343Sopcode (xmat[0][0] * xmat[1][1] < 0)) {
9449ac52343Sopcode /* arcs require special handling */
9459ac52343Sopcode /* but, circles OK and mirror in both directions OK */
9469ac52343Sopcode /* otherwise, swap starting and ending points of arc */
9479ac52343Sopcode p1 = PTNextPoint(elt->ptlist);
9489ac52343Sopcode p2 = PTNextPoint(p1);
9499ac52343Sopcode pt.x = p1->x;
9509ac52343Sopcode pt.y = p1->y;
9519ac52343Sopcode p1->x = p2->x;
9529ac52343Sopcode p1->y = p2->y;
9539ac52343Sopcode p2->x = pt.x;
9549ac52343Sopcode p2->y = pt.y;
9559ac52343Sopcode }
9569ac52343Sopcode DISScreenAdd(elt, pixmask | csetmask);
9579ac52343Sopcode }
9589ac52343Sopcode elt = DBNextofSet(elt);
9599ac52343Sopcode }
9609ac52343Sopcode CP();
9619ac52343Sopcode } /* end mirror */
9629ac52343Sopcode
9639ac52343Sopcode
9649ac52343Sopcode /*
9659ac52343Sopcode * This routine mirrors the elements in the current set VERTICALLY
9669ac52343Sopcode * The mirroring is accomplished by defining a transformation
9679ac52343Sopcode * matrix and calling DBXform.
9689ac52343Sopcode */
LGVMirror()9699ac52343Sopcode LGVMirror()
9709ac52343Sopcode {
9719ac52343Sopcode float xmat[3][2];
9729ac52343Sopcode
9739ac52343Sopcode if (SEQ < 1) { /* not enough points */
9749ac52343Sopcode error("not enough points");
9759ac52343Sopcode return;
9769ac52343Sopcode }
9779ac52343Sopcode
9789ac52343Sopcode if (DBNullelt(cset)) {
9799ac52343Sopcode error("no current set");
9809ac52343Sopcode return;
9819ac52343Sopcode }
9829ac52343Sopcode
9839ac52343Sopcode /* create transformation matrix to translate set to origin,
9849ac52343Sopcode perform the mirroring and translate back */
9859ac52343Sopcode
9869ac52343Sopcode xmat[0][0] = -1.0;
9879ac52343Sopcode xmat[1][1] = 1.0;
9889ac52343Sopcode xmat[1][0] = xmat[0][1] = xmat[2][1] = 0.0;
9899ac52343Sopcode xmat[2][0] = 2.0 * POINTLIST->x;
9909ac52343Sopcode
9919ac52343Sopcode mirror(xmat);
9929ac52343Sopcode CHANGED = TRUE;
9939ac52343Sopcode } /* end LGVMirror */
9949ac52343Sopcode
9959ac52343Sopcode
9969ac52343Sopcode /*
9979ac52343Sopcode * This routine mirrors the elements in the current set HORIZONTALLY
9989ac52343Sopcode * The mirroring is accomplished by defining a transformation
9999ac52343Sopcode * matrix and calling DBXform.
10009ac52343Sopcode */
LGHMirror()10019ac52343Sopcode LGHMirror()
10029ac52343Sopcode {
10039ac52343Sopcode float xmat[3][2];
10049ac52343Sopcode
10059ac52343Sopcode if (SEQ < 1) { /* not enough points */
10069ac52343Sopcode error("not enough points");
10079ac52343Sopcode return;
10089ac52343Sopcode }
10099ac52343Sopcode
10109ac52343Sopcode if (DBNullelt(cset)) {
10119ac52343Sopcode error("no current set");
10129ac52343Sopcode return;
10139ac52343Sopcode }
10149ac52343Sopcode
10159ac52343Sopcode /* create transformation matrix to translate set to origin,
10169ac52343Sopcode perform the mirroring and translate back */
10179ac52343Sopcode
10189ac52343Sopcode xmat[0][0] = 1.0;
10199ac52343Sopcode xmat[1][1] = -1.0;
10209ac52343Sopcode xmat[1][0] = xmat[0][1] = xmat[2][0] = 0.0;
10219ac52343Sopcode xmat[2][1] = 2.0 * POINTLIST->y;
10229ac52343Sopcode
10239ac52343Sopcode mirror(xmat);
10249ac52343Sopcode CHANGED = TRUE;
10259ac52343Sopcode } /* end LGHMirror */
10269ac52343Sopcode
10279ac52343Sopcode
10289ac52343Sopcode /*
10299ac52343Sopcode * This routine looks at the command line for parameters to set
10309ac52343Sopcode * the current search path.
10319ac52343Sopcode */
LGPath()10329ac52343Sopcode LGPath()
10339ac52343Sopcode {
10349ac52343Sopcode char buf[TEXT_BUFMAX];
10359ac52343Sopcode char buf2[TEXT_BUFMAX];
10369ac52343Sopcode register i, i2;
10379ac52343Sopcode
10389ac52343Sopcode i = i2 = -1;
10399ac52343Sopcode text_getvalue(&buf[0]);
10409ac52343Sopcode while (buf[++i]) {
10419ac52343Sopcode if (buf[i] != ' ')
10429ac52343Sopcode buf2[++i2] = buf[i];
10439ac52343Sopcode }
10449ac52343Sopcode buf2[++i2] = '\0';
10459ac52343Sopcode
10469ac52343Sopcode if (*buf2 == '\0')
10479ac52343Sopcode TxPutMsg(PGetPath()); /* no arguments */
10489ac52343Sopcode else {
10499ac52343Sopcode SEARCH = TRUE;
10509ac52343Sopcode PSetPath(buf2);
10519ac52343Sopcode }
10529ac52343Sopcode
10539ac52343Sopcode TxKillLine();
10549ac52343Sopcode } /* end LGPath */
10559ac52343Sopcode
10569ac52343Sopcode
1057*b3593ea1Sopcode /*
1058*b3593ea1Sopcode * Sometimes it's important to do nothing.
1059*b3593ea1Sopcode */
nop()10609ac52343Sopcode nop()
10619ac52343Sopcode {
10629ac52343Sopcode }
1063