region.c

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

C
1,892
字号
        _free( Set_coll.coll );
    }

    Set_coll.num_sets = 0;
    Set_coll.num_used = 0;
    Set_coll.coll = NULL;
}


HANDLE rgn_end(
/*************/
    void
) {
    HANDLE          hld;
    HANDLE          rgn_hld;
    rgn_tag_def *   tag;
    char far *      ptr;
    char far *      src;
    long            size;

    if( Curr_state != RGN_STATE_OFF && Region_list != NULL ) {
        /* allocate the contigous block of memory */
        size = sizeof(rgn_tag_def) + get_set_coll_size() + Region_used_size;
        hld = GlobalAlloc( GMEM_MOVEABLE, size );

        /* copy the pieces */
        if( hld != NULL ) {
            ptr = (char far *)GlobalLock( hld );
            tag = (rgn_tag_def *) ptr;
            ptr += sizeof(rgn_tag_def);
            tag->set_coll_offset = _get_offset( tag, ptr );
            ptr = (char far *) copy_set_coll( (char *) ptr );
            tag->rgn_offset = _get_offset( tag, ptr );
            tag->rgn_size = Region_used_size;
            src = _ptr_add( Region_list, Region_size - Region_used_size );
            _fmemcpy( ptr, src, Region_used_size );
            GlobalUnlock( hld );
        }

        /* free up unneed memory */
        rgn_hld = (HANDLE) _wpi_getglobalhdl( (DWORD) Region_list );
        GlobalUnlock( rgn_hld );
        GlobalFree( rgn_hld );
        Region_list = NULL;
        free_set_coll();
    } else {
        hld = NULL;
    }

    return( hld );
}

static rgn_def far * get_rgn_list_ptr(
/************************************/
    int                 size
) {
    HANDLE                  hld;
    rgn_def far            *ret;
    rgn_def far            *src;
    rgn_def far            *dst;
    rgn_def far            *ptr;

    if (Region_list == NULL) {
        Region_size = BLOCK_SIZE;
        hld = GlobalAlloc( GMEM_MOVEABLE, (Region_size + sizeof(short)) );
        Region_list = (rgn_def far *)GlobalLock( hld );
    }

    if (Region_size < Region_used_size + size) {
        src = (rgn_def far *)((long)Region_list + Region_size -
                                                        Region_used_size);
        if (size > BLOCK_SIZE) {
            Region_size += size;
        } else {
            Region_size += BLOCK_SIZE;
        }
        hld = GlobalAlloc( GMEM_MOVEABLE, (Region_size + sizeof(short)) );
        ptr = (rgn_def far *)GlobalLock( hld );
        dst = (rgn_def far *)((long)ptr + Region_size - Region_used_size);
        _fmemmove( dst, src, Region_used_size );
        GlobalUnlock( _wpi_getglobalhdl( Region_list ) );
        GlobalFree( _wpi_getglobalhdl( Region_list ) );
        Region_list = ptr;
    }

    Region_used_size += size;
    ret = (rgn_def far *)((long)Region_list + Region_size - Region_used_size);

    return( ret );
}

BOOL rgn_is_on(
/*************/

) {
    return( Curr_state == RGN_STATE_ON );
}

void rgn_set_ids(
/***************/

    int                 major_id,
    int                 minor_id,
    int                 data_row,
    int                 data_col
) {
    Major_id = major_id;
    Minor_id = minor_id;
    Data_row = data_row;
    Data_col = data_col;
}

static void get_rect(
/*******************/
    WPI_POINT far       *pts,
    int                 num_pts,
    WPI_RECT far        *rect
) {
    int                 count;
    int                 left, right, top, bottom;

    _wpi_setintrectvalues( (WPI_RECT *) rect,
                        pts[0].x, pts[0].y, pts[0].x, pts[0].y );

    for (count = 1; count < num_pts; count++) {
        _wpi_getintrectvalues( *rect, &left, &top, &right, &bottom );
        if (pts[count].x < left) {
            _wpi_setintrectvalues( (WPI_RECT *) rect,
                        pts[count].x, top, right, bottom );
            _wpi_getintrectvalues( *rect, &left, &top, &right, &bottom );
        }
        if (pts[count].x > right) {
            _wpi_setintrectvalues( (WPI_RECT *) rect,
                        left, top, pts[count].x, bottom );
            _wpi_getintrectvalues( *rect, &left, &top, &right, &bottom );
        }
        if (pts[count].y < top) {
            _wpi_setintrectvalues( (WPI_RECT *) rect,
                        left, pts[count].y, right, bottom );
            _wpi_getintrectvalues( *rect, &left, &top, &right, &bottom );
        }
        if (pts[count].y > bottom) {
            _wpi_setintrectvalues( (WPI_RECT *) rect,
                        left, top, right, pts[count].y );
        }
    }
}

