MakeFISImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Michael Plass, April 8, 1986 1:25:58 pm PST
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: BOOLFALSE;
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] };
Note: we use the typeface mask proc directly to avoid the extraneous ScaleT and DoSaveAll
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: ROPENIL;
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.STREAMIO.RIS[cmd.commandLine];
outputName: ROPE ← GetCmdToken[stream];
secondTokenIndex: INTIO.GetIndex[stream];
gets: ROPE ← GetCmdToken[stream];
inputName: ROPENIL;
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.