1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/motif/dcclient.cpp 
   3 // Purpose:     wxClientDCImpl class 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13   About pens, brushes, and the m_autoSetting flag: 
  15   Under X, pens and brushes control some of the same X drawing 
  16   parameters.  Therefore, it is impossible to independently maintain 
  17   the current pen and the current brush. Also, some settings depend on 
  18   the current logical function. The m_currentFill, etc. instance 
  19   variables remember state across the brush and pen. 
  21   Since pens are used more than brushes, the m_autoSetting flag is used to 
  22   indicate that a brush was recently used, and SetPen must be called to 
  23   reinstall the current pen's parameters. If m_autoSetting includes 0x2, then the 
  24   pens color may need to be set based on XOR. 
  26   There is, unfortunately, some confusion between setting the current pen/brush 
  27   and actually installing the brush/pen parameters. Both functionalies are 
  28   perform by SetPen and SetBrush. C'est la vie. 
  31 // ============================================================================ 
  33 // ============================================================================ 
  35 // ---------------------------------------------------------------------------- 
  37 // ---------------------------------------------------------------------------- 
  39 // For compilers that support precompilation, includes "wx.h". 
  40 #include "wx/wxprec.h" 
  45     #include "wx/window.h" 
  46     #include "wx/dcmemory.h" 
  49     #include "wx/dcclient.h" 
  53 #pragma message disable nosimpint 
  57 #pragma message enable nosimpint 
  60 #include "wx/motif/private.h" 
  61 #include "wx/motif/dcclient.h" 
  64     #include <float.h>          // for M_PI 
  74 static Pixmap bdiag
, cdiag
, fdiag
, cross
, horiz
, verti
; 
  76 // ---------------------------------------------------------------------------- 
  78 // ---------------------------------------------------------------------------- 
  80 // Fudge factor (VZ: what??) 
  83 // ---------------------------------------------------------------------------- 
  85 // ---------------------------------------------------------------------------- 
  87 IMPLEMENT_ABSTRACT_CLASS(wxClientDCImpl
, wxWindowDCImpl
) 
  88 IMPLEMENT_ABSTRACT_CLASS(wxPaintDCImpl
, wxWindowDCImpl
) 
  89 IMPLEMENT_ABSTRACT_CLASS(wxWindowDCImpl
, wxMotifDCImpl
) 
  91 #define IS_HATCH(s)    ((s)>=wxFIRST_HATCH && (s)<=wxLAST_HATCH) 
  93 // FIXME: left over after removal of wxDC::GetOptimization() 
  94 #define GET_OPTIMIZATION false 
  96 // ---------------------------------------------------------------------------- 
  98 // ---------------------------------------------------------------------------- 
 100 static void XCopyRemote(Display 
*src_display
, Display 
*dest_display
, 
 101                         Drawable src
, Drawable dest
, 
 104                         unsigned int w
, unsigned int h
, 
 105                         int destx
, int desty
, 
 106                         bool more
, XImage 
**cache
); 
 108 // ============================================================================ 
 110 // ============================================================================ 
 113  * compare two doubles and return the larger rounded 
 116 static int roundmax(double a
, double b
) 
 118     return (int)((a 
> b 
? a 
: b
) + 0.5); 
 122  * compare two doubles and return the smaller rounded 
 125 static int roundmin(double a
, double b
) 
 127     return (int)((a 
< b 
? a 
: b
) - 0.5); 
 131 // ---------------------------------------------------------------------------- 
 133 // ---------------------------------------------------------------------------- 
 135 void wxWindowDCImpl::Init() 
 138     m_gcBacking 
= (WXGC
) 0; 
 140     m_backgroundPixel 
= -1; 
 141     m_currentPenWidth 
= 1; 
 142     m_currentPenJoin 
= -1; 
 143     m_currentPenDashCount 
= -1; 
 144     m_currentPenDash 
= (wxX11Dash
*) NULL
; 
 147     m_colour 
= wxColourDisplay(); 
 148     m_display 
= (WXDisplay
*) NULL
; 
 149     m_pixmap 
= (WXPixmap
) 0; 
 152     m_clipRegion 
= (WXRegion
) 0; 
 155 wxWindowDCImpl::wxWindowDCImpl(wxDC 
*owner
) 
 156               : wxMotifDCImpl(owner
) 
 161 wxWindowDCImpl::wxWindowDCImpl(wxDC 
*owner
, wxWindow 
*window
) 
 162               : wxMotifDCImpl(owner
) 
 164     wxASSERT_MSG( (window 
!= (wxWindow
*) NULL
), "You must pass a valid wxWindow to wxWindowDCImpl/wxClientDCImpl/wxPaintDCImpl constructor." ); 
 169     m_font 
= window
->GetFont(); 
 172     m_display 
= window
->GetXDisplay(); 
 173     m_pixmap 
= window
->GetXWindow(); 
 174     Display
* display 
= (Display
*) m_display
; 
 176     XSetWindowColormap (display
, (Pixmap
) m_pixmap
, (Colormap
) wxTheApp
->GetMainColormap(m_display
)); 
 179     gcvalues
.foreground 
= BlackPixel (display
, DefaultScreen (display
)); 
 180     gcvalues
.background 
= WhitePixel (display
, DefaultScreen (display
)); 
 181     gcvalues
.graphics_exposures 
= False
; 
 182     gcvalues
.subwindow_mode 
= IncludeInferiors
; 
 183     gcvalues
.line_width 
= 1; 
 184 #if !wxMOTIF_NEW_FONT_HANDLING 
 185     WXFontStructPtr pFontStruct 
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
); 
 186     gcvalues
.font 
= ((XFontStruct
*)pFontStruct
)->fid
; 
 188     m_gc 
= (WXGC
) XCreateGC (display
, RootWindow (display
, DefaultScreen (display
)), 
 189         GCForeground 
| GCBackground 
| GCGraphicsExposures 
| GCLineWidth 
| GCSubwindowMode
 
 190 #if !wxMOTIF_NEW_FONT_HANDLING 
 196     if (m_window
->GetBackingPixmap()) 
 198         m_gcBacking 
= (WXGC
) XCreateGC (display
, RootWindow (display
, 
 199             DefaultScreen (display
)), 
 200             GCForeground 
| GCBackground 
| GCGraphicsExposures 
| GCLineWidth 
| GCSubwindowMode
, 
 204     m_backgroundPixel 
= gcvalues
.background
; 
 206     SetBackground(wxBrush(m_window
->GetBackgroundColour(), wxSOLID
)); 
 209 wxWindowDCImpl::~wxWindowDCImpl() 
 212         XFreeGC ((Display
*) m_display
, (GC
) m_gc
); 
 216         XFreeGC ((Display
*) m_display
, (GC
) m_gcBacking
); 
 217     m_gcBacking 
= (WXGC
) 0; 
 220         XDestroyRegion ((Region
) m_clipRegion
); 
 221     m_clipRegion 
= (WXRegion
) 0; 
 224 extern bool wxDoFloodFill(wxDC 
*dc
, wxCoord x
, wxCoord y
, 
 225                           const wxColour 
& col
, int style
); 
 227 bool wxWindowDCImpl::DoFloodFill(wxCoord x
, wxCoord y
, 
 228                              const wxColour
& col
, int style
) 
 230     return wxDoFloodFill(GetOwner(), x
, y
, col
, style
); 
 233 bool wxWindowDCImpl::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour 
*col 
) const 
 235     // Generic (and therefore rather inefficient) method. 
 236     // Could be improved. 
 238     wxBitmap 
bitmap(1, 1); 
 239     memdc
.SelectObject(bitmap
); 
 240     memdc
.Blit(0, 0, 1, 1, GetOwner(), x1
, y1
); 
 241     memdc
.SelectObject(wxNullBitmap
); 
 242     wxImage image 
= bitmap
.ConvertToImage(); 
 243     col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0)); 
 247 void wxWindowDCImpl::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2 
) 
 249     wxCHECK_RET( IsOk(), "invalid dc" ); 
 251     int x1d
, y1d
, x2d
, y2d
; 
 261     XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x1d
, y1d
, x2d
, y2d
); 
 263     if (m_window 
&& m_window
->GetBackingPixmap()) 
 264         XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
, 
 265         XLOG2DEV_2(x1
), YLOG2DEV_2(y1
), 
 266         XLOG2DEV_2(x2
), YLOG2DEV_2(y2
)); 
 268     CalcBoundingBox(x1
, y1
); 
 269     CalcBoundingBox(x2
, y2
); 
 272 void wxWindowDCImpl::DoCrossHair( wxCoord x
, wxCoord y 
) 
 274     wxCHECK_RET( IsOk(), "invalid dc" ); 
 279     int xx 
= XLOG2DEV (x
); 
 280     int yy 
= YLOG2DEV (y
); 
 282     wxDisplaySize (&ww
, &hh
); 
 283     XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, yy
, 
 285     XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xx
, 0, 
 288     if (m_window 
&& m_window
->GetBackingPixmap()) 
 292         XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
, 
 295         XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
, 
 301 void wxWindowDCImpl::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc 
) 
 303     wxCHECK_RET( IsOk(), "invalid dc" ); 
 305     int xx1 
= XLOG2DEV (x1
); 
 306     int yy1 
= YLOG2DEV (y1
); 
 307     int xx2 
= XLOG2DEV (x2
); 
 308     int yy2 
= YLOG2DEV (y2
); 
 309     int xxc 
= XLOG2DEV (xc
); 
 310     int yyc 
= YLOG2DEV (yc
); 
 311     int xxc_2 
= XLOG2DEV_2 (xc
); 
 312     int yyc_2 
= YLOG2DEV_2 (yc
); 
 314     wxCoord dx 
= xx1 
- xxc
; 
 315     wxCoord dy 
= yy1 
- yyc
; 
 316     double radius 
= sqrt ((double)(dx 
* dx 
+ dy 
* dy
)); 
 317     wxCoord r 
= (wxCoord
) radius
; 
 319     double radius1
, radius2
; 
 321     if (xx1 
== xx2 
&& yy1 
== yy2
) 
 326     else if (radius 
== 0.0) 
 327         radius1 
= radius2 
= 0.0; 
 336                 radius1 
= -atan2 ((double) (yy1 
- yyc
), (double) (xx1 
- xxc
)) * 360.0 / (2 * M_PI
); 
 344                     radius2 
= -atan2 ((double) (yy2 
- yyc
), (double) (xx2 
- xxc
)) * 360.0 / (2 * M_PI
); 
 348     int alpha1 
= (int) radius1
; 
 349     int alpha2 
= (int) (radius2 
- radius1
); 
 352     while (alpha2 
> 360 * 64) 
 355     if (m_brush
.IsOk() && m_brush
.GetStyle () != wxTRANSPARENT
) 
 358         XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) (GC
) m_gc
, 
 359             xxc 
- r
, yyc 
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
); 
 361         if (m_window 
&& m_window
->GetBackingPixmap()) 
 362             XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
, 
 363             xxc_2 
- r
, yyc_2 
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
); 
 367     if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
) 
 371         XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 
 372             xxc 
- r
, yyc 
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
); 
 374         if (m_window 
&& m_window
->GetBackingPixmap()) 
 375             XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
, 
 376             xxc_2 
- r
, yyc_2 
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
); 
 378     CalcBoundingBox (x1
, y1
); 
 379     CalcBoundingBox (x2
, y2
); 
 382 void wxWindowDCImpl::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea 
) 
 384     wxCHECK_RET( IsOk(), "invalid dc" ); 
 390     wd 
= XLOG2DEVREL(width
); 
 391     hd 
= YLOG2DEVREL(height
); 
 393     if (sa
>=360 || sa
<=-360) sa
=sa
-int(sa
/360)*360; 
 394     if (ea
>=360 || ea
<=-360) ea
=ea
-int(ea
/360)*360; 
 395     int start 
= int(sa
*64); 
 396     int end   
= int(ea
*64); 
 397     if (start
<0) start
+=360*64; 
 398     if (end  
<0) end  
+=360*64; 
 399     if (end
>start
) end
-=start
; 
 400     else end
+=360*64-start
; 
 402     if (m_brush
.IsOk() && m_brush
.GetStyle () != wxTRANSPARENT
) 
 404         m_autoSetting 
= true;    // must be reset 
 407         XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
, end
); 
 409         if (m_window 
&& m_window
->GetBackingPixmap()) 
 410             XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
, 
 411             XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
); 
 414     if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
) 
 418         XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
,end
); 
 419         if (m_window 
&& m_window
->GetBackingPixmap()) 
 420             XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
, 
 421             XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
); 
 423     CalcBoundingBox (x
, y
); 
 424     CalcBoundingBox (x 
+ width
, y 
+ height
); 
 427 void wxWindowDCImpl::DoDrawPoint( wxCoord x
, wxCoord y 
) 
 429     wxCHECK_RET( IsOk(), "invalid dc" ); 
 431     if (m_pen
.IsOk() && m_autoSetting
) 
 434     XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
)); 
 435     if (m_window 
&& m_window
->GetBackingPixmap()) 
 436         XDrawPoint ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, XLOG2DEV_2 (x
), YLOG2DEV_2 (y
)); 
 438     CalcBoundingBox (x
, y
); 
 441 void wxWindowDCImpl::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset 
) 
 443     wxCHECK_RET( IsOk(), "invalid dc" ); 
 445     if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
) 
 450         XPoint 
*xpoints 
= new XPoint
[n
]; 
 453         for (i 
= 0; i 
< n
; i
++) 
 455             xpoints
[i
].x 
= (short)XLOG2DEV (points
[i
].x 
+ xoffset
); 
 456             xpoints
[i
].y 
= (short)YLOG2DEV (points
[i
].y 
+ yoffset
); 
 458         XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints
, n
, 0); 
 460         if (m_window 
&& m_window
->GetBackingPixmap()) 
 462             for (i 
= 0; i 
< n
; i
++) 
 464                 xpoints
[i
].x 
= (short)XLOG2DEV_2 (points
[i
].x 
+ xoffset
); 
 465                 xpoints
[i
].y 
= (short)YLOG2DEV_2 (points
[i
].y 
+ yoffset
); 
 467             XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints
, n
, 0); 
 473 void wxWindowDCImpl::DoDrawPolygon( int n
, wxPoint points
[], 
 474                                 wxCoord xoffset
, wxCoord yoffset
, int fillStyle 
) 
 476     wxCHECK_RET( IsOk(), "invalid dc" ); 
 478     XPoint 
*xpoints1 
= new XPoint
[n 
+ 1]; 
 479     XPoint 
*xpoints2 
= new XPoint
[n 
+ 1]; 
 481     for (i 
= 0; i 
< n
; i
++) 
 483         xpoints1
[i
].x 
= (short)XLOG2DEV (points
[i
].x 
+ xoffset
); 
 484         xpoints1
[i
].y 
= (short)YLOG2DEV (points
[i
].y 
+ yoffset
); 
 485         xpoints2
[i
].x 
= (short)XLOG2DEV_2 (points
[i
].x 
+ xoffset
); 
 486         xpoints2
[i
].y 
= (short)YLOG2DEV_2 (points
[i
].y 
+ yoffset
); 
 487         CalcBoundingBox (points
[i
].x 
+ xoffset
, points
[i
].y 
+ yoffset
); 
 490     // Close figure for XDrawLines (not needed for XFillPolygon) 
 491     xpoints1
[i
].x 
= xpoints1
[0].x
; 
 492     xpoints1
[i
].y 
= xpoints1
[0].y
; 
 493     xpoints2
[i
].x 
= xpoints2
[0].x
; 
 494     xpoints2
[i
].y 
= xpoints2
[0].y
; 
 496     if (m_brush
.IsOk() && m_brush
.GetStyle () != wxTRANSPARENT
) 
 499         XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, fillStyle 
== wxODDEVEN_RULE 
? EvenOddRule 
: WindingRule
); 
 500         XFillPolygon ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
, Complex
, 0); 
 501         XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, EvenOddRule
);    // default mode 
 502         if (m_window 
&& m_window
->GetBackingPixmap()) 
 504             XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
, 
 505                 fillStyle 
== wxODDEVEN_RULE 
? EvenOddRule 
: WindingRule
); 
 506             XFillPolygon ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
, Complex
, 0); 
 507             XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
, EvenOddRule
);    // default mode 
 511     if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
) 
 515         XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n 
+ 1, 0); 
 517         if (m_window 
&& m_window
->GetBackingPixmap()) 
 518             XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n 
+ 1, 0); 
 525 void wxWindowDCImpl::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 527     wxCHECK_RET( IsOk(), "invalid dc" ); 
 529     int xd
, yd
, wfd
, hfd
, wd
, hd
; 
 533     wfd 
= XLOG2DEVREL(width
); 
 535     hfd 
= YLOG2DEVREL(height
); 
 538     if (wfd 
== 0 || hfd 
== 0) return; 
 539     if (wd 
< 0) { wd 
= - wd
; xd 
= xd 
- wd
; } 
 540     if (hd 
< 0) { hd 
= - hd
; yd 
= yd 
- hd
; } 
 542     if (m_brush
.IsOk() && m_brush
.GetStyle () != wxTRANSPARENT
) 
 545         XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wfd
, hfd
); 
 547         if (m_window 
&& m_window
->GetBackingPixmap()) 
 548             XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 549             XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), 
 553     if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
) 
 557         XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
); 
 559         if (m_window 
&& m_window
->GetBackingPixmap()) 
 560             XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 561             XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), 
 564     CalcBoundingBox (x
, y
); 
 565     CalcBoundingBox (x 
+ width
, y 
+ height
); 
 568 void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius 
) 
 570     wxCHECK_RET( IsOk(), "invalid dc" ); 
 572     // If radius is negative, it's a proportion of the smaller dimension. 
 574     if (radius 
< 0.0) radius 
= - radius 
* ((width 
< height
) ? width 
: height
); 
 576     int xd 
= XLOG2DEV (x
); 
 577     int yd 
= YLOG2DEV (y
); 
 578     int rd 
= XLOG2DEVREL ((long) radius
); 
 579     int wd 
= XLOG2DEVREL (width
) - WX_GC_CF
; 
 580     int hd 
