DIRECTORY SF USING [Box, BoxAction, BoxGenerator]; ImagerManhattan: CEDAR DEFINITIONS ~ BEGIN Box: TYPE ~ SF.Box; BoxAction: TYPE ~ SF.BoxAction; BoxGenerator: TYPE ~ SF.BoxGenerator; Polygon: TYPE ~ LIST OF Box; Validate: PROC [polygon: Polygon] RETURNS [Polygon]; InvalidManhattanPolygon: ERROR; 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]; CreateFromBox: PROC [box: Box] RETURNS [Polygon]; CreateFromBoxes: PROC [boxes: BoxGenerator] RETURNS [Polygon]; Destroy: PROC [rectangleList: LIST OF Box]; 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]; Shift: PROC [polygon: Polygon, sShift, fShift: INTEGER]; Canonicalize: PROC [list: LIST OF Box] RETURNS [Polygon]; 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]; DestructiveUnion: PROC [a, b: Polygon] RETURNS [Polygon]; DestructiveIntersection: PROC [a, b: Polygon] RETURNS [Polygon]; DestructiveClip: PROC [a: Polygon, b: Box] RETURNS [Polygon]; DestructiveDifference: PROC [a, b: Polygon] RETURNS [Polygon]; END. ΦImagerManhattan.mesa Copyright c 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). Data types 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) Checks that the above invariant is satisfied. May be raised by Validate. Polygon Creation The runs proc should call run for each run, in nondecreasing s. It may call repeat to duplicate a scanline just entered. Polygon Destruction 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 Modifying existing Polygons 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 SELECT Intersection[mask, clipper] FROM = empty => invisible, = mask => visible, ENDCASE => partlyVisible; N. B. will return invisible if mask is empty. Modifying existing Polygons Recycles storage of a, does not modify b. Recycles storage of a, does not modify b. Recycles storage of a. Recycles storage of a, does not modify b. Κͺ˜code™Kšœ Οmœ=™HK™(K™-—K™K™*K™BK˜šΟk ˜ Kšžœžœ ˜(—K˜KšΠblœžœž ˜"Kšœž˜head™ Kšœžœžœ˜Kšœ žœžœ ˜šœžœžœ˜%K˜—šœ žœžœžœ˜™>Kšœžœžœ™@Kšž™Kšœ™—K˜—šΟnœžœžœ ˜4K™-K™—šœžœ˜K™——šœ™š œžœ˜šœžœΟc˜%Kšœžœ žœ žœ‘&˜SKšœžœžœ‘)˜SKšœ˜—Kšœžœ ˜Kšœx™xK˜—š  œžœ žœ ˜1K˜—š œžœžœ ˜>K˜——šœ™š œžœžœžœ˜+Kšœ‡™‡K˜——šœ™š œžœ žœ žœ ˜0K˜—š œžœžœ ˜.K˜—š  œžœžœ ˜5K˜—š  œžœžœ ˜3K˜——šœ™š œžœ$žœ˜8K˜—š   œžœžœžœžœ ˜9Kšœ:™:Kšœ;™;——šœ™š  œžœžœ˜3K˜—š  œžœžœžœ˜2K˜—š  œžœžœžœ˜1K˜—š œžœ0žœžœ˜GK˜—š œžœ:žœžœ˜RK˜—šœ žœ'˜7K˜—š  œžœžœ˜>šœ'™'Kšœ™Kšœ™Kšœ™—Kšœ-™-K˜——šœ™š œžœžœ ˜9K™)K˜—š œžœžœ ˜@K™)K˜—š œžœžœ ˜=K™K˜—š œžœžœ ˜>K™)—K˜—K˜Kšžœ˜—…—ΒB