]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/dc.cpp
wxFont can now raelly use the native fonts
[wxWidgets.git] / src / mac / dc.cpp
index 356e35848c47be9a6b91ddde865b963d815f6b8a..275f5147249ff5ceb6a918c28682fb6ff8beb04c 100644 (file)
@@ -38,7 +38,9 @@ IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
 #define twips2mm               0.0176388888889
 #define mm2pt                  2.83464566929
 #define pt2mm                  0.352777777778
+#ifndef __DARWIN__
 const double M_PI = 3.14159265358979 ;
+#endif
 const double RAD2DEG  = 180.0 / M_PI;
 
 //-----------------------------------------------------------------------------
@@ -88,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;
@@ -111,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 ;
@@ -237,7 +231,7 @@ 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 )
 {
@@ -249,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 );
@@ -277,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
@@ -525,13 +561,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 = XLOG2DEV(x1) - offset;
+        wxCoord yy1 = YLOG2DEV(y1) - offset;
+        wxCoord xx2 = XLOG2DEV(x2) - offset;
+        wxCoord yy2 = YLOG2DEV(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);
   }
 }
 
@@ -726,35 +783,59 @@ void  wxDC::DoDrawPolygon(int n, wxPoint points[],
                                wxCoord xoffset, wxCoord yoffset,
                                int fillStyle )
 {
-  wxCHECK_RET(Ok(), wxT("Invalid DC"));
-  wxMacPortSetter helper(this) ;
+       wxCHECK_RET(Ok(), wxT("Invalid DC"));
+       wxMacPortSetter helper(this) ;
+       
+       wxCoord x1, x2 , y1 , y2 ;
   
-  PolyHandle polygon = OpenPoly() ;
-  wxCoord x1, x2 , y1 , y2 ;
-  x1 = XLOG2DEV(points[0].x + xoffset);
-  y1 = YLOG2DEV(points[0].y + yoffset);   
-  ::MoveTo(x1,y1);
+       if (m_brush.GetStyle() != wxTRANSPARENT)
+       {
+               PolyHandle polygon = OpenPoly();
+               
+               x1 = XLOG2DEV(points[0].x + xoffset);
+               y1 = YLOG2DEV(points[0].y + yoffset);   
+               ::MoveTo(x1,y1);
   
-  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);
-  }
+               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);
+               }
 
-  ClosePoly() ;
-       if (m_brush.GetStyle() != wxTRANSPARENT) 
-       {
-               MacInstallBrush() ;
-               ::PaintPoly( polygon ) ;
+               ClosePoly();
+
+               MacInstallBrush();
+               ::PaintPoly( polygon );
+               
+               KillPoly( polygon );
        }
        
        if (m_pen.GetStyle() != wxTRANSPARENT) 
        {
+               PolyHandle polygon = OpenPoly();
+               
+               x1 = XLOG2DEV(points[0].x + xoffset);
+               y1 = YLOG2DEV(points[0].y + yoffset);   
+               ::MoveTo(x1,y1);
+  
+               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);
+               }
+               
+               // return to origin to close path
+               ::LineTo(x1,y1);
+
+               ClosePoly();
+       
                MacInstallPen() ;
                ::FramePoly( polygon ) ;
+               
+               KillPoly( polygon );
        }
-  KillPoly( polygon ) ;
 }
 
 void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
@@ -897,12 +978,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} ;
@@ -1229,10 +1317,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