= YLOG2DEVREL (height
) - WX_GC_CF
; 
 585     // If radius is zero use DrawRectangle() instead to avoid 
 586     // X drawing errors with small radii 
 589         DoDrawRectangle( x
, y
, width
, height 
); 
 593     // Draw nothing if transformed w or h is 0 
 594     if (wd 
== 0 || hd 
== 0) return; 
 596     // CMB: adjust size if outline is drawn otherwise the result is 
 597     // 1 pixel too wide and high 
 598     if (m_pen
.GetStyle() != wxTRANSPARENT
) 
 604     // CMB: ensure dd is not larger than rectangle otherwise we 
 605     // get an hour glass shape 
 606     if (rw_d 
> wd
) rw_d 
= wd
; 
 607     if (rw_d 
> hd
) rw_d 
= hd
; 
 610     // For backing pixmap 
 611     int xd2 
= XLOG2DEV_2 (x
); 
 612     int yd2 
= YLOG2DEV_2 (y
); 
 613     int rd2 
= XLOG2DEVREL ((long) radius
); 
 614     int wd2 
= XLOG2DEVREL (width
) ; 
 615     int hd2 
= YLOG2DEVREL (height
) ; 
 620     if (m_brush
.IsOk() && m_brush
.GetStyle () != wxTRANSPARENT
) 
 624         XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd 
+ rd
, yd
, 
 626         XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd 
+ rd
, 
 629         // Arcs start from 3 o'clock, positive angles anticlockwise 
 631         XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, 
 632             rw_d
, rh_d
, 90 * 64, 90 * 64); 
 634         XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd 
+ wd 
- rw_d
, yd
, 
 635             //        rw_d, rh_d, 0, 90 * 64); 
 636             rw_d
, rh_d
, 0, 91 * 64); 
 638         XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd 
+ wd 
- rw_d
, 
 640             //        rw_d, rh_d, 270 * 64, 90 * 64); 
 641             rw_d
, rh_d
, 269 * 64, 92 * 64); 
 643         XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd 
+ hd 
- rh_d
, 
 644             rw_d
, rh_d
, 180 * 64, 90 * 64); 
 646         if (m_window 
&& m_window
->GetBackingPixmap()) 
 648             XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 649                 xd2 
+ rd2
, yd2
, wd2 
- rw_d2
, hd2
); 
 650             XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 651                 xd2
, yd2 
+ rd2
, wd2
, hd2 
- rh_d2
); 
 653             XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 654                 xd2
, yd2
, rw_d2
, rh_d2
, 90 * 64, 90 * 64); 
 655             XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 656                 xd2 
+ wd2 
- rw_d2
, yd2
, 
 657                 //            rw_d2, rh_d2, 0, 90 * 64); 
 658                 rw_d2
, rh_d2
, 0, 91 * 64); 
 659             XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 662                 //            rw_d2, rh_d2, 270 * 64, 90 * 64); 
 663                 rw_d2
, rh_d2
, 269 * 64, 92 * 64); 
 664             XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 665                 xd2
, yd2 
+ hd2 
- rh_d2
, 
 666                 rw_d2
, rh_d2
, 180 * 64, 90 * 64); 
 670     if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
) 
 673         XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd 
+ rd
, yd
, 
 674             xd 
+ wd 
- rd 
+ 1, yd
); 
 675         XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd 
+ rd
, yd 
+ hd
, 
 676             xd 
+ wd 
- rd
, yd 
+ hd
); 
 678         XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd 
+ rd
, 
 680         XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd 
+ wd
, yd 
+ rd
, 
 681             xd 
+ wd
, yd 
+ hd 
- rd 
+ 1); 
 682         XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, 
 683             rw_d
, rh_d
, 90 * 64, 90 * 64); 
 684         XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd 
+ wd 
- rw_d
, yd
, 
 685             //        rw_d, rh_d, 0, 90 * 64); 
 686             rw_d
, rh_d
, 0, 91 * 64); 
 687         XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd 
+ wd 
- rw_d
, 
 689             rw_d
, rh_d
, 269 * 64, 92 * 64); 
 690         XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd 
+ hd 
- rh_d
, 
 691             rw_d
, rh_d
, 180 * 64, 90 * 64); 
 693         if (m_window 
&& m_window
->GetBackingPixmap()) 
 695             XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 697                 xd2 
+ wd2 
- rd2 
+ 1, yd2
); 
 698             XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 699                 xd2 
+ rd2
, yd2 
+ hd2
, 
 700                 xd2 
+ wd2 
- rd2
, yd2 
+ hd2
); 
 702             XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 704                 xd2
, yd2 
+ hd2 
- rd2
); 
 705             XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 706                 xd2 
+ wd2
, yd2 
+ rd2
, 
 707                 xd2 
+ wd2
, yd2 
+ hd2 
- rd2 
+ 1); 
 708             XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 710                 rw_d2
, rh_d2
, 90 * 64, 90 * 64); 
 711             XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 712                 xd2 
+ wd2 
- rw_d2
, yd2
, 
 713                 //            rw_d2, rh_d2, 0, 90 * 64); 
 714                 rw_d2
, rh_d2
, 0, 91 * 64); 
 715             XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 718                 rw_d2
, rh_d2
, 269 * 64, 92 * 64); 
 719             XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 720                 xd2
, yd2 
+ hd2 
- rh_d2
, 
 721                 rw_d2
, rh_d2
, 180 * 64, 90 * 64); 
 724     CalcBoundingBox (x
, y
); 
 725     CalcBoundingBox (x 
+ width
, y 
+ height
); 
 728 void wxWindowDCImpl::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 730     wxCHECK_RET( IsOk(), "invalid dc" ); 
 732     // Check for negative width and height 
 745     static const int angle 
= 23040; 
 751     wd 
= XLOG2DEVREL(width
) ; 
 752     hd 
= YLOG2DEVREL(height
) ; 
 754     if (m_brush
.IsOk() && m_brush
.GetStyle () != wxTRANSPARENT
) 
 757         XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
); 
 758         if (m_window 
&& m_window
->GetBackingPixmap()) 
 759             XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 760             XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), 
 761             XLOG2DEVREL (width
) - WX_GC_CF
, 
 762             YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
); 
 765     if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
) 
 769         XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
); 
 770         if (m_window 
&& m_window
->GetBackingPixmap()) 
 771             XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 772             XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), 
 773             XLOG2DEVREL (width
) - WX_GC_CF
, 
 774             YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
); 
 776     CalcBoundingBox (x
, y
); 
 777     CalcBoundingBox (x 
+ width
, y 
+ height
); 
 781 bool wxWindowDCImpl::CanDrawBitmap() const 
 783     wxCHECK_MSG( IsOk(), false, "invalid dc" ); 
 788 // TODO: use scaled Blit e.g. as per John Price's implementation 
 789 // in Contrib/Utilities 
 790 bool wxWindowDCImpl::DoBlit( wxCoord xdest
, wxCoord ydest
, 
 791                          wxCoord width
, wxCoord height
, 
 792                          wxDC 
*source
, wxCoord xsrc
, wxCoord ysrc
, 
 793                          int rop
, bool useMask
, 
 794                          wxCoord xsrcMask
, wxCoord ysrcMask 
) 
 796     wxCHECK_MSG( IsOk(), false, "invalid dc" ); 
 798     wxWindowDC 
const * sourceDC 
= wxDynamicCast(source
, wxWindowDC
); 
 799     wxCHECK_MSG( sourceDC
, false, "Blit source DC must be wxWindowDCImpl or derived class." ); 
 801     // cast is safe in virtue of the above wxCHECK_MSG() 
 802     const wxWindowDCImpl 
* const 
 803         srcImpl 
= static_cast<const wxWindowDCImpl 
*>(sourceDC
->GetImpl()); 
 804     WXDisplay 
* const srcDpy 
= srcImpl
->m_display
; 
 807     // Be sure that foreground pixels (1) of the Icon will be painted with 
 808     // foreground colour. [m_textForegroundColour] Background pixels (0) 
 809     // will be painted with backgound colour (m_textBackgroundColour) 
 810     // Using ::SetPen is horribly slow, so avoid doing it 
 811     WXPixel oldBackgroundPixel 
= -1; 
 812     WXPixel oldForegroundPixel 
= -1; 
 814     if (m_textBackgroundColour
.IsOk()) 
 816         oldBackgroundPixel 
= m_backgroundPixel
; 
 817         WXPixel pixel 
= m_textBackgroundColour
.AllocColour(m_display
); 
 819         XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
); 
 820         if (m_window 
&& m_window
->GetBackingPixmap()) 
 821             XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
, 
 824     if (m_textForegroundColour
.IsOk()) 
 826         oldForegroundPixel 
= m_currentColour
.GetPixel(); 
 828         if( m_textForegroundColour
.GetPixel() <= -1 ) 
 829             CalculatePixel( m_textForegroundColour
, 
 830                             m_textForegroundColour
, true); 
 832         WXPixel pixel 
= m_textForegroundColour
.GetPixel(); 
 834             SetForegroundPixelWithLogicalFunction(pixel
); 
 837     // Do bitmap scaling if necessary 
 839     wxBitmap 
*scaledBitmap 
= (wxBitmap
*) NULL
; 
 840     Pixmap sourcePixmap 
= (Pixmap
) NULL
; 
 841     double scaleX
, scaleY
; 
 842     GetUserScale(& scaleX
, & scaleY
); 
 845     /* TODO: use the mask origin when drawing transparently */ 
 846     if (xsrcMask 
== -1 && ysrcMask 
== -1) 
 848         xsrcMask 
