1 /////////////////////////////////////////////////////////////////////////////
2 // Name: x11/dcclient.cpp
3 // Purpose: wxClientDC class
4 // Author: Julian Smart, Robert Roebling
8 // Copyright: (c) Julian Smart, Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "dcclient.h"
16 #include "wx/dcclient.h"
17 #include "wx/dcmemory.h"
18 #include "wx/window.h"
22 #include "wx/x11/private.h"
26 //-----------------------------------------------------------------------------
28 //-----------------------------------------------------------------------------
30 #define USE_PAINT_REGION 1
32 //-----------------------------------------------------------------------------
34 //-----------------------------------------------------------------------------
44 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH)
45 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH)
47 static Pixmap hatches
[num_hatches
];
48 static Pixmap
*hatch_bitmap
= (Pixmap
*) NULL
;
50 //-----------------------------------------------------------------------------
52 //-----------------------------------------------------------------------------
54 const double RAD2DEG
= 180.0 / M_PI
;
56 // ----------------------------------------------------------------------------
58 // ----------------------------------------------------------------------------
60 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
61 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
63 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
65 //-----------------------------------------------------------------------------
66 // Implement Pool of Graphic contexts. Creating them takes too much time.
67 //-----------------------------------------------------------------------------
69 #define GC_POOL_SIZE 200
95 static wxGC wxGCPool
[GC_POOL_SIZE
];
97 static void wxInitGCPool()
99 memset( wxGCPool
, 0, GC_POOL_SIZE
*sizeof(wxGC
) );
102 static void wxCleanUpGCPool()
104 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
106 if (wxGCPool
[i
].m_gc
)
107 XFreeGC( wxGlobalDisplay(), wxGCPool
[i
].m_gc
);
111 static GC
wxGetPoolGC( Window window
, wxPoolGCType type
)
113 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
115 if (!wxGCPool
[i
].m_gc
)
117 wxGCPool
[i
].m_gc
= XCreateGC( wxGlobalDisplay(), window
, 0, NULL
);
118 XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool
[i
].m_gc
, FALSE
);
119 wxGCPool
[i
].m_type
= type
;
120 wxGCPool
[i
].m_used
= FALSE
;
122 if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type
== type
))
124 wxGCPool
[i
].m_used
= TRUE
;
125 return wxGCPool
[i
].m_gc
;
129 wxFAIL_MSG( wxT("No GC available") );
134 static void wxFreePoolGC( GC gc
)
136 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
138 if (wxGCPool
[i
].m_gc
== gc
)
140 wxGCPool
[i
].m_used
= FALSE
;
145 wxFAIL_MSG( wxT("Wrong GC") );
148 // ----------------------------------------------------------------------------
150 // ----------------------------------------------------------------------------
152 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
154 wxWindowDC::wxWindowDC()
156 m_display
= (WXDisplay
*) NULL
;
157 m_penGC
= (WXGC
*) NULL
;
158 m_brushGC
= (WXGC
*) NULL
;
159 m_textGC
= (WXGC
*) NULL
;
160 m_bgGC
= (WXGC
*) NULL
;
161 m_cmap
= (WXColormap
*) NULL
;
163 m_isScreenDC
= FALSE
;
164 m_owner
= (wxWindow
*)NULL
;
167 wxWindowDC::wxWindowDC( wxWindow
*window
)
169 wxASSERT_MSG( window
, wxT("DC needs a window") );
171 m_display
= (WXDisplay
*) NULL
;
172 m_penGC
= (WXGC
*) NULL
;
173 m_brushGC
= (WXGC
*) NULL
;
174 m_textGC
= (WXGC
*) NULL
;
175 m_bgGC
= (WXGC
*) NULL
;
176 m_cmap
= (WXColormap
*) NULL
;
177 m_owner
= (wxWindow
*)NULL
;
179 m_isScreenDC
= FALSE
;
180 m_font
= window
->GetFont();
182 m_window
= (WXWindow
*) window
->GetMainWindow();
187 // don't report problems
193 m_display
= (WXDisplay
*) wxGlobalDisplay();
195 int screen
= DefaultScreen( (Display
*) m_display
);
196 m_cmap
= (WXColormap
) DefaultColormap( (Display
*) m_display
, screen
);
200 /* this must be done after SetUpDC, bacause SetUpDC calls the
201 repective SetBrush, SetPen, SetBackground etc functions
202 to set up the DC. SetBackground call m_owner->SetBackground
203 and this might not be desired as the standard dc background
204 is white whereas a window might assume gray to be the
205 standard (as e.g. wxStatusBar) */
210 wxWindowDC::~wxWindowDC()
215 void wxWindowDC::SetUpDC()
219 wxASSERT_MSG( !m_penGC
, wxT("GCs already created") );
223 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_SCREEN
);
224 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_SCREEN
);
225 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_SCREEN
);
226 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_SCREEN
);
229 if (m_isMemDC
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1))
231 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_MONO
);
232 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_MONO
);
233 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_MONO
);
234 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_MONO
);
238 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_COLOUR
);
239 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_COLOUR
);
240 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_COLOUR
);
241 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_COLOUR
);
244 /* background colour */
245 m_backgroundBrush
= *wxWHITE_BRUSH
;
246 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
247 unsigned long bg_col
= m_backgroundBrush
.GetColour().GetPixel();
250 m_textForegroundColour
.CalcPixel( m_cmap
);
251 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
253 m_textBackgroundColour
.CalcPixel( m_cmap
);
254 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
256 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
259 // By default, draw transparently
260 GrSetGCUseBackground((GC
) m_textGC
, FALSE
);
264 m_pen
.GetColour().CalcPixel( m_cmap
);
265 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
266 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
268 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
271 m_brush
.GetColour().CalcPixel( m_cmap
);
272 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
273 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
275 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
278 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
279 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
281 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
284 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
285 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
286 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
289 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
290 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
291 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
292 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
296 int xscreen
= DefaultScreen( (Display
*) m_display
);
297 Window xroot
= RootWindow( (Display
*) m_display
, xscreen
);
299 hatch_bitmap
= hatches
;
300 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, bdiag_bits
, bdiag_width
, bdiag_height
);
301 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cdiag_bits
, cdiag_width
, cdiag_height
);
302 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, fdiag_bits
, fdiag_width
, fdiag_height
);
303 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cross_bits
, cross_width
, cross_height
);
304 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, horiz_bits
, horiz_width
, horiz_height
);
305 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, verti_bits
, verti_width
, verti_height
);
309 void wxWindowDC::DoGetSize( int* width
, int* height
) const
311 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
313 m_owner
->GetSize(width
, height
);
316 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
317 const wxColour
& col
, int style
);
319 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
320 const wxColour
& col
, int style
)
322 return wxDoFloodFill(this, x
, y
, col
, style
);
325 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
327 // Generic (and therefore rather inefficient) method.
328 // Could be improved.
330 wxBitmap
bitmap(1, 1);
331 memdc
.SelectObject(bitmap
);
332 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
333 memdc
.SelectObject(wxNullBitmap
);
334 wxImage
image(bitmap
);
335 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
339 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
341 wxCHECK_RET( Ok(), wxT("invalid window dc") );
343 if (m_pen
.GetStyle() != wxTRANSPARENT
)
346 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
347 (GC
) m_penGC
, XLOG2DEV(x1
), YLOG2DEV(y1
), XLOG2DEV(x2
), YLOG2DEV(y2
) );
349 CalcBoundingBox(x1
, y1
);
350 CalcBoundingBox(x2
, y2
);
354 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
356 wxCHECK_RET( Ok(), wxT("invalid window dc") );
358 if (m_pen
.GetStyle() != wxTRANSPARENT
)
363 wxCoord xx
= XLOG2DEV(x
);
364 wxCoord yy
= YLOG2DEV(y
);
367 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
368 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
369 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
370 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
375 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
377 wxCHECK_RET( Ok(), wxT("invalid window dc") );
379 wxCoord xx1
= XLOG2DEV(x1
);
380 wxCoord yy1
= YLOG2DEV(y1
);
381 wxCoord xx2
= XLOG2DEV(x2
);
382 wxCoord yy2
= YLOG2DEV(y2
);
383 wxCoord xxc
= XLOG2DEV(xc
);
384 wxCoord yyc
= YLOG2DEV(yc
);
385 double dx
= xx1
- xxc
;
386 double dy
= yy1
- yyc
;
387 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
388 wxCoord r
= (wxCoord
)radius
;
389 double radius1
, radius2
;
391 if (xx1
== xx2
&& yy1
== yy2
)
399 radius1
= radius2
= 0.0;
403 radius1
= (xx1
- xxc
== 0) ?
404 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
405 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
406 radius2
= (xx2
- xxc
== 0) ?
407 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
408 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
410 wxCoord alpha1
= wxCoord(radius1
* 64.0);
411 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
412 while (alpha2
<= 0) alpha2
+= 360*64;
413 while (alpha1
> 360*64) alpha1
-= 360*64;
417 if (m_brush
.GetStyle() != wxTRANSPARENT
)
419 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
421 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
422 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
423 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
425 XFillArc( (Display
*) m_display
, (Window
) m_window
,
426 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
428 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
430 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
432 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
433 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
435 XFillArc( (Display
*) m_display
, (Window
) m_window
,
436 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
438 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
440 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
442 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
443 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
445 XFillArc( (Display
*) m_display
, (Window
) m_window
,
446 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
448 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
450 if (m_brush
.GetStyle() == wxSTIPPLE
)
452 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
453 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
454 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
456 XFillArc( (Display
*) m_display
, (Window
) m_window
,
457 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
459 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
463 XFillArc( (Display
*) m_display
, (Window
) m_window
,
464 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
468 if (m_pen
.GetStyle() != wxTRANSPARENT
)
470 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
471 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
473 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
474 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
476 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
477 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
481 CalcBoundingBox (x1
, y1
);
482 CalcBoundingBox (x2
, y2
);
485 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
487 wxCHECK_RET( Ok(), wxT("invalid window dc") );
489 wxCoord xx
= XLOG2DEV(x
);
490 wxCoord yy
= YLOG2DEV(y
);
491 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
492 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
494 // CMB: handle -ve width and/or height
495 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
496 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
500 wxCoord start
= wxCoord(sa
* 64.0);
501 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
503 if (m_brush
.GetStyle() != wxTRANSPARENT
)
505 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
507 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
508 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
509 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
511 XFillArc( (Display
*) m_display
, (Window
) m_window
,
512 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
514 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
516 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
518 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
519 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
521 XFillArc( (Display
*) m_display
, (Window
) m_window
,
522 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
524 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
526 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
528 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
529 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
531 XFillArc( (Display
*) m_display
, (Window
) m_window
,
532 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
534 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
536 if (m_brush
.GetStyle() == wxSTIPPLE
)
538 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
539 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
540 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
542 XFillArc( (Display
*) m_display
, (Window
) m_window
,
543 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
545 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
549 XFillArc( (Display
*) m_display
, (Window
) m_window
,
550 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
554 if (m_pen
.GetStyle() != wxTRANSPARENT
)
556 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
557 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
561 CalcBoundingBox (x
, y
);
562 CalcBoundingBox (x
+ width
, y
+ height
);
565 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
567 wxCHECK_RET( Ok(), wxT("invalid window dc") );
569 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
)
570 XDrawPoint( (Display
*) m_display
, (Window
) m_window
,
571 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
573 CalcBoundingBox (x
, y
);
576 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
578 wxCHECK_RET( Ok(), wxT("invalid window dc") );
580 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
583 XPoint
*xpoints
= new XPoint
[n
];
584 for (int i
= 0; i
< n
; i
++)
586 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
587 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
589 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
591 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
, 0 );
596 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
597 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
599 wxCHECK_RET( Ok(), wxT("invalid window dc") );
603 XPoint
*xpoints
= new XPoint
[n
+ 1];
605 for (i
= 0; i
< n
; i
++)
607 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
608 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
610 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
615 if (m_brush
.GetStyle() != wxTRANSPARENT
)
618 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
620 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
621 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
622 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
624 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
625 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
627 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
629 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
631 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
632 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
634 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
635 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
637 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
639 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
641 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
642 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
644 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
645 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
647 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
649 if (m_brush
.GetStyle() == wxSTIPPLE
)
651 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
652 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
653 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
655 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
656 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
658 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
662 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
663 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
667 if (m_pen
.GetStyle () != wxTRANSPARENT
)
669 // Close figure for XDrawLines
670 xpoints
[i
].x
= xpoints
[0].x
;
671 xpoints
[i
].y
= xpoints
[0].y
;
673 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
680 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
682 wxCHECK_RET( Ok(), wxT("invalid window dc") );
684 wxCoord xx
= XLOG2DEV(x
);
685 wxCoord yy
= YLOG2DEV(y
);
686 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
687 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
689 // CMB: draw nothing if transformed w or h is 0
690 if (ww
== 0 || hh
== 0) return;
692 // CMB: handle -ve width and/or height
693 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
694 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
698 if (m_brush
.GetStyle() != wxTRANSPARENT
)
700 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
702 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
703 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
704 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
706 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
707 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
709 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
711 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
713 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
714 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
716 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
717 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
719 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
721 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
723 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
724 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
726 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
727 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
729 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
731 if (m_brush
.GetStyle() == wxSTIPPLE
)
733 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
734 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
735 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
737 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
738 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
740 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
744 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
745 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
749 if (m_pen
.GetStyle () != wxTRANSPARENT
)
751 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
752 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
756 CalcBoundingBox( x
, y
);
757 CalcBoundingBox( x
+ width
, y
+ height
);
760 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
765 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
767 wxCHECK_RET( Ok(), wxT("invalid window dc") );
769 wxCoord xx
= XLOG2DEV(x
);
770 wxCoord yy
= YLOG2DEV(y
);
771 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
772 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
774 // CMB: handle -ve width and/or height
775 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
776 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
780 if (m_brush
.GetStyle() != wxTRANSPARENT
)
782 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
784 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
785 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
786 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
788 XFillArc( (Display
*) m_display
, (Window
) m_window
,
789 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
791 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
793 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
795 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
796 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
798 XFillArc( (Display
*) m_display
, (Window
) m_window
,
799 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
801 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
803 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
805 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
806 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
808 XFillArc( (Display
*) m_display
, (Window
) m_window
,
809 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
811 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
813 if (m_brush
.GetStyle() == wxSTIPPLE
)
815 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
816 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
817 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
819 XFillArc( (Display
*) m_display
, (Window
) m_window
,
820 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
822 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
826 XFillArc( (Display
*) m_display
, (Window
) m_window
,
827 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
831 if (m_pen
.GetStyle () != wxTRANSPARENT
)
833 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
834 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
838 CalcBoundingBox( x
, y
);
839 CalcBoundingBox( x
+ width
, y
+ height
);
842 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
844 DoDrawBitmap(icon
, x
, y
, TRUE
);
848 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
849 wxCoord x
, wxCoord y
,
852 wxCHECK_RET( Ok(), wxT("invalid window dc") );
854 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
856 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
858 /* scale/translate size and position */
859 int xx
= XLOG2DEV(x
);
860 int yy
= YLOG2DEV(y
);
862 int w
= bitmap
.GetWidth();
863 int h
= bitmap
.GetHeight();
865 CalcBoundingBox( x
, y
);
866 CalcBoundingBox( x
+ w
, y
+ h
);
868 if (!m_window
) return;
870 int ww
= XLOG2DEVREL(w
);
871 int hh
= YLOG2DEVREL(h
);
873 /* compare to current clipping region */
874 if (!m_currentClippingRegion
.IsNull())
876 wxRegion
tmp( xx
,yy
,ww
,hh
);
877 tmp
.Intersect( m_currentClippingRegion
);
882 /* scale bitmap if required */
884 if ((w
!= ww
) || (h
!= hh
))
886 wxImage
image( bitmap
);
887 image
.Rescale( ww
, hh
);
890 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
893 use_bitmap
= image
.ConvertToBitmap();
900 /* apply mask if any */
901 WXPixmap mask
= NULL
;
902 if (use_bitmap
.GetMask())
903 mask
= use_bitmap
.GetMask()->GetBitmap();
907 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
908 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
909 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
911 GrSetGCUseBackground(gc
, FALSE
);
912 GrSetGCMode(gc
, GR_MODE_COPY
);
914 // This code assumes that background and foreground
915 // colours are used in ROPs, like in MSW.
916 // Not sure if this is true.
918 // Copy destination to buffer.
919 // In DoBlit, we need this step because Blit has
920 // a ROP argument. Here, we don't need it.
921 // In DoBlit, we may be able to eliminate this step
922 // if we check if the rop = copy
924 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_window
,
928 // Copy src to buffer using selected raster op (none selected
929 // in DrawBitmap, so just use Gxcopy)
930 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
933 // Set masked area in buffer to BLACK (pixel value 0)
934 GrSetGCBackground(gc
, WHITE
);
935 GrSetGCForeground(gc
, BLACK
);
936 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
939 // set unmasked area in dest to BLACK
940 GrSetGCBackground(gc
, BLACK
);
941 GrSetGCForeground(gc
, WHITE
);
942 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
946 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
950 GrDestroyWindow(bufPixmap
);
953 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
954 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
956 /* remove mask again if any */
959 if (!m_currentClippingRegion
.IsNull())
960 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
967 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
968 wxCoord x
, wxCoord y
,
971 wxCHECK_RET( Ok(), wxT("invalid window dc") );
973 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
975 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
977 // scale/translate size and position
978 int xx
= XLOG2DEV(x
);
979 int yy
= YLOG2DEV(y
);
981 int w
= bitmap
.GetWidth();
982 int h
= bitmap
.GetHeight();
984 CalcBoundingBox( x
, y
);
985 CalcBoundingBox( x
+ w
, y
+ h
);
987 if (!m_window
) return;
989 int ww
= XLOG2DEVREL(w
);
990 int hh
= YLOG2DEVREL(h
);
992 // compare to current clipping region
993 if (!m_currentClippingRegion
.IsNull())
995 wxRegion
tmp( xx
,yy
,ww
,hh
);
996 tmp
.Intersect( m_currentClippingRegion
);
1001 // scale bitmap if required
1002 wxBitmap use_bitmap
;
1003 if ((w
!= ww
) || (h
!= hh
))
1005 wxImage
image( bitmap
);
1006 image
.Rescale( ww
, hh
);
1009 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1012 use_bitmap
= image
.ConvertToBitmap();
1016 use_bitmap
= bitmap
;
1019 // apply mask if any
1020 WXPixmap mask
= NULL
;
1021 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1023 if (useMask
&& mask
)
1025 WXPixmap new_mask
= NULL
;
1027 if (!m_currentClippingRegion
.IsNull())
1030 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 );
1031 GdkGC
*gc
= gdk_gc_new( new_mask
);
1033 gdk_gc_set_foreground( gc
, &col
);
1034 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1036 gdk_gc_set_background( gc
, &col
);
1038 gdk_gc_set_foreground( gc
, &col
);
1039 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1040 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1041 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1042 gdk_gc_set_stipple( gc
, mask
);
1043 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1050 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1052 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1053 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1058 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1060 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1061 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1065 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1068 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1069 // drawing a mono-bitmap (XBitmap) we use the current text GC
1071 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1072 (GC
) m_textGC
, 0, 0, w
, h
, xx
, yy
, 1 );
1074 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1075 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1077 // remove mask again if any
1078 if (useMask
&& mask
)
1082 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1083 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1084 if (!m_currentClippingRegion
.IsNull())
1085 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1089 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1090 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1091 if (!m_currentClippingRegion
.IsNull())
1092 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1097 // wxUSE_NANOX/!wxUSE_NANOX
1099 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1100 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1101 wxCoord xsrcMask
, wxCoord ysrcMask
)
1103 /* this is the nth try to get this utterly useless function to
1104 work. it now completely ignores the scaling or translation
1105 of the source dc, but scales correctly on the target dc and
1106 knows about possible mask information in a memory dc. */
1108 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid window dc") );
1110 wxCHECK_MSG( source
, FALSE
, wxT("invalid source dc") );
1112 if (!m_window
) return FALSE
;
1114 // transform the source DC coords to the device ones
1115 xsrc
= source
->XLOG2DEV(xsrc
);
1116 ysrc
= source
->YLOG2DEV(ysrc
);
1118 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1119 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1121 bool use_bitmap_method
= FALSE
;
1122 bool is_mono
= FALSE
;
1124 // TODO: use the mask origin when drawing transparently
1125 if (xsrcMask
== -1 && ysrcMask
== -1)
1131 if (srcDC
->m_isMemDC
)
1133 if (!memDC
->m_selected
.Ok()) return FALSE
;
1135 /* we use the "XCopyArea" way to copy a memory dc into
1136 y different window if the memory dc BOTH
1137 a) doesn't have any mask or its mask isn't used
1141 if (useMask
&& (memDC
->m_selected
.GetMask()))
1143 /* we HAVE TO use the direct way for memory dcs
1144 that have mask since the XCopyArea doesn't know
1146 use_bitmap_method
= TRUE
;
1148 else if (memDC
->m_selected
.GetDepth() == 1)
1150 /* we HAVE TO use the direct way for memory dcs
1151 that are bitmaps because XCopyArea doesn't cope
1152 with different bit depths */
1154 use_bitmap_method
= TRUE
;
1156 else if ((xsrc
== 0) && (ysrc
== 0) &&
1157 (width
== memDC
->m_selected
.GetWidth()) &&
1158 (height
== memDC
->m_selected
.GetHeight()))
1160 /* we SHOULD use the direct way if all of the bitmap
1161 in the memory dc is copied in which case XCopyArea
1162 wouldn't be able able to boost performace by reducing
1163 the area to be scaled */
1164 use_bitmap_method
= TRUE
;
1168 use_bitmap_method
= FALSE
;
1172 CalcBoundingBox( xdest
, ydest
);
1173 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1175 // scale/translate size and position
1176 wxCoord xx
= XLOG2DEV(xdest
);
1177 wxCoord yy
= YLOG2DEV(ydest
);
1179 wxCoord ww
= XLOG2DEVREL(width
);
1180 wxCoord hh
= YLOG2DEVREL(height
);
1182 // compare to current clipping region
1183 if (!m_currentClippingRegion
.IsNull())
1185 wxRegion
tmp( xx
,yy
,ww
,hh
);
1186 tmp
.Intersect( m_currentClippingRegion
);
1191 int old_logical_func
= m_logicalFunction
;
1192 SetLogicalFunction( logical_func
);
1194 if (use_bitmap_method
)
1196 // scale/translate bitmap size
1197 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1198 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1200 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1201 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1203 // scale bitmap if required
1204 wxBitmap use_bitmap
;
1206 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1208 wxImage
image( memDC
->m_selected
);
1209 image
= image
.Scale( bm_ww
, bm_hh
);
1213 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1216 use_bitmap
= image
.ConvertToBitmap();
1220 use_bitmap
= memDC
->m_selected
;
1223 // apply mask if any
1224 WXPixmap mask
= NULL
;
1225 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1227 if (useMask
&& mask
)
1229 WXPixmap new_mask
= NULL
;
1231 if (!m_currentClippingRegion
.IsNull())
1234 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1235 GdkGC
*gc
= gdk_gc_new( new_mask
);
1237 gdk_gc_set_foreground( gc
, &col
);
1238 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1240 gdk_gc_set_background( gc
, &col
);
1242 gdk_gc_set_foreground( gc
, &col
);
1243 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1244 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1245 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1246 gdk_gc_set_stipple( gc
, mask
);
1247 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1254 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1256 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1257 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1262 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1264 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1265 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1269 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1272 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1273 // drawing a mono-bitmap (XBitmap) we use the current text GC
1276 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1277 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1279 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1280 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1282 // remove mask again if any
1283 if (useMask
&& mask
)
1287 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1288 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1289 if (!m_currentClippingRegion
.IsNull())
1290 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1294 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1295 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1296 if (!m_currentClippingRegion
.IsNull())
1297 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1301 else // use_bitmap_method
1303 if ((width
!= ww
) || (height
!= hh
))
1305 /* Draw source window into a bitmap as we cannot scale
1306 a window in contrast to a bitmap. this would actually
1307 work with memory dcs as well, but we'd lose the mask
1308 information and waste one step in this process since
1309 a memory already has a bitmap. all this is slightly
1310 inefficient as we could take an XImage directly from
1311 an X window, but we'd then also have to care that
1312 the window is not outside the screen (in which case
1313 we'd get a BadMatch or what not).
1314 Is a double XGetImage and combined XGetPixel and
1315 XPutPixel really faster? I'm not sure. look at wxXt
1316 for a different implementation of the same problem. */
1318 wxBitmap
bitmap( width
, height
);
1320 // copy including child window contents
1321 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1322 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) bitmap
.GetPixmap(),
1323 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1324 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1327 wxImage
image( bitmap
);
1328 image
= image
.Scale( ww
, hh
);
1330 // convert to bitmap
1331 bitmap
= image
.ConvertToBitmap();
1333 // draw scaled bitmap
1334 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_window
,
1335 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1339 // No scaling and not a memory dc with a mask either
1341 // copy including child window contents
1342 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1343 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) m_window
,
1344 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1345 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1349 SetLogicalFunction( old_logical_func
);
1354 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1356 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1358 if (!m_window
) return;
1360 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1362 wxCHECK_RET( xfont
, wxT("invalid font") );
1367 // First draw a rectangle representing the text background, if a text
1368 // background is specified
1369 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1371 // Since X draws from the baseline of the text, must add the text height
1376 int direction
, descent
;
1378 slen
= strlen(text
);
1379 XCharStruct overall_return
;
1381 (void)XTextExtents(xfont
, (char*) text
.c_str(), slen
, &direction
,
1382 &ascent
, &descent
, &overall_return
);
1384 cx
= overall_return
.width
;
1385 cy
= ascent
+ descent
;
1386 m_textBackgroundColour
.CalcPixel(m_cmap
);
1387 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1388 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
1389 (GC
) m_textGC
, x
, y
, cx
, cy
);
1390 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1394 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1396 if ((xfont
->min_byte1
== 0) && (xfont
->max_byte1
== 0))
1399 XDrawString( (Display
*) m_display
, (Window
) m_window
,
1400 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.Len() );
1404 if (m_font
.GetUnderlined())
1406 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1407 if (font
->descent
> 0) ul_y
++;
1408 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1411 width
= wxCoord(width
/ m_scaleX
);
1412 height
= wxCoord(height
/ m_scaleY
);
1414 CalcBoundingBox (x
+ width
, y
+ height
);
1415 CalcBoundingBox (x
, y
);
1419 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
, double angle
)
1424 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1425 wxCoord
*descent
, wxCoord
*externalLeading
,
1426 wxFont
*font
) const
1428 wxCHECK_RET( Ok(), "invalid dc" );
1430 wxFont fontToUse
= m_font
;
1431 if (font
) fontToUse
= *font
;
1433 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
1435 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1437 wxCHECK_RET( xfont
, wxT("invalid font") );
1439 int direction
, ascent
, descent2
;
1440 XCharStruct overall
;
1442 XTextExtents( xfont
, (char*) string
.c_str(), string
.Len(), &direction
,
1443 &ascent
, &descent2
, &overall
);
1446 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1448 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1450 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1451 if (externalLeading
)
1452 *externalLeading
= 0; // ??
1455 wxCoord
wxWindowDC::GetCharWidth() const
1457 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1459 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1461 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1463 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1465 int direction
, ascent
, descent
;
1466 XCharStruct overall
;
1468 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1470 return (wxCoord
)(overall
.width
/ m_scaleX
);
1473 wxCoord
wxWindowDC::GetCharHeight() const
1475 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1477 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1479 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1481 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1483 int direction
, ascent
, descent
;
1484 XCharStruct overall
;
1486 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1488 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1491 void wxWindowDC::Clear()
1493 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1495 if (!m_window
) return;
1497 /* - we either are a memory dc or have a window as the
1498 owner. anything else shouldn't happen.
1499 - we don't use gdk_window_clear() as we don't set
1500 the window's background colour anymore. it is too
1501 much pain to keep the DC's and the window's back-
1502 ground colour in synch. */
1507 m_owner
->GetSize( &width
, &height
);
1508 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1515 GetSize( &width
, &height
);
1516 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1521 void wxWindowDC::SetFont( const wxFont
&font
)
1523 wxCHECK_RET( Ok(), "invalid dc" );
1528 void wxWindowDC::SetPen( const wxPen
&pen
)
1530 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1532 if (m_pen
== pen
) return;
1536 if (!m_pen
.Ok()) return;
1538 if (!m_window
) return;
1540 int width
= m_pen
.GetWidth();
1543 // CMB: if width is non-zero scale it with the dc
1548 // X doesn't allow different width in x and y and so we take
1551 ( fabs((double) XLOG2DEVREL(width
)) +
1552 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1556 static const wxX11Dash dotted
[] = {1, 1};
1557 static const wxX11Dash short_dashed
[] = {2, 2};
1558 static const wxX11Dash long_dashed
[] = {2, 4};
1559 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1561 // We express dash pattern in pen width unit, so we are
1562 // independent of zoom factor and so on...
1564 const wxX11Dash
*req_dash
;
1566 int lineStyle
= LineSolid
;
1567 switch (m_pen
.GetStyle())
1571 lineStyle
= LineOnOffDash
;
1572 req_nb_dash
= m_pen
.GetDashCount();
1573 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1578 lineStyle
= LineOnOffDash
;
1585 lineStyle
= LineOnOffDash
;
1587 req_dash
= long_dashed
;
1592 lineStyle
= LineOnOffDash
;
1594 req_dash
= short_dashed
;
1599 // lineStyle = LineDoubleDash;
1600 lineStyle
= LineOnOffDash
;
1602 req_dash
= dotted_dashed
;
1607 case wxSTIPPLE_MASK_OPAQUE
:
1612 lineStyle
= LineSolid
;
1613 req_dash
= (wxX11Dash
*)NULL
;
1619 int capStyle
= CapRound
;
1620 switch (m_pen
.GetCap())
1622 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1623 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1630 capStyle
= CapNotLast
;
1634 capStyle
= CapRound
;
1640 int joinStyle
= JoinRound
;
1641 switch (m_pen
.GetJoin())
1643 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1644 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1646 default: { joinStyle
= JoinRound
; break; }
1649 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1651 m_pen
.GetColour().CalcPixel( m_cmap
);
1652 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1655 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1657 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1659 if (m_brush
== brush
) return;
1663 if (!m_brush
.Ok()) return;
1665 if (!m_window
) return;
1667 m_brush
.GetColour().CalcPixel( m_cmap
);
1668 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1670 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1672 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1674 if (m_brush
.GetStipple()->GetPixmap())
1676 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1677 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1681 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1682 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1686 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1688 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1689 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1692 if (IS_HATCH(m_brush
.GetStyle()))
1694 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1695 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1696 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1700 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1702 /* CMB 21/7/98: Added SetBackground. Sets background brush
1703 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1705 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1707 if (m_backgroundBrush
== brush
) return;
1709 m_backgroundBrush
= brush
;
1711 if (!m_backgroundBrush
.Ok()) return;
1713 if (!m_window
) return;
1715 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1716 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1717 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1718 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1719 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1721 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1723 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1725 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1727 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1728 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1732 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1733 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
1737 if (IS_HATCH(m_backgroundBrush
.GetStyle()))
1739 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1740 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
1741 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
1745 void wxWindowDC::SetLogicalFunction( int function
)
1747 wxCHECK_RET( Ok(), "invalid dc" );
1751 if (m_logicalFunction
== function
)
1754 // VZ: shouldn't this be a CHECK?
1761 x_function
= GXclear
;
1767 x_function
= GXinvert
;
1770 x_function
= GXorReverse
;
1773 x_function
= GXandReverse
;
1782 x_function
= GXandInverted
;
1785 x_function
= GXnoop
;
1791 x_function
= GXequiv
;
1794 x_function
= GXcopyInverted
;
1797 x_function
= GXorInverted
;
1800 x_function
= GXnand
;
1807 x_function
= GXcopy
;
1811 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
1812 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
1814 // to stay compatible with wxMSW, we don't apply ROPs to the text
1815 // operations (i.e. DrawText/DrawRotatedText).
1816 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
1817 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
1819 m_logicalFunction
= function
;
1822 void wxWindowDC::SetTextForeground( const wxColour
&col
)
1824 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1826 // don't set m_textForegroundColour to an invalid colour as we'd crash
1827 // later then (we use m_textForegroundColour.GetColor() without checking
1829 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
1832 m_textForegroundColour
= col
;
1836 m_textForegroundColour
.CalcPixel( m_cmap
);
1837 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
1841 void wxWindowDC::SetTextBackground( const wxColour
&col
)
1843 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1846 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
1849 m_textBackgroundColour
= col
;
1853 m_textBackgroundColour
.CalcPixel( m_cmap
);
1854 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
1858 void wxWindowDC::SetBackgroundMode( int mode
)
1860 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1862 m_backgroundMode
= mode
;
1865 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
1868 if (!m_window
) return;
1870 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
1871 // transparent/solid background mode
1873 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
1875 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
1876 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
1880 void wxWindowDC::SetPalette( const wxPalette
& palette
)
1886 /* Use GetXColormap */
1887 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1888 (Colormap
) palette
.GetXColormap());
1890 /* Use wxGetMainColormap */
1891 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1892 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
1897 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
1899 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1901 if (!m_window
) return;
1904 rect
.x
= XLOG2DEV(x
);
1905 rect
.y
= YLOG2DEV(y
);
1906 rect
.width
= XLOG2DEVREL(width
);
1907 rect
.height
= YLOG2DEVREL(height
);
1909 if (!m_currentClippingRegion
.IsNull())
1910 m_currentClippingRegion
.Intersect( rect
);
1912 m_currentClippingRegion
.Union( rect
);
1914 #if USE_PAINT_REGION
1915 if (!m_paintClippingRegion
.IsNull())
1916 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
1919 wxCoord xx
, yy
, ww
, hh
;
1920 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
1921 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
1923 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1924 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1925 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1926 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1929 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
1931 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1935 DestroyClippingRegion();
1939 if (!m_window
) return;
1941 if (!m_currentClippingRegion
.IsNull())
1942 m_currentClippingRegion
.Intersect( region
);
1944 m_currentClippingRegion
.Union( region
);
1946 #if USE_PAINT_REGION
1947 if (!m_paintClippingRegion
.IsNull())
1948 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
1951 wxCoord xx
, yy
, ww
, hh
;
1952 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
1953 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
1955 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1956 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1957 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1958 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1961 void wxWindowDC::DestroyClippingRegion()
1963 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1965 wxDC::DestroyClippingRegion();
1967 m_currentClippingRegion
.Clear();
1969 #if USE_PAINT_REGION
1970 if (!m_paintClippingRegion
.IsEmpty())
1971 m_currentClippingRegion
.Union( m_paintClippingRegion
);
1974 if (!m_window
) return;
1976 if (m_currentClippingRegion
.IsEmpty())
1978 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1979 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
1980 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1981 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
1985 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1986 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1987 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1988 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1992 void wxWindowDC::Destroy()
1994 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
1996 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
1998 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2000 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2004 void wxWindowDC::ComputeScaleAndOrigin()
2006 /* CMB: copy scale to see if it changes */
2007 double origScaleX
= m_scaleX
;
2008 double origScaleY
= m_scaleY
;
2010 wxDC::ComputeScaleAndOrigin();
2012 /* CMB: if scale has changed call SetPen to recalulate the line width */
2013 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2016 /* this is a bit artificial, but we need to force wxDC to think
2017 the pen has changed */
2024 wxSize
wxWindowDC::GetPPI() const
2026 return wxSize(100, 100);
2029 int wxWindowDC::GetDepth() const
2031 wxFAIL_MSG(wxT("not implemented"));
2036 //-----------------------------------------------------------------------------
2038 //-----------------------------------------------------------------------------
2040 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2042 wxClientDC::wxClientDC( wxWindow
*window
)
2043 : wxWindowDC( window
)
2045 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2047 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2049 #if wxUSE_TWO_WINDOWS
2051 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2052 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2053 wxSize size
= window
->GetClientSize();
2054 SetClippingRegion(wxPoint(0, 0), size
);
2058 void wxClientDC::DoGetSize(int *width
, int *height
) const
2060 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2062 m_owner
->GetClientSize( width
, height
);
2065 // ----------------------------------------------------------------------------
2067 // ----------------------------------------------------------------------------
2069 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2071 wxPaintDC::wxPaintDC(wxWindow
* window
)
2072 : wxClientDC(window
)
2074 #if USE_PAINT_REGION
2075 if (!window
->GetClipPaintRegion())
2078 m_paintClippingRegion
= window
->GetUpdateRegion();
2079 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2082 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2084 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2085 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2086 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2087 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2089 #endif // USE_PAINT_REGION
2092 // ----------------------------------------------------------------------------
2094 // ----------------------------------------------------------------------------
2096 class wxDCModule
: public wxModule
2103 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2106 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)
2108 bool wxDCModule::OnInit()
2114 void wxDCModule::OnExit()