]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/dcclient.cpp
fixed the menu bug introduced by the previous commit
[wxWidgets.git] / src / gtk1 / dcclient.cpp
index 00ff2ed06c18dd5aa7462aea0422877b447e4521..d7eee8e5dec280213ee27222a1eb2e04ae5ffc8c 100644 (file)
@@ -77,15 +77,15 @@ static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
 
 #include "gdk/gdkprivate.h"
 
-void gdk_wx_draw_bitmap     (GdkDrawable  *drawable,
-                          GdkGC               *gc,
-                          GdkDrawable  *src,
-                          gint                xsrc,
-                          gint                ysrc,
-                          gint                xdest,
-                          gint                ydest,
-                          gint                width,
-                          gint                height)
+void gdk_wx_draw_bitmap(GdkDrawable  *drawable,
+                        GdkGC        *gc,
+                        GdkDrawable  *src,
+                        gint         xsrc,
+                        gint         ysrc,
+                        gint         xdest,
+                        gint         ydest,
+                        gint         width,
+                        gint         height)
 {
     gint src_width, src_height;
 #ifndef __WXGTK20__
@@ -246,6 +246,8 @@ wxWindowDC::wxWindowDC()
 
 wxWindowDC::wxWindowDC( wxWindow *window )
 {
+    wxASSERT_MSG( window, wxT("DC needs a window") );
+
     m_penGC = (GdkGC *) NULL;
     m_brushGC = (GdkGC *) NULL;
     m_textGC = (GdkGC *) NULL;
@@ -256,8 +258,6 @@ wxWindowDC::wxWindowDC( wxWindow *window )
     m_isScreenDC = FALSE;
     m_font = window->GetFont();
 
-    wxASSERT_MSG( window, wxT("DC needs a window") );
-
     GtkWidget *widget = window->m_wxwindow;
 
     // some controls don't have m_wxwindow - like wxStaticBox, but the user
@@ -416,7 +416,7 @@ bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const
     memdc.Blit(0, 0, 1, 1, (wxDC*) this, x1, y1);
     memdc.SelectObject(wxNullBitmap);
 
-    wxImage image(bitmap);
+    wxImage image = bitmap.ConvertToImage();
     col->Set(image.GetRed(0, 0), image.GetGreen(0, 0), image.GetBlue(0, 0));
     return TRUE;
 }
@@ -999,12 +999,12 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
     wxBitmap use_bitmap;
     if ((w != ww) || (h != hh))
     {
-        wxImage image( bitmap );
+        wxImage image = bitmap.ConvertToImage();
         image.Rescale( ww, hh );
         if (is_mono)
-            use_bitmap = image.ConvertToMonoBitmap(255,255,255);
+            use_bitmap = wxBitmap(image.ConvertToMono(255,255,255), 1);
         else
-            use_bitmap = image.ConvertToBitmap();
+            use_bitmap = wxBitmap(image);
     }
     else
     {
@@ -1085,9 +1085,13 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
     }
 }
 
-bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
-                         wxDC *source, wxCoord xsrc, wxCoord ysrc,
-                         int logical_func, bool useMask )
+bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
+                         wxCoord width, wxCoord height,
+                         wxDC *source,
+                         wxCoord xsrc, wxCoord ysrc,
+                         int logical_func,
+                         bool useMask,
+                         wxCoord xsrcMask, wxCoord ysrcMask )
 {
    /* this is the nth try to get this utterly useless function to
       work. it now completely ignores the scaling or translation
@@ -1100,12 +1104,24 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
 
     if (!m_window) return FALSE;
 
+#if 1
+    // transform the source DC coords to the device ones
+    xsrc = source->XLOG2DEV(xsrc);
+    ysrc = source->YLOG2DEV(ysrc);
+#endif
+
     wxClientDC *srcDC = (wxClientDC*)source;
     wxMemoryDC *memDC = (wxMemoryDC*)source;
 
     bool use_bitmap_method = FALSE;
     bool is_mono = FALSE;
 
+    /* TODO: use the mask origin when drawing transparently */
+    if (xsrcMask == -1 && ysrcMask == -1)
+    {
+        xsrcMask = xsrc; ysrcMask = ysrc;
+    }
+
     if (srcDC->m_isMemDC)
     {
         if (!memDC->m_selected.Ok()) return FALSE;
@@ -1183,13 +1199,13 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
 
         if ((bm_width != bm_ww) || (bm_height != bm_hh))
         {
-            wxImage image( memDC->m_selected );
+            wxImage image = memDC->m_selected.ConvertToImage();
             image = image.Scale( bm_ww, bm_hh );
 
             if (is_mono)
-                use_bitmap = image.ConvertToMonoBitmap(255,255,255);
+                use_bitmap = wxBitmap(image.ConvertToMono(255,255,255), 1);
             else
-                use_bitmap = image.ConvertToBitmap();
+                use_bitmap = wxBitmap(image);
         }
         else
         {
@@ -1297,11 +1313,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
             gdk_gc_set_subwindow( m_penGC, GDK_CLIP_BY_CHILDREN );
 
             /* scale image */
-            wxImage image( bitmap );
+            wxImage image = bitmap.ConvertToImage();
             image = image.Scale( ww, hh );
 
             /* convert to bitmap */
-            bitmap = image.ConvertToBitmap();
+            bitmap = wxBitmap(image);
 
             /* draw scaled bitmap */
             gdk_draw_pixmap( m_window, m_penGC, bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 );
@@ -1342,11 +1358,11 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
     y = YLOG2DEV(y);
 
 #if defined(__WXGTK20__) && wxUSE_WCHAR_T
-    /* FIXME: the layout engine should probably be abstracted at a higher level in wxDC... */
+    // TODO: the layout engine should be abstracted at a higher level!
     PangoLayout *layout = pango_layout_new(m_context);
     pango_layout_set_font_description(layout, m_fontdesc);
     {
-        wxWX2MBbuf data = text.mb_str(wxConvUTF8);
+        const wxWX2MBbuf data = text.mb_str(wxConvUTF8);
         pango_layout_set_text(layout, data, strlen(data));
     }
     PangoLayoutLine *line = (PangoLayoutLine *)pango_layout_get_lines(layout)->data;
@@ -1355,18 +1371,18 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
     wxCoord width = rect.width;
     wxCoord height = rect.height;
     gdk_draw_layout( m_window, m_textGC, x, y, layout );
-#else
+#else // GTK+ 1.x
     wxCoord width = gdk_string_width( font, text.mbc_str() );
     wxCoord height = font->ascent + font->descent;
-    /* CMB 21/5/98: draw text background if mode is wxSOLID */
-    if (m_backgroundMode == wxSOLID)
+
+    if ( m_backgroundMode == wxSOLID )
     {
         gdk_gc_set_foreground( m_textGC, m_textBackgroundColour.GetColor() );
         gdk_draw_rectangle( m_window, m_textGC, TRUE, x, y, width, height );
         gdk_gc_set_foreground( m_textGC, m_textForegroundColour.GetColor() );
     }
     gdk_draw_string( m_window, font, m_textGC, x, y + font->ascent, text.mbc_str() );
-#endif
+#endif // GTK+ 2.0/1.x
 
     /* CMB 17/7/98: simple underline: ignores scaling and underlying
        X font's XA_UNDERLINE_POSITION and XA_UNDERLINE_THICKNESS
@@ -1417,7 +1433,6 @@ void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y,
     dc.SetBrush(*wxBLACK_BRUSH);
     dc.Clear();
     dc.DrawText(text, 0, 0);
-    dc.SetFont(wxNullFont);
     dc.SelectObject(wxNullBitmap);
 
     // Calculate the size of the rotated bounding box.
@@ -1441,7 +1456,7 @@ void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y,
             minY = (wxCoord)(dmin(y2, dmin(y3, y4)) - 0.5);
 
     // prepare to blit-with-rotate the bitmap to the DC
-    wxImage image(src);
+    wxImage image = src.ConvertToImage();
 
     GdkColor *colText = m_textForegroundColour.GetColor(),
              *colBack = m_textBackgroundColour.GetColor();
@@ -1564,6 +1579,8 @@ void wxWindowDC::Clear()
 
 void wxWindowDC::SetFont( const wxFont &font )
 {
+    wxCHECK_RET( font.Ok(), _T("invalid font in wxWindowDC::SetFont") );
+
     m_font = font;
 #ifdef __WXGTK20__
     // fix fontdesc?
@@ -1862,30 +1879,36 @@ void wxWindowDC::SetTextForeground( const wxColour &col )
 {
     wxCHECK_RET( Ok(), wxT("invalid window dc") );
 
-    if (m_textForegroundColour == col) return;
+    // don't set m_textForegroundColour to an invalid colour as we'd crash
+    // later then (we use m_textForegroundColour.GetColor() without checking
+    // in a few places)
+    if ( !col.Ok() || (m_textForegroundColour == col) )
+        return;
 
     m_textForegroundColour = col;
-    if (!m_textForegroundColour.Ok()) return;
-
-    if (!m_window) return;
 
-    m_textForegroundColour.CalcPixel( m_cmap );
-    gdk_gc_set_foreground( m_textGC, m_textForegroundColour.GetColor() );
+    if ( m_window )
+    {
+        m_textForegroundColour.CalcPixel( m_cmap );
+        gdk_gc_set_foreground( m_textGC, m_textForegroundColour.GetColor() );
+    }
 }
 
 void wxWindowDC::SetTextBackground( const wxColour &col )
 {
     wxCHECK_RET( Ok(), wxT("invalid window dc") );
 
-    if (m_textBackgroundColour == col) return;
+    // same as above
+    if ( !col.Ok() || (m_textBackgroundColour == col) )
+        return;
 
     m_textBackgroundColour = col;
-    if (!m_textBackgroundColour.Ok()) return;
-
-    if (!m_window) return;
 
-    m_textBackgroundColour.CalcPixel( m_cmap );
-    gdk_gc_set_background( m_textGC, m_textBackgroundColour.GetColor() );
+    if ( m_window )
+    {
+        m_textBackgroundColour.CalcPixel( m_cmap );
+        gdk_gc_set_background( m_textGC, m_textBackgroundColour.GetColor() );
+    }
 }
 
 void wxWindowDC::SetBackgroundMode( int mode )
@@ -2069,14 +2092,19 @@ wxPaintDC::wxPaintDC( wxWindow *win )
     GdkRegion *region = m_paintClippingRegion.GetRegion();
     if ( region )
     {
-        m_currentClippingRegion.Union( m_paintClippingRegion );
+        m_paintClippingRegion = win->GetUpdateRegion();
+        GdkRegion *region = m_paintClippingRegion.GetRegion();
+        if ( region )
+        {
+            m_currentClippingRegion.Union( m_paintClippingRegion );
 
-        gdk_gc_set_clip_region( m_penGC, region );
-        gdk_gc_set_clip_region( m_brushGC, region );
-        gdk_gc_set_clip_region( m_textGC, region );
-        gdk_gc_set_clip_region( m_bgGC, region );
+            gdk_gc_set_clip_region( m_penGC, region );
+            gdk_gc_set_clip_region( m_brushGC, region );
+            gdk_gc_set_clip_region( m_textGC, region );
+            gdk_gc_set_clip_region( m_bgGC, region );
+        }
     }
-#endif
+#endif // USE_PAINT_REGION
 }
 
 //-----------------------------------------------------------------------------
@@ -2088,6 +2116,14 @@ IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC)
 wxClientDC::wxClientDC( wxWindow *win )
           : wxWindowDC( win )
 {
+    wxCHECK_RET( win, _T("NULL window in wxClientDC::wxClientDC") );
+
+#ifdef __WXUNIVERSAL__
+    wxPoint ptOrigin = win->GetClientAreaOrigin();
+    SetDeviceOrigin(ptOrigin.x, ptOrigin.y);
+    wxSize size = win->GetClientSize();
+    SetClippingRegion(wxPoint(0, 0), size);
+#endif // __WXUNIVERSAL__
 }
 
 void wxClientDC::DoGetSize(int *width, int *height) const