region.c

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

C
1,892
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


/*
 Description:
 ============
    Pick 'n poke region stuff.


*/

#ifdef PLAT_OS2
#define INCL_PM
#include <os2.h>
#else
#include <windows.h>
#endif

#ifndef PROD
#define  TRACK_MEM
#endif

#include "mem.h"

#include "wpi.h"
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "region.h"
#include "cgrids.h"


#define MAG_OVERFLOW                    100000
#define BLOCK_SIZE                      100
#define MARK_SIZE                       3
#define VECTOR_FUZZ                     3
#define VECTOR_COEF                     100.0
#define LINE_ZONE_SIZE                  3
#define PI                              3.14159265
#define COLL_BLOCKS                     10
#define LIST_BLOCKS                     10
#define RGN_ELLIPSE_BWIDTH              3

#define _get_offset( top, ptr ) ((unsigned short) \
                                ((char *)(ptr) - (char *) top))
#define _ptr_add( ptr, amnt ) ((void *)((char *)(ptr) + (amnt)) )


enum {
    RGN_STATE_OFF,
    RGN_STATE_ON,
    RGN_STATE_DISABLED
};

enum {
    RGN_REGULAR,
    RGN_GROUP,
    RGN_SET,
    RGN_MAN_GROUP,
    RGN_MAN_SET
};

static rgn_def far                 *Region_list;
static unsigned short               Region_size;
static unsigned short               Region_used_size;
static int                          Curr_state;

static int                          Set_state;
static rgn_set_coll                 Set_coll;       // collection of sets
static int                          Set_curr;

static int                          Major_id;
static int                          Minor_id;
static int                          Data_row;
static int                          Data_col;

#define sqr( xxx )      ((long)(xxx) * (long)(xxx))
#define sgn( xxx )      (((xxx) == 0) ? 0 : (xxx) / abs( xxx ))

static BOOL is_pt_in_rect(
/************************/
    WPI_RECT            *rect,
    WPI_POINT           pt
) {
    int                 left, right, top, bottom;

    _wpi_getintrectvalues( *rect, &left, &top, &right, &bottom );
    return( pt.x >= left && pt.x <= right && pt.y >= top && pt.y <= bottom  );
}

void rgn_off(
/***********/

) {
    Curr_state = RGN_STATE_OFF;
}

void rgn_on(
/**********/

) {
    Curr_state = RGN_STATE_ON;
}

int rgn_disable(
/**************/

) {
    int         old_state;

    old_state = Curr_state;
    if( Curr_state != RGN_STATE_OFF ) {
        Curr_state = RGN_STATE_DISABLED;
    }

    return( old_state );
}

void rgn_enable(
/**************/

    int                 state
) {
    if( Curr_state != RGN_STATE_OFF ) {
        Curr_state = state;
    }
}

static int get_new_rgn_set(
/*************************/
    void
) {
    rgn_set_def **  old_sets;
    int             set_num;

    if( Set_coll.coll == NULL ) {
        _new( Set_coll.coll, COLL_BLOCKS );
        Set_coll.num_sets = COLL_BLOCKS;
        Set_coll.num_used = 0;
        for( set_num = 0; set_num < COLL_BLOCKS; set_num++ ) {
            Set_coll.coll[ set_num ] = NULL;
        }
    }

    if( Set_coll.num_used >= Set_coll.num_sets ) {
        old_sets = Set_coll.coll;
        _renew( Set_coll.coll, Set_coll.num_sets + COLL_BLOCKS );
        if( Set_coll.coll == NULL ) {
            Set_coll.coll = old_sets;
            return( -1 );
        } else {
            for( set_num = Set_coll.num_sets; set_num < Set_coll.num_sets +
                            COLL_BLOCKS; set_num++ ) {
                Set_coll.coll[ set_num ] = NULL;
            }
            Set_coll.num_sets += COLL_BLOCKS;
        }
    }

    Set_coll.num_used++;

    return( Set_coll.num_used - 1 );
}

static rgn_set_def * get_rgn_set_ptr(
/***********************************/
    int             set_num
) {
    rgn_set_def **  coll;

    if( set_num < Set_coll.num_used ) {
        coll = Set_coll.coll;
        if( coll[ set_num ] == NULL ) {
            coll[ set_num ] = _galloc( sizeof(rgn_set_header_def) +
                        LIST_BLOCKS * sizeof(rgn_set_list_def) );
            if( coll[ set_num ] != NULL ) {
                coll[ set_num ]->info.num_items = LIST_BLOCKS;
                coll[ set_num ]->info.num_used = 0;
            }
        }
        return( coll[ set_num ] );
    } else {
        return( NULL );
    }
}

static void set_rgn_set_ptr(
/**************************/
    int                 set_num,
    rgn_set_def *       curr
) {
    if( set_num < Set_coll.num_used ) {
        Set_coll.coll[ set_num ] = curr;
    }
}

static void add_rgn_def(
/**********************/
    int                 set_num,
    rgn_set_list_def *  new_def
) {
    rgn_set_def *       curr;

    curr = get_rgn_set_ptr( set_num );
    if( curr != NULL ) {
        if( curr->info.num_used >= curr->info.num_items ) {
            _grenew( curr, curr->info.num_items + LIST_BLOCKS );
            if( curr == NULL ) {
                return;
            }
            set_rgn_set_ptr( set_num, curr );
            curr->info.num_items += LIST_BLOCKS;
        }
        curr->list[ curr->info.num_used ] = *new_def;
        curr->info.num_used++;
    }
}

