-- File CIFExtUtils.mesa
-- Written by Dan Fitzpatrick and Martin Newell, June 1980
-- Last updated: November 13, 1980 1:22 AM

DIRECTORY

CIFDevicesDefs: FROM "CIFDevicesDefs" USING [MaxLENGTHLayerArray],
CIFExtIODefs: FROM "CIFExtIODefs" USING [ReadStringDirect, ReadLong, WriteStringDirect, WriteLong, WriteLineDirect],
CIFExtScanDefs: FROM "CIFExtScanDefs" USING [Edge],
CIFExtUtilsDefs: FROM "CIFExtUtilsDefs",
Graphics: FROM "Graphics" USING [Texture],
IODefs: FROM "IODefs" USING [WriteString, WriteLine],
SegmentDefs: FROM "SegmentDefs" USING[Read, Write, Append],
StreamDefs: FROM "StreamDefs" USING[DiskHandle, NewByteStream],
SystemDefs: FROM "SystemDefs" USING[AllocateHeapString, AllocateHeapNode,
FreeHeapString, FreeHeapNode],
StringDefs: FROM "StringDefs" USING[AppendLongDecimal, AppendString];

CIFExtUtils: PROGRAM
IMPORTS CIFExtIODefs, IODefs, StreamDefs, StringDefs, SystemDefs
EXPORTS CIFExtUtilsDefs =

BEGIN OPEN CIFDevicesDefs, CIFExtIODefs, CIFExtScanDefs, Graphics, IODefs, StringDefs, SegmentDefs, StreamDefs, SystemDefs;

SetExtLayer: PUBLIC PROCEDURE[layer:CARDINAL, v0,v1,v2,v3: CARDINAL] =
BEGIN
Stipple[layer] ← v0;
END;

DrawNumber: PUBLIC PROCEDURE[layer: CARDINAL, n: LONG POINTER, x,y: REAL] =
--draw node number on screen for debugging
--x,y are in screen coords
BEGIN
s: STRING ← [20];
AppendLongDecimal[s,LOOPHOLE[n,LONG CARDINAL]];
DrawString[s,x,y];
END;

DrawString
: PUBLIC PROCEDURE[s: STRING, x,y: REAL] =
--draw string on screen for debugging
--x,y are in screen coords
BEGIN
--
xc,yc,x0,y0,w,h: REAL;
--
saveOutputTrapezoid: PROCEDURE [t:POINTER TO TrapezoidBlock] ← GetOutputTrapezoid[];
--
SetOutputTrapezoid[ScreenTrapezoid];
--
PushBaseContext[];
--
BEGIN
--
ENABLE ANY => BEGIN CONTINUE END;
--
[xc,yc] ← InverseTransform[x,y];
--
w ← GetStringWidth[s];
--
h ← GetFontDimensions[].ascent;
--
x0 ← xc-w/2;
--
y0 ← yc-h/2;
--
SetAreaPaint[erase];
--
DrawBoxArea[[x0,y0,x0+w,y0+h]];
--
SetAreaPaint[paint];
--
MoveTo[x0,y0];
--
DisplayString[s];
--
END;
--
PopDisplayContext[];
--
SetOutputTrapezoid[saveOutputTrapezoid];
END;

DrawTrap: PUBLIC PROCEDURE[left: Edge, ystart: REAL, right: Edge, yend: REAL, layer: CARDINAL] =
BEGIN --draw left and right edges on screen for debugging
--
t: TrapezoidBlock ← [
--
ystart: ystart,
--
yend: yend,
--
xsleft: XatY[left,ystart],
--
xsright: XatY[right,ystart],
--
xeleft: XatY[left,yend],
--
xeright: XatY[right,yend],
--
function: paint,
--
xbase: ScreenBase,
--
xwords: ScreenWords,
--
texture: @Stipple[layer]
--
];
--
ScreenTrapezoid[@t];
END;

WriteLongDecimal: PUBLIC PROCEDURE[n: LONG CARDINAL] =
BEGIN
s: STRING ← [20];
AppendLongDecimal[s,n]; WriteString[s];
END;

Tag: PUBLIC PROCEDURE[this,that: STRING] RETURNS [STRING] =
-- Tags this with that and returns a string
BEGIN
s: STRING;
s ← AllocateHeapString[this.length+that.length+2];
AppendString[s,this];
AppendString[s,"."];
AppendString[s,that];
RETURN[s];
END;

SortNames: PUBLIC PROCEDURE[fileName: STRING] =
BEGIN
s: STRING ← [50];
LabelLocationFile: DiskHandle;
Name: TYPE = POINTER TO NameRecord;
NameRecord: TYPE = RECORD [
next: Name,
label: STRING,
x,y: LONG INTEGER,
key: REAL
];
label, nameList, sortedList, ptr: Name;
NoNameFile: BOOLEAN ← FALSE;

-- Open the file; if it doesn’t exist return
LabelLocationFile ← NewByteStream[fileName,Read !
ANY => BEGIN
WriteString[fileName]; WriteLine[": cannot open"];
NoNameFile ← TRUE;
CONTINUE;
END
];
IF NoNameFile THEN RETURN;
LabelLocationFile.reset[LabelLocationFile];

-- Read the file and put it onto a sorted list
nameList ← sortedList ← NIL;
UNTIL LabelLocationFile.endof[LabelLocationFile] DO
label ← AllocateHeapNode[SIZE[NameRecord]];
ReadStringDirect[s, LabelLocationFile];
IF LabelLocationFile.endof[LabelLocationFile] THEN BEGIN -- in case last line ends
FreeHeapNode[label];-- with white space
EXIT;
END;
label.label ← AllocateHeapString[s.length];
AppendString[label.label, s];
label.x ← ReadLong[LabelLocationFile];
label.y ← ReadLong[LabelLocationFile];
-- insert the new element (label) into the list, leaving the list
-- in ascending order
IF nameList = NIL OR nameList.y > label.y THEN BEGIN
label.next ← nameList;
nameList ← label;
LOOP;
END;
FOR ptr ← nameList, ptr.next UNTIL ptr.next = NIL DO
IF ptr.next.y > label.y THEN EXIT;
ENDLOOP;
label.next ← ptr.next;
ptr.next ← label;
ENDLOOP;
LabelLocationFile.destroy[LabelLocationFile];

-- Flip around pointers so list is in decending order
FOR label ← nameList, nameList UNTIL label = NIL DO
nameList ← label.next;
label.next ← sortedList;
sortedList ← label;
ENDLOOP;

-- Write the list back onto the file
LabelLocationFile ← NewByteStream[fileName,Write+Append];
LabelLocationFile.reset[LabelLocationFile];
FOR label ← sortedList, sortedList UNTIL label = NIL DO
sortedList ← label.next;
WriteStringDirect[label.label, LabelLocationFile];
WriteStringDirect[" ", LabelLocationFile];
WriteLong[label.x, LabelLocationFile];
WriteStringDirect[" ", LabelLocationFile];
WriteLong[label.y, LabelLocationFile];
WriteLineDirect["",LabelLocationFile];
FreeHeapString[label.label];
FreeHeapNode[label];
ENDLOOP;
LabelLocationFile.destroy[LabelLocationFile];
END;


--ScreenTrapezoid: PROCEDURE [t:POINTER TO TrapezoidBlock] ← GetDefaultOutputTrapezoid[];

Stipple: ARRAY [0..MaxLENGTHLayerArray) OF Texture ← 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.