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

📄 dccg.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////
// Name:        src/mac/carbon/dccg.cpp
// Purpose:     wxDC class
// Author:      Stefan Csomor
// Modified by:
// Created:     01/02/97
// RCS-ID:      $Id: dccg.cpp,v 1.46 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
        #include "math.h"
        // in case our functions were defined outside std, we make it known all the same
        namespace std { }
        using namespace std ;
    #endif
#endif

#include "wx/mac/private.h"

IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)

#ifndef wxMAC_USE_CORE_GRAPHICS_BLEND_MODES
#define wxMAC_USE_CORE_GRAPHICS_BLEND_MODES 0
#endif

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

#if !defined( __DARWIN__ ) || defined(__MWERKS__)
#ifndef M_PI
const double M_PI = 3.14159265358979 ;
#endif
#endif

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

extern TECObjectRef s_TECNativeCToUnicode ;


// TODO: update
// The textctrl implementation still needs that (needs what?) for the non-HIView implementation
//
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 ) ;
}

// minimal implementation only used for appearance drawing < 10.3

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) ;
}

//-----------------------------------------------------------------------------
// 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; }

//-----------------------------------------------------------------------------
// device context implementation
//
// more and more of the dc functionality should be implemented by calling
// the appropricate wxMacCGContext, but we will have to do that step by step
// also coordinate conversions should be moved to native matrix ops
//-----------------------------------------------------------------------------

// we always stock two context states, one at entry, to be able to preserve the
// state we were called with, the other one after changing to HI Graphics orientation
// (this one is used for getting back clippings etc)

wxMacCGPath::wxMacCGPath()
{
    m_path = CGPathCreateMutable() ;
}

wxMacCGPath::~wxMacCGPath()
{
    CGPathRelease( m_path ) ;
}

// opens (starts) a new subpath
void wxMacCGPath::MoveToPoint( wxCoord x1 , wxCoord y1 )
{
    CGPathMoveToPoint( m_path , NULL , x1 , y1 ) ;
}

void wxMacCGPath::AddLineToPoint( wxCoord x1 , wxCoord y1 )
{
    CGPathAddLineToPoint( m_path , NULL , x1 , y1 ) ;
}

void wxMacCGPath::AddQuadCurveToPoint( wxCoord cx1, wxCoord cy1, wxCoord x1, wxCoord y1 )
{
    CGPathAddQuadCurveToPoint( m_path , NULL , cx1 , cy1 , x1 , y1 );
}

void wxMacCGPath::AddRectangle( wxCoord x, wxCoord y, wxCoord w, wxCoord h )
{
    CGRect cgRect = { { x , y } , { w , h } } ;
    CGPathAddRect( m_path , NULL , cgRect ) ;
}

void wxMacCGPath::AddCircle( wxCoord x, wxCoord y , wxCoord r )
{
    CGPathAddArc( m_path , NULL , x , y , r , 0.0 , 2 * M_PI , true ) ;
}

// closes the current subpath
void wxMacCGPath::CloseSubpath()
{
    CGPathCloseSubpath( m_path ) ;
}

CGPathRef wxMacCGPath::GetPath() const
{
    return m_path ;
}

wxMacCGContext::wxMacCGContext( CGrafPtr port )
{
    m_qdPort = port ;
    m_cgContext = NULL ;
}

wxMacCGContext::wxMacCGContext( CGContextRef cgcontext )
{
    m_qdPort = NULL ;
    m_cgContext = cgcontext ;
    CGContextSaveGState( m_cgContext ) ;
    CGContextSaveGState( m_cgContext ) ;
}

wxMacCGContext::wxMacCGContext()
{
    m_qdPort = NULL ;
    m_cgContext = NULL ;
}

wxMacCGContext::~wxMacCGContext()
{
    if ( m_cgContext )
    {
        CGContextSynchronize( m_cgContext ) ;
        CGContextRestoreGState( m_cgContext ) ;
        CGContextRestoreGState( m_cgContext ) ;
    }

    if ( m_qdPort )
        CGContextRelease( m_cgContext ) ;
}


void wxMacCGContext::Clip( const wxRegion &region )
{
//    ClipCGContextToRegion ( m_cgContext, &bounds , (RgnHandle) dc->m_macCurrentClipRgn ) ;
}

void wxMacCGContext::StrokePath( const wxGraphicPath *p )
{
    const wxMacCGPath* path = dynamic_cast< const wxMacCGPath*>( p ) ;
    CGContextAddPath( m_cgContext , path->GetPath() ) ;
    CGContextStrokePath( m_cgContext ) ;
}

void wxMacCGContext::DrawPath( const wxGraphicPath *p , int fillStyle )
{
    const wxMacCGPath* path = dynamic_cast< const wxMacCGPath*>( p ) ;
    CGPathDrawingMode mode = m_mode ;

    if ( fillStyle == wxODDEVEN_RULE )
    {
        if ( mode == kCGPathFill )
            mode = kCGPathEOFill ;
        else if ( mode == kCGPathFillStroke )
            mode = kCGPathEOFillStroke ;
    }

    CGContextAddPath( m_cgContext , path->GetPath() ) ;
    CGContextDrawPath( m_cgContext , mode ) ;
}

