📄 dc.cpp
字号:
/////////////////////////////////////////////////////////////////////////////// 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.133 2006/10/09 05:14:37 PC 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 1IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)//-----------------------------------------------------------------------------// constants//-----------------------------------------------------------------------------const double RAD2DEG = 180.0 / M_PI;const short kEmulatedMode = -1 ;const short kUnsupportedMode = -2 ;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_DCclass 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 ;} ;#elsetypedef wxMacPortSetter wxMacFastPortSetter ;#endifwxMacWindowClipper::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 ) ;}//-----------------------------------------------------------------------------// wxDC//-----------------------------------------------------------------------------// this function emulates all wx colour manipulations, used to verify the implementation// by setting the mode in the blitting functions to kEmulatedModevoid 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 ( GetPortBitMapForCopyBits(bmapworld), GetPortBitMapForCopyBits(MAC_WXHBITMAP(maskworld)), GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ), &source, &source, &dest, mode, NULL ); UnlockPixels(GetGWorldPixMap(MAC_WXHBITMAP(maskworld))); } } else { CopyBits( GetPortBitMapForCopyBits( bmapworld ), GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ), &source, &dest, mode, NULL ) ; } UnlockPixels( bmappixels ) ; m_macPenInstalled = false ; m_macBrushInstalled = false ; m_macFontInstalled = false ;}void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y ){ wxCHECK_RET(Ok(), wxT("wxDC::DoDrawIcon - invalid DC")); wxCHECK_RET(icon.Ok(), wxT("wxDC::DoDrawIcon - invalid icon"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -