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

📄 dc.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////
// Name:        src/mac/carbon/dc.cpp
// Purpose:     wxDC class
// Author:      Stefan Csomor
// Modified by:
// Created:     01/02/97
// RCS-ID:      $Id: dc.cpp,v 1.132 2006/07/03 19:02:28 ABX Exp $
// Copyright:   (c) Stefan Csomor
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

#include "wx/wxprec.h"

#include "wx/dc.h"

#if !wxMAC_USE_CORE_GRAPHICS

#ifndef WX_PRECOMP
    #include "wx/log.h"
    #include "wx/app.h"
    #include "wx/dcmemory.h"
    #include "wx/dcprint.h"
    #include "wx/region.h"
    #include "wx/image.h"
#endif

#include "wx/mac/uma.h"

#ifdef __MSL__
    #if __MSL__ >= 0x6000
        namespace std {}
        using namespace std ;
    #endif
#endif

#include "wx/mac/private.h"
#ifndef __DARWIN__
#include <ATSUnicode.h>
#include <TextCommon.h>
#include <TextEncodingConverter.h>
#endif


// set to 0 if problems arise
#define wxMAC_EXPERIMENTAL_DC 1


IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)

//-----------------------------------------------------------------------------
// constants
//-----------------------------------------------------------------------------

const double RAD2DEG  = 180.0 / M_PI;
const short kEmulatedMode = -1 ;
const short kUnsupportedMode = -2 ;

extern TECObjectRef s_TECNativeCToUnicode ;


wxMacPortSetter::wxMacPortSetter( const wxDC* dc ) :
    m_ph( (GrafPtr) dc->m_macPort )
{
    wxASSERT( dc->Ok() ) ;
    m_dc = dc ;
    dc->MacSetupPort(&m_ph) ;
}

wxMacPortSetter::~wxMacPortSetter()
{
    m_dc->MacCleanupPort(&m_ph) ;
}

#if wxMAC_EXPERIMENTAL_DC
class wxMacFastPortSetter
{
public :
    wxMacFastPortSetter( const wxDC *dc )
    {
        wxASSERT( dc->Ok() ) ;
        m_swapped = QDSwapPort( (GrafPtr) dc->m_macPort , &m_oldPort ) ;
        m_clipRgn = NewRgn() ;
        GetClip( m_clipRgn ) ;
        m_dc = dc ;
        dc->MacSetupPort( NULL ) ;
    }

    ~wxMacFastPortSetter()
    {
        // SetPort( (GrafPtr) m_dc->m_macPort ) ;
        SetClip( m_clipRgn ) ;
        if ( m_swapped )
            SetPort( m_oldPort ) ;
        m_dc->MacCleanupPort( NULL ) ;
        DisposeRgn( m_clipRgn ) ;
    }

private :
    bool m_swapped ;
    RgnHandle m_clipRgn ;
    GrafPtr m_oldPort ;
    const wxDC*   m_dc ;
} ;

#else
typedef wxMacPortSetter wxMacFastPortSetter ;
#endif

wxMacWindowClipper::wxMacWindowClipper( const wxWindow* win ) :
    wxMacPortSaver( (GrafPtr) GetWindowPort((WindowRef) win->MacGetTopLevelWindowRef()) )
{
    m_newPort =(GrafPtr) GetWindowPort((WindowRef) win->MacGetTopLevelWindowRef()) ;
    m_formerClip = NewRgn() ;
    m_newClip = NewRgn() ;
    GetClip( m_formerClip ) ;

    if ( win )
    {
        // guard against half constructed objects, this just leads to a empty clip
        if ( win->GetPeer() )
        {
            int x = 0 , y = 0;
            win->MacWindowToRootWindow( &x, &y ) ;

            // get area including focus rect
            CopyRgn( (RgnHandle) ((wxWindow*)win)->MacGetVisibleRegion(true).GetWXHRGN() , m_newClip ) ;
            if ( !EmptyRgn( m_newClip ) )
                OffsetRgn( m_newClip , x , y ) ;
        }

        SetClip( m_newClip ) ;
    }
}

