]>
git.saurik.com Git - wxWidgets.git/blob - src/gtk/dcclient.cpp
06455771d912edd459b4201d35bcd9058575bc48
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        gtk/dcclient.cpp 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling, Chris Breeze 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  11 #pragma implementation "dcclient.h" 
  14 // For compilers that support precompilation, includes "wx.h". 
  15 #include "wx/wxprec.h" 
  18 #define XCopyPlane XCOPYPLANE 
  21 #include "wx/dcclient.h" 
  22 #include "wx/dcmemory.h" 
  24 #include "wx/module.h" 
  26 #include "wx/fontutil.h" 
  28 #include "wx/gtk/win_gtk.h" 
  30 #include <math.h>               // for floating-point functions 
  34 #include <gdk/gdkprivate.h> 
  37 //----------------------------------------------------------------------------- 
  39 //----------------------------------------------------------------------------- 
  41 #define USE_PAINT_REGION 1 
  43 //----------------------------------------------------------------------------- 
  45 //----------------------------------------------------------------------------- 
  55 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH) 
  56 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH) 
  59 static GdkPixmap  
*hatches
[num_hatches
]; 
  60 static GdkPixmap 
**hatch_bitmap 
= (GdkPixmap 
**) NULL
; 
  62 extern GtkWidget 
*wxGetRootWindow(); 
  64 //----------------------------------------------------------------------------- 
  66 //----------------------------------------------------------------------------- 
  68 const double RAD2DEG  
= 180.0 / M_PI
; 
  70 // ---------------------------------------------------------------------------- 
  72 // ---------------------------------------------------------------------------- 
  74 static inline double dmax(double a
, double b
) { return a 
> b 
? a 
: b
; } 
  75 static inline double dmin(double a
, double b
) { return a 
< b 
? a 
: b
; } 
  77 static inline double DegToRad(double deg
) { return (deg 
* M_PI
) / 180.0; } 
  79 //----------------------------------------------------------------------------- 
  80 // temporary implementation of the missing GDK function 
  81 //----------------------------------------------------------------------------- 
  83 #include "gdk/gdkprivate.h" 
  85 void gdk_wx_draw_bitmap(GdkDrawable  
*drawable
, 
  95     gint src_width
, src_height
; 
  97     GdkWindowPrivate 
*drawable_private
; 
  98     GdkWindowPrivate 
*src_private
; 
  99     GdkGCPrivate 
*gc_private
; 
 102     g_return_if_fail (drawable 
!= NULL
); 
 103     g_return_if_fail (src 
!= NULL
); 
 104     g_return_if_fail (gc 
!= NULL
); 
 107     // This doesn't seem to exist for bitmaps (1-bit) 
 108     // if (GDK_WINDOW_DESTROYED(drawable) || GDK_WINDOW_DESTROYED(src)) 
 111     gdk_drawable_get_size(src
, &src_width
, &src_height
); 
 113     drawable_private 
= (GdkWindowPrivate
*) drawable
; 
 114     src_private 
= (GdkWindowPrivate
*) src
; 
 115     if (drawable_private
->destroyed 
|| src_private
->destroyed
) 
 118     src_width 
= src_private
->width
; 
 119     src_height 
= src_private
->height
; 
 121     gc_private 
= (GdkGCPrivate
*) gc
; 
 124     if (width 
== -1) width 
= src_width
; 
 125     if (height 
== -1) height 
= src_height
; 
 128     XCopyPlane( GDK_WINDOW_XDISPLAY(drawable
), 
 130                 GDK_WINDOW_XID(drawable
), 
 137     XCopyPlane( drawable_private
->xdisplay
, 
 138                 src_private
->xwindow
, 
 139                 drawable_private
->xwindow
, 
 148 //----------------------------------------------------------------------------- 
 149 // Implement Pool of Graphic contexts. Creating them takes too much time. 
 150 //----------------------------------------------------------------------------- 
 152 #define GC_POOL_SIZE 200 
 178 #define GC_POOL_ALLOC_SIZE 100 
 180 static int wxGCPoolSize 
= 0; 
 182 static wxGC 
*wxGCPool 
= NULL
; 
 184 static void wxInitGCPool() 
 186     // This really could wait until the first call to 
 187     // wxGetPoolGC, but we will make the first allocation 
 188     // now when other initialization is being performed. 
 190     // Set initial pool size. 
 191     wxGCPoolSize 
= GC_POOL_ALLOC_SIZE
; 
 193     // Allocate initial pool. 
 194     wxGCPool 
= (wxGC 
*)malloc(wxGCPoolSize 
* sizeof(wxGC
)); 
 195     if (wxGCPool 
== NULL
) 
 197         // If we cannot malloc, then fail with error 
 198         // when debug is enabled.  If debug is not enabled, 
 199         // the problem will eventually get caught 
 201         wxFAIL_MSG( wxT("Cannot allocate GC pool") ); 
 205     // Zero initial pool. 
 206     memset(wxGCPool
, 0, wxGCPoolSize 
* sizeof(wxGC
)); 
 209 static void wxCleanUpGCPool() 
 211     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 213         if (wxGCPool
[i
].m_gc
) 
 214             gdk_gc_unref( wxGCPool
[i
].m_gc 
); 
 222 static GdkGC
* wxGetPoolGC( GdkWindow 
*window
, wxPoolGCType type 
) 
 226     // Look for an available GC. 
 227     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 229         if (!wxGCPool
[i
].m_gc
) 
 231             wxGCPool
[i
].m_gc 
= gdk_gc_new( window 
); 
 232             gdk_gc_set_exposures( wxGCPool
[i
].m_gc
, FALSE 
); 
 233             wxGCPool
[i
].m_type 
= type
; 
 234             wxGCPool
[i
].m_used 
= FALSE
; 
 236         if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type 
== type
)) 
 238             wxGCPool
[i
].m_used 
= TRUE
; 
 239             return wxGCPool
[i
].m_gc
; 
 243     // We did not find an available GC. 
 244     // We need to grow the GC pool. 
 245     pptr 
= (wxGC 
*)realloc(wxGCPool
, 
 246                 (wxGCPoolSize 
+ GC_POOL_ALLOC_SIZE
)*sizeof(wxGC
)); 
 249         // Initialize newly allocated pool. 
 251         memset(&wxGCPool
[wxGCPoolSize
], 0, 
 252                         GC_POOL_ALLOC_SIZE
*sizeof(wxGC
)); 
 254         // Initialize entry we will return.     
 255         wxGCPool
[wxGCPoolSize
].m_gc 
= gdk_gc_new( window 
); 
 256         gdk_gc_set_exposures( wxGCPool
[wxGCPoolSize
].m_gc
, FALSE 
); 
 257         wxGCPool
[wxGCPoolSize
].m_type 
= type
; 
 258         wxGCPool
[wxGCPoolSize
].m_used 
= TRUE
; 
 260         // Set new value of pool size. 
 261         wxGCPoolSize 
+= GC_POOL_ALLOC_SIZE
; 
 263         // Return newly allocated entry. 
 264         return wxGCPool
[wxGCPoolSize
-GC_POOL_ALLOC_SIZE
].m_gc
; 
 267     // The realloc failed.  Fall through to error. 
 268     wxFAIL_MSG( wxT("No GC available") ); 
 270     return (GdkGC
*) NULL
; 
 273 static void wxFreePoolGC( GdkGC 
*gc 
) 
 275     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 277         if (wxGCPool
[i
].m_gc 
== gc
) 
 279             wxGCPool
[i
].m_used 
= FALSE
; 
 284     wxFAIL_MSG( wxT("Wrong GC") ); 
 287 //----------------------------------------------------------------------------- 
 289 //----------------------------------------------------------------------------- 
 291 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
) 
 293 wxWindowDC::wxWindowDC() 
 295     m_penGC 
= (GdkGC 
*) NULL
; 
 296     m_brushGC 
= (GdkGC 
*) NULL
; 
 297     m_textGC 
= (GdkGC 
*) NULL
; 
 298     m_bgGC 
= (GdkGC 
*) NULL
; 
 299     m_cmap 
= (GdkColormap 
*) NULL
; 
 301     m_isScreenDC 
= FALSE
; 
 302     m_owner 
= (wxWindow 
*)NULL
; 
 304     m_context 
