-- BoardPaint.mesa
-- last modified by E. McCreight, October 15, 1982 4:21 pm
DIRECTORY
DoradoBoard,
Graphics USING [black, Color, Context, DrawBox, DrawRope, RopeBox,
Restore, Rotate, Save, Scale, SetColor, SetCP, SetPaintMode,
Translate, white, NewContext,
CopyContext, Map, Box, GetBounds, GetDefaultFont, FontRef, FontBox],
GraphicsColor USING [red, green, blue, magenta, cyan, yellow, black],
IO USING [SetIndex, PutFR, int, char],
Real USING [RoundI],
RealFns USING [ArcTanDeg, SqRt, TanDeg],
Rope USING [ROPE],
ViewerClasses USING [PaintProc];
BoardPaint: CEDAR MONITOR
IMPORTS DoradoBoard, Graphics, IO, Real, RealFns
EXPORTS DoradoBoard =
BEGIN OPEN DoradoBoard, Graphics;
------ global module values ------
bottom: Mils = 1410; -- bottom border
left: Mils = 1110; -- left border
chipW: Mils = 800; -- dimensions of a chip
chipH: Mils = 400;
maxRows: INTEGER = 24;
maxCols: INTEGER = 12;
sipH: Mils = 100; -- dimensions of sip
sipW: Mils = 800;
tenth: Mils = 100; -- one hundred Mils = five pixels at scale=1.0
middleWidth: Mils = 750;
MilsBox: TYPE = RECORD[xmin, ymin, xmax, ymax: Mils];
PaintBoard: PUBLIC ENTRY ViewerClasses.PaintProc =
TRUSTED BEGIN
JOIN (FORK DoPaintBoard[self: self, context: context, whatChanged: whatChanged,
clear: clear]);
END;
DoPaintBoard: ViewerClasses.PaintProc =
TRUSTED BEGIN
state: Board = NARROW[self.data];
nextRow: Mils;
[] ← BoardContext[state, context];
[] ← SetPaintMode[context, opaque];
SetColor[context, black];
IF state.showPads AND state.milsPerPixel<20 THEN PaintPads[state, context];
PaintFingers[state, context];
nextRow ← PaintRows[state, context];
PaintFingers[state, context, nextRow+400];
FOR s: SigPadList ← state.signalPads, s.rest WHILE s#NIL DO
PaintSignalInner[state, context, s.first];
ENDLOOP;
END; -- of DoPaintBoard --
PaintSignalInner: PROC [state: Board, context: Context, index: PadIndex] =
TRUSTED BEGIN
IF state.padCount <= index THEN RETURN;
index ← GetCanonicalPad[state, index];
FOR layer: WiringLayer IN WiringLayer DO
IF state.plotLayer[layer] THEN DrawLayer[state, context, layer, index];
ENDLOOP;
END; -- of PaintSignalInner --
DrawLayer: PROC [state: Board, context: Context, layer, count: CARDINAL] =
-- Draw the wires on the corresponding layer.
TRUSTED BEGIN
index: INT ← state.pads[count].segs.l[layer];
IF index # 0 THEN --do nothing if there are no segments to paint
BEGIN
box: MilsBox;
segCount: CARDINAL;
[] ← Save[context];
Translate[context, asiOffset.x, asiOffset.y];
box ← GetMilsBox[context];
SetColor[context, colorTable[layer]];
state.asiFile.SetIndex[index];
segCount ← GetCardinal[state];
FOR i: CARDINAL IN [0 ..segCount) DO
start: Point = GetPoint[state];
end: Point = GetPoint[state];
IF MIN[start.x, end.x]<=box.xmax AND box.xmin<=MAX[start.x, end.x] AND
MIN[start.y, end.y]<=box.ymax AND box.ymin<=MAX[start.y, end.y] THEN
DrawWire[state, context, start.x, start.y, end.x, end.y];
ENDLOOP;
Restore[context];
END;
END; -- of DrawLayer --
DrawWire: PROC [state: Board, context: Context, x, y, xx, yy: Mils] =
TRUSTED BEGIN OPEN RealFns;
dx: REAL = xx-x;
dy: REAL = yy-y;
halfLineWidth: REAL = MAX[2*state.milsPerPixel, 10]/2; -- in mils
[] ← Save[context];
Translate[context, x, y];
Rotate[context, ArcTanDeg[x: dx, y: dy]];
DrawBox[context, [-tanHalf45*halfLineWidth, -halfLineWidth,
SqRt[dx*dx+dy*dy]+tanHalf45*halfLineWidth, halfLineWidth]];
Restore[context];
END; -- of DrawWire --
BoardContext: PUBLIC PROC [state: Board, context: Context ← NIL] RETURNS [Context] =
TRUSTED BEGIN
cx, cy, dx, dy: REAL;
start: Context;
IF context = NIL THEN
context ← NewContext[];
start ← CopyContext[context];
Rotate[context, state.rotAngle];
Scale[context, state.mirFact*state.scale*.05, state.scale*.05];
[dx: cx, dy: cy] ← Map[dc: context, sc: start,
sx: state.boardPicture.ww/2, sy: state.boardPicture.wh/2];
Translate[context, cx-state.center.x, cy-state.center.y];
[dx: cx, dy: cy] ← Map[dc: context, sc: start,
sx: 0, sy: 0];
[dx: dx, dy: dy] ← Map[dc: context, sc: start,
sx: 1, sy: 1];
state.milsPerPixel ← MAX[ABS[dx-cx], ABS[dy-cy]]+.001 -- epsilon --;
RETURN[context];
END;
PaintText: PROC [state: Board, context: Context, height: Mils, center: Point, text: Rope.ROPE,
color: Graphics.Color ← Graphics.black, font: Graphics.FontRef ← NIL] =
TRUSTED BEGIN
xmin, xmax, ymin, ymax, scanLinesPerFontPixel, scaleAdjust: REAL;
IF font = NIL THEN font ← context.GetDefaultFont[];
[ymin: ymin, ymax: ymax] ← FontBox[font];
scanLinesPerFontPixel ← height/(state.milsPerPixel*(ymax-ymin));
scaleAdjust ← state.milsPerPixel*MAX[1.0, Real.RoundI[scanLinesPerFontPixel]]
+ .001 -- epsilon --;
[] ← Save[context];
[xmin: xmin, xmax: xmax] ← RopeBox[font, text];
Translate[context, center.x-scaleAdjust*(xmax+xmin)/2,
center.y-scaleAdjust*(ymax+ymin)/2];
Scale[context, scaleAdjust, scaleAdjust];
SetCP[context, 0, 0];
SetColor[context, color];
DrawRope[context, text];
Restore[context];
END; -- of PaintText --
PaintChip: PROC [state: Board, context: Context, x, y: Mils, chipName: Rope.ROPE] =
TRUSTED BEGIN
SetColor[context, black];
DrawBox[context, [x, y, x+chipW, y+state.milsPerPixel]];
DrawBox[context, [x, y+chipH-state.milsPerPixel, x+chipW, y+chipH]];
DrawBox[context, [x, y, x+state.milsPerPixel, y+chipH]];
DrawBox[context, [x+chipW-state.milsPerPixel, y, x+chipW, y+120]];
DrawBox[context, [x+chipW-state.milsPerPixel, y+chipH-120, x+chipW, y+chipH]];
IF state.showLabels THEN
PaintText[state: state, context: context, height: 200,
center: [x: x+chipW/2, y: y+chipH/2], text: chipName];
END; -- of PaintChip --
PaintFingers: PROC [state: Board, context: Context, fngRow: Mils ← 0] =
TRUSTED BEGIN
box: MilsBox = GetMilsBox[context];
fngW: Mils = 120;
fngH: Mils = 1000;
x: Mils ← 0;
IF box.ymin<=fngRow+fngH+20 AND fngRow<=box.ymax THEN
BEGIN
SetColor[context, black];
DrawBox[context, [x, fngRow, x+boardWidth-20, fngRow+fngH+20]];
SetColor[context, white];
x ← left;
FOR j: INTEGER IN [0 .. 100)
WHILE x < boardWidth DO
DrawBox[context, [x+20, fngRow+20, x+fngW, fngRow+fngH]];
x ← x + fngW;
ENDLOOP;
END;
END; -- of PaintFingers --
PaintPads: PROC [state: Board, context: Context] =
TRUSTED BEGIN
box: MilsBox;
qtrTenth: Mils ← tenth/4;
[] ← Save[context];
Translate[context, asiOffset.x, asiOffset.y];
box ← GetMilsBox[context];
FOR i: CARDINAL IN
[MinPadGE[state, box.xmin] .. MinPadGE[state, box.xmax+1])
DO
p: Point = state.pads[i].p;
IF p.y IN [box.ymin..box.ymax] THEN
BEGIN
SetColor[context, SELECT state.pads[i].type.t FROM
noProbe => GraphicsColor.magenta,
signal => GraphicsColor.yellow,
gnd => GraphicsColor.black,
vee => GraphicsColor.green,
vdd => GraphicsColor.cyan,
vtt => GraphicsColor.blue,
vcc => GraphicsColor.red
ENDCASE => GraphicsColor.black];
DrawBox[context, [p.x-qtrTenth, p.y-qtrTenth, p.x+qtrTenth, p.y+qtrTenth]];
END;
ENDLOOP;
Restore[context];
END; -- of PaintPads --
PaintRows: PROC [state: Board, context: Context] RETURNS [nextRow: Mils] =
TRUSTED BEGIN
box: MilsBox = GetMilsBox[context];
y: Mils;
y ← bottom;
FOR i: INTEGER IN [0 .. maxRows) DO -- paint rows
x: Mils ← left;
IF box.ymin<=y+chipH+tenth/2 AND y<=box.ymax THEN
FOR col: INTEGER IN [0 .. maxCols) DO
IF i=maxRows-1 THEN
PaintText[state, context, 300, [x: x+chipW/2, y: y+chipH+2*tenth],
IO.PutFR[v1: IO.char['A+col]]];
PaintChip[state, context, x, y,
IO.PutFR["%g%02d", IO.char['A + col], IO.int[maxRows-i]]];
SELECT TRUE FROM
col = 5 => { -- paint row numbers
PaintText[state, context, 300,
[x: x+chipW+middleWidth/2, y: y+chipH/2],
IO.PutFR[v1: IO.int[maxRows-i]]];
x ← x + chipW + middleWidth;
};
((col+1) MOD 3) = 0 => x ← x + chipW + 2*tenth; -- every third chip
ENDCASE => x ← x + chipW + tenth;
ENDLOOP;
y ← y + chipH + tenth/2;
IF (i MOD 2) = 0 THEN
BEGIN
IF box.ymin<=y+sipH+tenth/2 AND y<=box.ymax THEN PaintSips[state, context, y];
y ← y + sipH + tenth/2;
END;
ENDLOOP;
nextRow ← y;
END; -- of PaintRows --
PaintSips: PROC [state: Board, context: Context, y: Mils] =
TRUSTED BEGIN
x: Mils ← left;
qtrTenth: Mils ← tenth/4;
FOR col: INTEGER IN [0 .. maxCols) DO
SetColor[context, black];
OutlineBox[context, [x+sipW/2, y+sipH/2], [sipW/2, sipH/2], state.milsPerPixel];
SELECT TRUE FROM
col = 5 => x ← x + sipW + middleWidth;
((col+1) MOD 3) = 0 => x ← x + sipW + 2*tenth;
ENDCASE => x ← x + sipW + tenth;
ENDLOOP;
END; -- of PaintSips --
OutlineBox: PROC [context: Context, center, radius: Point, width: REAL] =
BEGIN
DrawBox[context, [center.x-radius.x, center.y-radius.y,
center.x-radius.x+width, center.y+radius.y]];
DrawBox[context, [center.x-radius.x, center.y-radius.y,
center.x+radius.x, center.y-radius.y+width]];
DrawBox[context, [center.x-radius.x, center.y+radius.y-width,
center.x+radius.x, center.y+radius.y]];
DrawBox[context, [center.x+radius.x-width, center.y-radius.y,
center.x+radius.x, center.y+radius.y]];
END;
colorTable: ARRAY WiringLayer OF Color =
[GraphicsColor.red, GraphicsColor.green, GraphicsColor.blue, GraphicsColor.magenta];
tanHalf45: REAL -- = RealFns.TanDeg[22.5] --;
GetMilsBox: PROC [context: Context] RETURNS [MilsBox] =
TRUSTED BEGIN
box: Graphics.Box = GetBounds[context];
RETURN[[
xmin: Real.RoundI[box.xmin],
ymin: Real.RoundI[box.ymin],
xmax: Real.RoundI[box.xmax],
ymax: Real.RoundI[box.ymax]]];
END;
TRUSTED BEGIN
tanHalf45 ← RealFns.TanDeg[22.5];
END;
END. -- of BoardPaint --
CHANGE LOG
Created by L. Hilton, September 9, 1982 7:05 pm