117278Sopcode /*
2*17643Sopcode  * @(#)db.c	1.2	01/03/85
317278Sopcode  *
417278Sopcode  * This file contains routines for database manipulation for the
517278Sopcode  * SUN Gremlin picture editor.
617278Sopcode  *
717278Sopcode  * Mark Opperman (opcode@monet.BERKELEY)
817278Sopcode  *
917278Sopcode  */
1017278Sopcode 
1117278Sopcode #include "gremlin.h"
1217278Sopcode #include <ctype.h>
1317278Sopcode 
1417278Sopcode /* imports from undodb */
1517278Sopcode 
1617278Sopcode extern UNRembAdd();
1717278Sopcode extern UNRembDelete();
1817278Sopcode extern UNRembMod();
1917278Sopcode 
2017278Sopcode /* imports from C */
2117278Sopcode 
2217278Sopcode extern char *malloc();
2317278Sopcode 
2417278Sopcode /* imports from point.c */
2517278Sopcode 
2617278Sopcode extern PTModifyTextPoints();
2717278Sopcode extern POINT *PTMakePoint();
2817278Sopcode 
2917278Sopcode /* imports from text.c  */
3017278Sopcode 
3117278Sopcode extern TxPutMsg();
3217278Sopcode extern TxMsgOK();
3317278Sopcode 
3417278Sopcode /* imports from main */
3517278Sopcode 
3617278Sopcode extern SEARCH;			/* Search the path for filename */
3717278Sopcode extern TOOLINSTALLED;
3817278Sopcode 
3917278Sopcode /* cset is a pointer to the current set available to the outside world. */
4017278Sopcode 
4117278Sopcode ELT *cset;
4217278Sopcode 
4317278Sopcode /*
4417278Sopcode  * This routine creates a new element with the specified attributes and
4517278Sopcode  * links it into database db.
4617278Sopcode  */
4717278Sopcode ELT *
DBCreateElt(type,pointlist,brush,size,text,db)4817278Sopcode DBCreateElt(type, pointlist, brush, size, text, db)
4917278Sopcode int type, brush, size;
5017278Sopcode POINT *pointlist;
5117278Sopcode char *text;
5217278Sopcode ELT *(*db);
5317278Sopcode {
5417278Sopcode     register ELT *temp;
5517278Sopcode 
5617278Sopcode     temp = (ELT *) malloc(sizeof(ELT));
5717278Sopcode     temp->nextelt = *db;
5817278Sopcode     temp->type = type;
5917278Sopcode     temp->ptlist = pointlist;
6017278Sopcode     temp->brushf = brush;
6117278Sopcode     temp->size = size;
6217278Sopcode     temp->textpt = text;
6317278Sopcode     *db = temp;
6417278Sopcode     UNRembAdd(temp, db);
6517278Sopcode     return(temp);
6617278Sopcode } /* end DBCreateElt */
6717278Sopcode 
6817278Sopcode 
6917278Sopcode /*
7017278Sopcode  * This routine deletes the specified element by searching the database
7117278Sopcode  * for its predecessor and deleting the pointer to the element.
7217278Sopcode  * Flag indicates whether or not the element was in the current set
7317278Sopcode  * and is passed along for use by the undo routines.
7417278Sopcode  */
7517278Sopcode DBDelete(elt, db)
7617278Sopcode register ELT *elt, *(*db);
7717278Sopcode {
7817278Sopcode     register ELT *(*temp);
7917278Sopcode 
8017278Sopcode     temp = db;
8117278Sopcode 
8217278Sopcode     while (*temp != elt) {
8317278Sopcode         if (DBNullelt(*temp)) {
8417278Sopcode             error("no such element");
8517278Sopcode             return;
8617278Sopcode         }
8717278Sopcode         temp = &(DBNextElt((*temp)));
8817278Sopcode     }
8917278Sopcode 
9017278Sopcode     UNRembDelete(*temp, db);
9117278Sopcode     *temp = DBNextElt(elt);
9217278Sopcode }  /* end DBDelete */
9317278Sopcode 
9417278Sopcode 
9517278Sopcode #define highval 100000			/* arbitrary value greater than any
9617278Sopcode 					 * expected distance */
9717278Sopcode 
9817278Sopcode 
9917278Sopcode /*
10017278Sopcode  * This routine searches the database for the point closest to
10117278Sopcode  * (Euclidean distance) point1.  This point is returned as point2
10217278Sopcode  * and the element which contained the point is also returned.
10317278Sopcode  * The point must be closer than some predefined maximum distance
10417278Sopcode  * in order to be gravitated.
10517278Sopcode  * If setonly == TRUE the element's "setnext" pointer is used to
10617278Sopcode  * find the elements in the list, otherwise "nextelt" is used.
10717278Sopcode  */
DBGravitate(x1,y1,x2,y2,point,elt,db,setonly)10817278Sopcode DBGravitate(x1, y1, x2, y2, point, elt, db, setonly)
10917278Sopcode float x1, y1, *x2, *y2;
11017278Sopcode POINT *(*point);
11117278Sopcode ELT *(*elt), *db;
11217278Sopcode int setonly;
11317278Sopcode {
11417278Sopcode     register POINT *holdpt;
11517278Sopcode     register ELT *temp;
11617278Sopcode     register t, t1, t2;
11717278Sopcode     register distance = highval;
11817278Sopcode 
11917278Sopcode     temp = db;
12017278Sopcode     *elt = DBInit();
12117278Sopcode     *x2 = x1;
12217278Sopcode     *y2 = y1;
12317278Sopcode     while (!DBNullelt(temp)) {
12417278Sopcode         holdpt = temp->ptlist;
12517278Sopcode         while (!Nullpoint(holdpt)) {
12617278Sopcode 	    /* Calculate the distance between the point in the data
12717278Sopcode 	       base and the specified point.  Use Euclidean distance
12817278Sopcode 	       except that, since we only need relative distance and
12917278Sopcode 	       not an absolute number, it is not necessary to take the
13017278Sopcode 	       square root.  The equation for the distance was broken up
13117278Sopcode 	       as below in order to allow integer arithmetic wherever
13217278Sopcode 	       possible to increase efficiency when it was discovered
13317278Sopcode 	       that this routine was too slow. */
13417278Sopcode             t1 = holdpt->x - x1;
13517278Sopcode             t1 *= t1;
13617278Sopcode             t2 = holdpt->y - y1;
13717278Sopcode             t2 *= t2;
13817278Sopcode             t = t1 + t2;
13917278Sopcode 
14017278Sopcode             if ((t < distance) && (t < MAXGDIST)) {
14117278Sopcode                 distance = t;
14217278Sopcode                 *x2 = holdpt->x;
14317278Sopcode                 *y2 = holdpt->y;
14417278Sopcode     		*point = holdpt;
14517278Sopcode                 *elt = temp;
14617278Sopcode             }
14717278Sopcode 
14817278Sopcode             holdpt = holdpt->nextpt;
14917278Sopcode         }
15017278Sopcode         temp = setonly ? DBNextofSet(temp) : DBNextElt(temp);
15117278Sopcode     }
15217278Sopcode }  /* end DBGravitate */
15317278Sopcode 
15417278Sopcode 
15517278Sopcode /*
15617278Sopcode  * This routine returns all storage associated with the element to
15717278Sopcode  * free storage.
15817278Sopcode  */
DBClearElt(elt)15917278Sopcode DBClearElt(elt)
16017278Sopcode register ELT *elt;
16117278Sopcode {
16217278Sopcode     register POINT *pt, *pt2;
16317278Sopcode 
16417278Sopcode     pt = elt->ptlist;
16517278Sopcode 
16617278Sopcode     while (!Nullpoint(pt)) {
16717278Sopcode         pt2 = PTNextPoint(pt);
16817278Sopcode         free ((char *) pt);
16917278Sopcode         pt = pt2;
17017278Sopcode     }
17117278Sopcode 
17217278Sopcode     free(elt->textpt);
17317278Sopcode     free((char *) elt);
17417278Sopcode }  /* end DBClearElt */
17517278Sopcode 
17617278Sopcode 
17717278Sopcode /*
17817278Sopcode  * This routine reads the specified file into a database and
17917278Sopcode  * returns a pointer to that database.  Orient and pos are also set
18017278Sopcode  * from the file.
18117278Sopcode  *
18217278Sopcode  * The format of a file written by gremlin is:
18317278Sopcode  * the string: "gremlinfile" followed by a carriage return.
18417278Sopcode  * the orientation (integer) and the x and y coordinates of a positioning
18517278Sopcode  * point (float) followed by another carriage return.
18617278Sopcode  * The output of 0 or more elements (see below).
18717278Sopcode  * a -1 (integer) indicating end of data.
18817278Sopcode  *
18917278Sopcode  * The format of each element is:
19017278Sopcode  * The element type (integer) followed by a carriage return.
19117278Sopcode  * a list of 0 or more pairs of point coordinates (float) each on separate
19217278Sopcode  * lines and terminated by the coordinates -1.0 -1.0.
19317278Sopcode  * the brush (font) and size (integer) the element was defined with then <cr>
19417278Sopcode  * the length (integer) of the string followed by the string terminated with
19517278Sopcode  * a carriage return.
19617278Sopcode  *
19717278Sopcode  * All numbers are printed using standard C output conversion (ascii).
19817278Sopcode  *
19917278Sopcode  * +++ NEW FORMAT FOR SUN +++
20017278Sopcode  *
20117278Sopcode  * "sungremlinfile" is keyword in place of "gremlinfile"
20217278Sopcode  *
20317278Sopcode  * Point lists are terminated by a line containing a single asterik ('*')
20417278Sopcode  * to allow the legal point (-1.00 -1.00) in the point list.  All negative
20517278Sopcode  * coordinates are now legal.  Element types are indicated by ascii text,
20617278Sopcode  * eg, POLYGON, VECTOR, ARC, BOTLEFT, TOPCENT, etc.
20717278Sopcode  */
20817278Sopcode ELT *
DBRead(filename,orient,pos)20917278Sopcode DBRead(filename, orient, pos)
21017278Sopcode char *filename;
21117278Sopcode int *orient;
21217278Sopcode POINT *pos;
21317278Sopcode {
21417278Sopcode     FILE *fp, *POpen();
21517278Sopcode     ELT *elt, *elist;
21617278Sopcode     POINT *plist;
21717278Sopcode     char string[128], *txt, *prealname;
21817278Sopcode     float x, y;
21917278Sopcode     int len, type, i, brush, size, done, lastpoint, sunfile;
22017278Sopcode 
22117278Sopcode     sunfile = FALSE;
22217278Sopcode     elist = DBInit();
22317278Sopcode     fp = POpen(filename, &prealname, SEARCH);
22417278Sopcode 
22517278Sopcode     if (fp == NULL) {
22617278Sopcode         (void) sprintf(string, "can't open %s",filename);
22717278Sopcode         error(string);
22817278Sopcode         return(elist);
22917278Sopcode     }
23017278Sopcode 
23117278Sopcode     if (TOOLINSTALLED)		/* no message if reading startup edit file */
23217278Sopcode 	TxPutMsg("reading file...");
23317278Sopcode     (void) fscanf(fp, "%s\n", string);
23417278Sopcode 
23517278Sopcode     if (strcmp(string, "gremlinfile")) {
23617278Sopcode 	if (strcmp(string, "sungremlinfile")) {
23717278Sopcode 	    error("not gremlin file");
23817278Sopcode 	    return(elist);
23917278Sopcode 	}
24017278Sopcode 	sunfile = TRUE;
24117278Sopcode     }
24217278Sopcode 
24317278Sopcode     (void) fscanf(fp, "%d%f%f\n", orient, &x, &y);
24417278Sopcode     pos->x = x;
24517278Sopcode     pos->y = y;
24617278Sopcode 
24717278Sopcode     done = FALSE;
24817278Sopcode     while (!done) {
24917278Sopcode         if (fscanf(fp,"%s\n", string) == EOF) {		/* element type */
25017278Sopcode             error("error in file format");
25117278Sopcode 	    fclose(fp);
25217278Sopcode             return(elist);
25317278Sopcode         }
25417278Sopcode 
25517278Sopcode         if ((type = DBGetType(string)) < 0) {		/* no more data */
25617278Sopcode             done = TRUE;
25717278Sopcode         }
25817278Sopcode         else {
25917278Sopcode             plist = PTInit();
26017278Sopcode             (void) fscanf(fp, "%f%f\n", &x, &y);	/* read first point */
26117278Sopcode 
26217278Sopcode 	    /* Files created on the SUN have point lists terminated
26317278Sopcode 	     * by a line containing only an asterik ('*').  Files
26417278Sopcode 	     * created on the AED have point lists terminated by the
26517278Sopcode 	     * coordinate pair (-1.00 -1.00).
26617278Sopcode 	     */
26717278Sopcode 	    lastpoint = FALSE;
26817278Sopcode 	    do {
26917278Sopcode 		(void) PTMakePoint(x, y, &plist);
27017278Sopcode 		fgets(string, 127, fp);
27117278Sopcode 		if (string[0] == '*') {     /* SUN gremlin file */
27217278Sopcode 		    lastpoint = TRUE;
27317278Sopcode 		}
27417278Sopcode 		else {
27517278Sopcode 		    (void) sscanf(string, "%f%f", &x, &y);
27617278Sopcode 		    if ((x == -1.00 && y == -1.00) && (!sunfile))
27717278Sopcode 			lastpoint = TRUE;
27817278Sopcode 		}
27917278Sopcode 	    } while (!lastpoint);
28017278Sopcode #ifdef oldway
28117278Sopcode             while ((x != -1) && (y != -1)) { /* plist terminated by -1, -1 */
28217278Sopcode                 (void) PTMakePoint(x, y, &plist);
28317278Sopcode                 (void) fscanf(fp, "%f%f\n", &x, &y);
28417278Sopcode             }
28517278Sopcode #endif
28617278Sopcode 
28717278Sopcode 	    (void) fscanf(fp, "%d%d\n", &brush, &size);
28817278Sopcode 	    (void) fscanf(fp, "%d", &len);
28917278Sopcode 	    (void) getc(fp);	/* eat blank */
29017278Sopcode             txt = malloc((unsigned) len + 1);
29117278Sopcode             for (i=0; i<len; ++i)
29217278Sopcode                 txt[i] = getc(fp);
29317278Sopcode             txt[len] = '\0';
29417278Sopcode             elt = DBCreateElt(type, plist, brush, size, txt, &elist);
29517278Sopcode 	    if (TEXT(elt->type))	/* recompute text reference points */
29617278Sopcode 		PTModifyTextPoints(elt);
29717278Sopcode         }
29817278Sopcode     }
29917278Sopcode 
30017278Sopcode     TxMsgOK();
30117278Sopcode     fclose(fp);
30217278Sopcode     return(elist);
30317278Sopcode } /* end DBRead */
30417278Sopcode 
30517278Sopcode 
30617278Sopcode /*
30717278Sopcode  * Interpret element type in string s.
30817278Sopcode  * Old file format consisted of integer element types.
30917278Sopcode  * New file format has literal names for element types.
31017278Sopcode  */
DBGetType(s)31117278Sopcode DBGetType(s)
31217278Sopcode register char *s;
31317278Sopcode {
31417278Sopcode     if (isdigit(s[0]) || (s[0] == '-'))		/* old element format or EOF */
31517278Sopcode 	return(atoi(s));
31617278Sopcode 
31717278Sopcode     switch (s[0]) {
31817278Sopcode 	case 'P':
31917278Sopcode 	    return(POLYGON);
32017278Sopcode 	case 'V':
32117278Sopcode 	    return(VECTOR);
32217278Sopcode 	case 'A':
32317278Sopcode 	    return(ARC);
32417278Sopcode 	case 'C':
32517278Sopcode 	    if (s[1] == 'U')
32617278Sopcode 		return(CURVE);
32717278Sopcode 	    switch (s[4]) {
32817278Sopcode 		case 'L':
32917278Sopcode 		    return(CENTLEFT);
33017278Sopcode 		case 'C':
33117278Sopcode 		    return(CENTCENT);
33217278Sopcode 		case 'R':
33317278Sopcode 		    return(CENTRIGHT);
33417278Sopcode 		default:
33517278Sopcode 		    error("unknown element type");
33617278Sopcode 		    return(-1);
33717278Sopcode 	    }
33817278Sopcode 	case 'B':
33917278Sopcode 	    switch (s[3]) {
34017278Sopcode 		case 'L':
34117278Sopcode 		    return(BOTLEFT);
34217278Sopcode 		case 'C':
34317278Sopcode 		    return(BOTCENT);
34417278Sopcode 		case 'R':
34517278Sopcode 		    return(BOTRIGHT);
34617278Sopcode 		default:
34717278Sopcode 		    error("unknown element type");
34817278Sopcode 		    return(-1);
34917278Sopcode 	    }
35017278Sopcode 	case 'T':
35117278Sopcode 	    switch (s[3]) {
35217278Sopcode 		case 'L':
35317278Sopcode 		    return(TOPLEFT);
35417278Sopcode 		case 'C':
35517278Sopcode 		    return(TOPCENT);
35617278Sopcode 		case 'R':
35717278Sopcode 		    return(TOPRIGHT);
35817278Sopcode 		default:
35917278Sopcode 		    error("unknown element type");
36017278Sopcode 		    return(-1);
36117278Sopcode 	    }
36217278Sopcode 	default:
36317278Sopcode 	    error("unknown element type");
36417278Sopcode 	    return(-1);
36517278Sopcode     }
36617278Sopcode }  /* end DBGetType */
36717278Sopcode 
36817278Sopcode 
36917278Sopcode /*
37017278Sopcode  * This routine returns true if all points in elt are bounded by
37117278Sopcode  * the rectangle who diagonal is formed by (x1, y1) and (x2, y2).
37217278Sopcode  */
DBBounded(elt,x1,y1,x2,y2)37317278Sopcode DBBounded(elt, x1, y1, x2, y2)
37417278Sopcode register ELT *elt;
37517278Sopcode register float x1, y1, x2, y2;
37617278Sopcode {
37717278Sopcode     register POINT *p1;
37817278Sopcode     register float lox, loy, hix, hiy;	/* OK to compare register floats */
37917278Sopcode 
38017278Sopcode     lox = (x1 < x2) ? x1 : x2;
38117278Sopcode     loy = (y1 < y2) ? y1 : y2;
38217278Sopcode     hix = (x1 > x2) ? x1 : x2;
38317278Sopcode     hiy = (y1 > y2) ? y1 : y2;
38417278Sopcode     p1 = elt->ptlist;
38517278Sopcode 
38617278Sopcode     while (!Nullpoint(p1)) {
38717278Sopcode 	if ((p1->x < lox) || (p1->x > hix) || (p1->y < loy) || (p1->y > hiy))
38817278Sopcode 	    return(FALSE);
38917278Sopcode 	p1 = PTNextPoint(p1);
39017278Sopcode     }
39117278Sopcode 
39217278Sopcode     return(TRUE);
39317278Sopcode }  /* end DBBounded */
39417278Sopcode 
39517278Sopcode 
39617278Sopcode /*
39717278Sopcode  * This routine creates a copy of the the element transformed by
39817278Sopcode  * the transformation matrix and adds the new copy to the database.
39917278Sopcode  */
40017278Sopcode ELT *
DBCopy(elt,transform,db)40117278Sopcode DBCopy(elt, transform, db)
40217278Sopcode register ELT *elt;
40317278Sopcode ELT *(*db);
40417278Sopcode float transform[3][2];
40517278Sopcode {
40617278Sopcode     register POINT *pt;
40717278Sopcode     POINT *newlist;
40817278Sopcode     char *newtext;
40917278Sopcode 
41017278Sopcode     newlist = PTInit();
41117278Sopcode     pt = elt->ptlist;
41217278Sopcode 
41317278Sopcode     while (!Nullpoint(pt)) { /* matrix multiply */
41417278Sopcode 	(void) PTMakePoint((((pt->x) * transform[0][0]) +
41517278Sopcode 			    ((pt->y) * transform[1][0]) +
41617278Sopcode 				       transform[2][0]),
41717278Sopcode 			   (((pt->x) * transform[0][1]) +
41817278Sopcode 			    ((pt->y) * transform[1][1]) +
41917278Sopcode 				       transform[2][1]), &newlist);
42017278Sopcode 	pt = pt->nextpt;
42117278Sopcode     }
42217278Sopcode 
42317278Sopcode     newtext = malloc((unsigned) strlen(elt->textpt) + 1);
42417278Sopcode     (void) strcpy(newtext, elt->textpt);
42517278Sopcode     return( DBCreateElt(elt->type, newlist, elt->brushf,
42617278Sopcode 			elt->size, newtext, db) );
42717278Sopcode }  /* end DBCopy */
42817278Sopcode 
42917278Sopcode 
43017278Sopcode /*
43117278Sopcode  * This routine transforms the element by multiplying the
43217278Sopcode  * coordinates of each of the points in the element by the
43317278Sopcode  * transformation matrix.
43417278Sopcode  */
DBXform(elt,transform,db)43517278Sopcode DBXform(elt, transform, db)
43617278Sopcode register ELT *elt;
43717278Sopcode float transform[3][2];
43817278Sopcode ELT *(*db);
43917278Sopcode {
44017278Sopcode     register POINT *pt;
44117278Sopcode     float px, py;
44217278Sopcode 
44317278Sopcode     UNRembMod(elt, db);
44417278Sopcode     pt = elt->ptlist;
44517278Sopcode 
44617278Sopcode     while (!Nullpoint(pt)) {
44717278Sopcode 	px =  ((pt->x) * transform[0][0]) +
44817278Sopcode 	      ((pt->y) * transform[1][0]) + transform[2][0];
44917278Sopcode 	py =  ((pt->x) * transform[0][1]) +
45017278Sopcode 	      ((pt->y) * transform[1][1]) + transform[2][1];
45117278Sopcode 	pt->x = px;
45217278Sopcode 	pt->y = py;
45317278Sopcode 	pt = pt->nextpt;
45417278Sopcode     }
45517278Sopcode }  /* end DBXform */
45617278Sopcode 
45717278Sopcode 
45817278Sopcode /*
45917278Sopcode  * This routine changes the brush attribute of the element.
46017278Sopcode  */
46117278Sopcode DBChangeBrush(elt, brush, db)
46217278Sopcode ELT *elt, *(*db);
46317278Sopcode int brush;
46417278Sopcode {
46517278Sopcode     UNRembMod(elt, db);
46617278Sopcode     elt->brushf = brush;
46717278Sopcode }  /* end DBChangeBrush */
46817278Sopcode 
46917278Sopcode 
47017278Sopcode /*
47117278Sopcode  * This routine changes the justify attribute of the element.
47217278Sopcode  */
47317278Sopcode DBChangeJustify(elt, justmode, db)
47417278Sopcode ELT *elt, *(*db);
47517278Sopcode int justmode;
47617278Sopcode {
47717278Sopcode     register length;
47817278Sopcode     register POINT *pos, *point;
47917278Sopcode 
48017278Sopcode     UNRembMod(elt, db);
48117278Sopcode     elt->type = justmode;
48217278Sopcode     PTModifyTextPoints(elt);
48317278Sopcode }  /* end DBChangeJustify */
48417278Sopcode 
48517278Sopcode 
48617278Sopcode /*
48717278Sopcode  * This routine changes the font attribute of the given element.
48817278Sopcode  */
48917278Sopcode DBChangeFont(elt, font, db)
49017278Sopcode ELT *elt, *(*db);
49117278Sopcode int font;
49217278Sopcode {
49317278Sopcode     UNRembMod(elt, db);
49417278Sopcode     elt->brushf = font;
49517278Sopcode     PTModifyTextPoints(elt);
49617278Sopcode }  /* end DBChangeFont */
49717278Sopcode 
49817278Sopcode 
49917278Sopcode /*
50017278Sopcode  * This routine changes the size attribute of the given element.
50117278Sopcode  */
50217278Sopcode DBChangeSize(elt, size, db)
50317278Sopcode ELT *elt, *(*db);
50417278Sopcode int size;
50517278Sopcode {
50617278Sopcode     UNRembMod(elt, db);
50717278Sopcode     elt->size = size;
50817278Sopcode     PTModifyTextPoints(elt);
50917278Sopcode }  /* end DBChangeSize */
51017278Sopcode 
51117278Sopcode 
51217278Sopcode /*
51317278Sopcode  * This routine changes the stipple attribute of the given element.
51417278Sopcode  */
51517278Sopcode DBChangeStipple(elt, stipple, db)
51617278Sopcode ELT *elt, *(*db);
51717278Sopcode int stipple;
51817278Sopcode {
51917278Sopcode     UNRembMod(elt, db);
52017278Sopcode     elt->size = stipple;
52117278Sopcode }  /* end DBChangeStipple */
52217278Sopcode 
52317278Sopcode 
52417278Sopcode /*
52517278Sopcode  * This routine changes the text attribute of the given element.
52617278Sopcode  */
52717278Sopcode DBChangeText(elt, text, db)
52817278Sopcode ELT *elt, *(*db);
52917278Sopcode char *text;
53017278Sopcode {
53117278Sopcode     char *new;
53217278Sopcode 
53317278Sopcode     UNRembMod(elt, db);
53417278Sopcode     free(elt->textpt);
53517278Sopcode     new = malloc((unsigned) strlen(text) + 1);
53617278Sopcode     (void) strcpy(new, text);
53717278Sopcode     elt->textpt = new;
53817278Sopcode     PTModifyTextPoints(elt);
53917278Sopcode }  /* end DBChangeText */
54017278Sopcode 
54117278Sopcode 
54217278Sopcode /*
54317278Sopcode  * This routine changes the type attribute of the given element.
54417278Sopcode  */
54517278Sopcode DBChangeType(elt, newtype, db)
54617278Sopcode ELT *elt, *(*db);
54717278Sopcode int newtype;
54817278Sopcode {
54917278Sopcode     UNRembMod(elt, db);
55017278Sopcode     elt->type = newtype;
55117278Sopcode }  /* end DBChangeType */
55217278Sopcode 
55317278Sopcode 
55417278Sopcode /*
55517278Sopcode  * This routine changes the type and stipple attributes of the given element.
55617278Sopcode  */
55717278Sopcode DBChangeTypeStipple(elt, newtype, newstipple, db)
55817278Sopcode ELT *elt, *(*db);
55917278Sopcode int newtype, newstipple;
56017278Sopcode {
56117278Sopcode     UNRembMod(elt, db);
56217278Sopcode     elt->type = newtype;
56317278Sopcode     elt->size = newstipple;
56417278Sopcode }  /* end DBChangeType */
56517278Sopcode 
56617278Sopcode 
56717278Sopcode /*
56817278Sopcode  * This routine changes the type, brush and stipple attributes
56917278Sopcode  * of the given element.
57017278Sopcode  */
57117278Sopcode DBChangeTypeBrushStipple(elt, newtype, newbrush, newstipple, db)
57217278Sopcode ELT *elt, *(*db);
57317278Sopcode int newtype, newbrush, newstipple;
57417278Sopcode {
57517278Sopcode     UNRembMod(elt, db);
57617278Sopcode     elt->type = newtype;
57717278Sopcode     elt->brushf = newbrush;
57817278Sopcode     elt->size = newstipple;
57917278Sopcode }  /* end DBChangeType */
58017278Sopcode 
58117278Sopcode 
58217278Sopcode /*
58317278Sopcode  * This routine adds the element to the current set database.
58417278Sopcode  */
DBAddSet(elt)58517278Sopcode DBAddSet(elt)
58617278Sopcode register ELT *elt;
58717278Sopcode {
58817278Sopcode     register ELT *elist;
58917278Sopcode 
59017278Sopcode     elist = cset;
59117278Sopcode 
59217278Sopcode     while (!DBNullelt(elist)) { /* makes sure element not already in list */
59317278Sopcode 	if (elist == elt)
59417278Sopcode 	    return;
59517278Sopcode 	elist = DBNextofSet(elist);
59617278Sopcode     }
59717278Sopcode 
59817278Sopcode     elt->setnext = cset;
59917278Sopcode     cset = elt;
60017278Sopcode }  /* end DBAddSet */
60117278Sopcode 
60217278Sopcode 
60317278Sopcode /*
60417278Sopcode  *  Return TRUE if element in current set, else FALSE.
60517278Sopcode  */
DBInCset(elt)60617278Sopcode DBInCset(elt)
60717278Sopcode register ELT *elt;
60817278Sopcode {
60917278Sopcode     register ELT *elist;
61017278Sopcode 
61117278Sopcode     elist = cset;
61217278Sopcode 
61317278Sopcode     while (!DBNullelt(elist)) { /* makes sure element not already in list */
61417278Sopcode 	if (elist == elt)
61517278Sopcode 	    return(TRUE);
61617278Sopcode 	elist = DBNextofSet(elist);
61717278Sopcode     }
61817278Sopcode     return(FALSE);
61917278Sopcode }  /* end DBInCset */
62017278Sopcode 
62117278Sopcode 
62217278Sopcode /*
62317278Sopcode  * This routine clears the current set by setting the pointer
62417278Sopcode  * to a null element.
62517278Sopcode  */
DBClearSet()62617278Sopcode DBClearSet()
62717278Sopcode {
62817278Sopcode     while (!DBNullelt(cset))
62917278Sopcode 	cset = DBNextofSet(cset);
63017278Sopcode }  /* end DBClearSet */
631