CDPlotImpl.mesa
Curry, July 21, 1986 1:59:43 pm PDT
DIRECTORY
CD, CDBasics, CDCommandOps, CDDirectory, CDIO, CDPlot, CDOps, CDOrient, CDProperties, CDSequencer, CDViewer, CMos, CommandTool, Commander, Convert, FileNames, FS, IO, PDFileWriter, PeachPrint, Rope, SymTab, TerminalIO, ThisMachine, TokenIO, ViewerOps;
CDPlotImpl: CEDAR PROGRAM
IMPORTS CDBasics, CDCommandOps, CDDirectory, CDIO, CDOps, CDOrient, CDPlot, CDProperties, CDSequencer, CDViewer, CommandTool, Commander, Convert, FileNames, FS, IO, PeachPrint, Rope, SymTab, TerminalIO, ThisMachine, TokenIO, ViewerOps
EXPORTS CDPlot =
BEGIN
NEW4: PUBLIC PROC[stipple: CDPlot.Stipple4] RETURNS[REF] =
{RETURN[IF stipple = ALL[0] THEN NIL ELSE NEW[CDPlot.Stipple4 ← stipple]]};
NEW8: PUBLIC PROC[stipple: CDPlot.Stipple8] RETURNS[REF] =
{RETURN[IF stipple = ALL[0] THEN NIL ELSE NEW[CDPlot.Stipple8 ← stipple]]};
NEWLayerTonerSipples: PUBLIC PROC[size: CD.Layer]
RETURNS[lts: REF CDPlot.LayerTonerSipples] = {
lts ← NEW[CDPlot.LayerTonerSipples[size]];
FOR layer: CD.Layer IN [0..size) DO
FOR toner: CDPlot.Toner IN CDPlot.Toner DO
lts[layer][toner] ← NIL ENDLOOP ENDLOOP };
thisMachine: REF CDPlot.PrinterDesc = NEW[ CDPlot.PrinterDesc ←
[name: ThisMachine.Name[], iFace: peach ] ];
CDPlotProc: Commander.CommandProc = {
ENABLE {
ABORTED  => GOTO Abort;
PeachPrint.PupAborted => GOTO Abort };
design:   CD.Design;
printer:   REF CDPlot.PrinterDesc;
dName:   Rope.ROPE;
pName:   Rope.ROPE;
nn, nofNums: INT ← 0;
xn, yn:   INT ← 1;
clip:    CD.Rect ← [0, 0, 0, 0];
argv:    CommandTool.ArgumentVector ← CommandTool.Parse[cmd];
load, exp, killC, noSend: BOOLFALSE;
color:       BOOLTRUE;
FOR ii: INT DECREASING IN [1..argv.argc) DO
rope: Rope.ROPE ← CommandTool.ArgN[cmd, ii];
SELECT rope.Fetch[0] FROM
'- => SELECT rope.Fetch[1] FROM
'l, 'L => load  ← TRUE; -- just load for interactive use
'k, 'K => killC  ← TRUE; -- kill CMosB comments
'b, 'B => color  ← FALSE;
'c, 'C => color  ← TRUE;
'e, 'E => exp  ← TRUE;
'n, 'N => noSend ← TRUE;
ENDCASE;
IN ['0..'9] => {
temp: INTMAX[0, Convert.IntFromRope[rope]];
SELECT nofNums FROM
0 => {xn   ← MIN[20,  MAX[1, Convert.IntFromRope[rope]]]};
1 => {yn ← xn; xn ← MIN[20,  MAX[1, Convert.IntFromRope[rope]]]};
2 => {nn   ← MIN[xn*yn-1, MAX[0, Convert.IntFromRope[rope]]]};
ENDCASE => ERROR;
nofNums ← nofNums +1};
ENDCASE => {pName ← dName; dName ← rope} ENDLOOP;
IF NOT IsPrinterName[pName] AND IsPrinterName[dName] THEN
{temp: Rope.ROPE ← dName; dName ← pName; pName ← temp};
color ← col OR NOT (design.technology.key=$chipnsil OR bw);
printer ← GetPrinter[pName: pName, color: color];
IF printer=NIL THEN {cmd.out.PutRope["Printer not found\n"]; RETURN};
color ← printer.color;
IF exp THEN [] ← CommandTool.DoCommand["PeachExpand", cmd];
IF dName # NIL THEN [design, clip] ← GetDesignClip[dName, cmd];
IF design#NIL AND nofNums=3 THEN {clip ← GetNthOfXYSections[nn, xn, yn, clip]; xn←yn𡤁};
IF load OR design=NIL THEN {cmd.out.PutRope["CDPlot loaded\n"]; RETURN};
IF color
THEN {
ENABLE Error => {cmd.out.PutRope[msg]; ERROR ABORTED};
rect: CD.Rect ← CDCommandOps.BoundingBox[design];
pdc: REF CDPlot.PDControlRec ← NEW[CDPlot.PDControlRec ← [
ipType:  printer.ipType,
stripes:  xn,
clip:   clip ]];
IF CDSequencer.FetchCommand[$PDAutoPlot, design.technology]=NIL
THEN [] ← CommandTool.DoCommand["CDPlotPD", cmd];
[] ← CommandTool.DoCommand["CDPlotPD", cmd];
[] ← CommandTool.DoCommand["STPServer start", cmd];
InitTechnologyStipples[design.technology.key, cmd, killC];
IF killC THEN KillCmosBComments[];
CDPDPlot[design, pdc];
IF ~noSend THEN FOR xx: INT IN [1..xn] DO
IF exp
THEN {
PrintPD[thisMachine, primary,  xx, cmd];
PrintPD[printer,   secondary, xx, cmd]}
ELSE {
PrintPD[printer, primary, xx, cmd]}
ENDLOOP;
IF killC THEN RestoreCmosBComments[]}
ELSE {
firstNm:  Rope.ROPE ← PeachPrint.FileName[long, primary, 1, ".ip"];
secondNm: Rope.ROPE ← PeachPrint.FileName[long, secondary, 1, ".pd"];
line:   Rope.ROPE ← Rope.Cat["InterpressToPD ", secondNm, " ← ", firstNm];
ipc: REF CDPlot.IPControlRec ← NEW[CDPlot.IPControlRec ← [
pageNumX: xn,
pageNumY: yn,
type:   IF printer.pgType=stripe THEN stripe ELSE variable,
borders:  yes,
clip:   clip,
altFonts:  FALSE,
altFontsFile: NIL ]];
IF CDSequencer.FetchCommand[$IPAutoPlot, design.technology]=NIL
THEN [] ← CommandTool.DoCommand["CDPlotIP", cmd];
[] ← CommandTool.DoCommand["CDPlotIP", cmd];
CDIPPlot[design, ipc];
[]𡤌ommandTool.DoCommand[Rope.Cat[line, " ", printerNames[printer.ipType] ], cmd];
IF ~noSend THEN PrintPD[printer, secondary, 1, cmd]};
EXITS Abort => {cmd.out.PutF["aborted\n"]; RETURN[$Failure]; } };
ParseName: PROC[name: Rope.ROPE] RETURNS[root, ext: Rope.ROPE] = {
index: INT ← Rope.Find[name, "."];
SELECT index FROM
-1      => RETURN[name, NIL];
0      => RETURN[NIL,  NIL];
name.Length[]-1 => RETURN[Rope.Substr[name, 0, index], NIL]
ENDCASE    => RETURN[Rope.Substr[name, 0, index], Rope.Substr[name, index+1]]};
GetDesignClip: PROC [name: Rope.ROPE, cmd: Commander.Handle]
RETURNS [design: CD.Design, clip: CD.Rect] = {
inst:  CD.Instance;
root, ext: Rope.ROPE;
[root, ext] ← ParseName[name];
design  ← GetDesign[root, cmd];
IF design=NIL THEN RETURN[NIL, [0,0,0,0]];
clip ← CDCommandOps.BoundingBox[design];
IF Rope.Length[ext]=0 OR Rope.Equal[ext, "dale", FALSE] THEN RETURN[design, clip];
inst ← GetTopDesignObjInst[design, ext];
IF inst=NIL THEN RETURN[NIL, [0,0,0,0]];
clip ← CDOrient.RectAt[inst.location, inst.ob.size, inst.orientation];
RETURN[design, clip]};
GetTopDesignObjInst: PROC [design: CD.Design, name: Rope.ROPE] RETURNS[inst: CD.Instance]={
object: CD.Object ← CDDirectory.Fetch[design, name].object;
IF object=NIL THEN RETURN[NIL];
FOR l: CD.InstanceList ← CDOps.InstList[design], l.rest WHILE l#NIL DO
IF l.first.ob=object THEN RETURN[l.first]; ENDLOOP;
RETURN[NIL]};
GetDesign: PROC [name: Rope.ROPE, cmd: Commander.Handle]
RETURNS [design: CD.Design] = {
runFile: Rope.ROPE;
design ← FindDesignViewer[name];
IF design#NIL THEN RETURN[design];
IF Rope.Length[name]=0 THEN RETURN[NIL];
design ← CDIO.ReadDesign[name];
IF design#NIL THEN RETURN[design];
runFile ← SELECT PeekAtTechnology[name].techKey FROM
$chipnsil  => "CDSil",
$nmos  => "CDNMos",
$cmos   => "CDCMosA",
$cmosB  => "CDCMosB",
ENDCASE  => ERROR ABORTED;
[ ] ← CommandTool.DoCommand[runFile, cmd];
design ← CDIO.ReadDesign[name] };
InitTechnologyStipples: PROC [techKey: ATOM, cmd: Commander.Handle, killC: BOOL] = {
SELECT techKey FROM
$chipnsil  => CDPlot.InitSil[];
$nmos  => CDPlot.InitNMos[];
$cmos   => CDPlot.InitCMosA[];
$cmosB  => CDPlot.InitCMosB[];
ENDCASE  => ERROR ABORTED };
CommentStipples: ARRAY CDPlot.PrinterType OF ARRAY CDPlot.Toner OF REFALL[ALL[NIL]];
KillCmosBComments: PROC = {
cmosBPtrLTS: REF CDPlot.PrinterLTS ← NARROW[CDProperties.GetProp[$cmosB, $stipples]];
IF cmosBPtrLTS=NIL THEN RETURN;
FOR printer: CDPlot.PrinterType IN CDPlot.PrinterType DO
IF cmosBPtrLTS[printer]=NIL THEN LOOP;
CommentStipples[printer] ← cmosBPtrLTS[printer][CD.commentLayer];
cmosBPtrLTS[printer][CD.commentLayer] ← ALL[NIL] ENDLOOP};
RestoreCmosBComments: PROC = {
cmosBPtrLTS: REF CDPlot.PrinterLTS ← NARROW[CDProperties.GetProp[$cmosB, $stipples]];
IF cmosBPtrLTS=NIL THEN RETURN;
FOR printer: CDPlot.PrinterType IN CDPlot.PrinterType DO
IF cmosBPtrLTS[printer]=NIL THEN LOOP;
cmosBPtrLTS[printer][CD.commentLayer] ← CommentStipples[printer] ENDLOOP};
FindDesignViewer: PROC[name: Rope.ROPE] RETURNS[design: CD.Design←NIL] = {
Checker: ViewerOps.EnumProc ~ {design ← CDViewer.DesignOf[v]; RETURN[design=NIL]};
IF name.Length[]#0 THEN RETURN[CDViewer.FindDesign[name]];
ViewerOps.EnumerateViewers[Checker] };
PeekAtTechnology: PROC[name: Rope.ROPE] RETURNS[techKey:ATOM, techName: Rope.ROPE] ={
wDir: Rope.ROPE ← FileNames.CurrentWorkingDirectory[];
fileName: Rope.ROPE ← CDIO.MakeName[name, "dale", wDir];
ok: BOOL ← TRUE;
versionKey: INT ← 0;
binfile: FS.STREAM;
binfile ← FS.StreamOpen[fileName ! FS.Error =>
IF error.group = user THEN {
TerminalIO.WriteRope[Rope.Cat[fileName, " not opened: ", error.explanation, "\n"]];
ok ← FALSE; CONTINUE }];
IF NOT ok THEN RETURN[NIL, NIL];
IF binfile=NIL THEN ERROR;
TokenIO.AttachReader[binfile !
TokenIO.Error => {
r: Rope.ROPE ← "bad explanation";
IF ISTYPE[explanation, Rope.ROPE] THEN r←NARROW[explanation];
TerminalIO.WriteRopes[r, "... not attached\n"];
ok ← FALSE; CONTINUE }];
IF NOT ok THEN RETURN[NIL, NIL];
IF TokenIO.ReadInt[]#12121983
THEN {TerminalIO.WriteRope["Not a ChipNDale file\n"]; RETURN[NIL, NIL]};
versionKey ← TokenIO.ReadInt[];
IF TokenIO.ReadInt[]#-1
THEN {TerminalIO.WriteRope["File does not have a seal\n"]; RETURN[NIL, NIL]};
techKey ← TokenIO.ReadAtom[];
techName ← TokenIO.ReadRope[];
TokenIO.ReleaseReader[] };
IsPrinterName: PROC [pName: Rope.ROPE] RETURNS[BOOL] =
{RETURN[
SymTab.Fetch[printerTable, PrinterKey[pName, TRUE]].found
OR
SymTab.Fetch[printerTable, PrinterKey[pName, FALSE]].found ]};
PrinterKey: PROC [pName: Rope.ROPE, color: BOOL] RETURNS[Rope.ROPE] =
{RETURN[Rope.Cat[(IF color THEN "+" ELSE "-"), pName]]};
GetPrinter: PROC [pName: Rope.ROPE, color: BOOL]
RETURNS [printer: REF CDPlot.PrinterDesc] = {
found: BOOL;
val:  REF;
IF pName#NIL THEN {
[found, val] ← SymTab.Fetch[printerTable, PrinterKey[pName, color]];
IF ~found THEN color ← ~color;
[found, val] ← SymTab.Fetch[printerTable, PrinterKey[pName, color]];
IF ~found THEN RETURN[NIL];
RETURN[NARROW[val]] };
RETURN[IF color THEN defaultColorPrinter ELSE defaultBandWPrinter] };
GetNthOfXYSections: PROC [n, x, y: INT, clip: CD.Rect] RETURNS[CD.Rect] = {
size: CD.Position ← CDBasics.SizeOfRect  [clip];
pos: CD.Position ← CDBasics.BaseOfRect [clip];
size.y ← (size.y + (y-1))/y;
size.x ← (size.x + (x-1))/x;
pos ← [size.x * (n MOD x), size.y * (n / x)];
RETURN[CDBasics.RectAt[pos, size]]};
PrintPD: PROC [printer: REF CDPlot.PrinterDesc, order: PeachPrint.FileNameOrder, index: INT,
cmd: Commander.Handle] = {
file: Rope.ROPE ← PeachPrint.FileName[long, order, index, ".pd"];
IF printer.iFace=tsetter
THEN []𡤌ommandTool.DoCommand[Rope.Cat["Tsetter ",  printer.name, " ", file], cmd]
ELSE []𡤌ommandTool.DoCommand[Rope.Cat["PeachPrint ", printer.name, " ", file], cmd]};
CDIPPlot: PUBLIC PROC[design: CD.Design, ipc: REF CDPlot.IPControlRec] = {
command: CDSequencer.Command ← NEW[CDSequencer.CommandRec ←
[design: design, data: ipc, key: $IPAutoPlot]];
CDSequencer.ExecuteCommand[comm: command]};
CDPDPlot: PUBLIC PROC[design: CD.Design, pdc: REF CDPlot.PDControlRec] = {
command: CDSequencer.Command ← NEW[CDSequencer.CommandRec ←
[design: design, data: pdc, key: $PDAutoPlot]];
CDSequencer.ExecuteCommand[comm: command]};
Want to do the commnad line version (above) in order to not load the IP stuff unless needed.
See: [Cedar]<CedarChest6.0>InterpressTools>PrintFileConvertImpl.InterpressToPDAction
InterpressToPD: PROC
[iName: ROPE, oName: ROPE, printerType: ImagerPD.PrinterType, cmd: Commander.Handle] ~ {
printerTypePPD: ARRAY ImagerPD.PrinterType OF REAL ← [
nil:   5, raven300:  6, raven384:  6, o3:     5,
plateMaker: 9, o5:    5, puffin:  6, colorVersatec: 5,
versatec:  5, color400:  7, c150:   4, o11:    5,
o12:   5, o13:   5, o14:   5, o15:    5 ];
realPPD:  REAL ~ printerTypePPD[printerType];
interpress: Interpress.OpenMaster ~ Interpress.Open[iName, Log, cmd];
pd:   ImagerPD.PD ~
ImagerPD.CreateFromPrinterType[oName, printerType, NIL, NIL, realPPD];
FOR i: INT IN [0..interpress.pages) DO
action: PROC [context: Imager.Context] ~
{Interpress.DoPage[master: interpress, context: context, page: i+1]};
cmd.out.PutF[" [%g", IO.int[i+1]];
ImagerPD.DoPage[pd: pd, action: action, pixelUnits: FALSE];
cmd.out.PutChar[']];
ENDLOOP;
cmd.out.PutChar[' ];
ImagerPD.Close[pd] };
printerNames: ARRAY CDPlot.PrinterType OF Rope.ROPE ← [
nil:    NIL,
raven300:   "Raven300",
raven384:   "Raven384",
o3:     NIL,
plateMaker:  "PlateMaker",
o5:     NIL,
puffin:   "Puffin",
colorVersatec: "ColorVersatec",
versatec:   "Versatec",
color400:   "Color400",
c150:    "C150",
d4020:    "d4020",
bw400:   "bw400",
o13:    NIL,
o14:    NIL,
o15:    NIL ];
Error: ERROR [msg: Rope.ROPE] = CODE;
GetStipples: PUBLIC PROC [design: CD.Design, printerType: CDPlot.PrinterType]
RETURNS [stipples: REF CDPlot.LayerTonerSipples] = {
printerStipples: REF CDPlot.PrinterLTS;
color:    BOOL;
stippleSource: ATOM;
val:    REF ← CDProperties.GetProp[from: design, prop: $stipples];
IF val#NIL THEN RETURN[NARROW[val]];
color ← SELECT printerType FROM
colorVersatec, color400, c150 => TRUE,
ENDCASE => FALSE;
Interpretations:  TYPE = {sil, silBW, sticks, nmos, cmosA, cmosB, other};
$chipnsil, $silBW and $sticks  initialized by CDPlotPDSil
$nmos        initialized by CDPlotPDNMos
$cmos         initialized by CDPlotPDCMosA
$cmosB        initialized by CDPlotPDCMosB
stippleSource ← SELECT design.technology.key FROM
$chipnsil  => IF color THEN $chipnsil ELSE $silBW,
$nmos  => IF color THEN $nmos  ELSE NIL,
$cmos   => IF color THEN $cmos  ELSE NIL,
$cmosB  => IF color THEN $cmosB  ELSE NIL,
Sticks.Sticks => IF color THEN $sticks  ELSE NIL, -- how should this be done?
ENDCASE  => NIL;
val ← CDProperties.GetProp[from: stippleSource, prop: $stipples];
IF val=NIL THEN ERROR Error["I can't find stipples for this technology\n"];
printerStipples ← NARROW[val];
stipples ← printerStipples[printerType];
IF stipples=NIL THEN ERROR Error["I can't find stipples for this device\n"];
RETURN[stipples] };
SwapSipples: PUBLIC PROC[stipples: REF CDPlot.LayerTonerSipples] = {
FOR layer: CD.Layer IN [0..stipples.size) DO
SwapRefRec: TYPE = RECORD[r0, r1: REF];
[stipples[layer][black], stipples[layer][yellow]] ←
SwapRefRec[  stipples[layer][yellow], stipples[layer][black]];
[stipples[layer][cyan], stipples[layer][magenta]] ←
SwapRefRec[  stipples[layer][magenta], stipples[layer][cyan]]; ENDLOOP};
Init: PROC = {
Store: PROC[printerRec: CDPlot.PrinterDesc] = {
printer: REF CDPlot.PrinterDesc ← NEW[CDPlot.PrinterDesc ← printerRec];
[] ← SymTab.Store[printerTable, PrinterKey[printer.name, printer.color], printer]};
colorKey: Rope.ROPE = PrinterKey["Sleepy", col];
bwKey: Rope.ROPE = PrinterKey["Sleepy", bw];
col: BOOL = TRUE;
bw: BOOL = FALSE;
Store[["Sleepy",  col, stripe, peach, colorVersatec ]];
Store[["Sleepy",  bw, stripe, peach, versatec  ]];
Store[["MtFuji",  col, page, peach, color400  ]];
Store[["ColorPatch", col, page, peach, color400  ]];
Store[["MtDiablo", col, page, peach, d4020   ]];
Store[["Stinger",  bw, page, tsetter, raven384  ]];
Store[["Quoth",  bw, page, tsetter, raven384  ]];
defaultColorPrinter  ← NARROW[SymTab.Fetch[printerTable, colorKey ].val];
defaultBandWPrinter ← NARROW[SymTab.Fetch[printerTable, bwKey  ].val];
[ ] ← CDProperties.RegisterProperty[ prop: $stipples, registrationKey: $CDPlot] };
printerTable:    SymTab.Ref ← SymTab.Create[case: FALSE];
defaultColorPrinter:  REF CDPlot.PrinterDesc;
defaultBandWPrinter: REF CDPlot.PrinterDesc;
doc:      Rope.ROPE = " Design Nx𡤁 Ny𡤁 Server";
Init[];
Commander.Register[key:"CDPlot", proc: CDPlotProc, doc: doc];
END.