From 1acf8029313100d93bc1cf097a2cdca70c4b5fdf Mon Sep 17 00:00:00 2001 From: Dave Slattengren Date: Mon, 18 Apr 1983 20:45:43 -0800 Subject: [PATCH] date and time created 83/04/18 13:45:43 by slatteng SCCS-vsn: local/ditroff/ditroff.old.okeeffe/gremlin.aed/gremlin/long2.c 1.1 --- .../gremlin.aed/gremlin/long2.c | 843 ++++++++++++++++++ 1 file changed, 843 insertions(+) create mode 100644 usr/src/local/ditroff/ditroff.old.okeeffe/gremlin.aed/gremlin/long2.c diff --git a/usr/src/local/ditroff/ditroff.old.okeeffe/gremlin.aed/gremlin/long2.c b/usr/src/local/ditroff/ditroff.old.okeeffe/gremlin.aed/gremlin/long2.c new file mode 100644 index 0000000000..232c2da0c4 --- /dev/null +++ b/usr/src/local/ditroff/ditroff.old.okeeffe/gremlin.aed/gremlin/long2.c @@ -0,0 +1,843 @@ + + +/* long2.c - + * + * Copyright -C- 1982 Barry S. Roitblat + * + * + * This file contains routines to implement the long text commands + * of the gremlin PICTURE editor. + * + */ + +#include "gremlin.h" +#include "grem2.h" +#include + +/* imports from graphics files */ + +extern GRVector(), GRArc(), GRPutText(), GRClose(); +extern GRDisplayPoint(), GRDeletePoint(), GRBlankPoints(); +extern charxsize, charysize, GrXMax, GrYMax; + +/* import from path.c */ + +extern int PSetPath(), PConvertTilde(); +extern char *PGetPath(); + +/* imports from display.c */ + +extern DISScreenAdd(), DISScreenErase(); +extern DISDisplaySet(), DISEraseSet(), DISClearSetDisplay(); + +/* imports from database files */ + +extern ELT *DBInit(), *DBCreateElt(), *DBRead(); +extern DBDelete(), DBGravitate(), DBClearElt(); +extern ELT *DBCopy(); +extern DBXform(), DBChangeBrush(); +extern DBAddSet(), DBClearSet(); +extern POINT *PTInit(), *PTMakePoint(); +extern PTDeletePoint(); + +/* imports from undodb.c */ + +extern UNELT *unlist, *unback; +extern UNForget(); + +/* imports from short.c */ + +extern SHUpdate(); +extern int adj[]; + +/* imports from textio.c */ + +extern TxPutString(), TxPutMsg(), TxMsgOK(), TxClose(); +extern TXFIELD TAlign, TAdjust, TBrush, TFont, TGravity, TCSize; +extern TEdit, TJustmode; + +/* imports from menu.c */ + +extern MNHighLt(), MNUnHighLt(); +extern HiMen[], HiFont[], HiBrush[], HiMode[]; + +/* imports from c */ + +extern char *malloc(); +extern char *strcpy(), *sprintf(); + +/* imports from main.c */ + +extern ELT *PICTURE; /* current PICTURE database */ +extern ELT *cset; /* current set database */ +extern CBRUSH, CSIZE, CFONT; /* current brush, size, font */ +extern CJUST; /* current text justification */ +extern Gridon; /* grid mode flag */ +extern Orientation; /* orientation of workspace */ +extern SEARCH; /* flag for path search */ +extern Alignment; /* point alignment indicator */ +extern float PX, PY; /* cursor coordinates */ +extern float Lastx, Lasty; /* previous cursor coordinates */ +extern SEQ; /* point sequence number */ +extern POINT *POINTLIST, *BACKPOINT;/* accumulated point list */ +extern Gridsize; /* grid spacing */ +extern Adjustment; /* point adjustment mode */ +extern GravityOn; /* gravity mode flag */ +extern Consume; /* point clear flag */ +extern CHANGED; /* PICTURE changed flag */ +extern ELT *MEN[]; /* pointers for user symbols */ +extern POINT MENPOINT[]; /* pointers used fo user symbols */ +extern cmdbuf[]; /* line buffer for commands */ +extern char *textpos[], *dispmode[];/* text positioning modes */ +extern int textmode[]; /* text positioning */ +extern char *lines[], *fonts[]; /* line and character styles */ +extern int jmodes, lnum[], fnum[]; + +/* imports from long1.c */ +extern bang; +extern GetNumParm(); +extern LGLookup(); +extern SetOrient(); + +char *Editfile; + +#define BADNUM -1 +#define NONUM -2 +#define Delimiter(c) ((c == '\0') || (c == ' ') || (c == ',')) + +static char badarg[10] = "bad args"; + + +LGFont(line) +char *line; +/* + * This routine looks at the command line for parameters to set + * the current Font. + */ + +{ + int new, index; + char string[2]; + + Consume = FALSE; + index = 0; + if (isalpha(*(++line))) + { + new = LGLookup(line, fonts, &index); + if ( new >= 0) new = fnum[new]; + else new = BADNUM; + } + else new = GetNumParm(line, &index); + if ( (new == BADNUM) || (new > NFONTS) ) + { + error(badarg); + return; + } + if (new != NONUM) + { + MNUnHighLt(HiFont[CFONT-1]); + MNHighLt(HiFont[new-1], hicolor); + CFONT = new; + (void) sprintf(string, "%1d",new); + TxPutString(&TFont,string); + } +} /* end LGFont */ + + +LGJust(line) +char *line; +/* + * This routine looks at the command line for parameters to set + * the current text justification mode. + */ + +{ + int new, index; + + Consume = FALSE; + index = 0; + if (isalpha(*(++line))) + { + /* make sure mode is in lower case, and look up in table */ + if (isupper(*line)) + { + *line = tolower(*line); + *(line+1) = tolower(*(line+1)); + } + for (new = 0; (strcmp(line, textpos[new]) != 0); ++new) + if (new > jmodes) + { + error("no such mode"); + return; + } + if ( new < 0) new = BADNUM; + } + else new = GetNumParm(line, &index) - 1; + if ( (new <= BADNUM) || (new > jmodes) ) + { + error(badarg); + return; + } + if (new != NONUM) + { + new = textmode[new]; + CJUST = new; + TxPutString(&TJustmode,dispmode[new]); + } +} /* end LGJust */ + + +LGSize(line) +char *line; +/* + * This routine changes the current character size. + */ + +{ + int new, index; + char string[2]; + + index = 1; + new = GetNumParm(line, &index); + if ( (new == BADNUM) || (new > NSIZES) ) + { + error(badarg); + return; + } + if (new != NONUM) + { + CSIZE = new; + (void) sprintf(string, "%1d",new); + TxPutString(&TCSize,string); + } + Consume = FALSE; +} /* end LGSize */ + +LGAlign(line) +char *line; +/* + * This routine sets the point alignment indicator + */ + +{ + int newalign, index; + char string[4]; + + index = 1; + newalign = GetNumParm(line, &index); + if (newalign == NONUM) + if (Alignment == 1) Alignment = Gridsize; + else Alignment = 1; + else + { + if ((newalign < 1) || (newalign > GrYMax/2) ) + { + error(badarg); + return; + } + Alignment = newalign; + } + (void) sprintf(string, "%3d",Alignment); + TxPutString(&TAlign,string); + Consume = FALSE; +} /* end LGAlign */ + + +LGIncludeSet(line) +char *line; +/* + * This routine adds all elements selected by points in POINTLIST + * to the current set. It does not remove previously selected elements. + * + */ + +{ + POINT *p1, *p2; + ELT *e1; + float n1, n2; + + if (DBNullelt(PICTURE)) return; + if (SEQ == 0) /* no points: entire picture becomes */ + { /* current set */ + e1 = PICTURE; + while ( !DBNullelt(e1) ) + { + DBAddSet(e1); + DISDisplaySet(e1); + e1 = DBNextElt(e1); + } + } /* end if */ + else + { + p1 = POINTLIST; + while ( !Nullpoint(p1) ) + { + DBGravitate(p1->x, p1->y, &n1, &n2, &p2, &e1, PICTURE); + if ( !DBNullelt(e1) ) + { + DBAddSet(e1); + DISDisplaySet(e1); + } + p1 = PTNextPoint(p1); + } /* end while */; + } /* end else */ +} /* end LGIncludeSet */ + + + +LGMenu(line) +char *line; +/* + * This routine implements the menu command. The contents of + * the specified user menu item is copied into the PICTURE transformed + * to the positioning point. + */ + +{ + + ELT *elist, *e1; + POINT *plist; + int symbol, index; + float xmat[3][2]; + + if (SEQ < 1) + { + error("no positioning point"); + return; + } + index = 1; + symbol = GetNumParm(line, &index); + if ( (symbol <= 0) || (symbol > NUSER) ) + { + error(badarg); + return; + } + symbol--; /* users inputs number between 1 and N, actual + symbol number is between 0 and N-1 */ + xmat[0][0] = xmat[1][1] = 1; /* create transformation matrix */ + xmat[0][1] = xmat[1][0] = 0; /* for copy into PICTURE */ + plist = POINTLIST; + while ( !Nullpoint(plist) ) + { + DISClearSetDisplay(); /* Clear old current set */ + DBClearSet(); + xmat[2][0] = plist->x - (MENPOINT[symbol]).x; + xmat[2][1] = plist->y - (MENPOINT[symbol]).y; + elist = MEN[symbol]; + while ( !DBNullelt(elist) ) /* copy buffer to picture */ + { + e1 = DBCopy(elist, xmat, &PICTURE); + DBAddSet(e1); + DISScreenAdd(e1, (linemask | setmask)); + elist = DBNextElt(elist); + } /* end while */ + plist = PTNextPoint(plist); + } /* end while */ + CHANGED = TRUE; +} /* end LGMenu */ + + +LGRead(line) +char *line; +/* + * This routine reads in the specified filename (command line) to the + * selected user symbol or current set if no user symbol is selected. If + * no filename is specified, the current set is copied to the user symbol; + */ + +{ + POINT pos, ppos; + ELT *elist, *e1; + char tname[50], filename[100]; + float xmat[3][2]; + int i, orient; + + if ( *line == '\0' ) /* no arguments */ + { + error(badarg); + return; + } + ++line; + (void) sscanf(line, "%s", tname); + elist = DBRead(tname, &orient, &pos); /* read file */ + UNForget(); /* forget changes registered by DBRead */ + if (SEQ < 1) /* no positioning point */ + { + ppos.x = pos.x; + ppos.y = pos.y; + } + else + { + ppos.x = POINTLIST->x; + ppos.y = POINTLIST->y; + } + xmat[0][0] = xmat[1][1] = 1; /* set up matrix to copy to */ + xmat[0][1] = xmat[1][0] = 0; /* appropriate place in */ + xmat[2][0] = ppos.x - pos.x; /* picture as current set */ + xmat[2][1] = ppos.y - pos.y; + DBClearSet(); + DISClearSetDisplay(); + while ( !DBNullelt(elist) ) + { + e1 = DBCopy(elist, xmat, &PICTURE); + DISScreenAdd(e1, (linemask | setmask)); + DBAddSet(e1); + e1 = DBNextElt(elist); + DBClearElt(elist); + elist = e1; + } + CHANGED = TRUE; +} /* end LGRead */ + + +LGEdit(line) +char *line; +/* + * This routine reads in a new PICTURE for editing + */ + +{ + FILE *fp, *POpen(); + POINT pos; + ELT *e1; + char *tn, tname[50]; + int i; + + if (!bang) /* no ! */ + { + if (CHANGED) + { + error("no write"); + return; + } + } /* end if !bang */; + DBClearSet(); + while ( !DBNullelt(PICTURE) ) /* clear current PICTURE */ + { + e1 = DBNextElt(PICTURE); + DBClearElt(PICTURE); + PICTURE = e1; + }; + ++line; + tn = tname; + (void) sscanf(line, "%s", tname); + + POINTLIST = PTInit(); /* Initialize globals */ + SEQ = 0; + CHANGED = FALSE; + + i = strlen(tname); + if (i > 0) /* filename present */ + { + fp = POpen(tname, (char **) NULL, SEARCH); + TxPutString(&TEdit, tname); + if (fp == NULL) + { + PICTURE = DBInit(); + error(" (creating new file)"); + } + else + { + PICTURE = DBRead(tname, &Orientation, &pos); + SetOrient(Orientation); /* Set appropriate picture area + * orientation */ + } + (void) strcpy (Editfile, tname); + } + else + { + TxPutString(&TEdit, ""); + (void) strcpy(Editfile, ""); + } + unlist = unback = nullun; + CP(); + SHUpdate(); /* display new picture */ +} /* end LGEdit */ + +static restorepoints() + +/* This routine (re) displays the points in the back-up pointlist + */ +{ + + int i; + POINT *plist, *pl1, *pl2; + + GRBlankPoints(); + plist = BACKPOINT; + for (i=0; !Nullpoint(plist); ++i) + { + Lastx = plist->x; + Lasty = plist->y; + GRDisplayPoint( (int) plist->x, (int) plist->y, i, pointstyle ); + plist = PTNextPoint(plist); + } + pl1 = POINTLIST; + POINTLIST = BACKPOINT; + SEQ = i; + BACKPOINT = pl1; +} /* end restorepoints */ + + +LGUndo(line) +char *line; +/* + * This routine uses the information in the undo database to reconstruct + * the PICTURE as it was before the last command. The undo database is set + * so that the next undo would nullify this one. + * An undo of an Add is to delete the new element. + * Add the old element back to undo a delete. + * Modified elements are undone by copying the old element into the database + * in place of the modified element. + */ + +{ + UNELT *fix, *temp; + ELT *(*e1); + + fix = unlist; /* initialize unlist so that undo-ing can */ + unlist = nullun; /* add items to properly undo the undo */ + if (fix == nullun) + { + fix = unback; + unback = nullun; + } + DBClearSet(); + DISClearSetDisplay(); + GRBlankPoints(); + while (fix != nullun) + { + switch (fix->action) + { + case ADD: DISScreenErase(fix->newelt, linemask); + TxMsgOK(); + restorepoints(); + DBDelete(fix->newelt, fix->dbase); + temp = fix->nextun; + free((char *) fix); + fix = temp; + break; + + case DELETE: fix->action = ADD; /* create undo unelt */ + fix->newelt = fix->oldelt; + fix->oldelt = NULL; + fix->newelt->nextelt = PICTURE; + restorepoints(); + DBAddSet(fix->newelt); + DISScreenAdd(fix->newelt,(linemask|setmask)); + PICTURE = fix->newelt; /* put in database */ + temp = fix->nextun; + fix->nextun = unlist; /* link into unlist */ + unlist = fix; + fix = temp; + break; + + case MOD: DISScreenErase(fix->newelt, linemask); + TxMsgOK(); + restorepoints(); + DISScreenAdd(fix->oldelt, (setmask | linemask)); + DBAddSet(fix->oldelt); + e1 = fix->dbase; + while ( *e1 != fix->newelt ) + { /* find elt to replace */ + e1 = &(DBNextElt((*e1))); + } + fix->oldelt->nextelt = DBNextElt((*e1)); + *e1 = fix->oldelt; + fix->oldelt = fix->newelt; + fix->newelt = *e1; /* create undo unelt */ + temp = fix->nextun; + fix->nextun = unlist; + unlist = fix; /* link into unlist */ + fix = temp; + break; + + } /* end switch */; + } /* end while */ + Consume = FALSE; +} /* LGUndo */ + + +LGWrite(line) +char *line; +/* + * This routine writes the current PICTURE into the specified filename + * or to the current Editfile + */ + +{ + FILE *fp, *fopen(); + char tname[50], filename[100], string[100], *tn, *fn, *wfile; + ELT *elist; + POINT *plist, pos; + int i, space, stat; + + space = 100; + ++line; + tn = tname; fn = filename; + (void) sscanf(line, "%s", tname); + i = strlen(tname); + if (i == 0) /* no filename */ + { + if ( *Editfile == '\0' ) + { + error("write to where?"); + return; + } + fp = fopen(Editfile, "w"); + wfile = Editfile; + } + else + { + stat = PConvertTilde(&tn, &fn, &space); + *fn = '\0'; + if (stat == FALSE) + { + sprintf(string, "unknown path %s", tname); + error(string); + return; + } + if ( !bang ) /* user doesn't insist */ + { + fp = fopen(filename, "r"); + if ( fp != NULL ) + { + error("file already exists"); + return; + } + } + fp = fopen(filename, "w"); + wfile = filename; + }; + if (fp == NULL) /* file error */ + { + (void) sprintf(string,"can't open %s", wfile); + error(string); + return; + }; + TxPutMsg("writing file..."); + CHANGED = FALSE; + if (SEQ > 0) /* specified a positioning point */ + { + pos.x = POINTLIST->x; + pos.y = POINTLIST->y; + } + else + { + if ( !DBNullelt(PICTURE) ) + { + pos.x = PICTURE->ptlist->x; + pos.y = PICTURE->ptlist->y; + } + else + { + pos.x = pos.y = 0; + }; + } + fprintf(fp,"gremlinfile\n"); /* write header */ + fprintf(fp, "%d %1.2f %1.2f\n", Orientation, pos.x, pos.y); + elist = PICTURE; + while ( !DBNullelt(elist) ) /* write each element */ + { + fprintf(fp, "%d\n", elist->type); + plist = elist->ptlist; + while ( !Nullpoint(plist) ) /* write each point */ + { + fprintf(fp, "%1.2f %1.2f\n",plist->x, plist->y); + plist = PTNextPoint(plist); + } /* end while plist */ + fprintf(fp, "%1.2f %1.2f\n", -1.0, -1.0); /* end pointlist */ + fprintf(fp, "%d %d\n",elist->brushf, elist->size); + fprintf(fp,"%d %s\n ", strlen(elist->textpt), elist->textpt); + elist = DBNextElt(elist); + } /* end while */ + fprintf(fp,"%d\n",-1); /* end of element list */ + TxMsgOK(); + (void) fclose(fp); +} /* end LGWrite */; + + +LGQuit(line) +char *line; +/* + * This routine terminates the editor. The terminal states for the text + * terminal and the graphics display are restored and an EXIT is performed. + */ + +{ + if (!bang) + { + if (CHANGED) + { + error("no write"); + return; + } + } /* end if */; + GRClose(); + TxClose(); + exit(0); +} /* end LGQuit */ + +LGHAdjust() +/* + * Horizontal adjust - + * This routine toggles the adjustment mode. + */ + +{ + if (Adjustment == HORZ) + { + MNUnHighLt(HiMode[adj[HORZ]]); + Adjustment = NOADJ; + TxPutString(&TAdjust, "NO ADJUSTMENT"); + } + else + { + MNUnHighLt(HiMode[adj[Adjustment]]); + MNHighLt(HiMode[adj[HORZ]], hicolor); + Adjustment = HORZ; + TxPutString(&TAdjust, " HORIZONTAL "); + } + Consume = FALSE; +} + + +LGVAdjust() +/* + * Vertical adjust - + * This routine toggles the adjustment mode. + */ + +{ + if (Adjustment == VERT) + { + MNUnHighLt(HiMode[adj[VERT]]); + Adjustment = NOADJ; + TxPutString(&TAdjust, "NO ADJUSTMENT"); + } + else + { + MNUnHighLt(HiMode[adj[Adjustment]]); + MNHighLt(HiMode[adj[VERT]], hicolor); + Adjustment = VERT; + TxPutString(&TAdjust, " VERTICAL "); + } + Consume = FALSE; +} + + + +static sign(x) +float x; +/* + * This local routine returns 1 if x >= 0 + * otherwise returns 0; + */ + +{ + if (x >= 0) return(1); + else return(0); +} + +LGMirror(line) +char *line; +/* + * This routine mirrors the elements in the current set as defined + * by points. The mirroring is accomplished by defining a transformation + * matrix and calling DBXform. + */ + +{ + ELT *e1; + POINT pt, pos, *p1, *p2; + float xmat[3][2], scalex, scaley; + int i, j; + + if (SEQ < 3) /* not enough points */ + { + error("not enough points"); + return; + } + if (DBNullelt(cset)) + { + error("no current set"); + return; + } + p1 = PTNextPoint(POINTLIST); + p2 = PTNextPoint(p1); + scalex = scaley = 1; + if (sign(p1->x - POINTLIST->x) != sign(p2->x - POINTLIST->x)) + scalex = -scalex; + if (sign(p1->y - POINTLIST->y) != sign(p2->y - POINTLIST->y)) + scaley = -scaley; + + /* create transformation matrix to translate set to origin, + performing the mirroring and translating back */ + + xmat[0][0] = scalex; + xmat[1][1] = scaley; + xmat[1][0] = xmat[0][1] = 0; + xmat[2][0] = - POINTLIST->x * (scalex - 1.0); + xmat[2][1] = - POINTLIST->y * (scaley - 1.0); + e1 = cset; + while ( !DBNullelt(e1) ) + { + DISScreenErase(e1, (linemask | setmask)); + TxMsgOK(); + DBXform(e1, xmat, &PICTURE); + if (TEXT(e1->type)) + { + GRsetwmask(textmask | setmask); + p1 = e1->ptlist; + GRPutText(e1->type, p1, e1->brushf, e1->size,e1->textpt, &pos); + i= strlen(e1->textpt); + p2 = PTInit(); + (void) PTMakePoint(p1->x, p1->y, &p2); + /* add extra positioning points */ + (void) PTMakePoint(pos.x, pos.y, &p2); + (void) PTMakePoint(pos.x + i * charxsize / 2, pos.y, &p2); + (void) PTMakePoint(pos.x + i * charxsize, pos.y, &p2); + e1->ptlist = p2; + } /* end if TEXT */ + else + { + if (e1->type == ARC) /* arcs require special handling */ + if (e1->size > 0) /* circles are OK */ + if (scalex * scaley < 0) /* both directions OK */ + { /* swap starting and ending points of arc */ + p1 = PTNextPoint(e1->ptlist); + p2 = PTNextPoint(p1); + pt.x = p1->x; + pt.y = p1->y; + p1->x = p2->x; + p1->y = p2->y; + p2->x = pt.x; + p2->y = pt.y; + } + DISScreenAdd(e1, (linemask | setmask)); + } /* end else */ + e1 = DBNextofSet(e1); + } /* end while */ + CHANGED = TRUE; +} /* end LGMirror */ + + +LGPath(line) +char *line; +/* + * This routine looks at the command line for parameters to set + * the current search path. + */ + +{ + char path[100]; + + if ( *line == '\0' ) TxPutMsg(PGetPath()); /* no arguments */ + else + { + SEARCH = TRUE; + (void) sscanf(line, "%s", path); + PSetPath(path); + } + Consume = FALSE; +} /* end LGFont */ -- 2.20.1