]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/dc.cpp
don't crash in UnselectAll() if the tree has no root
[wxWidgets.git] / src / mac / dc.cpp
index aaa3df65f445f461f25eaa7c5dc256a4a7089495..59472ddfa54b71968894b93fe310e60db8f562ec 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,12 @@ 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 ;
@@ -144,8 +134,8 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
  
      wxMacPortSetter helper(this) ;
  
-     wxCoord xx = XLOG2DEV(x);
-     wxCoord yy = YLOG2DEV(y);
+     wxCoord xx = XLOG2DEVMAC(x);
+     wxCoord yy = YLOG2DEVMAC(y);
      wxCoord w = bmp.GetWidth();
      wxCoord h = bmp.GetHeight();
      wxCoord ww = XLOG2DEVREL(w);
@@ -239,18 +229,21 @@ void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y )
  
      wxCHECK_RET(icon.Ok(), wxT("Invalid icon wxDC::DoDrawIcon"));
  
-    DoDrawBitmap( icon , x , y ) ;
+    DoDrawBitmap( icon , x , y , icon.GetMask() != NULL ) ;
 }
 void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
 {
     wxCHECK_RET(Ok(), wxT("wxDC::DoSetClippingRegion  Invalid DC"));
     wxCoord xx, yy, ww, hh;
 
-    xx = XLOG2DEV(x);
-    yy = YLOG2DEV(y);
+    xx = XLOG2DEVMAC(x);
+    yy = YLOG2DEVMAC(y);
     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 +272,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 = XLOG2DEVMAC(x);
+    yy = YLOG2DEVMAC(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 +471,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 +487,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 +496,6 @@ void  wxDC::SetBrush( const wxBrush &brush )
 
 void  wxDC::SetBackground( const wxBrush &brush )
 {
-  wxCHECK_RET(Ok(), wxT("Invalid DC"));
-  
   if (m_backgroundBrush == brush) 
        return;
   
@@ -505,7 +529,7 @@ bool  wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const
 
     RGBColor colour;
 
-    GetCPixel( XLOG2DEV(x), YLOG2DEV(y), &colour );
+    GetCPixel( XLOG2DEVMAC(x), YLOG2DEVMAC(y), &colour );
 
     // Convert from Mac colour to wx
     col->Set( colour.red   >> 8,
@@ -527,13 +551,34 @@ void  wxDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 )
                wxCoord offset = ( (m_pen.GetWidth() == 0 ? 1 :
                             m_pen.GetWidth() ) * (wxCoord)m_scaleX - 1) / 2;
 
-        wxCoord xx1 = XLOG2DEV(x1);
-        wxCoord yy1 = YLOG2DEV(y1);
-        wxCoord xx2 = XLOG2DEV(x2);
-        wxCoord yy2 = YLOG2DEV(y2);
-
-               ::MoveTo(xx1 - offset, yy1 - offset);
-               ::LineTo(xx2 - offset, yy2 - offset);
+        wxCoord xx1 = XLOG2DEVMAC(x1) - offset;
+        wxCoord yy1 = YLOG2DEVMAC(y1) - offset;
+        wxCoord xx2 = XLOG2DEVMAC(x2) - offset;
+        wxCoord yy2 = YLOG2DEVMAC(y2) - offset;
+
+        if ((m_pen.GetCap() == wxCAP_ROUND) &&
+            (m_pen.GetWidth() <= 1))
+       {
+           // Implement LAST_NOT for MAC at least for
+           // orthogonal lines. RR.
+               if (xx1 == xx2)
+               {
+                       if (yy1 < yy2)
+                               yy2--;
+                   if (yy1 > yy2)
+                       yy2++;
+               }
+               if (yy1 == yy2)
+               {
+                       if (xx1 < xx2)
+                               xx2--;
+                   if (xx1 > xx2)
+                       xx2++;
+               }
+       }
+       
+               ::MoveTo(xx1, yy1);
+               ::LineTo(xx2, yy2);
   }
 }
 
@@ -546,14 +591,14 @@ void  wxDC::DoCrossHair( wxCoord x, wxCoord y )
         int w = 0;
         int h = 0;
         GetSize( &w, &h );
-        wxCoord xx = XLOG2DEV(x);
-        wxCoord yy = YLOG2DEV(y);
+        wxCoord xx = XLOG2DEVMAC(x);
+        wxCoord yy = YLOG2DEVMAC(y);
 
         MacInstallPen();
-        ::MoveTo( 0, yy );
-        ::LineTo( XLOG2DEVREL(w), yy );
-        ::MoveTo( xx, 0 );
-        ::LineTo( xx, YLOG2DEVREL(h) );
+        ::MoveTo( XLOG2DEVMAC(0), yy );
+        ::LineTo( XLOG2DEVMAC(w), yy );
+        ::MoveTo( xx, YLOG2DEVMAC(0) );
+        ::LineTo( xx, YLOG2DEVMAC(h) );
     }
 }
 
