-- File: BuildLaurelFont.mesa
-- last edited by Levin: November 19, 1980 9:59 AM
-- last edited by Brotz: January 22, 1981 11:09 AM
-- last edited by Barth: December 10, 1980 1:03 PM

DIRECTORY
Ascii,
ImageDefs,
SegmentDefs,
StreamDefs;

BuildLaurelFont: PROGRAM IMPORTS ImageDefs, SegmentDefs, StreamDefs =

BEGIN

OPEN SegmentDefs;

ALFont: TYPE = MACHINE DEPENDENT RECORD
[padding (0: 0 .. 31): LONG UNSPECIFIED,
charTable (2): ARRAY CHARACTER OF CARDINAL];
font: POINTER TO ALFont;

XWords: TYPE = MACHINE DEPENDENT RECORD
[widthOrExtension: [0 .. 77777B], -- either a width field or an extension
hasNoExtension: [0 .. 1], -- 1 means above field is a width
hd: [0..377B], -- scan lines to skip above
xh: [0..377B]]; -- height of bitmap
XwPtr: TYPE = POINTER TO XWords;

XHData0: TYPE = MACHINE DEPENDENT RECORD
[xw: XWords]; -- self-relative pointers point here

XHData1: TYPE = MACHINE DEPENDENT RECORD
[bitData: ARRAY [1 .. 1] OF WORD,
xw: XWords]; -- self-relative pointers point here

XHData4: TYPE = MACHINE DEPENDENT RECORD
[bitData: ARRAY [1 .. 4] OF WORD,
xw: XWords]; -- self-relative pointers point here

XHData7: TYPE = MACHINE DEPENDENT RECORD
[bitData: ARRAY [1 .. 7] OF WORD,
xw: XWords]; -- self-relative pointers point here

XHData8: TYPE = MACHINE DEPENDENT RECORD
[bitData: ARRAY [1 .. 8] OF WORD,
xw: XWords]; -- self-relative pointers point here

XHData9: TYPE = MACHINE DEPENDENT RECORD
[bitData: ARRAY [1 .. 9] OF WORD,
xw: XWords]; -- self-relative pointers point here

XHData10: TYPE = MACHINE DEPENDENT RECORD
[bitData: ARRAY [1 .. 10] OF WORD,
xw: XWords]; -- self-relative pointers point here

XHData11: TYPE = MACHINE DEPENDENT RECORD
[bitData: ARRAY [1 .. 11] OF WORD,
xw: XWords]; -- self-relative pointers point here

XHData12: TYPE = MACHINE DEPENDENT RECORD
[bitData: ARRAY [1 .. 12] OF WORD,
xw: XWords]; -- self-relative pointers point here

smudge: XHData9 ←
[bitData: ALL[74000B],
xw: XWords[widthOrExtension: 6, hasNoExtension: 1, hd: 1, xh: 9]];

leftSmudge: XHData9 ←
[bitData: [040000B, 060000B, 070000B, 074000B, 076000B,
074000B, 070000B, 060000B, 040000B],
xw: XWords[widthOrExtension: 7, hasNoExtension: 1, hd: 1, xh: 9]];

rightSmudge: XHData9 ←
[bitData: [002000B, 006000B, 016000B, 036000B, 076000B,
036000B, 016000B, 006000B, 002000B],
xw: XWords[widthOrExtension: 7, hasNoExtension: 1, hd: 1, xh: 9]];

cherry: XHData12 ←
[bitData: [000400B, 001200B, 001200B, 002100B, 002100B, 034070B,
076174B, 157336B, 157336B, 147316B, 076174B, 034070B],
xw: XWords[widthOrExtension: 16, hasNoExtension: 1, hd: 0, xh: 12]];

degree: XHData4 ←
[bitData: [060000B, 110000B, 110000B, 060000B],
xw: XWords[widthOrExtension: 5, hasNoExtension: 1, hd: 1, xh: 4]];

whistle: XHData11 ←
[bitData: [177770B, 120344B, 110162B, 047776B, 024002B,
017776B, 001336B, 001336B, 001316B, 000574B, 000370B],
xw: XWords[widthOrExtension: 16, hasNoExtension: 1, hd: 1, xh: 11]];

bell: XHData11 ←
[bitData: [007000B, 017400B, 037600B, 033600B, 033600B,
033600B, 030600B, 077700B, 077700B, 177740B, 016000B],
xw: XWords[widthOrExtension: 12, hasNoExtension: 1, hd: 0, xh: 11]];

