<> <> <> <<>> DIRECTORY Ascii, Basics USING [BytePair], DiabloStreams USING [StreamOpen], PDFileFormat, ImagerPixelMap, PDInterpBitmap, PDInterpOutput, PDQueue, IO, Rope; PDInterpOutputD4020Impl: PROGRAM IMPORTS DiabloStreams, ImagerPixelMap, IO, PDQueue EXPORTS PDInterpOutput = BEGIN OPEN Ascii; Toner: TYPE ~ PDFileFormat.Toner; pageMap: ARRAY Toner OF ImagerPixelMap.PixelMap _ ALL[ImagerPixelMap.Create[0, [0, 0, 0, 0]]]; currentStartImage: PDFileFormat.StartImage; currentHerald: PDFileFormat.Herald; bandNumber: NAT _ 0; currentToner: Toner _ cyan; print: BOOL _ TRUE; feed, strip: BOOL _ FALSE; ROPE: TYPE ~ Rope.ROPE; PrinterParameters: TYPE ~ REF PrinterParametersRep; PrinterParametersRep: TYPE ~ RECORD [ fSize: CARDINAL _ 120*8+120/2 + 4, -- The size of sheet on fast edge sSize: CARDINAL _ 240*11, -- The size of sheet on the slow edge fDPI: CARDINAL _ 120, -- Fast edge dots per inch sDPI: CARDINAL _ 240 -- Slow edge dots per inch ]; pp: PrinterParameters = NEW [PrinterParametersRep]; fSize: CARDINAL _ 120*8+120/2 + 4; sSize: CARDINAL _ 240*11; StartImage: PUBLIC PROC [herald: PDFileFormat.Herald, startImage: PDFileFormat.StartImage, request: PDQueue.Request] RETURNS [PDInterpBitmap.BitmapDesc] = { bandMap: ImagerPixelMap.PixelMap; IF pp.fDPI # herald.fResolution THEN ERROR; IF pp.sDPI # herald.sResolution THEN ERROR; fSize _ (herald.imageFSize+7)/8*8; sSize _ (herald.imageSSize+3)/4*4; feed _ startImage.feed; strip _ startImage.strip; currentToner _ startImage.toner; PDQueue.LogMessage[message: IO.PutFR1["Getting storage for %g.", IO.rope[(SELECT startImage.toner FROM black => "black", cyan => "cyan", magenta => "magenta", yellow => "yellow", ENDCASE => ERROR)]], userName: request.requestor]; pageMap[startImage.toner] _ ImagerPixelMap.Reshape[pageMap[startImage.toner].refRep, 0, [0, 0, sSize, fSize]]; ImagerPixelMap.Clear[pageMap[startImage.toner]]; PDQueue.LogMessage[message: "Done. Making bitmap.", userName: request.requestor]; currentStartImage _ startImage; currentHerald _ herald; bandNumber _ 0; bandMap _ ImagerPixelMap.Clip[pageMap[startImage.toner], [startImage.passBands*herald.bandSSize, startImage.fMinPage, herald.bandSSize, startImage.fSizePage]]; RETURN [[ sOrigin: bandMap.sOrigin, fOrigin: bandMap.fOrigin, sMin: bandMap.sMin, fMin: bandMap.fMin, sSize: bandMap.sSize, fSize: bandMap.fSize, pointer: bandMap.refRep.pointer, rast: bandMap.refRep.rast, lines: bandMap.refRep.lines ]] }; EndBand: PUBLIC PROC RETURNS [PDInterpBitmap.BitmapDesc] = { bandMap: ImagerPixelMap.PixelMap; bandNumber _ bandNumber + 1; bandMap _ ImagerPixelMap.Clip[pageMap[currentToner], [(currentStartImage.passBands+bandNumber)*currentHerald.bandSSize, currentStartImage.fMinPage, currentHerald.bandSSize, currentStartImage.fSizePage]]; RETURN [[ sOrigin: bandMap.sOrigin, fOrigin: bandMap.fOrigin, sMin: bandMap.sMin, fMin: bandMap.fMin, sSize: bandMap.sSize, fSize: bandMap.fSize, pointer: bandMap.refRep.pointer, rast: bandMap.refRep.rast, lines: bandMap.refRep.lines ]] }; EndImage: PUBLIC PROC [request: PDQueue.Request] = { IF strip THEN { PDQueue.LogMessage[message: "Bitmap complete.", userName: request.requestor]; PDQueue.LogMessage[message: "Starting printer.", userName: request.requestor]; PrintIt[request]} ELSE PDQueue.LogMessage[message: "Bitmap complete.", userName: request.requestor]; feed _ FALSE; strip _ FALSE; }; ReprintLastPage: PUBLIC PROC [copies: CARDINAL] = { IF currentHerald.password # PDFileFormat.passwordValue THEN RETURN; currentHerald.copies _ copies; PDQueue.LogMessage[message: "Starting printer.", userName: "Reprint"]; Replay[["Reprint", NIL, NIL, NIL, NIL, copies]]; }; MicroLine: TYPE ~ [0..4); graphicsChar: ARRAY Toner OF ARRAY MicroLine OF CHAR ~ [ cyan: ['<, '=, '>, '?], magenta: ['4, '5, '6, '7], yellow: ['8, '9, ':, ';], black: ['0, '1, '2, '3] ]; STREAM: TYPE ~ IO.STREAM; MicroLineFeed1: PROC [s: STREAM] = { IO.PutChar[s, ESC]; IO.PutChar[s, 'k]; IO.PutChar[s, '1]}; MicroLineFeed2: PROC [s: STREAM] = { IO.PutChar[s, ESC]; IO.PutChar[s, 'k]; IO.PutChar[s, '2]}; Replay: PROC [request: PDQueue.Request] = BEGIN smallPM: ImagerPixelMap.PixelMap; s: STREAM = DiabloStreams.StreamOpen[]; FOR i: CARDINAL IN [0 .. request.copies) DO IO.PutRope[s, "\033\nP"]; -- ESC CR P IO.PutRope[s, "\033r85\n\l"]; -- ESC r 85 CRLF IO.PutF[s, "%g %g %g\n\n\n\n\n\n\n\n\n\n\n\n", IO.rope[request.requestor], IO.rope[request.fileName], IO.rope[request.separator]]; FOR lines: CARDINAL IN [0 .. sSize/8) DO allBlank: BOOL _ TRUE; FOR microLine: MicroLine IN MicroLine DO activeLine: CARDINAL = lines*8 + microLine*2; FOR toner: Toner IN Toner DO smallPM _ ImagerPixelMap.Clip[pageMap[toner], [activeLine, 0, 1, fSize]]; -- One line in one toner. IF ImagerPixelMap.IsAll[smallPM, 0] THEN LOOP ELSE { ptr: LONG POINTER TO Basics.BytePair _ smallPM.refRep.pointer + LONG[activeLine - smallPM.sOrigin] * smallPM.refRep.rast; -- points to the line. allBlank _ FALSE; IO.PutChar[s, ESC]; IO.PutChar[s, 'g]; IO.PutChar[s, graphicsChar[toner][microLine]]; IO.Put[s, IO.int[fSize/8]]; IO.PutChar[s, SP]; FOR i: CARDINAL IN [0 .. fSize/16) DO TRUSTED { w: Basics.BytePair _ (ptr+i)^; IO.PutChar[s, LOOPHOLE[w.high, CHAR]]; IO.PutChar[s, LOOPHOLE[w.low, CHAR]]; } ENDLOOP; }; ENDLOOP; -- Toner ENDLOOP; -- MicroLine MicroLineFeed2[s]; FOR microLine: MicroLine IN MicroLine DO activeLine: CARDINAL = lines*8 + microLine*2 + 1; FOR toner: Toner IN Toner DO smallPM _ ImagerPixelMap.Clip[pageMap[toner], [activeLine, 0, 1, fSize]]; -- One line in one toner. IF ImagerPixelMap.IsAll[smallPM, 0] THEN LOOP ELSE { ptr: LONG POINTER TO Basics.BytePair _ smallPM.refRep.pointer + LONG[activeLine - smallPM.sOrigin] * smallPM.refRep.rast; -- points to the line. allBlank _ FALSE; IO.PutChar[s, ESC]; IO.PutChar[s, 'g]; IO.PutChar[s, graphicsChar[toner][microLine]]; IO.Put[s, IO.int[fSize/8]]; IO.PutChar[s, SP]; FOR i: CARDINAL IN [0 .. fSize/16) DO TRUSTED { w: Basics.BytePair _ (ptr+i)^; IO.PutChar[s, LOOPHOLE[w.high, CHAR]]; IO.PutChar[s, LOOPHOLE[w.low, CHAR]]; } ENDLOOP; }; ENDLOOP; -- Toner ENDLOOP; -- MicroLine MicroLineFeed1[s]; ENDLOOP; -- lines IO.PutF[s, "\n\n\n\n\n\n\n\n\n\n\n\n%g %g %g\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", IO.rope[request.requestor], IO.rope[request.fileName], IO.rope[request.separator]]; ENDLOOP; -- Copies IO.Close[s]; PDQueue.LogMessage[message: "Done.", userName: request.requestor]; END; PrintIt: PROC [request: PDQueue.Request] = BEGIN Replay[request]; END; END.