IKFontFormat.mesa
Michael Plass, November 17, 1986 10:36:22 am PST
Copyright © 1986 by Xerox Corporation. All rights reserved.
Definitions for Ikarus IK spline font file format.
This is our best guess based on an annotated example.
DIRECTORY Basics;
IKFontFormat: CEDAR DEFINITIONS
~ BEGIN
BYTE: TYPE ~ Basics.BYTE;
Word: TYPE ~ MACHINE DEPENDENT RECORD [lo, hi: BYTE];
Little-endian 16-bit word.
SWord: TYPE ~ Word;
Little-endian 16-bit signed word.
bytesPerWord: NAT ~ 2;
Not necessarily the same as the machine word size!
Double: TYPE ~ MACHINE DEPENDENT RECORD [ll, lh, hl, hh: BYTE];
Little-endian 32-bit quantity.
CardFromWord: PROC [word: Word] RETURNS [CARDINAL] ~ INLINE {RETURN [word.hi*256+word.lo]};
IntFromWord: PROC [word: SWord] RETURNS [INTEGER] ~ INLINE {RETURN [LOOPHOLE[CardFromWord[word]]]};
CardFromDouble: PROC [d: Double] RETURNS [CARD] ~ INLINE {
ln: Basics.LongNumber ~ [bytes[ll: d.ll, lh: d.lh, hl: d.hl, hh: d.hh]];
RETURN [ln.lc]
};
Date: TYPE ~ MACHINE DEPENDENT RECORD [day, month, year: Word];
bytesPerPhysicalRecord: INT ~ 4096;
FilePosition: TYPE ~ MACHINE DEPENDENT RECORD [
physicalRecordNumber: Word, -- physical record number, numbered from 1
wordNumber: Word  -- word number in physical record, also numbered from 1
];
ByteOffsetFromFilePosition: PROC [f: FilePosition] RETURNS [INT] ~ INLINE {
RETURN [ (CardFromWord[f.physicalRecordNumber]-1)*bytesPerPhysicalRecord + CardFromWord[f.wordNumber]*bytesPerWord ]
};
DataLength: TYPE ~ MACHINE DEPENDENT RECORD [
physicalRecordCount: Word, -- number of whole physical records
wordCount: Word  -- remaining number of words
];
ByteCountFromDataLength: PROC [d: DataLength] RETURNS [INT] ~ INLINE {
RETURN [ CardFromWord[d.physicalRecordCount]*bytesPerPhysicalRecord + CardFromWord[d.wordCount]*bytesPerWord ]
};
Header: TYPE ~ MACHINE DEPENDENT RECORD [length: Word];
Followed by sections:
NameSection: TYPE ~ MACHINE DEPENDENT RECORD [
length: Word,   -- length of name section, in Words
filler: Word,
fileName: PACKED ARRAY [0..14) OF CHAR, -- The file name
fontName: PACKED ARRAY [0..78) OF CHAR, -- The font name
dataFormat: PACKED ARRAY [0..2) OF CHAR, -- should be ['I, 'K]
productionDate: Date,
lastEditDate: Date
];
FontInfoSection: TYPE ~ MACHINE DEPENDENT RECORD [
length: Word,   -- length of FontInfo section
indicator: Word,
numberOfCharacters: Word,
capHeight: Word,   -- (square) (in 1/100mm)
bodySize: Word,
xHeight: Word,
distanceFromBaselineToLowerBodyLine: Word,
textLineDistanceForSetting: Word,
stemThickness: Word,
italicAngle: Word,   -- in 0.01 degree units
optimumPointSize: Word,
averageCharacterWidth: Word
];
HierarchySection: TYPE ~ MACHINE DEPENDENT RECORD [
length: Word   -- length of HierarchySection
];
CharacterIndexSection: TYPE ~ MACHINE DEPENDENT RECORD [
length: Word,   -- length of CharacterIndex section
lengthOfFontInPhysicalRecords: Word, -- physical records are 4096 bytes long
lastWordOfLastRecord: Word
followed by CharacterIndexEntry items
];
CharacterIndexEntry: TYPE ~ MACHINE DEPENDENT RECORD [
characterCode: Word,   -- the character code
filePositionOfCharacterData: FilePosition
];
CharacterData: TYPE ~ MACHINE DEPENDENT RECORD [
dataLength: DataLength
Followed by char sections:
];
CharNameSection: TYPE ~ MACHINE DEPENDENT RECORD [
length: Word,
characterCode: Word,
numberOfFollowingPart: Word -- ?
];
CharSettingInfo: TYPE ~ MACHINE DEPENDENT RECORD [
length: Word,
characterTypeCode: Word,
numberOfDigitizations: Word,
totalSetWidth: Word,  -- T = L+W+R
leftSideBearing: Word,  -- L
width: Word,  -- W
rightSideBearing: Word,  -- R
xMin: Word,
xMax: Word,
yMin: Word,
yMax: Word,
unit: Word   -- 1 is 1/100mm
];
CharContourIndex: TYPE ~ MACHINE DEPENDENT RECORD [
dataLength: DataLength
Followed by CharContourIndexEntry items
];
CharContourIndexEntry: TYPE ~ MACHINE DEPENDENT RECORD [
filePositionOfContour: FilePosition, -- pointer to image information
directionOfTurn: SWord,  -- -1 means clockwise
nesting: Word,  -- 0 = outer, 1 = inner
colorInside: Word,  -- 0 = transparent
numberOfDigitizations: Word -- number of Digitization items
];
ImageInformation: TYPE ~ MACHINE DEPENDENT RECORD [
dataLength: DataLength
Followed by Digitization items
];
Digitization: TYPE ~ MACHINE DEPENDENT RECORD [xCode, yCode: SWord];
PointType: TYPE ~ {none, start, corner, curve, tangent};
Point: TYPE ~ RECORD [type: PointType, x, y: NAT];
PointFromDigitization: PROC [d: Digitization] RETURNS [Point] ~ INLINE {
xCode: INTEGER ~ IntFromWord[d.xCode];
yCode: INTEGER ~ IntFromWord[d.yCode];
SELECT TRUE FROM
(xCode < 0 AND yCode > 0) => RETURN [[start, -xCode-1, yCode-1]];
(xCode < 0 AND yCode < 0) => RETURN [[corner, -xCode-1, -yCode-1]];
(xCode > 0 AND yCode > 0) => RETURN [[curve, xCode-1, yCode-1]];
(xCode > 0 AND yCode < 0) => RETURN [[tangent, xCode-1, -yCode-1]];
ENDCASE => RETURN [[none, 0, 0]];
};
END.