]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/dcclient.cpp
fixed deadlock when calling wxPostEvent() from worker thread
[wxWidgets.git] / src / gtk / dcclient.cpp
index 56073aa547dbdfe76c8e775f849304bb4df2ae5c..c79e4175d6f8ec223d5d8fb1c10d287086e1c2c0 100644 (file)
@@ -391,6 +391,8 @@ void wxWindowDC::SetUpDC()
     gdk_gc_set_background( m_textGC, m_textBackgroundColour.GetColor() );
 
     gdk_gc_set_fill( m_textGC, GDK_SOLID );
+    
+    gdk_gc_set_colormap( m_textGC, m_cmap );
 
     /* m_penGC */
     m_pen.GetColour().CalcPixel( m_cmap );
@@ -1215,9 +1217,9 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
     xsrc = source->LogicalToDeviceX(xsrc);
     ysrc = source->LogicalToDeviceY(ysrc);
 
-    wxClientDC *srcDC = (wxClientDC*)source;
-    wxMemoryDC *memDC = (wxMemoryDC*)source;
-
+    wxMemoryDC *memDC = wxDynamicCast(source, wxMemoryDC);
+    wxBitmap selected = source->GetSelectedBitmap();
+    
     bool use_bitmap_method = false;
     bool is_mono = false;
 
@@ -1227,11 +1229,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
         ysrcMask = ysrc;
     }
 
