]>
git.saurik.com Git - wxWidgets.git/blob - src/gtk/dcclient.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        gtk/dcclient.cpp 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling, Chris Breeze 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  11 #pragma implementation "dcclient.h" 
  15 #define XCopyPlane XCOPYPLANE 
  18 #include "wx/dcclient.h" 
  19 #include "wx/dcmemory.h" 
  21 #include "wx/module.h" 
  23 #include "wx/fontutil.h" 
  25 #include "wx/gtk/win_gtk.h" 
  27 #include <math.h>               // for floating-point functions 
  31 #include <gdk/gdkprivate.h> 
  34 //----------------------------------------------------------------------------- 
  36 //----------------------------------------------------------------------------- 
  38 #define USE_PAINT_REGION 1 
  40 //----------------------------------------------------------------------------- 
  42 //----------------------------------------------------------------------------- 
  52 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH) 
  53 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH) 
  56 static GdkPixmap  
*hatches
[num_hatches
]; 
  57 static GdkPixmap 
**hatch_bitmap 
= (GdkPixmap 
**) NULL
; 
  59 extern GtkWidget 
*wxGetRootWindow(); 
  61 //----------------------------------------------------------------------------- 
  63 //----------------------------------------------------------------------------- 
  65 const double RAD2DEG  
= 180.0 / M_PI
; 
  67 // ---------------------------------------------------------------------------- 
  69 // ---------------------------------------------------------------------------- 
  71 static inline double dmax(double a
, double b
) { return a 
> b 
? a 
: b
; } 
  72 static inline double dmin(double a
, double b
) { return a 
< b 
? a 
: b
; } 
  74 static inline double DegToRad(double deg
) { return (deg 
* M_PI
) / 180.0; } 
  76 //----------------------------------------------------------------------------- 
  77 // temporary implementation of the missing GDK function 
  78 //----------------------------------------------------------------------------- 
  80 #include "gdk/gdkprivate.h" 
  82 void gdk_wx_draw_bitmap(GdkDrawable  
*drawable
, 
  92     gint src_width
, src_height
; 
  94     GdkWindowPrivate 
*drawable_private
; 
  95     GdkWindowPrivate 
*src_private
; 
  96     GdkGCPrivate 
*gc_private
; 
  99     g_return_if_fail (drawable 
!= NULL
); 
 100     g_return_if_fail (src 
!= NULL
); 
 101     g_return_if_fail (gc 
!= NULL
); 
 104     if (GDK_WINDOW_DESTROYED(drawable
) || GDK_WINDOW_DESTROYED(src
)) 
 107     gdk_drawable_get_size(src
, &src_width
, &src_height
); 
 109     drawable_private 
= (GdkWindowPrivate
*) drawable
; 
 110     src_private 
= (GdkWindowPrivate
*) src
; 
 111     if (drawable_private
->destroyed 
|| src_private
->destroyed
) 
 114     src_width 
= src_private
->width
; 
 115     src_height 
= src_private
->height
; 
 117     gc_private 
= (GdkGCPrivate
*) gc
; 
 120     if (width 
== -1) width 
= src_width
; 
 121     if (height 
== -1) height 
= src_height
; 
 124     XCopyPlane( GDK_WINDOW_XDISPLAY(drawable
), 
 126                 GDK_WINDOW_XID(drawable
), 
 133     XCopyPlane( drawable_private
->xdisplay
, 
 134                 src_private
->xwindow
, 
 135                 drawable_private
->xwindow
, 
 144 //----------------------------------------------------------------------------- 
 145 // Implement Pool of Graphic contexts. Creating them takes too much time. 
 146 //----------------------------------------------------------------------------- 
 148 #define GC_POOL_SIZE 200 
 174 #define GC_POOL_ALLOC_SIZE 100 
 176 static int wxGCPoolSize 
= 0; 
 178 static wxGC 
*wxGCPool 
= NULL
; 
 180 static void wxInitGCPool() 
 182     // This really could wait until the first call to 
 183     // wxGetPoolGC, but we will make the first allocation 
 184     // now when other initialization is being performed. 
 186     // Set initial pool size. 
 187     wxGCPoolSize 
= GC_POOL_ALLOC_SIZE
; 
 189     // Allocate initial pool. 
 190     wxGCPool 
= (wxGC 
*)malloc(wxGCPoolSize 
* sizeof(wxGC
)); 
 191     if (wxGCPool 
== NULL
) 
 193         // If we cannot malloc, then fail with error 
 194         // when debug is enabled.  If debug is not enabled, 
 195         // the problem will eventually get caught 
 197         wxFAIL_MSG( wxT("Cannot allocate GC pool") ); 
 201     // Zero initial pool. 
 202     memset(wxGCPool
, 0, wxGCPoolSize 
* sizeof(wxGC
)); 
 205 static void wxCleanUpGCPool() 
 207     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 209         if (wxGCPool
[i
].m_gc
) 
 210             gdk_gc_unref( wxGCPool
[i
].m_gc 
); 
 218 static GdkGC
* wxGetPoolGC( GdkWindow 
*window
, wxPoolGCType type 
) 
 222     // Look for an available GC. 
 223     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 225         if (!wxGCPool
[i
].m_gc
) 
 227             wxGCPool
[i
].m_gc 
= gdk_gc_new( window 
); 
 228             gdk_gc_set_exposures( wxGCPool
[i
].m_gc
, FALSE 
); 
 229             wxGCPool
[i
].m_type 
= type
; 
 230             wxGCPool
[i
].m_used 
= FALSE
; 
 232         if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type 
== type
)) 
 234             wxGCPool
[i
].m_used 
= TRUE
; 
 235             return wxGCPool
[i
].m_gc
; 
 239     // We did not find an available GC. 
 240     // We need to grow the GC pool. 
 241     pptr 
= (wxGC 
*)realloc(wxGCPool
, 
 242                 (wxGCPoolSize 
+ GC_POOL_ALLOC_SIZE
)*sizeof(wxGC
)); 
 245         // Initialize newly allocated pool. 
 247         memset(&wxGCPool
[wxGCPoolSize
], 0, 
 248                         GC_POOL_ALLOC_SIZE
*sizeof(wxGC
)); 
 250         // Initialize entry we will return.     
 251         wxGCPool
[wxGCPoolSize
].m_gc 
= gdk_gc_new( window 
); 
 252         gdk_gc_set_exposures( wxGCPool
[wxGCPoolSize
].m_gc
, FALSE 
); 
 253         wxGCPool
[wxGCPoolSize
].m_type 
= type
; 
 254         wxGCPool
[wxGCPoolSize
].m_used 
= TRUE
; 
 256         // Set new value of pool size. 
 257         wxGCPoolSize 
+= GC_POOL_ALLOC_SIZE
; 
 259         // Return newly allocated entry. 
 260         return wxGCPool
[wxGCPoolSize
-GC_POOL_ALLOC_SIZE
].m_gc
; 
 263     // The realloc failed.  Fall through to error. 
 264     wxFAIL_MSG( wxT("No GC available") ); 
 266     return (GdkGC
*) NULL
; 
 269 static void wxFreePoolGC( GdkGC 
*gc 
) 
 271     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 273         if (wxGCPool
[i
].m_gc 
== gc
) 
 275             wxGCPool
[i
].m_used 
= FALSE
; 
 280     wxFAIL_MSG( wxT("Wrong GC") ); 
 283 //----------------------------------------------------------------------------- 
 285 //----------------------------------------------------------------------------- 
 287 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
) 
 289 wxWindowDC::wxWindowDC() 
 291     m_penGC 
= (GdkGC 
*) NULL
; 
 292     m_brushGC 
= (GdkGC 
*) NULL
; 
 293     m_textGC 
= (GdkGC 
*) NULL
; 
 294     m_bgGC 
= (GdkGC 
*) NULL
; 
 295     m_cmap 
= (GdkColormap 
*) NULL
; 
 297     m_isScreenDC 
= FALSE
; 
 298     m_owner 
= (wxWindow 
*)NULL
; 
 300     m_context 
= (PangoContext 
*)NULL
; 
 301     m_layout 
= (PangoLayout 
*)NULL
; 
 302     m_fontdesc 
