[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference bulova::decw_jan-89_to_nov-90

Title:DECWINDOWS 26-JAN-89 to 29-NOV-90
Notice:See 1639.0 for VMS V5.3 kit; 2043.0 for 5.4 IFT kit
Moderator:STAR::VATNE
Created:Mon Oct 30 1989
Last Modified:Mon Dec 31 1990
Last Successful Update:Fri Jun 06 1997
Number of topics:3726
Total number of notes:19516

2067.0. "Complex area flood routine available." by WPOMM2::ZAMBOTTI () Thu Jan 18 1990 03:56

Hi again,

gee I've been a busy bee.  Gee bee, it's a joke son... Do you get it!

Ok I've debugged the flood routine, except for the XGetImage problem
(see 2066.0 & 2065.0).

Here follows the code.

/*
    Flood a complex bordered region using the current foreground color.
    Flood starts at the given X, Y coordinate and floods all pixels of
    the same color as the starting pixel (@ X, Y).

    Because flood uses the XDrawLine function to paint the area all the
    GC components that can be used for XDrawLine can be used for flood.
*/

unsigned long ReferencePixel, FillPixel ;
XImage        *FloodImage ;
Window        Win ;
Display       *Disp ;
GC            GCID ;

void flood(Displ, Wind, WinGC, X, Y)

Display *Displ ;
Window  Wind ;
GC      WinGC ;
int     X, Y ;

{
Window  RootWin ;
int     X1, X2, StartX, StartY, LineFound = FALSE, Width, Height, XPos, YPos, Border, Depth ;

    Disp = Displ ;
    Win = Wind ;
    GCID = WinGC ;

    XGetGeometry(Disp, Win, &RootWin, &XPos, &YPos, &Width, &Height, &Border, &Depth) ;
    FloodImage = XGetImage(Disp, Win, 0, 0, Width, Height, AllPlanes, XYPixmap) ;
    ReferencePixel = XGetPixel(FloodImage, X, Y) ;
    FillPixel = ~ReferencePixel ;

    for(X1 = X ; X1 && XGetPixel(FloodImage, X1, Y) == ReferencePixel ; X1--) ;
    for(X2 = X+1 ; X2 < Width && XGetPixel(FloodImage, X2, Y) == ReferencePixel ; X2++) ;

    FloodUp(X, Y) ;

    if(++Y < Height) {
        for( ; X1 <= X2 ; X1++) {
            if(LineFound && XGetPixel(FloodImage, X1, Y) != ReferencePixel) {
                LineFound = FALSE ;
            }
            else if(XGetPixel(FloodImage, X1, Y) == ReferencePixel) {
                LineFound = True ;
                FloodDown(X1, Y) ;
            }
        }
    }
}


FloodUp(StartX, StartY)

int     StartX, StartY ;

{
int     X1, X2, LineFound = FALSE ;

    for(X1 = StartX ; X1 && XGetPixel(FloodImage, X1, StartY) == ReferencePixel ; X1--) {
        XPutPixel(FloodImage, X1, StartY, FillPixel) ;
    }

    for(X2 = StartX+1 ; X2 < Width && XGetPixel(FloodImage, X2, StartY) == ReferencePixel ; X2++) {
        XPutPixel(FloodImage, X2, StartY, FillPixel) ;
    }

    XDrawLine(Disp, Win, GCID, ++X1, StartY, --X2, StartY) ;

    if(--StartY >= 0) {
        for( ; X1 <= X2 ; X1++) {
            if(LineFound && XGetPixel(FloodImage, X1, StartY) != ReferencePixel) {
                LineFound = FALSE ;
            }
            else if(XGetPixel(FloodImage, X1, StartY) == ReferencePixel) {
                LineFound = True ;
                FloodUp(X1, StartY) ;
            }
        }
    }
}


FloodDown(StartX, StartY)

int     StartX, StartY ;

{
int     X1, X2, LineFound = FALSE ;

    for(X1 = StartX ; X1 && XGetPixel(FloodImage, X1, StartY) == ReferencePixel ; X1--) {
        XPutPixel(FloodImage, X2, StartY, FillPixel) ;
    }

    for(X2 = StartX+1 ; X2 < Width && XGetPixel(FloodImage, X2, StartY) == ReferencePixel ; X2++) {
        XPutPixel(FloodImage, X2, StartY, FillPixel) ;
    }

    XDrawLine(Disp, Win1, GCID, ++X1, StartY, --X2, StartY) ;

    if(++StartY < Height) {
        for( ; X1 <= X2 ; X1++) {
            if(LineFound && XGetPixel(FloodImage, X1, StartY) != ReferencePixel) {
                LineFound = FALSE ;
            }
            else if(XGetPixel(FloodImage, X1, StartY) == ReferencePixel) {
                LineFound = True ;
                FloodDown(X1, StartY) ;
            }
        }
    }
}
T.RTitleUserPersonal
Name
DateLines
2067.1The all new buggless hyper version of flood (ver 2.0)!WPOMM2::ZAMBOTTIWed Jan 24 1990 04:02120
Hi people,

while I'm on the subject of speeding up the flood rountine here is the code.

/*
    Flood a complex bordered region using the current foreground color.
    Flood starts at the given X, Y coordinate and floods all pixels of
    the same color as the starting pixel (@ X, Y).

    Because flood uses the XDrawSegments function to paint the area all the
    GC components that can be used for XDrawLine can be used for flood.
*/

unsigned long ReferencePixel, FillPixel ;
XImage        *FloodImage ;
int           Width, Height, RunCnt ;

typedef struct FillRunClass {
    int                 X1, X2, Y ;
    struct FillRunClass *Next ;
}   FillRunInstance ;

FillRunInstance *CurrentRun = NULL, *FirstRun = NULL, *NewRun ;

void flood(Disp, Win1, PaintGC, X, Y)

Display *Disp ;
Window  Win1 ;
GC      PaintGC ;

{
Window   RootWin ;
int      X1, X2, StartX, StartY, LineFound = FALSE, Width, Height, XPos, YPos, Border, Depth ;
XSegment *FillRuns ;

    XGetGeometry(Disp, Win, &RootWin, &XPos, &YPos, &Width, &Height, &Border, &Depth) ;
    FloodImage = XGetImage(Disp, Win, 0, 0, Width, Height, AllPlanes, ZPixmap) ;
    ReferencePixel = XGetPixel(FloodImage, X, Y) ;
    FillPixel = ~ReferencePixel ;
    RunCnt = 0 ;

    FindRuns(X, Y) ;

    FillRuns = (XSegment*)malloc(sizeof(XSegment)*RunCnt) ;
    for(RunCnt = 0 , CurrentRun = FirstRun ; CurrentRun != NULL ; CurrentRun = NewRun, RunCnt++) {
        FillRuns[RunCnt].x1 = CurrentRun->X1 ;
        FillRuns[RunCnt].x2 = CurrentRun->X2 ;
        FillRuns[RunCnt].y1 = FillRuns[RunCnt].y2 = CurrentRun->Y ;
        NewRun = CurrentRun->Next ;
        free(CurrentRun) ;
    }

    XDrawSegments(Disp, Win1, PaintGC, FillRuns, RunCnt) ;

    free(FillRuns) ;
}


FindRuns(StartX, StartY)

int     StartX, StartY ;

{
int     X1, X2, YAbove, YBelow, LineAboveFound = FALSE, LineBelowFound = FALSE ;
char    *ImagePixel, PixelValue ;

    ImagePixel = &(FloodImage->data[StartY*DeviceWidth+StartX]) ;
    for(X1 = StartX ; X1 && *ImagePixel == ReferencePixel ; X1--, ImagePixel--) {
        *ImagePixel = FillPixel ;
    }

    ImagePixel = &(FloodImage->data[StartY*DeviceWidth+StartX+1]) ;
    for(X2 = StartX+1 ; X2 < Width && *ImagePixel == ReferencePixel ; X2++, ImagePixel++) {
        *ImagePixel = FillPixel ;
    }

    NewRun = (FillRunInstance*)malloc(sizeof(FillRunInstance)) ;

    if(CurrentRun == NULL) {
        FirstRun = CurrentRun = NewRun ;
    }
    else {
        CurrentRun = CurrentRun->Next = NewRun ;
    }

    NewRun->X1 = ++X1 ;
    NewRun->X2 = --X2 ;
    NewRun->Y = StartY ;
    NewRun->Next = NULL ;
    RunCnt++ ;

    YAbove = StartY - 1 ;
    YBelow = StartY + 1 ;

    for(ImagePixel = &(FloodImage->data[StartY*DeviceWidth+X1]) ; X1 <= X2 ; X1++, ImagePixel++) {
        if(YAbove >= 0) {
            PixelValue = *(ImagePixel-DeviceWidth) ;

            if(LineAboveFound && PixelValue != ReferencePixel) {
                LineAboveFound = FALSE ;
            }
            else if(!LineAboveFound && PixelValue == ReferencePixel) {
                LineAboveFound = True ;
                FindRuns(X1, YAbove) ;
            }
        }

        if(YBelow < DeviceHeight) {
            PixelValue = *(ImagePixel+DeviceWidth) ;

            if(LineBelowFound && PixelValue != ReferencePixel) {
                LineBelowFound = FALSE ;
            }
            else if(!LineBelowFound && PixelValue == ReferencePixel) {
                LineBelowFound = True ;
                FindRuns(X1, YBelow) ;
            }
        }
    }
}