DIRECTORY
IODefs: FROM "iodefs",
StreamDefs: FROM "streamdefs",
StringDefs: FROM "stringdefs",
SystemDefs: FROM "systemdefs",
PressDefs: FROM "pressdefs";

Divider: PROGRAM IMPORTS IODefs, StreamDefs, StringDefs, SystemDefs, PressDefs =
BEGIN

Font:TYPE = POINTER TO FontBody;
FontBody:TYPE = RECORD[family:STRING, size:CARDINAL ← 0, face:CARDINAL ← 0,
rotation:CARDINAL ← 0, widths:Widths ← NIL];
Widths:TYPE = POINTER TO WidthBody;
WidthBody:TYPE = RECORD[micaX:ARRAY [0..256) OF INTEGER,
bBox:ARRAY [0..4) OF INTEGER];
JustificationMode: TYPE = {leftJustified, rightJustified, centered,
bottomJustified, topJustified};

labelFont, entryFont, titleFont, commentFont, quoteFont, screamerFont1, screamerFont2: Font ← NIL;
wStream:StreamDefs.StreamHandle; --Fonts.Widths stream
outFile:POINTER TO PressDefs.PressFileDescriptor;
outFileName:STRING = "
Divider.Press";
str:STRING ← [40];
row,column:CARDINAL;
char:CHARACTER;

leftEdge:CARDINAL←4000;
rightEdge:CARDINAL←19000;
bottomEdge:CARDINAL←3000;
topEdge:CARDINAL←15000;
gridWidth:CARDINAL←20;
labelMargin:CARDINAL←200;
titleMargin:CARDINAL←400;
title:STRING = "The common names of the seven bit character codes.";

numCols:CARDINAL=8;
numRows:CARDINAL=16;
colWidth:CARDINAL=(rightEdge-leftEdge)/numCols;
rowHeight:CARDINAL=(topEdge-bottomEdge)/numRows;

PutBox:
PROCEDURE[thick,wide,high,x,y:CARDINAL]=
BEGIN
PressDefs.PutRectangle[outFile,x-wide/2-thick/2,y-high/2-thick/2,wide+thick,thick];
PressDefs.PutRectangle[outFile,x-wide/2-thick/2,y-high/2-thick/2,thick,high+thick];
PressDefs.PutRectangle[outFile,x-wide/2-thick/2,y+high/2-thick/2,wide+thick,thick];
PressDefs.PutRectangle[outFile,x+wide/2-thick/2,y-high/2-thick/2,thick,high+thick];
END;

FindWidths:
PROCEDURE[f:Font]=
BEGIN
success:BOOLEAN;
IF f=NIL THEN ERROR AttemptToFindWidthsOfNIL;
f.widths ← SystemDefs.AllocateHeapNode[SIZE[WidthBody]];
success ← PressDefs.LookupFontName[wStream, f.family, f.face, f.size,
f.rotation, @f.widths.micaX, NIL, @f.widths.bBox];
IF ~success THEN ERROR FontNotInWidthDictionary;
END;
FontNotInWidthDictionary: SIGNAL = CODE;
AttemptToFindWidthsOfNIL: SIGNAL = CODE;

PutString:
PROCEDURE[s:STRING,f:Font,x,y:CARDINAL,m:JustificationMode]=
BEGIN
length:CARDINAL ← 0;
height, i:CARDINAL;
IF f.widths=NIL THEN ERROR FontHasNoWidthData;
FOR i IN [0..s.length) DO
length ← length+f.widths.micaX[s[i]-0C];
ENDLOOP;
height ← f.widths.bBox[3]*8/10;
SELECT m FROM
leftJustified => BEGIN y ← y-height/2 END;
rightJustified => BEGIN y ← y-height/2; x ← x-length END;
centered => BEGIN y ← y-height/2; x ← x-length/2 END;
topJustified => BEGIN y ← y-height; x ← x-length/2 END;
bottomJustified => BEGIN x ← x-length/2 END;
ENDCASE;
PressDefs.SetFont[outFile, f.family, f.size, f.face, f.rotation];
PressDefs.PutText[outFile, s, x, y];
END;
FontHasNoWidthData:SIGNAL = CODE;

InitFont: PROCEDURE[fam:STRING, size:CARDINAL, face,rot:CARDINAL ← 0]
RETURNS [Font] =
BEGIN
f:Font;
f ← SystemDefs.AllocateHeapNode[SIZE[FontBody]];
f↑ ← FontBody[fam,size,face,rot,NIL];
RETURN [f];
END;

PutChar: PROCEDURE[char:CHARACTER, font:Font,x,y:CARDINAL] = INLINE
BEGIN
string:STRING ← [1];
string.length ← 1;
string[0] ← char;
PutString[string,font,x,y,centered];
END;

PutStringChar: PROCEDURE[string1:STRING,font1:Font,char:CHARACTER,
font2:Font,x,y:CARDINAL] = INLINE
BEGIN
string2:STRING ← [1];
string2.length ← 1;
string2[0] ← char;
PutStringString[string1,font1,string2,font2,x,y];
END;

PutStringString: PROCEDURE[string1:STRING,font1:Font,string2:STRING,
font2:Font,x,y:CARDINAL] = INLINE
BEGIN
PutString[string1,font1,x,y+50,bottomJustified];
PutString[string2,font2,x,y,topJustified];
END;

IODefs.WriteLine["Starting:"];
wStream ← StreamDefs.NewWordStream["Fonts.Widths",
StreamDefs.Read];
outFile ← SystemDefs.AllocateHeapNode[SIZE[PressDefs.PressFileDescriptor]];
PressDefs.InitPressFileDescriptor[outFile,outFileName];
labelFont ← InitFont["TimesRoman",10];
entryFont ← InitFont["TimesRoman",12];
titleFont ← InitFont["TimesRoman",12];
commentFont ← InitFont["TimesRoman",10];
quoteFont ← InitFont["Gacha",12];
screamerFont1 ← InitFont["OldEnglish",48];
screamerFont2 ← InitFont["OldEnglish",36];

FindWidths[labelFont];
FindWidths[entryFont];
FindWidths[titleFont];
FindWidths[commentFont];
FindWidths[quoteFont];
FindWidths[screamerFont1];
FindWidths[screamerFont2];

BEGIN
i:CARDINAL;
FOR i IN [0..80]
DO
PutBox[30,200*i,200*i,11000,17000];
ENDLOOP;
END;

PutString["Character Code Output",screamerFont1,11000,5000,centered];
PressDefs.WritePage[outFile];

PressDefs.ClosePressFile[outFile];

IODefs.WriteLine[""];
IODefs.WriteLine["Done."]

END.