-- File CIFPressControl.mesa
-- Written by Martin Newell, June 1980
-- Last updated: April 23, 1981 3:33 PM

DIRECTORY

CIFControlDefs: FROM "CIFControlDefs" USING [DrawCIF],
CIFDevicesDefs: FROM "CIFDevicesDefs" USING [DeviceDescriptor, DeviceDescriptorRecord,
RegisterDevice, MaxLENGTHLayerArray, GetCIFOutDevice],
CIFOutputDefs: FROM "CIFOutputDefs" USING [SetSorting],
CIFUtilitiesDefs: FROM "CIFUtilitiesDefs" USING [Rectangle,
SetClipRectangle, GetClipRectangle, SetUniformView, DrawClipRectangle,
SetDisplayContext, GetDisplayContext, MoveTo, DrawTo],
FileOpDefs: FROM "FileOpDefs" USING[SetUserAndPassword, StoreFile, FileOpFailed],
Graphics: FROM "Graphics" USING [DisplayContext, NewContext, PushContext, PopContext, Scale],
IODefs: FROM "IODefs" USING [WriteString, WriteLine, WriteDecimal, WriteChar],
JaMFnsDefs: FROM "JaMFnsDefs" USING [PopString, PopInteger],
OsStaticDefs: FROM "OsStaticDefs" USING [OsStatics],
PressDefs: FROM "PressDefs" USING[
InitPressFileDescriptor,
ClosePressFile, PressFileDescriptor, PutRectangle, SetColor, PutText,
StartOutline, PutDrawTo, EndOutline],
Real: FROM "Real" USING [FixC, Fix],
StringDefs: FROM "StringDefs" USING[AppendString, BcplToMesaString,
AppendDecimal, AppendChar];

CIFPressControl: PROGRAM
IMPORTS CIFControlDefs, CIFDevicesDefs, CIFOutputDefs, CIFUtilitiesDefs, FileOpDefs, Graphics, IODefs, JaMFnsDefs, PressDefs, Real, StringDefs =

BEGIN OPEN CIFControlDefs, CIFDevicesDefs, CIFOutputDefs, CIFUtilitiesDefs, FileOpDefs, Graphics, IODefs, JaMFnsDefs, OsStaticDefs, PressDefs, Real, StringDefs;


-- Press procedures

PressDeviceRecord: DeviceDescriptorRecord ← [
next:NIL,
name:"press",
deviceSelect: PressSelect,
deviceDrawFrame: PressDrawFrame,
deviceSetScale: PressSetScale,
deviceSetClipRegion: PressSetClipRegion,
deviceOutput: PressOutput,
deviceLayer: PressLayer,
deviceLoadLayer: PressLoadLayer,
deviceRectangle: PressRectangle,
deviceStartPoly: PressStartPoly,
devicePolyVertex: PressPolyVertex,
deviceEndPoly: PressEndPoly,
deviceText: PressText
];

PressSelect: PROCEDURE RETURNS[BOOLEAN] =
BEGIN --expects <pagesdown, pagesacross> (INTEGERs)
PagesAcross ← PopInteger[];
PagesDown ← PopInteger[];
PressSetClipRegion[GetClipRectangle[]];
RETURN[TRUE];
END;

PressDrawFrame: PROCEDURE =
BEGIN
r: Rectangle ← GetClipRectangle[];
DrawClipRectangle[];
BEGIN OPEN r; --show pages
width: REAL ← (urx-llx)/PagesAcross;
height: REAL ← (ury-lly)/PagesDown;
x: REAL ← llx;
y: REAL ← lly;
THROUGH [1..PagesAcross) DO
x ← x + width;
MoveTo[x,lly];
DrawTo[x,ury];
ENDLOOP;
THROUGH [1..PagesDown) DO
y ← y + height;
MoveTo[llx,y];
DrawTo[urx,y];
ENDLOOP;
END;
END;

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