void wxMacCGContext::FillPath( const wxGraphicPath *p , const wxColor &fillColor , int fillStyle )
{
    const wxMacCGPath* path = dynamic_cast< const wxMacCGPath*>( p ) ;
    CGContextSaveGState( m_cgContext ) ;

    RGBColor col = MAC_WXCOLORREF( fillColor.GetPixel() ) ;
    CGContextSetRGBFillColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
    CGPathDrawingMode mode = kCGPathFill ;

    if ( fillStyle == wxODDEVEN_RULE )
        mode = kCGPathEOFill ;

    CGContextBeginPath( m_cgContext ) ;
    CGContextAddPath( m_cgContext , path->GetPath() ) ;
    CGContextClosePath( m_cgContext ) ;
    CGContextDrawPath( m_cgContext , mode ) ;

    CGContextRestoreGState( m_cgContext ) ;
}

wxGraphicPath* wxMacCGContext::CreatePath()
{
    // make sure that we now have a real cgref, before doing
    // anything with paths
    CGContextRef cg = GetNativeContext() ;
    cg = NULL ;

    return new wxMacCGPath() ;
}

// in case we only got a QDPort only create a cgref now

CGContextRef wxMacCGContext::GetNativeContext()
{
    if ( m_cgContext == NULL )
    {
        Rect bounds ;
        GetPortBounds( (CGrafPtr) m_qdPort , &bounds ) ;
        OSStatus status = CreateCGContextForPort((CGrafPtr) m_qdPort , &m_cgContext) ;
        CGContextSaveGState( m_cgContext ) ;

        wxASSERT_MSG( status == noErr , wxT("Cannot nest wxDCs on the same window") ) ;

        CGContextTranslateCTM( m_cgContext , 0 , bounds.bottom - bounds.top ) ;
        CGContextScaleCTM( m_cgContext , 1 , -1 ) ;

        CGContextSaveGState( m_cgContext ) ;
        SetPen( m_pen ) ;
        SetBrush( m_brush ) ;
    }

    return m_cgContext ;
}

void wxMacCGContext::SetNativeContext( CGContextRef cg )
{
    // we allow either setting or clearing but not replacing
    wxASSERT( m_cgContext == NULL || cg == NULL ) ;

    if ( cg )
        CGContextSaveGState( cg ) ;
    m_cgContext = cg ;
}

#pragma mark -
#pragma mark wxMacCGPattern, ImagePattern, HatchPattern classes

// CGPattern wrapper class: always allocate on heap, never call destructor

class wxMacCGPattern
{
public :
    wxMacCGPattern() {}

    // is guaranteed to be called only with a non-Null CGContextRef
    virtual void Render( CGContextRef ctxRef ) = 0 ;

    operator CGPatternRef() const { return m_patternRef ; }

protected :
    virtual ~wxMacCGPattern()
    {
        // as this is called only when the m_patternRef is been released;
        // don't release it again
    }

    static void _Render( void *info, CGContextRef ctxRef )
    {
        wxMacCGPattern* self = (wxMacCGPattern*) info ;
        if ( self && ctxRef )
            self->Render( ctxRef ) ;
    }

    static void _Dispose( void *info )
    {
        wxMacCGPattern* self = (wxMacCGPattern*) info ;
        delete self ;
    }

    CGPatternRef m_patternRef ;

    static const CGPatternCallbacks ms_Callbacks ;
} ;

const CGPatternCallbacks wxMacCGPattern::ms_Callbacks = { 0, &wxMacCGPattern::_Render, &wxMacCGPattern::_Dispose };

class ImagePattern : public wxMacCGPattern
{
public :
    ImagePattern( const wxBitmap* bmp , CGAffineTransform transform )
    {
        wxASSERT( bmp && bmp->Ok() ) ;

        Init( (CGImageRef) bmp->CGImageCreate() , transform ) ;
    }

    // ImagePattern takes ownership of CGImageRef passed in
    ImagePattern( CGImageRef image , CGAffineTransform transform )
    {
        if ( image )
            CFRetain( image ) ;

        Init( image , transform ) ;
    }

    virtual void Render( CGContextRef ctxRef )
    {
        if (m_image != NULL)
            HIViewDrawCGImage( ctxRef, &m_imageBounds, m_image );
    }

protected :
    void Init( CGImageRef image, CGAffineTransform transform )
    {
        m_image = image ;
        if ( m_image )
        {
            m_imageBounds = CGRectMake( 0.0, 0.0, (float)CGImageGetWidth( m_image ), (float)CGImageGetHeight( m_image ) ) ;
            m_patternRef = CGPatternCreate(
                this , m_imageBounds, transform ,
                m_imageBounds.size.width, m_imageBounds.size.height,
                kCGPatternTilingNoDistortion, true , &wxMacCGPattern::ms_Callbacks ) ;
        }
    }

    ~ImagePattern()
    {
        if ( m_image )
            CGImageRelease( m_image ) ;
    }

    CGImageRef m_image ;
    CGRect m_imageBounds ;
} ;

class HatchPattern : public wxMacCGPattern
{
public :
    HatchPattern( int hatchstyle, CGAffineTransform transform )
    {
        m_hatch = hatchstyle ;

⌨️ 快捷键说明

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