<> <> <> <> <<>> DIRECTORY Menus, ImagerPixelMaps, ViewerClasses, ViewerOps, CGContext, Graphics, GraphicsOps, Real, ImagerFrameBuffer, ImagerManhattan, BitmapViewer; BitmapViewerImpl: CEDAR PROGRAM IMPORTS Menus, ImagerPixelMaps, ViewerOps, Graphics, GraphicsOps, Real, ImagerFrameBuffer, ImagerManhattan EXPORTS BitmapViewer = BEGIN OPEN BitmapViewer; ViewerData: TYPE = REF ViewerDataRep; ViewerDataRep: TYPE = RECORD [ sShift: INTEGER _ 0, fShift: INTEGER _ 0, bitmap: PixelMap _ ImagerPixelMaps.Create[0, [0,0,0,0]] ]; Create: PUBLIC PROC [info: ViewerClasses.ViewerRec _ [], paint: BOOL _ TRUE] RETURNS [Viewer] ~ { RETURN [ViewerOps.CreateViewer[flavor, info, paint]]; }; SetBitmap: PUBLIC PROC [viewer: Viewer, bitmap: PixelMap] ~ { data: ViewerData _ NARROW[viewer.data]; data.bitmap _ bitmap; ViewerOps.PaintViewer[viewer, client, FALSE]; }; GetBitmap: PUBLIC PROC [viewer: Viewer] RETURNS [bitmap: PixelMap] ~ { data: ViewerData _ NARROW[viewer.data]; bitmap _ data.bitmap; }; TouchUp: PUBLIC PROC [viewer: Viewer, deviceRectangle: DeviceRectangle] ~ { ViewerOps.PaintViewer[viewer, client, 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 _ 0; ViewerOps.PaintViewer[viewer, client, FALSE]; }; ViewerInit: ViewerClasses.InitProc = TRUSTED { viewerData: ViewerData _ NEW[ViewerDataRep]; menu: Menus.Menu _ Menus.CreateMenu[1]; Menus.InsertMenuEntry[menu, Menus.CreateEntry[name: "<<<-->>>", proc: HScrollHit]]; 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 _ 0; ViewerOps.PaintViewer[self, client]; 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]; }; lfGraphicsData: CGContext.Ref = NARROW[Graphics.NewContext[].data]; 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]; TRUSTED {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]]; }; Normalize: PROC [viewer: Viewer] RETURNS [Viewer] ~ { data: ViewerData _ NARROW[viewer.data]; b: DeviceRectangle _ data.bitmap.ShiftMap[data.sShift, data.fShift].Window; w: DeviceRectangle _ [-2*viewer.ch/3, -viewer.cw/3, viewer.ch, viewer.cw]; IF b.sMin >= w.sMin+w.sSize THEN data.sShift _ data.sShift - (b.sMin-(w.sMin+w.sSize)+1) ELSE IF b.sMin + b.sSize <= w.sMin THEN data.sShift _ data.sShift + (w.sMin-(b.sMin + b.sSize) + 1); IF b.fMin >= w.fMin+w.fSize THEN data.fShift _ data.fShift - (b.fMin-(w.fMin+w.fSize)+1) ELSE IF b.fMin + b.fSize <= w.fMin THEN data.fShift _ data.fShift + (w.fMin-(b.fMin + b.fSize) + 1); RETURN [viewer] }; ViewerPaint: ViewerClasses.PaintProc = TRUSTED { data: ViewerData _ NARROW [Normalize[self].data]; screen: PixelMap _ GetViewerPixelMap[context].ShiftMap[-2*self.ch/3, -self.cw/3]; bits: PixelMap _ data.bitmap.ShiftMap[data.sShift, data.fShift]; whiten: LIST OF DeviceRectangle _ ImagerManhattan.Difference[ ImagerManhattan.CreateFromBox[screen.Window], ImagerManhattan.CreateFromBox[bits.Window] ]; screen.Transfer[bits]; FOR w: LIST OF DeviceRectangle _ whiten, w.rest UNTIL w = NIL DO screen.Fill[w.first, 0]; ENDLOOP; ImagerManhattan.Destroy[whiten]; }; viewerClass: ViewerClasses.ViewerClass _ NEW [ViewerClasses.ViewerClassRec _ [ init: ViewerInit, paint: ViewerPaint, scroll: ViewerScroll, coordSys: bottom, icon: tool ]]; flavor: PUBLIC ViewerClasses.ViewerFlavor _ $BitmapViewer; ViewerOps.RegisterViewerClass[flavor, viewerClass]; END.