X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6de4336e3839d19f835a5e689c56659f9bdd15e9..293656292f058603a996b136eee9c7fefc6d3350:/src/gtk/dcclient.cpp?ds=inline diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index c7b1ce56c6..f9a123a20f 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -71,27 +71,42 @@ static GdkPixmap* GetHatch(int style) const int i = style - wxBRUSHSTYLE_FIRST_HATCH; if (hatches[i] == NULL) { + // This macro creates a bitmap from an XBM file included above. Notice + // the need for the cast because gdk_bitmap_create_from_data() doesn't + // accept unsigned data but the arrays in XBM need to be unsigned to + // avoid warnings (and even errors in C+0x mode) from g++. +#define CREATE_FROM_XBM_DATA(name) \ + gdk_bitmap_create_from_data \ + ( \ + NULL, \ + reinterpret_cast(name ## _bits), \ + name ## _width, \ + name ## _height \ + ) + switch (style) { case wxBRUSHSTYLE_BDIAGONAL_HATCH: - hatches[i] = gdk_bitmap_create_from_data(NULL, bdiag_bits, bdiag_width, bdiag_height); + hatches[i] = CREATE_FROM_XBM_DATA(bdiag); break; case wxBRUSHSTYLE_CROSSDIAG_HATCH: - hatches[i] = gdk_bitmap_create_from_data(NULL, cdiag_bits, cdiag_width, cdiag_height); + hatches[i] = CREATE_FROM_XBM_DATA(cdiag); break; case wxBRUSHSTYLE_CROSS_HATCH: - hatches[i] = gdk_bitmap_create_from_data(NULL, cross_bits, cross_width, cross_height); + hatches[i] = CREATE_FROM_XBM_DATA(cross); break; case wxBRUSHSTYLE_FDIAGONAL_HATCH: - hatches[i] = gdk_bitmap_create_from_data(NULL, fdiag_bits, fdiag_width, fdiag_height); + hatches[i] = CREATE_FROM_XBM_DATA(fdiag); break; case wxBRUSHSTYLE_HORIZONTAL_HATCH: - hatches[i] = gdk_bitmap_create_from_data(NULL, horiz_bits, horiz_width, horiz_height); + hatches[i] = CREATE_FROM_XBM_DATA(horiz); break; case wxBRUSHSTYLE_VERTICAL_HATCH: - hatches[i] = gdk_bitmap_create_from_data(NULL, verti_bits, verti_width, verti_height); + hatches[i] = CREATE_FROM_XBM_DATA(verti); break; } + +#undef CREATE_FROM_XBM_DATA } return hatches[i]; } @@ -216,7 +231,7 @@ static GdkGC* wxGetPoolGC( GdkWindow *window, wxPoolGCType type ) // The realloc failed. Fall through to error. wxFAIL_MSG( wxT("No GC available") ); - return (GdkGC*) NULL; + return NULL; } static void wxFreePoolGC( GdkGC *gc ) @@ -242,16 +257,16 @@ IMPLEMENT_ABSTRACT_CLASS(wxWindowDCImpl, wxGTKDCImpl) wxWindowDCImpl::wxWindowDCImpl( wxDC *owner ) : wxGTKDCImpl( owner ) { - m_gdkwindow = (GdkWindow*) NULL; - m_penGC = (GdkGC *) NULL; - m_brushGC = (GdkGC *) NULL; - m_textGC = (GdkGC *) NULL; - m_bgGC = (GdkGC *) NULL; - m_cmap = (GdkColormap *) NULL; + m_gdkwindow = NULL; + m_penGC = NULL; + m_brushGC = NULL; + m_textGC = NULL; + m_bgGC = NULL; + m_cmap = NULL; m_isScreenDC = false; - m_context = (PangoContext *)NULL; - m_layout = (PangoLayout *)NULL; - m_fontdesc = (PangoFontDescription *)NULL; + m_context = NULL; + m_layout = NULL; + m_fontdesc = NULL; } wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *window ) : @@ -259,35 +274,35 @@ wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *window ) : { wxASSERT_MSG( window, wxT("DC needs a window") ); - m_gdkwindow = (GdkWindow*) NULL; - m_penGC = (GdkGC *) NULL; - m_brushGC = (GdkGC *) NULL; - m_textGC = (GdkGC *) NULL; - m_bgGC = (GdkGC *) NULL; - m_cmap = (GdkColormap *) NULL; + m_gdkwindow = NULL; + m_penGC = NULL; + m_brushGC = NULL; + m_textGC = NULL; + m_bgGC = NULL; + m_cmap = NULL; m_isScreenDC = false; m_font = window->GetFont(); GtkWidget *widget = window->m_wxwindow; + m_gdkwindow = window->GTKGetDrawingWindow(); // Some controls don't have m_wxwindow - like wxStaticBox, but the user - // code should still be able to create wxClientDCs for them, so we will - // use the parent window here then. + // code should still be able to create wxClientDCs for them if ( !widget ) { - window = window->GetParent(); - if (window) - widget = window->m_wxwindow; - } + widget = window->m_widget; - wxASSERT_MSG( widget, wxT("DC needs a widget") ); + wxCHECK_RET(widget, "DC needs a widget"); - m_context = window->GtkGetPangoDefaultContext(); + m_gdkwindow = widget->window; + if (!gtk_widget_get_has_window(widget)) + SetDeviceLocalOrigin(widget->allocation.x, widget->allocation.y); + } + + m_context = window->GTKGetPangoDefaultContext(); m_layout = pango_layout_new( m_context ); m_fontdesc = pango_font_description_copy( widget->style->font_desc ); - m_gdkwindow = widget->window; - // Window not realized ? if (!m_gdkwindow) { @@ -297,7 +312,7 @@ wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *window ) : return; } - m_cmap = gtk_widget_get_colormap( widget ? widget : window->m_widget ); + m_cmap = gtk_widget_get_colormap(widget); SetUpDC(); @@ -411,15 +426,15 @@ void wxWindowDCImpl::SetUpDC( bool isMemDC ) gdk_gc_set_function( m_penGC, GDK_COPY ); /* clipping */ - gdk_gc_set_clip_rectangle( m_penGC, (GdkRectangle *) NULL ); - gdk_gc_set_clip_rectangle( m_brushGC, (GdkRectangle *) NULL ); - gdk_gc_set_clip_rectangle( m_textGC, (GdkRectangle *) NULL ); - gdk_gc_set_clip_rectangle( m_bgGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_penGC, NULL ); + gdk_gc_set_clip_rectangle( m_brushGC, NULL ); + gdk_gc_set_clip_rectangle( m_textGC, NULL ); + gdk_gc_set_clip_rectangle( m_bgGC, NULL ); } void wxWindowDCImpl::DoGetSize( int* width, int* height ) const { - wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") ); + wxCHECK_RET( m_window, wxT("GetSize() doesn't work without window") ); m_window->GetSize(width, height); } @@ -477,7 +492,7 @@ void wxWindowDCImpl::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { if (m_gdkwindow) gdk_draw_line( m_gdkwindow, m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) ); @@ -491,7 +506,7 @@ void wxWindowDCImpl::DoCrossHair( wxCoord x, wxCoord y ) { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { int w = 0; int h = 0; @@ -589,7 +604,7 @@ void wxWindowDCImpl::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, if (m_gdkwindow) { - if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) + if ( m_brush.IsNonTransparent() ) { GdkGC* gc; bool originChanged; @@ -601,11 +616,11 @@ void wxWindowDCImpl::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, gdk_gc_set_ts_origin(gc, 0, 0); } - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { gdk_draw_arc( m_gdkwindow, m_penGC, FALSE, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 ); - if ((m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) && (alpha2 - alpha1 != 360*64)) + if ( m_brush.IsNonTransparent() && (alpha2 - alpha1 != 360*64) ) { gdk_draw_line( m_gdkwindow, m_penGC, xx1, yy1, xxc, yyc ); gdk_draw_line( m_gdkwindow, m_penGC, xxc, yyc, xx2, yy2 ); @@ -635,7 +650,7 @@ void wxWindowDCImpl::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxC wxCoord start = wxCoord(sa * 64.0); wxCoord end = wxCoord((ea-sa) * 64.0); - if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) + if ( m_brush.IsNonTransparent() ) { GdkGC* gc; bool originChanged; @@ -647,7 +662,7 @@ void wxWindowDCImpl::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxC gdk_gc_set_ts_origin(gc, 0, 0); } - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) gdk_draw_arc( m_gdkwindow, m_penGC, FALSE, xx, yy, ww, hh, start, end ); } @@ -659,7 +674,7 @@ void wxWindowDCImpl::DoDrawPoint( wxCoord x, wxCoord y ) { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); - if ((m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) && m_gdkwindow) + if ( m_pen.IsNonTransparent() && m_gdkwindow ) gdk_draw_point( m_gdkwindow, m_penGC, XLOG2DEV(x), YLOG2DEV(y) ); CalcBoundingBox (x, y); @@ -669,9 +684,11 @@ void wxWindowDCImpl::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCo { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); - if (m_pen.GetStyle() == wxPENSTYLE_TRANSPARENT) return; if (n <= 0) return; + if ( m_pen.IsTransparent() ) + return; + //Check, if scaling is necessary const bool doScale = xoffset != 0 || yoffset != 0 || XLOG2DEV(10) != 10 || YLOG2DEV(10) != 10; @@ -730,7 +747,7 @@ void wxWindowDCImpl::DoDrawPolygon( int n, wxPoint points[], if (m_gdkwindow) { - if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) + if ( m_brush.IsNonTransparent() ) { GdkGC* gc; bool originChanged; @@ -742,7 +759,7 @@ void wxWindowDCImpl::DoDrawPolygon( int n, wxPoint points[], gdk_gc_set_ts_origin(gc, 0, 0); } - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { /* for (i = 0 ; i < n ; i++) @@ -781,7 +798,7 @@ void wxWindowDCImpl::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoo if (m_gdkwindow) { - if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) + if ( m_brush.IsNonTransparent() ) { GdkGC* gc; bool originChanged; @@ -793,9 +810,8 @@ void wxWindowDCImpl::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoo gdk_gc_set_ts_origin(gc, 0, 0); } - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { -#if 1 if ((m_pen.GetWidth() == 2) && (m_pen.GetCap() == wxCAP_ROUND) && (m_pen.GetJoin() == wxJOIN_ROUND) && (m_pen.GetStyle() == wxPENSTYLE_SOLID)) { @@ -818,7 +834,6 @@ void wxWindowDCImpl::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoo gdk_gc_set_line_attributes( m_penGC, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND ); } else -#endif { // Just use X11 for other cases gdk_draw_rectangle( m_gdkwindow, m_penGC, FALSE, xx, yy, ww-1, hh-1 ); @@ -859,7 +874,7 @@ void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width // CMB: adjust size if outline is drawn otherwise the result is // 1 pixel too wide and high - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { ww--; hh--; @@ -874,7 +889,7 @@ void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width if (dd > hh) dd = hh; rr = dd / 2; - if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) + if ( m_brush.IsNonTransparent() ) { GdkGC* gc; bool originChanged; @@ -891,7 +906,7 @@ void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width gdk_gc_set_ts_origin(gc, 0, 0); } - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { gdk_draw_line( m_gdkwindow, m_penGC, xx+rr+1, yy, xx+ww-rr, yy ); gdk_draw_line( m_gdkwindow, m_penGC, xx+rr+1, yy+hh, xx+ww-rr, yy+hh ); @@ -924,7 +939,7 @@ void wxWindowDCImpl::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord if (m_gdkwindow) { - if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) + if ( m_brush.IsNonTransparent() ) { GdkGC* gc; bool originChanged; @@ -932,7 +947,7 @@ void wxWindowDCImpl::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord // If the pen is transparent pen we increase the size // for better compatibility with other platforms. - if (m_pen.GetStyle() == wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { ++ww; ++hh; @@ -944,7 +959,7 @@ void wxWindowDCImpl::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord gdk_gc_set_ts_origin(gc, 0, 0); } - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) gdk_draw_arc( m_gdkwindow, m_penGC, false, xx, yy, ww, hh, 0, 360*64 ); } @@ -1059,8 +1074,11 @@ void wxWindowDCImpl::DoDrawBitmap( const wxBitmap &bitmap, const int w = bitmap.GetWidth(); const int h = bitmap.GetHeight(); + // notice that as the bitmap is not drawn upside down (or right to left) + // even if the corresponding axis direction is inversed, we need to take it + // into account when calculating its bounding box CalcBoundingBox(x, y); - CalcBoundingBox(x + w, y + h); + CalcBoundingBox(x + m_signX*w, y + m_signY*h); // device coords int xx = LogicalToDeviceX(x); @@ -1335,7 +1353,9 @@ bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest, return true; } -void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) +void wxWindowDCImpl::DoDrawText(const wxString& text, + wxCoord xLogical, + wxCoord yLogical) { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); @@ -1343,8 +1363,8 @@ void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) if (text.empty()) return; - x = XLOG2DEV(x); - y = YLOG2DEV(y); + wxCoord x = XLOG2DEV(xLogical), + y = YLOG2DEV(yLogical); wxCHECK_RET( m_context, wxT("no Pango context") ); wxCHECK_RET( m_layout, wxT("no Pango layout") ); @@ -1459,8 +1479,8 @@ void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) pango_layout_set_attributes(m_layout, NULL); } - CalcBoundingBox(x + int(w / m_scaleX), y + int(h / m_scaleY)); - CalcBoundingBox(x, y); + CalcBoundingBox(xLogical + int(w / m_scaleX), yLogical + int(h / m_scaleY)); + CalcBoundingBox(xLogical, yLogical); } // TODO: When GTK2.6 is required, merge DoDrawText and DoDrawRotatedText to @@ -1472,7 +1492,7 @@ void wxWindowDCImpl::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord wxCHECK_RET( IsOk(), wxT("invalid window dc") ); -#if __WXGTK26__ +#ifdef __WXGTK26__ if (!gtk_check_version(2,6,0)) { x = XLOG2DEV(x); @@ -1778,10 +1798,10 @@ wxCoord wxWindowDCImpl::GetCharWidth() const wxCoord wxWindowDCImpl::GetCharHeight() const { PangoFontMetrics *metrics = pango_context_get_metrics (m_context, m_fontdesc, pango_context_get_language(m_context)); - wxCHECK_MSG( metrics, -1, _T("failed to get pango font metrics") ); + wxCHECK_MSG( metrics, -1, wxT("failed to get pango font metrics") ); wxCoord h = PANGO_PIXELS (pango_font_metrics_get_descent (metrics) + - pango_font_metrics_get_ascent (metrics)); + pango_font_metrics_get_ascent (metrics)); pango_font_metrics_unref (metrics); return h; } @@ -1813,7 +1833,7 @@ void wxWindowDCImpl::SetFont( const wxFont &font ) { PangoContext *oldContext = m_context; - m_context = m_window->GtkGetPangoDefaultContext(); + m_context = m_window->GTKGetPangoDefaultContext(); // If we switch back/forth between different contexts // we also have to create a new layout. I think so, @@ -1905,7 +1925,7 @@ void wxWindowDCImpl::SetPen( const wxPen &pen ) case wxPENSTYLE_SOLID: default: lineStyle = GDK_LINE_SOLID; - req_dash = (wxGTKDash*)NULL; + req_dash = NULL; req_nb_dash = 0; break; } @@ -2081,6 +2101,9 @@ void wxWindowDCImpl::SetLogicalFunction( wxRasterOperationMode function ) case wxNO_OP: mode = GDK_NOOP; break; case wxSRC_INVERT: mode = GDK_COPY_INVERT; break; case wxNOR: mode = GDK_NOR; break; + default: + wxFAIL_MSG("unknown mode"); + return; } m_logicalFunction = function; @@ -2224,13 +2247,13 @@ void wxWindowDCImpl::DestroyClippingRegion() void wxWindowDCImpl::Destroy() { if (m_penGC) wxFreePoolGC( m_penGC ); - m_penGC = (GdkGC*) NULL; + m_penGC = NULL; if (m_brushGC) wxFreePoolGC( m_brushGC ); - m_brushGC = (GdkGC*) NULL; + m_brushGC = NULL; if (m_textGC) wxFreePoolGC( m_textGC ); - m_textGC = (GdkGC*) NULL; + m_textGC = NULL; if (m_bgGC) wxFreePoolGC( m_bgGC ); - m_bgGC = (GdkGC*) NULL; + m_bgGC = NULL; } void wxWindowDCImpl::SetDeviceOrigin( wxCoord x, wxCoord y ) @@ -2296,7 +2319,7 @@ wxClientDCImpl::wxClientDCImpl( wxDC *owner ) wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *win ) : wxWindowDCImpl( owner, win ) { - wxCHECK_RET( win, _T("NULL window in wxClientDCImpl::wxClientDC") ); + wxCHECK_RET( win, wxT("NULL window in wxClientDCImpl::wxClientDC") ); #ifdef __WXUNIVERSAL__ wxPoint ptOrigin = win->GetClientAreaOrigin(); @@ -2309,7 +2332,7 @@ wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *win ) void wxClientDCImpl::DoGetSize(int *width, int *height) const { - wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") ); + wxCHECK_RET( m_window, wxT("GetSize() doesn't work without window") ); m_window->GetClientSize( width, height ); }