GFtoPressExternalsImpl.mesa
Pavel, September 18, 1985 4:05:02 pm PDT
DIRECTORY
FS,
GFtoPressVars1,
GFtoPressVars2,
GFtoPressVars3,
GFtoPressPrivate,
IO,
PascalBasic,
PascalWizardFiles,
Real USING [RoundLI],
Rope,
SirPress USING [ClosePipe, ClosePress, GetFontCode, NewPipe, NewPressHandle, OpenPipe, Pipe, PipeChar, PipePosition, PressHandle, PutRectangle, SetFontFromCode, WritePage,
in, mica, texpt];
GFtoPressExternalsImpl: PROGRAM
IMPORTS FS, GFtoPressVars1, GFtoPressVars2, PascalBasic, PascalWizardFiles, Real, Rope, SirPress
EXPORTS GFtoPressPrivate
=
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: BOOLEANFALSE;
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];
};
END.