-- monochrome screen drawing module of silicon (pretty picture) program -- last modified by E. McCreight, March 29, 1983 12:13 PM DIRECTORY ChipOrient, InlineDefs, IODefs, AltoDefs, AltoFileDefs, MiscDefs, multiGraphicsDefs, SegmentDefs, ProcessDefs, ppdddefs,ppddefs, ppdefs, ppoutdefs; ppdrawBW: PROGRAM IMPORTS ChipOrient, ppdefs, ppddefs, InlineDefs, MiscDefs, multiGraphicsDefs, ProcessDefs, SegmentDefs, ppdddefs, ppoutdefs EXPORTS ppdefs, ppddefs = BEGIN OPEN ppdefs, ppddefs, ppdddefs,InlineDefs, multiGraphicsDefs, SegmentDefs, IODefs; bwScale: PUBLIC INTEGER ← 8; bwScaleN: PUBLIC INTEGER ← 1; bwScaleD: PUBLIC INTEGER ← 2; bwxoff, bwyoff: PUBLIC INTEGER ← 0; bwClipx1: PUBLIC INTEGER ← 0; bwClipx2: PUBLIC INTEGER ← 1212; bwClipy1: PUBLIC INTEGER ← 0; bwClipy2: PUBLIC INTEGER ← 1278; fnt: PUBLIC POINTER TO StrikeFont; bwCurs: PUBLIC ARRAY [0..15] OF CARDINAL ← [ 177400B, 177000B, 176000B, 176000B, 177000B, 177400B, 147600B, 103700B, 1740B, 760B, 370B, 174B, 76B, 37B, 16B, 4B]; bwCursI: PUBLIC ARRAY [0..15] OF CARDINAL ← [ 0B, 76000B, 74000B, 74000B, 76000B, 47000B, 03400B, 01600B, 700B, 340B, 160B, 70B, 34B, 16B, 4B, 0B]; bwCurs4: ARRAY [0..15] OF CARDINAL ← [ 140160B, 20774B, 21774B, 23776B, 23776B, 20776B, 20376B, 20174B, 20030B, 20034B, 20036B, 70077B, 77777B, 37777B, 20177B, 20177B]; bwCurs2: ARRAY [0..15] OF CARDINAL ← [ 170000B, 103740B, 117770B, 137774B, 37774B, 60006B, 63146B, 60006B, 60006B, 60006B, 160607B, 150013B, 146063B, 141703B, 140603B, 140603B]; bwCurs1: ARRAY [0..15] OF CARDINAL ← [ 100160B, 60370B, 70160B, 24040B, 22370B, 11406B, 4405B, 3405B, 776B, 404B, 404B, 404B, 774B, 120B, 120B, 734B]; grayLtab: ARRAY level OF Color ← [10, 1, 4, 2, 14, 8, 8, 10, 10,1,10,11,10,13,10,10]; bwscale: PROCEDURE [x, y: INTEGER] RETURNS [INTEGER, INTEGER] = INLINE BEGIN RETURN[((bwxoff + x)*bwScaleN)/bwScaleD, ((bwyoff + y)*bwScaleN)/bwScaleD]; END; bwscaleRect: PUBLIC PROCEDURE [x1, y1, x2, y2: INTEGER] RETURNS [BOOLEAN, INTEGER, INTEGER, INTEGER, INTEGER] = BEGIN t: INTEGER; IF x1 > x2 THEN BEGIN t ← x1; x1 ← x2; x2 ← t; END; IF y1 > y2 THEN BEGIN t ← y1; y1 ← y2; y2 ← t; END; IF x1 > bwClipx2 OR x2 < bwClipx1 OR y1 > bwClipy2 OR y2 < bwClipy1 THEN RETURN[FALSE, 0, 0, 0, 0]; [x1, y1] ← bwscale[MAX[x1, bwClipx1], MAX[y1, bwClipy1]]; [x2, y2] ← bwscale[MIN[x2, bwClipx2], MIN[y2, bwClipy2]]; RETURN[TRUE, x1, y1, x2, y2]; END; bwsAndClip: PROCEDURE [x1, y1, x2, y2: INTEGER, cr: POINTER TO Rect] RETURNS [BOOLEAN, INTEGER, INTEGER, INTEGER, INTEGER] = INLINE BEGIN IF x1 > cr.x2 OR x2 < cr.x1 OR y1 > cr.y2 OR y2 < cr.y1 THEN RETURN[FALSE, 0, 0, 0, 0]; [x1, y1] ← bwscale[MAX[x1, cr.x1], MAX[y1, cr.y1]]; [x2, y2] ← bwscale[MIN[x2, cr.x2], MIN[y2, cr.y2]]; RETURN[TRUE, x1, y1, x2, y2]; END; outlineBW: PUBLIC PROCEDURE [ w, x, y, z: INTEGER, q: color, clip: POINTER TO Rect ← NIL] = BEGIN oulBwArea[w, x, w, z, clip]; oulBwArea[y, x, y, z, clip]; oulBwArea[w, z, y, z, clip]; oulBwArea[w, x, y, x, clip]; END; orBwArea: PUBLIC PROCEDURE [ w, x, y, z: INTEGER, l: level, clip: POINTER TO Rect ← NIL] = BEGIN a, b, c, d: INTEGER; bb: BOOLEAN; [bb, a, b, c, d] ← bwsAndClip[w, x, y, z, clip]; IF bb THEN BEGIN SetGrayLevel[grayLtab[l]]; PutGray[a, b, c, d]; END; END; oulBwArea: PROCEDURE [ w, x, y, z: INTEGER, clip: POINTER TO Rect ← NIL] = BEGIN a, b, c, d: INTEGER; bb: BOOLEAN; [bb, a, b, c, d] ← bwsAndClip[w, x, y, z, clip]; IF bb THEN PutArea[a, b, c, d]; END; repBwArea: PUBLIC PROCEDURE [ w, x, y, z: INTEGER, l: level, clip: POINTER TO Rect ← NIL] = BEGIN a, b, c, d: INTEGER; bb: BOOLEAN; IF clip = NIL THEN [bb, a, b, c, d] ← bwscaleRect[w, x, y, z] ELSE [bb, a, b, c, d] ← bwsAndClip[w, x, y, z, clip]; IF bb THEN BEGIN SetGrayLevel[grayLtab[l]]; ReplaceGray[a, b, c, d]; END; END; eraseBwArea: PUBLIC PROCEDURE [w, x, y, z: INTEGER] = BEGIN a, b, c, d: INTEGER; bb: BOOLEAN; [bb, a, b, c, d] ← bwscaleRect[w, x, y, z]; IF bb THEN EraseArea[a, b, c, d]; END; drawBwMark: PROCEDURE [x, y: INTEGER] = BEGIN a, b, i: INTEGER; bb: BOOLEAN; [bb, a, b,,] ← bwscaleRect[x, y, x, y]; IF bb THEN BEGIN PutArea[a,b,a+6,b]; PutArea[a,b,a,b+6]; FOR i IN [1..6] DO PutPoint[a+i,b+i];ENDLOOP; END; END; drawBWText: PUBLIC PROCEDURE [ x, y, sx, sy: INTEGER, s: STRING, clip: POINTER TO Rect] = BEGIN a, b, c, d: INTEGER; bb: BOOLEAN; IF x + 4 < bwClipx1 THEN RETURN; IF clip = NIL THEN [bb, a, b, c, d] ← bwscaleRect[x, y, x + sx, y + sy] ELSE [bb, a, b, c, d] ← bwsAndClip[x, y, x + sx, y + sy, clip]; IF bb THEN BEGIN c ← ReplaceText[s, a, b, fnt, normal]; END; END; drawBWText10: PROCEDURE [ x, y, sx, sy: INTEGER, s: STRING, clip: POINTER TO Rect] = BEGIN a, b, c, d: INTEGER; bb: BOOLEAN; IF x + 5 < bwClipx1 THEN RETURN; IF clip = NIL THEN [bb, a, b, c, d] ← bwscaleRect[x, y, x, yy] ELSE [bb, a, b, c, d] ← bwsAndClip[x, y, x, y, clip]; IF bb THEN BEGIN c ← ReplaceText[s, a + 1, b + 11, fnt, normal]; END; END; drawString: PUBLIC PROCEDURE [s: STRING, x, y: INTEGER] = BEGIN pos: CARDINAL; pos ← ReplaceText[s, x, y, fnt, normal]; pos ← ReplaceText[" ", pos, y, fnt, normal]; END; bwremArray: LONG DESCRIPTOR FOR ARRAY OF rems ← DESCRIPTOR[ LongDataSegmentAddress[NewDataSegment[DefaultANYBase, remPages]], remLen]; bwremIdx: CARDINAL ← 0; bwDrR: drRecord ← [ [0, 0, 0, 0], [0, 0, 0, 0], orBwArea, rememberBW, outlineBW, drawBWText10, 1]; abortBW: PUBLIC BOOLEAN ← FALSE; updateBW: PUBLIC PROC = BEGIN OPEN ProcessDefs; DO bp: LONG CARDINAL; dangerousUpdateBW[! ANY => {MiscDefs.CallDebugger[ "B/W repainter signalled, ↑P to continue after next backup pass"]; CONTINUE}]; bp ← ppoutdefs.backupPass; WHILE ppoutdefs.backupPass=bp DO Pause[SecondsToTicks[1]] ENDLOOP; ENDLOOP; END; dangerousUpdateBW: PROC = BEGIN BWPaintList: PROC [head: LONG POINTER TO listPtr, background: BOOLEAN ← FALSE, pushee: listPtr ← NIL] = BEGIN next: listPtr; finished: BOOLEAN ← FALSE; WHILE NOT (finished OR abortBW) DO FOR lp: listPtr ← head↑, next WHILE lp # NIL DO next ← lp.nxt; IF abortBW OR lp.deleted THEN EXIT; IF lp # pushee THEN BEGIN lp.ob.p.drawme[lp.idx][lp.ob, lp.lx, lp.ly, @bwDrR]; IF lp.selected AND NOT background THEN BEGIN ii: [0..1] = ChipOrient.Rot90[lp.idx]; outlineBW[ lp.lx, lp.ly, lp.lx + lp.ob.size[ii], lp.ly + lp.ob.size[1-ii], 15, @bwEScreenRect]; END; END; IF NOT background THEN BEGIN ps: STRING ← [200]; ps.length ← 0; AppendProps[to: ps, from: lp.props]; IF ps.length>0 THEN drawBWText10[lp.lx, lp.ly, 0, 0, ps, @bwEScreenRect]; END; ProcessDefs.Yield[]; REPEAT FINISHED => finished ← TRUE; ENDLOOP; ENDLOOP; END; -- of BWPaintList doBwRemember: PROC [first, afterLast: CARDINAL] = BEGIN r: Rect; l: level; FOR i: CARDINAL IN [first..afterLast) DO IF abortBW THEN RETURN; [r: r, l: l] ← bwremArray[i]; repBwArea[r.x1, r.y1, r.x2, r.y2, l, NIL]; ENDLOOP; END; -- of doBwRemember bwScreenRect, bwEScreenRect: Rect; cmd: sCmd; ProcessDefs.SetPriority[0]; abortBW ← FALSE; DO ProcessDefs.Yield[]; cmd ← getBwNewRect[]; bwScreenRect ← [x1: bwClipx1, y1: bwClipy1, x2: bwClipx2, y2: bwClipy2]; -- entire b/w design screen in design coords, can be changed by user cmd bwEScreenRect ← [x1: bwScreenRect.x1-1, y1: bwScreenRect.y1-1, x2: bwScreenRect.x2+1, y2: bwScreenRect.y2+1]; bwDrR.minSize ← (bwGrain*bwScaleD)/bwScaleN; SELECT cmd.cmd FROM rect, all => BEGIN r, cmprect: Rect; bwRemBkgIdx: CARDINAL; SELECT cmd.cmd FROM all => r ← bwScreenRect; ENDCASE => BEGIN cmd.r ← cannonRect[cmd.r]; r ← ClipRect[cmd.r, bwScreenRect]; END; cmprect ← bwDrR.bigr ← [x1: MAX[bwScreenRect.x1, r.x1 - wellSurround], x2: MIN[bwScreenRect.x2, r.x2 + wellSurround], y1: MAX[bwScreenRect.y1, r.y1 - wellSurround], y2: MIN[bwScreenRect.y2, r.y2 + wellSurround]]; bwDrR.r ← r ← IF NOT cmd.ers THEN r ELSE cmprect; IF cmd.ers THEN eraseBwArea[cmprect.x1, cmprect.y1, cmprect.x2, cmprect.y2]; bwremIdx ← 0; FOR bkg: LONG POINTER TO cellSE ← cellStack, bkg.nxt WHILE bkg#NIL AND bkg.instance#NIL DO IF abortBW THEN EXIT; BWPaintList[head: @bkg.lp, background: TRUE, pushee: bkg.instance]; ENDLOOP; -- dim out the background here bwRemBkgIdx ← bwremIdx; BWPaintList[IF cellNameMode THEN @cnList ELSE @masterList]; doBwRemember[first: 0, afterLast: bwRemBkgIdx]; -- make these dim doBwRemember[first: bwRemBkgIdx, afterLast: bwremIdx]; IF didBW AND NOT abortBW THEN drawBwMark[markPnt.x, markPnt.y]; -- show where the color display is [, savCBbox.x1, savCBbox.y1] ← deScaledCursor[0, 0]; [, savCBbox.x2, savCBbox.y2] ← deScaledCursor[colWidth-1, colHeight-1]; IF NOT (abortBW OR cellNameMode) THEN outlineBW[ savCBbox.x1, savCBbox.y1, savCBbox.x2, savCBbox.y2, 0, @bwEScreenRect]; END; sel => BEGIN lp: listPtr = cmd.p; ii: [0..1] = ChipOrient.Rot90[lp.idx]; outlineBW[lp.lx, lp.ly, lp.lx + lp.ob.size[ii], lp.ly + lp.ob.size[1-ii], 15, @bwEScreenRect]; END; ENDCASE => ERROR; ENDLOOP; END; rememberBW: PROCEDURE [ x1, y1, x2, y2: INTEGER, l: level, clip: POINTER TO Rect] = BEGIN IF bwremIdx >= remLen OR (l = cut AND bwScale < 8) THEN RETURN; bwremArray[bwremIdx].r ← ClipRect[[x1, y1, x2, y2], clip↑]; IF NOT Empty[bwremArray[bwremIdx].r] THEN BEGIN bwremArray[bwremIdx].l ← l; bwremIdx ← bwremIdx + 1; END; END; END.