]>
git.saurik.com Git - wxWidgets.git/blob - src/gtk1/dcclient.cpp
329d62d9ebeb9988f2ba0c848c91788998b7688c
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk1/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 
  24     #include "wx/module.h" 
  27 #include "wx/fontutil.h" 
  29 #include "wx/gtk1/win_gtk.h" 
  33 #include <gdk/gdkprivate.h> 
  36 //----------------------------------------------------------------------------- 
  38 //----------------------------------------------------------------------------- 
  40 #define USE_PAINT_REGION 1 
  42 //----------------------------------------------------------------------------- 
  44 //----------------------------------------------------------------------------- 
  54 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH) 
  55 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH) 
  58 static GdkPixmap  
*hatches
[num_hatches
]; 
  59 static GdkPixmap 
**hatch_bitmap 
= (GdkPixmap 
**) NULL
; 
  61 extern GtkWidget 
*wxGetRootWindow(); 
  63 //----------------------------------------------------------------------------- 
  65 //----------------------------------------------------------------------------- 
  67 const double RAD2DEG  
= 180.0 / M_PI
; 
  69 // ---------------------------------------------------------------------------- 
  71 // ---------------------------------------------------------------------------- 
  73 static inline double dmax(double a
, double b
) { return a 
> b 
? a 
: b
; } 
  74 static inline double dmin(double a
, double b
) { return a 
< b 
? a 
: b
; } 
  76 static inline double DegToRad(double deg
) { return (deg 
* M_PI
) / 180.0; } 
  78 //----------------------------------------------------------------------------- 
  79 // temporary implementation of the missing GDK function 
  80 //----------------------------------------------------------------------------- 
  82 #include "gdk/gdkprivate.h" 
  84 void gdk_wx_draw_bitmap(GdkDrawable  
*drawable
, 
  94     wxCHECK_RET( drawable
, _T("NULL drawable in gdk_wx_draw_bitmap") ); 
  95     wxCHECK_RET( src
, _T("NULL src in gdk_wx_draw_bitmap") ); 
  96     wxCHECK_RET( gc
, _T("NULL gc in gdk_wx_draw_bitmap") ); 
  98     GdkWindowPrivate 
*drawable_private
; 
  99     GdkWindowPrivate 
*src_private
; 
 100     GdkGCPrivate 
*gc_private
; 
 102     drawable_private 
= (GdkWindowPrivate
*) drawable
; 
 103     src_private 
= (GdkWindowPrivate
*) src
; 
 104     if (drawable_private
->destroyed 
|| src_private
->destroyed
) 
 107     gint src_width 
= src_private
->width
; 
 108     gint src_height 
= src_private
->height
; 
 110     gc_private 
= (GdkGCPrivate
*) gc
; 
 112     if (width 
== -1) width 
= src_width
; 
 113     if (height 
== -1) height 
= src_height
; 
 115     XCopyPlane( drawable_private
->xdisplay
, 
 116                 src_private
->xwindow
, 
 117                 drawable_private
->xwindow
, 
 125 //----------------------------------------------------------------------------- 
 126 // Implement Pool of Graphic contexts. Creating them takes too much time. 
 127 //----------------------------------------------------------------------------- 
 153 #define GC_POOL_ALLOC_SIZE 100 
 155 static int wxGCPoolSize 
= 0; 
 157 static wxGC 
*wxGCPool 
= NULL
; 
 159 static void wxInitGCPool() 
 161     // This really could wait until the first call to 
 162     // wxGetPoolGC, but we will make the first allocation 
 163     // now when other initialization is being performed. 
 165     // Set initial pool size. 
 166     wxGCPoolSize 
= GC_POOL_ALLOC_SIZE
; 
 168     // Allocate initial pool. 
 169     wxGCPool 
= (wxGC 
*)malloc(wxGCPoolSize 
* sizeof(wxGC
)); 
 170     if (wxGCPool 
== NULL
) 
 172         // If we cannot malloc, then fail with error 
 173         // when debug is enabled.  If debug is not enabled, 
 174         // the problem will eventually get caught 
 176         wxFAIL_MSG( wxT("Cannot allocate GC pool") ); 
 180     // Zero initial pool. 
 181     memset(wxGCPool
, 0, wxGCPoolSize 
* sizeof(wxGC
)); 
 184 static void wxCleanUpGCPool() 
 186     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 188         if (wxGCPool
[i
].m_gc
) 
 189             gdk_gc_unref( wxGCPool
[i
].m_gc 
); 
 197 static GdkGC
* wxGetPoolGC( GdkWindow 
*window
, wxPoolGCType type 
) 
 201     // Look for an available GC. 
 202     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 204         if (!wxGCPool
[i
].m_gc
) 
 206             wxGCPool
[i
].m_gc 
= gdk_gc_new( window 
); 
 207             gdk_gc_set_exposures( wxGCPool
[i
].m_gc
, FALSE 
); 
 208             wxGCPool
[i
].m_type 
= type
; 
 209             wxGCPool
[i
].m_used 
= false; 
 211         if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type 
== type
)) 
 213             wxGCPool
[i
].m_used 
= true; 
 214             return wxGCPool
[i
].m_gc
; 
 218     // We did not find an available GC. 
 219     // We need to grow the GC pool. 
 220     pptr 
= (wxGC 
*)realloc(wxGCPool
, 
 221         (wxGCPoolSize 
+ GC_POOL_ALLOC_SIZE
)*sizeof(wxGC
)); 
 224         // Initialize newly allocated pool. 
 226         memset(&wxGCPool
[wxGCPoolSize
], 0, 
 227             GC_POOL_ALLOC_SIZE
*sizeof(wxGC
)); 
 229         // Initialize entry we will return. 
 230         wxGCPool
[wxGCPoolSize
].m_gc 
= gdk_gc_new( window 
); 
 231         gdk_gc_set_exposures( wxGCPool
[wxGCPoolSize
].m_gc
, FALSE 
); 
 232         wxGCPool
[wxGCPoolSize
].m_type 
= type
; 
 233         wxGCPool
[wxGCPoolSize
].m_used 
= true; 
 235         // Set new value of pool size. 
 236         wxGCPoolSize 
+= GC_POOL_ALLOC_SIZE
; 
 238         // Return newly allocated entry. 
 239         return wxGCPool
[wxGCPoolSize
-GC_POOL_ALLOC_SIZE
].m_gc
; 
 242     // The realloc failed.  Fall through to error. 
 243     wxFAIL_MSG( wxT("No GC available") ); 
 245     return (GdkGC
*) NULL
; 
 248 static void wxFreePoolGC( GdkGC 
*gc 
) 
 250     for (int i 
= 0; i 
< wxGCPoolSize
; i
++) 
 252         if (wxGCPool
[i
].m_gc 
== gc
) 
 254             wxGCPool
[i
].m_used 
= false; 
 259     wxFAIL_MSG( wxT("Wrong GC") ); 
 262 //----------------------------------------------------------------------------- 
 264 //----------------------------------------------------------------------------- 
 266 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
) 
 268 wxWindowDC::wxWindowDC() 
 270     m_penGC 
= (GdkGC 
*) NULL
; 
 271     m_brushGC 
= (GdkGC 
*) NULL
; 
 272     m_textGC 
= (GdkGC 
*) NULL
; 
 273     m_bgGC 
= (GdkGC 
*) NULL
; 
 274     m_cmap 
= (GdkColormap 
*) NULL
; 
 276     m_isScreenDC 
= false; 
 277     m_owner 
= (wxWindow 
*)NULL
; 
 280 wxWindowDC::wxWindowDC( wxWindow 
*window 
) 
 282     wxASSERT_MSG( window
, wxT("DC needs a window") ); 
 284     m_penGC 
= (GdkGC 
*) NULL
; 
 285     m_brushGC 
= (GdkGC 
*) NULL
; 
 286     m_textGC 
= (GdkGC 
*) NULL
; 
 287     m_bgGC 
= (GdkGC 
*) NULL
; 
 288     m_cmap 
= (GdkColormap 
*) NULL
; 
 289     m_owner 
= (wxWindow 
*)NULL
; 
 291     m_isScreenDC 
= false; 
 292     m_font 
= window
->GetFont(); 
 294     GtkWidget 