= (PangoContext 
*)NULL
; 
 305     m_layout 
= (PangoLayout 
*)NULL
; 
 306     m_fontdesc 
= (PangoFontDescription 
*)NULL
; 
 310 wxWindowDC::wxWindowDC( wxWindow 
*window 
) 
 312     wxASSERT_MSG( window
, wxT("DC needs a window") ); 
 314     m_penGC 
= (GdkGC 
*) NULL
; 
 315     m_brushGC 
= (GdkGC 
*) NULL
; 
 316     m_textGC 
= (GdkGC 
*) NULL
; 
 317     m_bgGC 
= (GdkGC 
*) NULL
; 
 318     m_cmap 
= (GdkColormap 
*) NULL
; 
 319     m_owner 
= (wxWindow 
*)NULL
; 
 321     m_isScreenDC 
= FALSE
; 
 322     m_font 
= window
->GetFont(); 
 324     GtkWidget 
*widget 
= window
->m_wxwindow
; 
 326     // Some controls don't have m_wxwindow - like wxStaticBox, but the user 
 327     // code should still be able to create wxClientDCs for them, so we will 
 328     // use the parent window here then. 
 331         window 
= window
->GetParent(); 
 332         widget 
= window
->m_wxwindow
; 
 335     wxASSERT_MSG( widget
, wxT("DC needs a widget") ); 
 338     m_context 
= window
->GtkGetPangoDefaultContext(); 
 339     m_layout 
= pango_layout_new( m_context 
); 
 340     m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
 343     GtkPizza 
*pizza 
= GTK_PIZZA( widget 
); 
 344     m_window 
= pizza
->bin_window
; 
 346     // Window not realized ? 
 349          // Don't report problems as per MSW. 
 355     m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
 359     /* this must be done after SetUpDC, bacause SetUpDC calls the 
 360        repective SetBrush, SetPen, SetBackground etc functions 
 361        to set up the DC. SetBackground call m_owner->SetBackground 
 362        and this might not be desired as the standard dc background 
 363        is white whereas a window might assume gray to be the 
 364        standard (as e.g. wxStatusBar) */ 
 369 wxWindowDC::~wxWindowDC() 
 375         g_object_unref( G_OBJECT( m_layout 
) ); 
 377         pango_font_description_free( m_fontdesc 
); 
 381 void wxWindowDC::SetUpDC() 
 385     wxASSERT_MSG( !m_penGC
, wxT("GCs already created") ); 
 389         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_SCREEN 
); 
 390         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_SCREEN 
); 
 391         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_SCREEN 
); 
 392         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_SCREEN 
); 
 395     if (m_isMemDC 
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1)) 
 397         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_MONO 
); 
 398         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_MONO 
); 
 399         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_MONO 
); 
 400         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_MONO 
); 
 404         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_COLOUR 
); 
 405         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_COLOUR 
); 
 406         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_COLOUR 
); 
 407         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_COLOUR 
); 
 410     /* background colour */ 
 411     m_backgroundBrush 
= *wxWHITE_BRUSH
; 
 412     m_backgroundBrush
.GetColour().CalcPixel( m_cmap 
); 
 413     GdkColor 
*bg_col 
= m_backgroundBrush
.GetColour().GetColor(); 
 416     m_textForegroundColour
.CalcPixel( m_cmap 
); 
 417     gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
 419     m_textBackgroundColour
.CalcPixel( m_cmap 
); 
 420     gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() ); 
 422     gdk_gc_set_fill( m_textGC
, GDK_SOLID 
); 
 425     m_pen
.GetColour().CalcPixel( m_cmap 
); 
 426     gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() ); 
 427     gdk_gc_set_background( m_penGC
, bg_col 
); 
 429     gdk_gc_set_line_attributes( m_penGC
, 0, GDK_LINE_SOLID
, GDK_CAP_NOT_LAST
, GDK_JOIN_ROUND 
); 
 432     m_brush
.GetColour().CalcPixel( m_cmap 
); 
 433     gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() ); 
 434     gdk_gc_set_background( m_brushGC
, bg_col 
); 
 436     gdk_gc_set_fill( m_brushGC
, GDK_SOLID 
); 
 439     gdk_gc_set_background( m_bgGC
, bg_col 
); 
 440     gdk_gc_set_foreground( m_bgGC
, bg_col 
); 
 442     gdk_gc_set_fill( m_bgGC
, GDK_SOLID 
); 
 445     gdk_gc_set_function( m_textGC
, GDK_COPY 
); 
 446     gdk_gc_set_function( m_brushGC
, GDK_COPY 
); 
 447     gdk_gc_set_function( m_penGC
, GDK_COPY 
); 
 450     gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle 
*) NULL 
); 
 451     gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle 
*) NULL 
); 
 452     gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle 
*) NULL 
); 
 453     gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle 
*) NULL 
); 
 457         hatch_bitmap    
= hatches
; 
 458         hatch_bitmap
[0] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, bdiag_bits
, bdiag_width
, bdiag_height 
); 
 459         hatch_bitmap
[1] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, cdiag_bits
, cdiag_width
, cdiag_height 
); 
 460         hatch_bitmap
[2] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, fdiag_bits
, fdiag_width
, fdiag_height 
); 
 461         hatch_bitmap
[3] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, cross_bits
, cross_width
, cross_height 
); 
 462         hatch_bitmap
[4] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, horiz_bits
, horiz_width
, horiz_height 
); 
 463         hatch_bitmap
[5] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, verti_bits
, verti_width
, verti_height 
); 
 467 void wxWindowDC::DoGetSize( int* width
, int* height 
) const 
 469     wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") ); 
 471     m_owner
->GetSize(width
, height
); 
 474 extern bool wxDoFloodFill(wxDC 
*dc
, wxCoord x
, wxCoord y
,  
 475                           const wxColour 
& col
, int style
); 
 477 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
, 
 478                              const wxColour
& col
, int style
) 
 480     return wxDoFloodFill(this, x
, y
, col
, style
); 
 483 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour 
*col 
) const 
 485     // Generic (and therefore rather inefficient) method. 
 486     // Could be improved. 
 488     wxBitmap 
bitmap(1, 1); 
 489     memdc
.SelectObject(bitmap
); 
 490     memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
); 
 491     memdc
.SelectObject(wxNullBitmap
); 
 493     wxImage image 
= bitmap
.ConvertToImage(); 
 494     col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0)); 
 498 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2 
) 
 500     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 502     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 505             gdk_draw_line( m_window
, m_penGC
, XLOG2DEV(x1
), YLOG2DEV(y1
), XLOG2DEV(x2
), YLOG2DEV(y2
) ); 
 507         CalcBoundingBox(x1
, y1
); 
 508         CalcBoundingBox(x2
, y2
); 
 512 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y 
) 
 514     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 516     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 521         wxCoord xx 
= XLOG2DEV(x
); 
 522         wxCoord yy 
= YLOG2DEV(y
); 
 525             gdk_draw_line( m_window
, m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy 
); 
 526             gdk_draw_line( m_window
, m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) ); 
 531 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, 
 532                             wxCoord xc
, wxCoord yc 
) 
 534     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 536     wxCoord xx1 
= XLOG2DEV(x1
); 
 537     wxCoord yy1 
= YLOG2DEV(y1
); 
 538     wxCoord xx2 
= XLOG2DEV(x2
); 
 539     wxCoord yy2 
= YLOG2DEV(y2
); 
 540     wxCoord xxc 
= XLOG2DEV(xc
); 
 541     wxCoord yyc 
= YLOG2DEV(yc
); 
 542     double dx 
= xx1 
- xxc
; 
 543     double dy 
= yy1 
- yyc
; 
 544     double radius 
= sqrt((double)(dx
*dx
+dy
*dy
)); 
 545     wxCoord   r      
= (wxCoord
)radius
; 
 546     double radius1
, radius2
; 
 548     if (xx1 
== xx2 
&& yy1 
== yy2
) 
 556         radius1 
= radius2 
= 0.0; 
 560         radius1 
= (xx1 
- xxc 
== 0) ? 
 561             (yy1 
- yyc 
< 0) ? 90.0 : -90.0 : 
 562             -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
; 
 563         radius2 
= (xx2 
- xxc 
== 0) ? 
 564             (yy2 
- yyc 
< 0) ? 90.0 : -90.0 : 
 565             -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
