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 void wxWindowDC::DoFloodFill( wxCoord x
, wxCoord y
,
317 const wxColour
& col
, int style
)
319 if (GetBrush().GetStyle() == wxTRANSPARENT
)
321 wxLogDebug(wxT("In FloodFill, current brush is transparent, no filling done"));
326 this->GetSize(&width
, &height
);
327 //it would be nice to fail if we don't get a sensible size...
328 if (width
< 1 || height
< 1)
330 wxLogError(wxT("In FloodFill, dc.GetSize routine failed, method not supported by this DC"));
334 //this is much faster than doing the individual pixels
336 wxBitmap
bitmap(width
, height
);
337 memdc
.SelectObject(bitmap
);
338 memdc
.Blit(0, 0, width
, height
, (wxDC
*) this, 0, 0);
339 memdc
.SelectObject(wxNullBitmap
);
341 wxImage
image(bitmap
);
342 image
.DoFloodFill (x
,y
, GetBrush(), col
, style
, GetLogicalFunction());
343 bitmap
= wxBitmap(image
);
344 memdc
.SelectObject(bitmap
);
345 this->Blit(0, 0, width
, height
, &memdc
, 0, 0);
346 memdc
.SelectObject(wxNullBitmap
);
349 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
351 // Generic (and therefore rather inefficient) method.
352 // Could be improved.
354 wxBitmap
bitmap(1, 1);
355 memdc
.SelectObject(bitmap
);
356 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
357 memdc
.SelectObject(wxNullBitmap
);
358 wxImage
image(bitmap
);
359 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
363 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
365 wxCHECK_RET( Ok(), wxT("invalid window dc") );
367 if (m_pen
.GetStyle() != wxTRANSPARENT
)
370 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
371 (GC
) m_penGC
, XLOG2DEV(x1
), YLOG2DEV(y1
), XLOG2DEV(x2
), YLOG2DEV(y2
) );
373 CalcBoundingBox(x1
, y1
);
374 CalcBoundingBox(x2
, y2
);
378 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
380 wxCHECK_RET( Ok(), wxT("invalid window dc") );
382 if (m_pen
.GetStyle() != wxTRANSPARENT
)
387 wxCoord xx
= XLOG2DEV(x
);
388 wxCoord yy
= YLOG2DEV(y
);
391 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
392 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
393 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
394 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
399 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
401 wxCHECK_RET( Ok(), wxT("invalid window dc") );
403 wxCoord xx1
= XLOG2DEV(x1
);
404 wxCoord yy1
= YLOG2DEV(y1
);
405 wxCoord xx2
= XLOG2DEV(x2
);
406 wxCoord yy2
= YLOG2DEV(y2
);
407 wxCoord xxc
= XLOG2DEV(xc
);
408 wxCoord yyc
= YLOG2DEV(yc
);
409 double dx
= xx1
- xxc
;
410 double dy
= yy1
- yyc
;
411 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
412 wxCoord r
= (wxCoord
)radius
;
413 double radius1
, radius2
;
415 if (xx1
== xx2
&& yy1
== yy2
)
423 radius1
= radius2
= 0.0;
427 radius1
= (xx1
- xxc
== 0) ?
428 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
429 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
430 radius2
= (xx2
- xxc
== 0) ?
431 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
432 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
434 wxCoord alpha1
= wxCoord(radius1
* 64.0);
435 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
436 while (alpha2
<= 0) alpha2
+= 360*64;
437 while (alpha1
> 360*64) alpha1
-= 360*64;
441 if (m_brush
.GetStyle() != wxTRANSPARENT
)
443 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
445 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
446 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
447 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
449 XFillArc( (Display
*) m_display
, (Window
) m_window
,
450 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
452 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
454 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
456 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
457 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
459 XFillArc( (Display
*) m_display
, (Window
) m_window
,
460 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
462 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
464 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
466 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
467 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
469 XFillArc( (Display
*) m_display
, (Window
) m_window
,
470 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
472 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
474 if (m_brush
.GetStyle() == wxSTIPPLE
)
476 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
477 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
478 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
480 XFillArc( (Display
*) m_display
, (Window
) m_window
,
481 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
483 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
487 XFillArc( (Display
*) m_display
, (Window
) m_window
,
488 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
492 if (m_pen
.GetStyle() != wxTRANSPARENT
)
494 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
495 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
497 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
498 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
500 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
501 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
505 CalcBoundingBox (x1
, y1
);
506 CalcBoundingBox (x2
, y2
);
509 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
511 wxCHECK_RET( Ok(), wxT("invalid window dc") );
513 wxCoord xx
= XLOG2DEV(x
);
514 wxCoord yy
= YLOG2DEV(y
);
515 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
516 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
518 // CMB: handle -ve width and/or height
519 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
520 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
524 wxCoord start
= wxCoord(sa
* 64.0);
525 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
527 if (m_brush
.GetStyle() != wxTRANSPARENT
)
529 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
531 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
532 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
533 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
535 XFillArc( (Display
*) m_display
, (Window
) m_window
,
536 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
538 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
540 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
542 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
543 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
545 XFillArc( (Display
*) m_display
, (Window
) m_window
,
546 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
548 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
550 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
552 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
553 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
555 XFillArc( (Display
*) m_display
, (Window
) m_window
,
556 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
558 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
560 if (m_brush
.GetStyle() == wxSTIPPLE
)
562 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
563 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
564 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
566 XFillArc( (Display
*) m_display
, (Window
) m_window
,
567 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
569 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
573 XFillArc( (Display
*) m_display
, (Window
) m_window
,
574 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
578 if (m_pen
.GetStyle() != wxTRANSPARENT
)
580 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
581 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
585 CalcBoundingBox (x
, y
);
586 CalcBoundingBox (x
+ width
, y
+ height
);
589 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
591 wxCHECK_RET( Ok(), wxT("invalid window dc") );
593 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
)
594 XDrawPoint( (Display
*) m_display
, (Window
) m_window
,
595 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
597 CalcBoundingBox (x
, y
);
600 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
602 wxCHECK_RET( Ok(), wxT("invalid window dc") );
604 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
607 XPoint
*xpoints
= new XPoint
[n
];
608 for (int i
= 0; i
< n
; i
++)
610 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
611 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
613 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
615 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
, 0 );
620 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
621 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
623 wxCHECK_RET( Ok(), wxT("invalid window dc") );
627 XPoint
*xpoints
= new XPoint
[n
+ 1];
629 for (i
= 0; i
< n
; i
++)
631 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
632 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
634 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
639 if (m_brush
.GetStyle() != wxTRANSPARENT
)
642 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
644 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
645 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
646 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
648 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
649 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
651 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
653 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
655 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
656 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
658 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
659 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
661 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
663 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
665 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
666 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
668 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
669 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
671 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
673 if (m_brush
.GetStyle() == wxSTIPPLE
)
675 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
676 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
677 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
679 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
680 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
682 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
686 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
687 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
691 if (m_pen
.GetStyle () != wxTRANSPARENT
)
693 // Close figure for XDrawLines
694 xpoints
[i
].x
= xpoints
[0].x
;
695 xpoints
[i
].y
= xpoints
[0].y
;
697 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
704 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
706 wxCHECK_RET( Ok(), wxT("invalid window dc") );
708 wxCoord xx
= XLOG2DEV(x
);
709 wxCoord yy
= YLOG2DEV(y
);
710 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
711 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
713 // CMB: draw nothing if transformed w or h is 0
714 if (ww
== 0 || hh
== 0) return;
716 // CMB: handle -ve width and/or height
717 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
718 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
722 if (m_brush
.GetStyle() != wxTRANSPARENT
)
724 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
726 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
727 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
728 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
730 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
731 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
733 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
735 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
737 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
738 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
740 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
741 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
743 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
745 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
747 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
748 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
750 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
751 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
753 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
755 if (m_brush
.GetStyle() == wxSTIPPLE
)
757 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
758 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
759 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
761 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
762 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
764 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
768 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
769 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
773 if (m_pen
.GetStyle () != wxTRANSPARENT
)
775 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
776 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
780 CalcBoundingBox( x
, y
);
781 CalcBoundingBox( x
+ width
, y
+ height
);
784 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
789 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
791 wxCHECK_RET( Ok(), wxT("invalid window dc") );
793 wxCoord xx
= XLOG2DEV(x
);
794 wxCoord yy
= YLOG2DEV(y
);
795 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
796 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
798 // CMB: handle -ve width and/or height
799 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
800 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
804 if (m_brush
.GetStyle() != wxTRANSPARENT
)
806 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
808 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
809 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
810 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
812 XFillArc( (Display
*) m_display
, (Window
) m_window
,
813 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
815 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
817 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
819 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
820 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
822 XFillArc( (Display
*) m_display
, (Window
) m_window
,
823 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
825 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
827 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
829 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
830 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
832 XFillArc( (Display
*) m_display
, (Window
) m_window
,
833 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
835 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
837 if (m_brush
.GetStyle() == wxSTIPPLE
)
839 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
840 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
841 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
843 XFillArc( (Display
*) m_display
, (Window
) m_window
,
844 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
846 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
850 XFillArc( (Display
*) m_display
, (Window
) m_window
,
851 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
855 if (m_pen
.GetStyle () != wxTRANSPARENT
)
857 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
858 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
862 CalcBoundingBox( x
, y
);
863 CalcBoundingBox( x
+ width
, y
+ height
);
866 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
868 DoDrawBitmap(icon
, x
, y
, TRUE
);
872 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
873 wxCoord x
, wxCoord y
,
876 wxCHECK_RET( Ok(), wxT("invalid window dc") );
878 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
880 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
882 /* scale/translate size and position */
883 int xx
= XLOG2DEV(x
);
884 int yy
= YLOG2DEV(y
);
886 int w
= bitmap
.GetWidth();
887 int h
= bitmap
.GetHeight();
889 CalcBoundingBox( x
, y
);
890 CalcBoundingBox( x
+ w
, y
+ h
);
892 if (!m_window
) return;
894 int ww
= XLOG2DEVREL(w
);
895 int hh
= YLOG2DEVREL(h
);
897 /* compare to current clipping region */
898 if (!m_currentClippingRegion
.IsNull())
900 wxRegion
tmp( xx
,yy
,ww
,hh
);
901 tmp
.Intersect( m_currentClippingRegion
);
906 /* scale bitmap if required */
908 if ((w
!= ww
) || (h
!= hh
))
910 wxImage
image( bitmap
);
911 image
.Rescale( ww
, hh
);
914 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
917 use_bitmap
= image
.ConvertToBitmap();
924 /* apply mask if any */
925 WXPixmap mask
= NULL
;
926 if (use_bitmap
.GetMask())
927 mask
= use_bitmap
.GetMask()->GetBitmap();
931 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
932 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
933 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
935 GrSetGCUseBackground(gc
, FALSE
);
936 GrSetGCMode(gc
, GR_MODE_COPY
);
938 // This code assumes that background and foreground
939 // colours are used in ROPs, like in MSW.
940 // Not sure if this is true.
942 // Copy destination to buffer.
943 // In DoBlit, we need this step because Blit has
944 // a ROP argument. Here, we don't need it.
945 // In DoBlit, we may be able to eliminate this step
946 // if we check if the rop = copy
948 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_window
,
952 // Copy src to buffer using selected raster op (none selected
953 // in DrawBitmap, so just use Gxcopy)
954 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
957 // Set masked area in buffer to BLACK (pixel value 0)
958 GrSetGCBackground(gc
, WHITE
);
959 GrSetGCForeground(gc
, BLACK
);
960 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
963 // set unmasked area in dest to BLACK
964 GrSetGCBackground(gc
, BLACK
);
965 GrSetGCForeground(gc
, WHITE
);
966 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
970 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
974 GrDestroyWindow(bufPixmap
);
977 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
978 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
980 /* remove mask again if any */
983 if (!m_currentClippingRegion
.IsNull())
984 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
991 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
992 wxCoord x
, wxCoord y
,
995 wxCHECK_RET( Ok(), wxT("invalid window dc") );
997 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
999 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1001 // scale/translate size and position
1002 int xx
= XLOG2DEV(x
);
1003 int yy
= YLOG2DEV(y
);
1005 int w
= bitmap
.GetWidth();
1006 int h
= bitmap
.GetHeight();
1008 CalcBoundingBox( x
, y
);
1009 CalcBoundingBox( x
+ w
, y
+ h
);
1011 if (!m_window
) return;
1013 int ww
= XLOG2DEVREL(w
);
1014 int hh
= YLOG2DEVREL(h
);
1016 // compare to current clipping region
1017 if (!m_currentClippingRegion
.IsNull())
1019 wxRegion
tmp( xx
,yy
,ww
,hh
);
1020 tmp
.Intersect( m_currentClippingRegion
);
1025 // scale bitmap if required
1026 wxBitmap use_bitmap
;
1027 if ((w
!= ww
) || (h
!= hh
))
1029 wxImage
image( bitmap
);
1030 image
.Rescale( ww
, hh
);
1033 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1036 use_bitmap
= image
.ConvertToBitmap();
1040 use_bitmap
= bitmap
;
1043 // apply mask if any
1044 WXPixmap mask
= NULL
;
1045 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1047 if (useMask
&& mask
)
1049 WXPixmap new_mask
= NULL
;
1051 if (!m_currentClippingRegion
.IsNull())
1054 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 );
1055 GdkGC
*gc
= gdk_gc_new( new_mask
);
1057 gdk_gc_set_foreground( gc
, &col
);
1058 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1060 gdk_gc_set_background( gc
, &col
);
1062 gdk_gc_set_foreground( gc
, &col
);
1063 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1064 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1065 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1066 gdk_gc_set_stipple( gc
, mask
);
1067 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1074 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1076 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1077 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1082 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1084 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1085 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1089 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1092 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1093 // drawing a mono-bitmap (XBitmap) we use the current text GC
1095 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1096 (GC
) m_textGC
, 0, 0, w
, h
, xx
, yy
, 1 );
1098 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1099 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1101 // remove mask again if any
1102 if (useMask
&& mask
)
1106 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1107 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1108 if (!m_currentClippingRegion
.IsNull())
1109 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1113 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1114 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1115 if (!m_currentClippingRegion
.IsNull())
1116 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1121 // wxUSE_NANOX/!wxUSE_NANOX
1123 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1124 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1125 wxCoord xsrcMask
, wxCoord ysrcMask
)
1127 /* this is the nth try to get this utterly useless function to
1128 work. it now completely ignores the scaling or translation
1129 of the source dc, but scales correctly on the target dc and
1130 knows about possible mask information in a memory dc. */
1132 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid window dc") );
1134 wxCHECK_MSG( source
, FALSE
, wxT("invalid source dc") );
1136 if (!m_window
) return FALSE
;
1138 // transform the source DC coords to the device ones
1139 xsrc
= source
->XLOG2DEV(xsrc
);
1140 ysrc
= source
->YLOG2DEV(ysrc
);
1142 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1143 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1145 bool use_bitmap_method
= FALSE
;
1146 bool is_mono
= FALSE
;
1148 // TODO: use the mask origin when drawing transparently
1149 if (xsrcMask
== -1 && ysrcMask
== -1)
1155 if (srcDC
->m_isMemDC
)
1157 if (!memDC
->m_selected
.Ok()) return FALSE
;
1159 /* we use the "XCopyArea" way to copy a memory dc into
1160 y different window if the memory dc BOTH
1161 a) doesn't have any mask or its mask isn't used
1165 if (useMask
&& (memDC
->m_selected
.GetMask()))
1167 /* we HAVE TO use the direct way for memory dcs
1168 that have mask since the XCopyArea doesn't know
1170 use_bitmap_method
= TRUE
;
1172 else if (memDC
->m_selected
.GetDepth() == 1)
1174 /* we HAVE TO use the direct way for memory dcs
1175 that are bitmaps because XCopyArea doesn't cope
1176 with different bit depths */
1178 use_bitmap_method
= TRUE
;
1180 else if ((xsrc
== 0) && (ysrc
== 0) &&
1181 (width
== memDC
->m_selected
.GetWidth()) &&
1182 (height
== memDC
->m_selected
.GetHeight()))
1184 /* we SHOULD use the direct way if all of the bitmap
1185 in the memory dc is copied in which case XCopyArea
1186 wouldn't be able able to boost performace by reducing
1187 the area to be scaled */
1188 use_bitmap_method
= TRUE
;
1192 use_bitmap_method
= FALSE
;
1196 CalcBoundingBox( xdest
, ydest
);
1197 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1199 // scale/translate size and position
1200 wxCoord xx
= XLOG2DEV(xdest
);
1201 wxCoord yy
= YLOG2DEV(ydest
);
1203 wxCoord ww
= XLOG2DEVREL(width
);
1204 wxCoord hh
= YLOG2DEVREL(height
);
1206 // compare to current clipping region
1207 if (!m_currentClippingRegion
.IsNull())
1209 wxRegion
tmp( xx
,yy
,ww
,hh
);
1210 tmp
.Intersect( m_currentClippingRegion
);
1215 int old_logical_func
= m_logicalFunction
;
1216 SetLogicalFunction( logical_func
);
1218 if (use_bitmap_method
)
1220 // scale/translate bitmap size
1221 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1222 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1224 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1225 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1227 // scale bitmap if required
1228 wxBitmap use_bitmap
;
1230 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1232 wxImage
image( memDC
->m_selected
);
1233 image
= image
.Scale( bm_ww
, bm_hh
);
1237 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1240 use_bitmap
= image
.ConvertToBitmap();
1244 use_bitmap
= memDC
->m_selected
;
1247 // apply mask if any
1248 WXPixmap mask
= NULL
;
1249 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1251 if (useMask
&& mask
)
1253 WXPixmap new_mask
= NULL
;
1255 if (!m_currentClippingRegion
.IsNull())
1258 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1259 GdkGC
*gc
= gdk_gc_new( new_mask
);
1261 gdk_gc_set_foreground( gc
, &col
);
1262 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1264 gdk_gc_set_background( gc
, &col
);
1266 gdk_gc_set_foreground( gc
, &col
);
1267 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1268 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1269 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1270 gdk_gc_set_stipple( gc
, mask
);
1271 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1278 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1280 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1281 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1286 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1288 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1289 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1293 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1296 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1297 // drawing a mono-bitmap (XBitmap) we use the current text GC
1300 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1301 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1303 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1304 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1306 // remove mask again if any
1307 if (useMask
&& mask
)
1311 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1312 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1313 if (!m_currentClippingRegion
.IsNull())
1314 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1318 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1319 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1320 if (!m_currentClippingRegion
.IsNull())
1321 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1325 else // use_bitmap_method
1327 if ((width
!= ww
) || (height
!= hh
))
1329 /* Draw source window into a bitmap as we cannot scale
1330 a window in contrast to a bitmap. this would actually
1331 work with memory dcs as well, but we'd lose the mask
1332 information and waste one step in this process since
1333 a memory already has a bitmap. all this is slightly
1334 inefficient as we could take an XImage directly from
1335 an X window, but we'd then also have to care that
1336 the window is not outside the screen (in which case
1337 we'd get a BadMatch or what not).
1338 Is a double XGetImage and combined XGetPixel and
1339 XPutPixel really faster? I'm not sure. look at wxXt
1340 for a different implementation of the same problem. */
1342 wxBitmap
bitmap( width
, height
);
1344 // copy including child window contents
1345 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1346 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) bitmap
.GetPixmap(),
1347 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1348 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1351 wxImage
image( bitmap
);
1352 image
= image
.Scale( ww
, hh
);
1354 // convert to bitmap
1355 bitmap
= image
.ConvertToBitmap();
1357 // draw scaled bitmap
1358 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_window
,
1359 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1363 // No scaling and not a memory dc with a mask either
1365 // copy including child window contents
1366 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1367 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) m_window
,
1368 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1369 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1373 SetLogicalFunction( old_logical_func
);
1378 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1380 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1382 if (!m_window
) return;
1384 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1386 wxCHECK_RET( xfont
, wxT("invalid font") );
1391 // First draw a rectangle representing the text background, if a text
1392 // background is specified
1393 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1395 // Since X draws from the baseline of the text, must add the text height
1400 int direction
, descent
;
1402 slen
= strlen(text
);
1403 XCharStruct overall_return
;
1405 (void)XTextExtents(xfont
, (char*) text
.c_str(), slen
, &direction
,
1406 &ascent
, &descent
, &overall_return
);
1408 cx
= overall_return
.width
;
1409 cy
= ascent
+ descent
;
1410 m_textBackgroundColour
.CalcPixel(m_cmap
);
1411 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1412 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
1413 (GC
) m_textGC
, x
, y
, cx
, cy
);
1414 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1418 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1420 if ((xfont
->min_byte1
== 0) && (xfont
->max_byte1
== 0))
1423 XDrawString( (Display
*) m_display
, (Window
) m_window
,
1424 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.Len() );
1428 if (m_font
.GetUnderlined())
1430 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1431 if (font
->descent
> 0) ul_y
++;
1432 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1435 width
= wxCoord(width
/ m_scaleX
);
1436 height
= wxCoord(height
/ m_scaleY
);
1438 CalcBoundingBox (x
+ width
, y
+ height
);
1439 CalcBoundingBox (x
, y
);
1443 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
, double angle
)
1448 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1449 wxCoord
*descent
, wxCoord
*externalLeading
,
1450 wxFont
*font
) const
1452 wxCHECK_RET( Ok(), "invalid dc" );
1454 wxFont fontToUse
= m_font
;
1455 if (font
) fontToUse
= *font
;
1457 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
1459 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1461 wxCHECK_RET( xfont
, wxT("invalid font") );
1463 int direction
, ascent
, descent2
;
1464 XCharStruct overall
;
1466 XTextExtents( xfont
, (char*) string
.c_str(), string
.Len(), &direction
,
1467 &ascent
, &descent2
, &overall
);
1470 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1472 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1474 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1475 if (externalLeading
)
1476 *externalLeading
= 0; // ??
1479 wxCoord
wxWindowDC::GetCharWidth() const
1481 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1483 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1485 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1487 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1489 int direction
, ascent
, descent
;
1490 XCharStruct overall
;
1492 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1494 return (wxCoord
)(overall
.width
/ m_scaleX
);
1497 wxCoord
wxWindowDC::GetCharHeight() const
1499 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1501 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1503 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1505 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1507 int direction
, ascent
, descent
;
1508 XCharStruct overall
;
1510 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1512 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1515 void wxWindowDC::Clear()
1517 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1519 if (!m_window
) return;
1521 /* - we either are a memory dc or have a window as the
1522 owner. anything else shouldn't happen.
1523 - we don't use gdk_window_clear() as we don't set
1524 the window's background colour anymore. it is too
1525 much pain to keep the DC's and the window's back-
1526 ground colour in synch. */
1531 m_owner
->GetSize( &width
, &height
);
1532 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1539 GetSize( &width
, &height
);
1540 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1545 void wxWindowDC::SetFont( const wxFont
&font
)
1547 wxCHECK_RET( Ok(), "invalid dc" );
1552 void wxWindowDC::SetPen( const wxPen
&pen
)
1554 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1556 if (m_pen
== pen
) return;
1560 if (!m_pen
.Ok()) return;
1562 if (!m_window
) return;
1564 int width
= m_pen
.GetWidth();
1567 // CMB: if width is non-zero scale it with the dc
1572 // X doesn't allow different width in x and y and so we take
1575 ( fabs((double) XLOG2DEVREL(width
)) +
1576 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1580 static const wxX11Dash dotted
[] = {1, 1};
1581 static const wxX11Dash short_dashed
[] = {2, 2};
1582 static const wxX11Dash long_dashed
[] = {2, 4};
1583 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1585 // We express dash pattern in pen width unit, so we are
1586 // independent of zoom factor and so on...
1588 const wxX11Dash
*req_dash
;
1590 int lineStyle
= LineSolid
;
1591 switch (m_pen
.GetStyle())
1595 lineStyle
= LineOnOffDash
;
1596 req_nb_dash
= m_pen
.GetDashCount();
1597 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1602 lineStyle
= LineOnOffDash
;
1609 lineStyle
= LineOnOffDash
;
1611 req_dash
= long_dashed
;
1616 lineStyle
= LineOnOffDash
;
1618 req_dash
= short_dashed
;
1623 // lineStyle = LineDoubleDash;
1624 lineStyle
= LineOnOffDash
;
1626 req_dash
= dotted_dashed
;
1631 case wxSTIPPLE_MASK_OPAQUE
:
1636 lineStyle
= LineSolid
;
1637 req_dash
= (wxX11Dash
*)NULL
;
1643 int capStyle
= CapRound
;
1644 switch (m_pen
.GetCap())
1646 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1647 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1654 capStyle
= CapNotLast
;
1658 capStyle
= CapRound
;
1664 int joinStyle
= JoinRound
;
1665 switch (m_pen
.GetJoin())
1667 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1668 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1670 default: { joinStyle
= JoinRound
; break; }
1673 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1675 m_pen
.GetColour().CalcPixel( m_cmap
);
1676 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1679 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1681 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1683 if (m_brush
== brush
) return;
1687 if (!m_brush
.Ok()) return;
1689 if (!m_window
) return;
1691 m_brush
.GetColour().CalcPixel( m_cmap
);
1692 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1694 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1696 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1698 if (m_brush
.GetStipple()->GetPixmap())
1700 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1701 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1705 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1706 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1710 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1712 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1713 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1716 if (IS_HATCH(m_brush
.GetStyle()))
1718 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1719 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1720 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1724 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1726 /* CMB 21/7/98: Added SetBackground. Sets background brush
1727 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1729 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1731 if (m_backgroundBrush
== brush
) return;
1733 m_backgroundBrush
= brush
;
1735 if (!m_backgroundBrush
.Ok()) return;
1737 if (!m_window
) return;
1739 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1740 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1741 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1742 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1743 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1745 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1747 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1749 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1751 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1752 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1756 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1757 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
1761 if (IS_HATCH(m_backgroundBrush
.GetStyle()))
1763 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1764 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
1765 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
1769 void wxWindowDC::SetLogicalFunction( int function
)
1771 wxCHECK_RET( Ok(), "invalid dc" );
1775 if (m_logicalFunction
== function
)
1778 // VZ: shouldn't this be a CHECK?
1785 x_function
= GXclear
;
1791 x_function
= GXinvert
;
1794 x_function
= GXorReverse
;
1797 x_function
= GXandReverse
;
1806 x_function
= GXandInverted
;
1809 x_function
= GXnoop
;
1815 x_function
= GXequiv
;
1818 x_function
= GXcopyInverted
;
1821 x_function
= GXorInverted
;
1824 x_function
= GXnand
;
1831 x_function
= GXcopy
;
1835 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
1836 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
1838 // to stay compatible with wxMSW, we don't apply ROPs to the text
1839 // operations (i.e. DrawText/DrawRotatedText).
1840 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
1841 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
1843 m_logicalFunction
= function
;
1846 void wxWindowDC::SetTextForeground( const wxColour
&col
)
1848 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1850 // don't set m_textForegroundColour to an invalid colour as we'd crash
1851 // later then (we use m_textForegroundColour.GetColor() without checking
1853 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
1856 m_textForegroundColour
= col
;
1860 m_textForegroundColour
.CalcPixel( m_cmap
);
1861 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
1865 void wxWindowDC::SetTextBackground( const wxColour
&col
)
1867 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1870 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
1873 m_textBackgroundColour
= col
;
1877 m_textBackgroundColour
.CalcPixel( m_cmap
);
1878 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
1882 void wxWindowDC::SetBackgroundMode( int mode
)
1884 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1886 m_backgroundMode
= mode
;
1889 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
1892 if (!m_window
) return;
1894 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
1895 // transparent/solid background mode
1897 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
1899 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
1900 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
1904 void wxWindowDC::SetPalette( const wxPalette
& palette
)
1910 /* Use GetXColormap */
1911 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1912 (Colormap
) palette
.GetXColormap());
1914 /* Use wxGetMainColormap */
1915 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1916 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
1921 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
1923 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1925 if (!m_window
) return;
1928 rect
.x
= XLOG2DEV(x
);
1929 rect
.y
= YLOG2DEV(y
);
1930 rect
.width
= XLOG2DEVREL(width
);
1931 rect
.height
= YLOG2DEVREL(height
);
1933 if (!m_currentClippingRegion
.IsNull())
1934 m_currentClippingRegion
.Intersect( rect
);
1936 m_currentClippingRegion
.Union( rect
);
1938 #if USE_PAINT_REGION
1939 if (!m_paintClippingRegion
.IsNull())
1940 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
1943 wxCoord xx
, yy
, ww
, hh
;
1944 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
1945 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
1947 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1948 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1949 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1950 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1953 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
1955 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1959 DestroyClippingRegion();
1963 if (!m_window
) return;
1965 if (!m_currentClippingRegion
.IsNull())
1966 m_currentClippingRegion
.Intersect( region
);
1968 m_currentClippingRegion
.Union( region
);
1970 #if USE_PAINT_REGION
1971 if (!m_paintClippingRegion
.IsNull())
1972 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
1975 wxCoord xx
, yy
, ww
, hh
;
1976 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
1977 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
1979 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1980 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1981 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1982 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1985 void wxWindowDC::DestroyClippingRegion()
1987 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1989 wxDC::DestroyClippingRegion();
1991 m_currentClippingRegion
.Clear();
1993 #if USE_PAINT_REGION
1994 if (!m_paintClippingRegion
.IsEmpty())
1995 m_currentClippingRegion
.Union( m_paintClippingRegion
);
1998 if (!m_window
) return;
2000 if (m_currentClippingRegion
.IsEmpty())
2002 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2003 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2004 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2005 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2009 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2010 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2011 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2012 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2016 void wxWindowDC::Destroy()
2018 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2020 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2022 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2024 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2028 void wxWindowDC::ComputeScaleAndOrigin()
2030 /* CMB: copy scale to see if it changes */
2031 double origScaleX
= m_scaleX
;
2032 double origScaleY
= m_scaleY
;
2034 wxDC::ComputeScaleAndOrigin();
2036 /* CMB: if scale has changed call SetPen to recalulate the line width */
2037 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2040 /* this is a bit artificial, but we need to force wxDC to think
2041 the pen has changed */
2048 wxSize
wxWindowDC::GetPPI() const
2050 return wxSize(100, 100);
2053 int wxWindowDC::GetDepth() const
2055 wxFAIL_MSG(wxT("not implemented"));
2060 //-----------------------------------------------------------------------------
2062 //-----------------------------------------------------------------------------
2064 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2066 wxClientDC::wxClientDC( wxWindow
*window
)
2067 : wxWindowDC( window
)
2069 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2071 m_window
= (WXWindow
*) window
->GetClientWindow();
2073 #if wxUSE_TWO_WINDOWS
2075 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2076 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2077 wxSize size
= window
->GetClientSize();
2078 SetClippingRegion(wxPoint(0, 0), size
);
2082 void wxClientDC::DoGetSize(int *width
, int *height
) const
2084 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2086 m_owner
->GetClientSize( width
, height
);
2089 // ----------------------------------------------------------------------------
2091 // ----------------------------------------------------------------------------
2093 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2095 wxPaintDC::wxPaintDC(wxWindow
* window
)
2096 : wxClientDC(window
)
2098 #if USE_PAINT_REGION
2099 if (!window
->GetClipPaintRegion())
2102 m_paintClippingRegion
= window
->GetUpdateRegion();
2103 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2106 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2108 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2109 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2110 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2111 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2113 #endif // USE_PAINT_REGION
2116 // ----------------------------------------------------------------------------
2118 // ----------------------------------------------------------------------------
2120 class wxDCModule
: public wxModule
2127 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2130 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)
2132 bool wxDCModule::OnInit()
2138 void wxDCModule::OnExit()