]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/dc.cpp
new redrawing code
[wxWidgets.git] / src / mac / dc.cpp
index acad87440d2c876e6f80bce00e957ce6ddc59faf..6d995bb99f1e11bbd84c68f78e2cf3af5057256e 100644 (file)
@@ -38,7 +38,7 @@ IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
 #define twips2mm               0.0176388888889
 #define mm2pt                  2.83464566929
 #define pt2mm                  0.352777777778
-#ifndef __UNIX__
+#ifndef __DARWIN__
 const double M_PI = 3.14159265358979 ;
 #endif
 const double RAD2DEG  = 180.0 / M_PI;
@@ -90,10 +90,11 @@ wxDC::wxDC()
        m_macPenInstalled = false ;
        
        m_macLocalOrigin.h = m_macLocalOrigin.v = 0 ;
-       m_macClipRect.left = -32000 ;
-       m_macClipRect.top = -32000 ;
-       m_macClipRect.right = 32000 ;
-       m_macClipRect.bottom = 32000 ;
+       m_macBoundaryClipRgn = NewRgn() ;
+       m_macCurrentClipRgn = NewRgn() ;
+
+       SetRectRgn( m_macBoundaryClipRgn , -32000 , -32000 , 32000 , 32000 ) ;
+       SetRectRgn( m_macCurrentClipRgn , -32000 , -32000 , 32000 , 32000 ) ;
 
     m_pen = *wxBLACK_PEN;
     m_font = *wxNORMAL_FONT;
@@ -113,23 +114,14 @@ wxMacPortSetter::~wxMacPortSetter()
 
 wxDC::~wxDC(void)
 {
+  DisposeRgn( m_macBoundaryClipRgn ) ;
+  DisposeRgn( m_macCurrentClipRgn ) ;
 }
 void wxDC::MacSetupPort(AGAPortHelper* help) const
 {
 //     help->Setup( m_macPort ) ;
        ::SetOrigin(-m_macLocalOrigin.h, -m_macLocalOrigin.v);
-
-       if ( m_clipping )
-       {
-               Rect clip = { m_clipY1 , m_clipX1 , m_clipY2 , m_clipX2 } ;
-               ::SectRect( &clip , &m_macClipRect , &clip ) ;
-               ::ClipRect( &clip ) ;
-       }
-       else
-       {
-               ::ClipRect(&m_macClipRect);
-       }
-
+       SetClip( m_macCurrentClipRgn);
 
        m_macFontInstalled = false ;
        m_macBrushInstalled = false ;
@@ -251,6 +243,9 @@ void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord hei
     ww = XLOG2DEVREL(width);
     hh = YLOG2DEVREL(height);
 
+    SetRectRgn( m_macCurrentClipRgn , xx , yy , xx + ww , yy + hh ) ;
+    SectRgn( m_macCurrentClipRgn , m_macBoundaryClipRgn , m_macCurrentClipRgn ) ;
+    
     if( m_clipping )
     {
         m_clipX1 = wxMax( m_clipX1 , xx );
@@ -279,14 +274,53 @@ void wxDC::DoSetClippingRegionAsRegion( const wxRegion &region  )
         return;
     }
 
+    wxCoord x, y, w, h;
+    region.GetBox( x, y, w, h );
     wxCoord xx, yy, ww, hh;
-    region.GetBox( xx, yy, ww, hh );
-    wxDC::DoSetClippingRegion( xx, yy, ww, hh );
+
+    xx = XLOG2DEV(x);
+    yy = YLOG2DEV(y);
+    ww = XLOG2DEVREL(w);
+    hh = YLOG2DEVREL(h);
+
+    // if we have a scaling that we cannot map onto native regions
+    // we must use the box
+
+    if ( ww != w || hh != h )
+    {
+        wxDC::DoSetClippingRegion( x, y, w, h );
+    }
+    else
+    {
+        CopyRgn( region.GetWXHRGN() , m_macCurrentClipRgn ) ;
+        if ( xx != x || yy != y )
+        {
+            OffsetRgn( m_macCurrentClipRgn , xx - x , yy - y ) ;
+        }
+        SectRgn( m_macCurrentClipRgn , m_macBoundaryClipRgn , m_macCurrentClipRgn ) ;
+        if( m_clipping )
+        {
+            m_clipX1 = wxMax( m_clipX1 , xx );
+            m_clipY1 = wxMax( m_clipY1 , yy );
+            m_clipX2 = wxMin( m_clipX2, (xx + ww));
+            m_clipY2 = wxMin( m_clipY2, (yy + hh));
+        }
+        else
+        {
+            m_clipping = TRUE;
+            m_clipX1 = xx;
+            m_clipY1 = yy;
+            m_clipX2 = xx + ww;
+            m_clipY2 = yy + hh;
+        }
+    }
+
 }
 
 void wxDC::DestroyClippingRegion()
 {
   wxMacPortSetter helper(this) ;
+  CopyRgn( m_macBoundaryClipRgn , m_macCurrentClipRgn ) ;
   m_clipping = FALSE;
 }    
 void wxDC::DoGetSize( int* width, int* height ) const