PressSetClipRegion: PROCEDURE [rt: Rectangle] =
BEGIN --fit to shape of pages
cx,cy,scale,halfwidth,halfheight: REAL;
pagesWidth: REAL ← PagesAcross*(pressClipRectangle.urx - pressClipRectangle.llx);
pagesHeight: REAL ← PagesDown*(pressClipRectangle.ury - pressClipRectangle.lly);
r: Rectangle ← GetClipRectangle[];
cx ← (r.urx + r.llx)/2;
cy ← (r.ury + r.lly)/2;
scale ← MIN[(rt.urx-rt.llx)/pagesWidth,
(rt.ury-rt.lly)/pagesHeight]/2;
halfwidth ← scale*pagesWidth;
halfheight ← scale*pagesHeight;
SetClipRectangle[[llx: cx-halfwidth,lly: cy-halfheight,
urx: cx+halfwidth,ury: cy+halfheight]];
END;

PressOutput: PROCEDURE =
--expects <i1 j1 i2 j2 fileName>
-- Generate pages i1-j1 through i2-j2 inclusive
BEGIN
fileName: STRING ← [100];
i,j,i1,j1,i2,j2: CARDINAL;
PopString[fileName];
j2 ← PopInteger[];
i2 ← PopInteger[];
j1 ← PopInteger[];
i1 ← PopInteger[];
FOR i IN [MinMax[1,i1,PagesDown]..MinMax[1,i2,PagesDown]] DO
FOR j IN [IF i=i1 THEN MinMax[1,j1,PagesAcross] ELSE 1 ..
IF i=i2 THEN MinMax[1,j2,PagesAcross] ELSE PagesAcross] DO
OutPressPage[fileName,i,j];
ENDLOOP;
ENDLOOP;
END;

OutPressPage: PROCEDURE[fileName: STRING, pageDown,pageAcross: CARDINAL] =
-- Generate single page
BEGIN
overlapRatio: REAL ← 68; --1/8 inch on 8.5
width,height,x,y,ovlap: REAL;
saveContext: DisplayContext ← GetDisplayContext[];
r,ru: Rectangle;
pageName: STRING ← [50];

r ← GetClipRectangle[]; --whole region in CIF units
width ← (r.urx-r.llx)/PagesAcross; --width of single page
height ← (r.ury-r.lly)/PagesDown; --height of single page
ovlap ← width/overlapRatio; --inter-page overlap
x ← r.llx + width*(pageAcross - 1); --x coord of top left corner of page
y ← r.ury - height*(pageDown - 1); --y coord of top left corner of page
-- draw page [x,y-height, x+width,y] extended by ovlap
ru ← [llx: x-ovlap, lly: y-height-ovlap, urx: x+width+ovlap, ury: y+ovlap];
PushContext[pressContext];
SetDisplayContext[pressContext];
SetClipRectangle[pressClipRectangle];
SetUniformView[ru,pressClipRectangle];
pageName.length ← 0;
AppendString[pageName,fileName];
AppendChar[pageName,’-];
AppendDecimal[pageName,pageDown];
AppendChar[pageName,’-];
AppendDecimal[pageName,pageAcross];
AppendString[pageName,".press"];
PressStart[pageName, pageDown,pageAcross];
DrawCIF[Fix[ru.llx],Fix[ru.urx],Fix[ru.lly],Fix[ru.ury]];
PressEnd[pageName];
SetDisplayContext[saveContext];
PopContext[pressContext];
SetClipRectangle[r];
END;

