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"
21 #include "wx/module.h"
22 #include "wx/fontutil.h"
24 #include "wx/x11/private.h"
30 #include "pango/pangox.h"
31 #include "pango/pangoxft.h"
33 #include "pango_x.cpp"
36 //-----------------------------------------------------------------------------
38 //-----------------------------------------------------------------------------
40 #define USE_PAINT_REGION 1
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
54 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH)
55 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH)
57 static Pixmap hatches
[num_hatches
];
58 static Pixmap
*hatch_bitmap
= (Pixmap
*) NULL
;
60 //-----------------------------------------------------------------------------
62 //-----------------------------------------------------------------------------
64 const double RAD2DEG
= 180.0 / M_PI
;
66 // ----------------------------------------------------------------------------
68 // ----------------------------------------------------------------------------
70 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
71 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
73 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
75 //-----------------------------------------------------------------------------
76 // Implement Pool of Graphic contexts. Creating them takes too much time.
77 //-----------------------------------------------------------------------------
79 #define GC_POOL_SIZE 200
105 static wxGC wxGCPool
[GC_POOL_SIZE
];
107 static void wxInitGCPool()
109 memset( wxGCPool
, 0, GC_POOL_SIZE
*sizeof(wxGC
) );
112 static void wxCleanUpGCPool()
114 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
116 if (wxGCPool
[i
].m_gc
)
117 XFreeGC( wxGlobalDisplay(), wxGCPool
[i
].m_gc
);
121 static GC
wxGetPoolGC( Window window
, wxPoolGCType type
)
123 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
125 if (!wxGCPool
[i
].m_gc
)
127 wxGCPool
[i
].m_gc
= XCreateGC( wxGlobalDisplay(), window
, 0, NULL
);
128 XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool
[i
].m_gc
, FALSE
);
129 wxGCPool
[i
].m_type
= type
;
130 wxGCPool
[i
].m_used
= FALSE
;
132 if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type
== type
))
134 wxGCPool
[i
].m_used
= TRUE
;
135 return wxGCPool
[i
].m_gc
;
139 wxFAIL_MSG( wxT("No GC available") );
144 static void wxFreePoolGC( GC gc
)
146 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
148 if (wxGCPool
[i
].m_gc
== gc
)
150 wxGCPool
[i
].m_used
= FALSE
;
155 wxFAIL_MSG( wxT("Wrong GC") );
158 // ----------------------------------------------------------------------------
160 // ----------------------------------------------------------------------------
162 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
164 wxWindowDC::wxWindowDC()
166 m_display
= (WXDisplay
*) NULL
;
167 m_penGC
= (WXGC
*) NULL
;
168 m_brushGC
= (WXGC
*) NULL
;
169 m_textGC
= (WXGC
*) NULL
;
170 m_bgGC
= (WXGC
*) NULL
;
171 m_cmap
= (WXColormap
*) NULL
;
173 m_isScreenDC
= FALSE
;
174 m_owner
= (wxWindow
*)NULL
;
177 m_context
= (PangoContext
*)NULL
;
178 m_fontdesc
= (PangoFontDescription
*)NULL
;
182 wxWindowDC::wxWindowDC( wxWindow
*window
)
184 wxASSERT_MSG( window
, wxT("DC needs a window") );
186 m_display
= (WXDisplay
*) NULL
;
187 m_penGC
= (WXGC
*) NULL
;
188 m_brushGC
= (WXGC
*) NULL
;
189 m_textGC
= (WXGC
*) NULL
;
190 m_bgGC
= (WXGC
*) NULL
;
191 m_cmap
= (WXColormap
*) NULL
;
192 m_owner
= (wxWindow
*)NULL
;
194 m_isScreenDC
= FALSE
;
195 m_font
= window
->GetFont();
197 m_window
= (WXWindow
*) window
->GetMainWindow();
202 // don't report problems
208 m_display
= (WXDisplay
*) wxGlobalDisplay();
211 m_context
= wxTheApp
->GetPangoContext();
212 m_fontdesc
= window
->GetFont().GetNativeFontInfo()->description
;
215 int screen
= DefaultScreen( (Display
*) m_display
);
216 m_cmap
= (WXColormap
) DefaultColormap( (Display
*) m_display
, screen
);
220 /* this must be done after SetUpDC, bacause SetUpDC calls the
221 repective SetBrush, SetPen, SetBackground etc functions
222 to set up the DC. SetBackground call m_owner->SetBackground
223 and this might not be desired as the standard dc background
224 is white whereas a window might assume gray to be the
225 standard (as e.g. wxStatusBar) */
230 wxWindowDC::~wxWindowDC()
235 void wxWindowDC::SetUpDC()
239 wxASSERT_MSG( !m_penGC
, wxT("GCs already created") );
243 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_SCREEN
);
244 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_SCREEN
);
245 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_SCREEN
);
246 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_SCREEN
);
249 if (m_isMemDC
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1))
251 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_MONO
);
252 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_MONO
);
253 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_MONO
);
254 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_MONO
);
258 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_COLOUR
);
259 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_COLOUR
);
260 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_COLOUR
);
261 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_COLOUR
);
264 /* background colour */
265 m_backgroundBrush
= *wxWHITE_BRUSH
;
266 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
267 unsigned long bg_col
= m_backgroundBrush
.GetColour().GetPixel();
270 m_textForegroundColour
.CalcPixel( m_cmap
);
271 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
273 m_textBackgroundColour
.CalcPixel( m_cmap
);
274 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
276 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
279 // By default, draw transparently
280 GrSetGCUseBackground((GC
) m_textGC
, FALSE
);
284 m_pen
.GetColour().CalcPixel( m_cmap
);
285 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
286 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
288 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
291 m_brush
.GetColour().CalcPixel( m_cmap
);
292 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
293 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
295 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
298 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
299 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
301 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
304 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
305 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
306 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
309 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
310 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
311 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
312 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
316 int xscreen
= DefaultScreen( (Display
*) m_display
);
317 Window xroot
= RootWindow( (Display
*) m_display
, xscreen
);
319 hatch_bitmap
= hatches
;
320 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, bdiag_bits
, bdiag_width
, bdiag_height
);
321 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cdiag_bits
, cdiag_width
, cdiag_height
);
322 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, fdiag_bits
, fdiag_width
, fdiag_height
);
323 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cross_bits
, cross_width
, cross_height
);
324 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, horiz_bits
, horiz_width
, horiz_height
);
325 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, verti_bits
, verti_width
, verti_height
);
329 void wxWindowDC::DoGetSize( int* width
, int* height
) const
331 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
333 m_owner
->GetSize(width
, height
);
336 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
337 const wxColour
& col
, int style
);
339 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
340 const wxColour
& col
, int style
)
342 return wxDoFloodFill(this, x
, y
, col
, style
);
345 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
347 // Generic (and therefore rather inefficient) method.
348 // Could be improved.
350 wxBitmap
bitmap(1, 1);
351 memdc
.SelectObject(bitmap
);
352 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
353 memdc
.SelectObject(wxNullBitmap
);
354 wxImage
image(bitmap
.ConvertToImage());
355 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
359 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
361 wxCHECK_RET( Ok(), wxT("invalid window dc") );
363 if (m_pen
.GetStyle() != wxTRANSPARENT
)
367 // This hack is for the iPaq: XDrawLine draws
368 // nothing, whereas XDrawLines works...
374 DrawLines( 2, points
, 0, 0 );
376 // XDrawLine( (Display*) m_display, (Window) m_window,
377 // (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
380 CalcBoundingBox(x1
, y1
);
381 CalcBoundingBox(x2
, y2
);
385 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
387 wxCHECK_RET( Ok(), wxT("invalid window dc") );
389 if (m_pen
.GetStyle() != wxTRANSPARENT
)
394 wxCoord xx
= XLOG2DEV(x
);
395 wxCoord yy
= YLOG2DEV(y
);
398 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
399 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
400 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
401 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
406 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
408 wxCHECK_RET( Ok(), wxT("invalid window dc") );
410 wxCoord xx1
= XLOG2DEV(x1
);
411 wxCoord yy1
= YLOG2DEV(y1
);
412 wxCoord xx2
= XLOG2DEV(x2
);
413 wxCoord yy2
= YLOG2DEV(y2
);
414 wxCoord xxc
= XLOG2DEV(xc
);
415 wxCoord yyc
= YLOG2DEV(yc
);
416 double dx
= xx1
- xxc
;
417 double dy
= yy1
- yyc
;
418 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
419 wxCoord r
= (wxCoord
)radius
;
420 double radius1
, radius2
;
422 if (xx1
== xx2
&& yy1
== yy2
)
430 radius1
= radius2
= 0.0;
434 radius1
= (xx1
- xxc
== 0) ?
435 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
436 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
437 radius2
= (xx2
- xxc
== 0) ?
438 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
439 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
441 wxCoord alpha1
= wxCoord(radius1
* 64.0);
442 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
443 while (alpha2
<= 0) alpha2
+= 360*64;
444 while (alpha1
> 360*64) alpha1
-= 360*64;
448 if (m_brush
.GetStyle() != wxTRANSPARENT
)
450 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
452 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
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_textGC
, 0, 0 );
461 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
463 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
464 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
466 XFillArc( (Display
*) m_display
, (Window
) m_window
,
467 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
469 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
471 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
473 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
474 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
476 XFillArc( (Display
*) m_display
, (Window
) m_window
,
477 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
479 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
481 if (m_brush
.GetStyle() == wxSTIPPLE
)
483 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
484 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
485 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
487 XFillArc( (Display
*) m_display
, (Window
) m_window
,
488 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
490 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
494 XFillArc( (Display
*) m_display
, (Window
) m_window
,
495 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
499 if (m_pen
.GetStyle() != wxTRANSPARENT
)
501 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
502 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
504 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
505 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
507 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
508 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
512 CalcBoundingBox (x1
, y1
);
513 CalcBoundingBox (x2
, y2
);
516 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
518 wxCHECK_RET( Ok(), wxT("invalid window dc") );
520 wxCoord xx
= XLOG2DEV(x
);
521 wxCoord yy
= YLOG2DEV(y
);
522 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
523 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
525 // CMB: handle -ve width and/or height
526 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
527 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
531 wxCoord start
= wxCoord(sa
* 64.0);
532 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
534 if (m_brush
.GetStyle() != wxTRANSPARENT
)
536 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
538 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
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_textGC
, xx
, yy
, ww
, hh
, start
, end
);
545 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
547 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
549 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
550 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
552 XFillArc( (Display
*) m_display
, (Window
) m_window
,
553 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
555 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
557 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
559 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
560 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
562 XFillArc( (Display
*) m_display
, (Window
) m_window
,
563 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
565 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
567 if (m_brush
.GetStyle() == wxSTIPPLE
)
569 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
570 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
571 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
573 XFillArc( (Display
*) m_display
, (Window
) m_window
,
574 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
576 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
580 XFillArc( (Display
*) m_display
, (Window
) m_window
,
581 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
585 if (m_pen
.GetStyle() != wxTRANSPARENT
)
587 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
588 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
592 CalcBoundingBox (x
, y
);
593 CalcBoundingBox (x
+ width
, y
+ height
);
596 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
598 wxCHECK_RET( Ok(), wxT("invalid window dc") );
600 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
)
601 XDrawPoint( (Display
*) m_display
, (Window
) m_window
,
602 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
604 CalcBoundingBox (x
, y
);
607 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
609 wxCHECK_RET( Ok(), wxT("invalid window dc") );
611 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
614 XPoint
*xpoints
= new XPoint
[n
];
615 for (int i
= 0; i
< n
; i
++)
617 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
618 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
620 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
622 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
, 0 );
627 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
628 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
630 wxCHECK_RET( Ok(), wxT("invalid window dc") );
634 XPoint
*xpoints
= new XPoint
[n
+ 1];
636 for (i
= 0; i
< n
; i
++)
638 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
639 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
641 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
646 if (m_brush
.GetStyle() != wxTRANSPARENT
)
649 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
651 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
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_textGC
, xpoints
, n
, Complex
, 0);
658 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
660 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
662 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
663 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
665 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
666 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
668 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
670 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
672 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
673 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
675 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
676 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
678 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
680 if (m_brush
.GetStyle() == wxSTIPPLE
)
682 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
683 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
684 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
686 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
687 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
689 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
693 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
694 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
698 if (m_pen
.GetStyle () != wxTRANSPARENT
)
700 // Close figure for XDrawLines
701 xpoints
[i
].x
= xpoints
[0].x
;
702 xpoints
[i
].y
= xpoints
[0].y
;
704 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
711 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
713 wxCHECK_RET( Ok(), wxT("invalid window dc") );
715 wxCoord xx
= XLOG2DEV(x
);
716 wxCoord yy
= YLOG2DEV(y
);
717 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
718 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
720 // CMB: draw nothing if transformed w or h is 0
721 if (ww
== 0 || hh
== 0) return;
723 // CMB: handle -ve width and/or height
724 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
725 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
729 if (m_brush
.GetStyle() != wxTRANSPARENT
)
731 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
733 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
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_textGC
, xx
, yy
, ww
, hh
);
740 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
742 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
744 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
745 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
747 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
748 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
750 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
752 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
754 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
755 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
757 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
758 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
760 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
762 if (m_brush
.GetStyle() == wxSTIPPLE
)
764 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
765 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
766 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
768 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
769 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
771 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
775 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
776 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
780 if (m_pen
.GetStyle () != wxTRANSPARENT
)
782 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
783 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
787 CalcBoundingBox( x
, y
);
788 CalcBoundingBox( x
+ width
, y
+ height
);
791 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
796 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
798 wxCHECK_RET( Ok(), wxT("invalid window dc") );
800 wxCoord xx
= XLOG2DEV(x
);
801 wxCoord yy
= YLOG2DEV(y
);
802 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
803 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
805 // CMB: handle -ve width and/or height
806 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
807 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
811 if (m_brush
.GetStyle() != wxTRANSPARENT
)
813 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
815 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
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_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
822 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
824 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
826 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
827 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
829 XFillArc( (Display
*) m_display
, (Window
) m_window
,
830 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
832 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
834 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
836 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
837 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
839 XFillArc( (Display
*) m_display
, (Window
) m_window
,
840 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
842 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
844 if (m_brush
.GetStyle() == wxSTIPPLE
)
846 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
847 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
848 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
850 XFillArc( (Display
*) m_display
, (Window
) m_window
,
851 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
853 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
857 XFillArc( (Display
*) m_display
, (Window
) m_window
,
858 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
862 if (m_pen
.GetStyle () != wxTRANSPARENT
)
864 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
865 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
869 CalcBoundingBox( x
, y
);
870 CalcBoundingBox( x
+ width
, y
+ height
);
873 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
875 DoDrawBitmap(icon
, x
, y
, TRUE
);
879 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
880 wxCoord x
, wxCoord y
,
883 wxCHECK_RET( Ok(), wxT("invalid window dc") );
885 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
887 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
889 /* scale/translate size and position */
890 int xx
= XLOG2DEV(x
);
891 int yy
= YLOG2DEV(y
);
893 int w
= bitmap
.GetWidth();
894 int h
= bitmap
.GetHeight();
896 CalcBoundingBox( x
, y
);
897 CalcBoundingBox( x
+ w
, y
+ h
);
899 if (!m_window
) return;
901 int ww
= XLOG2DEVREL(w
);
902 int hh
= YLOG2DEVREL(h
);
904 /* compare to current clipping region */
905 if (!m_currentClippingRegion
.IsNull())
907 wxRegion
tmp( xx
,yy
,ww
,hh
);
908 tmp
.Intersect( m_currentClippingRegion
);
913 /* scale bitmap if required */
915 if ((w
!= ww
) || (h
!= hh
))
917 wxImage
image( bitmap
.ConvertToImage() );
918 image
.Rescale( ww
, hh
);
921 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
931 /* apply mask if any */
932 WXPixmap mask
= NULL
;
933 if (use_bitmap
.GetMask())
934 mask
= use_bitmap
.GetMask()->GetBitmap();
938 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
939 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
940 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
942 GrSetGCUseBackground(gc
, FALSE
);
943 GrSetGCMode(gc
, GR_MODE_COPY
);
945 // This code assumes that background and foreground
946 // colours are used in ROPs, like in MSW.
947 // Not sure if this is true.
949 // Copy destination to buffer.
950 // In DoBlit, we need this step because Blit has
951 // a ROP argument. Here, we don't need it.
952 // In DoBlit, we may be able to eliminate this step
953 // if we check if the rop = copy
955 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_window
,
959 // Copy src to buffer using selected raster op (none selected
960 // in DrawBitmap, so just use Gxcopy)
961 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
964 // Set masked area in buffer to BLACK (pixel value 0)
965 GrSetGCBackground(gc
, WHITE
);
966 GrSetGCForeground(gc
, BLACK
);
967 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
970 // set unmasked area in dest to BLACK
971 GrSetGCBackground(gc
, BLACK
);
972 GrSetGCForeground(gc
, WHITE
);
973 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
977 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
981 GrDestroyWindow(bufPixmap
);
984 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
985 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
987 /* remove mask again if any */
990 if (!m_currentClippingRegion
.IsNull())
991 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
998 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
999 wxCoord x
, wxCoord y
,
1002 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1004 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1006 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1008 // scale/translate size and position
1009 int xx
= XLOG2DEV(x
);
1010 int yy
= YLOG2DEV(y
);
1012 int w
= bitmap
.GetWidth();
1013 int h
= bitmap
.GetHeight();
1015 CalcBoundingBox( x
, y
);
1016 CalcBoundingBox( x
+ w
, y
+ h
);
1018 if (!m_window
) return;
1020 int ww
= XLOG2DEVREL(w
);
1021 int hh
= YLOG2DEVREL(h
);
1023 // compare to current clipping region
1024 if (!m_currentClippingRegion
.IsNull())
1026 wxRegion
tmp( xx
,yy
,ww
,hh
);
1027 tmp
.Intersect( m_currentClippingRegion
);
1032 // scale bitmap if required
1033 wxBitmap use_bitmap
;
1034 if ((w
!= ww
) || (h
!= hh
))
1036 wxImage
image( bitmap
.ConvertToImage() );
1037 image
.Rescale( ww
, hh
);
1040 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1047 use_bitmap
= bitmap
;
1050 // apply mask if any
1051 WXPixmap mask
= NULL
;
1052 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1054 if (useMask
&& mask
)
1056 WXPixmap new_mask
= NULL
;
1058 if (!m_currentClippingRegion
.IsNull())
1061 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 );
1062 GdkGC
*gc
= gdk_gc_new( new_mask
);
1064 gdk_gc_set_foreground( gc
, &col
);
1065 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1067 gdk_gc_set_background( gc
, &col
);
1069 gdk_gc_set_foreground( gc
, &col
);
1070 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1071 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1072 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1073 gdk_gc_set_stipple( gc
, mask
);
1074 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1081 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1083 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1084 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1089 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1091 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1092 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1096 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1099 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1100 // drawing a mono-bitmap (XBitmap) we use the current text GC
1102 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1103 (GC
) m_textGC
, 0, 0, w
, h
, xx
, yy
, 1 );
1105 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1106 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1108 // remove mask again if any
1109 if (useMask
&& mask
)
1113 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1114 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1115 if (!m_currentClippingRegion
.IsNull())
1116 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1120 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1121 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1122 if (!m_currentClippingRegion
.IsNull())
1123 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1128 // wxUSE_NANOX/!wxUSE_NANOX
1130 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1131 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1132 wxCoord xsrcMask
, wxCoord ysrcMask
)
1134 /* this is the nth try to get this utterly useless function to
1135 work. it now completely ignores the scaling or translation
1136 of the source dc, but scales correctly on the target dc and
1137 knows about possible mask information in a memory dc. */
1139 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid window dc") );
1141 wxCHECK_MSG( source
, FALSE
, wxT("invalid source dc") );
1143 if (!m_window
) return FALSE
;
1145 // transform the source DC coords to the device ones
1146 xsrc
= source
->XLOG2DEV(xsrc
);
1147 ysrc
= source
->YLOG2DEV(ysrc
);
1149 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1150 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1152 bool use_bitmap_method
= FALSE
;
1153 bool is_mono
= FALSE
;
1155 // TODO: use the mask origin when drawing transparently
1156 if (xsrcMask
== -1 && ysrcMask
== -1)
1162 if (srcDC
->m_isMemDC
)
1164 if (!memDC
->m_selected
.Ok()) return FALSE
;
1166 /* we use the "XCopyArea" way to copy a memory dc into
1167 y different window if the memory dc BOTH
1168 a) doesn't have any mask or its mask isn't used
1172 if (useMask
&& (memDC
->m_selected
.GetMask()))
1174 /* we HAVE TO use the direct way for memory dcs
1175 that have mask since the XCopyArea doesn't know
1177 use_bitmap_method
= TRUE
;
1179 else if (memDC
->m_selected
.GetDepth() == 1)
1181 /* we HAVE TO use the direct way for memory dcs
1182 that are bitmaps because XCopyArea doesn't cope
1183 with different bit depths */
1185 use_bitmap_method
= TRUE
;
1187 else if ((xsrc
== 0) && (ysrc
== 0) &&
1188 (width
== memDC
->m_selected
.GetWidth()) &&
1189 (height
== memDC
->m_selected
.GetHeight()))
1191 /* we SHOULD use the direct way if all of the bitmap
1192 in the memory dc is copied in which case XCopyArea
1193 wouldn't be able able to boost performace by reducing
1194 the area to be scaled */
1195 use_bitmap_method
= TRUE
;
1199 use_bitmap_method
= FALSE
;
1203 CalcBoundingBox( xdest
, ydest
);
1204 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1206 // scale/translate size and position
1207 wxCoord xx
= XLOG2DEV(xdest
);
1208 wxCoord yy
= YLOG2DEV(ydest
);
1210 wxCoord ww
= XLOG2DEVREL(width
);
1211 wxCoord hh
= YLOG2DEVREL(height
);
1213 // compare to current clipping region
1214 if (!m_currentClippingRegion
.IsNull())
1216 wxRegion
tmp( xx
,yy
,ww
,hh
);
1217 tmp
.Intersect( m_currentClippingRegion
);
1222 int old_logical_func
= m_logicalFunction
;
1223 SetLogicalFunction( logical_func
);
1225 if (use_bitmap_method
)
1227 // scale/translate bitmap size
1228 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1229 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1231 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1232 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1234 // scale bitmap if required
1235 wxBitmap use_bitmap
;
1237 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1239 wxImage
image( memDC
->m_selected
.ConvertToImage() );
1240 image
= image
.Scale( bm_ww
, bm_hh
);
1244 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1251 use_bitmap
= memDC
->m_selected
;
1254 // apply mask if any
1255 WXPixmap mask
= NULL
;
1256 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1258 if (useMask
&& mask
)
1260 WXPixmap new_mask
= NULL
;
1262 if (!m_currentClippingRegion
.IsNull())
1265 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1266 GdkGC
*gc
= gdk_gc_new( new_mask
);
1268 gdk_gc_set_foreground( gc
, &col
);
1269 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1271 gdk_gc_set_background( gc
, &col
);
1273 gdk_gc_set_foreground( gc
, &col
);
1274 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1275 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1276 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1277 gdk_gc_set_stipple( gc
, mask
);
1278 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1285 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1287 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1288 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1293 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1295 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1296 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1300 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1303 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1304 // drawing a mono-bitmap (XBitmap) we use the current text GC
1307 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1308 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1310 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1311 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1313 // remove mask again if any
1314 if (useMask
&& mask
)
1318 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1319 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1320 if (!m_currentClippingRegion
.IsNull())
1321 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1325 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1326 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1327 if (!m_currentClippingRegion
.IsNull())
1328 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1332 else // use_bitmap_method
1334 if ((width
!= ww
) || (height
!= hh
))
1336 /* Draw source window into a bitmap as we cannot scale
1337 a window in contrast to a bitmap. this would actually
1338 work with memory dcs as well, but we'd lose the mask
1339 information and waste one step in this process since
1340 a memory already has a bitmap. all this is slightly
1341 inefficient as we could take an XImage directly from
1342 an X window, but we'd then also have to care that
1343 the window is not outside the screen (in which case
1344 we'd get a BadMatch or what not).
1345 Is a double XGetImage and combined XGetPixel and
1346 XPutPixel really faster? I'm not sure. look at wxXt
1347 for a different implementation of the same problem. */
1349 wxBitmap
bitmap( width
, height
);
1351 // copy including child window contents
1352 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1353 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) bitmap
.GetPixmap(),
1354 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1355 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1358 wxImage
image( bitmap
.ConvertToImage() );
1359 image
= image
.Scale( ww
, hh
);
1361 // convert to bitmap
1364 // draw scaled bitmap
1365 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_window
,
1366 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1370 // No scaling and not a memory dc with a mask either
1372 // copy including child window contents
1373 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1374 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) m_window
,
1375 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1376 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1380 SetLogicalFunction( old_logical_func
);
1385 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1387 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1389 if (!m_window
) return;
1395 PangoLayout
*layout
= pango_layout_new(m_context
);
1396 pango_layout_set_font_description(layout
, m_fontdesc
);
1398 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1399 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1403 pango_layout_get_pixel_size(layout
, &w
, &h
);
1408 x11_draw_layout( (Drawable
) m_window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1410 g_object_unref( G_OBJECT( layout
) );
1412 CalcBoundingBox (x
+ width
, y
+ height
);
1413 CalcBoundingBox (x
, y
);
1415 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1417 wxCHECK_RET( xfont
, wxT("invalid font") );
1419 // First draw a rectangle representing the text background, if a text
1420 // background is specified
1421 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1423 // Since X draws from the baseline of the text, must add the text height
1428 int direction
, descent
;
1430 slen
= strlen(text
);
1431 XCharStruct overall_return
;
1433 (void)XTextExtents(xfont
, (char*) text
.c_str(), slen
, &direction
,
1434 &ascent
, &descent
, &overall_return
);
1436 cx
= overall_return
.width
;
1437 cy
= ascent
+ descent
;
1438 m_textBackgroundColour
.CalcPixel(m_cmap
);
1439 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1440 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
1441 (GC
) m_textGC
, x
, y
, cx
, cy
);
1442 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1446 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1448 if ((xfont
->min_byte1
== 0) && (xfont
->max_byte1
== 0))
1451 XDrawString( (Display
*) m_display
, (Window
) m_window
,
1452 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.Len() );
1456 if (m_font
.GetUnderlined())
1458 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1459 if (font
->descent
> 0) ul_y
++;
1460 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1463 width
= wxCoord(width
/ m_scaleX
);
1464 height
= wxCoord(height
/ m_scaleY
);
1466 CalcBoundingBox (x
+ width
, y
+ height
);
1467 CalcBoundingBox (x
, y
);
1472 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
, double angle
)
1477 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1478 wxCoord
*descent
, wxCoord
*externalLeading
,
1479 wxFont
*font
) const
1481 wxCHECK_RET( Ok(), "invalid dc" );
1483 if (string
.IsEmpty())
1485 if (width
) (*width
) = 0;
1486 if (height
) (*height
) = 0;
1491 PangoLayout
*layout
= pango_layout_new( m_context
);
1494 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1496 pango_layout_set_font_description(layout
, m_fontdesc
);
1498 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1499 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1503 pango_layout_get_pixel_size(layout
, &w
, &h
);
1505 if (width
) (*width
) = (wxCoord
) w
;
1506 if (height
) (*height
) = (wxCoord
) h
;
1509 // Do something about metrics here. TODO.
1512 if (externalLeading
) (*externalLeading
) = 0; // ??
1514 g_object_unref( G_OBJECT( layout
) );
1516 wxFont fontToUse
= m_font
;
1517 if (font
) fontToUse
= *font
;
1519 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
1521 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1523 wxCHECK_RET( xfont
, wxT("invalid font") );
1525 int direction
, ascent
, descent2
;
1526 XCharStruct overall
;
1528 XTextExtents( xfont
, (char*) string
.c_str(), string
.Len(), &direction
,
1529 &ascent
, &descent2
, &overall
);
1532 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1534 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1536 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1537 if (externalLeading
)
1538 *externalLeading
= 0; // ??
1542 wxCoord
wxWindowDC::GetCharWidth() const
1544 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1547 PangoLayout
*layout
= pango_layout_new( m_context
);
1555 pango_layout_set_font_description(layout
, m_fontdesc
);
1556 pango_layout_set_text(layout
, "H", 1 );
1558 pango_layout_get_pixel_size(layout
, &w
, &h
);
1559 g_object_unref( G_OBJECT( layout
) );
1563 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1565 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1567 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1569 int direction
, ascent
, descent
;
1570 XCharStruct overall
;
1572 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1574 return (wxCoord
)(overall
.width
/ m_scaleX
);
1578 wxCoord
wxWindowDC::GetCharHeight() const
1580 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1583 PangoLayout
*layout
= pango_layout_new( m_context
);
1591 pango_layout_set_font_description(layout
, m_fontdesc
);
1593 pango_layout_set_text(layout
, "H", 1 );
1595 pango_layout_get_pixel_size(layout
, &w
, &h
);
1596 g_object_unref( G_OBJECT( layout
) );
1600 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1602 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1604 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1606 int direction
, ascent
, descent
;
1607 XCharStruct overall
;
1609 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1611 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1615 void wxWindowDC::Clear()
1617 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1619 if (!m_window
) return;
1621 /* - we either are a memory dc or have a window as the
1622 owner. anything else shouldn't happen.
1623 - we don't use gdk_window_clear() as we don't set
1624 the window's background colour anymore. it is too
1625 much pain to keep the DC's and the window's back-
1626 ground colour in synch. */
1631 m_owner
->GetSize( &width
, &height
);
1632 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1639 GetSize( &width
, &height
);
1640 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1645 void wxWindowDC::SetFont( const wxFont
&font
)
1647 wxCHECK_RET( Ok(), "invalid dc" );
1652 void wxWindowDC::SetPen( const wxPen
&pen
)
1654 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1656 if (m_pen
== pen
) return;
1660 if (!m_pen
.Ok()) return;
1662 if (!m_window
) return;
1664 int width
= m_pen
.GetWidth();
1667 // CMB: if width is non-zero scale it with the dc
1672 // X doesn't allow different width in x and y and so we take
1675 ( fabs((double) XLOG2DEVREL(width
)) +
1676 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1680 static const wxX11Dash dotted
[] = {1, 1};
1681 static const wxX11Dash short_dashed
[] = {2, 2};
1682 static const wxX11Dash long_dashed
[] = {2, 4};
1683 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1685 // We express dash pattern in pen width unit, so we are
1686 // independent of zoom factor and so on...
1688 const wxX11Dash
*req_dash
;
1690 int lineStyle
= LineSolid
;
1691 switch (m_pen
.GetStyle())
1695 lineStyle
= LineOnOffDash
;
1696 req_nb_dash
= m_pen
.GetDashCount();
1697 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1702 lineStyle
= LineOnOffDash
;
1709 lineStyle
= LineOnOffDash
;
1711 req_dash
= long_dashed
;
1716 lineStyle
= LineOnOffDash
;
1718 req_dash
= short_dashed
;
1723 // lineStyle = LineDoubleDash;
1724 lineStyle
= LineOnOffDash
;
1726 req_dash
= dotted_dashed
;
1731 case wxSTIPPLE_MASK_OPAQUE
:
1736 lineStyle
= LineSolid
;
1737 req_dash
= (wxX11Dash
*)NULL
;
1743 int capStyle
= CapRound
;
1744 switch (m_pen
.GetCap())
1746 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1747 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1754 capStyle
= CapNotLast
;
1758 capStyle
= CapRound
;
1764 int joinStyle
= JoinRound
;
1765 switch (m_pen
.GetJoin())
1767 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1768 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1770 default: { joinStyle
= JoinRound
; break; }
1773 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1775 m_pen
.GetColour().CalcPixel( m_cmap
);
1776 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1779 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1781 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1783 if (m_brush
== brush
) return;
1787 if (!m_brush
.Ok()) return;
1789 if (!m_window
) return;
1791 m_brush
.GetColour().CalcPixel( m_cmap
);
1792 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1794 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1796 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1798 if (m_brush
.GetStipple()->GetPixmap())
1800 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1801 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1805 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1806 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1810 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1812 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1813 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1816 if (IS_HATCH(m_brush
.GetStyle()))
1818 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1819 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1820 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1824 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1826 /* CMB 21/7/98: Added SetBackground. Sets background brush
1827 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1829 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1831 if (m_backgroundBrush
== brush
) return;
1833 m_backgroundBrush
= brush
;
1835 if (!m_backgroundBrush
.Ok()) return;
1837 if (!m_window
) return;
1839 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1840 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1841 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1842 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1843 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1845 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1847 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1849 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1851 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1852 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1856 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1857 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
1861 if (IS_HATCH(m_backgroundBrush
.GetStyle()))
1863 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1864 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
1865 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
1869 void wxWindowDC::SetLogicalFunction( int function
)
1871 wxCHECK_RET( Ok(), "invalid dc" );
1875 if (m_logicalFunction
== function
)
1878 // VZ: shouldn't this be a CHECK?
1885 x_function
= GXclear
;
1891 x_function
= GXinvert
;
1894 x_function
= GXorReverse
;
1897 x_function
= GXandReverse
;
1906 x_function
= GXandInverted
;
1909 x_function
= GXnoop
;
1915 x_function
= GXequiv
;
1918 x_function
= GXcopyInverted
;
1921 x_function
= GXorInverted
;
1924 x_function
= GXnand
;
1931 x_function
= GXcopy
;
1935 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
1936 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
1938 // to stay compatible with wxMSW, we don't apply ROPs to the text
1939 // operations (i.e. DrawText/DrawRotatedText).
1940 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
1941 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
1943 m_logicalFunction
= function
;
1946 void wxWindowDC::SetTextForeground( const wxColour
&col
)
1948 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1950 // don't set m_textForegroundColour to an invalid colour as we'd crash
1951 // later then (we use m_textForegroundColour.GetColor() without checking
1953 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
1956 m_textForegroundColour
= col
;
1960 m_textForegroundColour
.CalcPixel( m_cmap
);
1961 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
1965 void wxWindowDC::SetTextBackground( const wxColour
&col
)
1967 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1970 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
1973 m_textBackgroundColour
= col
;
1977 m_textBackgroundColour
.CalcPixel( m_cmap
);
1978 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
1982 void wxWindowDC::SetBackgroundMode( int mode
)
1984 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1986 m_backgroundMode
= mode
;
1989 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
1992 if (!m_window
) return;
1994 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
1995 // transparent/solid background mode
1997 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
1999 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2000 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2004 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2010 /* Use GetXColormap */
2011 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2012 (Colormap
) palette
.GetXColormap());
2014 /* Use wxGetMainColormap */
2015 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2016 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2021 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2023 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2025 if (!m_window
) return;
2028 rect
.x
= XLOG2DEV(x
);
2029 rect
.y
= YLOG2DEV(y
);
2030 rect
.width
= XLOG2DEVREL(width
);
2031 rect
.height
= YLOG2DEVREL(height
);
2033 if (!m_currentClippingRegion
.IsNull())
2034 m_currentClippingRegion
.Intersect( rect
);
2036 m_currentClippingRegion
.Union( rect
);
2038 #if USE_PAINT_REGION
2039 if (!m_paintClippingRegion
.IsNull())
2040 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2043 wxCoord xx
, yy
, ww
, hh
;
2044 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2045 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2047 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2048 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2049 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2050 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2053 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2055 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2059 DestroyClippingRegion();
2063 if (!m_window
) return;
2065 if (!m_currentClippingRegion
.IsNull())
2066 m_currentClippingRegion
.Intersect( region
);
2068 m_currentClippingRegion
.Union( region
);
2070 #if USE_PAINT_REGION
2071 if (!m_paintClippingRegion
.IsNull())
2072 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2075 wxCoord xx
, yy
, ww
, hh
;
2076 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2077 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2079 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2080 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2081 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2082 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2085 void wxWindowDC::DestroyClippingRegion()
2087 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2089 wxDC::DestroyClippingRegion();
2091 m_currentClippingRegion
.Clear();
2093 #if USE_PAINT_REGION
2094 if (!m_paintClippingRegion
.IsEmpty())
2095 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2098 if (!m_window
) return;
2100 if (m_currentClippingRegion
.IsEmpty())
2102 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2103 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2104 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2105 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2109 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2110 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2111 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2112 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2116 void wxWindowDC::Destroy()
2118 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2120 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2122 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2124 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2128 void wxWindowDC::ComputeScaleAndOrigin()
2130 /* CMB: copy scale to see if it changes */
2131 double origScaleX
= m_scaleX
;
2132 double origScaleY
= m_scaleY
;
2134 wxDC::ComputeScaleAndOrigin();
2136 /* CMB: if scale has changed call SetPen to recalulate the line width */
2137 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2140 /* this is a bit artificial, but we need to force wxDC to think
2141 the pen has changed */
2148 wxSize
wxWindowDC::GetPPI() const
2150 return wxSize(100, 100);
2153 int wxWindowDC::GetDepth() const
2155 wxFAIL_MSG(wxT("not implemented"));
2160 //-----------------------------------------------------------------------------
2162 //-----------------------------------------------------------------------------
2164 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2166 wxClientDC::wxClientDC( wxWindow
*window
)
2167 : wxWindowDC( window
)
2169 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2171 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2173 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2174 if (m_window
== (WXWindow
*) window
->GetMainWindow())
2176 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2177 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2178 wxSize size
= window
->GetClientSize();
2179 SetClippingRegion(wxPoint(0, 0), size
);
2183 void wxClientDC::DoGetSize(int *width
, int *height
) const
2185 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2187 m_owner
->GetClientSize( width
, height
);
2190 // ----------------------------------------------------------------------------
2192 // ----------------------------------------------------------------------------
2194 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2196 wxPaintDC::wxPaintDC(wxWindow
* window
)
2197 : wxClientDC(window
)
2199 #if USE_PAINT_REGION
2200 if (!window
->GetClipPaintRegion())
2203 m_paintClippingRegion
= window
->GetUpdateRegion();
2204 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2207 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2209 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2210 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2211 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2212 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2214 #endif // USE_PAINT_REGION
2217 // ----------------------------------------------------------------------------
2219 // ----------------------------------------------------------------------------
2221 class wxDCModule
: public wxModule
2228 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2231 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)
2233 bool wxDCModule::OnInit()
2239 void wxDCModule::OnExit()