@@ -439,16 +473,12 @@ void  wxDC::SetBackgroundMode( int mode )
 
 void  wxDC::SetFont( const wxFont &font )
 {
-    wxCHECK_RET(Ok(), wxT("Invalid DC"));
-
     m_font = font;
     m_macFontInstalled = false ;
 }
 
 void  wxDC::SetPen( const wxPen &pen )
 {
-    wxCHECK_RET(Ok(), wxT("Invalid DC"));
-
        if ( m_pen == pen )
                return ;
                
@@ -459,8 +489,6 @@ void  wxDC::SetPen( const wxPen &pen )
 
 void  wxDC::SetBrush( const wxBrush &brush )
 {
-  wxCHECK_RET(Ok(), wxT("Invalid DC"));
-  
   if (m_brush == brush) 
        return;
   
@@ -470,8 +498,6 @@ void  wxDC::SetBrush( const wxBrush &brush )
 
 void  wxDC::SetBackground( const wxBrush &brush )
 {
-  wxCHECK_RET(Ok(), wxT("Invalid DC"));
-  
   if (m_backgroundBrush == brush) 
        return;
   
@@ -944,12 +970,19 @@ bool  wxDC::CanDrawBitmap(void) const
 
 
 bool  wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
-                        wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask )
+                        wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask,
+                        wxCoord xsrcMask,  wxCoord ysrcMask )
 {
     wxCHECK_MSG(Ok(), false, wxT("wxDC::DoBlit Illegal dc"));
     wxCHECK_MSG(source->Ok(), false, wxT("wxDC::DoBlit  Illegal source DC"));
     wxMacPortSetter helper(this) ;
 
+    /* TODO: use the mask origin when drawing transparently */
+    if (xsrcMask == -1 && ysrcMask == -1)
+    {
+        xsrcMask = xsrc; ysrcMask = ysrc;
+    }
+
        CGrafPtr                        sourcePort = (CGrafPtr) source->m_macPort ;
        PixMapHandle    bmappixels =  GetGWorldPixMap( sourcePort ) ; 
        RGBColor        white = { 0xFFFF, 0xFFFF,0xFFFF} ;
@@ -962,10 +995,10 @@ bool  wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
        if ( LockPixels(bmappixels) )
        {
                Rect srcrect , dstrect ;
-               srcrect.top = source->YLOG2DEV(ysrc) ;
-               srcrect.left = source->XLOG2DEV(xsrc) ;
-               srcrect.right = source->XLOG2DEV(xsrc + width ) ;
-               srcrect.bottom = source->YLOG2DEV(ysrc + height) ;
+               srcrect.top = source->YLOG2DEV(ysrc) + source->m_macLocalOrigin.v ;
+               srcrect.left = source->XLOG2DEV(xsrc) + source->m_macLocalOrigin.h ;
+               srcrect.right = source->XLOG2DEV(xsrc + width ) + source->m_macLocalOrigin.v;
+               srcrect.bottom = source->YLOG2DEV(ysrc + height) + source->m_macLocalOrigin.h;
                dstrect.top = YLOG2DEV(ydest) ;
                dstrect.left = XLOG2DEV(xdest) ;
                dstrect.bottom = YLOG2DEV(ydest + height )  ;
@@ -987,15 +1020,31 @@ bool  wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
 
                if ( useMask && source->m_macMask )
                {
-                       wxASSERT( mode == srcCopy ) ;
-                       if ( LockPixels( GetGWorldPixMap( source->m_macMask ) ) )
-                       {
-                               CopyMask( GetPortBitMapForCopyBits( sourcePort ) , 
-                                           GetPortBitMapForCopyBits( source->m_macMask ) , 
-                                           GetPortBitMapForCopyBits( m_macPort ) ,
-                                               &srcrect, &srcrect , &dstrect ) ;
-                               UnlockPixels( GetGWorldPixMap( source->m_macMask )  ) ;
-                       }
+                   if ( mode == srcCopy )
+                   {
+                       if ( LockPixels( GetGWorldPixMap( source->m_macMask ) ) )
+                       {
+                               CopyMask( GetPortBitMapForCopyBits( sourcePort ) , 
+                                           GetPortBitMapForCopyBits( source->m_macMask ) , 
+                                           GetPortBitMapForCopyBits( m_macPort ) ,
+                                               &srcrect, &srcrect , &dstrect ) ;
+                               UnlockPixels( GetGWorldPixMap( source->m_macMask )  ) ;
+                       }
+                   }
+                   else
+                   {
+                RgnHandle clipRgn = NewRgn() ;
+                
+                LockPixels( GetGWorldPixMap( source->m_macMask ) ) ;
+                BitMapToRegion( clipRgn , (BitMap*) *GetGWorldPixMap( source->m_macMask ) ) ;
+                UnlockPixels( GetGWorldPixMap( source->m_macMask ) ) ;
+                //OffsetRgn( clipRgn , -source->m_macMask->portRect.left , -source->m_macMask->portRect.top ) ;
+                OffsetRgn( clipRgn , -srcrect.left + dstrect.left, -srcrect.top +  dstrect.top ) ;
+                       CopyBits( GetPortBitMapForCopyBits( sourcePort ) , 
+                           GetPortBitMapForCopyBits( m_macPort ) ,
+                               &srcrect, &dstrect, mode, clipRgn ) ;
+                   DisposeRgn( clipRgn ) ;
+               }
                }
                else
                {
@@ -1512,20 +1561,50 @@ void wxDC::MacInstallPen() const
        m_macFontInstalled = false ;
 }
 
+int wxDC::MacSetupBackgroundForCurrentPort(const wxBrush& background ) 
+{
+    Pattern whiteColor ;
+       if ( background.IsMacTheme() )
+       {
+           SetThemeBackground( background.GetMacTheme() , wxDisplayDepth() , true ) ;
+       }
+       else if ( background.IsMacThemeBackground() )
+       {
+           Rect originBox = { 0,0,1,1 } ;
+           ::ApplyThemeBackground( background.GetMacThemeBackground() , &originBox ,kThemeStateActive , 
+               wxDisplayDepth() , true ) ;
+       }
+       else
+       {
+       ::RGBBackColor( &background.GetColour().GetPixel() );
+       int brushStyle = background.GetStyle();
+       if (brushStyle == wxSOLID)
+               ::BackPat(GetQDGlobalsWhite(&whiteColor));
+       else if (IS_HATCH(brushStyle))
+       {
+               Pattern pat ;
+               wxMacGetHatchPattern(brushStyle, &pat);
+               ::BackPat(&pat);
+       }
+       else
+       {
+               ::BackPat(GetQDGlobalsWhite(&whiteColor));
+       }
+       }
+       return 0 ;
+}
+
 void wxDC::MacInstallBrush() const
 {
     wxCHECK_RET(Ok(), wxT("Invalid DC"));
 
-       Pattern  blackColor, whiteColor ;
+       Pattern  blackColor ;
 //     if ( m_macBrushInstalled )
 //             return ;
 
        // foreground
 
-       RGBColor forecolor = m_brush.GetColour().GetPixel();
-       RGBColor backcolor = m_backgroundBrush.GetColour().GetPixel();
-       ::RGBForeColor( &forecolor );
-       ::RGBBackColor( &backcolor );
+       ::RGBForeColor( &m_brush.GetColour().GetPixel() );
 
        int brushStyle = m_brush.GetStyle();
        if (brushStyle == wxSOLID)
@@ -1544,24 +1623,12 @@ void wxDC::MacInstallBrush() const
        
        // background
        
-       brushStyle = m_backgroundBrush.GetStyle();
-       if (brushStyle == wxSOLID)
-               ::BackPat(GetQDGlobalsWhite(&whiteColor));
-       else if (IS_HATCH(brushStyle))
-       {
-               Pattern pat ;
-               wxMacGetHatchPattern(brushStyle, &pat);
-               ::BackPat(&pat);
-       }
-       else
-       {
-               ::BackPat(GetQDGlobalsWhite(&whiteColor));
-       }
+    MacSetupBackgroundForCurrentPort( m_backgroundBrush ) ;
        
-       short mode = patCopy ;
 
        // todo :
        
+       short mode = patCopy ;
        switch( m_logicalFunction )
        {
                case wxCOPY:       // src