DIRECTORY Buttons, Carets, CaretsImpl, ChoiceButtons, CGAIS, Commander, Containers, Convert, FileIO, Graphics, GraphicsOps, IO, Labels, LFUtil, Menus, PieViewers, PressScreen, Process, Real, Rope, Rules, SirPress, TSViewerImpl, UserTerminal, ViewerClasses, ViewerLocks, ViewerOps, ViewerSpecs, ViewerTools; PressScreenImpl: CEDAR MONITOR IMPORTS Buttons, Carets, CaretsImpl, ChoiceButtons, Commander, Containers, Convert, FileIO, Graphics, GraphicsOps, IO, Labels, LFUtil, Menus, PieViewers, Process, Real, Rope, Rules, SirPress, UserTerminal, ViewerSpecs, ViewerLocks, ViewerOps, ViewerTools EXPORTS PressScreen SHARES CaretsImpl, TSViewerImpl, ViewerLocks = { OPEN PressScreen; ROPE: TYPE = Rope.ROPE; extraWords: NAT _ 6; -- Half-screen prints are widened by this much. PressScreen: PUBLIC PROC[pressFileName: Rope.ROPE, which: Side] = TRUSTED { screen: SirPress.PressHandle_ SirPress.Create[ fileNameForHeaderPage: pressFileName, outputStream: FileIO.Open[pressFileName, overwrite] ]; screenBitMap: GraphicsOps.BitmapRef_ GraphicsOps.ScreenBitmap[]; widthInWords: INT _ screenBitMap.width/16; halfWidthInWords: NAT _ widthInWords/2; screenPtr: LONG POINTER _ UserTerminal.GetBitBltTable[].dst.word; IF which=bothSides THEN { screen.SetPageSize[height: 85, width: 110, unit: SirPress.in/10]; screen.BeginScannedRectangle[ x: 1, y: 1, numberOfLines: screenBitMap.height, dotsPerLine: widthInWords*16, height: 8*4, unit: SirPress.in/4] } ELSE screen.BeginScannedRectangle[ x: 1, y: 1, numberOfLines: screenBitMap.height, dotsPerLine: (halfWidthInWords+extraWords)*16, unit: SirPress.in/4]; FOR i: INT IN [0..screenBitMap.height) DO offset: LONG CARDINAL _ i*widthInWords; IF which=rightSide THEN offset _ offset + halfWidthInWords - extraWords; screen.UnsafeShowLine[screenPtr + offset]; ENDLOOP; screen.EndScannedRectangle[]; screen.ClosePress[]; }; fileNameTemplate: ROPE _ "Screen#.press"; count: INT _ 0; NewPressName: PUBLIC ENTRY PROCEDURE RETURNS [pressFileName: Rope.ROPE] = { ENABLE UNWIND => NULL; i: INT = Rope.Find[s1: fileNameTemplate, s2: "#"]; pressFileName _ IF i = -1 THEN fileNameTemplate ELSE fileNameTemplate.Replace[start: i, len: 1, with: Convert.ValueToRope[[signed[(count _ count + 1)]]]]; }; MagnificationFactorTooLarge: PUBLIC SIGNAL = CODE; AISPageAlignmentHackFailed: PUBLIC SIGNAL = CODE; AISPressScreen: PUBLIC PROCEDURE [pressFileName: ROPE, sourceHeight: NAT _ ViewerSpecs.screenH, sourceWidth: NAT _ ViewerSpecs.screenW, sourceBottom: NAT _ 0, sourceLeft: NAT _ 0, magnification: REAL _ 0.5, scaleToFit: MagnificationType _ useMagnification, leftMarginInches, rightMarginInches: REAL _ 0.75, landscape: BOOLEAN _ FALSE, borderWidth: REAL _ 2.0, lockViewers: BOOLEAN _ TRUE, displayCursor: BOOLEAN _ FALSE, displayCarets: BOOLEAN _ FALSE] RETURNS [fileName: ROPE] = TRUSTED { trueName: Rope.ROPE _ IF pressFileName = NIL THEN NewAISPressName[] ELSE pressFileName; context: Graphics.Context _ Graphics.NewContext[]; outputStream: IO.STREAM _ FileIO.Open[trueName, overwrite]; bytesSoFar: INT; screen: SirPress.PressHandle; screenBitMap: GraphicsOps.BitmapRef _ GraphicsOps.ScreenBitmap[]; screenWidthInWords: NAT _ screenBitMap.width/16; sourceLeftInWords: NAT _ MIN[sourceLeft/16, screenWidthInWords]; sourceRightInWords: NAT _ MIN[(sourceLeft+sourceWidth+15)/16, screenWidthInWords]; paperHeight: REAL _ IF landscape THEN 8.5*2540 ELSE 11*2540; paperWidth: REAL _ (11+8.5)*2540 - paperHeight; pageBorder: REAL _ (leftMarginInches + rightMarginInches)*2540; x: REAL; y: REAL; screenPtr: LONG POINTER _ UserTerminal.GetBitBltTable[].dst.word; bytesPerPage: INT = 512; wordsOfPressCommands: INT = 8; -- count of Press commands generated before dots so that the AIS image starts on a page boundary AISHeader: TYPE = RECORD [ header: CGAIS.Header, rasterPart: CGAIS.RasterPart, uca: CGAIS.UCA]; aisHeader: AISHeader _ [ header: [ password: CGAIS.password, attributeLength: 0], rasterPart: [ aph: [ type: raster, length: SIZE[CGAIS.RasterPart]], scanCount: 0, scanLength: 0, scanDirection: 3, samplesPerPixel: 1, codingType: CGAIS.UCACodingType], uca: [ bitsPerSample: 0, wordsPerScanLine: 0, scanLinesPerBlock: 177777B]]; aisBlock: IO.UnsafeBlock _ [ base: @aisHeader, startIndex: 0, stopIndexPlusOne: 2*SIZE[AISHeader]]; SELECT scaleToFit FROM fullPage => { magnification _ MIN[ (paperWidth-pageBorder)/(32.0*16.0*(sourceRightInWords-sourceLeftInWords)), (paperHeight-pageBorder)/(32.0*sourceHeight)]; }; halfPage => { magnification _ MIN[ (paperWidth-pageBorder)/(32.0*16.0*(sourceRightInWords-sourceLeftInWords)), (paperHeight-2*pageBorder)/(2.0*32.0*sourceHeight)]; }; useMagnification => NULL; ENDCASE; x _ (paperWidth-32.0*16.0*(sourceRightInWords-sourceLeftInWords)*magnification)/2.0; y _ (paperHeight-32.0*sourceHeight*magnification)/2.0; IF x<0 OR y<0 OR x+32.0*16.0*(sourceRightInWords-sourceLeftInWords)*magnification>paperWidth OR y+32.0*sourceHeight*magnification>paperHeight THEN SIGNAL MagnificationFactorTooLarge; context.DrawBox[[sourceLeft, sourceBottom, sourceLeft+borderWidth, sourceBottom+sourceHeight]]; context.DrawBox[[sourceLeft+sourceWidth-borderWidth, sourceBottom, sourceLeft+sourceWidth, sourceBottom+sourceHeight]]; context.DrawBox[[sourceLeft, sourceBottom, sourceLeft+sourceWidth, sourceBottom+borderWidth]]; context.DrawBox[[sourceLeft, sourceBottom+sourceHeight-borderWidth, sourceLeft+sourceWidth, sourceBottom+sourceHeight]]; context.SetColor[Graphics.white]; context.DrawBox[[sourceLeft-16, sourceBottom, sourceLeft, sourceBottom+sourceHeight]]; context.DrawBox[[sourceLeft+sourceWidth, sourceBottom, sourceLeft+sourceWidth+16, sourceBottom+sourceHeight]]; aisHeader.uca.wordsPerScanLine _ sourceRightInWords-sourceLeftInWords; aisHeader.rasterPart.scanLength _ aisHeader.uca.wordsPerScanLine*16; aisHeader.rasterPart.scanCount _ sourceHeight; IO.UnsafePutBlock[outputStream, aisBlock]; THROUGH [0..bytesPerPage - 2*(SIZE[AISHeader]+wordsOfPressCommands)) DO IO.PutChar[outputStream, '$]; ENDLOOP; screen _ SirPress.Create[ fileNameForHeaderPage: trueName, outputStream: outputStream ]; IF landscape THEN screen.SetPageSize[height: 85, width: 110, unit: SirPress.in/10]; screen.BeginScannedRectangle[ x: Real.RoundLI[x], y: Real.RoundLI[y], numberOfLines: sourceHeight, dotsPerLine: (sourceRightInWords-sourceLeftInWords)*16, height: Real.RoundLI[32.0*sourceHeight*magnification], unit: SirPress.mica]; bytesSoFar _ IO.GetIndex[outputStream]; IF bytesSoFar # bytesPerPage THEN SIGNAL AISPageAlignmentHackFailed; aisHeader.header.attributeLength _ bytesSoFar/2; IO.SetIndex[outputStream, 0]; IO.UnsafePutBlock[outputStream, aisBlock]; IO.SetIndex[outputStream, bytesSoFar]; IF displayCarets THEN { Carets.SuspendCarets[]; IF Carets.pCaretViewer # NIL THEN InvertCaret[context, primary]; IF Carets.sCaretViewer # NIL THEN InvertCaret[context, secondary]; }; IF displayCursor THEN { cursorArray: UserTerminal.CursorArray _ UserTerminal.GetCursorPattern[]; [] _ context.Save[]; [] _ context.SetPaintMode[transparent]; context.SetColor[Graphics.black]; context.SetCP[UserTerminal.cursor.x, ViewerSpecs.screenH-UserTerminal.cursor.y]; context.procs.DrawBits[context, @cursorArray, 1, 0, 0, 0, 16, 16, 0, 0]; context.Restore[]; }; IF lockViewers THEN ViewerLocks.LockViewerTree[]; FOR i: INT IN [0..sourceHeight) DO offset: LONG CARDINAL _ (i+screenBitMap.height-sourceHeight-sourceBottom)*screenWidthInWords+sourceLeftInWords; screen.UnsafeShowLine[screenPtr + offset]; ENDLOOP; IF lockViewers THEN ViewerLocks.ReleaseViewerTree[]; IF displayCarets THEN { IF Carets.pCaretViewer # NIL THEN InvertCaret[context, primary]; IF Carets.sCaretViewer # NIL THEN InvertCaret[context, secondary]; Carets.ResumeCarets[]; }; screen.EndScannedRectangle[]; screen.ClosePress[]; ViewerOps.PaintEverything[]; RETURN [trueName]; }; aisFileNameTemplate: ROPE = "Screen#.AIS"; InvertCaret: PROC [context: Graphics.Context, id: Carets.CaretId, kill: BOOL _ FALSE] = TRUSTED BEGIN OPEN CaretsImpl; IF id=primary THEN BEGIN IF (~kill OR pDark) AND pCaretViewer#NIL THEN BEGIN IF pCaretViewer.column=color THEN RETURN; [] _ context.Save[]; [] _ context.SetPaintMode[invert]; context.SetColor[Graphics.black]; context.SetCP[pCaretX-caretXOffset, pCaretY]; GraphicsOps.DrawBitmap[context, pCaret, caretW, caretH]; context.Restore[]; pDark _ ~pDark; END; IF kill THEN pCaretViewer _ NIL; END ELSE BEGIN IF (~kill OR sDark) AND sCaretViewer#NIL THEN BEGIN IF sCaretViewer.column=color THEN RETURN; [] _ context.Save[]; [] _ context.SetPaintMode[invert]; context.SetColor[Graphics.black]; context.SetCP[sCaretX-caretXOffset, sCaretY]; GraphicsOps.DrawBitmap[context, sCaret, caretW, caretH]; context.Restore[]; sDark _ ~sDark; END; IF kill THEN sCaretViewer _ NIL; END; END; NewAISPressName: PUBLIC ENTRY PROCEDURE RETURNS [pressFileName: ROPE] = { ENABLE UNWIND => NULL; NextName: PROCEDURE RETURNS [ROPE] = { RETURN [aisFileNameTemplate.Replace[start: i, len: 1, with: Convert.ValueToRope[[signed[(count _ count + 1)]]]]]; }; i: INT = Rope.Find[s1: aisFileNameTemplate, s2: "#"]; s: IO.STREAM; pressFileName _ IF i = -1 THEN aisFileNameTemplate ELSE NextName[]; WHILE (s _ FileIO.Open[pressFileName ! FileIO.OpenFailed => GO TO ThisNameIsOkay]) # NIL DO s.Close[]; pressFileName _ NextName[]; ENDLOOP; EXITS ThisNameIsOkay => NULL; }; PressScreenTool: PUBLIC TYPE = REF PressScreenToolRec; PressScreenToolRec: PUBLIC TYPE = RECORD[ screenAreaChoice: ChoiceButtons.EnumTypeRef, magnificationChoice: ChoiceButtons.EnumTypeRef, magnificationViewer: ViewerClasses.Viewer, -- magnification factor ulx, uly, lrx, lry: ViewerClasses.Viewer, -- upper left, lower right coordinates formatViewer: ChoiceButtons.EnumTypeRef, borderViewer: ViewerClasses.Viewer, -- border width pageMarginViewer: ViewerClasses.Viewer, countDownTimerViewer: ViewerClasses.Viewer, countDownPieViewer: PieViewers.PieViewer, lockViewersTriState: ChoiceButtons.ThreeStateRef, displayCursorTriState: ChoiceButtons.ThreeStateRef, displayCaretsTriState: ChoiceButtons.ThreeStateRef, logViewer: ViewerClasses.Viewer, logMessage: ROPE ]; ScreenArea: TYPE = {leftColumn, rightColumn, wholeScreen, desiredArea}; indent: INTEGER ~ TSViewerImpl.indent; baseline: INTEGER ~ TSViewerImpl.baseline; NewPressScreenTool: PUBLIC PROCEDURE [serverName: ROPE] RETURNS[psTool: PressScreenTool] = { ENABLE UNWIND => NULL; viewer: ViewerClasses.Viewer _ ViewerOps.CreateViewer[ flavor: $PressScreen, info: [ name: IF serverName.Length = 0 THEN "PressScreen" ELSE Rope.Concat["PressScreen to ", serverName], column: right, scrollable: FALSE ], paint: TRUE ]; psTool _ NARROW[ViewerOps.FetchProp[viewer, $PressScreenData]]; }; InitPressScreenViewer: ViewerClasses.InitProc = { psTool: PressScreenTool _ NEW[PressScreenToolRec]; nextX: INTEGER; curY: INTEGER _ indent/2; NextY: PROCEDURE RETURNS [y:NAT] = {y _ curY _ curY+baseline}; button: ViewerClasses.Viewer; menu: Menus.Menu _ Menus.CreateMenu[]; InsertMenu: PROCEDURE [name: ROPE, proc: Menus.ClickProc, doc: ROPE] = { Menus.InsertMenuEntry[menu, Menus.CreateEntry[ name: name, proc: proc, clientData: psTool, documentation: doc ]]; }; LabelledTextViewer: PROCEDURE [name: ROPE] RETURNS [v: ViewerClasses.Viewer] = { v _ ViewerTools.MakeNewTextViewer[ info:[wx: button.wx+button.ww, wy: curY, ww: 50, wh: button.wh, parent: self, scrollable: FALSE, border: TRUE], paint: TRUE ]; button _ Labels.Create[ info: [name: name, wx: v.wx + v.ww, wy: curY+1, wh: button.wh, parent: self, scrollable: FALSE, border: FALSE], paint: TRUE ]; }; MyButton: PROCEDURE [name: ROPE, proc: Buttons.ButtonProc, doc: ROPE] RETURNS [Buttons.Button] = { RETURN [Buttons.Create[ info: [name: name, wx: indent, wy: NextY[], parent: self, border: FALSE], clientData: psTool, proc: proc, fork: TRUE, paint: TRUE, documentation: doc ]]}; triggerName: ROPE _ Atom.GetPName[Atom.Gensym['P]]; ViewerOps.AddProp[self, $PressScreenData, psTool]; containerInitProc[self]; -- since I know its really a $Container, I need to init it for him self.name _ self.name.Cat[" ", triggerName]; [] _ Buttons.Create[info: [name: triggerName], proc: DoItButton, clientData: psTool, documentation: "Convert the identified area of the screen image into an AIS/Press file"]; InsertMenu["GetSelectedViewer", GetSelectedViewerButton, "Gets the corners of the selected viewer for PressScreening."]; InsertMenu["FlashImage", FlashImageButton, "Flashes the identified area of the screen image."]; InsertMenu["SetCorners", SetCornersButton, "Permits designation of a rectangular screen area"]; InsertMenu["DoIt", DoItButton, "Convert the identified area of the screen image into an AIS/Press file"]; ViewerOps.SetMenu[self, menu]; psTool.screenAreaChoice _ ChoiceButtons.BuildEnumTypeSelection[ viewer: self, x: indent, y: curY, title: "Screen Area:", buttonNames: CONS["DesiredArea", CONS["WholeScreen", CONS["LeftColumn", CONS["RightColumn", NIL]]]], default: "WholeScreen", style: menuSelection]; button _ MyButton["Area Corners: ", AreaCornersButton, "Set the corners of the identified area of the screen"]; psTool.ulx _ LabelledTextViewer["x "]; psTool.uly _ LabelledTextViewer["y "]; psTool.lrx _ LabelledTextViewer["x "]; psTool.lry _ LabelledTextViewer["y"]; psTool.magnificationChoice _ ChoiceButtons.BuildEnumTypeSelection[ viewer: self, x: indent, y: NextY[], title: "Magnification:", buttonNames: CONS["FullPage", CONS["HalfPage", CONS["UseFactorBelow", NIL]]], default: "FullPage", style: menuSelection]; button _ MyButton["MagnificationFactor: ", MagnificationFactorButton, "Set the magnification factor"]; psTool.magnificationViewer _ LabelledTextViewer["%"]; psTool.formatViewer _ ChoiceButtons.BuildEnumTypeSelection[ viewer: self, x: indent, y: NextY[], title: "Page Format:", buttonNames: CONS["Portrait", CONS["Landscape", NIL]], default: "Portrait", style: menuSelection]; button _ MyButton["BlackBorder: ", BlackBorderButton, "Set the black border width surrounding the identified image area."]; psTool.borderViewer _ LabelledTextViewer["pixels"]; button _ MyButton["PageMargin: ", PageMarginButton, "Set the white space provided around the page"]; psTool.pageMarginViewer _ LabelledTextViewer["inches"]; button _ MyButton["CountDownTimer: ", CountDownTimerButton, "Set the time before the screen is copied"]; psTool.countDownTimerViewer _ LabelledTextViewer["seconds "]; psTool.countDownPieViewer _ PieViewers.Create[parent: self, x: button.wx+button.ww, y: curY]; button _ Labels.Create[ info: [name: "Viewer Controls: ", wx: indent, wy: NextY[]+1, wh: button.wh, parent: self, scrollable: FALSE, border: FALSE], paint: TRUE ]; [psTool.lockViewersTriState, nextX] _ ChoiceButtons.BuildTriStateButton[ viewer: self, x: button.wx+button.ww, y: curY, name: "LockViewers"]; [psTool.displayCursorTriState, nextX] _ ChoiceButtons.BuildTriStateButton[ viewer: self, x: nextX, y: curY, name: "DisplayCursor"]; [psTool.displayCaretsTriState, nextX] _ ChoiceButtons.BuildTriStateButton[ viewer: self, x: nextX, y: curY, name: "DisplayCarets"]; Containers.ChildXBound[self, Rules.Create[info: [wx: 0, wy: NextY[], wh: 1, parent: self]]]; psTool.logViewer _ ViewerTools.MakeNewTextViewer[ info: [wx: 0, wy: curY+2, parent: self, scrollable: TRUE, border: FALSE] ]; Containers.ChildXBound[self, psTool.logViewer]; Containers.ChildYBound[self, psTool.logViewer]; AppendLogMessage[psTool, "To set the area corners: left-click SetCorners and cursor changes to cross-hair; left-click-and-hold to set first corner; drag mouse to second corner and release the mouse button."]; AppendLogMessage[psTool, "To use GetSelectedViewer: make a point selection within a viewer or make the selection the name of a viewer and left-click GetSelectedViewer."]; [] _ psTool.logViewer.class.scroll[psTool.logViewer, thumb, 0]; ChoiceButtons.UpdateChoiceButtons[self, psTool.screenAreaChoice, "WholeScreen"]; ChoiceButtons.UpdateChoiceButtons[self, psTool.magnificationChoice, "FullPage"]; ViewerTools.SetContents[psTool.magnificationViewer, IO.PutFR["%g", IO.real[100.0]]]; ViewerTools.SetContents[psTool.ulx, IO.PutFR["%g", IO.int[0]]]; ViewerTools.SetContents[psTool.uly, IO.PutFR["%g", IO.int[807]]]; ViewerTools.SetContents[psTool.lrx, IO.PutFR["%g", IO.int[1023]]]; ViewerTools.SetContents[psTool.lry, IO.PutFR["%g", IO.int[0]]]; ChoiceButtons.UpdateChoiceButtons[self, psTool.formatViewer, "Portrait"]; ViewerTools.SetContents[psTool.borderViewer, IO.PutFR["%g", IO.int[2]]]; ViewerTools.SetContents[psTool.pageMarginViewer, IO.PutFR["%g", IO.real[0.75]]]; ViewerTools.SetContents[psTool.countDownTimerViewer, IO.PutFR["%g", IO.int[0]]]; PieViewers.Set[psTool.countDownPieViewer, 100.0]; ViewerOps.PaintViewer[self, all]; }; GetSelectedViewerButton: Buttons.ButtonProc = { psTool: PressScreenTool _ NARROW[clientData]; selectedViewer: ViewerClasses.Viewer _ ViewerTools.GetSelectedViewer[]; sourceName: ROPE _ IF selectedViewer = NIL OR selectedViewer.class.get = NIL THEN NIL ELSE NARROW[selectedViewer.class.get[selectedViewer, $SelChars]]; IF sourceName.Length <= 1 THEN { IF (selectedViewer = NIL) THEN { AppendLogMessage[psTool, "Selection not in text viewer"]; RETURN; } ELSE { WHILE sourceName.Length <= 1 AND selectedViewer # NIL DO sourceName _ selectedViewer.name; selectedViewer _ selectedViewer.parent; ENDLOOP; }; }; IF sourceName.Length > 1 THEN { selectedViewer _ ViewerOps.FindViewer[sourceName]; IF selectedViewer = NIL THEN AppendLogMessage[psTool, Rope.Cat["Viewer \"", sourceName, "\" wasn't found."]] ELSE { ViewerTools.SetContents[psTool.ulx, IO.PutFR["%g", IO.int[selectedViewer.wx]]]; ViewerTools.SetContents[psTool.uly, IO.PutFR["%g", IO.int[selectedViewer.wy+selectedViewer.wh]]]; ViewerTools.SetContents[psTool.lrx, IO.PutFR["%g", IO.int[selectedViewer.wx+selectedViewer.ww]]]; ViewerTools.SetContents[psTool.lry, IO.PutFR["%g", IO.int[selectedViewer.wy]]]; ChoiceButtons.UpdateChoiceButtons[NARROW[parent], psTool.screenAreaChoice, "DesiredArea"]; FlashScreenArea[psTool]; }; }; }; FlashImageButton: Buttons.ButtonProc = { psTool: PressScreenTool _ NARROW[clientData]; FlashScreenArea[psTool]; }; flashTime: Process.Milliseconds ~ 600; FlashScreenArea: PROCEDURE [psTool: PressScreenTool] = { ulx, uly, lrx, lry: REAL; context: Graphics.Context _ Graphics.NewContext[]; [] _ context.SetPaintMode[invert]; [ulx, uly, lrx, lry] _ ReadScreenCorners[psTool]; context.DrawBox[[lrx, lry, ulx, uly]]; Process.Pause[Process.MsecToTicks[flashTime]]; context.DrawBox[[lrx, lry, ulx, uly]]; }; SetCornersButton: Buttons.ButtonProc = { psTool: PressScreenTool _ NARROW[clientData]; sMin, fMin: INTEGER; sSize, fSize: NAT; [sMin, fMin, sSize, fSize] _ LFUtil.GetArea[ ! LFUtil.AbortAdjust => GOTO DoNothing]; ViewerTools.SetContents[psTool.ulx, IO.PutFR["%g", IO.int[fMin]]]; ViewerTools.SetContents[psTool.uly, IO.PutFR["%g", IO.int[sMin+sSize-1]]]; ViewerTools.SetContents[psTool.lrx, IO.PutFR["%g", IO.int[fMin+fSize-1]]]; ViewerTools.SetContents[psTool.lry, IO.PutFR["%g", IO.int[sMin]]]; ChoiceButtons.UpdateChoiceButtons[NARROW[parent], psTool.screenAreaChoice, "DesiredArea"]; FlashScreenArea[psTool]; EXITS DoNothing => NULL; }; DoItButton: Buttons.ButtonProc = { psTool: PressScreenTool _ NARROW[clientData]; screenAreaChoice: ROPE _ ChoiceButtons.GetSelectedButton[psTool.screenAreaChoice]; magnificationRope: ROPE _ ChoiceButtons.GetSelectedButton[psTool.magnificationChoice]; pageMargin: REAL _ ConvertRopeToReal[ViewerTools.GetContents[psTool.pageMarginViewer]]; countDownTimer: Process.Ticks _ Process.SecondsToTicks[MIN[100000, MAX[0, Real.FixC[ConvertRopeToReal[ViewerTools.GetContents[psTool.countDownTimerViewer]]]]]]; sourceHeight, sourceWidth, sourceBottom, sourceLeft: NAT _ 0; fileName: ROPE; SELECT TRUE FROM screenAreaChoice.Equal["LeftColumn"] => { sourceHeight _ ViewerSpecs.screenH; sourceWidth _ ViewerSpecs.openLeftWidth; sourceBottom _ 0; sourceLeft _ ViewerSpecs.openLeftLeftX; }; screenAreaChoice.Equal["RightColumn"] => { sourceHeight _ ViewerSpecs.screenH; sourceWidth _ ViewerSpecs.openRightWidth; sourceBottom _ 0; sourceLeft _ ViewerSpecs.openRightLeftX; }; screenAreaChoice.Equal["WholeScreen"] => { sourceHeight _ ViewerSpecs.screenH; sourceWidth _ ViewerSpecs.screenW; sourceBottom _ 0; sourceLeft _ 0; }; screenAreaChoice.Equal["DesiredArea"] => { ulx, uly, lrx, lry: REAL; [ulx, uly, lrx, lry] _ ReadScreenCorners[psTool]; sourceHeight _ Real.Fix[uly - lry + 1]; sourceWidth _ Real.Fix[lrx - ulx + 1]; sourceBottom _ Real.Fix[lry]; sourceLeft _ Real.Fix[ulx]; }; ENDCASE => { sourceHeight _ ViewerSpecs.screenH; sourceWidth _ ViewerSpecs.screenW; sourceBottom _ 0; sourceLeft _ 0; }; IF countDownTimer > 0 THEN { FOR i: CARDINAL IN [1..25] DO Process.Pause[countDownTimer/25]; PieViewers.Set[psTool.countDownPieViewer, 100.0-4*i]; ENDLOOP; }; fileName _ AISPressScreen[ pressFileName: NewAISPressName[], sourceHeight: sourceHeight, sourceWidth: sourceWidth, sourceBottom: sourceBottom, sourceLeft: sourceLeft, magnification: ConvertRopeToReal[ViewerTools.GetContents[psTool.magnificationViewer]]/100.0, scaleToFit: SELECT TRUE FROM magnificationRope.Equal["UseFactor"] => useMagnification, magnificationRope.Equal["HalfPage"] => halfPage, magnificationRope.Equal["FullPage"] => fullPage, ENDCASE => halfPage, leftMarginInches: pageMargin, rightMarginInches: pageMargin, landscape: SELECT ChoiceButtons.GetSelectedButton[psTool.formatViewer] FROM "Landscape" => TRUE, ENDCASE => FALSE, borderWidth: ConvertRopeToReal[ViewerTools.GetContents[psTool.borderViewer]], lockViewers: psTool.lockViewersTriState.state = on, displayCursor: psTool.displayCursorTriState.state = on, displayCarets: psTool.displayCaretsTriState.state = on ! MagnificationFactorTooLarge => GOTO ReportError]; AppendLogMessage[psTool, Rope.Concat[fileName, " written."]]; PieViewers.Set[psTool.countDownPieViewer, 100.0]; EXITS ReportError => AppendLogMessage[NARROW[clientData], "Magnification factor too large for identified area"]; }; MagnificationFactorButton: Buttons.ButtonProc = { psTool: PressScreenTool _ NARROW[clientData]; IF mouseButton = blue THEN ViewerTools.SetContents[psTool.magnificationViewer, ""]; ViewerTools.SetSelection[psTool.magnificationViewer]; }; AreaCornersButton: Buttons.ButtonProc = { psTool: PressScreenTool _ NARROW[clientData]; sourceHeight, sourceWidth, sourceBottom, sourceLeft: NAT _ 0; screenAreaChoice: ROPE _ ChoiceButtons.GetSelectedButton[psTool.screenAreaChoice]; SELECT TRUE FROM screenAreaChoice.Equal["LeftColumn"] => { sourceHeight _ ViewerSpecs.screenH; sourceWidth _ ViewerSpecs.openLeftWidth; sourceBottom _ 0; sourceLeft _ ViewerSpecs.openLeftLeftX; }; screenAreaChoice.Equal["RightColumn"] => { sourceHeight _ ViewerSpecs.screenH; sourceWidth _ ViewerSpecs.openRightWidth; sourceBottom _ 0; sourceLeft _ ViewerSpecs.openRightLeftX; }; screenAreaChoice.Equal["WholeScreen"] => { sourceHeight _ ViewerSpecs.screenH; sourceWidth _ ViewerSpecs.screenW; sourceBottom _ 0; sourceLeft _ 0; }; screenAreaChoice.Equal["DesiredArea"] => { sourceHeight _ sourceWidth _ sourceBottom _ sourceLeft _ 0; }; ENDCASE => { sourceHeight _ ViewerSpecs.screenH; sourceWidth _ ViewerSpecs.screenW; sourceBottom _ 0; sourceLeft _ 0; }; ViewerTools.SetContents[psTool.ulx, IO.PutFR["%g", IO.int[sourceLeft]]]; ViewerTools.SetContents[psTool.uly, IO.PutFR["%g", IO.int[sourceBottom+sourceHeight-1]]]; ViewerTools.SetContents[psTool.lrx, IO.PutFR["%g", IO.int[sourceLeft+sourceWidth-1]]]; ViewerTools.SetContents[psTool.lry, IO.PutFR["%g", IO.int[sourceBottom]]]; ViewerTools.SetSelection[psTool.ulx]; }; BlackBorderButton: Buttons.ButtonProc = { psTool: PressScreenTool _ NARROW[clientData]; IF mouseButton = blue THEN ViewerTools.SetContents[psTool.borderViewer, ""]; ViewerTools.SetSelection[psTool.borderViewer]; }; PageMarginButton: Buttons.ButtonProc = { psTool: PressScreenTool _ NARROW[clientData]; IF mouseButton = blue THEN ViewerTools.SetContents[psTool.pageMarginViewer, ""]; ViewerTools.SetSelection[psTool.pageMarginViewer]; }; CountDownTimerButton: Buttons.ButtonProc = { psTool: PressScreenTool _ NARROW[clientData]; IF mouseButton = blue THEN ViewerTools.SetContents[psTool.countDownTimerViewer, "0"]; ViewerTools.SetSelection[psTool.countDownTimerViewer]; }; AppendLogMessage: PROCEDURE [psTool: PressScreenTool, msg: ROPE] = { psTool.logMessage _ psTool.logMessage.Cat[msg, "\n"]; ViewerTools.SetContents[psTool.logViewer, psTool.logMessage]; [] _ psTool.logViewer.class.scroll[psTool.logViewer, thumb, 100]; }; ReadScreenCorners: PROCEDURE [psTool: PressScreenTool] RETURNS [ulx, uly, lrx, lry: REAL] = { ulx _ ConvertRopeToReal[ViewerTools.GetContents[psTool.ulx]]; uly _ ConvertRopeToReal[ViewerTools.GetContents[psTool.uly]]; lrx _ ConvertRopeToReal[ViewerTools.GetContents[psTool.lrx]]; lry _ ConvertRopeToReal[ViewerTools.GetContents[psTool.lry]]; }; ConvertRopeToReal: PROCEDURE [rope: ROPE] RETURNS [value: REAL] = { i : INT _ 0; Get: PROCEDURE RETURNS [c: CHARACTER] = { c _ IF i >= rope.Length THEN ' ELSE rope.Fetch[i]; i _ i + 1; RETURN[c]; }; RETURN[IF rope.Length = 0 THEN 0.0 ELSE Real.ReadReal[Get]]; }; PressScreenExecCommand: Commander.CommandProc = TRUSTED { stream: IO.STREAM _ IO.RIS[cmd.commandLine]; serverName: ROPE _ IO.GetToken[stream, IO.IDProc]; [] _ NewPressScreenTool[serverName]; }; pressScreenViewerClass: ViewerClasses.ViewerClass ~ NEW[ViewerClasses.ViewerClassRec _ ViewerOps.FetchViewerClass[$Container]^]; containerInitProc: ViewerClasses.InitProc _ pressScreenViewerClass.init; pressScreenViewerClass.init _ InitPressScreenViewer; ViewerOps.RegisterViewerClass[$PressScreen, pressScreenViewerClass]; Commander.Register[ key: "PressScreen", proc: PressScreenExecCommand, doc: "Create a tool to make AIS/Press files of portions of the bitmap display screen" ]; }. 6-Apr-82 12:01:31 Teitelman fixed PressScreenButton to clear message window first. May 4, 1982 4:39 pm Cattell: print msg saying whether half or full screen. Also, no longer need config 'cause SirPressPackage is external. June 18, 1982 1:58 pm Cattell: convert to 3.2; leave a little left margin to avoid printer truncation. November 15, 1982 12:30 pm Plass: Made client-callable interface. November 15, 1982 2:30 pm Plass: Made rightSide work, removed button interface, made half-screen resolution match what Spruce can sometimes handle. November 16, 1982 10:57 am Plass: Tracked SirPress changes. :PressScreenImpl.mesa Program to make AIS/press file of display Last edited by: Rick Cattell on June 18, 1982 1:58 pm Last edited by: Warren Teitelman on 6-Apr-82 12:02:06 Last edited by: Michael Plass on November 16, 1982 10:58 am Last Edited by: Beach, October 25, 1983 12:51 pm Old interface to convert part or all of the bit mapped screen into a press file. define the screen rectangle call ShowLine for each line of screen (or half-line, if left side) finish the rectangle and close the file count is incremented by one and substituted for # in the template Returns a file name like "Screen1.press", "Screen2.press", etc. The specified rectangle will not fit on an 8.5 by 11 inch page with the supplied margins and magnifications An internal error expected when the size of SirPress record definitions change (low probability) Converts the specified region of the bit mapped screen into a combination AIS and Press file. Such files can be used by CedarGraphics or printed by the TSetter. AISPressScreen can raise two signals: MagnificationFactorTooLarge when the specified rectangle will not fit on an 8.5 by 11 inch page with the supplied margins and magnifications; and AISPageAlignmentHackFailed for an internal error expected when the size of SirPress record definitions change (low probability). Create the AIS Header from the screen rectangle information define the screen rectangle in the Press file Stuff the current position of the Press file into the AIS Header call ShowLine for each line of screen (or half-line, if left side) IF displayCursor THEN ViewerOps.PaintEverything will fix cursor up finish the rectangle and close the file Returns a file name like "Screen1.ais", "Screen2.ais", etc. Creates a PressScreen tool viewer. The only way this proc is called is to init a new $PressScreen viewer. There is no reset menu entry posted. Create the PressScreen menu Screen Area: DesiredArea WholeScreen LeftColumn RightColumn Area Corners: #### x #### y #### x #### y Magnification: FullPage HalfPage UseFactorBelow MagnificationFactor: xxxx % Page Format: Landscape Portrait BlackBorder: xxxx pixels PageMargin: xxxx inches CountDownTimer: xxxx seconds Viewer Controls: LockViewers DisplayCursor DisplayCarets Rule between buttons and log viewer Create log viewer for file completion messages Display default settings Êì– "cedar" style˜JšÏc™Jš)™)Jš6™6Jš6™6Jš!œ™J˜J˜&šŸ œž œžœžœ˜H˜.Jšœ ˜ J˜ J˜Jšœ˜J˜—J˜—šŸœž œžœžœ˜Pšœ"˜"šœ?˜?Jšœžœ žœ˜/—Jšœž˜ J˜—˜JšœYžœ žœ˜oJšœž˜ J˜—J˜—š Ÿœž œžœ!žœžœ˜bšžœ˜JšœBžœ˜IJ˜Jšœ ˜ Jšœžœ˜ Jšœžœ˜ Jšœ˜Jšœ˜——Jšœ žœ"˜3J˜Jšœ2˜2J˜JšœB˜\J˜,J˜®J™J™J™J˜xJ˜_J˜_J˜iJ˜J™Jšœ;™;šœ?˜?Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜Jš œ žœžœžœžœžœ˜dJšœ˜Jšœ˜—J™Jš œÏeœ œ œ œ™*Jšœo˜oJšœ'˜'Jšœ'˜'Jšœ&˜&Jšœ%˜%J™Jšœ/™/šœB˜BJšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ˜Jš œ žœ žœ žœžœ˜MJ˜Jšœ˜—J™J™Jšœf˜fJšœ6˜6J™J™šœ;˜;Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ žœ žœžœ˜6Jšœ˜Jšœ˜—J™Jšœ™Jšœ{˜{Jšœ3˜3J™J™Jšœd˜dJšœ7˜7J™Jšœ™Jšœh˜hJšœ>˜>Jšœ^˜^J™J™8˜Jšœfžœ žœ˜|Jšœž˜ J˜—šœH˜HJšœ ˜ Jšœ˜Jšœ˜Jšœ˜—šœJ˜JJšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜—šœJ˜JJšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜—J™J™#J˜\J™J™.˜1Jšœ4žœ žœ˜HJ˜—J˜/J˜/J˜ÐJ˜ªJšœ?˜?J˜J˜J™J™JšœP˜PJšœP˜PJšœ4žœ žœ˜TJšœ$žœ žœ ˜?Jšœ$žœ žœ ˜AJšœ$žœ žœ ˜BJšœ$žœ žœ ˜?JšœI˜IJšœ-žœ žœ ˜HJšœ1žœ žœ˜PJšœ5žœ žœ ˜PJ˜1J˜J˜!J˜J˜—šŸœ˜/Jšœžœ ˜-J˜Gšœ žœ˜Jš žœžœžœžœžœž˜BJšžœžœ6˜A—šžœžœ˜ šžœžœžœ˜ Jšœ9˜9Jšžœ˜Jšœ˜—šžœ˜šžœžœžœž˜8Jšœ!˜!J˜'Jšž˜—Jšœ˜—J˜—šžœžœ˜J˜2šžœž˜JšœO˜O—šžœ˜Jšœ$žœ žœ˜OJšœ$žœ žœ,˜aJšœ$žœ žœ,˜aJšœ$žœ žœ˜OJšœ"žœ2˜ZJšœ˜J˜—Jšœ˜—J˜J˜—šŸœ˜(Jšœžœ ˜-Jšœ˜J˜J˜—J˜&šŸœž œ˜8Jšœžœ˜J˜2J˜"Jšœ1˜1Jšœ&˜&J˜.Jšœ&˜&J˜J˜—šÏaœ˜(Jšœžœ ˜-Jšœ žœ˜Jšœž˜JšœEžœ ˜UJšœ$žœ žœ ˜BJšœ$žœ žœ˜JJšœ$žœ žœ˜JJšœ$žœ žœ ˜BJšœ"žœ2˜ZJšœ˜šž˜Jšœ žœ˜—J˜J˜—šŸ œ˜"Jšœžœ ˜-Jšœžœ<˜RJšœžœ?˜VJšœ žœG˜WJšœ7žœ žœZ˜ Jšœ5žœ˜=Jšœ ž˜šžœžœž˜šœ)˜)Jšœ#˜#Jšœ(˜(Jšœ˜Jšœ'˜'Jšœ˜—šœ*˜*Jšœ#˜#Jšœ)˜)Jšœ˜Jšœ(˜(Jšœ˜—šœ*˜*Jšœ#˜#Jšœ"˜"Jšœ˜Jšœ˜Jšœ˜—šœ*˜*Jšœžœ˜Jšœ1˜1Jšœ'˜'Jšœ&˜&Jšœ˜Jšœ˜Jšœ˜—šžœ˜ Jšœ#˜#Jšœ"˜"Jšœ˜Jšœ˜Jšœ˜——šžœžœ˜šžœžœžœ ž˜Jšœ!˜!J˜5Jšž˜—Jšœ˜—šœ˜Jšœ!˜!Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ\˜\šœ žœžœž˜Jšœ9˜9Jšœ0˜0Jšœ0˜0Jšžœ ˜—Jšœ˜Jšœ˜šœ žœ6ž˜KJšœžœ˜Jšžœžœ˜—JšœM˜MJšœ3˜3Jšœ7˜7Jšœ6˜6Jšœ!žœ˜3—Jšœ=˜=J˜1šž˜šœ˜JšœžœD˜[——Jšœ˜J˜—šŸœ˜1Jšœžœ ˜-Jšžœžœ9˜SJšœ5˜5J˜J˜—šŸœ˜)Jšœžœ ˜-Jšœ5žœ˜=Jšœžœ<˜Ršžœžœž˜šœ)˜)Jšœ#˜#Jšœ(˜(Jšœ˜Jšœ'˜'Jšœ˜—šœ*˜*Jšœ#˜#Jšœ)˜)Jšœ˜Jšœ(˜(Jšœ˜—šœ*˜*Jšœ#˜#Jšœ"˜"Jšœ˜Jšœ˜Jšœ˜—šœ*˜*Jšœ;˜;Jšœ˜—šžœ˜ Jšœ#˜#Jšœ"˜"Jšœ˜Jšœ˜Jšœ˜——Jšœ$žœ žœ˜HJšœ$žœ žœ$˜YJšœ$žœ žœ!˜VJšœ$žœ žœ˜JJšœ%˜%J˜J˜—šŸœ˜)Jšœžœ ˜-Jšžœžœ2˜LJšœ.˜.J˜J˜—šŸœ˜(Jšœžœ ˜-Jšžœžœ6˜PJšœ2˜2J˜J˜—šŸœ˜,Jšœžœ ˜-Jšžœžœ;˜UJšœ6˜6J˜J˜—šŸœž œ žœ˜DJ˜5Jšœ=˜=JšœA˜AJ˜J˜—šŸœž œžœžœ˜]J˜=J˜=J˜=J˜=J˜J˜—š Ÿœž œžœžœ žœ˜CJšœžœ˜ šŸœž œžœž œ˜)Jšœžœžœžœ˜3J˜ Jšžœ˜ J˜—Jšžœžœžœžœ˜