-- File CIFDrcControl.mesa
-- Written by Dan Fitzpatrick and Martin Newell, August 1980
-- Last updated: March 25, 1981 3:13 PM

DIRECTORY

AltoDevice: FROM "AltoDevice" USING [ScreenOrigin],
CIFControlDefs: FROM "CIFControlDefs" USING [DrawCIF],
CIFDevicesDefs: FROM "CIFDevicesDefs" USING [DeviceDescriptor, DeviceDescriptorRecord,
RegisterDevice, GetCIFOutDevice],
CIFDrcDefs: FROM "CIFDrcDefs",
CIFDrcScanDefs: FROM "CIFDrcScanDefs" USING [DrcScanStart, DrcScanEnd, DrcTrigger, EnterEdge],
CIFDrcUtilsDefs: FROM "CIFDrcUtilsDefs" USING [Edge, MakeEdge],
CIFOutputDefs: FROM "CIFOutputDefs" USING [SetSorting],
CIFUtilitiesDefs: FROM "CIFUtilitiesDefs" USING [Rectangle,
SetClipRectangle, GetClipRectangle, DrawClipRectangle,
SetDisplayContext, GetDisplayContext, MapRectangle],
Graphics: FROM "Graphics" USING [DisplayContext, NewContext, PushContext,
PopContext, CopyContext, Scale,
ScreenToUser, UserToScreen],
IODefs: FROM "IODefs" USING [WriteLine],
IntDefs: FROM "IntDefs" USING[ILastBB],
JaMDrcDefs: FROM "JaMDrcDefs" USING[JaMDrcStartUp],
JaMFnsDefs: FROM "JaMFnsDefs" USING [PopString],
Real: FROM "Real" USING [Fix],
StringDefs: FROM "StringDefs" USING [AppendChar, AppendString]
,
Vector: FROM "Vector" USING [Vec]
;

CIFDrcControl: PROGRAM
IMPORTS
AltoDevice, CIFControlDefs, CIFDevicesDefs, CIFDrcScanDefs, CIFDrcUtilsDefs, CIFOutputDefs, CIFUtilitiesDefs, Graphics, IODefs, IntDefs, JaMDrcDefs, JaMFnsDefs, Real, StringDefs =

BEGIN OPEN
AltoDevice, CIFControlDefs, CIFDevicesDefs, CIFDrcScanDefs, CIFDrcUtilsDefs, CIFOutputDefs, CIFUtilitiesDefs, Graphics, IODefs, IntDefs, JaMDrcDefs, JaMFnsDefs, Real, StringDefs, Vector;


-- CIF DRC procedures

DrcDeviceRecord: DeviceDescriptorRecord ← [
next:NIL,
name:"drc",
deviceSelect: DrcSelect,
deviceDrawFrame: DrcDrawFrame,
deviceSetScale: DrcSetScale,
deviceSetClipRegion: DrcSetClipRegion,
deviceOutput: DrcOutput,
deviceLayer: DrcLayer,
deviceLoadLayer: DrcLoadLayer,
deviceRectangle: DrcRectangle,
deviceStartPoly: DrcStartPoly,
devicePolyVertex: DrcPolyVertex,
deviceEndPoly: DrcEndPoly,
deviceText: DrcText
];

DrcSelect: PROCEDURE RETURNS[BOOLEAN] =
BEGIN
--
DrcSetClipRegion[GetClipRectangle[]];
RETURN[TRUE];
END;

DrcDrawFrame: PROCEDURE =
BEGIN
DrawClipRectangle[];
END;

DrcSetScale: PROCEDURE [factor: REAL] =
BEGIN
dc: DisplayContext ← GetDisplayContext[];
PopContext[dc];
PushContext[dc];
Scale[dc, [factor,factor]];
END;

DrcSetClipRegion: PROCEDURE [rt: Rectangle] =
BEGIN
SetClipRectangle[rt];
END;

DrcOutput: PROCEDURE =
--expects <baseName> (STRING)
BEGIN
baseName: STRING ← [100];
r: Rectangle ← GetClipRectangle[]; --clipping region in CIF units
etop: REAL;
SaveContext ← GetDisplayContext[];
PopString[baseName];
SetDisplayContext[drcContext];
SetClipRectangle[r];
drcClipRectangle ← MapRectangle[r,drcContext,identityContext];
etop ← drcClipRectangle.ury;
DrcStart[baseName];
DrawCIF[Fix[r.llx],Fix[r.urx],Fix[r.lly],Fix[r.ury]];
DrcEnd[etop];
SetDisplayContext[SaveContext];
SetClipRectangle[r];
END;

