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;
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.