TSetterPDImpl.mesa
Michael Plass, March 15, 1984 4:52:51 pm PST
DIRECTORY
FS, Convert, Commander, Font, Imager, ImagerPD,
IO, NodeStyle, PutGet, RefText, Rope, TSFont, TSJaMPageBuilder, TSObject, TSOutput, TSTranslate, TSTypes;
TSetterPDImpl:
CEDAR
MONITOR
IMPORTS FS, Convert, Commander, Font, Imager, ImagerPD, IO, PutGet, RefText, Rope, TSOutput, TSJaMPageBuilder, TSTranslate, TSTypes = BEGIN
special: ImagerPD.PDFileDescription ← ImagerPD.Hornet[""];
FileDescription:
PROC [fileName:
ROPE, code:
REF]
RETURNS [pdFileDescription: ImagerPD.PDFileDescription] ~ {
SELECT code
FROM
$Platemaker => pdFileDescription ← ImagerPD.PlateMaker[fileName];
$Special => {pdFileDescription ← special; pdFileDescription.fileName ← fileName};
$Peach => {
pdFileDescription ← ImagerPD.Hornet[fileName];
pdFileDescription.leftovers ← FALSE;
pdFileDescription.maxLoadWords ← 120000;
pdFileDescription.bandSSize ← 100;
};
ENDCASE => pdFileDescription ← ImagerPD.Hornet[fileName];
};
lastImagerFont: Font.FONT ← NIL;
lastTSetterFont: TSFont.Ref ← NIL;
CheckLastFont:
ENTRY
PROC [tsetterFont: TSFont.Ref]
RETURNS [imagerFont: Font.
FONT] ~ {
imagerFont ← IF tsetterFont = lastTSetterFont THEN lastImagerFont ELSE NIL;
};
SetLastFont:
ENTRY
PROC [tsetterFont: TSFont.Ref, imagerFont: Font.
FONT] ~ {
lastImagerFont ← imagerFont;
lastTSetterFont ← tsetterFont;
};
prefix:
REF
TEXT ← "Xerox/PressFonts/";
FontForFont:
PROC [tsetterFont: TSFont.Ref]
RETURNS [imagerFont: Font.
FONT] ~ {
imagerFont ← CheckLastFont[tsetterFont];
IF imagerFont =
NIL
THEN {
family: ROPE ~ tsetterFont.fontTable.headerInfo.family;
face: NAT ← tsetterFont.fontTable.headerInfo.face;
size: REAL ~ TSTypes.Pt[tsetterFont.size];
text: REF TEXT ← RefText.ObtainScratch[Rope.Length[family]+prefix.length+4];
slope, weight, expansion: CHAR ← 'X;
slope ← IF (face MOD 2) = 0 THEN 'R ELSE 'I;
face ← face - (face MOD 2);
weight ←
SELECT (face
MOD 6)
FROM
0 => 'M, --medium
2 => 'B, --bold
4 => 'L, --light
ENDCASE => ERROR;
expansion ←
SELECT face - (face
MOD 6)
FROM
0 => 'R, --regular
6 => 'C, --condensed
12 => 'E, --expanded
ENDCASE => ERROR;
text.length ← 0;
text ← RefText.Append[text, prefix];
text ← RefText.AppendRope[text, family];
text[text.length] ← '/; text.length ← text.length + 1;
text[text.length] ← weight; text.length ← text.length + 1;
text[text.length] ← slope; text.length ← text.length + 1;
text[text.length] ← expansion; text.length ← text.length + 1;
imagerFont ← Font.CreateScaled[text, size, $Ideal];
RefText.ReleaseScratch[text];
SetLastFont[tsetterFont, imagerFont];
};
IF tsetterFont = lastTSetterFont THEN RETURN [lastImagerFont];
};
Char: TSOutput.CharProc ~ {
imager: Imager.Context ← NARROW[self.outputState];
imagerFont: Font.FONT ← FontForFont[font];
imager.SetXY[[TSTypes.Pt[x], TSTypes.Pt[y]]];
imager.ShowChar[char, imagerFont];
};
Rule: TSOutput.RuleProc ~ {
imager: Imager.Context ← NARROW[self.outputState];
imager.MaskRectangle[TSTypes.Pt[leftX], TSTypes.Pt[bottomY], TSTypes.Pt[width], TSTypes.Pt[height]];
};
Color: TSOutput.ColorProc ~ {
imager: Imager.Context ← NARROW[self.outputState];
imager.SetColor[Imager.MakeGray[1.0-brightness]];
};
metersPerPt: REAL ← 0.0254/72.27;
NewPage: TSOutput.NewPageProc ~ {
imager: Imager.Context ← NARROW[self.outputState];
cmd: Commander.Handle ← NARROW[imager.GetProp[$Commander]];
firstTime: REF ← imager.GetProp[$FirstTime];
pageNumberRef: REF INT ← NARROW[imager.GetProp[$PageNumber]];
maxPagesPerFileRef: REF INT ← NARROW[imager.GetProp[$MaxPagesPerFile]];
rootName: ROPE ← NARROW[imager.GetProp[$RootName]];
IF firstTime#$FALSE THEN imager.PutProp[$FirstTime, $FALSE]
ELSE
IF pageNumberRef^
MOD maxPagesPerFileRef^ = 0
THEN {
newFileName: ROPE ← rootName.Cat["-P", Convert.RopeFromInt[pageNumberRef^+1], ".pd"];
newImager: Imager.Context ← Imager.Create[$PD, FileDescription[newFileName, cmd.procData.clientData]];
newImager.PutProp[$Commander, cmd];
newImager.PutProp[$PageNumber, pageNumberRef];
newImager.PutProp[$MaxPagesPerFile, maxPagesPerFileRef];
newImager.PutProp[$Corners, imager.GetProp[$Corners]];
newImager.PutProp[$OutputFileName, newFileName];
newImager.PutProp[$FirstTime, $FALSE];
newImager.PutProp[$RootName, rootName];
[] ← imager.SpecialOp[$Close, NIL];
cmd.out.PutRope[NARROW[imager.GetProp[$OutputFileName]]];
cmd.out.PutRope[" written.\nMore . "];
self.outputState ← imager ← newImager;
}
ELSE {[] ← imager.SpecialOp[$NewPage, NIL]; IF cmd # NIL THEN cmd.out.PutRope[". "]};
pageNumberRef^ ← pageNumberRef^ + 1;
Imager.Reset[imager];
imager.ScaleT[metersPerPt];
};
PageSize: TSOutput.PageSizeProc ~ {
};
Finish: TSOutput.FinishProc ~ {
imager: Imager.Context ← NARROW[self.outputState];
[] ← imager.SpecialOp[$Close, NIL];
};
CreatePDOutput:
PROC [imager: Imager.Context]
RETURNS [outputHandle: TSOutput.Handle] ~ {
outputHandle ←
NEW[TSOutput.OutputRec ← [
charProc: Char,
ruleProc: Rule,
colorProc: Color,
newPageProc: NewPage,
pageSizeProc: PageSize,
finishProc: Finish,
outputState: imager
]];
imager.ScaleT[metersPerPt];
};
GetFileName:
PROC [rope:
ROPE]
RETURNS [fileName:
ROPE] ~ {
start: INT ← 0;
length: INT ← Rope.Length[rope];
end: INT ← 0;
WHILE start < length
DO
c: CHAR ← rope.Fetch[start];
IF c = '[ OR c = '/ OR c IN ['a..'z] OR c IN ['A..'Z] THEN EXIT;
start ← start + 1;
ENDLOOP;
end ← start;
WHILE end < length
DO
c: CHAR ← rope.Fetch[end];
IF c <= ' THEN EXIT;
end ← end + 1;
ENDLOOP;
fileName ← rope.Substr[start, end-start];
};
GetRootName:
PROC [rope:
ROPE]
RETURNS [rootName:
ROPE] ~ {
start: INT ← 0;
length: INT ← Rope.Length[rope];
end: INT ← Rope.Length[rope];
FOR i:
INT
IN [0..length)
DO
c: CHAR ← rope.Fetch[i];
IF c = '> OR c = '/ THEN start ← i + 1;
IF c = '. THEN end ← i;
IF c = '! THEN end ← MIN[end, i];
ENDLOOP;
rootName ← rope.Substr[start, end-start];
};
TSetterPDCommand: Commander.CommandProc ~ {
inputFileName: ROPE ~ GetFileName[cmd.commandLine];
outputName: ROPE ← GetRootName[inputFileName].Concat[".pd"];
pdFileDescription: ImagerPD.PDFileDescription ~ FileDescription[outputName, cmd.procData.clientData];
errorMsg: ROPE ← NIL;
isAborted: PROC RETURNS [BOOLEAN] = {RETURN[FALSE]};
node: PutGet.Ref ← NIL;
corners: BOOLEAN ← Rope.Find[cmd.commandLine, "Corners", 0, FALSE] >= 0;
maxPagesPerFile: INT ← IF Rope.Find[cmd.commandLine, "5 pages", 0, FALSE] >= 0 THEN 5 ELSE LAST[INT];
node ← PutGet.FromFile[fileName: inputFileName
! FS.Error => TRUSTED {errorMsg ← error.explanation; CONTINUE}
];
IF node = NIL THEN {cmd.out.PutRope[errorMsg]; cmd.out.PutChar['\n]}
ELSE
TRUSTED {
imager: Imager.Context ← Imager.Create[$PD, pdFileDescription];
outputHandle: TSOutput.Handle ← CreatePDOutput[imager];
galley: TSObject.ItemList;
style: NodeStyle.Ref;
cmd.out.PutRope["Typesetting "];
cmd.out.PutRope[inputFileName];
cmd.out.PutRope[" . "];
imager.PutProp[$Commander, cmd];
imager.PutProp[$PageNumber, NEW[INT ← 0]];
imager.PutProp[$MaxPagesPerFile, NEW[INT ← maxPagesPerFile]];
imager.PutProp[$OutputFileName, outputName];
IF corners THEN imager.PutProp[$Corners, $TRUE];
imager.PutProp[$RootName, GetRootName[inputFileName]];
{
ENABLE
UNWIND => {imager.PutProp[$Commander,
NIL]};
[galley, style] ← TSTranslate.TreeToVlist[node];
[] ← TSJaMPageBuilder.RunPageBuilder[
galley: galley,
style: style,
output: outputHandle,
abortCheckProc: isAborted,
documentName: inputFileName
! TSTranslate.FontNotFound => {
cmd.out.PutF["Unable to open TFM file for font &g (source location = &g)",
IO.rope[fontName],
IO.int[location]
];
CONTINUE;
};
];
};
imager ← NARROW[outputHandle.outputState];
outputName ← NARROW[imager.GetProp[$OutputFileName]];
TSOutput.Close[outputHandle];
imager.PutProp[$Commander, NIL];
cmd.out.PutRope[outputName];
cmd.out.PutRope[" written.\n"];
};
};
Commander.Register["TSPD", TSetterPDCommand, "Tioga doc to PD file."];
Commander.Register["TSetterPD", TSetterPDCommand, "Tioga doc to PD file."];
Commander.Register["TS880", TSetterPDCommand, "Tioga doc to Platemaker PD file.", $Platemaker];
Commander.Register["TS384B", TSetterPDCommand, "Tioga doc to Peach PD file.", $Peach];
END.