gtedges.cpp

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

CPP
512
字号
/****************************************************************************
*
*                            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!
*
****************************************************************************/


#include "gtbase.h"
#include "gtring.h"
#include "gtedges.h"
#include "assure.h"

const int HSKIP = 5;
const int VSKIP = 5;

const int POOLSIZE = 64;

MemoryPool TreeLine::_pool( sizeof( TreeLine ), "TreeLine", POOLSIZE );

TreeLine::TreeLine( TreeCoord _x1, TreeCoord _y1,
                    TreeCoord _x2, TreeCoord _y2,
                    LineType lineType )

    : _lineCoords( _x1, _y1, _x2, _y2 )
    , _lineType( lineType )
    , _pBrokenLineList( NULL )
//-----------------------------------------------
{
}

TreeLine::TreeLine()
    : _lineCoords( 0, 0, 0, 0 )
    , _lineType( TreeLine::Edge )
    , _pBrokenLineList( NULL )
//-------------------------------
{
}

TreeLine::~TreeLine()
{
    if( _pBrokenLineList ) {
        purgeList();
    }
}

void * TreeLine::operator new( size_t )
//-------------------------------------
{
    return( _pool.alloc() );
}

void TreeLine::operator delete( void * mem )
//------------------------------------------
{
    _pool.free( mem );
}

void TreeLine::purgeList( void )
//------------------------------
{
    int i;

    if( _pBrokenLineList ) {
        for( i = _pBrokenLineList->count() - 1; i >= 0; i -= 1 ) {
            delete (*_pBrokenLineList)[ i ];
        }
        _pBrokenLineList->reset();
        delete _pBrokenLineList;
        _pBrokenLineList = NULL;
    }
}

void TreeLine::set( TreeCoord _x1, TreeCoord _y1,
                    TreeCoord _x2, TreeCoord _y2,
                    LineType lineType )
//-----------------------------------------------
{
    _lineCoords.x1 = _x1;
    _lineCoords.x2 = _x2;
    _lineCoords.y1 = _y1;
    _lineCoords.y2 = _y2;
    _lineType = lineType;
}

void TreeLine::addSeg( TreeCoord x1, TreeCoord y1,
                       TreeCoord x2, TreeCoord y2 )
//-------------------------------------------------
{
    if( _pBrokenLineList == NULL ) {
        _pBrokenLineList = new TreeLineCoordList;
    }

    _pBrokenLineList->add( new TreeLineCoords( x1, y1, x2, y2 ));
}

TreeLine::LineType TreeLine::getLineType( void )
//----------------------------------------------
{
    return( _lineType );
}

bool TreeLine::isBroken( void )
//-----------------------------
{
    return( _pBrokenLineList != NULL );
}

void TreeLine::paint( OutputDevice *dev, TreeCoord xOff, TreeCoord yOff )
//-----------------------------------------------------------------------
{
    // NYI -- figure out paintinfo stuff (bandage)
    PaintInfo   pinf;
    PaintInfo * oPinf;

    oPinf = dev->getPaintInfo();

    if( oPinf == NULL ) {
        dev->setPaintInfo( &pinf );
    }

    if( _pBrokenLineList != NULL ) {
        int i;

        for( i = 0; i < _pBrokenLineList->count(); i += 1 ) {
            dev->moveTo( ( *_pBrokenLineList )[ i ]->x1 - xOff,
                         ( *_pBrokenLineList )[ i ]->y1 - yOff );
            dev->lineTo( ( *_pBrokenLineList )[ i ]->x2 - xOff,
                         ( *_pBrokenLineList )[ i ]->y2 - yOff );
        }
    } else {
        dev->moveTo( _lineCoords.x1 - xOff, _lineCoords.y1 - yOff );
        dev->lineTo( _lineCoords.x2 - xOff, _lineCoords.y2 - yOff );
    }

    dev->setPaintInfo( oPinf );
}

////////////////////////// TreeEdgeBreaker ///////////////////////////////

void TreeEdgeBreaker::addLine( TreeLine * _line )
//----------------------------------------------------------------------
// Categorize lines as_vertical or _horizontal
//
// isNodeLine indicates whether or not the line should be able to be
// broken -- for example, borders for nodes should remain intact
//
{
    ASSERT((( _line->_lineCoords.y1 == _line->_lineCoords.y2 ) ||
            ( _line->_lineCoords.x1 == _line->_lineCoords.x2 )),
           "Edge is neither H nor V\n", 0 );

    if( _line->_lineCoords.y1 == _line->_lineCoords.y2 ) {
        _horizontalLines.add( _line );
    } else {
        if( _line->_lineCoords.x1 == _line->_lineCoords.x2 ) {
            _verticalLines.add( _line );
        }
    }
}

void TreeEdgeBreaker::purgeContents( void )
//----------------------------------------
{
    int i;

    for( i = _verticalLines.count() - 1; i >= 0; i -= 1 ) {
        _verticalLines[ i ]->purgeList();
    }

    for( i = _horizontalLines.count() - 1; i >= 0; i -= 1 ) {
        _horizontalLines[ i ]->purgeList();
    }

    _verticalLines.reset();
    _horizontalLines.reset();

    _horizontalSorted = FALSE;
    _verticalSorted = FALSE;
}

static int TreeEdgeBreaker::compareLinesV( const TreeLine ** lineLhs,
                                           const TreeLine ** lineRhs )
//-------------------------------------------------------------------
// Compare two lines.
// Returns : -1 if LHS line starts above RHS
//            0 if LHS and RHS start at same y-coord
//           +1 if LHS line starts below RHS
//
{
    TreeCoord minLhsY, minRhsY;

    if(( *lineLhs )->_lineCoords.y1 < ( *lineLhs )->_lineCoords.y2 ) {
        minLhsY = ( *lineLhs )->_lineCoords.y1;
    } else {
        minLhsY = ( *lineLhs )->_lineCoords.y2;
    }

    if(( *lineRhs )->_lineCoords.y1 < ( *lineRhs )->_lineCoords.y2 ) {
        minRhsY = ( *lineRhs )->_lineCoords.y1;
    } else {
        minRhsY = ( *lineRhs )->_lineCoords.y2;
    }

    if( minLhsY < minRhsY ) {
        return -1;
    } else if ( minLhsY > minRhsY ) {
        return 1;
    } else {
        return 0;
    }
}

static int TreeEdgeBreaker::compareLinesH( const TreeLine ** lineLhs,
                                           const TreeLine ** lineRhs )
//-------------------------------------------------------------------
// Compare two lines.
// Returns : -1 if LHS line starts to the left of RHS
//            0 if LHS and RHS start at same x-coord
//           +1 if LHS line starts to the right of RHS
//
{
    TreeCoord minLhsX, minRhsX;

    if(( *lineLhs )->_lineCoords.x1 < ( *lineLhs )->_lineCoords.x2 ) {
        minLhsX = ( *lineLhs )->_lineCoords.x1;
    } else {
        minLhsX = ( *lineLhs )->_lineCoords.x2;
    }

    if(( *lineRhs )->_lineCoords.x1 < ( *lineRhs )->_lineCoords.x2 ) {
        minRhsX = ( *lineRhs )->_lineCoords.x1;

⌨️ 快捷键说明

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