1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/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" 
  21     #include "wx/dcmemory.h" 
  22     #include "wx/math.h" // for floating-point functions 
  26 #include "wx/module.h" 
  27 #include "wx/fontutil.h" 
  29 #include "wx/gtk/win_gtk.h" 
  30 #include "wx/gtk/private.h" 
  34 #include <gdk/gdkprivate.h> 
  37 //----------------------------------------------------------------------------- 
  39 //----------------------------------------------------------------------------- 
  41 #define USE_PAINT_REGION 1 
  43 //----------------------------------------------------------------------------- 
  45 //----------------------------------------------------------------------------- 
  55 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH) 
  56 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH) 
  59 static GdkPixmap  
*hatches
[num_hatches
]; 
  60 static GdkPixmap 
**hatch_bitmap 
= (GdkPixmap 
**) NULL
; 
  62 extern GtkWidget 
*wxGetRootWindow(); 
  64 //----------------------------------------------------------------------------- 
  66 //----------------------------------------------------------------------------- 
  68 const double RAD2DEG  
= 180.0 / M_PI
; 
  70 // ---------------------------------------------------------------------------- 
  72 // ---------------------------------------------------------------------------- 
  74 static inline double dmax(double a
, double b
) { return a 
> b 
? a 
: b
; } 
  75 static inline double dmin(double a
, double b
) { return a 
< b 
? a 
: b
; } 
  77 static inline double DegToRad(double deg
) { return (deg 
* M_PI
) / 180.0; } 
  79 //----------------------------------------------------------------------------- 
  80 // temporary implementation of the missing GDK function 
  81 //----------------------------------------------------------------------------- 
  83 #include "gdk/gdkprivate.h" 
  85 void gdk_wx_draw_bitmap(GdkDrawable  
*drawable
, 
  95     wxCHECK_RET( drawable
, _T("NULL drawable in gdk_wx_draw_bitmap") ); 
  96     wxCHECK_RET( src
, _T("NULL src in gdk_wx_draw_bitmap") ); 
  97     wxCHECK_RET( gc
, _T("NULL gc in gdk_wx_draw_bitmap") ); 
  99     gint src_width
, src_height
; 
 100     gdk_drawable_get_size(src
, &src_width
, &src_height
); 
 101     if (width 
== -1) width 
= src_width
; 
 102     if (height 
== -1) height 
= src_height
; 
 104     XCopyPlane( GDK_WINDOW_XDISPLAY(drawable
), 
 106                 GDK_WINDOW_XID(drawable
), 
 114 //----------------------------------------------------------------------------- 
 115 // Implement Pool of Graphic contexts. Creating them takes too much time. 
 116 //----------------------------------------------------------------------------- 
 142 #define GC_POOL_ALLOC_SIZE 100 
 144 static int wxGCPoolSize 
= 0; 
 146 static wxGC 
*wxGCPool 
= NULL
; 
 148 static void wxInitGCPool() 
 150     // This really could wait until the first call to 
 151     // wxGetPoolGC, but we will make the first allocation 
 152     // now when other initialization is being performed. 
 154     // Set initial pool size. 
 155     wxGCPoolSize 
= GC_POOL_ALLOC_SIZE
; 
 157     // Allocate initial pool. 
 158     wxGCPool 
= (wxGC 
*)malloc(wxGCPoolSize 
* sizeof(wxGC
)); 
 159     if (wxGCPool 
== NULL
) 
 161         // If we cannot malloc, then fail with error 
 162         // when debug is enabled.  If debug is not enabled, 
 163         // the problem will eventually get caught 
 165         wxFAIL_MSG( wxT("Cannot allocate GC pool") ); 
 169     // Zero initial pool. 
 170     memset(wxGCPool
, 0, wxGCPoolSize 
* sizeof(wxGC
)); 
 173 static void wxCleanUpGCPool() 
 175     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 177         if (wxGCPool
[i
].m_gc
) 
 178             g_object_unref (wxGCPool
[i
].m_gc
); 
 186 static GdkGC
* wxGetPoolGC( GdkWindow 
*window
, wxPoolGCType type 
) 
 190     // Look for an available GC. 
 191     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 193         if (!wxGCPool
[i
].m_gc
) 
 195             wxGCPool
[i
].m_gc 
= gdk_gc_new( window 
); 
 196             gdk_gc_set_exposures( wxGCPool
[i
].m_gc
, FALSE 
); 
 197             wxGCPool
[i
].m_type 
= type
; 
 198             wxGCPool
[i
].m_used 
= false; 
 200         if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type 
== type
)) 
 202             wxGCPool
[i
].m_used 
= true; 
 203             return wxGCPool
[i
].m_gc
; 
 207     // We did not find an available GC. 
 208     // We need to grow the GC pool. 
 209     pptr 
= (wxGC 
*)realloc(wxGCPool
, 
 210         (wxGCPoolSize 
+ GC_POOL_ALLOC_SIZE
)*sizeof(wxGC
)); 
 213         // Initialize newly allocated pool. 
 215         memset(&wxGCPool
[wxGCPoolSize
], 0, 
 216             GC_POOL_ALLOC_SIZE
*sizeof(wxGC
)); 
 218         // Initialize entry we will return. 
 219         wxGCPool
[wxGCPoolSize
].m_gc 
= gdk_gc_new( window 
); 
 220         gdk_gc_set_exposures( wxGCPool
[wxGCPoolSize
].m_gc
, FALSE 
); 
 221         wxGCPool
[wxGCPoolSize
].m_type 
= type
; 
 222         wxGCPool
[wxGCPoolSize
].m_used 
= true; 
 224         // Set new value of pool size. 
 225         wxGCPoolSize 
+= GC_POOL_ALLOC_SIZE
; 
 227         // Return newly allocated entry. 
 228         return wxGCPool
[wxGCPoolSize
-GC_POOL_ALLOC_SIZE
].m_gc
; 
 231     // The realloc failed.  Fall through to error. 
 232     wxFAIL_MSG( wxT("No GC available") ); 
 234     return (GdkGC
*) NULL
; 
 237 static void wxFreePoolGC( GdkGC 
*gc 
) 
 239     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 241         if (wxGCPool
[i
].m_gc 
== gc
) 
 243             wxGCPool