DrcStart: PROCEDURE[fileName: STRING] =
BEGIN
--Initialize EdgeList and ActiveList
WriteLine["Start Drc"];
SetSorting[incy];
DrcCurrentLayer ← 32000; --i.e. not set
DrcScanStart[fileName];
END;

DrcEnd: PROCEDURE [ymax: REAL] =
BEGIN
DrcScanEnd[ymax];
END;

DrcLayer: PROCEDURE [layer: CARDINAL] =
--used to trigger scan conversion up to bottom of object about to be received
BEGIN
l,r,b,t: LONG INTEGER;
bottom: REAL;
rec: Rectangle;
[l,r,b,t] ← ILastBB[]; --in chip coordinates
--kludge - need bottom of current object in Extractor coords
rec ← MapRectangle[[l,b,r,t], drcContext, identityContext]; --**may need to be in cifdrccontrol to get at drcContext (see CIFExtControl)
bottom ← MIN[rec.lly,rec.ury]-1; -- -1 to be on safe side
DrcTrigger[bottom];
DrcCurrentLayer ← layer;
END;

DrcLoadLayer: PROCEDURE[layer:CARDINAL, v0,v1,v2,v3: CARDINAL] =
BEGIN
END;


--DrcTrapezoid: PUBLIC PROCEDURE [t:POINTER TO TrapezoidBlock] =
--make two edges of appropriate types
--
BEGIN OPEN t;
--
edge: Edge;
--
IF DrcCurrentLayer > 4 THEN RETURN;
--
edge ← MakeEdge[xsleft,ystart,xeleft,yend,TRUE];
--
IF edge#NIL THEN EnterEdge[DrcCurrentLayer, edge];
--
edge ← MakeEdge[xsright,ystart,xeright,yend,FALSE];
--
IF edge#NIL THEN EnterEdge[DrcCurrentLayer, edge];
--
END;

DrcRectangle: PROCEDURE [r: Rectangle] =
--make two edges of appropriate types
BEGIN
edge: Edge;
IF DrcCurrentLayer>4 THEN RETURN;
edge ← MakeEdge[r.llx,r.lly, r.llx,r.ury, TRUE];
IF edge#NIL THEN EnterEdge[DrcCurrentLayer, edge];
edge ← MakeEdge[r.urx,r.lly, r.urx,r.ury, FALSE];
IF edge#NIL THEN EnterEdge[DrcCurrentLayer, edge];
END;

x0,y0: REAL;
xs,ys: REAL;

DrcStartPoly: PROCEDURE [x,y: REAL] =
BEGIN
x0 ← xs ← x;
y0 ← ys ← y;
END;

DrcPolyVertex: PROCEDURE [x,y: REAL] =
BEGIN
edge: Edge ← NIL;
IF DrcCurrentLayer>4 THEN RETURN;
SELECT TRUE FROM
y>ys=> edge ← MakeEdge[xs,ys, x,y,FALSE];
y<ys=> edge ← MakeEdge[x,y, xs,ys,TRUE];
ENDCASE;
IF edge#NIL THEN EnterEdge[DrcCurrentLayer, edge];
xs ← x;
ys ← y;
END;

DrcEndPoly: PROCEDURE =
BEGIN
DrcPolyVertex[x0,y0];
END;

DrcText: PROCEDURE[text: STRING, x,y: REAL] =
BEGIN
END;

DefaultExtension: PROCEDURE[name,ext: STRING] RETURNS[STRING] =
--set extension if not already present
BEGIN
i: CARDINAL;
FOR i IN [0..name.length) DO
IF name[i]=’. THEN RETURN[name];
ENDLOOP;
AppendChar[name,’.];
AppendString[name,ext];
RETURN[name];
END;

mousex: POINTER TO CARDINAL = LOOPHOLE[424B];
mousey: POINTER TO CARDINAL = LOOPHOLE[425B];

MoveCursorTo: PUBLIC PROCEDURE[x,y: REAL] =
BEGIN
s: Vec ← ScreenToUser[mannContext, [x,y]];
p: Vec ← UserToScreen[SaveContext, s];
x0,y0: REAL;
[x0,y0] ← ScreenOrigin[];
mousex↑ ← FixC[p.x];
mousey↑ ← FixC[p.y + y0];
END;

--Drc Parameters
drcClipRectangle: Rectangle;
drcContext: DisplayContext ← NewContext[GetCIFOutDevice[]];
identityContext: DisplayContext ← CopyContext[drcContext];
SaveContext: DisplayContext;

DrcCurrentLayer: CARDINAL;


--set up context

RegisterDevice[@DrcDeviceRecord];

JaMDrcStartUp[];

END.