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