<> <> <> <> <<>> DIRECTORY BufferedRefresh, Imager, ImagerBackdoor, ImagerBitmapContext, ImagerSample, Real; BufferedRefreshImpl: CEDAR PROGRAM IMPORTS Imager, ImagerBackdoor, ImagerBitmapContext, ImagerSample, Real EXPORTS BufferedRefresh = BEGIN RefreshProc: TYPE = BufferedRefresh.RefreshProc; Layer: TYPE = BufferedRefresh.Layer; Sandwich: TYPE = REF SandwichObj; SandwichObj: TYPE = BufferedRefresh.SandwichObj; LayerData: TYPE = REF LayerDataObj; LayerDataObj: TYPE = BufferedRefresh.LayerDataObj; StartLayerDataList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF LayerData] = { ptr _ entityList _ NIL; }; AddLayerData: PUBLIC PROC [entity: LayerData, entityList, ptr: LIST OF LayerData] RETURNS [newList, newPtr: LIST OF LayerData] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr _ newList _ CONS[entity, NIL]; RETURN; } ELSE { newList _ entityList; ptr.rest _ CONS[entity, NIL]; newPtr _ ptr.rest; }; }; <<>> CreateSandwich: PUBLIC PROC [layers: LIST OF Layer] RETURNS [sandwich: Sandwich] = { <> layerData: LayerData; ptr: LIST OF LayerData; sandwich _ NEW[SandwichObj]; [sandwich.layers, ptr] _ StartLayerDataList[]; FOR list: LIST OF Layer _ layers, list.rest UNTIL list = NIL DO layerData _ NEW[LayerDataObj _ [name: list.first.name, refreshProc: list.first.refreshProc, hasMap: list.first.backingMap]]; [sandwich.layers, ptr] _ AddLayerData[layerData, sandwich.layers, ptr]; ENDLOOP; }; FitSandwichToScreen: PUBLIC PROC [sandwich: Sandwich, cw, ch: INTEGER, clientToViewer: Imager.Transformation _ NIL] = { layer: LayerData; rect: Imager.Rectangle; <> <> <> <> <> <<]];>> <> <> <> <<];>> <> sandwich.chunkingBitmap _ ImagerSample.NewSampleMap[[max: [ch, cw]]]; sandwich.chunkingContext _ ImagerBitmapContext.Create[[ch, cw], [down, right], [72.0, 72.0], TRUE]; ImagerBitmapContext.SetBitmap[sandwich.chunkingContext, sandwich.chunkingBitmap]; IF clientToViewer # NIL THEN Imager.ConcatT[sandwich.chunkingContext, clientToViewer]; <> FOR list: LIST OF LayerData _ sandwich.layers, list.rest UNTIL list = NIL DO layer _ list.first; layer.backingMap _ ImagerSample.NewSampleMap[[max: [ch, cw]]]; layer.backingContext _ ImagerBitmapContext.Create[[ch, cw], [down, right], [72.0, 72.0], TRUE]; ImagerBitmapContext.SetBitmap[layer.backingContext, layer.backingMap]; IF clientToViewer # NIL THEN Imager.ConcatT[layer.backingContext, clientToViewer]; <> rect _ ImagerBackdoor.GetBounds[layer.backingContext]; Imager.SetColor[layer.backingContext, Imager.white]; Imager.MaskRectangle[layer.backingContext, rect]; ENDLOOP; }; DrawSandwich: PUBLIC PROC [sandwich: Sandwich, screen: Imager.Context, boundRect: Imager.Rectangle, viewerToClient: Imager.Transformation, clientData: REF ANY, ignoreBackingMap: BOOL _ FALSE] = { <> chunking: Imager.Context _ sandwich.chunkingContext; layer: LayerData; IF ignoreBackingMap THEN { Imager.SetColor[screen, Imager.white]; Imager.MaskRectangle[screen, boundRect]; } ELSE { Imager.SetColor[chunking, Imager.white]; Imager.MaskRectangle[chunking, boundRect]; }; FOR list: LIST OF LayerData _ sandwich.layers, list.rest UNTIL list = NIL DO layer _ list.first; IF ignoreBackingMap THEN { layer.refreshProc[screen, boundRect, clientData] } ELSE { IF NOT layer.hasMap THEN layer.refreshProc[chunking, boundRect, clientData] ELSE { IF NOT layer.mapOK THEN { UpdateBackingMap: PROC = { rect: Imager.Rectangle; rect _ ImagerBackdoor.GetBounds[layer.backingContext]; Imager.SetColor[layer.backingContext, Imager.white]; Imager.MaskRectangle[layer.backingContext, rect]; layer.refreshProc[layer.backingContext, boundRect, clientData]; }; Imager.DoSaveAll[layer.backingContext, UpdateBackingMap]; layer.mapOK _ TRUE; }; LayerToChunking[layer, chunking, viewerToClient]; }; }; ENDLOOP; IF NOT ignoreBackingMap THEN ChunkingToScreen[sandwich, screen, viewerToClient]; }; <> <> <> <<};>> <<>> ChunkingToScreen: PROC [sandwich: Sandwich, screen: Imager.Context, viewerToClient: Imager.Transformation _ NIL] = { ChunkingToScreenAux: PROC = { rect: Imager.Rectangle; rect _ ImagerBackdoor.GetBounds[sandwich.chunkingContext]; IF viewerToClient # NIL THEN Imager.ConcatT[screen, viewerToClient]; Imager.DrawBitmap[screen, chunkingBitmap, [Real.Fix[rect.h], 0]]; <> }; chunkingBitmap: Imager.SampleMap _ sandwich.chunkingBitmap; Imager.DoSaveAll[screen, ChunkingToScreenAux]; }; LayerToChunking: PROC [layer: LayerData, chunking: Imager.Context, viewerToClient: Imager.Transformation _ NIL] = { UpdateBackingMap: PROC = { rect: Imager.Rectangle; rect _ ImagerBackdoor.GetBounds[layer.backingContext]; IF viewerToClient # NIL THEN Imager.ConcatT[chunking, viewerToClient]; Imager.SetColor[chunking, Imager.black]; Imager.MaskBitmap[chunking, backingMap, [Real.Fix[rect.h], 0]]; <> }; backingMap: Imager.SampleMap _ layer.backingMap; Imager.DoSaveAll[chunking, UpdateBackingMap]; }; <<>> SetLayerOK: PUBLIC PROC [sandwich: Sandwich, layerName: ATOM, ok: BOOL] = { layer: LayerData _ FindLayer[sandwich, layerName]; layer.mapOK _ ok; }; GetLayerOK: PUBLIC PROC [sandwich: Sandwich, layerName: ATOM] RETURNS [ok: BOOL] = { layer: LayerData _ FindLayer[sandwich, layerName]; ok _ layer.mapOK; }; GetLayerContext: PUBLIC PROC [sandwich: Sandwich, layerName: ATOM] RETURNS [backingContext: Imager.Context] = { layer: LayerData _ FindLayer[sandwich, layerName]; backingContext _ layer.backingContext; }; FindLayer: PROC [sandwich: Sandwich, layerName: ATOM] RETURNS [layer: LayerData] = { FOR list: LIST OF LayerData _ sandwich.layers, list.rest UNTIL list = NIL DO IF list.first.name = layerName THEN RETURN[list.first]; ENDLOOP; ERROR; }; END.