⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dc.cpp

📁 A*算法 A*算法 A*算法 A*算法A*算法A*算法
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// including the coresoponding character in text.

bool wxDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const
{
    static int maxLenText = -1;
    static int maxWidth = -1;
    int fit = 0;
    SIZE sz = {0,0};
    int stlen = text.Length();

    if (maxLenText == -1)
    {
        // Win9x and WinNT+ have different limits
        int version = wxGetOsVersion();
        maxLenText = version == wxWINDOWS_NT ? 65535 : 8192;
        maxWidth =   version == wxWINDOWS_NT ? INT_MAX : 32767;
    }

    widths.Empty();
    widths.Add(0, stlen);  // fill the array with zeros
    if (stlen == 0)
        return true;

    if (!::GetTextExtentExPoint(GetHdc(),
                                text.c_str(),           // string to check
                                wxMin(stlen, maxLenText),
                                maxWidth,
                                &fit,                   // [out] count of chars
                                                        // that will fit
                                &widths[0],             // array to fill
                                &sz))
    {
        // API failed
        wxLogLastError(wxT("GetTextExtentExPoint"));
        return false;
    }

    return true;
}




void wxDC::SetMapMode(int mode)
{
    WXMICROWIN_CHECK_HDC

    m_mappingMode = mode;

    if ( mode == wxMM_TEXT )
    {
        m_logicalScaleX =
        m_logicalScaleY = 1.0;
    }
    else // need to do some calculations
    {
        int pixel_width = ::GetDeviceCaps(GetHdc(), HORZRES),
            pixel_height = ::GetDeviceCaps(GetHdc(), VERTRES),
            mm_width = ::GetDeviceCaps(GetHdc(), HORZSIZE),
            mm_height = ::GetDeviceCaps(GetHdc(), VERTSIZE);

        if ( (mm_width == 0) || (mm_height == 0) )
        {
            // we can't calculate mm2pixels[XY] then!
            return;
        }

        double mm2pixelsX = (double)pixel_width / mm_width,
               mm2pixelsY = (double)pixel_height / mm_height;

        switch (mode)
        {
            case wxMM_TWIPS:
                m_logicalScaleX = twips2mm * mm2pixelsX;
                m_logicalScaleY = twips2mm * mm2pixelsY;
                break;

            case wxMM_POINTS:
                m_logicalScaleX = pt2mm * mm2pixelsX;
                m_logicalScaleY = pt2mm * mm2pixelsY;
                break;

            case wxMM_METRIC:
                m_logicalScaleX = mm2pixelsX;
                m_logicalScaleY = mm2pixelsY;
                break;

            case wxMM_LOMETRIC:
                m_logicalScaleX = mm2pixelsX / 10.0;
                m_logicalScaleY = mm2pixelsY / 10.0;
                break;

            default:
                wxFAIL_MSG( _T("unknown mapping mode in SetMapMode") );
        }
    }

    // VZ: it seems very wasteful to always use MM_ANISOTROPIC when in 99% of
    //     cases we could do with MM_TEXT and in the remaining 0.9% with
    //     MM_ISOTROPIC (TODO!)
#ifndef __WXWINCE__
    ::SetMapMode(GetHdc(), MM_ANISOTROPIC);

    int width = DeviceToLogicalXRel(VIEWPORT_EXTENT)*m_signX,
        height = DeviceToLogicalYRel(VIEWPORT_EXTENT)*m_signY;

    ::SetViewportExtEx(GetHdc(), VIEWPORT_EXTENT, VIEWPORT_EXTENT, NULL);
    ::SetWindowExtEx(GetHdc(), width, height, NULL);

    ::SetViewportOrgEx(GetHdc(), m_deviceOriginX, m_deviceOriginY, NULL);
    ::SetWindowOrgEx(GetHdc(), m_logicalOriginX, m_logicalOriginY, NULL);
#endif
}

