<> <> 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 ROPE: TYPE ~ Rope.ROPE; 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.