[i
].m_used 
= false; 
 248     wxFAIL_MSG( wxT("Wrong GC") ); 
 251 //----------------------------------------------------------------------------- 
 253 //----------------------------------------------------------------------------- 
 255 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
) 
 257 wxWindowDC::wxWindowDC() 
 259     m_penGC 
= (GdkGC 
*) NULL
; 
 260     m_brushGC 
= (GdkGC 
*) NULL
; 
 261     m_textGC 
= (GdkGC 
*) NULL
; 
 262     m_bgGC 
= (GdkGC 
*) NULL
; 
 263     m_cmap 
= (GdkColormap 
*) NULL
; 
 265     m_isScreenDC 
= false; 
 266     m_owner 
= (wxWindow 
*)NULL
; 
 267     m_context 
= (PangoContext 
*)NULL
; 
 268     m_layout 
= (PangoLayout 
*)NULL
; 
 269     m_fontdesc 
= (PangoFontDescription 
*)NULL
; 
 272 wxWindowDC::wxWindowDC( wxWindow 
*window 
) 
 274     wxASSERT_MSG( window
, wxT("DC needs a window") ); 
 276     m_penGC 
= (GdkGC 
*) NULL
; 
 277     m_brushGC 
= (GdkGC 
*) NULL
; 
 278     m_textGC 
= (GdkGC 
*) NULL
; 
 279     m_bgGC 
= (GdkGC 
*) NULL
; 
 280     m_cmap 
= (GdkColormap 
*) NULL
; 
 281     m_owner 
= (wxWindow 
*)NULL
; 
 283     m_isScreenDC 
= false; 
 284     m_font 
= window
->GetFont(); 
 286     GtkWidget 
*widget 
= window
->m_wxwindow
; 
 288     // Some controls don't have m_wxwindow - like wxStaticBox, but the user 
 289     // code should still be able to create wxClientDCs for them, so we will 
 290     // use the parent window here then. 
 293         window 
= window
->GetParent(); 
 294         widget 
= window
->m_wxwindow
; 
 297     wxASSERT_MSG( widget
, wxT("DC needs a widget") ); 
 299     m_context 
= window
->GtkGetPangoDefaultContext(); 
 300     m_layout 
= pango_layout_new( m_context 
); 
 301     m_fontdesc 
= pango_font_description_copy( widget
->style
->font_desc 
); 
 303     GtkPizza 
*pizza 
= GTK_PIZZA( widget 
); 
 304     m_window 
= pizza
->bin_window
; 
 306     // Window not realized ? 
 309          // Don't report problems as per MSW. 
 315     m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
 319     /* this must be done after SetUpDC, bacause SetUpDC calls the 
 320        repective SetBrush, SetPen, SetBackground etc functions 
 321        to set up the DC. SetBackground call m_owner->SetBackground 
 322        and this might not be desired as the standard dc background 
 323        is white whereas a window might assume gray to be the 
 324        standard (as e.g. wxStatusBar) */ 
 329 wxWindowDC::~wxWindowDC() 
 334         g_object_unref (m_layout
); 
 336         pango_font_description_free( m_fontdesc 
); 
 339 void wxWindowDC::SetUpDC() 
 343     wxASSERT_MSG( !m_penGC
, wxT("GCs already created") ); 
 347         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_SCREEN 
); 
 348         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_SCREEN 
); 
 349         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_SCREEN 
); 
 350         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_SCREEN 
); 
 353     if (m_isMemDC 
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1)) 
 355         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_MONO 
); 
 356         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_MONO 
); 
 357         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_MONO 
); 
 358         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_MONO 
); 
 362         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_COLOUR 
); 
 363         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_COLOUR 
); 
 364         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_COLOUR 
); 
 365         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_COLOUR 
); 
 368     /* background colour */ 
 369     m_backgroundBrush 
= *wxWHITE_BRUSH
; 
 370     m_backgroundBrush
.GetColour().CalcPixel( m_cmap 
); 
 372     const GdkColor 
*bg_col 
= m_backgroundBrush
.GetColour().GetColor(); 
 374           GdkColor 
*bg_col 
= m_backgroundBrush
.GetColour().GetColor(); 
 378     m_textForegroundColour
.CalcPixel( m_cmap 
); 
 379     gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
 381     m_textBackgroundColour
.CalcPixel( m_cmap 
); 
 382     gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() ); 
 384     gdk_gc_set_fill( m_textGC
, GDK_SOLID 
); 
 387     m_pen
.GetColour().CalcPixel( m_cmap 
); 
 388     gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() ); 
 389     gdk_gc_set_background( m_penGC
, bg_col 
); 
 391     gdk_gc_set_line_attributes( m_penGC
, 0, GDK_LINE_SOLID
, GDK_CAP_NOT_LAST
, GDK_JOIN_ROUND 
); 
 394     m_brush
.GetColour().CalcPixel( m_cmap 
); 
 395     gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() ); 
 396     gdk_gc_set_background( m_brushGC
, bg_col 
); 
 398     gdk_gc_set_fill( m_brushGC
, GDK_SOLID 
); 
 401     gdk_gc_set_background( m_bgGC
, bg_col 
); 
 402     gdk_gc_set_foreground( m_bgGC
, bg_col 
); 
 404     gdk_gc_set_fill( m_bgGC
, GDK_SOLID 
); 
 407     gdk_gc_set_function( m_textGC
, GDK_COPY 
); 
 408     gdk_gc_set_function( m_brushGC
, GDK_COPY 
); 
 409     gdk_gc_set_function( m_penGC
, GDK_COPY 
); 
 412     gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle 
*) NULL 
); 
 413     gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle 
*) NULL 
); 
 414     gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle 
*) NULL 
); 
 415     gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle 
*) NULL 
); 
 419         hatch_bitmap    
= hatches
; 
 420         hatch_bitmap
[0] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, bdiag_bits
, bdiag_width
, bdiag_height 
); 
 421         hatch_bitmap
