l1fillar.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 542 行 · 第 1/2 页

C
542
字号
                    }
                } else {    // no upward extension
                    line->delete = TRUE;    // mark line to be deleted
                    continue;
                }
            }
            // Replace the current line segment with the line segment
            // from p1 to p2. Preserve the current left and right extensions.
            old_left = line->line.left_x;
            old_right = line->line.right_x;
            _LineInit( points[ p1 ].xcoord, points[ p1 ].ycoord,
                       points[ p2 ].xcoord, points[ p2 ].ycoord, &line->line );
            line->end_pt = p2;
            if( old_left < line->line.left_x ) {
                line->line.left_x = old_left;
            }
            if( old_right > line->line.right_x ) {
                line->line.right_x = old_right;
            }
        }
    }
}


static void PlotBetween( short y )
//================================

{
    struct seg_entry    *curr;
    struct seg_entry    *next;
    short               left_x;
    short               right_x;

    for( curr = LineList; curr != NULL; ) {
        next = curr->link;
        left_x = min( curr->line.left_x, next->line.left_x );
        right_x = max( curr->line.right_x, next->line.right_x );
        _L1ClipFill( left_x, right_x, y );
        curr = next->link;
    }
}


static void UpdateLines( void )
//=======================

//  Delete lines with no upward extension. These lines were previously
//  flagged by ExtendLines().

{
    struct seg_entry    *curr;
    struct seg_entry    *next;
    struct seg_entry    *prev;
    short               curr_x;
    short               re_sort;

    curr_x = 0;
    re_sort = FALSE;
    for( curr = LineList; curr != NULL; ) {
        next = curr->link;
        if( curr->delete ) {
            if( curr == LineList ) {
                LineList = next;
            } else {
                prev->link = next;
            }
            curr->link = FreeList;      // free element by adding to free list
            FreeList = curr;
        } else {
            _LineMove( &curr->line );
            if( curr->line.curr_x < curr_x ) {
                re_sort = TRUE;     // need to re-sort the line segments
            }
            curr_x = curr->line.curr_x;
            prev = curr;
        }
        curr = next;
    }
    if( re_sort ) {
        OrderLines();
    }
}


static short InitLineList( void )
//=========================

{
    short               max_lines;
    short               i;

    Stack += NumMinima * sizeof( short );
    StackSize -= NumMinima * sizeof( short );
    max_lines = StackSize / sizeof( struct seg_entry );
    if( max_lines < 2 ) {   // need at least 2, since we have 2 for each min
        _ErrorStatus = _GRINSUFFICIENTMEMORY;
        return( FALSE );
    }
    LineList = NULL;
    FreeList = (struct seg_entry *) Stack;  // initialize free list
    for( i = 0; i < max_lines - 1; ++i ) {
        FreeList[ i ].link = &FreeList[ i + 1 ];
    }
    FreeList[ max_lines - 1 ].link = NULL;
    return( TRUE );
}

#elif defined( __OS2__ )
    #include <limits.h>
#endif


short _L1FillArea( short n, struct xycoord _WCI86FAR *points )
//=======================================================