wxMacWindowClipper::~wxMacWindowClipper()
{
    SetPort( m_newPort ) ;
    SetClip( m_formerClip ) ;
    DisposeRgn( m_newClip ) ;
    DisposeRgn( m_formerClip ) ;
}

wxMacWindowStateSaver::wxMacWindowStateSaver( const wxWindow* win ) :
    wxMacWindowClipper( win )
{
    // the port is already set at this point
    m_newPort = (GrafPtr) GetWindowPort((WindowRef) win->MacGetTopLevelWindowRef()) ;
    GetThemeDrawingState( &m_themeDrawingState ) ;
}

wxMacWindowStateSaver::~wxMacWindowStateSaver()
{
    SetPort( m_newPort ) ;
    SetThemeDrawingState( m_themeDrawingState , true ) ;
}

//-----------------------------------------------------------------------------
// Local functions
//-----------------------------------------------------------------------------
static inline double dmin(double a, double b) { return a < b ? a : b; }
static inline double dmax(double a, double b) { return a > b ? a : b; }
static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }

//-----------------------------------------------------------------------------
// wxDC
//-----------------------------------------------------------------------------
// this function emulates all wx colour manipulations, used to verify the implementation
// by setting the mode in the blitting functions to kEmulatedMode
void wxMacCalculateColour( int logical_func , const RGBColor &srcColor , RGBColor &dstColor ) ;

void wxMacCalculateColour( int logical_func , const RGBColor &srcColor , RGBColor &dstColor )
{
    switch ( logical_func )
    {
        case wxAND:        // src AND dst
            dstColor.red = dstColor.red & srcColor.red ;
            dstColor.green = dstColor.green & srcColor.green ;
            dstColor.blue = dstColor.blue & srcColor.blue ;
            break ;

        case wxAND_INVERT: // (NOT src) AND dst
            dstColor.red = dstColor.red & ~srcColor.red ;
            dstColor.green = dstColor.green & ~srcColor.green ;
            dstColor.blue = dstColor.blue & ~srcColor.blue ;
            break ;

        case wxAND_REVERSE:// src AND (NOT dst)
            dstColor.red = ~dstColor.red & srcColor.red ;
            dstColor.green = ~dstColor.green & srcColor.green ;
            dstColor.blue = ~dstColor.blue & srcColor.blue ;
            break ;

        case wxCLEAR:      // 0
            dstColor.red = 0 ;
            dstColor.green = 0 ;
            dstColor.blue = 0 ;
            break ;

        case wxCOPY:       // src
            dstColor.red = srcColor.red ;
            dstColor.green = srcColor.green ;
            dstColor.blue = srcColor.blue ;
            break ;

        case wxEQUIV:      // (NOT src) XOR dst
            dstColor.red = dstColor.red ^ ~srcColor.red ;
            dstColor.green = dstColor.green ^ ~srcColor.green ;
            dstColor.blue = dstColor.blue ^ ~srcColor.blue ;
            break ;

        case wxINVERT:     // NOT dst
            dstColor.red = ~dstColor.red ;
            dstColor.green = ~dstColor.green ;
            dstColor.blue = ~dstColor.blue ;
            break ;

        case wxNAND:       // (NOT src) OR (NOT dst)
            dstColor.red = ~dstColor.red | ~srcColor.red ;
            dstColor.green = ~dstColor.green | ~srcColor.green ;
            dstColor.blue = ~dstColor.blue | ~srcColor.blue ;
            break ;

        case wxNOR:        // (NOT src) AND (NOT dst)
            dstColor.red = ~dstColor.red & ~srcColor.red ;
            dstColor.green = ~dstColor.green & ~srcColor.green ;
            dstColor.blue = ~dstColor.blue & ~srcColor.blue ;
            break ;

        case wxOR:         // src OR dst
            dstColor.red = dstColor.red | srcColor.red ;
            dstColor.green = dstColor.green | srcColor.green ;
            dstColor.blue = dstColor.blue | srcColor.blue ;
            break ;

        case wxOR_INVERT:  // (NOT src) OR dst
            dstColor.red = dstColor.red | ~srcColor.red ;
            dstColor.green = dstColor.green | ~srcColor.green ;
            dstColor.blue = dstColor.blue | ~srcColor.blue ;
            break ;

        case wxOR_REVERSE: // src OR (NOT dst)
            dstColor.red = ~dstColor.red | srcColor.red ;
            dstColor.green = ~dstColor.green | srcColor.green ;
            dstColor.blue = ~dstColor.blue | srcColor.blue ;
            break ;

        case wxSET:        // 1
            dstColor.red = 0xFFFF ;
            dstColor.green = 0xFFFF ;
            dstColor.blue = 0xFFFF ;
            break ;

        case wxSRC_INVERT: // (NOT src)
            dstColor.red = ~srcColor.red ;
            dstColor.green = ~srcColor.green ;
            dstColor.blue = ~srcColor.blue ;
            break ;

        case wxXOR:        // src XOR dst
            dstColor.red = dstColor.red ^ srcColor.red ;
            dstColor.green = dstColor.green ^ srcColor.green ;
            dstColor.blue = dstColor.blue ^ srcColor.blue ;
            break ;

        case wxNO_OP:      // dst
        default:
            break ;
    }
}

