1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/dcclient.cpp 
   3 // Purpose:     wxClientDC class 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #include "wx/wxprec.h" 
  14 #include "wx/dcclient.h" 
  18     #include "wx/window.h" 
  19     #include "wx/dcmemory.h" 
  20     #include "wx/settings.h" 
  21     #include "wx/toplevel.h" 
  23     #include "wx/region.h" 
  26 #include "wx/graphics.h" 
  27 #include "wx/rawbmp.h" 
  28 #include "wx/mac/private.h" 
  30 //----------------------------------------------------------------------------- 
  32 //----------------------------------------------------------------------------- 
  34 //----------------------------------------------------------------------------- 
  36 //----------------------------------------------------------------------------- 
  38 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
) 
  39 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
) 
  40 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxWindowDC
) 
  46 #include "wx/mac/uma.h" 
  47 #include "wx/notebook.h" 
  48 #include "wx/tabctrl.h" 
  51 static wxBrush 
MacGetBackgroundBrush( wxWindow
* window 
) 
  53     wxBrush bkdBrush 
= window
->MacGetBackgroundBrush() ; 
  55 #if !TARGET_API_MAC_OSX 
  56     // transparency cannot be handled by the OS when not using composited windows 
  57     wxWindow
* parent 
= window
->GetParent() ; 
  59     // if we have some 'pseudo' transparency 
  60     if ( ! bkdBrush
.Ok() || bkdBrush
.GetStyle() == wxTRANSPARENT 
|| window
->GetBackgroundColour() == wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE 
) ) 
  62         // walk up until we find something 
  63         while ( parent 
!= NULL 
) 
  65             if ( parent
->GetBackgroundColour() != wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE 
) ) 
  67                 // if we have any other colours in the hierarchy 
  68                 bkdBrush
.SetColour( parent
->GetBackgroundColour() ) ; 
  72             if ( parent
->IsKindOf( CLASSINFO(wxTopLevelWindow
) ) ) 
  74                 bkdBrush 
