1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/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 /////////////////////////////////////////////////////////////////////////////
12 // for compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
15 #include "wx/dcclient.h"
19 #include "wx/window.h"
22 #include "wx/module.h"
25 #include "wx/fontutil.h"
26 #include "wx/vector.h"
28 #include "wx/x11/private.h"
29 #include "wx/x11/dcclient.h"
30 #include "wx/x11/dcmemory.h"
34 #include "pango/pangox.h"
36 #include "pango/pangoxft.h"
39 #include "pango_x.cpp"
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
46 // VZ: what is this for exactly??
47 #define USE_PAINT_REGION 0
49 //-----------------------------------------------------------------------------
51 //-----------------------------------------------------------------------------
61 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH)
62 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH)
64 static Pixmap hatches
[num_hatches
];
65 static Pixmap
*hatch_bitmap
= (Pixmap
*) NULL
;
67 //-----------------------------------------------------------------------------
69 //-----------------------------------------------------------------------------
71 const double RAD2DEG
= 180.0 / M_PI
;
73 // ----------------------------------------------------------------------------
75 // ----------------------------------------------------------------------------
77 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
78 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
80 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
82 //-----------------------------------------------------------------------------
83 // Implement Pool of Graphic contexts. Creating them takes too much time.
84 //-----------------------------------------------------------------------------
86 #define GC_POOL_SIZE 200
112 static wxGC wxGCPool
[GC_POOL_SIZE
];
114 static void wxInitGCPool()
116 memset( wxGCPool
, 0, GC_POOL_SIZE
*sizeof(wxGC
) );
119 static void wxCleanUpGCPool()
121 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
123 if (wxGCPool
[i
].m_gc
)
124 XFreeGC( wxGlobalDisplay(), wxGCPool
[i
].m_gc
);
128 static GC
wxGetPoolGC( Window window
, wxPoolGCType type
)
130 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
132 if (!wxGCPool
[i
].m_gc
)
134 wxGCPool
[i
].m_gc
= XCreateGC( wxGlobalDisplay(), window
, 0, NULL
);
135 XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool
[i
].m_gc
, FALSE
);
136 wxGCPool
[i
].m_type
= type
;
137 wxGCPool
[i
].m_used
= false;
139 if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type
== type
))
141 wxGCPool
[i
].m_used
= true;
142 return wxGCPool
[i
].m_gc
;
146 wxFAIL_MSG( wxT("No GC available") );
151 static void wxFreePoolGC( GC gc
)
153 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
155 if (wxGCPool
[i
].m_gc
== gc
)
157 wxGCPool
[i
].m_used
= false;
162 wxFAIL_MSG( wxT("Wrong GC") );
165 // ----------------------------------------------------------------------------
167 // ----------------------------------------------------------------------------
169 IMPLEMENT_ABSTRACT_CLASS(wxWindowDCImpl
, wxX11DCImpl
)
171 wxWindowDCImpl::wxWindowDCImpl( wxDC
*owner
)
172 : wxX11DCImpl( owner
)
177 wxWindowDCImpl::wxWindowDCImpl( wxDC
* owner
, wxWindow
*window
)
178 : wxX11DCImpl( owner
)
180 wxASSERT_MSG( window
, wxT("DC needs a window") );
184 m_font
= window
->GetFont();
186 m_x11window
= (WXWindow
*) window
->GetMainWindow();
191 // don't report problems
197 m_display
= (WXDisplay
*) wxGlobalDisplay();
200 m_fontdesc
= window
->GetFont().GetNativeFontInfo()->description
;
203 int screen
= DefaultScreen( (Display
*) m_display
);
204 m_cmap
= (WXColormap
) DefaultColormap( (Display
*) m_display
, screen
);
208 /* this must be done after SetUpDC, bacause SetUpDC calls the
209 repective SetBrush, SetPen, SetBackground etc functions
210 to set up the DC. SetBackground call m_window->SetBackground
211 and this might not be desired as the standard dc background
212 is white whereas a window might assume gray to be the
213 standard (as e.g. wxStatusBar) */
218 wxWindowDCImpl::~wxWindowDCImpl()
223 void wxWindowDCImpl::Init()
225 m_display
= (WXDisplay
*) NULL
;
226 m_penGC
= (WXGC
*) NULL
;
227 m_brushGC
= (WXGC
*) NULL
;
228 m_textGC
= (WXGC
*) NULL
;
229 m_bgGC
= (WXGC
*) NULL
;
230 m_cmap
= (WXColormap
*) NULL
;
232 m_isScreenDC
= false;
233 m_x11window
= (WXWindow
*) NULL
;
236 m_context
= wxTheApp
->GetPangoContext();
237 m_fontdesc
= (PangoFontDescription
*)NULL
;
241 void wxWindowDCImpl::SetUpDC()
245 wxASSERT_MSG( !m_penGC
, wxT("GCs already created") );
250 wxMemoryDCImpl
*mem_impl
= (wxMemoryDCImpl
*) this;
251 if (mem_impl
->GetSelectedBitmap().IsOk())
252 ismono
= mem_impl
->GetSelectedBitmap().GetDepth() == 1;
257 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxPEN_SCREEN
);
258 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxBRUSH_SCREEN
);
259 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxTEXT_SCREEN
);
260 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxBG_SCREEN
);
263 if (m_isMemDC
&& ismono
)
265 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxPEN_MONO
);
266 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxBRUSH_MONO
);
267 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxTEXT_MONO
);
268 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxBG_MONO
);
272 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxPEN_COLOUR
);
273 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxBRUSH_COLOUR
);
274 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxTEXT_COLOUR
);
275 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxBG_COLOUR
);
278 /* background colour */
279 m_backgroundBrush
= *wxWHITE_BRUSH
;
280 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
281 unsigned long bg_col
= m_backgroundBrush
.GetColour().GetPixel();
283 m_textForegroundColour
= *wxBLACK
;
284 m_textBackgroundColour
= *wxWHITE
;
287 m_textForegroundColour
.CalcPixel( m_cmap
);
288 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
290 m_textBackgroundColour
.CalcPixel( m_cmap
);
291 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
293 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
296 // By default, draw transparently
297 GrSetGCUseBackground((GC
) m_textGC
, FALSE
);
301 m_pen
.GetColour().CalcPixel( m_cmap
);
302 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
303 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
305 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
308 m_brush
.GetColour().CalcPixel( m_cmap
);
309 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
310 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
312 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
315 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
316 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
318 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
321 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
322 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
323 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
326 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
327 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
328 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
329 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
333 int xscreen
= DefaultScreen( (Display
*) m_display
);
334 Window xroot
= RootWindow( (Display
*) m_display
, xscreen
);
336 hatch_bitmap
= hatches
;
337 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, bdiag_bits
, bdiag_width
, bdiag_height
);
338 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cdiag_bits
, cdiag_width
, cdiag_height
);
339 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, fdiag_bits
, fdiag_width
, fdiag_height
);
340 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cross_bits
, cross_width
, cross_height
);
341 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, horiz_bits
, horiz_width
, horiz_height
);
342 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, verti_bits
, verti_width
, verti_height
);
346 void wxWindowDCImpl::DoGetSize( int* width
, int* height
) const
348 wxCHECK_RET( m_window
, _T("GetSize() doesn't work without window") );
350 m_window
->GetSize(width
, height
);
353 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
354 const wxColour
& col
, int style
);
356 bool wxWindowDCImpl::DoFloodFill(wxCoord x
, wxCoord y
,
357 const wxColour
& col
, int style
)
359 return wxDoFloodFill(GetOwner(), x
, y
, col
, style
);
362 bool wxWindowDCImpl::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
364 // Generic (and therefore rather inefficient) method.
365 // Could be improved.
367 wxBitmap
bitmap(1, 1);
368 memdc
.SelectObject(bitmap
);
369 memdc
.Blit(0, 0, 1, 1, GetOwner(), x1
, y1
);
370 memdc
.SelectObject(wxNullBitmap
);
371 wxImage
image(bitmap
.ConvertToImage());
372 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
376 void wxWindowDCImpl::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
378 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
380 if (m_pen
.GetStyle() != wxTRANSPARENT
)
384 // This hack is for the iPaq: XDrawLine draws
385 // nothing, whereas XDrawLines works...
391 DoDrawLines( 2, points
, 0, 0 );
393 // XDrawLine( (Display*) m_display, (Window) m_x11window,
394 // (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
397 CalcBoundingBox(x1
, y1
);
398 CalcBoundingBox(x2
, y2
);
402 void wxWindowDCImpl::DoCrossHair( wxCoord x
, wxCoord y
)
404 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
406 if (m_pen
.GetStyle() != wxTRANSPARENT
)
411 wxCoord xx
= XLOG2DEV(x
);
412 wxCoord yy
= YLOG2DEV(y
);
415 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
,
416 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
417 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
,
418 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
423 void wxWindowDCImpl::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
425 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
427 wxCoord xx1
= XLOG2DEV(x1
);
428 wxCoord yy1
= YLOG2DEV(y1
);
429 wxCoord xx2
= XLOG2DEV(x2
);
430 wxCoord yy2
= YLOG2DEV(y2
);
431 wxCoord xxc
= XLOG2DEV(xc
);
432 wxCoord yyc
= YLOG2DEV(yc
);
433 double dx
= xx1
- xxc
;
434 double dy
= yy1
- yyc
;
435 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
436 wxCoord r
= (wxCoord
)radius
;
437 double radius1
, radius2
;
439 if (xx1
== xx2
&& yy1
== yy2
)
447 radius1
= radius2
= 0.0;
451 radius1
= (xx1
- xxc
== 0) ?
452 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
453 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
454 radius2
= (xx2
- xxc
== 0) ?
455 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
456 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
458 wxCoord alpha1
= wxCoord(radius1
* 64.0);
459 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
460 while (alpha2
<= 0) alpha2
+= 360*64;
461 while (alpha1
> 360*64) alpha1
-= 360*64;
465 if (m_brush
.GetStyle() != wxTRANSPARENT
)
467 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
469 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
470 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
471 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
473 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
474 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
476 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
478 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
480 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
481 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
483 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
484 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
486 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
488 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
490 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
491 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
493 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
494 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
496 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
498 if (m_brush
.GetStyle() == wxSTIPPLE
)
500 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
501 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
502 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
504 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
505 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
507 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
511 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
512 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
516 if (m_pen
.GetStyle() != wxTRANSPARENT
)
518 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
,
519 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
521 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
,
522 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
524 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
,
525 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
529 CalcBoundingBox (x1
, y1
);
530 CalcBoundingBox (x2
, y2
);
533 void wxWindowDCImpl::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
535 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
537 wxCoord xx
= XLOG2DEV(x
);
538 wxCoord yy
= YLOG2DEV(y
);
539 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
540 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
542 // CMB: handle -ve width and/or height
543 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
544 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
548 wxCoord start
= wxCoord(sa
* 64.0);
549 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
551 if (m_brush
.GetStyle() != wxTRANSPARENT
)
553 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
555 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
556 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
557 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
559 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
560 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
562 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
564 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
566 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
567 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
569 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
570 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
572 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
574 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
576 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
577 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
579 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
580 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
582 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
584 if (m_brush
.GetStyle() == wxSTIPPLE
)
586 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
587 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
588 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
590 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
591 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
593 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
597 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
598 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
602 if (m_pen
.GetStyle() != wxTRANSPARENT
)
604 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
,
605 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
609 CalcBoundingBox (x
, y
);
610 CalcBoundingBox (x
+ width
, y
+ height
);
613 void wxWindowDCImpl::DoDrawPoint( wxCoord x
, wxCoord y
)
615 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
617 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_x11window
)
618 XDrawPoint( (Display
*) m_display
, (Window
) m_x11window
,
619 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
621 CalcBoundingBox (x
, y
);
624 void wxWindowDCImpl::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
626 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
628 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
631 XPoint
*xpoints
= new XPoint
[n
];
632 for (int i
= 0; i
< n
; i
++)
634 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
635 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
637 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
639 XDrawLines( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xpoints
, n
, 0 );
644 void wxWindowDCImpl::DoDrawPolygon( int n
, wxPoint points
[],
645 wxCoord xoffset
, wxCoord yoffset
,
646 int WXUNUSED(fillStyle
) )
648 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
652 XPoint
*xpoints
= new XPoint
[n
+ 1];
654 for (i
= 0; i
< n
; i
++)
656 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
657 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
659 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
664 if (m_brush
.GetStyle() != wxTRANSPARENT
)
667 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
669 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
670 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
671 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
673 XFillPolygon( (Display
*) m_display
, (Window
) m_x11window
,
674 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
676 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
678 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
680 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
681 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
683 XFillPolygon( (Display
*) m_display
, (Window
) m_x11window
,
684 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
686 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
688 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
690 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
691 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
693 XFillPolygon( (Display
*) m_display
, (Window
) m_x11window
,
694 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
696 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
698 if (m_brush
.GetStyle() == wxSTIPPLE
)
700 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
701 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
702 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
704 XFillPolygon( (Display
*) m_display
, (Window
) m_x11window
,
705 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
707 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
711 XFillPolygon( (Display
*) m_display
, (Window
) m_x11window
,
712 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
716 if (m_pen
.GetStyle () != wxTRANSPARENT
)
718 // Close figure for XDrawLines
719 xpoints
[i
].x
= xpoints
[0].x
;
720 xpoints
[i
].y
= xpoints
[0].y
;
722 XDrawLines( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
729 void wxWindowDCImpl::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
731 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
733 wxCoord xx
= XLOG2DEV(x
);
734 wxCoord yy
= YLOG2DEV(y
);
735 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
736 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
738 // CMB: draw nothing if transformed w or h is 0
739 if (ww
== 0 || hh
== 0) return;
741 // CMB: handle -ve width and/or height
742 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
743 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
747 if (m_brush
.GetStyle() != wxTRANSPARENT
)
749 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
751 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
752 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
753 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
755 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
756 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
758 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
760 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
762 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
763 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
765 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
766 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
768 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
770 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
772 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
773 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
775 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
776 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
778 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
780 if (m_brush
.GetStyle() == wxSTIPPLE
)
782 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
783 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
784 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
786 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
787 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
789 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
793 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
794 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
798 if (m_pen
.GetStyle () != wxTRANSPARENT
)
800 XDrawRectangle( (Display
*) m_display
, (Window
) m_x11window
,
801 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
805 CalcBoundingBox( x
, y
);
806 CalcBoundingBox( x
+ width
, y
+ height
);
809 void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
811 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
813 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
815 wxCoord xx
= XLOG2DEV(x
);
816 wxCoord yy
= YLOG2DEV(y
);
817 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
818 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
819 wxCoord rr
= XLOG2DEVREL((wxCoord
)radius
);
821 // CMB: handle -ve width and/or height
822 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
823 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
825 // CMB: if radius is zero use DrawRectangle() instead to avoid
826 // X drawing errors with small radii
829 XDrawRectangle( (Display
*) m_display
, (Window
) m_x11window
,
830 (GC
) m_penGC
, x
, y
, width
, height
);
834 // CMB: draw nothing if transformed w or h is 0
835 if (ww
== 0 || hh
== 0) return;
837 // CMB: adjust size if outline is drawn otherwise the result is
838 // 1 pixel too wide and high
839 if (m_pen
.GetStyle() != wxTRANSPARENT
)
847 // CMB: ensure dd is not larger than rectangle otherwise we
848 // get an hour glass shape
850 if (dd
> ww
) dd
= ww
;
851 if (dd
> hh
) dd
= hh
;
854 if (m_brush
.GetStyle() != wxTRANSPARENT
)
856 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
858 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
859 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
860 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
861 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_textGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
862 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_textGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
863 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_textGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
864 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
865 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
866 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_textGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
867 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0);
869 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
871 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
872 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
873 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
874 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
875 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
876 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
877 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
878 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
880 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
882 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
883 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
884 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
885 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
886 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
887 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
888 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
889 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
891 if (m_brush
.GetStyle() == wxSTIPPLE
)
893 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
894 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
895 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
896 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
897 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
898 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
899 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
900 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
901 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
902 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
906 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
907 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
908 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
909 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
910 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
911 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
914 if (m_pen
.GetStyle() != wxTRANSPARENT
)
916 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy
);
917 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
918 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr
);
919 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr
);
920 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
921 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
922 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
923 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
927 // this ignores the radius
928 CalcBoundingBox( x
, y
);
929 CalcBoundingBox( x
+ width
, y
+ height
);
932 void wxWindowDCImpl::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
934 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
936 wxCoord xx
= XLOG2DEV(x
);
937 wxCoord yy
= YLOG2DEV(y
);
938 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
939 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
941 // CMB: handle -ve width and/or height
942 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
943 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
947 if (m_brush
.GetStyle() != wxTRANSPARENT
)
949 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
951 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
952 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
953 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
955 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
956 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
958 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
960 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
962 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
963 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
965 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
966 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
968 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
970 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
972 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
973 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
975 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
976 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
978 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
980 if (m_brush
.GetStyle() == wxSTIPPLE
)
982 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
983 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
984 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
986 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
987 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
989 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
993 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
994 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
998 if (m_pen
.GetStyle () != wxTRANSPARENT
)
1000 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
,
1001 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
1005 CalcBoundingBox( x
, y
);
1006 CalcBoundingBox( x
+ width
, y
+ height
);
1009 void wxWindowDCImpl::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
1011 DoDrawBitmap(icon
, x
, y
, true);
1015 void wxWindowDCImpl::DoDrawBitmap( const wxBitmap
&bitmap
,
1016 wxCoord x
, wxCoord y
,
1019 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1021 wxCHECK_RET( bitmap
.IsOk(), wxT("invalid bitmap") );
1023 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1025 /* scale/translate size and position */
1026 int xx
= XLOG2DEV(x
);
1027 int yy
= YLOG2DEV(y
);
1029 int w
= bitmap
.GetWidth();
1030 int h
= bitmap
.GetHeight();
1032 CalcBoundingBox( x
, y
);
1033 CalcBoundingBox( x
+ w
, y
+ h
);
1035 if (!m_x11window
) return;
1037 int ww
= XLOG2DEVREL(w
);
1038 int hh
= YLOG2DEVREL(h
);
1040 /* compare to current clipping region */
1041 if (!m_currentClippingRegion
.IsNull())
1043 wxRegion
tmp( xx
,yy
,ww
,hh
);
1044 tmp
.Intersect( m_currentClippingRegion
);
1049 /* scale bitmap if required */
1050 wxBitmap use_bitmap
;
1051 if ((w
!= ww
) || (h
!= hh
))
1053 wxImage
image( bitmap
.ConvertToImage() );
1054 image
.Rescale( ww
, hh
);
1057 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1064 use_bitmap
= bitmap
;
1067 /* apply mask if any */
1068 WXPixmap mask
= NULL
;
1069 if (use_bitmap
.GetMask())
1070 mask
= use_bitmap
.GetMask()->GetBitmap();
1072 if (useMask
&& mask
)
1074 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
1075 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
1076 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
1078 GrSetGCUseBackground(gc
, FALSE
);
1079 GrSetGCMode(gc
, GR_MODE_COPY
);
1081 // This code assumes that background and foreground
1082 // colours are used in ROPs, like in MSW.
1083 // Not sure if this is true.
1085 // Copy destination to buffer.
1086 // In DoBlit, we need this step because Blit has
1087 // a ROP argument. Here, we don't need it.
1088 // In DoBlit, we may be able to eliminate this step
1089 // if we check if the rop = copy
1091 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_x11window
,
1092 0, 0, GR_MODE_COPY
);
1095 // Copy src to buffer using selected raster op (none selected
1096 // in DrawBitmap, so just use Gxcopy)
1097 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
1098 0, 0, GR_MODE_COPY
);
1100 // Set masked area in buffer to BLACK (pixel value 0)
1101 GrSetGCBackground(gc
, WHITE
);
1102 GrSetGCForeground(gc
, BLACK
);
1103 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
1106 // set unmasked area in dest to BLACK
1107 GrSetGCBackground(gc
, BLACK
);
1108 GrSetGCForeground(gc
, WHITE
);
1109 GrCopyArea((Window
) m_x11window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
1112 // OR buffer to dest
1113 GrCopyArea((Window
) m_x11window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
1117 GrDestroyWindow(bufPixmap
);
1120 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_x11window
,
1121 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1123 /* remove mask again if any */
1124 if (useMask
&& mask
)
1126 if (!m_currentClippingRegion
.IsNull())
1127 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1134 void wxWindowDCImpl::DoDrawBitmap( const wxBitmap
&bitmap
,
1135 wxCoord x
, wxCoord y
,
1138 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1140 wxCHECK_RET( bitmap
.IsOk(), wxT("invalid bitmap") );
1142 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1144 // scale/translate size and position
1145 int xx
= XLOG2DEV(x
);
1146 int yy
= YLOG2DEV(y
);
1148 int w
= bitmap
.GetWidth();
1149 int h
= bitmap
.GetHeight();
1151 CalcBoundingBox( x
, y
);
1152 CalcBoundingBox( x
+ w
, y
+ h
);
1154 if (!m_x11window
) return;
1156 int ww
= XLOG2DEVREL(w
);
1157 int hh
= YLOG2DEVREL(h
);
1159 // compare to current clipping region
1160 if (!m_currentClippingRegion
.IsNull())
1162 wxRegion
tmp( xx
,yy
,ww
,hh
);
1163 tmp
.Intersect( m_currentClippingRegion
);
1168 // scale bitmap if required
1169 wxBitmap use_bitmap
;
1170 if ((w
!= ww
) || (h
!= hh
))
1172 wxImage
image( bitmap
.ConvertToImage() );
1173 image
.Rescale( ww
, hh
);
1176 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1183 use_bitmap
= bitmap
;
1186 // apply mask if any
1187 WXPixmap mask
= NULL
;
1188 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1190 bool setClipMask
= false;
1192 if (!m_currentClippingRegion
.IsNull() || (useMask
&& mask
))
1194 // XSetClipMask() call is necessary (because of clip region and/or transparent mask)
1196 Pixmap new_pixmap
= 0;
1198 if (!m_currentClippingRegion
.IsNull())
1200 // clipping necessary => create new_pixmap
1201 Display
*xdisplay
= (Display
*) m_display
;
1202 int xscreen
= DefaultScreen( xdisplay
);
1203 Window xroot
= RootWindow( xdisplay
, xscreen
);
1205 new_pixmap
= XCreatePixmap( xdisplay
, xroot
, ww
, hh
, 1 );
1206 GC gc
= XCreateGC( xdisplay
, new_pixmap
, 0, NULL
);
1208 XSetForeground( xdisplay
, gc
, BlackPixel(xdisplay
,xscreen
) );
1210 XSetFillStyle( xdisplay
, gc
, FillSolid
);
1211 XFillRectangle( xdisplay
, new_pixmap
, gc
, 0, 0, ww
, hh
);
1213 XSetForeground( xdisplay
, gc
, WhitePixel(xdisplay
,xscreen
) );
1215 if (useMask
&& mask
)
1217 // transparent mask => call XSetStipple
1218 XSetFillStyle( xdisplay
, gc
, FillStippled
);
1219 XSetTSOrigin( xdisplay
, gc
, 0, 0);
1220 XSetStipple( xdisplay
, gc
, (Pixmap
) mask
);
1223 wxVector
<XRectangle
> rects
;
1224 for ( wxRegionIterator
iter(m_currentClippingRegion
);
1229 rect
.x
= iter
.GetX() - xx
;
1230 rect
.y
= iter
.GetY() - yy
;
1231 rect
.width
= iter
.GetWidth();
1232 rect
.height
= iter
.GetHeight();
1233 rects
.push_back(rect
);
1236 XFillRectangles(xdisplay
, new_pixmap
, gc
, &rects
[0], rects
.size());
1238 XFreeGC( xdisplay
, gc
);
1244 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, new_pixmap
);
1246 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1247 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1252 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, new_pixmap
);
1254 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1255 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1259 XFreePixmap( (Display
*) m_display
, new_pixmap
);
1262 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1263 // drawing a mono-bitmap (XBitmap) we use the current text GC
1265 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_x11window
,
1266 (GC
) m_textGC
, 0, 0, ww
, hh
, xx
, yy
, 1 );
1268 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_x11window
,
1269 (GC
) m_penGC
, 0, 0, ww
, hh
, xx
, yy
);
1271 // remove mask again if any
1276 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1277 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1278 if (!m_currentClippingRegion
.IsNull())
1279 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1283 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1284 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1285 if (!m_currentClippingRegion
.IsNull())
1286 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1291 // wxUSE_NANOX/!wxUSE_NANOX
1293 bool wxWindowDCImpl::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1294 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1295 wxCoord xsrcMask
, wxCoord ysrcMask
)
1297 /* this is the nth try to get this utterly useless function to
1298 work. it now completely ignores the scaling or translation
1299 of the source dc, but scales correctly on the target dc and
1300 knows about possible mask information in a memory dc. */
1302 wxCHECK_MSG( IsOk(), false, wxT("invalid window dc") );
1304 wxCHECK_MSG( source
, false, wxT("invalid source dc") );
1306 if (!m_x11window
) return false;
1308 // transform the source DC coords to the device ones
1309 xsrc
= source
->LogicalToDeviceX(xsrc
);
1310 ysrc
= source
->LogicalToDeviceY(ysrc
);
1312 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1313 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1314 wxWindowDCImpl
*src_impl
= (wxWindowDCImpl
*) srcDC
->GetImpl();
1316 bool use_bitmap_method
= false;
1317 bool is_mono
= false;
1319 // TODO: use the mask origin when drawing transparently
1320 if (xsrcMask
== -1 && ysrcMask
== -1)
1326 if (src_impl
->m_isMemDC
)
1328 wxBitmap selected
= memDC
->GetSelectedBitmap();
1330 if (!selected
.IsOk()) return false;
1332 /* we use the "XCopyArea" way to copy a memory dc into
1333 y different window if the memory dc BOTH
1334 a) doesn't have any mask or its mask isn't used
1338 if (useMask
&& (selected
.GetMask()))
1340 /* we HAVE TO use the direct way for memory dcs
1341 that have mask since the XCopyArea doesn't know
1343 use_bitmap_method
= true;
1345 else if (selected
.GetDepth() == 1)
1347 /* we HAVE TO use the direct way for memory dcs
1348 that are bitmaps because XCopyArea doesn't cope
1349 with different bit depths */
1351 use_bitmap_method
= true;
1353 else if ((xsrc
== 0) && (ysrc
== 0) &&
1354 (width
== selected
.GetWidth()) &&
1355 (height
== selected
.GetHeight()))
1357 /* we SHOULD use the direct way if all of the bitmap
1358 in the memory dc is copied in which case XCopyArea
1359 wouldn't be able able to boost performace by reducing
1360 the area to be scaled */
1361 use_bitmap_method
= true;
1365 use_bitmap_method
= false;
1369 CalcBoundingBox( xdest
, ydest
);
1370 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1372 // scale/translate size and position
1373 wxCoord xx
= XLOG2DEV(xdest
);
1374 wxCoord yy
= YLOG2DEV(ydest
);
1376 wxCoord ww
= XLOG2DEVREL(width
);
1377 wxCoord hh
= YLOG2DEVREL(height
);
1379 // compare to current clipping region
1380 if (!m_currentClippingRegion
.IsNull())
1382 wxRegion
tmp( xx
,yy
,ww
,hh
);
1383 tmp
.Intersect( m_currentClippingRegion
);
1388 int old_logical_func
= m_logicalFunction
;
1389 SetLogicalFunction( logical_func
);
1391 if (use_bitmap_method
)
1393 wxBitmap selected
= memDC
->GetSelectedBitmap();
1395 // scale/translate bitmap size
1396 wxCoord bm_width
= selected
.GetWidth();
1397 wxCoord bm_height
= selected
.GetHeight();
1399 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1400 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1402 // scale bitmap if required
1403 wxBitmap use_bitmap
;
1405 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1407 wxImage
image( selected
.ConvertToImage() );
1408 image
= image
.Scale( bm_ww
, bm_hh
);
1412 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1419 use_bitmap
= selected
;
1422 // apply mask if any
1423 WXPixmap mask
= NULL
;
1424 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1426 if (useMask
&& mask
)
1428 WXPixmap new_mask
= NULL
;
1430 if (!m_currentClippingRegion
.IsNull())
1433 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1434 GdkGC
*gc
= gdk_gc_new( new_mask
);
1436 gdk_gc_set_foreground( gc
, &col
);
1437 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1439 gdk_gc_set_background( gc
, &col
);
1441 gdk_gc_set_foreground( gc
, &col
);
1442 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1443 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1444 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1445 gdk_gc_set_stipple( gc
, mask
);
1446 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1453 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1455 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1456 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1461 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1463 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1464 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1468 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1471 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1472 // drawing a mono-bitmap (XBitmap) we use the current text GC
1474 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_x11window
,
1475 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1477 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_x11window
,
1478 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1480 // remove mask again if any
1481 if (useMask
&& mask
)
1485 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1486 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1487 if (!m_currentClippingRegion
.IsNull())
1488 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1492 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1493 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1494 if (!m_currentClippingRegion
.IsNull())
1495 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1499 else // use_bitmap_method
1501 wxDCImpl
*impl
= srcDC
->GetImpl();
1502 wxWindowDCImpl
*x11_impl
= wxDynamicCast(impl
, wxWindowDCImpl
);
1505 SetLogicalFunction( old_logical_func
);
1509 if ((width
!= ww
) || (height
!= hh
))
1511 /* Draw source window into a bitmap as we cannot scale
1512 a window in contrast to a bitmap. this would actually
1513 work with memory dcs as well, but we'd lose the mask
1514 information and waste one step in this process since
1515 a memory already has a bitmap. all this is slightly
1516 inefficient as we could take an XImage directly from
1517 an X window, but we'd then also have to care that
1518 the window is not outside the screen (in which case
1519 we'd get a BadMatch or what not).
1520 Is a double XGetImage and combined XGetPixel and
1521 XPutPixel really faster? I'm not sure. look at wxXt
1522 for a different implementation of the same problem. */
1524 wxBitmap
bitmap( width
, height
);
1526 // copy including child window contents
1527 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1528 XCopyArea( (Display
*) m_display
, (Window
) x11_impl
->GetX11Window(), (Window
) bitmap
.GetPixmap(),
1529 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1530 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1533 wxImage
image( bitmap
.ConvertToImage() );
1534 image
= image
.Scale( ww
, hh
);
1536 // convert to bitmap
1539 // draw scaled bitmap
1540 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_x11window
,
1541 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1545 // No scaling and not a memory dc with a mask either
1546 // copy including child window contents
1547 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1548 XCopyArea( (Display
*) m_display
, (Window
) x11_impl
->GetX11Window(), (Window
) m_x11window
,
1549 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1550 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1554 SetLogicalFunction( old_logical_func
);
1559 void wxWindowDCImpl::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1561 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1563 if (!m_x11window
) return;
1569 PangoLayout
*layout
= pango_layout_new(m_context
);
1570 pango_layout_set_font_description(layout
, m_fontdesc
);
1572 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1573 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1577 pango_layout_get_pixel_size(layout
, &w
, &h
);
1582 x11_draw_layout( (Drawable
) m_x11window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1584 g_object_unref( G_OBJECT( layout
) );
1586 CalcBoundingBox (x
+ width
, y
+ height
);
1587 CalcBoundingBox (x
, y
);
1589 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1591 wxCHECK_RET( xfont
, wxT("invalid font") );
1593 // First draw a rectangle representing the text background, if a text
1594 // background is specified
1595 if (m_textBackgroundColour
.IsOk () && (m_backgroundMode
!= wxTRANSPARENT
))
1597 // Since X draws from the baseline of the text, must add the text height
1602 int direction
, descent
;
1604 slen
= strlen(text
);
1605 XCharStruct overall_return
;
1607 (void)XTextExtents(xfont
, (const char*) text
.c_str(), slen
, &direction
,
1608 &ascent
, &descent
, &overall_return
);
1610 cx
= overall_return
.width
;
1611 cy
= ascent
+ descent
;
1612 m_textBackgroundColour
.CalcPixel(m_cmap
);
1613 m_textForegroundColour
.CalcPixel(m_cmap
);
1614 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1615 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
1616 (GC
) m_textGC
, x
, y
, cx
, cy
);
1617 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1621 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1623 // This may be a test for whether the font is 16-bit, but it also
1624 // seems to fail for valid 8-bit fonts too.
1625 if (1) // (xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
1628 XDrawString( (Display
*) m_display
, (Window
) m_x11window
,
1629 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.length() );
1633 if (m_font
.GetUnderlined())
1635 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1636 if (font
->descent
> 0) ul_y
++;
1637 gdk_draw_line( m_x11window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1640 width
= wxCoord(width
/ m_scaleX
);
1641 height
= wxCoord(height
/ m_scaleY
);
1643 CalcBoundingBox (x
+ width
, y
+ height
);
1644 CalcBoundingBox (x
, y
);
1649 void wxWindowDCImpl::DoDrawRotatedText(const wxString
& WXUNUSED(text
),
1650 wxCoord
WXUNUSED(x
), wxCoord
WXUNUSED(y
),
1651 double WXUNUSED(angle
))
1653 wxFAIL_MSG( "not implemented" );
1656 void wxWindowDCImpl::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1657 wxCoord
*descent
, wxCoord
*externalLeading
,
1658 const wxFont
*font
) const
1660 wxCHECK_RET( IsOk(), wxT("invalid dc") );
1664 if (width
) (*width
) = 0;
1665 if (height
) (*height
) = 0;
1670 PangoLayout
*layout
= pango_layout_new( m_context
);
1673 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1675 pango_layout_set_font_description(layout
, m_fontdesc
);
1677 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1678 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1682 pango_layout_get_pixel_size(layout
, &w
, &h
);
1684 if (width
) (*width
) = (wxCoord
) w
;
1685 if (height
) (*height
) = (wxCoord
) h
;
1688 // Do something about metrics here. TODO.
1691 if (externalLeading
) (*externalLeading
) = 0; // ??
1693 g_object_unref( G_OBJECT( layout
) );
1695 wxFont fontToUse
= m_font
;
1696 if (font
) fontToUse
= *font
;
1698 wxCHECK_RET( fontToUse
.IsOk(), wxT("invalid font") );
1700 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1702 wxCHECK_RET( xfont
, wxT("invalid font") );
1704 int direction
, ascent
, descent2
;
1705 XCharStruct overall
;
1707 XTextExtents( xfont
, (const char*) string
.c_str(), string
.length(), &direction
,
1708 &ascent
, &descent2
, &overall
);
1711 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1713 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1715 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1716 if (externalLeading
)
1717 *externalLeading
= 0; // ??
1721 wxCoord
wxWindowDCImpl::GetCharWidth() const
1723 wxCHECK_MSG( IsOk(), 0, wxT("invalid dc") );
1726 PangoLayout
*layout
= pango_layout_new( m_context
);
1729 pango_layout_set_font_description(layout
, m_fontdesc
);
1731 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1733 pango_layout_set_text(layout
, "H", 1 );
1735 pango_layout_get_pixel_size(layout
, &w
, &h
);
1736 g_object_unref( G_OBJECT( layout
) );
1740 wxCHECK_MSG( m_font
.IsOk(), 0, wxT("invalid font") );
1742 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1744 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1746 int direction
, ascent
, descent
;
1747 XCharStruct overall
;
1749 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1751 return (wxCoord
)(overall
.width
/ m_scaleX
);
1755 wxCoord
wxWindowDCImpl::GetCharHeight() const
1757 wxCHECK_MSG( IsOk(), 0, wxT("invalid dc") );
1760 PangoLayout
*layout
= pango_layout_new( m_context
);
1763 pango_layout_set_font_description(layout
, m_fontdesc
);
1765 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1767 pango_layout_set_text(layout
, "H", 1 );
1769 pango_layout_get_pixel_size(layout
, &w
, &h
);
1770 g_object_unref( G_OBJECT( layout
) );
1774 wxCHECK_MSG( m_font
.IsOk(), 0, wxT("invalid font") );
1776 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1778 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1780 int direction
, ascent
, descent
;
1781 XCharStruct overall
;
1783 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1785 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1789 void wxWindowDCImpl::Clear()
1791 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1793 if (!m_x11window
) return;
1795 /* - we either are a memory dc or have a window as the
1796 owner. anything else shouldn't happen.
1797 - we don't use gdk_window_clear() as we don't set
1798 the window's background colour anymore. it is too
1799 much pain to keep the DC's and the window's back-
1800 ground colour in synch. */
1805 m_window
->GetSize( &width
, &height
);
1806 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1813 DoGetSize( &width
, &height
);
1814 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1819 void wxWindowDCImpl::SetFont( const wxFont
&font
)
1821 wxCHECK_RET( IsOk(), wxT("invalid dc") );
1826 m_fontdesc
= font
.GetNativeFontInfo()->description
;
1830 void wxWindowDCImpl::SetPen( const wxPen
&pen
)
1832 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1834 if (m_pen
== pen
) return;
1838 if (!m_pen
.IsOk()) return;
1840 if (!m_x11window
) return;
1842 int width
= m_pen
.GetWidth();
1845 // CMB: if width is non-zero scale it with the dc
1850 // X doesn't allow different width in x and y and so we take
1853 ( fabs((double) XLOG2DEVREL(width
)) +
1854 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1858 static const wxX11Dash dotted
[] = {1, 1};
1859 static const wxX11Dash short_dashed
[] = {2, 2};
1860 static const wxX11Dash long_dashed
[] = {2, 4};
1861 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1863 // We express dash pattern in pen width unit, so we are
1864 // independent of zoom factor and so on...
1866 const wxX11Dash
*req_dash
;
1868 int lineStyle
= LineSolid
;
1869 switch (m_pen
.GetStyle())
1873 lineStyle
= LineOnOffDash
;
1874 req_nb_dash
= m_pen
.GetDashCount();
1875 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1880 lineStyle
= LineOnOffDash
;
1887 lineStyle
= LineOnOffDash
;
1889 req_dash
= long_dashed
;
1894 lineStyle
= LineOnOffDash
;
1896 req_dash
= short_dashed
;
1901 // lineStyle = LineDoubleDash;
1902 lineStyle
= LineOnOffDash
;
1904 req_dash
= dotted_dashed
;
1909 case wxSTIPPLE_MASK_OPAQUE
:
1914 lineStyle
= LineSolid
;
1915 req_dash
= (wxX11Dash
*)NULL
;
1921 int capStyle
= CapRound
;
1922 switch (m_pen
.GetCap())
1924 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1925 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1932 capStyle
= CapNotLast
;
1936 capStyle
= CapRound
;
1942 int joinStyle
= JoinRound
;
1943 switch (m_pen
.GetJoin())
1945 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1946 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1948 default: { joinStyle
= JoinRound
; break; }
1951 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1953 m_pen
.GetColour().CalcPixel( m_cmap
);
1954 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1957 void wxWindowDCImpl::SetBrush( const wxBrush
&brush
)
1959 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1961 if (m_brush
== brush
) return;
1965 if (!m_brush
.IsOk()) return;
1967 if (!m_x11window
) return;
1969 m_brush
.GetColour().CalcPixel( m_cmap
);
1970 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1972 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1974 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->IsOk()))
1976 if (m_brush
.GetStipple()->GetPixmap())
1978 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1979 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1983 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1984 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1988 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1990 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1991 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1994 if (m_brush
.IsHatch())
1996 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1997 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1998 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
2002 void wxWindowDCImpl::SetBackground( const wxBrush
&brush
)
2004 /* CMB 21/7/98: Added SetBackground. Sets background brush
2005 * for Clear() and bg colour for shapes filled with cross-hatch brush */
2007 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2009 if (m_backgroundBrush
== brush
) return;
2011 m_backgroundBrush
= brush
;
2013 if (!m_backgroundBrush
.IsOk()) return;
2015 if (!m_x11window
) return;
2017 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
2018 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
2019 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
2020 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
2021 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
2023 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
2025 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->IsOk()))
2027 if (m_backgroundBrush
.GetStipple()->GetPixmap())
2029 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
2030 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
2034 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2035 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
2039 if (m_backgroundBrush
.IsHatch())
2041 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2042 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
2043 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
2047 void wxWindowDCImpl::SetLogicalFunction( int function
)
2049 wxCHECK_RET( IsOk(), wxT("invalid dc") );
2053 if (m_logicalFunction
== function
)
2056 // VZ: shouldn't this be a CHECK?
2063 x_function
= GXclear
;
2069 x_function
= GXinvert
;
2072 x_function
= GXorReverse
;
2075 x_function
= GXandReverse
;
2084 x_function
= GXandInverted
;
2087 x_function
= GXnoop
;
2093 x_function
= GXequiv
;
2096 x_function
= GXcopyInverted
;
2099 x_function
= GXorInverted
;
2102 x_function
= GXnand
;
2109 x_function
= GXcopy
;
2113 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2114 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2116 // to stay compatible with wxMSW, we don't apply ROPs to the text
2117 // operations (i.e. DrawText/DrawRotatedText).
2118 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2119 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2121 m_logicalFunction
= function
;
2124 void wxWindowDCImpl::SetTextForeground( const wxColour
&col
)
2126 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2128 // don't set m_textForegroundColour to an invalid colour as we'd crash
2129 // later then (we use m_textForegroundColour.GetColor() without checking
2131 if ( !col
.IsOk() || (m_textForegroundColour
== col
) )
2134 m_textForegroundColour
= col
;
2138 m_textForegroundColour
.CalcPixel( m_cmap
);
2139 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2143 void wxWindowDCImpl::SetTextBackground( const wxColour
&col
)
2145 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2148 if ( !col
.IsOk() || (m_textBackgroundColour
== col
) )
2151 m_textBackgroundColour
= col
;
2155 m_textBackgroundColour
.CalcPixel( m_cmap
);
2156 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2160 void wxWindowDCImpl::SetBackgroundMode( int mode
)
2162 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2164 m_backgroundMode
= mode
;
2167 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2170 if (!m_x11window
) return;
2172 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2173 // transparent/solid background mode
2175 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2177 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2178 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2182 void wxWindowDCImpl::SetPalette( const wxPalette
& WXUNUSED(palette
) )
2188 /* Use GetXColormap */
2189 XSetWindowColormap ((Display
*) m_display
, (Window
) m_x11window
->GetXWindow(),
2190 (Colormap
) palette
.GetXColormap());
2192 /* Use wxGetMainColormap */
2193 XSetWindowColormap ((Display
*) m_display
, (Window
) m_x11window
->GetXWindow(),
2194 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2199 void wxWindowDCImpl::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2201 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2203 if (!m_x11window
) return;
2212 rect
.x
= XLOG2DEV(x
);
2213 rect
.y
= YLOG2DEV(y
);
2214 rect
.width
= XLOG2DEVREL(width
);
2215 rect
.height
= YLOG2DEVREL(height
);
2217 if (!m_currentClippingRegion
.IsEmpty())
2218 m_currentClippingRegion
.Intersect( rect
);
2220 m_currentClippingRegion
= rect
;
2222 #if USE_PAINT_REGION
2223 if (!m_paintClippingRegion
.IsEmpty())
2224 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2227 wxCoord xx
, yy
, ww
, hh
;
2228 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2229 wxX11DCImpl::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2231 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2232 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2233 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2234 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2237 void wxWindowDCImpl::DoSetDeviceClippingRegion( const wxRegion
& region
)
2239 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2243 DestroyClippingRegion();
2247 if (!m_x11window
) return;
2249 if (!m_currentClippingRegion
.IsEmpty())
2250 m_currentClippingRegion
.Intersect( region
);
2252 m_currentClippingRegion
= region
;
2254 #if USE_PAINT_REGION
2255 if (!m_paintClippingRegion
.IsEmpty())
2256 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2259 wxCoord xx
, yy
, ww
, hh
;
2260 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2261 wxX11DCImpl::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2263 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2264 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2265 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2266 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2269 void wxWindowDCImpl::DestroyClippingRegion()
2271 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2273 wxDCImpl::DestroyClippingRegion();
2275 m_currentClippingRegion
.Clear();
2277 #if USE_PAINT_REGION
2278 if (!m_paintClippingRegion
.IsEmpty())
2279 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2282 if (!m_x11window
) return;
2284 if (m_currentClippingRegion
.IsEmpty())
2286 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2287 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2288 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2289 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2293 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2294 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2295 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2296 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2300 void wxWindowDCImpl::Destroy()
2302 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2304 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2306 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2308 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2312 void wxWindowDCImpl::ComputeScaleAndOrigin()
2314 /* CMB: copy scale to see if it changes */
2315 double origScaleX
= m_scaleX
;
2316 double origScaleY
= m_scaleY
;
2318 wxDCImpl::ComputeScaleAndOrigin();
2320 /* CMB: if scale has changed call SetPen to recalulate the line width */
2321 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2324 /* this is a bit artificial, but we need to force wxDC to think
2325 the pen has changed */
2332 wxSize
wxWindowDCImpl::GetPPI() const
2334 return wxSize(100, 100);
2337 int wxWindowDCImpl::GetDepth() const
2339 wxFAIL_MSG(wxT("not implemented"));
2344 //-----------------------------------------------------------------------------
2346 //-----------------------------------------------------------------------------
2348 IMPLEMENT_ABSTRACT_CLASS(wxClientDCImpl
, wxWindowDCImpl
)
2350 wxClientDCImpl::wxClientDCImpl( wxDC
*owner
, wxWindow
*window
)
2351 : wxWindowDCImpl( owner
, window
)
2353 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2355 m_x11window
= (WXWindow
*) window
->GetClientAreaWindow();
2357 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2358 if (m_x11window
== (WXWindow
*) window
->GetMainWindow())
2360 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2361 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2362 wxSize size
= window
->GetClientSize();
2363 DoSetClippingRegion( 0, 0, size
.x
, size
.y
);
2367 void wxClientDCImpl::DoGetSize(int *width
, int *height
) const
2369 wxCHECK_RET( m_window
, _T("GetSize() doesn't work without window") );
2371 m_window
->GetClientSize( width
, height
);
2374 // ----------------------------------------------------------------------------
2376 // ----------------------------------------------------------------------------
2378 IMPLEMENT_ABSTRACT_CLASS(wxPaintDCImpl
, wxClientDCImpl
)
2380 wxPaintDCImpl::wxPaintDCImpl(wxDC
*owner
, wxWindow
* window
)
2381 : wxClientDCImpl(owner
, window
)
2383 #if USE_PAINT_REGION
2384 if (!window
->GetClipPaintRegion())
2387 m_paintClippingRegion
= window
->GetUpdateRegion();
2388 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2391 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2393 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2394 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2395 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2396 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2398 #endif // USE_PAINT_REGION
2401 // ----------------------------------------------------------------------------
2403 // ----------------------------------------------------------------------------
2405 class wxDCModule
: public wxModule
2408 // we must be cleaned up before wxDisplayModule which closes the global
2412 AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule")));
2415 bool OnInit() { wxInitGCPool(); return true; }
2416 void OnExit() { wxCleanUpGCPool(); }
2419 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2422 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)