void rgn_begin_group(
/******************/
) {
    rgn_set_def far        *curr;

    if ((Curr_state == RGN_STATE_ON) && (Set_state == RGN_REGULAR)) {
        Set_curr = get_new_rgn_set();
        if( Set_curr == -1 ) {
            return;
        }

        Set_state = RGN_GROUP;

        curr = get_rgn_set_ptr( Set_curr );
        curr->info.exact = FALSE;
    }
}

static void rgn_group_add(
/************************/
) {
    rgn_set_list_def    curr;

    curr.offset = Region_used_size;
    add_rgn_def( Set_curr, &curr );
}

void rgn_end_group(
/*****************/
) {
    if ((Curr_state == RGN_STATE_ON) && (Set_state == RGN_GROUP)) {
        Set_state = RGN_REGULAR;
    }
}

void rgn_begin_set(
/*****************/
) {
    rgn_set_def far        *curr;

    if ((Curr_state == RGN_STATE_ON) && (Set_state == RGN_REGULAR)) {
        Set_curr = get_new_rgn_set();
        if( Set_curr == -1 ) {
            return;
        }

        Set_state = RGN_SET;

        curr = get_rgn_set_ptr( Set_curr );
        curr->info.exact = TRUE;
    }
}

void rgn_set_add(
/***************/
    WPI_POINT               *pt
) {
    rgn_set_list_def        curr;

    if ((Curr_state == RGN_STATE_ON) &&
                (Set_state == RGN_SET || Set_state == RGN_MAN_SET)) {
        curr.pt = *pt;
        add_rgn_def( Set_curr, &curr );
    }
}

void rgn_end_set(
/***************/
) {
    if ((Curr_state == RGN_STATE_ON) && (Set_state == RGN_SET)) {
        Set_state = RGN_REGULAR;
    }
}

extern int rgn_man_group_new(
/***************************/
    void
) {
    int                 group_num;
    rgn_set_def far     *curr;

    if( Curr_state == RGN_STATE_ON ) {
        group_num = get_new_rgn_set();
        curr = get_rgn_set_ptr( group_num );
        curr->info.exact = FALSE;
    } else {
        group_num = -1;
    }

    return( group_num );
}

extern void rgn_man_group_begin(
/******************************/
    int     group_num
) {
    if( (Curr_state == RGN_STATE_ON) && (Set_state == RGN_REGULAR) ) {
        if( 0 <= group_num && group_num < Set_coll.num_used ) {
            Set_state = RGN_MAN_GROUP;
            Set_curr = group_num;
        }
    }
}

extern void rgn_man_group_end(
/****************************/
    void
) {
    if( (Curr_state == RGN_STATE_ON) && (Set_state == RGN_MAN_GROUP) ) {
        Set_state = RGN_REGULAR;
    }
}

extern int rgn_man_set_new(
/*************************/
    void
) {
    int                 group_num;
    rgn_set_def far     *curr;

    if( Curr_state == RGN_STATE_ON ) {
        group_num = get_new_rgn_set();
        curr = get_rgn_set_ptr( group_num );
        curr->info.exact = TRUE;
    } else {
        group_num = -1;
    }

    return( group_num );
}

extern void rgn_man_set_begin(
/****************************/
    int     set_num
) {
    if( (Curr_state == RGN_STATE_ON) && (Set_state == RGN_REGULAR) ) {
        if( 0 <= set_num && set_num < Set_coll.num_used ) {
            Set_state = RGN_MAN_SET;
            Set_curr = set_num;
        }
    }
}

extern void rgn_man_set_end(
/**************************/
    void
) {
    if( (Curr_state == RGN_STATE_ON) && (Set_state == RGN_MAN_SET) ) {
        Set_state = RGN_REGULAR;
    }
}

void rgn_begin(
/*************/

) {
    if( Curr_state != RGN_STATE_OFF ) {
        Region_size = 0;
        Region_used_size = 0;
        Region_list = NULL;

        Set_state = RGN_REGULAR;
        Set_coll.num_sets = 0;
        Set_coll.num_used = 0;
        Set_coll.coll = NULL;
        Set_curr = 0;
    }
}

static long get_set_coll_size(
/****************************/
    void
) {
    long            size;
    rgn_set_def **  curr_set;

    /* room for the rgn_set_index */
    size = sizeof(rgn_set_coll_header) + Set_coll.num_used * sizeof(short);

    for( curr_set = Set_coll.coll; curr_set < Set_coll.coll +
            Set_coll.num_used; curr_set++ ) {
        size += sizeof(rgn_set_header_def) +
                    (**curr_set).info.num_used * sizeof(rgn_set_list_def);
    }

    return( size );
}

static char * copy_set_coll(
/**************************/
    char *          ptr
) {
    rgn_set_index * index;
    rgn_set_def *   curr_set;
    int             set_num;
    int             set_size;

    index = (rgn_set_index *) ptr;
    index->info.num_sets = Set_coll.num_used;
    ptr += sizeof(rgn_set_coll_header) + Set_coll.num_used * sizeof(short);

    for( set_num = 0; set_num < Set_coll.num_used; set_num++ ) {
        index->offset[ set_num ] = _get_offset( index, ptr );
        curr_set = Set_coll.coll[ set_num ];
        set_size = sizeof(rgn_set_header_def) +
                    curr_set->info.num_used * sizeof(rgn_set_list_def);
        memcpy( ptr, curr_set, set_size );
        ptr += set_size;
    }

    return( ptr );
}

static void free_set_coll(
/************************/
    void
) {
    rgn_set_def **      curr_set;

    if( Set_coll.coll != NULL ) {
        for( curr_set = Set_coll.coll; curr_set < Set_coll.coll +
                Set_coll.num_used; curr_set++ ) {
            if( *curr_set != NULL ) {
                _gfree( *curr_set );
            }
        }

⌨️ 快捷键说明

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