ImagerInteractiveImpl.mesa
Last Edited by: Crow, July 14, 1983 3:25 pm
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;
Display Procedures (exported to ImagerDisplay)
These operations may not work on all devices, will no-op on noninteractive devices.
Fast Track
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] = {
Uses uninterpreted Pixel Arrays, clip to rectangle. Handy for rubber-stamping, etc.
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] = {
Maintain shadow pixel array on the side for building images, use with "NewFrame".
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
};
Internal Procedures
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.