1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/dc.cpp 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #include "wx/wxprec.h" 
  16 #if !wxMAC_USE_CORE_GRAPHICS 
  21     #include "wx/dcmemory.h" 
  22     #include "wx/dcprint.h" 
  23     #include "wx/region.h" 
  27 #include "wx/mac/uma.h" 
  36 #include "wx/mac/private.h" 
  38 #include <ATSUnicode.h> 
  39 #include <TextCommon.h> 
  40 #include <TextEncodingConverter.h> 
  44 // set to 0 if problems arise 
  45 #define wxMAC_EXPERIMENTAL_DC 1 
  48 IMPLEMENT_ABSTRACT_CLASS(wxDC
, wxObject
) 
  50 //----------------------------------------------------------------------------- 
  52 //----------------------------------------------------------------------------- 
  54 const double RAD2DEG  
= 180.0 / M_PI
; 
  55 const short kEmulatedMode 
= -1 ; 
  56 const short kUnsupportedMode 
= -2 ; 
  58 wxMacPortSetter::wxMacPortSetter( const wxDC
* dc 
) : 
  59     m_ph( (GrafPtr
) dc
->m_macPort 
) 
  61     wxASSERT( dc
->Ok() ) ; 
  63     dc
->MacSetupPort(&m_ph
) ; 
  66 wxMacPortSetter::~wxMacPortSetter() 
  68     m_dc
->MacCleanupPort(&m_ph
) ; 
  71 #if wxMAC_EXPERIMENTAL_DC 
  72 class wxMacFastPortSetter
 
  75     wxMacFastPortSetter( const wxDC 
*dc 
) 
  77         wxASSERT( dc
->Ok() ) ; 
  78         m_swapped 
= QDSwapPort( (GrafPtr
) dc
->m_macPort 
, &m_oldPort 
) ; 
  79         m_clipRgn 
= NewRgn() ; 
  80         GetClip( m_clipRgn 
) ; 
  82         dc
->MacSetupPort( NULL 
) ; 
  85     ~wxMacFastPortSetter() 
  87         // SetPort( (GrafPtr) m_dc->m_macPort ) ; 
  88         SetClip( m_clipRgn 
) ; 
  90             SetPort( m_oldPort 
) ; 
  91         m_dc
->MacCleanupPort( NULL 
) ; 
  92         DisposeRgn( m_clipRgn 
) ; 
 103 typedef wxMacPortSetter wxMacFastPortSetter 
; 
 106 wxMacWindowClipper::wxMacWindowClipper( const wxWindow
* win 
) : 
 107     wxMacPortSaver( (GrafPtr
) GetWindowPort((WindowRef
) win
->MacGetTopLevelWindowRef()) ) 
 109     m_newPort 
=(GrafPtr
) GetWindowPort((WindowRef
) win
->MacGetTopLevelWindowRef()) ; 
 110     m_formerClip 
= NewRgn() ; 
 111     m_newClip 
= NewRgn() ; 
 112     GetClip( m_formerClip 
) ; 
 116         // guard against half constructed objects, this just leads to a empty clip 
 117         if ( win
->GetPeer() ) 
 120             win
->MacWindowToRootWindow( &x
, &y 
) ; 
 122             // get area including focus rect 
 123             CopyRgn( (RgnHandle
) ((wxWindow
*)win
)->MacGetVisibleRegion(true).GetWXHRGN() , m_newClip 
) ; 
 124             if ( !EmptyRgn( m_newClip 
) ) 
 125                 OffsetRgn( m_newClip 
, x 
, y 
) ; 
 128         SetClip( m_newClip 
) ; 
 132 wxMacWindowClipper::~wxMacWindowClipper() 
 134     SetPort( m_newPort 
) ; 
 135     SetClip( m_formerClip 
) ; 
 136     DisposeRgn( m_newClip 
) ; 
 137     DisposeRgn( m_formerClip 
) ; 
 140 wxMacWindowStateSaver::wxMacWindowStateSaver( const wxWindow
* win 
) : 
 141     wxMacWindowClipper( win 
) 
 143     // the port is already set at this point 
 144     m_newPort 
= (GrafPtr
) GetWindowPort((WindowRef
) win
->MacGetTopLevelWindowRef()) ; 
 145     GetThemeDrawingState( &m_themeDrawingState 
) ; 
 148 wxMacWindowStateSaver::~wxMacWindowStateSaver() 
 150     SetPort( m_newPort 
) ; 
 151     SetThemeDrawingState( m_themeDrawingState 
, true ) ; 
 154 //----------------------------------------------------------------------------- 
 156 //----------------------------------------------------------------------------- 
 157 // this function emulates all wx colour manipulations, used to verify the implementation 
 158 // by setting the mode in the blitting functions to kEmulatedMode 
 159 void wxMacCalculateColour( int logical_func 
, const RGBColor 
&srcColor 
, RGBColor 
&dstColor 
) ; 
 161 void wxMacCalculateColour( int logical_func 
, const RGBColor 
&srcColor 
, RGBColor 
&dstColor 
) 
 163     switch ( logical_func 
) 
 165         case wxAND
:        // src AND dst 
 166             dstColor
.red 
= dstColor
.red 
& srcColor
.red 
; 
 167             dstColor
.green 
= dstColor
.green 
& srcColor
.green 
; 
 168             dstColor
.blue 
= dstColor
.blue 
& srcColor
.blue 
; 
 171         case wxAND_INVERT
: // (NOT src) AND dst 
 172             dstColor
.red 
= dstColor
.red 
& ~srcColor
.red 
; 
 173             dstColor
.green 
= dstColor
.green 
& ~srcColor
.green 
; 
 174             dstColor
.blue 
= dstColor
.blue 
& ~srcColor
.blue 
; 
 177         case wxAND_REVERSE
:// src AND (NOT dst) 
 178             dstColor
.red 
= ~dstColor
.red 
& srcColor
.red 
; 
 179             dstColor
.green 
= ~dstColor
.green 
& srcColor
.green 
; 
 180             dstColor
.blue 
= ~dstColor
.blue 
& srcColor
.blue 
; 
 190             dstColor
.red 
= srcColor
.red 
; 
 191             dstColor
.green 
= srcColor
.green 
; 
 192             dstColor
.blue 
= srcColor
.blue 
; 
 195         case wxEQUIV
:      // (NOT src) XOR dst 
 196             dstColor
.red 
= dstColor
.red 
^ ~srcColor
.red 
; 
 197             dstColor
.green 
= dstColor
.green 
^ ~srcColor
.green 
; 
 198             dstColor
.blue 
= dstColor
.blue 
^ ~srcColor
.blue 
; 
 201         case wxINVERT
:     // NOT dst 
 202             dstColor
.red 
= ~dstColor
.red 
; 
 203             dstColor
.green 
= ~dstColor
.green 
; 
 204             dstColor
.blue 
= ~dstColor
.blue 
; 
 207         case wxNAND
:       // (NOT src) OR (NOT dst) 
 208             dstColor
.red 
= ~dstColor
.red 
| ~srcColor
.red 
; 
 209             dstColor
.green 
= ~dstColor
.green 
| ~srcColor
.green 
; 
 210             dstColor
.blue 
= ~dstColor
.blue 
| ~srcColor
.blue 
; 
 213         case wxNOR
:        // (NOT src) AND (NOT dst) 
 214             dstColor
.red 
= ~dstColor
.red 
& ~srcColor
.red 
; 
 215             dstColor
.green 
= ~dstColor
.green 
& ~srcColor
.green 
; 
 216             dstColor
.blue 
= ~dstColor
.blue 
& ~srcColor
.blue 
; 
 219         case wxOR
:         // src OR dst 
 220             dstColor
.red 
= dstColor
.red 
| srcColor
.red 
; 
 221             dstColor
.green 
= dstColor
.green 
| srcColor
.green 
; 
 222             dstColor
.blue 
= dstColor
.blue 
| srcColor
.blue 
; 
 225         case wxOR_INVERT
:  // (NOT src) OR dst 
 226             dstColor
.red 
= dstColor
.red 
| ~srcColor
.red 
; 
 227             dstColor
.green 
= dstColor
.green 
| ~srcColor
.green 
; 
 228             dstColor
.blue 
= dstColor
.blue 
| ~srcColor
.blue 
; 
 231         case wxOR_REVERSE
: // src OR (NOT dst) 
 232             dstColor
.red 
= ~dstColor
.red 
| srcColor
.red 
; 
 233             dstColor
.green 
= ~dstColor
.green 
| srcColor
.green 
; 
 234             dstColor
.blue 
= ~dstColor
.blue 
| srcColor
.blue 
; 
 238             dstColor
.red 
= 0xFFFF ; 
 239             dstColor
.green 
= 0xFFFF ; 
 240             dstColor
.blue 
= 0xFFFF ; 
 243         case wxSRC_INVERT
: // (NOT src) 
 244             dstColor
.red 
= ~srcColor
.red 
; 
 245             dstColor
.green 
= ~srcColor
.green 
; 
 246             dstColor
.blue 
= ~srcColor
.blue 
; 
 249         case wxXOR
:        // src XOR dst 
 250             dstColor
.red 
= dstColor
.red 
^ srcColor
.red 
; 
 251             dstColor
.green 
= dstColor
.green 
^ srcColor
.green 
; 
 252             dstColor
.blue 
= dstColor
.blue 
^ srcColor
.blue 
; 
 265     m_mm_to_pix_x 
= mm2pt
; 
 266     m_mm_to_pix_y 
= mm2pt
; 
 267     m_internalDeviceOriginX 
= 0; 
 268     m_internalDeviceOriginY 
= 0; 
 269     m_externalDeviceOriginX 
= 0; 
 270     m_externalDeviceOriginY 
= 0; 
 271     m_logicalScaleX 
= 1.0; 
 272     m_logicalScaleY 
= 1.0; 
 277     m_needComputeScaleX 
= false; 
 278     m_needComputeScaleY 
= false; 
 281     m_macFontInstalled 
= false ; 
 282     m_macBrushInstalled 
= false ; 
 283     m_macPenInstalled 
= false ; 
 284     m_macLocalOrigin
.x 
= m_macLocalOrigin
.y 
= 0 ; 
 285     m_macBoundaryClipRgn 
= NewRgn() ; 
 286     m_macCurrentClipRgn 
= NewRgn() ; 
 287     SetRectRgn( (RgnHandle
) m_macBoundaryClipRgn 
, -32000 , -32000 , 32000 , 32000 ) ; 
 288     SetRectRgn( (RgnHandle
) m_macCurrentClipRgn 
, -32000 , -32000 , 32000 , 32000 ) ; 
 289     m_pen 
= *wxBLACK_PEN
; 
 290     m_font 
= *wxNORMAL_FONT
; 
 291     m_brush 
= *wxWHITE_BRUSH
; 
 294     // needed to debug possible errors with two active drawing methods at the same time on 
 296     m_macCurrentPortStateHelper 
= NULL 
; 
 299     m_macATSUIStyle 
= NULL 
; 
 300     m_macAliasWasEnabled 
= false; 
 301     m_macForegroundPixMap 
= NULL 
; 
 302     m_macBackgroundPixMap 
= NULL 
; 
 307     DisposeRgn( (RgnHandle
) m_macBoundaryClipRgn 
) ; 
 308     DisposeRgn( (RgnHandle
) m_macCurrentClipRgn 
) ; 
 311 void wxDC::MacSetupPort(wxMacPortStateHelper
* help
) const 
 314     wxASSERT( m_macCurrentPortStateHelper 
== NULL 
) ; 
 315     m_macCurrentPortStateHelper 
= help 
; 
 318     SetClip( (RgnHandle
) m_macCurrentClipRgn
); 
 320 #if ! wxMAC_EXPERIMENTAL_DC 
 321     m_macFontInstalled 
= false ; 
 322     m_macBrushInstalled 
= false ; 
 323     m_macPenInstalled 
= false ; 
 327 void wxDC::MacCleanupPort(wxMacPortStateHelper
* help
) const 
 330     wxASSERT( m_macCurrentPortStateHelper 
== help 
) ; 
 331     m_macCurrentPortStateHelper 
= NULL 
; 
 334     if ( m_macATSUIStyle 
) 
 336         ::ATSUDisposeStyle((ATSUStyle
)m_macATSUIStyle
); 
 337         m_macATSUIStyle 
= NULL 
; 
 340     if ( m_macAliasWasEnabled 
) 
 342         SetAntiAliasedTextEnabled(m_macFormerAliasState
, m_macFormerAliasSize
); 
 343         m_macAliasWasEnabled 
= false ; 
 346     if ( m_macForegroundPixMap 
) 
 349         ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
 350         DisposePixPat( (PixPatHandle
) m_macForegroundPixMap 
) ; 
 351         m_macForegroundPixMap 
= NULL 
; 
 354     if ( m_macBackgroundPixMap 
) 
 357         ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
 358         DisposePixPat( (PixPatHandle
) m_macBackgroundPixMap 
) ; 
 359         m_macBackgroundPixMap 
= NULL 
; 
 363 void wxDC::DoDrawBitmap( const wxBitmap 
&bmp
, wxCoord x
, wxCoord y
, bool useMask 
) 
 365      wxCHECK_RET( Ok(), wxT("wxDC::DoDrawBitmap - invalid DC") ); 
 366      wxCHECK_RET( bmp
.Ok(), wxT("wxDC::DoDrawBitmap - invalid bitmap") ); 
 368      wxMacFastPortSetter 
helper(this) ; 
 369      wxCoord xx 
= XLOG2DEVMAC(x
); 
 370      wxCoord yy 
= YLOG2DEVMAC(y
); 
 371      wxCoord w 
= bmp
.GetWidth(); 
 372      wxCoord h 
= bmp
.GetHeight(); 
 373      wxCoord ww 
= XLOG2DEVREL(w
); 
 374      wxCoord hh 
= YLOG2DEVREL(h
); 
 376      // Set up drawing mode 
 377      short  mode 
= (m_logicalFunction 
== wxCOPY 
? srcCopy 
: 
 378                     //m_logicalFunction == wxCLEAR ? WHITENESS : 
 379                     //m_logicalFunction == wxSET ? BLACKNESS : 
 380                     m_logicalFunction 
== wxINVERT 
? hilite 
: 
 381                    //m_logicalFunction == wxAND ? MERGECOPY : 
 382                     m_logicalFunction 
== wxOR 
? srcOr 
: 
 383                     m_logicalFunction 
== wxSRC_INVERT 
? notSrcCopy 
: 
 384                     m_logicalFunction 
== wxXOR 
? srcXor 
: 
 385                     m_logicalFunction 
== wxOR_REVERSE 
? notSrcOr 
: 
 386                     //m_logicalFunction == wxAND_REVERSE ? SRCERASE : 
 387                     //m_logicalFunction == wxSRC_OR ? srcOr : 
 388                     //m_logicalFunction == wxSRC_AND ? SRCAND : 
 391      GWorldPtr maskworld 
= NULL 
; 
 392      GWorldPtr bmapworld 
= MAC_WXHBITMAP( bmp
.GetHBITMAP((WXHBITMAP
*)&maskworld
) ); 
 393      PixMapHandle bmappixels 
; 
 395      // Set foreground and background colours (for bitmaps depth = 1) 
 396      if (bmp
.GetDepth() == 1) 
 398          RGBColor fore 
= MAC_WXCOLORREF(m_textForegroundColour
.GetPixel()); 
 399          RGBColor back 
= MAC_WXCOLORREF(m_textBackgroundColour
.GetPixel()); 
 405          RGBColor white 
= { 0xFFFF, 0xFFFF, 0xFFFF } ; 
 406          RGBColor black 
= { 0, 0, 0 } ; 
 407          RGBForeColor( &black 
) ; 
 408          RGBBackColor( &white 
) ; 
 410      bmappixels 
= GetGWorldPixMap( bmapworld 
) ; 
 412      wxCHECK_RET(LockPixels(bmappixels
), 
 413                  wxT("wxDC::DoDrawBitmap - failed to lock pixels")); 
 415      Rect source 
= { 0, 0, h
, w 
}; 
 416      Rect dest   
= { yy
, xx
, yy 
+ hh
, xx 
+ ww 
}; 
 417      if ( useMask 
&& maskworld 
) 
 419          if ( LockPixels(GetGWorldPixMap(MAC_WXHBITMAP(maskworld
)))) 
 423                   GetPortBitMapForCopyBits(bmapworld
), 
 424                   GetPortBitMapForCopyBits(MAC_WXHBITMAP(maskworld
)), 
 425                   GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ), 
 426                   &source
, &source
, &dest
, mode
, NULL
 
 428              UnlockPixels(GetGWorldPixMap(MAC_WXHBITMAP(maskworld
))); 
 433          CopyBits( GetPortBitMapForCopyBits( bmapworld 
), 
 434                    GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ), 
 435                    &source
, &dest
, mode
, NULL 
) ; 
 437      UnlockPixels( bmappixels 
) ; 
 439      m_macPenInstalled 
= false ; 
 440      m_macBrushInstalled 
= false ; 
 441      m_macFontInstalled 
= false ; 
 444 void wxDC::DoDrawIcon( const wxIcon 
&icon
, wxCoord x
, wxCoord y 
) 
 446     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawIcon - invalid DC")); 
 447     wxCHECK_RET(icon
.Ok(), wxT("wxDC::DoDrawIcon - invalid icon")); 
 449     wxMacFastPortSetter 
helper(this) ; 
 451     wxCoord xx 
= XLOG2DEVMAC(x
); 
 452     wxCoord yy 
= YLOG2DEVMAC(y
); 
 453     wxCoord w 
= icon
.GetWidth(); 
 454     wxCoord h 
= icon
.GetHeight(); 
 455     wxCoord ww 
= XLOG2DEVREL(w
); 
 456     wxCoord hh 
= YLOG2DEVREL(h
); 
 458     Rect r 
= { yy 
, xx
, yy 
+ hh
, xx 
+ ww 
} ; 
 459     PlotIconRef( &r 
, kAlignNone 
, kTransformNone 
, kPlotIconRefNormalFlags 
, MAC_WXHICON( icon
.GetHICON() ) ) ; 
 462 void wxDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 464     wxCHECK_RET(Ok(), wxT("wxDC::DoSetClippingRegion - invalid DC")); 
 466     wxCoord xx
, yy
, ww
, hh
; 
 469     ww 
= XLOG2DEVREL(width
); 
 470     hh 
= YLOG2DEVREL(height
); 
 472     SetRectRgn( (RgnHandle
) m_macCurrentClipRgn 
, xx 
, yy 
, xx 
+ ww 
, yy 
+ hh 
) ; 
 473     SectRgn( (RgnHandle
) m_macCurrentClipRgn 
, (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) m_macCurrentClipRgn 
) ; 
 476         m_clipX1 
= wxMax( m_clipX1 
, xx 
); 
 477         m_clipY1 
= wxMax( m_clipY1 
, yy 
); 
 478         m_clipX2 
= wxMin( m_clipX2
, (xx 
+ ww
) ); 
 479         m_clipY2 
= wxMin( m_clipY2
, (yy 
+ hh
) ); 
 491 void wxDC::DoSetClippingRegionAsRegion( const wxRegion 
®ion 
) 
 493     wxCHECK_RET(Ok(), wxT("wxDC::DoSetClippingRegionAsRegion - invalid DC")); 
 495     wxMacFastPortSetter 
helper(this) ; 
 497     region
.GetBox( x
, y
, w
, h 
); 
 498     wxCoord xx
, yy
, ww
, hh
; 
 504     // if we have a scaling that we cannot map onto native regions 
 505     // we must use the box 
 506     if ( ww 
!= w 
|| hh 
!= h 
) 
 508         wxDC::DoSetClippingRegion( x
, y
, w
, h 
); 
 512         CopyRgn( (RgnHandle
) region
.GetWXHRGN() , (RgnHandle
) m_macCurrentClipRgn 
) ; 
 513         if ( xx 
!= x 
|| yy 
!= y 
) 
 514             OffsetRgn( (RgnHandle
) m_macCurrentClipRgn 
, xx 
- x 
, yy 
- y 
) ; 
 516         SectRgn( (RgnHandle
) m_macCurrentClipRgn 
, (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) m_macCurrentClipRgn 
) ; 
 519             m_clipX1 
= wxMax( m_clipX1 
, xx 
); 
 520             m_clipY1 
= wxMax( m_clipY1 
, yy 
); 
 521             m_clipX2 
= wxMin( m_clipX2
, (xx 
+ ww
) ); 
 522             m_clipY2 
= wxMin( m_clipY2
, (yy 
+ hh
) ); 
 535 void wxDC::DestroyClippingRegion() 
 537     wxMacFastPortSetter 
helper(this) ; 
 539     CopyRgn( (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) m_macCurrentClipRgn 
) ; 
 543 void wxDC::DoGetSizeMM( int* width
, int* height 
) const 
 549         *width 
= long( double(w
) / (m_scaleX 
* m_mm_to_pix_x
) ); 
 551         *height 
= long( double(h
) / (m_scaleY 
* m_mm_to_pix_y
) ); 
 554 void wxDC::SetTextForeground( const wxColour 
&col 
) 
 556     wxCHECK_RET(Ok(), wxT("wxDC::SetTextForeground - invalid DC")); 
 558     m_textForegroundColour 
= col
; 
 559     m_macFontInstalled 
= false ; 
 562 void wxDC::SetTextBackground( const wxColour 
&col 
) 
 564     wxCHECK_RET(Ok(), wxT("wxDC::SetTextBackground - invalid DC")); 
 566     m_textBackgroundColour 
= col
; 
 567     m_macFontInstalled 
= false ; 
 570 void wxDC::SetMapMode( int mode 
) 
 575         SetLogicalScale( twips2mm 
* m_mm_to_pix_x
, twips2mm 
* m_mm_to_pix_y 
); 
 579         SetLogicalScale( pt2mm 
* m_mm_to_pix_x
, pt2mm 
* m_mm_to_pix_y 
); 
 583         SetLogicalScale( m_mm_to_pix_x
, m_mm_to_pix_y 
); 
 587         SetLogicalScale( m_mm_to_pix_x 
/ 10.0, m_mm_to_pix_y 
/ 10.0 ); 
 592         SetLogicalScale( 1.0, 1.0 ); 
 596     if (mode 
!= wxMM_TEXT
) 
 598         m_needComputeScaleX 
= true; 
 599         m_needComputeScaleY 
= true; 
 603 void wxDC::SetUserScale( double x
, double y 
) 
 605     // allow negative ? -> no 
 608     ComputeScaleAndOrigin(); 
 611 void wxDC::SetLogicalScale( double x
, double y 
) 
 616     ComputeScaleAndOrigin(); 
 619 void wxDC::SetLogicalOrigin( wxCoord x
, wxCoord y 
) 
 621     // is this still correct ? 
 622     m_logicalOriginX 
= x 
* m_signX
; 
 623     m_logicalOriginY 
= y 
* m_signY
; 
 624     ComputeScaleAndOrigin(); 
 627 void wxDC::SetDeviceOrigin( wxCoord x
, wxCoord y 
) 
 629     m_externalDeviceOriginX 
= x
; 
 630     m_externalDeviceOriginY 
= y
; 
 631     ComputeScaleAndOrigin(); 
 634 void wxDC::SetAxisOrientation( bool xLeftRight
, bool yBottomUp 
) 
 636     m_signX 
= (xLeftRight 
?  1 : -1); 
 637     m_signY 
= (yBottomUp  
? -1 :  1); 
 638     ComputeScaleAndOrigin(); 
 641 wxSize 
wxDC::GetPPI() const 
 643     return wxSize(72, 72); 
 646 int wxDC::GetDepth() const 
 648     if ( IsPortColor( (CGrafPtr
) m_macPort 
) ) 
 649         return ( (**GetPortPixMap( (CGrafPtr
) m_macPort
)).pixelSize 
) ; 
 654 void wxDC::ComputeScaleAndOrigin() 
 656     // CMB: copy scale to see if it changes 
 657     double origScaleX 
= m_scaleX
; 
 658     double origScaleY 
= m_scaleY
; 
 659     m_scaleX 
= m_logicalScaleX 
* m_userScaleX
; 
 660     m_scaleY 
= m_logicalScaleY 
* m_userScaleY
; 
 661     m_deviceOriginX 
= m_internalDeviceOriginX 
+ m_externalDeviceOriginX
; 
 662     m_deviceOriginY 
= m_internalDeviceOriginY 
+ m_externalDeviceOriginY
; 
 664     // CMB: if scale has changed call SetPen to recalulate the line width 
 665     if (m_scaleX 
!= origScaleX 
|| m_scaleY 
!= origScaleY
) 
 667         // this is a bit artificial, but we need to force wxDC to think 
 668         // the pen has changed 
 675 void wxDC::SetPalette( const wxPalette
& palette 
) 
 679 void wxDC::SetBackgroundMode( int mode 
) 
 681     m_backgroundMode 
= mode 
; 
 684 void wxDC::SetFont( const wxFont 
&font 
) 
 687     m_macFontInstalled 
= false ; 
 690 void wxDC::SetPen( const wxPen 
&pen 
) 
 696     m_macPenInstalled 
= false ; 
 699 void wxDC::SetBrush( const wxBrush 
&brush 
) 
 701     if (m_brush 
== brush
) 
 705     m_macBrushInstalled 
= false ; 
 708 void wxDC::SetBackground( const wxBrush 
&brush 
) 
 710     if (m_backgroundBrush 
== brush
) 
 713     m_backgroundBrush 
= brush
; 
 714     if (m_backgroundBrush
.Ok()) 
 715         m_macBrushInstalled 
= false ; 
 718 void wxDC::SetLogicalFunction( int function 
) 
 720     if (m_logicalFunction 
== function
) 
 723     m_logicalFunction 
= function 
; 
 724     m_macFontInstalled 
= false ; 
 725     m_macBrushInstalled 
= false ; 
 726     m_macPenInstalled 
= false ; 
 729 extern bool wxDoFloodFill(wxDC 
*dc
, wxCoord x
, wxCoord y
, 
 730                           const wxColour 
& col
, int style
); 
 732 bool wxDC::DoFloodFill(wxCoord x
, wxCoord y
, 
 733                        const wxColour
& col
, int style
) 
 735     return wxDoFloodFill(this, x
, y
, col
, style
); 
 738 bool wxDC::DoGetPixel( wxCoord x
, wxCoord y
, wxColour 
*col 
) const 
 740     wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel - invalid DC") ); 
 742     wxMacFastPortSetter 
helper(this) ; 
 744     // NOTE: Get/SetCPixel are slow! 
 746     GetCPixel( XLOG2DEVMAC(x
), YLOG2DEVMAC(y
), &colour 
); 
 748     // convert from Mac colour to wx 
 754 void wxDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2 
) 
 756     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawLine - invalid DC")); 
 758     wxMacFastPortSetter 
helper(this) ; 
 760     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 763         wxCoord offset 
= ( (m_pen
.GetWidth() == 0 ? 1 : 
 764             m_pen
.GetWidth() ) * (wxCoord
)m_scaleX 
- 1) / 2; 
 765         wxCoord xx1 
= XLOG2DEVMAC(x1
) - offset
; 
 766         wxCoord yy1 
= YLOG2DEVMAC(y1
) - offset
; 
 767         wxCoord xx2 
= XLOG2DEVMAC(x2
) - offset
; 
 768         wxCoord yy2 
= YLOG2DEVMAC(y2
) - offset
; 
 770         if ((m_pen
.GetCap() == wxCAP_ROUND
) && 
 771             (m_pen
.GetWidth() <= 1)) 
 773             // Implement LAST_NOT for MAC at least for 
 774             // orthogonal lines. RR. 
 797 void wxDC::DoCrossHair( wxCoord x
, wxCoord y 
) 
 799     wxCHECK_RET(Ok(), wxT("wxDC::DoCrossHair - invalid DC")); 
 801     wxMacFastPortSetter 
helper(this) ; 
 803     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 808         wxCoord xx 
= XLOG2DEVMAC(x
); 
 809         wxCoord yy 
= YLOG2DEVMAC(y
); 
 812         ::MoveTo( XLOG2DEVMAC(0), yy 
); 
 813         ::LineTo( XLOG2DEVMAC(w
), yy 
); 
 814         ::MoveTo( xx
, YLOG2DEVMAC(0) ); 
 815         ::LineTo( xx
, YLOG2DEVMAC(h
) ); 
 816         CalcBoundingBox(x
, y
); 
 817         CalcBoundingBox(x 
+ w
, y 
+ h
); 
 822 * To draw arcs properly the angles need to be converted from the WX style: 
 823 * Angles start on the +ve X axis and go anti-clockwise (As you would draw on 
 824 * a normal axis on paper). 
 827 * Angles start on the +ve y axis and go clockwise. 
 830 static double wxConvertWXangleToMACangle(double angle
) 
 832     double newAngle 
= 90 - angle 
; 
 834     while ( newAngle 
> 360 ) 
 836     while ( newAngle 
< 0 ) 
 842 void wxDC::DoDrawArc( wxCoord x1
, wxCoord y1
, 
 843                       wxCoord x2
, wxCoord y2
, 
 844                       wxCoord xc
, wxCoord yc 
) 
 846     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawArc - invalid DC")); 
 848     wxMacFastPortSetter 
helper(this) ; 
 850     wxCoord xx1 
= XLOG2DEVMAC(x1
); 
 851     wxCoord yy1 
= YLOG2DEVMAC(y1
); 
 852     wxCoord xx2 
= XLOG2DEVMAC(x2
); 
 853     wxCoord yy2 
= YLOG2DEVMAC(y2
); 
 854     wxCoord xxc 
= XLOG2DEVMAC(xc
); 
 855     wxCoord yyc 
= YLOG2DEVMAC(yc
); 
 857     double dx 
= xx1 
- xxc
; 
 858     double dy 
= yy1 
- yyc
; 
 859     double radius 
= sqrt((double)(dx 
* dx 
+ dy 
* dy
)); 
 860     wxCoord rad 
= (wxCoord
)radius
; 
 861     double radius1
, radius2
; 
 863     if (xx1 
== xx2 
&& yy1 
== yy2
) 
 868     else if (radius 
== 0.0) 
 870         radius1 
= radius2 
= 0.0; 
 874         radius1 
= (xx1 
- xxc 
== 0) ? 
 875             (yy1 
- yyc 
< 0) ? 90.0 : -90.0 : 
 876         -atan2(double(yy1 
- yyc
), double(xx1 
- xxc
)) * RAD2DEG
; 
 877         radius2 
= (xx2 
- xxc 
== 0) ? 
 878             (yy2 
- yyc 
< 0) ? 90.0 : -90.0 : 
 879         -atan2(double(yy2 
- yyc
), double(xx2 
- xxc
)) * RAD2DEG
; 
 882     wxCoord alpha2 
= wxCoord(radius2 
- radius1
); 
 883     wxCoord alpha1 
= wxCoord(wxConvertWXangleToMACangle(radius1
)); 
 887     Rect r 
= { yyc 
- rad
, xxc 
- rad
, yyc 
+ rad
, xxc 
+ rad 
}; 
 889     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 892         PaintArc(&r
, alpha1
, alpha2
); 
 895     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 898         FrameArc(&r
, alpha1
, alpha2
); 
 902 void wxDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
, 
 903                               double sa
, double ea 
) 
 905     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawEllepticArc - invalid DC")); 
 906     wxMacFastPortSetter 
helper(this) ; 
 909     // Order important Mac in opposite direction to wx 
 910     // we have to make sure that the filling is always counter-clockwise 
 911     double angle 
= sa 
- ea
; 
 915     wxCoord xx 
= XLOG2DEVMAC(x
); 
 916     wxCoord yy 
= YLOG2DEVMAC(y
); 
 917     wxCoord ww 
= m_signX 
* XLOG2DEVREL(w
); 
 918     wxCoord hh 
= m_signY 
* YLOG2DEVREL(h
); 
 920     // handle -ve width and/or height 
 933     sa 
= wxConvertWXangleToMACangle(sa
); 
 939     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 942         PaintArc(&r
, (short)sa
, (short)angle
); 
 945     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 948         FrameArc(&r
, (short)sa
, (short)angle
); 
 952 void wxDC::DoDrawPoint( wxCoord x
, wxCoord y 
) 
 954     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawPoint - invalid DC")); 
 956     wxMacFastPortSetter 
helper(this) ; 
 958     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 960         wxCoord xx1 
= XLOG2DEVMAC(x
); 
 961         wxCoord yy1 
= YLOG2DEVMAC(y
); 
 962         RGBColor pencolor 
= MAC_WXCOLORREF( m_pen
.GetColour().GetPixel()); 
 964         // NOTE: Get/SetCPixel are slow! 
 965         ::SetCPixel( xx1
, yy1
, &pencolor
) ; 
 966         CalcBoundingBox(x
, y
); 
 970 void wxDC::DoDrawLines(int n
, wxPoint points
[], 
 971                         wxCoord xoffset
, wxCoord yoffset
) 
 973     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawLines - invalid DC")); 
 975     if (m_pen
.GetStyle() == wxTRANSPARENT
) 
 978     wxMacFastPortSetter 
helper(this) ; 
 981     wxCoord offset 
= ( (m_pen
.GetWidth() == 0 ? 1 : 
 982     m_pen
.GetWidth() ) * (wxCoord
)m_scaleX 
- 1) / 2 ; 
 984     wxCoord x1
, x2 
, y1 
, y2 
; 
 985     x1 
= XLOG2DEVMAC(points
[0].x 
+ xoffset
); 
 986     y1 
= YLOG2DEVMAC(points
[0].y 
+ yoffset
); 
 988     ::MoveTo( x1 
- offset
, y1 
- offset 
); 
 989     for (int i 
= 0; i 
< n
-1; i
++) 
 991         x2 
= XLOG2DEVMAC(points
[i 
+ 1].x 
+ xoffset
); 
 992         y2 
= YLOG2DEVMAC(points
[i 
+ 1].y 
+ yoffset
); 
 993         ::LineTo( x2 
- offset
, y2 
- offset 
); 
 997 void wxDC::DoDrawPolygon(int n
, wxPoint points
[], 
 998                           wxCoord xoffset
, wxCoord yoffset
, 
1001     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawPolygon - invalid DC")); 
1003     if ( m_brush
.GetStyle() == wxTRANSPARENT 
&& m_pen
.GetStyle() == wxTRANSPARENT 
) 
1006     wxMacFastPortSetter 
helper(this) ; 
1008     wxCoord x1
, x2 
, y1 
, y2 
; 
1009     PolyHandle polygon 
= OpenPoly(); 
1010     x2 
= x1 
= XLOG2DEVMAC(points
[0].x 
+ xoffset
); 
1011     y2 
= y1 
= YLOG2DEVMAC(points
[0].y 
+ yoffset
); 
1014     for (int i 
= 1; i 
< n
; i
++) 
1016         x2 
= XLOG2DEVMAC(points
[i
].x 
+ xoffset
); 
1017         y2 
= YLOG2DEVMAC(points
[i
].y 
+ yoffset
); 
1021     // close the polyline if necessary 
1022     if ( x1 
!= x2 
|| y1 
!= y2 
) 
1023         ::LineTo( x1
, y1 
) ; 
1026     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
1029         ::PaintPoly( polygon 
); 
1032     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1035         ::FramePoly( polygon 
) ; 
1038     KillPoly( polygon 
); 
1041 void wxDC::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
1043     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawRectangle - invalid DC")); 
1045     wxMacFastPortSetter 
helper(this) ; 
1047     wxCoord xx 
= XLOG2DEVMAC(x
); 
1048     wxCoord yy 
= YLOG2DEVMAC(y
); 
1049     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
1050     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
1052     // CMB: draw nothing if transformed w or h is 0 
1053     if (ww 
== 0 || hh 
== 0) 
1056     // CMB: handle -ve width and/or height 
1069     Rect rect 
= { yy 
, xx 
, yy 
+ hh 
, xx 
+ ww 
} ; 
1071     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
1074         ::PaintRect( &rect 
) ; 
1077     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1080         ::FrameRect( &rect 
) ; 
1084 void wxDC::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
, 
1085                                    wxCoord width
, wxCoord height
, 
1088     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawRoundedRectangle - invalid DC")); 
1090     wxMacFastPortSetter 
helper(this) ; 
1092         radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
1093     wxCoord xx 
= XLOG2DEVMAC(x
); 
1094     wxCoord yy 
= YLOG2DEVMAC(y
); 
1095     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
1096     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
1098     // CMB: draw nothing if transformed w or h is 0 
1099     if (ww 
== 0 || hh 
== 0) 
1102     // CMB: handle -ve width and/or height 
1115     Rect rect 
= { yy 
, xx 
, yy 
+ hh 
, xx 
+ ww 
} ; 
1117     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
1120         ::PaintRoundRect( &rect 
, int(radius 
* 2) , int(radius 
* 2) ) ; 
1123     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1126         ::FrameRoundRect( &rect 
, int(radius 
* 2) , int(radius 
* 2) ) ; 
1130 void wxDC::DoDrawEllipse(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
1132     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawEllipse - invalid DC")); 
1134     wxMacFastPortSetter 
helper(this) ; 
1136     wxCoord xx 
= XLOG2DEVMAC(x
); 
1137     wxCoord yy 
= YLOG2DEVMAC(y
); 
1138     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
1139     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
1141     // CMB: draw nothing if transformed w or h is 0 
1142     if (ww 
== 0 || hh 
== 0) 
1145     // CMB: handle -ve width and/or height 
1158     Rect rect 
= { yy 
, xx 
, yy 
+ hh 
, xx 
+ ww 
} ; 
1160     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
1163         ::PaintOval( &rect 
) ; 
1166     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1169         ::FrameOval( &rect 
) ; 
1173 bool wxDC::CanDrawBitmap(void) const 
1178 bool wxDC::DoBlit(wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
, 
1179                    wxDC 
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func 
, bool useMask
, 
1180                    wxCoord xsrcMask
, wxCoord ysrcMask 
) 
1182     wxCHECK_MSG(Ok(), false, wxT("wxDC::DoBlit - invalid DC")); 
1183     wxCHECK_MSG(source
->Ok(), false, wxT("wxDC::DoBlit - invalid source DC")); 
1185     if ( logical_func 
== wxNO_OP 
) 
1188     if (xsrcMask 
== -1 && ysrcMask 
== -1) 
1194     // correct the parameter in case this dc does not have a mask at all 
1195     if ( useMask 
&& !source
->m_macMask 
) 
1198     Rect srcrect 
, dstrect 
; 
1199     srcrect
.top 
= source
->YLOG2DEVMAC(ysrc
) ; 
1200     srcrect
.left 
= source
->XLOG2DEVMAC(xsrc
)  ; 
1201     srcrect
.right 
= source
->XLOG2DEVMAC(xsrc 
+ width 
) ; 
1202     srcrect
.bottom 
= source
->YLOG2DEVMAC(ysrc 
+ height
) ; 
1203     dstrect
.top 
= YLOG2DEVMAC(ydest
) ; 
1204     dstrect
.left 
= XLOG2DEVMAC(xdest
) ; 
1205     dstrect
.bottom 
= YLOG2DEVMAC(ydest 
+ height 
)  ; 
1206     dstrect
.right 
= XLOG2DEVMAC(xdest 
+ width 
) ; 
1207     short mode 
= kUnsupportedMode 
; 
1208     bool invertDestinationFirst 
= false ; 
1210     switch ( logical_func 
) 
1212     case wxAND
:        // src AND dst 
1213         mode 
= adMin 
; // ok 
1216     case wxAND_INVERT
: // (NOT src) AND dst 
1217         mode 
= notSrcOr  
; // ok 
1220     case wxAND_REVERSE
:// src AND (NOT dst) 
1221         invertDestinationFirst 
= true ; 
1226         mode 
= kEmulatedMode 
; 
1230         mode 
= srcCopy 
; // ok 
1233     case wxEQUIV
:      // (NOT src) XOR dst 
1234         mode 
= srcXor 
; // ok 
1237     case wxINVERT
:     // NOT dst 
1238         mode 
= kEmulatedMode 
; //or hilite ; 
1241     case wxNAND
:       // (NOT src) OR (NOT dst) 
1242         invertDestinationFirst 
= true ; 
1246     case wxNOR
:        // (NOT src) AND (NOT dst) 
1247         invertDestinationFirst 
= true ; 
1251     case wxNO_OP
:      // dst 
1252         mode 
= kEmulatedMode 
; // this has already been handled upon entry 
1255     case wxOR
:         // src OR dst 
1259     case wxOR_INVERT
:  // (NOT src) OR dst 
1263     case wxOR_REVERSE
: // src OR (NOT dst) 
1264         invertDestinationFirst 
= true ; 
1269         mode 
= kEmulatedMode 
; 
1272     case wxSRC_INVERT
: // (NOT src) 
1273         mode 
= notSrcCopy 
; // ok 
1276     case wxXOR
:        // src XOR dst 
1277         mode 
= notSrcXor 
; // ok 
1284     if ( mode 
== kUnsupportedMode 
) 
1286         wxFAIL_MSG(wxT("unsupported blitting mode" )); 
1291     CGrafPtr            sourcePort 
= (CGrafPtr
) source
->m_macPort 
; 
1292     PixMapHandle    bmappixels 
=  GetGWorldPixMap( sourcePort 
) ; 
1293     if ( LockPixels(bmappixels
) ) 
1295         wxMacFastPortSetter 
helper(this) ; 
1297         if ( source
->GetDepth() == 1 ) 
1299             RGBForeColor( &MAC_WXCOLORREF(m_textForegroundColour
.GetPixel()) ) ; 
1300             RGBBackColor( &MAC_WXCOLORREF(m_textBackgroundColour
.GetPixel()) ) ; 
1304             // the modes need this, otherwise we'll end up having really nice colors... 
1305             RGBColor white 
= { 0xFFFF, 0xFFFF, 0xFFFF } ; 
1306             RGBColor black 
= { 0, 0, 0 } ; 
1308             RGBForeColor( &black 
) ; 
1309             RGBBackColor( &white 
) ; 
1312         if ( useMask 
&& source
->m_macMask 
) 
1314             if ( mode 
== srcCopy 
) 
1316                 if ( LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) ) ) ) 
1318                     CopyMask( GetPortBitMapForCopyBits( sourcePort 
) , 
1319                         GetPortBitMapForCopyBits( MAC_WXHBITMAP(source
->m_macMask
) ) , 
1320                         GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ) , 
1321                         &srcrect
, &srcrect 
, &dstrect 
) ; 
1322                     UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) )  ) ; 
1327                 RgnHandle clipRgn 
= NewRgn() ; 
1328                 LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) ) ) ; 
1329                 BitMapToRegion( clipRgn 
, (BitMap
*) *GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) ) ) ; 
1330                 UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) ) ) ; 
1331                 OffsetRgn( clipRgn 
, -srcrect
.left 
+ dstrect
.left
, -srcrect
.top 
+  dstrect
.top 
) ; 
1333                 if ( mode 
== kEmulatedMode 
) 
1337                     ::PenPat(GetQDGlobalsBlack(&pat
)); 
1338                     if ( logical_func 
== wxSET 
) 
1340                         RGBColor col
= { 0xFFFF, 0xFFFF, 0xFFFF } ; 
1341                         ::RGBForeColor( &col  
) ; 
1342                         ::PaintRgn( clipRgn 
) ; 
1344                     else if ( logical_func 
== wxCLEAR 
) 
1346                         RGBColor col
= { 0x0000, 0x0000, 0x0000 } ; 
1347                         ::RGBForeColor( &col  
) ; 
1348                         ::PaintRgn( clipRgn 
) ; 
1350                     else if ( logical_func 
== wxINVERT 
) 
1352                         MacInvertRgn( clipRgn 
) ; 
1356                         for ( int y 
= 0 ; y 
< srcrect
.right 
- srcrect
.left 
; ++y 
) 
1358                             for ( int x 
= 0 ; x 
< srcrect
.bottom 
- srcrect
.top 
; ++x 
) 
1360                                 Point dstPoint 
= { dstrect
.top 
+ y 
, dstrect
.left 
+ x 
} ; 
1361                                 Point srcPoint 
= { srcrect
.top 
+ y 
, srcrect
.left 
+ x 
} ; 
1362                                 if ( PtInRgn( dstPoint 
, clipRgn 
) ) 
1364                                     RGBColor srcColor
, dstColor 
; 
1366                                     // NOTE: Get/SetCPixel are slow! 
1367                                     SetPort( (GrafPtr
) sourcePort 
) ; 
1368                                     GetCPixel( srcPoint
.h 
, srcPoint
.v 
, &srcColor 
) ; 
1369                                     SetPort( (GrafPtr
) m_macPort 
) ; 
1370                                     GetCPixel( dstPoint
.h 
, dstPoint
.v 
, &dstColor 
) ; 
1371                                     wxMacCalculateColour( logical_func 
, srcColor 
, dstColor 
) ; 
1372                                     SetCPixel( dstPoint
.h 
, dstPoint
.v 
, &dstColor 
) ; 
1380                     if ( invertDestinationFirst 
) 
1381                         MacInvertRgn( clipRgn 
) ; 
1383                     CopyBits( GetPortBitMapForCopyBits( sourcePort 
) , 
1384                         GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ) , 
1385                         &srcrect
, &dstrect
, mode
, clipRgn 
) ; 
1388                 DisposeRgn( clipRgn 
) ; 
1393             RgnHandle clipRgn 
= NewRgn() ; 
1394             SetRectRgn( clipRgn 
, dstrect
.left 
, dstrect
.top 
, dstrect
.right 
, dstrect
.bottom 
) ; 
1396             if ( mode 
== kEmulatedMode 
) 
1400                 ::PenPat(GetQDGlobalsBlack(&pat
)); 
1401                 if ( logical_func 
== wxSET 
) 
1403                     RGBColor col
= { 0xFFFF, 0xFFFF, 0xFFFF } ; 
1404                     ::RGBForeColor( &col  
) ; 
1405                     ::PaintRgn( clipRgn 
) ; 
1407                 else if ( logical_func 
== wxCLEAR 
) 
1409                     RGBColor col 
= { 0x0000, 0x0000, 0x0000 } ; 
1411                     ::RGBForeColor( &col  
) ; 
1412                     ::PaintRgn( clipRgn 
) ; 
1414                 else if ( logical_func 
== wxINVERT 
) 
1416                     MacInvertRgn( clipRgn 
) ; 
1420                     for ( int y 
= 0 ; y 
< srcrect
.right 
- srcrect
.left 
; ++y 
) 
1422                         for ( int x 
= 0 ; x 
< srcrect
.bottom 
- srcrect
.top 
; ++x 
) 
1424                             Point dstPoint 
= { dstrect
.top 
+ y 
, dstrect
.left 
+ x 
} ; 
1425                             Point srcPoint 
= { srcrect
.top 
+ y 
, srcrect
.left 
+ x 
} ; 
1427                                 RGBColor srcColor
, dstColor 
; 
1429                                 // NOTE: Get/SetCPixel are slow! 
1430                                 SetPort( (GrafPtr
) sourcePort 
) ; 
1431                                 GetCPixel( srcPoint
.h 
, srcPoint
.v 
, &srcColor
) ; 
1432                                 SetPort( (GrafPtr
) m_macPort 
) ; 
1433                                 GetCPixel( dstPoint
.h 
, dstPoint
.v 
, &dstColor 
) ; 
1434                                 wxMacCalculateColour( logical_func 
, srcColor 
, dstColor 
) ; 
1435                                 SetCPixel( dstPoint
.h 
, dstPoint
.v 
, &dstColor 
) ; 
1443                 if ( invertDestinationFirst 
) 
1444                     MacInvertRgn( clipRgn 
) ; 
1446                 CopyBits( GetPortBitMapForCopyBits( sourcePort 
) , 
1447                     GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ) , 
1448                     &srcrect
, &dstrect
, mode
, NULL 
) ; 
1451             DisposeRgn( clipRgn 
) ; 
1454         UnlockPixels( bmappixels 
) ; 
1457     m_macPenInstalled 
= false ; 
1458     m_macBrushInstalled 
= false ; 
1459     m_macFontInstalled 
= false ; 
1464 void wxDC::DoDrawRotatedText(const wxString
& str
, wxCoord x
, wxCoord y
, 
1467     wxCHECK_RET( Ok(), wxT("wxDC::DoDrawRotatedText - invalid DC") ); 
1472     wxMacFastPortSetter 
helper(this) ; 
1475     OSStatus status 
= noErr 
; 
1476     ATSUTextLayout atsuLayout 
; 
1478     wxMacUniCharBuffer 
unibuf( str 
) ; 
1479     UniCharCount chars 
= unibuf
.GetChars() ; 
1481     status 
= ::ATSUCreateTextLayoutWithTextPtr( unibuf
.GetBuffer() , 0 , chars 
, chars 
, 1 , 
1482         &chars 
, (ATSUStyle
*) &m_macATSUIStyle 
, &atsuLayout 
) ; 
1484     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create the layout of the rotated text") ); 
1486     status 
= ::ATSUSetTransientFontMatching( atsuLayout 
, true ) ; 
1487     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't setup transient font matching") ); 
1489     int iAngle 
= int( angle 
); 
1490     int drawX 
= XLOG2DEVMAC(x
) ; 
1491     int drawY 
= YLOG2DEVMAC(y
) ; 
1493     ATSUTextMeasurement textBefore
, textAfter 
; 
1494     ATSUTextMeasurement ascent
, descent 
; 
1496     ATSLineLayoutOptions layoutOptions 
= kATSLineNoLayoutOptions 
; 
1498     if (m_font
.GetNoAntiAliasing()) 
1500         layoutOptions 
|= kATSLineNoAntiAliasing 
; 
1503     Fixed atsuAngle 
= IntToFixed( iAngle 
) ; 
1505     ATSUAttributeTag atsuTags
[] = 
1507         kATSULineLayoutOptionsTag 
, 
1508         kATSULineRotationTag 
, 
1511     ByteCount atsuSizes
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1513         sizeof( ATSLineLayoutOptions 
) , 
1517     ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1523     status 
= ::ATSUSetLayoutControls(atsuLayout 
, sizeof(atsuTags
)/sizeof(ATSUAttributeTag
) - ( abs(iAngle
) > 0.001 ? 0 : 1), 
1524             atsuTags
, atsuSizes
, atsuValues 
) ; 
1526     status 
= ::ATSUMeasureText( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1527         &textBefore 
, &textAfter
, &ascent 
, &descent 
); 
1528     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't measure the rotated text") ); 
1530     if ( m_backgroundMode 
== wxSOLID 
) 
1532         // background painting must be done by hand, cannot be done by ATSUI 
1534         PolyHandle polygon 
= OpenPoly(); 
1536         ::MoveTo(drawX
, drawY
); 
1538         x2 
= (int) (drawX 
+ sin(angle 
/ RAD2DEG
) * FixedToInt(ascent 
+ descent
)) ; 
1539         y2 
= (int) (drawY 
+ cos(angle 
/ RAD2DEG
) * FixedToInt(ascent 
+ descent
)) ; 
1542         x2 
= (int) (drawX 
+ sin(angle 
/ RAD2DEG
) * FixedToInt(ascent 
+ descent 
) + cos(angle 
/ RAD2DEG
) * FixedToInt(textAfter
)) ; 
1543         y2 
= (int) (drawY 
+ cos(angle 
/ RAD2DEG
) * FixedToInt(ascent 
+ descent
) - sin(angle 
/ RAD2DEG
) * FixedToInt(textAfter
)) ; 
1546         x2 
= (int) (drawX 
+ cos(angle 
/ RAD2DEG
) * FixedToInt(textAfter
)) ; 
1547         y2 
= (int) (drawY 
- sin(angle 
/ RAD2DEG
) * FixedToInt(textAfter
)) ; 
1550         ::LineTo( drawX
, drawY
) ; 
1553         ::ErasePoly( polygon 
); 
1554         KillPoly( polygon 
); 
1557     drawX 
+= (int)(sin(angle 
/ RAD2DEG
) * FixedToInt(ascent
)); 
1558     drawY 
+= (int)(cos(angle 
/ RAD2DEG
) * FixedToInt(ascent
)); 
1559     status 
= ::ATSUDrawText( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1560         IntToFixed(drawX
) , IntToFixed(drawY
) ); 
1562     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't draw the rotated text") ); 
1565     status 
= ::ATSUMeasureTextImage( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1566         IntToFixed(drawX
) , IntToFixed(drawY
) , &rect 
); 
1567     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't measure the rotated text") ); 
1569     OffsetRect( &rect 
, -m_macLocalOrigin
.x 
, -m_macLocalOrigin
.y 
) ; 
1570     CalcBoundingBox(XDEV2LOG(rect
.left
), YDEV2LOG(rect
.top
) ); 
1571     CalcBoundingBox(XDEV2LOG(rect
.right
), YDEV2LOG(rect
.bottom
) ); 
1572     ::ATSUDisposeTextLayout(atsuLayout
); 
1575 void wxDC::DoDrawText(const wxString
& strtext
, wxCoord x
, wxCoord y
) 
1577     DoDrawRotatedText( strtext 
, x 
, y 
, 0) ; 
1580 bool wxDC::CanGetTextExtent() const 
1582     wxCHECK_MSG(Ok(), false, wxT("wxDC::CanGetTextExtent - invalid DC")); 
1588 void wxDC::DoGetTextExtent( const wxString 
&str
, wxCoord 
*width
, wxCoord 
*height
, 
1589                             wxCoord 
*descent
, wxCoord 
*externalLeading 
, 
1590                             wxFont 
*theFont 
) const 
1592     wxCHECK_RET(Ok(), wxT("wxDC::DoGetTextExtent - invalid DC")); 
1594     wxMacFastPortSetter 
helper(this) ; 
1595     wxFont formerFont 
= m_font 
; 
1598         // work around the constness 
1599         *((wxFont
*)(&m_font
)) = *theFont 
; 
1604     OSStatus status 
= noErr 
; 
1605     ATSUTextLayout atsuLayout 
; 
1607     wxMacUniCharBuffer 
unibuf( str 
) ; 
1608     UniCharCount chars 
= unibuf
.GetChars() ; 
1610     status 
= ::ATSUCreateTextLayoutWithTextPtr( unibuf
.GetBuffer() , 0 , chars 
, chars 
, 1 , 
1611         &chars 
, (ATSUStyle
*) &m_macATSUIStyle 
, &atsuLayout 
) ; 
1613     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create the layout of the text") ); 
1615     status 
= ::ATSUSetTransientFontMatching( atsuLayout 
, true ) ; 
1616     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't setup transient font matching") ); 
1618     ATSLineLayoutOptions layoutOptions 
= kATSLineNoLayoutOptions 
; 
1620     if (m_font
.GetNoAntiAliasing()) 
1622         layoutOptions 
|= kATSLineNoAntiAliasing 
; 
1625     ATSUAttributeTag atsuTags
[] = 
1627         kATSULineLayoutOptionsTag 
, 
1630     ByteCount atsuSizes
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1632         sizeof( ATSLineLayoutOptions 
) , 
1635     ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1640     status 
= ::ATSUSetLayoutControls(atsuLayout 
, sizeof(atsuTags
)/sizeof(ATSUAttributeTag
) , 
1641             atsuTags
, atsuSizes
, atsuValues 
) ; 
1643     ATSUTextMeasurement textBefore
, textAfter 
; 
1644     ATSUTextMeasurement textAscent
, textDescent 
; 
1646     status 
= ::ATSUGetUnjustifiedBounds( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1647         &textBefore 
, &textAfter
, &textAscent 
, &textDescent 
); 
1650         *height 
= YDEV2LOGREL( FixedToInt(textAscent 
+ textDescent
) ) ; 
1652         *descent 
=YDEV2LOGREL( FixedToInt(textDescent
) ); 
1653     if ( externalLeading 
) 
1654         *externalLeading 
= 0 ; 
1656         *width 
= XDEV2LOGREL( FixedToInt(textAfter 
- textBefore
) ) ; 
1658     ::ATSUDisposeTextLayout(atsuLayout
); 
1663         // work around the constness 
1664         *((wxFont
*)(&m_font
)) = formerFont 
; 
1665         m_macFontInstalled 
= false ; 
1669 bool wxDC::DoGetPartialTextExtents(const wxString
& text
, wxArrayInt
& widths
) const 
1671     wxCHECK_MSG(Ok(), false, wxT("wxDC::DoGetPartialTextExtents - invalid DC")); 
1674     widths
.Add(0, text
.length()); 
1676     if (text
.length() == 0) 
1679     wxMacFastPortSetter 
helper(this) ; 
1682     OSStatus status 
= noErr 
; 
1683     ATSUTextLayout atsuLayout 
; 
1685     wxMacUniCharBuffer 
unibuf( text 
) ; 
1686     UniCharCount chars 
= unibuf
.GetChars() ; 
1688     status 
= ::ATSUCreateTextLayoutWithTextPtr( unibuf
.GetBuffer() , 0 , chars 
, chars 
, 1 , 
1689         &chars 
, (ATSUStyle
*) &m_macATSUIStyle 
, &atsuLayout 
) ; 
1691     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create the layout of the text") ); 
1693     status 
= ::ATSUSetTransientFontMatching( atsuLayout 
, true ) ; 
1694     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't setup transient font matching") ); 
1696     ATSLineLayoutOptions layoutOptions 
= kATSLineNoLayoutOptions 
; 
1698     if (m_font
.GetNoAntiAliasing()) 
1700         layoutOptions 
|= kATSLineNoAntiAliasing 
; 
1703     ATSUAttributeTag atsuTags
[] = 
1705         kATSULineLayoutOptionsTag 
, 
1708     ByteCount atsuSizes
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1710         sizeof( ATSLineLayoutOptions 
) , 
1713     ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1718     status 
= ::ATSUSetLayoutControls(atsuLayout 
, sizeof(atsuTags
)/sizeof(ATSUAttributeTag
) , 
1719             atsuTags
, atsuSizes
, atsuValues 
) ; 
1721     for ( int pos 
= 0; pos 
< (int)chars 
; pos 
++ ) 
1723         unsigned long actualNumberOfBounds 
= 0; 
1724         ATSTrapezoid glyphBounds
; 
1726         // We get a single bound, since the text should only require one. If it requires more, there is an issue 
1728         result 
= ATSUGetGlyphBounds( atsuLayout
, 0, 0, kATSUFromTextBeginning
, pos 
+ 1, 
1729             kATSUseDeviceOrigins
, 1, &glyphBounds
, &actualNumberOfBounds 
); 
1730         if (result 
!= noErr 
|| actualNumberOfBounds 
!= 1 ) 
1733         widths
[pos
] = XDEV2LOGREL(FixedToInt( glyphBounds
.upperRight
.x 
- glyphBounds
.upperLeft
.x 
)); 
1736     ::ATSUDisposeTextLayout(atsuLayout
); 
1741 wxCoord 
wxDC::GetCharWidth(void) const 
1744     DoGetTextExtent( wxT("g"), &width 
, NULL 
, NULL 
, NULL 
, NULL 
) ; 
1748 wxCoord 
wxDC::GetCharHeight(void) const 
1751     DoGetTextExtent( wxT("g") , NULL 
, &height 
, NULL 
, NULL 
, NULL 
) ; 
1755 void wxDC::Clear(void) 
1757     wxCHECK_RET(Ok(), wxT("wxDC::Clear - invalid DC")); 
1759     wxMacFastPortSetter 
helper(this) ; 
1760     Rect rect 
= { -31000 , -31000 , 31000 , 31000 } ; 
1762     if ( m_backgroundBrush
.Ok() && m_backgroundBrush
.GetStyle() != wxTRANSPARENT
) 
1765         MacSetupBackgroundForCurrentPort( m_backgroundBrush 
) ; 
1766         ::EraseRect( &rect 
) ; 
1770 void wxDC::MacInstallFont() const 
1772     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
1774     //    if ( m_macFontInstalled ) 
1777     Pattern blackColor 
; 
1778     MacSetupBackgroundForCurrentPort(m_backgroundBrush
) ; 
1779     if ( m_backgroundMode 
!= wxTRANSPARENT 
) 
1781         Pattern whiteColor 
; 
1782         ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
1785     wxASSERT( m_font
.Ok() ) ; 
1787     ::TextFont( m_font
.MacGetFontNum() ) ; 
1788     ::TextSize( (short)(m_scaleY 
* m_font
.MacGetFontSize()) ) ; 
1789     ::TextFace( m_font
.MacGetFontStyle() ) ; 
1790     m_macFontInstalled 
= true ; 
1791     m_macBrushInstalled 
= false ; 
1792     m_macPenInstalled 
= false ; 
1793     RGBColor forecolor 
= MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()); 
1794     RGBColor backcolor 
= MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()); 
1795     ::RGBForeColor( &forecolor 
); 
1796     ::RGBBackColor( &backcolor 
); 
1799     short mode 
= patCopy 
; 
1800     switch ( m_logicalFunction 
) 
1806     case wxINVERT
:     // NOT dst 
1807         ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
1811     case wxXOR
:        // src XOR dst 
1815     case wxOR_REVERSE
: // src OR (NOT dst) 
1819     case wxSRC_INVERT
: // (NOT src) 
1823     case wxAND
: // src AND dst 
1827     // TODO: unsupported 
1829     case wxAND_REVERSE
:// src AND (NOT dst) 
1830     case wxAND_INVERT
: // (NOT src) AND dst 
1831     case wxNO_OP
:      // dst 
1832     case wxNOR
:        // (NOT src) AND (NOT dst) 
1833     case wxEQUIV
:      // (NOT src) XOR dst 
1834     case wxOR_INVERT
:  // (NOT src) OR dst 
1835     case wxNAND
:       // (NOT src) OR (NOT dst) 
1836     case wxOR
:         // src OR dst 
1838         //        case wxSRC_OR:     // source _bitmap_ OR destination 
1839         //        case wxSRC_AND:     // source _bitmap_ AND destination 
1847     OSStatus status 
= noErr 
; 
1848     status 
= ATSUCreateAndCopyStyle( (ATSUStyle
) m_font
.MacGetATSUStyle() , (ATSUStyle
*) &m_macATSUIStyle 
) ; 
1849     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't set create ATSU style") ) ; 
1851     Fixed atsuSize 
= IntToFixed( int(m_scaleY 
* m_font
.MacGetFontSize()) ) ; 
1852     ATSUAttributeTag atsuTags
[] = 
1856     ByteCount atsuSizes
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1860     ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1865     status 
= ::ATSUSetAttributes((ATSUStyle
)m_macATSUIStyle
, sizeof(atsuTags
)/sizeof(ATSUAttributeTag
) , 
1866         atsuTags
, atsuSizes
, atsuValues
); 
1868     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't modify ATSU style") ) ; 
1871 Pattern gPatterns
[] = 
1874     { { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } } , 
1875     { { 0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40 , 0x80 } } , 
1876     { { 0x80 , 0x40 , 0x20 , 0x10 , 0x08 , 0x04 , 0x02 , 0x01 } } , 
1877     { { 0x10 , 0x10 , 0x10 , 0xFF , 0x10 , 0x10 , 0x10 , 0x10 } } , 
1878     { { 0x00 , 0x00 , 0x00 , 0xFF , 0x00 , 0x00 , 0x00 , 0x00 } } , 
1879     { { 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 } } , 
1880     { { 0x81 , 0x42 , 0x24 , 0x18 , 0x18 , 0x24 , 0x42 , 0x81 } } , 
1883     { { 0xCC , 0x99 , 0x33 , 0x66 , 0xCC , 0x99 , 0x33 , 0x66 } } , // DOT 
1884     { { 0xFE , 0xFD , 0xFB , 0xF7 , 0xEF , 0xDF , 0xBF , 0x7F } } , // LONG_DASH 
1885     { { 0xEE , 0xDD , 0xBB , 0x77 , 0xEE , 0xDD , 0xBB , 0x77 } } , // SHORT_DASH 
1886     { { 0xDE , 0xBD , 0x7B , 0xF6 , 0xED , 0xDB , 0xB7 , 0x6F } } , // DOT_DASH 
1889 static void wxMacGetPattern(int penStyle
, Pattern 
*pattern
) 
1891     int index 
= 0;  // solid pattern by default 
1895         case wxBDIAGONAL_HATCH
:     index 
= 1; break; 
1896         case wxFDIAGONAL_HATCH
:     index 
= 2; break; 
1897         case wxCROSS_HATCH
:         index 
= 3; break; 
1898         case wxHORIZONTAL_HATCH
:    index 
= 4; break; 
1899         case wxVERTICAL_HATCH
:      index 
= 5; break; 
1900         case wxCROSSDIAG_HATCH
:     index 
= 6; break; 
1903         case wxDOT
:                 index 
= 7; break; 
1904         case wxLONG_DASH
:           index 
= 8; break; 
1905         case wxSHORT_DASH
:          index 
= 9; break; 
1906         case wxDOT_DASH
:            index 
= 10; break; 
1912     *pattern 
= gPatterns
[index
]; 
1915 void wxDC::MacInstallPen() const 
1917     wxCHECK_RET(Ok(), wxT("wxDC::MacInstallPen - invalid DC")); 
1919     //Pattern     blackColor; 
1920     //    if ( m_macPenInstalled ) 
1923     RGBColor forecolor 
= MAC_WXCOLORREF( m_pen
.GetColour().GetPixel()); 
1924     RGBColor backcolor 
= MAC_WXCOLORREF( m_backgroundBrush
.GetColour().GetPixel()); 
1925     ::RGBForeColor( &forecolor 
); 
1926     ::RGBBackColor( &backcolor 
); 
1929     // null means only one pixel, at whatever resolution 
1930     int penWidth 
= (int) (m_pen
.GetWidth() * m_scaleX
) ; 
1931     if ( penWidth 
== 0 ) 
1933     ::PenSize(penWidth
, penWidth
); 
1936     int penStyle 
= m_pen
.GetStyle(); 
1937     if (penStyle 
== wxUSER_DASH
) 
1939         // FIXME: there should be exactly 8 items in the dash 
1941         int number 
= m_pen
.GetDashes(&dash
) ; 
1943         for ( int i 
= 0 ; i 
< 8 ; ++i 
) 
1945             pat
.pat
[i
] = dash
[index
] ; 
1946             if (index 
< number 
- 1) 
1952         wxMacGetPattern(penStyle
, &pat
); 
1957     short mode 
= patCopy 
; 
1958     switch ( m_logicalFunction 
) 
1960     case wxCOPY
:       // only foreground color, leave background (thus not patCopy) 
1964     case wxINVERT
:     // NOT dst 
1965         //            ::PenPat(GetQDGlobalsBlack(&blackColor)); 
1969     case wxXOR
:        // src XOR dst 
1973     case wxOR_REVERSE
: // src OR (NOT dst) 
1977     case wxSRC_INVERT
: // (NOT src) 
1981     case wxAND
: // src AND dst 
1985     // TODO: unsupported 
1987     case wxAND_REVERSE
:// src AND (NOT dst) 
1988     case wxAND_INVERT
: // (NOT src) AND dst 
1989     case wxNO_OP
:      // dst 
1990     case wxNOR
:        // (NOT src) AND (NOT dst) 
1991     case wxEQUIV
:      // (NOT src) XOR dst 
1992     case wxOR_INVERT
:  // (NOT src) OR dst 
1993     case wxNAND
:       // (NOT src) OR (NOT dst) 
1994     case wxOR
:         // src OR dst 
1996         //        case wxSRC_OR:     // source _bitmap_ OR destination 
1997         //        case wxSRC_AND:     // source _bitmap_ AND destination 
2005     m_macPenInstalled 
= true ; 
2006     m_macBrushInstalled 
= false ; 
2007     m_macFontInstalled 
= false ; 
2010 void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush
& background 
) 
2012     Pattern whiteColor 
; 
2014     if ( background
.Ok() ) 
2016         switch ( background
.MacGetBrushKind() ) 
2018             case kwxMacBrushTheme 
: 
2019                 ::SetThemeBackground( background
.MacGetTheme() , wxDisplayDepth() , true ) ; 
2022             case kwxMacBrushThemeBackground 
: 
2025                 ThemeBackgroundKind bg 
= background
.MacGetThemeBackground( &extent 
) ; 
2026                 ::ApplyThemeBackground( bg 
, &extent
, kThemeStateActive 
, wxDisplayDepth() , true ) ; 
2030             case kwxMacBrushColour 
: 
2032                 ::RGBBackColor( &MAC_WXCOLORREF( background
.GetColour().GetPixel()) ); 
2033                 int brushStyle 
= background
.GetStyle(); 
2034                 if (brushStyle 
== wxSOLID
) 
2035                     ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
2036                 else if (background
.IsHatch()) 
2039                     wxMacGetPattern(brushStyle
, &pat
); 
2044                     ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
2055 void wxDC::MacInstallBrush() const 
2057     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
2059     //    if ( m_macBrushInstalled ) 
2062     Pattern     blackColor 
; 
2063     bool backgroundTransparent 
= (GetBackgroundMode() == wxTRANSPARENT
) ; 
2064     ::RGBForeColor( &MAC_WXCOLORREF( m_brush
.GetColour().GetPixel()) ); 
2065     ::RGBBackColor( &MAC_WXCOLORREF( m_backgroundBrush
.GetColour().GetPixel()) ); 
2067     int brushStyle 
= m_brush
.GetStyle(); 
2068     if (brushStyle 
== wxSOLID
) 
2070         switch ( m_brush
.MacGetBrushKind() ) 
2072             case kwxMacBrushTheme 
: 
2074                     Pattern whiteColor 
; 
2075                     ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
2076                     ::SetThemePen( m_brush
.MacGetTheme() , wxDisplayDepth() , true ) ; 
2081                 ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
2086     else if (m_brush
.IsHatch()) 
2090         wxMacGetPattern(brushStyle
, &pat
); 
2093     else if ( m_brush
.GetStyle() == wxSTIPPLE 
|| m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE 
) 
2095         // we force this in order to be compliant with wxMSW 
2096         backgroundTransparent 
= false ; 
2098         // for these the text fore (and back for MASK_OPAQUE) colors are used 
2099         wxBitmap
* bitmap 
= m_brush
.GetStipple() ; 
2100         int width 
= bitmap
->GetWidth() ; 
2101         int height 
= bitmap
->GetHeight() ; 
2102         GWorldPtr gw 
= NULL 
; 
2104         if ( m_brush
.GetStyle() == wxSTIPPLE 
) 
2105             gw 
= MAC_WXHBITMAP(bitmap
->GetHBITMAP(NULL
))  ; 
2107             gw 
= MAC_WXHBITMAP(bitmap
->GetMask()->GetHBITMAP()) ; 
2109         PixMapHandle gwpixmaphandle 
= GetGWorldPixMap( gw 
) ; 
2110         LockPixels( gwpixmaphandle 
) ; 
2111         bool isMonochrome 
= !IsPortColor( gw 
) ; 
2112         if ( !isMonochrome 
) 
2114             if ( (**gwpixmaphandle
).pixelSize 
== 1 ) 
2115                 isMonochrome 
= true ; 
2118         if ( isMonochrome 
&& width 
== 8 && height 
== 8 ) 
2120             ::RGBForeColor( &MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()) ); 
2121             ::RGBForeColor( &MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()) ); 
2122             BitMap
* gwbitmap 
= (BitMap
*) *gwpixmaphandle 
; // since the color depth is 1 it is a BitMap 
2123             UInt8 
*gwbits 
= (UInt8
*) gwbitmap
->baseAddr 
; 
2124             int alignment 
= gwbitmap
->rowBytes 
& 0x7FFF ; 
2127             for ( int i 
= 0 ; i 
< 8 ; ++i 
) 
2129                 pat
.pat
[i
] = gwbits
[i 
* alignment 
+ 0] ; 
2132             UnlockPixels( GetGWorldPixMap( gw 
) ) ; 
2137             // this will be the code to handle power of 2 patterns, we will have to arrive at a nice 
2138             // caching scheme before putting this into production 
2142             PixPatHandle pixpat 
= NewPixPat() ; 
2143             CopyPixMap(gwpixmaphandle
, (**pixpat
).patMap
); 
2144             imageSize 
= GetPixRowBytes((**pixpat
).patMap
) * 
2145                 ((**(**pixpat
).patMap
).bounds
.bottom 
- 
2146                 (**(**pixpat
).patMap
).bounds
.top
); 
2147             PtrToHand( (**gwpixmaphandle
).baseAddr
, &image
, imageSize 
); 
2148             (**pixpat
).patData 
= image
; 
2152                 CTabHandle ctable 
= ((**((**pixpat
).patMap
)).pmTable
) ; 
2153                 ColorSpecPtr ctspec 
= (ColorSpecPtr
) &(**ctable
).ctTable 
; 
2154                 if ( ctspec
[0].rgb
.red 
== 0x0000 ) 
2156                     ctspec
[1].rgb 
= MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()) ; 
2157                     ctspec
[0].rgb 
= MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()) ; 
2161                     ctspec
[0].rgb 
= MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()) ; 
2162                     ctspec
[1].rgb 
= MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()) ; 
2164                 ::CTabChanged( ctable 
) ; 
2167             ::PenPixPat(pixpat
); 
2168             m_macForegroundPixMap 
= pixpat 
; 
2171         UnlockPixels( gwpixmaphandle 
) ; 
2175         ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
2178     short mode 
= patCopy 
; 
2179     switch ( m_logicalFunction 
) 
2182         if ( backgroundTransparent 
) 
2188     case wxINVERT
:     // NOT dst 
2189         if ( !backgroundTransparent 
) 
2190             ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
2194     case wxXOR
:        // src XOR dst 
2198     case wxOR_REVERSE
: // src OR (NOT dst) 
2202     case wxSRC_INVERT
: // (NOT src) 
2206     case wxAND
: // src AND dst 
2210     // TODO: unsupported 
2212     case wxAND_REVERSE
:// src AND (NOT dst) 
2213     case wxAND_INVERT
: // (NOT src) AND dst 
2214     case wxNO_OP
:      // dst 
2215     case wxNOR
:        // (NOT src) AND (NOT dst) 
2216     case wxEQUIV
:      // (NOT src) XOR dst 
2217     case wxOR_INVERT
:  // (NOT src) OR dst 
2218     case wxNAND
:       // (NOT src) OR (NOT dst) 
2219     case wxOR
:         // src OR dst 
2221         //        case wxSRC_OR:     // source _bitmap_ OR destination 
2222         //        case wxSRC_AND:     // source _bitmap_ AND destination 
2230     m_macBrushInstalled 
= true ; 
2231     m_macPenInstalled 
= false ; 
2232     m_macFontInstalled 
= false ; 
2235 // --------------------------------------------------------------------------- 
2236 // coordinates transformations 
2237 // --------------------------------------------------------------------------- 
2239 wxCoord 
wxDCBase::DeviceToLogicalX(wxCoord x
) const 
2241     return ((wxDC 
*)this)->XDEV2LOG(x
); 
2244 wxCoord 
wxDCBase::DeviceToLogicalY(wxCoord y
) const 
2246     return ((wxDC 
*)this)->YDEV2LOG(y
); 
2249 wxCoord 
wxDCBase::DeviceToLogicalXRel(wxCoord x
) const 
2251     return ((wxDC 
*)this)->XDEV2LOGREL(x
); 
2254 wxCoord 
wxDCBase::DeviceToLogicalYRel(wxCoord y
) const 
2256     return ((wxDC 
*)this)->YDEV2LOGREL(y
); 
2259 wxCoord 
wxDCBase::LogicalToDeviceX(wxCoord x
) const 
2261     return ((wxDC 
*)this)->XLOG2DEV(x
); 
2264 wxCoord 
wxDCBase::LogicalToDeviceY(wxCoord y
) const 
2266     return ((wxDC 
*)this)->YLOG2DEV(y
); 
2269 wxCoord 
wxDCBase::LogicalToDeviceXRel(wxCoord x
) const 
2271     return ((wxDC 
*)this)->XLOG2DEVREL(x
); 
2274 wxCoord 
wxDCBase::LogicalToDeviceYRel(wxCoord y
) const 
2276     return ((wxDC 
*)this)->YLOG2DEVREL(y
); 
2279 #endif // !wxMAC_USE_CORE_GRAPHICS