]>
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 ///////////////////////////////////////////////////////////////////////////// 
  10 // For compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  14 #define XCopyPlane XCOPYPLANE 
  17 #include "wx/dcclient.h" 
  18 #include "wx/dcmemory.h" 
  20 #include "wx/module.h" 
  22 #include "wx/fontutil.h" 
  24 #include "wx/gtk/win_gtk.h" 
  26 #include "wx/math.h" // for floating-point functions 
  30 #include <gdk/gdkprivate.h> 
  33 //----------------------------------------------------------------------------- 
  35 //----------------------------------------------------------------------------- 
  37 #define USE_PAINT_REGION 1 
  39 //----------------------------------------------------------------------------- 
  41 //----------------------------------------------------------------------------- 
  51 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH) 
  52 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH) 
  55 static GdkPixmap  
*hatches
[num_hatches
]; 
  56 static GdkPixmap 
**hatch_bitmap 
= (GdkPixmap 
**) NULL
; 
  58 extern GtkWidget 
*wxGetRootWindow(); 
  60 //----------------------------------------------------------------------------- 
  62 //----------------------------------------------------------------------------- 
  64 const double RAD2DEG  
= 180.0 / M_PI
; 
  66 // ---------------------------------------------------------------------------- 
  68 // ---------------------------------------------------------------------------- 
  70 static inline double dmax(double a
, double b
) { return a 
> b 
? a 
: b
; } 
  71 static inline double dmin(double a
, double b
) { return a 
< b 
? a 
: b
; } 
  73 static inline double DegToRad(double deg
) { return (deg 
* M_PI
) / 180.0; } 
  75 //----------------------------------------------------------------------------- 
  76 // temporary implementation of the missing GDK function 
  77 //----------------------------------------------------------------------------- 
  79 #include "gdk/gdkprivate.h" 
  81 void gdk_wx_draw_bitmap(GdkDrawable  
*drawable
, 
  91     wxCHECK_RET( drawable
, _T("NULL drawable in gdk_wx_draw_bitmap") ); 
  92     wxCHECK_RET( src
, _T("NULL src in gdk_wx_draw_bitmap") ); 
  93     wxCHECK_RET( gc
, _T("NULL gc in gdk_wx_draw_bitmap") ); 
  95     gint src_width
, src_height
; 
  96     gdk_drawable_get_size(src
, &src_width
, &src_height
); 
  97     if (width 
== -1) width 
= src_width
; 
  98     if (height 
== -1) height 
= src_height
; 
 100     XCopyPlane( GDK_WINDOW_XDISPLAY(drawable
), 
 102                 GDK_WINDOW_XID(drawable
), 
 110 //----------------------------------------------------------------------------- 
 111 // Implement Pool of Graphic contexts. Creating them takes too much time. 
 112 //----------------------------------------------------------------------------- 
 138 #define GC_POOL_ALLOC_SIZE 100 
 140 static int wxGCPoolSize 
= 0; 
 142 static wxGC 
*wxGCPool 
= NULL
; 
 144 static void wxInitGCPool() 
 146     // This really could wait until the first call to 
 147     // wxGetPoolGC, but we will make the first allocation 
 148     // now when other initialization is being performed. 
 150     // Set initial pool size. 
 151     wxGCPoolSize 
= GC_POOL_ALLOC_SIZE
; 
 153     // Allocate initial pool. 
 154     wxGCPool 
= (wxGC 
*)malloc(wxGCPoolSize 
* sizeof(wxGC
)); 
 155     if (wxGCPool 
== NULL
) 
 157         // If we cannot malloc, then fail with error 
 158         // when debug is enabled.  If debug is not enabled, 
 159         // the problem will eventually get caught 
 161         wxFAIL_MSG( wxT("Cannot allocate GC pool") ); 
 165     // Zero initial pool. 
 166     memset(wxGCPool
, 0, wxGCPoolSize 
* sizeof(wxGC
)); 
 169 static void wxCleanUpGCPool() 
 171     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 173         if (wxGCPool
[i
].m_gc
) 
 174             gdk_gc_unref( wxGCPool
[i
].m_gc 
); 
 182 static GdkGC
* wxGetPoolGC( GdkWindow 
*window
, wxPoolGCType type 
) 
 186     // Look for an available GC. 
 187     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 189         if (!wxGCPool
[i
].m_gc
) 
 191             wxGCPool
[i
].m_gc 
= gdk_gc_new( window 
); 
 192             gdk_gc_set_exposures( wxGCPool
[i
].m_gc
, FALSE 
); 
 193             wxGCPool
[i
].m_type 
= type
; 
 194             wxGCPool
[i
].m_used 
= false; 
 196         if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type 
== type
)) 
 198             wxGCPool
[i
].m_used 
= true; 
 199             return wxGCPool
[i
].m_gc
; 
 203     // We did not find an available GC. 
 204     // We need to grow the GC pool. 
 205     pptr 
= (wxGC 
*)realloc(wxGCPool
, 
 206         (wxGCPoolSize 
+ GC_POOL_ALLOC_SIZE
)*sizeof(wxGC
)); 
 209         // Initialize newly allocated pool. 
 211         memset(&wxGCPool
[wxGCPoolSize
], 0, 
 212             GC_POOL_ALLOC_SIZE
*sizeof(wxGC
)); 
 214         // Initialize entry we will return. 
 215         wxGCPool
[wxGCPoolSize
].m_gc 
= gdk_gc_new( window 
); 
 216         gdk_gc_set_exposures( wxGCPool
[wxGCPoolSize
].m_gc
, FALSE 
); 
 217         wxGCPool
[wxGCPoolSize
].m_type 
= type
; 
 218         wxGCPool
[wxGCPoolSize
].m_used 
= true; 
 220         // Set new value of pool size. 
 221         wxGCPoolSize 
+= GC_POOL_ALLOC_SIZE
; 
 223         // Return newly allocated entry. 
 224         return wxGCPool
[wxGCPoolSize
-GC_POOL_ALLOC_SIZE
].m_gc
; 
 227     // The realloc failed.  Fall through to error. 
 228     wxFAIL_MSG( wxT("No GC available") ); 
 230     return (GdkGC
*) NULL
; 
 233 static void wxFreePoolGC( GdkGC 
*gc 
) 
 235     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 237         if (wxGCPool
[i
].m_gc 
== gc
) 
 239             wxGCPool
[i
].m_used 
= false; 
 244     wxFAIL_MSG( wxT("Wrong GC") ); 
 247 //----------------------------------------------------------------------------- 
 249 //----------------------------------------------------------------------------- 
 251 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
) 
 253 wxWindowDC::wxWindowDC() 
 255     m_penGC 
= (GdkGC 
*) NULL
; 
 256     m_brushGC 
= (GdkGC 
*) NULL
; 
 257     m_textGC 
= (GdkGC 
*) NULL
; 
 258     m_bgGC 
= (GdkGC 
*) NULL
; 
 259     m_cmap 
= (GdkColormap 
*) NULL
; 
 261     m_isScreenDC 
= false; 
 262     m_owner 
= (wxWindow 
*)NULL
; 
 263     m_context 
= (PangoContext 
*)NULL
; 
 264     m_layout 
= (PangoLayout 
*)NULL
; 
 265     m_fontdesc 
= (PangoFontDescription 
*)NULL
; 
 268 wxWindowDC::wxWindowDC( wxWindow 
*window 
) 
 270     wxASSERT_MSG( window
, wxT("DC needs a window") ); 
 272     m_penGC 
= (GdkGC 
*) NULL
; 
 273     m_brushGC 
= (GdkGC 
*) NULL
; 
 274     m_textGC 
= (GdkGC 
*) NULL
; 
 275     m_bgGC 
= (GdkGC 
*) NULL
; 
 276     m_cmap 
= (GdkColormap 
*) NULL
; 
 277     m_owner 
= (wxWindow 
*)NULL
; 
 279     m_isScreenDC 
= false; 
 280     m_font 
= window
->GetFont(); 
 282     GtkWidget 
*widget 
= window
->m_wxwindow
; 
 284     // Some controls don't have m_wxwindow - like wxStaticBox, but the user 
 285     // code should still be able to create wxClientDCs for them, so we will 
 286     // use the parent window here then. 
 289         window 
= window
->GetParent(); 
 290         widget 
= window
->m_wxwindow
; 
 293     wxASSERT_MSG( widget
, wxT("DC needs a widget") ); 
 295     m_context 