wxDC::wxDC()
{
    m_ok = false;
    m_colour = true;
    m_mm_to_pix_x = mm2pt;
    m_mm_to_pix_y = mm2pt;
    m_internalDeviceOriginX = 0;
    m_internalDeviceOriginY = 0;
    m_externalDeviceOriginX = 0;
    m_externalDeviceOriginY = 0;
    m_logicalScaleX = 1.0;
    m_logicalScaleY = 1.0;
    m_userScaleX = 1.0;
    m_userScaleY = 1.0;
    m_scaleX = 1.0;
    m_scaleY = 1.0;
    m_needComputeScaleX = false;
    m_needComputeScaleY = false;
    m_macPort = NULL ;
    m_macMask = NULL ;
    m_macFontInstalled = false ;
    m_macBrushInstalled = false ;
    m_macPenInstalled = false ;
    m_macLocalOrigin.x = m_macLocalOrigin.y = 0 ;
    m_macBoundaryClipRgn = NewRgn() ;
    m_macCurrentClipRgn = NewRgn() ;
    SetRectRgn( (RgnHandle) m_macBoundaryClipRgn , -32000 , -32000 , 32000 , 32000 ) ;
    SetRectRgn( (RgnHandle) m_macCurrentClipRgn , -32000 , -32000 , 32000 , 32000 ) ;
    m_pen = *wxBLACK_PEN;
    m_font = *wxNORMAL_FONT;
    m_brush = *wxWHITE_BRUSH;

#ifdef __WXDEBUG__
    // needed to debug possible errors with two active drawing methods at the same time on
    // the same DC
    m_macCurrentPortStateHelper = NULL ;
#endif

    m_macATSUIStyle = NULL ;
    m_macAliasWasEnabled = false;
    m_macForegroundPixMap = NULL ;
    m_macBackgroundPixMap = NULL ;
}

wxDC::~wxDC(void)
{
    DisposeRgn( (RgnHandle) m_macBoundaryClipRgn ) ;
    DisposeRgn( (RgnHandle) m_macCurrentClipRgn ) ;
}

void wxDC::MacSetupPort(wxMacPortStateHelper* help) const
{
#ifdef __WXDEBUG__
    wxASSERT( m_macCurrentPortStateHelper == NULL ) ;
    m_macCurrentPortStateHelper = help ;
#endif

    SetClip( (RgnHandle) m_macCurrentClipRgn);

#if ! wxMAC_EXPERIMENTAL_DC
    m_macFontInstalled = false ;
    m_macBrushInstalled = false ;
    m_macPenInstalled = false ;
#endif
}