; 
 567     wxCoord alpha1 
= wxCoord(radius1 
* 64.0); 
 568     wxCoord alpha2 
= wxCoord((radius2 
- radius1
) * 64.0); 
 569     while (alpha2 
<= 0) alpha2 
+= 360*64; 
 570     while (alpha1 
> 360*64) alpha1 
-= 360*64; 
 574         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 576             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 578                 gdk_gc_set_ts_origin( m_textGC
, 
 579                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 580                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 581                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 582                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 584             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 586                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 587                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 588                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 590             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 592                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 593                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 594                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 596             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 598                 gdk_gc_set_ts_origin( m_brushGC
, 
 599                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 600                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 601                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 602                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 606                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 610         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 612             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 614             gdk_draw_line( m_window
, m_penGC
, xx1
, yy1
, xxc
, yyc 
); 
 615             gdk_draw_line( m_window
, m_penGC
, xxc
, yyc
, xx2
, yy2 
); 
 619     CalcBoundingBox (x1
, y1
); 
 620     CalcBoundingBox (x2
, y2
); 
 623 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea 
) 
 625     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 627     wxCoord xx 
= XLOG2DEV(x
); 
 628     wxCoord yy 
= YLOG2DEV(y
); 
 629     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 630     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 632     // CMB: handle -ve width and/or height 
 633     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 634     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 638         wxCoord start 
= wxCoord(sa 
* 64.0); 
 639         wxCoord end 
= wxCoord((ea
-sa
) * 64.0); 
 641         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 643             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 645                 gdk_gc_set_ts_origin( m_textGC
, 
 646                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 647                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 648                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 649                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 651             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 653                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 654                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 655                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 657             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 659                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 660                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 661                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 663             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 665                 gdk_gc_set_ts_origin( m_brushGC
, 
 666                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 667                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 668                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 669                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 673                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 677         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 678             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, start
, end 
); 
 681     CalcBoundingBox (x
, y
); 
 682     CalcBoundingBox (x 
+ width
, y 
+ height
); 
 685 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y 
) 
 687     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 689     if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
) 
 690         gdk_draw_point( m_window
, m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
 692     CalcBoundingBox (x
, y
); 
 695 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset 
) 
 697     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 699     if (m_pen
.GetStyle() == wxTRANSPARENT
) return; 
 702     GdkPoint 
*gpts 
= new GdkPoint
[n
]; 
 705         wxFAIL_MSG( wxT("Cannot allocate PolyLine") ); 
 709     for (int i 
= 0; i 
< n
; i
++)  
 711         wxCoord x1 
= XLOG2DEV(points
[i
].x 
+ xoffset
); 
 712         wxCoord y1 
= YLOG2DEV(points
[i
].y 
+ yoffset
); 
 714         CalcBoundingBox( x1 
+ xoffset
, y1 
+ yoffset 
); 
 721         gdk_draw_lines( m_window
, m_penGC
, gpts
, n
); 
 726 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int WXUNUSED(fillStyle
) ) 
 728     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 732     GdkPoint 
*gdkpoints 
= new GdkPoint
[n
+1]; 
 734     for (i 
= 0 ; i 
< n 
; i
++) 
 736         gdkpoints
[i
].x 
= XLOG2DEV(points
[i
].x 
+ xoffset
); 
 737         gdkpoints
