DIRECTORY Commander, Convert, FS, Imager, ImagerFont, ImagerTransformation, IO, PressReader, Rope, Real, PressPrinter, RefText, ShowPress, Vector2; PressRescueImpl: CEDAR PROGRAM IMPORTS Commander, Convert, FS, ImagerFont, ImagerTransformation, IO, PressReader, Rope, Real, PressPrinter, RefText ~ BEGIN ROPE: TYPE ~ Rope.ROPE; bytesPerPage: NAT ~ 512; -- as per press file format. micasPerPoint: REAL = 2540.0/72.0; pointsPerMica: REAL = 72.0/2540.0; FontTable: TYPE ~ ARRAY [0..256) OF ShowPress.FontRec; RescuePressPage: PROC [stream: IO.STREAM, pressFile: PressReader.Handle, pageNumber: INT, fontTable: REF FontTable] RETURNS [ok: BOOLEAN _ TRUE] = { PageProc: PressReader.PageProc = { EntityProc: PressReader.EntityProc = { -- Xe, Ye, fontSet xe: INT _ entityTrailer.Xe; ye: INT _ entityTrailer.Ye; x: INT _ xe; y: INT _ ye; lastShowX, lastShowY: INT _ -1; currentFont: ShowPress.FontRec; -- will be established by setFont currentSpaceX, currentSpaceY: INT; -- will be established by setFont hue: REAL _ 0.0; saturation: REAL _ 1.0; brightness: REAL _ 0.0; skipAlternative, inAlternative: BOOL _ FALSE; reposition: BOOLEAN _ FALSE; showCharactersProc: PressReader.ShowCharactersProc = { xw, yw: INT _ 0; IF skipAlternative THEN RETURN; IF lastShowY # y THEN { stream.PutChar['\n]; lastShowX _ 2540; }; IF ABS[x - lastShowX] < 50 THEN NULL ELSE FOR i: INT _ x - lastShowX, i - 175 UNTIL i <= 0 DO stream.PutChar[' ] ENDLOOP; FOR i: INT IN [0..text.Length[]) DO c: CHAR _ text.Fetch[i]; IF c = ' THEN { xw _ xw+currentSpaceX; yw _ yw+currentSpaceY; } ELSE IF currentFont.imagerFont # NIL THEN { widthVec: ImagerFont.VEC ~ ImagerFont.Width[currentFont.imagerFont, [0, ORD[c]]]; xw _ xw+Real.RoundLI[widthVec.x]; yw _ yw+Real.RoundLI[widthVec.y]; } ENDLOOP; stream.PutRope[text]; x _ x + xw; y _ y + yw; lastShowX _ x; lastShowY _ y; }; -- showCharactersProc fontProc: PressReader.FontProc = { IF skipAlternative THEN RETURN; currentFont _ fontTable[entityTrailer.fontSet*16+font]; }; positionProc: PressReader.PositionProc = { IF skipAlternative THEN RETURN; IF opCode = setX THEN x _ xe + value ELSE y _ ye + value; reposition _ TRUE; }; spacingProc: PressReader.SpacingProc = { IF skipAlternative THEN RETURN; SELECT opCode FROM setSpaceX, setSpaceXShort => currentSpaceX _ value; setSpaceY, setSpaceYShort => currentSpaceY _ value; resetSpace => { currentSpaceX _ 200; currentSpaceY _ 0; }; ENDCASE => ERROR; IF opCode = resetSpace THEN NULL ELSE NULL; }; spaceProc: PressReader.SpaceProc = { showCharactersProc[showCharacterImmediate, 1, " "]; }; colorProc: PressReader.ColorProc = { IF skipAlternative THEN RETURN; SELECT opCode FROM setHue => NULL; setSaturation => NULL; setBrightness => NULL; ENDCASE => ERROR; }; showRectangleProc: PressReader.ShowRectangleProc = { IF skipAlternative THEN RETURN; NULL; }; alternativeProc: PressReader.AlternativeProc = { IF (types = 0) AND (elBytes = 0) AND (dlBytes = 0) THEN inAlternative _ skipAlternative _ FALSE ELSE IF inAlternative THEN skipAlternative _ TRUE ELSE inAlternative _ TRUE; }; showObjectProc: PressReader.ShowObjectProc = { NULL; }; -- showObjectProc showDotsProc: PressReader.ShowDotsProc = { NULL; }; -- showDotsProc fontProc[0]; pressFile.GetCommands[ showCharactersProc: showCharactersProc, fontProc: fontProc, positionProc: positionProc, spacingProc: spacingProc, spaceProc: spaceProc, colorProc: colorProc, showRectangleProc: showRectangleProc, alternativeProc: alternativeProc, showObjectProc: showObjectProc, showDotsProc: showDotsProc ]; }; -- EntityProc pressFile.GetPage[EntityProc]; stream.PutRope["\n\n------------------------------------------------------------------------"]; }; -- PageProc SkipFonts: PressReader.FontDirectoryProc = { ok _ FALSE; }; pressFile.GetParts[pageNumber, PageProc, SkipFonts]; }; Rescue: PROC [outputName, inputName1: ROPE] ~ { pressFile1: PressReader.Handle _ PressReader.OpenPressFile[inputName1]; documentDirectory1: PressReader.DocumentDirectory _ pressFile1.GetDocumentDirectory; pageNumber1: INT _ 1; fontTable: REF FontTable _ NEW[ARRAY [0..256) OF ShowPress.FontRec]; FontInitProc1: PressReader.FontEntryProc = { -- build a list of needed fonts sizeInMicas: REAL ~ ( IF fontDirectoryEntry.size > 0 THEN ((REAL[fontDirectoryEntry.size]*2540.0)/72.0) ELSE (REAL[-fontDirectoryEntry.size]) ); name: ROPE ~ NameFromPressFontID[fontDirectoryEntry.family, fontDirectoryEntry.face]; imagerFont: ImagerFont.Font _ ImagerFont.Scale[ImagerFont.Find[name], sizeInMicas]; IF fontDirectoryEntry.rotation#0 THEN { degrees: REAL _ fontDirectoryEntry.rotation/60.0; imagerFont _ ImagerFont.Modify[imagerFont, ImagerTransformation.Rotate[degrees]]; }; fontTable[fontDirectoryEntry.fontSet*16 + fontDirectoryEntry.font] _ [ imagerFont: imagerFont, family: fontDirectoryEntry.family, face: fontDirectoryEntry.face.encoding, size: sizeInMicas, rotation: REAL[fontDirectoryEntry.rotation]/60.0 ]; }; -- FontInitProc stream: IO.STREAM _ FS.StreamOpen[outputName, $create]; pressFile1.GetFonts[FontInitProc1]; WHILE RescuePressPage[stream, pressFile1, pageNumber1, fontTable] DO pageNumber1 _ pageNumber1 + 1; ENDLOOP; pressFile1.ClosePressFile[]; stream.Close; }; NameFromPressFontID: PROC [family: ROPE, face: PressReader.FontFace] RETURNS [name: ROPE] ~ { t: REF TEXT _ RefText.ObtainScratch[100]; t _ RefText.AppendRope[t, "Xerox/Pressfonts/"]; t _ RefText.AppendRope[t, family]; IF face.texDesignSize > 0 THEN { t _ Convert.AppendInt[t, Real.Round[face.texDesignSize]]; } ELSE { t _ RefText.AppendChar[t, '-]; t _ RefText.AppendChar[t, SELECT face.weight FROM medium => 'M, bold => 'B, light => 'L, ENDCASE => 'M ]; t _ RefText.AppendChar[t, SELECT face.slope FROM regular => 'R, italic => 'I, ENDCASE => 'R ]; t _ RefText.AppendChar[t, SELECT face.expansion FROM regular => 'R, condensed => 'C, expanded => 'E, ENDCASE => 'R ]; }; name _ Rope.FromRefText[t]; RefText.ReleaseScratch[t]; }; Break: PROC [char: CHAR] RETURNS [IO.CharClass] = { IF char = '_ THEN RETURN [break]; IF char = ' OR char = ' OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr]; RETURN [other]; }; FindFullName: PROC [inputName: ROPE] RETURNS [ROPE] ~ { fullFName: ROPE _ NIL; fullFName _ FS.FileInfo[inputName ! FS.Error => CONTINUE].fullFName; IF fullFName = NIL OR NOT PressPrinter.IsAPressFile[fullFName] THEN { IF inputName.Find[".press", 0, FALSE] = -1 THEN { inputName _ inputName.Concat[".press"]; }; fullFName _ FS.FileInfo[inputName].fullFName; }; RETURN [fullFName] }; PressRescueCommand: Commander.CommandProc ~ { stream: IO.STREAM _ IO.RIS[cmd.commandLine]; GetToken: PROC RETURNS [rope: ROPE] = { rope _ NIL; rope _ stream.GetTokenRope[Break ! IO.EndOfStream => CONTINUE].token; }; outputName: ROPE _ GetToken[]; gets: ROPE _ GetToken[]; inputName1: ROPE _ GetToken[]; IF NOT gets.Equal["_"] OR inputName1 = NIL THEN {cmd.out.PutRope["Specify output _ input, please"]; RETURN}; inputName1 _ FindFullName[inputName1 ! FS.Error => { IF error.group = user THEN {cmd.out.PutRope[error.explanation]; cmd.out.PutChar['\n]; GOTO Quit} ELSE REJECT }]; Rescue[outputName, inputName1]; cmd.out.PutRope[outputName]; cmd.out.PutRope[" written.\n"]; IF GetToken[].Length # 0 THEN {cmd.out.PutRope["Ignored: "]; cmd.out.PutRope[cmd.commandLine.Substr[stream.GetIndex]]; cmd.out.PutChar['\n]}; EXITS Quit => NULL }; Commander.Register["PressRescue", PressRescueCommand, "Rescue the text portions of a press file (output _ inputRescue)"]; END. °PressRescueImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Michael Plass, April 25, 1984 12:15:33 pm PST Rick Beach, July 31, 1985 2:27:09 pm PDT ΚŽ˜code– "cedar" stylešœ™K– "cedar" stylešœ Οmœ1™