= window
->GtkGetPangoDefaultContext(); 
 296     m_layout 
= pango_layout_new( m_context 
); 
 297     m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
 299     GtkPizza 
*pizza 
= GTK_PIZZA( widget 
); 
 300     m_window 
= pizza
->bin_window
; 
 302     // Window not realized ? 
 305          // Don't report problems as per MSW. 
 311     m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
 315     /* this must be done after SetUpDC, bacause SetUpDC calls the 
 316        repective SetBrush, SetPen, SetBackground etc functions 
 317        to set up the DC. SetBackground call m_owner->SetBackground 
 318        and this might not be desired as the standard dc background 
 319        is white whereas a window might assume gray to be the 
 320        standard (as e.g. wxStatusBar) */ 
 325 wxWindowDC::~wxWindowDC() 
 330         g_object_unref( G_OBJECT( m_layout 
) ); 
 332         pango_font_description_free( m_fontdesc 
); 
 335 void wxWindowDC::SetUpDC() 
 339     wxASSERT_MSG( !m_penGC
, wxT("GCs already created") ); 
 343         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_SCREEN 
); 
 344         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_SCREEN 
); 
 345         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_SCREEN 
); 
 346         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_SCREEN 
); 
 349     if (m_isMemDC 
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1)) 
 351         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_MONO 
); 
 352         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_MONO 
); 
 353         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_MONO 
); 
 354         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_MONO 
); 
 358         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_COLOUR 
); 
 359         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_COLOUR 
); 
 360         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_COLOUR 
); 
 361         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_COLOUR 
); 
 364     /* background colour */ 
 365     m_backgroundBrush 
= *wxWHITE_BRUSH
; 
 366     m_backgroundBrush
.GetColour().CalcPixel( m_cmap 
); 
 367     GdkColor 
*bg_col 
= m_backgroundBrush
.GetColour().GetColor(); 
 370     m_textForegroundColour
.CalcPixel( m_cmap 
); 
 371     gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
 373     m_textBackgroundColour
.CalcPixel( m_cmap 
); 
 374     gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() ); 
 376     gdk_gc_set_fill( m_textGC
, GDK_SOLID 
); 
 379     m_pen
.GetColour().CalcPixel( m_cmap 
); 
 380     gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() ); 
 381     gdk_gc_set_background( m_penGC
, bg_col 
); 
 383     gdk_gc_set_line_attributes( m_penGC
, 0, GDK_LINE_SOLID
, GDK_CAP_NOT_LAST
, GDK_JOIN_ROUND 
); 
 386     m_brush
.GetColour().CalcPixel( m_cmap 
); 
 387     gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() ); 
 388     gdk_gc_set_background( m_brushGC
, bg_col 
); 
 390     gdk_gc_set_fill( m_brushGC
, GDK_SOLID 
); 
 393     gdk_gc_set_background( m_bgGC
, bg_col 
); 
 394     gdk_gc_set_foreground( m_bgGC
, bg_col 
); 
 396     gdk_gc_set_fill( m_bgGC
, GDK_SOLID 
); 
 399     gdk_gc_set_function( m_textGC
, GDK_COPY 
); 
 400     gdk_gc_set_function( m_brushGC
, GDK_COPY 
); 
 401     gdk_gc_set_function( m_penGC
, GDK_COPY 
); 
 404     gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle 
*) NULL 
); 
 405     gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle 
*) NULL 
); 
 406     gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle 
*) NULL 
); 
 407     gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle 
*) NULL 
); 
 411         hatch_bitmap    
= hatches
; 
 412         hatch_bitmap
[0] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, bdiag_bits
, bdiag_width
, bdiag_height 
); 
 413         hatch_bitmap
[1] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, cdiag_bits
, cdiag_width
, cdiag_height 
); 
 414         hatch_bitmap
[2] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, fdiag_bits
, fdiag_width
, fdiag_height 
); 
 415         hatch_bitmap
[3] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, cross_bits
, cross_width
, cross_height 
); 
 416         hatch_bitmap
[4] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, horiz_bits
, horiz_width
, horiz_height 
); 
 417         hatch_bitmap
[5] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, verti_bits
, verti_width
, verti_height 
); 
 421 void wxWindowDC::DoGetSize( int* width
, int* height 
) const 
 423     wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") ); 
 425     m_owner
->GetSize(width
, height
); 
 428 extern bool wxDoFloodFill(wxDC 
*dc
, wxCoord x
, wxCoord y
, 
 429                           const wxColour 
& col
, int style
); 
 431 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
, 
 432                              const wxColour
& col
, int style
) 
 434     return wxDoFloodFill(this, x
, y
, col
, style
); 
 437 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour 
*col 
) const 
 439     // Generic (and therefore rather inefficient) method. 
 440     // Could be improved. 
 442     wxBitmap 
bitmap(1, 1); 
 443     memdc
.SelectObject(bitmap
); 
 444     memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
); 
 445     memdc
.SelectObject(wxNullBitmap
); 
 447     wxImage image 
= bitmap
.ConvertToImage(); 
 448     col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0)); 
 452 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2 
) 
 454     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 456     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 459             gdk_draw_line( m_window
, m_penGC
, XLOG2DEV(x1
), YLOG2DEV(y1
), XLOG2DEV(x2
), YLOG2DEV(y2
) ); 
 461         CalcBoundingBox(x1
, y1
); 
 462         CalcBoundingBox(x2
, y2
); 
 466 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y 
) 
 468     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 470     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 475         wxCoord xx 
= XLOG2DEV(x
); 
 476         wxCoord yy 
= YLOG2DEV(y
); 
 479             gdk_draw_line( m_window
, m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy 
); 
 480             gdk_draw_line( m_window
, m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) ); 
 485 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, 
 486                             wxCoord xc
, wxCoord yc 
) 
 488     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 490     wxCoord xx1 
= XLOG2DEV(x1
); 
 491     wxCoord yy1 
= YLOG2DEV(y1
); 
 492     wxCoord xx2 
= XLOG2DEV(x2
); 
 493     wxCoord yy2 
= YLOG2DEV(y2
); 
 494     wxCoord xxc 
= XLOG2DEV(xc
); 
 495     wxCoord yyc 
= YLOG2DEV(yc
); 
 496     double dx 
= xx1 
- xxc
; 
 497     double dy 
= yy1 
- yyc
; 
 498     double radius 
= sqrt((double)(dx
*dx
+dy
*dy
)); 
 499     wxCoord   r      
= (wxCoord
)radius
; 
 500     double radius1
, radius2
; 
 502     if (xx1 
== xx2 
&& yy1 
== yy2
) 
 507     else if ( wxIsNullDouble(radius
) ) 
 514         radius1 
= (xx1 
- xxc 
== 0) ? 
 515             (yy1 
- yyc 
< 0) ? 90.0 : -90.0 : 
 516             -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
; 
 517         radius2 
= (xx2 
- xxc 
== 0) ? 
 518             (yy2 
- yyc 
< 0) ? 90.0 : -90.0 : 
 519             -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
; 
 521     wxCoord alpha1 
= wxCoord(radius1 
* 64.0); 
 522     wxCoord alpha2 
= wxCoord((radius2 
- radius1
) * 64.0); 
 523     while (alpha2 
<= 0) alpha2 
+= 360*64; 
 524     while (alpha1 
> 360*64) alpha1 
-= 360*64; 
 528         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 530             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 532                 gdk_gc_set_ts_origin( m_textGC
, 
 533                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 534                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 535                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 536                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 538             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 540                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 541                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 542                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 544             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 546                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 547                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 548                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 550             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 552                 gdk_gc_set_ts_origin( m_brushGC
, 
 553                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 554                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 555                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 556                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 560                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 564         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 566             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 568             gdk_draw_line( m_window
, m_penGC
, xx1
, yy1
, xxc
, yyc 
); 
 569             gdk_draw_line( m_window
, m_penGC
, xxc
, yyc
, xx2
, yy2 
); 
 573     CalcBoundingBox (x1
, y1
); 
 574     CalcBoundingBox (x2
, y2
); 
 577 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea 
) 
 579     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 581     wxCoord xx 
= XLOG2DEV(x
); 
 582     wxCoord yy 
= YLOG2DEV(y
); 
 583     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 584     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 586     // CMB: handle -ve width and/or height 
 587     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 588     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 592         wxCoord start 
= wxCoord(sa 
* 64.0); 
 593         wxCoord end 
= wxCoord((ea
-sa
) * 64.0); 
 595         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 597             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 599                 gdk_gc_set_ts_origin( m_textGC
, 
 600                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 601                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 602                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 603                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 605             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 607                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 608                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 609                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 611             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 613                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 614                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 615                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 617             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 619                 gdk_gc_set_ts_origin( m_brushGC
, 
 620                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 621                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 622                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 623                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 627                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 631         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 632             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, start
, end 
); 
 635     CalcBoundingBox (x
, y
); 
 636     CalcBoundingBox (x 
+ width
, y 
+ height
); 
 639 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y 
) 
 641     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 643     if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
) 
 644         gdk_draw_point( m_window
, m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
 646     CalcBoundingBox (x
, y
); 
 649 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset 
) 
 651     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 653     if (m_pen
.GetStyle() == wxTRANSPARENT
) return; 
 656     //Check, if scaling is necessary 
 661             if (XLOG2DEV(val
)==val
) 
 662                 if (YLOG2DEV(val
)==val
) 
 665     GdkPoint 
