DIRECTORY Atom, CD, CDBasics, CDCommandOps, CDViewer, CDMenus, CDOps, CDProperties, CDSequencer, CornerStitching, Graphics, GraphicsOps, IO, PDFileFormat, PDFileWriter, Process, Real, Rope, TerminalIO, ViewerClasses, ViewerSpecs; CDColorVersatecImpl: CEDAR PROGRAM IMPORTS Atom, CD, CDBasics, CDCommandOps, CDMenus, CDViewer, CDOps, CDProperties, CDSequencer, CornerStitching, IO, PDFileWriter, Process, Real, TerminalIO = BEGIN Ink: TYPE = PDFileFormat.Toner; -- {black, cyan, magenta, yellow}; ColorRef: TYPE = REF ColorLoad_NIL; ColorLoad: TYPE = ARRAY Ink OF PDFileWriter.LoadReference; whiteLoadRef: PDFileWriter.LoadReference _ LAST[PDFileWriter.LoadReference]; pdState: PDFileWriter.PDState; pdx, pdy : CARDINAL _ 0; -- origin of band in pixel coords cdx, cdy, -- origin of band in chipndale coords xoffset, yoffset : INT _ 0; -- offset in transforming between coord systems plotScale: REAL; versatec: PDFileFormat.DeviceCode _ last; sRes, fRes: CARDINAL _ 200; -- resolution (slow directition, fast direction) in pixels per inch maxScanLineWidth: CARDINAL = 8000; maxPixPerLambda: REAL = 20; -- maximum # of pixels to make lambda overLap: CARDINAL = 300; -- number of pixels by which to overlap strips scanLineWidth: CARDINAL _ maxScanLineWidth; imageSSize: REAL _ 0; imageFSize: CARDINAL _ maxScanLineWidth; bandSSize: CARDINAL _ 64; debugging: BOOL _ FALSE; numBands, numRectangles: INT _ 0; PlotStateRef: TYPE = REF PlotState; PlotState: TYPE = RECORD [ text: REF CornerStitching.Tesselation _ NIL, tes: ARRAY CD.Level OF REF CornerStitching.Tesselation _ ALL[NIL], -- enumerates all the rectangles in a given level scale: REAL _ 1.0, -- pixels per CD.DesignNumber totalPlotClip, bandClip: CD.DesignRect _ [0,0,0,0], colorLoads: REF ARRAY CD.Level OF ColorRef ]; StripFileName: PROC [index: INTEGER] RETURNS [name: Rope.ROPE] = BEGIN name _ IO.PutFR[ "///temp/plot%d.pd", IO.int[index+1]]; END; VersatecColorPlotComm: PROC [ comm: CDSequencer.Command ] = BEGIN TerminalIO.WriteRope["Colorplot\n"]; [] _ CDCommandOps.CallWithResource[ProtectedPlotDesign, comm, $ColorPlot, abortPlot]; END; signalFont: Graphics.FontRef _ NIL; plotter: Rope.ROPE _ "vice"; plotFileToSpool: Rope.ROPE _ "[vice]plot.pd"; plotFileOnPlotter: Rope.ROPE _ "plot.pd"; plotFileOnLocalMachine: Rope.ROPE _ "plot0.pd"; spoolToPlotter: BOOL _ TRUE; abortPlot: REF BOOL = NEW[BOOL _ FALSE]; ProtectedPlotDesign: PROC [comm: CDSequencer.Command] = BEGIN design: CD.Design = comm.design; plotClip: CD.DesignRect = CDBasics.ToRect[comm.pos, comm.sPos]; s: IO.STREAM _ NIL; n: INT _ TerminalIO.RequestInt["How many vertical strips? [1..10] "]; strips: INT _ MAX[1, MIN[10, n]]; BEGIN ENABLE { -- for ERRORs UNWIND => { s _ AbortFile[s]; CDViewer.RemoveArrow[design]; TerminalIO.WriteRope[" ** plot aborted ** "] }; }; dr: CD.DrawRef = CD.NewNullDeviceDrawRef[design]; scale: REAL _ MIN[maxPixPerLambda/CD.lambda, (REAL[scanLineWidth]+REAL[scanLineWidth-overLap]*(strips-1))/(plotClip.x2-plotClip.x1)]; ps: PlotStateRef = NEW[ PlotState _ [ text: CornerStitching.NewTesselation[], scale: scale, totalPlotClip: plotClip, colorLoads: NEW[ARRAY CD.Level OF ColorRef_ALL[NIL]] ] ]; usedLevels: REF PACKED ARRAY CD.Level OF BOOL _ NIL; imageSSize _ (plotClip.y2-plotClip.y1)* scale; plotScale _ scale; IF debugging THEN { TerminalIO.WriteRope[" Scale factor (pixels/design#)*100 --> "]; TerminalIO.WriteInt[Real.RoundLI[plotScale*100]]; TerminalIO.WriteLn[]; }; TerminalIO.WriteRope["Starting Color Versatec plot "]; TerminalIO.WriteLn[]; TRUSTED {Process.SetPriority[Process.priorityBackground]}; dr.minimalSize _ 0; dr.drawRect _ dr.saveRect _ NoteLevel; dr.worldClip _ CDBasics.universe; dr.stopFlag _ abortPlot; dr.devicePrivate _ usedLevels _ NEW[PACKED ARRAY CD.Level OF BOOL _ ALL[FALSE]]; CDOps.DrawDesign[design, dr]; -- mark used levels dr.drawRect _ dr.saveRect _ NoteRectangle; dr.devicePrivate _ ps; FOR strip: INT IN [0..strips) DO clip: CD.DesignRect = [ x1: plotClip.x1+strip*((plotClip.x2-plotClip.x1)/strips), y1: plotClip.y1, x2: plotClip.x1+(strip+1)*((plotClip.x2-plotClip.x1)/strips)+ Real.Fix[overLap/scale]+1, y2: plotClip.y2]; tonerSet: PDFileWriter.TonerSet _ ALL[TRUE]; localFileName: Rope.ROPE = StripFileName[strip]; TerminalIO.WriteRope["Recording strip on file "]; TerminalIO.WriteRope[localFileName]; TerminalIO.WriteLn[]; pdState _ PDFileWriter.Create[ fileName: localFileName, deviceCode: versatec, sResolution: sRes, fResolution: fRes, imageSSize: Real.RoundC[imageSSize + 1], imageFSize: imageFSize, bandSSize: bandSSize, leftOverMode: FALSE]; ps.colorLoads^ _ ALL[NIL]; numBands _ 0; numRectangles _ 0; PDFileWriter.StartImage[pdState: pdState, toners: tonerSet]; FOR topLine: INT _ 0, topLine+bandSSize WHILE topLine "]; TerminalIO.WriteInt[numBands]; TerminalIO.WriteRope[" # rectangles -> "]; TerminalIO.WriteInt[numRectangles]; TerminalIO.WriteLn; }; CDViewer.RemoveArrow[design: design]; EXITS AbortPlot => { s _ AbortFile[s]; CDViewer.RemoveArrow[design]; TerminalIO.WriteRope[" ** plot aborted ** "]; }; END; -- enable END; -- PlotDesign NoteLevel: PROC [ r: CD.DesignRect, l: CD.Level, pr: CD.DrawRef ] = BEGIN ps: REF PACKED ARRAY CD.Level OF BOOL = NARROW[pr.devicePrivate]; ps[l] _ TRUE; END; NoteRectangle: PROC [ r: CD.DesignRect, l: CD.Level, pr: CD.DrawRef ] = BEGIN ps: PlotStateRef = NARROW[pr.devicePrivate]; IF CDBasics.NonEmpty[r] THEN { IF ps.tes[l]=NIL THEN ps.tes[l] _ CornerStitching.NewTesselation[]; ps.tes[l].ChangeRect[rect: r, newValue: $covered]; }; END; TonerKey: PROC [toner: PDFileFormat.Toner] RETURNS [ATOM] = INLINE { RETURN [ SELECT toner FROM black => $CDxVersatecBlack, cyan => $CDxVersatecCyan, magenta => $CDxVersatecMagenta, yellow => $CDxVersatecYellow, ENDCASE => $CDxVersatecBlack ] }; AnalyzeTesselations: PROC [ ps: PlotStateRef ] = BEGIN FOR lev: CD.Level IN CD.Level DO IF ps.tes[lev]#NIL THEN { IF ps.colorLoads^[lev]=NIL THEN { tex: REF; ps.colorLoads^[lev] _ NEW[ColorLoad]; FOR toner: Ink IN Ink DO tex _ CDProperties.GetPropFromLevel[from: lev, prop: TonerKey[toner]]; ps.colorLoads^[lev][toner] _ (IF tex = NIL THEN whiteLoadRef ELSE MakeLoadref[tex]); ENDLOOP; }; FOR toner: Ink IN Ink DO IF ps.colorLoads^[lev][toner] = whiteLoadRef THEN PDFileWriter.SetColorOff[pdState, toner] ELSE PDFileWriter.SetColorTile[pdState, toner, ps.colorLoads^[lev][toner], transparent]; ENDLOOP; [] _ ps.tes[lev].EnumerateArea[ rect: ps.bandClip, perTile: ProcessTile, data: ps, backgroundValue: $none ]; }; ENDLOOP; END; ProcessTile: PROCEDURE [tile: CornerStitching.TilePtr, data: REF ANY] -- CornerStitching.PerTileProc -- = BEGIN -- only called on covered tiles rightBound, x1, y1, x2, y2: INT; pdx1, pdx2, pdy1, pdy2 : CARDINAL; sSize, fSize : CARDINAL; ps: PlotStateRef = NARROW[data]; tileValue: REF = tile.Value; IF tileValue = $covered THEN BEGIN r: CD.DesignRect = tile.Area; x1 _ Real.RoundLI[xoffset + r.x1*plotScale]; y1 _ Real.RoundLI[yoffset + r.y1*(-plotScale)]; x2 _ Real.RoundLI[xoffset + r.x2*plotScale]; y2 _ Real.RoundLI[yoffset + r.y2*(-plotScale)]; rightBound _ Real.RoundLI[xoffset + ps.bandClip.x2*plotScale]; IF NOT ((( x1 > rightBound) OR (x2 < 0)) OR (( y1 < pdy) OR (y2 > MIN[imageSSize, pdy+bandSSize]))) THEN { pdx1 _ MAX[x1, 0]; pdx2 _ MIN[x2, rightBound, imageFSize]; pdy1 _ MIN[y1, pdy+bandSSize]; pdy2 _ MAX[y2, pdy]; fSize _ pdx2 - pdx1; sSize _ pdy1 - pdy2; IF pdy1 >= imageSSize THEN sSize _ Real.Fix[imageSSize - pdy2] ; IF ((sSize # 0) AND (fSize # 0)) THEN { PDFileWriter.MaskRectangle[pdState: pdState, sMin: pdy2, fMin: pdx1, sSize: sSize, fSize: fSize]; numRectangles _ numRectangles + 1; IF debugging THEN { TerminalIO.WriteRope[" position -> "]; TerminalIO.WriteInt[Real.RoundLI[y1]]; TerminalIO.WriteInt[Real.RoundLI[x1]]; TerminalIO.WriteRope[" size -> "]; TerminalIO.WriteInt[sSize]; TerminalIO.WriteInt[fSize]; TerminalIO.WriteLn; } } } END; END; SignalValueRef: TYPE = REF SignalValue; SignalValue: TYPE = RECORD [s: Rope.ROPE]; LookForSignalName: PROC [ design: CD.Design, aptr: CD.ApplicationPtr, x: REF ] RETURNS [done: BOOL_FALSE, removeMe: BOOL_FALSE, include: CD.ApplicationList_NIL, repaintMe: BOOL_FALSE, repaintInclude: BOOL_FALSE] -- CDCallSpecific.CallProc -- = BEGIN GetSignalName: PROC [signal: REF] RETURNS [s: Rope.ROPE] = BEGIN WITH signal SELECT FROM atom: ATOM => s _ Atom.GetPName[atom]; rope: Rope.ROPE => s _ rope; ENDCASE => s _ "?"; END; END; PaintASignalName: PROC [tile: CornerStitching.TilePtr, data: REF ANY] RETURNS [REF ANY] -- CornerStitching.PerTileProc -- = BEGIN ps: PlotStateRef = NARROW[data]; RETURN[data]; END; Stipple16: TYPE = ARRAY[0..16) OF CARDINAL; Stipple8: TYPE = ARRAY[0..8) OF [0..256); Stipple4: TYPE = ARRAY[0..4) OF [0..16); ToTexture: PROC [pattern: REF ANY] RETURNS [texture: Stipple16] = BEGIN IF pattern=NIL THEN RETURN[Stipple16[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]; -- should not occur 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; MakeLoadref: PROC [pattern: REF ANY] RETURNS [PDFileWriter.LoadReference] = TRUSTED BEGIN loadRef: PDFileWriter.LoadReference; texture: Stipple16 _ ToTexture[pattern]; loadRef _ PDFileWriter.LoadContiguousColorTile[pdState: pdState, phase: 0, sMin: 0, fMin: 0, sSize: 16, fSize: 16, bitsPtr: @texture]; RETURN[loadRef]; END; AbortFile: PROC [s: IO.STREAM ] RETURNS [ IO.STREAM ] = {IF s#NIL THEN s.Close[abort: TRUE]; RETURN[NIL]}; Init: PROC ~ { CDSequencer.ImplementCommand[a~$VersatecColorPlot, p~VersatecColorPlotComm]; CDMenus.CreateEntry[$RectProgramMenu, "Color Plot", $VersatecColorPlot]; TerminalIO.WriteRope["ChipNDale COLOR Versatec plotter loaded\n"]; }; Init[]; END. -- of CDColorVersatecImpl CDColorVersatecImpl.mesa Copyright c 1983, 1984 by Xerox Corporation. All rights reserved. written by E. McCreight, August 1, 1983 2:00 PM Last Edited by: McCreight, November 23, 1983 4:58 pm Last Edited by: Jacobi, October 27, 1983 12:36 pm Last Edited by: Jacobi, November 5, 1984 3:11:09 pm PST Last Edited by: Kimr, October 29, 1984 9:49:48 am PST -- a color associated with a level is a collection of textures associated with inks -- used to identify tiles without toner so that you can avoid recording them -- scale factor between systems, is negative for y-axis due to reversed direction of increasing values (when compared with pixel coordinates) ??? PDFileWriter seems to require that some value be given; at the current time, there wasn't one for versatec so I chose the only unassigned value --for the wide-bed Versatec, length in the "fast" direction -- number chosen because of buffer-size of versatec rectangles in design space touching all geometry in the plot, or this band Center the x range of the selected area of the design on the plotter bed, with at most maxPixPerLambda pixels per lambda. If multiple strips are called for, overlap adjacent ones by "overLap" pixels. -- total number of pixels across plot = REAL[scanLineWidth]+REAL[scanLineWidth-overLap]*(strips-1)) -- total width of design = plotClip.x2-plotClip.x1 -- length of plot in pixels -- Determine clip rectangle for strip -- For each band in the strip -- Determine coordinate transformations -- (negative scale to account for CD increasing y north, PD increasing y going south) -- rectangle in design space that ChipNDale can use to clip its recursive drawing --Display current band under consideration to pacify user -- clear previous tessalations -- assign each level a texture and draw all the rectangles in the region t: CornerStitching.TilePtr; -- Calculate absolute coords of rectangle here as offset from plot origin -- if rectangle is in bandarea, clip and write; otherwise disregard rectangle -- can't have rectangles landing on or over the imageSSize -- disregard rectangles without area TerminalIO.WriteRope["+"]; -- code for outlining rectangles Put lines at boundaries with regions of other color FOR t _ tile.NEastNeighbour, t.WSouthNeighbour WHILE tile.SouthEdge(ymax-ymin)) # ((r.x2-r.x1)>(r.y2-r.y1)) THEN textContext.Rotate[270]; textContext.SetColor[Graphics.white]; textContext.DrawBox[[xmin: -2, ymin: -2, xmax: xmax-xmin+2, ymax: ymax-ymin+2]]; leave a two-scan-line white patch all around textContext.SetColor[Graphics.black]; textContext.SetCP[x: 0, y: 0]; textContext.DrawRope[rope: signalValue.s, font: signalFont]; --tries to convert pattern to a texture stipple signalFont _ VFonts.GraphicsFont[VFonts.EstablishFont[family: "Helvetica", size: 18, bold: TRUE]]; Κ ˜šœ™J™Jšœ Οmœ7™BJšœ0™0Jšœ4™4J™1J™7J™5—J˜šΟk ˜ Jšœ˜Jšžœ˜Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ ˜ Jšœ ˜ Jšžœ˜J˜ J˜ Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜Jšœ ˜ J˜—šΟbœžœž˜"Jšžœžœ!Οcœ?žœ+˜žJšž˜J˜Jšœžœ "˜CJ˜Jšœ žœžœ žœ˜#šœ žœžœžœ˜:J™S—J˜šœ+žœ˜MJšœM™M—J˜J˜J˜J˜Jšœ žœ !˜;šœ %˜4Jšœžœ /˜LJ˜—šœ žœ˜Jš 2œ[™J™J™—šœ+˜+Jšœ“™“—J˜šœ žœ ˜Jš C˜C—šœžœ ˜#Jšœ;™;—Jšœžœ %˜AJšœ žœ  .˜HJšœžœ˜+Jšœ žœ˜Jšœ žœ˜(šœ žœ˜Jšœ3™3—J˜Jšœ žœžœ˜Jšœžœ˜!J˜J˜Jšœžœžœ ˜#šœ žœžœ˜Jšœžœžœ˜,Jšœžœžœžœžœžœžœ 1˜tJšœžœ ˜0šœžœ˜3JšœJ™J—Jš œ žœžœžœžœ ˜*Jšœ˜J˜J˜—š Οn œžœ žœžœ žœ˜@Icodešž˜Kšœžœžœ˜7Kšžœ˜—K˜š‘œžœ ˜;Jšžœ˜Jšœ%˜%JšœU˜UJšžœ˜J˜—Jšœžœ˜#Jšœžœ ˜Jšœžœ˜5Jšœžœ˜1Jšœžœ˜0Jšœžœžœ˜J˜Jš œ žœžœžœžœžœ˜(J˜š‘œžœ˜7Jšž˜J˜Jšœžœ˜ Jšœ žœ3˜?J˜Jšœžœžœžœ˜Jšœžœ?˜EJšœžœžœžœ ˜"˜šžœžœ  ˜šžœ˜ Jšœ˜Jšœ˜Jšœ,˜,Jšœ˜—Jšœ˜—J˜Jšœžœ žœ˜1J˜š œžœžœžœ žœžœ?˜…JšœΗ™ΗJšœ(žœžœ#™cJšœ3™3J™—J˜šœžœ˜%Jšœ'˜'Jšœ ˜ Jšœ˜Jš œ žœžœžœžœ žœžœ˜4Jšœ˜—J˜Jšœ žœžœžœžœžœžœžœ˜4šœ.˜.J™/J™—Jšœ˜J™J˜šžœ žœ˜J˜BJ˜1J˜J˜—J™Jšœ6˜6J˜Jšžœ3˜:Jšœ˜Jšœ&˜&J˜!Jšœ˜Jšœ žœžœžœžœžœžœžœžœ˜PJ˜Jšœ ˜1˜J˜—Jšœ*˜*J˜J˜Jšžœžœžœ ž˜ ˜J˜J™%šœžœ›˜€Jšœ!˜!—Jšœ˜J˜Jšœ"žœžœ˜,J˜Jšœžœ˜0J˜1J˜$J˜—˜JšœΩžœ˜ΰJ˜Jšœžœžœ˜J™J˜ J˜—™J˜˜>J˜J™Mšžœžœžœ ž˜,Jšœ žœžœžœ˜>Jšœžœ˜Jšœžœ˜'Jšœžœ˜Jšœžœ ˜J˜J˜J™:šžœž˜Jšœ%˜%—J™$šžœžœžœ˜'J˜aJšœ™J˜"šžœ žœ˜Jšœ*˜*Jšœ&˜&Jšœ&˜&Jšœ'˜'Jšœ˜Jšœ˜J˜Jšœ˜—Jšœ˜—J˜—Jšžœ˜—J™J™ Jšœ3™3šžœ,žœž™RJšœ#™#šžœž™Jšž™Jšœ-žœ™OJšœ.žœ™PJšžœ™—Jšžœ™—šžœ,žœž™PJšœ#™#šžœž™Jšž™Jšœžœ0™NJšœžœ0™OJšžœ™—Jšžœ™—J˜Jšžœ˜J˜J˜—J˜Jšœžœžœ ˜'Jšœ žœžœ žœ˜*J˜š"‘œžœ žœžœžœžœžœžœ žœžœ žœžœžœžœžœžœ œ˜χJšž˜J˜Jšœθ™θJ˜š ‘ œžœ žœžœ žœ˜:Jšž˜šžœžœž˜Jšœžœ˜&Jšœ žœ ˜Jšžœ ˜—Jšžœ˜J™—Jšœžœ™Jšœžœ\™aJšœžœ7™Bšžœ žœžœž™-Jšž™Jšœžœ+™LJš œžœžœžœžœ!™TJšœ3™3š žœžœžœžœ-žœžœž™UJšœH™HJšžœ™—Jšž™—Jšžœžœ™Jšžœ˜J˜J˜—š‘œžœ'žœžœžœžœžœ !œ˜{Jšž˜Jšœžœ˜ Jšœ?™?Jšœžœ™3Jšœ žœ™%JšœžœA™FJšœžœ%™,Jšœ\™\Jšœk™kJšœC ™[šžœ7ž™=Jšœ™—Jšœ%™%šœP™PJšœ,™,—Jšœ%™%Jšœ™Jšœ<™