<> <> <<>> 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: 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 _ 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.