]>
git.saurik.com Git - wxWidgets.git/blob - src/gtk1/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/gtk1/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     GdkWindowPrivate 
*drawable_private
; 
  96     GdkWindowPrivate 
*src_private
; 
  97     GdkGCPrivate 
*gc_private
; 
  99     drawable_private 
= (GdkWindowPrivate
*) drawable
; 
 100     src_private 
= (GdkWindowPrivate
*) src
; 
 101     if (drawable_private
->destroyed 
|| src_private
->destroyed
) 
 104     gint src_width 
= src_private
->width
; 
 105     gint src_height 
= src_private
->height
; 
 107     gc_private 
= (GdkGCPrivate
*) gc
; 
 109     if (width 
== -1) width 
= src_width
; 
 110     if (height 
== -1) height 
= src_height
; 
 112     XCopyPlane( drawable_private
->xdisplay
, 
 113                 src_private
->xwindow
, 
 114                 drawable_private
->xwindow
, 
 122 //----------------------------------------------------------------------------- 
 123 // Implement Pool of Graphic contexts. Creating them takes too much time. 
 124 //----------------------------------------------------------------------------- 
 150 #define GC_POOL_ALLOC_SIZE 100 
 152 static int wxGCPoolSize 
= 0; 
 154 static wxGC 
*wxGCPool 
= NULL
; 
 156 static void wxInitGCPool() 
 158     // This really could wait until the first call to 
 159     // wxGetPoolGC, but we will make the first allocation 
 160     // now when other initialization is being performed. 
 162     // Set initial pool size. 
 163     wxGCPoolSize 
= GC_POOL_ALLOC_SIZE
; 
 165     // Allocate initial pool. 
 166     wxGCPool 
= (wxGC 
*)malloc(wxGCPoolSize 
* sizeof(wxGC
)); 
 167     if (wxGCPool 
== NULL
) 
 169         // If we cannot malloc, then fail with error 
 170         // when debug is enabled.  If debug is not enabled, 
 171         // the problem will eventually get caught 
 173         wxFAIL_MSG( wxT("Cannot allocate GC pool") ); 
 177     // Zero initial pool. 
 178     memset(wxGCPool
, 0, wxGCPoolSize 
* sizeof(wxGC
)); 
 181 static void wxCleanUpGCPool() 
 183     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 185         if (wxGCPool
[i
].m_gc
) 
 186             gdk_gc_unref( wxGCPool
[i
].m_gc 
); 
 194 static GdkGC
* wxGetPoolGC( GdkWindow 
*window
, wxPoolGCType type 
) 
 198     // Look for an available GC. 
 199     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 201         if (!wxGCPool
[i
].m_gc
) 
 203             wxGCPool
[i
].m_gc 
= gdk_gc_new( window 
); 
 204             gdk_gc_set_exposures( wxGCPool
[i
].m_gc
, FALSE 
); 
 205             wxGCPool
[i
].m_type 
= type
; 
 206             wxGCPool
[i
].m_used 
= false; 
 208         if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type 
== type
)) 
 210             wxGCPool
[i
].m_used 
= true; 
 211             return wxGCPool
[i
].m_gc
; 
 215     // We did not find an available GC. 
 216     // We need to grow the GC pool. 
 217     pptr 
= (wxGC 
*)realloc(wxGCPool
, 
 218         (wxGCPoolSize 
+ GC_POOL_ALLOC_SIZE
)*sizeof(wxGC
)); 
 221         // Initialize newly allocated pool. 
 223         memset(&wxGCPool
[wxGCPoolSize
], 0, 
 224             GC_POOL_ALLOC_SIZE
*sizeof(wxGC
)); 
 226         // Initialize entry we will return. 
 227         wxGCPool
[wxGCPoolSize
].m_gc 
= gdk_gc_new( window 
); 
 228         gdk_gc_set_exposures( wxGCPool
[wxGCPoolSize
].m_gc
, FALSE 
); 
 229         wxGCPool
[wxGCPoolSize
].m_type 
= type
; 
 230         wxGCPool
[wxGCPoolSize
].m_used 
= true; 
 232         // Set new value of pool size. 
 233         wxGCPoolSize 
+= GC_POOL_ALLOC_SIZE
; 
 235         // Return newly allocated entry. 
 236         return wxGCPool
[wxGCPoolSize
-GC_POOL_ALLOC_SIZE
].m_gc
; 
 239     // The realloc failed.  Fall through to error. 
 240     wxFAIL_MSG( wxT("No GC available") ); 
 242     return (GdkGC
*) NULL
; 
 245 static void wxFreePoolGC( GdkGC 
*gc 
) 
 247     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 249         if (wxGCPool
[i
].m_gc 
== gc
) 
 251             wxGCPool
[i
].m_used 
= false; 
 256     wxFAIL_MSG( wxT("Wrong GC") ); 
 259 //----------------------------------------------------------------------------- 
 261 //----------------------------------------------------------------------------- 
 263 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
) 
 265 wxWindowDC::wxWindowDC() 
 267     m_penGC 
= (GdkGC 
*) NULL
; 
 268     m_brushGC 
= (GdkGC 
*) NULL
; 
 269     m_textGC 
= (GdkGC 
*) NULL
; 
 270     m_bgGC 
= (GdkGC 
*) NULL
; 
 271     m_cmap 
= (GdkColormap 
*) NULL
; 
 273     m_isScreenDC 
= false; 
 274     m_owner 