void rgn_rectangle(
/*****************/

    int                 x1,
    int                 y1,
    int                 x2,
    int                 y2
) {
    rgn_def far         *curr;
    WPI_POINT           pts[2];
    unsigned short      size;

    if( Curr_state == RGN_STATE_ON ) {
        size =  sizeof(rgn_info_def) + sizeof(rgn_rect_def);
        curr = get_rgn_list_ptr( size );
        if (curr != NULL) {
            curr->info.size = size;
            curr->info.type = CGR_RGN_RECT;
            curr->info.major_id = Major_id;
            curr->info.minor_id = Minor_id;
            curr->info.data_row = Data_row;
            curr->info.data_col = Data_col;
            pts[0].x = x1;
            pts[0].y = y1;
            pts[1].x = x2;
            pts[1].y = y2;
            get_rect( pts, 2, &(curr->data.rect.rect) );
            if (Set_state != RGN_REGULAR) {
                curr->info.set_num = Set_curr;
                if (Set_state == RGN_GROUP || Set_state == RGN_MAN_GROUP) {
                    rgn_group_add();
                }
            } else {
                curr->info.set_num = -1;
            }
        }
    }
}

void rgn_ellipse_set(
/*******************/
    int                 x1,
    int                 y1,
    int                 x2,
    int                 y2,
    rgn_type            type_ellipse
) {
    rgn_def far         *curr;
    WPI_POINT           pts[2];
    unsigned short      size;

    if( Curr_state == RGN_STATE_ON ) {
        size =  sizeof(rgn_info_def) + sizeof(rgn_ellipse_def);
        curr = get_rgn_list_ptr( size );
        if (curr != NULL) {
            curr->info.size = size;
            curr->info.type = type_ellipse;
            curr->info.major_id = Major_id;
            curr->info.minor_id = Minor_id;
            curr->info.data_row = Data_row;
            curr->info.data_col = Data_col;
            pts[0].x = x1;
            pts[0].y = y1;
            pts[1].x = x2;
            pts[1].y = y2;
            get_rect( pts, 2, &(curr->data.ellipse.rect) );
            if (Set_state != RGN_REGULAR) {
                curr->info.set_num = Set_curr;
                if (Set_state == RGN_GROUP || Set_state == RGN_MAN_GROUP) {
                    rgn_group_add();
                }
            } else {
                curr->info.set_num = -1;
            }
        }
    }
}

void rgn_ellipse(
/***************/
    int                 x1,
    int                 y1,
    int                 x2,
    int                 y2
) {
    rgn_ellipse_set( x1, y1, x2, y2, CGR_RGN_ELLIPSE );
}

void rgn_ellipse_border(
/**********************/
    int                 x1,
    int                 y1,
    int                 x2,
    int                 y2
) {
    rgn_ellipse_set( x1, y1, x2, y2, CGR_RGN_ELLIPSE_BORDER );
}


void rgn_line(
/************/

    int                 x1,
    int                 y1,
    int                 x2,
    int                 y2
) {
    rgn_def far        *curr;
    unsigned short      size;

    if( Curr_state == RGN_STATE_ON ) {
        size =  sizeof(rgn_info_def) + sizeof(rgn_line_def);
        curr = get_rgn_list_ptr( size );
        if (curr != NULL) {
            curr->info.size = size;
            curr->info.type = CGR_RGN_LINE;
            curr->info.major_id = Major_id;
            curr->info.minor_id = Minor_id;
            curr->info.data_row = Data_row;
            curr->info.data_col = Data_col;
            curr->data.line.p1.x = x1;
            curr->data.line.p1.y = y1;
            curr->data.line.p2.x = x2;
            curr->data.line.p2.y = y2;
            if (Set_state != RGN_REGULAR) {
                curr->info.set_num = Set_curr;
                if (Set_state == RGN_GROUP || Set_state == RGN_MAN_GROUP) {
                    rgn_group_add();
                }
            } else {
                curr->info.set_num = -1;
            }
        }
    }
}

void rgn_polygon(
/***************/

    WPI_POINT far       *pts,
    int                 num_pts
) {
    int                 count;
    rgn_def far         *curr;
    unsigned short      size;

    if( Curr_state == RGN_STATE_ON ) {
        size = sizeof(rgn_info_def) + sizeof(int) + (sizeof(WPI_POINT) * num_pts);
        curr = get_rgn_list_ptr( size );
        if (curr != NULL) {
            curr->info.size = size;
            curr->info.type = CGR_RGN_POLY;
            curr->info.major_id = Major_id;
            curr->info.minor_id = Minor_id;
            curr->info.data_row = Data_row;
            curr->info.data_col = Data_col;
            curr->data.poly.num_pts = num_pts;
            for (count = 0; count < num_pts; count++) {
                curr->data.poly.pts[count].x = pts[count].x;
                curr->data.poly.pts[count].y = pts[count].y;
            }
            if (Set_state != RGN_REGULAR) {
                curr->info.set_num = Set_curr;
                if (Set_state == RGN_GROUP || Set_state == RGN_MAN_GROUP) {
                    rgn_group_add();
                }
            } else {
                curr->info.set_num = -1;
            }
        }
    }
}

