BufferedRefresh.mesa
Copyright Ó 1986, 1987, 1988 by Xerox Corporation. All rights reserved.
Contents: Builds up an abstraction of transparent layers onto which shapes can be drawn. Each layer may have a backing pixel map, in which case it need not be redrawn when other layers change. This scheme is used by Gargoyle and Solidviews.
Last edited by Bier on February 3, 1987
Doug Wyatt, June 28, 1988 12:01:34 pm PDT
Bier, March 10, 1990 2:42:06 pm PST
DIRECTORY
Imager USING [Context, Rectangle, SampleMap, Transformation],
Real USING [LargestNumber];
BufferedRefresh: CEDAR DEFINITIONS =
BEGIN
Rectangle: TYPE = Imager.Rectangle;
SampleMap: TYPE = Imager.SampleMap;
RefreshProc: TYPE = PROC [dc: Imager.Context, boundRect: Rectangle, clientData: REF ANY] RETURNS [drawnOn: BOOLTRUE];
If drawnOn is FALSE, this layer can be ignored.
Layer: TYPE = RECORD [name: ATOM, backingMap: BOOL, refreshProc: RefreshProc];
Sandwich: TYPE = REF SandwichObj;
SandwichObj: TYPE = RECORD [
layers: LIST OF LayerData,
clientToViewer: Imager.Transformation, -- the transforms most recently seen by DrawSandwich
viewerToClient: Imager.Transformation,
cw, ch: INTEGER ← 0, -- current "screen" size
class: ATOMNIL -- current "screen" context class
];
LayerData: TYPE = REF LayerDataObj;
LayerDataObj: TYPE = RECORD [
name: ATOM,
refreshProc: RefreshProc,
wantsMap, hasMap: BOOL,
backingMap: SampleMap ← NIL,
savedMap: SampleMap ← NIL, -- saved by BufferedRefresh.SaveLayer
backingContext: Imager.Context ← NIL, -- derived from backingMap
mapOK: BOOLFALSE,
drawnOn: BOOLTRUE
];
[Artwork node; type 'ArtworkInterpress on' to command tool]
CreateSandwich: PROC [layers: LIST OF Layer] RETURNS [sandwich: Sandwich];
Layers should be specified in back to front order.
FitSandwichToScreen: PROC [sandwich: Sandwich, cw, ch: INTEGER, screen: Imager.Context];
DrawSandwich: PROC [sandwich: Sandwich, screen: Imager.Context,
clientToViewer, viewerToClient: Imager.Transformation, clientData: REF ANY,
ignoreBackingMap: BOOLFALSE, noBuffer: BOOLFALSE, changeRect: Imager.Rectangle ← [-Real.LargestNumber, -Real.LargestNumber, Real.LargestNumber, Real.LargestNumber]];
Draw the picture, derivable from the sandwich, on the screen. For backed layers that are OK, this will just dump the backing map on the screen. For backed layers that are not OK, this will remake the backing map by calling the refreshProc and dump the backing map on the screen. For unbacked layers, this will call the RefreshProc for that layer. Layers will be drawn in back-to-front order. All layers are initially NOT OK.
If ignoreBackingMap is TRUE, all layers will be drawn by calling their refresh proc. Since we currently use 1 bit per pixel backing maps, this must be done to show colors.
If noBuffer is TRUE, drawing will be done directly on the screen; otherwise Imager.DoWithBuffer will be called to update the screen atomically.
viewerToClient is your way to tell BufferedRefresh what your BiScrollers are doing (if you use them). Gargoyle uses the incantation:
[clientToViewer, viewerToClient] ← BiScrollers.GetStyle[].GetTransforms[BiScrollers.QuaBiScroller[gargoyleData.actionArea]];
Only that part of the screen that intersects changeRect will be drawn on. Using a small changeRect will noticeably improve performance on color displays.
SetLayerOK: PROC [sandwich: Sandwich, layerName: ATOM, ok: BOOL];
GetLayerOK: PROC [sandwich: Sandwich, layerName: ATOM] RETURNS [ok: BOOL];
RepairLayer: PROC [sandwich: Sandwich, layerName: ATOM, proc: RefreshProc,
clientData: REF ANYNIL, clear: BOOLFALSE];
If the named layer has a backing map, and it is OK or clear is TRUE, then proc is called with a context for that map (after the map is cleared if clear is TRUE), and the backing map becomes OK. Otherwise, nothing happens.
SaveLayer: PROC [sandwich: Sandwich, layerName: ATOM];
If the named layer is backed with a bitmap, that bitmap will be copied for later use (see RestoreLayer).
RestoreLayer: PROC [sandwich: Sandwich, layerName: ATOM];
If the named layer is backed with a bitmap, then that bitmap will be replaced by the bitmap that most recently was saved (see SaveLayer). This will only happen if the saved bitmap and the current bitmap are of the same size.
END.