#include "defs.h" /* * Add a shape or circle instance * * input = {-}[shape]^{^} * - flag: scale shape to other than the default size * shape: shape name -- if omitted, the last name typed is used; * if no 'L' entry exists for this name, the shape is drawn as a rectangle * rot: rotation (0-3) of the shape * ^: position of the center-left side of the shape * or = ^^ for circles. * ^^: position of centre and point on periphery */ achip(head, k, style) DL head; CHAR k; { REG DL p, q; DL1 p1, p2; STRING cnp, rots; INT dir, scaled; ITEM cn; INT k1=k; chkhd(head, "cBL"); if(k=='a') { k1='A'; rdname((cnp = cn), sizeof(cn)); rots=commasep(cnp); if(*cnp == '-'){ cnp++; scaled = 1; } else scaled = 0; if(rots) { dir=geti(rots)&DIR; } else dir=0; } else { dir = 0; scaled = 1; cnp = ""; } /* look for shape at xhairs */ while(cursor(p1)==SP) { copypt(xhairs, p2); q=findname('L', cnp); if(*cnp && q==0) error("shape not found"); if(scaled || *cnp==0) { wchar(p1, '+'); must(cursor(p2)); } if( head->type!='L' && (p=finda(head, p1)) ){ delete(succa(p)); delete(p); } cchip(p1, p2, q, dir, k); p = newdl(BEFORE, succ(head->type, head), k, START|dir, p1, style, cnp, nil(STRING)); newdlw(AFTER, p, k1, END, p2, style); destyl = 0; showh(head, 0); } } /* * compute rectangle p1, p2 containing a shape instance * p1 = 'centre' point * p2 = corner point * if p1 and p2 are same point * use default size * th = shape header or zero * dir is rotation required * k = type of shape, 'a' or 'o'. */ cchip(p1, p2, th, dir, k) REG DL p1, p2; DL th; INT dir; CHAR k; { DL1 r, s, w; INT dx, dy, d, v; DL tx; dx = p1->x - p2->x; dy = p1->y - p2->y; d = dir; if (dx < 0){ dx = -dx; if (dir & 1) d = d ^ 1; else d = 3 - d; } if (dy < 0){ dy = -dy; if (dir & 1) d = 3 - d; else d = d ^ 1; } if (k == 'o'){ if (dy > dx) dx = dy; p2->x = p1->x + dx; p2->y = p1->y + dx; p1->x -= dx; p1->y -= dx; } else { if (th && (tx = succ('x', th))){ copypt(tx, s); if ((tx = succa(tx))->type == 'X') copypt(tx, r); else copypt(point(0, s->y >> 1), r); } else { copypt(point(dx, dy << 1), s); copypt(point(0, dy), r); } copypt(r, w); switch(d){ case 0: break; case 1: case 2: r->y = s->y - r->y; if (d == 1) break; case 3: r->x = s->x - r->x; } if (dir & 1){ v = r->x; r->x = r->y; r->y = v; v = w->x; w->x = w->y; w->y = v; v = s->x; s->x = s->y; s->y = v; } switch(dir){ case 0: break; case 1: case 2: w->x = s->x - w->x; if (dir == 1) break; case 3: w->y = s->y - w->y; break; } if (dx == 0 || r->x == 0) dx = r->x = 1; if (dy == 0 || r->y == 0) dy = r->y = 1; p1->x -= scale(w->x, dx, r->x); p2->x = p1->x + scale(s->x, dx, r->x); p1->y -= scale(w->y, dy, r->y); p2->y = p1->y + scale(s->y, dy, r->y); } chkcur(p1); chkcur(p2); }