ImagerManhattan.mesa
Copyright © 1984, 1985, 1986 by Xerox Corporation. All rights reserved.
Michael Plass, December 30, 1983 2:22 pm
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];
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.
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.