[i
].y 
= YLOG2DEV(points
[i
].y 
+ yoffset
); 
 739         CalcBoundingBox( points
[i
].x 
+ xoffset
, points
[i
].y 
+ yoffset 
); 
 744         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 746             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 748                 gdk_gc_set_ts_origin( m_textGC
, 
 749                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 750                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 751                 gdk_draw_polygon( m_window
, m_textGC
, TRUE
, gdkpoints
, n 
); 
 752                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 754             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 756                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 757                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 758                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 760             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 762                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 763                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 764                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 766             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 768                 gdk_gc_set_ts_origin( m_brushGC
, 
 769                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 770                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 771                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 772                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 776                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 780         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 782             for (i 
= 0 ; i 
< n 
; i
++) 
 784                 gdk_draw_line( m_window
, m_penGC
, 
 787                                gdkpoints
[(i
+1)%n
].x
, 
 788                                gdkpoints
[(i
+1)%n
].y
); 
 796 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 798     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 800     wxCoord xx 
= XLOG2DEV(x
); 
 801     wxCoord yy 
= YLOG2DEV(y
); 
 802     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 803     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 805     // CMB: draw nothing if transformed w or h is 0 
 806     if (ww 
== 0 || hh 
== 0) return; 
 808     // CMB: handle -ve width and/or height 
 809     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 810     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 814         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 816             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 818                 gdk_gc_set_ts_origin( m_textGC
, 
 819                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 820                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 821                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 822                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 824             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 826                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 827                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 828                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 830             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 832                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 833                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 834                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 836             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 838                 gdk_gc_set_ts_origin( m_brushGC
, 
 839                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 840                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 841                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 842                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 846                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 850         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 851             gdk_draw_rectangle( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
-1, hh
-1 ); 
 854     CalcBoundingBox( x
, y 
); 
 855     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
 858 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius 
) 
 860     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 862     if (radius 
< 0.0) radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
 864     wxCoord xx 
= XLOG2DEV(x
); 
 865     wxCoord yy 
= YLOG2DEV(y
); 
 866     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 867     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 868     wxCoord rr 
= XLOG2DEVREL((wxCoord
)radius
); 
 870     // CMB: handle -ve width and/or height 
 871     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 872     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 874     // CMB: if radius is zero use DrawRectangle() instead to avoid 
 875     // X drawing errors with small radii 
 878         DrawRectangle( x
, y
, width
, height 
); 
 882     // CMB: draw nothing if transformed w or h is 0 
 883     if (ww 
== 0 || hh 
== 0) return; 
 885     // CMB: adjust size if outline is drawn otherwise the result is 
 886     // 1 pixel too wide and high 
 887     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 895         // CMB: ensure dd is not larger than rectangle otherwise we 
 896         // get an hour glass shape 
 898         if (dd 
> ww
) dd 
= ww
; 
 899         if (dd 
> hh
) dd 
= hh
; 
 902         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 904             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 906                 gdk_gc_set_ts_origin( m_textGC
, 
 907                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 908                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 909                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 910                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 911                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 912                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 913                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 914                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 915                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 917             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 919                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 920                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 921                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 922                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 923                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 924                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 925                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 926                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 928             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 930                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 931                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 932                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 933                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 934                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 935                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 936                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 937                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 939             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 941                 gdk_gc_set_ts_origin( m_brushGC
, 
 942                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 943                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 944                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 945                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 946                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 947                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 948                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 949                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 950                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 954                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 955                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 956                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 957                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 958                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 959                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 963         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 965             gdk_draw_line( m_window
, m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy 
); 
 966             gdk_draw_line( m_window
, m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh 
); 
 967             gdk_draw_line( m_window
, m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr 
); 
 968             gdk_draw_line( m_window
, m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr 
); 
 969             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 970             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 971             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 972             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 976     // this ignores the radius 
 977     CalcBoundingBox( x
, y 
); 
 978     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
 981 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 983     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 985     wxCoord xx 
= XLOG2DEV(x
); 
 986     wxCoord yy 
= YLOG2DEV(y
); 
 987     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 988     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 990     // CMB: handle -ve width and/or height 
 991     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 992     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 996         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 998             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
1000                 gdk_gc_set_ts_origin( m_textGC
, 
1001                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
1002                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
1003                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1004                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
1006             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
1008                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
1009                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1010                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1012             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
1014                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
1015                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1016                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1018             if (m_brush
.GetStyle() == wxSTIPPLE
) 
1020                 gdk_gc_set_ts_origin( m_brushGC
, 
1021                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
1022                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
1023                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1024                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1028                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1032         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1033             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1036     CalcBoundingBox( x
, y 
); 
1037     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
1040 void wxWindowDC::DoDrawIcon( const wxIcon 
&icon
, wxCoord x
, wxCoord y 
) 
1042     // VZ: egcs 1.0.3 refuses to compile this without cast, no idea why 
1043     DoDrawBitmap( (const wxBitmap
&)icon
, x
, y
, (bool)TRUE 
); 
1046 void wxWindowDC::DoDrawBitmap( const wxBitmap 
&bitmap
, 
1047                                wxCoord x
, wxCoord y
, 
1050     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1052     wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") ); 
1054     bool is_mono 
= (bitmap
.GetBitmap() != NULL
); 
1056     /* scale/translate size and position */ 
1057     int xx 
= XLOG2DEV(x
); 
1058     int yy 
= YLOG2DEV(y
); 
1060     int w 
= bitmap
.GetWidth(); 
1061     int h 
= bitmap
.GetHeight(); 
1063     CalcBoundingBox( x
, y 
); 
1064     CalcBoundingBox( x 
+ w
, y 
+ h 
); 
1066     if (!m_window
) return; 
1068     int ww 
= XLOG2DEVREL(w
); 
1069     int hh 
= YLOG2DEVREL(h
); 
1071     /* compare to current clipping region */ 
1072     if (!m_currentClippingRegion
.IsNull()) 
1074         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1075         tmp
.Intersect( m_currentClippingRegion 
); 
1080     /* scale bitmap if required */ 
1081     wxBitmap use_bitmap
; 
1082     if ((w 
!= ww
) || (h 
!= hh
)) 
1084         wxImage image 
= bitmap
.ConvertToImage(); 
1085         image
.Rescale( ww
, hh 
); 
1087             use_bitmap 
= wxBitmap(image
.ConvertToMono(255,255,255), 1); 
1089             use_bitmap 
= wxBitmap(image
); 
1093         use_bitmap 
= bitmap
; 
1096     /* apply mask if any */ 
1097     GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1098     if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1100         if (useMask 
&& mask
) 
1102             GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1103 #ifndef __WXGTK20__  // TODO fix crash 
1104             if (!m_currentClippingRegion
.IsNull()) 
1107                 new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 ); 
1108                 GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1110                 gdk_gc_set_foreground( gc
, &col 
); 
1111                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1113                 gdk_gc_set_background( gc
, &col 
); 
1115                 gdk_gc_set_foreground( gc
, &col 
); 
1116                 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1117                 gdk_gc_set_clip_origin( gc
, -xx
, -yy 
); 
1118                 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1119                 gdk_gc_set_stipple( gc
, mask 
); 
1120                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1127                     gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1129                     gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1130                 gdk_gc_set_clip_origin( m_textGC
, xx
, yy 
); 
1135                     gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1137                     gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1138                 gdk_gc_set_clip_origin( m_penGC
, xx
, yy 
); 
1142                 gdk_bitmap_unref( new_mask 
); 
1145     /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1146        drawing a mono-bitmap (XBitmap) we use the current text GC */ 
1148         gdk_wx_draw_bitmap( m_window
, m_textGC
, use_bitmap
.GetBitmap(), 0, 0, xx
, yy
, -1, -1 ); 
1150         gdk_draw_pixmap( m_window
, m_penGC
, use_bitmap
.GetPixmap(), 0, 0, xx
, yy
, -1, -1 ); 
1152     /* remove mask again if any */ 
1153     if (useMask 
&& mask
) 
1157             gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1158             gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1159             if (!m_currentClippingRegion
.IsNull()) 
1160                 gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1164             gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1165             gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1166             if (!m_currentClippingRegion
.IsNull()) 
1167                 gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1172 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, 
1173                          wxCoord width
, wxCoord height
, 
1175                          wxCoord xsrc
, wxCoord ysrc
, 
1178                          wxCoord xsrcMask
, wxCoord ysrcMask 
) 
1180    /* this is the nth try to get this utterly useless function to 
1181       work. it now completely ignores the scaling or translation 
1182       of the source dc, but scales correctly on the target dc and 
1183       knows about possible mask information in a memory dc. */ 
1185     wxCHECK_MSG( Ok(), FALSE
, wxT("invalid window dc") ); 
1187     wxCHECK_MSG( source
, FALSE
, wxT("invalid source dc") ); 
1189     if (!m_window
) return FALSE
; 
1192     // transform the source DC coords to the device ones 
1193     xsrc 
= source
->XLOG2DEV(xsrc
); 
1194     ysrc 
= source
->YLOG2DEV(ysrc
); 
1197     wxClientDC 
*srcDC 
= (wxClientDC
*)source
; 
1198     wxMemoryDC 
*memDC 
= (wxMemoryDC
*)source
; 
1200     bool use_bitmap_method 
= FALSE
; 
1201     bool is_mono 
= FALSE
; 
1203     /* TODO: use the mask origin when drawing transparently */ 
1204     if (xsrcMask 
== -1 && ysrcMask 
== -1) 
1206         xsrcMask 
= xsrc
; ysrcMask 
= ysrc
; 
1209     if (srcDC
->m_isMemDC
) 
1211         if (!memDC
->m_selected
.Ok()) return FALSE
; 
1213         /* we use the "XCopyArea" way to copy a memory dc into 
1214            y different window if the memory dc BOTH 
1215            a) doesn't have any mask or its mask isn't used 
1219         if (useMask 
&& (memDC
->m_selected
.GetMask())) 
1221            /* we HAVE TO use the direct way for memory dcs 
1222               that have mask since the XCopyArea doesn't know 
1224             use_bitmap_method 
= TRUE
; 
1226         else if (memDC
->m_selected
.GetDepth() == 1) 
1228            /* we HAVE TO use the direct way for memory dcs 
1229               that are bitmaps because XCopyArea doesn't cope 
1230               with different bit depths */ 
1232             use_bitmap_method 
= TRUE
; 
1234         else if ((xsrc 
== 0) && (ysrc 
== 0) && 
1235                  (width 
== memDC
->m_selected
.GetWidth()) && 
1236                  (height 
== memDC
->m_selected
.GetHeight())) 
1238            /* we SHOULD use the direct way if all of the bitmap 
1239               in the memory dc is copied in which case XCopyArea 
1240               wouldn't be able able to boost performace by reducing 
1241               the area to be scaled */ 
1242             use_bitmap_method 
= TRUE
; 
1246             use_bitmap_method 
= FALSE
; 
1250     CalcBoundingBox( xdest
, ydest 
); 
1251     CalcBoundingBox( xdest 
+ width
, ydest 
+ height 
); 
1253     /* scale/translate size and position */ 
1254     wxCoord xx 
= XLOG2DEV(xdest
); 
1255     wxCoord yy 
= YLOG2DEV(ydest
); 
1257     wxCoord ww 
= XLOG2DEVREL(width
); 
1258     wxCoord hh 
= YLOG2DEVREL(height
); 
1260     /* compare to current clipping region */ 
1261     if (!m_currentClippingRegion
.IsNull()) 
1263         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1264         tmp
.Intersect( m_currentClippingRegion 
); 
1269     int old_logical_func 
= m_logicalFunction
; 
1270     SetLogicalFunction( logical_func 
); 
1272     if (use_bitmap_method
) 
1274         /* scale/translate bitmap size */ 
1275         wxCoord bm_width 
= memDC
->m_selected
.GetWidth(); 
1276         wxCoord bm_height 
= memDC
->m_selected
.GetHeight(); 
1278         wxCoord bm_ww 
= XLOG2DEVREL( bm_width 
); 
1279         wxCoord bm_hh 
= YLOG2DEVREL( bm_height 
); 
1281         /* scale bitmap if required */ 
1282         wxBitmap use_bitmap
; 
1284         if ((bm_width 
!= bm_ww
) || (bm_height 
!= bm_hh
)) 
1286             wxImage image 
= memDC
->m_selected
.ConvertToImage(); 
1287             image 
= image
.Scale( bm_ww
, bm_hh 
); 
1290                 use_bitmap 
= wxBitmap(image
.ConvertToMono(255,255,255), 1); 
1292                 use_bitmap 
= wxBitmap(image
); 
1296             use_bitmap 
= memDC
->m_selected
; 
1299         /* apply mask if any */ 
1300         GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1301         if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1303         if (useMask 
&& mask
) 
1305             GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1306 #ifndef __WXGTK20__  // TODO fix crash 
1307             if (!m_currentClippingRegion
.IsNull()) 
1310                 new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 ); 
1311                 GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1313                 gdk_gc_set_foreground( gc
, &col 
); 
1314                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1316                 gdk_gc_set_background( gc
, &col 
); 
1318                 gdk_gc_set_foreground( gc
, &col 
); 
1319                 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1320                 gdk_gc_set_clip_origin( gc
, -xx
, -yy 
); 
1321                 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1322                 gdk_gc_set_stipple( gc
, mask 
); 
1323                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1330                     gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1332                     gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1333                 gdk_gc_set_clip_origin( m_textGC
, xx
, yy 
); 
1338                     gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1340                     gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1341                 gdk_gc_set_clip_origin( m_penGC
, xx
, yy 
); 
1344                 gdk_bitmap_unref( new_mask 
); 
1347         /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1348            drawing a mono-bitmap (XBitmap) we use the current text GC */ 
1351             gdk_wx_draw_bitmap( m_window
, m_textGC
, use_bitmap
.GetBitmap(), xsrc
, ysrc
, xx
, yy
, ww
, hh 
); 
1353             gdk_draw_pixmap( m_window
, m_penGC
, use_bitmap
.GetPixmap(), xsrc
, ysrc
, xx
, yy
, ww
, hh 
); 
1355         /* remove mask again if any */ 
1356         if (useMask 
&& mask
) 
1360                 gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1361                 gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1362                 if (!m_currentClippingRegion
.IsNull()) 
1363                     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1367                 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1368                 gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1369                 if (!m_currentClippingRegion
.IsNull()) 
1370                     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1374     else /* use_bitmap_method */ 
1376         if ((width 
!= ww
) || (height 
!= hh
)) 
1378             /* draw source window into a bitmap as we cannot scale 
1379                a window in contrast to a bitmap. this would actually 
1380                work with memory dcs as well, but we'd lose the mask 
1381                information and waste one step in this process since 
1382                a memory already has a bitmap. all this is slightly 
1383                inefficient as we could take an XImage directly from 
1384                an X window, but we'd then also have to care that 
1385                the window is not outside the screen (in which case 
1386                we'd get a BadMatch or what not). 
1387                Is a double XGetImage and combined XGetPixel and 
1388                XPutPixel really faster? I'm not sure. look at wxXt 
1389                for a different implementation of the same problem. */ 
1391             wxBitmap 
bitmap( width
, height 
); 
1393             /* copy including child window contents */ 
1394             gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS 
); 
1395             gdk_window_copy_area( bitmap
.GetPixmap(), m_penGC
, 0, 0, 
1397                                   xsrc
, ysrc
, width
, height 
); 
1398             gdk_gc_set_subwindow( m_penGC
, GDK_CLIP_BY_CHILDREN 
); 
1401             wxImage image 
= bitmap
.ConvertToImage(); 
1402             image 
= image
.Scale( ww
, hh 
); 
1404             /* convert to bitmap */ 
1405             bitmap 
= wxBitmap(image
); 
1407             /* draw scaled bitmap */ 
1408             gdk_draw_pixmap( m_window
, m_penGC
, bitmap
.GetPixmap(), 0, 0, xx
, yy
, -1, -1 ); 
1413             /* No scaling and not a memory dc with a mask either */ 
1415             /* copy including child window contents */ 
1416             gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS 
); 
1417             gdk_window_copy_area( m_window
, m_penGC
, xx
, yy
, 
1419                                   xsrc
, ysrc
, width
, height 
); 
1420             gdk_gc_set_subwindow( m_penGC
, GDK_CLIP_BY_CHILDREN 
); 
1424     SetLogicalFunction( old_logical_func 
); 
1428 void wxWindowDC::DoDrawText( const wxString 
&text
, wxCoord x
, wxCoord y 
) 
1430     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1432     if (!m_window
) return; 
1434     if (text
.empty()) return; 
1437     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1439     wxCHECK_RET( font
, wxT("invalid font") ); 
1446     wxCHECK_RET( m_context
, wxT("no Pango context") ); 
1447     wxCHECK_RET( m_layout
, wxT("no Pango layout") ); 
1448     wxCHECK_RET( m_fontdesc
, wxT("no Pango font description") ); 
1451     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( text 
); 
1453     const wxWCharBuffer wdata 
= wxConvLocal
.cMB2WC( text 
); 
1454     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( wdata 
); 
1456     pango_layout_set_text( m_layout
, (const char*) data
, strlen( (const char*) data 
)); 
1460     if (m_scaleY 
!= 1.0) 
1462          // If there is a user or actually any scale applied to 
1463          // the device context, scale the font. 
1465          // scale font description 
1466          gint oldSize 
= pango_font_description_get_size( m_fontdesc 
); 
1467          double size 
= oldSize
; 
1468          size 
= size 
* m_scaleY
; 
1469          pango_font_description_set_size( m_fontdesc
, (gint
)size 
); 
1471          // actually apply scaled font 
1472          pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1474          pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1475          if ( m_backgroundMode 
== wxSOLID 
) 
1477             gdk_gc_set_foreground(m_textGC
, m_textBackgroundColour
.GetColor()); 
1478             gdk_draw_rectangle(m_window
, m_textGC
, TRUE
, x
, y
, w
, h
); 
1479             gdk_gc_set_foreground(m_textGC
, m_textForegroundColour
.GetColor()); 
1483          gdk_draw_layout( m_window
, m_textGC
, x
, y
, m_layout 
); 
1485          // reset unscaled size 
1486          pango_font_description_set_size( m_fontdesc
, oldSize 
); 
1488          // actually apply unscaled font 
1489          pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1493         pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1494         if ( m_backgroundMode 
== wxSOLID 
) 
1496             gdk_gc_set_foreground(m_textGC
, m_textBackgroundColour
.GetColor()); 
1497             gdk_draw_rectangle(m_window
, m_textGC
, TRUE
, x
, y
, w
, h
); 
1498             gdk_gc_set_foreground(m_textGC
, m_textForegroundColour
.GetColor()); 
1501         gdk_draw_layout( m_window
, m_textGC
, x
, y
, m_layout 
); 
1508     wxCoord width 
= gdk_string_width( font
, text
.mbc_str() ); 
1509     wxCoord height 
= font
->ascent 
+ font
->descent
; 
1511     if ( m_backgroundMode 
== wxSOLID 
) 
1513         gdk_gc_set_foreground( m_textGC
, m_textBackgroundColour
.GetColor() ); 
1514         gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, x
, y
, width
, height 
); 
1515         gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
1517     gdk_draw_string( m_window
, font
, m_textGC
, x
, y 
+ font
->ascent
, text
.mbc_str() ); 
1519     /* CMB 17/7/98: simple underline: ignores scaling and underlying 
1520        X font's XA_UNDERLINE_POSITION and XA_UNDERLINE_THICKNESS 
1521        properties (see wxXt implementation) */ 
1522     if (m_font
.GetUnderlined()) 
1524         wxCoord ul_y 
= y 
+ font
->ascent
; 
1525         if (font
->descent 
> 0) ul_y
++; 
1526         gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x 
+ width
, ul_y
); 
1528 #endif // GTK+ 2.0/1.x 
1530     width 
= wxCoord(width 
/ m_scaleX
); 
1531     height 
= wxCoord(height 
/ m_scaleY
); 
1532     CalcBoundingBox (x 
+ width
, y 
+ height
); 
1533     CalcBoundingBox (x
, y
); 
1536 void wxWindowDC::DoDrawRotatedText( const wxString 
&text
, wxCoord x
, wxCoord y
, double angle 
) 
1540         DrawText(text
, x
, y
); 
1544     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1546     if (!m_window
) return; 
1549     // implement later without GdkFont for GTK 2.0 
1552     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1554     wxCHECK_RET( font
, wxT("invalid font") ); 
1556     // the size of the text 
1557     wxCoord w 
= gdk_string_width( font
, text
.mbc_str() ); 
1558     wxCoord h 
= font
->ascent 
+ font
->descent
; 
1560     // draw the string normally 
1563     dc
.SelectObject(src
); 
1564     dc
.SetFont(GetFont()); 
1565     dc
.SetBackground(*wxWHITE_BRUSH
); 
1566     dc
.SetBrush(*wxBLACK_BRUSH
); 
1568     dc
.DrawText(text
, 0, 0); 
1569     dc
.SelectObject(wxNullBitmap
); 
1571     // Calculate the size of the rotated bounding box. 
1572     double rad 
= DegToRad(angle
); 
1573     double dx 
= cos(rad
), 
1576     // the rectngle vertices are counted clockwise with the first one being at 
1577     // (0, 0) (or, rather, at (x, y)) 
1579            y2 
= -w
*dy
;      // y axis points to the bottom, hence minus 
1582     double x3 
= x4 
+ x2
, 
1586     wxCoord maxX 
= (wxCoord
)(dmax(x2
, dmax(x3
, x4
)) + 0.5), 
1587             maxY 
= (wxCoord
)(dmax(y2
, dmax(y3
, y4
)) + 0.5), 
1588             minX 
= (wxCoord
)(dmin(x2
, dmin(x3
, x4
)) - 0.5), 
1589             minY 
= (wxCoord
)(dmin(y2
, dmin(y3
, y4
)) - 0.5); 
1591     // prepare to blit-with-rotate the bitmap to the DC 
1592     wxImage image 
= src
.ConvertToImage(); 
1594     GdkColor 
*colText 
= m_textForegroundColour
.GetColor(), 
1595              *colBack 
= m_textBackgroundColour
.GetColor(); 
1597     bool textColSet 
= TRUE
; 
1599     unsigned char *data 
= image
.GetData(); 
1601     // paint pixel by pixel 
1602     for ( wxCoord srcX 
= 0; srcX 
< w
; srcX
++ ) 
1604         for ( wxCoord srcY 
= 0; srcY 
< h
; srcY
++ ) 
1606             // transform source coords to dest coords 
1607             double r 
= sqrt((double)srcX
*srcX 
+ srcY
*srcY
); 
1608             double angleOrig 
= atan2((double)srcY
, (double)srcX
) - rad
; 
1609             wxCoord dstX 
= (wxCoord
)(r
*cos(angleOrig
) + 0.5), 
1610                     dstY 
= (wxCoord
)(r
*sin(angleOrig
) + 0.5); 
1613             bool textPixel 
= data
[(srcY
*w 
+ srcX
)*3] == 0; 
1614             if ( textPixel 
|| (m_backgroundMode 
== wxSOLID
) ) 
1616                 // change colour if needed 
1617                 if ( textPixel 
!= textColSet 
) 
1619                     gdk_gc_set_foreground( m_textGC
, textPixel 
? colText
 
1622                     textColSet 
= textPixel
; 
1625                 // don't use DrawPoint() because it uses the current pen 
1626                 // colour, and we don't need it here 
1627                 gdk_draw_point( m_window
, m_textGC
, 
1628                                 XLOG2DEV(x
) + dstX
, YLOG2DEV(y
) + dstY 
); 
1633     // it would be better to draw with non underlined font and draw the line 
1634     // manually here (it would be more straight...) 
1636     if ( m_font
.GetUnderlined() ) 
1638         gdk_draw_line( m_window
, m_textGC
, 
1639                        XLOG2DEV(x 
+ x4
), YLOG2DEV(y 
+ y4 
+ font
->descent
), 
1640                        XLOG2DEV(x 
+ x3
), YLOG2DEV(y 
+ y3 
+ font
->descent
)); 
1644     // restore the font colour 
1645     gdk_gc_set_foreground( m_textGC
, colText 
); 
1647     // update the bounding box 
1648     CalcBoundingBox(x 
+ minX
, y 
+ minY
); 
1649     CalcBoundingBox(x 
+ maxX
, y 
+ maxY
); 
1653 void wxWindowDC::DoGetTextExtent(const wxString 
&string
, 
1654                                  wxCoord 
*width
, wxCoord 
*height
, 
1655                                  wxCoord 
*descent
, wxCoord 
*externalLeading
, 
1656                                  wxFont 
*theFont
) const 
1658     if (string
.IsEmpty()) 
1660         if (width
) (*width
) = 0; 
1661         if (height
) (*height
) = 0; 
1666     // Set new font description 
1668         pango_layout_set_font_description( m_layout
, theFont
->GetNativeFontInfo()->description 
); 
1670     // Set layout's text 
1672     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( string 
); 
1673     pango_layout_set_text( m_layout
, (const char*) data
, strlen( (const char*) data 
)); 
1675     const wxWCharBuffer wdata 
= wxConvLocal
.cMB2WC( string 
); 
1676     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( wdata 
); 
1677     pango_layout_set_text( m_layout
, (const char*) data
, strlen( (const char*) data 
)); 
1681     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1683     if (width
) (*width
) = (wxCoord
) w
;  
1684     if (height
) (*height
) = (wxCoord
) h
; 
1687         // Do something about metrics here. TODO. 
1690     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
1692     // Reset old font description 
1694         pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1696     wxFont fontToUse 
= m_font
; 
1697     if (theFont
) fontToUse 
= *theFont
; 
1699     GdkFont 
*font 
= fontToUse
.GetInternalFont( m_scaleY 
); 
1700     if (width
) (*width
) = wxCoord(gdk_string_width( font
, string
.mbc_str() ) / m_scaleX
); 
1701     if (height
) (*height
) = wxCoord((font
->ascent 
+ font
->descent
) / m_scaleY
); 
1702     if (descent
) (*descent
) = wxCoord(font
->descent 
/ m_scaleY
); 
1703     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
1707 wxCoord 
wxWindowDC::GetCharWidth() const 
1710     pango_layout_set_text( m_layout
, "H", 1 ); 
1712     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1715     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1716     wxCHECK_MSG( font
, -1, wxT("invalid font") ); 
1718     return wxCoord(gdk_string_width( font
, "H" ) / m_scaleX
); 
1722 wxCoord 
wxWindowDC::GetCharHeight() const 
1725     pango_layout_set_text( m_layout
, "H", 1 ); 
1727     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1730     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1731     wxCHECK_MSG( font
, -1, wxT("invalid font") ); 
1733     return wxCoord((font
->ascent 
+ font
->descent
) / m_scaleY
); 
1737 void wxWindowDC::Clear() 
1739     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1741     if (!m_window
) return; 
1743     // VZ: the code below results in infinite recursion and crashes when 
1744     //     dc.Clear() is done from OnPaint() so I disable it for now. 
1745     //     I don't know what the correct fix is but Clear() surely should not 
1746     //     reenter OnPaint()! 
1748     /* - we either are a memory dc or have a window as the 
1749        owner. anything else shouldn't happen. 
1750        - we don't use gdk_window_clear() as we don't set 
1751        the window's background colour anymore. it is too 
1752        much pain to keep the DC's and the window's back- 
1753        ground colour in synch. */ 
1764         GetSize( &width
, &height 
); 
1765         gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height 
); 
1770     GetSize( &width
, &height 
); 
1771     gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height 
); 
1775 void wxWindowDC::SetFont( const wxFont 
&font 
) 
1783             pango_font_description_free( m_fontdesc 
); 
1785         m_fontdesc 
= pango_font_description_copy( m_font
.GetNativeFontInfo()->description 
); 
1790             PangoContext 
*oldContext 
= m_context
; 
1792             // We might want to use the X11 context for faster 
1793             // rendering on screen 
1794             if (m_font
.GetNoAntiAliasing()) 
1795                 m_context 
= m_owner
->GtkGetPangoX11Context(); 
1797                 m_context 
= m_owner
->GtkGetPangoDefaultContext(); 
1799             // If we switch back/forth between different contexts 
1800             // we also have to create a new layout. I think so, 
1801             // at least, and it doesn't hurt to do it.  
1802             if (oldContext 
!= m_context
) 
1805                     g_object_unref( G_OBJECT( m_layout 
) ); 
1807                 m_layout 
= pango_layout_new( m_context 
); 
1811         pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1816 void wxWindowDC::SetPen( const wxPen 
&pen 
) 
1818     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1820     if (m_pen 
== pen
) return; 
1824     if (!m_pen
.Ok()) return; 
1826     if (!m_window
) return; 
1828     gint width 
= m_pen
.GetWidth(); 
1831         // CMB: if width is non-zero scale it with the dc 
1836         // X doesn't allow different width in x and y and so we take 
1839                    ( fabs((double) XLOG2DEVREL(width
)) + 
1840                      fabs((double) YLOG2DEVREL(width
)) ) / 2.0; 
1844             // width can't be 0 or an internal GTK error occurs inside 
1845             // gdk_gc_set_dashes() below 
1850     static const wxGTKDash dotted
[] = {1, 1}; 
1851     static const wxGTKDash short_dashed
[] = {2, 2}; 
1852     static const wxGTKDash wxCoord_dashed
[] = {2, 4}; 
1853     static const wxGTKDash dotted_dashed
[] = {3, 3, 1, 3}; 
1855     // We express dash pattern in pen width unit, so we are 
1856     // independent of zoom factor and so on... 
1858     const wxGTKDash 
*req_dash
; 
1860     GdkLineStyle lineStyle 
= GDK_LINE_SOLID
; 
1861     switch (m_pen
.GetStyle()) 
1865             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1866             req_nb_dash 
= m_pen
.GetDashCount(); 
1867             req_dash 
= (wxGTKDash
*)m_pen
.GetDash(); 
1872             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1879             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1881             req_dash 
= wxCoord_dashed
; 
1886             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1888             req_dash 
= short_dashed
; 
1893 //            lineStyle = GDK_LINE_DOUBLE_DASH; 
1894             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1896             req_dash 
= dotted_dashed
; 
1901         case wxSTIPPLE_MASK_OPAQUE
: 
1906             lineStyle 
= GDK_LINE_SOLID
; 
1907             req_dash 
= (wxGTKDash
*)NULL
; 
1913 #if (GTK_MINOR_VERSION > 0) || (GTK_MAJOR_VERSION > 1) 
1914     if (req_dash 
&& req_nb_dash
) 
1916         wxGTKDash 
*real_req_dash 
= new wxGTKDash
[req_nb_dash
]; 
1919             for (int i 
= 0; i 
< req_nb_dash
; i
++) 
1920                 real_req_dash
[i
] = req_dash
[i
] * width
; 
1921             gdk_gc_set_dashes( m_penGC
, 0, real_req_dash
, req_nb_dash 
); 
1922             delete[] real_req_dash
; 
1926             // No Memory. We use non-scaled dash pattern... 
1927             gdk_gc_set_dashes( m_penGC
, 0, (wxGTKDash
*)req_dash
, req_nb_dash 
); 
1930 #endif // GTK+ > 1.0 
1932     GdkCapStyle capStyle 
= GDK_CAP_ROUND
; 
1933     switch (m_pen
.GetCap()) 
1935         case wxCAP_PROJECTING
: { capStyle 
= GDK_CAP_PROJECTING
; break; } 
1936         case wxCAP_BUTT
:       { capStyle 
= GDK_CAP_BUTT
;       break; } 
1943                 capStyle 
= GDK_CAP_NOT_LAST
; 
1947                 capStyle 
= GDK_CAP_ROUND
; 
1953     GdkJoinStyle joinStyle 
= GDK_JOIN_ROUND
; 
1954     switch (m_pen
.GetJoin()) 
1956         case wxJOIN_BEVEL
: { joinStyle 
= GDK_JOIN_BEVEL
; break; } 
1957         case wxJOIN_MITER
: { joinStyle 
= GDK_JOIN_MITER
; break; } 
1959         default:           { joinStyle 
= GDK_JOIN_ROUND
; break; } 
1962     gdk_gc_set_line_attributes( m_penGC
, width
, lineStyle
, capStyle
, joinStyle 
); 
1964     m_pen
.GetColour().CalcPixel( m_cmap 
); 
1965     gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() ); 
1968 void wxWindowDC::SetBrush( const wxBrush 
&brush 
) 
1970     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1972     if (m_brush 
== brush
) return; 
1976     if (!m_brush
.Ok()) return; 
1978     if (!m_window
) return; 
1980     m_brush
.GetColour().CalcPixel( m_cmap 
); 
1981     gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() ); 
1983     gdk_gc_set_fill( m_brushGC
, GDK_SOLID 
); 
1985     if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok())) 
1987         if (m_brush
.GetStipple()->GetPixmap()) 
1989             gdk_gc_set_fill( m_brushGC
, GDK_TILED 
); 
1990             gdk_gc_set_tile( m_brushGC
, m_brush
.GetStipple()->GetPixmap() ); 
1994             gdk_gc_set_fill( m_brushGC
, GDK_STIPPLED 
); 
1995             gdk_gc_set_stipple( m_brushGC
, m_brush
.GetStipple()->GetBitmap() ); 
1999     if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
2001         gdk_gc_set_fill( m_textGC
, GDK_OPAQUE_STIPPLED
); 
2002         gdk_gc_set_stipple( m_textGC
, m_brush
.GetStipple()->GetMask()->GetBitmap() ); 
2005     if (IS_HATCH(m_brush
.GetStyle())) 
2007         gdk_gc_set_fill( m_brushGC
, GDK_STIPPLED 
); 
2008         int num 
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
; 
2009         gdk_gc_set_stipple( m_brushGC
, hatches
[num
] ); 
2013 void wxWindowDC::SetBackground( const wxBrush 
&brush 
) 
2015    /* CMB 21/7/98: Added SetBackground. Sets background brush 
2016     * for Clear() and bg colour for shapes filled with cross-hatch brush */ 
2018     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2020     if (m_backgroundBrush 
== brush
) return; 
2022     m_backgroundBrush 
= brush
; 
2024     if (!m_backgroundBrush
.Ok()) return; 
2026     if (!m_window
) return; 
2028     m_backgroundBrush
.GetColour().CalcPixel( m_cmap 
); 
2029     gdk_gc_set_background( m_brushGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2030     gdk_gc_set_background( m_penGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2031     gdk_gc_set_background( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2032     gdk_gc_set_foreground( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2034     gdk_gc_set_fill( m_bgGC
, GDK_SOLID 
); 
2036     if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok())) 
2038         if (m_backgroundBrush
.GetStipple()->GetPixmap()) 
2040             gdk_gc_set_fill( m_bgGC
, GDK_TILED 
); 
2041             gdk_gc_set_tile( m_bgGC
, m_backgroundBrush
.GetStipple()->GetPixmap() ); 
2045             gdk_gc_set_fill( m_bgGC
, GDK_STIPPLED 
); 
2046             gdk_gc_set_stipple( m_bgGC
, m_backgroundBrush
.GetStipple()->GetBitmap() ); 
2050     if (IS_HATCH(m_backgroundBrush
.GetStyle())) 
2052         gdk_gc_set_fill( m_bgGC
, GDK_STIPPLED 
); 
2053         int num 
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
; 
2054         gdk_gc_set_stipple( m_bgGC
, hatches
[num
] ); 
2058 void wxWindowDC::SetLogicalFunction( int function 
) 
2060     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2062     if (m_logicalFunction 
== function
) 
2065     // VZ: shouldn't this be a CHECK? 
2072         case wxXOR
:          mode 
= GDK_XOR
;           break; 
2073         case wxINVERT
:       mode 
= GDK_INVERT
;        break; 
2074 #if (GTK_MINOR_VERSION > 0) || (GTK_MAJOR_VERSION > 1) 
2075         case wxOR_REVERSE
:   mode 
= GDK_OR_REVERSE
;    break; 
2076         case wxAND_REVERSE
:  mode 
= GDK_AND_REVERSE
;   break; 
2077         case wxCLEAR
:        mode 
= GDK_CLEAR
;         break; 
2078         case wxSET
:          mode 
= GDK_SET
;           break; 
2079         case wxOR_INVERT
:    mode 
= GDK_OR_INVERT
;     break; 
2080         case wxAND
:          mode 
= GDK_AND
;           break; 
2081         case wxOR
:           mode 
= GDK_OR
;            break; 
2082         case wxEQUIV
:        mode 
= GDK_EQUIV
;         break; 
2083         case wxNAND
:         mode 
= GDK_NAND
;          break; 
2084         case wxAND_INVERT
:   mode 
= GDK_AND_INVERT
;    break; 
2085         case wxCOPY
:         mode 
= GDK_COPY
;          break; 
2086         case wxNO_OP
:        mode 
= GDK_NOOP
;          break; 
2087         case wxSRC_INVERT
:   mode 
= GDK_COPY_INVERT
;   break; 
2089         // unsupported by GTK 
2090         case wxNOR
:          mode 
= GDK_COPY
;          break; 
2091 #endif // GTK+ > 1.0 
2093            wxFAIL_MSG( wxT("unsupported logical function") ); 
2097     m_logicalFunction 
= function
; 
2099     gdk_gc_set_function( m_penGC
, mode 
); 
2100     gdk_gc_set_function( m_brushGC
, mode 
); 
2102     // to stay compatible with wxMSW, we don't apply ROPs to the text 
2103     // operations (i.e. DrawText/DrawRotatedText). 
2104     // True, but mono-bitmaps use the m_textGC and they use ROPs as well. 
2105     gdk_gc_set_function( m_textGC
, mode 
); 
2108 void wxWindowDC::SetTextForeground( const wxColour 
&col 
) 
2110     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2112     // don't set m_textForegroundColour to an invalid colour as we'd crash 
2113     // later then (we use m_textForegroundColour.GetColor() without checking 
2115     if ( !col
.Ok() || (m_textForegroundColour 
== col
) ) 
2118     m_textForegroundColour 
= col
; 
2122         m_textForegroundColour
.CalcPixel( m_cmap 
); 
2123         gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
2127 void wxWindowDC::SetTextBackground( const wxColour 
&col 
) 
2129     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2132     if ( !col
.Ok() || (m_textBackgroundColour 
== col
) ) 
2135     m_textBackgroundColour 
= col
; 
2139         m_textBackgroundColour
.CalcPixel( m_cmap 
); 
2140         gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() ); 
2144 void wxWindowDC::SetBackgroundMode( int mode 
) 
2146     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2148     m_backgroundMode 
= mode
; 
2150     if (!m_window
) return; 
2152     // CMB 21/7/98: fill style of cross-hatch brushes is affected by 
2153     // transparent/solid background mode 
2155     if (m_brush
.GetStyle() != wxSOLID 
&& m_brush
.GetStyle() != wxTRANSPARENT
) 
2157         gdk_gc_set_fill( m_brushGC
, 
2158           (m_backgroundMode 
== wxTRANSPARENT
) ? GDK_STIPPLED 
: GDK_OPAQUE_STIPPLED
); 
2162 void wxWindowDC::SetPalette( const wxPalette
& WXUNUSED(palette
) ) 
2164     wxFAIL_MSG( wxT("wxWindowDC::SetPalette not implemented") ); 
2167 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
2169     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2171     if (!m_window
) return; 
2174     rect
.x 
= XLOG2DEV(x
); 
2175     rect
.y 
= YLOG2DEV(y
); 
2176     rect
.width 
= XLOG2DEVREL(width
); 
2177     rect
.height 
= YLOG2DEVREL(height
); 
2179     if (!m_currentClippingRegion
.IsNull()) 
2180         m_currentClippingRegion
.Intersect( rect 
); 
2182         m_currentClippingRegion
.Union( rect 
); 
2184 #if USE_PAINT_REGION 
2185     if (!m_paintClippingRegion
.IsNull()) 
2186         m_currentClippingRegion
.Intersect( m_paintClippingRegion 
); 
2189     wxCoord xx
, yy
, ww
, hh
; 
2190     m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh 
); 
2191     wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh 
); 
2193     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2194     gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2195     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2196     gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2199 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion 
®ion  
) 
2201     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2205         DestroyClippingRegion(); 
2209     if (!m_window
) return; 
2211     if (!m_currentClippingRegion
.IsNull()) 
2212         m_currentClippingRegion
.Intersect( region 
); 
2214         m_currentClippingRegion
.Union( region 
); 
2216 #if USE_PAINT_REGION 
2217     if (!m_paintClippingRegion
.IsNull()) 
2218         m_currentClippingRegion
.Intersect( m_paintClippingRegion 
); 
2221     wxCoord xx
, yy
, ww
, hh
; 
2222     m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh 
); 
2223     wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh 
); 
2225     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2226     gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2227     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2228     gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2231 void wxWindowDC::DestroyClippingRegion() 
2233     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2235     wxDC::DestroyClippingRegion(); 
2237     m_currentClippingRegion
.Clear(); 
2239 #if USE_PAINT_REGION 
2240     if (!m_paintClippingRegion
.IsEmpty()) 
2241         m_currentClippingRegion
.Union( m_paintClippingRegion 
); 
2244     if (!m_window
) return; 
2246     if (m_currentClippingRegion
.IsEmpty()) 
2248         gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle 
*) NULL 
); 
2249         gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle 
*) NULL 
); 
2250         gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle 
*) NULL 
); 
2251         gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle 
*) NULL 
); 
2255         gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2256         gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2257         gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2258         gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2262 void wxWindowDC::Destroy() 
2264     if (m_penGC
) wxFreePoolGC( m_penGC 
); 
2265     m_penGC 
= (GdkGC
*) NULL
; 
2266     if (m_brushGC
) wxFreePoolGC( m_brushGC 
); 
2267     m_brushGC 
= (GdkGC
*) NULL
; 
2268     if (m_textGC
) wxFreePoolGC( m_textGC 
); 
2269     m_textGC 
= (GdkGC
*) NULL
; 
2270     if (m_bgGC
) wxFreePoolGC( m_bgGC 
); 
2271     m_bgGC 
= (GdkGC
*) NULL
; 
2274 void wxWindowDC::ComputeScaleAndOrigin() 
2276     /* CMB: copy scale to see if it changes */ 
2277     double origScaleX 
= m_scaleX
; 
2278     double origScaleY 
= m_scaleY
; 
2280     wxDC::ComputeScaleAndOrigin(); 
2282     /* CMB: if scale has changed call SetPen to recalulate the line width */ 
2283     if ((m_scaleX 
!= origScaleX 
|| m_scaleY 
!= origScaleY
) && 
2286       /* this is a bit artificial, but we need to force wxDC to think 
2287          the pen has changed */ 
2294 // Resolution in pixels per logical inch 
2295 wxSize 
wxWindowDC::GetPPI() const 
2297     return wxSize( (int) (m_mm_to_pix_x 
* 25.4 + 0.5), (int) (m_mm_to_pix_y 
* 25.4 + 0.5)); 
2300 int wxWindowDC::GetDepth() const 
2302     wxFAIL_MSG(wxT("not implemented")); 
2308 //----------------------------------------------------------------------------- 
2310 //----------------------------------------------------------------------------- 
2312 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
) 
2314 wxPaintDC::wxPaintDC( wxWindow 
*win 
) 
2317 #if USE_PAINT_REGION 
2318     if (!win
->m_clipPaintRegion
) 
2321     m_paintClippingRegion 
= win
->GetUpdateRegion(); 
2322     GdkRegion 
*region 
= m_paintClippingRegion
.GetRegion(); 
2325         m_paintClippingRegion 
= win
->GetUpdateRegion(); 
2326         GdkRegion 
*region 
= m_paintClippingRegion
.GetRegion(); 
2329             m_currentClippingRegion
.Union( m_paintClippingRegion 
); 
2331             gdk_gc_set_clip_region( m_penGC
, region 
); 
2332             gdk_gc_set_clip_region( m_brushGC
, region 
); 
2333             gdk_gc_set_clip_region( m_textGC
, region 
); 
2334             gdk_gc_set_clip_region( m_bgGC
, region 
); 
2337 #endif // USE_PAINT_REGION 
2340 //----------------------------------------------------------------------------- 
2342 //----------------------------------------------------------------------------- 
2344 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
) 
2346 wxClientDC::wxClientDC( wxWindow 
*win 
) 
2349     wxCHECK_RET( win
, _T("NULL window in wxClientDC::wxClientDC") ); 
2351 #ifdef __WXUNIVERSAL__ 
2352     wxPoint ptOrigin 
= win
->GetClientAreaOrigin(); 
2353     SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
); 
2354     wxSize size 
= win
->GetClientSize(); 
2355     SetClippingRegion(wxPoint(0, 0), size
); 
2356 #endif // __WXUNIVERSAL__ 
2359 void wxClientDC::DoGetSize(int *width
, int *height
) const 
2361     wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") ); 
2363     m_owner
->GetClientSize( width
, height 
); 
2366 // ---------------------------------------------------------------------------- 
2368 // ---------------------------------------------------------------------------- 
2370 class wxDCModule 
: public wxModule
 
2377     DECLARE_DYNAMIC_CLASS(wxDCModule
) 
2380 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
) 
2382 bool wxDCModule::OnInit() 
2388 void wxDCModule::OnExit()