117292Sopcode /*
2*17651Sopcode  * @(#)point.c	1.2	01/03/85
317292Sopcode  *
417292Sopcode  * Routines for manipulating the point data structures of the
517292Sopcode  * SUN Gremlin picture editor.
617292Sopcode  *
717292Sopcode  * Mark Opperman (opcode@monet.BERKELEY)
817292Sopcode  *
917292Sopcode  */
1017292Sopcode 
1117292Sopcode #include "gremlin.h"
1217292Sopcode 
1317292Sopcode /* imports from graphics.c */
1417292Sopcode 
1517292Sopcode extern GRFontStrlen();
1617292Sopcode 
1717292Sopcode /* imports from C */
1817292Sopcode 
1917292Sopcode extern char *malloc();
2017292Sopcode 
2117292Sopcode 
2217292Sopcode /*
2317292Sopcode  * This routine creates a new point with coordinates x and y and
2417292Sopcode  * links it into the pointlist.
2517292Sopcode  */
2617292Sopcode POINT *
PTMakePoint(x,y,pplist)2717292Sopcode PTMakePoint(x, y, pplist)
2817292Sopcode float x, y;
2917292Sopcode POINT **pplist;
3017292Sopcode {
3117292Sopcode     register POINT *point;
3217292Sopcode 
3317292Sopcode     if (Nullpoint(point = *pplist)) {	/* empty list */
3417292Sopcode 	*pplist = (POINT *) malloc(sizeof(POINT));
3517292Sopcode 	point = *pplist;
3617292Sopcode     }
3717292Sopcode     else {
3817292Sopcode 	while (!Nullpoint(point->nextpt))
3917292Sopcode 	    point = point->nextpt;
4017292Sopcode 	point->nextpt = (POINT *) malloc(sizeof(POINT));
4117292Sopcode 	point = point->nextpt;
4217292Sopcode     }
4317292Sopcode 
4417292Sopcode     point->x = x;
4517292Sopcode     point->y = y;
4617292Sopcode     point->nextpt = PTInit();
4717292Sopcode     return(point);
4817292Sopcode }  /* end PTMakePoint */
4917292Sopcode 
5017292Sopcode 
5117292Sopcode /*
5217292Sopcode  * This routine removes the specified point from the pointlist and
5317292Sopcode  * returns it to free storage.  Deletion is done in place by copying the
5417292Sopcode  * next point over the one to be deleted and then removing the (previously)
5517292Sopcode  * next point.
5617292Sopcode  *
5717292Sopcode  * It is up to the caller to ensure that, if a list contains only one POINT,
5817292Sopcode  * any pointers to that list are set to NULL after this call.
5917292Sopcode  */
PTDeletePoint(pt,plist)6017292Sopcode PTDeletePoint(pt, plist)
6117292Sopcode register POINT *pt;		/* the point to deleted */
6217292Sopcode register POINT **plist;		/* the address of the list from
6317292Sopcode 				   which it is to be deleted */
6417292Sopcode {
6517292Sopcode     register POINT *tempt;
6617292Sopcode 
6717292Sopcode     if (Nullpoint(pt->nextpt)) {	/* last POINT in list */
6817292Sopcode 	if (*plist == pt)		/* only POINT in list */
6917292Sopcode 	    *plist = (POINT *) NULL;
7017292Sopcode 	else {				/* search for previous point */
7117292Sopcode 	    tempt = *plist;
7217292Sopcode 	    while (tempt->nextpt != pt)
7317292Sopcode 		tempt = tempt->nextpt;
7417292Sopcode 	    tempt->nextpt = (POINT *) NULL;
7517292Sopcode 	}
7617292Sopcode 	free((char *) pt);
7717292Sopcode     }
7817292Sopcode     else {				/* copy over */
7917292Sopcode 	tempt = PTNextPoint(pt);
8017292Sopcode 	pt->x = tempt->x;
8117292Sopcode 	pt->y = tempt->y;
8217292Sopcode 	pt->nextpt = tempt->nextpt;
8317292Sopcode 	free((char *) tempt);
8417292Sopcode     }
8517292Sopcode }  /* end PTDeletePoint */
8617292Sopcode 
8717292Sopcode 
8817292Sopcode /*
8917292Sopcode  * This routine makes the four positioning points required for text
9017292Sopcode  * elements: (1) the point layed down by the user, (2) the bottom left
9117292Sopcode  * corner of the text display, (3) the midpoint of the bottom edge of
9217292Sopcode  * the text display, and (4) the bottom right corner of the text display.
9317292Sopcode  * A pointer to this list is returned.
9417292Sopcode  */
9517292Sopcode POINT *
PTMakeTextPoints(text,font,size,point,pos)9617292Sopcode PTMakeTextPoints(text, font, size, point, pos)
9717292Sopcode char *text;
9817292Sopcode int font, size;
9917292Sopcode register POINT *point;	/* point layed down by user */
10017292Sopcode register POINT *pos;	/* bottom left corner of text display */
10117292Sopcode {
10217292Sopcode     register length;
10317292Sopcode     POINT *pt;
10417292Sopcode 
10517292Sopcode     length = GRFontStrlen(text, font, size);
10617292Sopcode 
10717292Sopcode     pt = PTInit();
10817292Sopcode     (void) PTMakePoint(point->x, point->y, &pt);	    /* user's point */
10917292Sopcode     (void) PTMakePoint(pos->x, pos->y, &pt);		    /* bottom left */
11017292Sopcode     (void) PTMakePoint(pos->x + (length / 2), pos->y, &pt); /* bottom midpt */
11117292Sopcode     (void) PTMakePoint(pos->x + length, pos->y, &pt);	    /* bottom right */
11217292Sopcode 
11317292Sopcode     return(pt);
11417292Sopcode }
11517292Sopcode 
11617292Sopcode 
11717292Sopcode /*
11817292Sopcode  *  Change the text points to reflect the current justification,
11917292Sopcode  *  font and size of a text element.
12017292Sopcode  */
PTModifyTextPoints(elt)12117292Sopcode PTModifyTextPoints(elt)
12217292Sopcode register ELT *elt;
12317292Sopcode {
12417292Sopcode     register length;
12517292Sopcode     register POINT *pos, *point;
12617292Sopcode 
12717292Sopcode     length = GRFontStrlen(elt->textpt, elt->brushf, elt->size);
12817292Sopcode     pos = PTNextPoint(elt->ptlist);		/* bottom left */
12917292Sopcode 
13017292Sopcode     GRSetTextPos(elt->textpt, elt->type, elt->brushf, elt->size,
13117292Sopcode 							elt->ptlist, pos);
13217292Sopcode 
13317292Sopcode     point = PTNextPoint(pos);			/* bottom midpoint */
13417292Sopcode     point->x = pos->x + (length / 2);
13517292Sopcode     point->y = pos->y;
13617292Sopcode     point = PTNextPoint(point);			/* bottom right */
13717292Sopcode     point->x = pos->x + length;
13817292Sopcode     point->y = pos->y;
13917292Sopcode }
14017292Sopcode 
14117292Sopcode 
14217292Sopcode /*
14317292Sopcode  *  Return number of POINTs in an element.
14417292Sopcode  */
PTListLength(elt)14517292Sopcode PTListLength(elt)
14617292Sopcode register ELT *elt;
14717292Sopcode {
14817292Sopcode     register POINT *point;
14917292Sopcode     register length = 1;
15017292Sopcode 
15117292Sopcode     if (Nullpoint(point = elt->ptlist)) {
15217292Sopcode 	printf("PTListLength: empty point list\n");
15317292Sopcode 	return(0);
15417292Sopcode     }
15517292Sopcode 
15617292Sopcode     while (!Nullpoint(point->nextpt)) {
15717292Sopcode 	length++;
15817292Sopcode 	point = point->nextpt;
15917292Sopcode     }
16017292Sopcode 
16117292Sopcode     return(length);
16217292Sopcode }
163