*widget 
= window
->m_wxwindow
; 
 296     // Some controls don't have m_wxwindow - like wxStaticBox, but the user 
 297     // code should still be able to create wxClientDCs for them, so we will 
 298     // use the parent window here then. 
 301         window 
= window
->GetParent(); 
 302         widget 
= window
->m_wxwindow
; 
 305     wxASSERT_MSG( widget
, wxT("DC needs a widget") ); 
 307     GtkPizza 
*pizza 
= GTK_PIZZA( widget 
); 
 308     m_window 
= pizza
->bin_window
; 
 310     // Window not realized ? 
 313          // Don't report problems as per MSW. 
 319     m_cmap 
= gtk_widget_get_colormap( widget 
? widget 
: window
->m_widget 
); 
 323     /* this must be done after SetUpDC, bacause SetUpDC calls the 
 324        repective SetBrush, SetPen, SetBackground etc functions 
 325        to set up the DC. SetBackground call m_owner->SetBackground 
 326        and this might not be desired as the standard dc background 
 327        is white whereas a window might assume gray to be the 
 328        standard (as e.g. wxStatusBar) */ 
 333 wxWindowDC::~wxWindowDC() 
 338 void wxWindowDC::SetUpDC() 
 342     wxASSERT_MSG( !m_penGC
, wxT("GCs already created") ); 
 346         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_SCREEN 
); 
 347         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_SCREEN 
); 
 348         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_SCREEN 
); 
 349         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_SCREEN 
); 
 352     if (m_isMemDC 
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1)) 
 354         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_MONO 
); 
 355         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_MONO 
); 
 356         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_MONO 
); 
 357         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_MONO 
); 
 361         m_penGC 
= wxGetPoolGC( m_window
, wxPEN_COLOUR 
); 
 362         m_brushGC 
= wxGetPoolGC( m_window
, wxBRUSH_COLOUR 
); 
 363         m_textGC 
= wxGetPoolGC( m_window
, wxTEXT_COLOUR 
); 
 364         m_bgGC 
= wxGetPoolGC( m_window
, wxBG_COLOUR 
); 
 367     /* background colour */ 
 368     m_backgroundBrush 
= *wxWHITE_BRUSH
; 
 369     m_backgroundBrush
.GetColour().CalcPixel( m_cmap 
); 
 370     GdkColor 
*bg_col 
= m_backgroundBrush
.GetColour().GetColor(); 
 373     m_textForegroundColour
.CalcPixel( m_cmap 
); 
 374     gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
 376     m_textBackgroundColour
.CalcPixel( m_cmap 
); 
 377     gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() ); 
 379     gdk_gc_set_fill( m_textGC
, GDK_SOLID 
); 
 382     m_pen
.GetColour().CalcPixel( m_cmap 
); 
 383     gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() ); 
 384     gdk_gc_set_background( m_penGC
, bg_col 
); 
 386     gdk_gc_set_line_attributes( m_penGC
, 0, GDK_LINE_SOLID
, GDK_CAP_NOT_LAST
, GDK_JOIN_ROUND 
); 
 389     m_brush
.GetColour().CalcPixel( m_cmap 
); 
 390     gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() ); 
 391     gdk_gc_set_background( m_brushGC
, bg_col 
); 
 393     gdk_gc_set_fill( m_brushGC
, GDK_SOLID 
); 
 396     gdk_gc_set_background( m_bgGC
, bg_col 
); 
 397     gdk_gc_set_foreground( m_bgGC
, bg_col 
); 
 399     gdk_gc_set_fill( m_bgGC
, GDK_SOLID 
); 
 402     gdk_gc_set_function( m_textGC
, GDK_COPY 
); 
 403     gdk_gc_set_function( m_brushGC
, GDK_COPY 
); 
 404     gdk_gc_set_function( m_penGC
, GDK_COPY 
); 
 407     gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle 
*) NULL 
); 
 408     gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle 
*) NULL 
); 
 409     gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle 
*) NULL 
); 
 410     gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle 
*) NULL 
); 
 414         hatch_bitmap    
= hatches
; 
 415         hatch_bitmap
[0] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, bdiag_bits
, bdiag_width
, bdiag_height 
); 
 416         hatch_bitmap
[1] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, cdiag_bits
, cdiag_width
, cdiag_height 
); 
 417         hatch_bitmap
[2] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, fdiag_bits
, fdiag_width
, fdiag_height 
); 
 418         hatch_bitmap
[3] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, cross_bits
, cross_width
, cross_height 
); 
 419         hatch_bitmap
[4] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, horiz_bits
, horiz_width
, horiz_height 
); 
 420         hatch_bitmap
[5] = gdk_bitmap_create_from_data( (GdkWindow 
*) NULL
, verti_bits
, verti_width
, verti_height 
); 
 424 void wxWindowDC::DoGetSize( int* width
, int* height 
) const 
 426     wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") ); 
 428     m_owner
->GetSize(width
, height
); 
 431 extern bool wxDoFloodFill(wxDC 
*dc
, wxCoord x
, wxCoord y
, 
 432                           const wxColour 
& col
, int style
); 
 434 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
, 
 435                              const wxColour
& col
, int style
) 
 437     return wxDoFloodFill(this, x
, y
, col
, style
); 
 440 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour 
*col 
) const 
 442     // Generic (and therefore rather inefficient) method. 
 443     // Could be improved. 
 445     wxBitmap 
bitmap(1, 1); 
 446     memdc
.SelectObject(bitmap
); 
 447     memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
); 
 448     memdc
.SelectObject(wxNullBitmap
); 
 450     wxImage image 
= bitmap
.ConvertToImage(); 
 451     col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0)); 
 455 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2 
) 
 457     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 459     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 462             gdk_draw_line( m_window
, m_penGC
, XLOG2DEV(x1
), YLOG2DEV(y1
), XLOG2DEV(x2
), YLOG2DEV(y2
) ); 
 464         CalcBoundingBox(x1
, y1
); 
 465         CalcBoundingBox(x2
, y2
); 
 469 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y 
) 
 471     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 473     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 478         wxCoord xx 
= XLOG2DEV(x
); 
 479         wxCoord yy 
= YLOG2DEV(y
); 
 482             gdk_draw_line( m_window
, m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy 
); 
 483             gdk_draw_line( m_window
, m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) ); 
 488 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, 
 489                             wxCoord xc
, wxCoord yc 
) 
 491     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 493     wxCoord xx1 
= XLOG2DEV(x1
); 
 494     wxCoord yy1 
= YLOG2DEV(y1
); 
 495     wxCoord xx2 
= XLOG2DEV(x2
); 
 496     wxCoord yy2 
= YLOG2DEV(y2
); 
 497     wxCoord xxc 
= XLOG2DEV(xc
); 
 498     wxCoord yyc 
= YLOG2DEV(yc
); 
 499     double dx 
= xx1 
- xxc
; 
 500     double dy 
= yy1 
- yyc
; 
 501     double radius 
= sqrt((double)(dx
*dx
+dy
*dy
)); 
 502     wxCoord   r      
= (wxCoord
)radius
; 
 503     double radius1
, radius2
; 
 505     if (xx1 
== xx2 
&& yy1 
== yy2
) 
 510     else if ( wxIsNullDouble(radius
) ) 
 517         radius1 
= (xx1 
- xxc 
== 0) ? 
 518             (yy1 
- yyc 
< 0) ? 90.0 : -90.0 : 
 519             -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
; 
 520         radius2 
= (xx2 
- xxc 
== 0) ? 
 521             (yy2 
- yyc 
< 0) ? 90.0 : -90.0 : 
 522             -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
; 
 524     wxCoord alpha1 
= wxCoord(radius1 
* 64.0); 
 525     wxCoord alpha2 
= wxCoord((radius2 
- radius1
) * 64.0); 
 526     while (alpha2 
<= 0) alpha2 
+= 360*64; 
 527     while (alpha1 
> 360*64) alpha1 
-= 360*64; 
 531         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 533             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 535                 gdk_gc_set_ts_origin( m_textGC
, 
 536                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 537                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 538                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 539                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 541             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 543                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 544                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 545                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 547             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 549                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 550                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 551                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 553             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 555                 gdk_gc_set_ts_origin( m_brushGC
, 
 556                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 557                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 558                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 559                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 563                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 567         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 569             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2 
); 
 571             gdk_draw_line( m_window
, m_penGC
, xx1
, yy1
, xxc
, yyc 
); 
 572             gdk_draw_line( m_window
, m_penGC
, xxc
, yyc
, xx2
, yy2 
); 
 576     CalcBoundingBox (x1
, y1
); 
 577     CalcBoundingBox (x2
, y2
); 
 580 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea 
) 
 582     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 584     wxCoord xx 
