ImagerManhattan.mesa
Copyright Ó 1984, 1985, 1986, 1987, 1991 by Xerox Corporation. All rights reserved.
Michael Plass, August 2, 1989 12:42:07 pm PDT
Doug Wyatt, February 27, 1986 10:21:30 am PST
Provides operations on manhattan polygons.
The coordinates are given in terms of s and f (for slow and fast).
DIRECTORY
SF USING [Box, BoxAction, BoxGenerator];
ImagerManhattan: CEDAR DEFINITIONS
~ BEGIN
Data types
Box: TYPE ~ SF.Box;
BoxAction: TYPE ~ SF.BoxAction;
BoxGenerator: TYPE ~ SF.BoxGenerator;
Polygon: TYPE ~ LIST OF Box;
If a and b are consecutive boxes in the list, must have either
(a.min.s = b.min.s AND a.max.s = b.max.s AND a.max.f <= b.min.f)
OR
(a.max.s <= b.min.s)
Validate: PROC [polygon: Polygon] RETURNS [Polygon];
Checks that the above invariant is satisfied.
InvalidManhattanPolygon: ERROR;
May be raised by Validate.
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 nondecreasing s. It may call repeat to duplicate a scanline just entered.
CreateFromBox: PROC [box: Box] RETURNS [Polygon];
CreateFromBoxes: PROC [boxes: BoxGenerator] RETURNS [Polygon];
Polygon Destruction
Destroy: PROC [rectangleList: LIST OF Box];
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 [list: LIST OF Box] RETURNS [Polygon];
Turns a list of arbitrary rectangles into a valid Polygon.
Re-uses the storage, so copy first if list might be shared.
Extracting info from Polygons
BoundingBox: PROC [polygon: Polygon] RETURNS [Box];
CountBoxes: PROC [polygon: Polygon] RETURNS [INT];
CountRuns: PROC [polygon: Polygon] RETURNS [INT];
Map: PROC [polygon: Polygon, boxAction: BoxAction, runs: BOOL ¬ FALSE];
Clip: PROC [polygon: Polygon, box: Box, boxAction: BoxAction, runs: BOOL ¬ FALSE];
Equal: PROC [a, b: Polygon] RETURNS [BOOL];
Visibility: TYPE ~ {visible, partlyVisible, invisible};
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.
ClipBoxToMask: PROC [box: SF.Box, mask: Polygon, action: SF.BoxAction];
Modifying existing Polygons
DestructiveUnion: PROC [a, b: Polygon] RETURNS [Polygon];
Recycles storage of a, does not modify b.
DestructiveIntersection: PROC [a, b: Polygon] RETURNS [Polygon];
Recycles storage of a, does not modify b.
DestructiveClip: PROC [a: Polygon, b: Box] RETURNS [Polygon];
Recycles storage of a.
DestructiveDifference: PROC [a, b: Polygon] RETURNS [Polygon];
Recycles storage of a, does not modify b.
END.