DIRECTORY
AIS,
Basics USING [DivMod],
Commander USING [CommandProc, Register],
CommandTool USING [ParseToList],
Convert USING [RealFromRope],
DiabloStreams USING [StreamOpen],
FS USING [StreamOpen],
IO USING [STREAM, CR, ESC, LF, SP, char, card, Close, EndOfStream, GetChar, Put, PutChar, PutRope, Reset, rope],
Process USING [CheckForAbort],
Real USING [FixI],
Rope USING [ROPE, Concat, Fetch, Length],
UserProfile USING [Boolean, Number];
InkJetPrint:
CEDAR
PROGRAM
IMPORTS
AIS, Basics, Commander, CommandTool, Convert, DiabloStreams,
FS,
IO, Process, Real, Rope, UserProfile =
TRUSTED
BEGIN
ROPE: TYPE = Rope.ROPE;
Side: TYPE = {left, right};
PrimaryColor: TYPE = {cyan, magenta, yellow, black};
displayRasterPart:
TYPE =
AIS.RasterPart ← [
scanCount: 100,
scanLength: 100,
scanMode: rd,
bitsPerPixel: 8,
linesPerBlock: -1, -- for blocked AIS files. -1=no blocks
paddingPerBlock: 0 --in words
];
displayRaster: AIS.Raster ← NEW[displayRasterPart];
OpenAIS:
PROCEDURE [name:
ROPE]
RETURNS [window:
AIS.WRef] =
TRUSTED {
file: AIS.FRef ← AIS.OpenFile[name ! ANY => GOTO Exit];
window ← AIS.OpenWindow[file ! ANY => {AIS.CloseFile[file] ; GOTO Exit}];
EXITS
Exit => RETURN[NIL]
};
Closes a file and window
CloseAIS:
PROCEDURE [window:
AIS.WRef] =
TRUSTED {
file: AIS.FRef;
IF window=NIL THEN RETURN;
file ← window.fref;
AIS.CloseWindow[window];
window ← NIL;
AIS.CloseFile[file];
file ← NIL;
};
SetMargin:
SAFE
PROC [stream:
IO.
STREAM, arg:
CARDINAL, side: Side ← left] ~
TRUSTED {
OPEN IO;
Put[stream, char[ESC], char[IF side = left THEN 'l ELSE 'r], card[arg]];
Put[stream, char[CR]];
};
MicroLine: TYPE ~ [0..4);
MaxChars: CARDINAL ~ 200;
Buffer: TYPE ~ PACKED ARRAY [0..MaxChars*8) OF BOOLEAN; --Kluge
CBuffer: TYPE ~ PACKED ARRAY [0..MaxChars) OF CHAR; --Same size as Buffer!!!
Band: TYPE ~ ARRAY PrimaryColor OF ARRAY MicroLine OF Buffer;
emptyBuffer: Buffer ← ALL[FALSE];
graphicsChar:
ARRAY PrimaryColor
OF
ARRAY MicroLine
OF
CHAR ~ [
cyan: ['<, '=, '>, '?],
magenta: ['4, '5, '6, '7],
yellow: ['8, '9, ':, ';],
black: ['0, '1, '2, '3]
];
DoIt:
PROC [name:
ARRAY PrimaryColor
OF
ROPE, stream:
IO.
STREAM, lMarg, pWidth:
REAL, which:
ARRAY PrimaryColor
OF
BOOL ←
ALL[
TRUE]] ~
TRUSTED {
OPEN IO;
window: ARRAY PrimaryColor OF AIS.WRef ← ALL[NIL];
totalLength: CARDINAL;
imageWidth: INTEGER;
leftMargin: INTEGER ← Real.FixI[10.0 * lMarg];
printWidth: INTEGER ← Real.FixI[10.0 * pWidth];
inchesPerPage: INT ~ UserProfile.Number["Diablo.PageSize", 11];
verticalCenter: BOOL ~ UserProfile.Boolean["Diablo.VerticalCenter", TRUE];
FOR color: PrimaryColor
IN PrimaryColor
DO
IF which[color] THEN window[color] ← OpenAIS[name[color]];
IF window[color]#NIL THEN displayRaster ← AIS.ReadRaster[window[color].fref];
ENDLOOP;
imageWidth ← (displayRaster.scanLength + 11) / 12; -- next greater 1/10 inch
IO.PutRope[stream, "\033\015P"]; --Reset the terminal
IO.Put[stream, rope["\033\014"], char[LOOPHOLE[CARDINAL[inchesPerPage]*6]]]; --Set page length
IF verticalCenter
THEN {
--Do vertical centering
totalMicrolines: CARDINAL ~ (inchesPerPage*30 - displayRaster.scanCount/4)/2;
lfs, microlines: CARDINAL; --A lf is 1/6'', while microline is 1/30''.
[lfs, microlines] ← Basics.DivMod[totalMicrolines, 5];
THROUGH [1..lfs] DO IO.PutChar[stream, LF] ENDLOOP;
THROUGH [1..microlines] DO IO.PutRope[stream, "\033k1"] ENDLOOP;
};
SetMargin[
-- set the left margin
stream: stream,
arg: leftMargin + MAX[0, (printWidth - imageWidth) / 2],
side: left
];
SetMargin[
-- set the right margin
stream: stream,
arg: leftMargin + printWidth, -- let the printer truncate the image past the width
side: right
];
totalLength ← (displayRaster.scanLength+7) / 8;
FOR startLine:
CARDINAL ← 0, startLine+4
WHILE startLine < displayRaster.scanCount
DO
PrintBand:
PROC ~
TRUSTED {
FOR color: PrimaryColor
IN PrimaryColor
DO
IF window[color]=NIL THEN LOOP;
FOR line: MicroLine
IN MicroLine
DO
cBuffer: CBuffer ~ LOOPHOLE[band[color][line]];
Put[stream, char[ESC], char['g], char[graphicsChar[color][line]]];
Put[stream, card[totalLength], char[SP]];
FOR char:
CARDINAL
IN [0..totalLength]
DO
PutChar[stream, cBuffer[char]];
ENDLOOP;
ENDLOOP;
ENDLOOP;
Put[stream, char[ESC], char['k], char['1]];
Process.CheckForAbort[];
};
band: Band ← ALL[ALL[emptyBuffer]];
FOR line:
CARDINAL
IN [startLine..
MIN[displayRaster.scanCount-1, startLine+3]]
DO
microLine: CARDINAL ← line-startLine;
FOR color: PrimaryColor
IN PrimaryColor
DO
IF window[color]=NIL THEN LOOP;
FOR pixel:
CARDINAL
IN [0..displayRaster.scanLength)
DO
IF AIS.ReadSample[window[color], line, pixel]>0 THEN band[color][microLine][pixel] ← TRUE;
ENDLOOP;
ENDLOOP;
ENDLOOP;
PrintBand[];
ENDLOOP;
IF verticalCenter THEN IO.PutChar[stream, '\014]; --Form feed to next page
IO.Close[stream];
FOR color: PrimaryColor
IN PrimaryColor
DO
CloseAIS[window[color]];
ENDLOOP;
};
Print: Commander.CommandProc =
TRUSTED {
s: IO.STREAM ~ DiabloStreams.StreamOpen[];
{
ENABLE ABORTED => IF s#NIL THEN {IO.Reset[s]; IO.Close[s]};
DO
IO.PutChar[s, IO.GetChar[cmd.in ! IO.EndOfStream => EXIT]];
Process.CheckForAbort[];
ENDLOOP;
IO.Close[s];
};
};
FilePrint: Commander.CommandProc =
TRUSTED {
fileList: LIST OF ROPE;
length: INT;
s: IO.STREAM ~ DiabloStreams.StreamOpen[];
out: IO.STREAM;
[fileList, length] ← CommandTool.ParseToList[cmd: cmd];
out ← FS.StreamOpen[fileList.first];
{
ENABLE UNWIND => {IF s#NIL THEN {IO.Reset[s]; IO.Close[s]}; IF out#NIL THEN {IO.Close[out]}};
DO
IO.PutChar[s, IO.GetChar[out ! IO.EndOfStream => EXIT]];
Process.CheckForAbort[];
ENDLOOP;
IO.Close[out];
IO.Close[s];
};
};
MakeFile: Commander.CommandProc =
TRUSTED {
fileList: LIST OF ROPE;
length: INT;
which: ARRAY PrimaryColor OF BOOL ← ALL[TRUE];
s: IO.STREAM ← NIL;
[fileList, length] ← CommandTool.ParseToList[cmd: cmd];
IF length=0 THEN RETURN [msg: "Usage: IJMake [-cmyb] inFileNameRoot [leftMarg [printWidth]]"];
IF Rope.Fetch[fileList.first]='-
THEN {
rope: ROPE ~ fileList.first;
fileList ← fileList.rest;
length ← length - 1;
which ← ALL[FALSE];
FOR i:
CARDINAL
IN [1..
CARDINAL[Rope.Length[rope]])
DO
SELECT Rope.Fetch[rope, i]
FROM
'c => which[cyan] ← TRUE;
'm => which[magenta] ← TRUE;
'y => which[yellow] ← TRUE;
'b => which[black] ← TRUE;
ENDCASE;
ENDLOOP;
};
BEGIN
ENABLE
UNWIND =>
IF s#
NIL
THEN
IO.Close[s];
DoIt[
[Rope.Concat[fileList.first, "-cyan.ais"], Rope.Concat[fileList.first, "-mag.ais"], Rope.Concat[fileList.first, "-yel.ais"], Rope.Concat[fileList.first, "-black.ais"]],
(s ← FS.StreamOpen[Rope.Concat[fileList.first, ".c150"], create]),
IF length > 1
THEN Convert.RealFromRope[fileList.rest.first]
ELSE 0.5, -- default the left margin to 0.5 inch
IF length > 2
THEN Convert.RealFromRope[fileList.rest.rest.first]
ELSE 8.0, -- default the width to 8" from left
which
];
END;
};
Make: Commander.CommandProc =
TRUSTED {
fileList: LIST OF ROPE;
length: INT;
which: ARRAY PrimaryColor OF BOOL ← ALL[TRUE];
[fileList, length] ← CommandTool.ParseToList[cmd: cmd];
IF length=0 THEN RETURN [msg: "Usage: IJMake [-cmyb] inFileNameRoot [leftMarg [printWidth]]"];
IF Rope.Fetch[fileList.first]='-
THEN {
rope: ROPE ~ fileList.first;
fileList ← fileList.rest;
length ← length - 1;
which ← ALL[FALSE];
FOR i:
CARDINAL
IN [1..
CARDINAL[Rope.Length[rope]])
DO
SELECT Rope.Fetch[rope, i]
FROM
'c => which[cyan] ← TRUE;
'm => which[magenta] ← TRUE;
'y => which[yellow] ← TRUE;
'b => which[black] ← TRUE;
ENDCASE;
ENDLOOP;
};
DoIt[
[Rope.Concat[fileList.first, "-cyan.ais"], Rope.Concat[fileList.first, "-mag.ais"], Rope.Concat[fileList.first, "-yel.ais"], Rope.Concat[fileList.first, "-black.ais"]],
cmd.out,
IF length > 1
THEN Convert.RealFromRope[fileList.rest.first]
ELSE 0.5, -- default the left margin to 0.5 inch
IF length > 2
THEN Convert.RealFromRope[fileList.rest.rest.first]
ELSE 8.0, -- default the width to 8" from left
which
];
};
Commander.Register[
key: "FilePrint",
proc: FilePrint,
doc: "FilePrint -- print file to Diablo C150."];
Commander.Register[
key: "IJPrint",
proc: Print,
doc: "IJPrint -- print piped input stream the to Diablo C150."];
Commander.Register[
key: "IJMake",
proc: Make,
doc: "IJMake [-cmyb] inFileNameRoot [leftMarg [printWidth]] -- Create file for Diablo C150 from AIS sources."];
Commander.Register[
key: "MakeFile",
proc: MakeFile,
doc: "MakeFile [-cmyb] inFileNameRoot [leftMarg [printWidth]] -- Create disk file for Diablo C150 from AIS sources."];
END.