[1] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, cdiag_bits
, cdiag_width
, cdiag_height 
); 
 422         hatch_bitmap
[2] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, fdiag_bits
, fdiag_width
, fdiag_height 
); 
 423         hatch_bitmap
[3] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, cross_bits
, cross_width
, cross_height 
); 
 424         hatch_bitmap
[4] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, horiz_bits
, horiz_width
, horiz_height 
); 
 425         hatch_bitmap
[5] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, verti_bits
, verti_width
, verti_height 
); 
 429 void wxWindowDC::DoGetSize( int* width
, int* height 
) const 
 431     wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") ); 
 433     m_owner
->GetSize(width
, height
); 
 436 extern bool wxDoFloodFill(wxDC 
*dc
, wxCoord x
, wxCoord y
, 
 437                           const wxColour 
& col
, int style
); 
 439 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
, 
 440                              const wxColour
& col
, int style
) 
 442     return wxDoFloodFill(this, x
, y
, col
, style
); 
 445 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour 
*col 
) const 
 447     // Generic (and therefore rather inefficient) method. 
 448     // Could be improved. 
 450     wxBitmap 
bitmap(1, 1); 
 451     memdc
.SelectObject(bitmap
); 
 452     memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
); 
 453     memdc
.SelectObject(wxNullBitmap
); 
 455     wxImage image 
= bitmap
.ConvertToImage(); 
 456     col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0)); 
 460 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2 
) 
 462     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 464     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 467             gdk_draw_line( m_window
, m_penGC
, XLOG2DEV(x1
), YLOG2DEV(y1
), XLOG2DEV(x2
), YLOG2DEV(y2
) ); 
 469         CalcBoundingBox(x1
, y1
); 
 470         CalcBoundingBox(x2
, y2
); 
 474 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y 
) 
 476     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 478     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 483         wxCoord xx 
= XLOG2DEV(x
); 
 484         wxCoord yy 
= YLOG2DEV(y
); 
 487             gdk_draw_line( m_window
, m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy 
); 
 488             gdk_draw_line( m_window
, m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) ); 
 493 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, 
 494                             wxCoord xc
, wxCoord yc 
) 
 496     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 498     wxCoord xx1 
= XLOG2DEV(x1
); 
 499     wxCoord yy1 
= YLOG2DEV(y1
); 
 500     wxCoord xx2 
= XLOG2DEV(x2
); 
 501     wxCoord yy2 
= YLOG2DEV(y2
); 
 502     wxCoord xxc 
= XLOG2DEV(xc
); 
 503     wxCoord yyc 
= YLOG2DEV(yc
); 
 504     double dx 
= xx1 
- xxc
; 
 505     double dy 
= yy1 
- yyc
; 
 506     double radius 
= sqrt((double)(dx
*dx
+dy
*dy
)); 
 507     wxCoord   r      
= (wxCoord
)radius
; 
 508     double radius1
, radius2
; 
 510     if (xx1 
== xx2 
&& yy1 
== yy2
) 
 515     else if ( wxIsNullDouble(radius
) ) 
 522         radius1 
= (xx1 
- xxc 
== 0) ? 
 523             (yy1 
- yyc 
< 0) ? 90.0 : -90.0 : 
 524             -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
; 
 525         radius2 
= (xx2 
- xxc 
== 0) ? 
 526             (yy2 
- yyc 
< 0) ? 90.0 : -90.0 : 
 527             -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
; 
 529     wxCoord alpha1 
= wxCoord(radius1 
* 64.0); 
 530     wxCoord alpha2 
= wxCoord((radius2 
- radius1
) * 64.0); 
 531     while (alpha2 
<= 0) alpha2 
+= 360*64; 
 532     while (alpha1 
> 360*64) alpha1 
-= 360*64; 
 536         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 538             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 540                 gdk_gc_set_ts_origin( m_textGC
, 
 541                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 542                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 543                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 544                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 546             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 548                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 549                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 550                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 552             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 554                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 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 ); 
 558             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 560                 gdk_gc_set_ts_origin( m_brushGC
, 
 561                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 562                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 563                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 564                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 568                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 572         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 574             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 576             gdk_draw_line( m_window
, m_penGC
, xx1
, yy1
, xxc
, yyc 
); 
 577             gdk_draw_line( m_window
, m_penGC
, xxc
, yyc
, xx2
, yy2 
); 
 581     CalcBoundingBox (x1
, y1
); 
 582     CalcBoundingBox (x2
, y2
); 
 585 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea 
) 
 587     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 589     wxCoord xx 
= XLOG2DEV(x
); 
 590     wxCoord yy 
= YLOG2DEV(y
); 
 591     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 592     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 594     // CMB: handle -ve width and/or height 
 595     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 596     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 600         wxCoord start 
= wxCoord(sa 
* 64.0); 
 601         wxCoord end 
= wxCoord((ea
-sa
) * 64.0); 
 603         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 605             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 607                 gdk_gc_set_ts_origin( m_textGC
, 
 608                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 609                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 610                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 611                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 613             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 615                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 616                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 617                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 619             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 621                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 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 ); 
 625             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 627                 gdk_gc_set_ts_origin( m_brushGC
, 
 628                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 629                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 630                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 631                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 635                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 639         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 640             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, start
, end 
); 
 643     CalcBoundingBox (x
, y
); 
 644     CalcBoundingBox (x 
+ width
, y 
+ height
); 
 647 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y 
) 
 649     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 651     if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
) 
 652         gdk_draw_point( m_window
, m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
 654     CalcBoundingBox (x
, y
); 
 657 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset 
) 
 659     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 661     if (m_pen
.GetStyle() == wxTRANSPARENT
) return; 
 664     //Check, if scaling is necessary 
 669             if (XLOG2DEV(val
)==val
) 
 670                 if (YLOG2DEV(val
)==val
) 
 673     GdkPoint 
*gpts 
= NULL
; 
 676         gpts 
