1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:       wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "dc.h" 
  18 #include "wx/mac/uma.h" 
  19 #include "wx/dcmemory.h" 
  20 #include "wx/dcprint.h" 
  21 #include "wx/region.h" 
  30 #include "wx/mac/private.h" 
  31 #include <ATSUnicode.h> 
  32 #include <TextCommon.h> 
  33 #include <TextEncodingConverter.h> 
  35 #if !USE_SHARED_LIBRARY 
  36 IMPLEMENT_ABSTRACT_CLASS(wxDC
, wxObject
) 
  39 //----------------------------------------------------------------------------- 
  41 //----------------------------------------------------------------------------- 
  43 #define mm2inches        0.0393700787402 
  44 #define inches2mm        25.4 
  45 #define mm2twips        56.6929133859 
  46 #define twips2mm        0.0176388888889 
  47 #define mm2pt            2.83464566929 
  48 #define pt2mm            0.352777777778 
  49 #if !defined( __DARWIN__ ) || defined(__MWERKS__) 
  51 const double M_PI 
= 3.14159265358979 ; 
  54 const double RAD2DEG  
= 180.0 / M_PI
; 
  55 const short kEmulatedMode 
= -1 ; 
  56 const short kUnsupportedMode 
= -2 ; 
  58 extern TECObjectRef s_TECNativeCToUnicode 
; 
  60 // set to 0 if problems arise 
  61 #define wxMAC_EXPERIMENTAL_DC 1 
  63 wxMacPortSetter::wxMacPortSetter( const wxDC
* dc 
) : 
  64     m_ph( (GrafPtr
) dc
->m_macPort 
) 
  66     wxASSERT( dc
->Ok() ) ; 
  68     dc
->MacSetupPort(&m_ph
) ; 
  70 wxMacPortSetter::~wxMacPortSetter() 
  72     m_dc
->MacCleanupPort(&m_ph
) ; 
  75 #if wxMAC_EXPERIMENTAL_DC 
  76 class wxMacFastPortSetter
 
  79     wxMacFastPortSetter( const wxDC 
*dc 
)  
  81             wxASSERT( dc
->Ok() ) ; 
  82             GetPort( &m_oldPort 
) ; 
  83             SetPort( (GrafPtr
) dc
->m_macPort 
) ; 
  84             m_clipRgn 
= NewRgn() ; 
  85             GetClip( m_clipRgn 
) ; 
  87             dc
->MacSetupPort( NULL 
) ; 
  89     ~wxMacFastPortSetter() 
  91         SetPort( (GrafPtr
) m_dc
->m_macPort 
) ; 
  92         SetClip( m_clipRgn 
) ; 
  93             SetPort( m_oldPort 
) ; 
  94             m_dc
->MacCleanupPort( NULL 
) ; 
  95             DisposeRgn( m_clipRgn 
) ; 
 104 typedef wxMacPortSetter wxMacFastPortSetter 
; 
 109 // start moving to a dual implementation for QD and CGContextRef 
 111 class wxMacGraphicsContext
 
 114     void DrawBitmap( const wxBitmap 
&bmp
, wxCoord x
, wxCoord y
, bool useMask 
) = 0 ; 
 115     void SetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) = 0 ; 
 116     void SetClippingRegion( const wxRegion 
®ion  
) = 0 ; 
 117     void DestroyClippingRegion() = 0 ; 
 118     void SetTextForeground( const wxColour 
&col 
) = 0 ; 
 119     void SetTextBackground( const wxColour 
&col 
) = 0 ; 
 120     void SetLogicalScale( double x 
, double y 
) = 0 ; 
 121     void SetUserScale( double x 
, double y 
) = 0; 
 124 class wxMacQuickDrawContext 
: public wxMacGraphicsContext
 
 131 wxMacWindowClipper::wxMacWindowClipper( const wxWindow
* win 
)  
 133     m_formerClip 
= NewRgn() ; 
 134     m_newClip 
= NewRgn() ; 
 135     GetClip( m_formerClip 
) ; 
 140         // this clipping area was set to the parent window's drawing area, lead to problems 
 141         // with MacOSX controls drawing outside their wx' rectangle 
 142         RgnHandle insidergn 
= NewRgn() ; 
 144         wxWindow 
*parent 
= win
->GetParent() ; 
 145         parent
->MacWindowToRootWindow( &x
,&y 
) ; 
 146         wxSize size 
= parent
->GetSize() ; 
 147         SetRectRgn( insidergn 
, parent
->MacGetLeftBorderSize() , parent
->MacGetTopBorderSize() ,  
 148             size
.x 
- parent
->MacGetRightBorderSize(),  
 149             size
.y 
- parent
->MacGetBottomBorderSize()) ; 
 150         CopyRgn( (RgnHandle
) parent
->MacGetVisibleRegion(false).GetWXHRGN() , m_newClip 
) ; 
 151         SectRgn( m_newClip 
, insidergn 
, m_newClip 
) ; 
 152         OffsetRgn( m_newClip 
, x 
, y 
) ; 
 153         SetClip( m_newClip 
) ; 
 154         DisposeRgn( insidergn 
) ; 
 157         win
->MacWindowToRootWindow( &x
,&y 
) ; 
 158         CopyRgn( (RgnHandle
) ((wxWindow
*)win
)->MacGetVisibleRegion().GetWXHRGN() , m_newClip 
) ; 
 159         OffsetRgn( m_newClip 
, x 
, y 
) ; 
 160         SetClip( m_newClip 
) ; 
 165 wxMacWindowClipper::~wxMacWindowClipper()  
 167     SetClip( m_formerClip 
) ; 
 168     DisposeRgn( m_newClip 
) ; 
 169     DisposeRgn( m_formerClip 
) ; 
 172 //----------------------------------------------------------------------------- 
 174 //----------------------------------------------------------------------------- 
 175 static inline double dmin(double a
, double b
) { return a 
< b 
? a 
: b
; } 
 176 static inline double dmax(double a
, double b
) { return a 
> b 
? a 
: b
; } 
 177 static inline double DegToRad(double deg
) { return (deg 
* M_PI
) / 180.0; } 
 179 //----------------------------------------------------------------------------- 
 181 //----------------------------------------------------------------------------- 
 182 // this function emulates all wx colour manipulations, used to verify the implementation 
 183 // by setting the mode in the blitting functions to kEmulatedMode 
 184 void wxMacCalculateColour( int logical_func 
, const RGBColor 
&srcColor 
, RGBColor 
&dstColor 
) ; 
 186 void wxMacCalculateColour( int logical_func 
, const RGBColor 
&srcColor 
, RGBColor 
&dstColor 
) 
 188     switch ( logical_func 
) 
 190         case wxAND
:        // src AND dst 
 191             dstColor
.red 
= dstColor
.red 
& srcColor
.red 
; 
 192             dstColor
.green 
= dstColor
.green 
& srcColor
.green 
; 
 193             dstColor
.blue 
= dstColor
.blue 
& srcColor
.blue 
; 
 195         case wxAND_INVERT
: // (NOT src) AND dst 
 196             dstColor
.red 
= dstColor
.red 
& ~srcColor
.red 
; 
 197             dstColor
.green 
= dstColor
.green 
& ~srcColor
.green 
; 
 198             dstColor
.blue 
= dstColor
.blue 
& ~srcColor
.blue 
; 
 200         case wxAND_REVERSE
:// src AND (NOT dst) 
 201             dstColor
.red 
= ~dstColor
.red 
& srcColor
.red 
; 
 202             dstColor
.green 
= ~dstColor
.green 
& srcColor
.green 
; 
 203             dstColor
.blue 
= ~dstColor
.blue 
& srcColor
.blue 
; 
 211             dstColor
.red 
= srcColor
.red 
; 
 212             dstColor
.green 
= srcColor
.green 
; 
 213             dstColor
.blue 
= srcColor
.blue 
; 
 215         case wxEQUIV
:      // (NOT src) XOR dst 
 216             dstColor
.red 
= dstColor
.red 
^ ~srcColor
.red 
; 
 217             dstColor
.green 
= dstColor
.green 
^ ~srcColor
.green 
; 
 218             dstColor
.blue 
= dstColor
.blue 
^ ~srcColor
.blue 
; 
 220         case wxINVERT
:     // NOT dst 
 221             dstColor
.red 
= ~dstColor
.red 
; 
 222             dstColor
.green 
= ~dstColor
.green 
; 
 223             dstColor
.blue 
= ~dstColor
.blue 
; 
 225         case wxNAND
:       // (NOT src) OR (NOT dst) 
 226             dstColor
.red 
= ~dstColor
.red 
| ~srcColor
.red 
; 
 227             dstColor
.green 
= ~dstColor
.green 
| ~srcColor
.green 
; 
 228             dstColor
.blue 
= ~dstColor
.blue 
| ~srcColor
.blue 
; 
 230         case wxNOR
:        // (NOT src) AND (NOT dst) 
 231             dstColor
.red 
= ~dstColor
.red 
& ~srcColor
.red 
; 
 232             dstColor
.green 
= ~dstColor
.green 
& ~srcColor
.green 
; 
 233             dstColor
.blue 
= ~dstColor
.blue 
& ~srcColor
.blue 
; 
 237         case wxOR
:         // src OR dst 
 238             dstColor
.red 
= dstColor
.red 
| srcColor
.red 
; 
 239             dstColor
.green 
= dstColor
.green 
| srcColor
.green 
; 
 240             dstColor
.blue 
= dstColor
.blue 
| srcColor
.blue 
; 
 242         case wxOR_INVERT
:  // (NOT src) OR dst 
 243             dstColor
.red 
= dstColor
.red 
| ~srcColor
.red 
; 
 244             dstColor
.green 
= dstColor
.green 
| ~srcColor
.green 
; 
 245             dstColor
.blue 
= dstColor
.blue 
| ~srcColor
.blue 
; 
 247         case wxOR_REVERSE
: // src OR (NOT dst) 
 248             dstColor
.red 
= ~dstColor
.red 
| srcColor
.red 
; 
 249             dstColor
.green 
= ~dstColor
.green 
| srcColor
.green 
; 
 250             dstColor
.blue 
= ~dstColor
.blue 
| srcColor
.blue 
; 
 253             dstColor
.red 
= 0xFFFF ; 
 254             dstColor
.green 
= 0xFFFF ; 
 255             dstColor
.blue 
= 0xFFFF ; 
 257         case wxSRC_INVERT
: // (NOT src) 
 258             dstColor
.red 
= ~srcColor
.red 
; 
 259             dstColor
.green 
= ~srcColor
.green 
; 
 260             dstColor
.blue 
= ~srcColor
.blue 
; 
 262         case wxXOR
:        // src XOR dst 
 263             dstColor
.red 
= dstColor
.red 
^ srcColor
.red 
; 
 264             dstColor
.green 
= dstColor
.green 
^ srcColor
.green 
; 
 265             dstColor
.blue 
= dstColor
.blue 
^ srcColor
.blue 
; 
 274     m_mm_to_pix_x 
= mm2pt
; 
 275     m_mm_to_pix_y 
= mm2pt
; 
 276     m_internalDeviceOriginX 
= 0; 
 277     m_internalDeviceOriginY 
= 0; 
 278     m_externalDeviceOriginX 
= 0; 
 279     m_externalDeviceOriginY 
= 0; 
 280     m_logicalScaleX 
= 1.0; 
 281     m_logicalScaleY 
= 1.0; 
 286     m_needComputeScaleX 
= FALSE
; 
 287     m_needComputeScaleY 
= FALSE
; 
 291     m_macFontInstalled 
= false ; 
 292     m_macBrushInstalled 
= false ; 
 293     m_macPenInstalled 
= false ; 
 294     m_macLocalOrigin
.x 
= m_macLocalOrigin
.y 
= 0 ; 
 295     m_macBoundaryClipRgn 
= NewRgn() ; 
 296     m_macCurrentClipRgn 
= NewRgn() ; 
 297     SetRectRgn( (RgnHandle
) m_macBoundaryClipRgn 
, -32000 , -32000 , 32000 , 32000 ) ; 
 298     SetRectRgn( (RgnHandle
) m_macCurrentClipRgn 
, -32000 , -32000 , 32000 , 32000 ) ; 
 299     m_pen 
= *wxBLACK_PEN
; 
 300     m_font 
= *wxNORMAL_FONT
; 
 301     m_brush 
= *wxWHITE_BRUSH
; 
 303     // needed to debug possible errors with two active drawing methods at the same time on  
 305     m_macCurrentPortStateHelper 
= NULL 
; 
 307     m_macATSUIStyle 
= NULL 
; 
 308     m_macAliasWasEnabled 
= false; 
 309     m_macForegroundPixMap 
= NULL 
; 
 310     m_macBackgroundPixMap 
= NULL 
; 
 315     DisposeRgn( (RgnHandle
) m_macBoundaryClipRgn 
) ; 
 316     DisposeRgn( (RgnHandle
) m_macCurrentClipRgn 
) ; 
 319 void wxDC::MacSetupPort(wxMacPortStateHelper
* help
) const 
 322     wxASSERT( m_macCurrentPortStateHelper 
== NULL 
) ; 
 323     m_macCurrentPortStateHelper 
= help 
; 
 325     SetClip( (RgnHandle
) m_macCurrentClipRgn
); 
 326 #if ! wxMAC_EXPERIMENTAL_DC 
 327     m_macFontInstalled 
= false ; 
 328     m_macBrushInstalled 
= false ; 
 329     m_macPenInstalled 
= false ; 
 332 void wxDC::MacCleanupPort(wxMacPortStateHelper
* help
) const 
 335     wxASSERT( m_macCurrentPortStateHelper 
== help 
) ; 
 336     m_macCurrentPortStateHelper 
= NULL 
; 
 338     if( m_macATSUIStyle 
) 
 340         ::ATSUDisposeStyle((ATSUStyle
)m_macATSUIStyle
); 
 341         m_macATSUIStyle 
= NULL 
; 
 343     if ( m_macAliasWasEnabled 
) 
 345         SetAntiAliasedTextEnabled(m_macFormerAliasState
, m_macFormerAliasSize
); 
 346         m_macAliasWasEnabled 
= false ; 
 348     if ( m_macForegroundPixMap 
) 
 351         ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
 352         DisposePixPat( (PixPatHandle
) m_macForegroundPixMap 
) ; 
 353         m_macForegroundPixMap 
= NULL 
; 
 355     if ( m_macBackgroundPixMap 
) 
 358         ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
 359         DisposePixPat( (PixPatHandle
) m_macBackgroundPixMap 
) ; 
 360         m_macBackgroundPixMap 
= NULL 
; 
 364 void wxDC::DoDrawBitmap( const wxBitmap 
&bmp
, wxCoord x
, wxCoord y
, bool useMask 
) 
 366      wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 367      wxCHECK_RET( bmp
.Ok(), wxT("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
); 
 375      // Set up drawing mode 
 376      short  mode 
= (m_logicalFunction 
== wxCOPY 
? srcCopy 
: 
 377                     //m_logicalFunction == wxCLEAR ? WHITENESS : 
 378                     //m_logicalFunction == wxSET ? BLACKNESS : 
 379                     m_logicalFunction 
== wxINVERT 
? hilite 
: 
 380                    //m_logicalFunction == wxAND ? MERGECOPY : 
 381                     m_logicalFunction 
== wxOR 
? srcOr 
: 
 382                     m_logicalFunction 
== wxSRC_INVERT 
? notSrcCopy 
: 
 383                     m_logicalFunction 
== wxXOR 
? srcXor 
: 
 384                     m_logicalFunction 
== wxOR_REVERSE 
? notSrcOr 
: 
 385                     //m_logicalFunction == wxAND_REVERSE ? SRCERASE : 
 386                     //m_logicalFunction == wxSRC_OR ? srcOr : 
 387                     //m_logicalFunction == wxSRC_AND ? SRCAND : 
 389      if ( bmp
.GetBitmapType() == kMacBitmapTypePict 
) { 
 390          Rect bitmaprect 
= { 0 , 0 , hh
, ww 
}; 
 391          ::OffsetRect( &bitmaprect
, xx
, yy 
) ; 
 392          ::DrawPicture( (PicHandle
) bmp
.GetPict(), &bitmaprect 
) ; 
 394      else if ( bmp
.GetBitmapType() == kMacBitmapTypeGrafWorld 
) 
 396          GWorldPtr    bmapworld 
= MAC_WXHBITMAP( bmp
.GetHBITMAP() ); 
 397          PixMapHandle bmappixels 
; 
 398          // Set foreground and background colours (for bitmaps depth = 1) 
 399          if(bmp
.GetDepth() == 1) 
 401              RGBColor fore 
= MAC_WXCOLORREF(m_textForegroundColour
.GetPixel()); 
 402              RGBColor back 
= MAC_WXCOLORREF(m_textBackgroundColour
.GetPixel()); 
 408              RGBColor white 
= { 0xFFFF, 0xFFFF,0xFFFF} ; 
 409              RGBColor black 
= { 0,0,0} ; 
 410              RGBForeColor( &black 
) ; 
 411              RGBBackColor( &white 
) ; 
 413          bmappixels 
= GetGWorldPixMap( bmapworld 
) ; 
 414          wxCHECK_RET(LockPixels(bmappixels
), 
 415                      wxT("DoDrawBitmap:  Unable to lock pixels")); 
 416          Rect source 
= { 0, 0, h
, w 
}; 
 417          Rect dest   
= { yy
, xx
, yy 
+ hh
, xx 
+ ww 
}; 
 418          if ( useMask 
&& bmp
.GetMask() ) 
 420              if( LockPixels(GetGWorldPixMap(MAC_WXHBITMAP(bmp
.GetMask()->GetMaskBitmap())))) 
 424                       GetPortBitMapForCopyBits(bmapworld
), 
 425                       GetPortBitMapForCopyBits(MAC_WXHBITMAP(bmp
.GetMask()->GetMaskBitmap())), 
 426                       GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ), 
 427                       &source
, &source
, &dest
, mode
, NULL
 
 429                  UnlockPixels(GetGWorldPixMap(MAC_WXHBITMAP(bmp
.GetMask()->GetMaskBitmap()))); 
 433              CopyBits( GetPortBitMapForCopyBits( bmapworld 
), 
 434                        GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ), 
 435                        &source
, &dest
, mode
, NULL 
) ; 
 437          UnlockPixels( bmappixels 
) ; 
 439      else if ( bmp
.GetBitmapType() == kMacBitmapTypeIcon 
) 
 441         Rect bitmaprect 
= { 0 , 0 , bmp
.GetHeight(), bmp
.GetWidth() } ; 
 442         OffsetRect( &bitmaprect
, xx
, yy 
) ; 
 443         PlotCIconHandle( &bitmaprect 
, atNone 
, ttNone 
, MAC_WXHICON(bmp
.GetHICON()) ) ; 
 445      m_macPenInstalled 
= false ; 
 446      m_macBrushInstalled 
= false ; 
 447      m_macFontInstalled 
= false ; 
 450 void wxDC::DoDrawIcon( const wxIcon 
&icon
, wxCoord x
, wxCoord y 
) 
 452     wxCHECK_RET(Ok(), wxT("Invalid dc  wxDC::DoDrawIcon")); 
 453     wxCHECK_RET(icon
.Ok(), wxT("Invalid icon wxDC::DoDrawIcon")); 
 454     DoDrawBitmap( icon 
, x 
, y 
, icon
.GetMask() != NULL 
) ; 
 457 void wxDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 459     wxCHECK_RET(Ok(), wxT("wxDC::DoSetClippingRegion  Invalid DC")); 
 460     wxCoord xx
, yy
, ww
, hh
; 
 463     ww 
= XLOG2DEVREL(width
); 
 464     hh 
= YLOG2DEVREL(height
); 
 465     SetRectRgn( (RgnHandle
) m_macCurrentClipRgn 
, xx 
, yy 
, xx 
+ ww 
, yy 
+ hh 
) ; 
 466     SectRgn( (RgnHandle
) m_macCurrentClipRgn 
, (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) m_macCurrentClipRgn 
) ; 
 469         m_clipX1 
= wxMax( m_clipX1 
, xx 
); 
 470         m_clipY1 
= wxMax( m_clipY1 
, yy 
); 
 471         m_clipX2 
= wxMin( m_clipX2
, (xx 
+ ww
)); 
 472         m_clipY2 
= wxMin( m_clipY2
, (yy 
+ hh
)); 
 484 void wxDC::DoSetClippingRegionAsRegion( const wxRegion 
®ion  
) 
 486     wxCHECK_RET( Ok(), wxT("invalid window dc") ) ; 
 489         DestroyClippingRegion(); 
 492     wxMacFastPortSetter 
helper(this) ; 
 494     region
.GetBox( x
, y
, w
, h 
); 
 495     wxCoord xx
, yy
, ww
, hh
; 
 500     // if we have a scaling that we cannot map onto native regions 
 501     // we must use the box 
 502     if ( ww 
!= w 
|| hh 
!= h 
) 
 504         wxDC::DoSetClippingRegion( x
, y
, w
, h 
); 
 508         CopyRgn( (RgnHandle
) region
.GetWXHRGN() , (RgnHandle
) m_macCurrentClipRgn 
) ; 
 509         if ( xx 
!= x 
|| yy 
!= y 
) 
 511             OffsetRgn( (RgnHandle
) m_macCurrentClipRgn 
, xx 
- x 
, yy 
- y 
) ; 
 513         SectRgn( (RgnHandle
) m_macCurrentClipRgn 
, (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) m_macCurrentClipRgn 
) ; 
 516             m_clipX1 
= wxMax( m_clipX1 
, xx 
); 
 517             m_clipY1 
= wxMax( m_clipY1 
, yy 
); 
 518             m_clipX2 
= wxMin( m_clipX2
, (xx 
+ ww
)); 
 519             m_clipY2 
= wxMin( m_clipY2
, (yy 
+ hh
)); 
 532 void wxDC::DestroyClippingRegion() 
 534     wxMacFastPortSetter 
helper(this) ; 
 535     CopyRgn( (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) m_macCurrentClipRgn 
) ; 
 539 void wxDC::DoGetSizeMM( int* width
, int* height 
) const 
 544     *width 
= long( double(w
) / (m_scaleX
*m_mm_to_pix_x
) ); 
 545     *height 
= long( double(h
) / (m_scaleY
*m_mm_to_pix_y
) ); 
 548 void wxDC::SetTextForeground( const wxColour 
&col 
) 
 550     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
 551     m_textForegroundColour 
= col
; 
 552     m_macFontInstalled 
= false ; 
 555 void wxDC::SetTextBackground( const wxColour 
&col 
) 
 557     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
 558     m_textBackgroundColour 
= col
; 
 559     m_macFontInstalled 
= false ; 
 562 void wxDC::SetMapMode( int mode 
) 
 567         SetLogicalScale( twips2mm
*m_mm_to_pix_x
, twips2mm
*m_mm_to_pix_y 
); 
 570         SetLogicalScale( pt2mm
*m_mm_to_pix_x
, pt2mm
*m_mm_to_pix_y 
); 
 573         SetLogicalScale( m_mm_to_pix_x
, m_mm_to_pix_y 
); 
 576         SetLogicalScale( m_mm_to_pix_x
/10.0, m_mm_to_pix_y
/10.0 ); 
 580         SetLogicalScale( 1.0, 1.0 ); 
 583     if (mode 
!= wxMM_TEXT
) 
 585         m_needComputeScaleX 
= TRUE
; 
 586         m_needComputeScaleY 
= TRUE
; 
 590 void wxDC::SetUserScale( double x
, double y 
) 
 592     // allow negative ? -> no 
 595     ComputeScaleAndOrigin(); 
 598 void wxDC::SetLogicalScale( double x
, double y 
) 
 603     ComputeScaleAndOrigin(); 
 606 void wxDC::SetLogicalOrigin( wxCoord x
, wxCoord y 
) 
 608     m_logicalOriginX 
= x 
* m_signX
;   // is this still correct ? 
 609     m_logicalOriginY 
= y 
* m_signY
; 
 610     ComputeScaleAndOrigin(); 
 613 void wxDC::SetDeviceOrigin( wxCoord x
, wxCoord y 
) 
 615     m_externalDeviceOriginX 
= x
; 
 616     m_externalDeviceOriginY 
= y
; 
 617     ComputeScaleAndOrigin(); 
 621 void wxDC::SetInternalDeviceOrigin( long x
, long y 
) 
 623     m_internalDeviceOriginX 
= x
; 
 624     m_internalDeviceOriginY 
= y
; 
 625     ComputeScaleAndOrigin(); 
 627 void wxDC::GetInternalDeviceOrigin( long *x
, long *y 
) 
 629     if (x
) *x 
= m_internalDeviceOriginX
; 
 630     if (y
) *y 
= m_internalDeviceOriginY
; 
 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 
) ) 
 650         return ( (**GetPortPixMap( (CGrafPtr
) m_macPort
)).pixelSize 
) ; 
 655 void wxDC::ComputeScaleAndOrigin() 
 657     // CMB: copy scale to see if it changes 
 658     double origScaleX 
