XNSPSPrintImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Tim Diebert: April 9, 1987 11:54:57 am PDT
DIRECTORY
Atom USING [GetPName],
BasicTime,
Booting USING [switches],
FS USING [Delete, Error, StreamOpen],
Imager,
ImagerFont,
ImagerSample USING [Clear, RasterSampleMap],
Interpress USING [DoPage, LogProc, Open, Master],
IO,
IPMaster USING [Error],
PrintingP4V3,
Process USING [Priority, SetPriority, GetPriority, priorityBackground],
RavenDriver USING [ContextFromSampleMap, GetPrinterSampleMap, PrintFromSampleMap, PrintingError, RavenRegistration, RegisterStatusProc, SetRegistration, StatusProc, StatusType, WakeUp],
Rope USING [Concat, ROPE],
RuntimeError USING [UNCAUGHT],
SystemVersion USING [release, bootFileDate],
ThisMachine USING [Name],
XNSPSMessages USING [LogMessage],
XNSPSPrint;
XNSPSPrintImpl: CEDAR MONITOR
IMPORTS Atom, BasicTime, Booting, FS, Imager, ImagerFont, ImagerSample, Interpress, IO, IPMaster, Process, RavenDriver, Rope, RuntimeError, SystemVersion, ThisMachine, XNSPSMessages
EXPORTS XNSPSPrint
~ { OPEN PrintingP4V3;
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
bitmap: ImagerSample.RasterSampleMap ← NIL;
PrinterParameters: TYPE ~ REF PrinterParametersRep;
PrinterParametersRep: TYPE ~ RECORD [
margins: RavenDriver.RavenRegistration ← [10, 1]
];
pp: PrinterParameters;
buffer: REF TEXTNEW[TEXT[1000]];
FindCopyCount: PROC [po: PrintingP4V3.PrintOptions] RETURNS [copies: CARDINAL] = TRUSTED BEGIN
FOR i: CARDINAL IN [0 .. po.length) DO
option: Option ← po.body[i];
WITH option: option SELECT FROM
copyCount => {copies ← option.copyCount};
ENDCASE => NULL;
ENDLOOP;
END;
PrintFile: PUBLIC PROC [id: PrintingP4V3.RequestID, fileName: ROPE,
printAttributes: PrintingP4V3.PrintAttributes, printOptions: PrintingP4V3.PrintOptions] RETURNS [ok: BOOL] = {
old: Process.Priority ← Process.GetPriority[];
copies: CARDINAL ← FindCopyCount[printOptions];
Process.SetPriority[Process.priorityBackground];
{ENABLE RuntimeError.UNCAUGHT =>
{XNSPSMessages.LogMessage["UNCAUGHT Error", id];
IF dontCatch THEN REJECT ELSE GOTO Out};
{
ENABLE {
FS.Error => {
XNSPSMessages.LogMessage[error.explanation, id]; GOTO Out;
};
};
TRUSTED {RavenDriver.WakeUp[]};
PrintBreakPage[printAttributes];
XNSPSMessages.LogMessage["Starting Interpress master", id];
PrintInterpressFile[id, fileName, printOptions, copies];
XNSPSMessages.LogMessage["Deleting file", id];
FS.Delete[fileName ! FS.Error => CONTINUE];
EXITS
Out => {
FS.Delete[fileName ! FS.Error => CONTINUE];
Process.SetPriority[old];
RETURN[FALSE];
};
};
EXITS
Out => {
FS.Delete[fileName ! FS.Error => CONTINUE];
Process.SetPriority[old];
RETURN[FALSE];
};
};
Process.SetPriority[old];
RETURN [TRUE];
};
FindPrintStuff: PROC [pa: PrintingP4V3.PrintAttributes] RETURNS [printObjectName, printObjectCreateDate, senderName: ROPENIL] = TRUSTED BEGIN
FOR i: CARDINAL IN [0 .. pa.length) DO
option: Attribute ← pa.body[i];
WITH option: option SELECT FROM
printObjectName => {printObjectName ← option.printObjectName};
printObjectCreateDate => {
time: BasicTime.GMT;
time ← BasicTime.FromNSTime[option.printObjectCreateDate
! BasicTime.OutOfRange => {time ← BasicTime.earliestGMT; CONTINUE}];
IF LOOPHOLE[time, INT] < LOOPHOLE[BasicTime.earliestGMT, INT] THEN
time ← BasicTime.earliestGMT;
printObjectCreateDate ← IO.PutR1[IO.time[time]];
};
senderName => {senderName ← option.senderName};
ENDCASE => NULL;
ENDLOOP;
END;
PrintBreakPage: PROC [pa: PrintingP4V3.PrintAttributes] = BEGIN
CedarVersion: PROC RETURNS [v: ROPE] ~ {
out: IO.STREAMIO.ROS[];
IO.PutF[out, "Cedar %g.%g",
[integer[SystemVersion.release.major]], [integer[SystemVersion.release.minor]]];
IF SystemVersion.release.patch # 0 THEN
IO.PutF1[out, ".%g", [integer[SystemVersion.release.patch]]];
IO.PutF1[out, " of %t\n", [time[BasicTime.FromPupTime[SystemVersion.bootFileDate]]]];
v ← IO.RopeFromROS[out];
IO.Close[out];
};
CornerLogo: SAFE PROC ~ CHECKED {
CenterRope: SAFE PROC [context: Imager.Context, name: ROPE, size: REAL, r: ROPE, x, y: REAL] ~ CHECKED {
font: ImagerFont.Font ← ImagerFont.Scale[ImagerFont.Find[name], size];
box: ImagerFont.Extents ← ImagerFont.RopeBoundingBox[font: font, rope: r];
height: REAL ← box.descent + box.ascent;
length: REAL ← box.leftExtent + box.rightExtent;
Imager.SetXY[context: context, p: [x-length/2, y-height/2]];
Imager.SetFont[context: context, font: font];
Imager.ShowRope[context: context, rope: r];
};
Imager.TranslateT[context: context, t: [8.5*Imager.pointsPerInch, 11.0*Imager.pointsPerInch]];
Imager.RotateT[context: context, a: -45.0];
Imager.TranslateT[context: context, t: [0, -300]];
Imager.SetColor[context: context, color: Imager.black];
Imager.MaskRectangle[context: context, r: [-1000, 0, 10000, 10000]];
Imager.SetColor[context: context, color: Imager.white];
Imager.MaskRectangle[context: context, r: [-1000, 152, 10000, 8]];
Imager.MaskRectangle[context: context, r: [-1000, 104, 10000, 16]];
Imager.MaskRectangle[context: context, r: [-1000, 56, 10000, 24]];
Imager.MaskRectangle[context: context, r: [-1000, 8, 10000, 32]];
CenterRope[context, "Xerox/PressFonts/Logo-mrr", 40.0, "XEROX", 0, 180];
CenterRope[context, "Xerox/PressFonts/Classic-brr", 24.0, "INTERPRESS 3.0", 0, 136];
CenterRope[context, "Xerox/PressFonts/Classic-brr", 20.0, "Development Environment", 0, 96];
};
context: Imager.Context;
font: ImagerFont.Font;
error: ROPE;
status: RavenDriver.StatusType;
printObjectName, printObjectCreateDate, senderName: ROPE;
PrintAPage: ENTRY PROC[] = TRUSTED BEGIN ENABLE UNWIND => NULL;
[error, status]← RavenDriver.PrintFromSampleMap[bitmap
! RavenDriver.PrintingError => RETRY];
END;
TRUSTED {bitmap ← RavenDriver.GetPrinterSampleMap[];
context ← RavenDriver.ContextFromSampleMap[bitmap]};
ImagerSample.Clear[bitmap];
Imager.ScaleT[context: context, s: Imager.metersPerPoint];
Imager.DoSave[context: context, action: CornerLogo];
font ← ImagerFont.Scale[ImagerFont.Find["Xerox/PressFonts/Classic-mrr"], 10.0];
Imager.SetFont[context: context, font: font];
Imager.SetXY[context: context, p: [96, 386]];
Imager.ShowRope[context: context, rope: Rope.Concat["Printer: ", ThisMachine.Name[]]];
Imager.SetXY[context: context, p: [96, 374]];
Imager.ShowRope[context: context, rope: Rope.Concat["Software Version: ", CedarVersion[]]];
Imager.SetXY[context: context, p: [96, 350]];
[printObjectName, printObjectCreateDate, senderName] ← FindPrintStuff[pa];
Imager.ShowRope[context: context, rope: Rope.Concat["Interpress master: ", printObjectName]];
Imager.SetXY[context: context, p: [96, 338]];
Imager.ShowRope[context: context, rope: Rope.Concat["Creation Date: ", printObjectCreateDate]];
Imager.SetXY[context: context, p: [96, 314]];
Imager.ShowRope[context: context, rope: Rope.Concat["Printed by: ", senderName]];
Imager.SetXY[context: context, p: [96, 302]];
Imager.ShowRope[context: context, rope: Rope.Concat["Printing Date: ", IO.PutR1[IO.time[]]]];
PrintAPage[];
IF status = error THEN {
XNSPSMessages.LogMessage[Rope.Concat[error, " while printing."]];
ERROR ABORTED;
};
ImagerSample.Clear[bitmap];
END;
LogProc: Interpress.LogProc = TRUSTED {
LogProc: TYPE ~ PROC [class: INT, code: ATOM, explanation: ROPE];
XNSPSMessages.LogMessage[explanation];
};
PrintInterpressFile: PROC [id: PrintingP4V3.RequestID, fileName: ROPE, printOptions: PrintingP4V3.PrintOptions, copies: INT] = {
ENABLE {
Imager.Error => {
XNSPSMessages.LogMessage[error.explanation, id]; ERROR ABORTED;
};
IPMaster.Error => {
XNSPSMessages.LogMessage[Atom.GetPName[error.code], id];
XNSPSMessages.LogMessage[error.explanation, id];
ERROR ABORTED;
};
IO.EndOfStream, IO.Error =>
{XNSPSMessages.LogMessage["Unknown IO Error", id]; ERROR ABORTED;
};
};
status: RavenDriver.StatusType; error: ROPE;
master: Interpress.Master;
context: Imager.Context;
PrintAPage: ENTRY PROC[] = TRUSTED BEGIN ENABLE UNWIND => NULL;
[error, status]← RavenDriver.PrintFromSampleMap[bitmap
! RavenDriver.PrintingError => RETRY];
END;
TRUSTED {bitmap ← RavenDriver.GetPrinterSampleMap[];
context ← RavenDriver.ContextFromSampleMap[bitmap, fontTunerParms]};
master ← Interpress.Open[fileName, LogProc];
IF master.pages = 1 THEN { -- reprint page 1 from the bitmap efficiently
XNSPSMessages.LogMessage[IO.PutFR1["Started page %g", IO.card[1]], id];
ImagerSample.Clear[bitmap];
Interpress.DoPage[master, 1, context, LogProc];
FOR i: INT IN [1 .. copies] DO
XNSPSMessages.LogMessage["Printing", id];
PrintAPage[];
IF status = error THEN {
XNSPSMessages.LogMessage[Rope.Concat[error, " while printing."], id];
ERROR ABORTED;
};
ENDLOOP;
}
ELSE { -- struggle through interpretting each page in collation order. . .
FOR j: INT IN [1 .. copies] DO
FOR i: INT IN [1 .. master.pages] DO
XNSPSMessages.LogMessage[IO.PutFR1["Started page %g", IO.card[i]], id];
ImagerSample.Clear[bitmap];
Interpress.DoPage[master, i, context, LogProc];
XNSPSMessages.LogMessage["Printing", id];
PrintAPage[];
IF status = error THEN {
XNSPSMessages.LogMessage[Rope.Concat[error, " while printing."], id];
ERROR ABORTED;
};
ENDLOOP;
ENDLOOP;
};
XNSPSMessages.LogMessage["All Done", id];
};
Status: RavenDriver.StatusProc = {
XNSPSMessages.LogMessage[status];
};
fontTunerParms: ROPENIL; -- "[Cedar]<CedarChest6.1>FontTune>Simple0";
dontCatch: BOOLFALSE;
GetMargins: PUBLIC ENTRY SAFE PROC [] RETURNS [sMargin, fMargin: CARDINAL] = TRUSTED BEGIN
ENABLE UNWIND => NULL;
RETURN [pp.margins.short, pp.margins.long];
END;
SetMargins: PUBLIC ENTRY SAFE PROC [sMargin, fMargin: CARDINAL] = TRUSTED BEGIN
ENABLE UNWIND => NULL;
s: STREAMNIL;
IF sMargin NOT IN [1..30] THEN sMargin ← 10;
IF fMargin NOT IN [10..43] THEN fMargin ← 1;
pp.margins.short ← sMargin; pp.margins.long ← fMargin;
s ← FS.StreamOpen[fileName: "///PrinterParameters.DontDeleteMe", accessOptions: create ! FS.Error => CONTINUE];
IF s # NIL THEN BEGIN
IO.PutF[s, "%g %g\n", IO.card[sMargin], IO.card[fMargin]];
IO.Close[s];
END;
RavenDriver.SetRegistration[pp.margins];
END;
Init: ENTRY PROC [] = TRUSTED {
ENABLE UNWIND => NULL;
s: STREAMNIL; sMargin, fMargin: CARDINAL;
IF Booting.switches[z] THEN fontTunerParms ← "[Cedar]<CedarChest6.1>FontTune>Simple0";
The font tuner adds .fontTune
IF Booting.switches[y] THEN dontCatch ← TRUE;
pp ← NEW [PrinterParametersRep ← [margins: [10, 1]]];
BEGIN
s ← FS.StreamOpen[fileName: "///PrinterParameters.DontDeleteMe", accessOptions: read ! FS.Error => CONTINUE];
IF s # NIL THEN BEGIN ENABLE IO.Error => GOTO Out;
sMargin ← IO.GetCard[s];
fMargin ← IO.GetCard[s];
IO.Close[s];
IF sMargin NOT IN [1..30] THEN sMargin ← 1;
IF fMargin NOT IN [10..43] THEN fMargin ← 10;
pp.margins.short ← sMargin; pp.margins.long ← fMargin;
END;
EXITS Out => NULL;
END;
RavenDriver.SetRegistration[pp.margins];
XNSPSMessages.LogMessage["Booted."];
Process.Detach[FORK Main[]];
RavenDriver.RegisterStatusProc[Status];
};
Init[];
}.