regiong.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,957 行 · 第 1/4 页

CPP
1,957
字号
/////////////////////////////////////////////////////////////////////////////
// Name:        generic/region.cpp
// Purpose:     generic wxRegion class
// Author:      David Elliott
// Modified by:
// Created:     2004/04/12
// RCS-ID:      $Id: regiong.cpp,v 1.7 2005/08/28 15:37:54 VZ Exp $
// Copyright:   (c) 2004 David Elliott
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

#include "wx/generic/region.h"
#include "wx/utils.h"

// ========================================================================
// Classes to interface with X.org code
// ========================================================================

typedef struct Box
{
    wxCoord x1, x2, y1, y2;
} Box, BOX, BoxRec, *BoxPtr;

typedef struct REGION *Region;

struct REGION
{
public:
    // Default constructor initializes nothing
    REGION() {}

    REGION(const wxRect& rect)
    {
        rects = &extents;
        numRects = 1;
        extents.x1 = rect.x;
        extents.y1 = rect.y;
        extents.x2 = rect.x + rect.width;
        extents.y2 = rect.y + rect.height;
        size = 1;
    }

    BoxPtr GetBox(int i)
    {
        return i < numRects ? rects + i : NULL;
    }

    // X.org methods
    static bool XClipBox(
        Region r,
        wxRect *rect);
    static bool XOffsetRegion(
        register Region pRegion,
        register int x,
        register int y);
    static bool XIntersectRegion(
        Region reg1,
        Region reg2,          /* source regions     */
        register Region newReg);               /* destination Region */
    static bool XUnionRegion(
        Region reg1,
        Region reg2,             /* source regions     */
        Region newReg);                  /* destination Region */
    static bool XSubtractRegion(
        Region regM,
        Region regS,
        register Region regD);
    static bool XXorRegion(Region sra, Region srb, Region dr);
    static bool XEmptyRegion(
        Region r);
    static bool XEqualRegion(Region r1, Region r2);
    static bool XPointInRegion(
        Region pRegion,
        int x, int y);
    static wxRegionContain XRectInRegion(
        register Region region,
        int rx, int ry,
        unsigned int rwidth, unsigned int rheight);

protected:
    static Region XCreateRegion(void);
    static void miSetExtents (
        Region pReg);
    static bool XDestroyRegion(Region r);
    static int miIntersectO (
        register Region pReg,
        register BoxPtr r1,
        BoxPtr r1End,
        register BoxPtr r2,
        BoxPtr r2End,
        wxCoord y1,
        wxCoord y2);
    static void miRegionCopy(
        register Region dstrgn,
        register Region rgn);
    static int miCoalesce(
        register Region pReg, /* Region to coalesce */
        int prevStart, /* Index of start of previous band */
        int curStart); /* Index of start of current band */
    static void miRegionOp(
        register Region newReg, /* Place to store result */
        Region reg1, /* First region in operation */
        Region reg2, /* 2d region in operation */
        int (*overlapFunc)(
            register Region     pReg,
            register BoxPtr     r1,
            BoxPtr              r1End,
            register BoxPtr     r2,
            BoxPtr              r2End,
            wxCoord             y1,
            wxCoord             y2), /* Function to call for over-
                                      * lapping bands */
        int (*nonOverlap1Func)(
            register Region     pReg,
            register BoxPtr     r,
            BoxPtr              rEnd,
            register wxCoord    y1,
            register wxCoord    y2), /* Function to call for non-
                                      * overlapping bands in region
                                      * 1 */
        int (*nonOverlap2Func)(
            register Region     pReg,
            register BoxPtr     r,
            BoxPtr              rEnd,
            register wxCoord    y1,
            register wxCoord    y2)); /* Function to call for non-
                                       * overlapping bands in region
                                       * 2 */
    static int miUnionNonO (
        register Region pReg,
        register BoxPtr r,
        BoxPtr rEnd,
        register wxCoord y1,
        register wxCoord y2);
    static int miUnionO (
        register Region pReg,
        register BoxPtr r1,
        BoxPtr r1End,
        register BoxPtr r2,
        BoxPtr r2End,
        register wxCoord y1,
        register wxCoord y2);
    static int miSubtractNonO1 (
        register Region pReg,
        register BoxPtr r,
        BoxPtr rEnd,
        register wxCoord y1,
        register wxCoord y2);
    static int miSubtractO (
        register Region pReg,
        register BoxPtr r1,
        BoxPtr r1End,
        register BoxPtr r2,
        BoxPtr r2End,
        register wxCoord y1,
        register wxCoord y2);
protected:
    long size;
    long numRects;
    Box *rects;
    Box extents;
};

// ========================================================================
// wxRegionRefData
// ========================================================================

