/////////////////////////////////////////////////////////////////////////////
// Name: src/gtk/dcclient.cpp
-// Purpose:
+// Purpose: wxWindowDCImpl implementation
// Author: Robert Roebling
// RCS-ID: $Id$
// Copyright: (c) 1998 Robert Roebling, Chris Breeze
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<gchar *>(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];
}
// The realloc failed. Fall through to error.
wxFAIL_MSG( wxT("No GC available") );
- return (GdkGC*) NULL;
+ return NULL;
}
static void wxFreePoolGC( GdkGC *gc )
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 ) :
{
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();
- 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)
{
return;
}
- m_cmap = gtk_widget_get_colormap( widget ? widget : window->m_widget );
+ m_cmap = gtk_widget_get_colormap(widget);
SetUpDC();
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);
}
{
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) );
{
wxCHECK_RET( IsOk(), wxT("invalid window dc") );
- if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT)
+ if ( m_pen.IsNonTransparent() )
{
int w = 0;
int h = 0;
if (m_gdkwindow)
{
- if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
+ if ( m_brush.IsNonTransparent() )
{
GdkGC* gc;
bool originChanged;
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 );
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;
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 );
}
{
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);
{
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;
if (m_gdkwindow)
{
- if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
+ if ( m_brush.IsNonTransparent() )
{
GdkGC* gc;
bool originChanged;
gdk_gc_set_ts_origin(gc, 0, 0);
}
- if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT)
+ if ( m_pen.IsNonTransparent() )
{
/*
for (i = 0 ; i < n ; i++)
if (m_gdkwindow)
{
- if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
+ if ( m_brush.IsNonTransparent() )
{
GdkGC* gc;
bool originChanged;
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))
{
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 );
// 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--;
if (dd > hh) dd = hh;
rr = dd / 2;
- if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
+ if ( m_brush.IsNonTransparent() )
{
GdkGC* gc;
bool originChanged;
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 );
if (m_gdkwindow)
{
- if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
+ if ( m_brush.IsNonTransparent() )
{
GdkGC* gc;
bool originChanged;
// 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;
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 );
}
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);
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") );
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") );
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
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;
}
{
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,
case wxPENSTYLE_SOLID:
default:
lineStyle = GDK_LINE_SOLID;
- req_dash = (wxGTKDash*)NULL;
+ req_dash = NULL;
req_nb_dash = 0;
break;
}
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;
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 )
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();
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 );
}