GetScreenSpaceWidth:
PUBLIC
PROC[style: NodeStyle.Ref]
RETURNS[
REAL] ~ {
font: ImagerFont.Font ← style.font;
IF font = NIL THEN font ← NodeStyleFont.FontFromStyleParams[prefix: style.name[fontPrefix], family: style.name[fontFamily], face: style.fontFace, size: NodeStyle.GetReal[style, fontSize], alphabets: style.fontAlphabets];
RETURN[ImagerFont.Width[font, [set: 0, code: 40B]].x];
};
GetPrintSpaceWidth:
PUBLIC
PROC[style: NodeStyle.Ref]
RETURNS[width:
REAL] ~ {
family: ROPE ~ Atom.GetPName[NodeStyle.GetFontFamily[style]];
face: NodeStyle.FontFace ~ NodeStyle.GetFontFace[style];
size: REAL ~ NodeStyle.GetFontSize[style];
fontName: ROPE ~ family.Concat[SELECT face FROM
Regular => "", Bold => "B", Italic => "I", BoldItalic => "BI", ENDCASE => ERROR];
tfmName: ROPE ~ Rope.Cat["///Fonts/FontMetrics/", fontName, ".tfm"];
stream: IO.STREAM ← NIL;
oops: BOOL ← FALSE;
binaryStreamOptions: FS.StreamOptions ~ [tiogaRead: FALSE, commitAndReopenTransOnFlush: TRUE, truncatePagesOnClose: TRUE, finishTransOnClose: TRUE, closeFSOpenFileOnClose: TRUE];
Protest:
PROC [why:
ROPE] = {
MessageWindow.Append[why, TRUE];
MessageWindow.Append[" (using 1/2 font size for space size)", FALSE];
MessageWindow.Blink[];
};
width ← size/2; -- default in case of disaster;
stream ←
FS.StreamOpen[fileName: tfmName, accessOptions: $read, streamOptions: binaryStreamOptions
!
FS.Error => {
Protest[error.explanation];
CONTINUE
}];
IF stream#
NIL
THEN
TRUSTED {
dir: Directory;
dirAddr: LONG POINTER ← @dir;
param: Param;
paramAddr: LONG POINTER ← @param;
[] ← stream.UnsafeGetBlock[
[base: dirAddr, startIndex: 0, count:
SIZE[Directory]*Basics.bytesPerWord]
! IO.Error => {oops ← TRUE; CONTINUE}
];
oops ← oops OR NOT ValidDirectory[dir];
IF
NOT oops
THEN stream.SetIndex[ParamStart[dir]*
SIZE[Word]*Basics.bytesPerWord
! IO.Error => {oops ← TRUE; CONTINUE}
];
IF
NOT oops
THEN [] ← stream.UnsafeGetBlock[
[base: paramAddr, startIndex: 0, count:
SIZE[Param]*Basics.bytesPerWord]
! IO.Error => {oops ← TRUE; CONTINUE}
];
IF oops
THEN Protest[Rope.Concat[tfmName, " is invalid"]]
ELSE {
unscaledSpaceWidth: REAL ← Long[param[spaceWidth]]/realTwoToTheTwentieth;
width ← unscaledSpaceWidth*size;
};
stream.Close[! IO.Error => CONTINUE];
};
};