void wxDC::SetUserScale(double x, double y)
{
    WXMICROWIN_CHECK_HDC

    if ( x == m_userScaleX && y == m_userScaleY )
        return;

    m_userScaleX = x;
    m_userScaleY = y;

    this->SetMapMode(m_mappingMode);
}

void wxDC::SetAxisOrientation(bool WXUNUSED_IN_WINCE(xLeftRight),
                              bool WXUNUSED_IN_WINCE(yBottomUp))
{
    WXMICROWIN_CHECK_HDC

#ifndef __WXWINCE__
    int signX = xLeftRight ? 1 : -1,
        signY = yBottomUp ? -1 : 1;

    if ( signX != m_signX || signY != m_signY )
    {
        m_signX = signX;
        m_signY = signY;

        SetMapMode(m_mappingMode);
    }
#endif
}

void wxDC::SetSystemScale(double x, double y)
{
    WXMICROWIN_CHECK_HDC

    if ( x == m_scaleX && y == m_scaleY )
        return;

    m_scaleX = x;
    m_scaleY = y;

#ifndef __WXWINCE__
    SetMapMode(m_mappingMode);
#endif
}

void wxDC::SetLogicalOrigin(wxCoord x, wxCoord y)
{
    WXMICROWIN_CHECK_HDC

    if ( x == m_logicalOriginX && y == m_logicalOriginY )
        return;

    m_logicalOriginX = x;
    m_logicalOriginY = y;

#ifndef __WXWINCE__
    ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX, (int)m_logicalOriginY, NULL);
#endif
}

void wxDC::SetDeviceOrigin(wxCoord x, wxCoord y)
{
    WXMICROWIN_CHECK_HDC

    if ( x == m_deviceOriginX && y == m_deviceOriginY )
        return;

    m_deviceOriginX = x;
    m_deviceOriginY = y;

    ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX, (int)m_deviceOriginY, NULL);
}

// ---------------------------------------------------------------------------
// coordinates transformations
// ---------------------------------------------------------------------------

wxCoord wxDCBase::DeviceToLogicalX(wxCoord x) const
{
    return DeviceToLogicalXRel(x - m_deviceOriginX)*m_signX + m_logicalOriginX;
}

wxCoord wxDCBase::DeviceToLogicalXRel(wxCoord x) const
{
    // axis orientation is not taken into account for conversion of a distance
    return (wxCoord)(x / (m_logicalScaleX*m_userScaleX*m_scaleX));
}

wxCoord wxDCBase::DeviceToLogicalY(wxCoord y) const
{
    return DeviceToLogicalYRel(y - m_deviceOriginY)*m_signY + m_logicalOriginY;
}

wxCoord wxDCBase::DeviceToLogicalYRel(wxCoord y) const
{
    // axis orientation is not taken into account for conversion of a distance
    return (wxCoord)( y / (m_logicalScaleY*m_userScaleY*m_scaleY));
}

wxCoord wxDCBase::LogicalToDeviceX(wxCoord x) const
{
    return LogicalToDeviceXRel(x - m_logicalOriginX)*m_signX + m_deviceOriginX;
}

wxCoord wxDCBase::LogicalToDeviceXRel(wxCoord x) const
{
    // axis orientation is not taken into account for conversion of a distance
    return (wxCoord) (x*m_logicalScaleX*m_userScaleX*m_scaleX);
}

wxCoord wxDCBase::LogicalToDeviceY(wxCoord y) const
{
    return LogicalToDeviceYRel(y - m_logicalOriginY)*m_signY + m_deviceOriginY;
}

wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const
{
    // axis orientation is not taken into account for conversion of a distance
    return (wxCoord) (y*m_logicalScaleY*m_userScaleY*m_scaleY);
}

// ---------------------------------------------------------------------------
// bit blit
// ---------------------------------------------------------------------------

bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
                  wxCoord width, wxCoord height,
                  wxDC *source, wxCoord xsrc, wxCoord ysrc,
                  int rop, bool useMask,
                  wxCoord xsrcMask, wxCoord ysrcMask)
{
    wxCHECK_MSG( source, false, _T("wxDC::Blit(): NULL wxDC pointer") );

    WXMICROWIN_CHECK_HDC_RET(false)

    // if either the source or destination has alpha channel, we must use
    // AlphaBlt() as other function don't handle it correctly
    const wxBitmap& bmpSrc = source->m_selectedBitmap;
    if ( bmpSrc.Ok() && (bmpSrc.HasAlpha() ||
            (m_selectedBitmap.Ok() && m_selectedBitmap.HasAlpha())) )
    {
        if ( AlphaBlt(GetHdc(), xdest, ydest, width, height,
                      xsrc, ysrc, GetHdcOf(*source), bmpSrc) )
            return true;
    }

    wxMask *mask = NULL;
    if ( useMask )
    {
        mask = bmpSrc.GetMask();

        if ( !(bmpSrc.Ok() && mask && mask->GetMaskBitmap()) )
        {
            // don't give assert here because this would break existing
            // programs - just silently ignore useMask parameter
            useMask = false;
        }
    }

    if (xsrcMask == -1 && ysrcMask == -1)
    {
        xsrcMask = xsrc; ysrcMask = ysrc;
    }

    COLORREF old_textground = ::GetTextColor(GetHdc());
    COLORREF old_background = ::GetBkColor(GetHdc());
    if (m_textForegroundColour.Ok())
    {
        ::SetTextColor(GetHdc(), m_textForegroundColour.GetPixel() );
    }
    if (m_textBackgroundColour.Ok())
    {
        ::SetBkColor(GetHdc(), m_textBackgroundColour.GetPixel() );
    }

    DWORD dwRop;
    switch (rop)
    {
        case wxXOR:          dwRop = SRCINVERT;        break;
        case wxINVERT:       dwRop = DSTINVERT;        break;
        case wxOR_REVERSE:   dwRop = 0x00DD0228;       break;
        case wxAND_REVERSE:  dwRop = SRCERASE;         break;
        case wxCLEAR:        dwRop = BLACKNESS;        break;
        case wxSET:          dwRop = WHITENESS;        break;
        case wxOR_INVERT:    dwRop = MERGEPAINT;       break;
        case wxAND:          dwRop = SRCAND;           break;
        case wxOR:           dwRop = SRCPAINT;         break;
        case wxEQUIV:        dwRop = 0x00990066;       break;
        case wxNAND:         dwRop = 0x007700E6;       break;
        case wxAND_INVERT:   dwRop = 0x00220326;       break;
        case wxCOPY:         dwRop = SRCCOPY;          break;
        case wxNO_OP:        dwRop = DSTCOPY;          break;
        case wxSRC_INVERT:   dwRop = NOTSRCCOPY;       break;
        case wxNOR:          dwRop = NOTSRCCOPY;       break;
        default:
           wxFAIL_MSG( wxT("unsupported logical function") );
           return false;
    }

    bool success = false;

    if (useMask)
    {
#ifdef __WIN32__
        // we want the part of the image corresponding to the mask to be
        // transparent, so use "DSTCOPY" ROP for the mask points (the usual
        // meaning of fg and bg is inverted which corresponds to wxWin notion
        // of the mask which is also contrary to the Windows one)

        // On some systems, MaskBlt succeeds yet is much much slower
        // than the wxWidgets fall-back implementation. So we need
        // to be able to switch this on and off at runtime.
#if wxUSE_SYSTEM_OPTIONS
        if (wxSystemOptions::GetOptionInt(wxT("no-maskblt")) == 0)
#endif
        {
           success = ::MaskBlt
                       (
                            GetHdc(),
                            xdest, ydest, width, height,
                            GetHdcOf(*source),
                            xsrc, ysrc,
                            (HBITMAP)mask->GetMaskBitmap(),
                            xsrcMask, ysrcMask,
                            MAKEROP4(dwRop, DSTCOPY)
                        ) != 0;
        }

        if ( !success )
#endif // Win32
        {
            // Blit bitmap with mask
            HDC dc_mask ;
            HDC  dc_buffer ;
            HBITMAP buffer_bmap ;

#if wxUSE_DC_CACHEING
            // create a temp buffer bitmap and DCs to access it and the mask
            wxDCCacheEntry* dcCacheEntry1 = FindDCInCache(NULL, source->GetHDC());
            dc_mask = (HDC) dcCacheEntry1->m_dc;

            wxDCCacheEntry* dcCacheEntry2 = FindDCInCache(dcCacheEntry1, GetHDC());
            dc_buffer = (HDC) dcCacheEntry2->m_dc;

            wxDCCacheEntry* bitmapCacheEntry = FindBitmapInCache(GetHDC(),
                width, height);

            buffer_bmap = (HBITMAP) bitmapCacheEntry->m_bitmap;
#else // !wxUSE_DC_CACHEING
            // create a temp buffer bitmap and DCs to access it and the mask
            dc_mask = ::CreateCompatibleDC(GetHdcOf(*source));
            dc_buffer = ::CreateCompatibleDC(GetHdc());
            buffer_bmap = ::CreateCompatibleBitmap(GetHdc(), width, height);
#endif // wxUSE_DC_CACHEING/!wxUSE_DC_CACHEING
            HGDIOBJ hOldMaskBitmap = ::SelectObject(dc_mask, (HBITMAP) mask->GetMaskBitmap());
            HGDIOBJ hOldBufferBitmap = ::SelectObject(dc_buffer, buffer_bmap);

            // copy dest to buffer
            if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
                           GetHdc(), xdest, ydest, SRCCOPY) )
            {
                wxLogLastError(wxT("BitBlt"));
            }

            // copy src to buffer using selected raster op
            if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
                           GetHdcOf(*source), xsrc, ysrc, dwRop) )
            {
                wxLogLastError(wxT("BitBlt"));
            }

            // set masked area in buffer to BLACK (pixel value 0)
            COLORREF prevBkCol = ::SetBkColor(GetHdc(), RGB(255, 255, 255));
            COLORREF prevCol = ::SetTextColor(GetHdc(), RGB(0, 0, 0));
            if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
                           dc_mask, xsrcMask, ysrcMask, SRCAND) )
            {
                wxLogLastError(wxT("BitBlt"));
            }

            // set unmasked area in dest to BLACK
            ::SetBkColor(GetHdc(), RGB(0, 0, 0));
            ::SetTextColor(GetHdc(), RGB(255, 255, 255));
            if ( !::BitBlt(GetHdc(), xdest, ydest, (int)width, (int)height,
                           dc_mask, xsrcMask, ysrcMask, SRCAND) )
            {
                wxLogLastError(wxT("BitBlt"));
            }
            ::SetBkColor(GetHdc(), prevBkCol);   // restore colours to original values
            ::SetTextColor(GetHdc(), prevCol);

            // OR buffer to dest
            success = ::BitBlt(GetHdc(), xdest, ydest,
                               (int)width, (int)height,
                               dc_buffer, 0, 0, SRCPAINT) != 0;
            if ( !success )
            {
                wxLogLastError(wxT("BitBlt"));
            }

            // tidy up temporary DCs and bitmap
            ::SelectObject(dc_mask, hOldMaskBitmap);
            ::SelectObject(dc_buffer, hOldBufferBitmap);

#if !wxUSE_DC_CACHEING
            {
                ::DeleteDC(dc_mask);
                ::DeleteDC(dc_buffer);
                ::DeleteObject(buffer_bmap);
            }
#endif
        }
    }
    else // no mask, just BitBlt() it
    {
        // if we already have a DIB, draw it using StretchDIBits(), otherwise
        // use StretchBlt() if available and finally fall back to BitBlt()

        // FIXME: use appropriate WinCE functions
#ifndef __WXWINCE__
        const int caps = ::GetDeviceCaps(GetHdc(), RASTERCAPS);
        if 

⌨️ 快捷键说明

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