= XLOG2DEV(x
); 
 585     wxCoord yy 
= YLOG2DEV(y
); 
 586     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 587     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 589     // CMB: handle -ve width and/or height 
 590     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 591     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 595         wxCoord start 
= wxCoord(sa 
* 64.0); 
 596         wxCoord end 
= wxCoord((ea
-sa
) * 64.0); 
 598         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 600             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 602                 gdk_gc_set_ts_origin( m_textGC
, 
 603                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 604                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 605                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 606                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 608             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 610                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 611                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 612                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 614             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 616                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 617                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 618                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 620             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 622                 gdk_gc_set_ts_origin( m_brushGC
, 
 623                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 624                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 625                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 626                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 630                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end 
); 
 634         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 635             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, start
, end 
); 
 638     CalcBoundingBox (x
, y
); 
 639     CalcBoundingBox (x 
+ width
, y 
+ height
); 
 642 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y 
) 
 644     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 646     if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
) 
 647         gdk_draw_point( m_window
, m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) ); 
 649     CalcBoundingBox (x
, y
); 
 652 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset 
) 
 654     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 656     if (m_pen
.GetStyle() == wxTRANSPARENT
) return; 
 659     //Check, if scaling is necessary 
 664             if (XLOG2DEV(val
)==val
) 
 665                 if (YLOG2DEV(val
)==val
) 
 668     GdkPoint 
*gpts 
= NULL
; 
 671         gpts 
= new GdkPoint
[n
]; 
 674         wxFAIL_MSG( wxT("Cannot allocate PolyLine") ); 
 678     for (int i 
= 0; i 
< n
; i
++) 
 680         wxCoord x1 
= XLOG2DEV(points
[i
].x 
+ xoffset
); 
 681         wxCoord y1 
= YLOG2DEV(points
[i
].y 
+ yoffset
); 
 683         CalcBoundingBox( x1 
+ xoffset
, y1 
+ yoffset 
); 
 690         for (int i 
= 0; i 
< n
; i
++) { 
 691             CalcBoundingBox( points
[i
].x
, points
[i
].y 
); 
 694         //GdkPoint and wxPoint have the same memory allignment, so we can cast one into another 
 695         gpts 
= reinterpret_cast<GdkPoint
*>(points
); 
 699         gdk_draw_lines( m_window
, m_penGC
, gpts
, n
); 
 705 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
, int WXUNUSED(fillStyle
) ) 
 707     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 711     //Check, if scaling is necessary 
 716             if (XLOG2DEV(val
)==val
) 
 717                 if (YLOG2DEV(val
)==val
){ 
 721     GdkPoint 
*gdkpoints 
= NULL
; 
 724         gdkpoints 
= new GdkPoint
[n
+1]; //FIXME: Why the "+1" 
 727     for (i 
= 0 ; i 
< n 
; i
++) 
 729         gdkpoints
[i
].x 
= XLOG2DEV(points
[i
].x 
+ xoffset
); 
 730         gdkpoints
[i
].y 
= YLOG2DEV(points
[i
].y 
+ yoffset
); 
 732         CalcBoundingBox( points
[i
].x 
+ xoffset
, points
[i
].y 
+ yoffset 
); 
 737         for (; i 
< n 
; ++i
) { 
 738             CalcBoundingBox( points
[i
].x
, points
[i
].y 
); 
 740         //GdkPoint and wxPoint have the same memory allignment, so we can cast one into another 
 741         gdkpoints 
= reinterpret_cast<GdkPoint
*> (points
); 
 746         //I think wxSOLID is the most often used style (it is for me), 
 747         //so I put it in front of the if ... ifelse's 
 748         if (m_brush
.GetStyle() == wxSOLID
) 
 750             gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 752         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 754             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 756                 gdk_gc_set_ts_origin( m_textGC
, 
 757                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 758                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 759                 gdk_draw_polygon( m_window
, m_textGC
, TRUE
, gdkpoints
, n 
); 
 760                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 762             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 764                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 765                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 766                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 768             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 770                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 771                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 772                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 774             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 776                 gdk_gc_set_ts_origin( m_brushGC
, 
 777                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 778                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 779                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 780                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 784                 gdk_draw_polygon( m_window
, m_brushGC
, TRUE
, gdkpoints
, n 
); 
 788         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 791             for (i = 0 ; i < n ; i++) 
 793                 gdk_draw_line( m_window, m_penGC, 
 796                                gdkpoints[(i+1)%n].x, 
 797                                gdkpoints[(i+1)%n].y); 
 800             gdk_draw_polygon( m_window
, m_penGC
, FALSE
, gdkpoints
, n 
); 
 809 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 811     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 813     wxCoord xx 
= XLOG2DEV(x
); 
 814     wxCoord yy 
= YLOG2DEV(y
); 
 815     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 816     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 818     // CMB: draw nothing if transformed w or h is 0 
 819     if (ww 
== 0 || hh 
== 0) return; 
 821     // CMB: handle -ve width and/or height 
 822     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 823     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 827         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 829             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 831                 gdk_gc_set_ts_origin( m_textGC
, 
 832                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 833                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 834                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 835                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 837             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 839                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 840                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 841                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 843             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 845                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 846                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 847                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 849             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 851                 gdk_gc_set_ts_origin( m_brushGC
, 
 852                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 853                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 854                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 855                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 859                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh 
); 
 863         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 864             gdk_draw_rectangle( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
-1, hh
-1 ); 
 867     CalcBoundingBox( x
, y 
); 
 868     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
 871 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius 
) 
 873     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 875     if (radius 
< 0.0) radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
 877     wxCoord xx 
= XLOG2DEV(x
); 
 878     wxCoord yy 
= YLOG2DEV(y
); 
 879     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
 880     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
 881     wxCoord rr 
= XLOG2DEVREL((wxCoord
)radius
); 
 883     // CMB: handle -ve width and/or height 
 884     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
 885     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
 887     // CMB: if radius is zero use DrawRectangle() instead to avoid 
 888     // X drawing errors with small radii 
 891         DrawRectangle( x
, y
, width
, height 
); 
 895     // CMB: draw nothing if transformed w or h is 0 
 896     if (ww 
== 0 || hh 
== 0) return; 
 898     // CMB: adjust size if outline is drawn otherwise the result is 
 899     // 1 pixel too wide and high 
 900     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 908         // CMB: ensure dd is not larger than rectangle otherwise we 
 909         // get an hour glass shape 
 911         if (dd 
> ww
) dd 
= ww
; 
 912         if (dd 
> hh
) dd 
= hh
; 
 915         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
 917             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
 919                 gdk_gc_set_ts_origin( m_textGC
, 
 920                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 921                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 922                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 923                 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 924                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 925                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 926                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 927                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 928                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
 930             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
 932                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
 933                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 934                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 935                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 936                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 937                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 938                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 939                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 941             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
 943                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
 944                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 945                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 946                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 947                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 948                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 949                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 950                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 952             if (m_brush
.GetStyle() == wxSTIPPLE
) 
 954                 gdk_gc_set_ts_origin( m_brushGC
, 
 955                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
 956                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
 957                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 958                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 959                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 960                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 961                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 962                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 963                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
 967                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh 
); 
 968                 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 ); 
 969                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 970                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 971                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 972                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 976         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 978             gdk_draw_line( m_window
, m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy 
); 
 979             gdk_draw_line( m_window
, m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh 
); 
 980             gdk_draw_line( m_window
, m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr 
); 
 981             gdk_draw_line( m_window
, m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr 
); 
 982             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, dd
, dd
, 90*64, 90*64 ); 
 983             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 ); 
 984             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 ); 
 985             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 ); 
 989     // this ignores the radius 
 990     CalcBoundingBox( x
, y 
); 
 991     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
 994 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 996     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
 998     wxCoord xx 
= XLOG2DEV(x
); 
 999     wxCoord yy 
