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:
BOOLEAN ←
FALSE]
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.