= (wxWindow 
*)NULL
; 
 277 wxWindowDC::wxWindowDC( wxWindow 
*window 
) 
 279     wxASSERT_MSG( window
, wxT("DC needs a window") ); 
 281     m_penGC 
= (GdkGC 
*) NULL
; 
 282     m_brushGC 
= (GdkGC 
*) NULL
; 
 283     m_textGC 
= (GdkGC 
*) NULL
; 
 284     m_bgGC 
= (GdkGC 
*) NULL
; 
 285     m_cmap 
= (GdkColormap 
*) NULL
; 
 286     m_owner 
= (wxWindow 
*)NULL
; 
 288     m_isScreenDC 
= false; 
 289     m_font 
= window
->GetFont(); 
 291     GtkWidget 
*widget 
= window
->m_wxwindow
; 
 293     // Some controls don't have m_wxwindow - like wxStaticBox, but the user 
 294     // code should still be able to create wxClientDCs for them, so we will 
 295     // use the parent window here then. 
 298         window 
= window
->GetParent(); 
 299         widget 
= window
->m_wxwindow
; 
 302     wxASSERT_MSG( widget
, wxT("DC needs a widget") ); 
 304     GtkPizza 
*pizza 
= GTK_PIZZA( widget 
); 
 305     m_window 
= pizza
->bin_window
; 
 307     // Window not realized ? 
 310          // Don't report problems as per MSW. 
 316     m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
 320     /* this must be done after SetUpDC, bacause SetUpDC calls the 
 321        repective SetBrush, SetPen, SetBackground etc functions 
 322        to set up the DC. SetBackground call m_owner->SetBackground 
 323        and this might not be desired as the standard dc background 
 324        is white whereas a window might assume gray to be the 
 325        standard (as e.g. wxStatusBar) */ 
 330 wxWindowDC::~wxWindowDC() 
 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     // NB: We can't render pixbufs with GTK+ < 2.2, we need to use pixmaps code. 
