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