= parent
->MacGetBackgroundBrush() ; 
  78             if ( parent
->IsKindOf( CLASSINFO( wxNotebook 
) ) 
  80                  || parent
->IsKindOf( CLASSINFO( wxTabCtrl 
) ) 
  81 #endif // wxUSE_TAB_DIALOG 
  84                 Rect extent 
= { 0 , 0 , 0 , 0 } ; 
  87                 wxSize size 
= parent
->GetSize() ; 
  88                 parent
->MacClientToRootWindow( &x 
, &y 
) ; 
  92                 extent
.right 
= x 
+ size
.x 
; 
  93                 extent
.bottom 
= y 
+ size
.y 
; 
  94                 bkdBrush
.MacSetThemeBackground( kThemeBackgroundTabPane 
, (WXRECTPTR
) &extent 
) ; 
  98             parent 
= parent
->GetParent() ; 
 102     if ( !bkdBrush
.Ok() || bkdBrush
.GetStyle() == wxTRANSPARENT 
) 
 104         // if we did not find something, use a default 
 105         bkdBrush
.MacSetTheme( kThemeBrushDialogBackgroundActive 
) ; 
 112 wxWindowDC::wxWindowDC() 
 117 wxWindowDC::wxWindowDC(wxWindow 
*window
) 
 120     wxTopLevelWindowMac
* rootwindow 
= window
->MacGetTopLevelWindow() ; 
 126     window
->MacWindowToRootWindow( &x 
, &y 
) ; 
 129 #if wxMAC_USE_CORE_GRAPHICS 
 130     m_window
->GetSize( &m_width 
, &m_height
); 
 131     CGContextRef cg 
= (CGContextRef
) window
->MacGetCGContextRef(); 
 135         SetGraphicsContext( wxGraphicsContext::Create( window 
) ) ; 
 136         SetDeviceOrigin( x
, y 
); 
 140         CGContextSaveGState( cg 
); 
 142         // make sure the context is having its origin at the wx-window coordinates of the  
 143         // view (read at the top of window.cpp about the differences) 
 144         if ( window
->MacGetLeftBorderSize() != 0 || window
->MacGetTopBorderSize() != 0 ) 
 145             CGContextTranslateCTM( cg 
, -window
->MacGetLeftBorderSize() , -window
->MacGetTopBorderSize() ); 
 147         SetGraphicsContext( wxGraphicsContext::CreateFromNative( cg 
) ); 
 149     m_graphicContext
->SetPen( m_pen 
) ; 
 150     m_graphicContext
->SetBrush( m_brush 
) ; 
 151     SetClippingRegion( 0 , 0 , m_width 
, m_height 
) ; 
 153     m_macLocalOrigin
.x 
= x 
; 
 154     m_macLocalOrigin
.y 
= y 
; 
 155     m_macPort 
= UMAGetWindowPort( (WindowRef
) rootwindow
->MacGetWindowRef() ) ; 
 157     CopyRgn( (RgnHandle
) window
->MacGetVisibleRegion(true).GetWXHRGN() , (RgnHandle
) m_macBoundaryClipRgn 
) ; 
 158     OffsetRgn( (RgnHandle
) m_macBoundaryClipRgn 
, m_macLocalOrigin
.x 
, m_macLocalOrigin
.y 
) ; 
 159     CopyRgn( (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) m_macCurrentClipRgn 
) ; 
 161     SetBackground(MacGetBackgroundBrush(window
)); 
 163     SetFont( window
->GetFont() ) ; 
 166 wxWindowDC::~wxWindowDC() 
 168 #if wxMAC_USE_CORE_GRAPHICS 
 169     if ( m_release 
&& m_graphicContext 
) 
 171         CGContextRef cg 
= (CGContextRef
) m_window
->MacGetCGContextRef(); 
 172         CGContextRestoreGState(cg
); 
 173         //CGContextRef cg = (CGContextRef) m_graphicContext->GetNativeContext() ; 
 178 void wxWindowDC::DoGetSize( int* width
, int* height 
) const 
 180 #if wxMAC_USE_CORE_GRAPHICS 
 186     wxCHECK_RET( m_window
, _T("GetSize() doesn't work without window") ); 
 187     m_window
->GetSize(width
, height
); 
 191 wxBitmap 
wxWindowDC::DoGetAsBitmap() const 
 193     ControlRef handle 
= (ControlRef
) m_window
->GetHandle();  
 199     CGContextRef context
; 
 204     HIViewCreateOffscreenImage( handle
, 0, &rect
, &image
); 
 206     int width 
= rect
.size
.width
; 
 207     int height 
= rect
.size
.height
;  
 209     bytesPerRow 
= ( ( width 
* 8 * 4 + 7 ) / 8 ); 
 211     data 
= calloc( 1, bytesPerRow 
* height 
); 
 212     context 
= CGBitmapContextCreate( data
, width
, height
, 8, bytesPerRow
, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedFirst 
); 
 214     CGContextDrawImage( context
, rect
, image 
); 
 216     unsigned char* buffer 
= (unsigned char*) data
;           
 217     wxBitmap bmp 
= wxBitmap(width
, height
, 32); 
 218     wxAlphaPixelData 
pixData(bmp
, wxPoint(0,0), wxSize(width
, height
)); 
 221     wxAlphaPixelData::Iterator 
p(pixData
); 
 222     for (int y
=0; y
<height
; y
++) { 
 223         wxAlphaPixelData::Iterator rowStart 
= p
; 
 224         for (int x
=0; x
<width
; x
++) { 
 225             unsigned char a 
= buffer
[3]; 
 226             p
.Red()   = a
; buffer
++; 
 227             p
.Green() = a
; buffer
++; 
 228             p
.Blue()  = a
; buffer
++; 
 229             p
.Alpha() = a
; buffer
++; 
 233         p
.OffsetY(pixData
, 1); 
 243 wxClientDC::wxClientDC() 
 248 #if wxMAC_USE_CORE_GRAPHICS 
 249 wxClientDC::wxClientDC(wxWindow 
*window
) : 
 252     wxPoint origin 
= window
->GetClientAreaOrigin() ; 
 253     wxSize size 
= window
->GetClientSize() ; 
 257     window
->MacWindowToRootWindow( &x 
, &y 
) ; 
 258     m_window
->GetClientSize( &m_width 
, &m_height
); 
 259     SetDeviceOrigin( origin
.x
, origin
.y 
); 
 260     SetClippingRegion( 0 , 0 , m_width 
, m_height 
) ; 
 263 wxClientDC::wxClientDC(wxWindow 
*window
) 
 266     wxTopLevelWindowMac
* rootwindow 
= window
->MacGetTopLevelWindow() ; 
 270     WindowRef windowref 
= (WindowRef
) rootwindow
->MacGetWindowRef() ; 
 271     wxPoint origin 
= window
->GetClientAreaOrigin() ; 
 272     wxSize size 
= window
->GetClientSize() ; 
 276     window
->MacWindowToRootWindow( &x 
, &y 
) ; 
 277     m_macPort 
= UMAGetWindowPort( windowref 
) ; 
 280     m_macLocalOrigin
.x 
= x 
; 
 281     m_macLocalOrigin
.y 
= y 
; 
 282     SetRectRgn( (RgnHandle
) m_macBoundaryClipRgn 
, origin
.x 
, origin
.y 
, origin
.x 
+ size
.x 
, origin
.y 
+ size
.y 
) ; 
 283     SectRgn( (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) window
->MacGetVisibleRegion().GetWXHRGN() , (RgnHandle
) m_macBoundaryClipRgn 
) ; 
 284     OffsetRgn( (RgnHandle
) m_macBoundaryClipRgn 
, -origin
.x 
, -origin
.y 
) ; 
 285     OffsetRgn( (RgnHandle
) m_macBoundaryClipRgn 
, m_macLocalOrigin
.x 
, m_macLocalOrigin
.y 
) ; 
 286     CopyRgn( (RgnHandle
) m_macBoundaryClipRgn 
,(RgnHandle
)  m_macCurrentClipRgn 
) ; 
 288     SetBackground(MacGetBackgroundBrush(window
)); 
 289     SetFont( window
->GetFont() ) ; 
 293 wxClientDC::~wxClientDC() 
 297 #if !wxMAC_USE_CORE_GRAPHICS 
 298 void wxClientDC::DoGetSize(int *width
, int *height
) const 
 300     wxCHECK_RET( m_window
, _T("GetSize() doesn't work without window") ); 
 302     m_window
->GetClientSize( width
, height 
); 
 310 wxPaintDC::wxPaintDC() 
 315 #if wxMAC_USE_CORE_GRAPHICS 
 316 wxPaintDC::wxPaintDC(wxWindow 
*window
) : 
 319     wxPoint origin 
= window
->GetClientAreaOrigin() ; 
 320     wxSize size 
= window
->GetClientSize() ; 
 324     window
->MacWindowToRootWindow( &x 
, &y 
) ; 
 325     m_window
->GetClientSize( &m_width 
, &m_height
); 
 326     SetDeviceOrigin( origin
.x
, origin
.y 
); 
 327     SetClippingRegion( 0 , 0 , m_width 
, m_height 
) ; 
 330 wxPaintDC::wxPaintDC(wxWindow 
*window
) 
 333     wxTopLevelWindowMac
* rootwindow 
= window
->MacGetTopLevelWindow() ; 
 334     WindowRef windowref 
= (WindowRef
) rootwindow
->MacGetWindowRef() ; 
 335     wxPoint origin 
= window
->GetClientAreaOrigin() ; 
 336     wxSize size 
= window
->GetClientSize() ; 
 340     window
->MacWindowToRootWindow( &x 
, &y 
) ; 
 341     m_macPort 
= UMAGetWindowPort( windowref 
) ; 
 344 #if wxMAC_USE_CORE_GRAPHICS 
 345     if ( window
->MacGetCGContextRef() ) 
 347         m_graphicContext 
= new wxMacCGContext( (CGContextRef
) window
->MacGetCGContextRef() ) ; 
 348         m_graphicContext
->SetPen( m_pen 
) ; 
 349         m_graphicContext
->SetBrush( m_brush 
) ; 
 350         SetClippingRegion( 0 , 0 , size
.x 
, size
.y 
) ; 
 351         SetBackground(MacGetBackgroundBrush(window
)); 
 355         wxLogDebug(wxT("You cannot create a wxPaintDC outside an OS-draw event") ) ; 
 356         m_graphicContext 
= NULL 
; 
 358     // there is no out-of-order drawing on OSX 
 360     m_macLocalOrigin
.x 
= x 
; 
 361     m_macLocalOrigin
.y 
= y 
; 
 362     SetRectRgn( (RgnHandle
) m_macBoundaryClipRgn 
, origin
.x 
, origin
.y 
, origin
.x 
+ size
.x 
, origin
.y 
+ size
.y 
) ; 
 363     SectRgn( (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) window
->MacGetVisibleRegion().GetWXHRGN() , (RgnHandle
) m_macBoundaryClipRgn 
) ; 
 364     OffsetRgn( (RgnHandle
) m_macBoundaryClipRgn 
, -origin
.x 
, -origin
.y 
) ; 
 365     SectRgn( (RgnHandle
) m_macBoundaryClipRgn  
, (RgnHandle
) window
->GetUpdateRegion().GetWXHRGN() , (RgnHandle
) m_macBoundaryClipRgn 
) ; 
 366     OffsetRgn( (RgnHandle
) m_macBoundaryClipRgn 
, m_macLocalOrigin
.x 
, m_macLocalOrigin
.y 
) ; 
 367     CopyRgn( (RgnHandle
) m_macBoundaryClipRgn 
, (RgnHandle
) m_macCurrentClipRgn 
) ; 
 368     SetBackground(MacGetBackgroundBrush(window
)); 
 371     SetFont( window
->GetFont() ) ; 
 375 wxPaintDC::~wxPaintDC() 
 379 #if !wxMAC_USE_CORE_GRAPHICS 
 380 void wxPaintDC::DoGetSize(int *width
, int *height
) const 
 382     wxCHECK_RET( m_window
, _T("GetSize() doesn't work without window") ); 
 384     m_window
->GetClientSize( width
, height 
);