visibleTab: XHData10 ←
[bitData: [140000B, 140000B, 140000B, 140000B, 174000B,
174000B, 140000B, 140000B, 140000B, 140000B],
xw: XWords[widthOrExtension: 6, hasNoExtension: 1, hd: 1, xh: 10]];

lambda: XHData8 ←
[bitData: [140000B, 020000B, 020000B, 020000B,
050000B, 050000B, 104000B, 106000B],
xw: XWords[widthOrExtension: 8, hasNoExtension: 1, hd: 1, xh: 8]];

visibleCR: XHData9 ←
[bitData: [014000B, 006000B, 003000B, 003000B,
003000B, 046000B, 074000B, 070000B, 074000B],
xw: XWords[widthOrExtension: 8, hasNoExtension: 1, hd: 2, xh: 9]];

minus: XHData1 ←
[bitData: [077400B],
xw: XWords[widthOrExtension: 9, hasNoExtension: 1, hd: 5, xh: 1]];

hyphen: XHData1 ←
[bitData: [074000B],
xw: XWords[widthOrExtension: 6, hasNoExtension: 1, hd: 5, xh: 1]];

plus: XHData7 ←
[bitData: [004000B, 004000B, 004000B, 077400B, 004000B, 004000B, 004000B],
xw: XWords[widthOrExtension: 9, hasNoExtension: 1, hd: 2, xh: 7]];

plusOrMinus: XHData7 ←
[bitData: [010000B, 010000B, 076000B, 010000B, 010000B, 000000B, 076000B],
xw: XWords[widthOrExtension: 7, hasNoExtension: 1, hd: 2, xh: 7]];

angstrom: XHData9 ←
[bitData: [014000B, 022000B, 014000B, 014000B,
022000B, 022000B, 077000B, 041000B, 163400B],
xw: XWords[widthOrExtension: 9, hasNoExtension: 1, hd: 0, xh: 9]];

omega: XHData8 ←
[bitData: [036000B, 041000B, 041000B, 041000B,
041000B, 022000B, 122400B, 163400B],
xw: XWords[widthOrExtension: 9, hasNoExtension: 1, hd: 1, xh: 8]];

bravoTrailer: XHData9 ←
[bitData: [177700B, 161700B, 164700B, 161700B,
164700B, 161700B, 177774B, 060600B, 060600B],
xw: XWords[widthOrExtension: 14, hasNoExtension: 1, hd: 1, xh: 9]];

mu: XHData8 ←
[bitData: [044000B, 044000B, 044000B, 044000B,
065000B, 052000B, 100000B, 100000B],
xw: XWords[widthOrExtension: 7, hasNoExtension: 1, hd: 4, xh: 8]];

illegalChar: XHData0 ←
[xw: XWords[widthOrExtension: 0, hasNoExtension: 1, hd: 0, xh: 0]];

space: XHData0 ←
[xw: XWords[widthOrExtension: 5, hasNoExtension: 1, hd: 0, xh: 0]];

figureSpace: XHData0 ←
[xw: XWords[widthOrExtension: 6, hasNoExtension: 1, hd: 0, xh: 0]];

tab: XHData0 ←
[xw: XWords[widthOrExtension: 56, hasNoExtension: 1, hd: 0, xh: 0]];

cr: XHData0 ←
[xw: XWords[widthOrExtension: 5, hasNoExtension: 1, hd: 0, xh: 0]];

visibleTabCode: CHARACTER = (Ascii.TAB - 0C) + 200C;
visibleCRCode: CHARACTER = (Ascii.CR - 0C) + 200C;
lastLegalChar: CHARACTER = visibleCRCode;
outputCharTable: ARRAY CHARACTER[0C .. lastLegalChar] OF CARDINAL;
inputCharTable: POINTER TO ARRAY CHARACTER OF CARDINAL;
xwPtr: XwPtr;
smudgeOffset, currentOffset: CARDINAL;
ch: CHARACTER;

input: FileHandle = NewFile["LaurelFont.al", Read, OldFileOnly];
inputSeg: FileSegmentHandle = NewFileSegment[input, 1, DefaultPages, Read];
outputStream: StreamDefs.DiskHandle =
StreamDefs.NewWordStream["LaurelFont.temp", ReadWriteAppend];

SwapIn[inputSeg];
font ← FileSegmentAddress[inputSeg];
inputCharTable ← @font.charTable;