= m_scaleX
; 
 659     double origScaleY 
= m_scaleY
; 
 660     m_scaleX 
= m_logicalScaleX 
* m_userScaleX
; 
 661     m_scaleY 
= m_logicalScaleY 
* m_userScaleY
; 
 662     m_deviceOriginX 
= m_internalDeviceOriginX 
+ m_externalDeviceOriginX
; 
 663     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 
 669         wxPen
* pen 
= & GetPen(); 
 676 void  wxDC::SetPalette( const wxPalette
& palette 
) 
 680 void  wxDC::SetBackgroundMode( int mode 
) 
 682     m_backgroundMode 
= mode 
; 
 685 void  wxDC::SetFont( const wxFont 
&font 
) 
 688     m_macFontInstalled 
= false ; 
 691 void  wxDC::SetPen( const wxPen 
&pen 
) 
 696     m_macPenInstalled 
= false ; 
 699 void  wxDC::SetBrush( const wxBrush 
&brush 
) 
 701     if (m_brush 
== brush
) 
 704     m_macBrushInstalled 
= false ; 
 707 void  wxDC::SetBackground( const wxBrush 
&brush 
) 
 709     if (m_backgroundBrush 
== brush
) 
 711     m_backgroundBrush 
= brush
; 
 712     if (!m_backgroundBrush
.Ok()) 
 714     m_macBrushInstalled 
= false ; 
 717 void  wxDC::SetLogicalFunction( int function 
) 
 719     if (m_logicalFunction 
== function
) 
 721     m_logicalFunction 
= function 
; 
 722     m_macFontInstalled 
= false ; 
 723     m_macBrushInstalled 
= false ; 
 724     m_macPenInstalled 
= false ; 
 727 extern bool wxDoFloodFill(wxDC 
*dc
, wxCoord x
, wxCoord y
, 
 728                           const wxColour 
& col
, int style
); 
 730 bool wxDC::DoFloodFill(wxCoord x
, wxCoord y
, 
 731                        const wxColour
& col
, int style
) 
 733     return wxDoFloodFill(this, x
, y
, col
, style
); 
 736 bool  wxDC::DoGetPixel( wxCoord x
, wxCoord y
, wxColour 
*col 
) const 
 738     wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel  Invalid DC") ); 
 739     wxMacFastPortSetter 
helper(this) ; 
 741     GetCPixel( XLOG2DEVMAC(x
), YLOG2DEVMAC(y
), &colour 
); 
 742     // Convert from Mac colour to wx 
 743     col
->Set( colour
.red   
>> 8, 
 749 void  wxDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2 
) 
 751     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
 752     wxMacFastPortSetter 
helper(this) ; 
 753     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 756         wxCoord offset 
= ( (m_pen
.GetWidth() == 0 ? 1 : 
 757         m_pen
.GetWidth() ) * (wxCoord
)m_scaleX 
- 1) / 2; 
 758         wxCoord xx1 
= XLOG2DEVMAC(x1
) - offset
; 
 759         wxCoord yy1 
= YLOG2DEVMAC(y1
) - offset
; 
 760         wxCoord xx2 
= XLOG2DEVMAC(x2
) - offset
; 
 761         wxCoord yy2 
= YLOG2DEVMAC(y2
) - offset
; 
 762         if ((m_pen
.GetCap() == wxCAP_ROUND
) && 
 763             (m_pen
.GetWidth() <= 1)) 
 765             // Implement LAST_NOT for MAC at least for 
 766             // orthogonal lines. RR. 
 787 void  wxDC::DoCrossHair( wxCoord x
, wxCoord y 
) 
 789     wxCHECK_RET( Ok(), wxT("wxDC::DoCrossHair  Invalid window dc") ); 
 790     wxMacFastPortSetter 
helper(this) ; 
 791     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 796         wxCoord xx 
= XLOG2DEVMAC(x
); 
 797         wxCoord yy 
= YLOG2DEVMAC(y
); 
 799         ::MoveTo( XLOG2DEVMAC(0), yy 
); 
 800         ::LineTo( XLOG2DEVMAC(w
), yy 
); 
 801         ::MoveTo( xx
, YLOG2DEVMAC(0) ); 
 802         ::LineTo( xx
, YLOG2DEVMAC(h
) ); 
 803         CalcBoundingBox(x
, y
); 
 804         CalcBoundingBox(x
+w
, y
+h
); 
 809 * To draw arcs properly the angles need to be converted from the WX style: 
 810 * Angles start on the +ve X axis and go anti-clockwise (As you would draw on 
 811 * a normal axis on paper). 
 814 * Angles start on the +ve y axis and go clockwise. 
 817 static double wxConvertWXangleToMACangle(double angle
) 
 819     double newAngle 
= 90 - angle 
; 
 825 void  wxDC::DoDrawArc( wxCoord x1
, wxCoord y1
, 
 826                       wxCoord x2
, wxCoord y2
, 
 827                       wxCoord xc
, wxCoord yc 
) 
 829     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawArc  Invalid DC")); 
 830     wxMacFastPortSetter 
helper(this) ; 
 831     wxCoord xx1 
= XLOG2DEVMAC(x1
); 
 832     wxCoord yy1 
= YLOG2DEVMAC(y1
); 
 833     wxCoord xx2 
= XLOG2DEVMAC(x2
); 
 834     wxCoord yy2 
= YLOG2DEVMAC(y2
); 
 835     wxCoord xxc 
= XLOG2DEVMAC(xc
); 
 836     wxCoord yyc 
= YLOG2DEVMAC(yc
); 
 837     double dx 
= xx1 
- xxc
; 
 838     double dy 
= yy1 
- yyc
; 
 839     double radius 
= sqrt((double)(dx
*dx
+dy
*dy
)); 
 840     wxCoord rad   
= (wxCoord
)radius
; 
 841     double radius1
, radius2
; 
 842     if (xx1 
== xx2 
&& yy1 
== yy2
) 
 847     else if (radius 
== 0.0) 
 849         radius1 
= radius2 
= 0.0; 
 853         radius1 
= (xx1 
- xxc 
== 0) ? 
 854             (yy1 
- yyc 
< 0) ? 90.0 : -90.0 : 
 855         -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
; 
 856         radius2 
= (xx2 
- xxc 
== 0) ? 
 857             (yy2 
- yyc 
< 0) ? 90.0 : -90.0 : 
 858         -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
; 
 860     wxCoord alpha2 
= wxCoord(radius2 
- radius1
); 
 861     wxCoord alpha1 