= (PangoFontDescription 
*)NULL
; 
 306 wxWindowDC::wxWindowDC( wxWindow 
*window 
) 
 308     wxASSERT_MSG( window
, wxT("DC needs a window") ); 
 310     m_penGC 
= (GdkGC 
*) NULL
; 
 311     m_brushGC 
= (GdkGC 
*) NULL
; 
 312     m_textGC 
= (GdkGC 
*) NULL
; 
 313     m_bgGC 
= (GdkGC 
*) NULL
; 
 314     m_cmap 
= (GdkColormap 
*) NULL
; 
 315     m_owner 
= (wxWindow 
*)NULL
; 
 317     m_isScreenDC 
= FALSE
; 
 318     m_font 
= window
->GetFont(); 
 320     GtkWidget 
*widget 
= window
->m_wxwindow
; 
 322     // Some controls don't have m_wxwindow - like wxStaticBox, but the user 
 323     // code should still be able to create wxClientDCs for them, so we will 
 324     // use the parent window here then. 
 327         window 
= window
->GetParent(); 
 328         widget 
= window
->m_wxwindow
; 
 331     wxASSERT_MSG( widget
, wxT("DC needs a widget") ); 
 334     m_context 
= window
->GtkGetPangoDefaultContext(); 
 335     m_layout 
= pango_layout_new( m_context 
); 
 336     m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
 339     GtkPizza 
*pizza 
= GTK_PIZZA( widget 
); 
 340     m_window 
= pizza
->bin_window
; 
 342     // Window not realized ? 
 345          // Don't report problems as per MSW. 
 351     m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
 355     /* this must be done after SetUpDC, bacause SetUpDC calls the 
 356        repective SetBrush, SetPen, SetBackground etc functions 
 357        to set up the DC. SetBackground call m_owner->SetBackground 
 358        and this might not be desired as the standard dc background 
 359        is white whereas a window might assume gray to be the 
 360        standard (as e.g. wxStatusBar) */ 
 365 wxWindowDC::~wxWindowDC() 
 371         g_object_unref( G_OBJECT( m_layout 
) ); 
 373         pango_font_description_free( m_fontdesc 
); 
 377 void wxWindowDC::SetUpDC() 
 381     wxASSERT_MSG( !m_penGC
, wxT("GCs already created") ); 
 385         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_SCREEN 
); 
 386         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_SCREEN 
); 
 387         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_SCREEN 
); 
 388         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_SCREEN 
); 
 391     if (m_isMemDC 
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1)) 
 393         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_MONO 
); 
 394         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_MONO 
); 
 395         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_MONO 
); 
 396         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_MONO 
); 
 400         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_COLOUR 
); 
 401         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_COLOUR 
); 
 402         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_COLOUR 
); 
 403         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_COLOUR 
); 
 406     /* background colour */ 
 407     m_backgroundBrush 
= *wxWHITE_BRUSH
; 
 408     m_backgroundBrush
.GetColour().CalcPixel( m_cmap 
); 
 409     GdkColor 
*bg_col 
= m_backgroundBrush
.GetColour().GetColor(); 
 412     m_textForegroundColour
.CalcPixel( m_cmap 
); 
 413     gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
 415     m_textBackgroundColour
.CalcPixel( m_cmap 
); 
 416     gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() ); 
 418     gdk_gc_set_fill( m_textGC
, GDK_SOLID 
); 
 421     m_pen
.GetColour().CalcPixel( m_cmap 
); 
 422     gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() ); 
 423     gdk_gc_set_background( m_penGC
, bg_col 
); 
 425     gdk_gc_set_line_attributes( m_penGC
, 0, GDK_LINE_SOLID
, GDK_CAP_NOT_LAST
, GDK_JOIN_ROUND 
); 
 428     m_brush
.GetColour().CalcPixel( m_cmap 
); 
 429     gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() ); 
 430     gdk_gc_set_background( m_brushGC
, bg_col 
); 
 432     gdk_gc_set_fill( m_brushGC
, GDK_SOLID 
); 
 435     gdk_gc_set_background( m_bgGC
, bg_col 
); 
 436     gdk_gc_set_foreground( m_bgGC
, bg_col 
); 
 438     gdk_gc_set_fill( m_bgGC
, GDK_SOLID 
); 
 441     gdk_gc_set_function( m_textGC
, GDK_COPY 
); 
 442     gdk_gc_set_function( m_brushGC
, GDK_COPY 
); 
 443     gdk_gc_set_function( m_penGC
, GDK_COPY 
); 
 446     gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle 
*) NULL 
); 
 447     gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle 
*) NULL 
); 
 448     gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle 
*) NULL 
); 
 449     gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle 
*) NULL 
); 
 453         hatch_bitmap    
= hatches
; 
 454         hatch_bitmap
[0] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, bdiag_bits
, bdiag_width
, bdiag_height 
); 
 455         hatch_bitmap
[1] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, cdiag_bits
, cdiag_width
, cdiag_height 
); 
 456         hatch_bitmap
[2] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, fdiag_bits
, fdiag_width
, fdiag_height 
); 
 457         hatch_bitmap
[3] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, cross_bits
, cross_width
, cross_height 
); 
 458         hatch_bitmap
[4] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, horiz_bits
, horiz_width
, horiz_height 
); 
 459         hatch_bitmap
[5] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, verti_bits
, verti_width
, verti_height 
); 
 463 void wxWindowDC::DoGetSize( int* width
, int* height 
) const 
 465     wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") ); 
 467     m_owner
->GetSize(width
, height
); 
 470 extern bool wxDoFloodFill(wxDC 
*dc
, wxCoord x
, wxCoord y
,  
 471                           const wxColour 
& col
, int style
); 
 473 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
, 
 474                              const wxColour
& col
, int style
) 
 476     return wxDoFloodFill(this, x
, y
, col
, style
); 
 479 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour 
*col 
) const 
 481     // Generic (and therefore rather inefficient) method. 
 482     // Could be improved. 
 484     wxBitmap 
bitmap(1, 1); 
 485     memdc
.SelectObject(bitmap
); 
 486     memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
); 
 487     memdc
.SelectObject(wxNullBitmap
); 
 489     wxImage image 
= bitmap
.ConvertToImage(); 
 490     col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0)); 
 494 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2 
) 
 496     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 498     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 501             gdk_draw_line( m_window
, m_penGC
, XLOG2DEV(x1
), YLOG2DEV(y1
), XLOG2DEV(x2
), YLOG2DEV(y2
) ); 
 503         CalcBoundingBox(x1
, y1
); 
 504         CalcBoundingBox(x2
, y2
); 
 508 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y 
) 
 510     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 512     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 517         wxCoord xx 
= XLOG2DEV(x
); 
 518         wxCoord yy 
= YLOG2DEV(y
); 
 521             gdk_draw_line( m_window
, m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy 
); 
 522             gdk_draw_line( m_window
, m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) ); 
 527 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, 
 528                             wxCoord xc
, wxCoord yc 
) 
 530     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 532     wxCoord xx1 
= XLOG2DEV(x1
); 
 533     wxCoord yy1 
= YLOG2DEV(y1
); 
 534     wxCoord xx2 
= XLOG2DEV(x2
); 
 535     wxCoord yy2 
= YLOG2DEV(y2
); 
 536     wxCoord xxc 
= XLOG2DEV(xc
); 
 537     wxCoord yyc 
= YLOG2DEV(yc
); 
 538     double dx 
= xx1 
- xxc
; 
 539     double dy 
= yy1 
- yyc
; 
 540     double radius 
= sqrt((double)(dx
*dx
+dy
*dy
)); 
 541     wxCoord   r      
= (wxCoord
)radius
; 
 542     double radius1
, radius2
; 
 544     if (xx1 
== xx2 
&& yy1 
== yy2
) 
 552         radius1 
= radius2 
= 0.0; 
 556         radius1 
= (xx1 
- xxc 
== 0) ? 
 557             (yy1 
- yyc 
< 0) ? 90.0 : -90.0 : 
 558             -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
; 
 559         radius2 
= (xx2 
- xxc 
== 0) ? 
 560             (yy2 
- yyc 
< 0) ? 90.0 : -90.0 : 
 561             -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
; 
 563     wxCoord alpha1 
= wxCoord(radius1 
* 64.0); 
 564     wxCoord alpha2 
