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 * 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 */ 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 * 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 */ 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 */ 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