= YLOG2DEV(y
); 
1000     wxCoord ww 
= m_signX 
* XLOG2DEVREL(width
); 
1001     wxCoord hh 
= m_signY 
* YLOG2DEVREL(height
); 
1003     // CMB: handle -ve width and/or height 
1004     if (ww 
< 0) { ww 
= -ww
; xx 
= xx 
- ww
; } 
1005     if (hh 
< 0) { hh 
= -hh
; yy 
= yy 
- hh
; } 
1009         if (m_brush
.GetStyle() != wxTRANSPARENT
) 
1011             if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
1013                 gdk_gc_set_ts_origin( m_textGC
, 
1014                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
1015                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
1016                 gdk_draw_arc( m_window
, m_textGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1017                 gdk_gc_set_ts_origin( m_textGC
, 0, 0 ); 
1019             if (IS_15_PIX_HATCH(m_brush
.GetStyle())) 
1021                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 15, m_deviceOriginY 
% 15 ); 
1022                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1023                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1025             if (IS_16_PIX_HATCH(m_brush
.GetStyle())) 
1027                 gdk_gc_set_ts_origin( m_brushGC
, m_deviceOriginX 
% 16, m_deviceOriginY 
% 16 ); 
1028                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1029                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1031             if (m_brush
.GetStyle() == wxSTIPPLE
) 
1033                 gdk_gc_set_ts_origin( m_brushGC
, 
1034                                       m_deviceOriginX 
% m_brush
.GetStipple()->GetWidth(), 
1035                                       m_deviceOriginY 
% m_brush
.GetStipple()->GetHeight() ); 
1036                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1037                 gdk_gc_set_ts_origin( m_brushGC
, 0, 0 ); 
1041                 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1045         if (m_pen
.GetStyle() != wxTRANSPARENT
) 
1046             gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, 0, 360*64 ); 
1049     CalcBoundingBox( x
, y 
); 
1050     CalcBoundingBox( x 
+ width
, y 
+ height 
); 
1053 void wxWindowDC::DoDrawIcon( const wxIcon 
&icon
, wxCoord x
, wxCoord y 
) 
1055     // VZ: egcs 1.0.3 refuses to compile this without cast, no idea why 
1056     DoDrawBitmap( (const wxBitmap
&)icon
, x
, y
, true ); 
1059 void wxWindowDC::DoDrawBitmap( const wxBitmap 
&bitmap
, 
1060                                wxCoord x
, wxCoord y
, 
1063     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1065     wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") ); 
1067     bool is_mono 
= (bitmap
.GetBitmap() != NULL
); 
1069     // scale/translate size and position 
1070     int xx 
= XLOG2DEV(x
); 
1071     int yy 
= YLOG2DEV(y
); 
1073     int w 
= bitmap
.GetWidth(); 
1074     int h 
= bitmap
.GetHeight(); 
1076     CalcBoundingBox( x
, y 
); 
1077     CalcBoundingBox( x 
+ w
, y 
+ h 
); 
1079     if (!m_window
) return; 
1081     int ww 
= XLOG2DEVREL(w
); 
1082     int hh 
= YLOG2DEVREL(h
); 
1084     // compare to current clipping region 
1085     if (!m_currentClippingRegion
.IsNull()) 
1087         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1088         tmp
.Intersect( m_currentClippingRegion 
); 
1093     // scale bitmap if required 
1094     wxBitmap use_bitmap 
= bitmap
; 
1095     if ((w 
!= ww
) || (h 
!= hh
)) 
1096         use_bitmap 
= use_bitmap
.Rescale( 0, 0, ww
, hh
, ww
, hh 
); 
1098     // NB: We can't render pixbufs with GTK+ < 2.2, we need to use pixmaps code. 
1099     //     Pixbufs-based bitmaps with alpha channel don't have a mask, so we 
1100     //     have to call GetPixmap() here -- it converts the pixbuf into pixmap 
1101     //     and also creates the mask as a side-effect: 
1102     use_bitmap
.GetPixmap(); 
1104     // apply mask if any 
1105     GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1106     if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1108     GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1110     if (useMask 
&& mask
) 
1112         if (!m_currentClippingRegion
.IsNull()) 
1115             new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 ); 
1116             GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1118             gdk_gc_set_foreground( gc
, &col 
); 
1119             gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1121             gdk_gc_set_background( gc
, &col 
); 
1123             gdk_gc_set_foreground( gc
, &col 
); 
1124             gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1125             gdk_gc_set_clip_origin( gc
, -xx
, -yy 
); 
1126             gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1127             gdk_gc_set_stipple( gc
, mask 
); 
1128             gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh 
); 
1135                 gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1137                 gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1138             gdk_gc_set_clip_origin( m_textGC
, xx
, yy 
); 
1143                 gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1145                 gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1146             gdk_gc_set_clip_origin( m_penGC
, xx
, yy 
); 
1150     // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1151     // drawing a mono-bitmap (XBitmap) we use the current text GC 
1154         gdk_wx_draw_bitmap( m_window
, m_textGC
, use_bitmap
.GetBitmap(), 0, 0, xx
, yy
, -1, -1 ); 
1158         gdk_draw_pixmap(m_window
, m_penGC
, 
1159                         use_bitmap
.GetPixmap(), 
1160                         0, 0, xx
, yy
, -1, -1); 
1163     // remove mask again if any 
1164     if (useMask 
&& mask
) 
1168             gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1169             gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1170             if (!m_currentClippingRegion
.IsNull()) 
1171                 gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1175             gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1176             gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1177             if (!m_currentClippingRegion
.IsNull()) 
1178                 gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1183         gdk_bitmap_unref( new_mask 
); 
1186 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, 
1187                          wxCoord width
, wxCoord height
, 
1189                          wxCoord xsrc
, wxCoord ysrc
, 
1192                          wxCoord xsrcMask
, wxCoord ysrcMask 
) 
1194     wxCHECK_MSG( Ok(), false, wxT("invalid window dc") ); 
1196     wxCHECK_MSG( source
, false, wxT("invalid source dc") ); 
1198     if (!m_window
) return false; 
1200     // transform the source DC coords to the device ones 
1201     xsrc 
= source
->XLOG2DEV(xsrc
); 
1202     ysrc 
= source
->YLOG2DEV(ysrc
); 
1204     wxClientDC 
*srcDC 
= (wxClientDC
*)source
; 
1205     wxMemoryDC 
*memDC 
= (wxMemoryDC
*)source
; 
1207     bool use_bitmap_method 
= false; 
1208     bool is_mono 
= false; 
1210     if (xsrcMask 
== -1 && ysrcMask 
== -1) 
1216     if (srcDC
->m_isMemDC
) 
1218         if (!memDC
->m_selected
.Ok()) return false; 
1220         is_mono 
= (memDC
->m_selected
.GetDepth() == 1); 
1222         // we use the "XCopyArea" way to copy a memory dc into 
1223         // a different window if the memory dc BOTH 
1224         // a) doesn't have any mask or its mask isn't used 
1228         if (useMask 
&& (memDC
->m_selected
.GetMask())) 
1230             // we HAVE TO use the direct way for memory dcs 
1231             // that have mask since the XCopyArea doesn't know 
1233             use_bitmap_method 
= true; 
1237             // we HAVE TO use the direct way for memory dcs 
1238             // that are bitmaps because XCopyArea doesn't cope 
1239             // with different bit depths 
1240             use_bitmap_method 
= true; 
1242         else if ((xsrc 
== 0) && (ysrc 
== 0) && 
1243                  (width 
== memDC
->m_selected
.GetWidth()) && 
1244                  (height 
== memDC
->m_selected
.GetHeight())) 
1246             // we SHOULD use the direct way if all of the bitmap 
1247             // in the memory dc is copied in which case XCopyArea 
1248             // wouldn't be able able to boost performace by reducing 
1249             // the area to be scaled 
1250             use_bitmap_method 
= true; 
1254             use_bitmap_method 
= false; 
1258     CalcBoundingBox( xdest
, ydest 
); 
1259     CalcBoundingBox( xdest 
+ width
, ydest 
+ height 
); 
1261     // scale/translate size and position 
1262     wxCoord xx 
= XLOG2DEV(xdest
); 
1263     wxCoord yy 
= YLOG2DEV(ydest
); 
1265     wxCoord ww 
= XLOG2DEVREL(width
); 
1266     wxCoord hh 
= YLOG2DEVREL(height
); 
1268     // compare to current clipping region 
1269     if (!m_currentClippingRegion
.IsNull()) 
1271         wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1272         tmp
.Intersect( m_currentClippingRegion 
); 
1277     int old_logical_func 
= m_logicalFunction
; 
1278     SetLogicalFunction( logical_func 
); 
1280     if (use_bitmap_method
) 
1282         // scale/translate bitmap size 
1283         wxCoord bm_width 
= memDC
->m_selected
.GetWidth(); 
1284         wxCoord bm_height 
= memDC
->m_selected
.GetHeight(); 
1286         // Get clip coords for the bitmap. If we don't 
1287         // use wxBitmap::Rescale(), which can clip the 
1288         // bitmap, these are the same as the original 
1295         // interpret userscale of src too 
1297         memDC
->GetUserScale(&xsc
,&ysc
); 
1298         bm_width 
= (int) (bm_width 
/ xsc
); 
1299         bm_height 
= (int) (bm_height 
/ ysc
); 
1301         wxCoord bm_ww 
= XLOG2DEVREL( bm_width 
); 
1302         wxCoord bm_hh 
= YLOG2DEVREL( bm_height 
); 
1304         // Scale bitmap if required 
1305         wxBitmap use_bitmap
; 
1306         if ((memDC
->m_selected
.GetWidth()!= bm_ww
) || ( memDC
->m_selected
.GetHeight()!= bm_hh
)) 
1308             // This indicates that the blitting code below will get 
1309             // a clipped bitmap and therefore needs to move the origin 
1311             wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1312             tmp
.Intersect( m_currentClippingRegion 
); 
1313             tmp
.GetBox(cx
,cy
,cw
,ch
); 
1315             // Scale and clipped bitmap 
1316             use_bitmap 
= memDC
->m_selected
.Rescale(cx
-xx
,cy
-yy
,cw
,ch
,bm_ww
,bm_hh
); 
1320             // Don't scale bitmap 
1321             use_bitmap 
= memDC
->m_selected
; 
1324         // apply mask if any 
1325         GdkBitmap 
*mask 
= (GdkBitmap 
*) NULL
; 
1326         if (use_bitmap
.GetMask()) mask 
= use_bitmap
.GetMask()->GetBitmap(); 
1328         GdkBitmap 
*new_mask 
= (GdkBitmap
*) NULL
; 
1330         if (useMask 
&& mask
) 
1332             if (!m_currentClippingRegion
.IsNull()) 
1335                 new_mask 
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 ); 
1336                 GdkGC 
*gc 
= gdk_gc_new( new_mask 
); 
1338                 gdk_gc_set_foreground( gc
, &col 
); 
1339                 gdk_gc_set_ts_origin( gc
, -xsrcMask
, -ysrcMask
); 
1340                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1342                 gdk_gc_set_background( gc
, &col 
); 
1344                 gdk_gc_set_foreground( gc
, &col 
); 
1345                 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() ); 
1346                 // was: gdk_gc_set_clip_origin( gc, -xx, -yy ); 
1347                 gdk_gc_set_clip_origin( gc
, -cx
, -cy 
); 
1348                 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED 
); 
1349                 gdk_gc_set_stipple( gc
, mask 
); 
1350                 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh 
); 
1358                     gdk_gc_set_clip_mask( m_textGC
, new_mask 
); 
1359                     gdk_gc_set_clip_origin( m_textGC
, cx
, cy 
); 
1363                     gdk_gc_set_clip_mask( m_textGC
, mask 
); 
1364                     gdk_gc_set_clip_origin( m_textGC
, cx
-xsrcMask
, cy
-ysrcMask 
); 
1371                     gdk_gc_set_clip_mask( m_penGC
, new_mask 
); 
1372                     gdk_gc_set_clip_origin( m_penGC
, cx
, cy 
); 
1376                     gdk_gc_set_clip_mask( m_penGC
, mask 
); 
1377                     gdk_gc_set_clip_origin( m_penGC
, cx
-xsrcMask
, cy
-ysrcMask 
); 
1382         // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For 
1383         // drawing a mono-bitmap (XBitmap) we use the current text GC 
1387             // was: gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), xsrc, ysrc, xx, yy, ww, hh ); 
1388             gdk_wx_draw_bitmap( m_window
, m_textGC
, use_bitmap
.GetBitmap(), xsrc
, ysrc
, cx
, cy
, cw
, ch 
); 
1392             // was: gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, xx, yy, ww, hh ); 
1393             gdk_draw_pixmap( m_window
, m_penGC
, use_bitmap
.GetPixmap(), xsrc
, ysrc
, cx
, cy
, cw
, ch 
); 
1396         // remove mask again if any 
1397         if (useMask 
&& mask
) 
1401                 gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap 
*) NULL 
); 
1402                 gdk_gc_set_clip_origin( m_textGC
, 0, 0 ); 
1403                 if (!m_currentClippingRegion
.IsNull()) 
1404                     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
1408                 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap 
*) NULL 
); 
1409                 gdk_gc_set_clip_origin( m_penGC
, 0, 0 ); 
1410                 if (!m_currentClippingRegion
.IsNull()) 
1411                     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
1416             gdk_bitmap_unref( new_mask 
); 
1418     else // use_bitmap_method 
1420         if ((width 
!= ww
) || (height 
!= hh
)) 
1423             wxRegion 
tmp( xx
,yy
,ww
,hh 
); 
1424             tmp
.Intersect( m_currentClippingRegion 
); 
1425             wxCoord cx
,cy
,cw
,ch
; 
1426             tmp
.GetBox(cx
,cy
,cw
,ch
); 
1429             wxBitmap bitmap 
= memDC
->m_selected
.Rescale( cx
-xx
, cy
-yy
, cw
, ch
, ww
, hh 
); 
1431             // draw scaled bitmap 
1432             // was: gdk_draw_pixmap( m_window, m_penGC, bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 ); 
1433             gdk_draw_pixmap( m_window
, m_penGC
, bitmap
.GetPixmap(), 0, 0, cx
, cy
, -1, -1 ); 
1437             // No scaling and not a memory dc with a mask either 
1439             // copy including child window contents 
1440             gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS 
); 
1441             gdk_window_copy_area( m_window
, m_penGC
, xx
, yy
, 
1443                                   xsrc
, ysrc
, width
, height 
); 
1444             gdk_gc_set_subwindow( m_penGC
, GDK_CLIP_BY_CHILDREN 
); 
1448     SetLogicalFunction( old_logical_func 
); 
1453 void wxWindowDC::DoDrawText( const wxString 
&text
, wxCoord x
, wxCoord y 
) 
1455     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1457     if (!m_window
) return; 
1459     if (text
.empty()) return; 
1461     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1463     wxCHECK_RET( font
, wxT("invalid font") ); 
1468     wxCoord width 
= gdk_string_width( font
, text
.mbc_str() ); 
1469     wxCoord height 
= font
->ascent 
+ font
->descent
; 
1471     if ( m_backgroundMode 
== wxSOLID 
) 
1473         gdk_gc_set_foreground( m_textGC
, m_textBackgroundColour
.GetColor() ); 
1474         gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, x
, y
, width
, height 
); 
1475         gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
1477     gdk_draw_string( m_window
, font
, m_textGC
, x
, y 
+ font
->ascent
, text
.mbc_str() ); 
1479     /* CMB 17/7/98: simple underline: ignores scaling and underlying 
1480        X font's XA_UNDERLINE_POSITION and XA_UNDERLINE_THICKNESS 
1481        properties (see wxXt implementation) */ 
1482     if (m_font
.GetUnderlined()) 
1484         wxCoord ul_y 
= y 
+ font
->ascent
; 
1485         if (font
->descent 
> 0) ul_y
++; 
1486         gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x 
+ width
, ul_y
); 
1489     width 
= wxCoord(width 
/ m_scaleX
); 
1490     height 
= wxCoord(height 
/ m_scaleY
); 
1491     CalcBoundingBox (x 
+ width
, y 
+ height
); 
1492     CalcBoundingBox (x
, y
); 
1496 // TODO: There is an example of rotating text with GTK2 that would probably be 
1497 // a better approach here: 
1498 //           http://www.daa.com.au/pipermail/pygtk/2003-April/005052.html 
1500 void wxWindowDC::DoDrawRotatedText( const wxString 
&text
, wxCoord x
, wxCoord y
, double angle 
) 
1502     if ( wxIsNullDouble(angle
) ) 
1504         DrawText(text
, x
, y
); 
1508     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1510     if (!m_window
) return; 
1515     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1517     wxCHECK_RET( font
, wxT("invalid font") ); 
1519     // the size of the text 
1520     w 
= gdk_string_width( font
, text
.mbc_str() ); 
1521     h 
= font
->ascent 
+ font
->descent
; 
1523     // draw the string normally 
1526     dc
.SelectObject(src
); 
1527     dc
.SetFont(GetFont()); 
1528     dc
.SetBackground(*wxBLACK_BRUSH
); 
1529     dc
.SetBrush(*wxBLACK_BRUSH
); 
1531     dc
.SetTextForeground( *wxWHITE 
); 
1532     dc
.DrawText(text
, 0, 0); 
1533     dc
.SelectObject(wxNullBitmap
); 
1535     // Calculate the size of the rotated bounding box. 
1536     double rad 
= DegToRad(angle
); 
1537     double dx 
= cos(rad
), 
1540     // the rectngle vertices are counted clockwise with the first one being at 
1541     // (0, 0) (or, rather, at (x, y)) 
1543            y2 
= -w
*dy
;      // y axis points to the bottom, hence minus 
1546     double x3 
= x4 
+ x2
, 
1550     wxCoord maxX 
= (wxCoord
)(dmax(x2
, dmax(x3
, x4
)) + 0.5), 
1551             maxY 
= (wxCoord
)(dmax(y2
, dmax(y3
, y4
)) + 0.5), 
1552             minX 
= (wxCoord
)(dmin(x2
, dmin(x3
, x4
)) - 0.5), 
1553             minY 
= (wxCoord
)(dmin(y2
, dmin(y3
, y4
)) - 0.5); 
1556     wxImage image 
= src
.ConvertToImage(); 
1558     image
.ConvertColourToAlpha( m_textForegroundColour
.Red(), 
1559                                 m_textForegroundColour
.Green(), 
1560                                 m_textForegroundColour
.Blue() ); 
1561     image 
= image
.Rotate( rad
, wxPoint(0,0) ); 
1563     int i_angle 
= (int) angle
; 
1564     i_angle 
= i_angle 
% 360; 
1568     if ((i_angle 
>= 90.0) && (i_angle 
< 270.0)) 
1569         xoffset 
= image
.GetWidth(); 
1571     if ((i_angle 
>= 0.0) && (i_angle 
< 180.0)) 
1572         yoffset 
= image
.GetHeight(); 
1574     if ((i_angle 
>= 0) && (i_angle 
< 90)) 
1575         yoffset 
-= (int)( cos(rad
)*h 
); 
1576     if ((i_angle 
>= 90) && (i_angle 
< 180)) 
1577         xoffset 
-= (int)( sin(rad
)*h 
); 
1578     if ((i_angle 
>= 180) && (i_angle 
< 270)) 
1579         yoffset 
-= (int)( cos(rad
)*h 
); 
1580     if ((i_angle 
>= 270) && (i_angle 
< 360)) 
1581         xoffset 
-= (int)( sin(rad
)*h 
); 
1583     int i_x 
= x 
- xoffset
; 
1584     int i_y 
= y 
- yoffset
; 
1587     DoDrawBitmap( src
, i_x
, i_y
, true ); 
1590     // it would be better to draw with non underlined font and draw the line 
1591     // manually here (it would be more straight...) 
1593     if ( m_font
.GetUnderlined() ) 
1595         gdk_draw_line( m_window
, m_textGC
, 
1596                        XLOG2DEV(x 
+ x4
), YLOG2DEV(y 
+ y4 
+ font
->descent
), 
1597                        XLOG2DEV(x 
+ x3
), YLOG2DEV(y 
+ y3 
+ font
->descent
)); 
1601     // update the bounding box 
1602     CalcBoundingBox(x 
+ minX
, y 
+ minY
); 
1603     CalcBoundingBox(x 
+ maxX
, y 
+ maxY
); 
1606 void wxWindowDC::DoGetTextExtent(const wxString 
&string
, 
1607                                  wxCoord 
*width
, wxCoord 
*height
, 
1608                                  wxCoord 
*descent
, wxCoord 
*externalLeading
, 
1609                                  wxFont 
*theFont
) const 
1617     if ( externalLeading 
) 
1618         *externalLeading 
= 0; 
1625     wxFont fontToUse 
= m_font
; 
1627         fontToUse 
= *theFont
; 
1629     GdkFont 
*font 
= fontToUse
.GetInternalFont( m_scaleY 
); 
1634         *width 
= wxCoord(gdk_string_width( font
, string
.mbc_str() ) / m_scaleX
); 
1636         *height 
= wxCoord((font
->ascent 
+ font
->descent
) / m_scaleY
); 
1638         *descent 
= wxCoord(font
->descent 
/ m_scaleY
); 
1641 wxCoord 
wxWindowDC::GetCharWidth() const 
1643     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1644     wxCHECK_MSG( font
, -1, wxT("invalid font") ); 
1646     return wxCoord(gdk_string_width( font
, "H" ) / m_scaleX
); 
1649 wxCoord 
wxWindowDC::GetCharHeight() const 
1651     GdkFont 
*font 
= m_font
.GetInternalFont( m_scaleY 
); 
1652     wxCHECK_MSG( font
, -1, wxT("invalid font") ); 
1654     return wxCoord((font
->ascent 
+ font
->descent
) / m_scaleY
); 
1657 void wxWindowDC::Clear() 
1659     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1661     if (!m_window
) return; 
1663     // VZ: the code below results in infinite recursion and crashes when 
1664     //     dc.Clear() is done from OnPaint() so I disable it for now. 
1665     //     I don't know what the correct fix is but Clear() surely should not 
1666     //     reenter OnPaint()! 
1668     /* - we either are a memory dc or have a window as the 
1669        owner. anything else shouldn't happen. 
1670        - we don't use gdk_window_clear() as we don't set 
1671        the window's background colour anymore. it is too 
1672        much pain to keep the DC's and the window's back- 
1673        ground colour in synch. */ 
1684         GetSize( &width
, &height 
); 
1685         gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height 
); 
1690     GetSize( &width
, &height 
); 
1691     gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height 
); 
1695 void wxWindowDC::SetFont( const wxFont 
&font 
) 
1700 void wxWindowDC::SetPen( const wxPen 
&pen 
) 
1702     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1704     if (m_pen 
== pen
) return; 
1708     if (!m_pen
.Ok()) return; 
1710     if (!m_window
) return; 
1712     gint width 
= m_pen
.GetWidth(); 
1715         // CMB: if width is non-zero scale it with the dc 
1720         // X doesn't allow different width in x and y and so we take 
1723                    ( fabs((double) XLOG2DEVREL(width
)) + 
1724                      fabs((double) YLOG2DEVREL(width
)) ) / 2.0; 
1728             // width can't be 0 or an internal GTK error occurs inside 
1729             // gdk_gc_set_dashes() below 
1734     static const wxGTKDash dotted
[] = {1, 1}; 
1735     static const wxGTKDash short_dashed
[] = {2, 2}; 
1736     static const wxGTKDash wxCoord_dashed
[] = {2, 4}; 
1737     static const wxGTKDash dotted_dashed
[] = {3, 3, 1, 3}; 
1739     // We express dash pattern in pen width unit, so we are 
1740     // independent of zoom factor and so on... 
1742     const wxGTKDash 
*req_dash
; 
1744     GdkLineStyle lineStyle 
= GDK_LINE_SOLID
; 
1745     switch (m_pen
.GetStyle()) 
1749             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1750             req_nb_dash 
= m_pen
.GetDashCount(); 
1751             req_dash 
= (wxGTKDash
*)m_pen
.GetDash(); 
1756             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1763             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1765             req_dash 
= wxCoord_dashed
; 
1770             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1772             req_dash 
= short_dashed
; 
1777 //            lineStyle = GDK_LINE_DOUBLE_DASH; 
1778             lineStyle 
= GDK_LINE_ON_OFF_DASH
; 
1780             req_dash 
= dotted_dashed
; 
1785         case wxSTIPPLE_MASK_OPAQUE
: 
1790             lineStyle 
= GDK_LINE_SOLID
; 
1791             req_dash 
= (wxGTKDash
*)NULL
; 
1797     if (req_dash 
&& req_nb_dash
) 
1799         wxGTKDash 
*real_req_dash 
= new wxGTKDash
[req_nb_dash
]; 
1802             for (int i 
= 0; i 
< req_nb_dash
; i
++) 
1803                 real_req_dash
[i
] = req_dash
[i
] * width
; 
1804             gdk_gc_set_dashes( m_penGC
, 0, real_req_dash
, req_nb_dash 
); 
1805             delete[] real_req_dash
; 
1809             // No Memory. We use non-scaled dash pattern... 
1810             gdk_gc_set_dashes( m_penGC
, 0, (wxGTKDash
*)req_dash
, req_nb_dash 
); 
1814     GdkCapStyle capStyle 
= GDK_CAP_ROUND
; 
1815     switch (m_pen
.GetCap()) 
1817         case wxCAP_PROJECTING
: { capStyle 
= GDK_CAP_PROJECTING
; break; } 
1818         case wxCAP_BUTT
:       { capStyle 
= GDK_CAP_BUTT
;       break; } 
1825                 capStyle 
= GDK_CAP_NOT_LAST
; 
1829                 capStyle 
= GDK_CAP_ROUND
; 
1835     GdkJoinStyle joinStyle 
= GDK_JOIN_ROUND
; 
1836     switch (m_pen
.GetJoin()) 
1838         case wxJOIN_BEVEL
: { joinStyle 
= GDK_JOIN_BEVEL
; break; } 
1839         case wxJOIN_MITER
: { joinStyle 
= GDK_JOIN_MITER
; break; } 
1841         default:           { joinStyle 
= GDK_JOIN_ROUND
; break; } 
1844     gdk_gc_set_line_attributes( m_penGC
, width
, lineStyle
, capStyle
, joinStyle 
); 
1846     m_pen
.GetColour().CalcPixel( m_cmap 
); 
1847     gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() ); 
1850 void wxWindowDC::SetBrush( const wxBrush 
&brush 
) 
1852     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1854     if (m_brush 
== brush
) return; 
1858     if (!m_brush
.Ok()) return; 
1860     if (!m_window
) return; 
1862     m_brush
.GetColour().CalcPixel( m_cmap 
); 
1863     gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() ); 
1865     gdk_gc_set_fill( m_brushGC
, GDK_SOLID 
); 
1867     if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok())) 
1869         if (m_brush
.GetStipple()->GetPixmap()) 
1871             gdk_gc_set_fill( m_brushGC
, GDK_TILED 
); 
1872             gdk_gc_set_tile( m_brushGC
, m_brush
.GetStipple()->GetPixmap() ); 
1876             gdk_gc_set_fill( m_brushGC
, GDK_STIPPLED 
); 
1877             gdk_gc_set_stipple( m_brushGC
, m_brush
.GetStipple()->GetBitmap() ); 
1881     if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask())) 
1883         gdk_gc_set_fill( m_textGC
, GDK_OPAQUE_STIPPLED
); 
1884         gdk_gc_set_stipple( m_textGC
, m_brush
.GetStipple()->GetMask()->GetBitmap() ); 
1887     if (m_brush
.IsHatch()) 
1889         gdk_gc_set_fill( m_brushGC
, GDK_STIPPLED 
); 
1890         int num 
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
; 
1891         gdk_gc_set_stipple( m_brushGC
, hatches
[num
] ); 
1895 void wxWindowDC::SetBackground( const wxBrush 
&brush 
) 
1897    /* CMB 21/7/98: Added SetBackground. Sets background brush 
1898     * for Clear() and bg colour for shapes filled with cross-hatch brush */ 
1900     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1902     if (m_backgroundBrush 
== brush
) return; 
1904     m_backgroundBrush 
= brush
; 
1906     if (!m_backgroundBrush
.Ok()) return; 
1908     if (!m_window
) return; 
1910     m_backgroundBrush
.GetColour().CalcPixel( m_cmap 
); 
1911     gdk_gc_set_background( m_brushGC
, m_backgroundBrush
.GetColour().GetColor() ); 
1912     gdk_gc_set_background( m_penGC
, m_backgroundBrush
.GetColour().GetColor() ); 
1913     gdk_gc_set_background( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() ); 
1914     gdk_gc_set_foreground( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() ); 
1916     gdk_gc_set_fill( m_bgGC
, GDK_SOLID 
); 
1918     if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok())) 
1920         if (m_backgroundBrush
.GetStipple()->GetPixmap()) 
1922             gdk_gc_set_fill( m_bgGC
, GDK_TILED 
); 
1923             gdk_gc_set_tile( m_bgGC
, m_backgroundBrush
.GetStipple()->GetPixmap() ); 
1927             gdk_gc_set_fill( m_bgGC
, GDK_STIPPLED 
); 
1928             gdk_gc_set_stipple( m_bgGC
, m_backgroundBrush
.GetStipple()->GetBitmap() ); 
1932     if (m_backgroundBrush
.IsHatch()) 
1934         gdk_gc_set_fill( m_bgGC
, GDK_STIPPLED 
); 
1935         int num 
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
; 
1936         gdk_gc_set_stipple( m_bgGC
, hatches
[num
] ); 
1940 void wxWindowDC::SetLogicalFunction( int function 
) 
1942     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1944     if (m_logicalFunction 
== function
) 
1947     // VZ: shouldn't this be a CHECK? 
1954         case wxXOR
:          mode 
= GDK_XOR
;           break; 
1955         case wxINVERT
:       mode 
= GDK_INVERT
;        break; 
1956         case wxOR_REVERSE
:   mode 
= GDK_OR_REVERSE
;    break; 
1957         case wxAND_REVERSE
:  mode 
= GDK_AND_REVERSE
;   break; 
1958         case wxCLEAR
:        mode 
= GDK_CLEAR
;         break; 
1959         case wxSET
:          mode 
= GDK_SET
;           break; 
1960         case wxOR_INVERT
:    mode 
= GDK_OR_INVERT
;     break; 
1961         case wxAND
:          mode 
= GDK_AND
;           break; 
1962         case wxOR
:           mode 
= GDK_OR
;            break; 
1963         case wxEQUIV
:        mode 
= GDK_EQUIV
;         break; 
1964         case wxNAND
:         mode 
= GDK_NAND
;          break; 
1965         case wxAND_INVERT
:   mode 
= GDK_AND_INVERT
;    break; 
1966         case wxCOPY
:         mode 
= GDK_COPY
;          break; 
1967         case wxNO_OP
:        mode 
= GDK_NOOP
;          break; 
1968         case wxSRC_INVERT
:   mode 
= GDK_COPY_INVERT
;   break; 
1970         // unsupported by GTK 
1971         case wxNOR
:          mode 
= GDK_COPY
;          break; 
1973            wxFAIL_MSG( wxT("unsupported logical function") ); 
1977     m_logicalFunction 
= function
; 
1979     gdk_gc_set_function( m_penGC
, mode 
); 
1980     gdk_gc_set_function( m_brushGC
, mode 
); 
1982     // to stay compatible with wxMSW, we don't apply ROPs to the text 
1983     // operations (i.e. DrawText/DrawRotatedText). 
1984     // True, but mono-bitmaps use the m_textGC and they use ROPs as well. 
1985     gdk_gc_set_function( m_textGC
, mode 
); 
1988 void wxWindowDC::SetTextForeground( const wxColour 
&col 
) 
1990     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1992     // don't set m_textForegroundColour to an invalid colour as we'd crash 
1993     // later then (we use m_textForegroundColour.GetColor() without checking 
1995     if ( !col
.Ok() || (m_textForegroundColour 
== col
) ) 
1998     m_textForegroundColour 
= col
; 
2002         m_textForegroundColour
.CalcPixel( m_cmap 
); 
2003         gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() ); 
2007 void wxWindowDC::SetTextBackground( const wxColour 
&col 
) 
2009     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2012     if ( !col
.Ok() || (m_textBackgroundColour 
== col
) ) 
2015     m_textBackgroundColour 
= col
; 
2019         m_textBackgroundColour
.CalcPixel( m_cmap 
); 
2020         gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() ); 
2024 void wxWindowDC::SetBackgroundMode( int mode 
) 
2026     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2028     m_backgroundMode 
= mode
; 
2030     if (!m_window
) return; 
2032     // CMB 21/7/98: fill style of cross-hatch brushes is affected by 
2033     // transparent/solid background mode 
2035     if (m_brush
.GetStyle() != wxSOLID 
&& m_brush
.GetStyle() != wxTRANSPARENT
) 
2037         gdk_gc_set_fill( m_brushGC
, 
2038           (m_backgroundMode 
== wxTRANSPARENT
) ? GDK_STIPPLED 
: GDK_OPAQUE_STIPPLED
); 
2042 void wxWindowDC::SetPalette( const wxPalette
& WXUNUSED(palette
) ) 
2044     wxFAIL_MSG( wxT("wxWindowDC::SetPalette not implemented") ); 
2047 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
2049     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2051     if (!m_window
) return; 
2054     rect
.x 
= XLOG2DEV(x
); 
2055     rect
.y 
= YLOG2DEV(y
); 
2056     rect
.width 
= XLOG2DEVREL(width
); 
2057     rect
.height 
= YLOG2DEVREL(height
); 
2059     if (!m_currentClippingRegion
.IsNull()) 
2060         m_currentClippingRegion
.Intersect( rect 
); 
2062         m_currentClippingRegion
.Union( rect 
); 
2064 #if USE_PAINT_REGION 
2065     if (!m_paintClippingRegion
.IsNull()) 
2066         m_currentClippingRegion
.Intersect( m_paintClippingRegion 
); 
2069     wxCoord xx
, yy
, ww
, hh
; 
2070     m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh 
); 
2071     wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh 
); 
2073     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2074     gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2075     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2076     gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2079 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion 
®ion  
) 
2081     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2085         DestroyClippingRegion(); 
2089     if (!m_window
) return; 
2091     if (!m_currentClippingRegion
.IsNull()) 
2092         m_currentClippingRegion
.Intersect( region 
); 
2094         m_currentClippingRegion
.Union( region 
); 
2096 #if USE_PAINT_REGION 
2097     if (!m_paintClippingRegion
.IsNull()) 
2098         m_currentClippingRegion
.Intersect( m_paintClippingRegion 
); 
2101     wxCoord xx
, yy
, ww
, hh
; 
2102     m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh 
); 
2103     wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh 
); 
2105     gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2106     gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2107     gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2108     gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2111 void wxWindowDC::DestroyClippingRegion() 
2113     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
2115     wxDC::DestroyClippingRegion(); 
2117     m_currentClippingRegion
.Clear(); 
2119 #if USE_PAINT_REGION 
2120     if (!m_paintClippingRegion
.IsEmpty()) 
2121         m_currentClippingRegion
.Union( m_paintClippingRegion 
); 
2124     if (!m_window
) return; 
2126     if (m_currentClippingRegion
.IsEmpty()) 
2128         gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle 
*) NULL 
); 
2129         gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle 
*) NULL 
); 
2130         gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle 
*) NULL 
); 
2131         gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle 
*) NULL 
); 
2135         gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() ); 
2136         gdk_gc_set_clip_region( m_brushGC
, m_currentClippingRegion
.GetRegion() ); 
2137         gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() ); 
2138         gdk_gc_set_clip_region( m_bgGC
, m_currentClippingRegion
.GetRegion() ); 
2142 void wxWindowDC::Destroy() 
2144     if (m_penGC
) wxFreePoolGC( m_penGC 
); 
2145     m_penGC 
= (GdkGC
*) NULL
; 
2146     if (m_brushGC
) wxFreePoolGC( m_brushGC 
); 
2147     m_brushGC 
= (GdkGC
*) NULL
; 
2148     if (m_textGC
) wxFreePoolGC( m_textGC 
); 
2149     m_textGC 
= (GdkGC
*) NULL
; 
2150     if (m_bgGC
) wxFreePoolGC( m_bgGC 
); 
2151     m_bgGC 
= (GdkGC
*) NULL
; 
2154 void wxWindowDC::ComputeScaleAndOrigin() 
2156     const wxRealPoint 
origScale(m_scaleX
, m_scaleY
); 
2158     wxDC::ComputeScaleAndOrigin(); 
2160     // if scale has changed call SetPen to recalulate the line width 
2161     if ( wxRealPoint(m_scaleX
, m_scaleY
) != origScale 
&& m_pen
.Ok() ) 
2163         // this is a bit artificial, but we need to force wxDC to think the pen 
2171 // Resolution in pixels per logical inch 
2172 wxSize 
wxWindowDC::GetPPI() const 
2174     return wxSize( (int) (m_mm_to_pix_x 
* 25.4 + 0.5), (int) (m_mm_to_pix_y 
* 25.4 + 0.5)); 
2177 int wxWindowDC::GetDepth() const 
2179     wxFAIL_MSG(wxT("not implemented")); 
2185 //----------------------------------------------------------------------------- 
2187 //----------------------------------------------------------------------------- 
2189 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
) 
2191 // Limit the paint region to the window size. Sometimes 
2192 // the paint region is too big, and this risks X11 errors 
2193 static void wxLimitRegionToSize(wxRegion
& region
, const wxSize
& sz
) 
2195     wxRect originalRect 
= region
.GetBox(); 
2196     wxRect 
rect(originalRect
); 
2197     if (rect
.width 
+ rect
.x 
> sz
.x
) 
2198         rect
.width 
= sz
.x 
- rect
.x
; 
2199     if (rect
.height 
+ rect
.y 
> sz
.y
) 
2200         rect
.height 
= sz
.y 
- rect
.y
; 
2201     if (rect 
!= originalRect
) 
2203         region 
= wxRegion(rect
); 
2204         wxLogTrace(wxT("painting"), wxT("Limiting region from %d, %d, %d, %d to %d, %d, %d, %d\n"), 
2205                    originalRect
.x
, originalRect
.y
, originalRect
.width
, originalRect
.height
, 
2206                    rect
.x
, rect
.y
, rect
.width
, rect
.height
); 
2210 wxPaintDC::wxPaintDC( wxWindow 
*win 
) 
2213 #if USE_PAINT_REGION 
2214     if (!win
->m_clipPaintRegion
) 
2217     wxSize sz 
= win
->GetSize(); 
2218     m_paintClippingRegion 
= win
->GetUpdateRegion(); 
2219     wxLimitRegionToSize(m_paintClippingRegion
, sz
); 
2221     GdkRegion 
*region 
= m_paintClippingRegion
.GetRegion(); 
2224         m_currentClippingRegion
.Union( m_paintClippingRegion 
); 
2225         wxLimitRegionToSize(m_currentClippingRegion
, sz
); 
2227         if (sz
.x 
<= 0 || sz
.y 
<= 0) 
2230         gdk_gc_set_clip_region( m_penGC
, region 
); 
2231         gdk_gc_set_clip_region( m_brushGC
, region 
); 
2232         gdk_gc_set_clip_region( m_textGC
, region 
); 
2233         gdk_gc_set_clip_region( m_bgGC
, region 
); 
2235 #endif // USE_PAINT_REGION 
2238 //----------------------------------------------------------------------------- 
2240 //----------------------------------------------------------------------------- 
2242 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
) 
2244 wxClientDC::wxClientDC( wxWindow 
*win 
) 
2247     wxCHECK_RET( win
, _T("NULL window in wxClientDC::wxClientDC") ); 
2249 #ifdef __WXUNIVERSAL__ 
2250     wxPoint ptOrigin 
= win
->GetClientAreaOrigin(); 
2251     SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
); 
2252     wxSize size 
= win
->GetClientSize(); 
2253     SetClippingRegion(wxPoint(0, 0), size
); 
2254 #endif // __WXUNIVERSAL__ 
2257 void wxClientDC::DoGetSize(int *width
, int *height
) const 
2259     wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") ); 
2261     m_owner
->GetClientSize( width
, height 
); 
2264 // ---------------------------------------------------------------------------- 
2266 // ---------------------------------------------------------------------------- 
2268 class wxDCModule 
: public wxModule
 
2275     DECLARE_DYNAMIC_CLASS(wxDCModule
) 
2278 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
) 
2280 bool wxDCModule::OnInit() 
2286 void wxDCModule::OnExit()