= wxCoord((radius2 
- radius1
) * 64.0); 
 565     while (alpha2 
<= 0) alpha2 
+= 360*64; 
 566     while (alpha1 
> 360*64) alpha1 
-= 360*64; 
 570         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 572             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 574                 gdk_gc_set_ts_origin( m_textGC
, 
 575                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 576                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 577                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 578                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 580             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 582                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 583                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 584                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 586             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 588                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 589                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 590                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 592             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 594                 gdk_gc_set_ts_origin( m_brushGC
, 
 595                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 596                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 597                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 598                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 602                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 606         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 608             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 610             gdk_draw_line( m_window
, m_penGC
, xx1
, yy1
, xxc
, yyc 
); 
 611             gdk_draw_line( m_window
, m_penGC
, xxc
, yyc
, xx2
, yy2 
); 
 615     CalcBoundingBox (x1
, y1
); 
 616     CalcBoundingBox (x2
, y2
); 
 619 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea 
) 
 621     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 623     wxCoord xx 
= XLOG2DEV(x
); 
 624     wxCoord yy 
= YLOG2DEV(y
); 
 625     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 626     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 628     // CMB: handle -ve width and/or height 
 629     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 630     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 634         wxCoord start 
= wxCoord(sa 
* 64.0); 
 635         wxCoord end 
= wxCoord((ea
-sa
) * 64.0); 
 637         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 639             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 641                 gdk_gc_set_ts_origin( m_textGC
, 
 642                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 643                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 644                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 645                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 647             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 649                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 650                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 651                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 653             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 655                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 656                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 657                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 659             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 661                 gdk_gc_set_ts_origin( m_brushGC
, 
 662                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 663                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 664                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 665                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 669                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 673         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 674             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, start
, end 
); 
 677     CalcBoundingBox (x
, y
); 
 678     CalcBoundingBox (x 
+ width
, y 
+ height
); 
 681 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y 
) 
 683     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 685     if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
) 
 686         gdk_draw_point( m_window
, m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
 688     CalcBoundingBox (x
, y
); 
 691 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset 
) 
 693     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 695     if (m_pen
.GetStyle() == wxTRANSPARENT
) return; 
 698     GdkPoint 
*gpts 
= new GdkPoint
[n
]; 
 701         wxFAIL_MSG( wxT("Cannot allocate PolyLine") ); 
 705     for (int i 
= 0; i 
< n
; i
++)  
 707         wxCoord x1 
= XLOG2DEV(points
[i
].x 
+ xoffset
); 
 708         wxCoord y1 
= YLOG2DEV(points
[i
].y 
+ yoffset
); 
 710         CalcBoundingBox( x1 
+ xoffset
, y1 
+ yoffset 
); 
 717         gdk_draw_lines( m_window
, m_penGC
, gpts
, n
); 
 722 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int WXUNUSED(fillStyle
) ) 
 724     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 728     GdkPoint 
*gdkpoints 
= new GdkPoint
[n
+1]; 
 730     for (i 
= 0 ; i 
< n 
; i
++) 
 732         gdkpoints
[i
].x 
= XLOG2DEV(points
[i
].x 
+ xoffset
); 
 733         gdkpoints