-    if (srcDC->m_isMemDC)
+    if (memDC && !selected.Ok()) return false;
+    
+    if (selected.Ok())
     {
-        if (!memDC->m_selected.Ok()) return false;
-
-        is_mono = (memDC->m_selected.GetDepth() == 1);
+        is_mono = (selected.GetDepth() == 1);
 
         // we use the "XCopyArea" way to copy a memory dc into
         // a different window if the memory dc BOTH
@@ -1239,7 +1241,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
         // b) it is clipped
         // c) is not 1-bit
 
-        if (useMask && (memDC->m_selected.GetMask()))
+        if (useMask && (selected.GetMask()))
         {
             // we HAVE TO use the direct way for memory dcs
             // that have mask since the XCopyArea doesn't know
@@ -1254,8 +1256,8 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
             use_bitmap_method = true;
         }
         else if ((xsrc == 0) && (ysrc == 0) &&
-                 (width == memDC->m_selected.GetWidth()) &&
-                 (height == memDC->m_selected.GetHeight()))
+                 (width == selected.GetWidth()) &&
+                 (height == selected.GetHeight()))
         {
             // we SHOULD use the direct way if all of the bitmap
             // in the memory dc is copied in which case XCopyArea
@@ -1290,8 +1292,8 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
     if (use_bitmap_method)
     {
         // scale/translate bitmap size
-        wxCoord bm_width = memDC->m_selected.GetWidth();
-        wxCoord bm_height = memDC->m_selected.GetHeight();
+        wxCoord bm_width = selected.GetWidth();
+        wxCoord bm_height = selected.GetHeight();
 
         // Get clip coords for the bitmap. If we don't
         // use wxBitmap::Rescale(), which can clip the
@@ -1312,18 +1314,19 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
         wxCoord bm_hh = YLOG2DEVREL( bm_height );
 
         // Scale bitmap if required
-        wxBitmap use_bitmap = memDC->m_selected;
-        if ((memDC->m_selected.GetWidth()!= bm_ww) || ( memDC->m_selected.GetHeight()!= bm_hh))
+        wxBitmap use_bitmap = selected;
+        if ((selected.GetWidth()!= bm_ww) || ( selected.GetHeight()!= bm_hh))
         {
             // This indicates that the blitting code below will get
             // a clipped bitmap and therefore needs to move the origin
             // accordingly
             wxRegion tmp( xx,yy,ww,hh );
-            tmp.Intersect( m_currentClippingRegion );
+            if (!m_currentClippingRegion.IsNull())
+                tmp.Intersect( m_currentClippingRegion );
             tmp.GetBox(cx,cy,cw,ch);
 
             // Scale and clipped bitmap
-            use_bitmap = memDC->m_selected.Rescale(cx-xx,cy-yy,cw,ch,bm_ww,bm_hh);
+            use_bitmap = selected.Rescale(cx-xx,cy-yy,cw,ch,bm_ww,bm_hh);
         }
 
         // apply mask if any
@@ -1403,7 +1406,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
     }
     else // use_bitmap_method
     {
-        if ((width != ww) || (height != hh))
+        if (selected.Ok() && ((width != ww) || (height != hh)))
         {
             // get clip coords
             wxRegion tmp( xx,yy,ww,hh );
@@ -1412,7 +1415,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
             tmp.GetBox(cx,cy,cw,ch);
 
             // rescale bitmap
-            wxBitmap bitmap = memDC->m_selected.Rescale( cx-xx, cy-yy, cw, ch, ww, hh );
+            wxBitmap bitmap = selected.Rescale( cx-xx, cy-yy, cw, ch, ww, hh );
 
             // draw scaled bitmap
             // was: gdk_draw_drawable( m_window, m_penGC, bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 );
@@ -1422,10 +1425,14 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
         {
             // No scaling and not a memory dc with a mask either
 
+            GdkWindow* window = source->GetGDKWindow();
+            if ( !window )
+                return false;
+            
             // copy including child window contents
             gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS );
             gdk_draw_drawable( m_window, m_penGC,
-                               srcDC->GetWindow(),
+                               window,
                                xsrc, ysrc, xx, yy,
                                width, height );
             gdk_gc_set_subwindow( m_penGC, GDK_CLIP_BY_CHILDREN );
@@ -1452,6 +1459,8 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
     wxCHECK_RET( m_layout, wxT("no Pango layout") );
     wxCHECK_RET( m_fontdesc, wxT("no Pango font description") );
 
+    gdk_pango_context_set_colormap( m_context, m_cmap );
+
     bool underlined = m_font.Ok() && m_font.GetUnderlined();
 
     const wxCharBuffer data = wxGTK_CONV( text );
@@ -1762,10 +1771,54 @@ void wxWindowDC::DoGetTextExtent(const wxString &string,
     }
 
     // Reset old font description
-    if (theFont)
+    if (theFont->IsOk())
         pango_layout_set_font_description( m_layout, m_fontdesc );
 }
 
+
+bool wxWindowDC::DoGetPartialTextExtents(const wxString& text,
+                                         wxArrayInt& widths) const
+{
+    const size_t len = text.length();
+    widths.Empty();
+    widths.Add(0, len);
+
+    if (text.empty())
+        return true;
+
+    // Set layout's text
+    const wxCharBuffer dataUTF8 = wxGTK_CONV_FONT(text, m_font);
+    if ( !dataUTF8 )
+    {
+        // hardly ideal, but what else can we do if conversion failed?
+        wxLogLastError(wxT("DoGetPartialTextExtents"));
+        return false;
+    }
+
+    pango_layout_set_text( m_layout, dataUTF8, strlen(dataUTF8) );
+    
+    // Calculate the position of each character based on the widths of
+    // the previous characters
+
+    // Code borrowed from Scintilla's PlatGTK
+    PangoLayoutIter *iter = pango_layout_get_iter(m_layout);
+    PangoRectangle pos;
+    pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
+    size_t i = 0;
+    while (pango_layout_iter_next_cluster(iter))
+    {
+        pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
+        int position = PANGO_PIXELS(pos.x);
+        widths[i++] = position;
+    }
+    while (i < len)
+        widths[i++] = PANGO_PIXELS(pos.x + pos.width);
+    pango_layout_iter_free(iter);
+
+    return true;
+}
+
+
 wxCoord wxWindowDC::GetCharWidth() const
 {
     pango_layout_set_text( m_layout, "H", 1 );