ImagerManhattan.mesa
Michael Plass, December 30, 1983 2:22 pm
Provides operations on manhattan polygons. The coordinates are given in terms of s and f (for slow and fast).
DIRECTORY ImagerBasic USING [Visibility, DeviceRectangle];
ImagerManhattan: CEDAR DEFINITIONS ~ BEGIN
Data types
DeviceRectangle: TYPE ~ ImagerBasic.DeviceRectangle;
RECORD [sMin, fMin: INTEGER, sSize, fSize: NAT];
Visibility: TYPE ~ ImagerBasic.Visibility;
{visible, partlyVisible, invisible};
Polygon: TYPE ~ LIST OF DeviceRectangle;
If a and b are consecutive boxes in the list, must have either
a.sMin = b.sMin AND a.sSize = b.sSize AND a.fMin+a.fSize <= b.fMin
OR
a.sMin+a.sSize <= b.sMin
Validate: PROC [polygon: Polygon] RETURNS [Polygon];
Checks that the above invariant is satisfied.
InvalidManhattanPolygon: ERROR;
Polygon Creation
CreateFromRuns: 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 [Polygon];
The runs proc should call run for each run, in non-descreasing s. It may call repeat to duplicate a scanline just entered.
CreateFromBox: PROC [deviceRectangle: DeviceRectangle] RETURNS [Polygon];
Polygon Destruction
Destroy: PROC [rectangleList: LIST OF DeviceRectangle];
Puts the nodes on an avail list to be re-used; much faster than letting the garbage collector do the work, but don't destroy a list unless you are sure nobody is depending on it. (The avail list nodes will get garbage collected eventually if they are unneeded.)
Making new Polygons from old
Copy: PROC [polygon: Polygon] RETURNS [Polygon];
Union: PROC [a, b: Polygon] RETURNS [Polygon];
Intersection: PROC [a, b: Polygon] RETURNS [Polygon];
Difference: PROC [a, b: Polygon] RETURNS [Polygon];
Modifying existing Polygons
Shift: PROC [polygon: Polygon, sShift, fShift: INTEGER];
Canonicalize: PROC [rectangleList: LIST OF DeviceRectangle] RETURNS [Polygon];
Turns a list of arbitrary rectangles into a valid Polygon. Re-uses the storage, so copy first if rectangleList might be shared.
Extracting info from Polygons
BoundingBox: PROC [polygon: Polygon] RETURNS [DeviceRectangle];
CountBoxes: PROC [polygon: Polygon] RETURNS [INT];
CountRuns: PROC [polygon: Polygon] RETURNS [INT];
MapRuns: PROC [polygon: Polygon, run: PROC [sMin, fMin: INTEGER, fSize: NAT]];
IsVisible: PROC [mask, clipper: Polygon] RETURNS [Visibility];
SELECT Intersection[mask, clipper] FROM
= empty => invisible,
= mask => visible,
ENDCASE => partlyVisible;
N. B. will return invisible if mask is empty.
END.