📄 dccg.cpp
字号:
/////////////////////////////////////////////////////////////////////////////// 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.62 2006/10/30 20:34:25 VZ 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/dcmemory.h" #include "wx/region.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"#ifndef wxMAC_USE_CORE_GRAPHICS_BLEND_MODES#define wxMAC_USE_CORE_GRAPHICS_BLEND_MODES 0#endif#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4typedef float CGFloat ;#endif//-----------------------------------------------------------------------------// constants//-----------------------------------------------------------------------------#if !defined( __DARWIN__ ) || defined(__MWERKS__)#ifndef M_PIconst double M_PI = 3.14159265358979 ;#endif#endifstatic const double RAD2DEG = 180.0 / M_PI;#ifndef __LP64__// 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#ifndef wxMAC_USE_CORE_GRAPHICSwxMacPortSetter::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) ;}#endif#endif//-----------------------------------------------------------------------------// Local functions//-----------------------------------------------------------------------------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)//-----------------------------------------------------------------------------// wxGraphicPath implementation//-----------------------------------------------------------------------------#if !wxUSE_GRAPHICS_CONTEXTIMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)wxMacCGPath::wxMacCGPath(){ m_path = CGPathCreateMutable() ;}wxMacCGPath::~wxMacCGPath(){ CGPathRelease( m_path ) ;}// opens (starts) a new subpathvoid 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 subpathvoid wxMacCGPath::CloseSubpath(){ CGPathCloseSubpath( m_path ) ;}CGPathRef wxMacCGPath::GetPath() const{ return m_path ;}void wxMacCGPath::AddArcToPoint( wxCoord x1, wxCoord y1 , wxCoord x2, wxCoord y2, wxCoord r ){ CGPathAddArcToPoint( m_path, NULL , x1, y1, x2, y2, r);}void wxMacCGPath::AddArc( wxCoord x, wxCoord y, wxCoord r, double startAngle, double endAngle, bool clockwise ){ CGPathAddArc( m_path, NULL , x, y, r, startAngle, endAngle, clockwise);}//-----------------------------------------------------------------------------// wxGraphicContext implementation//-----------------------------------------------------------------------------wxMacCGContext::wxMacCGContext( CGrafPtr port ){ m_qdPort = port ; m_cgContext = NULL ; m_mode = kCGPathFill; m_macATSUIStyle = NULL ;}wxMacCGContext::wxMacCGContext( CGContextRef cgcontext ){ m_qdPort = NULL ; m_cgContext = cgcontext ; m_mode = kCGPathFill; m_macATSUIStyle = NULL ; CGContextSaveGState( m_cgContext ) ; CGContextSaveGState( m_cgContext ) ;}wxMacCGContext::wxMacCGContext(){ m_qdPort = NULL ; m_cgContext = NULL ; m_mode = kCGPathFill; m_macATSUIStyle = NULL ;}wxMacCGContext::~wxMacCGContext(){ if ( m_cgContext ) { CGContextSynchronize( m_cgContext ) ; CGContextRestoreGState( m_cgContext ) ; CGContextRestoreGState( m_cgContext ) ; }#ifndef __LP64__ if ( m_qdPort ) QDEndCGContext( m_qdPort, &m_cgContext ) ;#endif}void wxMacCGContext::Clip( const wxRegion ®ion ){// ClipCGContextToRegion ( m_cgContext, &bounds , (RgnHandle) dc->m_macCurrentClipRgn ) ;}void wxMacCGContext::StrokePath( const wxGraphicPath *p ){ const wxMacCGPath* path = dynamic_cast< const wxMacCGPath*>( p ) ; int width = m_pen.GetWidth(); if ( width == 0 ) width = 1 ; if ( m_pen.GetStyle() == wxTRANSPARENT ) width = 0 ; bool offset = ( width % 2 ) == 1 ; if ( offset ) CGContextTranslateCTM( m_cgContext, 0.5, 0.5 ); CGContextAddPath( m_cgContext , path->GetPath() ) ; CGContextStrokePath( m_cgContext ) ; if ( offset ) CGContextTranslateCTM( m_cgContext, -0.5, -0.5 );}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 ; } int width = m_pen.GetWidth(); if ( width == 0 ) width = 1 ; if ( m_pen.GetStyle() == wxTRANSPARENT ) width = 0 ; bool offset = ( width % 2 ) == 1 ; if ( offset ) CGContextTranslateCTM( m_cgContext, 0.5, 0.5 ); CGContextAddPath( m_cgContext , path->GetPath() ) ; CGContextDrawPath( m_cgContext , mode ) ; if ( offset ) CGContextTranslateCTM( m_cgContext, -0.5, -0.5 );}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 nowCGContextRef wxMacCGContext::GetNativeContext(){ if ( m_cgContext == NULL ) { Rect bounds ; OSStatus status = noErr;#ifndef __LP64__ GetPortBounds( (CGrafPtr) m_qdPort , &bounds ) ; status = QDBeginCGContext((CGrafPtr) m_qdPort , &m_cgContext) ;#endif 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 ;}void wxMacCGContext::Translate( wxCoord dx , wxCoord dy ){ CGContextTranslateCTM( m_cgContext, dx, dy );}void wxMacCGContext::Scale( wxCoord xScale , wxCoord yScale ){ CGContextScaleCTM( m_cgContext , xScale , yScale ) ;}void wxMacCGContext::DrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, wxCoord w, wxCoord h ){ CGImageRef image = (CGImageRef)( bmp.CGImageCreate() ) ; HIRect r = CGRectMake( 0 , 0 , w , h ); CGContextSaveGState( m_cgContext ); CGContextTranslateCTM( m_cgContext, x , y + h ); CGContextScaleCTM( m_cgContext, 1, -1 ); // in case image is a mask, set the foreground color CGContextSetRGBFillColor( m_cgContext , m_textForegroundColor.Red() / 255.0 , m_textForegroundColor.Green() / 255.0 , m_textForegroundColor.Blue() / 255.0 , m_textForegroundColor.Alpha() / 255.0 ) ; CGContextDrawImage( m_cgContext, r, image ); CGContextRestoreGState( m_cgContext ); CGImageRelease( image ) ;}void wxMacCGContext::DrawIcon( const wxIcon &icon, wxCoord x, wxCoord y, wxCoord w, wxCoord h ){ CGRect r = CGRectMake( 0 , 0 , w , h ) ; CGContextSaveGState( m_cgContext ); CGContextTranslateCTM( m_cgContext, x , y + h ); CGContextScaleCTM( m_cgContext, 1, -1 ); PlotIconRefInContext( m_cgContext , &r , kAlignNone , kTransformNone , NULL , kPlotIconRefNormalFlags , MAC_WXHICON( icon.GetHICON() ) ) ; CGContextRestoreGState( m_cgContext ) ;}void wxMacCGContext::PushState(){ CGContextSaveGState( m_cgContext );}void wxMacCGContext::PopState(){ CGContextRestoreGState( m_cgContext );}void wxMacCGContext::SetTextColor( const wxColour &col ){ m_textForegroundColor = col ;}#pragma mark -#pragma mark wxMacCGPattern, ImagePattern, HatchPattern classes// CGPattern wrapper class: always allocate on heap, never call destructorclass wxMacCGPattern{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -