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 
; 
 267     m_macFontInstalled 
= false ; 
 268     m_macBrushInstalled 
= false ; 
 269     m_macPenInstalled 
= false ; 
 270     m_macBoundaryClipRgn 
= NewRgn() ; 
 271     m_macCurrentClipRgn 
= NewRgn() ; 
 272     SetRectRgn( (RgnHandle
) m_macBoundaryClipRgn 
, -32000 , -32000 , 32000 , 32000 ) ; 
 273     SetRectRgn( (RgnHandle
) m_macCurrentClipRgn 
, -32000 , -32000 , 32000 , 32000 ) ; 
 274     m_pen 
= *wxBLACK_PEN
; 
 275     m_font 
= *wxNORMAL_FONT
; 
 276     m_brush 
= *wxWHITE_BRUSH
; 
 279     // needed to debug possible errors with two active drawing methods at the same time on 
 281     m_macCurrentPortStateHelper 
= NULL 
; 
 284     m_macATSUIStyle 
= NULL 
; 
 285     m_macAliasWasEnabled 
= false; 
 286     m_macForegroundPixMap 
= NULL 
; 
 287     m_macBackgroundPixMap 
= NULL 
; 
 292     DisposeRgn( (RgnHandle
) m_macBoundaryClipRgn 
) ; 
 293     DisposeRgn( (RgnHandle
) m_macCurrentClipRgn 
) ; 
 296 void wxDC::MacSetupPort(wxMacPortStateHelper
* help
) const 
 299     wxASSERT( m_macCurrentPortStateHelper 
== NULL 
) ; 
 300     m_macCurrentPortStateHelper 
= help 
; 
 303     SetClip( (RgnHandle
) m_macCurrentClipRgn
); 
 305 #if ! wxMAC_EXPERIMENTAL_DC 
 306     m_macFontInstalled 
= false ; 
 307     m_macBrushInstalled 
= false ; 
 308     m_macPenInstalled 
= false ; 
 312 void wxDC::MacCleanupPort(wxMacPortStateHelper
* help
) const 
 315     wxASSERT( m_macCurrentPortStateHelper 
== help 
) ; 
 316     m_macCurrentPortStateHelper 
= NULL 
; 
 319     if ( m_macATSUIStyle 
) 
 321         ::ATSUDisposeStyle((ATSUStyle
)m_macATSUIStyle
); 
 322         m_macATSUIStyle 
= NULL 
; 
 325     if ( m_macAliasWasEnabled 
) 
 327         SetAntiAliasedTextEnabled(m_macFormerAliasState
, m_macFormerAliasSize
); 
 328         m_macAliasWasEnabled 
= false ; 
 331     if ( m_macForegroundPixMap 
) 
 334         ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
 335         DisposePixPat( (PixPatHandle
) m_macForegroundPixMap 
) ; 
 336         m_macForegroundPixMap 
= NULL 
; 
 339     if ( m_macBackgroundPixMap 
) 
 342         ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
 343         DisposePixPat( (PixPatHandle
) m_macBackgroundPixMap 
) ; 
 344         m_macBackgroundPixMap 
= NULL 
; 
 348 void wxDC::DoDrawBitmap( const wxBitmap 
&bmp
, wxCoord x
, wxCoord y
, bool useMask 
) 
 350      wxCHECK_RET( Ok(), wxT("wxDC::DoDrawBitmap - invalid DC") ); 
 351      wxCHECK_RET( bmp
.Ok(), wxT("wxDC::DoDrawBitmap - invalid bitmap") ); 
 353      wxMacFastPortSetter 
helper(this) ; 
 354      wxCoord xx 
= XLOG2DEVMAC(x
); 
 355      wxCoord yy 
= YLOG2DEVMAC(y
); 
 356      wxCoord w 
= bmp
.GetWidth(); 
 357      wxCoord h 
= bmp
.GetHeight(); 
 358      wxCoord ww 
= XLOG2DEVREL(w
); 
 359      wxCoord hh 
= YLOG2DEVREL(h
); 
 361      // Set up drawing mode 
 362      short  mode 
= (m_logicalFunction 
== wxCOPY 
? srcCopy 
: 
 363                     //m_logicalFunction == wxCLEAR ? WHITENESS : 
 364                     //m_logicalFunction == wxSET ? BLACKNESS : 
 365                     m_logicalFunction 
== wxINVERT 
? hilite 
: 
 366                    //m_logicalFunction == wxAND ? MERGECOPY : 
 367                     m_logicalFunction 
== wxOR 
? srcOr 
: 
 368                     m_logicalFunction 
== wxSRC_INVERT 
? notSrcCopy 
: 
 369                     m_logicalFunction 
== wxXOR 
? srcXor 
: 
 370                     m_logicalFunction 
== wxOR_REVERSE 
? notSrcOr 
: 
 371                     //m_logicalFunction == wxAND_REVERSE ? SRCERASE : 
 372                     //m_logicalFunction == wxSRC_OR ? srcOr : 
 373                     //m_logicalFunction == wxSRC_AND ? SRCAND : 
 376      GWorldPtr maskworld 
= NULL 
; 
 377      GWorldPtr bmapworld 
= MAC_WXHBITMAP( bmp
.GetHBITMAP((WXHBITMAP
*)&maskworld
) ); 
 378      PixMapHandle bmappixels 
; 
 380      // Set foreground and background colours (for bitmaps depth = 1) 
 381      if (bmp
.GetDepth() == 1) 
 383          RGBColor fore 
= MAC_WXCOLORREF(m_textForegroundColour
.GetPixel()); 
 384          RGBColor back 
= MAC_WXCOLORREF(m_textBackgroundColour
.GetPixel()); 
 390          RGBColor white 
= { 0xFFFF, 0xFFFF, 0xFFFF } ; 
 391          RGBColor black 
= { 0, 0, 0 } ; 
 392          RGBForeColor( &black 
) ; 
 393          RGBBackColor( &white 
) ; 
 395      bmappixels 
= GetGWorldPixMap( bmapworld 
) ; 
 397      wxCHECK_RET(LockPixels(bmappixels
), 
 398                  wxT("wxDC::DoDrawBitmap - failed to lock pixels")); 
 400      Rect source 
= { 0, 0, h
, w 
}; 
 401      Rect dest   
= { yy
, xx
, yy 
+ hh
, xx 
+ ww 
}; 
 402      if ( useMask 
&& maskworld 
) 
 404          if ( LockPixels(GetGWorldPixMap(MAC_WXHBITMAP(maskworld
)))) 
 408                   GetPortBitMapForCopyBits(bmapworld
), 
 409                   GetPortBitMapForCopyBits(MAC_WXHBITMAP(maskworld
)), 
 410                   GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ), 
 411                   &source
, &source
, &dest
, mode
, NULL
 
 413              UnlockPixels(GetGWorldPixMap(MAC_WXHBITMAP(maskworld
))); 
 418          CopyBits( GetPortBitMapForCopyBits( bmapworld 
), 
 419                    GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ), 
 420                    &source
, &dest
, mode
, NULL 
) ; 
 422      UnlockPixels( bmappixels 
) ; 
 424      m_macPenInstalled 
= false ; 
 425      m_macBrushInstalled 
= false ; 
 426      m_macFontInstalled 
= false ; 
 429 void wxDC::DoDrawIcon( const wxIcon 
&icon
, wxCoord x
, wxCoord y 
) 
 431     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawIcon - invalid DC")); 
 432     wxCHECK_RET(icon
.Ok(), wxT("wxDC::DoDrawIcon - invalid icon")); 
 434     wxMacFastPortSetter 
helper(this) ; 
 436     wxCoord xx 
= XLOG2DEVMAC(x
); 
 437     wxCoord yy 
= YLOG2DEVMAC(y
); 
 438     wxCoord w 
= icon
.GetWidth(); 
 439     wxCoord h 
= icon
.GetHeight(); 
 440     wxCoord ww 
= XLOG2DEVREL(w
); 
 441     wxCoord hh 
= YLOG2DEVREL(h
); 
 443     Rect r 
= { yy 
, xx
, yy 
+ hh
, xx 
+ ww 
} ; 
 444     PlotIconRef( &r 
, kAlignNone 
, kTransformNone 
, kPlotIconRefNormalFlags 
, MAC_WXHICON( icon
.GetHICON() ) ) ; 
 447 void wxDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 449     wxCHECK_RET(Ok(), wxT("wxDC::DoSetClippingRegion - invalid DC")); 
 451     wxCoord xx
, yy
, ww
, hh
; 
 454     ww 
= XLOG2DEVREL(width
); 
 455     hh 
= YLOG2DEVREL(height
); 
 457     SetRectRgn( (RgnHandle
) m_macCurrentClipRgn 
, xx 
, yy 
, xx 
+ ww 
, yy 
+ hh 
) ; 
 458     SectRgn( (RgnHandle
) m_macCurrentClipRgn 
, (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) m_macCurrentClipRgn 
) ; 
 461         m_clipX1 
= wxMax( m_clipX1 
, xx 
); 
 462         m_clipY1 
= wxMax( m_clipY1 
, yy 
); 
 463         m_clipX2 
= wxMin( m_clipX2
, (xx 
+ ww
) ); 
 464         m_clipY2 
= wxMin( m_clipY2
, (yy 
+ hh
) ); 
 476 void wxDC::DoSetClippingRegionAsRegion( const wxRegion 
®ion 
) 
 478     wxCHECK_RET(Ok(), wxT("wxDC::DoSetClippingRegionAsRegion - invalid DC")); 
 480     wxMacFastPortSetter 
helper(this) ; 
 482     region
.GetBox( x
, y
, w
, h 
); 
 483     wxCoord xx
, yy
, ww
, hh
; 
 489     // if we have a scaling that we cannot map onto native regions 
 490     // we must use the box 
 491     if ( ww 
!= w 
|| hh 
!= h 
) 
 493         wxDC::DoSetClippingRegion( x
, y
, w
, h 
); 
 497         CopyRgn( (RgnHandle
) region
.GetWXHRGN() , (RgnHandle
) m_macCurrentClipRgn 
) ; 
 498         if ( xx 
!= x 
|| yy 
!= y 
) 
 499             OffsetRgn( (RgnHandle
) m_macCurrentClipRgn 
, xx 
- x 
, yy 
- y 
) ; 
 501         SectRgn( (RgnHandle
) m_macCurrentClipRgn 
, (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) m_macCurrentClipRgn 
) ; 
 504             m_clipX1 
= wxMax( m_clipX1 
, xx 
); 
 505             m_clipY1 
= wxMax( m_clipY1 
, yy 
); 
 506             m_clipX2 
= wxMin( m_clipX2
, (xx 
+ ww
) ); 
 507             m_clipY2 
= wxMin( m_clipY2
, (yy 
+ hh
) ); 
 520 void wxDC::DestroyClippingRegion() 
 522     wxMacFastPortSetter 
helper(this) ; 
 524     CopyRgn( (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) m_macCurrentClipRgn 
) ; 
 528 void wxDC::DoGetSizeMM( int* width
, int* height 
) const 
 534         *width 
= long( double(w
) / (m_scaleX 
* m_mm_to_pix_x
) ); 
 536         *height 
= long( double(h
) / (m_scaleY 
* m_mm_to_pix_y
) ); 
 539 void wxDC::SetTextForeground( const wxColour 
&col 
) 
 541     wxCHECK_RET(Ok(), wxT("wxDC::SetTextForeground - invalid DC")); 
 543     m_textForegroundColour 
= col
; 
 544     m_macFontInstalled 
= false ; 
 547 void wxDC::SetTextBackground( const wxColour 
&col 
) 
 549     wxCHECK_RET(Ok(), wxT("wxDC::SetTextBackground - invalid DC")); 
 551     m_textBackgroundColour 
= col
; 
 552     m_macFontInstalled 
= false ; 
 555 wxSize 
wxDC::GetPPI() const 
 557     return wxSize(72, 72); 
 560 int wxDC::GetDepth() const 
 562     if ( IsPortColor( (CGrafPtr
) m_macPort 
) ) 
 563         return ( (**GetPortPixMap( (CGrafPtr
) m_macPort
)).pixelSize 
) ; 
 568 void wxDC::SetPalette( const wxPalette
& palette 
) 
 572 void wxDC::SetBackgroundMode( int mode 
) 
 574     m_backgroundMode 
= mode 
; 
 577 void wxDC::SetFont( const wxFont 
&font 
) 
 580     m_macFontInstalled 
= false ; 
 583 void wxDC::SetPen( const wxPen 
&pen 
) 
 589     m_macPenInstalled 
= false ; 
 592 void wxDC::SetBrush( const wxBrush 
&brush 
) 
 594     if (m_brush 
== brush
) 
 598     m_macBrushInstalled 
= false ; 
 601 void wxDC::SetBackground( const wxBrush 
&brush 
) 
 603     if (m_backgroundBrush 
== brush
) 
 606     m_backgroundBrush 
= brush
; 
 607     if (m_backgroundBrush
.Ok()) 
 608         m_macBrushInstalled 
= false ; 
 611 void wxDC::SetLogicalFunction( int function 
) 
 613     if (m_logicalFunction 
== function
) 
 616     m_logicalFunction 
= function 
; 
 617     m_macFontInstalled 
= false ; 
 618     m_macBrushInstalled 
= false ; 
 619     m_macPenInstalled 
= false ; 
 622 extern bool wxDoFloodFill(wxDC 
*dc
, wxCoord x
, wxCoord y
, 
 623                           const wxColour 
& col
, int style
); 
 625 bool wxDC::DoFloodFill(wxCoord x
, wxCoord y
, 
 626                        const wxColour
& col
, int style
) 
 628     return wxDoFloodFill(this, x
, y
, col
, style
); 
 631 bool wxDC::DoGetPixel( wxCoord x
, wxCoord y
, wxColour 
*col 
) const 
 633     wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel - invalid DC") ); 
 635     wxMacFastPortSetter 
helper(this) ; 
 637     // NOTE: Get/SetCPixel are slow! 
 639     GetCPixel( XLOG2DEVMAC(x
), YLOG2DEVMAC(y
), &colour 
); 
 641     // convert from Mac colour to wx 
 647 void wxDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2 
) 
 649     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawLine - invalid DC")); 
 651     wxMacFastPortSetter 
helper(this) ; 
 653     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 656         wxCoord offset 
= ( (m_pen
.GetWidth() == 0 ? 1 : 
 657             m_pen
.GetWidth() ) * (wxCoord
)m_scaleX 
- 1) / 2; 
 658         wxCoord xx1 
= XLOG2DEVMAC(x1
) - offset
; 
 659         wxCoord yy1 
= YLOG2DEVMAC(y1
) - offset
; 
 660         wxCoord xx2 
= XLOG2DEVMAC(x2
) - offset
; 
 661         wxCoord yy2 
= YLOG2DEVMAC(y2
) - offset
; 
 663         if ((m_pen
.GetCap() == wxCAP_ROUND
) && 
 664             (m_pen
.GetWidth() <= 1)) 
 666             // Implement LAST_NOT for MAC at least for 
 667             // orthogonal lines. RR. 
 690 void wxDC::DoCrossHair( wxCoord x
, wxCoord y 
) 
 692     wxCHECK_RET(Ok(), wxT("wxDC::DoCrossHair - invalid DC")); 
 694     wxMacFastPortSetter 
helper(this) ; 
 696     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 701         wxCoord xx 
= XLOG2DEVMAC(x
); 
 702         wxCoord yy 
= YLOG2DEVMAC(y
); 
 705         ::MoveTo( XLOG2DEVMAC(0), yy 
); 
 706         ::LineTo( XLOG2DEVMAC(w
), yy 
); 
 707         ::MoveTo( xx
, YLOG2DEVMAC(0) ); 
 708         ::LineTo( xx
, YLOG2DEVMAC(h
) ); 
 709         CalcBoundingBox(x
, y
); 
 710         CalcBoundingBox(x 
+ w
, y 
+ h
); 
 715 * To draw arcs properly the angles need to be converted from the WX style: 
 716 * Angles start on the +ve X axis and go anti-clockwise (As you would draw on 
 717 * a normal axis on paper). 
 720 * Angles start on the +ve y axis and go clockwise. 
 723 static double wxConvertWXangleToMACangle(double angle
) 
 725     double newAngle 
= 90 - angle 
; 
 727     while ( newAngle 
> 360 ) 
 729     while ( newAngle 
< 0 ) 
 735 void wxDC::DoDrawArc( wxCoord x1
, wxCoord y1
, 
 736                       wxCoord x2
, wxCoord y2
, 
 737                       wxCoord xc
, wxCoord yc 
) 
 739     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawArc - invalid DC")); 
 741     wxMacFastPortSetter 
helper(this) ; 
 743     wxCoord xx1 
= XLOG2DEVMAC(x1
); 
 744     wxCoord yy1 
= YLOG2DEVMAC(y1
); 
 745     wxCoord xx2 
= XLOG2DEVMAC(x2
); 
 746     wxCoord yy2 
= YLOG2DEVMAC(y2
); 
 747     wxCoord xxc 
= XLOG2DEVMAC(xc
); 
 748     wxCoord yyc 
= YLOG2DEVMAC(yc
); 
 750     double dx 
= xx1 
- xxc
; 
 751     double dy 
= yy1 
- yyc
; 
 752     double radius 
= sqrt((double)(dx 
* dx 
+ dy 
* dy
)); 
 753     wxCoord rad 
= (wxCoord
)radius
; 
 754     double radius1
, radius2
; 
 756     if (xx1 
== xx2 
&& yy1 
== yy2
) 
 761     else if (radius 
== 0.0) 
 763         radius1 
= radius2 
= 0.0; 
 767         radius1 
= (xx1 
- xxc 
== 0) ? 
 768             (yy1 
- yyc 
< 0) ? 90.0 : -90.0 : 
 769         -atan2(double(yy1 
- yyc
), double(xx1 
- xxc
)) * RAD2DEG
; 
 770         radius2 
= (xx2 
- xxc 
== 0) ? 
 771             (yy2 
- yyc 
< 0) ? 90.0 : -90.0 : 
 772         -atan2(double(yy2 
- yyc
), double(xx2 
- xxc
)) * RAD2DEG
; 
 775     wxCoord alpha2 
= wxCoord(radius2 
- radius1
); 
 776     wxCoord alpha1 
= wxCoord(wxConvertWXangleToMACangle(radius1
)); 
 780     Rect r 
= { yyc 
- rad
, xxc 
- rad
, yyc 
+ rad
, xxc 
+ rad 
}; 
 782     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 785         PaintArc(&r
, alpha1
, alpha2
); 
 788     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 791         FrameArc(&r
, alpha1
, alpha2
); 
 795 void wxDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
, 
 796                               double sa
, double ea 
) 
 798     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawEllepticArc - invalid DC")); 
 799     wxMacFastPortSetter 
helper(this) ; 
 802     // Order important Mac in opposite direction to wx 
 803     // we have to make sure that the filling is always counter-clockwise 
 804     double angle 
= sa 
- ea
; 
 808     wxCoord xx 
= XLOG2DEVMAC(x
); 
 809     wxCoord yy 
= YLOG2DEVMAC(y
); 
 810     wxCoord ww 
= m_signX 
* XLOG2DEVREL(w
); 
 811     wxCoord hh 
= m_signY 
* YLOG2DEVREL(h
); 
 813     // handle -ve width and/or height 
 826     sa 
= wxConvertWXangleToMACangle(sa
); 
 832     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 835         PaintArc(&r
, (short)sa
, (short)angle
); 
 838     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 841         FrameArc(&r
, (short)sa
, (short)angle
); 
 845 void wxDC::DoDrawPoint( wxCoord x
, wxCoord y 
) 
 847     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawPoint - invalid DC")); 
 849     wxMacFastPortSetter 
helper(this) ; 
 851     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 853         wxCoord xx1 
= XLOG2DEVMAC(x
); 
 854         wxCoord yy1 
= YLOG2DEVMAC(y
); 
 855         RGBColor pencolor 
= MAC_WXCOLORREF( m_pen
.GetColour().GetPixel()); 
 857         // NOTE: Get/SetCPixel are slow! 
 858         ::SetCPixel( xx1
, yy1
, &pencolor
) ; 
 859         CalcBoundingBox(x
, y
); 
 863 void wxDC::DoDrawLines(int n
, wxPoint points
[], 
 864                         wxCoord xoffset
, wxCoord yoffset
) 
 866     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawLines - invalid DC")); 
 868     if (m_pen
.GetStyle() == wxTRANSPARENT
) 
 871     wxMacFastPortSetter 
helper(this) ; 
 874     wxCoord offset 
= ( (m_pen
.GetWidth() == 0 ? 1 : 
 875     m_pen
.GetWidth() ) * (wxCoord
)m_scaleX 
- 1) / 2 ; 
 877     wxCoord x1
, x2 
, y1 
, y2 
; 
 878     x1 
= XLOG2DEVMAC(points
[0].x 
+ xoffset
); 
 879     y1 
= YLOG2DEVMAC(points
[0].y 
+ yoffset
); 
 881     ::MoveTo( x1 
- offset
, y1 
- offset 
); 
 882     for (int i 
= 0; i 
< n
-1; i
++) 
 884         x2 
= XLOG2DEVMAC(points
[i 
+ 1].x 
+ xoffset
); 
 885         y2 
= YLOG2DEVMAC(points
[i 
+ 1].y 
+ yoffset
); 
 886         ::LineTo( x2 
- offset
, y2 
- offset 
); 
 890 void wxDC::DoDrawPolygon(int n
, wxPoint points
[], 
 891                           wxCoord xoffset
, wxCoord yoffset
, 
 894     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawPolygon - invalid DC")); 
 896     if ( m_brush
.GetStyle() == wxTRANSPARENT 
&& m_pen
.GetStyle() == wxTRANSPARENT 
) 
 899     wxMacFastPortSetter 
helper(this) ; 
 901     wxCoord x1
, x2 
, y1 
, y2 
; 
 902     PolyHandle polygon 
= OpenPoly(); 
 903     x2 
= x1 
= XLOG2DEVMAC(points
[0].x 
+ xoffset
); 
 904     y2 
= y1 
= YLOG2DEVMAC(points
[0].y 
+ yoffset
); 
 907     for (int i 
= 1; i 
< n
; i
++) 
 909         x2 
= XLOG2DEVMAC(points
[i
].x 
+ xoffset
); 
 910         y2 
= YLOG2DEVMAC(points
[i
].y 
+ yoffset
); 
 914     // close the polyline if necessary 
 915     if ( x1 
!= x2 
|| y1 
!= y2 
) 
 919     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 922         ::PaintPoly( polygon 
); 
 925     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 928         ::FramePoly( polygon 
) ; 
 934 void wxDC::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
 936     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawRectangle - invalid DC")); 
 938     wxMacFastPortSetter 
helper(this) ; 
 940     wxCoord xx 
= XLOG2DEVMAC(x
); 
 941     wxCoord yy 
= YLOG2DEVMAC(y
); 
 942     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 943     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 945     // CMB: draw nothing if transformed w or h is 0 
 946     if (ww 
== 0 || hh 
== 0) 
 949     // CMB: handle -ve width and/or height 
 962     Rect rect 
= { yy 
, xx 
, yy 
+ hh 
, xx 
+ ww 
} ; 
 964     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 967         ::PaintRect( &rect 
) ; 
 970     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 973         ::FrameRect( &rect 
) ; 
 977 void wxDC::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
, 
 978                                    wxCoord width
, wxCoord height
, 
 981     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawRoundedRectangle - invalid DC")); 
 983     wxMacFastPortSetter 
helper(this) ; 
 985         radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
 986     wxCoord xx 
= XLOG2DEVMAC(x
); 
 987     wxCoord yy 
= YLOG2DEVMAC(y
); 
 988     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 989     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 991     // CMB: draw nothing if transformed w or h is 0 
 992     if (ww 
== 0 || hh 
== 0) 
 995     // CMB: handle -ve width and/or height 
1008     Rect rect 
= { yy 
, xx 
, yy 
+ hh 
, xx 
+ ww 
} ; 
1010     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
1013         ::PaintRoundRect( &rect 
, int(radius 
* 2) , int(radius 
* 2) ) ; 
1016     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1019         ::FrameRoundRect( &rect 
, int(radius 
* 2) , int(radius 
* 2) ) ; 
1023 void wxDC::DoDrawEllipse(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
1025     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawEllipse - invalid DC")); 
1027     wxMacFastPortSetter 
helper(this) ; 
1029     wxCoord xx 
= XLOG2DEVMAC(x
); 
1030     wxCoord yy 
= YLOG2DEVMAC(y
); 
1031     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
1032     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
1034     // CMB: draw nothing if transformed w or h is 0 
1035     if (ww 
== 0 || hh 
== 0) 
1038     // CMB: handle -ve width and/or height 
1051     Rect rect 
= { yy 
, xx 
, yy 
+ hh 
, xx 
+ ww 
} ; 
1053     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
1056         ::PaintOval( &rect 
) ; 
1059     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1062         ::FrameOval( &rect 
) ; 
1066 bool wxDC::CanDrawBitmap(void) const 
1071 bool wxDC::DoBlit(wxCoord xdest
, wxCoord ydest
, wxCoord dstWidth
, wxCoord dstHeight
, 
1072                    wxDC 
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func 
, bool useMask
, 
1073                    wxCoord xsrcMask
, wxCoord ysrcMask 
) 
1075     return DoStretchBlit( xdest
, ydest
, dstWidth
, dstHeight
, 
1076                            source
, xsrc
, ysrc
, dstWidth
, dstHeight
,  
1077                            logical_func
, useMask
, 
1078                            xsrcMask
, ysrcMask 
); 
1081 bool wxDC::DoStretchBlit(wxCoord xdest
, wxCoord ydest
, 
1082                          wxCoord dstWidth
, wxCoord dstHeight
, 
1084                          wxCoord xsrc
, wxCoord ysrc
, 
1085                          wxCoord srcWidth
, wxCoord srcHeight
, 
1086                          int logical_func
, bool useMask
, 
1087                          wxCoord xsrcMask
, wxCoord ysrcMask
) 
1089     wxCHECK_MSG(Ok(), false, wxT("wxDC::DoStretchBlit - invalid DC")); 
1090     wxCHECK_MSG(source
->Ok(), false, wxT("wxDC::DoStretchBlit - invalid source DC")); 
1092     if ( logical_func 
== wxNO_OP 
) 
1095     if (xsrcMask 
== -1 && ysrcMask 
== -1) 
1101     // correct the parameter in case this dc does not have a mask at all 
1102     if ( useMask 
&& !source
->m_macMask 
) 
1105     Rect srcrect 
, dstrect 
; 
1106     srcrect
.top 
= source
->YLOG2DEVMAC(ysrc
) ; 
1107     srcrect
.left 
= source
->XLOG2DEVMAC(xsrc
)  ; 
1108     srcrect
.right 
= source
->XLOG2DEVMAC(xsrc 
+ srcWidth 
) ; 
1109     srcrect
.bottom 
= source
->YLOG2DEVMAC(ysrc 
+ srcHeight
) ; 
1110     dstrect
.top 
= YLOG2DEVMAC(ydest
) ; 
1111     dstrect
.left 
= XLOG2DEVMAC(xdest
) ; 
1112     dstrect
.bottom 
= YLOG2DEVMAC(ydest 
+ dstHeight 
)  ; 
1113     dstrect
.right 
= XLOG2DEVMAC(xdest 
+ dstWidth 
) ; 
1114     short mode 
= kUnsupportedMode 
; 
1115     bool invertDestinationFirst 
= false ; 
1117     switch ( logical_func 
) 
1119     case wxAND
:        // src AND dst 
1120         mode 
= adMin 
; // ok 
1123     case wxAND_INVERT
: // (NOT src) AND dst 
1124         mode 
= notSrcOr  
; // ok 
1127     case wxAND_REVERSE
:// src AND (NOT dst) 
1128         invertDestinationFirst 
= true ; 
1133         mode 
= kEmulatedMode 
; 
1137         mode 
= srcCopy 
; // ok 
1140     case wxEQUIV
:      // (NOT src) XOR dst 
1141         mode 
= srcXor 
; // ok 
1144     case wxINVERT
:     // NOT dst 
1145         mode 
= kEmulatedMode 
; //or hilite ; 
1148     case wxNAND
:       // (NOT src) OR (NOT dst) 
1149         invertDestinationFirst 
= true ; 
1153     case wxNOR
:        // (NOT src) AND (NOT dst) 
1154         invertDestinationFirst 
= true ; 
1158     case wxNO_OP
:      // dst 
1159         mode 
= kEmulatedMode 
; // this has already been handled upon entry 
1162     case wxOR
:         // src OR dst 
1166     case wxOR_INVERT
:  // (NOT src) OR dst 
1170     case wxOR_REVERSE
: // src OR (NOT dst) 
1171         invertDestinationFirst 
= true ; 
1176         mode 
= kEmulatedMode 
; 
1179     case wxSRC_INVERT
: // (NOT src) 
1180         mode 
= notSrcCopy 
; // ok 
1183     case wxXOR
:        // src XOR dst 
1184         mode 
= notSrcXor 
; // ok 
1191     if ( mode 
== kUnsupportedMode 
) 
1193         wxFAIL_MSG(wxT("unsupported blitting mode" )); 
1198     CGrafPtr            sourcePort 
= (CGrafPtr
) source
->m_macPort 
; 
1199     PixMapHandle    bmappixels 
=  GetGWorldPixMap( sourcePort 
) ; 
1200     if ( LockPixels(bmappixels
) ) 
1202         wxMacFastPortSetter 
helper(this) ; 
1204         if ( source
->GetDepth() == 1 ) 
1206             RGBForeColor( &MAC_WXCOLORREF(m_textForegroundColour
.GetPixel()) ) ; 
1207             RGBBackColor( &MAC_WXCOLORREF(m_textBackgroundColour
.GetPixel()) ) ; 
1211             // the modes need this, otherwise we'll end up having really nice colors... 
1212             RGBColor white 
= { 0xFFFF, 0xFFFF, 0xFFFF } ; 
1213             RGBColor black 
= { 0, 0, 0 } ; 
1215             RGBForeColor( &black 
) ; 
1216             RGBBackColor( &white 
) ; 
1219         if ( useMask 
&& source
->m_macMask 
) 
1221             if ( mode 
== srcCopy 
) 
1223                 if ( LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) ) ) ) 
1225                     CopyMask( GetPortBitMapForCopyBits( sourcePort 
) , 
1226                         GetPortBitMapForCopyBits( MAC_WXHBITMAP(source
->m_macMask
) ) , 
1227                         GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ) , 
1228                         &srcrect
, &srcrect 
, &dstrect 
) ; 
1229                     UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) )  ) ; 
1234                 RgnHandle clipRgn 
= NewRgn() ; 
1235                 LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) ) ) ; 
1236                 BitMapToRegion( clipRgn 
, (BitMap
*) *GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) ) ) ; 
1237                 UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) ) ) ; 
1238                 OffsetRgn( clipRgn 
, -srcrect
.left 
+ dstrect
.left
, -srcrect
.top 
+  dstrect
.top 
) ; 
1240                 if ( mode 
== kEmulatedMode 
) 
1244                     ::PenPat(GetQDGlobalsBlack(&pat
)); 
1245                     if ( logical_func 
== wxSET 
) 
1247                         RGBColor col
= { 0xFFFF, 0xFFFF, 0xFFFF } ; 
1248                         ::RGBForeColor( &col  
) ; 
1249                         ::PaintRgn( clipRgn 
) ; 
1251                     else if ( logical_func 
== wxCLEAR 
) 
1253                         RGBColor col
= { 0x0000, 0x0000, 0x0000 } ; 
1254                         ::RGBForeColor( &col  
) ; 
1255                         ::PaintRgn( clipRgn 
) ; 
1257                     else if ( logical_func 
== wxINVERT 
) 
1259                         MacInvertRgn( clipRgn 
) ; 
1263                         for ( int y 
= 0 ; y 
< srcrect
.right 
- srcrect
.left 
; ++y 
) 
1265                             for ( int x 
= 0 ; x 
< srcrect
.bottom 
- srcrect
.top 
; ++x 
) 
1267                                 Point dstPoint 
= { dstrect
.top 
+ y 
, dstrect
.left 
+ x 
} ; 
1268                                 Point srcPoint 
= { srcrect
.top 
+ y 
, srcrect
.left 
+ x 
} ; 
1269                                 if ( PtInRgn( dstPoint 
, clipRgn 
) ) 
1271                                     RGBColor srcColor
, dstColor 
; 
1273                                     // NOTE: Get/SetCPixel are slow! 
1274                                     SetPort( (GrafPtr
) sourcePort 
) ; 
1275                                     GetCPixel( srcPoint
.h 
, srcPoint
.v 
, &srcColor 
) ; 
1276                                     SetPort( (GrafPtr
) m_macPort 
) ; 
1277                                     GetCPixel( dstPoint
.h 
, dstPoint
.v 
, &dstColor 
) ; 
1278                                     wxMacCalculateColour( logical_func 
, srcColor 
, dstColor 
) ; 
1279                                     SetCPixel( dstPoint
.h 
, dstPoint
.v 
, &dstColor 
) ; 
1287                     if ( invertDestinationFirst 
) 
1288                         MacInvertRgn( clipRgn 
) ; 
1290                     CopyBits( GetPortBitMapForCopyBits( sourcePort 
) , 
1291                         GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ) , 
1292                         &srcrect
, &dstrect
, mode
, clipRgn 
) ; 
1295                 DisposeRgn( clipRgn 
) ; 
1300             RgnHandle clipRgn 
= NewRgn() ; 
1301             SetRectRgn( clipRgn 
, dstrect
.left 
, dstrect
.top 
, dstrect
.right 
, dstrect
.bottom 
) ; 
1303             if ( mode 
== kEmulatedMode 
) 
1307                 ::PenPat(GetQDGlobalsBlack(&pat
)); 
1308                 if ( logical_func 
== wxSET 
) 
1310                     RGBColor col
= { 0xFFFF, 0xFFFF, 0xFFFF } ; 
1311                     ::RGBForeColor( &col  
) ; 
1312                     ::PaintRgn( clipRgn 
) ; 
1314                 else if ( logical_func 
== wxCLEAR 
) 
1316                     RGBColor col 
= { 0x0000, 0x0000, 0x0000 } ; 
1318                     ::RGBForeColor( &col  
) ; 
1319                     ::PaintRgn( clipRgn 
) ; 
1321                 else if ( logical_func 
== wxINVERT 
) 
1323                     MacInvertRgn( clipRgn 
) ; 
1327                     for ( int y 
= 0 ; y 
< srcrect
.right 
- srcrect
.left 
; ++y 
) 
1329                         for ( int x 
= 0 ; x 
< srcrect
.bottom 
- srcrect
.top 
; ++x 
) 
1331                             Point dstPoint 
= { dstrect
.top 
+ y 
, dstrect
.left 
+ x 
} ; 
1332                             Point srcPoint 
= { srcrect
.top 
+ y 
, srcrect
.left 
+ x 
} ; 
1334                                 RGBColor srcColor
, dstColor 
; 
1336                                 // NOTE: Get/SetCPixel are slow! 
1337                                 SetPort( (GrafPtr
) sourcePort 
) ; 
1338                                 GetCPixel( srcPoint
.h 
, srcPoint
.v 
, &srcColor
) ; 
1339                                 SetPort( (GrafPtr
) m_macPort 
) ; 
1340                                 GetCPixel( dstPoint
.h 
, dstPoint
.v 
, &dstColor 
) ; 
1341                                 wxMacCalculateColour( logical_func 
, srcColor 
, dstColor 
) ; 
1342                                 SetCPixel( dstPoint
.h 
, dstPoint
.v 
, &dstColor 
) ; 
1350                 if ( invertDestinationFirst 
) 
1351                     MacInvertRgn( clipRgn 
) ; 
1353                 CopyBits( GetPortBitMapForCopyBits( sourcePort 
) , 
1354                     GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ) , 
1355                     &srcrect
, &dstrect
, mode
, NULL 
) ; 
1358             DisposeRgn( clipRgn 
) ; 
1361         UnlockPixels( bmappixels 
) ; 
1364     m_macPenInstalled 
= false ; 
1365     m_macBrushInstalled 
= false ; 
1366     m_macFontInstalled 
= false ; 
1371 void wxDC::DoDrawRotatedText(const wxString
& str
, wxCoord x
, wxCoord y
, 
1374     wxCHECK_RET( Ok(), wxT("wxDC::DoDrawRotatedText - invalid DC") ); 
1379     wxMacFastPortSetter 
helper(this) ; 
1382     OSStatus status 
= noErr 
; 
1383     ATSUTextLayout atsuLayout 
; 
1385     wxMacUniCharBuffer 
unibuf( str 
) ; 
1386     UniCharCount chars 
= unibuf
.GetChars() ; 
1388     status 
= ::ATSUCreateTextLayoutWithTextPtr( unibuf
.GetBuffer() , 0 , chars 
, chars 
, 1 , 
1389         &chars 
, (ATSUStyle
*) &m_macATSUIStyle 
, &atsuLayout 
) ; 
1391     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create the layout of the rotated text") ); 
1393     status 
= ::ATSUSetTransientFontMatching( atsuLayout 
, true ) ; 
1394     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't setup transient font matching") ); 
1396     int iAngle 
= int( angle 
); 
1397     int drawX 
= XLOG2DEVMAC(x
) ; 
1398     int drawY 
= YLOG2DEVMAC(y
) ; 
1400     ATSUTextMeasurement textBefore
, textAfter 
; 
1401     ATSUTextMeasurement ascent
, descent 
; 
1403     ATSLineLayoutOptions layoutOptions 
= kATSLineNoLayoutOptions 
; 
1405     if (m_font
.GetNoAntiAliasing()) 
1407         layoutOptions 
|= kATSLineNoAntiAliasing 
; 
1410     Fixed atsuAngle 
= IntToFixed( iAngle 
) ; 
1412     ATSUAttributeTag atsuTags
[] = 
1414         kATSULineLayoutOptionsTag 
, 
1415         kATSULineRotationTag 
, 
1418     ByteCount atsuSizes
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1420         sizeof( ATSLineLayoutOptions 
) , 
1424     ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1430     status 
= ::ATSUSetLayoutControls(atsuLayout 
, sizeof(atsuTags
)/sizeof(ATSUAttributeTag
) - ( abs(iAngle
) > 0.001 ? 0 : 1), 
1431             atsuTags
, atsuSizes
, atsuValues 
) ; 
1433     status 
= ::ATSUMeasureText( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1434         &textBefore 
, &textAfter
, &ascent 
, &descent 
); 
1435     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't measure the rotated text") ); 
1437     if ( m_backgroundMode 
== wxSOLID 
) 
1439         // background painting must be done by hand, cannot be done by ATSUI 
1441         PolyHandle polygon 
= OpenPoly(); 
1443         ::MoveTo(drawX
, drawY
); 
1445         x2 
= (int) (drawX 
+ sin(angle 
/ RAD2DEG
) * FixedToInt(ascent 
+ descent
)) ; 
1446         y2 
= (int) (drawY 
+ cos(angle 
/ RAD2DEG
) * FixedToInt(ascent 
+ descent
)) ; 
1449         x2 
= (int) (drawX 
+ sin(angle 
/ RAD2DEG
) * FixedToInt(ascent 
+ descent 
) + cos(angle 
/ RAD2DEG
) * FixedToInt(textAfter
)) ; 
1450         y2 
= (int) (drawY 
+ cos(angle 
/ RAD2DEG
) * FixedToInt(ascent 
+ descent
) - sin(angle 
/ RAD2DEG
) * FixedToInt(textAfter
)) ; 
1453         x2 
= (int) (drawX 
+ cos(angle 
/ RAD2DEG
) * FixedToInt(textAfter
)) ; 
1454         y2 
= (int) (drawY 
- sin(angle 
/ RAD2DEG
) * FixedToInt(textAfter
)) ; 
1457         ::LineTo( drawX
, drawY
) ; 
1460         ::ErasePoly( polygon 
); 
1461         KillPoly( polygon 
); 
1464     drawX 
+= (int)(sin(angle 
/ RAD2DEG
) * FixedToInt(ascent
)); 
1465     drawY 
+= (int)(cos(angle 
/ RAD2DEG
) * FixedToInt(ascent
)); 
1466     status 
= ::ATSUDrawText( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1467         IntToFixed(drawX
) , IntToFixed(drawY
) ); 
1469     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't draw the rotated text") ); 
1472     status 
= ::ATSUMeasureTextImage( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1473         IntToFixed(drawX
) , IntToFixed(drawY
) , &rect 
); 
1474     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't measure the rotated text") ); 
1476     OffsetRect( &rect 
, -m_deviceLocalOriginX 
, -m_deviceLocalOriginY 
) ; 
1477     CalcBoundingBox(XDEV2LOG(rect
.left
), YDEV2LOG(rect
.top
) ); 
1478     CalcBoundingBox(XDEV2LOG(rect
.right
), YDEV2LOG(rect
.bottom
) ); 
1479     ::ATSUDisposeTextLayout(atsuLayout
); 
1482 void wxDC::DoDrawText(const wxString
& strtext
, wxCoord x
, wxCoord y
) 
1484     DoDrawRotatedText( strtext 
, x 
, y 
, 0) ; 
1487 bool wxDC::CanGetTextExtent() const 
1489     wxCHECK_MSG(Ok(), false, wxT("wxDC::CanGetTextExtent - invalid DC")); 
1495 void wxDC::DoGetTextExtent( const wxString 
&str
, wxCoord 
*width
, wxCoord 
*height
, 
1496                             wxCoord 
*descent
, wxCoord 
*externalLeading 
, 
1497                             const wxFont 
*theFont 
) const 
1499     wxCHECK_RET(Ok(), wxT("wxDC::DoGetTextExtent - invalid DC")); 
1501     wxMacFastPortSetter 
helper(this) ; 
1502     wxFont formerFont 
= m_font 
; 
1505         // work around the constness 
1506         *((wxFont
*)(&m_font
)) = *theFont 
; 
1511     OSStatus status 
= noErr 
; 
1512     ATSUTextLayout atsuLayout 
; 
1514     wxMacUniCharBuffer 
unibuf( str 
) ; 
1515     UniCharCount chars 
= unibuf
.GetChars() ; 
1517     status 
= ::ATSUCreateTextLayoutWithTextPtr( unibuf
.GetBuffer() , 0 , chars 
, chars 
, 1 , 
1518         &chars 
, (ATSUStyle
*) &m_macATSUIStyle 
, &atsuLayout 
) ; 
1520     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create the layout of the text") ); 
1522     status 
= ::ATSUSetTransientFontMatching( atsuLayout 
, true ) ; 
1523     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't setup transient font matching") ); 
1525     ATSLineLayoutOptions layoutOptions 
= kATSLineNoLayoutOptions 
; 
1527     if (m_font
.GetNoAntiAliasing()) 
1529         layoutOptions 
|= kATSLineNoAntiAliasing 
; 
1532     ATSUAttributeTag atsuTags
[] = 
1534         kATSULineLayoutOptionsTag 
, 
1537     ByteCount atsuSizes
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1539         sizeof( ATSLineLayoutOptions 
) , 
1542     ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1547     status 
= ::ATSUSetLayoutControls(atsuLayout 
, sizeof(atsuTags
)/sizeof(ATSUAttributeTag
) , 
1548             atsuTags
, atsuSizes
, atsuValues 
) ; 
1550     ATSUTextMeasurement textBefore
, textAfter 
; 
1551     ATSUTextMeasurement textAscent
, textDescent 
; 
1553     status 
= ::ATSUGetUnjustifiedBounds( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1554         &textBefore 
, &textAfter
, &textAscent 
, &textDescent 
); 
1557         *height 
= YDEV2LOGREL( FixedToInt(textAscent 
+ textDescent
) ) ; 
1559         *descent 
=YDEV2LOGREL( FixedToInt(textDescent
) ); 
1560     if ( externalLeading 
) 
1561         *externalLeading 
= 0 ; 
1563         *width 
= XDEV2LOGREL( FixedToInt(textAfter 
- textBefore
) ) ; 
1565     ::ATSUDisposeTextLayout(atsuLayout
); 
1570         // work around the constness 
1571         *((wxFont
*)(&m_font
)) = formerFont 
; 
1572         m_macFontInstalled 
= false ; 
1576 bool wxDC::DoGetPartialTextExtents(const wxString
& text
, wxArrayInt
& widths
) const 
1578     wxCHECK_MSG(Ok(), false, wxT("wxDC::DoGetPartialTextExtents - invalid DC")); 
1581     widths
.Add(0, text
.length()); 
1583     if (text
.length() == 0) 
1586     wxMacFastPortSetter 
helper(this) ; 
1589     OSStatus status 
= noErr 
; 
1590     ATSUTextLayout atsuLayout 
; 
1592     wxMacUniCharBuffer 
unibuf( text 
) ; 
1593     UniCharCount chars 
= unibuf
.GetChars() ; 
1595     status 
= ::ATSUCreateTextLayoutWithTextPtr( unibuf
.GetBuffer() , 0 , chars 
, chars 
, 1 , 
1596         &chars 
, (ATSUStyle
*) &m_macATSUIStyle 
, &atsuLayout 
) ; 
1598     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create the layout of the text") ); 
1600     status 
= ::ATSUSetTransientFontMatching( atsuLayout 
, true ) ; 
1601     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't setup transient font matching") ); 
1603     ATSLineLayoutOptions layoutOptions 
= kATSLineNoLayoutOptions 
; 
1605     if (m_font
.GetNoAntiAliasing()) 
1607         layoutOptions 
|= kATSLineNoAntiAliasing 
; 
1610     ATSUAttributeTag atsuTags
[] = 
1612         kATSULineLayoutOptionsTag 
, 
1615     ByteCount atsuSizes
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1617         sizeof( ATSLineLayoutOptions 
) , 
1620     ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1625     status 
= ::ATSUSetLayoutControls(atsuLayout 
, sizeof(atsuTags
)/sizeof(ATSUAttributeTag
) , 
1626             atsuTags
, atsuSizes
, atsuValues 
) ; 
1628     for ( int pos 
= 0; pos 
< (int)chars 
; pos 
++ ) 
1630         unsigned long actualNumberOfBounds 
= 0; 
1631         ATSTrapezoid glyphBounds
; 
1633         // We get a single bound, since the text should only require one. If it requires more, there is an issue 
1635         result 
= ATSUGetGlyphBounds( atsuLayout
, 0, 0, kATSUFromTextBeginning
, pos 
+ 1, 
1636             kATSUseDeviceOrigins
, 1, &glyphBounds
, &actualNumberOfBounds 
); 
1637         if (result 
!= noErr 
|| actualNumberOfBounds 
!= 1 ) 
1640         widths
[pos
] = XDEV2LOGREL(FixedToInt( glyphBounds
.upperRight
.x 
- glyphBounds
.upperLeft
.x 
)); 
1643     ::ATSUDisposeTextLayout(atsuLayout
); 
1648 wxCoord 
wxDC::GetCharWidth(void) const 
1651     DoGetTextExtent( wxT("g"), &width 
, NULL 
, NULL 
, NULL 
, NULL 
) ; 
1655 wxCoord 
wxDC::GetCharHeight(void) const 
1658     DoGetTextExtent( wxT("g") , NULL 
, &height 
, NULL 
, NULL 
, NULL 
) ; 
1662 void wxDC::Clear(void) 
1664     wxCHECK_RET(Ok(), wxT("wxDC::Clear - invalid DC")); 
1666     wxMacFastPortSetter 
helper(this) ; 
1667     Rect rect 
= { -31000 , -31000 , 31000 , 31000 } ; 
1669     if ( m_backgroundBrush
.Ok() && m_backgroundBrush
.GetStyle() != wxTRANSPARENT
) 
1672         MacSetupBackgroundForCurrentPort( m_backgroundBrush 
) ; 
1673         ::EraseRect( &rect 
) ; 
1677 void wxDC::MacInstallFont() const 
1679     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
1681     //    if ( m_macFontInstalled ) 
1684     Pattern blackColor 
; 
1685     MacSetupBackgroundForCurrentPort(m_backgroundBrush
) ; 
1686     if ( m_backgroundMode 
!= wxTRANSPARENT 
) 
1688         Pattern whiteColor 
; 
1689         ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
1692     wxASSERT( m_font
.Ok() ) ; 
1694     ::TextFont( m_font
.MacGetFontNum() ) ; 
1695     ::TextSize( (short)(m_scaleY 
* m_font
.MacGetFontSize()) ) ; 
1696     ::TextFace( m_font
.MacGetFontStyle() ) ; 
1697     m_macFontInstalled 
= true ; 
1698     m_macBrushInstalled 
= false ; 
1699     m_macPenInstalled 
= false ; 
1700     RGBColor forecolor 
= MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()); 
1701     RGBColor backcolor 
= MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()); 
1702     ::RGBForeColor( &forecolor 
); 
1703     ::RGBBackColor( &backcolor 
); 
1706     short mode 
= patCopy 
; 
1707     switch ( m_logicalFunction 
) 
1713     case wxINVERT
:     // NOT dst 
1714         ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
1718     case wxXOR
:        // src XOR dst 
1722     case wxOR_REVERSE
: // src OR (NOT dst) 
1726     case wxSRC_INVERT
: // (NOT src) 
1730     case wxAND
: // src AND dst 
1734     // TODO: unsupported 
1736     case wxAND_REVERSE
:// src AND (NOT dst) 
1737     case wxAND_INVERT
: // (NOT src) AND dst 
1738     case wxNO_OP
:      // dst 
1739     case wxNOR
:        // (NOT src) AND (NOT dst) 
1740     case wxEQUIV
:      // (NOT src) XOR dst 
1741     case wxOR_INVERT
:  // (NOT src) OR dst 
1742     case wxNAND
:       // (NOT src) OR (NOT dst) 
1743     case wxOR
:         // src OR dst 
1745         //        case wxSRC_OR:     // source _bitmap_ OR destination 
1746         //        case wxSRC_AND:     // source _bitmap_ AND destination 
1754     OSStatus status 
= noErr 
; 
1755     status 
= ATSUCreateAndCopyStyle( (ATSUStyle
) m_font
.MacGetATSUStyle() , (ATSUStyle
*) &m_macATSUIStyle 
) ; 
1756     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't set create ATSU style") ) ; 
1758     Fixed atsuSize 
= IntToFixed( int(m_scaleY 
* m_font
.MacGetFontSize()) ) ; 
1759     ATSUAttributeTag atsuTags
[] = 
1763     ByteCount atsuSizes
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1767     ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1772     status 
= ::ATSUSetAttributes((ATSUStyle
)m_macATSUIStyle
, sizeof(atsuTags
)/sizeof(ATSUAttributeTag
) , 
1773         atsuTags
, atsuSizes
, atsuValues
); 
1775     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't modify ATSU style") ) ; 
1778 Pattern gPatterns
[] = 
1781     { { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } } , 
1782     { { 0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40 , 0x80 } } , 
1783     { { 0x80 , 0x40 , 0x20 , 0x10 , 0x08 , 0x04 , 0x02 , 0x01 } } , 
1784     { { 0x10 , 0x10 , 0x10 , 0xFF , 0x10 , 0x10 , 0x10 , 0x10 } } , 
1785     { { 0x00 , 0x00 , 0x00 , 0xFF , 0x00 , 0x00 , 0x00 , 0x00 } } , 
1786     { { 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 } } , 
1787     { { 0x81 , 0x42 , 0x24 , 0x18 , 0x18 , 0x24 , 0x42 , 0x81 } } , 
1790     { { 0xCC , 0x99 , 0x33 , 0x66 , 0xCC , 0x99 , 0x33 , 0x66 } } , // DOT 
1791     { { 0xFE , 0xFD , 0xFB , 0xF7 , 0xEF , 0xDF , 0xBF , 0x7F } } , // LONG_DASH 
1792     { { 0xEE , 0xDD , 0xBB , 0x77 , 0xEE , 0xDD , 0xBB , 0x77 } } , // SHORT_DASH 
1793     { { 0xDE , 0xBD , 0x7B , 0xF6 , 0xED , 0xDB , 0xB7 , 0x6F } } , // DOT_DASH 
1796 static void wxMacGetPattern(int penStyle
, Pattern 
*pattern
) 
1798     int index 
= 0;  // solid pattern by default 
1802         case wxBDIAGONAL_HATCH
:     index 
= 1; break; 
1803         case wxFDIAGONAL_HATCH
:     index 
= 2; break; 
1804         case wxCROSS_HATCH
:         index 
= 3; break; 
1805         case wxHORIZONTAL_HATCH
:    index 
= 4; break; 
1806         case wxVERTICAL_HATCH
:      index 
= 5; break; 
1807         case wxCROSSDIAG_HATCH
:     index 
= 6; break; 
1810         case wxDOT
:                 index 
= 7; break; 
1811         case wxLONG_DASH
:           index 
= 8; break; 
1812         case wxSHORT_DASH
:          index 
= 9; break; 
1813         case wxDOT_DASH
:            index 
= 10; break; 
1819     *pattern 
= gPatterns
[index
]; 
1822 void wxDC::MacInstallPen() const 
1824     wxCHECK_RET(Ok(), wxT("wxDC::MacInstallPen - invalid DC")); 
1826     //Pattern     blackColor; 
1827     //    if ( m_macPenInstalled ) 
1830     RGBColor forecolor 
= MAC_WXCOLORREF( m_pen
.GetColour().GetPixel()); 
1831     RGBColor backcolor 
= MAC_WXCOLORREF( m_backgroundBrush
.GetColour().GetPixel()); 
1832     ::RGBForeColor( &forecolor 
); 
1833     ::RGBBackColor( &backcolor 
); 
1836     // null means only one pixel, at whatever resolution 
1837     int penWidth 
= (int) (m_pen
.GetWidth() * m_scaleX
) ; 
1838     if ( penWidth 
== 0 ) 
1840     ::PenSize(penWidth
, penWidth
); 
1843     int penStyle 
= m_pen
.GetStyle(); 
1844     if (penStyle 
== wxUSER_DASH
) 
1846         // FIXME: there should be exactly 8 items in the dash 
1848         int number 
= m_pen
.GetDashes(&dash
) ; 
1850         for ( int i 
= 0 ; i 
< 8 ; ++i 
) 
1852             pat
.pat
[i
] = dash
[index
] ; 
1853             if (index 
< number 
- 1) 
1859         wxMacGetPattern(penStyle
, &pat
); 
1864     short mode 
= patCopy 
; 
1865     switch ( m_logicalFunction 
) 
1867     case wxCOPY
:       // only foreground color, leave background (thus not patCopy) 
1871     case wxINVERT
:     // NOT dst 
1872         //            ::PenPat(GetQDGlobalsBlack(&blackColor)); 
1876     case wxXOR
:        // src XOR dst 
1880     case wxOR_REVERSE
: // src OR (NOT dst) 
1884     case wxSRC_INVERT
: // (NOT src) 
1888     case wxAND
: // src AND dst 
1892     // TODO: unsupported 
1894     case wxAND_REVERSE
:// src AND (NOT dst) 
1895     case wxAND_INVERT
: // (NOT src) AND dst 
1896     case wxNO_OP
:      // dst 
1897     case wxNOR
:        // (NOT src) AND (NOT dst) 
1898     case wxEQUIV
:      // (NOT src) XOR dst 
1899     case wxOR_INVERT
:  // (NOT src) OR dst 
1900     case wxNAND
:       // (NOT src) OR (NOT dst) 
1901     case wxOR
:         // src OR dst 
1903         //        case wxSRC_OR:     // source _bitmap_ OR destination 
1904         //        case wxSRC_AND:     // source _bitmap_ AND destination 
1912     m_macPenInstalled 
= true ; 
1913     m_macBrushInstalled 
= false ; 
1914     m_macFontInstalled 
= false ; 
1917 void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush
& background 
) 
1919     Pattern whiteColor 
; 
1921     if ( background
.Ok() ) 
1923         switch ( background
.MacGetBrushKind() ) 
1925             case kwxMacBrushTheme 
: 
1926                 ::SetThemeBackground( background
.MacGetTheme() , wxDisplayDepth() , true ) ; 
1929             case kwxMacBrushThemeBackground 
: 
1932                 ThemeBackgroundKind bg 
= background
.MacGetThemeBackground( &extent 
) ; 
1933                 ::ApplyThemeBackground( bg 
, &extent
, kThemeStateActive 
, wxDisplayDepth() , true ) ; 
1937             case kwxMacBrushColour 
: 
1939                 ::RGBBackColor( &MAC_WXCOLORREF( background
.GetColour().GetPixel()) ); 
1940                 int brushStyle 
= background
.GetStyle(); 
1941                 if (brushStyle 
== wxSOLID
) 
1942                     ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
1943                 else if (background
.IsHatch()) 
1946                     wxMacGetPattern(brushStyle
, &pat
); 
1951                     ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
1962 void wxDC::MacInstallBrush() const 
1964     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
1966     //    if ( m_macBrushInstalled ) 
1969     Pattern     blackColor 
; 
1970     bool backgroundTransparent 
= (GetBackgroundMode() == wxTRANSPARENT
) ; 
1971     ::RGBForeColor( &MAC_WXCOLORREF( m_brush
.GetColour().GetPixel()) ); 
1972     ::RGBBackColor( &MAC_WXCOLORREF( m_backgroundBrush
.GetColour().GetPixel()) ); 
1974     int brushStyle 
= m_brush
.GetStyle(); 
1975     if (brushStyle 
== wxSOLID
) 
1977         switch ( m_brush
.MacGetBrushKind() ) 
1979             case kwxMacBrushTheme 
: 
1981                     Pattern whiteColor 
; 
1982                     ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
1983                     ::SetThemePen( m_brush
.MacGetTheme() , wxDisplayDepth() , true ) ; 
1988                 ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
1993     else if (m_brush
.IsHatch()) 
1997         wxMacGetPattern(brushStyle
, &pat
); 
2000     else if ( m_brush
.GetStyle() == wxSTIPPLE 
|| m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE 
) 
2002         // we force this in order to be compliant with wxMSW 
2003         backgroundTransparent 
= false ; 
2005         // for these the text fore (and back for MASK_OPAQUE) colors are used 
2006         wxBitmap
* bitmap 
= m_brush
.GetStipple() ; 
2007         int width 
= bitmap
->GetWidth() ; 
2008         int height 
= bitmap
->GetHeight() ; 
2009         GWorldPtr gw 
= NULL 
; 
2011         if ( m_brush
.GetStyle() == wxSTIPPLE 
) 
2012             gw 
= MAC_WXHBITMAP(bitmap
->GetHBITMAP(NULL
))  ; 
2014             gw 
= MAC_WXHBITMAP(bitmap
->GetMask()->GetHBITMAP()) ; 
2016         PixMapHandle gwpixmaphandle 
= GetGWorldPixMap( gw 
) ; 
2017         LockPixels( gwpixmaphandle 
) ; 
2018         bool isMonochrome 
= !IsPortColor( gw 
) ; 
2019         if ( !isMonochrome 
) 
2021             if ( (**gwpixmaphandle
).pixelSize 
== 1 ) 
2022                 isMonochrome 
= true ; 
2025         if ( isMonochrome 
&& width 
== 8 && height 
== 8 ) 
2027             ::RGBForeColor( &MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()) ); 
2028             ::RGBForeColor( &MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()) ); 
2029             BitMap
* gwbitmap 
= (BitMap
*) *gwpixmaphandle 
; // since the color depth is 1 it is a BitMap 
2030             UInt8 
*gwbits 
= (UInt8
*) gwbitmap
->baseAddr 
; 
2031             int alignment 
= gwbitmap
->rowBytes 
& 0x7FFF ; 
2034             for ( int i 
= 0 ; i 
< 8 ; ++i 
) 
2036                 pat
.pat
[i
] = gwbits
[i 
* alignment 
+ 0] ; 
2039             UnlockPixels( GetGWorldPixMap( gw 
) ) ; 
2044             // this will be the code to handle power of 2 patterns, we will have to arrive at a nice 
2045             // caching scheme before putting this into production 
2049             PixPatHandle pixpat 
= NewPixPat() ; 
2050             CopyPixMap(gwpixmaphandle
, (**pixpat
).patMap
); 
2051             imageSize 
= GetPixRowBytes((**pixpat
).patMap
) * 
2052                 ((**(**pixpat
).patMap
).bounds
.bottom 
- 
2053                 (**(**pixpat
).patMap
).bounds
.top
); 
2054             PtrToHand( (**gwpixmaphandle
).baseAddr
, &image
, imageSize 
); 
2055             (**pixpat
).patData 
= image
; 
2059                 CTabHandle ctable 
= ((**((**pixpat
).patMap
)).pmTable
) ; 
2060                 ColorSpecPtr ctspec 
= (ColorSpecPtr
) &(**ctable
).ctTable 
; 
2061                 if ( ctspec
[0].rgb
.red 
== 0x0000 ) 
2063                     ctspec
[1].rgb 
= MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()) ; 
2064                     ctspec
[0].rgb 
= MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()) ; 
2068                     ctspec
[0].rgb 
= MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()) ; 
2069                     ctspec
[1].rgb 
= MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()) ; 
2071                 ::CTabChanged( ctable 
) ; 
2074             ::PenPixPat(pixpat
); 
2075             m_macForegroundPixMap 
= pixpat 
; 
2078         UnlockPixels( gwpixmaphandle 
) ; 
2082         ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
2085     short mode 
= patCopy 
; 
2086     switch ( m_logicalFunction 
) 
2089         if ( backgroundTransparent 
) 
2095     case wxINVERT
:     // NOT dst 
2096         if ( !backgroundTransparent 
) 
2097             ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
2101     case wxXOR
:        // src XOR dst 
2105     case wxOR_REVERSE
: // src OR (NOT dst) 
2109     case wxSRC_INVERT
: // (NOT src) 
2113     case wxAND
: // src AND dst 
2117     // TODO: unsupported 
2119     case wxAND_REVERSE
:// src AND (NOT dst) 
2120     case wxAND_INVERT
: // (NOT src) AND dst 
2121     case wxNO_OP
:      // dst 
2122     case wxNOR
:        // (NOT src) AND (NOT dst) 
2123     case wxEQUIV
:      // (NOT src) XOR dst 
2124     case wxOR_INVERT
:  // (NOT src) OR dst 
2125     case wxNAND
:       // (NOT src) OR (NOT dst) 
2126     case wxOR
:         // src OR dst 
2128         //        case wxSRC_OR:     // source _bitmap_ OR destination 
2129         //        case wxSRC_AND:     // source _bitmap_ AND destination 
2137     m_macBrushInstalled 
= true ; 
2138     m_macPenInstalled 
= false ; 
2139     m_macFontInstalled 
= false ; 
2142 #endif // !wxMAC_USE_CORE_GRAPHICS