home *** CD-ROM | disk | FTP | other *** search
- PROCEDURE Fill_Region (X, Y: Real);
-
- { Region-filling code developed from a description of the algorithm
- in Fundamentals of Interactive Computer Graphics, Foley & Van Dam
- 1982, p. 450-451.
-
- No provision has been made for differences between the FILL color
- and the BOUNDRY color; both are assumed to be the current set color.
- This is because the Graphix Toolbox is not set up to cope with multi-
- color high-resolution display images. }
-
- { By Fred Robinson
- Monotreme Software Copyright (c) 1987 Monotreme Software
- 29766 Everett
- Southfield, MI 48076
- USA }
-
- TYPE
- { Stack for storing potential starting points }
- Pair_Ptr = ^Pair;
- Pair = RECORD
- X, Y: Integer;
- Next: Pair_Ptr
- END;
-
- VAR
- Top_Pair, This_Pair: Pair_Ptr;
- Start_X, Start_Y, X1Loc, X2Loc: Integer;
-
- (****************************************************************)
-
- PROCEDURE Fill_Line (X, Y: Integer);
-
- { This procedure fills in the pixel line Y, starting at point X,
- first moving to the right to the rightmost unfilled pixel, then
- from (X, Y) to the left to the leftmost unfilled pixel. On both
- passes, the lines above & below are checked for candidate starting
- points. That is, if (X, Y) is not already filled in. }
-
- VAR
- X1, X2, Y_Above, Y_Below: Integer;
-
- (*************************************************************)
-
- PROCEDURE Check_Point (X, Y: Integer);
-
- { This procedure checks (X, Y) and, if it is a point to start
- filling at, adds it to the stack. }
-
- VAR
- This_Pair: Pair_Ptr;
-
- BEGIN
- IF (X>=X1Loc) AND (X<=X2Loc) AND (Y>=Y1RefGlb) AND
- (Y<=Y2RefGlb) THEN
- { Making sure that (X, Y) is within legal limits }
- IF NOT PD (X, Y) THEN
- IF (X=X2Loc) OR PD (X+1, Y) THEN
- { Believe it or not, this double-IF construct
- is faster than ANDing the two condiitons }
- BEGIN
- New (This_Pair);
- This_Pair^.X := X;
- This_Pair^.Y := Y;
- This_Pair^.Next := Top_Pair;
- Top_Pair := This_Pair
- END (* THEN, THEN, THEN *)
- END (* Check_Point *);
-
- (*************************************************************)
-
- BEGIN (* Fill_Line *)
- IF NOT PD (X, Y) THEN
- BEGIN
-
- { Fill in to the right of (X, Y) }
-
- X1 := X;
- Y_Above := Y - 1;
- Y_Below := Y + 1;
-
- WHILE (X1<=X2Loc) AND NOT PD (X1, Y) DO
- BEGIN
- Check_Point (X1, Y_Below);
- Check_Point (X1, Y_Above);
- DP (X1, Y);
- X1 := X1 + 1
- END (* WHILE *);
-
- { Check above and below beyond the right end of the line just
- filled in }
-
- X2 := X1 - 1;
-
- WHILE (X2<=X2Loc) AND NOT PD (X2, Y_Below) DO
- BEGIN
- Check_Point (X2, Y_Below);
- X2 := X2 + 1
- END (* WHILE *);
-
- X2 := X1 - 1;
-
- WHILE (X2<=X2Loc) AND NOT PD (X2, Y_Above) DO
- BEGIN
- Check_Point (X2, Y_Above);
- X2 := X2 + 1
- END (* WHILE *);
-
- { Fill in to the left of (X, Y) }
-
- X1 := X - 1;
-
- WHILE (X1>=X1Loc) AND NOT PD (X1, Y) DO
- BEGIN
- Check_Point (X1, Y_Below);
- Check_Point (X1, Y_Above);
- DP (X1, Y);
- X1 := X1 - 1
- END (* WHILE *)
- END (* THEN *)
- END (* Fill_Line *);
-
- (****************************************************************)
-
- BEGIN (* Fill_Region *)
-
- { Get pixel coordinates of (X, Y) }
-
- IF DirectModeGlb THEN
- BEGIN
- Start_X := Round (X);
- Start_Y := Round (Y)
- END (* THEN *)
-
- ELSE
- BEGIN
- Start_X := WindowX (X);
- Start_Y := WindowY (Y)
- END (* ELSE *);
-
- { Push the given starting point onto the stack }
-
- New (Top_Pair);
- Top_Pair^.Next := NIL;
- Top_Pair^.X := Start_X;
- Top_Pair^.Y := Start_Y;
-
- { Set the proper X-bounds }
-
- IF HatchGlb THEN
- BEGIN
- X1Loc := X1RefGlb;
- X2Loc := X2Refglb;
- END (* THEN *)
-
- ELSE
- BEGIN
- X1Loc := X1RefGlb SHL 3;
- X2Loc := X2RefGlb SHL 3 + 7
- END (* ELSE *);
-
- { Fill in until there are no more starting points on the stack }
-
- WHILE Top_Pair<>NIL DO
- BEGIN
- This_Pair := Top_Pair;
- Top_Pair := Top_Pair^.Next;
- Start_X := This_Pair^.X;
- Start_Y := This_Pair^.Y;
- Dispose (This_Pair);
- Fill_Line (Start_X, Start_Y);
- END (* WHILE *)
- END (* Fill_Region *);