DIRECTORY Basics; IKFontFormat: CEDAR DEFINITIONS ~ BEGIN BYTE: TYPE ~ Basics.BYTE; Word: TYPE ~ MACHINE DEPENDENT RECORD [lo, hi: BYTE]; SWord: TYPE ~ Word; bytesPerWord: NAT ~ 2; Double: TYPE ~ MACHINE DEPENDENT RECORD [ll, lh, hl, hh: BYTE]; 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]; 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 ]; CharacterIndexEntry: TYPE ~ MACHINE DEPENDENT RECORD [ characterCode: Word, -- the character code filePositionOfCharacterData: FilePosition ]; CharacterData: TYPE ~ MACHINE DEPENDENT RECORD [ dataLength: DataLength ]; 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 ]; 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 ]; 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. IKFontFormat.mesa Michael Plass, November 17, 1986 10:36:22 am PST Copyright c 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. Little-endian 16-bit word. Little-endian 16-bit signed word. Not necessarily the same as the machine word size! Little-endian 32-bit quantity. Followed by sections: followed by CharacterIndexEntry items Followed by char sections: Followed by CharContourIndexEntry items Followed by Digitization items ΚV˜™Icode™0Kšœ Οmœ1™Kšœ‘˜-Kšœ˜K˜—š  œžœžœžœžœ˜FKšžœh˜nKšœ˜K˜—š œžœžœž œžœ˜7K™K˜—š œ žœžœž œžœ˜.Kšœ‘#˜3Kšœ ˜ Kš œ žœžœ žœžœ‘˜8Kš œ žœžœ žœžœ‘˜8Kš œ žœžœžœžœ‘˜>Kšœ˜Kšœ˜Kšœ˜K˜—š œžœžœž œžœ˜2Kšœ‘˜-Kšœ˜Kšœ˜Kšœ‘˜+K˜K˜K˜*K˜!K˜Kšœ‘˜,K˜K˜Kšœ˜K˜—š œžœžœž œžœ˜3Kšœ‘˜,Kšœ˜K˜—š œžœžœž œžœ˜8Kšœ‘#˜3Kšœ%‘'˜LKšœ˜Kšœ%™%Kšœ˜K˜š œžœžœž œžœ˜6Kšœ‘˜,Kšœ)˜)Kšœ˜K˜——š œžœžœž œžœ˜0Kšœ˜Kšœ™Kšœ˜K˜š œžœžœž œžœ˜2K˜ Kšœ˜Kšœ‘˜ Kšœ˜K˜—š œžœžœž œžœ˜2K˜ K˜K˜Kšœ‘ ˜"Kšœ‘˜Kšœ‘˜Kšœ‘˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ‘˜Kšœ˜K˜—š œžœžœž œžœ˜3Kšœ˜Kšœ'™'Kšœ˜K˜š œžœžœž œžœ˜8Kšœ%‘˜DKšœ‘˜.Kšœ‘˜'Kšœ‘˜&Kšœ‘˜;Kšœ˜K˜———š œžœžœž œžœ˜3Kšœ˜Kšœ™Kšœ˜K˜š œžœžœž œžœ˜DK˜—šœ žœ)˜8K˜—šœžœžœžœ˜2K˜—š œžœžœ žœ˜HKšœžœ˜&Kšœžœ˜&šžœžœž˜Kšœ žœžœ˜AKšœ žœžœ ˜CKšœ žœžœ˜@Kšœ žœžœ ˜CKšžœžœ˜!—Kšœ˜———K˜Kšžœ˜—…—v