]>
git.saurik.com Git - wxWidgets.git/blob - src/gtk/dcclient.cpp
92ae53ff9d9b6af8ce7754fb08d46ec8733c45aa
   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     if (GDK_WINDOW_DESTROYED(drawable
) || GDK_WINDOW_DESTROYED(src
)) 
 110     gdk_drawable_get_size(src
, &src_width
, &src_height
); 
 112     drawable_private 
= (GdkWindowPrivate
*) drawable
; 
 113     src_private 
= (GdkWindowPrivate
*) src
; 
 114     if (drawable_private
->destroyed 
|| src_private
->destroyed
) 
 117     src_width 
= src_private
->width
; 
 118     src_height 
= src_private
->height
; 
 120     gc_private 
= (GdkGCPrivate
*) gc
; 
 123     if (width 
== -1) width 
= src_width
; 
 124     if (height 
== -1) height 
= src_height
; 
 127     XCopyPlane( GDK_WINDOW_XDISPLAY(drawable
), 
 129                 GDK_WINDOW_XID(drawable
), 
 136     XCopyPlane( drawable_private
->xdisplay
, 
 137                 src_private
->xwindow
, 
 138                 drawable_private
->xwindow
, 
 147 //----------------------------------------------------------------------------- 
 148 // Implement Pool of Graphic contexts. Creating them takes too much time. 
 149 //----------------------------------------------------------------------------- 
 151 #define GC_POOL_SIZE 200 
 177 #define GC_POOL_ALLOC_SIZE 100 
 179 static int wxGCPoolSize 
= 0; 
 181 static wxGC 
*wxGCPool 
= NULL
; 
 183 static void wxInitGCPool() 
 185     // This really could wait until the first call to 
 186     // wxGetPoolGC, but we will make the first allocation 
 187     // now when other initialization is being performed. 
 189     // Set initial pool size. 
 190     wxGCPoolSize 
= GC_POOL_ALLOC_SIZE
; 
 192     // Allocate initial pool. 
 193     wxGCPool 
= (wxGC 
*)malloc(wxGCPoolSize 
* sizeof(wxGC
)); 
 194     if (wxGCPool 
== NULL
) 
 196         // If we cannot malloc, then fail with error 
 197         // when debug is enabled.  If debug is not enabled, 
 198         // the problem will eventually get caught 
 200         wxFAIL_MSG( wxT("Cannot allocate GC pool") ); 
 204     // Zero initial pool. 
 205     memset(wxGCPool
, 0, wxGCPoolSize 
* sizeof(wxGC
)); 
 208 static void wxCleanUpGCPool() 
 210     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 212         if (wxGCPool
[i
].m_gc
) 
 213             gdk_gc_unref( wxGCPool
[i
].m_gc 
); 
 221 static GdkGC
* wxGetPoolGC( GdkWindow 
*window
, wxPoolGCType type 
) 
 225     // Look for an available GC. 
 226     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 228         if (!wxGCPool
[i
].m_gc
) 
 230             wxGCPool
[i
].m_gc 
= gdk_gc_new( window 
); 
 231             gdk_gc_set_exposures( wxGCPool
[i
].m_gc
, FALSE 
); 
 232             wxGCPool
[i
].m_type 
= type
; 
 233             wxGCPool
[i
].m_used 
= FALSE
; 
 235         if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type 
== type
)) 
 237             wxGCPool
[i
].m_used 
= TRUE
; 
 238             return wxGCPool
[i
].m_gc
; 
 242     // We did not find an available GC. 
 243     // We need to grow the GC pool. 
 244     pptr 
= (wxGC 
*)realloc(wxGCPool
, 
 245                 (wxGCPoolSize 
+ GC_POOL_ALLOC_SIZE
)*sizeof(wxGC
)); 
 248         // Initialize newly allocated pool. 
 250         memset(&wxGCPool
[wxGCPoolSize
], 0, 
 251                         GC_POOL_ALLOC_SIZE
*sizeof(wxGC
)); 
 253         // Initialize entry we will return.     
 254         wxGCPool
[wxGCPoolSize
].m_gc 
= gdk_gc_new( window 
); 
 255         gdk_gc_set_exposures( wxGCPool
[wxGCPoolSize
].m_gc
, FALSE 
); 
 256         wxGCPool
[wxGCPoolSize
].m_type 
= type
; 
 257         wxGCPool
[wxGCPoolSize
].m_used 
= TRUE
; 
 259         // Set new value of pool size. 
 260         wxGCPoolSize 
+= GC_POOL_ALLOC_SIZE
; 
 262         // Return newly allocated entry. 
 263         return wxGCPool
[wxGCPoolSize
-GC_POOL_ALLOC_SIZE
].m_gc
; 
 266     // The realloc failed.  Fall through to error. 
 267     wxFAIL_MSG( wxT("No GC available") ); 
 269     return (GdkGC
*) NULL
; 
 272 static void wxFreePoolGC( GdkGC 
*gc 
) 
 274     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 276         if (wxGCPool
[i
].m_gc 
== gc
) 
 278             wxGCPool
[i
].m_used 
= FALSE
; 
 283     wxFAIL_MSG( wxT("Wrong GC") ); 
 286 //----------------------------------------------------------------------------- 
 288 //----------------------------------------------------------------------------- 
 290 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
) 
 292 wxWindowDC::wxWindowDC() 
 294     m_penGC 
= (GdkGC 
*) NULL
; 
 295     m_brushGC 
= (GdkGC 
*) NULL
; 
 296     m_textGC 
= (GdkGC 
*) NULL
; 
 297     m_bgGC 
= (GdkGC 
*) NULL
; 
 298     m_cmap 
= (GdkColormap 
*) NULL
; 
 300     m_isScreenDC 
= FALSE
; 
 301     m_owner 
= (wxWindow 
*)NULL
; 
 303     m_context 
= (PangoContext 
*)NULL
; 
 304     m_layout 
= (PangoLayout 
*)NULL
; 
 305     m_fontdesc 
= (PangoFontDescription 
*)NULL
; 
 309 wxWindowDC::wxWindowDC( wxWindow 
*window 
) 
 311     wxASSERT_MSG( window
, wxT("DC needs a window") ); 
 313     m_penGC 
= (GdkGC 
*) NULL
; 
 314     m_brushGC 
= (GdkGC 
*) NULL
; 
 315     m_textGC 
= (GdkGC 
*) NULL
; 
 316     m_bgGC 
= (GdkGC 
*) NULL
; 
 317     m_cmap 
= (GdkColormap 
*) NULL
; 
 318     m_owner 
= (wxWindow 
*)NULL
; 
 320     m_isScreenDC 
= FALSE
; 
 321     m_font 
= window
->GetFont(); 
 323     GtkWidget 
*widget 
= window
->m_wxwindow
; 
 325     // Some controls don't have m_wxwindow - like wxStaticBox, but the user 
 326     // code should still be able to create wxClientDCs for them, so we will 
 327     // use the parent window here then. 
 330         window 
= window
->GetParent(); 
 331         widget 
= window
->m_wxwindow
; 
 334     wxASSERT_MSG( widget
, wxT("DC needs a widget") ); 
 337     m_context 
= window
->GtkGetPangoDefaultContext(); 
 338     m_layout 
= pango_layout_new( m_context 
); 
 339     m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
 342     GtkPizza 
*pizza 
= GTK_PIZZA( widget 
); 
 343     m_window 
