-- File: DisjointGraphics.mesa
-- Routines for generating graphical output for Disjoint
-- Written by Martin Newell/Dan Fitzpatrick February 1981
-- Last edited (Pilot): July 20, 1981 5:31 PM
DIRECTORY
CIFUtilitiesDefs: FROM "CIFUtilitiesDefs" USING [DrawRectangleOutline, GetClipRectangle, Rectangle, ScreenParams],
DisjointTypes: FROM "DisjointTypes" USING [DisCell, Instance, Symbol, Rectangle, Geometry],
DisjointAllocDefs: FROM "DisjointAllocDefs" USING [EnumerateSymbols],
DisjointGraphicsDefs: FROM "DisjointGraphicsDefs",
GSysPressDefs USING [ScreenToPress],
JaMFnsDefs: FROM "JaMFnsDefs" USING [GetJaMBreak],
MoreCIFUtilitiesDefs: FROM "MoreCIFUtilitiesDefs" USING [DrawRectangleArea, DrawStringAt, SetStipple];
DisjointGraphics: PROGRAM
IMPORTS CIFUtilitiesDefs, DisjointAllocDefs, GSysPressDefs, JaMFnsDefs, MoreCIFUtilitiesDefs
EXPORTS DisjointGraphicsDefs =
BEGIN
OPEN CIFUtilitiesDefs, DisjointTypes, DisjointAllocDefs, GSysPressDefs, JaMFnsDefs, MoreCIFUtilitiesDefs;
DrawInstance: PUBLIC PROCEDURE[inst: Instance] =
BEGIN OPEN inst;
window: DisjointTypes.Rectangle;
FOR window ← symbol.windows,window.next UNTIL window=NIL DO
left: REAL ← window.l+xOffset;
bottom: REAL ← window.b+yOffset;
right: REAL ← window.r+xOffset;
top: REAL ← window.t+yOffset;
DrawRectangleOutline[[left, bottom, right, top]];
DrawStringAt[symbol.name, (left+right)/2,(bottom+top)/2];
ENDLOOP;
END;
DrawDisCell: PUBLIC PROCEDURE[disCell: DisCell, stipple: CARDINAL] =
BEGIN
r: DisjointTypes.Rectangle;
FOR r ← disCell.windows, r.next UNTIL r=NIL DO
DrawRectangle[r.l,r.b,r.r,r.t, stipple];
ENDLOOP;
END;
DrawCellOffset: PUBLIC PROCEDURE[us: Symbol, x,y: REAL, stipple: CARDINAL] =
BEGIN
r: DisjointTypes.Rectangle;
FOR r ← us.windows, r.next UNTIL r=NIL DO
DrawRectangle[r.l+x,r.b+y,r.r+x,r.t+y, stipple];
ENDLOOP;
END;
DrawGeomOffset: PUBLIC PROCEDURE[us: Symbol, x,y: REAL] =
BEGIN
w: DisjointTypes.Rectangle;
FOR w ← us.windows, w.next UNTIL w=NIL DO
DrawRectangleOutline[[w.l+x,w.b+y,w.r+x,w.t+y]];
ENDLOOP;
FOR g:Geometry ← us.geom, g.next UNTIL g=NIL DO
DrawRectangle[g.l+x,g.b+y,g.r+x,g.t+y, Stipple[g.layer]];
ENDLOOP;
END;
DrawSymbol: PUBLIC PROCEDURE[s: Symbol, callOnce: BOOLEAN,
level: INTEGER] =
--draw all instances of s at given level of hierarchy
--level=0 is top level
--level=-1 will draw all geometry
--callOnce=TRUE will allow only the first call to each symbol
BEGIN
Mark: PROC[s: Symbol] RETURNS[BOOLEAN] =
BEGIN
--here .mark means symbol can still be called
s.mark ← TRUE;
RETURN[FALSE];
END;
count: CARDINAL ← 0;
r: CIFUtilitiesDefs.Rectangle;
-- mark all the symbols
[] ← EnumerateSymbols[Mark];
r ← GetClipRectangle[];
[ClipL,ClipB,ClipR,ClipT] ← r;
DrawSymbolR[s, callOnce, 0,0, level];
END;
DrawSymbolR: PROCEDURE[s: Symbol, callOnce: BOOLEAN,
x,y: REAL, level: INTEGER] =
-- draw all instances of s at given level of hierarchy
-- level=0 is top level
BEGIN
IF OutsideClipRegion[s, x,y] THEN RETURN;
IF level=0 THEN DrawCellOffset[s, x,y, s.data]
ELSE {
IF level=1 OR level<0 THEN DrawGeomOffset[s, x,y];
FOR i:Instance ← s.insts, i.next UNTIL i=NIL DO
IF GetJaMBreak[] THEN EXIT;
IF i.symbol.mark THEN
DrawSymbolR[i.symbol, callOnce, x+i.xOffset,y+i.yOffset, level-1];
IF callOnce THEN i.symbol.mark ← FALSE;
ENDLOOP;
};
END;
OutsideClipRegion: PROCEDURE[s: Symbol, x,y: REAL] RETURNS[BOOLEAN] =
BEGIN
l,b,r,t: REAL;
[l,b,r,t] ← BoundBox[s];
IF l+x<ClipR AND b+y<ClipT AND r+x>ClipL AND t+y>ClipB THEN RETURN[FALSE];
RETURN[TRUE];
END;
ClipL,ClipB,ClipR,ClipT: REAL;
BoundBox: PUBLIC PROCEDURE[s: Symbol] RETURNS[l,b,r,t: REAL] =
BEGIN
rec: DisjointTypes.Rectangle;
l ← s.windows.l;
b ← s.windows.b;
r ← s.windows.r;
t ← s.windows.t;
--always at least one window
FOR rec ← s.windows.next, rec.next UNTIL rec=NIL DO
l ← MIN[l,rec.l];
b ← MIN[b,rec.b];
r ← MAX[r,rec.r];
t ← MAX[t,rec.t];
ENDLOOP;
END;
DrawRectangle: PUBLIC PROCEDURE[l,b,r,t: REAL, stipple: CARDINAL] =
BEGIN
SetStipple[stipple];
DrawRectangleArea[[l,b,r,t]];
END;
ScreenToPress: PUBLIC PROCEDURE [name: STRING] =
BEGIN
base: LONG POINTER;
raster,height: CARDINAL;
[base,raster,height] ← ScreenParams[];
GSysPressDefs.ScreenToPress[name, base,raster,height];
END;
Stipple: ARRAY [0..16) OF CARDINAL ← ALL[177777B];--undef
--Set up default stipples
Stipple[0] ← 000020B;--implant
Stipple[1] ← 040501B;--diffusion
Stipple[2] ← 014102B;--poly
Stipple[3] ← 165627B;--contact
Stipple[4] ← 000050B;--metal
Stipple[5] ← 001110B;--buried
Stipple[6] ← 001122B;--glass
Stipple[7] ← 177777B;--undef
END.