void rgn_pie(
/***********/

    int                 x1,
    int                 y1,
    int                 x2,
    int                 y2,
    int                 x3,
    int                 y3,
    int                 x4,
    int                 y4
) {
    rgn_def far        *curr;
    unsigned short      size;

    if( Curr_state == RGN_STATE_ON ) {
        size = sizeof(rgn_info_def) + sizeof(rgn_pie_def);
        curr = get_rgn_list_ptr( size );
        if (curr != NULL) {
            curr->info.size = size;
            curr->info.type = CGR_RGN_PIE;
            curr->info.major_id = Major_id;
            curr->info.minor_id = Minor_id;
            curr->info.data_row = Data_row;
            curr->info.data_col = Data_col;
            curr->data.pie.pie_pts[0].x = x1;
            curr->data.pie.pie_pts[0].y = y1;
            curr->data.pie.pie_pts[1].x = x2;
            curr->data.pie.pie_pts[1].y = y2;
            curr->data.pie.pie_pts[2].x = x3;
            curr->data.pie.pie_pts[2].y = y3;
            curr->data.pie.pie_pts[3].x = x4;
            curr->data.pie.pie_pts[3].y = y4;
            if (Set_state != RGN_REGULAR) {
                curr->info.set_num = Set_curr;
                if (Set_state == RGN_GROUP || Set_state == RGN_MAN_GROUP) {
                    rgn_group_add();
                }
            } else {
                curr->info.set_num = -1;
            }
        }
    }
}

void rgn_line_boxes(
/******************/

    int                 x1,
    int                 y1,
    int                 x2,
    int                 y2
) {
    rgn_def far        *curr;
    unsigned short      size;

    if( Curr_state == RGN_STATE_ON ) {
        size =  sizeof(rgn_info_def) + sizeof(rgn_line_def);
        curr = get_rgn_list_ptr( size );
        if (curr != NULL) {
            curr->info.size = size;
            curr->info.type = CGR_RGN_LINE_BOXES;
            curr->info.major_id = Major_id;
            curr->info.minor_id = Minor_id;
            curr->info.data_row = Data_row;
            curr->info.data_col = Data_col;
            curr->data.line_boxes.p1.x = x1;
            curr->data.line_boxes.p1.y = y1;
            curr->data.line_boxes.p2.x = x2;
            curr->data.line_boxes.p2.y = y2;
            if (Set_state != RGN_REGULAR) {
                curr->info.set_num = Set_curr;
                if (Set_state == RGN_GROUP || Set_state == RGN_MAN_GROUP) {
                    rgn_group_add();
                }
            } else {
                curr->info.set_num = -1;
            }
        }
    }
}

static BOOL check_in_ellipse(
/***************************/
    WPI_RECT far    *rect,
    int             x,
    int             y
) {
    WPI_POINT       cen;
    long            a_sqr;
    long            b_sqr;
    int             left, right, top, bottom;

    _wpi_getintrectvalues( *rect, &left, &top, &right, &bottom );
    cen.x = (right + left) / 2;
    cen.y = (bottom + top) / 2;

    a_sqr = sqr( (right - left) / 2 );
    b_sqr = sqr( (bottom - top) / 2 );

    return( (b_sqr * (a_sqr - sqr( x - cen.x ))) >
                                    a_sqr * sqr( y - cen.y ) );
}

static BOOL check_in_line(
/************************/
    rgn_line_def far       *line,
    int                     x,
    int                     y
) {
    WPI_POINT               pt;
    WPI_POINT               rot_pt;
    int                     rad;

    pt.x = line->p2.x - line->p1.x;
    pt.y = line->p2.y - line->p1.y;
    x -= line->p1.x;
    y -= line->p1.y;

    rad = sqrt( sqr( pt.x ) + sqr( pt.y ) );
    if (rad != 0) {
        rot_pt.x = ((long)x * pt.x + (long)y * pt.y) / rad;
        rot_pt.y = ((long)y * pt.x - (long)x * pt.y) / rad;
        if( (rot_pt.x <= rad) && (rot_pt.x >= 0) &&
                                        (abs( rot_pt.y ) <= LINE_ZONE_SIZE) ) {
            return( TRUE );
        }
    } else if( x == 0 && y == 0 ) {
        return( TRUE );
    }

    return( FALSE );
}

static int next_idx(
/******************/

    int                 idx,
    int                 size
) {
    ++idx;
    if( idx == size ) {
        idx = 0;
    }

    return( idx );
}

static BOOL check_in_polygon(
/***************************/

    int                 num_pts,

⌨️ 快捷键说明

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