-- File CIFMann.mesa -- Output module for Mann 3000, metric or english units -- Written by Martin Newell, June 1980 -- Last updated: March 2, 1982 12:29 PM by Pasco --The following dimensions are on the MASK which is assumed to be a factor -- of 10 smaller than the reticles that the Mann machine generates --In metric units -- 1 Mann unit = 0.1 micron on the MASK -- Center of field at [50000,50000] Mann units --In english units -- 1 Mann unit = 0.001 mil on the MASK (but must be multiple of 5 units) -- Center of field at [200000,200000] Mann units 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, DrawClipRectangle, SetDisplayContext, GetDisplayContext], Graphics: FROM "Graphics" USING [DisplayContext, NewContext, PushContext, PopContext, Scale, Translate, CopyContext], InlineDefs: FROM "InlineDefs" USING [BITAND, LowHalf], IODefs: FROM "IODefs" USING [CR, WriteLine, WriteString, WriteChar, GetOutputStream, SetOutputStream, WriteDecimal], JaMFnsDefs: FROM "JaMFnsDefs" USING [PopString, PopInteger], Real: FROM "Real" USING [Fix, RoundI, RoundLI], RealFns: FROM "RealFns" USING [ArcTanDeg, SqRt], StreamDefs: FROM "StreamDefs" USING [StreamHandle, NewByteStream, Write, Append], StringDefs: FROM "StringDefs" USING[AppendString, AppendLongNumber, AppendDecimal, AppendChar, AppendLongDecimal]; CIFMann: PROGRAM IMPORTS CIFControlDefs, CIFDevicesDefs, CIFOutputDefs, CIFUtilitiesDefs, Graphics, InlineDefs, IODefs, JaMFnsDefs, Real, RealFns, StreamDefs, StringDefs = BEGIN OPEN CIFControlDefs, CIFDevicesDefs, CIFOutputDefs, CIFUtilitiesDefs, Graphics, InlineDefs, IODefs, JaMFnsDefs, Real, RealFns, StreamDefs, StringDefs; -- Mann procedures MannDeviceRecord: DeviceDescriptorRecord _ [ next: NIL, name: "mann", deviceSelect: MannSelect, deviceDrawFrame: MannDrawFrame, deviceSetScale: MannSetScale, deviceSetClipRegion: MannSetClipRegion, deviceOutput: MannOutput, deviceLayer: MannLayer, deviceLoadLayer: MannLoadLayer, deviceRectangle: MannRectangle, deviceStartPoly: MannStartPoly, devicePolyVertex: MannPolyVertex, deviceEndPoly: MannEndPoly, deviceText: MannText ]; MannSelect: PROCEDURE RETURNS[BOOLEAN] = BEGIN --expects (0=metric, #0=english) Units _ IF PopInteger[]=0 THEN metric ELSE english; MannSetClipRegion[GetClipRectangle[]]; RETURN[TRUE]; END; MannDrawFrame: PROCEDURE = BEGIN r: Rectangle _ GetClipRectangle[]; DrawClipRectangle[]; END; OldMannSetScale: PROCEDURE [factor: REAL] = BEGIN dc: DisplayContext _ GetDisplayContext[]; PopContext[dc]; PushContext[dc]; Scale[dc, [factor,factor]]; END; MannSetScale: PROCEDURE [factor: REAL] = BEGIN --taken as pre-scale to convert stored coords to 0.01 micron --useful if using english units and stored CIF file is not in units of 0.01 micron MannScale _ factor; END; MannSetClipRegion: PROCEDURE [rt: Rectangle] = BEGIN SetClipRectangle[rt]; END; MannOutput: PROCEDURE = --expects (STRING) BEGIN fileName: STRING _ [100]; saveContext: DisplayContext _ GetDisplayContext[]; r: Rectangle _ GetClipRectangle[]; --clipping region in CIF units s: REAL _ MannScale/MannCoords[Units]; PopString[fileName]; SetDisplayContext[mannContext]; PushContext[mannContext]; Translate[mannContext, [MannCenter[Units],MannCenter[Units]]]; --to center of Mann region Scale[mannContext, [-1,1]]; --invert x Scale[mannContext, [s,s]]; Translate[mannContext, [-(r.llx+r.urx)/2,-(r.lly+r.ury)/2]]; --window center to origin -- mannClipRectangle _ MapRectangle[r,mannContext,identityContext]; SetClipRectangle[r]; MannStart[fileName]; DrawCIF[Floor[r.llx],Floor[r.urx],Ceiling[r.lly],Ceiling[r.ury]]; MannEnd[]; PopContext[mannContext]; SetDisplayContext[saveContext]; SetClipRectangle[r]; END; MannStart: PROCEDURE[fileName: STRING] = BEGIN baseFileName.length _ 0; AppendString[baseFileName,fileName]; PolyGripe _ FALSE; SmallGripe _ FALSE; LayerStream _ ALL[NIL]; X _ ALL[-1]; Y _ ALL[-1]; H _ ALL[-1]; W _ ALL[-1]; A _ ALL[-1]; NRecs _ ALL[0]; SetSorting[incy]; MannCurrentLayer _ 32000; --i.e. not set END; MannEnd: PROCEDURE = BEGIN dir: StreamHandle; save: StreamHandle _ GetOutputStream[]; fileNumber: INTEGER _ 0; dirName: STRING _ [30]; name12: STRING _ [12]; FOR i:CARDINAL IN [0..baseFileName.length) UNTIL i=12 DO ch:CHARACTER _ baseFileName[i]; AppendChar[name12,IF ch IN ['a..'z] THEN ch-40B ELSE ch]; ENDLOOP; IF baseFileName.length<12 THEN THROUGH [0..12-baseFileName.length) DO AppendChar[name12,'X]; ENDLOOP; AppendString[dirName,baseFileName]; AppendString[dirName,".mann"]; dir _ NewByteStream[dirName, Write+Append]; -- SetOutputStream[dir]; --*** WriteString[""]; -- SetOutputStream[save]; WriteString[IF Units=metric THEN "Metric" ELSE "English"]; WriteLine[" format Mann output"]; WriteString["Mann directory on "]; WriteLine[dirName]; FOR i:CARDINAL IN [0..MaxLENGTHLayerArray) DO s: StreamHandle _ LayerStream[i]; IF s#NIL THEN { s.put[s,'$]; s.destroy[s]; SetOutputStream[dir]; WriteString[name12]; WriteLongNumberInField[ MIN[fileNumber_fileNumber+1,9999], 4]; WriteLongNumberInField[MIN[NRecs[i],9999], 4]; SetOutputStream[save]; WriteString["Mann layer file #"]; WriteDecimal[fileNumber]; WriteString[" from layer "]; WriteDecimal[i]; WriteString[" on file "]; WriteString[baseFileName]; WriteChar['-]; WriteDecimal[i]; WriteString[".mann. Flash count: "]; WriteLongDecimal[NRecs[i]]; WriteChar[CR]; }; ENDLOOP; dir.put[dir,'$]; dir.destroy[dir]; END; MannLayer: PROCEDURE [layer: CARDINAL] = BEGIN IF layer#MannCurrentLayer THEN BEGIN IF LayerStream[layer]=NIL THEN { fileName: STRING _ [100]; s: StreamHandle; save: StreamHandle _ GetOutputStream[]; AppendString[fileName,baseFileName]; AppendChar[fileName,'-]; AppendDecimal[fileName,layer]; AppendString[fileName,".mann"]; s _ NewByteStream[fileName, Write+Append]; LayerStream[layer] _ s; X[layer] _ -1; Y[layer] _ -1; H[layer] _ -1; W[layer] _ -1; A[layer] _ -1; NRecs[layer] _ 0; }; MannCurrentLayer _ layer; END; END; MannLoadLayer: PROCEDURE[layer:CARDINAL, v0,v1,v2,v3: CARDINAL] = -- meaningless BEGIN END; MannText: PROCEDURE[text: STRING, x,y: REAL] = --ignore it BEGIN END; --Private procedures-- MannRectangle: PROCEDURE [r: Rectangle] = --make two edges of appropriate types BEGIN left: LONG INTEGER _ Floor[r.llx]; bottom: LONG INTEGER _ Floor[r.lly]; right: LONG INTEGER _ Ceiling[r.urx]; top: LONG INTEGER _ Ceiling[r.ury]; width: LONG INTEGER _ right - left; height: LONG INTEGER _ top - bottom; small: LONG INTEGER _ Smallest[Units]; IF width0 THEN { b: LONG INTEGER _ Fix[r] + 1; c _ Fix[r-b] + b; } ELSE c _ Fix[r]; END; Floor: PROCEDURE[r: REAL] RETURNS[c: LONG INTEGER] = INLINE BEGIN --"Truncate" r down to next integer IF r<0 THEN { b: LONG INTEGER _ -Fix[r] + 1; c _ Fix[r+b] - b; } ELSE c _ Fix[r]; END; WriteLongDecimal: PROCEDURE[n: LONG INTEGER] = BEGIN s: STRING _ [50]; AppendLongDecimal[s,n]; WriteString[s]; END; WriteLongNumberInField: PROCEDURE[n: LONG UNSPECIFIED, field: CARDINAL] = BEGIN s: STRING _ [50]; AppendLongNumber[s,n,10]; IF s.length>field THEN { THROUGH [1..field] DO WriteChar['*]; ENDLOOP; RETURN; }; THROUGH [0..field-s.length) DO WriteChar['0]; ENDLOOP; WriteString[s]; END; --Mann parameters --mannClipRectangle: Rectangle; identityContext: DisplayContext _ NewContext[GetCIFOutDevice[]]; mannContext: DisplayContext _ CopyContext[identityContext]; baseFileName: STRING _ [100]; PolyGripe: BOOLEAN; SmallGripe: BOOLEAN; MannCurrentLayer: CARDINAL; MannScale: REAL _ 1; UnitType: TYPE = {metric, english, unknown}; Units: UnitType _ unknown; MannCoords: ARRAY UnitType OF REAL _ [10,1.27,1]; --MannCoords is used as divisor in MannOutput to convert CIF units (0.01 micron) to relevant output units --For metric, "relevant output units" are 0.1 micron (on MASK) --For english, "relevant output units" are .005 mil (on MASK), which -- will be rounded and multiplied by 5 to give 0.001 mil units restricted -- to multiples of 0.005 (see OutScale below) -- [note: 1.27 = 2.54(to get 0.01 mil)*0.1(to get 0.001 mil)*5(to get 0.005 mil)] OutScale: ARRAY UnitType OF INTEGER _ [1, 5, 1]; MannCenter: ARRAY UnitType OF REAL _ [50000, 40000, 0]; Smallest: ARRAY UnitType OF INTEGER _ [4, 4, 0]; --in steps Biggest: ARRAY UnitType OF INTEGER _ [3000, 2400, 0]; --in steps LayerStream: ARRAY [0..MaxLENGTHLayerArray) OF StreamHandle _ ALL[NIL]; X: ARRAY [0..MaxLENGTHLayerArray) OF LONG INTEGER _ ALL[-1]; Y: ARRAY [0..MaxLENGTHLayerArray) OF LONG INTEGER _ ALL[-1]; H: ARRAY [0..MaxLENGTHLayerArray) OF LONG INTEGER _ ALL[-1]; W: ARRAY [0..MaxLENGTHLayerArray) OF LONG INTEGER _ ALL[-1]; A: ARRAY [0..MaxLENGTHLayerArray) OF LONG INTEGER _ ALL[-1]; NRecs: ARRAY [0..MaxLENGTHLayerArray) OF LONG INTEGER _ ALL[0]; --set up context RegisterDevice[@MannDeviceRecord]; END. (635)\560b9B1063b7B816b10B194b13B86b15B150b12B208b17B67b10B856b9B324b7B1462b9B573b13B82b8B90b13B626b13B68b14B99b11B1439b17B1210b12B1119b5B123b7B190b5B193b16B106b22B