{
#if defined( _DEFAULT_WINDOWS )
    WPI_PRES            dc;
    HBITMAP             bm;
    HBRUSH              brush;
    HBRUSH              old_brush;
    HPEN                pen;
    HPEN                old_pen;
    HRGN                temprgn;
    WPI_COLOUR          color;
    WPI_RECT            clip_rect;
    short               clipy1, clipy2;
  #if defined( __WINDOWS__ )
    HRGN                Refresh;
  #else
    WPI_POINT*          stack;
    short               i;
    WPI_RECTDIM         minx, miny;
    WPI_RECTDIM         maxx, maxy;
  #endif
#else
    short               y;
    short               next_min;
#endif

    short               success;

#if defined( _DEFAULT_WINDOWS )
    dc = _Mem_dc;

// Do the clipping
    temprgn = _ClipRgn;
    clipy1 = _wpi_cvth_y( _CurrState->clip_def.ymin, _GetPresHeight() );
    clipy2 = _wpi_cvth_y( _CurrState->clip_def.ymax + 1, _GetPresHeight() );
    _wpi_setintwrectvalues( &clip_rect,
                           _CurrState->clip_def.xmin, clipy1,
                           _CurrState->clip_def.xmax + 1, clipy2 );
    _ClipRgn = _wpi_createrectrgn( dc, &clip_rect );
    _wpi_getclipbox( dc, &clip_rect);
    _wpi_selectcliprgn( dc, _ClipRgn );
    _wpi_deletecliprgn( dc, temprgn );

// setup before drawing
    color = _Col2RGB( _CurrColor );
    pen = _wpi_createpen( PS_NULL, 0, color );

    if( _HaveMask == 0 ) {
        brush = _wpi_createsolidbrush( color );
    } else {
        // if a mask is defined, convert it to bitmap
        bm = _Mask2Bitmap( dc, &_FillMask );
        brush = _wpi_createpatternbrush( bm );
    }

    old_pen = _wpi_selectpen( dc, pen );
    old_brush = _wpi_selectbrush( dc, brush );
  #if defined( __OS2__ )
    minx = miny = LONG_MAX;
    maxx = maxy = LONG_MIN;
    stack = _MyAlloc( n * sizeof( WPI_POINT ) );
    for( i = 0; i < n; i++ ) {
        stack[i].x = points[i].xcoord;
        stack[i].y = _wpi_cvth_y( points[i].ycoord, _GetPresHeight() );
        if( minx > points[i].xcoord ) {
            minx = points[i].xcoord;
        }
        if( miny > points[i].ycoord ) {
            miny = points[i].ycoord;
        }
        if( maxx < points[i].xcoord ) {
            maxx = points[i].xcoord;
        }
        if( maxy < points[i].ycoord ) {
            maxy = points[i].ycoord;
        }
    }
    _wpi_polygon( dc, stack, n );
    _MyFree( stack );
  #else
    _wpi_polygon( dc, (LPPOINT)points, n );
  #endif

// Clean up afterwards
    _wpi_getoldbrush( dc, old_brush );
    _wpi_deletebrush( brush );

    if( _HaveMask != 0 ) {
        _wpi_deletebitmap( bm );
    }

    _wpi_getoldpen( dc, old_pen );
    _wpi_deletepen( pen );

    temprgn = _ClipRgn;
    _ClipRgn = _wpi_createrectrgn( dc, &clip_rect );
    _wpi_selectcliprgn( dc, _ClipRgn );
    _wpi_deletecliprgn( dc, temprgn );

// Update the window
  #if defined( __WINDOWS__ )
    Refresh = CreatePolygonRgn( (LPPOINT)points, n, ALTERNATE );
    OffsetRgn( Refresh, -_BitBlt_Coord.xcoord, -_BitBlt_Coord.ycoord );
    InvalidateRgn( _CurrWin, Refresh, 0 );
  #else
    _MyInvalidate( minx, miny, maxx, maxy );
    _wpi_invalidaterect( _CurrWin, NULL, 0 );
  #endif
    _RefreshWindow();
  #if defined( __WINDOWS__ )
    DeleteObject( Refresh );
  #endif
    success = TRUE;

#else
    StackSize = _RoundUp( _stackavail() - 0x100 );  // obtain memory from stack
    if( StackSize > 0 ) {
        Stack = __alloca( StackSize );
    } else {
        _ErrorStatus = _GRINSUFFICIENTMEMORY;
        return( FALSE );
    }
    MinList = (short *)Stack;
    CalcMinima( n, points );
    if( NumMinima == 0 ) {
        return( FALSE );
    }
    if( !InitLineList() ) {
        return( FALSE );
    }
    y = points[ MinList[ 0 ] ].ycoord;
    next_min = y;
    _StartDevice();
    for( ; ; ++y ) {
        if( y == next_min ) {
            success = AddMinima( y, n, points );
            if( !success ) {
                break;
            }
            if( NumMinima == 0 ) {
                next_min = y - 1;
            } else {
                next_min = points[ MinList[ 0 ] ].ycoord;
            }
        }
        if( LineList == NULL ) {
            break;
        }
        ExtendLines( y, n, points );
        PlotBetween( y );
        UpdateLines();
    }
    _ResetDevice();
#endif
    return( success );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?