class wxRegionRefData : public wxObjectRefData,
                        public REGION
{
public:
    wxRegionRefData()
        : wxObjectRefData(),
          REGION()
    {
        size = 1;
        numRects = 0;
        rects = ( BOX * )malloc( (unsigned) sizeof( BOX ));
        extents.x1 = 0;
        extents.x2 = 0;
        extents.y1 = 0;
        extents.y2 = 0;
    }

    wxRegionRefData(const wxPoint& topLeft, const wxPoint& bottomRight)
        : wxObjectRefData(),
          REGION()
    {
        rects = (BOX*)malloc(sizeof(BOX));
        size = 1;
        numRects = 1;
        extents.x1 = topLeft.x;
        extents.y1 = topLeft.y;
        extents.x2 = bottomRight.x;
        extents.y2 = bottomRight.y;
        *rects = extents;
    }

    wxRegionRefData(const wxRect& rect)
        : wxObjectRefData(),
          REGION(rect)
    {
        rects = (BOX*)malloc(sizeof(BOX));
        *rects = extents;
    }

    wxRegionRefData(const wxRegionRefData& refData)
        : wxObjectRefData(),
          REGION()
    {
        size = refData.size;
        numRects = refData.numRects;
        rects = (Box*)malloc(numRects*sizeof(Box));
        memcpy(rects, refData.rects, numRects*sizeof(Box));
        extents = refData.extents;
    }

    ~wxRegionRefData()
    {
        free(rects);
    }

private:
    // Don't allow this
    wxRegionRefData(const REGION&);
};

// ========================================================================
// wxRegionGeneric
// ========================================================================
//IMPLEMENT_DYNAMIC_CLASS(wxRegionGeneric, wxGDIObject);

#define M_REGIONDATA ((wxRegionRefData *)m_refData)
#define M_REGIONDATA_OF(rgn) ((wxRegionRefData *)(rgn.m_refData))

// ----------------------------------------------------------------------------
// wxRegionGeneric construction
// ----------------------------------------------------------------------------

wxRegionGeneric::wxRegionGeneric()
{
}

wxRegionGeneric::~wxRegionGeneric()
{
}

