232c2da0c43bee219f5436053747a813e657403c
* Copyright -C- 1982 Barry S. Roitblat
* This file contains routines to implement the long text commands
* of the gremlin PICTURE editor.
/* imports from graphics files */
extern GRVector(), GRArc(), GRPutText(), GRClose();
extern GRDisplayPoint(), GRDeletePoint(), GRBlankPoints();
extern charxsize
, charysize
, GrXMax
, GrYMax
;
extern int PSetPath(), PConvertTilde();
/* 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 DBXform(), DBChangeBrush();
extern DBAddSet(), DBClearSet();
extern POINT
*PTInit(), *PTMakePoint();
/* imports from undodb.c */
extern UNELT
*unlist
, *unback
;
/* imports from short.c */
/* imports from textio.c */
extern TxPutString(), TxPutMsg(), TxMsgOK(), TxClose();
extern TXFIELD TAlign
, TAdjust
, TBrush
, TFont
, TGravity
, TCSize
;
/* imports from menu.c */
extern MNHighLt(), MNUnHighLt();
extern HiMen
[], HiFont
[], HiBrush
[], HiMode
[];
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 */
#define Delimiter(c) ((c == '\0') || (c == ' ') || (c == ','))
static char badarg
[10] = "bad args";
* This routine looks at the command line for parameters to set
new = LGLookup(line
, fonts
, &index
);
if ( new >= 0) new = fnum
[new];
else new = GetNumParm(line
, &index
);
if ( (new == BADNUM
) || (new > NFONTS
) )
MNUnHighLt(HiFont
[CFONT
-1]);
MNHighLt(HiFont
[new-1], hicolor
);
(void) sprintf(string
, "%1d",new);
TxPutString(&TFont
,string
);
* This routine looks at the command line for parameters to set
* the current text justification mode.
/* make sure mode is in lower case, and look up in table */
*(line
+1) = tolower(*(line
+1));
for (new = 0; (strcmp(line
, textpos
[new]) != 0); ++new)
if ( new < 0) new = BADNUM
;
else new = GetNumParm(line
, &index
) - 1;
if ( (new <= BADNUM
) || (new > jmodes
) )
TxPutString(&TJustmode
,dispmode
[new]);
* This routine changes the current character size.
new = GetNumParm(line
, &index
);
if ( (new == BADNUM
) || (new > NSIZES
) )
(void) sprintf(string
, "%1d",new);
TxPutString(&TCSize
,string
);
* This routine sets the point alignment indicator
newalign
= GetNumParm(line
, &index
);
if (Alignment
== 1) Alignment
= Gridsize
;
if ((newalign
< 1) || (newalign
> GrYMax
/2) )
(void) sprintf(string
, "%3d",Alignment
);
TxPutString(&TAlign
,string
);
* This routine adds all elements selected by points in POINTLIST
* to the current set. It does not remove previously selected elements.
if (DBNullelt(PICTURE
)) return;
if (SEQ
== 0) /* no points: entire picture becomes */
DBGravitate(p1
->x
, p1
->y
, &n1
, &n2
, &p2
, &e1
, PICTURE
);
* This routine implements the menu command. The contents of
* the specified user menu item is copied into the PICTURE transformed
* to the positioning point.
error("no positioning point");
symbol
= GetNumParm(line
, &index
);
if ( (symbol
<= 0) || (symbol
> NUSER
) )
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 */
while ( !Nullpoint(plist
) )
DISClearSetDisplay(); /* Clear old current set */
xmat
[2][0] = plist
->x
- (MENPOINT
[symbol
]).x
;
xmat
[2][1] = plist
->y
- (MENPOINT
[symbol
]).y
;
while ( !DBNullelt(elist
) ) /* copy buffer to picture */
e1
= DBCopy(elist
, xmat
, &PICTURE
);
DISScreenAdd(e1
, (linemask
| setmask
));
elist
= DBNextElt(elist
);
plist
= PTNextPoint(plist
);
* 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;
char tname
[50], filename
[100];
if ( *line
== '\0' ) /* no arguments */
(void) sscanf(line
, "%s", tname
);
elist
= DBRead(tname
, &orient
, &pos
); /* read file */
UNForget(); /* forget changes registered by DBRead */
if (SEQ
< 1) /* no positioning point */
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
;
while ( !DBNullelt(elist
) )
e1
= DBCopy(elist
, xmat
, &PICTURE
);
DISScreenAdd(e1
, (linemask
| setmask
));
* This routine reads in a new PICTURE for editing
while ( !DBNullelt(PICTURE
) ) /* clear current PICTURE */
(void) sscanf(line
, "%s", tname
);
POINTLIST
= PTInit(); /* Initialize globals */
if (i
> 0) /* filename present */
fp
= POpen(tname
, (char **) NULL
, SEARCH
);
TxPutString(&TEdit
, tname
);
error(" (creating new file)");
PICTURE
= DBRead(tname
, &Orientation
, &pos
);
SetOrient(Orientation
); /* Set appropriate picture area
(void) strcpy (Editfile
, tname
);
(void) strcpy(Editfile
, "");
unlist
= unback
= nullun
;
SHUpdate(); /* display new picture */
/* This routine (re) displays the points in the back-up pointlist
POINT
*plist
, *pl1
, *pl2
;
for (i
=0; !Nullpoint(plist
); ++i
)
GRDisplayPoint( (int) plist
->x
, (int) plist
->y
, i
, pointstyle
);
plist
= PTNextPoint(plist
);
} /* end restorepoints */
* 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.
fix
= unlist
; /* initialize unlist so that undo-ing can */
unlist
= nullun
; /* add items to properly undo the undo */
case ADD
: DISScreenErase(fix
->newelt
, linemask
);
DBDelete(fix
->newelt
, fix
->dbase
);
case DELETE
: fix
->action
= ADD
; /* create undo unelt */
fix
->newelt
= fix
->oldelt
;
fix
->newelt
->nextelt
= PICTURE
;
DISScreenAdd(fix
->newelt
,(linemask
|setmask
));
PICTURE
= fix
->newelt
; /* put in database */
fix
->nextun
= unlist
; /* link into unlist */
case MOD
: DISScreenErase(fix
->newelt
, linemask
);
DISScreenAdd(fix
->oldelt
, (setmask
| linemask
));
while ( *e1
!= fix
->newelt
)
{ /* find elt to replace */
e1
= &(DBNextElt((*e1
)));
fix
->oldelt
->nextelt
= DBNextElt((*e1
));
fix
->oldelt
= fix
->newelt
;
fix
->newelt
= *e1
; /* create undo unelt */
unlist
= fix
; /* link into unlist */
* This routine writes the current PICTURE into the specified filename
* or to the current Editfile
char tname
[50], filename
[100], string
[100], *tn
, *fn
, *wfile
;
tn
= tname
; fn
= filename
;
(void) sscanf(line
, "%s", tname
);
if (i
== 0) /* no filename */
error("write to where?");
fp
= fopen(Editfile
, "w");
stat
= PConvertTilde(&tn
, &fn
, &space
);
sprintf(string
, "unknown path %s", tname
);
if ( !bang
) /* user doesn't insist */
fp
= fopen(filename
, "r");
error("file already exists");
fp
= fopen(filename
, "w");
if (fp
== NULL
) /* file error */
(void) sprintf(string
,"can't open %s", wfile
);
TxPutMsg("writing file...");
if (SEQ
> 0) /* specified a positioning point */
if ( !DBNullelt(PICTURE
) )
pos
.x
= PICTURE
->ptlist
->x
;
pos
.y
= PICTURE
->ptlist
->y
;
fprintf(fp
,"gremlinfile\n"); /* write header */
fprintf(fp
, "%d %1.2f %1.2f\n", Orientation
, pos
.x
, pos
.y
);
while ( !DBNullelt(elist
) ) /* write each element */
fprintf(fp
, "%d\n", elist
->type
);
while ( !Nullpoint(plist
) ) /* write each point */
fprintf(fp
, "%1.2f %1.2f\n",plist
->x
, plist
->y
);
plist
= PTNextPoint(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
);
fprintf(fp
,"%d\n",-1); /* end of element list */
* This routine terminates the editor. The terminal states for the text
* terminal and the graphics display are restored and an EXIT is performed.
* This routine toggles the adjustment mode.
MNUnHighLt(HiMode
[adj
[HORZ
]]);
TxPutString(&TAdjust
, "NO ADJUSTMENT");
MNUnHighLt(HiMode
[adj
[Adjustment
]]);
MNHighLt(HiMode
[adj
[HORZ
]], hicolor
);
TxPutString(&TAdjust
, " HORIZONTAL ");
* This routine toggles the adjustment mode.
MNUnHighLt(HiMode
[adj
[VERT
]]);
TxPutString(&TAdjust
, "NO ADJUSTMENT");
MNUnHighLt(HiMode
[adj
[Adjustment
]]);
MNHighLt(HiMode
[adj
[VERT
]], hicolor
);
TxPutString(&TAdjust
, " VERTICAL ");
* This local routine returns 1 if x >= 0
* 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.
float xmat
[3][2], scalex
, scaley
;
if (SEQ
< 3) /* not enough points */
error("not enough points");
p1
= PTNextPoint(POINTLIST
);
if (sign(p1
->x
- POINTLIST
->x
) != sign(p2
->x
- POINTLIST
->x
))
if (sign(p1
->y
- POINTLIST
->y
) != sign(p2
->y
- POINTLIST
->y
))
/* create transformation matrix to translate set to origin,
performing the mirroring and translating back */
xmat
[1][0] = xmat
[0][1] = 0;
xmat
[2][0] = - POINTLIST
->x
* (scalex
- 1.0);
xmat
[2][1] = - POINTLIST
->y
* (scaley
- 1.0);
DISScreenErase(e1
, (linemask
| setmask
));
DBXform(e1
, xmat
, &PICTURE
);
GRsetwmask(textmask
| setmask
);
GRPutText(e1
->type
, p1
, e1
->brushf
, e1
->size
,e1
->textpt
, &pos
);
(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
);
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
);
DISScreenAdd(e1
, (linemask
| setmask
));
* This routine looks at the command line for parameters to set
* the current search path.
if ( *line
== '\0' ) TxPutMsg(PGetPath()); /* no arguments */
(void) sscanf(line
, "%s", path
);