*gpts 
= NULL
; 
 668         gpts 
= new GdkPoint
[n
]; 
 671         wxFAIL_MSG( wxT("Cannot allocate PolyLine") ); 
 675     for (int i 
= 0; i 
< n
; i
++) 
 677         wxCoord x1 
= XLOG2DEV(points
[i
].x 
+ xoffset
); 
 678         wxCoord y1 
= YLOG2DEV(points
[i
].y 
+ yoffset
); 
 680         CalcBoundingBox( x1 
+ xoffset
, y1 
+ yoffset 
); 
 687         for (int i 
= 0; i 
< n
; i
++) { 
 688             CalcBoundingBox( points
[i
].x
, points
[i
].y 
); 
 691         //GdkPoint and wxPoint have the same memory allignment, so we can cast one into another 
 692         gpts 
= reinterpret_cast<GdkPoint
*>(points
); 
 696         gdk_draw_lines( m_window
, m_penGC
, gpts
, n
); 
 702 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int WXUNUSED(fillStyle
) ) 
 704     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 708     //Check, if scaling is necessary 
 713             if (XLOG2DEV(val
)==val
) 
 714                 if (YLOG2DEV(val
)==val
){ 
 718     GdkPoint 
*gdkpoints 
= NULL
; 
 721         gdkpoints 
= new GdkPoint
[n
+1]; //FIXME: Why the "+1" 
 724     for (i 
= 0 ; i 
< n 
; i
++) 
 726         gdkpoints
[i
].x 
= XLOG2DEV(points
[i
].x 
+ xoffset
); 
 727         gdkpoints
[i
].y 
= YLOG2DEV(points
[i
].y 
+ yoffset
); 
 729         CalcBoundingBox( points
[i
].x 
+ xoffset
, points
[i
].y 
+ yoffset 
); 
 734         for (; i 
< n 
; ++i
) { 
 735             CalcBoundingBox( points
[i
].x
, points
[i
].y 
); 
 737         //GdkPoint and wxPoint have the same memory allignment, so we can cast one into another 
 738         gdkpoints 
= reinterpret_cast<GdkPoint
*> (points
); 
 743         //I think wxSOLID is the most often used style (it is for me), 
 744         //so I put it in front of the if ... ifelse's 
 745         if (m_brush
.GetStyle() == wxSOLID
) 
 747             gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 749         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 751             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 753                 gdk_gc_set_ts_origin( m_textGC
, 
 754                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 755                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 756                 gdk_draw_polygon( m_window
, m_textGC
, TRUE
, gdkpoints
, n 
); 
 757                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 759             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 761                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 762                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 763                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 765             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 767                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 768                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 769                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 771             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 773                 gdk_gc_set_ts_origin( m_brushGC
, 
 774                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 775                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 776                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 777                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 781                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 785         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 788             for (i = 0 ; i < n ; i++) 
 790                 gdk_draw_line( m_window, m_penGC, 
 793                                gdkpoints[(i+1)%n].x, 
 794                                gdkpoints[(i+1)%n].y); 
 797             gdk_draw_polygon( m_window
, m_penGC
, FALSE
, gdkpoints
, n 
); 
 806 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 808     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 810     wxCoord xx 
= XLOG2DEV(x
); 
 811     wxCoord yy 
= YLOG2DEV(y
); 
 812     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 813     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 815     // CMB: draw nothing if transformed w or h is 0 
 816     if (ww 
== 0 || hh 
== 0) return; 
 818     // CMB: handle -ve width and/or height 
 819     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 820     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 824         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 826             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 828                 gdk_gc_set_ts_origin( m_textGC
, 
 829                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 830                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 831                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 832                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 834             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 836                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 837                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 838                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 840             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 842                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 843                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 844                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 846             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 848                 gdk_gc_set_ts_origin( m_brushGC
, 
 849                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 850                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 851                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 852                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 856                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 860         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 861             gdk_draw_rectangle( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
-1, hh
-1 ); 
 864     CalcBoundingBox( x
, y 
); 
 865     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
 868 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius 
) 
 870     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 872     if (radius 
< 0.0) radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
 874     wxCoord xx 
= XLOG2DEV(x
); 
 875     wxCoord yy 
= YLOG2DEV(y
); 
 876     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 877     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 878     wxCoord rr 
= XLOG2DEVREL((wxCoord
)radius
); 
 880     // CMB: handle -ve width and/or height 
 881     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 882     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 884     // CMB: if radius is zero use DrawRectangle() instead to avoid 
 885     // X drawing errors with small radii 
 888         DrawRectangle( x
, y
, width
, height 
); 
 892     // CMB: draw nothing if transformed w or h is 0 
 893     if (ww 
== 0 || hh 
== 0) return; 
 895     // CMB: adjust size if outline is drawn otherwise the result is 
 896     // 1 pixel too wide and high 
 897     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 905         // CMB: ensure dd is not larger than rectangle otherwise we 
 906         // get an hour glass shape 
 908         if (dd 
> ww
) dd 
= ww
; 
 909         if (dd 
> hh
) dd 
= hh
; 
 912         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 914             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 916                 gdk_gc_set_ts_origin( m_textGC
, 
 917                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 918                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 919                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 920                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 921                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 922                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 923                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 924                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 925                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 927             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 929                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 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 (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 940                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 941                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 942                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 943                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 944                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 945                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 946                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 947                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 949             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 951                 gdk_gc_set_ts_origin( m_brushGC
, 
 952                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 953                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 954                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 955                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 956                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 957                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 958                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 959                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 960                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 964                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 965                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 966                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 967                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 968                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 969                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 973         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 975             gdk_draw_line( m_window
, m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy 
); 
 976             gdk_draw_line( m_window
, m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh 
); 
 977             gdk_draw_line( m_window
, m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr 
); 
 978             gdk_draw_line( m_window
, m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr 
); 
 979             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 980             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 981             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 982             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 986     // this ignores the radius 
 987     CalcBoundingBox( x
, y 
); 
 988     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
 991 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 993     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 995     wxCoord xx 
= XLOG2DEV(x
); 
 996     wxCoord yy 
= YLOG2DEV(y
); 
 997     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 998     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
1000     // CMB: handle -ve width and/or height 
1001     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
1002     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
1006         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
1008             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
1010                 gdk_gc_set_ts_origin( m_textGC
, 
1011                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
1012                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
1013                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1014                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
1016             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
1018                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
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 ); 
1022             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
1024                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
1025                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1026                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1028             if (m_brush
.GetStyle() == wxSTIPPLE
) 
1030                 gdk_gc_set_ts_origin( m_brushGC
, 
1031                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
1032                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
1033                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1034                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1038                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1042         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1043             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1046     CalcBoundingBox( x
, y 
); 
1047     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
1050 void wxWindowDC::DoDrawIcon( const wxIcon 
&icon
, wxCoord x
, wxCoord y 
) 
1052     // VZ: egcs 1.0.3 refuses to compile this without cast, no idea why 
1053     DoDrawBitmap( (const wxBitmap
&)icon
, x
, y
, true ); 
1056 void wxWindowDC::DoDrawBitmap( const wxBitmap 
&bitmap
, 
1057                                wxCoord x
, wxCoord y
, 
1060     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1062     wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") ); 
1064     bool is_mono 
= (bitmap
.GetBitmap() != NULL
); 
1066     // scale/translate size and position 
1067     int xx 
= XLOG2DEV(x
); 
1068     int yy 
= YLOG2DEV(y
); 
1070     int w 
= bitmap
.GetWidth(); 
1071     int h 
= bitmap
.GetHeight(); 
1073     CalcBoundingBox( x
, y 
); 
1074     CalcBoundingBox( x 
+ w
, y 
+ h 
); 
1076     if (!m_window
) return; 
1078     int ww 
= XLOG2DEVREL(w
); 
1079     int hh 
= YLOG2DEVREL(h
); 
1081     // compare to current clipping region 
1082     if (!m_currentClippingRegion
.IsNull()) 
1084         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1085         tmp
.Intersect( m_currentClippingRegion 
); 
1090     // scale bitmap if required 
1091     wxBitmap use_bitmap 
= bitmap
; 
1092     if ((w 
!= ww
) || (h 
!= hh
)) 
1093         use_bitmap 
= use_bitmap
.Rescale( 0, 0, ww
, hh
, ww
, hh 
); 
1095 #if !GTK_CHECK_VERSION(2,2,0) 
1096     // NB: We can't render pixbufs with GTK+ < 2.2, we need to use pixmaps code. 
1097     //     Pixbufs-based bitmaps with alpha channel don't have a mask, so we 
1098     //     have to call GetPixmap() here -- it converts the pixbuf into pixmap 
1099     //     and also creates the mask as a side-effect: 
1100     use_bitmap
.GetPixmap(); 
1103     // apply mask if any 
1104     GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1105     if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1107     GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1109     if (useMask 
&& mask
) 
1111         if (!m_currentClippingRegion
.IsNull()) 
1114             new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 ); 
1115             GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1117             gdk_gc_set_foreground( gc
, &col 
); 
1118             gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1120             gdk_gc_set_background( gc
, &col 
); 
1122             gdk_gc_set_foreground( gc
, &col 
); 
1123             gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1124             gdk_gc_set_clip_origin( gc
, -xx
, -yy 
); 
1125             gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1126             gdk_gc_set_stipple( gc
, mask 
); 
1127             gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1134                 gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1136                 gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1137             gdk_gc_set_clip_origin( m_textGC
, xx
, yy 
); 
1142                 gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1144                 gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1145             gdk_gc_set_clip_origin( m_penGC
, xx
, yy 
); 
1149     // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1150     // drawing a mono-bitmap (XBitmap) we use the current text GC 
1153         GdkPixmap 
*bitmap2 
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, -1 ); 
1154         GdkGC 
*gc 
= gdk_gc_new( bitmap2 
); 
1155         gdk_gc_set_foreground( gc
, m_textForegroundColour
.GetColor() ); 
1156         gdk_gc_set_background( gc
, m_textBackgroundColour
.GetColor() ); 
1157         gdk_wx_draw_bitmap( bitmap2
, gc
, use_bitmap
.GetBitmap(), 0, 0, 0, 0, -1, -1 ); 
1159         gdk_draw_drawable( m_window
, m_textGC
, bitmap2
, 0, 0, xx
, yy
, -1, -1 ); 
1161         gdk_bitmap_unref( bitmap2 
); 
1166 #if GTK_CHECK_VERSION(2,2,0) 
1167         if (!gtk_check_version(2,2,0) && use_bitmap
.HasPixbuf()) 
1169             gdk_draw_pixbuf(m_window
, m_penGC
, 
1170                             use_bitmap
.GetPixbuf(), 
1171                             0, 0, xx
, yy
, -1, -1, 
1172                             GDK_RGB_DITHER_NORMAL
, xx
, yy
); 
1177             gdk_draw_pixmap(m_window
, m_penGC
, 
1178                             use_bitmap
.GetPixmap(), 
1179                             0, 0, xx
, yy
, -1, -1); 
1183     // remove mask again if any 
1184     if (useMask 
&& mask
) 
1188             gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1189             gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1190             if (!m_currentClippingRegion
.IsNull()) 
1191                 gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1195             gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1196             gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1197             if (!m_currentClippingRegion
.IsNull()) 
1198                 gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1203         gdk_bitmap_unref( new_mask 
); 
1206 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, 
1207                          wxCoord width
, wxCoord height
, 
1209                          wxCoord xsrc
, wxCoord ysrc
, 
1212                          wxCoord xsrcMask
, wxCoord ysrcMask 
) 
1214     wxCHECK_MSG( Ok(), false, wxT("invalid window dc") ); 
1216     wxCHECK_MSG( source
, false, wxT("invalid source dc") ); 
1218     if (!m_window
) return false; 
1220     // transform the source DC coords to the device ones 
1221     xsrc 
= source
->XLOG2DEV(xsrc
); 
1222     ysrc 
= source
->YLOG2DEV(ysrc
); 
1224     wxClientDC 
*srcDC 
= (wxClientDC
*)source
; 
1225     wxMemoryDC 
*memDC 
= (wxMemoryDC
*)source
; 
1227     bool use_bitmap_method 
= false; 
1228     bool is_mono 
= false; 
1230     if (xsrcMask 
== -1 && ysrcMask 
== -1) 
1236     if (srcDC
->m_isMemDC
) 
1238         if (!memDC
->m_selected
.Ok()) return false; 
1240         is_mono 
= (memDC
->m_selected
.GetDepth() == 1); 
1242         // we use the "XCopyArea" way to copy a memory dc into 
1243         // a different window if the memory dc BOTH 
1244         // a) doesn't have any mask or its mask isn't used 
1248         if (useMask 
&& (memDC
->m_selected
.GetMask())) 
1250             // we HAVE TO use the direct way for memory dcs 
1251             // that have mask since the XCopyArea doesn't know 
1253             use_bitmap_method 
= true; 
1257             // we HAVE TO use the direct way for memory dcs 
1258             // that are bitmaps because XCopyArea doesn't cope 
1259             // with different bit depths 
1260             use_bitmap_method 
= true; 
1262         else if ((xsrc 
== 0) && (ysrc 
== 0) && 
1263                  (width 
== memDC
->m_selected
.GetWidth()) && 
1264                  (height 
== memDC
->m_selected
.GetHeight())) 
1266             // we SHOULD use the direct way if all of the bitmap 
1267             // in the memory dc is copied in which case XCopyArea 
1268             // wouldn't be able able to boost performace by reducing 
1269             // the area to be scaled 
1270             use_bitmap_method 
= true; 
1274             use_bitmap_method 
= false; 
1278     CalcBoundingBox( xdest
, ydest 
); 
1279     CalcBoundingBox( xdest 
+ width
, ydest 
+ height 
); 
1281     // scale/translate size and position 
1282     wxCoord xx 
= XLOG2DEV(xdest
); 
1283     wxCoord yy 
= YLOG2DEV(ydest
); 
1285     wxCoord ww 
= XLOG2DEVREL(width
); 
1286     wxCoord hh 
= YLOG2DEVREL(height
); 
1288     // compare to current clipping region 
1289     if (!m_currentClippingRegion
.IsNull()) 
1291         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1292         tmp
.Intersect( m_currentClippingRegion 
); 
1297     int old_logical_func 
= m_logicalFunction
; 
1298     SetLogicalFunction( logical_func 
); 
1300     if (use_bitmap_method
) 
1302         // scale/translate bitmap size 
1303         wxCoord bm_width 
= memDC
->m_selected
.GetWidth(); 
1304         wxCoord bm_height 
= memDC
->m_selected
.GetHeight(); 
1306         // Get clip coords for the bitmap. If we don't 
1307         // use wxBitmap::Rescale(), which can clip the 
1308         // bitmap, these are the same as the original 
1315         // interpret userscale of src too 
1317         memDC
->GetUserScale(&xsc
,&ysc
); 
1318         bm_width 
= (int) (bm_width 
/ xsc
); 
1319         bm_height 
= (int) (bm_height 
/ ysc
); 
1321         wxCoord bm_ww 
= XLOG2DEVREL( bm_width 
); 
1322         wxCoord bm_hh 
= YLOG2DEVREL( bm_height 
); 
1324         // Scale bitmap if required 
1325         wxBitmap use_bitmap
; 
1326         if ((memDC
->m_selected
.GetWidth()!= bm_ww
) || ( memDC
->m_selected
.GetHeight()!= bm_hh
)) 
1328             // This indicates that the blitting code below will get 
1329             // a clipped bitmap and therefore needs to move the origin 
1331             wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1332             tmp
.Intersect( m_currentClippingRegion 
); 
1333             tmp
.GetBox(cx
,cy
,cw
,ch
); 
1335             // Scale and clipped bitmap 
1336             use_bitmap 
= memDC
->m_selected
.Rescale(cx
-xx
,cy
-yy
,cw
,ch
,bm_ww
,bm_hh
); 
1340             // Don't scale bitmap 
1341             use_bitmap 
= memDC
->m_selected
; 
1344         // apply mask if any 
1345         GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1346         if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1348         GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1350         if (useMask 
&& mask
) 
1352             if (!m_currentClippingRegion
.IsNull()) 
1355                 new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 ); 
1356                 GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1358                 gdk_gc_set_foreground( gc
, &col 
); 
1359                 gdk_gc_set_ts_origin( gc
, -xsrcMask
, -ysrcMask
); 
1360                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1362                 gdk_gc_set_background( gc
, &col 
); 
1364                 gdk_gc_set_foreground( gc
, &col 
); 
1365                 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1366                 // was: gdk_gc_set_clip_origin( gc, -xx, -yy ); 
1367                 gdk_gc_set_clip_origin( gc
, -cx
, -cy 
); 
1368                 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1369                 gdk_gc_set_stipple( gc
, mask 
); 
1370                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1378                     gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1379                     gdk_gc_set_clip_origin( m_textGC
, cx
, cy 
); 
1383                     gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1384                     gdk_gc_set_clip_origin( m_textGC
, cx
-xsrcMask
, cy
-ysrcMask 
); 
1391                     gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1392                     gdk_gc_set_clip_origin( m_penGC
, cx
, cy 
); 
1396                     gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1397                     gdk_gc_set_clip_origin( m_penGC
, cx
-xsrcMask
, cy
-ysrcMask 
); 
1402         // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1403         // drawing a mono-bitmap (XBitmap) we use the current text GC 
1407             GdkPixmap 
*bitmap 
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, -1 ); 
1408             GdkGC 
*gc 
= gdk_gc_new( bitmap 
); 
1409             gdk_gc_set_foreground( gc
, m_textForegroundColour
.GetColor() ); 
1410             gdk_gc_set_background( gc
, m_textBackgroundColour
.GetColor() ); 
1411             gdk_wx_draw_bitmap( bitmap
, gc
, use_bitmap
.GetBitmap(), 0, 0, 0, 0, -1, -1 ); 
1413             gdk_draw_drawable( m_window
, m_textGC
, bitmap
, xsrc
, ysrc
, cx
, cy
, cw
, ch 
); 
1415             gdk_bitmap_unref( bitmap 
); 
1420             // was: gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, xx, yy, ww, hh ); 
1421             gdk_draw_pixmap( m_window
, m_penGC
, use_bitmap
.GetPixmap(), xsrc
, ysrc
, cx
, cy
, cw
, ch 
); 
1424         // remove mask again if any 
1425         if (useMask 
&& mask
) 
1429                 gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1430                 gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1431                 if (!m_currentClippingRegion
.IsNull()) 
1432                     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1436                 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1437                 gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1438                 if (!m_currentClippingRegion
.IsNull()) 
1439                     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1444             gdk_bitmap_unref( new_mask 
); 
1446     else // use_bitmap_method 
1448         if ((width 
!= ww
) || (height 
!= hh
)) 
1451             wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1452             tmp
.Intersect( m_currentClippingRegion 
); 
1453             wxCoord cx
,cy
,cw
,ch
; 
1454             tmp
.GetBox(cx
,cy
,cw
,ch
); 
1457             wxBitmap bitmap 
= memDC
->m_selected
.Rescale( cx
-xx
, cy
-yy
, cw
, ch
, ww
, hh 
); 
1459             // draw scaled bitmap 
1460             // was: gdk_draw_pixmap( m_window, m_penGC, bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 ); 
1461             gdk_draw_pixmap( m_window
, m_penGC
, bitmap
.GetPixmap(), 0, 0, cx
, cy
, -1, -1 ); 
1465             // No scaling and not a memory dc with a mask either 
1467             // copy including child window contents 
1468             gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS 
); 
1469             gdk_window_copy_area( m_window
, m_penGC
, xx
, yy
, 
1471                                   xsrc
, ysrc
, width
, height 
); 
1472             gdk_gc_set_subwindow( m_penGC
, GDK_CLIP_BY_CHILDREN 
); 
1476     SetLogicalFunction( old_logical_func 
); 
1481 void wxWindowDC::DoDrawText( const wxString 
&text
, wxCoord x
, wxCoord y 
) 
1483     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1485     if (!m_window
) return; 
1487     if (text
.empty()) return; 
1492     wxCHECK_RET( m_context
, wxT("no Pango context") ); 
1493     wxCHECK_RET( m_layout
, wxT("no Pango layout") ); 
1494     wxCHECK_RET( m_fontdesc
, wxT("no Pango font description") ); 
1496     bool underlined 
= m_font
.Ok() && m_font
.GetUnderlined(); 
1499     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( text 
); 
1501     const wxWCharBuffer wdata 
= wxConvLocal
.cMB2WC( text 
); 
1504     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( wdata 
); 
1506     size_t datalen 
= strlen((const char*)data
); 
1507     pango_layout_set_text( m_layout
, (const char*) data
, datalen
); 
1511         PangoAttrList 
*attrs 
= pango_attr_list_new(); 
1512         PangoAttribute 
*a 
= pango_attr_underline_new(PANGO_UNDERLINE_SINGLE
); 
1514         a
->end_index 
= datalen
; 
1515         pango_attr_list_insert(attrs
, a
); 
1516         pango_layout_set_attributes(m_layout
, attrs
); 
1517         pango_attr_list_unref(attrs
); 
1522     if (fabs(m_scaleY 
- 1.0) > 0.00001) 
1524          // If there is a user or actually any scale applied to 
1525          // the device context, scale the font. 
1527          // scale font description 
1528          gint oldSize 
= pango_font_description_get_size( m_fontdesc 
); 
1529          double size 
= oldSize
; 
1530          size 
= size 
* m_scaleY
; 
1531          pango_font_description_set_size( m_fontdesc
, (gint
)size 
); 
1533          // actually apply scaled font 
1534          pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1536          pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1537          if ( m_backgroundMode 
== wxSOLID 
) 
1539             gdk_gc_set_foreground(m_textGC
, m_textBackgroundColour
.GetColor()); 
1540             gdk_draw_rectangle(m_window
, m_textGC
, TRUE
, x
, y
, w
, h
); 
1541             gdk_gc_set_foreground(m_textGC
, m_textForegroundColour
.GetColor()); 
1545          gdk_draw_layout( m_window
, m_textGC
, x
, y
, m_layout 
); 
1547          // reset unscaled size 
1548          pango_font_description_set_size( m_fontdesc
, oldSize 
); 
1550          // actually apply unscaled font 
1551          pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1555         pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1556         if ( m_backgroundMode 
== wxSOLID 
) 
1558             gdk_gc_set_foreground(m_textGC
, m_textBackgroundColour
.GetColor()); 
1559             gdk_draw_rectangle(m_window
, m_textGC
, TRUE
, x
, y
, w
, h
); 
1560             gdk_gc_set_foreground(m_textGC
, m_textForegroundColour
.GetColor()); 
1563         gdk_draw_layout( m_window
, m_textGC
, x
, y
, m_layout 
); 
1568         // undo underline attributes setting: 
1569         pango_layout_set_attributes(m_layout
, NULL
); 
1575     width 
= wxCoord(width 
/ m_scaleX
); 
1576     height 
= wxCoord(height 
/ m_scaleY
); 
1577     CalcBoundingBox (x 
+ width
, y 
+ height
); 
1578     CalcBoundingBox (x
, y
); 
1582 // TODO: There is an example of rotating text with GTK2 that would probably be 
1583 // a better approach here: 
1584 //           http://www.daa.com.au/pipermail/pygtk/2003-April/005052.html 
1586 void wxWindowDC::DoDrawRotatedText( const wxString 
&text
, wxCoord x
, wxCoord y
, double angle 
) 
1588     if ( wxIsNullDouble(angle
) ) 
1590         DrawText(text
, x
, y
); 
1594     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1596     if (!m_window
) return; 
1601     // TODO: implement later without GdkFont for GTK 2.0 
1602     GetTextExtent(text
, &w
, &h
, NULL
,NULL
, &m_font
); 
1604     // draw the string normally 
1607     dc
.SelectObject(src
); 
1608     dc
.SetFont(GetFont()); 
1609     dc
.SetBackground(*wxBLACK_BRUSH
); 
1610     dc
.SetBrush(*wxBLACK_BRUSH
); 
1612     dc
.SetTextForeground( *wxWHITE 
); 
1613     dc
.DrawText(text
, 0, 0); 
1614     dc
.SelectObject(wxNullBitmap
); 
1616     // Calculate the size of the rotated bounding box. 
1617     double rad 
= DegToRad(angle
); 
1618     double dx 
= cos(rad
), 
1621     // the rectngle vertices are counted clockwise with the first one being at 
1622     // (0, 0) (or, rather, at (x, y)) 
1624            y2 
= -w
*dy
;      // y axis points to the bottom, hence minus 
1627     double x3 
= x4 
+ x2
, 
1631     wxCoord maxX 
= (wxCoord
)(dmax(x2
, dmax(x3
, x4
)) + 0.5), 
1632             maxY 
= (wxCoord
)(dmax(y2
, dmax(y3
, y4
)) + 0.5), 
1633             minX 
= (wxCoord
)(dmin(x2
, dmin(x3
, x4
)) - 0.5), 
1634             minY 
= (wxCoord
)(dmin(y2
, dmin(y3
, y4
)) - 0.5); 
1637     wxImage image 
= src
.ConvertToImage(); 
1639     image
.ConvertColourToAlpha( m_textForegroundColour
.Red(), 
1640                                 m_textForegroundColour
.Green(), 
1641                                 m_textForegroundColour
.Blue() ); 
1642     image 
= image
.Rotate( rad
, wxPoint(0,0) ); 
1644     int i_angle 
= (int) angle
; 
1645     i_angle 
= i_angle 
% 360; 
1649     if ((i_angle 
>= 90.0) && (i_angle 
< 270.0)) 
1650         xoffset 
= image
.GetWidth(); 
1652     if ((i_angle 
>= 0.0) && (i_angle 
< 180.0)) 
1653         yoffset 
= image
.GetHeight(); 
1655     if ((i_angle 
>= 0) && (i_angle 
< 90)) 
1656         yoffset 
-= (int)( cos(rad
)*h 
); 
1657     if ((i_angle 
>= 90) && (i_angle 
< 180)) 
1658         xoffset 
-= (int)( sin(rad
)*h 
); 
1659     if ((i_angle 
>= 180) && (i_angle 
< 270)) 
1660         yoffset 
-= (int)( cos(rad
)*h 
); 
1661     if ((i_angle 
>= 270) && (i_angle 
< 360)) 
1662         xoffset 
-= (int)( sin(rad
)*h 
); 
1664     int i_x 
= x 
- xoffset
; 
1665     int i_y 
= y 
- yoffset
; 
1668     DoDrawBitmap( src
, i_x
, i_y
, true ); 
1671     // it would be better to draw with non underlined font and draw the line 
1672     // manually here (it would be more straight...) 
1674     if ( m_font
.GetUnderlined() ) 
1676         gdk_draw_line( m_window
, m_textGC
, 
1677                        XLOG2DEV(x 
+ x4
), YLOG2DEV(y 
+ y4 
+ font
->descent
), 
1678                        XLOG2DEV(x 
+ x3
), YLOG2DEV(y 
+ y3 
+ font
->descent
)); 
1682     // update the bounding box 
1683     CalcBoundingBox(x 
+ minX
, y 
+ minY
); 
1684     CalcBoundingBox(x 
+ maxX
, y 
+ maxY
); 
1687 void wxWindowDC::DoGetTextExtent(const wxString 
&string
, 
1688                                  wxCoord 
*width
, wxCoord 
*height
, 
1689                                  wxCoord 
*descent
, wxCoord 
*externalLeading
, 
1690                                  wxFont 
*theFont
) const 
1698     if ( externalLeading 
) 
1699         *externalLeading 
= 0; 
1706     // Set new font description 
1708         pango_layout_set_font_description( m_layout
, theFont
->GetNativeFontInfo()->description 
); 
1710     // Set layout's text 
1712     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( string 
); 
1713     const char *dataUTF8 
= (const char *)data
; 
1715     const wxWCharBuffer wdata 
= wxConvLocal
.cMB2WC( string 
); 
1719     const wxCharBuffer data 
= wxConvUTF8
.cWC2MB( wdata 
); 
1720     const char *dataUTF8 
= (const char *)data
; 
1725         // hardly ideal, but what else can we do if conversion failed? 
1729     pango_layout_set_text( m_layout
, dataUTF8
, strlen(dataUTF8
) ); 
1734         pango_layout_get_pixel_size( m_layout
, width
, &h 
); 
1735         PangoLayoutIter 
*iter 
= pango_layout_get_iter(m_layout
); 
1736         int baseline 
= pango_layout_iter_get_baseline(iter
); 
1737         pango_layout_iter_free(iter
); 
1738         *descent 
= h 
- PANGO_PIXELS(baseline
); 
1741             *height 
= (wxCoord
) h
; 
1745         pango_layout_get_pixel_size( m_layout
, width
, height 
); 
1748     // Reset old font description 
1750         pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1753 wxCoord 
wxWindowDC::GetCharWidth() const 
1755     pango_layout_set_text( m_layout
, "H", 1 ); 
1757     pango_layout_get_pixel_size( m_layout
, &w
, NULL 
); 
1761 wxCoord 
wxWindowDC::GetCharHeight() const 
1763     pango_layout_set_text( m_layout
, "H", 1 ); 
1765     pango_layout_get_pixel_size( m_layout
, NULL
, &h 
); 
1769 void wxWindowDC::Clear() 
1771     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1773     if (!m_window
) return; 
1775     // VZ: the code below results in infinite recursion and crashes when 
1776     //     dc.Clear() is done from OnPaint() so I disable it for now. 
1777     //     I don't know what the correct fix is but Clear() surely should not 
1778     //     reenter OnPaint()! 
1780     /* - we either are a memory dc or have a window as the 
1781        owner. anything else shouldn't happen. 
1782        - we don't use gdk_window_clear() as we don't set 
1783        the window's background colour anymore. it is too 
1784        much pain to keep the DC's and the window's back- 
1785        ground colour in synch. */ 
1796         GetSize( &width
, &height 
); 
1797         gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height 
); 
1802     GetSize( &width
, &height 
); 
1803     gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height 
); 
1807 void wxWindowDC::SetFont( const wxFont 
&font 
) 
1814             pango_font_description_free( m_fontdesc 
); 
1816         m_fontdesc 
= pango_font_description_copy( m_font
.GetNativeFontInfo()->description 
); 
1821             PangoContext 
*oldContext 
= m_context
; 
1823             m_context 
= m_owner
->GtkGetPangoDefaultContext(); 
1825             // If we switch back/forth between different contexts 
1826             // we also have to create a new layout. I think so, 
1827             // at least, and it doesn't hurt to do it. 
1828             if (oldContext 
!= m_context
) 
1831                     g_object_unref( G_OBJECT( m_layout 
) ); 
1833                 m_layout 
= pango_layout_new( m_context 
); 
1837         pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1841 void wxWindowDC::SetPen( const wxPen 
&pen 
) 
1843     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1845     if (m_pen 
== pen
) return; 
1849     if (!m_pen
.Ok()) return; 
1851     if (!m_window
) return; 
1853     gint width 
= m_pen
.GetWidth(); 
1856         // CMB: if width is non-zero scale it with the dc 
1861         // X doesn't allow different width in x and y and so we take 
1864                    ( fabs((double) XLOG2DEVREL(width
)) + 
1865                      fabs((double) YLOG2DEVREL(width
)) ) / 2.0; 
1869             // width can't be 0 or an internal GTK error occurs inside 
1870             // gdk_gc_set_dashes() below 
1875     static const wxGTKDash dotted
[] = {1, 1}; 
1876     static const wxGTKDash short_dashed
[] = {2, 2}; 
1877     static const wxGTKDash wxCoord_dashed
[] = {2, 4}; 
1878     static const wxGTKDash dotted_dashed
[] = {3, 3, 1, 3}; 
1880     // We express dash pattern in pen width unit, so we are 
1881     // independent of zoom factor and so on... 
1883     const wxGTKDash 
*req_dash
; 
1885     GdkLineStyle lineStyle 
= GDK_LINE_SOLID
; 
1886     switch (m_pen
.GetStyle()) 
1890             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1891             req_nb_dash 
= m_pen
.GetDashCount(); 
1892             req_dash 
= (wxGTKDash
*)m_pen
.GetDash(); 
1897             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1904             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1906             req_dash 
= wxCoord_dashed
; 
1911             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1913             req_dash 
= short_dashed
; 
1918 //            lineStyle = GDK_LINE_DOUBLE_DASH; 
1919             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1921             req_dash 
= dotted_dashed
; 
1926         case wxSTIPPLE_MASK_OPAQUE
: 
1931             lineStyle 
= GDK_LINE_SOLID
; 
1932             req_dash 
= (wxGTKDash
*)NULL
; 
1938     if (req_dash 
&& req_nb_dash
) 
1940         wxGTKDash 
*real_req_dash 
= new wxGTKDash
[req_nb_dash
]; 
1943             for (int i 
= 0; i 
< req_nb_dash
; i
++) 
1944                 real_req_dash
[i
] = req_dash
[i
] * width
; 
1945             gdk_gc_set_dashes( m_penGC
, 0, real_req_dash
, req_nb_dash 
); 
1946             delete[] real_req_dash
; 
1950             // No Memory. We use non-scaled dash pattern... 
1951             gdk_gc_set_dashes( m_penGC
, 0, (wxGTKDash
*)req_dash
, req_nb_dash 
); 
1955     GdkCapStyle capStyle 
= GDK_CAP_ROUND
; 
1956     switch (m_pen
.GetCap()) 
1958         case wxCAP_PROJECTING
: { capStyle 
= GDK_CAP_PROJECTING
; break; } 
1959         case wxCAP_BUTT
:       { capStyle 
= GDK_CAP_BUTT
;       break; } 
1966                 capStyle 
= GDK_CAP_NOT_LAST
; 
1970                 capStyle 
= GDK_CAP_ROUND
; 
1976     GdkJoinStyle joinStyle 
= GDK_JOIN_ROUND
; 
1977     switch (m_pen
.GetJoin()) 
1979         case wxJOIN_BEVEL
: { joinStyle 
= GDK_JOIN_BEVEL
; break; } 
1980         case wxJOIN_MITER
: { joinStyle 
= GDK_JOIN_MITER
; break; } 
1982         default:           { joinStyle 
= GDK_JOIN_ROUND
; break; } 
1985     gdk_gc_set_line_attributes( m_penGC
, width
, lineStyle
, capStyle
, joinStyle 
); 
1987     m_pen
.GetColour().CalcPixel( m_cmap 
); 
1988     gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() ); 
1991 void wxWindowDC::SetBrush( const wxBrush 
&brush 
) 
1993     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1995     if (m_brush 
== brush
) return; 
1999     if (!m_brush
.Ok()) return; 
2001     if (!m_window
) return; 
2003     m_brush
.GetColour().CalcPixel( m_cmap 
); 
2004     gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() ); 
2006     gdk_gc_set_fill( m_brushGC
, GDK_SOLID 
); 
2008     if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok())) 
2010         if (m_brush
.GetStipple()->GetPixmap()) 
2012             gdk_gc_set_fill( m_brushGC
, GDK_TILED 
); 
2013             gdk_gc_set_tile( m_brushGC
, m_brush
.GetStipple()->GetPixmap() ); 
2017             gdk_gc_set_fill( m_brushGC
, GDK_STIPPLED 
); 
2018             gdk_gc_set_stipple( m_brushGC
, m_brush
.GetStipple()->GetBitmap() ); 
2022     if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
2024         gdk_gc_set_fill( m_textGC
, GDK_OPAQUE_STIPPLED
); 
2025         gdk_gc_set_stipple( m_textGC
, m_brush
.GetStipple()->GetMask()->GetBitmap() ); 
2028     if (m_brush
.IsHatch()) 
2030         gdk_gc_set_fill( m_brushGC
, GDK_STIPPLED 
); 
2031         int num 
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
; 
2032         gdk_gc_set_stipple( m_brushGC
, hatches
[num
] ); 
2036 void wxWindowDC::SetBackground( const wxBrush 
&brush 
) 
2038    /* CMB 21/7/98: Added SetBackground. Sets background brush 
2039     * for Clear() and bg colour for shapes filled with cross-hatch brush */ 
2041     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2043     if (m_backgroundBrush 
== brush
) return; 
2045     m_backgroundBrush 
= brush
; 
2047     if (!m_backgroundBrush
.Ok()) return; 
2049     if (!m_window
) return; 
2051     m_backgroundBrush
.GetColour().CalcPixel( m_cmap 
); 
2052     gdk_gc_set_background( m_brushGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2053     gdk_gc_set_background( m_penGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2054     gdk_gc_set_background( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2055     gdk_gc_set_foreground( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() ); 
2057     gdk_gc_set_fill( m_bgGC
, GDK_SOLID 
); 
2059     if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok())) 
2061         if (m_backgroundBrush
.GetStipple()->GetPixmap()) 
2063             gdk_gc_set_fill( m_bgGC
, GDK_TILED 
); 
2064             gdk_gc_set_tile( m_bgGC
, m_backgroundBrush
.GetStipple()->GetPixmap() ); 
2068             gdk_gc_set_fill( m_bgGC
, GDK_STIPPLED 
); 
2069             gdk_gc_set_stipple( m_bgGC
, m_backgroundBrush
.GetStipple()->GetBitmap() ); 
2073     if (m_backgroundBrush
.IsHatch()) 
2075         gdk_gc_set_fill( m_bgGC
, GDK_STIPPLED 
); 
2076         int num 
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
; 
2077         gdk_gc_set_stipple( m_bgGC
, hatches
[num
] ); 
2081 void wxWindowDC::SetLogicalFunction( int function 
) 
2083     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2085     if (m_logicalFunction 
== function
) 
2088     // VZ: shouldn't this be a CHECK? 
2095         case wxXOR
:          mode 
= GDK_XOR
;           break; 
2096         case wxINVERT
:       mode 
= GDK_INVERT
;        break; 
2097         case wxOR_REVERSE
:   mode 
= GDK_OR_REVERSE
;    break; 
2098         case wxAND_REVERSE
:  mode 
= GDK_AND_REVERSE
;   break; 
2099         case wxCLEAR
:        mode 
= GDK_CLEAR
;         break; 
2100         case wxSET
:          mode 
= GDK_SET
;           break; 
2101         case wxOR_INVERT
:    mode 
= GDK_OR_INVERT
;     break; 
2102         case wxAND
:          mode 
= GDK_AND
;           break; 
2103         case wxOR
:           mode 
= GDK_OR
;            break; 
2104         case wxEQUIV
:        mode 
= GDK_EQUIV
;         break; 
2105         case wxNAND
:         mode 
= GDK_NAND
;          break; 
2106         case wxAND_INVERT
:   mode 
= GDK_AND_INVERT
;    break; 
2107         case wxCOPY
:         mode 
= GDK_COPY
;          break; 
2108         case wxNO_OP
:        mode 
= GDK_NOOP
;          break; 
2109         case wxSRC_INVERT
:   mode 
= GDK_COPY_INVERT
;   break; 
2111         // unsupported by GTK 
2112         case wxNOR
:          mode 
= GDK_COPY
;          break; 
2114            wxFAIL_MSG( wxT("unsupported logical function") ); 
2118     m_logicalFunction 
= function
; 
2120     gdk_gc_set_function( m_penGC
, mode 
); 
2121     gdk_gc_set_function( m_brushGC
, mode 
); 
2123     // to stay compatible with wxMSW, we don't apply ROPs to the text 
2124     // operations (i.e. DrawText/DrawRotatedText). 
2125     // True, but mono-bitmaps use the m_textGC and they use ROPs as well. 
2126     gdk_gc_set_function( m_textGC
, mode 
); 
2129 void wxWindowDC::SetTextForeground( const wxColour 
&col 
) 
2131     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2133     // don't set m_textForegroundColour to an invalid colour as we'd crash 
2134     // later then (we use m_textForegroundColour.GetColor() without checking 
2136     if ( !col
.Ok() || (m_textForegroundColour 
== col
) ) 
2139     m_textForegroundColour 
= col
; 
2143         m_textForegroundColour
.CalcPixel( m_cmap 
); 
2144         gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
2148 void wxWindowDC::SetTextBackground( const wxColour 
&col 
) 
2150     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2153     if ( !col
.Ok() || (m_textBackgroundColour 
== col
) ) 
2156     m_textBackgroundColour 
= col
; 
2160         m_textBackgroundColour
.CalcPixel( m_cmap 
); 
2161         gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() ); 
2165 void wxWindowDC::SetBackgroundMode( int mode 
) 
2167     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2169     m_backgroundMode 
= mode
; 
2171     if (!m_window
) return; 
2173     // CMB 21/7/98: fill style of cross-hatch brushes is affected by 
2174     // transparent/solid background mode 
2176     if (m_brush
.GetStyle() != wxSOLID 
&& m_brush
.GetStyle() != wxTRANSPARENT
) 
2178         gdk_gc_set_fill( m_brushGC
, 
2179           (m_backgroundMode 
== wxTRANSPARENT
) ? GDK_STIPPLED 
: GDK_OPAQUE_STIPPLED
); 
2183 void wxWindowDC::SetPalette( const wxPalette
& WXUNUSED(palette
) ) 
2185     wxFAIL_MSG( wxT("wxWindowDC::SetPalette not implemented") ); 
2188 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
2190     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2192     if (!m_window
) return; 
2195     rect
.x 
= XLOG2DEV(x
); 
2196     rect
.y 
= YLOG2DEV(y
); 
2197     rect
.width 
= XLOG2DEVREL(width
); 
2198     rect
.height 
= YLOG2DEVREL(height
); 
2200     if (!m_currentClippingRegion
.IsNull()) 
2201         m_currentClippingRegion
.Intersect( rect 
); 
2203         m_currentClippingRegion
.Union( rect 
); 
2205 #if USE_PAINT_REGION 
2206     if (!m_paintClippingRegion
.IsNull()) 
2207         m_currentClippingRegion
.Intersect( m_paintClippingRegion 
); 
2210     wxCoord xx
, yy
, ww
, hh
; 
2211     m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh 
); 
2212     wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh 
); 
2214     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2215     gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2216     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2217     gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2220 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion 
®ion  
) 
2222     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2226         DestroyClippingRegion(); 
2230     if (!m_window
) return; 
2232     if (!m_currentClippingRegion
.IsNull()) 
2233         m_currentClippingRegion
.Intersect( region 
); 
2235         m_currentClippingRegion
.Union( region 
); 
2237 #if USE_PAINT_REGION 
2238     if (!m_paintClippingRegion
.IsNull()) 
2239         m_currentClippingRegion
.Intersect( m_paintClippingRegion 
); 
2242     wxCoord xx
, yy
, ww
, hh
; 
2243     m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh 
); 
2244     wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh 
); 
2246     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2247     gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2248     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2249     gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2252 void wxWindowDC::DestroyClippingRegion() 
2254     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2256     wxDC::DestroyClippingRegion(); 
2258     m_currentClippingRegion
.Clear(); 
2260 #if USE_PAINT_REGION 
2261     if (!m_paintClippingRegion
.IsEmpty()) 
2262         m_currentClippingRegion
.Union( m_paintClippingRegion 
); 
2265     if (!m_window
) return; 
2267     if (m_currentClippingRegion
.IsEmpty()) 
2269         gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle 
*) NULL 
); 
2270         gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle 
*) NULL 
); 
2271         gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle 
*) NULL 
); 
2272         gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle 
*) NULL 
); 
2276         gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2277         gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2278         gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2279         gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2283 void wxWindowDC::Destroy() 
2285     if (m_penGC
) wxFreePoolGC( m_penGC 
); 
2286     m_penGC 
= (GdkGC
*) NULL
; 
2287     if (m_brushGC
) wxFreePoolGC( m_brushGC 
); 
2288     m_brushGC 
= (GdkGC
*) NULL
; 
2289     if (m_textGC
) wxFreePoolGC( m_textGC 
); 
2290     m_textGC 
= (GdkGC
*) NULL
; 
2291     if (m_bgGC
) wxFreePoolGC( m_bgGC 
); 
2292     m_bgGC 
= (GdkGC
*) NULL
; 
2295 void wxWindowDC::ComputeScaleAndOrigin() 
2297     const wxRealPoint 
origScale(m_scaleX
, m_scaleY
); 
2299     wxDC::ComputeScaleAndOrigin(); 
2301     // if scale has changed call SetPen to recalulate the line width 
2302     if ( wxRealPoint(m_scaleX
, m_scaleY
) != origScale 
&& m_pen
.Ok() ) 
2304         // this is a bit artificial, but we need to force wxDC to think the pen 
2312 // Resolution in pixels per logical inch 
2313 wxSize 
wxWindowDC::GetPPI() const 
2315     return wxSize( (int) (m_mm_to_pix_x 
* 25.4 + 0.5), (int) (m_mm_to_pix_y 
* 25.4 + 0.5)); 
2318 int wxWindowDC::GetDepth() const 
2320     return gdk_drawable_get_depth(m_window
); 
2324 //----------------------------------------------------------------------------- 
2326 //----------------------------------------------------------------------------- 
2328 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
) 
2330 // Limit the paint region to the window size. Sometimes 
2331 // the paint region is too big, and this risks X11 errors 
2332 static void wxLimitRegionToSize(wxRegion
& region
, const wxSize
& sz
) 
2334     wxRect originalRect 
= region
.GetBox(); 
2335     wxRect 
rect(originalRect
); 
2336     if (rect
.width 
+ rect
.x 
> sz
.x
) 
2337         rect
.width 
= sz
.x 
- rect
.x
; 
2338     if (rect
.height 
+ rect
.y 
> sz
.y
) 
2339         rect
.height 
= sz
.y 
- rect
.y
; 
2340     if (rect 
!= originalRect
) 
2342         region 
= wxRegion(rect
); 
2343         wxLogTrace(wxT("painting"), wxT("Limiting region from %d, %d, %d, %d to %d, %d, %d, %d\n"), 
2344                    originalRect
.x
, originalRect
.y
, originalRect
.width
, originalRect
.height
, 
2345                    rect
.x
, rect
.y
, rect
.width
, rect
.height
); 
2349 wxPaintDC::wxPaintDC( wxWindow 
*win 
) 
2352 #if USE_PAINT_REGION 
2353     if (!win
->m_clipPaintRegion
) 
2356     wxSize sz 
= win
->GetSize(); 
2357     m_paintClippingRegion 
= win
->GetUpdateRegion(); 
2358     wxLimitRegionToSize(m_paintClippingRegion
, sz
); 
2360     GdkRegion 
*region 
= m_paintClippingRegion
.GetRegion(); 
2363         m_currentClippingRegion
.Union( m_paintClippingRegion 
); 
2364         wxLimitRegionToSize(m_currentClippingRegion
, sz
); 
2366         if (sz
.x 
<= 0 || sz
.y 
<= 0) 
2369         gdk_gc_set_clip_region( m_penGC
, region 
); 
2370         gdk_gc_set_clip_region( m_brushGC
, region 
); 
2371         gdk_gc_set_clip_region( m_textGC
, region 
); 
2372         gdk_gc_set_clip_region( m_bgGC
, region 
); 
2374 #endif // USE_PAINT_REGION 
2377 //----------------------------------------------------------------------------- 
2379 //----------------------------------------------------------------------------- 
2381 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
) 
2383 wxClientDC::wxClientDC( wxWindow 
*win 
) 
2386     wxCHECK_RET( win
, _T("NULL window in wxClientDC::wxClientDC") ); 
2388 #ifdef __WXUNIVERSAL__ 
2389     wxPoint ptOrigin 
= win
->GetClientAreaOrigin(); 
2390     SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
); 
2391     wxSize size 
= win
->GetClientSize(); 
2392     SetClippingRegion(wxPoint(0, 0), size
); 
2393 #endif // __WXUNIVERSAL__ 
2396 void wxClientDC::DoGetSize(int *width
, int *height
) const 
2398     wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") ); 
2400     m_owner
->GetClientSize( width
, height 
); 
2403 // ---------------------------------------------------------------------------- 
2405 // ---------------------------------------------------------------------------- 
2407 class wxDCModule 
: public wxModule
 
2414     DECLARE_DYNAMIC_CLASS(wxDCModule
) 
2417 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
) 
2419 bool wxDCModule::OnInit() 
2425 void wxDCModule::OnExit()