DIRECTORY
Atom,
CD,
CDBasics,
CDCommandOps,
CDDefaultProcs,
CDEnvironment,
CDIO,
CDVArrow,
CDCurves,
CDOps,
CDOrient,
CDPDPlot,
CDProperties,
CDPropertyTools,
CDSequencer,
CDValue,
GraphicsBasic,
CGArea,
CGClipper,
CGReducer,
Commander,
CStitching,
IO,
PeachPrint,
PDFileFormat,
PDFileWriter,
Process,
Real,
Rope,
RuntimeError USING [UNCAUGHT],
TerminalIO,
ViewerClasses,
ViewerSpecs;
CDPDPlotImpl: CEDAR MONITOR
IMPORTS Atom, CD, CDBasics, CDCommandOps, CDDefaultProcs, CDEnvironment, CDIO, CDValue, CDVArrow, CDOps, CDOrient, CDCurves, CDProperties, CDPropertyTools, CDSequencer, CGArea, CGClipper, CGReducer, Commander, CStitching, IO, PDFileWriter, PeachPrint, Process, Real, Rope, RuntimeError, TerminalIO
EXPORTS CDPDPlot =
BEGIN
retry: CONDITION;
plottingInProgress: BOOL _ FALSE;
Enter: ENTRY PROC [d: CD.Design] = {
ENABLE UNWIND => NULL;
BROADCAST retry; --to make others call CheckAborted
WHILE plottingInProgress DO
WAIT retry;
CDSequencer.CheckAborted[d]; --UNWIND IS CATCHED !!!
ENDLOOP;
plottingInProgress _ TRUE
};
Leave: ENTRY PROC [] = {
ENABLE UNWIND => NULL;
plottingInProgress _ FALSE;
BROADCAST retry
};
lastTechPropKey: REF _ $CDxLastTechnology; --a property of the dd.stippleKey
abortPlot: REF BOOL _ NEW[BOOL _ FALSE];
Toner: TYPE = PDFileFormat.Toner; -- {black, cyan, magenta, yellow, .. 15};
TonerKeys: TYPE = ARRAY Toner OF REF;
LoadArray: TYPE = ARRAY Toner OF PDFileWriter.LoadReference;
ColorDescription: TYPE = ARRAY CD.Layer OF REF LoadArray _ ALL[NIL];
noColor: PDFileWriter.LoadReference = LAST[PDFileWriter.LoadReference];
fullColor: PDFileWriter.LoadReference = noColor-1;
tonerToKeyKeys: REF TonerKeys = NEW[TonerKeys _ ALL[NIL]];
DeviceDesc: TYPE = CDPDPlot.DeviceDesc;
TaskDesc: TYPE = CDPDPlot.TaskDesc;
PageMode: TYPE = {fixedPage, finiteStripe, anyStripe};
Stipple4: TYPE = ARRAY[0..4) OF [0..16);
Stipple8: TYPE = ARRAY[0..8) OF [0..256);
Stipple16: TYPE = ARRAY[0..16) OF CARDINAL;
fiddleDevice: PUBLIC REF DeviceDesc _ NIL;
error: ERROR = CODE;
MakeDevice: PUBLIC PROC [key: ATOM] RETURNS [dd: REF DeviceDesc] =
BEGIN
ColorVersatec: PROC [dd: REF DeviceDesc] =
BEGIN
dd.deviceCode _ last; --does not yet has an assigned value, use "last"
dd.sResolution _ 200; -- resolution (slow directition), pixels / inch
dd.fResolution _ 200; -- resolution (fast direction), pixels / inch
dd.imageFSize _ 8000; --for the wide-bed Versatec, length in the "fast" direction;
dd.toners _ ALL[FALSE];
dd.toners[black] _ TRUE;
dd.toners[cyan] _ TRUE;
dd.toners[magenta] _ TRUE;
dd.toners[yellow] _ TRUE;
dd.bandSSize _ 64; -- number chosen because of buffer-size of versatec
dd.overlap _ 300; -- number of pixels by which to overlap strips
dd.maxPixPerLambda _ 20; -- maximum # of pixels to make lambda
dd.pageMode _ anyStripe;
dd.leftOverMode _ FALSE;
dd.stippleKey _ $CDxVersatec;
dd.name _ "color versatec";
END;
InkJetC150: PROC [dd: REF DeviceDesc] =
BEGIN
dd.deviceCode _ VAL[10];
dd.sResolution _ 120; -- resolution (slow directition), pixels / inch
dd.fResolution _ 120; -- resolution (fast direction), pixels / inch
dd.imageFSize _ 1020;
dd.toners _ ALL[FALSE];
dd.toners[black] _ TRUE;
dd.toners[cyan] _ TRUE;
dd.toners[magenta] _ TRUE;
dd.toners[yellow] _ TRUE;
dd.bandSSize _ 48; --
dd.overlap _ 30; -- number of pixels by which to overlap strips
dd.maxPixPerLambda _ 20; -- maximum # of pixels to make lambda
dd.pageMode _ finiteStripe;
dd.pageSlowSize _ 1020;
dd.leftOverMode _ FALSE;
dd.stippleKey _ $CDxVersatec;
dd.name _ "ink jet";
END;
Color400: PROC [dd: REF DeviceDesc] =
BEGIN
dd.deviceCode _ VAL[9];
dd.sResolution _ 400; -- resolution (slow directition), pixels / inch
dd.fResolution _ 400; -- resolution (fast direction), pixels / inch
dd.imageFSize _ 4096;
dd.toners _ ALL[FALSE];
dd.toners[black] _ TRUE;
dd.toners[cyan] _ TRUE;
dd.toners[magenta] _ TRUE;
dd.toners[yellow] _ TRUE;
dd.bandSSize _ 50; --
dd.overlap _ 30; -- number of pixels by which to overlap strips
dd.maxPixPerLambda _ 240; -- maximum # of pixels to make lambda
dd.pageMode _ fixedPage;
dd.pageSlowSize _ 5500;
dd.leftOverMode _ FALSE;
dd.stippleKey _ $CDxC400;
dd.name _ "Color400";
END;
Puffin: PROC [dd: REF DeviceDesc] =
BEGIN
dd.deviceCode _ PDFileFormat.DeviceCode[puffin];
dd.sResolution _ 384; -- resolution (slow directition), pixels / inch
dd.fResolution _ 384; -- resolution (fast direction), pixels / inch
dd.imageFSize _ dd.fResolution * 17 / 2;
dd.toners _ ALL[FALSE];
dd.toners[black] _ FALSE;
dd.toners[cyan] _ TRUE;
dd.toners[magenta] _ TRUE;
dd.toners[yellow] _ TRUE;
dd.bandSSize _ 16; --
dd.overlap _ 30; -- number of pixels by which to overlap strips
dd.maxPixPerLambda _ 20; -- maximum # of pixels to make lambda
dd.pageMode _ fixedPage;
dd.pageSlowSize _ dd.sResolution*11;
dd.leftOverMode _ TRUE;
dd.stippleKey _ $CDxPuffin;
dd.name _ "Puffin";
END;
PlateMaker: PROC [dd: REF DeviceDesc] =
BEGIN
dd.deviceCode _ PDFileFormat.DeviceCode[last];
dd.sResolution _ 1200; -- resolution (slow directition), pixels / inch
dd.fResolution _ 1200; -- resolution (fast direction), pixels / inch
dd.imageFSize _ dd.fResolution * 17 / 2;
dd.toners _ ALL[FALSE];
dd.toners[black] _ TRUE;
dd.bandSSize _ 16; --
dd.overlap _ 30; -- number of pixels by which to overlap strips
dd.maxPixPerLambda _ 20; -- maximum # of pixels to make lambda
dd.pageMode _ fixedPage;
dd.pageSlowSize _ dd.sResolution*11;
dd.leftOverMode _ TRUE;
dd.stippleKey _ $CDxPDPlotPlatemaker;
dd.name _ "platemaker [color separation]";
END;
Raven384: PROC [dd: REF DeviceDesc] =
BEGIN
dd.deviceCode _ PDFileFormat.DeviceCode[raven];
dd.sResolution _ 384; -- resolution (slow directition), pixels / inch
dd.fResolution _ 384; -- resolution (fast direction), pixels / inch
dd.imageFSize _ dd.fResolution * 17 / 2;
dd.toners _ ALL[FALSE];
dd.toners[black] _ TRUE;
dd.bandSSize _ 16; --
dd.overlap _ 30; -- number of pixels by which to overlap strips
dd.maxPixPerLambda _ 20; -- maximum # of pixels to make lambda
dd.pageMode _ fixedPage;
dd.pageSlowSize _ dd.sResolution*11;
dd.leftOverMode _ TRUE;
dd.stippleKey _ $CDxPDPlotRaven384;
dd.name _ "Raven384 [color separation]";
END;
dd _ NEW[DeviceDesc];
dd.contextFilter _ NEW[CD.ContextFilter_ALL[TRUE]];
SELECT key FROM
$Versatec, $PDPlotVersatec => ColorVersatec[dd];
$C150, $PDPlotC150 => InkJetC150[dd];
$Puffin, $PDPlotPuffin => Puffin[dd];
$Platemaker, $PDPlotPlatemaker => PlateMaker[dd];
$Raven384, $PDPlotRaven384 => Raven384[dd];
$Color400, $PDPlotColor400 => Color400[dd];
$UserDevice, $PDPlotUserDevice => dd _ fiddleDevice;
ENDCASE => ERROR error;
END;
PlotState: TYPE = REF PlotStateRec;
PlotStateRec: TYPE = RECORD [
tes: ARRAY CD.Layer OF CStitching.Tesselation _ ALL[NIL],
plotScale: REAL _ 1.0, -- pixels per CD.Number
plotClip, bandClip: CD.Rect _ [0, 0, 0, 0],
pdState: PDFileWriter.PDState,
colorLoads: REF ColorDescription,
anouncedLayer: INT _ -1,
design: CD.Design,
pdy: CARDINAL _ 0, -- top of band in pixel coords
dd: REF DeviceDesc
];
Plot: PUBLIC PROC [task: REF TaskDesc] =
BEGIN
ps: PlotState;
clipSize: CD.Position;
dd: REF DeviceDesc _ task.dd;
design: CD.Design _ task.design;
pageStep: CD.Position;
pageWidth: CD.Position;
dr: CD.DrawRef;
IF design=NIL OR dd=NIL THEN ERROR;
BEGIN
ENABLE { -- for ERRORs
UNWIND => {
CDVArrow.RemoveArrow[design];
TerminalIO.WriteRope[" ** plot aborted **\n"];
Leave[];
};
};
Enter[design];
TRUSTED {Process.SetPriority[Process.priorityBackground]};
task.strips _ MAX[1, MIN[10, task.strips]];
IF task.abort=NIL THEN task.abort _ NEW[BOOL_FALSE];
IF ~CDBasics.NonEmpty[task.clip] THEN task.clip _ CDCommandOps.BoundingBox[design];
clipSize _ CDBasics.SizeOfRect[task.clip];
dr _ CD.CreateDrawRef[[
design: design,
stopFlag: task.abort,
drawRect: NoteRectangle,
drawContext: DrawContext,
contextFilter: dd.contextFilter
]];
SetStipples[dd, design.technology];
CheckSpecialScale[task];
ps _ NEW[PlotStateRec _ [
plotClip: task.clip,
colorLoads: NEW[ColorDescription _ ALL[NIL]],
design: design,
plotScale: task.scale,
dd: dd
]];
IF ps.plotScale<=0 THEN {
ps.plotScale _ MIN[
REAL[dd.maxPixPerLambda] / design.technology.lambda,
REAL[(dd.imageFSize-dd.overlap)*task.strips+dd.overlap] / clipSize.x
]
};
dd.imageSSize _ Real.FixC[clipSize.y*ps.plotScale]+1;
IF dd.pageMode=fixedPage THEN {
dd.imageSSize _ MIN[dd.imageSSize, dd.pageSlowSize];
ps.plotScale _ MIN[ps.plotScale, REAL[dd.pageSlowSize]/(clipSize.y+1)];
};
pageStep _ [clipSize.x/task.strips, clipSize.y];
pageWidth _ [Real.Round[dd.imageFSize/ps.plotScale], clipSize.y];
dr.devicePrivate _ ps;
TerminalIO.WriteRopes["start ploting\n"];
FOR strip: INT IN [0..task.strips) DO
fileName: Rope.ROPE _ MakeName[task.fileName, strip, task.strips];
dd.stripClip _ [ --but not yet intersected with complete design clip
x1: ps.plotClip.x1+strip*pageStep.x,
y1: ps.plotClip.y1,
x2: ps.plotClip.x1+strip*pageStep.x+pageWidth.x,
y2: ps.plotClip.y2
];
ps.pdState _ PDFileWriter.Create[
fileName: fileName,
deviceCode: dd.deviceCode,
sResolution: dd.sResolution,
fResolution: dd.fResolution,
imageSSize: dd.imageSSize,
imageFSize: dd.imageFSize,
bandSSize: dd.bandSSize,
leftOverMode: dd.leftOverMode,
maxLoadWords: dd.maxLoadWords,
copies: dd.copies
];
ps.colorLoads^ _ ALL[NIL];
PDFileWriter.StartImage[pdState: ps.pdState, toners: dd.toners];
FOR bandYtop: INT _ 0, bandYtop+dd.bandSSize WHILE bandYtop
TerminalIO.WriteRopes["color stipples used: [", r, "]\n"];
ENDCASE => {
TerminalIO.WriteRope["**color stipples are not defined\n"];
ERROR ABORTED
};
IF technology.key#CDProperties.GetAtomProp[dd.stippleKey, lastTechPropKey] THEN {
TerminalIO.WriteRope["**Warning: another technology registered in the meantime; the technology independent stipples are redefined\n"];
};
dd.tonerToKey _ NEW[TonerKeys _ ALL[NIL]];
FOR t: PDFileWriter.Toner IN PDFileWriter.Toner DO
dd.tonerToKey^[t] _ CDProperties.GetAtomProp[dd.stippleKey, tonerToKeyKeys[t]];
IF ~dd.toners[t] OR dd.tonerToKey^[t]=NIL THEN {
dd.toners[t] _ FALSE;
dd.tonerToKey^[t] _ NEW[INT];
}
ENDLOOP;
PrepareContextFilter[dd];
END;
SetColor: PROC [ps: PlotState, lev: CD.Layer] =
BEGIN
MakeLoadref: PROC [pattern: REF ANY] RETURNS [loadRef: PDFileWriter.LoadReference] =
TRUSTED BEGIN
ToTexture: PROC [pattern: REF ANY] RETURNS [texture: Stipple16] =
CHECKED BEGIN
WITH pattern SELECT FROM
s16: REF Stipple16 => texture _ s16^;
s8: REF Stipple8 =>
FOR i: [0..8) IN [0..8) DO
texture[i] _ texture[i+8] _ (256+1)*s8[i];
ENDLOOP;
s4: REF Stipple4 =>
FOR i: [0..4) IN [0..4) DO
texture[i] _ texture[i+4] _ texture[i+8] _ texture[i+12] _ s4[i]*1111H;
ENDLOOP;
ENDCASE => RETURN[Stipple16[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0FFFFH]]; -- error texture
RETURN [texture]
END; -- ToTexture
IF pattern=NIL THEN loadRef _ noColor
ELSE IF pattern=$ink THEN loadRef _ fullColor
ELSE {
texture: Stipple16 _ ToTexture[pattern];
loadRef _ PDFileWriter.LoadContiguousColorTile[pdState: ps.pdState, phase: 0, sMin: 0, fMin: 0, sSize: 16, fSize: 16, bitsPtr: @texture];
IF loadRef>=fullColor THEN ERROR;
};
END; -- MakeLoadref
MakeLoad: PROC [ps: PlotState, lev: CD.Layer] = INLINE
BEGIN
IF ps.colorLoads^[lev]=NIL THEN {
ps.colorLoads^[lev] _ NEW[LoadArray];
FOR toner: Toner IN Toner DO
tex: REF _ CDProperties.GetLayerProp[from: lev, prop: ps.dd.tonerToKey[toner]];
IF tex=NIL THEN ps.colorLoads^[lev][toner] _ noColor
ELSE ps.colorLoads^[lev][toner] _ MakeLoadref[tex]
ENDLOOP;
};
END; --MakeLoad
IF ps.anouncedLayer=lev THEN RETURN;
IF ps.colorLoads^[lev]=NIL THEN MakeLoad[ps, lev];
FOR toner: Toner IN Toner DO
IF ps.colorLoads^[lev][toner] = noColor THEN
PDFileWriter.SetColorOff[ps.pdState, toner]
ELSE IF ps.colorLoads^[lev][toner] = fullColor THEN
PDFileWriter.SetColorInk[ps.pdState, toner]
ELSE
PDFileWriter.SetColorTile[ps.pdState, toner, ps.colorLoads^[lev][toner], transparent];
ENDLOOP;
ps.anouncedLayer _ lev
END;
PlotPolygon: PROC [ps: PlotState, ob: CD.Object, pos: CD.Position, orient: CD.Orientation] =
BEGIN
OutputTrapezoid: PROC [xbotL: REAL, xbotR: REAL, ybot: REAL, xtopL: REAL, xtopR: REAL, ytop: REAL] =
BEGIN
PDFileWriter.MaskTrapezoid[
pdState: ps.pdState,
sMin: Real.RoundC[ybot],
sSize: Real.RoundC[ytop-ybot],
fMin: Real.RoundC[xbotL],
fSize: Real.RoundC[xbotR-xbotL],
fMinLast: Real.RoundC[xtopL],
fSizeLast: Real.RoundC[xtopR-xtopL]
];
END; --OutputTrapezoid
dd: REF DeviceDesc = ps.dd;
pp: CDCurves.CurvePtr = NARROW[ob.specificRef];
polygon: CGReducer.Ref = CGReducer.New[size: 8];
tiling: CGArea.Ref = CGArea.New[size: 4];
clipRef: CGClipper.Ref = CGClipper.New[size: 4];
clip: GraphicsBasic.Box _ [
xmin: 0,
ymin: ps.pdy,
xmax: MIN[(ps.bandClip.x2-dd.stripClip.x1)*ps.plotScale, dd.imageFSize],
ymax: MIN[ps.pdy+dd.bandSSize, dd.imageSSize]
];
CGClipper.SetBox[self: clipRef, box: clip];
CGClipper.Load[self: clipRef, reducer: polygon];
FOR p: LIST OF CD.Position _ pp.points, p.rest WHILE p#NIL DO
at: CD.Position = CDOrient.MapPoint[
pointInCell: p.first,
cellSize: ob.size,
cellInstOrient: orient,
cellInstPos: pos
];
CGReducer.Vertex[self: polygon, v: [
x: (at.x-dd.stripClip.x1)*ps.plotScale,
y: (dd.stripClip.y2-at.y)*ps.plotScale
]]
ENDLOOP;
CGReducer.Close[polygon];
CGReducer.Generate[self: polygon, area: tiling];
UNTIL CGArea.Empty[tiling] DO
t: GraphicsBasic.Trap = CGArea.Remove[tiling];
OutputTrapezoid[t.xbotL, t.xbotR, t.ybot, t.xtopL, t.xtopR, t.ytop];
ENDLOOP;
END; --PlotPolygon
DrawContext: PROC [pr: CD.DrawRef, proc: CD.DrawContextLayerProc, ob: CD.Object, pos: CD.Position, orient: CD.Orientation, layer: CD.Layer] =
BEGIN
IF CDCurves.IsPolygon[ob] THEN {
ps: PlotState = NARROW[pr.devicePrivate];
SetColor[ps, layer];
PlotPolygon[ps, ob, pos, orient];
}
ELSE CDDefaultProcs.DrawContext[pr, proc, ob, pos, orient, layer]
END;
AnalyzeTesselations: PROC [ps: PlotState] =
BEGIN
FOR lev: CD.Layer IN CD.Layer DO
IF ps.tes[lev]#NIL THEN {
SetColor[ps, lev];
CStitching.EnumerateArea[plane: ps.tes[lev], rect: ps.bandClip, eachTile: ProcessTile, data: ps];
};
ENDLOOP;
END;
ProcessTile: PROC [tile: CStitching.Tile, data: REF ANY] =
BEGIN
IF tile.value = $covered THEN {
rightBound, xStart, xStop, yStart, yStop: INT;
cxStart, cxStop, cyStop, cyStart: CARDINAL;
sSize, fSize: CARDINAL;
ps: PlotState = NARROW[data];
dd: REF DeviceDesc = ps.dd;
r: CD.Rect = tile.Area;
xStart _ Real.Round[(r.x1-dd.stripClip.x1)*ps.plotScale];
yStop _ Real.Round[(dd.stripClip.y2-r.y1)*ps.plotScale];
xStop _ Real.Round[(r.x2-dd.stripClip.x1)*ps.plotScale];
yStart _ Real.Round[(dd.stripClip.y2-r.y2)*ps.plotScale];
rightBound _ Real.Round[(ps.bandClip.x2-dd.stripClip.x1)*ps.plotScale];
IF xStart>rightBound OR xStop<0 THEN RETURN;
IF yStopMIN[dd.imageSSize, ps.pdy+dd.bandSSize] THEN RETURN;
cxStart _ MAX[xStart, 0];
cxStop _ MIN[xStop, rightBound, dd.imageFSize];
cyStart _ MAX[yStart, ps.pdy];
cyStop _ MIN[yStop, ps.pdy+dd.bandSSize, dd.imageSSize];
fSize _ cxStop - cxStart;
sSize _ cyStop - cyStart;
IF sSize>0 AND fSize>0 THEN
PDFileWriter.MaskRectangle[pdState: ps.pdState, sMin: cyStart, fMin: cxStart, sSize: sSize, fSize: fSize];
};
END;
CheckSpecialScale: PROC [task: REF TaskDesc] = {
micronsPerInch: REAL ~ 25400;
dd: REF DeviceDesc _ task.dd;
specialScale: REAL _ -1; --means microns on plotted device per lambda
WITH CDProperties.GetAtomProp[dd.stippleKey, $CDxPDPlotScale] SELECT FROM
ri: REF INT => specialScale _ ri^;
rr: REF REAL => specialScale _ rr^;
ENDCASE => specialScale _ -1;
IF specialScale>0 THEN {
size: CD.Position _ CDBasics.SizeOfRect[task.clip];
task.scale _ specialScale*dd.sResolution/micronsPerInch/task.design.technology.lambda;
TerminalIO.WriteF["plotting at special scale %g microns/lambda [%g pixels/chipndaleUnit]\n", [real[specialScale]], [real[task.scale]]];
IF dd.pageMode=fixedPage THEN {
IF task.scale > REAL[dd.pageSlowSize]/(size.y+1) THEN
TerminalIO.WriteRope["doesn't fit on page; must change scale\n"];
};
};
};
cnt: INT _ 0;
PDColorPlotComm: PROC [comm: CDSequencer.Command] =
BEGIN
ENABLE error => {
SELECT TerminalIO.RequestSelection["ERROR", LIST["abort plot", "reset and abort plot", "debug"]] FROM
1 => GOTO tobad;
2 => {currTech _ NIL; GOTO tobad};
3 => REJECT;
ENDCASE => GOTO tobad;
};
clip: CD.Rect;
mustSendToDevice: BOOL _ FALSE;
server: Rope.ROPE; copies: INT _ 1;
task: REF TaskDesc _ NEW[TaskDesc _ [design: comm.design, abort: abortPlot, strips: 1]];
TerminalIO.WriteRope["Color plot\n"];
task.dd _ MakeDevice[comm.key];
IF task.dd=NIL THEN {
TerminalIO.WriteRope["no device specified\n"];
RETURN
};
TerminalIO.WriteRopes[task.dd.name, "\n"];
SELECT TerminalIO.RequestSelection["PD Plot", LIST["plot complete design", "plot drawn rectangle", "specials, strips, servers..."]] FROM
1 => {
clip _ CDCommandOps.BoundingBox[comm.design];
TerminalIO.WriteRope["plot all\n"];
};
2 => {
clip _ CDBasics.ToRect[comm.pos, comm.sPos];
TerminalIO.WriteRope["plot rectangle\n"];
};
3 => {
default: Rope.ROPE _ NIL;
choice: LIST OF Rope.ROPE _ LIST["no", "type name of server"];
TerminalIO.WriteRope["special\n"];
SELECT TerminalIO.RequestSelection["Plot", LIST["plot complete design", "plot drawn rectangle"]] FROM
1 => {
clip _ CDCommandOps.BoundingBox[comm.design];
TerminalIO.WriteRope["plot all\n"];
};
2 => {
clip _ CDBasics.ToRect[comm.pos, comm.sPos];
TerminalIO.WriteRope["plot rectangle\n"];
};
ENDCASE => ERROR ABORTED;
IF task.dd.pageMode=anyStripe THEN {
IF TerminalIO.Confirm[label: "plot multiple vertical strips", choice: "yes"] THEN
task.strips _ TerminalIO.RequestInt["How many vertical strips? [1..10] "];
};
IF TerminalIO.Confirm[label: "ommit comments", choice: "yes"] THEN
task.dd.contextFilter[CD.commentLayer] _ FALSE;
IF comm.key=$PDPlotVersatec THEN default _ "Sleepy"
ELSE IF comm.key=$PDPlotColor400 THEN default _ "MtFuji";
IF default#NIL THEN choice.rest.rest _ LIST[default];
SELECT TerminalIO.RequestSelection["send immediately to server", choice] FROM
0, 1 => NULL;
2 => {
mustSendToDevice _ TRUE;
server _ TerminalIO.RequestRope["server name>"];
};
3 => {
mustSendToDevice _ TRUE;
server _ default;
};
ENDCASE => NULL;
IF mustSendToDevice THEN {
IF TerminalIO.Confirm[label: "multiple copies", choice: "yes"] THEN
copies _ TerminalIO.RequestInt["copies>"];
IF copies<1 OR copies>10 THEN {
TerminalIO.WriteRope["unreasonable number of copies\n"];
ERROR ABORTED
};
};
};
ENDCASE => ERROR ABORTED;
IF clip.x1>=clip.x2 OR clip.y1>=clip.y2 THEN {
TerminalIO.WriteRope["**cannot plot empty area\n"];
ERROR ABORTED
};
task.clip _ clip;
IF mustSendToDevice THEN
task.fileName _ IO.PutFR["///temp/chipndale/pdplots/Plot%gX.pd", IO.int[cnt _ cnt+1]];
Plot[task];
IF mustSendToDevice THEN {
FOR strip: INT IN [0..task.strips) DO
PeachPrint.DoPeachPrintCommand[
server: server,
file: MakeName[task.fileName, strip, task.strips],
log: TerminalIO.TOS[],
copies: copies,
fork: TRUE
!
PeachPrint.PupAborted => {TerminalIO.WriteRope["**Pup aborted plotting\n"]; CONTINUE};
RuntimeError.UNCAUGHT => {TerminalIO.WriteRope["**Peach aborted plotting\n"]; CONTINUE};
];
ENDLOOP
};
EXITS tobad => NULL
END;
MakeName: PROC [base: Rope.ROPE, strip, strips: INT_1] RETURNS [fileName: Rope.ROPE] = {
modifier: Rope.ROPE _ IF strips>1 THEN IO.PutFR["%d", IO.int[strip+1]] ELSE NIL;
IF Rope.IsEmpty[base] THEN base _ "PDPlot";
fileName _ CDIO.MakeName[wDir: "///temp/", base: base, modifier: modifier, ext: "pd"];
};
WaitPlotFinishedCommand: Commander.CommandProc =
BEGIN
prio: Process.Priority = Process.GetPriority[];
IF ~plottingInProgress THEN {
IO.PutRope[cmd.out, " waiting for plot to start"];
WHILE ~plottingInProgress DO
Process.Pause[Process.SecondsToTicks[1]];
ENDLOOP;
IO.PutRope[cmd.out, ". plot started...\n"]
};
Process.SetPriority[Process.priorityBackground];
WHILE plottingInProgress DO
Process.Pause[Process.SecondsToTicks[2]];
ENDLOOP;
Process.SetPriority[prio];
IO.PutRope[cmd.out, " finished\n"]
END;
blackX: REF _ NIL;
cyanX: REF _ NIL;
yellowX: REF _ NIL;
magentaX: REF _ NIL;
currTech: CD.Technology _ NIL;
currLayer: CD.Layer _ CD.undefLayer;
Forgett: PROC [l: CD.Layer] =
BEGIN
IF blackX#NIL THEN CDProperties.PutLayerProp[onto: l, prop: blackX, val: NIL];
IF cyanX#NIL THEN CDProperties.PutLayerProp[onto: l, prop: cyanX, val: NIL];
IF magentaX#NIL THEN CDProperties.PutLayerProp[onto: l, prop: magentaX, val: NIL];
IF yellowX#NIL THEN CDProperties.PutLayerProp[onto: l, prop: yellowX, val: NIL];
END;
Start: PUBLIC PROC[tech, device, b, c, m, y: ATOM, text: Rope.ROPE_NIL, invert: BOOL_FALSE] =
BEGIN
IF currTech#NIL THEN ERROR error;
CDPropertyTools.RemoveProperties[$CDxPDPlotScale];
CDPropertyTools.RemoveProperties[device];
CDProperties.PutAtomProp[device, $CDxPDPlotScale, NIL]; --might be not associated
IF b#NIL THEN CDPropertyTools.RemoveProperties[b];
IF c#NIL THEN CDPropertyTools.RemoveProperties[c];
IF m#NIL THEN CDPropertyTools.RemoveProperties[m];
IF y#NIL THEN CDPropertyTools.RemoveProperties[y];
currTech _ CD.FetchTechnology[tech];
blackX _ b;
cyanX _ c;
yellowX _ y;
magentaX _ m;
CDValue.Store[currTech, device, text];
IF invert THEN {
CDProperties.PutAtomProp[device, tonerToKeyKeys[black], yellowX];
CDProperties.PutAtomProp[device, tonerToKeyKeys[cyan], magentaX];
CDProperties.PutAtomProp[device, tonerToKeyKeys[yellow], blackX];
CDProperties.PutAtomProp[device, tonerToKeyKeys[magenta], cyanX];
}
ELSE {
CDProperties.PutAtomProp[device, tonerToKeyKeys[black], blackX];
CDProperties.PutAtomProp[device, tonerToKeyKeys[cyan], cyanX];
CDProperties.PutAtomProp[device, tonerToKeyKeys[yellow], yellowX];
CDProperties.PutAtomProp[device, tonerToKeyKeys[magenta], magentaX];
};
CDProperties.PutAtomProp[device, $CDxLastTechnology, currTech.key];
FOR l: CD.Layer IN CD.Layer DO Forgett[l] ENDLOOP;
END;
End: PUBLIC PROC [] = {
currTech _ NIL
};
Layer: PUBLIC PROC [uniqueKey: ATOM] =
BEGIN
currLayer _ CD.FetchLayer[t: currTech, uniqueKey: uniqueKey];
Forgett[currLayer]
END;
LayerNumber: PUBLIC PROC [layer: NAT] =
BEGIN
currLayer _ layer;
Forgett[currLayer]
END;
Color1: PUBLIC PROC [key: ATOM] =
BEGIN
CDProperties.PutLayerProp[onto: currLayer, prop: key, val: $ink]
END;
Color4: PUBLIC PROC [key: ATOM, i0, i1, i2, i3: [0..16)] =
BEGIN
CDProperties.PutLayerProp[onto: currLayer, prop: key,
val:
IF i0=0 AND i1=0 AND i2=0 AND i3=0 THEN NIL
ELSE IF i0=15 AND i1=15 AND i2=15 AND i3=15 THEN $ink
ELSE NEW[Stipple4 _ [i0, i1, i2, i3]]
]
END;
Color8: PUBLIC PROC [key: ATOM, i0, i1, i2, i3, i4, i5, i6, i7: [0..256)] =
BEGIN
CDProperties.PutLayerProp[onto: currLayer, prop: key,
val:
IF i0=0 AND i1=0 AND i2=0 AND i3=0 AND i4=0 AND i5=0 AND i6=0 AND i7=0 THEN NIL
ELSE IF i0=255 AND i1=i0 AND i2=i0 AND i3=i0 AND i4=i0 AND i5=i0 AND i6=i0 AND i7=i0 THEN $ink
ELSE NEW[Stipple8 _ [i0, i1, i2, i3, i4, i5, i6, i7]]
]
END;
Init: PROC [] =
BEGIN
CDPropertyTools.Associate[$CDxPDPlotScale, $CDxPDPlotScale];
tonerToKeyKeys[black] _ $CDxPDPlotBlack;
tonerToKeyKeys[cyan] _ $CDxPDPlotCyan;
tonerToKeyKeys[magenta] _ $CDxPDPlotMagenta;
tonerToKeyKeys[yellow] _ $CDxPDPlotYellow;
CDSequencer.ImplementCommand[key: $PDPlotVersatec, proc: PDColorPlotComm, queue: doQueue];
CDSequencer.ImplementCommand[key: $PDPlotC150, proc: PDColorPlotComm, queue: doQueue];
CDSequencer.ImplementCommand[key: $PDPlotColor400, proc: PDColorPlotComm, queue: doQueue];
CDSequencer.ImplementCommand[key: $PDPlotUserDevice, proc: PDColorPlotComm, queue: doQueue];
Commander.Register[
key: "///Commands/CDWaitPlotFinished",
proc: WaitPlotFinishedCommand,
doc: "waits until ChipNDale pd plotting is finished once"
];
TerminalIO.WriteRope["ChipNDale PD color plot program loaded\n"];
END;
Init[];
END.
μ CDPDPlotImpl.mesa
Copyright c 1983, 1986 by Xerox Corporation. All rights reserved.
History
Black and white versatec plot written by: E. McCreight, August 1, 1983
Changed for color Versatec by: Kim Rachmeler, 1983
Rewritten by: Christian Jacobi, April 11, 1985 3:21:48 pm PST
Last Edited by: Christian Jacobi, August 25, 1986 12:03:08 pm PDT
--MONITOR: to protect the stipples
--handling colors
-- used to identify tiles without toner so that you can avoid recording them
-- used to identify tiles with full toner so that you can avoid recording them
--gives a key to get the keys to get the color stipple as property of the layers
--device description
--state of plot
--rectangles in design space touching all geometry in the plot, or this band
xoffset: INT _ -dd.stripClip.x1*scale;
yoffset: INT _ dd.stripClip.y2*scale;
--Center the x range of the selected area of the design on the plotter bed, with at most dd.maxPixPerLambda pixels per lambda. If multiple task.strips are called for, overlap adjacent ones by "dd.toners" pixels.
-- total number of pixels across plot = imageFSize+[imageFSize-overlap]*(strips-1))
-- For each band in the strip
-- Determine coordinate transformations
--Display current band under consideration to pacify user
-- clear previous tessalations
--tries to convert pattern to a texture stipple
--makes the load if it does not already exist
--SetColor
--lower left x, lower right x, lower y, upper left x, upper right x, upper y
--global variables ps, dd.stripClip, ps.plotScale, dd.imageFSize, dd.imageSSize, ps.pdy
--x-Fast
--y-Slow
--PlotPolygon
-- calculate device coords of rectangle
-- clip device rectangle
-- print device rectangle
--command level
--interpreter set up
--initializations
CD Menus.CreateEntry[$HardCopyMenu, "PD Color Versatec", $PDPlotVersatec];
CD Menus.CreateEntry[$HardCopyMenu, "PD C150", $PDPlotC150];
CD Menus.CreateEntry[$HardCopyMenu, "PD Color400", $PDPlotColor400];
CD Menus.CreateEntry[$HardCopyMenu, "PD using commandfile", $PDPlotUserDevice];
Κ Τ codeK
Οm7BKGGK22K>>KAK Οk KKK K
KKKK K KK K K
KKKKK
K
K
KKKK
K
KKKK
KKKK ΠbnK7I©KKK KΠbk"K K K!K Οn$JK Οc"3KK’4KKKK ‘JKK KK K’!LK(K K KΟbK K’)LK %K