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