wxRegionGeneric::wxRegionGeneric(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
{
    m_refData = new wxRegionRefData(wxRect(x,y,w,h));
}

wxRegionGeneric::wxRegionGeneric(const wxRect& rect)
{
    m_refData = new wxRegionRefData(rect);
}

wxRegionGeneric::wxRegionGeneric(const wxPoint& topLeft, const wxPoint& bottomRight)
{
    m_refData = new wxRegionRefData(topLeft, bottomRight);
}

void wxRegionGeneric::Clear()
{
    UnRef();
}

wxObjectRefData *wxRegionGeneric::CreateRefData() const
{
    return new wxRegionRefData;
}

wxObjectRefData *wxRegionGeneric::CloneRefData(const wxObjectRefData *data) const
{
    return new wxRegionRefData(*(wxRegionRefData *)data);
}

bool wxRegionGeneric::operator== (const wxRegionGeneric& region)
{
    wxASSERT(m_refData && region.m_refData);
    return REGION::XEqualRegion(M_REGIONDATA,M_REGIONDATA_OF(region));
}

wxRect wxRegionGeneric::GetBox() const
{
    wxASSERT(m_refData);
    wxRect rect;
    REGION::XClipBox(M_REGIONDATA,&rect);
    return rect;
}

void wxRegionGeneric::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const
{
    wxASSERT(m_refData);
    wxRect rect;
    REGION::XClipBox(M_REGIONDATA,&rect);
    x = rect.x;
    y = rect.y;
    w = rect.width;
    h = rect.height;
}

// ----------------------------------------------------------------------------
// wxRegionGeneric operations
// ----------------------------------------------------------------------------

bool wxRegionGeneric::Union(const wxRect& rect)
/* XUnionRectWithRegion */
{
    if (!rect.width || !rect.height)
        return false;

    AllocExclusive();
    REGION region(rect);
    return REGION::XUnionRegion(&region,M_REGIONDATA,M_REGIONDATA);
}

bool wxRegionGeneric::Union(const wxRegionGeneric& region)
{
    AllocExclusive();
    return REGION::XUnionRegion(M_REGIONDATA_OF(region),M_REGIONDATA,M_REGIONDATA);
}

bool wxRegionGeneric::Intersect(const wxRect& rect)
{
    if (!rect.width || !rect.height)
        return false;
    AllocExclusive();
    REGION region(rect);

    return REGION::XIntersectRegion(&region,M_REGIONDATA,M_REGIONDATA);
}

bool wxRegionGeneric::Intersect(const wxRegionGeneric& region)
{
    AllocExclusive();
    return REGION::XIntersectRegion(M_REGIONDATA_OF(region),M_REGIONDATA,M_REGIONDATA);
}

bool wxRegionGeneric::Subtract(const wxRect& rect)
{
    if (!rect.width || !rect.height)
        return false;
    AllocExclusive();
    REGION region(rect);

    return REGION::XSubtractRegion(&region,M_REGIONDATA,M_REGIONDATA);
}

bool wxRegionGeneric::Subtract(const wxRegionGeneric& region)
{
    return REGION::XSubtractRegion(M_REGIONDATA_OF(region),M_REGIONDATA,M_REGIONDATA);
}

bool wxRegionGeneric::Xor(const wxRect& rect)
{
    if (!rect.width || !rect.height)
        return false;
    AllocExclusive();
    REGION region(rect);

    return REGION::XXorRegion(&region,M_REGIONDATA,M_REGIONDATA);
}

bool wxRegionGeneric::Xor(const wxRegionGeneric& region)
{
    AllocExclusive();
    return REGION::XXorRegion(M_REGIONDATA_OF(region),M_REGIONDATA,M_REGIONDATA);
}

bool wxRegionGeneric::Offset(wxCoord x, wxCoord y)
{
    AllocExclusive();
    return REGION::XOffsetRegion(M_REGIONDATA, x, y);
}

// ----------------------------------------------------------------------------
// wxRegionGeneric comparison
// ----------------------------------------------------------------------------

bool wxRegionGeneric::Empty() const
{
    wxASSERT(m_refData);
    return REGION::XEmptyRegion(M_REGIONDATA);
}

// Does the region contain the point (x,y)?
wxRegionContain wxRegionGeneric::Contains(long x, long y) const
{
    wxASSERT(m_refData);
    return REGION::XPointInRegion(M_REGIONDATA,x,y)?wxInRegion:wxOutRegion;
}

// Does the region contain the point pt?
wxRegionContain wxRegionGeneric::Contains(const wxPoint& pt) const
{
    wxASSERT(m_refData);
    return REGION::XPointInRegion(M_REGIONDATA,pt.x,pt.y)?wxInRegion:wxOutRegion;
}

// Does the region contain the rectangle (x, y, w, h)?
wxRegionContain wxRegionGeneric::Contains(long x, long y, long w, long h) const
{
    wxASSERT(m_refData);
    return REGION::XRectInRegion(M_REGIONDATA,x,y,w,h);
}

// Does the region contain the rectangle rect?
wxRegionContain wxRegionGeneric::Contains(const wxRect& rect) const
{
    wxASSERT(m_refData);
    return REGION::XRectInRegion(M_REGIONDATA,rect.x,rect.y,rect.width,rect.height);
}

// ========================================================================
// wxRegionIteratorGeneric
// ========================================================================
//IMPLEMENT_DYNAMIC_CLASS(wxRegionIteratorGeneric,wxObject);

wxRegionIteratorGeneric::wxRegionIteratorGeneric()
{
    m_current = 0;
}

wxRegionIteratorGeneric::wxRegionIteratorGeneric(const wxRegionGeneric& region)
:   m_region(region)
{
    m_current = 0;
}

wxRegionIteratorGeneric::wxRegionIteratorGeneric(const wxRegionIteratorGeneric& iterator)
:   m_region(iterator.m_region)
{
    m_current = iterator.m_current;
}

void wxRegionIteratorGeneric::Reset(const wxRegionGeneric& region)
{
    m_region = region;
    m_current = 0;
}

bool wxRegionIteratorGeneric::HaveRects() const
{
    return M_REGIONDATA_OF(m_region)->GetBox(m_current);
}

wxRegionIteratorGeneric& wxRegionIteratorGeneric::operator++()
{
    ++m_current;
    return *this;
}

wxRegionIteratorGeneric wxRegionIteratorGeneric::operator++(int)
{
    wxRegionIteratorGeneric copy(*this);
    ++*this;
    return copy;
}

wxRect wxRegionIteratorGeneric::GetRect() const
{
    wxASSERT(m_region.m_refData);
    const Box *box = M_REGIONDATA_OF(m_region)->GetBox(m_current);
    wxASSERT(box);
    return wxRect
    (   box->x1
    ,   box->y1
    ,   box->x2 - box->x1
    ,   box->y2 - box->y1
    );
}

long wxRegionIteratorGeneric::GetX() const
{
    wxASSERT(m_region.m_refData);
    const Box *box = M_REGIONDATA_OF(m_region)->GetBox(m_current);
    wxASSERT(box);
    return box->x1;
}

long wxRegionIteratorGeneric::GetY() const
{
    wxASSERT(m_region.m_refData);
    const Box *box = M_REGIONDATA_OF(m_region)->GetBox(m_current);
    wxASSERT(box);
    return box->y1;
}

long wxRegionIteratorGeneric::GetW() const

⌨️ 快捷键说明

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