ImagerMasks.mesa
Michael Plass, September 29, 1983 3:34 pm
Provides operations on device-resolution masks, in various representations. The coordinates are given in terms of s and f (for slow and fast).
DIRECTORY
ImagerBasic USING [Visibility],
ImagerPixelMaps,
ImagerScanConverter
;
ImagerMasks: CEDAR DEFINITIONS ~ BEGIN
Data types
DeviceRectangle: TYPE ~ ImagerPixelMaps.DeviceRectangle;
PixelMap: TYPE ~ ImagerPixelMaps.PixelMap;
DevicePath: TYPE ~ ImagerScanConverter.DevicePath;
Visibility: TYPE ~ ImagerBasic.Visibility;
Mask: TYPE ~ RECORD [
sMin, fMin: INTEGER,
sSize, fSize: NAT,
refRep: REF
This may be a REF to one of:
ImagerPixelMaps.PixelMapRep with lgBitsPerPixel=0
RunsRep
];
Making new Masks from scratch
Create: PROC [
runs: PROC[ -- Create calls this back
run: PROC[sMin, fMin: INTEGER, fSize: NAT], -- client calls this from inside runs.
repeat: PROC[timesToRepeatScanline: NAT] -- client calls this to repeat a scanline
]
] RETURNS [Mask];
The runs proc should call run for each run, in non-descreasing s. It may call repeat to duplicate a scanline just entered.
MaskFromPixelMap: PROC [pixelMap: PixelMap, minValue: CARDINAL ← 1, maxValue: CARDINAL ← 1] RETURNS [Mask];
The mask will be active where the pixel values are in the range [minValue..maxValue].
Causes copying.
MaskFromDevicePath: PROC [devicePath: DevicePath, parityFill: BOOLEANFALSE] RETURNS [Mask];
Box: PROC [r: DeviceRectangle] RETURNS [Mask];
InlineBox: PROC [r: DeviceRectangle] RETURNS [Mask]
~ INLINE {RETURN [[r.sMin, r.fMin, r.sSize, r.fSize, NIL]]};
Making new Masks from old
And: PROC [a, b: Mask] RETURNS [Mask];
Or: PROC [a, b: Mask] RETURNS [Mask];
Difference: PROC [a, b: Mask] RETURNS [Mask];
Shift: PROC [mask: Mask, s, f: INTEGER] RETURNS [Mask];
InlineShift: PROC [mask: Mask, s, f: INTEGER] RETURNS [Mask]
~ INLINE {RETURN[[mask.sMin+s, mask.fMin+f, mask.sSize, mask.fSize, mask.refRep]]};
Bitmap: PROC [mask: Mask] RETURNS [Mask];
Forces a bitmap representation. Does NOT copy if it is already a bitmap.
Extracting info from Masks
SMin: PROC [mask: Mask] RETURNS [INTEGER] ~ INLINE {RETURN[mask.sMin]};
FMin: PROC [mask: Mask] RETURNS [INTEGER] ~ INLINE {RETURN[mask.fMin]};
SSize: PROC [mask: Mask] RETURNS [CARDINAL] ~ INLINE {RETURN[mask.sSize]};
FSize: PROC [mask: Mask] RETURNS [CARDINAL] ~ INLINE {RETURN[mask.fSize]};
CountRuns: PROC [mask: Mask] RETURNS [INT];
MapRuns: PROC [mask: Mask, run: PROC [sMin, fMin: INTEGER, fSize: NAT]];
MapBoxes: PROC [mask: Mask, box: PROC [DeviceRectangle]];
MapClippedRuns: PROC [mask, clipper: Mask, run: PROC [sMin, fMin: INTEGER, fSize: NAT]];
MapClippedBoxes: PROC [mask, clipper: Mask, box: PROC [DeviceRectangle]];
IsVisible: PROC [mask, clipper: Mask] RETURNS [Visibility];
SELECT And[mask, clipper] FROM
= empty => invisible,
= mask => visible,
ENDCASE => partlyVisible;
N. B. will return invisible if mask = empty.
Applying masks
MaskTile: PROC [dest: PixelMap, mask: Mask, tile: ImagerPixelMaps.Tile, function: ImagerPixelMaps.Function ← [null, null]];
Representations
RunsRep: TYPE ~ RECORD [
SEQUENCE length: NAT OF RunBlock
];
RunBlock: TYPE ~ REF RunBlockRep;
RunBlockRep: TYPE ~ RECORD [
seq: SEQUENCE length: NAT OF RunRep
];
RunRep: TYPE ~ MACHINE DEPENDENT RECORD [
newLineRepeatCount: CARDINAL, -- zero if the run does not start a new scanline
fMin: CARDINAL,
fSize: CARDINAL
];
RunsOutOfOrder: ERROR;
END.