<> <> <> DIRECTORY Atom, Commander, IO, FS, Rope, Imager, ImagerTypeface, ImagerFont, ImagerInterpressPreamble, ImagerFontPrivate, ImagerTransformation; <<>> MakeFISImpl: CEDAR PROGRAM IMPORTS Atom, Commander, IO, FS, Rope, Imager, ImagerFont, ImagerInterpressPreamble, ImagerTransformation EXPORTS ImagerFont ~ BEGIN ROPE: TYPE ~ Rope.ROPE; Font: TYPE ~ ImagerFont.Font; Context: TYPE ~ Imager.Context; XChar: TYPE ~ ImagerFont.XChar; nullXChar: XChar ~ ImagerFont.nullXChar; substituteXChar: XChar ~ [360B, 312B]; substituteIndex: CARDINAL ~ CARDINAL[substituteXChar.set]*256+substituteXChar.code; Typeface: TYPE ~ ImagerTypeface.Typeface; FontImpl: TYPE ~ ImagerFontPrivate.FontImpl; FontImplRep: PUBLIC TYPE ~ ImagerFontPrivate.FontImplRep; -- export to ImagerFont ActionProc: TYPE ~ PROC [inputName: ROPE, outputName: ROPE, cmd: Commander.Handle, cmds: IO.STREAM]; PushFontDescription: PROC [output: ImagerInterpressPreamble.Ref, font: Font, msg: IO.STREAM] ~ { impl: FontImpl ~ font.impl; typeface: Typeface ~ impl.typeface; Desc: ImagerInterpressPreamble.VectorProc ~ { substituteFound: BOOL _ FALSE; Masks: PROC ~ { FOR xc: XChar _ ImagerFont.NextChar[font, nullXChar], ImagerFont.NextChar[font, xc] UNTIL xc = nullXChar DO code: CARDINAL ~ CARDINAL[xc.set]*256+xc.code; action: PROC [context: Context] ~ { typeface.class.Mask[typeface, xc, context] }; <> IF xc = substituteXChar THEN substituteFound _ TRUE; IF msg#NIL THEN IO.PutF[msg, "(%b|%b) ", IO.int[xc.set], IO.int[xc.code]]; putInt[code]; putImageOp[action]; ENDLOOP; IF NOT substituteFound THEN { action: PROC [context: Context] ~ {Imager.MaskRectangle[context, [0.1, 0.0, 0.4, 0.6]]}; putInt[substituteIndex]; putImageOp[action]; }; }; Metrics: PROC ~ { IF msg#NIL THEN IO.PutRope[msg, "Metrics . . . "]; FOR xc: XChar _ ImagerFont.NextChar[font, nullXChar], ImagerFont.NextChar[font, xc] UNTIL xc = nullXChar DO code: CARDINAL ~ CARDINAL[xc.set]*256+xc.code; currentXC _ xc; putInt[code]; putVector[CharMetrics]; ENDLOOP; IF NOT substituteFound THEN { putInt[substituteIndex]; putVector[SubstituteMetrics]; }; }; currentXC: XChar _ nullXChar; CharMetrics: PROC ~ { esc: Imager.VEC ~ ImagerFont.Escapement[font, currentXC]; corr: ImagerFont.CorrectionType ~ ImagerFont.Correction[font, currentXC]; ext: ImagerFont.Extents ~ ImagerFont.BoundingBox[font, currentXC]; IF esc.x # 0.0 THEN { putIdentifier[$escapementX]; putReal[esc.x] }; IF esc.y # 0.0 THEN { putIdentifier[$escapementY]; putReal[esc.y] }; IF ImagerFont.Amplified[font, currentXC] THEN { putIdentifier[$amplified]; putInt[1] }; IF corr#mask THEN { putIdentifier[$correction]; putInt[ORD[corr]] }; putIdentifier[$leftExtent]; putReal[ext.leftExtent]; putIdentifier[$rightExtent]; putReal[ext.rightExtent]; putIdentifier[$ascent]; putReal[ext.ascent]; putIdentifier[$descent]; putReal[ext.descent]; }; SubstituteMetrics: PROC ~ { putIdentifier[$escapementX]; putReal[0.5]; putIdentifier[$leftExtent]; putReal[-0.1]; putIdentifier[$rightExtent]; putReal[0.4]; putIdentifier[$ascent]; putReal[0.6]; putIdentifier[$descent]; putReal[0]; }; putIdentifier[$transformation]; putTransformation[ImagerTransformation.Scale[1]]; putIdentifier[$characterMasks]; putVector[Masks]; putIdentifier[$characterMetrics]; putVector[Metrics]; putIdentifier[$substituteIndex]; putInt[substituteIndex]; }; IF font.charToClient.form#3 OR font.charToClient.a#1.0 THEN { Imager.Error[[$IllegalTransformation, "Scaled font not allowed in font description"]]; }; ImagerInterpressPreamble.DeclareIdentifier[output, $escapementX]; ImagerInterpressPreamble.DeclareIdentifier[output, $escapementY]; ImagerInterpressPreamble.DeclareIdentifier[output, $amplified]; ImagerInterpressPreamble.DeclareIdentifier[output, $correction]; ImagerInterpressPreamble.DeclareIdentifier[output, $leftExtent]; ImagerInterpressPreamble.DeclareIdentifier[output, $rightExtent]; ImagerInterpressPreamble.DeclareIdentifier[output, $ascent]; ImagerInterpressPreamble.DeclareIdentifier[output, $descent]; ImagerInterpressPreamble.PushVector[output, Desc]; }; MakeFISAction: PROC [inputName: ROPE, outputName: ROPE, cmd: Commander.Handle, cmds: IO.STREAM] ~ { font: Font ~ ImagerFont.Find[inputName]; output: ImagerInterpressPreamble.Ref ~ ImagerInterpressPreamble.Create[outputName]; PushFontDescription[output, font, cmd.out]; ImagerInterpressPreamble.Close[output]; }; MakeFontProofAction: PROC [inputName: ROPE, outputName: ROPE, cmd: Commander.Handle, cmds: IO.STREAM] ~ { font: Font ~ ImagerFont.Find[inputName]; captionFont: Font ~ ImagerFont.Find["Xerox/XC1-1-1/Modern"].Scale[0.04]; output: ImagerInterpressPreamble.Ref ~ ImagerInterpressPreamble.Create[outputName]; pageT: Imager.Transformation ~ ImagerTransformation.Scale[0.1].PreTranslate[[0.4,0.6]]; ImagerInterpressPreamble.DeclareIdentifier[output, $escapementX]; ImagerInterpressPreamble.DeclareIdentifier[output, $escapementY]; ImagerInterpressPreamble.DeclareIdentifier[output, $amplified]; ImagerInterpressPreamble.DeclareIdentifier[output, $correction]; ImagerInterpressPreamble.DeclareIdentifier[output, $leftExtent]; ImagerInterpressPreamble.DeclareIdentifier[output, $rightExtent]; ImagerInterpressPreamble.DeclareIdentifier[output, $ascent]; ImagerInterpressPreamble.DeclareIdentifier[output, $descent]; ImagerInterpressPreamble.DeclareFont[output, font]; FOR xc: XChar _ ImagerFont.NextChar[font, nullXChar], ImagerFont.NextChar[font, xc] UNTIL xc = nullXChar DO action: PROC [context: Context] ~ { Imager.ConcatT[context, pageT]; Imager.SetFont[context, captionFont]; Imager.SetXY[context, [0, -0.4]]; Imager.ShowRope[context, IO.PutFR["%g (%b|%b)", IO.rope[inputName], IO.int[xc.set], IO.int[xc.code]]]; IO.PutF[cmd.out, "(%b|%b) ", IO.int[xc.set], IO.int[xc.code]]; Imager.SetFont[context, font]; Imager.SetXY[context, [0, 0]]; Imager.ShowXChar[context, xc]; Imager.SetStrokeWidth[context, 0.02]; Imager.MaskVector[context, [-.08, 0], [.08, 0]]; Imager.MaskVector[context, [0, -.08], [0, .08]]; Imager.SetStrokeWidth[context, 0.005]; Imager.SetGray[context, 0]; Imager.MaskVector[context, [-0.075, 0], [0.075, 0]]; Imager.MaskVector[context, [0, -0.075], [0, 0.075]]; Imager.Move[context]; Imager.SetGray[context, 1]; Imager.SetStrokeWidth[context, 0.02]; Imager.MaskVector[context, [-0.05, 0], [0.05, 0]]; Imager.MaskVector[context, [0, -0.05], [0, 0.05]]; Imager.SetStrokeWidth[context, 0.005]; Imager.SetGray[context, 0]; Imager.MaskVector[context, [-0.045, 0], [0.045, 0]]; Imager.MaskVector[context, [0, -0.045], [0, 0.045]]; }; ImagerInterpressPreamble.DoPage[output, action]; ENDLOOP; ImagerInterpressPreamble.Close[output]; }; 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 = '_ 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; }; Complain: 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: " "]; RETURN [Rope.Cat[inputName, ".", 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 _ GetCmdToken[stream]; secondTokenIndex: INT _ IO.GetIndex[stream]; gets: ROPE _ GetCmdToken[stream]; 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]; IF outputName = NIL THEN { outputName _ MakeOutputName[inputName, cmd.procData.doc]; }; cmd.out.PutRope["Converting "]; cmd.out.PutRope[inputName]; cmd.out.PutRope[" . . . "]; refAction^[inputName, outputName, cmd, stream ! Complain => {result _ $Failure; msg _ complaint; GOTO Quit}; FS.Error => {result _ $Failure; msg _ error.explanation; GOTO Quit}; Imager.Error => {result _ $Failure; msg _ IO.PutFR["Imager.Error[[$%g, %g]]", IO.rope[Atom.GetPName[error.code]], IO.rope[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 }; Commander.Register["MakeFIS", Command, "Convert Imager font file to FIS (Font Interchange Standard) ( [ outputFileName _ ] inputFontName", NEW[ActionProc _ MakeFISAction]]; Commander.Register["MakeFontProof", Command, "Imager font to Interpress proof ( [ outputFileName _ ] inputFontName", NEW[ActionProc _ MakeFontProofAction]]; END.