BEGIN
OPEN GFtoPressVars1, GFtoPressVars2, GFtoPressVars3, GFtoPressPrivate, PascalBasic, PascalWizardFiles;
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
ph: SirPress.PressHandle;
pipe: SirPress.Pipe ← SirPress.NewPipe[];
pipeOpen: BOOLEAN ← FALSE;
pipePosnLimit: INTEGER = 200;
pipePosnCount: INTEGER;
currentFont: InternalFontNumber;
currentWidthBase, currentCharBase: INT;
xCoord, yCoord: INTEGER;
coordStackSize: INTEGER = 3;
coordStack: ARRAY [1..coordStackSize] OF RECORD [x, y: INTEGER];
coordTop: [0..coordStackSize] ← 0;
pageHeightInMicas: INTEGER = 11 * SirPress.in / SirPress.mica;
xOffsetInMicas: INTEGER = SirPress.in / SirPress.mica;
yOffsetInMicas: INTEGER = - SirPress.in / SirPress.mica;
SPtoMicas:
PROC[sp:
INT]
RETURNS [micas:
INTEGER] =
INLINE {
micas ← LOOPHOLE[Basics.HighHalf[(sp / 100) * SirPress.texpt / 100], INTEGER];
micas ← Real.RoundLI[sp / (65536.0 * 10000 / SirPress.texpt)];
};
XSPtoPress:
PROC[xInSP:
INT]
RETURNS [pressXInMicas:
INTEGER] =
INLINE {
pressXInMicas ← SPtoMicas[xInSP] + xOffsetInMicas;
};
YSPtoPress:
PROC[yInSP:
INT]
RETURNS [pressYInMicas:
INTEGER] =
INLINE {
pressYInMicas ← pageHeightInMicas - SPtoMicas[yInSP] + yOffsetInMicas;
};
PressOpenFile:
PUBLIC PROCEDURE = {
ph ← SirPress.NewPressHandle[RopeFromNameOfFile[]];
xCoord ← XSPtoPress[0];
yCoord ← YSPtoPress[0];
};
PressGetFontCode:
PUBLIC
PROCEDURE[F: InternalFontNumber]
RETURNS[PressGetFontCodeResult: CedarNat] = {
FlushPipe[];
RETURN[
ph.GetFontCode[
family: RopeFromStringNumber[FontFamily^[F]],
size: SPtoMicas[FontSize^[F]],
face: FontFace^[F],
unit: SirPress.mica
]
];
};
FlushPipe:
PROCEDURE = {
IF pipeOpen
THEN {
ph.ClosePipe[pipe: pipe, y: yCoord];
pipeOpen ← FALSE;
};
};
StartPiping:
PROCEDURE = {
ph.OpenPipe[pipe];
pipeOpen ← TRUE;
pipe.PipePosition[xCoord];
pipePosnCount ← 1;
};
PressSetFont:
PUBLIC PROCEDURE[F: InternalFontNumber] = {
FlushPipe[];
currentFont ← F;
currentWidthBase ← WidthBase^[F];
currentCharBase ← CharBase^[F];
ph.SetFontFromCode[FontPressCode^[F]];
};
CharWidth:
PROCEDURE [Ch: EightBits]
RETURNS [widthInMicas:
INTEGER] =
INLINE {
widthInSP: INT ←
FontInfo^[currentWidthBase + FontInfo^[currentCharBase + Ch].Qqqq.B0].Sc;
widthInMicas ← SPtoMicas[widthInSP];
};
PressSetChar:
PUBLIC PROCEDURE[Ch: EightBits] = {
IF
NOT pipeOpen
THEN
StartPiping[];
pipe.PipeChar[LOOPHOLE[Ch]];
xCoord ← xCoord + CharWidth[Ch];
};
PressPushPos:
PUBLIC PROCEDURE = {
IF coordTop = coordStackSize
THEN
ERROR;
FlushPipe[];
coordTop ← coordTop + 1;
coordStack[coordTop] ← [x: xCoord, y: yCoord];
};
PressPopPos:
PUBLIC PROCEDURE = {
IF coordTop = 0
THEN
ERROR;
FlushPipe[];
[x: xCoord, y: yCoord] ← coordStack[coordTop];
coordTop ← coordTop - 1;
};
PressGoto:
PUBLIC PROCEDURE[X,Y: Scaled] = {
FlushPipe[];
xCoord ← XSPtoPress[X];
yCoord ← YSPtoPress[Y];
};
PressMoveX:
PUBLIC PROCEDURE[X: Scaled] = {
xCoord ← xCoord + SPtoMicas[X];
IF pipeOpen
THEN {
IF pipePosnCount = pipePosnLimit
THEN {
ph.ClosePipe[pipe: pipe, y: yCoord];
StartPiping[];
}
ELSE {
pipePosnCount ← pipePosnCount + 1;
pipe.PipePosition[xCoord];
};
};
};
PressMoveY:
PUBLIC PROCEDURE[Y: Scaled] = {
FlushPipe[];
yCoord ← yCoord - SPtoMicas[Y];
};
PressSetRule:
PUBLIC PROCEDURE[H, W: Scaled] = {
FlushPipe[];
ph.PutRectangle[
xstart: xCoord,
ystart: yCoord,
xlen: SPtoMicas[W],
ylen: SPtoMicas[H],
unit: SirPress.mica];
};
PressWritePage:
PUBLIC PROCEDURE = {
FlushPipe[];
ph.WritePage[];
xCoord ← XSPtoPress[0];
yCoord ← YSPtoPress[0];
};
PressCloseFile:
PUBLIC PROCEDURE = {
FlushPipe[];
ph.ClosePress[];
};
TtyReset:
PUBLIC PROCEDURE[F:
LONG
POINTER
TO TextFile] = {
PascalOpenTextFileTTYInput[F];
};
TtyRewrite:
PUBLIC PROCEDURE[F:
LONG
POINTER
TO TextFile] = {
PascalOpenTextFileTTYOutput[F];
};
ByteFileReset:
PUBLIC PROCEDURE[F:
LONG
POINTER
TO ByteFile] = {
inStream: IO.STREAM;
so: FS.StreamOptions ← FS.defaultStreamOptions;
so[tiogaRead] ← FALSE;
inStream ← FS.StreamOpen[
fileName: RopeFromNameOfFile[],
streamOptions: so
];
PascalOpenFileWithStream[@(F^.baseFile), inStream];
PascalRESET[file: @(F^.baseFile), length: 1, element: @(F^.element)];
};
GetCommandLine:
PUBLIC PROCEDURE = {
Copy: Rope.ActionType =
TRUSTED {
[c: CHAR] RETURNS [quit: BOOL ← FALSE]
Buffer[LineLength] ← Xord[c];
LineLength ← LineLength + 1;
};
LineLength ← 0;
[] ← Rope.Map[base: PascalBasic.commandLineTail, len: TerminalLineLength, action: Copy];
};
RopeFromNameOfFile:
PROCEDURE
RETURNS [rope:
ROPE] = {
i: NAT ← 0;
length: NAT ← 0;
Chars:
SAFE
PROCEDURE
RETURNS [
CHAR] =
TRUSTED {
i ← i+1;
RETURN[NameOfFile[i]];
};
WHILE length < FileNameSize
AND NameOfFile[length + 1] # '
DO
length ← length + 1;
ENDLOOP;
rope ← Rope.FromProc[length, Chars];
IF i # length
THEN
ERROR;
};
RopeFromStringNumber:
PROCEDURE [s: StrNumber]
RETURNS [rope:
ROPE] = {
i: PoolPointer ← StrStart^[s];
length: NAT ← StrStart^[s+1]-i;
Chars:
SAFE
PROCEDURE
RETURNS [c:
CHAR] =
TRUSTED {
c ← Xchr[StrPool[i]];
i ← i+1;
};
rope ← Rope.FromProc[length, Chars];
};