= new GdkPoint
[n
]; 
 679         wxFAIL_MSG( wxT("Cannot allocate PolyLine") ); 
 683     for (int i 
= 0; i 
< n
; i
++) 
 685         wxCoord x1 
= XLOG2DEV(points
[i
].x 
+ xoffset
); 
 686         wxCoord y1 
= YLOG2DEV(points
[i
].y 
+ yoffset
); 
 688         CalcBoundingBox( x1 
+ xoffset
, y1 
+ yoffset 
); 
 695         for (int i 
= 0; i 
< n
; i
++) { 
 696             CalcBoundingBox( points
[i
].x
, points
[i
].y 
); 
 699         //GdkPoint and wxPoint have the same memory allignment, so we can cast one into another 
 700         gpts 
= reinterpret_cast<GdkPoint
*>(points
); 
 704         gdk_draw_lines( m_window
, m_penGC
, gpts
, n
); 
 710 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int WXUNUSED(fillStyle
) ) 
 712     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 716     //Check, if scaling is necessary 
 721             if (XLOG2DEV(val
)==val
) 
 722                 if (YLOG2DEV(val
)==val
){ 
 726     GdkPoint 
*gdkpoints 
= NULL
; 
 729         gdkpoints 
= new GdkPoint
[n
+1]; //FIXME: Why the "+1" 
 732     for (i 
= 0 ; i 
< n 
; i
++) 
 734         gdkpoints
[i
].x 
= XLOG2DEV(points
[i
].x 
+ xoffset
); 
 735         gdkpoints
[i
].y 
= YLOG2DEV(points
[i
].y 
+ yoffset
); 
 737         CalcBoundingBox( points
[i
].x 
+ xoffset
, points
[i
].y 
+ yoffset 
); 
 742         for (; i 
< n 
; ++i
) { 
 743             CalcBoundingBox( points
[i
].x
, points
[i
].y 
); 
 745         //GdkPoint and wxPoint have the same memory allignment, so we can cast one into another 
 746         gdkpoints 
= reinterpret_cast<GdkPoint
*> (points
); 
 751         //I think wxSOLID is the most often used style (it is for me), 
 752         //so I put it in front of the if ... ifelse's 
 753         if (m_brush
.GetStyle() == wxSOLID
) 
 755             gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 757         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 759             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 761                 gdk_gc_set_ts_origin( m_textGC
, 
 762                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 763                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 764                 gdk_draw_polygon( m_window
, m_textGC
, TRUE
, gdkpoints
, n 
); 
 765                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 767             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 769                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 770                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 771                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 773             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 775                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 776                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 777                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 779             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 781                 gdk_gc_set_ts_origin( m_brushGC
, 
 782                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 783                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 784                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 785                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 789                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 793         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 796             for (i = 0 ; i < n ; i++) 
 798                 gdk_draw_line( m_window, m_penGC, 
 801                                gdkpoints[(i+1)%n].x, 
 802                                gdkpoints[(i+1)%n].y); 
 805             gdk_draw_polygon( m_window
, m_penGC
, FALSE
, gdkpoints
, n 
); 
 814 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 816     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 818     wxCoord xx 
= XLOG2DEV(x
); 
 819     wxCoord yy 
= YLOG2DEV(y
); 
 820     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 821     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 823     // CMB: draw nothing if transformed w or h is 0 
 824     if (ww 
== 0 || hh 
== 0) return; 
 826     // CMB: handle -ve width and/or height 
 827     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 828     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 832         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 834             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 836                 gdk_gc_set_ts_origin( m_textGC
, 
 837                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 838                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 839                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 840                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 842             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 844                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 845                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 846                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 848             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 850                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 851                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 852                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 854             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 856                 gdk_gc_set_ts_origin( m_brushGC
, 
 857                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 858                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 859                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 860                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 864                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 868         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 869             gdk_draw_rectangle( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
-1, hh
-1 ); 
 872     CalcBoundingBox( x
, y 
); 
 873     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
 876 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius 
) 
 878     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 880     if (radius 
< 0.0) radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
 882     wxCoord xx 
= XLOG2DEV(x
); 
 883     wxCoord yy 
= YLOG2DEV(y
); 
 884     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 885     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 886     wxCoord rr 
= XLOG2DEVREL((wxCoord
)radius
); 
 888     // CMB: handle -ve width and/or height 
 889     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 890     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 892     // CMB: if radius is zero use DrawRectangle() instead to avoid 
 893     // X drawing errors with small radii 
 896         DrawRectangle( x
, y
, width
, height 
); 
 900     // CMB: draw nothing if transformed w or h is 0 
 901     if (ww 
== 0 || hh 
== 0) return; 
 903     // CMB: adjust size if outline is drawn otherwise the result is 
 904     // 1 pixel too wide and high 
 905     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 913         // CMB: ensure dd is not larger than rectangle otherwise we 
 914         // get an hour glass shape 
 916         if (dd 
> ww
) dd 
= ww
; 
 917         if (dd 
> hh
) dd 
= hh
; 
 920         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 922             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 924                 gdk_gc_set_ts_origin( m_textGC
, 
 925                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 926                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 927                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 928                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 929                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 930                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 931                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 932                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 933                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 935             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 937                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 938                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 939                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 940                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 941                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 942                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 943                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 944                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 946             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 948                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 949                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 950                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 951                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 952                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 953                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 954                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 955                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 957             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 959                 gdk_gc_set_ts_origin( m_brushGC
, 
 960                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 961                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 962                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 963                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 964                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 965                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 966                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 967                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 968                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 972                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 973                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 974                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 975                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 976                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 977                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 981         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 983             gdk_draw_line( m_window
, m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy 
); 
 984             gdk_draw_line( m_window
, m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh 
); 
 985             gdk_draw_line( m_window
, m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr 
); 
 986             gdk_draw_line( m_window
, m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr 
); 
 987             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 988             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 989             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 990             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 994     // this ignores the radius 
 995     CalcBoundingBox( x
, y 
); 
 996     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
 999 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
1001     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1003     wxCoord xx 
= XLOG2DEV(x
); 
1004     wxCoord yy 
= YLOG2DEV(y
); 
1005     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
1006     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
1008     // CMB: handle -ve width and/or height 
1009     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
1010     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
1014         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
1016             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
1018                 gdk_gc_set_ts_origin( m_textGC
, 
1019                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
1020                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
1021                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1022                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
1024             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
1026                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
1027                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1028                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1030             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
1032                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
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 ); 
1036             if (m_brush
.GetStyle() == wxSTIPPLE
) 
1038                 gdk_gc_set_ts_origin( m_brushGC
, 
1039                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
1040                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
1041                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1042                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1046                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1050         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1051             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1054     CalcBoundingBox( x
, y 
); 
1055     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
1058 void wxWindowDC::DoDrawIcon( const wxIcon 
&icon
, wxCoord x
, wxCoord y 
) 
1060     // VZ: egcs 1.0.3 refuses to compile this without cast, no idea why 
1061     DoDrawBitmap( (const wxBitmap
&)icon
, x
, y
, true ); 
1064 void wxWindowDC::DoDrawBitmap( const wxBitmap 
&bitmap
, 
1065                                wxCoord x
, wxCoord y
, 
1068     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1070     wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") ); 
1072     bool is_mono 
= bitmap
.GetDepth() == 1; 
1074     // scale/translate size and position 
1075     int xx 
= XLOG2DEV(x
); 
1076     int yy 
= YLOG2DEV(y
); 
1078     int w 
= bitmap
.GetWidth(); 
1079     int h 
= bitmap
.GetHeight(); 
1081     CalcBoundingBox( x
, y 
); 
1082     CalcBoundingBox( x 
+ w
, y 
+ h 
); 
1084     if (!m_window
) return; 
1086     int ww 
= XLOG2DEVREL(w
); 
1087     int hh 
= YLOG2DEVREL(h
); 
1089     // compare to current clipping region 
1090     if (!m_currentClippingRegion
.IsNull()) 
1092         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1093         tmp
.Intersect( m_currentClippingRegion 
); 
1098     // scale bitmap if required 
1099     wxBitmap use_bitmap 
= bitmap
; 
1100     if ((w 
!= ww
) || (h 
!= hh
)) 
1101         use_bitmap 
= use_bitmap
.Rescale( 0, 0, ww
, hh
, ww
, hh 
); 
1103 #if !GTK_CHECK_VERSION(2,2,0) 
1104     // NB: We can't render pixbufs with GTK+ < 2.2, we need to use pixmaps code. 
1105     //     Pixbufs-based bitmaps with alpha channel don't have a mask, so we 
1106     //     have to call GetPixmap() here -- it converts the pixbuf into pixmap 
1107     //     and also creates the mask as a side-effect: 
1108     use_bitmap
.GetPixmap(); 
1111     // apply mask if any 
1112     GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1113     if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1115     GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1117     if (useMask 
&& mask
) 
1119         if (!m_currentClippingRegion
.IsNull()) 
1122             new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 ); 
1123             GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1125             gdk_gc_set_foreground( gc
, &col 
); 
1126             gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1128             gdk_gc_set_background( gc
, &col 
); 
1130             gdk_gc_set_foreground( gc
, &col 
); 
1131             gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1132             gdk_gc_set_clip_origin( gc
, -xx
, -yy 
); 
1133             gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1134             gdk_gc_set_stipple( gc
, mask 
); 
1135             gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1136             g_object_unref (gc
); 
1142                 gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1144                 gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1145             gdk_gc_set_clip_origin( m_textGC
, xx
, yy 
); 
1150                 gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1152                 gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1153             gdk_gc_set_clip_origin( m_penGC
, xx
, yy 
); 
1157     // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1158     // drawing a mono-bitmap (XBitmap) we use the current text GC 
1161         GdkPixmap 
*bitmap2 
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, -1 ); 
1162         GdkGC 
*gc 
= gdk_gc_new( bitmap2 
); 
1163         gdk_gc_set_foreground( gc
, m_textForegroundColour
.GetColor() ); 
1164         gdk_gc_set_background( gc
, m_textBackgroundColour
.GetColor() ); 
1165         gdk_wx_draw_bitmap( bitmap2
, gc
, use_bitmap
.GetPixmap(), 0, 0, 0, 0, -1, -1 ); 
1167         gdk_draw_drawable( m_window
, m_textGC
, bitmap2
, 0, 0, xx
, yy
, -1, -1 ); 
1169         g_object_unref (bitmap2
); 
1170         g_object_unref (gc
); 
1174 #if GTK_CHECK_VERSION(2,2,0) 
1175         if (!gtk_check_version(2,2,0) && use_bitmap
.HasPixbuf()) 
1177             gdk_draw_pixbuf(m_window
, m_penGC
, 
1178                             use_bitmap
.GetPixbuf(), 
1179                             0, 0, xx
, yy
, -1, -1, 
1180                             GDK_RGB_DITHER_NORMAL
, xx
, yy
); 
1185             gdk_draw_drawable(m_window
, m_penGC
, 
1186                               use_bitmap
.GetPixmap(), 
1187                               0, 0, xx
, yy
, -1, -1); 
1191     // remove mask again if any 
1192     if (useMask 
&& mask
) 
1196             gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1197             gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1198             if (!m_currentClippingRegion
.IsNull()) 
1199                 gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1203             gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1204             gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1205             if (!m_currentClippingRegion
.IsNull()) 
1206                 gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1211         g_object_unref (new_mask
); 
1214 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, 
1215                          wxCoord width
, wxCoord height
, 
1217                          wxCoord xsrc
, wxCoord ysrc
, 
1220                          wxCoord xsrcMask
, wxCoord ysrcMask 
) 
1222     wxCHECK_MSG( Ok(), false, wxT("invalid window dc") ); 
1224     wxCHECK_MSG( source
, false, wxT("invalid source dc") ); 
1226     if (!m_window
) return false; 
1228     // transform the source DC coords to the device ones 
1229     xsrc 
= source
->XLOG2DEV(xsrc
); 
1230     ysrc 
= source
->YLOG2DEV(ysrc
); 
1232     wxClientDC 
*srcDC 
= (wxClientDC
*)source
; 
1233     wxMemoryDC 
*memDC 
= (wxMemoryDC
*)source
; 
1235     bool use_bitmap_method 
= false; 
1236     bool is_mono 
= false; 
1238     if (xsrcMask 
== -1 && ysrcMask 
== -1) 
1244     if (srcDC
->m_isMemDC
) 
1246         if (!memDC
->m_selected
.Ok()) return false; 
1248         is_mono 
= (memDC
->m_selected
.GetDepth() == 1); 
1250         // we use the "XCopyArea" way to copy a memory dc into 
1251         // a different window if the memory dc BOTH 
1252         // a) doesn't have any mask or its mask isn't used 
1256         if (useMask 
&& (memDC
->m_selected
.GetMask())) 
1258             // we HAVE TO use the direct way for memory dcs 
1259             // that have mask since the XCopyArea doesn't know 
1261             use_bitmap_method 
= true; 
1265             // we HAVE TO use the direct way for memory dcs 
1266             // that are bitmaps because XCopyArea doesn't cope 
1267             // with different bit depths 
1268             use_bitmap_method 
= true; 
1270         else if ((xsrc 
== 0) && (ysrc 
== 0) && 
1271                  (width 
== memDC
->m_selected
.GetWidth()) && 
1272                  (height 
== memDC
->m_selected
.GetHeight())) 
1274             // we SHOULD use the direct way if all of the bitmap 
1275             // in the memory dc is copied in which case XCopyArea 
1276             // wouldn't be able able to boost performace by reducing 
1277             // the area to be scaled 
1278             use_bitmap_method 
= true; 
1282             use_bitmap_method 
= false; 
1286     CalcBoundingBox( xdest
, ydest 
); 
1287     CalcBoundingBox( xdest 
+ width
, ydest 
+ height 
); 
1289     // scale/translate size and position 
1290     wxCoord xx 
= XLOG2DEV(xdest
); 
1291     wxCoord yy 
= YLOG2DEV(ydest
); 
1293     wxCoord ww 
= XLOG2DEVREL(width
); 
1294     wxCoord hh 
= YLOG2DEVREL(height
); 
1296     // compare to current clipping region 
1297     if (!m_currentClippingRegion
.IsNull()) 
1299         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1300         tmp
.Intersect( m_currentClippingRegion 
); 
1305     int old_logical_func 
= m_logicalFunction
; 
1306     SetLogicalFunction( logical_func 
); 
1308     if (use_bitmap_method
) 
1310         // scale/translate bitmap size 
1311         wxCoord bm_width 
= memDC
->m_selected
.GetWidth(); 
1312         wxCoord bm_height 
= memDC
->m_selected
.GetHeight(); 
1314         // Get clip coords for the bitmap. If we don't 
1315         // use wxBitmap::Rescale(), which can clip the 
1316         // bitmap, these are the same as the original 
1323         // interpret userscale of src too 
1325         memDC
->GetUserScale(&xsc
,&ysc
); 
1326         bm_width 
= (int) (bm_width 
/ xsc
); 
1327         bm_height 
= (int) (bm_height 
/ ysc
); 
1329         wxCoord bm_ww 
= XLOG2DEVREL( bm_width 
); 
1330         wxCoord bm_hh 
= YLOG2DEVREL( bm_height 
); 
1332         // Scale bitmap if required 
1333         wxBitmap use_bitmap
; 
1334         if ((memDC
->m_selected
.GetWidth()!= bm_ww
) || ( memDC
->m_selected
.GetHeight()!= bm_hh
)) 
1336             // This indicates that the blitting code below will get 
1337             // a clipped bitmap and therefore needs to move the origin 
1339             wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1340             tmp
.Intersect( m_currentClippingRegion 
); 
1341             tmp
.GetBox(cx
,cy
,cw
,ch
); 
1343             // Scale and clipped bitmap 
1344             use_bitmap 
= memDC
->m_selected
.Rescale(cx
-xx
,cy
-yy
,cw
,ch
,bm_ww
,bm_hh
); 
1348             // Don't scale bitmap 
1349             use_bitmap 
= memDC
->m_selected
; 
1352         // apply mask if any 
1353         GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1354         if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1356         GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1358         if (useMask 
&& mask
) 
1360             if (!m_currentClippingRegion
.IsNull()) 
1363                 new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 ); 
1364                 GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1366                 gdk_gc_set_foreground( gc
, &col 
); 
1367                 gdk_gc_set_ts_origin( gc
, -xsrcMask
, -ysrcMask
); 
1368                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1370                 gdk_gc_set_background( gc
, &col 
); 
1372                 gdk_gc_set_foreground( gc
, &col 
); 
1373                 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1374                 // was: gdk_gc_set_clip_origin( gc, -xx, -yy ); 
1375                 gdk_gc_set_clip_origin( gc
, -cx
, -cy 
); 
1376                 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1377                 gdk_gc_set_stipple( gc
, mask 
); 
1378                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1379                 g_object_unref (gc
); 
1386                     gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1387                     gdk_gc_set_clip_origin( m_textGC
, cx
, cy 
); 
1391                     gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1392                     gdk_gc_set_clip_origin( m_textGC
, cx
-xsrcMask
, cy
-ysrcMask 
); 
1399                     gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1400                     gdk_gc_set_clip_origin( m_penGC
, cx
, cy 
); 
1404                     gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1405                     gdk_gc_set_clip_origin( m_penGC
, cx
-xsrcMask
, cy
-ysrcMask 
); 
1410         // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1411         // drawing a mono-bitmap (XBitmap) we use the current text GC 
1415             GdkPixmap 
*bitmap 
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, -1 ); 
1416             GdkGC 
*gc 
= gdk_gc_new( bitmap 
); 
1417             gdk_gc_set_foreground( gc
, m_textForegroundColour
.GetColor() ); 
1418             gdk_gc_set_background( gc
, m_textBackgroundColour
.GetColor() ); 
1419             gdk_wx_draw_bitmap( bitmap
, gc
, use_bitmap
.GetPixmap(), 0, 0, 0, 0, -1, -1 ); 
1421             gdk_draw_drawable( m_window
, m_textGC
, bitmap
, xsrc
, ysrc
, cx
, cy
, cw
, ch 
); 
1423             g_object_unref (bitmap
); 
1424             g_object_unref (gc
); 
1428             // was: gdk_draw_drawable( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, xx, yy, ww, hh ); 
1429             gdk_draw_drawable( m_window
, m_penGC
, use_bitmap
.GetPixmap(), xsrc
, ysrc
, cx
, cy
, cw
, ch 
); 
1432         // remove mask again if any 
1433         if (useMask 
&& mask
) 
1437                 gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1438                 gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1439                 if (!m_currentClippingRegion
.IsNull()) 
1440                     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1444                 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1445                 gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1446                 if (!m_currentClippingRegion
.IsNull()) 
1447                     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1452             g_object_unref (new_mask
); 
1454     else // use_bitmap_method 
1456         if ((width 
!= ww
) || (height 
!= hh
)) 
1459             wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1460             tmp
.Intersect( m_currentClippingRegion 
); 
1461             wxCoord cx
,cy
,cw
,ch
; 
1462             tmp
.GetBox(cx
,cy
,cw
,ch
); 
1465             wxBitmap bitmap 
= memDC
->m_selected
.Rescale( cx
-xx
, cy
-yy
, cw
, ch
, ww
, hh 
); 
1467             // draw scaled bitmap 
1468             // was: gdk_draw_drawable( m_window, m_penGC, bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 ); 
1469             gdk_draw_drawable( m_window
, m_penGC
, bitmap
.GetPixmap(), 0, 0, cx
, cy
, -1, -1 ); 
1473             // No scaling and not a memory dc with a mask either 
1475             // copy including child window contents 
1476             gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS 
); 
1477             gdk_draw_drawable( m_window
, m_penGC
, 
1481             gdk_gc_set_subwindow( m_penGC
, GDK_CLIP_BY_CHILDREN 
); 
1485     SetLogicalFunction( old_logical_func 
); 
1490 void wxWindowDC::DoDrawText( const wxString 
&text
, wxCoord x
, wxCoord y 
) 
1492     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1494     if (!m_window
) return; 
1496     if (text
.empty()) return; 
1501     wxCHECK_RET( m_context
, wxT("no Pango context") ); 
1502     wxCHECK_RET( m_layout
, wxT("no Pango layout") ); 
1503     wxCHECK_RET( m_fontdesc
, wxT("no Pango font description") ); 
1505     bool underlined 
= m_font
.Ok() && m_font
.GetUnderlined(); 
1507     const wxCharBuffer data 
= wxGTK_CONV( text 
); 
1510     const size_t datalen 
= strlen(data
); 
1511     pango_layout_set_text( m_layout
, data
, datalen
); 
1515         PangoAttrList 
*attrs 
= pango_attr_list_new(); 
1516         PangoAttribute 
*a 
= pango_attr_underline_new(PANGO_UNDERLINE_SINGLE
); 
1518         a
->end_index 
= datalen
; 
1519         pango_attr_list_insert(attrs
, a
); 
1520         pango_layout_set_attributes(m_layout
, attrs
); 
1521         pango_attr_list_unref(attrs
); 
1526     if (fabs(m_scaleY 
- 1.0) > 0.00001) 
1528          // If there is a user or actually any scale applied to 
1529          // the device context, scale the font. 
1531          // scale font description 
1532          gint oldSize 
= pango_font_description_get_size( m_fontdesc 
); 
1533          double size 
= oldSize
; 
1534          size 
= size 
* m_scaleY
; 
1535          pango_font_description_set_size( m_fontdesc
, (gint
)size 
); 
1537          // actually apply scaled font 
1538          pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1540          pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1541          if ( m_backgroundMode 
== wxSOLID 
) 
1543             gdk_gc_set_foreground(m_textGC
, m_textBackgroundColour
.GetColor()); 
1544             gdk_draw_rectangle(m_window
, m_textGC
, TRUE
, x
, y
, w
, h
); 
1545             gdk_gc_set_foreground(m_textGC
, m_textForegroundColour
.GetColor()); 
1549          gdk_draw_layout( m_window
, m_textGC
, x
, y
, m_layout 
); 
1551          // reset unscaled size 
1552          pango_font_description_set_size( m_fontdesc
, oldSize 
); 
1554          // actually apply unscaled font 
1555          pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1559         pango_layout_get_pixel_size( m_layout
, &w
, &h 
); 
1560         if ( m_backgroundMode 
== wxSOLID 
) 
1562             gdk_gc_set_foreground(m_textGC
, m_textBackgroundColour
.GetColor()); 
1563             gdk_draw_rectangle(m_window
, m_textGC
, TRUE
, x
, y
, w
, h
); 
1564             gdk_gc_set_foreground(m_textGC
, m_textForegroundColour
.GetColor()); 
1567         gdk_draw_layout( m_window
, m_textGC
, x
, y
, m_layout 
); 
1572         // undo underline attributes setting: 
1573         pango_layout_set_attributes(m_layout
, NULL
); 
1579     width 
= wxCoord(width 
/ m_scaleX
); 
1580     height 
= wxCoord(height 
/ m_scaleY
); 
1581     CalcBoundingBox (x 
+ width
, y 
+ height
); 
1582     CalcBoundingBox (x
, y
); 
1586 // TODO: There is an example of rotating text with GTK2 that would probably be 
1587 // a better approach here: 
1588 //           http://www.daa.com.au/pipermail/pygtk/2003-April/005052.html 
1590 void wxWindowDC::DoDrawRotatedText( const wxString 
&text
, wxCoord x
, wxCoord y
, double angle 
) 
1592     if (!m_window 
|| text
.empty()) 
1595     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1597     if ( wxIsNullDouble(angle
) ) 
1599         DrawText(text
, x
, y
); 
1606     // TODO: implement later without GdkFont for GTK 2.0 
1607     GetTextExtent(text
, &w
, &h
, NULL
,NULL
, &m_font
); 
1609     // draw the string normally 
1612     dc
.SelectObject(src
); 
1613     dc
.SetFont(GetFont()); 
1614     dc
.SetBackground(*wxBLACK_BRUSH
); 
1615     dc
.SetBrush(*wxBLACK_BRUSH
); 
1617     dc
.SetTextForeground( *wxWHITE 
); 
1618     dc
.DrawText(text
, 0, 0); 
1619     dc
.SelectObject(wxNullBitmap
); 
1621     // Calculate the size of the rotated bounding box. 
1622     double rad 
= DegToRad(angle
); 
1623     double dx 
= cos(rad
), 
1626     // the rectngle vertices are counted clockwise with the first one being at 
1627     // (0, 0) (or, rather, at (x, y)) 
1629            y2 
= -w
*dy
;      // y axis points to the bottom, hence minus 
1632     double x3 
= x4 
+ x2
, 
1636     wxCoord maxX 
= (wxCoord
)(dmax(x2
, dmax(x3
, x4
)) + 0.5), 
1637             maxY 
= (wxCoord
)(dmax(y2
, dmax(y3
, y4
)) + 0.5), 
1638             minX 
= (wxCoord
)(dmin(x2
, dmin(x3
, x4
)) - 0.5), 
1639             minY 
= (wxCoord
)(dmin(y2
, dmin(y3
, y4
)) - 0.5); 
1642     wxImage image 
= src
.ConvertToImage(); 
1644     image
.ConvertColourToAlpha( m_textForegroundColour
.Red(), 
1645                                 m_textForegroundColour
.Green(), 
1646                                 m_textForegroundColour
.Blue() ); 
1647     image 
= image
.Rotate( rad
, wxPoint(0,0) ); 
1649     int i_angle 
= (int) angle
; 
1650     i_angle 
= i_angle 
% 360; 
1654     if ((i_angle 
>= 90.0) && (i_angle 
< 270.0)) 
1655         xoffset 
= image
.GetWidth(); 
1657     if ((i_angle 
>= 0.0) && (i_angle 
< 180.0)) 
1658         yoffset 
= image
.GetHeight(); 
1660     if ((i_angle 
>= 0) && (i_angle 
< 90)) 
1661         yoffset 
-= (int)( cos(rad
)*h 
); 
1662     if ((i_angle 
>= 90) && (i_angle 
< 180)) 
1663         xoffset 
-= (int)( sin(rad
)*h 
); 
1664     if ((i_angle 
>= 180) && (i_angle 
< 270)) 
1665         yoffset 
-= (int)( cos(rad
)*h 
); 
1666     if ((i_angle 
>= 270) && (i_angle 
< 360)) 
1667         xoffset 
-= (int)( sin(rad
)*h 
); 
1669     int i_x 
= x 
- xoffset
; 
1670     int i_y 
= y 
- yoffset
; 
1673     DoDrawBitmap( src
, i_x
, i_y
, true ); 
1676     // it would be better to draw with non underlined font and draw the line 
1677     // manually here (it would be more straight...) 
1679     if ( m_font
.GetUnderlined() ) 
1681         gdk_draw_line( m_window
, m_textGC
, 
1682                        XLOG2DEV(x 
+ x4
), YLOG2DEV(y 
+ y4 
+ font
->descent
), 
1683                        XLOG2DEV(x 
+ x3
), YLOG2DEV(y 
+ y3 
+ font
->descent
)); 
1687     // update the bounding box 
1688     CalcBoundingBox(x 
+ minX
, y 
+ minY
); 
1689     CalcBoundingBox(x 
+ maxX
, y 
+ maxY
); 
1692 void wxWindowDC::DoGetTextExtent(const wxString 
&string
, 
1693                                  wxCoord 
*width
, wxCoord 
*height
, 
1694                                  wxCoord 
*descent
, wxCoord 
*externalLeading
, 
1695                                  wxFont 
*theFont
) const 
1703     if ( externalLeading 
) 
1704         *externalLeading 
= 0; 
1709     // ensure that theFont is always non-NULL 
1710     if ( !theFont 
|| !theFont
->Ok() ) 
1711         theFont 
= wx_const_cast(wxFont 
*, &m_font
); 
1713     // and use it if it's valid 
1714     if ( theFont
->Ok() ) 
1716         pango_layout_set_font_description
 
1719             theFont
->GetNativeFontInfo()->description
 
1723     // Set layout's text 
1724     const wxCharBuffer dataUTF8 
= wxGTK_CONV_FONT(string
, *theFont
); 
1727         // hardly ideal, but what else can we do if conversion failed? 
1731     pango_layout_set_text( m_layout
, dataUTF8
, strlen(dataUTF8
) ); 
1736         pango_layout_get_pixel_size( m_layout
, width
, &h 
); 
1737         PangoLayoutIter 
*iter 
= pango_layout_get_iter(m_layout
); 
1738         int baseline 
= pango_layout_iter_get_baseline(iter
); 
1739         pango_layout_iter_free(iter
); 
1740         *descent 
= h 
- PANGO_PIXELS(baseline
); 
1743             *height 
= (wxCoord
) h
; 
1747         pango_layout_get_pixel_size( m_layout
, width
, height 
); 
1750     // Reset old font description 
1752         pango_layout_set_font_description( m_layout
, m_fontdesc 
); 
1755 wxCoord 
wxWindowDC::GetCharWidth() const 
1757     pango_layout_set_text( m_layout
, "H", 1 ); 
1759     pango_layout_get_pixel_size( m_layout
, &w
, NULL 
); 
1763 wxCoord 
wxWindowDC::GetCharHeight() const 
1765     PangoFontMetrics 
*metrics 
= pango_context_get_metrics (m_context
, m_fontdesc
, NULL
); 
1766     return PANGO_PIXELS (pango_font_metrics_get_descent (metrics
) + pango_font_metrics_get_ascent (metrics
)); 
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 (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()->GetDepth() != 1) 
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()->GetPixmap() ); 
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()->GetDepth() != 1) 
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()->GetPixmap() ); 
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()