= xsrc
; ysrcMask 
= ysrc
; 
 851     // Sorry, can't scale masks just yet 
 852     if (!useMask 
&& (scaleX 
!= 1.0 || scaleY 
!= 1.0) && sourceDC
->IsKindOf(CLASSINFO(wxMemoryDC
))) 
 854         wxMemoryDC
* memDC 
= (wxMemoryDC
*) sourceDC
; 
 855         wxBitmap
& bitmap 
= memDC
->GetSelectedBitmap(); 
 857         wxASSERT_MSG( (bitmap
.IsOk()), "Bad source bitmap in wxWindowDCImpl::Blit"); 
 859         wxImage image 
= bitmap
.ConvertToImage(); 
 862             sourcePixmap 
= (Pixmap
) bitmap
.GetDrawable(); 
 866             int scaledW 
= (int) (bitmap
.GetWidth() * scaleX
); 
 867             int scaledH 
= (int) (bitmap
.GetHeight() * scaleY
); 
 869             image 
= image
.Scale(scaledW
, scaledH
); 
 870             scaledBitmap 
= new wxBitmap(image
); 
 871             sourcePixmap 
= (Pixmap
) scaledBitmap
->GetDrawable(); 
 876         sourcePixmap 
= (Pixmap
) srcImpl
->m_pixmap
; 
 879     if (m_pixmap 
&& sourcePixmap
) 
 882         int orig 
= m_logicalFunction
; 
 884         SetLogicalFunction (rop
); 
 886         if (m_display 
!= srcDpy
) 
 888             XImage 
*cache 
= NULL
; 
 890             if (m_window 
&& m_window
->GetBackingPixmap()) 
 891                 XCopyRemote((Display
*) srcDpy
, (Display
*) m_display
, 
 892                 (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(), 
 894                 source
->LogicalToDeviceX (xsrc
), 
 895                 source
->LogicalToDeviceY (ysrc
), 
 896                 source
->LogicalToDeviceXRel(width
), 
 897                 source
->LogicalToDeviceYRel(height
), 
 898                 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 
 901             if ( useMask 
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) ) 
 903                 wxMemoryDC 
*memDC 
= (wxMemoryDC 
*)source
; 
 904                 wxBitmap
& sel 
= memDC
->GetSelectedBitmap(); 
 905                 if ( sel
.IsOk() && sel
.GetMask() && sel
.GetMask()->GetBitmap() ) 
 907                     XSetClipMask   ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap()); 
 908                     XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
)); 
 912             XCopyRemote((Display
*) srcDpy
, (Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 
 913                 source
->LogicalToDeviceX (xsrc
), 
 914                 source
->LogicalToDeviceY (ysrc
), 
 915                 source
->LogicalToDeviceXRel(width
), 
 916                 source
->LogicalToDeviceYRel(height
), 
 917                 XLOG2DEV (xdest
), YLOG2DEV (ydest
), 
 923                     XSetRegion ((Display
*) m_display
, (GC
) m_gc
, 
 924                                 (Region
) m_clipRegion
); 
 926                     XSetClipMask   ((Display
*) m_display
, (GC
) m_gc
, None
); 
 928                 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0); 
 932         {        //XGCValues values; 
 933         //XGetGCValues((Display*)m_display, (GC)m_gc, GCForeground, &values); 
 935             if (m_window 
&& m_window
->GetBackingPixmap()) 
 937                 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1 
 938                 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetSelectedBitmap().GetDepth() == 1) 
 940                     XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 941                         source
->LogicalToDeviceX (xsrc
), 
 942                         source
->LogicalToDeviceY (ysrc
), 
 943                         source
->LogicalToDeviceXRel(width
), 
 944                         source
->LogicalToDeviceYRel(height
), 
 945                         XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 1); 
 949                     XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
 950                         source
->LogicalToDeviceX (xsrc
), 
 951                         source
->LogicalToDeviceY (ysrc
), 
 952                         source
->LogicalToDeviceXRel(width
), 
 953                         source
->LogicalToDeviceYRel(height
), 
 954                         XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
)); 
 957             if ( useMask 
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) ) 
 959                 wxMemoryDC 
*memDC 
= (wxMemoryDC 
*)source
; 
 960                 wxBitmap
& sel 
= memDC
->GetSelectedBitmap(); 
 961                 if ( sel
.IsOk() && sel
.GetMask() && sel
.GetMask()->GetBitmap() ) 
 963                     XSetClipMask   ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap()); 
 964                     XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
)); 
 968             // Check if we're copying from a mono bitmap 
 969             if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && 
 970                 ((wxMemoryDC
*)source
)->GetSelectedBitmap().IsOk() && 
 971                 (((wxMemoryDC
*)source
)->GetSelectedBitmap().GetDepth () == 1)) 
 973                 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 
 974                     source
->LogicalToDeviceX (xsrc
), 
 975                     source
->LogicalToDeviceY (ysrc
), 
 976                     source
->LogicalToDeviceXRel(width
), 
 977                     source
->LogicalToDeviceYRel(height
), 
 978                     XLOG2DEV (xdest
), YLOG2DEV (ydest
), 1); 
 982                 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 
 983                     source
->LogicalToDeviceX (xsrc
), 
 984                     source
->LogicalToDeviceY (ysrc
), 
 985                     source
->LogicalToDeviceXRel(width
), 
 986                     source
->LogicalToDeviceYRel(height
), 
 987                     XLOG2DEV (xdest
), YLOG2DEV (ydest
)); 
 993                     XSetRegion ((Display
*) m_display
, (GC
) m_gc
, 
 994                                 (Region
) m_clipRegion
); 
 996                     XSetClipMask   ((Display
*) m_display
, (GC
) m_gc
, None
); 
 998                 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0); 