-- Build output self-relative pointer table

outputCharTable[Ascii.NUL]
← smudgeOffset ← currentOffset ← lastLegalChar - 0C + 1
+ SIZE[XHData9] - SIZE[XWords];
outputCharTable[Ascii.ControlA]
← (currentOffset ← currentOffset + SIZE[XHData9]) - (Ascii.ControlA - 0C);
outputCharTable[Ascii.ControlB]
← (currentOffset ← currentOffset + SIZE[XHData9]) - (Ascii.ControlB - 0C);
outputCharTable[Ascii.ControlC]
← (currentOffset ← currentOffset + SIZE[XHData12]) - (Ascii.ControlC - 0C);
outputCharTable[Ascii.ControlD]
← (currentOffset ← currentOffset + SIZE[XHData4]) - (Ascii.ControlD - 0C);
outputCharTable[Ascii.ControlE]
← (currentOffset ← currentOffset + SIZE[XHData11]) - (Ascii.ControlE - 0C);
FOR ch IN (Ascii.ControlE .. Ascii.BEL) DO
outputCharTable[ch] ← smudgeOffset - (ch - 0C);
ENDLOOP;
outputCharTable[Ascii.BEL]
← (currentOffset ← currentOffset + SIZE[XHData11]) - (Ascii.BEL - 0C);
FOR ch IN (Ascii.BEL .. Ascii.TAB) DO
outputCharTable[ch] ← smudgeOffset - (ch - 0C);
ENDLOOP;
outputCharTable[Ascii.TAB]
← (currentOffset ← currentOffset + SIZE[XHData0]) - (Ascii.TAB - 0C);
FOR ch IN (Ascii.TAB .. Ascii.CR) DO
outputCharTable[ch] ← smudgeOffset - (ch - 0C);
ENDLOOP;
outputCharTable[Ascii.CR]
← (currentOffset ← currentOffset + SIZE[XHData0]) - (Ascii.CR - 0C);
FOR ch IN (Ascii.CR .. Ascii.ControlO) DO
outputCharTable[ch] ← smudgeOffset - (ch - 0C);
ENDLOOP;
outputCharTable[Ascii.ControlO]
← (currentOffset ← currentOffset + SIZE[XHData9]) - (Ascii.ControlO - 0C);
outputCharTable[Ascii.ControlP]
← (currentOffset ← currentOffset + SIZE[XHData7]) - (Ascii.ControlP - 0C);
FOR ch IN (Ascii.ControlP .. Ascii.ControlT) DO
outputCharTable[ch] ← smudgeOffset - (ch - 0C);
ENDLOOP;
outputCharTable[Ascii.ControlT]
← (currentOffset ← currentOffset + SIZE[XHData8]) - (Ascii.ControlT - 0C);
outputCharTable[Ascii.ControlU]
← (currentOffset ← currentOffset + SIZE[XHData8]) - (Ascii.ControlU - 0C);
outputCharTable[Ascii.ControlV]
← (currentOffset ← currentOffset + SIZE[XHData8]) - (Ascii.ControlV - 0C);
FOR ch IN (Ascii.ControlV .. Ascii.ControlX) DO
outputCharTable[ch] ← smudgeOffset - (ch - 0C);
ENDLOOP;
outputCharTable[Ascii.ControlX]
← (currentOffset ← currentOffset + SIZE[XHData1]) - (Ascii.ControlX - 0C);
outputCharTable[Ascii.ControlY]
← (currentOffset ← currentOffset + SIZE[XHData0]) - (Ascii.ControlY - 0C);
outputCharTable[Ascii.ControlZ]
← (currentOffset ← currentOffset + SIZE[XHData9]) - (Ascii.ControlZ - 0C);
FOR ch IN (Ascii.ControlZ .. Ascii.SP) DO
outputCharTable[ch] ← smudgeOffset - (ch - 0C);
ENDLOOP;
outputCharTable[Ascii.SP]
← (currentOffset ← currentOffset + SIZE[XHData0]) - (Ascii.SP - 0C);
FOR ch IN (Ascii.SP .. ’+) DO
outputCharTable[ch]
← (currentOffset ← currentOffset + SIZE[XWords]
+ LOOPHOLE[@inputCharTable[ch] + inputCharTable[ch], XwPtr].xh)
- (ch - 0C);
ENDLOOP;
outputCharTable[’+]
← (currentOffset ← currentOffset + SIZE[XHData7]) - (’+ - 0C);
FOR ch IN (’+ .. ’-) DO
outputCharTable[ch]
← (currentOffset ← currentOffset + SIZE[XWords]
+ LOOPHOLE[@inputCharTable[ch] + inputCharTable[ch], XwPtr].xh)
- (ch - 0C);
ENDLOOP;
outputCharTable[’-]
← (currentOffset ← currentOffset + SIZE[XHData1]) - (’- - 0C);
FOR ch IN (’- .. 140C) DO
outputCharTable[ch]
← (currentOffset ← currentOffset + SIZE[XWords]
+ LOOPHOLE[@inputCharTable[ch] + inputCharTable[ch], XwPtr].xh)
- (ch - 0C);
ENDLOOP;
outputCharTable[140C]
← outputCharTable[’’ -- single quote --] - (140C - ’’ -- single quote --);
FOR ch IN (140C .. Ascii.DEL) DO
outputCharTable[ch]
← (currentOffset ← currentOffset + SIZE[XWords]
+ LOOPHOLE[@inputCharTable[ch] + inputCharTable[ch], XwPtr].xh)
- (ch - 0C);
ENDLOOP;
FOR ch IN [Ascii.DEL .. visibleTabCode) DO
outputCharTable[ch] ← smudgeOffset - (ch - 0C);
ENDLOOP;
outputCharTable[visibleTabCode]
← (currentOffset ← currentOffset + SIZE[XHData10]) - (visibleTabCode - 0C);
FOR ch IN (visibleTabCode .. visibleCRCode) DO
outputCharTable[ch] ← smudgeOffset - (ch - 0C);
ENDLOOP;
outputCharTable[visibleCRCode]
← (currentOffset ← currentOffset + SIZE[XHData9]) - (visibleCRCode - 0C);

