DIRECTORY Atom, CD, CDApplications, CDCallSpecific, CDViewer, CDExtras, CDInline, CDOps, CDProperties, CDSequencer, CornerStitching, FS, Graphics, GraphicsOps, List, Menus, IO, PDFileFormat, PDFileWriter, Process, Real, Rope, TerminalIO, VFonts, ViewerClasses, ViewerSpecs; CDColorVersatecImpl: CEDAR MONITOR IMPORTS Atom, CD, -- CDCallSpecific,-- CDViewer, CDInline, CDOps, CDProperties, CDSequencer, CornerStitching, IO, Menus, PDFileWriter, Process, Real, TerminalIO, VFonts EXPORTS = BEGIN Ink: TYPE = PDFileFormat.Toner; -- {black, cyan, magenta, yellow}; ColorLoad: TYPE = ARRAY Ink OF PDFileWriter.LoadReference; TexVector: TYPE = ARRAY Ink OF CARDINAL; whiteLoadRef: PDFileWriter.LoadReference _ LAST[PDFileWriter.LoadReference]; localFile: Rope.ROPE _ "///temp/plot0.pd"; versatec: PDFileFormat.DeviceCode _ last; -- ??? sRes, fRes: CARDINAL _ 200; -- pixels per inch 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 bet coord systems plotScale: REAL; -- scale factor between systems, is negative for y numStipples: CARDINAL = 27; texValue: REF ARRAY [0..100] OF PDFileWriter.LoadReference _ NEW[ARRAY [0..100] OF PDFileWriter.LoadReference] ; ColorRef: TYPE = REF ColorLoad_NIL; maxScanLineWidth: CARDINAL = 8000; 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 ]; currentFlavor: ViewerClasses.ViewerFlavor = $ChipndaleVersatecPlot; Init: ENTRY PROC ~ { menu: Menus.Menu = Menus.CreateMenu[]; Menus.AppendMenuEntry[menu: menu, entry: Menus.CreateEntry[name: "AbortPlot", proc: AbortProc, guarded: TRUE]]; CDSequencer.ImplementCommand[a~$VPlotLocal, p~PlotDesignToLocalFile]; CDSequencer.ImplementCommand[a~$VersatecColorPlot, p~PlotDesignToAny]; CDSequencer.ImplementCommand[a~$VPlot, p~PlotDesignToAny]; signalFont _ VFonts.GraphicsFont[VFonts.EstablishFont[family: "Helvetica", size: 18, bold: TRUE]]; TerminalIO.WriteRope["ChipNDale COLOR Versatec plotter loaded\n"]; }; NewPlotName: PROC [index: INTEGER] RETURNS [name: Rope.ROPE] = BEGIN name _ IO.PutFR[ "///temp/plot%d.pd", IO.int[index+1]]; END; PlotDesignToAny: ENTRY PROC [ c: CDSequencer.Command ] = BEGIN ENABLE UNWIND => NULL; n: CARDINAL _ 0; TerminalIO.WriteRope["Color plot\n"]; n _ 2; SELECT n FROM 1 => { TerminalIO.WriteRope["plotter is not yet implemented\n"]; }; 2 => PlotDesign[c: c, to: localFile]; 3 => { TerminalIO.WriteRope[" requestFilename is not yet implemented\n"] }; 4 => { TerminalIO.WriteRope["remote is not yet implemented\n"]; }; ENDCASE => TerminalIO.WriteRope["skipped\n"]; END; PlotDesignToLocalFile: ENTRY PROC [ c: CDSequencer.Command ] = BEGIN ENABLE UNWIND => NULL; TerminalIO.WriteRope["Color plot to local file\n"]; PlotDesign[c: c, to: localFile]; END; PlotDesignToRemoteFile: ENTRY PROC [ c: CDSequencer.Command ] = BEGIN ENABLE UNWIND => NULL; TerminalIO.WriteRope["Color plot to remote file\n"]; PlotDesign[c: c, to: remoteFile]; END; PlotDesignToPlotter: ENTRY PROC [ c: CDSequencer.Command ] = BEGIN ENABLE UNWIND => NULL; TerminalIO.WriteRope["Color plot directly to plotter\n"]; PlotDesign[c: c, to: plotter]; END; signalFont: Graphics.FontRef _ NIL; viewer: ViewerClasses.Viewer _ NIL; plotter: Rope.ROPE _ "vice"; plotFileToSpool: Rope.ROPE _ "[vice]plot.pd"; plotFileOnPlotter: Rope.ROPE _ "plot.pd"; plotFileOnLocalMachine: Rope.ROPE _ "plot0.pd"; plotFileOnServer: Rope.ROPE _ "[Luther.alpine]plot.pd"; latestPlotFile: Rope.ROPE _ NIL; spoolToPlotter: BOOL _ TRUE; abortPlot: BOOL _ FALSE; PlotDesign: INTERNAL PROC [ c: CDSequencer.Command, to: {localFile, remoteFile, plotter, requestFilename}] = BEGIN 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 BEGIN UNWIND => {s _ AbortFile[s]; CDViewer.RemoveArrow[design: c.design]; TerminalIO.WriteRope[" ** plot aborted ** "]}; END; design: CD.Design = c.design; plotClip: CD.DesignRect = CDInline.ToRect[c.pos, c.sPos]; dr: CD.DrawRef = CD.NewNullDeviceDrawRef[design]; scale: REAL _ MIN[32.0/CD.lambda, (REAL[scanLineWidth]+REAL[scanLineWidth-150]*(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[]; }; abortPlot _ FALSE; TerminalIO.WriteRope["Starting Color Versatec plot "]; TerminalIO.WriteLn[]; TRUSTED {Process.SetPriority[Process.priorityBackground]}; dr.minimalSize _ 0; dr.drawRect _ dr.saveRect _ NoteLevel; dr.devicePrivate _ usedLevels; dr.worldClip _ CDInline.universe; 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; localFile _ "///temp/plot0.pd"; 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[150./scale]+1, y2: plotClip.y2]; tonerSet: PDFileWriter.TonerSet _ ALL[TRUE]; TerminalIO.WriteRope["Recording strip on file "]; TerminalIO.WriteRope[localFile]; TerminalIO.WriteLn[]; pdState _ PDFileWriter.Create[ fileName: localFile, 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: c.design]; TerminalIO.WriteRope[" ** plot aborted ** "]; abortPlot _ FALSE}; 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 CDInline.NonEmpty[r] THEN BEGIN IF ps.tes[l]=NIL THEN ps.tes[l] _ CornerStitching.NewTesselation[]; ps.tes[l].ChangeRect[rect: r, newValue: $covered]; END; 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; Center: PROC [ r: CD.Rect ] RETURNS [ CD.Position ] = {RETURN[[x: (r.x1+r.x2)/2, y: (r.y1+r.y2)/2]]}; 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; AbortProc: Menus.MenuProc = {abortPlot _ TRUE}; AbortFile: PROC [s: IO.STREAM ] RETURNS [ IO.STREAM ] = {IF s#NIL THEN s.Close[abort: TRUE]; RETURN[NIL]}; Init[]; END. -- of VersatecImpl ΔCDColorVersatecImpl.mesa YOU'L FIND INTERESTING PLACES BY LOOKING FOR "???" 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, May 15, 1984 2:37:12 pm PDT Last Edited by: Kimr, July 23, 1984 11:36:55 am PDT -- a color associated with a level is a collection of textures associated with inks -- used to generate LoadReferences through indexes, there are four textures to a color -- used to identify tiles without toner axis due to reversed direction of increasing values -- number of stipple patterns defined by MakeLoadref -- used to make sure that a given texture is only put into the load once the wide-bed Versatec, length in the "fast" direction rectangles in design space touching all geometry in the plot, or this band p: CARDINAL _ TerminalIO.RequestSelection[ label: "Debugging", choice: LIST["yes", "no"] ]; SELECT p FROM 1 => debugging _ TRUE; 2 => debugging _ FALSE; ENDCASE => debugging _ FALSE; TerminalIO.RequestSelection[ label: "Versatec Plot", choice: LIST[" plotter", " local", " read name", " remote"] ]; PlotDesign[c: c, to: plotter] PlotDesign[c: c, to: requestFilename] PlotDesign[c: c, to: remoteFile]; ???x.Error => BEGIN TerminalIO.WriteRope[]; GOTO AbortPlot; END; -- takes the right and left sides of the square outlined by -- the user and returns normalized rectangle coordinates Center the x range of the selected area of the design on the plotter bed, with at most 32 pixels per lambda. If multiple strips are called for, overlap adjacent ones by 150 pixels. -- total number of pixels in plot = REAL[scanLineWidth]+REAL[scanLineWidth-150]*(strips-1)) -- total width of design = plotClip.x2-plotClip.x1 -- length of plot in pixels For each strip in the design -- 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 tonerKey: ARRAY [PDFileFormat.Toner] OF ATOM _ [$CDxVersatecBlack, $CDxVersatecCyan, $CDxVersatecMagenta, $CDxVersatecYellow]; 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["+"]; 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 Module START code... Κp˜JšœL™LJ˜Jšœ0™0J™4J™1J™3J™3šΟk ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ 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œ9˜«Jšœ˜ Jš˜J˜JšœœŸ"˜CJ˜šœ œœœ˜:J™S—J˜š œ œœœœ˜*J™WJ™—šœ+œ˜MJšœ'™'—J˜Jšœœ˜*J˜Jšœ+Ÿ˜1J˜Jšœ œ Ÿ˜/J˜J˜J˜J˜Jšœ œŸ!˜;šœŸ%˜4JšœœŸ+˜HJ˜—šœ œŸ2˜DJ™3J™—šœ œ˜J™5—šœ œœ œ˜;Jšœœœ œ˜5J™H—J˜Jšœ œœ œ˜#J˜J˜šœœ ˜#Jšœ5™5J™—Jšœœ˜+Jšœ œ˜Jšœ œ˜(Jšœ œ˜J˜Jšœ œœ˜Jšœœ˜!J˜J˜J˜Jšœœœ ˜#šœ œœ˜Jšœœœ˜,JšœœœœœœœŸ1˜tJšœœŸ˜0šœœ˜3JšœJ™J—Jš œ œœœœ ˜*Jšœ˜J˜J˜—JšœC˜CJ˜šΟnœœœ˜Jšœ&˜&Jšœhœ˜oJšœE˜EJ™JšœF˜FJšœ:˜:Jšœ[œ˜bJšœB˜BJ˜J˜—š   œœ œœ œ˜>Icodeš˜Kšœœœ˜7Kšœ˜—K˜š œœœ˜8Jšœœœœ˜Jšœœ˜Jšœ%˜%J™šœœ™*J™Jšœœ ™J™—šœ™ Jšœœ™Jšœœ™Jšœœ™J˜—šœ˜Jšœ™Jšœ™Jšœœ/™;Jšœ™—šœ˜ šœ˜Jšœ9˜9Jšœ™Jšœ˜—Jšœ%˜%šœ˜JšœA˜AJšœ%™%Jšœ˜—šœ˜Jšœ8˜8Jšœ!™!J˜—Jšœ&˜-—Jšœ˜J˜—š œœœ˜>Jšœœœœ˜Jšœ3˜3Jšœ ˜ Jšœ˜J˜J˜—š œœœ˜?Jšœœœœ˜Jšœ4˜4Jšœ!˜!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šœ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šœ<™