PressStart: PROCEDURE[pageName: STRING, pageDown,pageAcross: CARDINAL] =
BEGIN
title: STRING ← [256];
user: STRING ← [20];
WriteString["Page "];
WriteDecimal[pageDown]; WriteChar[’,]; WriteDecimal[pageAcross];
WriteString[". Press File: "];
WriteLine[pageName];
localName.length ← 0;
IF pageName[0]=’[
THENBEGIN
AppendString[localName,localFileBufferName];
WriteString["...buffered on "];
WriteLine[localFileBufferName];
END
ELSEAppendString[localName,pageName];
InitPressFileDescriptor[@pressFileDescriptor,localName];

AppendString[title,"Page "];
AppendDecimal[title, pageDown];
AppendChar[title, ’,];
AppendDecimal[title, pageAcross];
AppendString[title," of "];
AppendDecimal[title, PagesDown];
AppendChar[title, ’,];
AppendDecimal[title, PagesAcross];
AppendString[title," from file "];
AppendString[title,pageName];
AppendString[title," for "];
BcplToMesaString[OsStatics↑.UserName,user];
AppendString[title,user];
PutText[@pressFileDescriptor,title,635,254];

SetSorting[none];
PressCurrentLayer ← 7; --i.e. not set
END;

localName: STRING ← [50]; --in global frame since press shares it

PressEnd: PROCEDURE[pageName: STRING] =
BEGIN
ClosePressFile[@pressFileDescriptor];
--check if need to write it to a file server
IF pageName[0]=’[
THENBEGIN
ENABLE FileOpFailed =>
BEGIN
WriteString[" ---Store failed: "];
WriteLine[reason];
CONTINUE;
END;
user: STRING ← [40];
password: STRING ← [40];
WriteString["Transferring "];
WriteString[localFileBufferName];
WriteString[" to "];
WriteLine[pageName];
BcplToMesaString[OsStatics↑.UserName,user];
BcplToMesaString[OsStatics↑.UserPassword,password];
SetUserAndPassword[user,password];
StoreFile[localFileBufferName,pageName,binary];
END;
END;

PressLayer: PROCEDURE [layer: CARDINAL] =
BEGIN
IF layer#PressCurrentLayer THEN
BEGIN
SetColor[@pressFileDescriptor,
Color[layer][hue], Color[layer][sat], Color[layer][bright]];
PressCurrentLayer ← layer;
END;
END;

PressLoadLayer: PROCEDURE[layer:CARDINAL, v0,v1,v2,v3: CARDINAL] =
-- v0,v1,v2 are hue,sat,bri, v3 ignored
BEGIN
Color[layer] ← [v0,v1,v2];
END;

PressText: PROCEDURE[text: STRING, x,y: REAL] =
BEGIN
SetColor[@pressFileDescriptor, 0,0,0];
PutText[@pressFileDescriptor,text,FixC[x],FixC[y]];
SetColor[@pressFileDescriptor, Color[PressCurrentLayer][hue],
Color[PressCurrentLayer][sat], Color[PressCurrentLayer][bright]];
END;


--Private procedures--

PressRectangle: PROCEDURE [r: Rectangle] =
--make two edges of appropriate types
BEGIN
left: CARDINAL ← FixC[r.llx];
bottom: CARDINAL ← FixC[r.lly];
right: CARDINAL ← FixC[r.urx];
top: CARDINAL ← FixC[r.ury];
PutRectangle[@pressFileDescriptor,
left, bottom, right-left, top-bottom];
END;

PressStartPoly: PROCEDURE [x,y: REAL] =
BEGIN
StartOutline[@pressFileDescriptor, FixC[x], FixC[y]];
END;

PressPolyVertex: PROCEDURE [x,y: REAL] =
BEGIN
PutDrawTo[@pressFileDescriptor, FixC[x], FixC[y]];
END;

PressEndPoly: PROCEDURE =
BEGIN
EndOutline[@pressFileDescriptor];
END;

MinMax: PROCEDURE[lower,value,upper: CARDINAL] RETURNS[CARDINAL] =
BEGIN
RETURN[MIN[MAX[lower,value],upper]];
END;

--Press parameters
PagesAcross: CARDINAL ← 1;
PagesDown: CARDINAL ← 1;
pressClipRectangle: Rectangle ← [llx: 635, lly: 635, urx: 21590-635, ury: 27940-635];
pressContext: DisplayContext ← NewContext[GetCIFOutDevice[]];

PressCurrentLayer: CARDINAL;
pressFileDescriptor: PressFileDescriptor;
localFileBufferName: STRING ← "CIF.press$";

ColorComponent: TYPE = {hue,sat,bright};
Color: ARRAY [0..MaxLENGTHLayerArray) OF ARRAY ColorComponent OF CARDINAL ←
ALL[[ 15, 255, 150]];--undef


--set up context

--Set up default colors
Color[0] ← [ 40, 220, 255];
--implant
Color[1] ← [ 80, 150, 255];
--diffusion
Color[2] ← [ 200, 190, 255];
--poly
Color[3] ← [ 0, 0, 64];
--contact
Color[4] ← [ 140, 170, 255];
--metal
Color[5] ← [ 130, 220, 255];
--buried
Color[6] ← [ 0, 220, 255];
--glass
Color[7] ← [ 0, 0, 0];
--undef

RegisterDevice[@PressDeviceRecord];

END.