<> <> <> <> <> <> <> DIRECTORY Atom USING [GetPName, MakeAtom], Commander USING [CommandProc, Handle, Register], Convert USING [AtomFromRope, Error, IntFromRope, RealFromRope, RopeFromInt], FS USING [ComponentPositions, Error, ExpandName, FileInfo, StreamOpen], Imager USING [Context, DoSave, MaskRectangle, metersPerInch, PixelArray, Rectangle, RotateT, Scale2T, ScaleT, SetFont, SetPriorityImportant, SetSampledColor, SetXY, ShowRope, TranslateT, VEC], ImagerBrick USING [Brick, BrickRep], ImagerColorOperator USING [GrayLinearColorModel, RGBLinearColorModel], ImagerFont USING [Find, Scale], ImagerFontFilter USING [CharacterCodeMap, CharRangeMap, FilterFonts, FontMap, FontMapEntry], ImagerInterpress USING [Close, Create, DeclarePixelArray, DoPage, Ref], ImagerPD USING [Close, CreateFromParameters, DoPage, PD, SetHalftoneProperties, Toner, Toners], ImagerPixelArray USING [FromAIS, Join3AIS, MaxSampleValue], ImagerPixelMap USING [Create, Fill, PixelMap], ImagerPress USING [Close, NewPage, PrinterType, SimpleCreate], ImagerSmooth USING [Create, LikeScreen, SetComponent], ImagerToJaM USING [Close, Create], ImagerTransformation USING [TransformRectangle], Interpress USING [classAppearanceError, classAppearanceWarning, classComment, classMasterError, classMasterWarning, DoPage, LogProc, Master, Open], IO USING [CharClass, EndOf, EndOfStream, GetBlock, GetIndex, GetLength, GetLineRope, GetTokenRope, int, PutChar, PutF, PutFR, PutRope, refAny, RIS, rope, SetIndex, STREAM], PixelMapOps USING [StoreAIS], PrintFileConvert USING [PDParams, ProgressProc], Process USING [CheckForAbort], Real USING [Round, RoundLI], Rope USING [Cat, Concat, Equal, Fetch, Find, FromRefText, Index, Length, ROPE, Size, Substr, Translate, TranslatorType], RopeFile USING [Create], RuntimeError USING [UNCAUGHT], ShowPress USING [DrawPressPage, Handle, Open]; PrintFileConvertImpl: CEDAR PROGRAM IMPORTS Atom, Commander, Convert, FS, Imager, ImagerColorOperator, ImagerFont, ImagerFontFilter, ImagerInterpress, ImagerPD, ImagerPixelArray, ImagerPixelMap, ImagerPress, ImagerSmooth, ImagerToJaM, ImagerTransformation, Interpress, IO, PixelMapOps, Process, Real, Rope, RopeFile, RuntimeError, ShowPress EXPORTS PrintFileConvert ~ BEGIN OPEN PrintFileConvert; ROPE: TYPE ~ Rope.ROPE; ActionProc: TYPE ~ PROC [inputName: ROPE, outputName: ROPE, cmd: Commander.Handle, cmds: IO.STREAM]; LogError: PROC [msg: IO.STREAM, class: INT, code: ATOM, explanation: ROPE] ~ { msg.PutRope[ SELECT class FROM Interpress.classMasterError => "Master Error: ", Interpress.classMasterWarning => "Master Warning: ", Interpress.classAppearanceError => "Appearance Error: ", Interpress.classAppearanceWarning => "Appearance Warning: ", Interpress.classComment => "Comment: ", ENDCASE => Rope.Cat["Class ", Convert.RopeFromInt[class], " Error: "] ]; msg.PutRope[explanation]; msg.PutRope[" . . . "]; }; InterpressToAISAction: ActionProc = { AColor: TYPE = {red, green, blue}; aA: ARRAY AColor OF ATOM = [$Red, $Green, $Blue]; om: Interpress.Master; sPixelsPerInch, fPixelsPerInch: REAL _ 72.0; sPixelsPerInchI, fPixelsPerInchI: INT; pixelMap: ImagerPixelMap.PixelMap; context: Imager.Context; gray: BOOL _ FALSE; complaint: ROPE; Log: Interpress.LogProc ~ { LogError[cmd.out, class, code, explanation] }; UNTIL IO.EndOf[self: cmds] DO { token: ROPE ~ GetCmdToken[cmds]; IF token=NIL THEN LOOP; SELECT TRUE FROM Rope.Equal[token, "gray", FALSE] => gray _ TRUE; Rope.Equal[token, "ppi:", FALSE] => sPixelsPerInch _ fPixelsPerInch _ Convert.RealFromRope[r: GetCmdToken[cmds] ! Convert.Error => {cmd.out.PutRope["\nIllegal value for ppi.\n"]; GOTO Fail}]; Rope.Equal[token, "sppi:", FALSE] => sPixelsPerInch _ Convert.RealFromRope[r: GetCmdToken[cmds] ! Convert.Error => {complaint _ "\nIllegal value for sppi.\n"; GOTO Fail}]; Rope.Equal[token, "fppi:", FALSE] => fPixelsPerInch _ Convert.RealFromRope[r: GetCmdToken[cmds] ! Convert.Error => {complaint _ "\nIllegal value for fppi.\n"; GOTO Fail}]; ENDCASE => {complaint _ Rope.Cat["\nUnrecognized token: ", token, "\n"]; GOTO Fail}; EXITS Fail => Complain[complaint] } ENDLOOP; om _ Interpress.Open[inputName, Log]; sPixelsPerInchI _ Real.RoundLI[sPixelsPerInch]; fPixelsPerInchI _ Real.RoundLI[fPixelsPerInch]; pixelMap _ ImagerPixelMap.Create[3, [0, 0, 11*sPixelsPerInchI, (85*fPixelsPerInchI)/10]]; context _ ImagerSmooth.Create[pixelMap: pixelMap, component: $Intensity, viewToPixel: ImagerSmooth.LikeScreen[11*sPixelsPerInchI], initialScale: fPixelsPerInch/0.0254, change: NIL, changeData: NIL, cacheFonts: TRUE, surfaceUnitsPerPixel: 5]; IF gray THEN { -- Intensity map Process.CheckForAbort[]; cmd.out.PutF["[%g", IO.int[1]]; ImagerPixelMap.Fill[dest: pixelMap, area: [0, 0, 10000, 10000], value: 377B]; Interpress.DoPage[master: om, page: 1, context: context, log: Log]; PixelMapOps.StoreAIS[Rope.Cat[outputName, ".ais"], [pixelMap, FALSE, NIL]]; cmd.out.PutRope["] "]; } ELSE FOR i: AColor IN AColor DO Process.CheckForAbort[]; cmd.out.PutF["[%g", IO.refAny[aA[i]]]; ImagerPixelMap.Fill[dest: pixelMap, area: [0, 0, 10000, 10000], value: 377B]; ImagerSmooth.SetComponent[context, aA[i]]; Interpress.DoPage[master: om, page: 1, context: context, log: Log]; PixelMapOps.StoreAIS[Rope.Cat[outputName, "-", Atom.GetPName[aA[i]], ".ais"], [pixelMap, FALSE, NIL]]; cmd.out.PutRope["] "]; ENDLOOP; }; PressToInterpressAction: ActionProc ~ { version: ROPE ~ GetCmdToken[cmds]; verbose: ROPE ~ GetCmdToken[cmds]; header: ROPE ~ IF Rope.Size[version] = 3 AND Rope.Fetch[version, 1] = '. THEN Rope.Cat["Interpress/Xerox/", version, " "] ELSE NIL; showPress: ShowPress.Handle ~ ShowPress.Open[inputName]; interpress: ImagerInterpress.Ref _ ImagerInterpress.Create[outputName, header]; xc: BOOL _ Rope.Size[version] = 3 AND Rope.Fetch[version, 0] < '3; FOR i: INT IN [1..showPress.lastPart) DO Paint: PROC [context: Imager.Context] ~ { cmd.out.PutF["[%g", IO.int[i]]; IF xc THEN context _ FontTranslator[context, version, cmd, verbose.Equal["verbose", FALSE]]; Imager.SetPriorityImportant[context, TRUE]; ShowPress.DrawPressPage[context: context, show: showPress, pageNumber: i]; cmd.out.PutRope["] "]; }; Process.CheckForAbort[]; ImagerInterpress.DoPage[self: interpress, action: Paint, scale: 1.0E-5]; ENDLOOP; ImagerInterpress.Close[interpress]; }; inch: REAL ~ 0.0254; headerSampled: ROPE _ "Interpress/Xerox/3.0 "; aisMargin: REAL _ 0.25*inch; pageWidth: REAL _ 8.5*inch; pageHeight: REAL _ 11*inch; captionFont: ROPE _ "xerox/pressfonts/helvetica-mir"; captionLoc: Imager.VEC ~ [72, 9]; FileChoice: PROC [r: Rope.ROPE, a: ARRAY [0..3) OF Rope.ROPE] RETURNS [result: Rope.ROPE _ NIL] ~ { FOR i: NAT IN [0..3) DO IF a[i] # NIL THEN { name: ROPE ~ Rope.Cat[r, "-", a[i], ".ais"]; result _ FS.FileInfo[name ! FS.Error => {IF error.code = $unknownFile THEN CONTINUE}].fullFName; IF result# NIL THEN RETURN; }; ENDLOOP; }; GetColorNames: PROC [name: Rope.ROPE] RETURNS [ok: BOOL, red, grn, blu: Rope.ROPE] ~ { red _ FileChoice[name, ["red", "r", NIL]]; IF red = NIL THEN { ok _ FALSE; RETURN}; grn _ FileChoice[name, ["grn", "green", "g"]]; IF grn = NIL THEN { ok _ FALSE; RETURN}; blu _ FileChoice[name, ["blu", "blue", "b"]]; ok _ blu # NIL; }; ColorAISToInterpressCommand: Commander.CommandProc ~ { red, grn, blu: ROPE; interpress: ImagerInterpress.Ref; pa: Imager.PixelArray; maxSample: CARDINAL; rect: Imager.Rectangle; scale: REAL; Paint: PROC [context: Imager.Context] ~ { Caption: PROC ~ { Imager.ScaleT[context, inch/72]; Imager.SetFont[context, ImagerFont.Scale[ImagerFont.Find[captionFont], 9]]; Imager.SetXY[context, [72, 9]]; Imager.ShowRope[context, cmd.commandLine]; }; Imager.SetPriorityImportant[context, TRUE]; Imager.DoSave[context, Caption]; Imager.TranslateT[context, [pageWidth*0.5, pageHeight*0.5]]; Imager.ScaleT[context, scale]; Imager.TranslateT[context, [-(rect.x+rect.w*0.5), -(rect.y+rect.h*0.5)]]; Imager.SetSampledColor[context: context, pa: pa, m: NIL, colorOperator: ImagerColorOperator.RGBLinearColorModel[maxSample]]; Imager.MaskRectangle[context, rect]; }; stream: IO.STREAM _ IO.RIS[cmd.commandLine]; outputName: ROPE _ GetCmdToken[stream]; secondTokenIndex: INT _ IO.GetIndex[stream]; gets: ROPE _ GetCmdToken[stream]; ok: BOOL _ FALSE; inputName: ROPE _ NIL; IF NOT gets.Equal["_"] THEN { inputName _ outputName; outputName _ NIL; stream.SetIndex[secondTokenIndex]; } ELSE {inputName _ GetCmdToken[stream]}; IF inputName = NIL THEN RETURN[result: $Failure, msg: cmd.procData.doc]; [ok, red, grn, blu] _ GetColorNames[inputName ! FS.Error => { IF error.group = user THEN {result _ $Failure; msg _ error.explanation; GOTO Quit} }]; IF NOT ok THEN RETURN[result: $Failure, msg: "Could not find one or more of the input files\n"]; IF outputName = NIL THEN { outputName _ MakeOutputName[inputName, cmd.procData.doc]; }; cmd.out.PutF["Reading\n %g\n %g\n %g . . . ", IO.rope[red], IO.rope[grn], IO.rope[blu]]; pa _ ImagerPixelArray.Join3AIS[red, grn, blu]; maxSample _ ImagerPixelArray.MaxSampleValue[pa, 0]; rect _ ImagerTransformation.TransformRectangle[pa.m, [0, 0, pa.sSize, pa.fSize]]; scale _ MIN[(pageWidth-2*aisMargin)/rect.w, (pageHeight-2*aisMargin)/rect.h]; interpress _ ImagerInterpress.Create[outputName, headerSampled]; ImagerInterpress.DeclarePixelArray[interpress, pa]; ImagerInterpress.DoPage[self: interpress, action: Paint, scale: 1.0]; ImagerInterpress.Close[interpress]; outputName _ FindFullName[outputName]; cmd.out.PutRope["\n "]; cmd.out.PutRope[outputName]; cmd.out.PutRope[" written.\n"]; EXITS Quit => NULL }; AISToInterpressAction: ActionProc ~ { interpress: ImagerInterpress.Ref _ ImagerInterpress.Create[outputName, headerSampled]; pa: Imager.PixelArray _ ImagerPixelArray.FromAIS[inputName]; maxSample: CARDINAL ~ ImagerPixelArray.MaxSampleValue[pa, 0]; rect: Imager.Rectangle _ ImagerTransformation.TransformRectangle[pa.m, [0, 0, pa.sSize, pa.fSize]]; scale: REAL _ MIN[(pageWidth-2*aisMargin)/rect.w, (pageHeight-2*aisMargin)/rect.h]; Paint: PROC [context: Imager.Context] ~ { Caption: PROC ~ { Imager.ScaleT[context, inch/72]; Imager.SetFont[context, ImagerFont.Scale[ImagerFont.Find[captionFont], 9]]; Imager.SetXY[context, [72, 9]]; Imager.ShowRope[context, cmd.commandLine]; }; Imager.SetPriorityImportant[context, TRUE]; Imager.DoSave[context, Caption]; Imager.TranslateT[context, [pageWidth*0.5, pageHeight*0.5]]; Imager.ScaleT[context, scale]; Imager.TranslateT[context, [-(rect.x+rect.w*0.5), -(rect.y+rect.h*0.5)]]; Imager.SetSampledColor[context: context, pa: pa, m: NIL, colorOperator: ImagerColorOperator.GrayLinearColorModel[maxSample, 0, maxSample]]; Imager.MaskRectangle[context, rect]; }; cmd.out.PutF["[%g", IO.int[1]]; ImagerInterpress.DeclarePixelArray[interpress, pa]; ImagerInterpress.DoPage[self: interpress, action: Paint, scale: 1.0]; cmd.out.PutRope["] "]; ImagerInterpress.Close[interpress]; }; InterpressToPressAction: ActionProc ~ { Log: Interpress.LogProc ~ { LogError[cmd.out, class, code, explanation] }; interpress: Interpress.Master ~ Interpress.Open[inputName, Log]; context: Imager.Context ~ ImagerPress.SimpleCreate[fileName: outputName, printerType: press]; FOR i: INT IN [1..interpress.pages] DO Process.CheckForAbort[]; cmd.out.PutF["[%g", IO.int[i]]; Interpress.DoPage[master: interpress, page: i, context: context, log: Log]; cmd.out.PutRope["] "]; IF i # interpress.pages THEN ImagerPress.NewPage[context]; ENDLOOP; ImagerPress.Close[context]; }; InterpressToJaMAction: ActionProc ~ { Log: Interpress.LogProc ~ { LogError[cmd.out, class, code, explanation] }; interpress: Interpress.Master ~ Interpress.Open[inputName, Log]; stream: IO.STREAM ~ FS.StreamOpen[outputName, $create]; context: Imager.Context ~ ImagerToJaM.Create[stream]; stream.PutRope["% Produced from "]; stream.PutRope[inputName]; stream.PutRope["\n"]; FOR i: INT IN [1..interpress.pages] DO Process.CheckForAbort[]; stream.PutF["%% Page %g\n", IO.int[i]]; Interpress.DoPage[master: interpress, page: i, context: context, log: Log]; ENDLOOP; ImagerToJaM.Close[context]; }; Rev: PROC [list: ImagerPD.Toners] RETURNS [ImagerPD.Toners] ~ { l1, l2, l3: ImagerPD.Toners _ NIL; IF list = NIL THEN RETURN[NIL]; l3 _ list; UNTIL (l1 _ l3) = NIL DO l3 _ l3.rest; l1.rest _ l2; l2 _ l1; ENDLOOP; RETURN[l2]; }; Bound: TYPE ~ RECORD [first, last: INT]; int: Bound ~ [INT.FIRST, INT.LAST]; nat: Bound ~ [NAT.FIRST, NAT.LAST]; card: Bound ~ [CARDINAL.FIRST, CARDINAL.LAST]; RealToNum: PROC [real: REAL, bounds: Bound _ int, name: ROPE _ NIL] RETURNS [number: INT _ 0] ~ { IF name=NIL THEN name _ "Value"; number _ Real.Round[real ! RuntimeError.UNCAUGHT => CONTINUE]; IF real#number THEN Complain[IO.PutFR[format: "%g (%g) should be integral.", v1: [rope [name]], v2: [real [real]]]]; IF number NOT IN [bounds.first .. bounds.last] THEN Complain[IO.PutFR[format: "Value (%g) should be in range [%g .. %g]", v1: [rope [name]], v2: [integer [bounds.first]], v3: [integer [bounds.last]]]]; }; xStar: ROPE ~ FS.ExpandName["*"].fullFName; regDir: ROPE ~ Rope.Substr[xStar, 0, Rope.Size[xStar]-1]; wDirList: LIST OF ROPE _ LIST[NIL, regDir]; FileContents: PROC [base, ext: ROPE] RETURNS [ROPE] ~ { FOR each: LIST OF ROPE _ wDirList, each.rest UNTIL each = NIL DO name: ROPE ~ FS.ExpandName[name: Rope.Cat[base, ext], wDir: each.first].fullFName; RETURN [RopeFile.Create[name: name, raw: FALSE ! FS.Error => {IF error.group = user THEN CONTINUE}]]; ENDLOOP; Complain[IO.PutFR[format: "Device type %g undefined.", v1: [rope [base]]]]; }; Specs: TYPE ~ RECORD [ params: PDParams, -- PD parameters sx, sy: REAL _ 1.0, -- scale rotateDegrees: REAL _ 1.0, -- rotate tx, ty: REAL _ 0.0, -- translate skipPages: INT _ 0, nPages: INT _ INT.LAST ]; GetSpecs: PROC [deviceCodeRope: ROPE _ NIL, deviceSpecRope: ROPE _ NIL] RETURNS [Specs] ~ { ToLowerCase: Rope.TranslatorType = { <<[old: CHAR] RETURNS [new: CHAR]>> RETURN [SELECT old FROM IN ['A .. 'Z] => old + ('a - 'A), ENDCASE => old ] }; Err: PROC ~ { IF tok#NIL THEN Complain[Rope.Concat["Unknown keyword: ", tok]] ELSE Complain["Malformed command"]; }; specsFromFile: ROPE ~ FileContents[deviceCodeRope, ".pdDeviceSpec"]; specsRope: ROPE ~ Rope.Cat[specsFromFile, "CommandLineParameters ", deviceSpecRope]; cmds: IO.STREAM ~ IO.RIS[specsRope]; params: PDParams _ []; tok: ROPE _ NIL; tx, ty: REAL _ 0.0; rotateDegrees: REAL _ 0.0; sx, sy: REAL _ 1.0; skipPages: INT _ 0; nPages: INT _ INT.LAST; toners: ImagerPD.Toners _ NIL; tokensSinceLastToner: CARDINAL _ 1; parsingPDDeviceSpecFile: BOOLEAN _ TRUE; leftBracket: ATOM ~ Atom.MakeAtom["["]; ParseBrick: PROC ~ { a: REF ARRAY [0..1000) OF REAL _ NEW[ARRAY [0..1000) OF REAL]; sSize: NAT _ 0; fSize: NAT _ 0; phase: NAT _ 0; toner: ImagerPD.Toner _ black; n: NAT _ 0; brick: ImagerBrick.Brick _ NIL; tok _ GetCmdToken[cmds]; WHILE Rope.Equal[tok, "["] DO tok _ GetCmdToken[cmds]; WHILE tok # NIL AND NOT Rope.Equal[tok, "]"] DO real: REAL ~ RealFromRope[tok]; IF real NOT IN [0.0..1.0] THEN Complain["Brick values should be between 0 and 1"]; a[n] _ real; n _ n + 1; IF sSize = 0 THEN fSize _ fSize + 1; tok _ GetCmdToken[cmds]; ENDLOOP; sSize _ sSize + 1; IF n MOD fSize # 0 THEN Complain["Malformed array"]; tok _ GetCmdToken[cmds]; ENDLOOP; IF Rope.Equal[tok, "]"] THEN tok _ GetCmdToken[cmds] ELSE Complain["Malformed array"]; phase _ RealToNum[RealFromRope[tok], card]; tok _ GetCmdToken[cmds]; SELECT TRUE FROM Rope.Equal[tok, "black", FALSE] => toner _ black; Rope.Equal[tok, "cyan", FALSE] => toner _ cyan; Rope.Equal[tok, "magenta", FALSE] => toner _ magenta; Rope.Equal[tok, "yellow", FALSE] => toner _ yellow; ENDCASE => Complain[Rope.Cat["Expected toner name, but found \"", tok, "\""]]; tok _ GetCmdToken[cmds]; IF NOT Rope.Equal[tok, "brick", FALSE] THEN Complain["Missing \"brick\" Keyword"]; brick _ NEW[ImagerBrick.BrickRep[n]]; brick.sSize _ sSize; brick.fSize _ fSize; brick.phase _ phase; brick.u _ 0; brick.v _ 0; FOR i: NAT IN [0..n) DO brick[i] _ a[i] ENDLOOP; params.bricks[toner] _ brick; }; params.ppd _ -1.0; params.sRes _ params.fRes _ 384; params.deviceCode _ 15; params.pageSSize _ 11.0; params.pageFSize _ 8.5; UNTIL (tok _ GetCmdToken[cmds]) = NIL DO atom: ATOM _ Convert.AtomFromRope[Rope.Translate[base: tok, translator: ToLowerCase]]; tokensSinceLastToner _ tokensSinceLastToner + 1; IF tok.Length[]>1 AND tok.Substr[len: 2].Equal["--"] THEN { --Handle double-dash comments pos: INT ~ tok.Find[s2: "\n"]; IF pos=-1 THEN { [] _ IO.GetLineRope[cmds ! IO.EndOfStream => CONTINUE]; LOOP; } ELSE atom _ Convert.AtomFromRope[Rope.Translate[base: tok _ Rope.Substr[base: tok, start: pos+1], translator: ToLowerCase]]; }; SELECT atom FROM leftBracket => ParseBrick[]; $commandlineparameters => parsingPDDeviceSpecFile _ FALSE; --Mostly used to separate potential toner strings from each other if a toner string is the last thing in a pdDeviceSpec file $black, $cyan, $magenta, $yellow => { IF tokensSinceLastToner > 1 THEN toners _ NIL; tokensSinceLastToner _ 0; toners _ CONS[SELECT atom FROM $black=>black, $cyan=>cyan, $magenta=>magenta, $yellow=>yellow, ENDCASE => ERROR, toners]; }; $leftovers => params.leftovers _ TRUE; $noleftovers => params.leftovers _ FALSE; $fonttuning => params.fontTuning _ GetCmdToken[cmds]; $of => { tok _ GetCmdToken[cmds]; SELECT TRUE FROM Rope.Equal[tok, "3", FALSE] => { params.tonerUniverse _ LIST[cyan, magenta, yellow]; }; Rope.Equal[tok, "4", FALSE] => { params.tonerUniverse _ LIST[black, cyan, magenta, yellow]; }; ENDCASE => Err[]; }; ENDCASE => { real: REAL ~ RealFromRope[tok]; atom _ Convert.AtomFromRope[Rope.Translate[base: tok _ GetCmdToken[cmds], translator: ToLowerCase]]; --Assign to tok for error reporting SELECT atom FROM $ppd => params.ppd _ real; -- ppd $in => { -- in in translate tx _ real; ty _ RealFromRope[GetCmdToken[cmds]]; Require[cmds, "in", FALSE]; Require[cmds, "translate", FALSE]; }; $rotate => rotateDegrees _ real; -- rotate $scale => sx _ sy _ real; -- scale $scalex => sx _ real; -- scaleX $scaley => sy _ real; -- scaleY $skippages => skipPages _ RealToNum[real,int,tok]; -- skipPages $npages => nPages _ RealToNum[real,int,tok]; -- nPages $sresolution => params.sRes _ RealToNum[real, card]; -- sResolution $fresolution => params.fRes _ RealToNum[real, card]; -- fResolution $resolution => params.sRes _ params.fRes _ RealToNum[real, card]; -- Resolution $devicecode => params.deviceCode _ RealToNum[real, [0,15]]; -- deviceCode $pagessize => params.pageSSize _ real; -- pageSSize $pagefsize => params.pageFSize _ real; -- pageFSize $bandsize => params.bandSize _ RealToNum[real,nat,tok]; -- bandSize $load => params.load _ RealToNum[real,int,tok]; -- load $gamma => params.ucr.blackGamma _ real; -- gamma $threshold => params.ucr.blackThreshold _ real; -- threshold $removedfraction => params.ucr.removedFraction _ real; -- removedFraction ENDCASE => Err[]; }; ENDLOOP; params.toners _ Rev[toners]; RETURN [[params: params, sx: sx, sy: sy, rotateDegrees: rotateDegrees, tx: tx, ty: ty, skipPages: skipPages, nPages: nPages]]; }; IPToPDAction: ActionProc ~ { deviceCodeRope: ROPE ~ GetCmdToken[cmds]; text: REF TEXT ~ NEW[TEXT[IO.GetLength[cmds]-IO.GetIndex[cmds]]]; nBytesRead: [0..0] ~ IO.GetBlock[self: cmds, block: text]-text.maxLength; specs: Specs ~ GetSpecs[deviceCodeRope, Rope.FromRefText[text]]; Log: Interpress.LogProc ~ { LogError[cmd.out, class, code, explanation] }; Progress: ProgressProc ~ { IF begin THEN cmd.out.PutF["[%g", IO.int[page]] ELSE cmd.out.PutRope["] "]; }; cmd.out.PutChar[' ]; InterpressToPD[inputName: inputName, outputName: outputName, params: specs.params, sx: specs.sx, sy: specs.sy, rotateDegrees: specs.rotateDegrees, tx: specs.tx, ty: specs.ty, skipPages: specs.skipPages, nPages: specs.nPages, logProc: Log, progressProc: Progress]; }; InterpressToPD: PUBLIC PROC [ inputName: ROPE, -- name of Interpress file outputName: ROPE, -- name of PD file params: PDParams, -- PD parameters sx, sy: REAL _ 1.0, -- scale tx, ty: REAL _ 0.0, -- translate rotateDegrees: REAL _ 0.0, -- rotation (degrees) skipPages: INT _ 0, nPages: INT _ INT.LAST, logProc: Interpress.LogProc _ NIL, -- called for errors during Interpress execution progressProc: ProgressProc _ NIL -- called at the beginning and end of each page ] ~ { interpress: Interpress.Master ~ Interpress.Open[inputName, logProc]; pd: ImagerPD.PD _ ImagerPD.CreateFromParameters[ name: outputName, deviceCode: params.deviceCode, sResolution: params.sRes, fResolution: params.fRes, imageSSize: Real.Round[params.pageSSize*params.sRes], imageFSize: Real.Round[params.pageFSize*params.fRes], toners: params.toners, leftovers: params.leftovers, bandSSize: params.bandSize, maxLoadWords: params.load, fontTuning: params.fontTuning, tonerUniverse: params.tonerUniverse, pixelsPerHalftoneDot: params.ppd, ucr: params.ucr ]; FOR t: ImagerPD.Toner IN ImagerPD.Toner DO IF params.bricks[t] # NIL THEN ImagerPD.SetHalftoneProperties[pd, t, params.bricks[t]]; ENDLOOP; skipPages _ MIN[MAX[skipPages, 0], interpress.pages]; nPages _ MIN[nPages, interpress.pages-skipPages]; FOR i: INT IN [skipPages..skipPages+nPages) DO page: INT ~ i+1; action: PROC [context: Imager.Context] ~ { IF tx#0.0 OR ty#0.0 THEN { Imager.TranslateT[context, [tx*Imager.metersPerInch, ty*Imager.metersPerInch]]; }; IF rotateDegrees # 0.0 THEN { Imager.RotateT[context, rotateDegrees]; }; IF sx#1.0 OR sy#1.0 THEN { IF sx = sy THEN Imager.ScaleT[context, sx] ELSE Imager.Scale2T[context, [sx, sy]]; }; Interpress.DoPage[master: interpress, page: page, context: context, log: logProc]; }; IF progressProc#NIL THEN progressProc[begin: TRUE, page: page]; ImagerPD.DoPage[pd: pd, action: action, pixelUnits: FALSE]; IF progressProc#NIL THEN progressProc[begin: FALSE, page: page]; ENDLOOP; ImagerPD.Close[pd]; }; <> <<>> <> <<>> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<};>> <<>> ParamsFromPrinterType: PUBLIC PROC [type: ATOM] RETURNS [PDParams] ~ { specs: Specs; specs _ GetSpecs[Atom.GetPName[type], NIL]; RETURN [specs.params]; }; FontTranslator: PROC [c: Imager.Context, version: ROPE, cmd: Commander.Handle, verbose: BOOL] RETURNS [context: Imager.Context] ~ { fontMap: ImagerFontFilter.FontMap _ xc1map; RETURN [ImagerFontFilter.FilterFonts[c, fontMap, cmd, verbose]]; }; CH: PROC [char: CHAR] RETURNS [WORD] ~ INLINE {RETURN [ORD[char]]}; XC: PROC [set: [0..256), code: [0..256)] RETURNS [WORD] ~ {RETURN [set*256+code]}; C1: PROC [char: CHAR, set: [0..256), code: [0..256)] RETURNS [ImagerFontFilter.CharRangeMap] ~ { RETURN [[bc: CH[char], ec: CH[char], newbc: XC[set, code]]] }; classicModernEtAl: LIST OF ROPE _ LIST["Classic", "Modern"]; timesRomanEtAl: LIST OF LIST OF ROPE _ LIST[LIST["TimesRoman", "Classic"], LIST["Helvetica", "Modern"], LIST["Gacha", "XeroxBook"], LIST["Tioga", "Classic"], LIST["Laurel", "Classic"]]; mrrEtAl: LIST OF ROPE _ LIST["-mrr", "-mir-italic", "-bir-bold-italic", "-brr-bold"]; alphaMap: ImagerFontFilter.CharacterCodeMap ~ LIST [ [bc: CH[' ], ec: CH['~], newbc: CH[' ]] ]; mathMap: ImagerFontFilter.CharacterCodeMap _ LIST [ C1['©, 0, 323B], C1['®, 0, 322B] ]; oisMap: ImagerFontFilter.CharacterCodeMap _ LIST [ [bc: CH['a], ec: CH['~], newbc: CH['a]], [bc: CH['.], ec: CH[']], newbc: CH['.]], [bc: CH['%], ec: CH[',], newbc: CH['%]], [bc: CH['-], ec: CH['-], newbc: XC[357B, 42B]], [bc: CH[' ], ec: CH['!], newbc: CH[' ]], [bc: CH['\"], ec: CH['\"], newbc: XC[0, 271B]], [bc: CH['#], ec: CH['#], newbc: CH['#]], [bc: CH['$], ec: CH['$], newbc: XC[0, 244B]], [bc: CH['^], ec: CH['^], newbc: XC[0, 255B]], [bc: CH['_], ec: CH['_], newbc: XC[0, 254B]], C1['\030, 357B, 45B], C1['\267, 357B, 146B], C1['\265, 41B, 172B], C1['\140, 0, 140B], C1[', 357B, 064B], C1[', 357B, 065B], ]; xc1map: ImagerFontFilter.FontMap _ MakeXC1map[]; MakeXC1map: PROC RETURNS [f: ImagerFontFilter.FontMap] ~ { Enter: PROC [e: ImagerFontFilter.FontMapEntry] ~ {f _ CONS[e, f]}; FOR family: LIST OF ROPE _ classicModernEtAl, family.rest UNTIL family = NIL DO FOR face: LIST OF ROPE _ mrrEtAl, face.rest UNTIL face = NIL DO Enter[[ inputName: Rope.Cat["Xerox/Pressfonts/", family.first, face.first.Substr[0, 4]], output: LIST[[newName: Rope.Cat["Xerox/xc1-1-1/", family.first, face.first.Substr[4]], charMap: oisMap]] ]]; ENDLOOP; ENDLOOP; FOR family: LIST OF LIST OF ROPE _ timesRomanEtAl, family.rest UNTIL family = NIL DO FOR face: LIST OF ROPE _ mrrEtAl, face.rest UNTIL face = NIL DO Enter[[ inputName: Rope.Cat["Xerox/Pressfonts/", family.first.first, face.first.Substr[0, 4]], output: LIST[[newName: Rope.Cat["Xerox/xc1-1-1/", family.first.rest.first, face.first.Substr[4]], charMap: oisMap]], warn: TRUE ]]; ENDLOOP; ENDLOOP; Enter[[ inputName: "Xerox/Pressfonts/Logo-mrr", output: LIST[[newName: "Xerox/xc1-1-1/Logotypes-Xerox", charMap: alphaMap]] ]]; Enter[[ inputName: "Xerox/Pressfonts/Math-mrr", output: LIST[[newName: "Xerox/xc1-1-1/Modern", charMap: mathMap]] ]]; Enter[[ inputName: "Xerox/Pressfonts/Math-mir", output: LIST[[newName: "Xerox/xc1-1-1/Modern-italic", charMap: mathMap]] ]]; }; FindFullName: PROC [inputName: ROPE] RETURNS [ROPE] ~ { fullFName: ROPE _ NIL; fullFName _ FS.FileInfo[inputName].fullFName; RETURN [fullFName] }; CmdTokenBreak: PROC [char: CHAR] RETURNS [IO.CharClass] = { IF char = '_ OR char = '[ OR char = '] THEN RETURN [break]; IF char = ' OR char = '\t OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr]; RETURN [other]; }; GetCmdToken: PROC [stream: IO.STREAM] RETURNS [rope: ROPE] = { rope _ NIL; rope _ stream.GetTokenRope[CmdTokenBreak ! IO.EndOfStream => CONTINUE].token; }; FileNameTokenBreak: PROC [char: CHAR] RETURNS [IO.CharClass] = { IF char = '_ THEN RETURN [break]; IF char = ' OR char = '\t OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr]; RETURN [other]; }; GetFileNameToken: PROC [stream: IO.STREAM] RETURNS [rope: ROPE] = { rope _ NIL; rope _ stream.GetTokenRope[FileNameTokenBreak ! IO.EndOfStream => CONTINUE].token; }; RealFromRope: PROC [rope: ROPE] RETURNS [real: REAL] = { oops: BOOL _ FALSE; real _ Convert.RealFromRope[rope ! Convert.Error => {oops _ TRUE; CONTINUE}]; IF oops THEN {oops _ FALSE; real _ Convert.IntFromRope[rope ! Convert.Error => {oops _ TRUE; CONTINUE}]}; IF oops THEN Complain[Rope.Concat["Number expected: ", rope]]; }; Require: PROC [stream: IO.STREAM, rope: ROPE, case: BOOLEAN _ FALSE] ~ { IF NOT Rope.Equal[s1: rope, s2: GetCmdToken[stream], case: case] THEN Complain[Rope.Cat["Expected \"", rope, "\"."]]; }; Complain: PUBLIC ERROR [complaint: ROPE] ~ CODE; MakeOutputName: PROC [inputName: ROPE, doc: ROPE] RETURNS [ROPE] ~ { start: INT _ Rope.Index[s1: doc, s2: " to "]+4; end: INT _ Rope.Index[s1: doc, pos1: start, s2: " "]; cp: FS.ComponentPositions; isAIS: BOOL _ Rope.Equal[Rope.Substr[doc, start, end-start], "ais", FALSE]; [inputName, cp] _ FS.ExpandName[inputName]; RETURN [Rope.Cat[ Rope.Substr[inputName, cp.base.start, cp.base.length], IF isAIS THEN NIL ELSE ".", IF isAIS THEN NIL ELSE Rope.Substr[doc, start, end-start] ]] }; Command: Commander.CommandProc ~ { refAction: REF ActionProc ~ NARROW[cmd.procData.clientData]; stream: IO.STREAM _ IO.RIS[cmd.commandLine]; outputName: ROPE _ GetFileNameToken[stream]; secondTokenIndex: INT _ IO.GetIndex[stream]; gets: ROPE _ GetFileNameToken[stream]; inputName: ROPE _ NIL; IF NOT gets.Equal["_"] THEN { inputName _ outputName; outputName _ NIL; stream.SetIndex[secondTokenIndex]; } ELSE {inputName _ GetFileNameToken[stream]}; IF inputName = NIL THEN RETURN[result: $Failure, msg: cmd.procData.doc]; inputName _ FindFullName[inputName ! FS.Error => { IF error.group = user THEN {result _ $Failure; msg _ error.explanation; GOTO Quit} }]; IF outputName = NIL THEN { outputName _ MakeOutputName[inputName, cmd.procData.doc]; }; cmd.out.PutRope["Reading "]; cmd.out.PutRope[inputName]; cmd.out.PutRope[" . . . "]; refAction^[inputName, outputName, cmd, stream ! Complain => {result _ $Failure; msg _ complaint; GOTO Quit}; FS.Error => { IF error.group = user THEN {result _ $Failure; msg _ error.explanation; GOTO Quit} } ]; outputName _ FindFullName[outputName ! FS.Error => { outputName _ "Output file(s)"; CONTINUE}; ]; cmd.out.PutRope[outputName]; cmd.out.PutRope[" written.\n"]; EXITS Quit => NULL }; docIPToPD: ROPE ~ "Convert Interpress file to PD (output _ input printerType {{black | cyan | magenta | yellow} | (of (3 | 4)) | ( ppd) | ( in in translate) | ( (scale | scaleX | scaleY)) | ( skipPages) | ( nPages) | leftovers | noLeftovers | (fontTuning ) | ( (sResolution | fResolution | Resolution)) | ( (pageSSize | pageFSize)) | ( (bandSize | load | deviceCode)) | ( (gamma | threshold | removedFraction))})\n"; Commander.Register["PressToInterpress", Command, "Convert Press file to Interpress (output _ input [version])\n", NEW[ActionProc _ PressToInterpressAction]]; Commander.Register["AISToInterpress", Command, "Convert AIS file to Interpress (output _ input)\n", NEW[ActionProc _ AISToInterpressAction]]; Commander.Register["ColorAISToInterpress", Command, "Convert Color AIS file to Interpress (output _ input)\n", NEW[ActionProc _ AISToInterpressAction]]; Commander.Register["InterpressToPress", Command, "Convert Interpress file to Press (output _ input)\n", NEW[ActionProc _ InterpressToPressAction]]; Commander.Register["InterpressToJaM", Command, "Convert Interpress file to JaM (output _ input)\n", NEW[ActionProc _ InterpressToJaMAction]]; Commander.Register["InterpressToPD", Command, docIPToPD, NEW[ActionProc _ IPToPDAction]]; Commander.Register["IPToPD", Command, docIPToPD, NEW[ActionProc _ IPToPDAction]]; Commander.Register["ColorAISToInterpress", ColorAISToInterpressCommand, "Convert Color AIS files to Interpress (output _ inputRoot)\n"]; Commander.Register["InterpressToAIS", Command, "Convert Interpress file to AIS (outputRoot _ input) {Gray} {ppi: }\n", NEW[ActionProc _ InterpressToAISAction]]; END.