-- 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.