X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/24bbbfb112cd755a944a76555b540af67d7f8ab1..125817d0e302ec5f4a3ae0186ac97c477a35455e:/src/gtk/dcclient.cpp diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 285fb6aade..4d69ff1d0f 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -324,7 +324,7 @@ wxWindowDC::wxWindowDC( wxWindow *window ) standard (as e.g. wxStatusBar) */ m_owner = window; - + if (m_owner && m_owner->m_wxwindow && (m_owner->GetLayoutDirection() == wxLayout_RightToLeft)) { // reverse sense @@ -392,6 +392,8 @@ void wxWindowDC::SetUpDC() gdk_gc_set_fill( m_textGC, GDK_SOLID ); + gdk_gc_set_colormap( m_textGC, m_cmap ); + /* m_penGC */ m_pen.GetColour().CalcPixel( m_cmap ); gdk_gc_set_foreground( m_penGC, m_pen.GetColour().GetColor() ); @@ -860,7 +862,7 @@ void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord h gdk_draw_rectangle( m_window, m_penGC, FALSE, xx, yy, ww-2, hh-2 ); gdk_draw_rectangle( m_window, m_penGC, FALSE, xx-1, yy-1, ww, hh ); } - + // reset gdk_gc_set_line_attributes( m_penGC, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND ); } @@ -1081,10 +1083,10 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, int w = bitmap.GetWidth(); int h = bitmap.GetHeight(); - + if (m_owner && m_owner->GetLayoutDirection() == wxLayout_RightToLeft) xx -= w; - + CalcBoundingBox( x, y ); CalcBoundingBox( x + w, y + h ); @@ -1215,8 +1217,8 @@ 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->m_selected.Ok()) return false; + if (memDC && !selected.Ok()) return false; - is_mono = (memDC->m_selected.GetDepth() == 1); + if (selected.Ok()) + { + 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 ); @@ -1572,7 +1579,7 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) gdk_draw_rectangle(m_window, m_textGC, TRUE, x, y, w, h); gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor()); } - + // Draw layout. if (m_owner && m_owner->GetLayoutDirection() == wxLayout_RightToLeft) gdk_draw_layout( m_window, m_textGC, x-w, y, m_layout ); @@ -1764,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 ); @@ -2317,7 +2368,7 @@ void wxWindowDC::SetDeviceOrigin( wxCoord x, wxCoord y ) { m_deviceOriginX = x; m_deviceOriginY = y; - + ComputeScaleAndOrigin(); } @@ -2325,10 +2376,10 @@ void wxWindowDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp ) { m_signX = (xLeftRight ? 1 : -1); m_signY = (yBottomUp ? -1 : 1); - + if (m_owner && m_owner->m_wxwindow && (m_owner->GetLayoutDirection() == wxLayout_RightToLeft)) - m_signX = -m_signX; - + m_signX = -m_signX; + ComputeScaleAndOrigin(); }