= wxCoord(wxConvertWXangleToMACangle(radius1
)); 
 862     if( (xx1 
> xx2
) || (yy1 
> yy2
) ) { 
 865     Rect r 
= { yyc 
- rad
, xxc 
- rad
, yyc 
+ rad
, xxc 
+ rad 
}; 
 866     if(m_brush
.GetStyle() != wxTRANSPARENT
) { 
 868         PaintArc(&r
, alpha1
, alpha2
); 
 870     if(m_pen
.GetStyle() != wxTRANSPARENT
) { 
 872         FrameArc(&r
, alpha1
, alpha2
); 
 876 void  wxDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
, 
 877                               double sa
, double ea 
) 
 879     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawEllepticArc  Invalid DC")); 
 880     wxMacFastPortSetter 
helper(this) ; 
 882     double angle 
= sa 
- ea
;  // Order important Mac in opposite direction to wx 
 883     // we have to make sure that the filling is always counter-clockwise 
 886     wxCoord xx 
= XLOG2DEVMAC(x
); 
 887     wxCoord yy 
= YLOG2DEVMAC(y
); 
 888     wxCoord ww 
= m_signX 
* XLOG2DEVREL(w
); 
 889     wxCoord hh 
= m_signY 
* YLOG2DEVREL(h
); 
 890     // handle -ve width and/or height 
 891     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 892     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 893     sa 
= wxConvertWXangleToMACangle(sa
); 
 898     if(m_brush
.GetStyle() != wxTRANSPARENT
) { 
 900         PaintArc(&r
, (short)sa
, (short)angle
); 
 902     if(m_pen
.GetStyle() != wxTRANSPARENT
) { 
 904         FrameArc(&r
, (short)sa
, (short)angle
); 
 908 void  wxDC::DoDrawPoint( wxCoord x
, wxCoord y 
) 
 910     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
 911     wxMacFastPortSetter 
helper(this) ; 
 912     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 914         wxCoord xx1 
= XLOG2DEVMAC(x
); 
 915         wxCoord yy1 
= YLOG2DEVMAC(y
); 
 916         RGBColor pencolor 
= MAC_WXCOLORREF( m_pen
.GetColour().GetPixel()); 
 917         ::SetCPixel( xx1
,yy1
,&pencolor
) ; 
 918         CalcBoundingBox(x
, y
); 
 922 void  wxDC::DoDrawLines(int n
, wxPoint points
[], 
 923                         wxCoord xoffset
, wxCoord yoffset
) 
 925     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
 926     wxMacFastPortSetter 
helper(this) ; 
 927     if (m_pen
.GetStyle() == wxTRANSPARENT
) 
 930     wxCoord offset 
= ( (m_pen
.GetWidth() == 0 ? 1 : 
 931     m_pen
.GetWidth() ) * (wxCoord
)m_scaleX 
- 1) / 2 ; 
 932     wxCoord x1
, x2 
, y1 
, y2 
; 
 933     x1 
= XLOG2DEVMAC(points
[0].x 
+ xoffset
); 
 934     y1 
= YLOG2DEVMAC(points
[0].y 
+ yoffset
); 
 935     ::MoveTo(x1 
- offset
, y1 
- offset 
); 
 936     for (int i 
= 0; i 
< n
-1; i
++) 
 938         x2 
= XLOG2DEVMAC(points
[i
+1].x 
+ xoffset
); 
 939         y2 
= YLOG2DEVMAC(points
[i
+1].y 
+ yoffset
); 
 940         ::LineTo( x2 
- offset
, y2 
- offset 
); 
 944 void  wxDC::DoDrawPolygon(int n
, wxPoint points
[], 
 945                           wxCoord xoffset
, wxCoord yoffset
, 
 948     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
 949     wxMacFastPortSetter 
helper(this) ; 
 950     wxCoord x1
, x2 
, y1 
, y2 
; 
 951     if ( m_brush
.GetStyle() == wxTRANSPARENT 
&& m_pen
.GetStyle() == wxTRANSPARENT 
) 
 953     PolyHandle polygon 
= OpenPoly(); 
 954     x2 
= x1 
= XLOG2DEVMAC(points
[0].x 
+ xoffset
); 
 955     y2 
= y1 
= YLOG2DEVMAC(points
[0].y 
+ yoffset
); 
 957     for (int i 
= 1; i 
< n
; i
++) 
 959         x2 
= XLOG2DEVMAC(points
[i
].x 
+ xoffset
); 
 960         y2 
= YLOG2DEVMAC(points
[i
].y 
+ yoffset
); 
 963     // close the polyline if necessary 
 964     if ( x1 
!= x2 
|| y1 
!= y2 
) 
 969     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 972         ::PaintPoly( polygon 
); 
 974     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 977         ::FramePoly( polygon 
) ; 
 982 void wxDC::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
 984     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
 985     wxMacFastPortSetter 
helper(this) ; 
 986     wxCoord xx 
= XLOG2DEVMAC(x
); 
 987     wxCoord yy 
= YLOG2DEVMAC(y
); 
 988     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 989     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 990     // CMB: draw nothing if transformed w or h is 0 
 991     if (ww 
== 0 || hh 
== 0) 
 993     // CMB: handle -ve width and/or height 
1004     Rect rect 
= { yy 
, xx 
, yy 
+ hh 
, xx 
+ ww 
} ; 
1005     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
1008         ::PaintRect( &rect 
) ; 
1010     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1013         ::FrameRect( &rect 
) ; 
1017 void  wxDC::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
, 
1018                                    wxCoord width
, wxCoord height
, 
1021     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
1022     wxMacFastPortSetter 
helper(this) ; 
1024         radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
1025     wxCoord xx 
= XLOG2DEVMAC(x
); 
1026     wxCoord yy 
= YLOG2DEVMAC(y
); 
1027     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
1028     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
1029     // CMB: draw nothing if transformed w or h is 0 
1030     if (ww 
== 0 || hh 
== 0) 
1032     // CMB: handle -ve width and/or height 
1043     Rect rect 
= { yy 
, xx 
, yy 
+ hh 
, xx 
+ ww 
} ; 
1044     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
1047         ::PaintRoundRect( &rect 
, int(radius 
* 2) , int(radius 
* 2) ) ; 
1049     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1052         ::FrameRoundRect( &rect 
, int(radius 
* 2) , int(radius 
* 2) ) ; 
1056 void  wxDC::DoDrawEllipse(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
) 
1058     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
1059     wxMacFastPortSetter 
helper(this) ; 
1060     wxCoord xx 
= XLOG2DEVMAC(x
); 
1061     wxCoord yy 
= YLOG2DEVMAC(y
); 
1062     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
1063     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
1064     // CMB: draw nothing if transformed w or h is 0 
1065     if (ww 
== 0 || hh 
== 0) 
1067     // CMB: handle -ve width and/or height 
1078     Rect rect 
= { yy 
, xx 
, yy 
+ hh 
, xx 
+ ww 
} ; 
1079     if (m_brush
.GetStyle() != wxTRANSPARENT
) 
1082         ::PaintOval( &rect 
) ; 
1084     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1087         ::FrameOval( &rect 
) ; 
1091 bool  wxDC::CanDrawBitmap(void) const 
1096 bool  wxDC::DoBlit(wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
, 
1097                    wxDC 
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func 
, bool useMask
, 
1098                    wxCoord xsrcMask
,  wxCoord ysrcMask 
) 
1100     wxCHECK_MSG(Ok(), false, wxT("wxDC::DoBlit Illegal dc")); 
1101     wxCHECK_MSG(source
->Ok(), false, wxT("wxDC::DoBlit  Illegal source DC")); 
1102     if ( logical_func 
== wxNO_OP 
) 
1104     if (xsrcMask 
== -1 && ysrcMask 
== -1) 
1106         xsrcMask 
= xsrc
; ysrcMask 
= ysrc
; 
1108     // correct the parameter in case this dc does not have a mask at all 
1109     if ( useMask 
&& !source
->m_macMask 
) 
1111     Rect srcrect 
, dstrect 
; 
1112     srcrect
.top 
= source
->YLOG2DEVMAC(ysrc
) ; 
1113     srcrect
.left 
= source
->XLOG2DEVMAC(xsrc
)  ; 
1114     srcrect
.right 
= source
->XLOG2DEVMAC(xsrc 
+ width 
) ; 
1115     srcrect
.bottom 
= source
->YLOG2DEVMAC(ysrc 
+ height
) ; 
1116     dstrect
.top 
= YLOG2DEVMAC(ydest
) ; 
1117     dstrect
.left 
= XLOG2DEVMAC(xdest
) ; 
1118     dstrect
.bottom 
= YLOG2DEVMAC(ydest 
+ height 
)  ; 
1119     dstrect
.right 
= XLOG2DEVMAC(xdest 
+ width 
) ; 
1120     short mode 
= kUnsupportedMode 
; 
1121     bool invertDestinationFirst 
= false ; 
1122     switch ( logical_func 
) 
1124     case wxAND
:        // src AND dst 
1125         mode 
= adMin 
; // ok 
1127     case wxAND_INVERT
: // (NOT src) AND dst 
1128         mode 
= notSrcOr  
; // ok 
1130     case wxAND_REVERSE
:// src AND (NOT dst) 
1131         invertDestinationFirst 
= true ; 
1135         mode 
= kEmulatedMode 
; 
1138         mode 
= srcCopy 
; // ok 
1140     case wxEQUIV
:      // (NOT src) XOR dst 
1141         mode 
= srcXor 
; // ok 
1143     case wxINVERT
:     // NOT dst 
1144         mode 
= kEmulatedMode 
; //or hilite ; 
1146     case wxNAND
:       // (NOT src) OR (NOT dst) 
1147         invertDestinationFirst 
= true ; 
1150     case wxNOR
:        // (NOT src) AND (NOT dst) 
1151         invertDestinationFirst 
= true ; 
1154     case wxNO_OP
:      // dst 
1155         mode 
= kEmulatedMode 
; // this has already been handled upon entry 
1157     case wxOR
:         // src OR dst 
1160     case wxOR_INVERT
:  // (NOT src) OR dst 
1163     case wxOR_REVERSE
: // src OR (NOT dst) 
1164         invertDestinationFirst 
= true ; 
1168         mode 
= kEmulatedMode 
; 
1170     case wxSRC_INVERT
: // (NOT src) 
1171         mode 
= notSrcCopy 
; // ok 
1173     case wxXOR
:        // src XOR dst 
1174         mode 
= notSrcXor 
; // ok 
1179     if ( mode 
== kUnsupportedMode 
) 
1181         wxFAIL_MSG(wxT("unsupported blitting mode" )); 
1184     CGrafPtr            sourcePort 
= (CGrafPtr
) source
->m_macPort 
; 
1185     PixMapHandle    bmappixels 
=  GetGWorldPixMap( sourcePort 
) ; 
1186     if ( LockPixels(bmappixels
) ) 
1188         wxMacFastPortSetter 
helper(this) ; 
1189         if ( source
->GetDepth() == 1 ) 
1191             RGBForeColor( &MAC_WXCOLORREF(m_textForegroundColour
.GetPixel()) ) ; 
1192             RGBBackColor( &MAC_WXCOLORREF(m_textBackgroundColour
.GetPixel()) ) ; 
1196             // the modes need this, otherwise we'll end up having really nice colors... 
1197             RGBColor    white 
= { 0xFFFF, 0xFFFF,0xFFFF} ; 
1198             RGBColor    black 
= { 0,0,0} ; 
1199             RGBForeColor( &black 
) ; 
1200             RGBBackColor( &white 
) ; 
1202         if ( useMask 
&& source
->m_macMask 
) 
1204             if ( mode 
== srcCopy 
) 
1206                 if ( LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) ) ) ) 
1208                     CopyMask( GetPortBitMapForCopyBits( sourcePort 
) , 
1209                         GetPortBitMapForCopyBits( MAC_WXHBITMAP(source
->m_macMask
) ) , 
1210                         GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ) , 
1211                         &srcrect
, &srcrect 
, &dstrect 
) ; 
1212                     UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) )  ) ; 
1217                 RgnHandle clipRgn 
= NewRgn() ; 
1218                 LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) ) ) ; 
1219                 BitMapToRegion( clipRgn 
, (BitMap
*) *GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) ) ) ; 
1220                 UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source
->m_macMask
) ) ) ; 
1221                 OffsetRgn( clipRgn 
, -srcrect
.left 
+ dstrect
.left
, -srcrect
.top 
+  dstrect
.top 
) ; 
1222                 if ( mode 
== kEmulatedMode 
) 
1225                     ::PenPat(GetQDGlobalsBlack(&pat
)); 
1226                     if ( logical_func 
== wxSET 
) 
1228                         RGBColor col
= { 0xFFFF, 0xFFFF, 0xFFFF } ; 
1229                         ::RGBForeColor( &col  
) ; 
1230                         ::PaintRgn( clipRgn 
) ; 
1232                     else if ( logical_func 
== wxCLEAR 
) 
1234                         RGBColor col
= { 0x0000, 0x0000, 0x0000 } ; 
1235                         ::RGBForeColor( &col  
) ; 
1236                         ::PaintRgn( clipRgn 
) ; 
1238                     else if ( logical_func 
== wxINVERT 
) 
1240                         MacInvertRgn( clipRgn 
) ; 
1244                         for ( int y 
= 0 ; y 
< srcrect
.right 
- srcrect
.left 
; ++y 
) 
1246                             for ( int x 
= 0 ; x 
< srcrect
.bottom 
- srcrect
.top 
; ++x 
) 
1248                                 Point dstPoint 
= { dstrect
.top 
+ y 
, dstrect
.left 
+ x 
} ; 
1249                                 Point srcPoint 
= { srcrect
.top 
+ y 
, srcrect
.left 
+ x 
} ; 
1250                                 if ( PtInRgn( dstPoint 
, clipRgn 
) ) 
1254                                     SetPort( (GrafPtr
) sourcePort 
) ; 
1255                                     GetCPixel(  srcPoint
.h 
, srcPoint
.v 
, &srcColor
) ; 
1256                                     SetPort( (GrafPtr
) m_macPort 
) ; 
1257                                     GetCPixel( dstPoint
.h 
, dstPoint
.v 
, &dstColor 
) ; 
1258                                     wxMacCalculateColour( logical_func 
, srcColor 
,  dstColor 
) ; 
1259                                     SetCPixel( dstPoint
.h 
, dstPoint
.v 
, &dstColor 
) ; 
1267                     if ( invertDestinationFirst 
) 
1269                         MacInvertRgn( clipRgn 
) ; 
1271                     CopyBits( GetPortBitMapForCopyBits( sourcePort 
) , 
1272                         GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ) , 
1273                         &srcrect
, &dstrect
, mode
, clipRgn 
) ; 
1275                 DisposeRgn( clipRgn 
) ; 
1280             RgnHandle clipRgn 
= NewRgn() ; 
1281             SetRectRgn( clipRgn 
, dstrect
.left 
, dstrect
.top 
, dstrect
.right 
, dstrect
.bottom 
) ; 
1282             if ( mode 
== kEmulatedMode 
) 
1285                 ::PenPat(GetQDGlobalsBlack(&pat
)); 
1286                 if ( logical_func 
== wxSET 
) 
1288                     RGBColor col
= { 0xFFFF, 0xFFFF, 0xFFFF } ; 
1289                     ::RGBForeColor( &col  
) ; 
1290                     ::PaintRgn( clipRgn 
) ; 
1292                 else if ( logical_func 
== wxCLEAR 
) 
1294                     RGBColor col
= { 0x0000, 0x0000, 0x0000 } ; 
1295                     ::RGBForeColor( &col  
) ; 
1296                     ::PaintRgn( clipRgn 
) ; 
1298                 else if ( logical_func 
== wxINVERT 
) 
1300                     MacInvertRgn( clipRgn 
) ; 
1304                     for ( int y 
= 0 ; y 
< srcrect
.right 
- srcrect
.left 
; ++y 
) 
1306                         for ( int x 
= 0 ; x 
< srcrect
.bottom 
- srcrect
.top 
; ++x 
) 
1308                             Point dstPoint 
= { dstrect
.top 
+ y 
, dstrect
.left 
+ x 
} ; 
1309                             Point srcPoint 
= { srcrect
.top 
+ y 
, srcrect
.left 
+ x 
} ; 
1313                                 SetPort( (GrafPtr
) sourcePort 
) ; 
1314                                 GetCPixel(  srcPoint
.h 
, srcPoint
.v 
, &srcColor
) ; 
1315                                 SetPort( (GrafPtr
) m_macPort 
) ; 
1316                                 GetCPixel( dstPoint
.h 
, dstPoint
.v 
, &dstColor 
) ; 
1317                                 wxMacCalculateColour( logical_func 
, srcColor 
,  dstColor 
) ; 
1318                                 SetCPixel( dstPoint
.h 
, dstPoint
.v 
, &dstColor 
) ; 
1326                 if ( invertDestinationFirst 
) 
1328                     MacInvertRgn( clipRgn 
) ; 
1330                 CopyBits( GetPortBitMapForCopyBits( sourcePort 
) , 
1331                     GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort
) ) , 
1332                     &srcrect
, &dstrect
, mode
, NULL 
) ; 
1334             DisposeRgn( clipRgn 
) ; 
1336         UnlockPixels( bmappixels 
) ; 
1338     m_macPenInstalled 
= false ; 
1339     m_macBrushInstalled 
= false ; 
1340     m_macFontInstalled 
= false ; 
1345 // as macro in FixMath.h for 10.3 
1346 inline Fixed    
IntToFixed( int inInt 
) 
1348     return (((SInt32
) inInt
) << 16); 
1351 inline int    FixedToInt( Fixed inFixed 
) 
1353     return (((SInt32
) inFixed
) >> 16); 
1357 void  wxDC::DoDrawRotatedText(const wxString
& str
, wxCoord x
, wxCoord y
, 
1360     wxCHECK_RET( Ok(), wxT("wxDC::DoDrawRotatedText  Invalid window dc") ); 
1364         DrawText(str
, x
, y
); 
1368     if ( str
.Length() == 0 ) 
1371     wxMacFastPortSetter 
helper(this) ; 
1376         m_macFormerAliasState 
= IsAntiAliasedTextEnabled(&m_macFormerAliasSize
); 
1377         SetAntiAliasedTextEnabled(true, SInt16(m_scaleY 
* m_font
.GetMacFontSize())); 
1378         m_macAliasWasEnabled 
= true ; 
1380     OSStatus status 
= noErr 
; 
1381     ATSUTextLayout atsuLayout 
; 
1382     UniCharCount chars 
= str
.Length() ; 
1384     status 
= ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr
) (const wxChar
*) str 
, 0 , str
.Length() , str
.Length() , 1 , 
1385         &chars 
, (ATSUStyle
*) &m_macATSUIStyle 
, &atsuLayout 
) ; 
1387     wxWCharBuffer wchar 
= str
.wc_str( wxConvLocal 
) ; 
1388     int wlen 
= wxWcslen( wchar
.data() ) ; 
1389     status 
= ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr
) wchar
.data() , 0 , wlen 
, wlen 
, 1 , 
1390         &chars 
, (ATSUStyle
*) &m_macATSUIStyle 
, &atsuLayout 
) ; 
1392     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create the layout of the rotated text") ); 
1393     int iAngle 
= int( angle 
); 
1394     int drawX 
= XLOG2DEVMAC(x
) ; 
1395     int drawY 
= YLOG2DEVMAC(y
) ; 
1397     ATSUTextMeasurement textBefore 
; 
1398     ATSUTextMeasurement textAfter 
; 
1399     ATSUTextMeasurement ascent 
; 
1400     ATSUTextMeasurement descent 
; 
1403     if ( abs(iAngle
) > 0 ) 
1405         Fixed atsuAngle 
= IntToFixed( iAngle 
) ; 
1406         ATSUAttributeTag atsuTags
[] = 
1408             kATSULineRotationTag 
, 
1410         ByteCount atsuSizes
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1414         ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1418         status 
= ::ATSUSetLayoutControls(atsuLayout 
, sizeof(atsuTags
)/sizeof(ATSUAttributeTag
), 
1419             atsuTags
, atsuSizes
, atsuValues 
) ; 
1421     status 
= ::ATSUMeasureText( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1422         &textBefore 
, &textAfter
, &ascent 
, &descent 
); 
1424     drawX 
+= (int)(sin(angle
/RAD2DEG
) * FixedToInt(ascent
)); 
1425     drawY 
+= (int)(cos(angle
/RAD2DEG
) * FixedToInt(ascent
)); 
1426     status 
= ::ATSUDrawText( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1427         IntToFixed(drawX
) , IntToFixed(drawY
) ); 
1428     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't draw the rotated text") ); 
1430     status 
= ::ATSUMeasureTextImage( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1431         IntToFixed(drawX
) , IntToFixed(drawY
) , &rect 
); 
1432     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't measure the rotated text") ); 
1433     OffsetRect( &rect 
, -m_macLocalOrigin
.x 
, -m_macLocalOrigin
.y 
) ; 
1434     CalcBoundingBox(XDEV2LOG(rect
.left
), YDEV2LOG(rect
.top
) ); 
1435     CalcBoundingBox(XDEV2LOG(rect
.right
), YDEV2LOG(rect
.bottom
) ); 
1436     ::ATSUDisposeTextLayout(atsuLayout
); 
1439 void  wxDC::DoDrawText(const wxString
& strtext
, wxCoord x
, wxCoord y
) 
1441     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawText  Invalid DC")); 
1443     wxMacFastPortSetter 
helper(this) ; 
1444     long xx 
= XLOG2DEVMAC(x
); 
1445     long yy 
= YLOG2DEVMAC(y
); 
1447     bool useDrawThemeText 
= ( DrawThemeTextBox 
!= (void*) kUnresolvedCFragSymbolAddress 
) ; 
1448     if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC 
) ) || m_font
.GetNoAntiAliasing() ) 
1449         useDrawThemeText 
= false ; 
1454         m_macFormerAliasState 
= IsAntiAliasedTextEnabled(&m_macFormerAliasSize
); 
1455         SetAntiAliasedTextEnabled(true, 8); 
1456         m_macAliasWasEnabled 
= true ; 
1459     ::GetFontInfo( &fi 
) ; 
1461     if ( !useDrawThemeText 
) 
1464     ::MoveTo( xx 
, yy 
); 
1465     if (  m_backgroundMode 
== wxTRANSPARENT 
) 
1467         ::TextMode( srcOr
) ; 
1471         ::TextMode( srcCopy 
) ; 
1473     int length 
= strtext
.Length() ; 
1479 #if 0 // we don't have to do all that here 
1482             if( strtext
[i
] == 13 || strtext
[i
] == 10) 
1484                 wxString linetext 
= strtext
.Mid( laststop 
, i 
- laststop 
) ; 
1486                 if ( useDrawThemeText 
) 
1488                     Rect frame 
= { yy 
+ line
*(fi
.descent 
+ fi
.ascent 
+ fi
.leading
)  ,xx 
, yy 
+ (line
+1)*(fi
.descent 
+ fi
.ascent 
+ fi
.leading
) , xx 
+ 10000 } ; 
1489                     wxMacCFStringHolder 
mString( linetext 
, m_font
.GetEncoding() ) ; 
1490                     if ( m_backgroundMode 
!= wxTRANSPARENT 
) 
1492                         Point bounds
={0,0} ; 
1493                         Rect background 
= frame 
; 
1495                         ::GetThemeTextDimensions( mString
, 
1496                             kThemeCurrentPortFont
, 
1501                         background
.right 
= background
.left 
+ bounds
.h 
; 
1502                         background
.bottom 
= background
.top 
+ bounds
.v 
; 
1503                         ::EraseRect( &background 
) ; 
1505                     ::DrawThemeTextBox( mString
, 
1506                         kThemeCurrentPortFont
, 
1517                     wxCharBuffer text 
= linetext
.mb_str(wxConvLocal
) ;  
1518                     ::DrawText( text 
, 0 , strlen(text
) ) ; 
1519                     if ( m_backgroundMode 
!= wxTRANSPARENT 
) 
1521                         Point bounds
={0,0} ; 
1522                         Rect background 
= frame 
; 
1524                         ::GetThemeTextDimensions( mString
, 
1525                             kThemeCurrentPortFont
, 
1530                         background
.right 
= background
.left 
+ bounds
.h 
; 
1531                         background
.bottom 
= background
.top 
+ bounds
.v 
; 
1532                         ::EraseRect( &background 
) ; 
1535                     ::MoveTo( xx 
, yy 
+ line
*(fi
.descent 
+ fi
.ascent 
+ fi
.leading
) ); 
1541         wxString linetext 
= strtext
.Mid( laststop 
, i 
- laststop 
) ; 
1543         wxString linetext 
= strtext 
; 
1545         if ( useDrawThemeText 
) 
1547             Rect frame 
= { yy 
+ line
*(fi
.descent 
+ fi
.ascent 
+ fi
.leading
)  ,xx 
, yy 
+ (line
+1)*(fi
.descent 
+ fi
.ascent 
+ fi
.leading
) , xx 
+ 10000 } ; 
1548             wxMacCFStringHolder 
mString( linetext 
, m_font
.GetEncoding()) ; 
1550             if ( m_backgroundMode 
!= wxTRANSPARENT 
) 
1552                 Point bounds
={0,0} ; 
1553                 Rect background 
= frame 
; 
1555                 ::GetThemeTextDimensions( mString
, 
1556                     kThemeCurrentPortFont
, 
1561                 background
.right 
= background
.left 
+ bounds
.h 
; 
1562                 background
.bottom 
= background
.top 
+ bounds
.v 
; 
1563                 ::EraseRect( &background 
) ; 
1565             ::DrawThemeTextBox( mString
, 
1566                 kThemeCurrentPortFont
, 
1576             wxCharBuffer text 
= linetext
.mb_str(wxConvLocal
) ;  
1577             if ( m_backgroundMode 
!= wxTRANSPARENT 
) 
1579                 Rect frame 
= { yy 
- fi
.ascent 
+ line
*(fi
.descent 
+ fi
.ascent 
+ fi
.leading
)  ,xx 
, yy 
- fi
.ascent 
+ (line
+1)*(fi
.descent 
+ fi
.ascent 
+ fi
.leading
) , xx 
+ 10000 } ; 
1580                 short width 
= ::TextWidth( text 
, 0 , strlen(text
) ) ; 
1581                 frame
.right 
= frame
.left 
+ width 
; 
1583                 ::EraseRect( &frame 
) ; 
1585             ::DrawText( text 
, 0 , strlen(text
) ) ; 
1588     ::TextMode( srcOr 
) ; 
1591 bool  wxDC::CanGetTextExtent() const 
1593     wxCHECK_MSG(Ok(), false, wxT("Invalid DC")); 
1597 void  wxDC::DoGetTextExtent( const wxString 
&strtext
, wxCoord 
*width
, wxCoord 
*height
, 
1598                             wxCoord 
*descent
, wxCoord 
*externalLeading 
, 
1599                             wxFont 
*theFont 
) const 
1601     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
1602     wxMacFastPortSetter 
helper(this) ; 
1603     wxFont formerFont 
= m_font 
; 
1606         // work around the constness 
1607         *((wxFont
*)(&m_font
)) = *theFont 
; 
1611     ::GetFontInfo( &fi 
) ; 
1613     bool useGetThemeText 
= ( GetThemeTextDimensions 
!= (void*) kUnresolvedCFragSymbolAddress 
) ; 
1614     if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC 
) ) || ((wxFont
*)&m_font
)->GetNoAntiAliasing() ) 
1615         useGetThemeText 
= false ; 
1618         *height 
= YDEV2LOGREL( fi
.descent 
+ fi
.ascent 
) ; 
1620         *descent 
=YDEV2LOGREL( fi
.descent 
); 
1621     if ( externalLeading 
) 
1622         *externalLeading 
= YDEV2LOGREL( fi
.leading 
) ; 
1623     int length 
= strtext
.Length() ; 
1631 #if 0 // apparently we don't have to do all that 
1634             if( strtext
[i
] == 13 || strtext
[i
] == 10) 
1636                 wxString linetext 
= strtext
.Mid( laststop 
, i 
- laststop 
) ; 
1638                     *height 
+= YDEV2LOGREL( fi
.descent 
+ fi
.ascent 
+ fi
.leading 
) ; 
1640                 if ( useGetThemeText 
) 
1642                     Point bounds
={0,0} ; 
1644                     wxMacCFStringHolder 
mString( linetext 
, m_font
.GetEncoding() ) ; 
1645                     ::GetThemeTextDimensions( mString
, 
1646                         kThemeCurrentPortFont
, 
1651                     curwidth 
= bounds
.h 
; 
1656                     wxCharBuffer text 
= linetext
.mb_str(wxConvLocal
) ;  
1657                     curwidth 
= ::TextWidth( text 
, 0 , strlen(text
) ) ; 
1659                 if ( curwidth 
> *width 
) 
1660                     *width 
= XDEV2LOGREL( curwidth 
) ; 
1666         wxString linetext 
= strtext
.Mid( laststop 
, i 
- laststop 
) ; 
1668         wxString linetext 
= strtext 
; 
1670         if ( useGetThemeText 
) 
1672             Point bounds
={0,0} ; 
1674             wxMacCFStringHolder 
mString( linetext 
, m_font
.GetEncoding() ) ; 
1675             ::GetThemeTextDimensions( mString
, 
1676                 kThemeCurrentPortFont
, 
1681             curwidth 
= bounds
.h 
; 
1686             wxCharBuffer text 
= linetext
.mb_str(wxConvLocal
) ;   
1687             curwidth 
= ::TextWidth( text 
, 0 , strlen(text
) ) ; 
1689         if ( curwidth 
> *width 
) 
1690             *width 
= XDEV2LOGREL( curwidth 
) ; 
1694         // work around the constness 
1695         *((wxFont
*)(&m_font
)) = formerFont 
; 
1696         m_macFontInstalled 
= false ; 
1701 bool wxDC::DoGetPartialTextExtents(const wxString
& text
, wxArrayInt
& widths
) const 
1703     wxCHECK_MSG(Ok(), false, wxT("Invalid DC")); 
1706     widths
.Add(0, text
.Length()); 
1708     if (text
.Length() == 0) 
1711     wxMacFastPortSetter 
helper(this) ; 
1714     bool useGetThemeText 
= ( GetThemeTextDimensions 
!= (void*) kUnresolvedCFragSymbolAddress 
) ; 
1715     if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC 
) ) || ((wxFont
*)&m_font
)->GetNoAntiAliasing() ) 
1716         useGetThemeText 
= false ; 
1718     if ( useGetThemeText 
) 
1720         // If anybody knows how to do this more efficiently yet still handle 
1721         // the fractional glyph widths that may be present when using AA 
1722         // fonts, please change it.  Currently it is measuring from the 
1723         // begining of the string for each succeding substring, which is much 
1724         // slower than this should be. 
1725         for (size_t i
=0; i
<text
.Length(); i
++) 
1727             wxString 
str(text
.Left(i
+1)); 
1728             Point bounds 
= {0,0}; 
1730             wxMacCFStringHolder 
mString(str
, m_font
.GetEncoding()); 
1731             ::GetThemeTextDimensions( mString
, 
1732                                       kThemeCurrentPortFont
, 
1737             widths
[i
] = XDEV2LOGREL(bounds
.h
); 
1743         wxCharBuffer buff 
= text
.mb_str(wxConvLocal
); 
1744         size_t len 
= strlen(buff
); 
1745         short* measurements 
= new short[len
+1]; 
1746         MeasureText(len
, buff
.data(), measurements
); 
1748         // Copy to widths, starting at measurements[1] 
1749         // NOTE: this doesn't take into account any multi-byte characters 
1750         // in buff, it probabkly should... 
1751         for (size_t i
=0; i
<text
.Length(); i
++) 
1752             widths
[i
] = XDEV2LOGREL(measurements
[i
+1]); 
1754         delete [] measurements
;         
1762 wxCoord   
wxDC::GetCharWidth(void) const 
1764     wxCHECK_MSG(Ok(), 1, wxT("Invalid DC")); 
1765     wxMacFastPortSetter 
helper(this) ; 
1769     bool useGetThemeText 
= ( GetThemeTextDimensions 
!= (void*) kUnresolvedCFragSymbolAddress 
) ; 
1770     if ( UMAGetSystemVersion() < 0x1000 || ((wxFont
*)&m_font
)->GetNoAntiAliasing() ) 
1771         useGetThemeText 
= false ; 
1775     if ( useGetThemeText 
) 
1777         Point bounds
={0,0} ; 
1779         CFStringRef mString 
= CFStringCreateWithBytes( NULL 
, (UInt8
*) text 
, 1 , CFStringGetSystemEncoding(), false ) ; 
1780         ::GetThemeTextDimensions( mString
, 
1781             kThemeCurrentPortFont
, 
1786         CFRelease( mString 
) ; 
1792         width 
= ::TextWidth( text 
, 0 , 1 ) ; 
1794     return YDEV2LOGREL(width
) ; 
1797 wxCoord   
wxDC::GetCharHeight(void) const 
1799     wxCHECK_MSG(Ok(), 1, wxT("Invalid DC")); 
1800     wxMacFastPortSetter 
helper(this) ; 
1803     ::GetFontInfo( &fi 
) ; 
1804     return YDEV2LOGREL( fi
.descent 
+ fi
.ascent 
); 
1807 void  wxDC::Clear(void) 
1809     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
1810     wxMacFastPortSetter 
helper(this) ; 
1811     Rect rect 
= { -31000 , -31000 , 31000 , 31000 } ; 
1812     if (m_backgroundBrush
.GetStyle() != wxTRANSPARENT
) 
1815         //MacInstallBrush() ; 
1816         MacSetupBackgroundForCurrentPort( m_backgroundBrush 
) ; 
1817         ::EraseRect( &rect 
) ; 
1821 void wxDC::MacInstallFont() const 
1823     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
1824     //    if ( m_macFontInstalled ) 
1826     Pattern blackColor 
; 
1827     MacSetupBackgroundForCurrentPort(m_backgroundBrush
) ; 
1830         ::TextFont( m_font
.GetMacFontNum() ) ; 
1831         ::TextSize( (short)(m_scaleY 
* m_font
.GetMacFontSize()) ) ; 
1832         ::TextFace( m_font
.GetMacFontStyle() ) ; 
1833         m_macFontInstalled 
= true ; 
1834         m_macBrushInstalled 
= false ; 
1835         m_macPenInstalled 
= false ; 
1836         RGBColor forecolor 
= MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()); 
1837         RGBColor backcolor 
= MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()); 
1838         ::RGBForeColor( &forecolor 
); 
1839         ::RGBBackColor( &backcolor 
); 
1843         FontFamilyID fontId 
; 
1847         GetThemeFont(kThemeSmallSystemFont 
, GetApplicationScript() , fontName 
, &fontSize 
, &fontStyle 
) ; 
1848         GetFNum( fontName
, &fontId 
); 
1849         ::TextFont( fontId 
) ; 
1850         ::TextSize( short(m_scaleY 
* fontSize
) ) ; 
1851         ::TextFace( fontStyle 
) ; 
1852         // todo reset after spacing changes - or store the current spacing somewhere 
1853         m_macFontInstalled 
= true ; 
1854         m_macBrushInstalled 
= false ; 
1855         m_macPenInstalled 
= false ; 
1856         RGBColor forecolor 
= MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()); 
1857         RGBColor backcolor 
= MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()); 
1858         ::RGBForeColor( &forecolor 
); 
1859         ::RGBBackColor( &backcolor 
); 
1861     short mode 
= patCopy 
; 
1863     switch( m_logicalFunction 
) 
1868     case wxINVERT
:     // NOT dst 
1869         ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
1872     case wxXOR
:        // src XOR dst 
1875     case wxOR_REVERSE
: // src OR (NOT dst) 
1878     case wxSRC_INVERT
: // (NOT src) 
1881     case wxAND
: // src AND dst 
1886     case wxAND_REVERSE
:// src AND (NOT dst) 
1887     case wxAND_INVERT
: // (NOT src) AND dst 
1888     case wxNO_OP
:      // dst 
1889     case wxNOR
:        // (NOT src) AND (NOT dst) 
1890     case wxEQUIV
:      // (NOT src) XOR dst 
1891     case wxOR_INVERT
:  // (NOT src) OR dst 
1892     case wxNAND
:       // (NOT src) OR (NOT dst) 
1893     case wxOR
:         // src OR dst 
1895         //        case wxSRC_OR:     // source _bitmap_ OR destination 
1896         //        case wxSRC_AND:     // source _bitmap_ AND destination 
1900     OSStatus status 
= noErr 
; 
1901     Fixed atsuSize 
= IntToFixed( int(m_scaleY 
* m_font
.GetMacFontSize()) ) ; 
1902     Style qdStyle 
= m_font
.GetMacFontStyle() ; 
1903     ATSUFontID    atsuFont 
= m_font
.GetMacATSUFontID() ; 
1904     status 
= ::ATSUCreateStyle((ATSUStyle 
*)&m_macATSUIStyle
) ; 
1905     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create ATSU style") ) ; 
1906     ATSUAttributeTag atsuTags
[] = 
1911             //        kATSUBaselineClassTag , 
1912             kATSUVerticalCharacterTag
, 
1913             kATSUQDBoldfaceTag 
, 
1915             kATSUQDUnderlineTag 
, 
1916             kATSUQDCondensedTag 
, 
1917             kATSUQDExtendedTag 
, 
1919     ByteCount atsuSizes
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1921         sizeof( ATSUFontID 
) , 
1923             //        sizeof( RGBColor ) , 
1924             //        sizeof( BslnBaselineClass ) , 
1925             sizeof( ATSUVerticalCharacterType
), 
1932     Boolean kTrue 
= true ; 
1933     Boolean kFalse 
= false ; 
1934     //BslnBaselineClass kBaselineDefault = kBSLNHangingBaseline ; 
1935     ATSUVerticalCharacterType kHorizontal 
= kATSUStronglyHorizontal
; 
1936     ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
)/sizeof(ATSUAttributeTag
)] = 
1940             //        &MAC_WXCOLORREF( m_textForegroundColour.GetPixel() ) , 
1941             //        &kBaselineDefault , 
1943             (qdStyle 
& bold
) ? &kTrue 
: &kFalse 
, 
1944             (qdStyle 
& italic
) ? &kTrue 
: &kFalse 
, 
1945             (qdStyle 
& underline
) ? &kTrue 
: &kFalse 
, 
1946             (qdStyle 
& condense
) ? &kTrue 
: &kFalse 
, 
1947             (qdStyle 
& extend
) ? &kTrue 
: &kFalse 
, 
1949     status 
= ::ATSUSetAttributes((ATSUStyle
)m_macATSUIStyle
, sizeof(atsuTags
)/sizeof(ATSUAttributeTag
) , 
1950         atsuTags
, atsuSizes
, atsuValues
); 
1951     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't set create ATSU style") ) ; 
1954 Pattern gPatterns
[] = 
1956     { { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } } , 
1957     { { 0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40 , 0x80 } } , 
1958     { { 0x80 , 0x40 , 0x20 , 0x10 , 0x08 , 0x04 , 0x02 , 0x01 } } , 
1959     { { 0x10 , 0x10 , 0x10 , 0xFF , 0x10 , 0x10 , 0x10 , 0x10 } } , 
1960     { { 0x00 , 0x00 , 0x00 , 0xFF , 0x00 , 0x00 , 0x00 , 0x00 } } , 
1961     { { 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 } } , 
1962     { { 0x81 , 0x42 , 0x24 , 0x18 , 0x18 , 0x24 , 0x42 , 0x81 } } , 
1964     { { 0xCC , 0x99 , 0x33 , 0x66 , 0xCC , 0x99 , 0x33 , 0x66 } } , // DOT 
1965     { { 0xFE , 0xFD , 0xFB , 0xF7 , 0xEF , 0xDF , 0xBF , 0x7F } } , // LONG_DASH 
1966     { { 0xEE , 0xDD , 0xBB , 0x77 , 0xEE , 0xDD , 0xBB , 0x77 } } , // SHORT_DASH 
1967     { { 0xDE , 0xBD , 0x7B , 0xF6 , 0xED , 0xDB , 0xB7 , 0x6F } } , // DOT_DASH 
1970 static void wxMacGetPattern(int penStyle
, Pattern 
*pattern
) 
1972     int index 
= 0;  // solid pattern by default 
1976         case wxBDIAGONAL_HATCH
:     index 
= 1; break; 
1977         case wxFDIAGONAL_HATCH
:     index 
= 2; break; 
1978         case wxCROSS_HATCH
:         index 
= 3; break; 
1979         case wxHORIZONTAL_HATCH
:    index 
= 4; break; 
1980         case wxVERTICAL_HATCH
:      index 
= 5; break; 
1981         case wxCROSSDIAG_HATCH
:     index 
= 6; break; 
1983         case wxDOT
:                 index 
= 7; break; 
1984         case wxLONG_DASH
:           index 
= 8; break; 
1985         case wxSHORT_DASH
:          index 
= 9; break; 
1986         case wxDOT_DASH
:            index 
= 10; break; 
1988     *pattern 
= gPatterns
[index
];     
1991 void wxDC::MacInstallPen() const 
1993     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
1994     //Pattern     blackColor; 
1995     //    if ( m_macPenInstalled ) 
1997     RGBColor forecolor 
= MAC_WXCOLORREF( m_pen
.GetColour().GetPixel()); 
1998     RGBColor backcolor 
= MAC_WXCOLORREF( m_backgroundBrush
.GetColour().GetPixel()); 
1999     ::RGBForeColor( &forecolor 
); 
2000     ::RGBBackColor( &backcolor 
); 
2002     int penWidth 
= (int) (m_pen
.GetWidth() * m_scaleX
) ; ; 
2003     // null means only one pixel, at whatever resolution 
2004     if ( penWidth 
== 0 ) 
2006     ::PenSize(penWidth
, penWidth
); 
2008     int penStyle 
= m_pen
.GetStyle(); 
2010     if (penStyle 
== wxUSER_DASH
) 
2012         // FIXME: there should be exactly 8 items in the dash 
2014         int number 
= m_pen
.GetDashes(&dash
) ; 
2016         for ( int i 
= 0 ; i 
< 8 ; ++i 
) 
2018             pat
.pat
[i
] = dash
[index
] ; 
2019             if (index 
< number 
- 1) 
2025         wxMacGetPattern(penStyle
, &pat
); 
2029     short mode 
= patCopy 
; 
2031     switch( m_logicalFunction 
) 
2033     case wxCOPY
:       // only foreground color, leave background (thus not patCopy) 
2036     case wxINVERT
:     // NOT dst 
2037         //            ::PenPat(GetQDGlobalsBlack(&blackColor)); 
2040     case wxXOR
:        // src XOR dst 
2043     case wxOR_REVERSE
: // src OR (NOT dst) 
2046     case wxSRC_INVERT
: // (NOT src) 
2049     case wxAND
: // src AND dst 
2054     case wxAND_REVERSE
:// src AND (NOT dst) 
2055     case wxAND_INVERT
: // (NOT src) AND dst 
2056     case wxNO_OP
:      // dst 
2057     case wxNOR
:        // (NOT src) AND (NOT dst) 
2058     case wxEQUIV
:      // (NOT src) XOR dst 
2059     case wxOR_INVERT
:  // (NOT src) OR dst 
2060     case wxNAND
:       // (NOT src) OR (NOT dst) 
2061     case wxOR
:         // src OR dst 
2063         //        case wxSRC_OR:     // source _bitmap_ OR destination 
2064         //        case wxSRC_AND:     // source _bitmap_ AND destination 
2068     m_macPenInstalled 
= true ; 
2069     m_macBrushInstalled 
= false ; 
2070     m_macFontInstalled 
= false ; 
2073 void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush
& background 
) 
2075     Pattern whiteColor 
; 
2076     switch( background
.MacGetBrushKind() ) 
2078         case kwxMacBrushTheme 
: 
2080             ::SetThemeBackground( background
.GetMacTheme() , wxDisplayDepth() , true ) ; 
2083         case kwxMacBrushThemeBackground 
: 
2086             ThemeBackgroundKind bg 
= background
.GetMacThemeBackground( &extent 
) ; 
2087             ::ApplyThemeBackground( bg 
, &extent 
,kThemeStateActive 
, wxDisplayDepth() , true ) ; 
2090         case kwxMacBrushColour 
: 
2092             ::RGBBackColor( &MAC_WXCOLORREF( background
.GetColour().GetPixel()) ); 
2093             int brushStyle 
= background
.GetStyle(); 
2094             if (brushStyle 
== wxSOLID
) 
2095                 ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
2096             else if (IS_HATCH(brushStyle
)) 
2099                 wxMacGetPattern(brushStyle
, &pat
); 
2104                 ::BackPat(GetQDGlobalsWhite(&whiteColor
)); 
2111 void wxDC::MacInstallBrush() const 
2113     wxCHECK_RET(Ok(), wxT("Invalid DC")); 
2114     Pattern     blackColor 
; 
2115     //    if ( m_macBrushInstalled ) 
2118     bool backgroundTransparent 
= (GetBackgroundMode() == wxTRANSPARENT
) ; 
2119     ::RGBForeColor( &MAC_WXCOLORREF( m_brush
.GetColour().GetPixel()) ); 
2120     ::RGBBackColor( &MAC_WXCOLORREF( m_backgroundBrush
.GetColour().GetPixel()) ); 
2121     int brushStyle 
= m_brush
.GetStyle(); 
2122     if (brushStyle 
== wxSOLID
) 
2124         ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
2126     else if (IS_HATCH(brushStyle
)) 
2129         wxMacGetPattern(brushStyle
, &pat
); 
2132     else if ( m_brush
.GetStyle() == wxSTIPPLE 
|| m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE 
) 
2134         // we force this in order to be compliant with wxMSW 
2135         backgroundTransparent 
= false ; 
2136         // for these the text fore (and back for MASK_OPAQUE) colors are used 
2137         wxBitmap
* bitmap 
= m_brush
.GetStipple() ; 
2138         int width 
= bitmap
->GetWidth() ; 
2139         int height 
= bitmap
->GetHeight() ; 
2140         GWorldPtr gw 
= NULL 
; 
2141         if ( m_brush
.GetStyle() == wxSTIPPLE 
) 
2142             gw 
= MAC_WXHBITMAP(bitmap
->GetHBITMAP())  ; 
2144             gw 
= MAC_WXHBITMAP(bitmap
->GetMask()->GetMaskBitmap()) ; 
2145         PixMapHandle gwpixmaphandle 
= GetGWorldPixMap( gw 
) ; 
2146         LockPixels( gwpixmaphandle 
) ; 
2147         bool isMonochrome 
= !IsPortColor( gw 
) ; 
2148         if ( !isMonochrome 
) 
2150             if ( (**gwpixmaphandle
).pixelSize 
== 1 ) 
2151                 isMonochrome 
= true ; 
2153         if ( isMonochrome 
&& width 
== 8 && height 
== 8 ) 
2155             ::RGBForeColor( &MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()) ); 
2156             ::RGBForeColor( &MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()) ); 
2157             BitMap
* gwbitmap 
= (BitMap
*) *gwpixmaphandle 
; // since the color depth is 1 it is a BitMap 
2158             UInt8 
*gwbits 
= (UInt8
*) gwbitmap
->baseAddr 
; 
2159             int alignment 
= gwbitmap
->rowBytes 
& 0x7FFF ; 
2161             for ( int i 
= 0 ; i 
< 8 ; ++i 
) 
2163                 pat
.pat
[i
] = gwbits
[i
*alignment
+0] ; 
2165             UnlockPixels( GetGWorldPixMap( gw 
) ) ; 
2170             // this will be the code to handle power of 2 patterns, we will have to arrive at a nice 
2171             // caching scheme before putting this into production 
2174             PixPatHandle pixpat 
= NewPixPat() ; 
2175             CopyPixMap(gwpixmaphandle
, (**pixpat
).patMap
); 
2176             imageSize 
= GetPixRowBytes((**pixpat
).patMap
) * 
2177                 ((**(**pixpat
).patMap
).bounds
.bottom 
- 
2178                 (**(**pixpat
).patMap
).bounds
.top
); 
2179             PtrToHand( (**gwpixmaphandle
).baseAddr
, &image
, imageSize 
); 
2180             (**pixpat
).patData 
= image
; 
2183                 CTabHandle ctable 
= ((**((**pixpat
).patMap
)).pmTable
) ; 
2184                 ColorSpecPtr ctspec 
= (ColorSpecPtr
) &(**ctable
).ctTable 
; 
2185                 if ( ctspec
[0].rgb
.red 
== 0x0000 ) 
2187                     ctspec
[1].rgb 
= MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()) ; 
2188                     ctspec
[0].rgb 
= MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()) ; 
2192                     ctspec
[0].rgb 
= MAC_WXCOLORREF( m_textBackgroundColour
.GetPixel()) ; 
2193                     ctspec
[1].rgb 
= MAC_WXCOLORREF( m_textForegroundColour
.GetPixel()) ; 
2195                 ::CTabChanged( ctable 
) ; 
2197             ::PenPixPat(pixpat
); 
2198             m_macForegroundPixMap 
= pixpat 
; 
2200         UnlockPixels( gwpixmaphandle 
) ; 
2204         ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
2206     short mode 
= patCopy 
; 
2207     switch( m_logicalFunction 
) 
2210         if ( backgroundTransparent 
) 
2215     case wxINVERT
:     // NOT dst 
2216         if ( !backgroundTransparent 
) 
2218             ::PenPat(GetQDGlobalsBlack(&blackColor
)); 
2222     case wxXOR
:        // src XOR dst 
2225     case wxOR_REVERSE
: // src OR (NOT dst) 
2228     case wxSRC_INVERT
: // (NOT src) 
2231     case wxAND
: // src AND dst 
2236     case wxAND_REVERSE
:// src AND (NOT dst) 
2237     case wxAND_INVERT
: // (NOT src) AND dst 
2238     case wxNO_OP
:      // dst 
2239     case wxNOR
:        // (NOT src) AND (NOT dst) 
2240     case wxEQUIV
:      // (NOT src) XOR dst 
2241     case wxOR_INVERT
:  // (NOT src) OR dst 
2242     case wxNAND
:       // (NOT src) OR (NOT dst) 
2243     case wxOR
:         // src OR dst 
2245         //        case wxSRC_OR:     // source _bitmap_ OR destination 
2246         //        case wxSRC_AND:     // source _bitmap_ AND destination 
2250     m_macBrushInstalled 
= true ; 
2251     m_macPenInstalled 
= false ; 
2252     m_macFontInstalled 
= false ; 
2255 // --------------------------------------------------------------------------- 
2256 // coordinates transformations 
2257 // --------------------------------------------------------------------------- 
2259 wxCoord 
wxDCBase::DeviceToLogicalX(wxCoord x
) const 
2261     return ((wxDC 
*)this)->XDEV2LOG(x
); 
2264 wxCoord 
wxDCBase::DeviceToLogicalY(wxCoord y
) const 
2266     return ((wxDC 
*)this)->YDEV2LOG(y
); 
2269 wxCoord 
wxDCBase::DeviceToLogicalXRel(wxCoord x
) const 
2271     return ((wxDC 
*)this)->XDEV2LOGREL(x
); 
2274 wxCoord 
wxDCBase::DeviceToLogicalYRel(wxCoord y
) const 
2276     return ((wxDC 
*)this)->YDEV2LOGREL(y
); 
2279 wxCoord 
wxDCBase::LogicalToDeviceX(wxCoord x
) const 
2281     return ((wxDC 
*)this)->XLOG2DEV(x
); 
2284 wxCoord 
wxDCBase::LogicalToDeviceY(wxCoord y
) const 
2286     return ((wxDC 
*)this)->YLOG2DEV(y
); 
2289 wxCoord 
wxDCBase::LogicalToDeviceXRel(wxCoord x
) const 
2291     return ((wxDC 
*)this)->XLOG2DEVREL(x
); 
2294 wxCoord 
wxDCBase::LogicalToDeviceYRel(wxCoord y
) const 
2296     return ((wxDC 
*)this)->YLOG2DEVREL(y
);