NodeStyleSpacesImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Michael Plass, May 16, 1984 5:31:11 pm PDT
Doug Wyatt, March 2, 1985 5:36:36 pm PST
Rick Beach, March 17, 1985 2:29:16 pm PST
DIRECTORY
Basics USING [bytesPerWord, LongNumber],
DefaultRemoteNames USING [Get],
FS USING [Error, StreamOpen, StreamOptions],
IO USING [Close, Error, SetIndex, STREAM, UnsafeGetBlock],
MessageWindow USING [Append, Blink],
NameSymbolTable USING [RopeFromName],
NodeStyle USING [FontFace, GetFontFace, GetFontFamily, GetFontSize, GetFontSizeI, Ref],
Rope USING [Cat, Concat, ROPE],
VFonts USING [CharWidth, EstablishFont, Font];
NodeStyleSpacesImpl: CEDAR PROGRAM
IMPORTS DefaultRemoteNames, FS, IO, MessageWindow, NameSymbolTable, NodeStyle, Rope, VFonts
EXPORTS NodeStyle
=
BEGIN
ROPE: TYPE ~ Rope.ROPE;
Space width attributes (exported to NodeStyle)
GetScreenSpaceWidth:
PUBLIC
PROC[style: NodeStyle.Ref]
RETURNS[
REAL] = {
family: ROPE ~ NameSymbolTable.RopeFromName[NodeStyle.GetFontFamily[style]];
face: NodeStyle.FontFace ~ NodeStyle.GetFontFace[style];
size: CARDINAL ~ NodeStyle.GetFontSizeI[style];
font: VFonts.Font ~ VFonts.EstablishFont[family: family, size: size,
bold: face=Bold OR face=BoldItalic, italic: face=Italic OR face=BoldItalic];
RETURN[VFonts.CharWidth[40C, font]];
};
GetPrintSpaceWidth:
PUBLIC
PROC[style: NodeStyle.Ref]
RETURNS[width:
REAL] ~ {
family: ROPE ~ NameSymbolTable.RopeFromName[NodeStyle.GetFontFamily[style]];
face: NodeStyle.FontFace ~ NodeStyle.GetFontFace[style];
size: REAL ~ NodeStyle.GetFontSize[style];
hostName: ROPE ~ DefaultRemoteNames.Get[].systemHost; -- for example, "[Indigo]"
fontName:
ROPE ~ family.Concat[
SELECT face
FROM
Regular => "", Bold => "B", Italic => "I", BoldItalic => "BI", ENDCASE => ERROR];
tfmName: ROPE ~ hostName.Cat["<Tioga>TFM>", fontName, ".tfm"];
stream: IO.STREAM ← NIL;
oops: BOOLEAN ← FALSE;
binaryStreamOptions: FS.StreamOptions ~ [tiogaRead: FALSE, commitAndReopenTransOnFlush: TRUE, truncatePagesOnClose: TRUE, finishTransOnClose: TRUE, closeFSOpenFileOnClose: TRUE];
width ← size/2; -- default in case of disaster;
stream ← FS.StreamOpen[fileName: tfmName, accessOptions: $read, streamOptions: binaryStreamOptions ! FS.Error => {
MessageWindow.Append[error.explanation, TRUE];
MessageWindow.Append[" (using 1/2 font size for space size instead)", FALSE];
MessageWindow.Blink[];
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 {
MessageWindow.Append[tfmName, TRUE];
MessageWindow.Append[" not a valid TFM file (using 1/2 font size for space size instead)", FALSE];
MessageWindow.Blink[];
}
ELSE {
unscaledSpaceWidth: REAL ← Long[param[spaceWidth]]/realTwoToTheTwentieth;
width ← unscaledSpaceWidth*size;
};
stream.Close[! IO.Error => CONTINUE];
};
};
twoToTheTenth: INT = 2*2*2*2*2 * 2*2*2*2*2;
twoToTheTwentieth: INT = twoToTheTenth*twoToTheTenth;
realTwoToTheTwentieth: REAL = twoToTheTwentieth;
Copied from TFM defs
Word: TYPE = MACHINE DEPENDENT RECORD [hiHalf, lowHalf: CARDINAL]; -- note a Word is 32 bits long, and in BigEndian order.
Fixed: TYPE = MACHINE DEPENDENT RECORD [ValueTimesTwoToTheTwentieth: Word];
FixedArray:
TYPE =
MACHINE
DEPENDENT
RECORD [
entry(0): PACKED SEQUENCE COMPUTED CARDINAL OF Fixed];
Long:
PROCEDURE [w: Word]
RETURNS [
LONG
INTEGER] =
INLINE {
t: Basics.LongNumber ← [num[lowbits: w.lowHalf, highbits: w.hiHalf]];
RETURN[t.li]
};
Directory:
TYPE =
MACHINE
DEPENDENT
RECORD [
lf: CARDINAL, -- length of entire file in Words
lh: CARDINAL, -- length of header data
bc: CARDINAL, -- first character code in font
ec: CARDINAL, -- last character code in font
nw: CARDINAL, -- number of Words in width table
nh: CARDINAL, -- number of Words in height table
nd: CARDINAL, -- number of Words in depth table
ni: CARDINAL, -- number of Words in italic correction table
nl: CARDINAL, -- number of Words of lig/kern program
nk: CARDINAL, -- number of Words in kern table
ne: CARDINAL, -- number of Words in extensible character table
np: CARDINAL -- number of font parameters
ValidDirectory:
PROCEDURE [h: Directory]
RETURNS [
BOOLEAN] = {
OPEN h;
RETURN [lh<=24
-- Allow headers to grow a bit --
AND
ec>=bc AND ec<256 AND
nw <= 256 AND
nh <= 16 AND
nd <= 16 AND
ni <= 64 AND
nl <= 256 AND
nk <= 256 AND
ne <= 256 AND
np <= 24 AND
lf = 6 + lh + (ec-bc+1) + nw + nh + nd + ni + nl + nk + ne + np]
};
ParamStart:
PROCEDURE [h: Directory]
RETURNS [
CARDINAL] =
INLINE {
OPEN h;
RETURN [6 + lh + (ec-bc+1) + nw + nh + nd + ni + nl + nk + ne]
};
Param:
TYPE =
PACKED
ARRAY ParamIndex
OF Fixed;
ParamIndex:
TYPE =
MACHINE
DEPENDENT {
-- see MetaFont manual, pages 98-100
slant(0), -- index for amount of italic slant (do not scale)
spaceWidth(1),
spaceStretch(2),
spaceShrink(3),
xHeight(4),
quad(5),
x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,mathSyParamLen
};
END.