]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
iconv() really never set the trailing 0.
[wxWidgets.git] / src / gtk / window.cpp
index 2786d91934b6c0e1617a3cebae9f9049bcbce267..ad3161a7d5e8228c3b9967f0cf14cf768a6771ec 100644 (file)
 #include "wx/intl.h"
 #include "wx/settings.h"
 #include "wx/log.h"
+#include "wx/fontutil.h"
 
 #ifdef __WXDEBUG__
     #include "wx/thread.h"
 #endif
 
 #include <math.h>
+#include <ctype.h>
 
 #include "wx/gtk/private.h"
 #include <gdk/gdkprivate.h>
@@ -508,6 +510,22 @@ static int gtk_window_expose_callback( GtkWidget *widget,
     }
 #endif
 
+#ifdef __WXGTK20__
+    // This callback gets called in drawing-idle time under
+    // GTK 2.0, so we don't need to defer anything to idle
+    // time anymore.
+    
+    win->GetUpdateRegion() = wxRegion( gdk_event->region );
+
+    win->GtkSendPaintEvents();
+
+    // Draw window less widgets
+    (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event);
+#else
+    // This gets called immediately after an expose event
+    // under GTK 1.2 so we collect the calls and wait for
+    // the idle handler to pick things up.
+    
     win->GetUpdateRegion().Union( gdk_event->area.x,
                                   gdk_event->area.y,
                                   gdk_event->area.width,
@@ -519,13 +537,9 @@ static int gtk_window_expose_callback( GtkWidget *widget,
 
     // Actual redrawing takes place in idle time.
     // win->GtkUpdate();
-
-#ifdef __WXGTK20__
-
-    (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event);
-
 #endif
 
+
     return TRUE;
 }
 
@@ -3137,12 +3151,61 @@ void wxWindowGTK::GetTextExtent( const wxString& string,
     if (theFont) fontToUse = *theFont;
 
     wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") );
+    
+    if (string.IsEmpty())
+    {
+        if (x) (*x) = 0;
+        if (y) (*y) = 0;
+        return;
+    }
+#ifdef __WXGTK20__
 
+    PangoContext *context = NULL;
+    if (m_widget)
+        gtk_widget_get_pango_context( m_widget );
+        
+    if (!context)
+    {
+        if (x) (*x) = 0;
+        if (y) (*y) = 0;
+        return;
+    }
+    
+    PangoFontDescription *desc = fontToUse.GetNativeFontInfo()->description;
+    PangoLayout *layout = pango_layout_new(context);
+    pango_layout_set_font_description(layout, desc);
+    {
+#if wxUSE_UNICODE
+        const wxCharBuffer data = wxConvUTF8.cWC2MB( string );
+        pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data ));
+#else
+        const wxWCharBuffer wdata = wxConvLocal.cMB2WC( string );
+        const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata );
+        pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data ));
+#endif
+    }
+    PangoLayoutLine *line = (PangoLayoutLine *)pango_layout_get_lines(layout)->data;
+    PangoRectangle rect;
+    pango_layout_line_get_extents(line, NULL, &rect);
+       
+    if (x) (*x) = (wxCoord) (rect.width / PANGO_SCALE);
+    if (y) (*y) = (wxCoord) (rect.height / PANGO_SCALE);
+    if (descent)
+    {
+        // Do something about metrics here
+        (*descent) = 0;
+    }
+    if (externalLeading) (*externalLeading) = 0;  // ??
+    
+    g_object_unref( G_OBJECT( layout ) );
+#else
     GdkFont *font = fontToUse.GetInternalFont( 1.0 );
-    if (x) (*x) = gdk_string_width( font, string.mbc_str() );
+    if (x) (*x) = gdk_string_width( font, wxGTK_CONV( string ) );
     if (y) (*y) = font->ascent + font->descent;
     if (descent) (*descent) = font->descent;
     if (externalLeading) (*externalLeading) = 0;  // ??
+#endif
 }
 
 void wxWindowGTK::SetFocus()
@@ -3391,27 +3454,31 @@ void wxWindowGTK::GtkUpdate()
 #ifdef __WXGTK20__
     if (m_wxwindow && GTK_PIZZA(m_wxwindow)->bin_window)
         gdk_window_process_updates( GTK_PIZZA(m_wxwindow)->bin_window, FALSE );
-#endif
-
+#else
     if (!m_updateRegion.IsEmpty())
         GtkSendPaintEvents();
+#endif
 }
 
 void wxWindowGTK::GtkSendPaintEvents()
 {
     if (!m_wxwindow)
     {
+#ifndef __WXGTK20__    
         m_clearRegion.Clear();
+#endif
         m_updateRegion.Clear();
         return;
     }
 
+    // Clip to paint region in wxClientDC
+    m_clipPaintRegion = TRUE;
+
+#ifndef __WXGTK20__
     // widget to draw on
     GtkPizza *pizza = GTK_PIZZA (m_wxwindow);
             
-    // Clip to paint region in wxClientDC
-    m_clipPaintRegion = TRUE;
-    
+    // later for GTK 2.0, too.
     if (GetThemeEnabled())
     {
         // find ancestor from which to steal background
@@ -3443,7 +3510,20 @@ void wxWindowGTK::GtkSendPaintEvents()
         }
     }
     else
-    // if (!m_clearRegion.IsEmpty())   // always send an erase event
+#endif
+
+#ifdef __WXGTK20__
+    {
+        wxWindowDC dc( (wxWindow*)this );
+        dc.SetClippingRegion( m_updateRegion );
+
+        wxEraseEvent erase_event( GetId(), &dc );
+        erase_event.SetEventObject( this );
+
+        GetEventHandler()->ProcessEvent(erase_event);
+    }
+#else
+    // if (!m_clearRegion.IsEmpty())   // Always send an erase event under GTK 1.2
     {
         wxWindowDC dc( (wxWindow*)this );
         if (m_clearRegion.IsEmpty())
@@ -3473,6 +3553,7 @@ void wxWindowGTK::GtkSendPaintEvents()
         }
         m_clearRegion.Clear();
     }
+#endif
 
     wxNcPaintEvent nc_paint_event( GetId() );
     nc_paint_event.SetEventObject( this );
@@ -3535,6 +3616,7 @@ void wxWindowGTK::Clear()
 {
     wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
 
+#ifndef __WXGTK20__
     if (m_wxwindow && m_wxwindow->window)
     {
         m_clearRegion.Clear();
@@ -3544,6 +3626,7 @@ void wxWindowGTK::Clear()
         // Better do this in idle?
         GtkUpdate();
     }
+#endif
 }
 
 #if wxUSE_TOOLTIPS