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: BOOL ← FALSE;
color: BOOL ← TRUE;
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: INT ← MAX[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 REF ← ALL[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.