1001         } /* Remote/local (Display*) m_display */ 
1002         CalcBoundingBox (xdest
, ydest
); 
1003         CalcBoundingBox (xdest 
+ width
, ydest 
+ height
); 
1005         SetLogicalFunction(orig
); 
1009   if (scaledBitmap
) delete scaledBitmap
; 
1011   if (oldBackgroundPixel 
> -1) 
1013       XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
); 
1014       if (m_window 
&& m_window
->GetBackingPixmap()) 
1015           XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
, 
1016                           oldBackgroundPixel
); 
1018   if (oldForegroundPixel 
> -1) 
1020       XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
); 
1021       if (m_window 
&& m_window
->GetBackingPixmap()) 
1022           XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, 
1023                           oldForegroundPixel
); 
1029 void wxWindowDCImpl::DoDrawText( const wxString 
&text
, wxCoord x
, wxCoord y 
) 
1031     wxCHECK_RET( IsOk(), "invalid dc" ); 
1033     // Since X draws from the baseline of the text, must add the text height 
1037     int slen 
= text
.length(); 
1039     // Set FillStyle, otherwise X will use current stipple! 
1040     XGCValues gcV
, gcBackingV
; 
1042     XGetGCValues ((Display
*) m_display
, (GC
)m_gc
, GCFillStyle
, &gcV
); 
1043     XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
); 
1044     if (m_window 
&& m_window
->GetBackingPixmap()) 
1046         XGetGCValues ((Display
*) m_display
, (GC
)m_gcBacking
, GCFillStyle
, 
1048         XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
, FillSolid
); 
1052         wxGetTextExtent (m_display
, m_font
, m_userScaleY 
* m_logicalScaleY
, 
1053                          text
, &cx
, &cy
, &ascent
, NULL
); 
1055     // First draw a rectangle representing the text background, if a text 
1056     // background is specified 
1057     if (m_textBackgroundColour
.IsOk () && (m_backgroundMode 
!= wxTRANSPARENT
)) 
1059         wxColour oldPenColour 
= m_currentColour
; 
1060         m_currentColour 
= m_textBackgroundColour
; 
1061         bool sameColour 
= (oldPenColour
.IsOk () && m_textBackgroundColour
.IsOk () && 
1062             (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) && 
1063             (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) && 
1064             (oldPenColour
.Green () == m_textBackgroundColour
.Green ())); 
1066         // This separation of the big && test required for gcc2.7/HP UX 9.02 
1067         // or pixel value can be corrupted! 
1068         sameColour 
= (sameColour 
&& 
1069             (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel())); 
1071         if (!sameColour 
|| !GET_OPTIMIZATION
) 
1073             WXPixel pixel 
= m_textBackgroundColour
.AllocColour(m_display
); 
1074             m_currentColour 
= m_textBackgroundColour
; 
1076             // Set the GC to the required colour 
1079                 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
); 
1080                 if (m_window 
&& m_window
->GetBackingPixmap()) 
1081                     XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
); 
1085             m_textBackgroundColour 
= oldPenColour 
; 
1087         XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
); 
1088         if (m_window 
&& m_window
->GetBackingPixmap()) 
1089             XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
1090             XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
); 
1093     // Now set the text foreground and draw the text 
1094     if (m_textForegroundColour
.IsOk ()) 
1096         wxColour oldPenColour 
= m_currentColour
; 
1097         m_currentColour 
= m_textForegroundColour
; 
1098         bool sameColour 
= (oldPenColour
.IsOk () && m_currentColour
.IsOk () && 
1099             (oldPenColour
.Red () == m_currentColour
.Red ()) && 
1100             (oldPenColour
.Blue () == m_currentColour
.Blue ()) && 
1101             (oldPenColour
.Green () == m_currentColour
.Green ()) && 
1102             (oldPenColour
.GetPixel() == m_currentColour
.GetPixel())); 
1104         if (!sameColour 
|| !GET_OPTIMIZATION
) 
1106             WXPixel pixel 
= CalculatePixel(m_textForegroundColour
, 
1107                                            m_currentColour
, false); 
1109             // Set the GC to the required colour 
1112                 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
); 
1113                 if (m_window 
&& m_window
->GetBackingPixmap()) 
1114                     XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
); 
1118             m_textForegroundColour 
= oldPenColour
; 
1121     // We need to add the ascent, not the whole height, since X draws at the 
1122     // point above the descender. 
1125         XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
, 
1126         (XChar2b 
*)(char*) (const char*) text
, slen
); 
1129 #if wxMOTIF_NEW_FONT_HANDLING 
1130         XFontSet fset 
= (XFontSet
) m_font
.GetFontSet (m_userScaleY 
* m_logicalScaleY
, m_display
); 
1131         XmbDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, fset
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
, text
, slen
); 
1133         XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
, text
, slen
); 
1136     if (m_window 
&& m_window
->GetBackingPixmap()) { 
1139             XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
, 
1140             XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
, 
1141             (XChar2b 
*)(char*) (const char*) text
, slen
); 
1144 #if wxMOTIF_NEW_FONT_HANDLING 
1145             XmbDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), fset
, (GC
) m_gcBacking
, 
1146             XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
, 
1147                         text
.mb_str(), slen
); 
1149             XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
, 
1150             XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
, 
1151                         text
.mb_str(), slen
); 
1155     // restore fill style 
1156     XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, gcV
.fill_style
); 
1157     if (m_window 
&& m_window
->GetBackingPixmap()) 
1158         XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
, 
1159                        gcBackingV
.fill_style
); 
1162     DoGetTextExtent (text
, &w
, &h
); 
1163     CalcBoundingBox (x 
+ w
, y 
+ h
); 
1164     CalcBoundingBox (x
, y
); 
1167 void wxWindowDCImpl::DoDrawRotatedText( const wxString 
&text
, wxCoord x
, wxCoord y
, 
1172         DoDrawText(text
, x
, y
); 
1176     wxCHECK_RET( IsOk(), "invalid dc" ); 
1178     WXPixel oldBackgroundPixel 
= -1; 
1179     WXPixel oldForegroundPixel 
= -1; 
1180     WXPixel foregroundPixel 
= -1; 
1181     WXPixel backgroundPixel 
= -1; 
1183     if (m_textBackgroundColour
.IsOk()) 
1185         oldBackgroundPixel 
= m_backgroundPixel
; 
1186         backgroundPixel 
= m_textBackgroundColour
.AllocColour(m_display
); 
1188     if (m_textForegroundColour
.IsOk()) 
1190         oldForegroundPixel 
= m_currentColour
.GetPixel(); 
1192         if( m_textForegroundColour
.GetPixel() <= -1 ) 
1193             CalculatePixel( m_textForegroundColour
, 
1194                             m_textForegroundColour
, true); 
1196         foregroundPixel 
= m_textForegroundColour
.GetPixel(); 
1199     // Since X draws from the baseline of the text, must add the text height 
1205         wxGetTextExtent (m_display
, m_font
, m_userScaleY 
* m_logicalScaleY
, 
1206                          text
, &cx
, &cy
, &ascent
, NULL
); 
1208     wxBitmap 
src(cx
, cy
); 
1210     dc
.SelectObject(src
); 
1211     dc
.SetFont(GetFont()); 
1212     dc
.SetBackground(*wxWHITE_BRUSH
); 
1213     dc
.SetBrush(*wxBLACK_BRUSH
); 
1215     dc
.DrawText(text
, 0, 0); 
1216     dc
.SetFont(wxNullFont
); 
1218     // Calculate the size of the rotated bounding box. 
1219     double dx 
= cos(angle 
/ 180.0 * M_PI
); 
1220     double dy 
= sin(angle 
/ 180.0 * M_PI
); 
1221     double x4 
= cy 
* dy
; 
1222     double y4 
= cy 
* dx
; 
1223     double x3 
= cx 
* dx
; 
1224     double y3 
= -cx 
* dy
; 
1225     double x2 
= x3 
+ x4
; 
1226     double y2 
= y3 
+ y4
; 
1230     // Create image from the source bitmap after writing the text into it. 
1231     wxImage  image 
= src
.ConvertToImage(); 
1233     int minx 
= roundmin(0, roundmin(x4
, roundmin(x2
, x3
))); 
1234     int miny 
= roundmin(0, roundmin(y4
, roundmin(y2
, y3
))); 
1235     int maxx 
= roundmax(0, roundmax(x4
, roundmax(x2
, x3
))); 
1236     int maxy 
= roundmax(0, roundmax(y4
, roundmax(y2
, y3
))); 
1238     bool lastFore 
= false, lastBack 
= false; 
1240     // This rotates counterclockwise around the top left corner. 
1241     for (int rx 
= minx
; rx 
< maxx
; rx
++) 
1243         for (int ry 
= miny
; ry 
< maxy
; ry
++) 
1245             // transform dest coords to source coords 
1246             int sx 
= (int) (rx 
* dx 
- ry 
* dy 
+ 0.5); 
1247             int sy 
= - (int) (-ry 
* dx 
- rx 
* dy 
+ 0.5); 
1248             if (sx 
>= 0 && sx 
< cx 
&& sy 
>= 0 && sy 
< cy
) 
1250                 bool textPixel 
= image
.GetRed(sx
, sy
) == 0; 
1252                 if (!textPixel 
&& m_backgroundMode 
!= wxSOLID
) 
1255                 wxCoord ox 
= (wxCoord
) (x1 
+ rx
), 
1256                         oy 
= (wxCoord
) (y1 
+ ry
); 
1257                 // draw black pixels, ignore white ones (i.e. transparent b/g) 
1258                 if (textPixel 
&& !lastFore
) 
1260                     XSetForeground ((Display
*) m_display
, (GC
) m_gc
, 
1265                 else if (!textPixel 
&& !lastBack
) 
1267                     XSetForeground ((Display
*) m_display
, (GC
) m_gc
, 
1273                 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
, 
1274                             (GC
) m_gc
, XLOG2DEV (ox
), YLOG2DEV (oy
)); 
1275                 if (m_window 
&& m_window
->GetBackingPixmap()) 
1276                     XDrawPoint ((Display
*) m_display
, 
1277                                 (Pixmap
) m_window
->GetBackingPixmap(), 
1279                                 XLOG2DEV_2 (ox
), YLOG2DEV_2 (oy
)); 
1284     if (oldBackgroundPixel 
> -1) 
1286         XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
); 
1287         if (m_window 
&& m_window
->GetBackingPixmap()) 
1288             XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
, 
1289                             oldBackgroundPixel
); 
1291     if (oldForegroundPixel 
> -1) 
1293         XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
); 
1294         if (m_window 
&& m_window
->GetBackingPixmap()) 
1295             XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, 
1296                             oldForegroundPixel
); 
1299     CalcBoundingBox (minx
, miny
); 
1300     CalcBoundingBox (maxx
, maxy
); 
1303 bool wxWindowDCImpl::CanGetTextExtent() const 
1308 void wxWindowDCImpl::DoGetTextExtent( const wxString 
&string
, wxCoord 
*width
, wxCoord 
*height
, 
1309                                 wxCoord 
*descent
, wxCoord 
*externalLeading
, 
1310                                 const wxFont 
*font 
) const 
1312     wxCHECK_RET( IsOk(), "invalid dc" ); 
1314     const wxFont
* theFont 
= font 
? font 
: &m_font
; 
1316     if (!theFont
->IsOk()) 
1318         // TODO: this should be an error log function 
1319         wxFAIL_MSG("set a valid font before calling GetTextExtent!"); 
1321         if (width
) *width 
= -1; 
1322         if (height
) *height 
= -1; 
1326     wxGetTextExtent(m_display
, *theFont
, m_userScaleY 
* m_logicalScaleY
, 
1327                     string
, width
, height
, NULL
, descent
); 
1329     if (width
) *width 
= XDEV2LOGREL (*width
); 
1330     if (height
) *height 
= YDEV2LOGREL (*height
); 
1331     if (externalLeading
) 
1332         *externalLeading 
= 0; 
1335 wxCoord 
wxWindowDCImpl::GetCharWidth() const 
1337     wxCHECK_MSG( IsOk(), 0, "invalid dc" ); 
1338     wxCHECK_MSG( m_font
.IsOk(), 0, "invalid font" ); 
1342     wxGetTextExtent (m_display
, m_font
, m_userScaleY 
* m_logicalScaleY
, 
1343                      "x", &width
, NULL
, NULL
, NULL
); 
1345     return XDEV2LOGREL(width
); 
1348 wxCoord 
wxWindowDCImpl::GetCharHeight() const 
1350     wxCHECK_MSG( IsOk(), 0, "invalid dc" ); 
1351     wxCHECK_MSG( m_font
.IsOk(), 0, "invalid font" ); 
1355     wxGetTextExtent (m_display
, m_font
, m_userScaleY 
* m_logicalScaleY
, 
1356                      "x", NULL
, &height
, NULL
, NULL
); 
1358     return XDEV2LOGREL(height
); 
1361 void wxWindowDCImpl::DoGetSize( int *width
, int *height 
) const 
1367         if( m_window
->GetBackingPixmap() ) 
1369             w 
= m_window
->GetPixmapWidth(); 
1370             h 
= m_window
->GetPixmapHeight(); 
1373             m_window
->GetSize( &w
, &h 
); 
1376     if( width 
) *width 
= w
; 
1377     if( height 
) *height 
= h
; 
1380 void wxWindowDCImpl::Clear() 
1382     wxCHECK_RET( IsOk(), "invalid dc" ); 
1384     wxRect 
rect( GetSize() ); 
1388 void wxWindowDCImpl::Clear(const wxRect
& rect
) 
1390     wxCHECK_RET( IsOk(), "invalid dc" ); 
1392     int x 
= rect
.x
; int y 
= rect
.y
; 
1393     int w 
= rect
.width
; int h 
= rect
.height
; 
1395     wxBrush saveBrush 
= m_brush
; 
1396     SetBrush (m_backgroundBrush
); 
1398     XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 
1401     if (m_window 
&& m_window
->GetBackingPixmap()) 
1402         XFillRectangle ((Display
*) m_display
, 
1403                         (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 
1406     m_brush 
= saveBrush
; 
1409 void wxWindowDCImpl::SetFont( const wxFont 
&font 
) 
1411     wxCHECK_RET( IsOk(), "invalid dc" ); 
1420 #if !wxMOTIF_NEW_FONT_HANDLING 
1421     WXFontStructPtr pFontStruct 
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
); 
1423     Font fontId 
= ((XFontStruct
*)pFontStruct
)->fid
; 
1424     XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
); 
1426     if (m_window 
&& m_window
->GetBackingPixmap()) 
1427         XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
); 
1431 void wxWindowDCImpl::SetForegroundPixelWithLogicalFunction(WXPixel pixel
) 
1433     if (m_logicalFunction 
== wxXOR
) 
1436         XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
); 
1437         XSetForeground ((Display
*) m_display
, (GC
) m_gc
, 
1438                         pixel 
^ values
.background
); 
1439         if (m_window 
&& m_window
->GetBackingPixmap()) 
1440             XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, 
1441                             pixel 
^ values
.background
); 
1445         XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
); 
1446         if (m_window 
&& m_window
->GetBackingPixmap()) 
1447             XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
); 
1451 WXPixel 
wxWindowDCImpl::CalculatePixel(wxColour
& colour
, wxColour
& curCol
, 
1452                                bool roundToWhite
) const 
1454     const unsigned char wp 
= (unsigned char)255; 
1457     if(!m_colour
) // Mono display 
1459         unsigned char red 
= colour
.Red (); 
1460         unsigned char blue 
= colour
.Blue (); 
1461         unsigned char green 
= colour
.Green (); 
1463         if((red 
== wp 
&& blue 
== wp 
&& green 
== wp
) || 
1464            // not black and roundToWhite was specified 
1465            ((red 
!= 0 || blue 
!= 0 || green 
!= 0) && roundToWhite
)) 
1468             pixel 
= WhitePixel((Display
*) m_display
, 
1469                                DefaultScreen((Display
*) m_display
)); 
1470             curCol
.SetPixel(pixel
); 
1471             colour
.SetPixel(pixel
); 
1476             pixel 
= BlackPixel((Display
*) m_display
, 
1477                                DefaultScreen((Display
*) m_display
)); 
1478             curCol
.SetPixel(pixel
); 
1479             colour
.SetPixel(pixel
); 
1485         pixel 
= colour
.AllocColour((Display
*) m_display
); 
1486         curCol
.SetPixel(pixel
); 
1492 void wxWindowDCImpl::SetPen( const wxPen 
&pen 
) 
1494     wxCHECK_RET( IsOk(), "invalid dc" ); 
1500     wxBitmap oldStipple 
= m_currentStipple
; 
1501     int oldStyle 
= m_currentStyle
; 
1502     int oldFill 
= m_currentFill
; 
1503     int old_pen_width 
= m_currentPenWidth
; 
1504     int old_pen_join 
= m_currentPenJoin
; 
1505     int old_pen_cap 
= m_currentPenCap
; 
1506     int old_pen_nb_dash 
= m_currentPenDashCount
; 
1507     wxX11Dash 
*old_pen_dash 
= m_currentPenDash
; 
1509     wxColour oldPenColour 
= m_currentColour
; 
1510     m_currentColour 
= m_pen
.GetColour (); 
1511     m_currentStyle 
= m_pen
.GetStyle (); 
1512     m_currentFill 
= m_pen
.GetStyle (); // TODO? 
1513     m_currentPenWidth 
= m_pen
.GetWidth (); 
1514     m_currentPenJoin 
= m_pen
.GetJoin (); 
1515     m_currentPenCap 
= m_pen
.GetCap (); 
1516     m_currentPenDashCount 
= m_pen
.GetDashCount(); 
1517     m_currentPenDash 
= (wxX11Dash
*)m_pen
.GetDash(); 
1519     if (m_currentStyle 
== wxSTIPPLE
) 
1520         m_currentStipple 
= * m_pen
.GetStipple (); 
1522     bool sameStyle 
= (oldStyle 
== m_currentStyle 
&& 
1523         oldFill 
== m_currentFill 
&& 
1524         old_pen_join 
== m_currentPenJoin 
&& 
1525         old_pen_cap 
== m_currentPenCap 
&& 
1526         old_pen_nb_dash 
== m_currentPenDashCount 
&& 
1527         old_pen_dash 
== m_currentPenDash 
&& 
1528         old_pen_width 
== m_currentPenWidth
); 
1530     bool sameColour 
= (oldPenColour
.IsOk () && 
1531         (oldPenColour
.Red () == m_currentColour
.Red ()) && 
1532         (oldPenColour
.Blue () == m_currentColour
.Blue ()) && 
1533         (oldPenColour
.Green () == m_currentColour
.Green ()) && 
1534         (oldPenColour
.GetPixel() == m_currentColour
.GetPixel())); 
1536     if (!sameStyle 
|| !GET_OPTIMIZATION
) 
1538         int scaled_width 
= (int) XLOG2DEVREL (m_pen
.GetWidth ()); 
1539         if (scaled_width 
< 0) 
1545         static const wxX11Dash dotted
[] = {2, 5}; 
1546         static const wxX11Dash short_dashed
[] = {4, 4}; 
1547         static const wxX11Dash long_dashed
[] = {4, 8}; 
1548         static const wxX11Dash dotted_dashed
[] = {6, 6, 2, 6}; 
1550         // We express dash pattern in pen width unit, so we are 
1551         // independent of zoom factor and so on... 
1553         const wxX11Dash 
*req_dash
; 
1555         switch (m_pen
.GetStyle ()) 
1558             req_nb_dash 
= m_currentPenDashCount
; 
1559             req_dash 
= m_currentPenDash
; 
1560             style 
= LineOnOffDash
; 
1565             style 
= LineOnOffDash
; 
1569             req_dash 
= short_dashed
; 
1570             style 
= LineOnOffDash
; 
1574             req_dash 
= long_dashed
; 
1575             style 
= LineOnOffDash
; 
1579             req_dash 
= dotted_dashed
; 
1580             style 
= LineOnOffDash
; 
1587             req_dash 
= (wxX11Dash
*)NULL
; 
1591         if (req_dash 
&& req_nb_dash
) 
1593             wxX11Dash 
*real_req_dash 
= new wxX11Dash
[req_nb_dash
]; 
1596                 int factor 
= scaled_width 
== 0 ? 1 : scaled_width
; 
1597                 for (int i 
= 0; i 
< req_nb_dash
; i
++) 
1598                     real_req_dash
[i
] = (wxX11Dash
)(req_dash
[i
] * factor
); 
1599                 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
); 
1601                 if (m_window 
&& m_window
->GetBackingPixmap()) 
1602                     XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
); 
1603                 delete[]real_req_dash
; 
1607                 // No Memory. We use non-scaled dash pattern... 
1608                 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
); 
1610                 if (m_window 
&& m_window
->GetBackingPixmap()) 
1611                     XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
); 
1615         switch (m_pen
.GetCap ()) 
1617         case wxCAP_PROJECTING
: 
1618             cap 
= CapProjecting
; 
1625             cap 
= (scaled_width 
<= 1) ? CapNotLast 
: CapRound
; 
1629         switch (m_pen
.GetJoin ()) 
1643         XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
); 
1645         if (m_window 
&& m_window
->GetBackingPixmap()) 
1646             XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
); 
1649     if (IS_HATCH(m_currentFill
) && ((m_currentFill 
!= oldFill
) || !GET_OPTIMIZATION
)) 
1653         oldStipple 
= wxNullBitmap
;    // For later reset!! 
1655         switch (m_currentFill
) 
1657         case wxBDIAGONAL_HATCH
: 
1658             if (bdiag 
== (Pixmap
) 0) 
1659                 bdiag 
= XCreateBitmapFromData ((Display
*) m_display
, 
1660                 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)), 
1661                 bdiag_bits
, bdiag_width
, bdiag_height
); 
1664         case wxFDIAGONAL_HATCH
: 
1665             if (fdiag 
== (Pixmap
) 0) 
1666                 fdiag 
= XCreateBitmapFromData ((Display
*) m_display
, 
1667                 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)), 
1668                 fdiag_bits
, fdiag_width
, fdiag_height
); 
1672             if (cross 
== (Pixmap
) 0) 
1673                 cross 
= XCreateBitmapFromData ((Display
*) m_display
, 
1674                 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)), 
1675                 cross_bits
, cross_width
, cross_height
); 
1678         case wxHORIZONTAL_HATCH
: 
1679             if (horiz 
== (Pixmap
) 0) 
1680                 horiz 
= XCreateBitmapFromData ((Display
*) m_display
, 
1681                 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)), 
1682                 horiz_bits
, horiz_width
, horiz_height
); 
1685         case wxVERTICAL_HATCH
: 
1686             if (verti 
== (Pixmap
) 0) 
1687                 verti 
= XCreateBitmapFromData ((Display
*) m_display
, 
1688                 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)), 
1689                 verti_bits
, verti_width
, verti_height
); 
1692         case wxCROSSDIAG_HATCH
: 
1694             if (cdiag 
== (Pixmap
) 0) 
1695                 cdiag 
= XCreateBitmapFromData ((Display
*) m_display
, 
1696                 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)), 
1697                 cdiag_bits
, cdiag_width
, cdiag_height
); 
1701         XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
); 
1703         if (m_window 
&& m_window
->GetBackingPixmap()) 
1704             XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
); 
1706     else if (m_currentStyle 
== wxSTIPPLE 
&& m_currentStipple
.IsOk() 
1707         && ((!m_currentStipple
.IsSameAs(oldStipple
)) || !GET_OPTIMIZATION
)) 
1709         XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetDrawable()); 
1711         if (m_window 
&& m_window
->GetBackingPixmap()) 
1712             XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetDrawable()); 
1715     if ((m_currentFill 
!= oldFill
) || !GET_OPTIMIZATION
) 
1719         if (m_currentFill 
== wxSTIPPLE
) 
1720             fill_style 
= FillStippled
; 
1721         else if (IS_HATCH (m_currentFill
)) 
1722             fill_style 
= FillStippled
; 
1724             fill_style 
= FillSolid
; 
1725         XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
); 
1726         if (m_window 
&& m_window
->GetBackingPixmap()) 
1727             XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
); 
1730     // must test m_logicalFunction, because it involves background! 
1731     if (!sameColour 
|| !GET_OPTIMIZATION
 
1732         || ((m_logicalFunction 
== wxXOR
) || (m_autoSetting 
& 0x2))) 
1735         if (m_pen
.GetStyle () == wxTRANSPARENT
) 
1736             pixel 
= m_backgroundPixel
; 
1739             pixel 
= CalculatePixel(m_pen
.GetColour(), m_currentColour
, false); 
1742         // Finally, set the GC to the required colour 
1744             SetForegroundPixelWithLogicalFunction(pixel
); 
1747         m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel()); 
1752 void wxWindowDCImpl::SetBrush( const wxBrush 
&brush 
) 
1754     wxCHECK_RET( IsOk(), "invalid dc" ); 
1758     if (!m_brush
.IsOk() || m_brush
.GetStyle () == wxTRANSPARENT
) 
1761     int oldFill 
= m_currentFill
; 
1762     wxBitmap oldStipple 
= m_currentStipple
; 
1764     m_autoSetting 
|= 0x1; 
1766     m_currentFill 
= m_brush
.GetStyle (); 
1767     if (m_currentFill 
== wxSTIPPLE
) 
1768         m_currentStipple 
= * m_brush
.GetStipple (); 
1770     wxColour 
oldBrushColour(m_currentColour
); 
1771     m_currentColour 
= m_brush
.GetColour (); 
1773     bool sameColour 
= (oldBrushColour
.IsOk () && 
1774         (oldBrushColour
.Red () == m_currentColour
.Red ()) && 
1775         (oldBrushColour
.Blue () == m_currentColour
.Blue ()) && 
1776         (oldBrushColour
.Green () == m_currentColour
.Green ()) && 
1777         (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel())); 
1779     int stippleDepth 
= -1; 
1781     if ((oldFill 
!= m_brush
.GetStyle ()) || !GET_OPTIMIZATION
) 
1783         switch (brush
.GetStyle ()) 
1788             stippleDepth 
= m_currentStipple
.GetDepth(); 
1790         case wxBDIAGONAL_HATCH
: 
1791         case wxCROSSDIAG_HATCH
: 
1792         case wxFDIAGONAL_HATCH
: 
1794         case wxHORIZONTAL_HATCH
: 
1795         case wxVERTICAL_HATCH
: 
1797                 if (stippleDepth 
== -1) stippleDepth 
= 1; 
1799                 // Chris Breeze 23/07/97: use background mode to 
1800                 // determine whether fill style should be solid or 
1802                 int style 
= stippleDepth 
== 1 ? 
1803                     (m_backgroundMode 
== wxSOLID 
? 
1804                      FillOpaqueStippled 
: FillStippled
) : 
1806                 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
); 
1807                 if (m_window 
&& m_window
->GetBackingPixmap()) 
1808                     XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
); 
1813             XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
); 
1814             if (m_window 
&& m_window
->GetBackingPixmap()) 
1815                 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, 
1820     if (IS_HATCH(m_currentFill
) && ((m_currentFill 
!= oldFill
) || !GET_OPTIMIZATION
)) 
1824         switch (m_currentFill
) 
1826         case wxBDIAGONAL_HATCH
: 
1827             if (bdiag 
== (Pixmap
) 0) 
1828                 bdiag 
= XCreateBitmapFromData ((Display
*) m_display
, 
1829                 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)), 
1830                 bdiag_bits
, bdiag_width
, bdiag_height
); 
1833         case wxFDIAGONAL_HATCH
: 
1834             if (fdiag 
== (Pixmap
) 0) 
1835                 fdiag 
= XCreateBitmapFromData ((Display
*) m_display
, 
1836                 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)), 
1837                 fdiag_bits
, fdiag_width
, fdiag_height
); 
1841             if (cross 
== (Pixmap
) 0) 
1842                 cross 
= XCreateBitmapFromData ((Display
*) m_display
, 
1843                 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)), 
1844                 cross_bits
, cross_width
, cross_height
); 
1847         case wxHORIZONTAL_HATCH
: 
1848             if (horiz 
== (Pixmap
) 0) 
1849                 horiz 
= XCreateBitmapFromData ((Display
*) m_display
, 
1850                 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)), 
1851                 horiz_bits
, horiz_width
, horiz_height
); 
1854         case wxVERTICAL_HATCH
: 
1855             if (verti 
== (Pixmap
) 0) 
1856                 verti 
= XCreateBitmapFromData ((Display
*) m_display
, 
1857                 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)), 
1858                 verti_bits
, verti_width
, verti_height
); 
1861         case wxCROSSDIAG_HATCH
: 
1863             if (cdiag 
== (Pixmap
) 0) 
1864                 cdiag 
= XCreateBitmapFromData ((Display
*) m_display
, 
1865                 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)), 
1866                 cdiag_bits
, cdiag_width
, cdiag_height
); 
1870         XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
); 
1872         if (m_window 
&& m_window
->GetBackingPixmap()) 
1873             XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
); 
1875     // X can forget the stipple value when resizing a window (apparently) 
1876     // so always set the stipple. 
1877     else if (m_currentFill 
!= wxSOLID 
&& m_currentFill 
!= wxTRANSPARENT 
&& 
1878              m_currentStipple
.IsOk()) // && m_currentStipple != oldStipple) 
1880         if (m_currentStipple
.GetDepth() == 1) 
1882             XSetStipple ((Display
*) m_display
, (GC
) m_gc
, 
1883                          (Pixmap
) m_currentStipple
.GetDrawable()); 
1884         if (m_window 
&& m_window
->GetBackingPixmap()) 
1885                 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, 
1886                              (Pixmap
) m_currentStipple
.GetDrawable()); 
1890             XSetTile ((Display
*) m_display
, (GC
) m_gc
, 
1891                       (Pixmap
) m_currentStipple
.GetDrawable()); 
1892             if (m_window 
&& m_window
->GetBackingPixmap()) 
1893                 XSetTile ((Display
*) m_display
,(GC
) m_gcBacking
, 
1894                           (Pixmap
) m_currentStipple
.GetDrawable()); 
1898     // must test m_logicalFunction, because it involves background! 
1899     if (!sameColour 
|| !GET_OPTIMIZATION 
|| m_logicalFunction 
== wxXOR
) 
1901         WXPixel pixel 
= CalculatePixel(m_brush
.GetColour(), m_currentColour
, true); 
1904             SetForegroundPixelWithLogicalFunction(pixel
); 
1907         m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel()); 
1910 void wxWindowDCImpl::SetBackground( const wxBrush 
&brush 
) 
1912     wxCHECK_RET( IsOk(), "invalid dc" ); 
1914     m_backgroundBrush 
= brush
; 
1916     if (!m_backgroundBrush
.IsOk()) 
1919     m_backgroundPixel 
= m_backgroundBrush
.GetColour().AllocColour(m_display
); 
1921     // Necessary for ::DrawIcon, which use fg/bg pixel or the GC. 
1922     // And Blit,... (Any fct that use XCopyPlane, in fact.) 
1923     XSetBackground ((Display
*) m_display
, (GC
) m_gc
, m_backgroundPixel
); 
1924     if (m_window 
&& m_window
->GetBackingPixmap()) 
1925         XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
, 
1929 void wxWindowDCImpl::SetLogicalFunction( int function 
) 
1931     wxCHECK_RET( IsOk(), "invalid dc" ); 
1936     if (m_logicalFunction 
== function
) 
1942         x_function 
= GXclear
; 
1948         x_function 
= GXinvert
; 
1951         x_function 
= GXorReverse
; 
1954         x_function 
= GXandReverse
; 
1963         x_function 
= GXandInverted
; 
1966         x_function 
= GXnoop
; 
1972         x_function 
= GXequiv
; 
1975         x_function 
= GXcopyInverted
; 
1978         x_function 
= GXorInverted
; 
1981         x_function 
= GXnand
; 
1988         x_function 
= GXcopy
; 
1992     XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
); 
1993     if (m_window 
&& m_window
->GetBackingPixmap()) 
1994         XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
); 
1996     if ((m_logicalFunction 
== wxXOR
) != (function 
== wxXOR
)) 
1997         /* MATTHEW: [9] Need to redo pen simply */ 
1998         m_autoSetting 
|= 0x2; 
2000     m_logicalFunction 
= function
; 
2004 void wxWindowDCImpl::SetTextForeground( const wxColour 
&col 
) 
2006     wxCHECK_RET( IsOk(), "invalid dc" ); 
2008     m_textForegroundColour 
= col
; 
2011 void wxWindowDCImpl::SetTextBackground( const wxColour 
&col 
) 
2013     wxCHECK_RET( IsOk(), "invalid dc" ); 
2015     m_textBackgroundColour 
= col
; 
2018 void wxWindowDCImpl::SetBackgroundMode( int mode 
) 
2020     m_backgroundMode 
= mode
; 
2023 void wxWindowDCImpl::SetPalette( const wxPalette
& palette 
) 
2028             /* Use GetXColormap */ 
2029             XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(), 
2030             (Colormap
) palette
.GetXColormap()); 
2032             /* Use wxGetMainColormap */ 
2033             XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(), 
2034             (Colormap
) wxTheApp
->GetMainColormap(m_display
)); 
2038 static void wxCopyRegion( WXRegion src
, WXRegion
& dst 
) 
2041         dst 
= XCreateRegion(); 
2042     XUnionRegion( (Region
)src
, (Region
)src
, (Region
)dst 
); 
2045 // Helper function; userRegion is the region set by calling SetClippingRegion 
2046 void wxWindowDCImpl::SetDCClipping( WXRegion userRegion 
) 
2048     bool hasUpdateRegion 
= m_window 
&& m_window
->GetUpdateRegion().IsOk(); 
2049     // this means that we should start the clip region from scratch, 
2050     // or from the update region, if any 
2054             XDestroyRegion( (Region
)m_clipRegion 
); 
2055         m_clipRegion 
= (WXRegion
)NULL
; 
2057         if( hasUpdateRegion 
) 
2058             wxCopyRegion( m_window
->GetUpdateRegion().GetX11Region(), 
2061     // intersect the user region, if any, with the 
2062     // exisiting clip region 
2063     else // if( userRegion ) 
2066             wxCopyRegion( userRegion
, m_clipRegion 
); 
2068             XIntersectRegion( (Region
)m_clipRegion
, 
2069                               (Region
)userRegion
, (Region
)m_clipRegion 
); 
2073         XSetRegion( (Display
*)m_display
, (GC
)m_gc
, (Region
)m_clipRegion 
); 
2075         XSetClipMask( (Display
*)m_display
, (GC
)m_gc
, None 
); 
2078 void wxWindowDCImpl::DoSetClippingRegion( wxCoord x
, wxCoord y
, 
2079                                       wxCoord width
, wxCoord height 
) 
2081     wxMotifDCImpl::DoSetClippingRegion( x
, y
, width
, height 
); 
2083     wxRegion 
temp(XLOG2DEV(x
), YLOG2DEV(y
), 
2084                   XLOG2DEVREL(width
), YLOG2DEVREL(height
)); 
2086     SetDCClipping(temp
.GetX11Region()); 
2088     // Needs to work differently for Pixmap: without this, 
2089     // there's a nasty (Display*) m_display bug. 8/12/94 
2090     if (m_window 
&& m_window
->GetBackingPixmap()) 
2092         XRectangle rects
[1]; 
2093         rects
[0].x 
= (short)XLOG2DEV_2(x
); 
2094         rects
[0].y 
= (short)YLOG2DEV_2(y
); 
2095         rects
[0].width 
= (unsigned short)XLOG2DEVREL(width
); 
2096         rects
[0].height 
= (unsigned short)YLOG2DEVREL(height
); 
2097         XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 
2098                            0, 0, rects
, 1, Unsorted
); 
2102 void wxWindowDCImpl::DoSetClippingRegionAsRegion( const wxRegion
& region 
) 
2104     SetDCClipping(region
.GetX11Region()); 
2106     // Needs to work differently for Pixmap: without this, 
2107     // there's a nasty (Display*) m_display bug. 8/12/94 
2108     if (m_window 
&& m_window
->GetBackingPixmap()) 
2110         wxRect box 
= region
.GetBox(); 
2112         XRectangle rects
[1]; 
2113         rects
[0].x 
= (short)XLOG2DEV_2(box
.x
); 
2114         rects
[0].y 
= (short)YLOG2DEV_2(box
.y
); 
2115         rects
[0].width 
= (unsigned short)XLOG2DEVREL(box
.width
); 
2116         rects
[0].height 
= (unsigned short)YLOG2DEVREL(box
.height
); 
2117         XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 
2118                            0, 0, rects
, 1, Unsorted
); 
2123 void wxWindowDCImpl::DestroyClippingRegion() 
2125     wxMotifDCImpl::DestroyClippingRegion(); 
2127     SetDCClipping(NULL
); 
2129     if (m_window 
&& m_window
->GetBackingPixmap()) 
2130         XSetClipMask ((Display
*) m_display
, (GC
) m_gcBacking
, None
); 
2133 // Resolution in pixels per logical inch 
2134 wxSize 
wxWindowDCImpl::GetPPI() const 
2137     return wxSize(100, 100); 
2140 int wxWindowDCImpl::GetDepth() const 
2149 // ---------------------------------------------------------------------------- 
2151 // ---------------------------------------------------------------------------- 
2153 wxPaintDCImpl::wxPaintDCImpl(wxDC 
*owner
, wxWindow
* win
) 
2154              : wxWindowDCImpl(owner
, win
) 
2156     // Set the clipping region.to the update region 
2157     SetDCClipping((WXRegion
)NULL
); 
2160 wxPaintDCImpl::~wxPaintDCImpl() 
2163         m_window
->ClearUpdateRegion(); 
2164     SetDCClipping((WXRegion
)NULL
); 
2167 // ---------------------------------------------------------------------------- 
2168 // private functions 
2169 // ---------------------------------------------------------------------------- 
2172    Used when copying between drawables on different (Display*) m_displays. Not 
2173    very fast, but better than giving up. 
2176 static void XCopyRemote(Display 
*src_display
, Display 
*dest_display
, 
2177                         Drawable src
, Drawable dest
, 
2180                         unsigned int w
, unsigned int h
, 
2181                         int destx
, int desty
, 
2182                         bool more
, XImage 
**cache
) 
2184     XImage 
*image
, *destimage
; 
2185     Colormap destcm
, srccm
; 
2186     static const int CACHE_SIZE 
= 256; 
2189     Pixel cachesrc
[CACHE_SIZE
], cachedest
[CACHE_SIZE
]; 
2190     int k
, cache_pos
, all_cache
; 
2192     if (!cache 
|| !*cache
) 
2193         image 
= XGetImage(src_display
, src
, srcx
, srcy
, w
, h
, AllPlanes
, ZPixmap
); 
2197     destimage 
= XGetImage(dest_display
, dest
, destx
, desty
, w
, h
, AllPlanes
, ZPixmap
); 
2199     srccm 
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) src_display
); 
2200     destcm 
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dest_display
); 
2205     for (i 
= 0; i 
< w
; i
++) 
2206         for (j 
= 0; j 
< h
; j
++) { 
2210             pixel 
= XGetPixel(image
, i
, j
); 
2211             for (k 
= cache_pos
; k
--; ) 
2212                 if (cachesrc
[k
] == pixel
) { 
2213                     pixel 
= cachedest
[k
]; 
2217                     for (k 
= CACHE_SIZE
; k
-- > cache_pos
; ) 
2218                         if (cachesrc
[k
] == pixel
) { 
2219                             pixel 
= cachedest
[k
]; 
2223                         cachesrc
[cache_pos
] = xcol
.pixel 
= pixel
; 
2224                         XQueryColor(src_display
, srccm
, &xcol
); 
2225                         if (!XAllocColor(dest_display
, destcm
, &xcol
)) 
2227                         cachedest
[cache_pos
] = pixel 
= xcol
.pixel
; 
2229                         if (++cache_pos 
>= CACHE_SIZE
) { 
2235                         XPutPixel(destimage
, i
, j
, pixel
); 
2238         XPutImage(dest_display
, dest
, destgc
, destimage
, 0, 0, destx
, desty
, w
, h
); 
2239         XDestroyImage(destimage
); 
2244             XDestroyImage(image
);