<> <> <> <> <<>> DIRECTORY PDFileFormat, PDInterpBitmap, Menus, ImagerPixelMaps, PDInterpOutput, ViewerClasses, ViewerOps, CGContext, Graphics, GraphicsOps, Real, ImagerFrameBuffer, Process, PDTextBitmap, String, PDQueue, IO, FS; PDInterpOutputViewerImpl: PROGRAM IMPORTS Menus, ImagerPixelMaps, ViewerOps, Graphics, GraphicsOps, Real, ImagerFrameBuffer, Process, PDTextBitmap, PDInterpBitmap, String, IO, FS, PDQueue EXPORTS PDInterpOutput = BEGIN viewer: ViewerClasses.Viewer _ NIL; pageMap: ImagerPixelMaps.PixelMap _ ImagerPixelMaps.Create[0, [0,0,0,0]]; currentStartImage: PDFileFormat.StartImage; currentHerald: PDFileFormat.Herald; bandNumber: NAT _ 0; oneBandAtATime: BOOLEAN _ FALSE; StartImage: PUBLIC PROC [herald: PDFileFormat.Herald, startImage: PDFileFormat.StartImage, request: PDQueue.Request] RETURNS [PDInterpBitmap.BitmapDesc] = { bandMap: ImagerPixelMaps.PixelMap; pageMapLines: NAT _ IF oneBandAtATime THEN herald.bandSSize ELSE startImage.nBands*herald.bandSSize; pageMap _ ImagerPixelMaps.Create[0, [startImage.passBands*herald.bandSSize, startImage.fMinPage, pageMapLines, startImage.fSizePage]]; currentStartImage _ startImage; currentHerald _ herald; bandNumber _ 0; pageMap.Clear; bandMap _ pageMap.Clip[[startImage.passBands*herald.bandSSize, startImage.fMinPage, herald.bandSSize, startImage.fSizePage]]; RETURN [[ sOrigin: bandMap.sOrigin, fOrigin: bandMap.fOrigin, sMin: bandMap.sMin, fMin: bandMap.fMin, sSize: bandMap.sSize, fSize: bandMap.fSize, pointer: bandMap.refRep.pointer, rast: bandMap.refRep.rast, lines: bandMap.refRep.lines ]] }; EndBand: PUBLIC PROC RETURNS [PDInterpBitmap.BitmapDesc] = { bandMap: ImagerPixelMaps.PixelMap; bandNumber _ bandNumber + 1; IF oneBandAtATime THEN ShowPage[]; IF oneBandAtATime THEN {pageMap _ pageMap.ShiftMap[currentHerald.bandSSize, 0]; pageMap.Clear}; bandMap _ pageMap.Clip[[(currentStartImage.passBands+bandNumber)*currentHerald.bandSSize, currentStartImage.fMinPage, currentHerald.bandSSize, currentStartImage.fSizePage]]; RETURN [[ sOrigin: bandMap.sOrigin, fOrigin: bandMap.fOrigin, sMin: bandMap.sMin, fMin: bandMap.fMin, sSize: bandMap.sSize, fSize: bandMap.fSize, pointer: bandMap.refRep.pointer, rast: bandMap.refRep.rast, lines: bandMap.refRep.lines ]] }; ShowPage: PROC = { data: ViewerData; IF viewer = NIL OR viewer.destroyed THEN viewer _ ViewerOps.CreateViewer[$PDInterpOutputViewerClass, [name: "PD page", column: left, iconic: TRUE]]; data _ NARROW [viewer.data]; data.nextPage _ FALSE; data.sShift _ -pageMap.sOrigin; data.fShift _ -pageMap.fOrigin; ViewerOps.PaintViewer[viewer, client]; DO IF viewer.destroyed OR data.nextPage OR data.noPause OR oneBandAtATime THEN EXIT; Process.Pause[Process.MsecToTicks[200]]; ENDLOOP; }; EndImage: PUBLIC PROC [request: PDQueue.Request] = { separator: LONG STRING _ [160]; String.Copy[separator, request.requestTime]; THROUGH [0..2) DO String.AppendChar[separator, ' ] ENDLOOP; String.AppendString[separator, request.fileName]; THROUGH [0..2) DO String.AppendChar[separator, ' ] ENDLOOP; String.AppendString[separator, request.requestor]; THROUGH [0..2) DO String.AppendChar[separator, ' ] ENDLOOP; ShowPage[]; IF PDTextBitmap.fontName.length = 0 THEN IF NOT PDTextBitmap.SetFont["[Indigo]Fonts>TimesRoman36B.ks", request.requestor, request.requestorPassword] THEN ERROR; pageMap _ pageMap.refRep.Reshape[0, [-1-PDTextBitmap.FontAscent[], -PDTextBitmap.FontAscent[], PDTextBitmap.FontAscent[]+PDTextBitmap.FontDescent[]+2, PDTextBitmap.TextWidth[separator]+2*PDTextBitmap.FontAscent[]]]; { bits: PDInterpBitmap.BitmapDesc _ [ sOrigin: pageMap.sOrigin, fOrigin: pageMap.fOrigin, sMin: pageMap.sMin, fMin: pageMap.fMin, sSize: pageMap.sSize, fSize: pageMap.fSize, pointer: pageMap.refRep.pointer, rast: pageMap.refRep.rast, lines: pageMap.refRep.lines ]; PDInterpBitmap.Fill[bits, [-10000, -10000, 20000, 20000], 1]; PDTextBitmap.TextToBitmap[dest: bits, string: separator, function: [and, complement]]; }; ShowPage[]; }; ReprintLastPage: PUBLIC PROC [copies: CARDINAL] = { IF currentHerald.password # PDFileFormat.passwordValue THEN RETURN; currentHerald.copies _ copies; ShowPage[]; }; viewerClass: ViewerClasses.ViewerClass _ NEW [ViewerClasses.ViewerClassRec _ [ init: ViewerInit, paint: ViewerPaint, scroll: ViewerScroll, coordSys: bottom, icon: tool ]]; ViewerData: TYPE = REF ViewerDataRep; ViewerDataRep: TYPE = RECORD [ sShift: INTEGER _ 0, fShift: INTEGER _ 0, nextPage: BOOLEAN _ FALSE, noPause: BOOLEAN _ FALSE ]; HScrollHit: Menus.ClickProc = TRUSTED { viewer: ViewerClasses.Viewer _ NARROW[parent]; data: ViewerData _ NARROW[viewer.data]; IF data = NIL THEN RETURN; data.fShift _ data.fShift + (IF mouseButton = red THEN -128 ELSE 128); IF mouseButton = yellow THEN data.fShift _ -pageMap.fMin; ViewerOps.PaintViewer[viewer, client]; }; PageHit: Menus.ClickProc = TRUSTED { viewer: ViewerClasses.Viewer _ NARROW[parent]; data: ViewerData _ NARROW[viewer.data]; IF data = NIL THEN RETURN; data.nextPage _ TRUE; }; NoPauseHit: Menus.ClickProc = TRUSTED { viewer: ViewerClasses.Viewer _ NARROW[parent]; data: ViewerData _ NARROW[viewer.data]; IF data = NIL THEN RETURN; data.noPause _ mouseButton = red; }; lfGraphicsData: CGContext.Ref = NARROW[Graphics.NewContext[].data]; ViewerInit: ViewerClasses.InitProc = TRUSTED { viewerData: ViewerData _ NEW[ViewerDataRep]; menu: Menus.Menu _ Menus.CreateMenu[1]; Menus.InsertMenuEntry[menu, Menus.CreateEntry[name: "<<<-->>>", proc: HScrollHit]]; Menus.InsertMenuEntry[menu, Menus.CreateEntry[name: "Page", proc: PageHit]]; Menus.InsertMenuEntry[menu, Menus.CreateEntry[name: "NoPause", proc: NoPauseHit]]; viewerData.sShift _ 0; viewerData.fShift _ 0; self.data _ viewerData; self.menu _ menu; }; ViewerScroll: ViewerClasses.ScrollProc = TRUSTED { data: ViewerData _ NARROW [self.data]; IF data = NIL OR op = query THEN RETURN [0, 100]; IF op = thumb THEN {data.sShift _ -pageMap.sOrigin; RETURN [0, 100]}; IF amount = 0 THEN RETURN [0, 100]; IF op = down THEN amount _ -amount; data.sShift _ data.sShift - amount; ViewerOps.PaintViewer[self, client]; RETURN [0, 100]; }; OnLFDisplay: PROC [graphics: Graphics.Context] RETURNS [BOOLEAN] = { data: CGContext.Ref = NARROW[graphics.data]; RETURN [data.device.Show = lfGraphicsData.device.Show] }; GetViewerPixelMap: PROC [graphics: Graphics.Context] RETURNS [pixelMap: ImagerPixelMaps.PixelMap] = { x, y, w, h: REAL; [x, y] _ GraphicsOps.UserToDevice[graphics,0,0]; IF GraphicsOps.UserToDevice[graphics,0,1].ty > y THEN ERROR; [[xmax: w, ymax: h]] _ Graphics.GetBounds[graphics]; IF OnLFDisplay[graphics] THEN { sMin: INTEGER _ Real.RoundLI[y]-Real.RoundLI[h]; pixelMap _ ImagerFrameBuffer.LFDisplay[]; pixelMap _ pixelMap.ShiftMap[-sMin, -Real.RoundLI[x]]; pixelMap _ pixelMap.Clip[[0, 0, Real.RoundLI[h], Real.RoundLI[w]]]; } ELSE pixelMap _ ImagerPixelMaps.Create[0, [0,0,0,0]]; }; ViewerPaint: ViewerClasses.PaintProc = TRUSTED { data: ViewerData _ NARROW [self.data]; pixelMap: ImagerPixelMaps.PixelMap _ GetViewerPixelMap[context]; pixelMap.Transfer[pageMap.ShiftMap[data.sShift, data.fShift]]; }; ReadQueue: PROC [address: LONG POINTER, nwords: CARDINAL] = TRUSTED { stream: IO.STREAM; stream _ FS.StreamOpen["[]<>Peach.queue", $read, ALL[FALSE] ! FS.Error => CONTINUE]; IF stream#NIL THEN { [] _ stream.UnsafeGetBlock[[base: address, startIndex: 0, count: nwords*2]]; stream.Close; }; }; WriteQueue: PROC [address: LONG POINTER, nwords: CARDINAL] = TRUSTED { stream: IO.STREAM _ FS.StreamOpen["[]<>Peach.queue", $create]; [] _ stream.UnsafePutBlock[[base: address, startIndex: 0, count: nwords*2]]; stream.Close; }; RegisterDisk: PROC = {PDQueue.RegisterDisk[ReadQueue, WriteQueue, 1024]}; ViewerOps.RegisterViewerClass[$PDInterpOutputViewerClass, viewerClass]; currentHerald.password _ 0; PDQueue.RegisterDisk[ReadQueue, WriteQueue, 1024]; END.