@@ -598,12 +643,12 @@ void  wxDC::DoDrawArc( wxCoord x1, wxCoord y1,
 {
     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawArc  Invalid DC"));
 
-    wxCoord xx1 = XLOG2DEV(x1);
-    wxCoord yy1 = YLOG2DEV(y1);
-    wxCoord xx2 = XLOG2DEV(x2);
-    wxCoord yy2 = YLOG2DEV(y2);
-    wxCoord xxc = XLOG2DEV(xc);
-    wxCoord yyc = YLOG2DEV(yc);
+    wxCoord xx1 = XLOG2DEVMAC(x1);
+    wxCoord yy1 = YLOG2DEVMAC(y1);
+    wxCoord xx2 = XLOG2DEVMAC(x2);
+    wxCoord yy2 = YLOG2DEVMAC(y2);
+    wxCoord xxc = XLOG2DEVMAC(xc);
+    wxCoord yyc = YLOG2DEVMAC(yc);
     double dx = xx1 - xxc;
     double dy = yy1 - yyc;
     double radius = sqrt((double)(dx*dx+dy*dy));
@@ -654,8 +699,8 @@ void  wxDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h,
     Rect r;
     double angle = sa - ea;  // Order important Mac in opposite direction to wx
  
-    wxCoord xx = XLOG2DEV(x);
-    wxCoord yy = YLOG2DEV(y);
+    wxCoord xx = XLOG2DEVMAC(x);
+    wxCoord yy = YLOG2DEVMAC(y);
     wxCoord ww = m_signX * XLOG2DEVREL(w);
     wxCoord hh = m_signY * YLOG2DEVREL(h);
 
@@ -689,8 +734,8 @@ void  wxDC::DoDrawPoint( wxCoord x, wxCoord y )
   if (m_pen.GetStyle() != wxTRANSPARENT) 
   {
                MacInstallPen() ;
-        wxCoord xx1 = XLOG2DEV(x); 
-        wxCoord yy1 = YLOG2DEV(y);
+        wxCoord xx1 = XLOG2DEVMAC(x); 
+        wxCoord yy1 = YLOG2DEVMAC(y);
        
                ::MoveTo(xx1,yy1);
                ::LineTo(xx1+1, yy1+1);
@@ -712,14 +757,14 @@ void  wxDC::DoDrawLines(int n, wxPoint points[],
                       m_pen.GetWidth() ) * (wxCoord)m_scaleX - 1) / 2 ;
 
   wxCoord x1, x2 , y1 , y2 ;
-  x1 = XLOG2DEV(points[0].x + xoffset);
-  y1 = YLOG2DEV(points[0].y + yoffset);   
+  x1 = XLOG2DEVMAC(points[0].x + xoffset);
+  y1 = YLOG2DEVMAC(points[0].y + yoffset);   
   ::MoveTo(x1 - offset, y1 - offset );
   
   for (int i = 0; i < n-1; i++)
   {
-    x2 = XLOG2DEV(points[i+1].x + xoffset);
-    y2 = YLOG2DEV(points[i+1].y + yoffset);
+    x2 = XLOG2DEVMAC(points[i+1].x + xoffset);
+    y2 = YLOG2DEVMAC(points[i+1].y + yoffset);
     ::LineTo( x2 - offset, y2 - offset );
   }
 }
@@ -728,35 +773,45 @@ void  wxDC::DoDrawPolygon(int n, wxPoint points[],
                                wxCoord xoffset, wxCoord yoffset,
                                int fillStyle )
 {
-  wxCHECK_RET(Ok(), wxT("Invalid DC"));
-  wxMacPortSetter helper(this) ;
-  
-  PolyHandle polygon = OpenPoly() ;
-  wxCoord x1, x2 , y1 , y2 ;
-  x1 = XLOG2DEV(points[0].x + xoffset);
-  y1 = YLOG2DEV(points[0].y + yoffset);   
-  ::MoveTo(x1,y1);
+       wxCHECK_RET(Ok(), wxT("Invalid DC"));
+       wxMacPortSetter helper(this) ;
+       
+       wxCoord x1, x2 , y1 , y2 ;
   
-  for (int i = 0; i < n-1; i++)
-  {
-    x2 = XLOG2DEV(points[i+1].x + xoffset);
-    y2 = YLOG2DEV(points[i+1].y + yoffset);
-    ::LineTo(x2, y2);
-  }
+    if ( m_brush.GetStyle() == wxTRANSPARENT && m_pen.GetStyle() == wxTRANSPARENT )
+        return ;
+        
+       PolyHandle polygon = OpenPoly();
+       
+       x1 = XLOG2DEVMAC(points[0].x + xoffset);
+       y1 = YLOG2DEVMAC(points[0].y + yoffset);   
+       ::MoveTo(x1,y1);
 
-  ClosePoly() ;
-       if (m_brush.GetStyle() != wxTRANSPARENT) 
+       for (int i = 0; i < n-1; i++)
        {
-               MacInstallBrush() ;
-               ::PaintPoly( polygon ) ;
+               x2 = XLOG2DEVMAC(points[i+1].x + xoffset);
+               y2 = YLOG2DEVMAC(points[i+1].y + yoffset);
+               ::LineTo(x2, y2);
+       }
+
+       ClosePoly();
+
+       if (m_brush.GetStyle() != wxTRANSPARENT)
+       {
+
+               MacInstallBrush();
+               ::PaintPoly( polygon );
+               
        }
        
        if (m_pen.GetStyle() != wxTRANSPARENT) 
        {
+       
                MacInstallPen() ;
                ::FramePoly( polygon ) ;
+               
        }
-  KillPoly( polygon ) ;
+       KillPoly( polygon );
 }
 
 void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
@@ -764,8 +819,8 @@ void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
     wxCHECK_RET(Ok(), wxT("Invalid DC"));
     wxMacPortSetter helper(this) ;
 
-       wxCoord xx = XLOG2DEV(x);
-       wxCoord yy = YLOG2DEV(y);
+       wxCoord xx = XLOG2DEVMAC(x);
+       wxCoord yy = YLOG2DEVMAC(y);
        wxCoord ww = m_signX * XLOG2DEVREL(width);
        wxCoord hh = m_signY * YLOG2DEVREL(height);
        
@@ -811,8 +866,8 @@ void  wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y,
     if (radius < 0.0) 
            radius = - radius * ((width < height) ? width : height);
        
-       wxCoord xx = XLOG2DEV(x);
-       wxCoord yy = YLOG2DEV(y);
+       wxCoord xx = XLOG2DEVMAC(x);
+       wxCoord yy = YLOG2DEVMAC(y);
        wxCoord ww = m_signX * XLOG2DEVREL(width);
        wxCoord hh = m_signY * YLOG2DEVREL(height);
        
@@ -853,8 +908,8 @@ void  wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
     wxCHECK_RET(Ok(), wxT("Invalid DC"));
     wxMacPortSetter helper(this) ;
 
-       wxCoord xx = XLOG2DEV(x);
-       wxCoord yy = YLOG2DEV(y);
+       wxCoord xx = XLOG2DEVMAC(x);
+       wxCoord yy = YLOG2DEVMAC(y);
        wxCoord ww = m_signX * XLOG2DEVREL(width);
        wxCoord hh = m_signY * YLOG2DEVREL(height);
 
@@ -899,12 +954,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} ;
@@ -917,14 +979,14 @@ 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) ;
-               dstrect.top = YLOG2DEV(ydest) ;
-               dstrect.left = XLOG2DEV(xdest) ;
-               dstrect.bottom = YLOG2DEV(ydest + height )  ;
-               dstrect.right = XLOG2DEV(xdest + width ) ;
+               srcrect.top = source->YLOG2DEVMAC(ysrc) ;
+               srcrect.left = source->XLOG2DEVMAC(xsrc)  ;
+               srcrect.right = source->XLOG2DEVMAC(xsrc + width ) ;
+               srcrect.bottom = source->YLOG2DEVMAC(ysrc + height) ;
+               dstrect.top = YLOG2DEVMAC(ydest) ;
+               dstrect.left = XLOG2DEVMAC(xdest) ;
+               dstrect.bottom = YLOG2DEVMAC(ydest + height )  ;
+               dstrect.right = XLOG2DEVMAC(xdest + width ) ;
 
        short  mode = (logical_func == wxCOPY ? srcCopy :
  //    logical_func == wxCLEAR ? WHITENESS :
@@ -942,15 +1004,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
                {
@@ -1046,7 +1124,7 @@ void  wxDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y,
             textPixel = data[(srcY*w + srcX)*3] == 0;
             if ( textPixel || (m_backgroundMode == wxSOLID) )
             {
-                SetCPixel(XLOG2DEV(x + dstX), YLOG2DEV(y + dstY),
+                SetCPixel(XLOG2DEVMAC(x + dstX), YLOG2DEVMAC(y + dstY),
                           textPixel ? &colText : &colBack);
             }
         }
@@ -1057,8 +1135,8 @@ void  wxDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y,
 #if 0
     if ( m_font.GetUnderlined() )
     {
-        ::MoveTo(XLOG2DEV(x + x4), YLOG2DEV(y + y4 + font->descent));
-        ::LineTo(XLOG2DEV(x + x3), YLOG2DEV(y + y3 + font->descent));
+        ::MoveTo(XLOG2DEVMAC(x + x4), YLOG2DEVMAC(y + y4 + font->descent));
+        ::LineTo(XLOG2DEVMAC(x + x3), YLOG2DEVMAC(y + y3 + font->descent));
     }
 #endif // 0
 
@@ -1071,8 +1149,8 @@ void  wxDC::DoDrawText(const wxString& strtext, wxCoord x, wxCoord y)
     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawText  Invalid DC"));
     wxMacPortSetter helper(this) ;
 
-       long xx = XLOG2DEV(x);
-       long yy = YLOG2DEV(y);
+       long xx = XLOG2DEVMAC(x);
+       long yy = YLOG2DEVMAC(y);
   
 //     if (m_pen.GetStyle() != wxTRANSPARENT)
        {
@@ -1231,10 +1309,9 @@ wxCoord   wxDC::GetCharWidth(void) const
 
        MacInstallFont() ;
 
-       FontInfo fi ;
-       ::GetFontInfo( &fi ) ;
+    int width = ::TextWidth( "n" , 0 , 1 ) ;
 
-       return YDEV2LOGREL((fi.descent + fi.ascent) / 2) ;
+       return YDEV2LOGREL(width) ;
 }
 
 wxCoord   wxDC::GetCharHeight(void) const
@@ -1354,27 +1431,28 @@ void wxDC::MacInstallFont() const
 
 static void wxMacGetHatchPattern(int hatchStyle, Pattern *pattern)
 {
-       int thePatListID = sysPatListID;
+    // we have our own pattern list now
+       int thePatListID = 128;
        int theIndex;
        switch(hatchStyle)
        {
                case wxBDIAGONAL_HATCH:
-                       theIndex = 34; // WCH: this is not good
+                       theIndex = 2; 
                        break;
                case wxFDIAGONAL_HATCH:
-                       theIndex = 26;
+                       theIndex = 3;
                        break;
                case wxCROSS_HATCH:
-                       theIndex = 5;
+                       theIndex = 4;
                        break;
                case wxHORIZONTAL_HATCH:
-                       theIndex = 25;
+                       theIndex = 5;
                        break;
                case wxVERTICAL_HATCH:
                        theIndex = 6;
                        break;
                case wxCROSSDIAG_HATCH:
-                       theIndex = 4; // WCH: this is not good
+                       theIndex = 7; 
                        break;
                default:
                        theIndex = 1; // solid pattern
@@ -1419,7 +1497,46 @@ void wxDC::MacInstallPen() const
        }
        else
        {
-               ::PenPat(GetQDGlobalsBlack(&blackColor));
+           Pattern pat = *GetQDGlobalsBlack(&blackColor) ;
+           switch( penStyle )
+           {
+               case wxDOT :
+                for ( int i = 0 ; i < 8 ; ++i )
+                {
+                    pat.pat[i] = 0xCC ;
+                }
+                   break ;
+               case wxLONG_DASH :
+                for ( int i = 0 ; i < 8 ; ++i )
+                {
+                    pat.pat[i] = 0xFE ;
+                }
+                   break ;
+               case wxSHORT_DASH :
+                for ( int i = 0 ; i < 8 ; ++i )
+                {
+                    pat.pat[i] = 0xEE ;
+                }
+                   break ;
+               case wxDOT_DASH :
+                for ( int i = 0 ; i < 8 ; ++i )
+                {
+                    pat.pat[i] = 0x6F ;
+                }
+                   break ;
+               case wxUSER_DASH :
+                   {
+                       wxDash* dash ;
+                       int number = m_pen.GetDashes(&dash) ;
+                       // right now we don't allocate larger pixmaps
+                       for ( int i = 0 ; i < 8 ; ++i )
+                       {
+                           pat.pat[i] = dash[0] ;
+                       }
+                   }
+                   break ;
+           }
+               ::PenPat(&pat);
        }
 
        short mode = patCopy ;
@@ -1428,11 +1545,11 @@ void wxDC::MacInstallPen() const
        
        switch( m_logicalFunction )
        {
-               case wxCOPY:       // src
-                       mode = patCopy ;
+               case wxCOPY:       // only foreground color, leave background (thus not patCopy)
+                       mode = patOr ;
                        break ;
                case wxINVERT:     // NOT dst
-                       ::PenPat(GetQDGlobalsBlack(&blackColor));
+//                     ::PenPat(GetQDGlobalsBlack(&blackColor));
                        mode = patXor ;
                        break ;
                case wxXOR:        // src XOR dst
@@ -1468,20 +1585,55 @@ void wxDC::MacInstallPen() const
        m_macFontInstalled = false ;
 }
 
+void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush& background ) 
+{
+    Pattern whiteColor ;
+    switch( background.MacGetBrushKind() )
+    {
+      case kwxMacBrushTheme :
+        {
+               ::SetThemeBackground( background.GetMacTheme() , wxDisplayDepth() , true ) ;
+          break ;
+        }
+      case kwxMacBrushThemeBackground :
+        {
+               Rect extent ;
+               ThemeBackgroundKind bg = background.GetMacThemeBackground( &extent ) ;
+               ::ApplyThemeBackground( bg , &extent ,kThemeStateActive , wxDisplayDepth() , true ) ;
+          break ;
+        }
+      case kwxMacBrushColour :
+        {
+                 ::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));
+               }
+          break ;
+        }
+    }
+}
+
 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)
