#include "defs.h" /* * Delete all entries contained within a given rectangle. */ delarea(head) DL head; { DL1 p1, p2; chkhd(head, "MwcBL"); markarea(p1, p2); scanarea(head, p1, p2, nil(DL), 2); } /* * Move all entries within a rectangle to another area of the drawing * or to/from a file * * head is zero for global move, item addr otherwise * k is command letter 'm', 't', 'M', 'T' * M and T followed by >< */ INT movearea(head, k) DL head; CHAR k; { ITEM in; DL1 p1, p2, p3; CHAR k1; INT marked=0; INT mv=0; INT result; chkhd(head, "MwcBL"); result = head->type=='M'; if(any(head->type, "wc")) { showh(head, 0); } openfd = -1; switch(k) { case 'U': p1->x=maxx-1; p1->y=maxy-1; p2->x=0; p2->y=0; marked++; case 'T': case 'M': k1=key(); break; case 't': openfd=maketmp(2); if(openfd<0) error("cannot create tmp file"); default: k1=0; } switch(k1) { case '<': /* from file */ rdname(in, sizeof(in)); fileopen(in, 0); chkrd(openfd, adr(p1), DLPSIZ); chkrd(openfd, adr(p2), DLPSIZ); if(p1->type != 't' || p2->type != 't') error("not a copy file"); marked++; break; case '>': /* to file */ rdname(in, sizeof(in)); fileopen(in, 1); break; case 0: k1=k; break; default: error("bad T,M or U"); } if(marked==0) markarea(p1, p2); switch(k1){ case '>': if(k=='U') Lseek(openfd, 0L, 2); case 't': scanarea(head, p1, p2, nil(DL), 0); } switch(k) { case 'M': mv++; if(k1 != '<') scanarea(head, p1, p2, nil(DL), 2); } switch(k1){ case '<': case 't': do{ if(k=='U'){ lastnum=0; p3->x=p3->y=0; result++; } else markdest(p1, p2, p3); getall(head, p3, mv); } while(--lastnum > 0); break; case 'm': markdest(p1, p2, p3); scanarea(head, p1, p2, p3, 1); } fileclose(); return(result); } /* * routine to get part of a drawing from file * * head is zero for global, chip or wire modes * otherwise is addr of header into which inserting * p is place drawing is to go. * p is zero if coords to remain unchanged * mv is true if inserted picture comes a move command */ getall(head, p, mv) REG DL head, p; INT mv; { DLH1 mword; DL1 p1, p2; REG DL op; DL hp; DL np; INT dx, dy; INT k, f; Lseek(openfd, 0L, 0); chkrd(openfd, adr(p1), DLPSIZ); chkrd(openfd, adr(p2), DLPSIZ); dx = p->x - p2->x; dy = p->y - p2->y; chkcur(p); chkcur(offset(p1, dx, dy)); hp = 0; while(1) { chkrd(openfd, adr(mword), DLHSIZ); k=mword->type; f=mword->flag; switch(k){ case 'M': case 'B': case 'L': if (hp) showh(hp, 0); if (head->type != k) error("get context error"); hp = op = head; ignore(f); break; case 'Z': if (hp) showh(hp, 0); return; case 'c': case 'w': if (hp) showh(hp, 0); if (head->type=='M' || head->type==k) { if(hp) cleanit(hp); op = last(k); rdin(op, f); if(op->flag&END) { delete(op); } elif( (np=findname(k, dln(op)->name)) && (np!=op) ) { if(mv) { delete(op); op = np; } else { fixname(op, noname(), ctype(op)); } } } else error("get context error"); hp = op; break; case 'a': case 'A': case 'b': case 'o': case 'e': case 'h': case 'p': case 'v': case 'V': rdin(op, f); mvone(op, dx, dy); break; default: error("file format error"); } op = succa(op); } } LOC ignore(siz) INT siz; { DL1 t; chkrd(openfd, adr(t), siz); } /* * move one item * * p is addr of item. * dx and dy are amount to move */ LOC mvone(p, dx, dy) REG DL p; INT dx, dy; { switch(p->type){ case 'a': case 'A': case 'o': case 'h': case 'p': case 'e': case 'v': case 'V': case 'X': p->x += dx; p->y += dy; } } /* * scans an area for move put and delete * * transfer drawing from one place to another. * points p1, p2 define source. * destination is file if p3 is nil * scan main drawing area if head is zero, othewise just that item */ scanarea(head, p1, p2, p3, fn) DL head, p1, p2, p3; INT fn; { REG DL p, q; DLH1 eofmark; CHAR endc; INT dx, dy; DL h=0; DL pred; INT f; switch(fn) { case 0: p1->type = p2->type = 't'; chkwt(openfd, adr(p1), DLPSIZ); chkwt(openfd, adr(p2), DLPSIZ); break; case 1: dx = p3->x - p2->x; dy = p3->y - p2->y; chkcur(p3); chkcur(offset(p1, dx, dy)); } p = head; endc = p->type; while(p) { q=succa(p); switch(p->type){ case 'w': h=p; case 'L': case 'B': case 'c': case 'M': switch(fn) { case 0: putone(p, 0); break; case 1: break; case 2: break; } break; case 'e': f=START; pred=nil(DL); while(p->type=='e') { q=succa(p); if(within(p1,p,p2)) { if(q->type!='e' || !within(p1,q,p2)) { f |= END; } switch(fn) { case 0: if(f!=(START|END)) putone(p, f); break; case 1: if(h) h->flag |= DIRTY; mvone(p, dx, dy); break; case 2: if(h) h->flag |= DIRTY; if((p->flag&START)==0) { if(pred) pred->flag |= END; } if((p->flag&END)==0) { if(q->type=='e') q->flag |= START; } delete(p); q=p; p=0; } /* when q outside box f&END is true */ if(f&END) f=START; else f=0; } pred=p; p=q; } q=p; break; case 'a': case 'o': if(within(p1, p, p2) && within(p1, q, p2)){ switch(fn) { case 0: putone(p, 0); break; case 1: mvone(p, dx, dy); break; case 2: delete(p); q=p; break; } } else break; p=q; q=succa(p); case 'h': case 'p': case 'v': case 'V': if(within(p1, p, p2)) { switch(fn) { case 0: putone(p, 0); break; case 1: mvone(p, dx, dy); break; case 2: delete(p); q=p; break; } } break; case 'X': case 'x': break; } if((q->type)!=endc) p=q; else p=nil(DL); } switch(fn) { case 0: eofmark->type = 'Z'; chkwt(openfd, adr(eofmark), DLHSIZ); } } /* * * p is addr of entry to be output * */ LOC putone(p, f) REG DL p; INT f; { DLH1 mword; INT saveflag=p->flag; REG S_POS L; mword->type = p->type; mword->flag = L = len(p); p->flag|=f; chkwt(openfd, adr(mword), DLHSIZ); chkwt(openfd, adr(p), L); p->flag=saveflag; } /* * read one item from file * * p is addr of item before which to insert * n is size of item to be read from file */ LOC rdin(p, n) REG DL p; REG INT n; { movedown(p, n); if (chkrd(openfd, adr(p), n) == 0){ moveup(p, n); fileclose(); error("read error in get"); } }