1096     //     Pixbufs-based bitmaps with alpha channel don't have a mask, so we 
1097     //     have to call GetPixmap() here -- it converts the pixbuf into pixmap 
1098     //     and also creates the mask as a side-effect: 
1099     use_bitmap
.GetPixmap(); 
1101     // apply mask if any 
1102     GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1103     if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1105     GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1107     if (useMask 
&& mask
) 
1109         if (!m_currentClippingRegion
.IsNull()) 
1112             new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 ); 
1113             GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1115             gdk_gc_set_foreground( gc
, &col 
); 
1116             gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1118             gdk_gc_set_background( gc
, &col 
); 
1120             gdk_gc_set_foreground( gc
, &col 
); 
1121             gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1122             gdk_gc_set_clip_origin( gc
, -xx
, -yy 
); 
1123             gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1124             gdk_gc_set_stipple( gc
, mask 
); 
1125             gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1132                 gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1134                 gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1135             gdk_gc_set_clip_origin( m_textGC
, xx
, yy 
); 
1140                 gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1142                 gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1143             gdk_gc_set_clip_origin( m_penGC
, xx
, yy 
); 
1147     // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1148     // drawing a mono-bitmap (XBitmap) we use the current text GC 
1151         gdk_wx_draw_bitmap( m_window
, m_textGC
, use_bitmap
.GetBitmap(), 0, 0, xx
, yy
, -1, -1 ); 
1155         gdk_draw_pixmap(m_window
, m_penGC
, 
1156                         use_bitmap
.GetPixmap(), 
1157                         0, 0, xx
, yy
, -1, -1); 
1160     // remove mask again if any 
1161     if (useMask 
&& mask
) 
1165             gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1166             gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1167             if (!m_currentClippingRegion
.IsNull()) 
1168                 gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1172             gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1173             gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1174             if (!m_currentClippingRegion
.IsNull()) 
1175                 gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1180         gdk_bitmap_unref( new_mask 
); 
1183 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, 
1184                          wxCoord width
, wxCoord height
, 
1186                          wxCoord xsrc
, wxCoord ysrc
, 
1189                          wxCoord xsrcMask
, wxCoord ysrcMask 
) 
1191     wxCHECK_MSG( Ok(), false, wxT("invalid window dc") ); 
1193     wxCHECK_MSG( source
, false, wxT("invalid source dc") ); 
1195     if (!m_window
) return false; 
1197     // transform the source DC coords to the device ones 
1198     xsrc 
= source
->XLOG2DEV(xsrc
); 
1199     ysrc 
= source
->YLOG2DEV(ysrc
); 
1201     wxClientDC 
*srcDC 
= (wxClientDC
*)source
; 
1202     wxMemoryDC 
*memDC 
= (wxMemoryDC
*)source
; 
1204     bool use_bitmap_method 
= false; 
1205     bool is_mono 
= false; 
1207     if (xsrcMask 
== -1 && ysrcMask 
== -1) 
1213     if (srcDC
->m_isMemDC
) 
1215         if (!memDC
->m_selected
.Ok()) return false; 
1217         is_mono 
= (memDC
->m_selected
.GetDepth() == 1); 
1219         // we use the "XCopyArea" way to copy a memory dc into 
1220         // a different window if the memory dc BOTH 
1221         // a) doesn't have any mask or its mask isn't used 
1225         if (useMask 
&& (memDC
->m_selected
.GetMask())) 
1227             // we HAVE TO use the direct way for memory dcs 
1228             // that have mask since the XCopyArea doesn't know 
1230             use_bitmap_method 
= true; 
1234             // we HAVE TO use the direct way for memory dcs 
1235             // that are bitmaps because XCopyArea doesn't cope 
1236             // with different bit depths 
1237             use_bitmap_method 
= true; 
1239         else if ((xsrc 
== 0) && (ysrc 
== 0) && 
1240                  (width 
== memDC
->m_selected
.GetWidth()) && 
1241                  (height 
== memDC
->m_selected
.GetHeight())) 
1243             // we SHOULD use the direct way if all of the bitmap 
1244             // in the memory dc is copied in which case XCopyArea 
1245             // wouldn't be able able to boost performace by reducing 
1246             // the area to be scaled 
1247             use_bitmap_method 
= true; 
1251             use_bitmap_method 
= false; 
1255     CalcBoundingBox( xdest
, ydest 
); 
1256     CalcBoundingBox( xdest 
+ width
, ydest 
+ height 
); 
1258     // scale/translate size and position 
1259     wxCoord xx 
= XLOG2DEV(xdest
); 
1260     wxCoord yy 
= YLOG2DEV(ydest
); 
1262     wxCoord ww 
= XLOG2DEVREL(width
); 
1263     wxCoord hh 
= YLOG2DEVREL(height
); 
1265     // compare to current clipping region 
1266     if (!m_currentClippingRegion
.IsNull()) 
1268         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1269         tmp
.Intersect( m_currentClippingRegion 
); 
1274     int old_logical_func 
= m_logicalFunction
; 
1275     SetLogicalFunction( logical_func 
); 
1277     if (use_bitmap_method
) 
1279         // scale/translate bitmap size 
1280         wxCoord bm_width 
= memDC
->m_selected
.GetWidth(); 
1281         wxCoord bm_height 
= memDC
->m_selected
.GetHeight(); 
1283         // Get clip coords for the bitmap. If we don't 
1284         // use wxBitmap::Rescale(), which can clip the 
1285         // bitmap, these are the same as the original 
1292         // interpret userscale of src too 
1294         memDC
->GetUserScale(&xsc
,&ysc
); 
1295         bm_width 
= (int) (bm_width 
/ xsc
); 
1296         bm_height 
= (int) (bm_height 
/ ysc
); 
1298         wxCoord bm_ww 
= XLOG2DEVREL( bm_width 
); 
1299         wxCoord bm_hh 
= YLOG2DEVREL( bm_height 
); 
1301         // Scale bitmap if required 
1302         wxBitmap use_bitmap
; 
1303         if ((memDC
->m_selected
.GetWidth()!= bm_ww
) || ( memDC
->m_selected
.GetHeight()!= bm_hh
)) 
1305             // This indicates that the blitting code below will get 
1306             // a clipped bitmap and therefore needs to move the origin 
1308             wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1309             tmp
.Intersect( m_currentClippingRegion 
); 
1310             tmp
.GetBox(cx
,cy
,cw
,ch
); 
1312             // Scale and clipped bitmap 
1313             use_bitmap 
= memDC
->m_selected
.Rescale(cx
-xx
,cy
-yy
,cw
,ch
,bm_ww
,bm_hh
); 
1317             // Don't scale bitmap 
1318             use_bitmap 
= memDC
->m_selected
; 
1321         // apply mask if any 
1322         GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1323         if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1325         GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1327         if (useMask 
&& mask
) 
1329             if (!m_currentClippingRegion
.IsNull()) 
1332                 new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 ); 
1333                 GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1335                 gdk_gc_set_foreground( gc
, &col 
); 
1336                 gdk_gc_set_ts_origin( gc
, -xsrcMask
, -ysrcMask
); 
1337                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1339                 gdk_gc_set_background( gc
, &col 
); 
1341                 gdk_gc_set_foreground( gc
, &col 
); 
1342                 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1343                 // was: gdk_gc_set_clip_origin( gc, -xx, -yy ); 
1344                 gdk_gc_set_clip_origin( gc
, -cx
, -cy 
); 
1345                 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1346                 gdk_gc_set_stipple( gc
, mask 
); 
1347                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1355                     gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1356                     gdk_gc_set_clip_origin( m_textGC
, cx
, cy 
); 
1360                     gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1361                     gdk_gc_set_clip_origin( m_textGC
, cx
-xsrcMask
, cy
-ysrcMask 
); 
1368                     gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1369                     gdk_gc_set_clip_origin( m_penGC
, cx
, cy 
); 
1373                     gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1374                     gdk_gc_set_clip_origin( m_penGC
, cx
-xsrcMask
, cy
-ysrcMask 
); 
1379         // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1380         // drawing a mono-bitmap (XBitmap) we use the current text GC 
1384             // was: gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), xsrc, ysrc, xx, yy, ww, hh ); 
1385             gdk_wx_draw_bitmap( m_window
, m_textGC
, use_bitmap
.GetBitmap(), xsrc
, ysrc
, cx
, cy
, cw
, ch 
); 
1389             // was: gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, xx, yy, ww, hh ); 
1390             gdk_draw_pixmap( m_window
, m_penGC
, use_bitmap
.GetPixmap(), xsrc
, ysrc
, cx
, cy
, cw
, ch 
); 
1393         // remove mask again if any 
1394         if (useMask 
&& mask
) 
1398                 gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1399                 gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1400                 if (!m_currentClippingRegion
.IsNull()) 
1401                     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1405                 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1406                 gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1407                 if (!m_currentClippingRegion
.IsNull()) 
1408                     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1413             gdk_bitmap_unref( new_mask 
); 
1415     else // use_bitmap_method 
1417         if ((width 
!= ww
) || (height 
!= hh
)) 
1420             wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1421             tmp
.Intersect( m_currentClippingRegion 
); 
1422             wxCoord cx
,cy
,cw
,ch
; 
1423             tmp
.GetBox(cx
,cy
,cw
,ch
); 
1426             wxBitmap bitmap 
= memDC
->m_selected
.Rescale( cx
-xx
, cy
-yy
, cw
, ch
, ww
, hh 
); 
1428             // draw scaled bitmap 
1429             // was: gdk_draw_pixmap( m_window, m_penGC, bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 ); 
1430             gdk_draw_pixmap( m_window
, m_penGC
, bitmap
.GetPixmap(), 0, 0, cx
, cy
, -1, -1 ); 
1434             // No scaling and not a memory dc with a mask either 
1436             // copy including child window contents 
1437             gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS 
); 
1438             gdk_window_copy_area( m_window
, m_penGC
, xx
, yy
, 
1440                                   xsrc
, ysrc
, width
, height 
); 
1441             gdk_gc_set_subwindow( m_penGC
, GDK_CLIP_BY_CHILDREN 
); 
1445     SetLogicalFunction( old_logical_func 
); 
1450 void wxWindowDC::DoDrawText( const wxString 
&text
, wxCoord x
, wxCoord y 
) 
1452     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1454     if (!m_window
) return; 
1456     if (text
.empty()) return; 
1458     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1460     wxCHECK_RET( font
, wxT("invalid font") ); 
1465     wxCoord width 
= gdk_string_width( font
, text
.mbc_str() ); 
1466     wxCoord height 
= font
->ascent 
+ font
->descent
; 
1468     if ( m_backgroundMode 
== wxSOLID 
) 
1470         gdk_gc_set_foreground( m_textGC
, m_textBackgroundColour
.GetColor() ); 
1471         gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, x
, y
, width
, height 
); 
1472         gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
1474     gdk_draw_string( m_window
, font
, m_textGC
, x
, y 
+ font
->ascent
, text
.mbc_str() ); 
1476     /* CMB 17/7/98: simple underline: ignores scaling and underlying 
1477        X font's XA_UNDERLINE_POSITION and XA_UNDERLINE_THICKNESS 
1478        properties (see wxXt implementation) */ 
1479     if (m_font
.GetUnderlined()) 
1481         wxCoord ul_y 
= y 
+ font
->ascent
; 
1482         if (font
->descent 
> 0) ul_y
++; 
1483         gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x 
+ width
, ul_y
); 
1486     width 
= wxCoord(width 
/ m_scaleX
); 
1487     height 
= wxCoord(height 
/ m_scaleY
); 
1488     CalcBoundingBox (x 
+ width
, y 
+ height
); 
1489     CalcBoundingBox (x
, y
); 
1493 // TODO: There is an example of rotating text with GTK2 that would probably be 
1494 // a better approach here: 
1495 //           http://www.daa.com.au/pipermail/pygtk/2003-April/005052.html 
1497 void wxWindowDC::DoDrawRotatedText( const wxString 
&text
, wxCoord x
, wxCoord y
, double angle 
) 
1499     if ( wxIsNullDouble(angle
) ) 
1501         DrawText(text
, x
, y
); 
1505     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1507     if (!m_window
) return; 
1512     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1514     wxCHECK_RET( font
, wxT("invalid font") ); 
1516     // the size of the text 
1517     w 
= gdk_string_width( font
, text
.mbc_str() ); 
1518     h 
= font
->ascent 
+ font
->descent
; 
1520     // draw the string normally 
1523     dc
.SelectObject(src
); 
1524     dc
.SetFont(GetFont()); 
1525     dc
.SetBackground(*wxBLACK_BRUSH
); 
1526     dc
.SetBrush(*wxBLACK_BRUSH
); 
1528     dc
.SetTextForeground( *wxWHITE 
); 
1529     dc
.DrawText(text
, 0, 0); 
1530     dc
.SelectObject(wxNullBitmap
); 
1532     // Calculate the size of the rotated bounding box. 
1533     double rad 
= DegToRad(angle
); 
1534     double dx 
= cos(rad
), 
1537     // the rectngle vertices are counted clockwise with the first one being at 
1538     // (0, 0) (or, rather, at (x, y)) 
1540            y2 
= -w
*dy
;      // y axis points to the bottom, hence minus 
1543     double x3 
= x4 
+ x2
, 
1547     wxCoord maxX 
= (wxCoord
)(dmax(x2
, dmax(x3
, x4
)) + 0.5), 
1548             maxY 
= (wxCoord
)(dmax(y2
, dmax(y3
, y4
)) + 0.5), 
1549             minX 
= (wxCoord
)(dmin(x2
, dmin(x3
, x4
)) - 0.5), 
1550             minY 
= (wxCoord
)(dmin(y2
, dmin(y3
, y4
)) - 0.5); 
1553     wxImage image 
= src
.ConvertToImage(); 
1555     image
.ConvertColourToAlpha( m_textForegroundColour
.Red(), 
1556                                 m_textForegroundColour
.Green(), 
1557                                 m_textForegroundColour
.Blue() ); 
1558     image 
= image
.Rotate( rad
, wxPoint(0,0) ); 
1560     int i_angle 
= (int) angle
; 
1561     i_angle 
= i_angle 
% 360; 
1565     if ((i_angle 
>= 90.0) && (i_angle 
< 270.0)) 
1566         xoffset 
= image
.GetWidth(); 
1568     if ((i_angle 
>= 0.0) && (i_angle 
< 180.0)) 
1569         yoffset 
= image
.GetHeight(); 
1571     if ((i_angle 
>= 0) && (i_angle 
< 90)) 
1572         yoffset 
-= (int)( cos(rad
)*h 
); 
1573     if ((i_angle 
>= 90) && (i_angle 
< 180)) 
1574         xoffset 
-= (int)( sin(rad
)*h 
); 
1575     if ((i_angle 
>= 180) && (i_angle 
< 270)) 
1576         yoffset 
-= (int)( cos(rad
)*h 
); 
1577     if ((i_angle 
>= 270) && (i_angle 
< 360)) 
1578         xoffset 
-= (int)( sin(rad
)*h 
); 
1580     int i_x 
= x 
- xoffset
; 
1581     int i_y 
= y 
- yoffset
; 
1584     DoDrawBitmap( src
, i_x
, i_y
, true ); 
1587     // it would be better to draw with non underlined font and draw the line 
1588     // manually here (it would be more straight...) 
1590     if ( m_font
.GetUnderlined() ) 
1592         gdk_draw_line( m_window
, m_textGC
, 
1593                        XLOG2DEV(x 
+ x4
), YLOG2DEV(y 
+ y4 
+ font
->descent
), 
1594                        XLOG2DEV(x 
+ x3
), YLOG2DEV(y 
+ y3 
+ font
->descent
)); 
1598     // update the bounding box 
1599     CalcBoundingBox(x 
+ minX
, y 
+ minY
); 
1600     CalcBoundingBox(x 
+ maxX
, y 
+ maxY
); 
1603 void wxWindowDC::DoGetTextExtent(const wxString 
&string
, 
1604                                  wxCoord 
*width
, wxCoord 
*height
, 
1605                                  wxCoord 
*descent
, wxCoord 
*externalLeading
, 
1606                                  wxFont 
*theFont
) const 
1614     if ( externalLeading 
) 
1615         *externalLeading 
= 0; 
1622     wxFont fontToUse 
= m_font
; 
1624         fontToUse 
= *theFont
; 
1626     GdkFont 
*font 
= fontToUse
.GetInternalFont( m_scaleY 
); 
1631         *width 
= wxCoord(gdk_string_width( font
, string
.mbc_str() ) / m_scaleX
); 
1633         *height 
= wxCoord((font
->ascent 
+ font
->descent
) / m_scaleY
); 
1635         *descent 
= wxCoord(font
->descent 
/ m_scaleY
); 
1638 wxCoord 
wxWindowDC::GetCharWidth() const 
1640     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1641     wxCHECK_MSG( font
, -1, wxT("invalid font") ); 
1643     return wxCoord(gdk_string_width( font
, "H" ) / m_scaleX
); 
1646 wxCoord 
wxWindowDC::GetCharHeight() const 
1648     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1649     wxCHECK_MSG( font
, -1, wxT("invalid font") ); 
1651     return wxCoord((font
->ascent 
+ font
->descent
) / m_scaleY
); 
1654 void wxWindowDC::Clear() 
1656     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1658     if (!m_window
) return; 
1660     // VZ: the code below results in infinite recursion and crashes when 
1661     //     dc.Clear() is done from OnPaint() so I disable it for now. 
1662     //     I don't know what the correct fix is but Clear() surely should not 
1663     //     reenter OnPaint()! 
1665     /* - we either are a memory dc or have a window as the 
1666        owner. anything else shouldn't happen. 
1667        - we don't use gdk_window_clear() as we don't set 
1668        the window's background colour anymore. it is too 
1669        much pain to keep the DC's and the window's back- 
1670        ground colour in synch. */ 
1681         GetSize( &width
, &height 
); 
1682         gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height 
); 
1687     GetSize( &width
, &height 
); 
1688     gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height 
); 
1692 void wxWindowDC::SetFont( const wxFont 
&font 
) 
1697 void wxWindowDC::SetPen( const wxPen 
&pen 
) 
1699     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1701     if (m_pen 
== pen
) return; 
1705     if (!m_pen
.Ok()) return; 
1707     if (!m_window
) return; 
1709     gint width 
= m_pen
.GetWidth(); 
1712         // CMB: if width is non-zero scale it with the dc 
1717         // X doesn't allow different width in x and y and so we take 
1720                    ( fabs((double) XLOG2DEVREL(width
)) + 
1721                      fabs((double) YLOG2DEVREL(width
)) ) / 2.0; 
1725             // width can't be 0 or an internal GTK error occurs inside 
1726             // gdk_gc_set_dashes() below 
1731     static const wxGTKDash dotted
[] = {1, 1}; 
1732     static const wxGTKDash short_dashed
[] = {2, 2}; 
1733     static const wxGTKDash wxCoord_dashed
[] = {2, 4}; 
1734     static const wxGTKDash dotted_dashed
[] = {3, 3, 1, 3}; 
1736     // We express dash pattern in pen width unit, so we are 
1737     // independent of zoom factor and so on... 
1739     const wxGTKDash 
*req_dash
; 
1741     GdkLineStyle lineStyle 
= GDK_LINE_SOLID
; 
1742     switch (m_pen
.GetStyle()) 
1746             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1747             req_nb_dash 
= m_pen
.GetDashCount(); 
1748             req_dash 
= (wxGTKDash
*)m_pen
.GetDash(); 
1753             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1760             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1762             req_dash 
= wxCoord_dashed
; 
1767             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1769             req_dash 
= short_dashed
; 
1774 //            lineStyle = GDK_LINE_DOUBLE_DASH; 
1775             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1777             req_dash 
= dotted_dashed
; 
1782         case wxSTIPPLE_MASK_OPAQUE
: 
1787             lineStyle 
= GDK_LINE_SOLID
; 
1788             req_dash 
= (wxGTKDash
*)NULL
; 
1794     if (req_dash 
&& req_nb_dash
) 
1796         wxGTKDash 
*real_req_dash 
= new wxGTKDash
[req_nb_dash
]; 
1799             for (int i 
= 0; i 
< req_nb_dash
; i
++) 
1800                 real_req_dash
[i
] = req_dash
[i
] * width
; 
1801             gdk_gc_set_dashes( m_penGC
, 0, real_req_dash
, req_nb_dash 
); 
1802             delete[] real_req_dash
; 
1806             // No Memory. We use non-scaled dash pattern... 
1807             gdk_gc_set_dashes( m_penGC
, 0, (wxGTKDash
*)req_dash
, req_nb_dash 
); 
1811     GdkCapStyle capStyle 
= GDK_CAP_ROUND
; 
1812     switch (m_pen
.GetCap()) 
1814         case wxCAP_PROJECTING
: { capStyle 
= GDK_CAP_PROJECTING
; break; } 
1815         case wxCAP_BUTT
:       { capStyle 
= GDK_CAP_BUTT
;       break; } 
1822                 capStyle 
= GDK_CAP_NOT_LAST
; 
1826                 capStyle 
= GDK_CAP_ROUND
; 
1832     GdkJoinStyle joinStyle 
= GDK_JOIN_ROUND
; 
1833     switch (m_pen
.GetJoin()) 
1835         case wxJOIN_BEVEL
: { joinStyle 
= GDK_JOIN_BEVEL
; break; } 
1836         case wxJOIN_MITER
: { joinStyle 
= GDK_JOIN_MITER
; break; } 
1838         default:           { joinStyle 
= GDK_JOIN_ROUND
; break; } 
1841     gdk_gc_set_line_attributes( m_penGC
, width
, lineStyle
, capStyle
, joinStyle 
); 
1843     m_pen
.GetColour().CalcPixel( m_cmap 
); 
1844     gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() ); 
1847 void wxWindowDC::SetBrush( const wxBrush 
&brush 
) 
1849     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1851     if (m_brush 
== brush
) return; 
1855     if (!m_brush
.Ok()) return; 
1857     if (!m_window
) return; 
1859     m_brush
.GetColour().CalcPixel( m_cmap 
); 
1860     gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() ); 
1862     gdk_gc_set_fill( m_brushGC
, GDK_SOLID 
); 
1864     if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok())) 
1866         if (m_brush
.GetStipple()->GetPixmap()) 
1868             gdk_gc_set_fill( m_brushGC
, GDK_TILED 
); 
1869             gdk_gc_set_tile( m_brushGC
, m_brush
.GetStipple()->GetPixmap() ); 
1873             gdk_gc_set_fill( m_brushGC
, GDK_STIPPLED 
); 
1874             gdk_gc_set_stipple( m_brushGC
, m_brush
.GetStipple()->GetBitmap() ); 
1878     if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
1880         gdk_gc_set_fill( m_textGC
, GDK_OPAQUE_STIPPLED
); 
1881         gdk_gc_set_stipple( m_textGC
, m_brush
.GetStipple()->GetMask()->GetBitmap() ); 
1884     if (m_brush
.IsHatch()) 
1886         gdk_gc_set_fill( m_brushGC
, GDK_STIPPLED 
); 
1887         int num 
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
; 
1888         gdk_gc_set_stipple( m_brushGC
, hatches
[num
] ); 
1892 void wxWindowDC::SetBackground( const wxBrush 
&brush 
) 
1894    /* CMB 21/7/98: Added SetBackground. Sets background brush 
1895     * for Clear() and bg colour for shapes filled with cross-hatch brush */ 
1897     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1899     if (m_backgroundBrush 
== brush
) return; 
1901     m_backgroundBrush 
= brush
; 
1903     if (!m_backgroundBrush
.Ok()) return; 
1905     if (!m_window
) return; 
1907     m_backgroundBrush
.GetColour().CalcPixel( m_cmap 
); 
1908     gdk_gc_set_background( m_brushGC
, m_backgroundBrush
.GetColour().GetColor() ); 
1909     gdk_gc_set_background( m_penGC
, m_backgroundBrush
.GetColour().GetColor() ); 
1910     gdk_gc_set_background( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() ); 
1911     gdk_gc_set_foreground( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() ); 
1913     gdk_gc_set_fill( m_bgGC
, GDK_SOLID 
); 
1915     if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok())) 
1917         if (m_backgroundBrush
.GetStipple()->GetPixmap()) 
1919             gdk_gc_set_fill( m_bgGC
, GDK_TILED 
); 
1920             gdk_gc_set_tile( m_bgGC
, m_backgroundBrush
.GetStipple()->GetPixmap() ); 
1924             gdk_gc_set_fill( m_bgGC
, GDK_STIPPLED 
); 
1925             gdk_gc_set_stipple( m_bgGC
, m_backgroundBrush
.GetStipple()->GetBitmap() ); 
1929     if (m_backgroundBrush
.IsHatch()) 
1931         gdk_gc_set_fill( m_bgGC
, GDK_STIPPLED 
); 
1932         int num 
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
; 
1933         gdk_gc_set_stipple( m_bgGC
, hatches
[num
] ); 
1937 void wxWindowDC::SetLogicalFunction( int function 
) 
1939     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1941     if (m_logicalFunction 
== function
) 
1944     // VZ: shouldn't this be a CHECK? 
1951         case wxXOR
:          mode 
= GDK_XOR
;           break; 
1952         case wxINVERT
:       mode 
= GDK_INVERT
;        break; 
1953         case wxOR_REVERSE
:   mode 
= GDK_OR_REVERSE
;    break; 
1954         case wxAND_REVERSE
:  mode 
= GDK_AND_REVERSE
;   break; 
1955         case wxCLEAR
:        mode 
= GDK_CLEAR
;         break; 
1956         case wxSET
:          mode 
= GDK_SET
;           break; 
1957         case wxOR_INVERT
:    mode 
= GDK_OR_INVERT
;     break; 
1958         case wxAND
:          mode 
= GDK_AND
;           break; 
1959         case wxOR
:           mode 
= GDK_OR
;            break; 
1960         case wxEQUIV
:        mode 
= GDK_EQUIV
;         break; 
1961         case wxNAND
:         mode 
= GDK_NAND
;          break; 
1962         case wxAND_INVERT
:   mode 
= GDK_AND_INVERT
;    break; 
1963         case wxCOPY
:         mode 
= GDK_COPY
;          break; 
1964         case wxNO_OP
:        mode 
= GDK_NOOP
;          break; 
1965         case wxSRC_INVERT
:   mode 
= GDK_COPY_INVERT
;   break; 
1967         // unsupported by GTK 
1968         case wxNOR
:          mode 
= GDK_COPY
;          break; 
1970            wxFAIL_MSG( wxT("unsupported logical function") ); 
1974     m_logicalFunction 
= function
; 
1976     gdk_gc_set_function( m_penGC
, mode 
); 
1977     gdk_gc_set_function( m_brushGC
, mode 
); 
1979     // to stay compatible with wxMSW, we don't apply ROPs to the text 
1980     // operations (i.e. DrawText/DrawRotatedText). 
1981     // True, but mono-bitmaps use the m_textGC and they use ROPs as well. 
1982     gdk_gc_set_function( m_textGC
, mode 
); 
1985 void wxWindowDC::SetTextForeground( const wxColour 
&col 
) 
1987     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1989     // don't set m_textForegroundColour to an invalid colour as we'd crash 
1990     // later then (we use m_textForegroundColour.GetColor() without checking 
1992     if ( !col
.Ok() || (m_textForegroundColour 
== col
) ) 
1995     m_textForegroundColour 
= col
; 
1999         m_textForegroundColour
.CalcPixel( m_cmap 
); 
2000         gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
2004 void wxWindowDC::SetTextBackground( const wxColour 
&col 
) 
2006     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2009     if ( !col
.Ok() || (m_textBackgroundColour 
== col
) ) 
2012     m_textBackgroundColour 
= col
; 
2016         m_textBackgroundColour
.CalcPixel( m_cmap 
); 
2017         gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() ); 
2021 void wxWindowDC::SetBackgroundMode( int mode 
) 
2023     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2025     m_backgroundMode 
= mode
; 
2027     if (!m_window
) return; 
2029     // CMB 21/7/98: fill style of cross-hatch brushes is affected by 
2030     // transparent/solid background mode 
2032     if (m_brush
.GetStyle() != wxSOLID 
&& m_brush
.GetStyle() != wxTRANSPARENT
) 
2034         gdk_gc_set_fill( m_brushGC
, 
2035           (m_backgroundMode 
== wxTRANSPARENT
) ? GDK_STIPPLED 
: GDK_OPAQUE_STIPPLED
); 
2039 void wxWindowDC::SetPalette( const wxPalette
& WXUNUSED(palette
) ) 
2041     wxFAIL_MSG( wxT("wxWindowDC::SetPalette not implemented") ); 
2044 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
2046     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2048     if (!m_window
) return; 
2051     rect
.x 
= XLOG2DEV(x
); 
2052     rect
.y 
= YLOG2DEV(y
); 
2053     rect
.width 
= XLOG2DEVREL(width
); 
2054     rect
.height 
= YLOG2DEVREL(height
); 
2056     if (!m_currentClippingRegion
.IsNull()) 
2057         m_currentClippingRegion
.Intersect( rect 
); 
2059         m_currentClippingRegion
.Union( rect 
); 
2061 #if USE_PAINT_REGION 
2062     if (!m_paintClippingRegion
.IsNull()) 
2063         m_currentClippingRegion
.Intersect( m_paintClippingRegion 
); 
2066     wxCoord xx
, yy
, ww
, hh
; 
2067     m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh 
); 
2068     wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh 
); 
2070     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2071     gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2072     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2073     gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2076 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion 
®ion  
) 
2078     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2082         DestroyClippingRegion(); 
2086     if (!m_window
) return; 
2088     if (!m_currentClippingRegion
.IsNull()) 
2089         m_currentClippingRegion
.Intersect( region 
); 
2091         m_currentClippingRegion
.Union( region 
); 
2093 #if USE_PAINT_REGION 
2094     if (!m_paintClippingRegion
.IsNull()) 
2095         m_currentClippingRegion
.Intersect( m_paintClippingRegion 
); 
2098     wxCoord xx
, yy
, ww
, hh
; 
2099     m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh 
); 
2100     wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh 
); 
2102     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2103     gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2104     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2105     gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2108 void wxWindowDC::DestroyClippingRegion() 
2110     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2112     wxDC::DestroyClippingRegion(); 
2114     m_currentClippingRegion
.Clear(); 
2116 #if USE_PAINT_REGION 
2117     if (!m_paintClippingRegion
.IsEmpty()) 
2118         m_currentClippingRegion
.Union( m_paintClippingRegion 
); 
2121     if (!m_window
) return; 
2123     if (m_currentClippingRegion
.IsEmpty()) 
2125         gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle 
*) NULL 
); 
2126         gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle 
*) NULL 
); 
2127         gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle 
*) NULL 
); 
2128         gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle 
*) NULL 
); 
2132         gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2133         gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2134         gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2135         gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2139 void wxWindowDC::Destroy() 
2141     if (m_penGC
) wxFreePoolGC( m_penGC 
); 
2142     m_penGC 
= (GdkGC
*) NULL
; 
2143     if (m_brushGC
) wxFreePoolGC( m_brushGC 
); 
2144     m_brushGC 
= (GdkGC
*) NULL
; 
2145     if (m_textGC
) wxFreePoolGC( m_textGC 
); 
2146     m_textGC 
= (GdkGC
*) NULL
; 
2147     if (m_bgGC
) wxFreePoolGC( m_bgGC 
); 
2148     m_bgGC 
= (GdkGC
*) NULL
; 
2151 void wxWindowDC::ComputeScaleAndOrigin() 
2153     const wxRealPoint 
origScale(m_scaleX
, m_scaleY
); 
2155     wxDC::ComputeScaleAndOrigin(); 
2157     // if scale has changed call SetPen to recalulate the line width 
2158     if ( wxRealPoint(m_scaleX
, m_scaleY
) != origScale 
&& m_pen
.Ok() ) 
2160         // this is a bit artificial, but we need to force wxDC to think the pen 
2168 // Resolution in pixels per logical inch 
2169 wxSize 
wxWindowDC::GetPPI() const 
2171     return wxSize( (int) (m_mm_to_pix_x 
* 25.4 + 0.5), (int) (m_mm_to_pix_y 
* 25.4 + 0.5)); 
2174 int wxWindowDC::GetDepth() const 
2176     wxFAIL_MSG(wxT("not implemented")); 
2182 //----------------------------------------------------------------------------- 
2184 //----------------------------------------------------------------------------- 
2186 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
) 
2188 // Limit the paint region to the window size. Sometimes 
2189 // the paint region is too big, and this risks X11 errors 
2190 static void wxLimitRegionToSize(wxRegion
& region
, const wxSize
& sz
) 
2192     wxRect originalRect 
= region
.GetBox(); 
2193     wxRect 
rect(originalRect
); 
2194     if (rect
.width 
+ rect
.x 
> sz
.x
) 
2195         rect
.width 
= sz
.x 
- rect
.x
; 
2196     if (rect
.height 
+ rect
.y 
> sz
.y
) 
2197         rect
.height 
= sz
.y 
- rect
.y
; 
2198     if (rect 
!= originalRect
) 
2200         region 
= wxRegion(rect
); 
2201         wxLogTrace(wxT("painting"), wxT("Limiting region from %d, %d, %d, %d to %d, %d, %d, %d\n"), 
2202                    originalRect
.x
, originalRect
.y
, originalRect
.width
, originalRect
.height
, 
2203                    rect
.x
, rect
.y
, rect
.width
, rect
.height
); 
2207 wxPaintDC::wxPaintDC( wxWindow 
*win 
) 
2210 #if USE_PAINT_REGION 
2211     if (!win
->m_clipPaintRegion
) 
2214     wxSize sz 
= win
->GetSize(); 
2215     m_paintClippingRegion 
= win
->GetUpdateRegion(); 
2216     wxLimitRegionToSize(m_paintClippingRegion
, sz
); 
2218     GdkRegion 
*region 
= m_paintClippingRegion
.GetRegion(); 
2221         m_currentClippingRegion
.Union( m_paintClippingRegion 
); 
2222         wxLimitRegionToSize(m_currentClippingRegion
, sz
); 
2224         if (sz
.x 
<= 0 || sz
.y 
<= 0) 
2227         gdk_gc_set_clip_region( m_penGC
, region 
); 
2228         gdk_gc_set_clip_region( m_brushGC
, region 
); 
2229         gdk_gc_set_clip_region( m_textGC
, region 
); 
2230         gdk_gc_set_clip_region( m_bgGC
, region 
); 
2232 #endif // USE_PAINT_REGION 
2235 //----------------------------------------------------------------------------- 
2237 //----------------------------------------------------------------------------- 
2239 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
) 
2241 wxClientDC::wxClientDC( wxWindow 
*win 
) 
2244     wxCHECK_RET( win
, _T("NULL window in wxClientDC::wxClientDC") ); 
2246 #ifdef __WXUNIVERSAL__ 
2247     wxPoint ptOrigin 
= win
->GetClientAreaOrigin(); 
2248     SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
); 
2249     wxSize size 
= win
->GetClientSize(); 
2250     SetClippingRegion(wxPoint(0, 0), size
); 
2251 #endif // __WXUNIVERSAL__ 
2254 void wxClientDC::DoGetSize(int *width
, int *height
) const 
2256     wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") ); 
2258     m_owner
->GetClientSize( width
, height 
); 
2261 // ---------------------------------------------------------------------------- 
2263 // ---------------------------------------------------------------------------- 
2265 class wxDCModule 
: public wxModule
 
2272     DECLARE_DYNAMIC_CLASS(wxDCModule
) 
2275 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
) 
2277 bool wxDCModule::OnInit() 
2283 void wxDCModule::OnExit()