@@ -1492,32 +1644,57 @@ void wxDC::MacInstallBrush() const
                wxMacGetHatchPattern(brushStyle, &pat);
                ::PenPat(&pat);
        }
-       else
+       else if ( m_brush.GetStyle() == wxSTIPPLE || m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE )
        {
-               ::PenPat(GetQDGlobalsBlack(&blackColor));
+           // for these the text fore (and back for MASK_OPAQUE) colors are used
+           wxBitmap* bitmap = m_brush.GetStipple() ;
+           int width = bitmap->GetWidth() ;
+           int height = bitmap->GetHeight() ;
+           int depth = bitmap->GetDepth() ;
+           if ( m_brush.GetStyle() == wxSTIPPLE )
+           {
+               GWorldPtr gw = bitmap->GetHBITMAP() ;
+               if ( width == 8 && height == 8 && depth == 1)
+               {
+                   Pattern pat ;
+                LockPixels( GetGWorldPixMap( gw ) ) ;
+                BitMap* gwbitmap = (BitMap*) *GetGWorldPixMap( gw ) ; // since the color depth is 1 it is a BitMap
+                   int alignment = gwbitmap->rowBytes & 0x7FFF ;
+                UInt8 *gwbits = (UInt8*) gwbitmap->baseAddr ;
+                for ( int i = 0 ; i < 8 ; ++i )
+                {
+                    pat.pat[i] = gwbits[i*alignment+0] ;
+                }
+                UnlockPixels( GetGWorldPixMap( gw ) ) ;
+                   
+                   ::PenPat( &pat ) ;
+               }
+               else
+               {
+                       ::PenPat(GetQDGlobalsBlack(&blackColor));
+                   }
+           }
+           else if (m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE )
+           {
+               ::RGBForeColor( &m_textForegroundColour.GetPixel() );
+               ::RGBForeColor( &m_textBackgroundColour.GetPixel() );
+                   ::PenPat(GetQDGlobalsBlack(&blackColor));
+           }
+       }
+    else
+    {
+           ::PenPat(GetQDGlobalsBlack(&blackColor));
        }
 
        
        // 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