[i
].y 
= YLOG2DEV(points
[i
].y 
+ yoffset
); 
 735         CalcBoundingBox( points
[i
].x 
+ xoffset
, points
[i
].y 
+ yoffset 
); 
 740         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 742             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 744                 gdk_gc_set_ts_origin( m_textGC
, 
 745                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 746                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 747                 gdk_draw_polygon( m_window
, m_textGC
, TRUE
, gdkpoints
, n 
); 
 748                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 750             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 752                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 753                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 754                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 756             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 758                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 759                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 760                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 762             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 764                 gdk_gc_set_ts_origin( m_brushGC
, 
 765                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 766                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 767                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 768                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 772                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 776         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 778             for (i 
= 0 ; i 
< n 
; i
++) 
 780                 gdk_draw_line( m_window
, m_penGC
, 
 783                                gdkpoints
[(i
+1)%n
].x
, 
 784                                gdkpoints
[(i
+1)%n
].y
); 
 792 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 794     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 796     wxCoord xx 
= XLOG2DEV(x
); 
 797     wxCoord yy 
= YLOG2DEV(y
); 
 798     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 799     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 801     // CMB: draw nothing if transformed w or h is 0 
 802     if (ww 
== 0 || hh 
== 0) return; 
 804     // CMB: handle -ve width and/or height 
 805     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 806     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 810         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 812             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 814                 gdk_gc_set_ts_origin( m_textGC
, 
 815                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 816                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 817                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 818                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 820             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 822                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 823                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 824                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 826             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 828                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 829                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 830                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 832             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 834                 gdk_gc_set_ts_origin( m_brushGC
, 
 835                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 836                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 837                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 838                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 842                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 846         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 847             gdk_draw_rectangle( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
-1, hh
-1 ); 
 850     CalcBoundingBox( x
, y 
); 
 851     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
 854 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius 
) 
 856     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 858     if (radius 
< 0.0) radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
 860     wxCoord xx 
= XLOG2DEV(x
); 
 861     wxCoord yy 
= YLOG2DEV(y
); 
 862     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 863     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 864     wxCoord rr 
= XLOG2DEVREL((wxCoord
)radius
); 
 866     // CMB: handle -ve width and/or height 
 867     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 868     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 870     // CMB: if radius is zero use DrawRectangle() instead to avoid 
 871     // X drawing errors with small radii 
 874         DrawRectangle( x
, y
, width
, height 
); 
 878     // CMB: draw nothing if transformed w or h is 0 
 879     if (ww 
== 0 || hh 
== 0) return; 
 881     // CMB: adjust size if outline is drawn otherwise the result is 
 882     // 1 pixel too wide and high 
 883     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 891         // CMB: ensure dd is not larger than rectangle otherwise we 
 892         // get an hour glass shape 
 894         if (dd 
> ww
) dd 
= ww
; 
 895         if (dd 
> hh
) dd 
= hh
; 
 898         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 900             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 902                 gdk_gc_set_ts_origin( m_textGC
, 
 903                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 904                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 905                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 906                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 907                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 908                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 909                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 910                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 911                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 913             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 915                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 916                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 917                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 918                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 919                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 920                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 921                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 922                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 924             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 926                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 927                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 928                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 929                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 930                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 931                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 932                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 933                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 935             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 937                 gdk_gc_set_ts_origin( m_brushGC
, 
 938                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 939                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 940                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 941                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 942                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 943                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 944                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 945                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 946                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 950                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 951                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 952                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 953                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 954                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 955                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 959         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 961             gdk_draw_line( m_window
, m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy 
); 
 962             gdk_draw_line( m_window
, m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh 
); 
 963             gdk_draw_line( m_window
, m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr 
); 
 964             gdk_draw_line( m_window
, m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr 
); 
 965             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 966             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 967             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 968             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 972     // this ignores the radius 
 973     CalcBoundingBox( x
, y 
); 
 974     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
 977 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 979     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 981     wxCoord xx 
= XLOG2DEV(x
); 
 982     wxCoord yy 
= YLOG2DEV(y
); 
 983     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 984     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 986     // CMB: handle -ve width and/or height 
 987     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 988     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 992         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 994             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 996                 gdk_gc_set_ts_origin( m_textGC
, 
 997                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 998                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 999                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1000                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
1002             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
1004                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
1005                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1006                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1008             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
1010                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
1011                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1012                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1014             if (m_brush
.GetStyle() == wxSTIPPLE
) 
1016                 gdk_gc_set_ts_origin( m_brushGC
, 
1017                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
1018                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
1019                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1020                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1024                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1028         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1029             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1032     CalcBoundingBox( x
, y 
); 
1033     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
1036 void wxWindowDC::DoDrawIcon( const wxIcon 
&icon
, wxCoord x
, wxCoord y 
) 
1038     // VZ: egcs 1.0.3 refuses to compile this without cast, no idea why 
1039     DoDrawBitmap( (const wxBitmap
&)icon
, x
, y
, (bool)TRUE 
); 
1042 void wxWindowDC::DoDrawBitmap( const wxBitmap 
&bitmap
, 
1043                                wxCoord x
, wxCoord y
, 
1046     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1048     wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") ); 
1050     bool is_mono 
= (bitmap
.GetBitmap() != NULL
); 
1052     /* scale/translate size and position */ 
1053     int xx 
= XLOG2DEV(x
); 
1054     int yy 
= YLOG2DEV(y
); 
1056     int w 
= bitmap
.GetWidth(); 
1057     int h 
= bitmap
.GetHeight(); 
1059     CalcBoundingBox( x
, y 
); 
1060     CalcBoundingBox( x 
+ w
, y 
+ h 
); 
1062     if (!m_window
) return; 
1064     int ww 
= XLOG2DEVREL(w
); 
1065     int hh 
= YLOG2DEVREL(h
); 
1067     /* compare to current clipping region */ 
1068     if (!m_currentClippingRegion
.IsNull()) 
1070         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1071         tmp
.Intersect( m_currentClippingRegion 
); 
1076     /* scale bitmap if required */ 
1077     wxBitmap use_bitmap
; 
1078     if ((w 
!= ww
) || (h 
!= hh
)) 
1080         wxImage image 
= bitmap
.ConvertToImage(); 
1081         image
.Rescale( ww
, hh 
); 
1083             use_bitmap 
= wxBitmap(image
.ConvertToMono(255,255,255), 1); 
1085             use_bitmap 
= wxBitmap(image
); 
1089         use_bitmap 
= bitmap
; 
1092     /* apply mask if any */ 
1093     GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1094     if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1096         if (useMask 
&& mask
) 
1098             GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1099 #ifndef __WXGTK20__  // TODO fix crash 
1100             if (!m_currentClippingRegion
.IsNull()) 
1103                 new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 ); 
1104                 GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1106                 gdk_gc_set_foreground( gc
, &col 
); 
1107                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1109                 gdk_gc_set_background( gc
, &col 
); 
1111                 gdk_gc_set_foreground( gc
, &col 
); 
1112                 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1113                 gdk_gc_set_clip_origin( gc
, -xx
, -yy 
); 
1114                 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1115                 gdk_gc_set_stipple( gc
, mask 
); 
1116                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1123                     gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1125                     gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1126                 gdk_gc_set_clip_origin( m_textGC
, xx
, yy 
); 
1131                     gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1133                     gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1134                 gdk_gc_set_clip_origin( m_penGC
, xx
, yy 
); 
1138                 gdk_bitmap_unref( new_mask 
); 
1141     /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1142        drawing a mono-bitmap (XBitmap) we use the current text GC */ 
1144         gdk_wx_draw_bitmap( m_window
, m_textGC
, use_bitmap
.GetBitmap(), 0, 0, xx
, yy
, -1, -1 ); 
1146         gdk_draw_pixmap( m_window
, m_penGC
, use_bitmap
.GetPixmap(), 0, 0, xx
, yy
, -1, -1 ); 
1148     /* remove mask again if any */ 
1149     if (useMask 
&& mask
) 
1153             gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1154             gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1155             if (!m_currentClippingRegion
.IsNull()) 
1156                 gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1160             gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1161             gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1162             if (!m_currentClippingRegion
.IsNull()) 
1163                 gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1168 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, 
1169                          wxCoord width
, wxCoord height
, 
1171                          wxCoord xsrc
, wxCoord ysrc
, 
1174                          wxCoord xsrcMask
, wxCoord ysrcMask 
) 
1176    /* this is the nth try to get this utterly useless function to 
1177       work. it now completely ignores the scaling or translation 
1178       of the source dc, but scales correctly on the target dc and 
1179       knows about possible mask information in a memory dc. */ 
1181     wxCHECK_MSG( Ok(), FALSE
, wxT("invalid window dc") ); 
1183     wxCHECK_MSG( source
, FALSE
, wxT("invalid source dc") ); 
1185     if (!m_window
) return FALSE
; 
1188     // transform the source DC coords to the device ones 
1189     xsrc 
= source
->XLOG2DEV(xsrc
); 
1190     ysrc 
= source
->YLOG2DEV(ysrc
); 
1193     wxClientDC 
*srcDC 
= (wxClientDC
*)source
; 
1194     wxMemoryDC 
*memDC 
= (wxMemoryDC
*)source
; 
1196     bool use_bitmap_method 
= FALSE
; 
1197     bool is_mono 
= FALSE
; 
1199     /* TODO: use the mask origin when drawing transparently */ 
1200     if (xsrcMask 
== -1 && ysrcMask 
== -1) 
1202         xsrcMask 
= xsrc
; ysrcMask 
= ysrc
; 
1205     if (srcDC
->m_isMemDC
) 
1207         if (!memDC
->m_selected
.Ok()) return FALSE
; 
1209         /* we use the "XCopyArea" way to copy a memory dc into 
1210            y different window if the memory dc BOTH 
1211            a) doesn't have any mask or its mask isn't used 
1215         if (useMask 
&& (memDC
->m_selected
.GetMask())) 
1217            /* we HAVE TO use the direct way for memory dcs 
1218               that have mask since the XCopyArea doesn't know 
1220             use_bitmap_method 
= TRUE
; 
1222         else if (memDC
->m_selected
.GetDepth() == 1) 
1224            /* we HAVE TO use the direct way for memory dcs 
1225               that are bitmaps because XCopyArea doesn't cope 
1226               with different bit depths */ 
1228             use_bitmap_method 
= TRUE
; 
1230         else if ((xsrc 
== 0) && (ysrc 
== 0) && 
1231                  (width 
== memDC
->m_selected
.GetWidth()) && 
1232                  (height 
== memDC
->m_selected
.GetHeight())) 
1234            /* we SHOULD use the direct way if all of the bitmap 
1235               in the memory dc is copied in which case XCopyArea 
1236               wouldn't be able able to boost performace by reducing 
1237               the area to be scaled */ 
1238             use_bitmap_method 
= TRUE
; 
1242             use_bitmap_method 
= FALSE
; 
1246     CalcBoundingBox( xdest
, ydest 
); 
1247     CalcBoundingBox( xdest 
+ width
, ydest 
+ height 
); 
1249     /* scale/translate size and position */ 
1250     wxCoord xx 
= XLOG2DEV(xdest
); 
1251     wxCoord yy 
= YLOG2DEV(ydest
); 
1253     wxCoord ww 
= XLOG2DEVREL(width
); 
1254     wxCoord hh 
= YLOG2DEVREL(height
); 
1256     /* compare to current clipping region */ 
1257     if (!m_currentClippingRegion
.IsNull()) 
1259         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1260         tmp
.Intersect( m_currentClippingRegion 
); 
1265     int old_logical_func 
= m_logicalFunction
; 
1266     SetLogicalFunction( logical_func 
); 
1268     if (use_bitmap_method
) 
1270         /* scale/translate bitmap size */ 
1271         wxCoord bm_width 
= memDC
->m_selected
.GetWidth(); 
1272         wxCoord bm_height 
= memDC
->m_selected
.GetHeight(); 
1274         wxCoord bm_ww 
= XLOG2DEVREL( bm_width 
); 
1275         wxCoord bm_hh 
= YLOG2DEVREL( bm_height 
); 
1277         /* scale bitmap if required */ 
1278         wxBitmap use_bitmap
; 
1280         if ((bm_width 
!= bm_ww
) || (bm_height 
!= bm_hh
)) 
1282             wxImage image 
= memDC
->m_selected
.ConvertToImage(); 
1283             image 
= image
.Scale( bm_ww
, bm_hh 
); 
1286                 use_bitmap 
= wxBitmap(image
.ConvertToMono(255,255,255), 1); 
1288                 use_bitmap 
= wxBitmap(image
); 
1292             use_bitmap 
= memDC
->m_selected
; 
1295         /* apply mask if any */ 
1296         GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1297         if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1299         if (useMask 
&& mask
) 
1301             GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1302 #ifndef __WXGTK20__  // TODO fix crash 
1303             if (!m_currentClippingRegion
.IsNull()) 
1306                 new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 ); 
1307                 GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1309                 gdk_gc_set_foreground( gc
, &col 
); 
1310                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1312                 gdk_gc_set_background( gc
, &col 
); 
1314                 gdk_gc_set_foreground( gc
, &col 
); 
1315                 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1316                 gdk_gc_set_clip_origin( gc
, -xx
, -yy 
); 
1317                 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1318                 gdk_gc_set_stipple( gc
, mask 
); 
1319                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1326                     gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1328                     gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1329                 gdk_gc_set_clip_origin( m_textGC
, xx
, yy 
); 
1334                     gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1336                     gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1337                 gdk_gc_set_clip_origin( m_penGC
, xx
, yy 
); 
1340                 gdk_bitmap_unref( new_mask 
); 
1343         /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1344            drawing a mono-bitmap (XBitmap) we use the current text GC */ 
1347             gdk_wx_draw_bitmap( m_window
, m_textGC
, use_bitmap
.GetBitmap(), xsrc
, ysrc
, xx
, yy
, ww
, hh 
); 
1349             gdk_draw_pixmap( m_window
, m_penGC
, use_bitmap
.GetPixmap(), xsrc
, ysrc
, xx
, yy
, ww
, hh 
); 
1351         /* remove mask again if any */ 
1352         if (useMask 
&& mask
) 
1356                 gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1357                 gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1358                 if (!m_currentClippingRegion
.IsNull()) 
1359                     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1363                 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1364                 gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1365                 if (!m_currentClippingRegion
.IsNull()) 
1366                     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1370     else /* use_bitmap_method */ 
1372         if ((width 
!= ww
) || (height 
!= hh
)) 
1374             /* draw source window into a bitmap as we cannot scale 
1375                a window in contrast to a bitmap. this would actually 
1376                work with memory dcs as well, but we'd lose the mask 
1377                information and waste one step in this process since 
1378                a memory already has a bitmap. all this is slightly 
1379                inefficient as we could take an XImage directly from 
1380                an X window, but we'd then also have to care that 
1381                the window is not outside the screen (in which case 
1382                we'd get a BadMatch or what not). 
1383                Is a double XGetImage and combined XGetPixel and 
1384                XPutPixel really faster? I'm not sure. look at wxXt 
1385                for a different implementation of the same problem. */ 
1387             wxBitmap 
bitmap( width
, height 
); 
1389             /* copy including child window contents */ 
1390             gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS 
); 
1391             gdk_window_copy_area( bitmap
.GetPixmap(), m_penGC
, 0, 0, 
1393                                   xsrc
, ysrc
, width
, height 
); 
1394             gdk_gc_set_subwindow( m_penGC
, GDK_CLIP_BY_CHILDREN 
); 
1397             wxImage image 
= bitmap
.ConvertToImage(); 
1398             image 
= image
.Scale( ww
, hh 
); 
1400             /* convert to bitmap */ 
1401             bitmap 
= wxBitmap(image
); 
1403             /* draw scaled bitmap */ 
1404             gdk_draw_pixmap( m_window
, m_penGC
, bitmap
.GetPixmap(), 0, 0, xx
, yy
, -1, -1 ); 
1409             /* No scaling and not a memory dc with a mask either */ 
1411             /* copy including child window contents */ 
1412             gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS 
); 
1413             gdk_window_copy_area( m_window
, m_penGC
, xx
, yy
, 
1415                                   xsrc
, ysrc
, width
, height 
); 
1416             gdk_gc_set_subwindow( m_penGC
, GDK_CLIP_BY_CHILDREN 
); 
1420     SetLogicalFunction( old_logical_func 
); 
1424 void wxWindowDC::DoDrawText( const wxString 
&text
, wxCoord x
, wxCoord y 
) 
1426     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1428     if (!m_window
) return; 
1430     if (text
.empty()) return; 
1433     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1435     wxCHECK_RET( font
, wxT("invalid font") ); 
1442     wxCHECK_RET( m_context
, wxT("no Pango context") ); 
1443     wxCHECK_RET( m_layout
, wxT("no Pango layout") ); 
1444     wxCHECK_RET( m_fontdesc
, wxT("no Pango font description") ); 
1447     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( text 
); 
1449     const wxWCharBuffer wdata 
= wxConvLocal
.cMB2WC( text 
); 
1450     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( wdata 
); 
1452     pango_layout_set_text( m_layout
, (const char*) data
, strlen( (const char*) data 
)); 
1456     if (m_scaleY 
!= 1.0) 
1458          // If there is a user or actually any scale applied to 
1459          // the device context, scale the font. 
1461          // scale font description 
1462          gint oldSize 
= pango_font_description_get_size( m_fontdesc 
); 
1463          double size 
= oldSize
; 
1464          size 
= size 
* m_scaleY
; 
1465          pango_font_description_set_size( m_fontdesc
, (gint
)size 
); 
1467          // actually apply scaled font 
1468          pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1470          pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1471          if ( m_backgroundMode 
== wxSOLID 
) 
1473             gdk_gc_set_foreground(m_textGC
, m_textBackgroundColour
.GetColor()); 
1474             gdk_draw_rectangle(m_window
, m_textGC
, TRUE
, x
, y
, w
, h
); 
1475             gdk_gc_set_foreground(m_textGC
, m_textForegroundColour
.GetColor()); 
1479          gdk_draw_layout( m_window
, m_textGC
, x
, y
, m_layout 
); 
1481          // reset unscaled size 
1482          pango_font_description_set_size( m_fontdesc
, oldSize 
); 
1484          // actually apply unscaled font 
1485          pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1489         pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1490         if ( m_backgroundMode 
== wxSOLID 
) 
1492             gdk_gc_set_foreground(m_textGC
, m_textBackgroundColour
.GetColor()); 
1493             gdk_draw_rectangle(m_window
, m_textGC
, TRUE
, x
, y
, w
, h
); 
1494             gdk_gc_set_foreground(m_textGC
, m_textForegroundColour
.GetColor()); 
1497         gdk_draw_layout( m_window
, m_textGC
, x
, y
, m_layout 
); 
1504     wxCoord width 
= gdk_string_width( font
, text
.mbc_str() ); 
1505     wxCoord height 
= font
->ascent 
+ font
->descent
; 
1507     if ( m_backgroundMode 
== wxSOLID 
) 
1509         gdk_gc_set_foreground( m_textGC
, m_textBackgroundColour
.GetColor() ); 
1510         gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, x
, y
, width
, height 
); 
1511         gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
1513     gdk_draw_string( m_window
, font
, m_textGC
, x
, y 
+ font
->ascent
, text
.mbc_str() ); 
1515     /* CMB 17/7/98: simple underline: ignores scaling and underlying 
1516        X font's XA_UNDERLINE_POSITION and XA_UNDERLINE_THICKNESS 
1517        properties (see wxXt implementation) */ 
1518     if (m_font
.GetUnderlined()) 
1520         wxCoord ul_y 
= y 
+ font
->ascent
; 
1521         if (font
->descent 
> 0) ul_y
++; 
1522         gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x 
+ width
, ul_y
); 
1524 #endif // GTK+ 2.0/1.x 
1526     width 
= wxCoord(width 
/ m_scaleX
); 
1527     height 
= wxCoord(height 
/ m_scaleY
); 
1528     CalcBoundingBox (x 
+ width
, y 
+ height
); 
1529     CalcBoundingBox (x
, y
); 
1532 void wxWindowDC::DoDrawRotatedText( const wxString 
&text
, wxCoord x
, wxCoord y
, double angle 
) 
1536         DrawText(text
, x
, y
); 
1540     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1542     if (!m_window
) return; 
1545     // implement later without GdkFont for GTK 2.0 
1548     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1550     wxCHECK_RET( font
, wxT("invalid font") ); 
1552     // the size of the text 
1553     wxCoord w 
= gdk_string_width( font
, text
.mbc_str() ); 
1554     wxCoord h 
= font
->ascent 
+ font
->descent
; 
1556     // draw the string normally 
1559     dc
.SelectObject(src
); 
1560     dc
.SetFont(GetFont()); 
1561     dc
.SetBackground(*wxWHITE_BRUSH
); 
1562     dc
.SetBrush(*wxBLACK_BRUSH
); 
1564     dc
.DrawText(text
, 0, 0); 
1565     dc
.SelectObject(wxNullBitmap
); 
1567     // Calculate the size of the rotated bounding box. 
1568     double rad 
= DegToRad(angle
); 
1569     double dx 
= cos(rad
), 
1572     // the rectngle vertices are counted clockwise with the first one being at 
1573     // (0, 0) (or, rather, at (x, y)) 
1575            y2 
= -w
*dy
;      // y axis points to the bottom, hence minus 
1578     double x3 
= x4 
+ x2
, 
1582     wxCoord maxX 
= (wxCoord
)(dmax(x2
, dmax(x3
, x4
)) + 0.5), 
1583             maxY 
= (wxCoord
)(dmax(y2
, dmax(y3
, y4
)) + 0.5), 
1584             minX 
= (wxCoord
)(dmin(x2
, dmin(x3
, x4
)) - 0.5), 
1585             minY 
= (wxCoord
)(dmin(y2
, dmin(y3
, y4
)) - 0.5); 
1587     // prepare to blit-with-rotate the bitmap to the DC 
1588     wxImage image 
= src
.ConvertToImage(); 
1590     GdkColor 
*colText 
= m_textForegroundColour
.GetColor(), 
1591              *colBack 
= m_textBackgroundColour
.GetColor(); 
1593     bool textColSet 
= TRUE
; 
1595     unsigned char *data 
= image
.GetData(); 
1597     // paint pixel by pixel 
1598     for ( wxCoord srcX 
= 0; srcX 
< w
; srcX
++ ) 
1600         for ( wxCoord srcY 
= 0; srcY 
< h
; srcY
++ ) 
1602             // transform source coords to dest coords 
1603             double r 
= sqrt((double)srcX
*srcX 
+ srcY
*srcY
); 
1604             double angleOrig 
= atan2((double)srcY
, (double)srcX
) - rad
; 
1605             wxCoord dstX 
= (wxCoord
)(r
*cos(angleOrig
) + 0.5), 
1606                     dstY 
= (wxCoord
)(r
*sin(angleOrig
) + 0.5); 
1609             bool textPixel 
= data
[(srcY
*w 
+ srcX
)*3] == 0; 
1610             if ( textPixel 
|| (m_backgroundMode 
== wxSOLID
) ) 
1612                 // change colour if needed 
1613                 if ( textPixel 
!= textColSet 
) 
1615                     gdk_gc_set_foreground( m_textGC
, textPixel 
? colText
 
1618                     textColSet 
= textPixel
; 
1621                 // don't use DrawPoint() because it uses the current pen 
1622                 // colour, and we don't need it here 
1623                 gdk_draw_point( m_window
, m_textGC
, 
1624                                 XLOG2DEV(x
) + dstX
, YLOG2DEV(y
) + dstY 
); 
1629     // it would be better to draw with non underlined font and draw the line 
1630     // manually here (it would be more straight...) 
1632     if ( m_font
.GetUnderlined() ) 
1634         gdk_draw_line( m_window
, m_textGC
, 
1635                        XLOG2DEV(x 
+ x4
), YLOG2DEV(y 
+ y4 
+ font
->descent
), 
1636                        XLOG2DEV(x 
+ x3
), YLOG2DEV(y 
+ y3 
+ font
->descent
)); 
1640     // restore the font colour 
1641     gdk_gc_set_foreground( m_textGC
, colText 
); 
1643     // update the bounding box 
1644     CalcBoundingBox(x 
+ minX
, y 
+ minY
); 
1645     CalcBoundingBox(x 
+ maxX
, y 
+ maxY
); 
1649 void wxWindowDC::DoGetTextExtent(const wxString 
&string
, 
1650                                  wxCoord 
*width
, wxCoord 
*height
, 
1651                                  wxCoord 
*descent
, wxCoord 
*externalLeading
, 
1652                                  wxFont 
*theFont
) const 
1654     if (string
.IsEmpty()) 
1656         if (width
) (*width
) = 0; 
1657         if (height
) (*height
) = 0; 
1662     // Set new font description 
1664         pango_layout_set_font_description( m_layout
, theFont
->GetNativeFontInfo()->description 
); 
1666     // Set layout's text 
1668     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( string 
); 
1669     pango_layout_set_text( m_layout
, (const char*) data
, strlen( (const char*) data 
)); 
1671     const wxWCharBuffer wdata 
= wxConvLocal
.cMB2WC( string 
); 
1672     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( wdata 
); 
1673     pango_layout_set_text( m_layout
, (const char*) data
, strlen( (const char*) data 
)); 
1677     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1679     if (width
) (*width
) = (wxCoord
) w
;  
1680     if (height
) (*height
) = (wxCoord
) h
; 
1683         // Do something about metrics here. TODO. 
1686     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
1688     // Reset old font description 
1690         pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1692     wxFont fontToUse 
= m_font
; 
1693     if (theFont
) fontToUse 
= *theFont
; 
1695     GdkFont 
*font 
= fontToUse
.GetInternalFont( m_scaleY 
); 
1696     if (width
) (*width
) = wxCoord(gdk_string_width( font
, string
.mbc_str() ) / m_scaleX
); 
1697     if (height
) (*height
) = wxCoord((font
->ascent 
+ font
->descent
) / m_scaleY
); 
1698     if (descent
) (*descent
) = wxCoord(font
->descent 
/ m_scaleY
); 
1699     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
1703 wxCoord 
wxWindowDC::GetCharWidth() const 
1706     pango_layout_set_text( m_layout
, "H", 1 ); 
1708     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1711     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1712     wxCHECK_MSG( font
, -1, wxT("invalid font") ); 
1714     return wxCoord(gdk_string_width( font
, "H" ) / m_scaleX
); 
1718 wxCoord 
wxWindowDC::GetCharHeight() const 
1721     pango_layout_set_text( m_layout
, "H", 1 ); 
1723     pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1726     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1727     wxCHECK_MSG( font
, -1, wxT("invalid font") ); 
1729     return wxCoord((font
->ascent 
+ font
->descent
) / m_scaleY
); 
1733 void wxWindowDC::Clear() 
1735     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1737     if (!m_window
) return; 
1739     // VZ: the code below results in infinite recursion and crashes when 
1740     //     dc.Clear() is done from OnPaint() so I disable it for now. 
1741     //     I don't know what the correct fix is but Clear() surely should not 
1742     //     reenter OnPaint()! 
1744     /* - we either are a memory dc or have a window as the 
1745        owner. anything else shouldn't happen. 
1746        - we don't use gdk_window_clear() as we don't set 
1747        the window's background colour anymore. it is too 
1748        much pain to keep the DC's and the window's back- 
1749        ground colour in synch. */ 
1760         GetSize( &width
, &height 
); 
1761         gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height 
); 
1766     GetSize( &width
, &height 
); 
1767     gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height 
); 
1771 void wxWindowDC::SetFont( const wxFont 
&font 
) 
1779             pango_font_description_free( m_fontdesc 
); 
1781         m_fontdesc 
= pango_font_description_copy( m_font
.GetNativeFontInfo()->description 
); 
1786             PangoContext 
*oldContext 
= m_context
; 
1788             // We might want to use the X11 context for faster 
1789             // rendering on screen 
1790             if (m_font
.GetNoAntiAliasing()) 
1791                 m_context 
= m_owner
->GtkGetPangoX11Context(); 
1793                 m_context 
= m_owner
->GtkGetPangoDefaultContext(); 
1795             // If we switch back/forth between different contexts 
1796             // we also have to create a new layout. I think so, 
1797             // at least, and it doesn't hurt to do it.  
1798             if (oldContext 
!= m_context
) 
1801                     g_object_unref( G_OBJECT( m_layout 
) ); 
1803                 m_layout 
= pango_layout_new( m_context 
); 
1807         pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1812 void wxWindowDC::SetPen( const wxPen 
&pen 
) 
1814     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1816     if (m_pen 
== pen
) return; 
1820     if (!m_pen
.Ok()) return; 
1822     if (!m_window
) return; 
1824     gint width 
= m_pen
.GetWidth(); 
1827         // CMB: if width is non-zero scale it with the dc 
1832         // X doesn't allow different width in x and y and so we take 
1835                    ( fabs((double) XLOG2DEVREL(width
)) + 
1836                      fabs((double) YLOG2DEVREL(width
)) ) / 2.0; 
1840     static const wxGTKDash dotted
[] = {1, 1}; 
1841     static const wxGTKDash short_dashed
[] = {2, 2}; 
1842     static const wxGTKDash wxCoord_dashed
[] = {2, 4}; 
1843     static const wxGTKDash dotted_dashed
[] = {3, 3, 1, 3}; 
1845     // We express dash pattern in pen width unit, so we are 
1846     // independent of zoom factor and so on... 
1848     const wxGTKDash 
*req_dash
; 
1850     GdkLineStyle lineStyle 
= GDK_LINE_SOLID
; 
1851     switch (m_pen
.GetStyle()) 
1855             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1856             req_nb_dash 
= m_pen
.GetDashCount(); 
1857             req_dash 
= (wxGTKDash
*)m_pen
.GetDash(); 
1862             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1869             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1871             req_dash 
= wxCoord_dashed
; 
1876             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1878             req_dash 
= short_dashed
; 
1883 //            lineStyle = GDK_LINE_DOUBLE_DASH; 
1884             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1886             req_dash 
= dotted_dashed
; 
1891         case wxSTIPPLE_MASK_OPAQUE
: 
1896             lineStyle 
= GDK_LINE_SOLID
; 
1897             req_dash 
= (wxGTKDash
*)NULL
; 
1903 #if (GTK_MINOR_VERSION > 0) || (GTK_MAJOR_VERSION > 1) 
1904     if (req_dash 
&& req_nb_dash
) 
1906         wxGTKDash 
*real_req_dash 
= new wxGTKDash
[req_nb_dash
]; 
1909             for (int i 
= 0; i 
< req_nb_dash
; i
++) 
1910                 real_req_dash
[i
] = req_dash
[i
] * width
; 
1911             gdk_gc_set_dashes( m_penGC
, 0, real_req_dash
, req_nb_dash 
); 
1912             delete[] real_req_dash
; 
1916             // No Memory. We use non-scaled dash pattern... 
1917             gdk_gc_set_dashes( m_penGC
, 0, (wxGTKDash
*)req_dash
, req_nb_dash 
); 
1920 #endif // GTK+ > 1.0 
1922     GdkCapStyle capStyle 
= GDK_CAP_ROUND
; 
1923     switch (m_pen
.GetCap()) 
1925         case wxCAP_PROJECTING
: { capStyle 
= GDK_CAP_PROJECTING
; break; } 
1926         case wxCAP_BUTT
:       { capStyle 
= GDK_CAP_BUTT
;       break; } 
1933                 capStyle 
= GDK_CAP_NOT_LAST
; 
1937                 capStyle 
= GDK_CAP_ROUND
; 
1943     GdkJoinStyle joinStyle 
= GDK_JOIN_ROUND
; 
1944     switch (m_pen
.GetJoin()) 
1946         case wxJOIN_BEVEL
: { joinStyle 
= GDK_JOIN_BEVEL
; break; } 
1947         case wxJOIN_MITER
: { joinStyle 
= GDK_JOIN_MITER
; break; } 
1949         default:           { joinStyle 
= GDK_JOIN_ROUND
; break; } 
1952     gdk_gc_set_line_attributes( m_penGC
, width
, lineStyle
, capStyle
, joinStyle 
); 
1954     m_pen
.GetColour().CalcPixel( m_cmap 
); 
1955     gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() ); 
1958 void wxWindowDC::SetBrush( const wxBrush 
&brush 
) 
1960     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1962     if (m_brush 
== brush
) return; 
1966     if (!m_brush
.Ok()) return; 
1968     if (!m_window
) return; 
1970     m_brush
.GetColour().CalcPixel( m_cmap 
); 
1971     gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() ); 
1973     gdk_gc_set_fill( m_brushGC
, GDK_SOLID 
); 
1975     if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok())) 
1977         if (m_brush
.GetStipple()->GetPixmap()) 
1979             gdk_gc_set_fill( m_brushGC
, GDK_TILED 
); 
1980             gdk_gc_set_tile( m_brushGC
, m_brush
.GetStipple()->GetPixmap() ); 
1984             gdk_gc_set_fill( m_brushGC
, GDK_STIPPLED 
); 
1985             gdk_gc_set_stipple( m_brushGC
, m_brush
.GetStipple()->GetBitmap() ); 
1989     if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
1991         gdk_gc_set_fill( m_textGC
, GDK_OPAQUE_STIPPLED
); 
1992         gdk_gc_set_stipple( m_textGC
, m_brush
.GetStipple()->GetMask()->GetBitmap() ); 
1995     if (IS_HATCH(m_brush
.GetStyle())) 
1997         gdk_gc_set_fill( m_brushGC
, GDK_STIPPLED 
); 
1998         int num 
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
; 
1999         gdk_gc_set_stipple( m_brushGC
, hatches
[num
] ); 
2003 void wxWindowDC::SetBackground( const wxBrush 
&brush 
) 
2005    /* CMB 21/7/98: Added SetBackground. Sets background brush 
2006     * for Clear() and bg colour for shapes filled with cross-hatch brush */ 
2008     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2010     if (m_backgroundBrush 
== brush
) return; 
2012     m_backgroundBrush 
= brush
; 
2014     if (!m_backgroundBrush
.Ok()) return; 
2016     if (!m_window
) return; 
2018     m_backgroundBrush
.GetColour().CalcPixel( m_cmap 
); 
2019     gdk_gc_set_background( m_brushGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2020     gdk_gc_set_background( m_penGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2021     gdk_gc_set_background( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2022     gdk_gc_set_foreground( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2024     gdk_gc_set_fill( m_bgGC
, GDK_SOLID 
); 
2026     if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok())) 
2028         if (m_backgroundBrush
.GetStipple()->GetPixmap()) 
2030             gdk_gc_set_fill( m_bgGC
, GDK_TILED 
); 
2031             gdk_gc_set_tile( m_bgGC
, m_backgroundBrush
.GetStipple()->GetPixmap() ); 
2035             gdk_gc_set_fill( m_bgGC
, GDK_STIPPLED 
); 
2036             gdk_gc_set_stipple( m_bgGC
, m_backgroundBrush
.GetStipple()->GetBitmap() ); 
2040     if (IS_HATCH(m_backgroundBrush
.GetStyle())) 
2042         gdk_gc_set_fill( m_bgGC
, GDK_STIPPLED 
); 
2043         int num 
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
; 
2044         gdk_gc_set_stipple( m_bgGC
, hatches
[num
] ); 
2048 void wxWindowDC::SetLogicalFunction( int function 
) 
2050     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2052     if (m_logicalFunction 
== function
) 
2055     // VZ: shouldn't this be a CHECK? 
2062         case wxXOR
:          mode 
= GDK_XOR
;           break; 
2063         case wxINVERT
:       mode 
= GDK_INVERT
;        break; 
2064 #if (GTK_MINOR_VERSION > 0) || (GTK_MAJOR_VERSION > 1) 
2065         case wxOR_REVERSE
:   mode 
= GDK_OR_REVERSE
;    break; 
2066         case wxAND_REVERSE
:  mode 
= GDK_AND_REVERSE
;   break; 
2067         case wxCLEAR
:        mode 
= GDK_CLEAR
;         break; 
2068         case wxSET
:          mode 
= GDK_SET
;           break; 
2069         case wxOR_INVERT
:    mode 
= GDK_OR_INVERT
;     break; 
2070         case wxAND
:          mode 
= GDK_AND
;           break; 
2071         case wxOR
:           mode 
= GDK_OR
;            break; 
2072         case wxEQUIV
:        mode 
= GDK_EQUIV
;         break; 
2073         case wxNAND
:         mode 
= GDK_NAND
;          break; 
2074         case wxAND_INVERT
:   mode 
= GDK_AND_INVERT
;    break; 
2075         case wxCOPY
:         mode 
= GDK_COPY
;          break; 
2076         case wxNO_OP
:        mode 
= GDK_NOOP
;          break; 
2077         case wxSRC_INVERT
:   mode 
= GDK_COPY_INVERT
;   break; 
2079         // unsupported by GTK 
2080         case wxNOR
:          mode 
= GDK_COPY
;          break; 
2081 #endif // GTK+ > 1.0 
2083            wxFAIL_MSG( wxT("unsupported logical function") ); 
2087     m_logicalFunction 
= function
; 
2089     gdk_gc_set_function( m_penGC
, mode 
); 
2090     gdk_gc_set_function( m_brushGC
, mode 
); 
2092     // to stay compatible with wxMSW, we don't apply ROPs to the text 
2093     // operations (i.e. DrawText/DrawRotatedText). 
2094     // True, but mono-bitmaps use the m_textGC and they use ROPs as well. 
2095     gdk_gc_set_function( m_textGC
, mode 
); 
2098 void wxWindowDC::SetTextForeground( const wxColour 
&col 
) 
2100     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2102     // don't set m_textForegroundColour to an invalid colour as we'd crash 
2103     // later then (we use m_textForegroundColour.GetColor() without checking 
2105     if ( !col
.Ok() || (m_textForegroundColour 
== col
) ) 
2108     m_textForegroundColour 
= col
; 
2112         m_textForegroundColour
.CalcPixel( m_cmap 
); 
2113         gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
2117 void wxWindowDC::SetTextBackground( const wxColour 
&col 
) 
2119     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2122     if ( !col
.Ok() || (m_textBackgroundColour 
== col
) ) 
2125     m_textBackgroundColour 
= col
; 
2129         m_textBackgroundColour
.CalcPixel( m_cmap 
); 
2130         gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() ); 
2134 void wxWindowDC::SetBackgroundMode( int mode 
) 
2136     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2138     m_backgroundMode 
= mode
; 
2140     if (!m_window
) return; 
2142     // CMB 21/7/98: fill style of cross-hatch brushes is affected by 
2143     // transparent/solid background mode 
2145     if (m_brush
.GetStyle() != wxSOLID 
&& m_brush
.GetStyle() != wxTRANSPARENT
) 
2147         gdk_gc_set_fill( m_brushGC
, 
2148           (m_backgroundMode 
== wxTRANSPARENT
) ? GDK_STIPPLED 
: GDK_OPAQUE_STIPPLED
); 
2152 void wxWindowDC::SetPalette( const wxPalette
& WXUNUSED(palette
) ) 
2154     wxFAIL_MSG( wxT("wxWindowDC::SetPalette not implemented") ); 
2157 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
2159     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2161     if (!m_window
) return; 
2164     rect
.x 
= XLOG2DEV(x
); 
2165     rect
.y 
= YLOG2DEV(y
); 
2166     rect
.width 
= XLOG2DEVREL(width
); 
2167     rect
.height 
= YLOG2DEVREL(height
); 
2169     if (!m_currentClippingRegion
.IsNull()) 
2170         m_currentClippingRegion
.Intersect( rect 
); 
2172         m_currentClippingRegion
.Union( rect 
); 
2174 #if USE_PAINT_REGION 
2175     if (!m_paintClippingRegion
.IsNull()) 
2176         m_currentClippingRegion
.Intersect( m_paintClippingRegion 
); 
2179     wxCoord xx
, yy
, ww
, hh
; 
2180     m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh 
); 
2181     wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh 
); 
2183     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2184     gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2185     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2186     gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2189 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion 
®ion  
) 
2191     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2195         DestroyClippingRegion(); 
2199     if (!m_window
) return; 
2201     if (!m_currentClippingRegion
.IsNull()) 
2202         m_currentClippingRegion
.Intersect( region 
); 
2204         m_currentClippingRegion
.Union( region 
); 
2206 #if USE_PAINT_REGION 
2207     if (!m_paintClippingRegion
.IsNull()) 
2208         m_currentClippingRegion
.Intersect( m_paintClippingRegion 
); 
2211     wxCoord xx
, yy
, ww
, hh
; 
2212     m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh 
); 
2213     wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh 
); 
2215     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2216     gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2217     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2218     gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2221 void wxWindowDC::DestroyClippingRegion() 
2223     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2225     wxDC::DestroyClippingRegion(); 
2227     m_currentClippingRegion
.Clear(); 
2229 #if USE_PAINT_REGION 
2230     if (!m_paintClippingRegion
.IsEmpty()) 
2231         m_currentClippingRegion
.Union( m_paintClippingRegion 
); 
2234     if (!m_window
) return; 
2236     if (m_currentClippingRegion
.IsEmpty()) 
2238         gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle 
*) NULL 
); 
2239         gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle 
*) NULL 
); 
2240         gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle 
*) NULL 
); 
2241         gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle 
*) NULL 
); 
2245         gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2246         gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2247         gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2248         gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2252 void wxWindowDC::Destroy() 
2254     if (m_penGC
) wxFreePoolGC( m_penGC 
); 
2255     m_penGC 
= (GdkGC
*) NULL
; 
2256     if (m_brushGC
) wxFreePoolGC( m_brushGC 
); 
2257     m_brushGC 
= (GdkGC
*) NULL
; 
2258     if (m_textGC
) wxFreePoolGC( m_textGC 
); 
2259     m_textGC 
= (GdkGC
*) NULL
; 
2260     if (m_bgGC
) wxFreePoolGC( m_bgGC 
); 
2261     m_bgGC 
= (GdkGC
*) NULL
; 
2264 void wxWindowDC::ComputeScaleAndOrigin() 
2266     /* CMB: copy scale to see if it changes */ 
2267     double origScaleX 
= m_scaleX
; 
2268     double origScaleY 
= m_scaleY
; 
2270     wxDC::ComputeScaleAndOrigin(); 
2272     /* CMB: if scale has changed call SetPen to recalulate the line width */ 
2273     if ((m_scaleX 
!= origScaleX 
|| m_scaleY 
!= origScaleY
) && 
2276       /* this is a bit artificial, but we need to force wxDC to think 
2277          the pen has changed */ 
2284 // Resolution in pixels per logical inch 
2285 wxSize 
wxWindowDC::GetPPI() const 
2287     return wxSize( (int) (m_mm_to_pix_x 
* 25.4 + 0.5), (int) (m_mm_to_pix_y 
* 25.4 + 0.5)); 
2290 int wxWindowDC::GetDepth() const 
2292     wxFAIL_MSG(wxT("not implemented")); 
2298 //----------------------------------------------------------------------------- 
2300 //----------------------------------------------------------------------------- 
2302 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
) 
2304 wxPaintDC::wxPaintDC( wxWindow 
*win 
) 
2307 #if USE_PAINT_REGION 
2308     if (!win
->m_clipPaintRegion
) 
2311     m_paintClippingRegion 
= win
->GetUpdateRegion(); 
2312     GdkRegion 
*region 
= m_paintClippingRegion
.GetRegion(); 
2315         m_paintClippingRegion 
= win
->GetUpdateRegion(); 
2316         GdkRegion 
*region 
= m_paintClippingRegion
.GetRegion(); 
2319             m_currentClippingRegion
.Union( m_paintClippingRegion 
); 
2321             gdk_gc_set_clip_region( m_penGC
, region 
); 
2322             gdk_gc_set_clip_region( m_brushGC
, region 
); 
2323             gdk_gc_set_clip_region( m_textGC
, region 
); 
2324             gdk_gc_set_clip_region( m_bgGC
, region 
); 
2327 #endif // USE_PAINT_REGION 
2330 //----------------------------------------------------------------------------- 
2332 //----------------------------------------------------------------------------- 
2334 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
) 
2336 wxClientDC::wxClientDC( wxWindow 
*win 
) 
2339     wxCHECK_RET( win
, _T("NULL window in wxClientDC::wxClientDC") ); 
2341 #ifdef __WXUNIVERSAL__ 
2342     wxPoint ptOrigin 
= win
->GetClientAreaOrigin(); 
2343     SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
); 
2344     wxSize size 
= win
->GetClientSize(); 
2345     SetClippingRegion(wxPoint(0, 0), size
); 
2346 #endif // __WXUNIVERSAL__ 
2349 void wxClientDC::DoGetSize(int *width
, int *height
) const 
2351     wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") ); 
2353     m_owner
->GetClientSize( width
, height 
); 
2356 // ---------------------------------------------------------------------------- 
2358 // ---------------------------------------------------------------------------- 
2360 class wxDCModule 
: public wxModule
 
2367     DECLARE_DYNAMIC_CLASS(wxDCModule
) 
2370 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
) 
2372 bool wxDCModule::OnInit() 
2378 void wxDCModule::OnExit()