void wxDC::MacCleanupPort(wxMacPortStateHelper* help) const
{
#ifdef __WXDEBUG__
    wxASSERT( m_macCurrentPortStateHelper == help ) ;
    m_macCurrentPortStateHelper = NULL ;
#endif

    if ( m_macATSUIStyle )
    {
        ::ATSUDisposeStyle((ATSUStyle)m_macATSUIStyle);
        m_macATSUIStyle = NULL ;
    }

    if ( m_macAliasWasEnabled )
    {
        SetAntiAliasedTextEnabled(m_macFormerAliasState, m_macFormerAliasSize);
        m_macAliasWasEnabled = false ;
    }

    if ( m_macForegroundPixMap )
    {
        Pattern blackColor ;
        ::PenPat(GetQDGlobalsBlack(&blackColor));
        DisposePixPat( (PixPatHandle) m_macForegroundPixMap ) ;
        m_macForegroundPixMap = NULL ;
    }

    if ( m_macBackgroundPixMap )
    {
        Pattern whiteColor ;
        ::BackPat(GetQDGlobalsWhite(&whiteColor));
        DisposePixPat( (PixPatHandle) m_macBackgroundPixMap ) ;
        m_macBackgroundPixMap = NULL ;
    }
}

void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask )
{
     wxCHECK_RET( Ok(), wxT("wxDC::DoDrawBitmap - invalid DC") );
     wxCHECK_RET( bmp.Ok(), wxT("wxDC::DoDrawBitmap - invalid bitmap") );

     wxMacFastPortSetter helper(this) ;
     wxCoord xx = XLOG2DEVMAC(x);
     wxCoord yy = YLOG2DEVMAC(y);
     wxCoord w = bmp.GetWidth();
     wxCoord h = bmp.GetHeight();
     wxCoord ww = XLOG2DEVREL(w);
     wxCoord hh = YLOG2DEVREL(h);

     // Set up drawing mode
     short  mode = (m_logicalFunction == wxCOPY ? srcCopy :
                    //m_logicalFunction == wxCLEAR ? WHITENESS :
                    //m_logicalFunction == wxSET ? BLACKNESS :
                    m_logicalFunction == wxINVERT ? hilite :
                   //m_logicalFunction == wxAND ? MERGECOPY :
                    m_logicalFunction == wxOR ? srcOr :
                    m_logicalFunction == wxSRC_INVERT ? notSrcCopy :
                    m_logicalFunction == wxXOR ? srcXor :
                    m_logicalFunction == wxOR_REVERSE ? notSrcOr :
                    //m_logicalFunction == wxAND_REVERSE ? SRCERASE :
                    //m_logicalFunction == wxSRC_OR ? srcOr :
                    //m_logicalFunction == wxSRC_AND ? SRCAND :
                    srcCopy );

     GWorldPtr maskworld = NULL ;
     GWorldPtr bmapworld = MAC_WXHBITMAP( bmp.GetHBITMAP((WXHBITMAP*)&maskworld) );
     PixMapHandle bmappixels ;

     // Set foreground and background colours (for bitmaps depth = 1)
     if (bmp.GetDepth() == 1)
     {
         RGBColor fore = MAC_WXCOLORREF(m_textForegroundColour.GetPixel());
         RGBColor back = MAC_WXCOLORREF(m_textBackgroundColour.GetPixel());
         RGBForeColor(&fore);
         RGBBackColor(&back);
     }
     else
     {
         RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF } ;
         RGBColor black = { 0, 0, 0 } ;
         RGBForeColor( &black ) ;
         RGBBackColor( &white ) ;
     }
     bmappixels = GetGWorldPixMap( bmapworld ) ;

     wxCHECK_RET(LockPixels(bmappixels),
                 wxT("wxDC::DoDrawBitmap - failed to lock pixels"));

     Rect source = { 0, 0, h, w };
     Rect dest   = { yy, xx, yy + hh, xx + ww };
     if ( useMask && maskworld )
     {
         if ( LockPixels(GetGWorldPixMap(MAC_WXHBITMAP(maskworld))))
         {
             CopyDeepMask

⌨️ 快捷键说明

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