-- procedure exporting module of silicon (pretty picture) program -- last modified by E. McCreight, February 2, 1983 3:40 PM DIRECTORY InlineDefs, SegmentDefs, StringDefs, multiGraphicsDefs, ppddefs, ppdddefs, ppdefs; ppprocs6:PROGRAM IMPORTS ppddefs,ppdddefs, ppdefs, multiGraphicsDefs, InlineDefs EXPORTS ppdddefs, ppddefs = BEGIN OPEN ppdefs, ppddefs, ppdddefs,SegmentDefs, InlineDefs, multiGraphicsDefs; lp: LONG POINTER TO list; noChange: PUBLIC BOOLEAN; cChange, bChange: PUBLIC BOOLEAN; doingAreaSel: PUBLIC BOOLEAN; didBW:PUBLIC BOOLEAN←FALSE; doMove: PUBLIC cmdProc = BEGIN dx, dy: INTEGER; dx ← xx - markPnt.x; dy ← yy - markPnt.y; movSel[dx, dy]; putMark[xx, yy,FALSE]; END; lList:TYPE = RECORD[nxt:LONG POINTER TO lList,lp:LONG POINTER TO list, horz,top,bot:BOOLEAN←FALSE]; noMatches:PROCEDURE[rt:Rect,llt,ll:LONG POINTER TO lList,primary:BOOLEAN] RETURNS[BOOLEAN] = BEGIN rb:Rect; top,bot:BOOLEAN; rb.x2←rt.x2; rb.y2←rt.y2; IF BITAND[llt.lp.idx,4] = 0 THEN BEGIN rb.x1←rt.x1; rb.y1←rt.y2; rt.y2←rt.y1; END ELSE BEGIN rb.x1←rt.x2; rb.y1←rt.y1; rt.x2←rt.x1; llt.horz←TRUE; END; WHILE ll#NIL DO IF rb.x2>=ll.lp.lx AND rb.y2>=ll.lp.ly THEN BEGIN ii:CARDINAL←IF BITAND[ll.lp.idx,4]=0 THEN 0 ELSE 1; top←rt.x2>=ll.lp.lx AND rt.y2>=ll.lp.ly AND rt.x1<=ll.lp.lx+ll.lp.ob.size[ii] AND rt.y1<=ll.lp.ly+ll.lp.ob.size[ii+1]; bot←rb.x2>=ll.lp.lx AND rb.y2>=ll.lp.ly AND rb.x1<=ll.lp.lx+ll.lp.ob.size[ii] AND rb.y1<=ll.lp.ly+ll.lp.ob.size[ii+1]; IF top OR bot THEN BEGIN WITH ob:ll.lp.ob↑ SELECT FROM cell,rect => NULL; wire,bus => BEGIN IF ob.l#llt.lp.ob.l THEN top←bot←FALSE; IF NOT primary AND ll.horz=llt.horz THEN top←bot←FALSE; END; xstr => BEGIN IF llt.lp.ob.l=met THEN top←bot←FALSE; END; cont => BEGIN SELECT llt.lp.ob.l FROM dif => IF ob.typ=mPol THEN top←bot←FALSE; pol => IF ob.typ=mDif THEN top←bot←FALSE; met => IF ob.typ=burr THEN top←bot←FALSE; ENDCASE => top←bot←FALSE; END; ENDCASE => top←bot←FALSE; llt.top←llt.top OR top; llt.bot←llt.bot OR bot; END; END; ll←ll.nxt; ENDLOOP; RETURN[NOT (llt.top OR llt.bot)]; END; freeuplList:PROCEDURE[l:LONG POINTER TO lList] = BEGIN ll:LONG POINTER TO lList; WHILE l#NIL DO ll←l.nxt; FreeSpace[l]; l←ll; ENDLOOP; END; fiddleWire:PROCEDURE[ll:LONG POINTER TO lList,dx,dy:INTEGER,primary:BOOLEAN]= BEGIN mx:INTEGER←dx; my:INTEGER←dy; r:Rect←getRect[ll.lp]; IF ll.top THEN BEGIN IF NOT primary THEN {IF ll.horz THEN my←0 ELSE mx←0;}; IF NOT ll.bot THEN []←ll.lp.ob.p.setParm[ll.lp,length, -(IF ll.horz THEN dx ELSE dy),1,FALSE]; END ELSE IF ll.bot THEN BEGIN IF ll.horz THEN {mx←0;IF NOT primary THEN my←0;} ELSE {my←0;IF NOT primary THEN mx←0;}; []←ll.lp.ob.p.setParm[ll.lp,length, (IF ll.horz THEN dx ELSE dy),1,FALSE]; END ELSE RETURN; moveOb[ll.lp,mx,my]; reDrawRect[r, 1, TRUE, TRUE, FALSE]; reDrawRect[getRect[ll.lp], 0, TRUE, TRUE, FALSE]; END; movSel: PROCEDURE [dx, dy: INTEGER] = BEGIN anyChanges ← sinceIOchanges ← TRUE; IF Stretchy THEN BEGIN ll1,ll2,ll3,ll4:LONG POINTER TO lList←NIL; llt,lltt:LONG POINTER TO lList; rt,rm:Rect; lp←masterList; WHILE lp#NIL DO IF lp.selected THEN BEGIN rt←getRect[lp]; IF ll1=NIL THEN rm←rt ELSE rm←mergeRects[rm,rt]; llt←GetSpace[SIZE[lList]]; llt↑←[ll1,lp]; ll1←llt; END; lp ← lp.nxt; ENDLOOP; IF ll1=NIL THEN RETURN; lp←masterList; WHILE lp#NIL DO IF lp.ob.otyp=wire AND NOT lp.selected THEN BEGIN llt←GetSpace[SIZE[lList]]; llt↑←[nxt:NIL,lp:lp]; IF lp.lx>rm.x2 OR lp.ly>rm.y2 OR (rt←getRect[lp]).x2<rm.x1 OR rt.y2<rm.y1 OR noMatches[rt,llt,ll1,TRUE] THEN {llt.nxt←ll3;ll3←llt} ELSE {llt.nxt←ll2;ll2←llt}; END; lp ← lp.nxt; ENDLOOP; lltt←ll3; ll3←NIL; WHILE lltt#NIL DO llt←lltt; lltt←llt.nxt; rt←getRect[llt.lp]; IF noMatches[rt,llt,ll2,FALSE] THEN {llt.nxt←ll4;ll4←llt} ELSE {llt.nxt←ll3;ll3←llt}; ENDLOOP; freeuplList[ll4]; llt←ll3; WHILE llt#NIL DO fiddleWire[llt,dx,dy,FALSE]; llt←llt.nxt; ENDLOOP; llt←ll2; WHILE llt#NIL DO fiddleWire[llt,dx,dy,TRUE]; llt←llt.nxt; ENDLOOP; llt←ll1; WHILE llt#NIL DO moveOb[llt.lp,dx,dy]; llt←llt.nxt; ENDLOOP; freeuplList[ll3]; freeuplList[ll2]; freeuplList[ll1]; RETURN; END; lp ← masterList; WHILE lp # NIL DO IF lp.selected THEN moveOb[lp, dx, dy]; lp ← lp.nxt; ENDLOOP; END; movUp: PUBLIC cmdProc = {movSel[0, -Lambda]}; movDn: PUBLIC cmdProc = {movSel[0, Lambda]}; movLft: PUBLIC cmdProc = {movSel[-Lambda, 0]}; movRgt: PUBLIC cmdProc = {movSel[Lambda, 0]}; dispErf: PUBLIC cmdProc = BEGIN x, y: INTEGER; st: STRING; b: BOOLEAN; i: INTEGER; [x, y, st, b] ← rdErfLine[]; IF st.length = 0 THEN RETURN; noChange ← TRUE; EraseArea[200, 640, 606, 660]; ReplaceArea[195, 641, 196, 659]; i ← ReplaceText[st, 200, 656, fnt, normal]; ReplaceArea[195, 641, i + 8, 642]; ReplaceArea[195, 658, i + 8, 659]; ReplaceArea[i + 8, 641, i + 9, 659]; IF b THEN BEGIN cChange ← TRUE; setCoffset[x, y]; markPnt ← [x, y]; END; END; rotSel: PUBLIC cmdProc = BEGIN rotReflSel[FALSE]; END; rotPnt: PUBLIC cmdProc = BEGIN IF NOT bb THEN RETURN; rotReflPnt[FALSE, xx, yy]; END; mirrorSel: PUBLIC cmdProc = BEGIN rotReflSel[TRUE]; END; mirrorPnt: PUBLIC cmdProc = BEGIN IF bb THEN rotReflPnt[TRUE, xx, yy]; END; setCols: PUBLIC cmdProc = BEGIN setColors[]; dChange ← TRUE; END; doCopy: PUBLIC cmdProc = BEGIN dx, dy: INTEGER; anyChanges ← sinceIOchanges ← TRUE; dx ← xx - markPnt.x; dy ← yy - markPnt.y; lp ← masterList; WHILE lp # NIL DO IF lp.selected THEN BEGIN lp.selected ← FALSE; masterList ← copyObject[lp, masterList, dx, dy]; masterList.selected ← TRUE; END; lp ← lp.nxt; ENDLOOP; putMark[xx, yy,FALSE]; dChange ← TRUE; END; putMark: PUBLIC PROCEDURE [xx, yy: INTEGER, bw:BOOLEAN←FALSE] = BEGIN ww: INTEGER ← ((cScaleN + 16)*cScaleD)/cScaleN; qq: INTEGER ← ((bwScaleN + 15)*bwScaleD)/bwScaleN; x, y: INTEGER; [x, y] ← markPnt; markPnt ← [xx, yy]; markDPnt ← [xx - x, yy - y]; reDrawRect[[x, y, x + ww, y + ww], 1, FALSE, TRUE, FALSE]; IF didBW THEN reDrawRect[[x, y, x + qq, y + qq], 1, TRUE, FALSE, FALSE]; didBW←bw; reDrawRect[[xx, yy, xx + ww, yy + ww], 0, FALSE, TRUE, FALSE]; IF bw THEN reDrawRect[[xx, yy, xx + qq, yy + qq], 0, TRUE, FALSE, FALSE]; IF NOT doingAreaSel THEN selMarkPnt ← markPnt; END; setBWoffset: PUBLIC PROCEDURE [x, y: INTEGER] = {CenterAndScale[center: [x, y], scale: bwScale, bw: TRUE]}; setCoffset: PUBLIC PROCEDURE [x, y: INTEGER] = {CenterAndScale[center: [x, y], scale: cScale, col: TRUE]}; setBWscale: PUBLIC PROCEDURE [qq: INTEGER] = BEGIN xx, yy: INTEGER; [, xx, yy] ← deScaledCursor[colWidth + 303, bwBottom/2]; CenterAndScale[center: [xx, yy], scale: qq, bw: TRUE]; END; setCscale: PUBLIC PROCEDURE [qq: INTEGER] = BEGIN xx, yy: INTEGER; [, xx, yy] ← deScaledCursor[colWidth/2, colHeight/2]; CenterAndScale[center: [xx, yy], scale: qq, col: TRUE]; END; END.