-- Write out the output char table.

[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @font.padding, words: 2];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @outputCharTable,
words: LENGTH[outputCharTable]];

-- Now write out each bitmap plus XWords in order.

[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @smudge, words: SIZE[XHData9]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @leftSmudge, words: SIZE[XHData9]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @rightSmudge, words: SIZE[XHData9]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @cherry, words: SIZE[XHData12]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @degree, words: SIZE[XHData4]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @whistle, words: SIZE[XHData11]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @bell, words: SIZE[XHData11]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @tab, words: SIZE[XHData0]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @cr, words: SIZE[XHData0]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @angstrom, words: SIZE[XHData9]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @plusOrMinus, words: SIZE[XHData7]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @lambda, words: SIZE[XHData8]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @mu, words: SIZE[XHData8]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @omega, words: SIZE[XHData8]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @minus, words: SIZE[XHData1]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @figureSpace, words: SIZE[XHData0]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @bravoTrailer, words: SIZE[XHData9]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @space, words: SIZE[XHData0]];
FOR ch IN (Ascii.SP .. ’+) DO
xwPtr ← LOOPHOLE[@inputCharTable[ch] + inputCharTable[ch]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: xwPtr - xwPtr.xh,
words: SIZE[XWords] + xwPtr.xh];
ENDLOOP;
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @plus, words: SIZE[XHData7]];
FOR ch IN (’+ .. ’-) DO
xwPtr ← LOOPHOLE[@inputCharTable[ch] + inputCharTable[ch]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: xwPtr - xwPtr.xh,
words: SIZE[XWords] + xwPtr.xh];
ENDLOOP;
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @hyphen, words: SIZE[XHData1]];
FOR ch IN (’- .. 140C) DO
xwPtr ← LOOPHOLE[@inputCharTable[ch] + inputCharTable[ch]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: xwPtr - xwPtr.xh,
words: SIZE[XWords] + xwPtr.xh];
ENDLOOP;
FOR ch IN (140C .. Ascii.DEL) DO
xwPtr ← LOOPHOLE[@inputCharTable[ch] + inputCharTable[ch]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: xwPtr - xwPtr.xh,
words: SIZE[XWords] + xwPtr.xh];
ENDLOOP;
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @visibleTab, words: SIZE[XHData10]];
[] ← StreamDefs.WriteBlock
[stream: outputStream, address: @visibleCR, words: SIZE[XHData9]];

-- Close output stream and we’re done.
outputStream.destroy[outputStream];


ImageDefs.StopMesa[];

END. -- of BuildLaurelFont --