* Copyright -C- 1982 Barry S. Roitblat
* This file contains routines for database manipulation for the
* gremlin picture editor.
/* imports from undodb */
extern UNRembAdd(), UNRembDelete();
/* imports from point.c */
extern POINT
*PTMakePoint();
/* imports from textio.c */
extern TxPutMsg(), TxMsgOK();
extern int SEARCH
; /* Search the path for filename ?? */
* This routine returns a pointer to an initialized database element
* which would be the only element in an empty list.
ELT
*DBCreateElt(type
, pointlist
, brush
, size
, text
, db
)
* This routine creates a new element with the specified attributes and
* links it into database.
temp
= (ELT
*) malloc(sizeof(ELT
));
temp
->ptlist
= pointlist
;
* This routine deletes the specified element by searching the database
* for its predecessor and deleting the pointer to the element.
* Flag indicates whether or not the element was in the current set
* and is passed along for use by the undo routines.
error("no such element");
temp
= &(DBNextElt((*temp
)));
*temp
= DBNextElt(element
);
#define highval 10000 /* arbitrary value greater than any
DBGravitate(x1
, y1
, x2
, y2
, point
, element
, db
)
* This routine searches the database for the point closest to
* (Euclidean distance) point1. This point is returned as point2
* and the element which contained the point is also returned.
* The point must be closer than some predefined maximum distance
* in order to be gravitated.
long int t
, t1
, t2
, distance
= highval
;
while ( !DBNullelt(temp
) )
while ( !Nullpoint(holdpt
) )
/* Calculate the distance between the point in the data
* base and the specified point. Use Euclidean distance
* except that, since we only need relative distance and
* not an absolute number, it is not necessary to take the
* square root. The equation for the distance was broken up
* as below in order to allow integer arithmetic wherever
* possible to increase efficiency when it was discovered
* that this routine was too slow.
if ((t
< distance
) && (t
< MAXGDIST
))
} /* end while holdpt */;
DBSetGravitate(x1
, y1
, x2
, y2
, point
, element
, db
)
* This routine searches the database for the point closest to
* (Euclidean distance) point1. This point is returned as point2
* and the element which contained the point is also returned.
* The point must be closer than some predefined maximum distance
* in order to be gravitated.
long int t
, t1
, t2
, distance
= highval
;
while ( !DBNullelt(temp
) )
while ( !Nullpoint(holdpt
) )
/* Calculate the distance between the point in the data
* base and the specified point. Use Euclidean distance
* except that, since we only need relative distance and
* not an absolute number, it is not necessary to take the
* square root. The equation for the distance was broken up
* as below in order to allow integer arithmetic wherever
* possible to increase efficiency when it was discovered
* that this routine was too slow.
if ((t
< distance
) && (t
< MAXGDIST
))
} /* end while holdpt */;
* This routine returns all storage associated with the element to
ELT
*DBRead(filename
, orient
, pos
)
* This routine reads the specified file into a database and
* returns a pointer to that database. Orient and pos are also set
* The format of a file written by gremlin is:
* the string: "gremlinfile" followed by a carriage return.
* the orientation (integer) and the x and y coordinates of a positioning
* point (float) followed by another carriage return.
* The output of 0 or more elements (see below).
* a -1 (integer) indicating end of data.
* The format of each element is:
* The element type (integer) followed by a carriage return.
* a list of 0 or more pairs of point coordinates (float) each on separate
* lines and terminated by the coordinates -1.0 -1.0.
* the brush (font) and size (integer) the element was defined with then <cr>
* the length (integer) of the string followed by the string terminated with
* All numbers are printed using standard c output conversion (ascii).
int len
, type
, i
, brush
, size
, done
;
fp
= POpen(filename
,(char **) NULL
,SEARCH
);
(void) sprintf(string
, "can't open %s",filename
);
TxPutMsg("reading file...");
(void) fscanf(fp
,"%s",string
);
if ( strcmp(string
, "gremlinfile") )
error("not gremlin file");
(void) fscanf(fp
, "%d%f%f", orient
, &x
, &y
);
if ( fscanf(fp
,"%d", &type
) == EOF
)
error("error in file format");
if (type
< 0) /* no more data */
(void) fscanf(fp
, "%f%f", &x
, &y
);
while ((x
!= -1) && (y
!= -1)) /* pointlist terminated by -1, -1 */
(void) PTMakePoint(x
, y
, &plist
);
(void) fscanf(fp
, "%f%f", &x
, &y
);
(void) fscanf(fp
, "%d%d", &brush
, &size
);
(void) fscanf(fp
, "%d", &len
);
txt
= malloc((unsigned) len
+ 1);
(void) getc(fp
); /* throw away space character */
(void) DBCreateElt(type
, plist
, brush
, size
, txt
, &elist
);
} /* end while not done */;
DBBounded(elt
, x1
, y1
, x2
, y2
)
* This routine returns true if all points in elt are bounded by
* the rectangle who diagonal is formed by (x1, y1) and (x2, y2).
float lox
, loy
, hix
, hiy
;
lox
= (x1
< x2
) ? x1
: x2
;
loy
= (y1
< y2
) ? y1
: y2
;
hix
= (x1
> x2
) ? x1
: x2
;
hiy
= (y1
> y2
) ? y1
: y2
;
if (p1
->x
< lox
) return(FALSE
);
if (p1
->x
> hix
) return(FALSE
);
if (p1
->y
< loy
) return(FALSE
);
if (p1
->y
> hiy
) return(FALSE
);