<> <> DIRECTORY ImagerBasic USING [IntRectangle, IntPair, PixelArray], Imager USING [Context], ImagerTransform USING [TransformIntRectangle], ImagerDisplayPrivate USING [ContextData], ImagerDisplay USING [Mask]; ImagerInteractiveImpl: CEDAR PROGRAM IMPORTS ImagerTransform EXPORTS ImagerDisplay = BEGIN OPEN ImagerBasic; NonRectangularClipper: PUBLIC SIGNAL = CODE; <> <> <> HighlightIntRectangle: PUBLIC PROC [context: Imager.Context, area: IntRectangle] = { data: REF _ context.data; WITH data SELECT FROM displayContext: ImagerDisplayPrivate.ContextData => { }; ENDCASE; -- No-op if not display device }; MoveIntRectangle: PUBLIC PROC [context: Imager.Context, source: IntRectangle, destination: IntPair] = { -- Client's way to use BitBlt data: REF _ context.data; destRect: IntRectangle _ [ destination.x, destination.y, source.w, source.h]; WITH data SELECT FROM displayContext: ImagerDisplayPrivate.ContextData => { source _RectClip[ ImagerTransform.TransformIntRectangle[source, displayContext.transform], displayContext.clipper]; destRect _ RectClip[ ImagerTransform.TransformIntRectangle[destRect, displayContext.transform], displayContext.clipper]; displayContext.deviceProcs.movePxls[ [ source.x, source.y, MIN[source.w, destRect.w], MIN[source.h, destRect.h] ], [ destRect.x, destRect.y ] ]; }; ENDCASE; -- No-op if not display device }; <<>> GetPixelArray: PUBLIC PROC [context: Imager.Context, source: IntRectangle] RETURNS [PixelArray] = { <> dummyPixelArray: PixelArray _ NIL; data: REF _ context.data; WITH data SELECT FROM displayContext: ImagerDisplayPrivate.ContextData => RETURN [ displayContext.deviceProcs.storePxls[source] ]; ENDCASE => RETURN [ dummyPixelArray ]; -- No-op if not display device }; PutPixelArray: PUBLIC PROC [context: Imager.Context, destination: IntRectangle, image: PixelArray] = { data: REF _ context.data; WITH data SELECT FROM displayContext: ImagerDisplayPrivate.ContextData => { displayContext.deviceProcs.loadPxls[image, destination]; }; ENDCASE; -- No-op if not display device }; StartDoubleBuffering: PUBLIC PROC [context: Imager.Context] = { <> data: REF _ context.data; pxls: PixelArray; WITH data SELECT FROM displayContext: ImagerDisplayPrivate.ContextData => pxls _ displayContext.deviceProcs.openPixelBuffer[displayContext.clipper]; ENDCASE; -- No-op if not display device }; StopDoubleBuffering: PUBLIC PROC [context: Imager.Context] = { data: REF _ context.data; WITH data SELECT FROM displayContext: ImagerDisplayPrivate.ContextData => displayContext.deviceProcs.closePixelBuffer[]; ENDCASE; -- No-op if not display device }; <> RectClip: PROC[rect: IntRectangle, clipper: ImagerDisplay.Mask] RETURNS[IntRectangle] = { IF clipper.refRep = NIL THEN { OPEN clipper; sMax, fMax: INTEGER; fMin _ MAX[fMin, rect.x]; sMin _ MAX[sMin, rect.y]; fMax _ MIN[fMin + fSize, rect.x + rect.w]; sMax _ MIN[sMin + sSize, rect.y + rect.h]; fSize _ IF fMax > fMin THEN fMax - fMin + 1 ELSE 0; sSize _ IF sMax > sMin THEN sMax - sMin + 1 ELSE 0; RETURN [ [fMin, sMin, fSize, sSize] ]; } ELSE ERROR NonRectangularClipper[]; }; END.