= pizza
->bin_window
; 
 345     // Window not realized ? 
 348          // Don't report problems as per MSW. 
 354     m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
 358     /* this must be done after SetUpDC, bacause SetUpDC calls the 
 359        repective SetBrush, SetPen, SetBackground etc functions 
 360        to set up the DC. SetBackground call m_owner->SetBackground 
 361        and this might not be desired as the standard dc background 
 362        is white whereas a window might assume gray to be the 
 363        standard (as e.g. wxStatusBar) */ 
 368 wxWindowDC::~wxWindowDC() 
 374         g_object_unref( G_OBJECT( m_layout 
) ); 
 376         pango_font_description_free( m_fontdesc 
); 
 380 void wxWindowDC::SetUpDC() 
 384     wxASSERT_MSG( !m_penGC
, wxT("GCs already created") ); 
 388         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_SCREEN 
); 
 389         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_SCREEN 
); 
 390         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_SCREEN 
); 
 391         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_SCREEN 
); 
 394     if (m_isMemDC 
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1)) 
 396         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_MONO 
); 
 397         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_MONO 
); 
 398         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_MONO 
); 
 399         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_MONO 
); 
 403         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_COLOUR 
); 
 404         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_COLOUR 
); 
 405         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_COLOUR 
); 
 406         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_COLOUR 
); 
 409     /* background colour */ 
 410     m_backgroundBrush 
= *wxWHITE_BRUSH
; 
 411     m_backgroundBrush
.GetColour().CalcPixel( m_cmap 
); 
 412     GdkColor 
*bg_col 
= m_backgroundBrush
.GetColour().GetColor(); 
 415     m_textForegroundColour
.CalcPixel( m_cmap 
); 
 416     gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
 418     m_textBackgroundColour
.CalcPixel( m_cmap 
); 
 419     gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() ); 
 421     gdk_gc_set_fill( m_textGC
, GDK_SOLID 
); 
 424     m_pen
.GetColour().CalcPixel( m_cmap 
); 
 425     gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() ); 
 426     gdk_gc_set_background( m_penGC
, bg_col 
); 
 428     gdk_gc_set_line_attributes( m_penGC
, 0, GDK_LINE_SOLID
, GDK_CAP_NOT_LAST
, GDK_JOIN_ROUND 
); 
 431     m_brush
.GetColour().CalcPixel( m_cmap 
); 
 432     gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() ); 
 433     gdk_gc_set_background( m_brushGC
, bg_col 
); 
 435     gdk_gc_set_fill( m_brushGC
, GDK_SOLID 
); 
 438     gdk_gc_set_background( m_bgGC
, bg_col 
); 
 439     gdk_gc_set_foreground( m_bgGC
, bg_col 
); 
 441     gdk_gc_set_fill( m_bgGC
, GDK_SOLID 
); 
 444     gdk_gc_set_function( m_textGC
, GDK_COPY 
); 
 445     gdk_gc_set_function( m_brushGC
, GDK_COPY 
); 
 446     gdk_gc_set_function( m_penGC
, GDK_COPY 
); 
 449     gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle 
*) NULL 
); 
 450     gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle 
*) NULL 
); 
 451     gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle 
*) NULL 
); 
 452     gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle 
*) NULL 
); 
 456         hatch_bitmap    
= hatches
; 
 457         hatch_bitmap
[0] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, bdiag_bits
, bdiag_width
, bdiag_height 
); 
 458         hatch_bitmap
[1] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, cdiag_bits
, cdiag_width
, cdiag_height 
); 
 459         hatch_bitmap
[2] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, fdiag_bits
, fdiag_width
, fdiag_height 
); 
 460         hatch_bitmap
[3] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, cross_bits
, cross_width
, cross_height 
); 
 461         hatch_bitmap
[4] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, horiz_bits
, horiz_width
, horiz_height 
); 
 462         hatch_bitmap
[5] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, verti_bits
, verti_width
, verti_height 
); 
 466 void wxWindowDC::DoGetSize( int* width
, int* height 
) const 
 468     wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") ); 
 470     m_owner
->GetSize(width
, height
); 
 473 extern bool wxDoFloodFill(wxDC 
*dc
, wxCoord x
, wxCoord y
,  
 474                           const wxColour 
& col
, int style
); 
 476 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
, 
 477                              const wxColour
& col
, int style
) 
 479     return wxDoFloodFill(this, x
, y
, col
, style
); 
 482 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour 
*col 
) const 
 484     // Generic (and therefore rather inefficient) method. 
 485     // Could be improved. 
 487     wxBitmap 
bitmap(1, 1); 
 488     memdc
.SelectObject(bitmap
); 
 489     memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
); 
 490     memdc
.SelectObject(wxNullBitmap
); 
 492     wxImage image 
= bitmap
.ConvertToImage(); 
 493     col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0)); 
 497 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2 
) 
 499     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 501     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 504             gdk_draw_line( m_window
, m_penGC
, XLOG2DEV(x1
), YLOG2DEV(y1
), XLOG2DEV(x2
), YLOG2DEV(y2
) ); 
 506         CalcBoundingBox(x1
, y1
); 
 507         CalcBoundingBox(x2
, y2
); 
 511 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y 
) 
 513     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 515     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 520         wxCoord xx 
= XLOG2DEV(x
); 
 521         wxCoord yy 
= YLOG2DEV(y
); 
 524             gdk_draw_line( m_window
, m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy 
); 
 525             gdk_draw_line( m_window
, m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) ); 
 530 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, 
 531                             wxCoord xc
, wxCoord yc 
) 
 533     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 535     wxCoord xx1 
= XLOG2DEV(x1
); 
 536     wxCoord yy1 
= YLOG2DEV(y1
); 
 537     wxCoord xx2 
= XLOG2DEV(x2
); 
 538     wxCoord yy2 
= YLOG2DEV(y2
); 
 539     wxCoord xxc 
= XLOG2DEV(xc
); 
 540     wxCoord yyc 
= YLOG2DEV(yc
); 
 541     double dx 
= xx1 
- xxc
; 
 542     double dy 
= yy1 
- yyc
; 
 543     double radius 
= sqrt((double)(dx
*dx
+dy
*dy
)); 
 544     wxCoord   r      
= (wxCoord
)radius
; 
 545     double radius1
, radius2
; 
 547     if (xx1 
== xx2 
&& yy1 
== yy2
) 
 555         radius1 
= radius2 
= 0.0; 
 559         radius1 
= (xx1 
- xxc 
== 0) ? 
 560             (yy1 
- yyc 
< 0) ? 90.0 : -90.0 : 
 561             -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
; 
 562         radius2 
= (xx2 
- xxc 
== 0) ? 
 563             (yy2 
- yyc 
< 0) ? 90.0 : -90.0 : 
 564             -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
; 
 566     wxCoord alpha1 
= wxCoord(radius1 
* 64.0); 
 567     wxCoord alpha2 
= wxCoord((radius2 
- radius1
) * 64.0); 
 568     while (alpha2 
<= 0) alpha2 
+= 360*64; 
 569     while (alpha1 
> 360*64) alpha1 
-= 360*64; 
 573         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 575             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 577                 gdk_gc_set_ts_origin( m_textGC
, 
 578                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 579                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 580                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 581                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 583             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 585                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 586                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 587                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 589             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 591                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 592                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 593                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 595             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 597                 gdk_gc_set_ts_origin( m_brushGC
, 
 598                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 599                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 600                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 601                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 605                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 609         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 611             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 613             gdk_draw_line( m_window
, m_penGC
, xx1
, yy1
, xxc
, yyc 
); 
 614             gdk_draw_line( m_window
, m_penGC
, xxc
, yyc
, xx2
, yy2 
); 
 618     CalcBoundingBox (x1
, y1
); 
 619     CalcBoundingBox (x2
, y2
); 
 622 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea 
) 
 624     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 626     wxCoord xx 
= XLOG2DEV(x
); 
 627     wxCoord yy 
= YLOG2DEV(y
); 
 628     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 629     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 631     // CMB: handle -ve width and/or height 
 632     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 633     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 637         wxCoord start 
= wxCoord(sa 
* 64.0); 
 638         wxCoord end 
= wxCoord((ea
-sa
) * 64.0); 
 640         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 642             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 644                 gdk_gc_set_ts_origin( m_textGC
, 
 645                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 646                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 647                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 648                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 650             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 652                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 653                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 654                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 656             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 658                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 659                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 660                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 662             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 664                 gdk_gc_set_ts_origin( m_brushGC
, 
 665                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 666                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 667                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 668                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 672                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 676         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 677             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, start
, end 
); 
 680     CalcBoundingBox (x
, y
); 
 681     CalcBoundingBox (x 
+ width
, y 
+ height
); 
 684 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y 
) 
 686     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 688     if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
) 
 689         gdk_draw_point( m_window
, m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
 691     CalcBoundingBox (x
, y
); 
 694 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset 
) 
 696     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 698     if (m_pen
.GetStyle() == wxTRANSPARENT
) return; 
 701     GdkPoint 
