1 #ifndef lint 2 static char sccsid[] = "@(#)blockgen.c 3.1 (CWI) 85/07/30"; 3 #endif lint 4 5 #include <stdio.h> 6 #include "pic.h" 7 #include "y.tab.h" 8 9 #define NBRACK 20 /* depth of [...] */ 10 #define NBRACE 20 /* depth of {...} */ 11 12 struct pushstack stack[NBRACK]; 13 int nstack = 0; 14 struct pushstack bracestack[NBRACE]; 15 int nbstack = 0; 16 17 obj *leftthing(c) /* called for {... or [... */ 18 /* really ought to be separate functions */ 19 int c; 20 { 21 obj *p; 22 23 if (c == '[') { 24 if (nstack >= NBRACK) 25 fatal("[...] nested too deep"); 26 stack[nstack].p_x = curx; 27 stack[nstack].p_y = cury; 28 stack[nstack].p_hvmode = hvmode; 29 curx = cury = 0; 30 stack[nstack].p_xmin = xmin; 31 stack[nstack].p_xmax = xmax; 32 stack[nstack].p_ymin = ymin; 33 stack[nstack].p_ymax = ymax; 34 nstack++; 35 xmin = ymin = 30000; 36 xmax = ymax = -30000; 37 p = makenode(BLOCK, 7); 38 p->o_val[4] = nobj; /* 1st item within [...] */ 39 if (p->o_nobj != nobj-1) 40 fprintf(stderr, "nobjs wrong%d %d\n", p->o_nobj, nobj); 41 } else { 42 if (nbstack >= NBRACK) 43 fatal("{...} nested too deep"); 44 bracestack[nbstack].p_x = curx; 45 bracestack[nbstack].p_y = cury; 46 bracestack[nbstack].p_hvmode = hvmode; 47 nbstack++; 48 p = NULL; 49 } 50 return(p); 51 } 52 53 obj *rightthing(p, c) /* called for ... ] or ... } */ 54 obj *p; 55 { 56 obj *q; 57 58 if (c == '}') { 59 nbstack--; 60 curx = bracestack[nbstack].p_x; 61 cury = bracestack[nbstack].p_y; 62 hvmode = bracestack[nbstack].p_hvmode; 63 q = makenode(MOVE, 0); 64 dprintf("M %g %g\n", curx, cury); 65 } else { 66 nstack--; 67 curx = stack[nstack].p_x; 68 cury = stack[nstack].p_y; 69 hvmode = stack[nstack].p_hvmode; 70 q = makenode(BLOCKEND, 7); 71 q->o_val[4] = p->o_nobj + 1; /* back pointer */ 72 p->o_val[5] = q->o_nobj - 1; /* forward pointer */ 73 p->o_val[0] = xmin; p->o_val[1] = ymin; 74 p->o_val[2] = xmax; p->o_val[3] = ymax; 75 p->o_symtab = q->o_symtab = stack[nstack+1].p_symtab; 76 xmin = stack[nstack].p_xmin; 77 ymin = stack[nstack].p_ymin; 78 xmax = stack[nstack].p_xmax; 79 ymax = stack[nstack].p_ymax; 80 } 81 return(q); 82 } 83 84 obj *blockgen(p, type, q) /* handles [...] */ 85 obj *p, *q; 86 int type; 87 { 88 int i, invis, at, ddtype, with; 89 float ddval, h, w, xwith, ywith; 90 float x0, y0, x1, y1, cx, cy; 91 obj *ppos; 92 Attr *ap; 93 94 invis = at = 0; 95 with = xwith = ywith = 0; 96 ddtype = ddval = 0; 97 w = p->o_val[2] - p->o_val[0]; 98 h = p->o_val[3] - p->o_val[1]; 99 cx = (p->o_val[2] + p->o_val[0]) / 2; /* geom ctr of [] wrt local orogin */ 100 cy = (p->o_val[3] + p->o_val[1]) / 2; 101 dprintf("cx,cy=%g,%g\n", cx, cy); 102 for (i = 0; i < nattr; i++) { 103 ap = &attr[i]; 104 switch (ap->a_type) { 105 case HEIGHT: 106 h = ap->a_val.f; 107 break; 108 case WIDTH: 109 w = ap->a_val.f; 110 break; 111 case WITH: 112 with = ap->a_val.i; /* corner */ 113 break; 114 case PLACE: /* actually with position ... */ 115 ppos = ap->a_val.o; 116 xwith = cx - ppos->o_x; 117 ywith = cy - ppos->o_y; 118 with = PLACE; 119 break; 120 case AT: 121 case FROM: 122 ppos = ap->a_val.o; 123 curx = ppos->o_x; 124 cury = ppos->o_y; 125 at++; 126 break; 127 case INVIS: 128 invis = INVIS; 129 break; 130 case TEXTATTR: 131 savetext(ap->a_sub, ap->a_val.p); 132 break; 133 } 134 } 135 if (with) { 136 switch (with) { 137 case NORTH: ywith = -h / 2; break; 138 case SOUTH: ywith = h / 2; break; 139 case EAST: xwith = -w / 2; break; 140 case WEST: xwith = w / 2; break; 141 case NE: xwith = -w / 2; ywith = -h / 2; break; 142 case SE: xwith = -w / 2; ywith = h / 2; break; 143 case NW: xwith = w / 2; ywith = -h / 2; break; 144 case SW: xwith = w / 2; ywith = h / 2; break; 145 } 146 curx += xwith; 147 cury += ywith; 148 } 149 if (!at) { 150 if (isright(hvmode)) 151 curx += w / 2; 152 else if (isleft(hvmode)) 153 curx -= w / 2; 154 else if (isup(hvmode)) 155 cury += h / 2; 156 else 157 cury -= h / 2; 158 } 159 x0 = curx - w / 2; 160 y0 = cury - h / 2; 161 x1 = curx + w / 2; 162 y1 = cury + h / 2; 163 extreme(x0, y0); 164 extreme(x1, y1); 165 p->o_x = curx; 166 p->o_y = cury; 167 p->o_nt1 = ntext1; 168 p->o_nt2 = ntext; 169 ntext1 = ntext; 170 p->o_val[0] = w; 171 p->o_val[1] = h; 172 p->o_val[2] = cx; 173 p->o_val[3] = cy; 174 p->o_val[5] = q->o_nobj - 1; /* last item in [...] */ 175 p->o_ddval = ddval; 176 p->o_attr = invis; 177 dprintf("[] %g %g %g %g at %g %g, h=%g, w=%g\n", x0, y0, x1, y1, curx, cury, h, w); 178 if (isright(hvmode)) 179 curx = x1; 180 else if (isleft(hvmode)) 181 curx = x0; 182 else if (isup(hvmode)) 183 cury = y1; 184 else 185 cury = y0; 186 for (i = 0; i <= 5; i++) 187 q->o_val[i] = p->o_val[i]; 188 stack[nstack+1].p_symtab = NULL; /* so won't be found again */ 189 blockadj(p); /* fix up coords for enclosed blocks */ 190 return(p); 191 } 192 193 blockadj(p) /* adjust coords in block starting at p */ 194 obj *p; 195 { 196 obj *q; 197 float dx, dy; 198 int n, lev; 199 200 dx = p->o_x - p->o_val[2]; 201 dy = p->o_y - p->o_val[3]; 202 n = p->o_nobj + 1; 203 q = objlist[n]; 204 dprintf("into blockadj: dx,dy=%g,%g\n", dx, dy); 205 for (lev = 1; lev > 0; n++) { 206 p = objlist[n]; 207 if (p->o_type == BLOCK) 208 lev++; 209 else if (p->o_type == BLOCKEND) 210 lev--; 211 dprintf("blockadj: type=%d o_x,y=%g,%g;", p->o_type, p->o_x, p->o_y); 212 p->o_x += dx; 213 p->o_y += dy; 214 dprintf(" becomes %g,%g\n", p->o_x, p->o_y); 215 switch (p->o_type) { /* other absolute coords */ 216 case LINE: 217 case ARROW: 218 case SPLINE: 219 p->o_val[0] += dx; 220 p->o_val[1] += dy; 221 break; 222 case ARC: 223 p->o_val[0] += dx; 224 p->o_val[1] += dy; 225 p->o_val[2] += dx; 226 p->o_val[3] += dy; 227 break; 228 } 229 } 230 } 231