1 /*
2  * @(#)point.c	1.2	01/03/85
3  *
4  * Routines for manipulating the point data structures of the
5  * SUN Gremlin picture editor.
6  *
7  * Mark Opperman (opcode@monet.BERKELEY)
8  *
9  */
10 
11 #include "gremlin.h"
12 
13 /* imports from graphics.c */
14 
15 extern GRFontStrlen();
16 
17 /* imports from C */
18 
19 extern char *malloc();
20 
21 
22 /*
23  * This routine creates a new point with coordinates x and y and
24  * links it into the pointlist.
25  */
26 POINT *
PTMakePoint(x,y,pplist)27 PTMakePoint(x, y, pplist)
28 float x, y;
29 POINT **pplist;
30 {
31     register POINT *point;
32 
33     if (Nullpoint(point = *pplist)) {	/* empty list */
34 	*pplist = (POINT *) malloc(sizeof(POINT));
35 	point = *pplist;
36     }
37     else {
38 	while (!Nullpoint(point->nextpt))
39 	    point = point->nextpt;
40 	point->nextpt = (POINT *) malloc(sizeof(POINT));
41 	point = point->nextpt;
42     }
43 
44     point->x = x;
45     point->y = y;
46     point->nextpt = PTInit();
47     return(point);
48 }  /* end PTMakePoint */
49 
50 
51 /*
52  * This routine removes the specified point from the pointlist and
53  * returns it to free storage.  Deletion is done in place by copying the
54  * next point over the one to be deleted and then removing the (previously)
55  * next point.
56  *
57  * It is up to the caller to ensure that, if a list contains only one POINT,
58  * any pointers to that list are set to NULL after this call.
59  */
PTDeletePoint(pt,plist)60 PTDeletePoint(pt, plist)
61 register POINT *pt;		/* the point to deleted */
62 register POINT **plist;		/* the address of the list from
63 				   which it is to be deleted */
64 {
65     register POINT *tempt;
66 
67     if (Nullpoint(pt->nextpt)) {	/* last POINT in list */
68 	if (*plist == pt)		/* only POINT in list */
69 	    *plist = (POINT *) NULL;
70 	else {				/* search for previous point */
71 	    tempt = *plist;
72 	    while (tempt->nextpt != pt)
73 		tempt = tempt->nextpt;
74 	    tempt->nextpt = (POINT *) NULL;
75 	}
76 	free((char *) pt);
77     }
78     else {				/* copy over */
79 	tempt = PTNextPoint(pt);
80 	pt->x = tempt->x;
81 	pt->y = tempt->y;
82 	pt->nextpt = tempt->nextpt;
83 	free((char *) tempt);
84     }
85 }  /* end PTDeletePoint */
86 
87 
88 /*
89  * This routine makes the four positioning points required for text
90  * elements: (1) the point layed down by the user, (2) the bottom left
91  * corner of the text display, (3) the midpoint of the bottom edge of
92  * the text display, and (4) the bottom right corner of the text display.
93  * A pointer to this list is returned.
94  */
95 POINT *
PTMakeTextPoints(text,font,size,point,pos)96 PTMakeTextPoints(text, font, size, point, pos)
97 char *text;
98 int font, size;
99 register POINT *point;	/* point layed down by user */
100 register POINT *pos;	/* bottom left corner of text display */
101 {
102     register length;
103     POINT *pt;
104 
105     length = GRFontStrlen(text, font, size);
106 
107     pt = PTInit();
108     (void) PTMakePoint(point->x, point->y, &pt);	    /* user's point */
109     (void) PTMakePoint(pos->x, pos->y, &pt);		    /* bottom left */
110     (void) PTMakePoint(pos->x + (length / 2), pos->y, &pt); /* bottom midpt */
111     (void) PTMakePoint(pos->x + length, pos->y, &pt);	    /* bottom right */
112 
113     return(pt);
114 }
115 
116 
117 /*
118  *  Change the text points to reflect the current justification,
119  *  font and size of a text element.
120  */
PTModifyTextPoints(elt)121 PTModifyTextPoints(elt)
122 register ELT *elt;
123 {
124     register length;
125     register POINT *pos, *point;
126 
127     length = GRFontStrlen(elt->textpt, elt->brushf, elt->size);
128     pos = PTNextPoint(elt->ptlist);		/* bottom left */
129 
130     GRSetTextPos(elt->textpt, elt->type, elt->brushf, elt->size,
131 							elt->ptlist, pos);
132 
133     point = PTNextPoint(pos);			/* bottom midpoint */
134     point->x = pos->x + (length / 2);
135     point->y = pos->y;
136     point = PTNextPoint(point);			/* bottom right */
137     point->x = pos->x + length;
138     point->y = pos->y;
139 }
140 
141 
142 /*
143  *  Return number of POINTs in an element.
144  */
PTListLength(elt)145 PTListLength(elt)
146 register ELT *elt;
147 {
148     register POINT *point;
149     register length = 1;
150 
151     if (Nullpoint(point = elt->ptlist)) {
152 	printf("PTListLength: empty point list\n");
153 	return(0);
154     }
155 
156     while (!Nullpoint(point->nextpt)) {
157 	length++;
158 	point = point->nextpt;
159     }
160 
161     return(length);
162 }
163