*gpts 
= new GdkPoint
[n
]; 
 704         wxFAIL_MSG( wxT("Cannot allocate PolyLine") ); 
 708     for (int i 
= 0; i 
< n
; i
++)  
 710         wxCoord x1 
= XLOG2DEV(points
[i
].x 
+ xoffset
); 
 711         wxCoord y1 
= YLOG2DEV(points
[i
].y 
+ yoffset
); 
 713         CalcBoundingBox( x1 
+ xoffset
, y1 
+ yoffset 
); 
 720         gdk_draw_lines( m_window
, m_penGC
, gpts
, n
); 
 725 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int WXUNUSED(fillStyle
) ) 
 727     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 731     GdkPoint 
*gdkpoints 
= new GdkPoint
[n
+1]; 
 733     for (i 
= 0 ; i 
< n 
; i
++) 
 735         gdkpoints
[i
].x 
= XLOG2DEV(points
[i
].x 
+ xoffset
); 
 736         gdkpoints
[i
].y 
= YLOG2DEV(points
[i
].y 
+ yoffset
); 
 738         CalcBoundingBox( points
[i
].x 
+ xoffset
, points
[i
].y 
+ yoffset 
); 
 743         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 745             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 747                 gdk_gc_set_ts_origin( m_textGC
, 
 748                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 749                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 750                 gdk_draw_polygon( m_window
, m_textGC
, TRUE
, gdkpoints
, n 
); 
 751                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 753             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 755                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 756                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 757                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 759             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 761                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 762                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 763                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 765             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 767                 gdk_gc_set_ts_origin( m_brushGC
, 
 768                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 769                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 770                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 771                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 775                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 779         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 781             for (i 
= 0 ; i 
< n 
; i
++) 
 783                 gdk_draw_line( m_window
, m_penGC
, 
 786                                gdkpoints
[(i
+1)%n
].x
, 
 787                                gdkpoints
[(i
+1)%n
].y
); 
 795 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 797     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 799     wxCoord xx 
= XLOG2DEV(x
); 
 800     wxCoord yy 
= YLOG2DEV(y
); 
 801     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 802     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 804     // CMB: draw nothing if transformed w or h is 0 
 805     if (ww 
== 0 || hh 
== 0) return; 
 807     // CMB: handle -ve width and/or height 
 808     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 809     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 813         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 815             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 817                 gdk_gc_set_ts_origin( m_textGC
, 
 818                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 819                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 820                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 821                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 823             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 825                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 826                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 827                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 829             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 831                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 832                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 833                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 835             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 837                 gdk_gc_set_ts_origin( m_brushGC
, 
 838                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 839                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 840                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 841                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 845                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 849         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 850             gdk_draw_rectangle( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
-1, hh
-1 ); 
 853     CalcBoundingBox( x
, y 
); 
 854     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
 857 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius 
) 
 859     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 861     if (radius 
< 0.0) radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
 863     wxCoord xx 
= XLOG2DEV(x
); 
 864     wxCoord yy 
= YLOG2DEV(y
); 
 865     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 866     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 867     wxCoord rr 
= XLOG2DEVREL((wxCoord
)radius
); 
 869     // CMB: handle -ve width and/or height 
 870     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 871     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 873     // CMB: if radius is zero use DrawRectangle() instead to avoid 
 874     // X drawing errors with small radii 
 877         DrawRectangle( x
, y
, width
, height 
); 
 881     // CMB: draw nothing if transformed w or h is 0 
 882     if (ww 
== 0 || hh 
== 0) return; 
 884     // CMB: adjust size if outline is drawn otherwise the result is 
 885     // 1 pixel too wide and high 
 886     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 894         // CMB: ensure dd is not larger than rectangle otherwise we 
 895         // get an hour glass shape 
 897         if (dd 
> ww
) dd 
= ww
; 
 898         if (dd 
> hh
) dd 
= hh
; 
 901         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 903             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 905                 gdk_gc_set_ts_origin( m_textGC
, 
 906                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 907                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 908                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 909                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 910                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 911                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 912                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 913                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 914                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 916             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 918                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 919                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 920                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 921                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 922                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 923                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 924                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 925                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 927             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 929                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 930                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 931                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 932                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 933                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 934                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 935                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 936                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 938             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 940                 gdk_gc_set_ts_origin( m_brushGC
, 
 941                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 942                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 943                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 944                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 945                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 946                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 947                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 948                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 949                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 953                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 954                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 955                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 956                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 957                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 958                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 962         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 964             gdk_draw_line( m_window
, m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy 
); 
 965             gdk_draw_line( m_window
, m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh 
); 
 966             gdk_draw_line( m_window
, m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr 
); 
 967             gdk_draw_line( m_window
, m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr 
); 
 968             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 969             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 970             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 971             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 975     // this ignores the radius 
 976     CalcBoundingBox( x
, y 
); 
 977     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
 980 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 982     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 984     wxCoord xx 
= XLOG2DEV(x
); 
 985     wxCoord yy 
= YLOG2DEV(y
); 
 986     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 987     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 989     // CMB: handle -ve width and/or height 
 990     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 991     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 995         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 997             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 999                 gdk_gc_set_ts_origin( m_textGC
, 
1000                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
1001                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
1002                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1003                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
1005             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
1007                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
1008                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1009                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1011             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
1013                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
1014                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1015                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1017             if (m_brush
.GetStyle() == wxSTIPPLE
) 
1019                 gdk_gc_set_ts_origin( m_brushGC
, 
1020                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
1021                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
1022                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1023                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1027                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1031         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1032             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1035     CalcBoundingBox( x
, y 
); 
1036     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
1039 void wxWindowDC::DoDrawIcon( const wxIcon 
&icon
, wxCoord x
, wxCoord y 
) 
1041     // VZ: egcs 1.0.3 refuses to compile this without cast, no idea why 
1042     DoDrawBitmap( (const wxBitmap
&)icon
, x
, y
, (bool)TRUE 
); 
1045 void wxWindowDC::DoDrawBitmap( const wxBitmap 
&bitmap
, 
1046                                wxCoord x
, wxCoord y
, 
1049     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1051     wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") ); 
1053     bool is_mono 
= (bitmap
.GetBitmap() != NULL
); 
1055     /* scale/translate size and position */ 
1056     int xx 
= XLOG2DEV(x
); 
1057     int yy 
= YLOG2DEV(y
); 
1059     int w 
= bitmap
.GetWidth(); 
1060     int h 
= bitmap
.GetHeight(); 
1062     CalcBoundingBox( x
, y 
); 
1063     CalcBoundingBox( x 
+ w
, y 
+ h 
); 
1065     if (!m_window
) return; 
1067     int ww 
= XLOG2DEVREL(w
); 
1068     int hh 
= YLOG2DEVREL(h
); 
1070     /* compare to current clipping region */ 
1071     if (!m_currentClippingRegion
.IsNull()) 
1073         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1074         tmp
.Intersect( m_currentClippingRegion 
); 
1079     /* scale bitmap if required */ 
1080     wxBitmap use_bitmap
; 
1081     if ((w 
!= ww
) || (h 
!= hh
)) 
1083         wxImage image 
= bitmap
.ConvertToImage(); 
1084         image
.Rescale( ww
, hh 
); 
1086             use_bitmap 
= wxBitmap(image
.ConvertToMono(255,255,255), 1); 
1088             use_bitmap 
= wxBitmap(image
); 
1092         use_bitmap 
= bitmap
; 
1095     /* apply mask if any */ 
1096     GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1097     if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1099         if (useMask 
&& mask
) 
1101             GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1102 #ifndef __WXGTK20__  // TODO fix crash 
1103             if (!m_currentClippingRegion
.IsNull()) 
1106                 new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 ); 
1107                 GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1109                 gdk_gc_set_foreground( gc
, &col 
); 
1110                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1112                 gdk_gc_set_background( gc
, &col 
); 
1114                 gdk_gc_set_foreground( gc
, &col 
); 
1115                 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1116                 gdk_gc_set_clip_origin( gc
, -xx
, -yy 
); 
1117                 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1118                 gdk_gc_set_stipple( gc
, mask 
); 
1119                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1126                     gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1128                     gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1129                 gdk_gc_set_clip_origin( m_textGC
, xx
, yy 
); 
1134                     gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1136                     gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1137                 gdk_gc_set_clip_origin( m_penGC
, xx
, yy 
); 
1141                 gdk_bitmap_unref( new_mask 
); 
1144     /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1145        drawing a mono-bitmap (XBitmap) we use the current text GC */ 
1147         gdk_wx_draw_bitmap( m_window
, m_textGC
, use_bitmap
.GetBitmap(), 0, 0, xx
, yy
, -1, -1 ); 
1149         gdk_draw_pixmap( m_window
, m_penGC
, use_bitmap
.GetPixmap(), 0, 0, xx
, yy
, -1, -1 ); 
1151     /* remove mask again if any */ 
1152     if (useMask 
&& mask
) 
1156             gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1157             gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1158             if (!m_currentClippingRegion
.IsNull()) 
1159                 gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1163             gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1164             gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1165             if (!m_currentClippingRegion
.IsNull()) 
1166                 gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1171 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, 
1172                          wxCoord width
, wxCoord height
, 
1174                          wxCoord xsrc
, wxCoord ysrc
, 
1177                          wxCoord xsrcMask
, wxCoord ysrcMask 
) 
1179    /* this is the nth try to get this utterly useless function to 
1180       work. it now completely ignores the scaling or translation 
1181       of the source dc, but scales correctly on the target dc and 
1182       knows about possible mask information in a memory dc. */ 
1184     wxCHECK_MSG( Ok(), FALSE
, wxT("invalid window dc") ); 
1186     wxCHECK_MSG( source
, FALSE
, wxT("invalid source dc") ); 
1188     if (!m_window
) return FALSE
; 
1191     // transform the source DC coords to the device ones 
1192     xsrc 
= source
->XLOG2DEV(xsrc
); 
1193     ysrc 
= source
->YLOG2DEV(ysrc
); 
1196     wxClientDC 
*srcDC 
= (wxClientDC
*)source
; 
1197     wxMemoryDC 
*memDC 
= (wxMemoryDC
*)source
; 
1199     bool use_bitmap_method 
= FALSE
; 
1200     bool is_mono 
= FALSE
; 
1202     /* TODO: use the mask origin when drawing transparently */ 
1203     if (xsrcMask 
== -1 && ysrcMask 
== -1) 
1205         xsrcMask 
= xsrc
; ysrcMask 
= ysrc
; 
1208     if (srcDC
->m_isMemDC
) 
1210         if (!memDC
->m_selected
.Ok()) return FALSE
; 
1212         /* we use the "XCopyArea" way to copy a memory dc into 
1213            y different window if the memory dc BOTH 
1214            a) doesn't have any mask or its mask isn't used 
1218         if (useMask 
&& (memDC
->m_selected
.GetMask())) 
1220            /* we HAVE TO use the direct way for memory dcs 
1221               that have mask since the XCopyArea doesn't know 
1223             use_bitmap_method 
= TRUE
; 
1225         else if (memDC
->m_selected
.GetDepth() == 1) 
1227            /* we HAVE TO use the direct way for memory dcs 
1228               that are bitmaps because XCopyArea doesn't cope 
1229               with different bit depths */ 
1231             use_bitmap_method 
= TRUE
; 
1233         else if ((xsrc 
== 0) && (ysrc 
== 0) && 
1234                  (width 
== memDC
->m_selected
.GetWidth()) && 
1235                  (height 
== memDC
->m_selected
.GetHeight())) 
1237            /* we SHOULD use the direct way if all of the bitmap 
1238               in the memory dc is copied in which case XCopyArea 
1239               wouldn't be able able to boost performace by reducing 
1240               the area to be scaled */ 
1241             use_bitmap_method 
= TRUE
; 
1245             use_bitmap_method 
= FALSE
; 
1249     CalcBoundingBox( xdest
, ydest 
); 
1250     CalcBoundingBox( xdest 
+ width
, ydest 
+ height 
); 
1252     /* scale/translate size and position */ 
1253     wxCoord xx 
= XLOG2DEV(xdest
); 
1254     wxCoord yy 
= YLOG2DEV(ydest
); 
1256     wxCoord ww 
= XLOG2DEVREL(width
); 
1257     wxCoord hh 
= YLOG2DEVREL(height
); 
1259     /* compare to current clipping region */ 
1260     if (!m_currentClippingRegion
.IsNull()) 
1262         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1263         tmp
.Intersect( m_currentClippingRegion 
); 
1268     int old_logical_func 
= m_logicalFunction
; 
1269     SetLogicalFunction( logical_func 
); 
1271     if (use_bitmap_method
) 
1273         /* scale/translate bitmap size */ 
1274         wxCoord bm_width 
= memDC
->m_selected
.GetWidth(); 
1275         wxCoord bm_height 
= memDC
->m_selected
.GetHeight(); 
1277         wxCoord bm_ww 
= XLOG2DEVREL( bm_width 
); 
1278         wxCoord bm_hh 
= YLOG2DEVREL( bm_height 
); 
1280         /* scale bitmap if required */ 
1281         wxBitmap use_bitmap
; 
1283         if ((bm_width 
!= bm_ww
) || (bm_height 
!= bm_hh
)) 
1285             wxImage image 
= memDC
->m_selected
.ConvertToImage(); 
1286             image 
= image
.Scale( bm_ww
, bm_hh 
); 
1289                 use_bitmap 
= wxBitmap(image
.ConvertToMono(255,255,255), 1); 
1291                 use_bitmap 
= wxBitmap(image
); 
1295             use_bitmap 
= memDC
->m_selected
; 
1298         /* apply mask if any */ 
1299         GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1300         if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1302         if (useMask 
&& mask
) 
1304             GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1305 #ifndef __WXGTK20__  // TODO fix crash 
1306             if (!m_currentClippingRegion
.IsNull()) 
1309                 new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 ); 
1310                 GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1312                 gdk_gc_set_foreground( gc
, &col 
); 
1313                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1315                 gdk_gc_set_background( gc
, &col 
); 
1317                 gdk_gc_set_foreground( gc
, &col 
); 
1318                 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1319                 gdk_gc_set_clip_origin( gc
, -xx
, -yy 
); 
1320                 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1321                 gdk_gc_set_stipple( gc
, mask 
); 
1322                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1329                     gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1331                     gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1332                 gdk_gc_set_clip_origin( m_textGC
, xx
, yy 
); 
1337                     gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1339                     gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1340                 gdk_gc_set_clip_origin( m_penGC
, xx
, yy 
); 
1343                 gdk_bitmap_unref( new_mask 
); 
1346         /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1347            drawing a mono-bitmap (XBitmap) we use the current text GC */ 
1350             gdk_wx_draw_bitmap( m_window
, m_textGC
, use_bitmap
.GetBitmap(), xsrc
, ysrc
, xx
, yy
, ww
, hh 
); 
1352             gdk_draw_pixmap( m_window
, m_penGC
, use_bitmap
.GetPixmap(), xsrc
, ysrc
, xx
, yy
, ww
, hh 
); 
1354         /* remove mask again if any */ 
1355         if (useMask 
&& mask
) 
1359                 gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1360                 gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1361                 if (!m_currentClippingRegion
.IsNull()) 
1362                     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1366                 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1367                 gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1368                 if (!m_currentClippingRegion
.IsNull()) 
1369                     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1373     else /* use_bitmap_method */ 
1375         if ((width 
!= ww
) || (height 
!= hh
)) 
1377             /* draw source window into a bitmap as we cannot scale 
1378                a window in contrast to a bitmap. this would actually 
1379                work with memory dcs as well, but we'd lose the mask 
1380                information and waste one step in this process since 
1381                a memory already has a bitmap. all this is slightly 
1382                inefficient as we could take an XImage directly from 
1383                an X window, but we'd then also have to care that 
1384                the window is not outside the screen (in which case 
1385                we'd get a BadMatch or what not). 
1386                Is a double XGetImage and combined XGetPixel and 
1387                XPutPixel really faster? I'm not sure. look at wxXt 
1388                for a different implementation of the same problem. */ 
1390             wxBitmap 
bitmap( width
, height 
); 
1392             /* copy including child window contents */ 
1393             gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS 
); 
1394             gdk_window_copy_area( bitmap
.GetPixmap(), m_penGC
, 0, 0, 
1396                                   xsrc
, ysrc
, width
, height 
); 
1397             gdk_gc_set_subwindow( m_penGC
, GDK_CLIP_BY_CHILDREN 
); 
1400             wxImage image 
= bitmap
.ConvertToImage(); 
1401             image 
= image
.Scale( ww
, hh 
); 
1403             /* convert to bitmap */ 
1404             bitmap 
= wxBitmap(image
); 
1406             /* draw scaled bitmap */ 
1407             gdk_draw_pixmap( m_window
, m_penGC
, bitmap
.GetPixmap(), 0, 0, xx
, yy
, -1, -1 ); 
1412             /* No scaling and not a memory dc with a mask either */ 
1414             /* copy including child window contents */ 
1415             gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS 
); 
1416             gdk_window_copy_area( m_window
, m_penGC
, xx
, yy
, 
1418                                   xsrc
, ysrc
, width
, height 
); 
1419             gdk_gc_set_subwindow( m_penGC
, GDK_CLIP_BY_CHILDREN 
); 
1423     SetLogicalFunction( old_logical_func 
); 
1427 void wxWindowDC::DoDrawText( const wxString 
&text
, wxCoord x
, wxCoord y 
) 
1429     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1431     if (!m_window
) return; 
1433     if (text
.empty()) return; 
1436     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1438     wxCHECK_RET( font
, wxT("invalid font") ); 
1445     wxCHECK_RET( m_context
, wxT("no Pango context") ); 
1446     wxCHECK_RET( m_layout
, wxT("no Pango layout") ); 
1447     wxCHECK_RET( m_fontdesc
, wxT("no Pango font description") ); 
1450     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( text 
); 
1452     const wxWCharBuffer wdata 
= wxConvLocal
.cMB2WC( text 
); 
1453     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( wdata 
); 
1455     pango_layout_set_text( m_layout
, (const char*) data
, strlen( (const char*) data 
)); 
1459     if (m_scaleY 
!= 1.0) 
1461          // If there is a user or actually any scale applied to 
1462          // the device context, scale the font. 
1464          // scale font description 
1465          gint oldSize 
= pango_font_description_get_size( m_fontdesc 
); 
1466          double size 
= oldSize
; 
1467          size 
= size 
* m_scaleY
; 
1468          pango_font_description_set_size( m_fontdesc
, (gint
)size 
); 
1470          // actually apply scaled font 
1471          pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1473          pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1474          if ( m_backgroundMode 
== wxSOLID 
) 
1476             gdk_gc_set_foreground(m_textGC
, m_textBackgroundColour
.GetColor()); 
1477             gdk_draw_rectangle(m_window
, m_textGC
, TRUE
, x
, y
, w
, h
); 
1478             gdk_gc_set_foreground(m_textGC
, m_textForegroundColour
.GetColor()); 
1482          gdk_draw_layout( m_window
, m_textGC
, x
, y
, m_layout 
); 
1484          // reset unscaled size 
1485          pango_font_description_set_size( m_fontdesc
, oldSize 
); 
1487          // actually apply unscaled font 
1488          pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1492         pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1493         if ( m_backgroundMode 
== wxSOLID 
) 
1495             gdk_gc_set_foreground(m_textGC
, m_textBackgroundColour
.GetColor()); 
1496             gdk_draw_rectangle(m_window
, m_textGC
, TRUE
, x
, y
, w
, h
); 
1497             gdk_gc_set_foreground(m_textGC
, m_textForegroundColour
.GetColor()); 
1500         gdk_draw_layout( m_window
, m_textGC
, x
, y
, m_layout 
); 
1507     wxCoord width 
= gdk_string_width( font
, text
.mbc_str() ); 
1508     wxCoord height 
= font
->ascent 
+ font
->descent
; 
1510     if ( m_backgroundMode 
== wxSOLID 
) 
1512         gdk_gc_set_foreground( m_textGC
, m_textBackgroundColour
.GetColor() ); 
1513         gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, x
, y
, width
, height 
); 
1514         gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
1516     gdk_draw_string( m_window
, font
, m_textGC
, x
, y 
+ font
->ascent
, text
.mbc_str() ); 
1518     /* CMB 17/7/98: simple underline: ignores scaling and underlying 
1519        X font's XA_UNDERLINE_POSITION and XA_UNDERLINE_THICKNESS 
1520        properties (see wxXt implementation) */ 
1521     if (m_font
.GetUnderlined()) 
1523         wxCoord ul_y 
= y 
+ font
->ascent
; 
1524         if (font
->descent 
> 0) ul_y
++; 
1525         gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x 
+ width
, ul_y
); 
1527 #endif // GTK+ 2.0/1.x 
1529     width 
= wxCoord(width 
/ m_scaleX
); 
1530     height 
= wxCoord(height 
/ m_scaleY
); 
1531     CalcBoundingBox (x 
+ width
, y 
+ height
); 
1532     CalcBoundingBox (x
, y
); 
1535 void wxWindowDC::DoDrawRotatedText( const wxString 
&text
, wxCoord x
, wxCoord y
, double angle 
) 
1539         DrawText(text
, x
, y
); 
1543     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1545     if (!m_window
) return; 
1548     // implement later without GdkFont for GTK 2.0 
1551     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1553     wxCHECK_RET( font
, wxT("invalid font") ); 
1555     // the size of the text 
1556     wxCoord w 
= gdk_string_width( font
, text
.mbc_str() ); 
1557     wxCoord h 
= font
->ascent 
+ font
->descent
; 
1559     // draw the string normally 
1562     dc
.SelectObject(src
); 
1563     dc
.SetFont(GetFont()); 
1564     dc
.SetBackground(*wxWHITE_BRUSH
); 
1565     dc
.SetBrush(*wxBLACK_BRUSH
); 
1567     dc
.DrawText(text
, 0, 0); 
1568     dc
.SelectObject(wxNullBitmap
); 
1570     // Calculate the size of the rotated bounding box. 
1571     double rad 
= DegToRad(angle
); 
1572     double dx 
= cos(rad
), 
1575     // the rectngle vertices are counted clockwise with the first one being at 
1576     // (0, 0) (or, rather, at (x, y)) 
1578            y2 
= -w
*dy
;      // y axis points to the bottom, hence minus 
1581     double x3 
= x4 
+ x2
, 
1585     wxCoord maxX 
= (wxCoord
)(dmax(x2
, dmax(x3
, x4
)) + 0.5), 
1586             maxY 
= (wxCoord
)(dmax(y2
, dmax(y3
, y4
)) + 0.5), 
1587             minX 
= (wxCoord
)(dmin(x2
, dmin(x3
, x4
)) - 0.5), 
1588             minY 
= (wxCoord
)(dmin(y2
, dmin(y3
, y4
)) - 0.5); 
1590     // prepare to blit-with-rotate the bitmap to the DC 
1591     wxImage image 
= src
.ConvertToImage(); 
1593     GdkColor 
*colText 
= m_textForegroundColour
.GetColor(), 
1594              *colBack 
= m_textBackgroundColour
.GetColor(); 
1596     bool textColSet 
= TRUE
; 
1598     unsigned char *data 
= image
.GetData(); 
1600     // paint pixel by pixel 
1601     for ( wxCoord srcX 
= 0; srcX 
< w
; srcX
++ ) 
1603         for ( wxCoord srcY 
= 0; srcY 
< h
; srcY
++ ) 
1605             // transform source coords to dest coords 
1606             double r 
= sqrt((double)srcX
*srcX 
+ srcY
*srcY
); 
1607             double angleOrig 
= atan2((double)srcY
, (double)srcX
) - rad
; 
1608             wxCoord dstX 
= (wxCoord
)(r
*cos(angleOrig
) + 0.5), 
1609                     dstY 
= (wxCoord
)(r
*sin(angleOrig
) + 0.5); 
1612             bool textPixel 
= data
[(srcY
*w 
+ srcX
)*3] == 0; 
1613             if ( textPixel 
|| (m_backgroundMode 
== wxSOLID
) ) 
1615                 // change colour if needed 
1616                 if ( textPixel 
!= textColSet 
) 
1618                     gdk_gc_set_foreground( m_textGC
, textPixel 
? colText
 
1621                     textColSet 
= textPixel
; 
1624                 // don't use DrawPoint() because it uses the current pen 
1625                 // colour, and we don't need it here 
1626                 gdk_draw_point( m_window
, m_textGC
, 
1627                                 XLOG2DEV(x
) + dstX
, YLOG2DEV(y
) + dstY 
); 
1632     // it would be better to draw with non underlined font and draw the line 
1633     // manually here (it would be more straight...) 
1635     if ( m_font
.GetUnderlined() ) 
1637         gdk_draw_line( m_window
, m_textGC
, 
1638                        XLOG2DEV(x 
+ x4
), YLOG2DEV(y 
+ y4 
+ font
->descent
), 
1639                        XLOG2DEV(x 
+ x3
), YLOG2DEV(y 
+ y3 
+ font
->descent
)); 
1643     // restore the font colour 
1644     gdk_gc_set_foreground( m_textGC
, colText 
); 
1646     // update the bounding box 
1647     CalcBoundingBox(x 
+ minX
, y 
+ minY
); 
1648     CalcBoundingBox(x 
+ maxX
, y 
+ maxY
); 
1652 void wxWindowDC::DoGetTextExtent(const wxString 
&string
, 
1653                                  wxCoord 
*width
, wxCoord 
*height
, 
1654                                  wxCoord 
*descent
, wxCoord 
*externalLeading
, 
1655                                  wxFont 
*theFont
) const 
1657     if (string
.IsEmpty()) 
1659         if (width
) (*width
) = 0; 
1660         if (height
) (*height
) = 0; 
1665     // Set new font description 
1667         pango_layout_set_font_description( m_layout
, theFont
->GetNativeFontInfo()->description 
); 
1669     // Set layout's text 
1671     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( string 
); 
1672     pango_layout_set_text( m_layout
, (const char*) data
, strlen( (const char*) data 
)); 
1674     const wxWCharBuffer wdata 
= wxConvLocal
.cMB2WC( string 
); 
1675     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( wdata 
); 
1676     pango_layout_set_text( m_layout
, (const char*) data
, strlen( (const char*) data 
)); 
1680     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1682     if (width
) (*width
) = (wxCoord
) w
;  
1683     if (height
) (*height
) = (wxCoord
) h
; 
1686         // Do something about metrics here. TODO. 
1689     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
1691     // Reset old font description 
1693         pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1695     wxFont fontToUse 
= m_font
; 
1696     if (theFont
) fontToUse 
= *theFont
; 
1698     GdkFont 
*font 
= fontToUse
.GetInternalFont( m_scaleY 
); 
1699     if (width
) (*width
) = wxCoord(gdk_string_width( font
, string
.mbc_str() ) / m_scaleX
); 
1700     if (height
) (*height
) = wxCoord((font
->ascent 
+ font
->descent
) / m_scaleY
); 
1701     if (descent
) (*descent
) = wxCoord(font
->descent 
/ m_scaleY
); 
1702     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
1706 wxCoord 
wxWindowDC::GetCharWidth() const 
1709     pango_layout_set_text( m_layout
, "H", 1 ); 
1711     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1714     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1715     wxCHECK_MSG( font
, -1, wxT("invalid font") ); 
1717     return wxCoord(gdk_string_width( font
, "H" ) / m_scaleX
); 
1721 wxCoord 
wxWindowDC::GetCharHeight() const 
1724     pango_layout_set_text( m_layout
, "H", 1 ); 
1726     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1729     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1730     wxCHECK_MSG( font
, -1, wxT("invalid font") ); 
1732     return wxCoord((font
->ascent 
+ font
->descent
) / m_scaleY
); 
1736 void wxWindowDC::Clear() 
1738     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1740     if (!m_window
) return; 
1742     // VZ: the code below results in infinite recursion and crashes when 
1743     //     dc.Clear() is done from OnPaint() so I disable it for now. 
1744     //     I don't know what the correct fix is but Clear() surely should not 
1745     //     reenter OnPaint()! 
1747     /* - we either are a memory dc or have a window as the 
1748        owner. anything else shouldn't happen. 
1749        - we don't use gdk_window_clear() as we don't set 
1750        the window's background colour anymore. it is too 
1751        much pain to keep the DC's and the window's back- 
1752        ground colour in synch. */ 
1763         GetSize( &width
, &height 
); 
1764         gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height 
); 
1769     GetSize( &width
, &height 
); 
1770     gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height 
); 
1774 void wxWindowDC::SetFont( const wxFont 
&font 
) 
1782             pango_font_description_free( m_fontdesc 
); 
1784         m_fontdesc 
= pango_font_description_copy( m_font
.GetNativeFontInfo()->description 
); 
1789             PangoContext 
*oldContext 
= m_context
; 
1791             // We might want to use the X11 context for faster 
1792             // rendering on screen 
1793             if (m_font
.GetNoAntiAliasing()) 
1794                 m_context 
= m_owner
->GtkGetPangoX11Context(); 
1796                 m_context 
= m_owner
->GtkGetPangoDefaultContext(); 
1798             // If we switch back/forth between different contexts 
1799             // we also have to create a new layout. I think so, 
1800             // at least, and it doesn't hurt to do it.  
1801             if (oldContext 
!= m_context
) 
1804                     g_object_unref( G_OBJECT( m_layout 
) ); 
1806                 m_layout 
= pango_layout_new( m_context 
); 
1810         pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1815 void wxWindowDC::SetPen( const wxPen 
&pen 
) 
1817     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1819     if (m_pen 
== pen
) return; 
1823     if (!m_pen
.Ok()) return; 
1825     if (!m_window
) return; 
1827     gint width 
= m_pen
.GetWidth(); 
1830         // CMB: if width is non-zero scale it with the dc 
1835         // X doesn't allow different width in x and y and so we take 
1838                    ( fabs((double) XLOG2DEVREL(width
)) + 
1839                      fabs((double) YLOG2DEVREL(width
)) ) / 2.0; 
1843             // width can't be 0 or an internal GTK error occurs inside 
1844             // gdk_gc_set_dashes() below 
1849     static const wxGTKDash dotted
[] = {1, 1}; 
1850     static const wxGTKDash short_dashed
[] = {2, 2}; 
1851     static const wxGTKDash wxCoord_dashed
[] = {2, 4}; 
1852     static const wxGTKDash dotted_dashed
[] = {3, 3, 1, 3}; 
1854     // We express dash pattern in pen width unit, so we are 
1855     // independent of zoom factor and so on... 
1857     const wxGTKDash 
*req_dash
; 
1859     GdkLineStyle lineStyle 
= GDK_LINE_SOLID
; 
1860     switch (m_pen
.GetStyle()) 
1864             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1865             req_nb_dash 
= m_pen
.GetDashCount(); 
1866             req_dash 
= (wxGTKDash
*)m_pen
.GetDash(); 
1871             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1878             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1880             req_dash 
= wxCoord_dashed
; 
1885             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1887             req_dash 
= short_dashed
; 
1892 //            lineStyle = GDK_LINE_DOUBLE_DASH; 
1893             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1895             req_dash 
= dotted_dashed
; 
1900         case wxSTIPPLE_MASK_OPAQUE
: 
1905             lineStyle 
= GDK_LINE_SOLID
; 
1906             req_dash 
= (wxGTKDash
*)NULL
; 
1912 #if (GTK_MINOR_VERSION > 0) || (GTK_MAJOR_VERSION > 1) 
1913     if (req_dash 
&& req_nb_dash
) 
1915         wxGTKDash 
*real_req_dash 
= new wxGTKDash
[req_nb_dash
]; 
1918             for (int i 
= 0; i 
< req_nb_dash
; i
++) 
1919                 real_req_dash
[i
] = req_dash
[i
] * width
; 
1920             gdk_gc_set_dashes( m_penGC
, 0, real_req_dash
, req_nb_dash 
); 
1921             delete[] real_req_dash
; 
1925             // No Memory. We use non-scaled dash pattern... 
1926             gdk_gc_set_dashes( m_penGC
, 0, (wxGTKDash
*)req_dash
, req_nb_dash 
); 
1929 #endif // GTK+ > 1.0 
1931     GdkCapStyle capStyle 
= GDK_CAP_ROUND
; 
1932     switch (m_pen
.GetCap()) 
1934         case wxCAP_PROJECTING
: { capStyle 
= GDK_CAP_PROJECTING
; break; } 
1935         case wxCAP_BUTT
:       { capStyle 
= GDK_CAP_BUTT
;       break; } 
1942                 capStyle 
= GDK_CAP_NOT_LAST
; 
1946                 capStyle 
= GDK_CAP_ROUND
; 
1952     GdkJoinStyle joinStyle 
= GDK_JOIN_ROUND
; 
1953     switch (m_pen
.GetJoin()) 
1955         case wxJOIN_BEVEL
: { joinStyle 
= GDK_JOIN_BEVEL
; break; } 
1956         case wxJOIN_MITER
: { joinStyle 
= GDK_JOIN_MITER
; break; } 
1958         default:           { joinStyle 
= GDK_JOIN_ROUND
; break; } 
1961     gdk_gc_set_line_attributes( m_penGC
, width
, lineStyle
, capStyle
, joinStyle 
); 
1963     m_pen
.GetColour().CalcPixel( m_cmap 
); 
1964     gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() ); 
1967 void wxWindowDC::SetBrush( const wxBrush 
&brush 
) 
1969     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1971     if (m_brush 
== brush
) return; 
1975     if (!m_brush
.Ok()) return; 
1977     if (!m_window
) return; 
1979     m_brush
.GetColour().CalcPixel( m_cmap 
); 
1980     gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() ); 
1982     gdk_gc_set_fill( m_brushGC
, GDK_SOLID 
); 
1984     if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok())) 
1986         if (m_brush
.GetStipple()->GetPixmap()) 
1988             gdk_gc_set_fill( m_brushGC
, GDK_TILED 
); 
1989             gdk_gc_set_tile( m_brushGC
, m_brush
.GetStipple()->GetPixmap() ); 
1993             gdk_gc_set_fill( m_brushGC
, GDK_STIPPLED 
); 
1994             gdk_gc_set_stipple( m_brushGC
, m_brush
.GetStipple()->GetBitmap() ); 
1998     if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
2000         gdk_gc_set_fill( m_textGC
, GDK_OPAQUE_STIPPLED
); 
2001         gdk_gc_set_stipple( m_textGC
, m_brush
.GetStipple()->GetMask()->GetBitmap() ); 
2004     if (IS_HATCH(m_brush
.GetStyle())) 
2006         gdk_gc_set_fill( m_brushGC
, GDK_STIPPLED 
); 
2007         int num 
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
; 
2008         gdk_gc_set_stipple( m_brushGC
, hatches
[num
] ); 
2012 void wxWindowDC::SetBackground( const wxBrush 
&brush 
) 
2014    /* CMB 21/7/98: Added SetBackground. Sets background brush 
2015     * for Clear() and bg colour for shapes filled with cross-hatch brush */ 
2017     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2019     if (m_backgroundBrush 
== brush
) return; 
2021     m_backgroundBrush 
= brush
; 
2023     if (!m_backgroundBrush
.Ok()) return; 
2025     if (!m_window
) return; 
2027     m_backgroundBrush
.GetColour().CalcPixel( m_cmap 
); 
2028     gdk_gc_set_background( m_brushGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2029     gdk_gc_set_background( m_penGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2030     gdk_gc_set_background( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2031     gdk_gc_set_foreground( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2033     gdk_gc_set_fill( m_bgGC
, GDK_SOLID 
); 
2035     if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok())) 
2037         if (m_backgroundBrush
.GetStipple()->GetPixmap()) 
2039             gdk_gc_set_fill( m_bgGC
, GDK_TILED 
); 
2040             gdk_gc_set_tile( m_bgGC
, m_backgroundBrush
.GetStipple()->GetPixmap() ); 
2044             gdk_gc_set_fill( m_bgGC
, GDK_STIPPLED 
); 
2045             gdk_gc_set_stipple( m_bgGC
, m_backgroundBrush
.GetStipple()->GetBitmap() ); 
2049     if (IS_HATCH(m_backgroundBrush
.GetStyle())) 
2051         gdk_gc_set_fill( m_bgGC
, GDK_STIPPLED 
); 
2052         int num 
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
; 
2053         gdk_gc_set_stipple( m_bgGC
, hatches
[num
] ); 
2057 void wxWindowDC::SetLogicalFunction( int function 
) 
2059     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2061     if (m_logicalFunction 
== function
) 
2064     // VZ: shouldn't this be a CHECK? 
2071         case wxXOR
:          mode 
= GDK_XOR
;           break; 
2072         case wxINVERT
:       mode 
= GDK_INVERT
;        break; 
2073 #if (GTK_MINOR_VERSION > 0) || (GTK_MAJOR_VERSION > 1) 
2074         case wxOR_REVERSE
:   mode 
= GDK_OR_REVERSE
;    break; 
2075         case wxAND_REVERSE
:  mode 
= GDK_AND_REVERSE
;   break; 
2076         case wxCLEAR
:        mode 
= GDK_CLEAR
;         break; 
2077         case wxSET
:          mode 
= GDK_SET
;           break; 
2078         case wxOR_INVERT
:    mode 
= GDK_OR_INVERT
;     break; 
2079         case wxAND
:          mode 
= GDK_AND
;           break; 
2080         case wxOR
:           mode 
= GDK_OR
;            break; 
2081         case wxEQUIV
:        mode 
= GDK_EQUIV
;         break; 
2082         case wxNAND
:         mode 
= GDK_NAND
;          break; 
2083         case wxAND_INVERT
:   mode 
= GDK_AND_INVERT
;    break; 
2084         case wxCOPY
:         mode 
= GDK_COPY
;          break; 
2085         case wxNO_OP
:        mode 
= GDK_NOOP
;          break; 
2086         case wxSRC_INVERT
:   mode 
= GDK_COPY_INVERT
;   break; 
2088         // unsupported by GTK 
2089         case wxNOR
:          mode 
= GDK_COPY
;          break; 
2090 #endif // GTK+ > 1.0 
2092            wxFAIL_MSG( wxT("unsupported logical function") ); 
2096     m_logicalFunction 
= function
; 
2098     gdk_gc_set_function( m_penGC
, mode 
); 
2099     gdk_gc_set_function( m_brushGC
, mode 
); 
2101     // to stay compatible with wxMSW, we don't apply ROPs to the text 
2102     // operations (i.e. DrawText/DrawRotatedText). 
2103     // True, but mono-bitmaps use the m_textGC and they use ROPs as well. 
2104     gdk_gc_set_function( m_textGC
, mode 
); 
2107 void wxWindowDC::SetTextForeground( const wxColour 
&col 
) 
2109     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2111     // don't set m_textForegroundColour to an invalid colour as we'd crash 
2112     // later then (we use m_textForegroundColour.GetColor() without checking 
2114     if ( !col
.Ok() || (m_textForegroundColour 
== col
) ) 
2117     m_textForegroundColour 
= col
; 
2121         m_textForegroundColour
.CalcPixel( m_cmap 
); 
2122         gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
2126 void wxWindowDC::SetTextBackground( const wxColour 
&col 
) 
2128     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2131     if ( !col
.Ok() || (m_textBackgroundColour 
== col
) ) 
2134     m_textBackgroundColour 
= col
; 
2138         m_textBackgroundColour
.CalcPixel( m_cmap 
); 
2139         gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() ); 
2143 void wxWindowDC::SetBackgroundMode( int mode 
) 
2145     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2147     m_backgroundMode 
= mode
; 
2149     if (!m_window
) return; 
2151     // CMB 21/7/98: fill style of cross-hatch brushes is affected by 
2152     // transparent/solid background mode 
2154     if (m_brush
.GetStyle() != wxSOLID 
&& m_brush
.GetStyle() != wxTRANSPARENT
) 
2156         gdk_gc_set_fill( m_brushGC
, 
2157           (m_backgroundMode 
== wxTRANSPARENT
) ? GDK_STIPPLED 
: GDK_OPAQUE_STIPPLED
); 
2161 void wxWindowDC::SetPalette( const wxPalette
& WXUNUSED(palette
) ) 
2163     wxFAIL_MSG( wxT("wxWindowDC::SetPalette not implemented") ); 
2166 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
2168     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2170     if (!m_window
) return; 
2173     rect
.x 
= XLOG2DEV(x
); 
2174     rect
.y 
= YLOG2DEV(y
); 
2175     rect
.width 
= XLOG2DEVREL(width
); 
2176     rect
.height 
= YLOG2DEVREL(height
); 
2178     if (!m_currentClippingRegion
.IsNull()) 
2179         m_currentClippingRegion
.Intersect( rect 
); 
2181         m_currentClippingRegion
.Union( rect 
); 
2183 #if USE_PAINT_REGION 
2184     if (!m_paintClippingRegion
.IsNull()) 
2185         m_currentClippingRegion
.Intersect( m_paintClippingRegion 
); 
2188     wxCoord xx
, yy
, ww
, hh
; 
2189     m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh 
); 
2190     wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh 
); 
2192     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2193     gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2194     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2195     gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2198 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion 
®ion  
) 
2200     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2204         DestroyClippingRegion(); 
2208     if (!m_window
) return; 
2210     if (!m_currentClippingRegion
.IsNull()) 
2211         m_currentClippingRegion
.Intersect( region 
); 
2213         m_currentClippingRegion
.Union( region 
); 
2215 #if USE_PAINT_REGION 
2216     if (!m_paintClippingRegion
.IsNull()) 
2217         m_currentClippingRegion
.Intersect( m_paintClippingRegion 
); 
2220     wxCoord xx
, yy
, ww
, hh
; 
2221     m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh 
); 
2222     wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh 
); 
2224     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2225     gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2226     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2227     gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2230 void wxWindowDC::DestroyClippingRegion() 
2232     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2234     wxDC::DestroyClippingRegion(); 
2236     m_currentClippingRegion
.Clear(); 
2238 #if USE_PAINT_REGION 
2239     if (!m_paintClippingRegion
.IsEmpty()) 
2240         m_currentClippingRegion
.Union( m_paintClippingRegion 
); 
2243     if (!m_window
) return; 
2245     if (m_currentClippingRegion
.IsEmpty()) 
2247         gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle 
*) NULL 
); 
2248         gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle 
*) NULL 
); 
2249         gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle 
*) NULL 
); 
2250         gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle 
*) NULL 
); 
2254         gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2255         gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2256         gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2257         gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2261 void wxWindowDC::Destroy() 
2263     if (m_penGC
) wxFreePoolGC( m_penGC 
); 
2264     m_penGC 
= (GdkGC
*) NULL
; 
2265     if (m_brushGC
) wxFreePoolGC( m_brushGC 
); 
2266     m_brushGC 
= (GdkGC
*) NULL
; 
2267     if (m_textGC
) wxFreePoolGC( m_textGC 
); 
2268     m_textGC 
= (GdkGC
*) NULL
; 
2269     if (m_bgGC
) wxFreePoolGC( m_bgGC 
); 
2270     m_bgGC 
= (GdkGC
*) NULL
; 
2273 void wxWindowDC::ComputeScaleAndOrigin() 
2275     /* CMB: copy scale to see if it changes */ 
2276     double origScaleX 
= m_scaleX
; 
2277     double origScaleY 
= m_scaleY
; 
2279     wxDC::ComputeScaleAndOrigin(); 
2281     /* CMB: if scale has changed call SetPen to recalulate the line width */ 
2282     if ((m_scaleX 
!= origScaleX 
|| m_scaleY 
!= origScaleY
) && 
2285       /* this is a bit artificial, but we need to force wxDC to think 
2286          the pen has changed */ 
2293 // Resolution in pixels per logical inch 
2294 wxSize 
wxWindowDC::GetPPI() const 
2296     return wxSize( (int) (m_mm_to_pix_x 
* 25.4 + 0.5), (int) (m_mm_to_pix_y 
* 25.4 + 0.5)); 
2299 int wxWindowDC::GetDepth() const 
2301     wxFAIL_MSG(wxT("not implemented")); 
2307 //----------------------------------------------------------------------------- 
2309 //----------------------------------------------------------------------------- 
2311 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
) 
2313 wxPaintDC::wxPaintDC( wxWindow 
*win 
) 
2316 #if USE_PAINT_REGION 
2317     if (!win
->m_clipPaintRegion
) 
2320     m_paintClippingRegion 
= win
->GetUpdateRegion(); 
2321     GdkRegion 
*region 
= m_paintClippingRegion
.GetRegion(); 
2324         m_paintClippingRegion 
= win
->GetUpdateRegion(); 
2325         GdkRegion 
*region 
= m_paintClippingRegion
.GetRegion(); 
2328             m_currentClippingRegion
.Union( m_paintClippingRegion 
); 
2330             gdk_gc_set_clip_region( m_penGC
, region 
); 
2331             gdk_gc_set_clip_region( m_brushGC
, region 
); 
2332             gdk_gc_set_clip_region( m_textGC
, region 
); 
2333             gdk_gc_set_clip_region( m_bgGC
, region 
); 
2336 #endif // USE_PAINT_REGION 
2339 //----------------------------------------------------------------------------- 
2341 //----------------------------------------------------------------------------- 
2343 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
) 
2345 wxClientDC::wxClientDC( wxWindow 
*win 
) 
2348     wxCHECK_RET( win
, _T("NULL window in wxClientDC::wxClientDC") ); 
2350 #ifdef __WXUNIVERSAL__ 
2351     wxPoint ptOrigin 
= win
->GetClientAreaOrigin(); 
2352     SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
); 
2353     wxSize size 
= win
->GetClientSize(); 
2354     SetClippingRegion(wxPoint(0, 0), size
); 
2355 #endif // __WXUNIVERSAL__ 
2358 void wxClientDC::DoGetSize(int *width
, int *height
) const 
2360     wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") ); 
2362     m_owner
->GetClientSize( width
, height 
); 
2365 // ---------------------------------------------------------------------------- 
2367 // ---------------------------------------------------------------------------- 
2369 class wxDCModule 
: public wxModule
 
2376     DECLARE_DYNAMIC_CLASS(wxDCModule
) 
2379 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
) 
2381 bool wxDCModule::OnInit() 
2387 void wxDCModule::OnExit()