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
, wxFloodFillStyle style
);
356 bool wxWindowDCImpl::DoFloodFill(wxCoord x
, wxCoord y
,
357 const wxColour
& col
, wxFloodFillStyle 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 wxPolygonFillMode
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
,
1295 wxRasterOperationMode logical_func
, bool useMask
,
1296 wxCoord xsrcMask
, wxCoord ysrcMask
)
1298 /* this is the nth try to get this utterly useless function to
1299 work. it now completely ignores the scaling or translation
1300 of the source dc, but scales correctly on the target dc and
1301 knows about possible mask information in a memory dc. */
1303 wxCHECK_MSG( IsOk(), false, wxT("invalid window dc") );
1305 wxCHECK_MSG( source
, false, wxT("invalid source dc") );
1307 if (!m_x11window
) return false;
1309 // transform the source DC coords to the device ones
1310 xsrc
= source
->LogicalToDeviceX(xsrc
);
1311 ysrc
= source
->LogicalToDeviceY(ysrc
);
1313 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1314 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1315 wxWindowDCImpl
*src_impl
= (wxWindowDCImpl
*) srcDC
->GetImpl();
1317 bool use_bitmap_method
= false;
1318 bool is_mono
= false;
1320 // TODO: use the mask origin when drawing transparently
1321 if (xsrcMask
== -1 && ysrcMask
== -1)
1327 if (src_impl
->m_isMemDC
)
1329 wxBitmap selected
= memDC
->GetSelectedBitmap();
1331 if (!selected
.IsOk()) return false;
1333 /* we use the "XCopyArea" way to copy a memory dc into
1334 y different window if the memory dc BOTH
1335 a) doesn't have any mask or its mask isn't used
1339 if (useMask
&& (selected
.GetMask()))
1341 /* we HAVE TO use the direct way for memory dcs
1342 that have mask since the XCopyArea doesn't know
1344 use_bitmap_method
= true;
1346 else if (selected
.GetDepth() == 1)
1348 /* we HAVE TO use the direct way for memory dcs
1349 that are bitmaps because XCopyArea doesn't cope
1350 with different bit depths */
1352 use_bitmap_method
= true;
1354 else if ((xsrc
== 0) && (ysrc
== 0) &&
1355 (width
== selected
.GetWidth()) &&
1356 (height
== selected
.GetHeight()))
1358 /* we SHOULD use the direct way if all of the bitmap
1359 in the memory dc is copied in which case XCopyArea
1360 wouldn't be able able to boost performace by reducing
1361 the area to be scaled */
1362 use_bitmap_method
= true;
1366 use_bitmap_method
= false;
1370 CalcBoundingBox( xdest
, ydest
);
1371 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1373 // scale/translate size and position
1374 wxCoord xx
= XLOG2DEV(xdest
);
1375 wxCoord yy
= YLOG2DEV(ydest
);
1377 wxCoord ww
= XLOG2DEVREL(width
);
1378 wxCoord hh
= YLOG2DEVREL(height
);
1380 // compare to current clipping region
1381 if (!m_currentClippingRegion
.IsNull())
1383 wxRegion
tmp( xx
,yy
,ww
,hh
);
1384 tmp
.Intersect( m_currentClippingRegion
);
1389 wxRasterOperationMode old_logical_func
= m_logicalFunction
;
1390 SetLogicalFunction( logical_func
);
1392 if (use_bitmap_method
)
1394 wxBitmap selected
= memDC
->GetSelectedBitmap();
1396 // scale/translate bitmap size
1397 wxCoord bm_width
= selected
.GetWidth();
1398 wxCoord bm_height
= selected
.GetHeight();
1400 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1401 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1403 // scale bitmap if required
1404 wxBitmap use_bitmap
;
1406 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1408 wxImage
image( selected
.ConvertToImage() );
1409 image
= image
.Scale( bm_ww
, bm_hh
);
1413 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1420 use_bitmap
= selected
;
1423 // apply mask if any
1424 WXPixmap mask
= NULL
;
1425 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1427 if (useMask
&& mask
)
1429 WXPixmap new_mask
= NULL
;
1431 if (!m_currentClippingRegion
.IsNull())
1434 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1435 GdkGC
*gc
= gdk_gc_new( new_mask
);
1437 gdk_gc_set_foreground( gc
, &col
);
1438 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1440 gdk_gc_set_background( gc
, &col
);
1442 gdk_gc_set_foreground( gc
, &col
);
1443 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1444 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1445 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1446 gdk_gc_set_stipple( gc
, mask
);
1447 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1454 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1456 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1457 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1462 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1464 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1465 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1469 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1472 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1473 // drawing a mono-bitmap (XBitmap) we use the current text GC
1475 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_x11window
,
1476 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1478 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_x11window
,
1479 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1481 // remove mask again if any
1482 if (useMask
&& mask
)
1486 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1487 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1488 if (!m_currentClippingRegion
.IsNull())
1489 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1493 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1494 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1495 if (!m_currentClippingRegion
.IsNull())
1496 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1500 else // use_bitmap_method
1502 wxDCImpl
*impl
= srcDC
->GetImpl();
1503 wxWindowDCImpl
*x11_impl
= wxDynamicCast(impl
, wxWindowDCImpl
);
1506 SetLogicalFunction( old_logical_func
);
1510 if ((width
!= ww
) || (height
!= hh
))
1512 /* Draw source window into a bitmap as we cannot scale
1513 a window in contrast to a bitmap. this would actually
1514 work with memory dcs as well, but we'd lose the mask
1515 information and waste one step in this process since
1516 a memory already has a bitmap. all this is slightly
1517 inefficient as we could take an XImage directly from
1518 an X window, but we'd then also have to care that
1519 the window is not outside the screen (in which case
1520 we'd get a BadMatch or what not).
1521 Is a double XGetImage and combined XGetPixel and
1522 XPutPixel really faster? I'm not sure. look at wxXt
1523 for a different implementation of the same problem. */
1525 wxBitmap
bitmap( width
, height
);
1527 // copy including child window contents
1528 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1529 XCopyArea( (Display
*) m_display
, (Window
) x11_impl
->GetX11Window(), (Window
) bitmap
.GetPixmap(),
1530 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1531 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1534 wxImage
image( bitmap
.ConvertToImage() );
1535 image
= image
.Scale( ww
, hh
);
1537 // convert to bitmap
1540 // draw scaled bitmap
1541 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_x11window
,
1542 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1546 // No scaling and not a memory dc with a mask either
1547 // copy including child window contents
1548 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1549 XCopyArea( (Display
*) m_display
, (Window
) x11_impl
->GetX11Window(), (Window
) m_x11window
,
1550 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1551 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1555 SetLogicalFunction( old_logical_func
);
1560 void wxWindowDCImpl::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1562 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1564 if (!m_x11window
) return;
1570 PangoLayout
*layout
= pango_layout_new(m_context
);
1571 pango_layout_set_font_description(layout
, m_fontdesc
);
1573 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1574 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1578 pango_layout_get_pixel_size(layout
, &w
, &h
);
1583 x11_draw_layout( (Drawable
) m_x11window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1585 g_object_unref( G_OBJECT( layout
) );
1587 CalcBoundingBox (x
+ width
, y
+ height
);
1588 CalcBoundingBox (x
, y
);
1590 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1592 wxCHECK_RET( xfont
, wxT("invalid font") );
1594 // First draw a rectangle representing the text background, if a text
1595 // background is specified
1596 if (m_textBackgroundColour
.IsOk () && (m_backgroundMode
!= wxTRANSPARENT
))
1598 // Since X draws from the baseline of the text, must add the text height
1603 int direction
, descent
;
1605 slen
= strlen(text
);
1606 XCharStruct overall_return
;
1608 (void)XTextExtents(xfont
, (const char*) text
.c_str(), slen
, &direction
,
1609 &ascent
, &descent
, &overall_return
);
1611 cx
= overall_return
.width
;
1612 cy
= ascent
+ descent
;
1613 m_textBackgroundColour
.CalcPixel(m_cmap
);
1614 m_textForegroundColour
.CalcPixel(m_cmap
);
1615 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1616 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
1617 (GC
) m_textGC
, x
, y
, cx
, cy
);
1618 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1622 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1624 // This may be a test for whether the font is 16-bit, but it also
1625 // seems to fail for valid 8-bit fonts too.
1626 if (1) // (xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
1629 XDrawString( (Display
*) m_display
, (Window
) m_x11window
,
1630 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.length() );
1634 if (m_font
.GetUnderlined())
1636 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1637 if (font
->descent
> 0) ul_y
++;
1638 gdk_draw_line( m_x11window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1641 width
= wxCoord(width
/ m_scaleX
);
1642 height
= wxCoord(height
/ m_scaleY
);
1644 CalcBoundingBox (x
+ width
, y
+ height
);
1645 CalcBoundingBox (x
, y
);
1650 void wxWindowDCImpl::DoDrawRotatedText(const wxString
& WXUNUSED(text
),
1651 wxCoord
WXUNUSED(x
), wxCoord
WXUNUSED(y
),
1652 double WXUNUSED(angle
))
1654 wxFAIL_MSG( "not implemented" );
1657 void wxWindowDCImpl::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1658 wxCoord
*descent
, wxCoord
*externalLeading
,
1659 const wxFont
*font
) const
1661 wxCHECK_RET( IsOk(), wxT("invalid dc") );
1665 if (width
) (*width
) = 0;
1666 if (height
) (*height
) = 0;
1671 PangoLayout
*layout
= pango_layout_new( m_context
);
1674 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1676 pango_layout_set_font_description(layout
, m_fontdesc
);
1678 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1679 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1683 pango_layout_get_pixel_size(layout
, &w
, &h
);
1685 if (width
) (*width
) = (wxCoord
) w
;
1686 if (height
) (*height
) = (wxCoord
) h
;
1689 // Do something about metrics here. TODO.
1692 if (externalLeading
) (*externalLeading
) = 0; // ??
1694 g_object_unref( G_OBJECT( layout
) );
1696 wxFont fontToUse
= m_font
;
1697 if (font
) fontToUse
= *font
;
1699 wxCHECK_RET( fontToUse
.IsOk(), wxT("invalid font") );
1701 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1703 wxCHECK_RET( xfont
, wxT("invalid font") );
1705 int direction
, ascent
, descent2
;
1706 XCharStruct overall
;
1708 XTextExtents( xfont
, (const char*) string
.c_str(), string
.length(), &direction
,
1709 &ascent
, &descent2
, &overall
);
1712 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1714 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1716 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1717 if (externalLeading
)
1718 *externalLeading
= 0; // ??
1722 wxCoord
wxWindowDCImpl::GetCharWidth() const
1724 wxCHECK_MSG( IsOk(), 0, wxT("invalid dc") );
1727 PangoLayout
*layout
= pango_layout_new( m_context
);
1730 pango_layout_set_font_description(layout
, m_fontdesc
);
1732 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1734 pango_layout_set_text(layout
, "H", 1 );
1736 pango_layout_get_pixel_size(layout
, &w
, &h
);
1737 g_object_unref( G_OBJECT( layout
) );
1741 wxCHECK_MSG( m_font
.IsOk(), 0, wxT("invalid font") );
1743 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1745 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1747 int direction
, ascent
, descent
;
1748 XCharStruct overall
;
1750 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1752 return (wxCoord
)(overall
.width
/ m_scaleX
);
1756 wxCoord
wxWindowDCImpl::GetCharHeight() const
1758 wxCHECK_MSG( IsOk(), 0, wxT("invalid dc") );
1761 PangoLayout
*layout
= pango_layout_new( m_context
);
1764 pango_layout_set_font_description(layout
, m_fontdesc
);
1766 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1768 pango_layout_set_text(layout
, "H", 1 );
1770 pango_layout_get_pixel_size(layout
, &w
, &h
);
1771 g_object_unref( G_OBJECT( layout
) );
1775 wxCHECK_MSG( m_font
.IsOk(), 0, wxT("invalid font") );
1777 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1779 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1781 int direction
, ascent
, descent
;
1782 XCharStruct overall
;
1784 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1786 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1790 void wxWindowDCImpl::Clear()
1792 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1794 if (!m_x11window
) return;
1796 /* - we either are a memory dc or have a window as the
1797 owner. anything else shouldn't happen.
1798 - we don't use gdk_window_clear() as we don't set
1799 the window's background colour anymore. it is too
1800 much pain to keep the DC's and the window's back-
1801 ground colour in synch. */
1806 m_window
->GetSize( &width
, &height
);
1807 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1814 DoGetSize( &width
, &height
);
1815 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1820 void wxWindowDCImpl::SetFont( const wxFont
&font
)
1822 wxCHECK_RET( IsOk(), wxT("invalid dc") );
1827 m_fontdesc
= font
.GetNativeFontInfo()->description
;
1831 void wxWindowDCImpl::SetPen( const wxPen
&pen
)
1833 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1835 if (m_pen
== pen
) return;
1839 if (!m_pen
.IsOk()) return;
1841 if (!m_x11window
) return;
1843 int width
= m_pen
.GetWidth();
1846 // CMB: if width is non-zero scale it with the dc
1851 // X doesn't allow different width in x and y and so we take
1854 ( fabs((double) XLOG2DEVREL(width
)) +
1855 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1859 static const wxX11Dash dotted
[] = {1, 1};
1860 static const wxX11Dash short_dashed
[] = {2, 2};
1861 static const wxX11Dash long_dashed
[] = {2, 4};
1862 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1864 // We express dash pattern in pen width unit, so we are
1865 // independent of zoom factor and so on...
1867 const wxX11Dash
*req_dash
;
1869 int lineStyle
= LineSolid
;
1870 switch (m_pen
.GetStyle())
1874 lineStyle
= LineOnOffDash
;
1875 req_nb_dash
= m_pen
.GetDashCount();
1876 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1881 lineStyle
= LineOnOffDash
;
1888 lineStyle
= LineOnOffDash
;
1890 req_dash
= long_dashed
;
1895 lineStyle
= LineOnOffDash
;
1897 req_dash
= short_dashed
;
1902 // lineStyle = LineDoubleDash;
1903 lineStyle
= LineOnOffDash
;
1905 req_dash
= dotted_dashed
;
1910 case wxSTIPPLE_MASK_OPAQUE
:
1915 lineStyle
= LineSolid
;
1916 req_dash
= (wxX11Dash
*)NULL
;
1922 int capStyle
= CapRound
;
1923 switch (m_pen
.GetCap())
1925 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1926 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1933 capStyle
= CapNotLast
;
1937 capStyle
= CapRound
;
1943 int joinStyle
= JoinRound
;
1944 switch (m_pen
.GetJoin())
1946 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1947 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1949 default: { joinStyle
= JoinRound
; break; }
1952 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1954 m_pen
.GetColour().CalcPixel( m_cmap
);
1955 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1958 void wxWindowDCImpl::SetBrush( const wxBrush
&brush
)
1960 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1962 if (m_brush
== brush
) return;
1966 if (!m_brush
.IsOk()) return;
1968 if (!m_x11window
) return;
1970 m_brush
.GetColour().CalcPixel( m_cmap
);
1971 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1973 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1975 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->IsOk()))
1977 if (m_brush
.GetStipple()->GetPixmap())
1979 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1980 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1984 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1985 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1989 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1991 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1992 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1995 if (m_brush
.IsHatch())
1997 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1998 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1999 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
2003 void wxWindowDCImpl::SetBackground( const wxBrush
&brush
)
2005 /* CMB 21/7/98: Added SetBackground. Sets background brush
2006 * for Clear() and bg colour for shapes filled with cross-hatch brush */
2008 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2010 if (m_backgroundBrush
== brush
) return;
2012 m_backgroundBrush
= brush
;
2014 if (!m_backgroundBrush
.IsOk()) return;
2016 if (!m_x11window
) return;
2018 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
2019 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
2020 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
2021 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
2022 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
2024 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
2026 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->IsOk()))
2028 if (m_backgroundBrush
.GetStipple()->GetPixmap())
2030 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
2031 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
2035 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2036 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
2040 if (m_backgroundBrush
.IsHatch())
2042 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2043 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
2044 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
2048 void wxWindowDCImpl::SetLogicalFunction( wxRasterOperationMode function
)
2050 wxCHECK_RET( IsOk(), wxT("invalid dc") );
2054 if (m_logicalFunction
== function
)
2057 // VZ: shouldn't this be a CHECK?
2064 x_function
= GXclear
;
2070 x_function
= GXinvert
;
2073 x_function
= GXorReverse
;
2076 x_function
= GXandReverse
;
2085 x_function
= GXandInverted
;
2088 x_function
= GXnoop
;
2094 x_function
= GXequiv
;
2097 x_function
= GXcopyInverted
;
2100 x_function
= GXorInverted
;
2103 x_function
= GXnand
;
2110 x_function
= GXcopy
;
2114 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2115 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2117 // to stay compatible with wxMSW, we don't apply ROPs to the text
2118 // operations (i.e. DrawText/DrawRotatedText).
2119 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2120 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2122 m_logicalFunction
= function
;
2125 void wxWindowDCImpl::SetTextForeground( const wxColour
&col
)
2127 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2129 // don't set m_textForegroundColour to an invalid colour as we'd crash
2130 // later then (we use m_textForegroundColour.GetColor() without checking
2132 if ( !col
.IsOk() || (m_textForegroundColour
== col
) )
2135 m_textForegroundColour
= col
;
2139 m_textForegroundColour
.CalcPixel( m_cmap
);
2140 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2144 void wxWindowDCImpl::SetTextBackground( const wxColour
&col
)
2146 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2149 if ( !col
.IsOk() || (m_textBackgroundColour
== col
) )
2152 m_textBackgroundColour
= col
;
2156 m_textBackgroundColour
.CalcPixel( m_cmap
);
2157 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2161 void wxWindowDCImpl::SetBackgroundMode( int mode
)
2163 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2165 m_backgroundMode
= mode
;
2168 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2171 if (!m_x11window
) return;
2173 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2174 // transparent/solid background mode
2176 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2178 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2179 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2183 void wxWindowDCImpl::SetPalette( const wxPalette
& WXUNUSED(palette
) )
2189 /* Use GetXColormap */
2190 XSetWindowColormap ((Display
*) m_display
, (Window
) m_x11window
->GetXWindow(),
2191 (Colormap
) palette
.GetXColormap());
2193 /* Use wxGetMainColormap */
2194 XSetWindowColormap ((Display
*) m_display
, (Window
) m_x11window
->GetXWindow(),
2195 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2200 void wxWindowDCImpl::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2202 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2204 if (!m_x11window
) return;
2213 rect
.x
= XLOG2DEV(x
);
2214 rect
.y
= YLOG2DEV(y
);
2215 rect
.width
= XLOG2DEVREL(width
);
2216 rect
.height
= YLOG2DEVREL(height
);
2218 if (!m_currentClippingRegion
.IsEmpty())
2219 m_currentClippingRegion
.Intersect( rect
);
2221 m_currentClippingRegion
= rect
;
2223 #if USE_PAINT_REGION
2224 if (!m_paintClippingRegion
.IsEmpty())
2225 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2228 wxCoord xx
, yy
, ww
, hh
;
2229 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2230 wxX11DCImpl::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2232 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2233 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2234 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2235 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2238 void wxWindowDCImpl::DoSetDeviceClippingRegion( const wxRegion
& region
)
2240 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2244 DestroyClippingRegion();
2248 if (!m_x11window
) return;
2250 if (!m_currentClippingRegion
.IsEmpty())
2251 m_currentClippingRegion
.Intersect( region
);
2253 m_currentClippingRegion
= region
;
2255 #if USE_PAINT_REGION
2256 if (!m_paintClippingRegion
.IsEmpty())
2257 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2260 wxCoord xx
, yy
, ww
, hh
;
2261 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2262 wxX11DCImpl::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2264 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2265 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2266 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2267 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2270 void wxWindowDCImpl::DestroyClippingRegion()
2272 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2274 wxDCImpl::DestroyClippingRegion();
2276 m_currentClippingRegion
.Clear();
2278 #if USE_PAINT_REGION
2279 if (!m_paintClippingRegion
.IsEmpty())
2280 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2283 if (!m_x11window
) return;
2285 if (m_currentClippingRegion
.IsEmpty())
2287 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2288 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2289 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2290 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2294 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2295 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2296 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2297 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2301 void wxWindowDCImpl::Destroy()
2303 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2305 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2307 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2309 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2313 void wxWindowDCImpl::ComputeScaleAndOrigin()
2315 /* CMB: copy scale to see if it changes */
2316 double origScaleX
= m_scaleX
;
2317 double origScaleY
= m_scaleY
;
2319 wxDCImpl::ComputeScaleAndOrigin();
2321 /* CMB: if scale has changed call SetPen to recalulate the line width */
2322 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2325 /* this is a bit artificial, but we need to force wxDC to think
2326 the pen has changed */
2333 wxSize
wxWindowDCImpl::GetPPI() const
2335 return wxSize(100, 100);
2338 int wxWindowDCImpl::GetDepth() const
2340 wxFAIL_MSG(wxT("not implemented"));
2345 //-----------------------------------------------------------------------------
2347 //-----------------------------------------------------------------------------
2349 IMPLEMENT_ABSTRACT_CLASS(wxClientDCImpl
, wxWindowDCImpl
)
2351 wxClientDCImpl::wxClientDCImpl( wxDC
*owner
, wxWindow
*window
)
2352 : wxWindowDCImpl( owner
, window
)
2354 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2356 m_x11window
= (WXWindow
*) window
->GetClientAreaWindow();
2358 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2359 if (m_x11window
== (WXWindow
*) window
->GetMainWindow())
2361 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2362 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2363 wxSize size
= window
->GetClientSize();
2364 DoSetClippingRegion( 0, 0, size
.x
, size
.y
);
2368 void wxClientDCImpl::DoGetSize(int *width
, int *height
) const
2370 wxCHECK_RET( m_window
, _T("GetSize() doesn't work without window") );
2372 m_window
->GetClientSize( width
, height
);
2375 // ----------------------------------------------------------------------------
2377 // ----------------------------------------------------------------------------
2379 IMPLEMENT_ABSTRACT_CLASS(wxPaintDCImpl
, wxClientDCImpl
)
2381 wxPaintDCImpl::wxPaintDCImpl(wxDC
*owner
, wxWindow
* window
)
2382 : wxClientDCImpl(owner
, window
)
2384 #if USE_PAINT_REGION
2385 if (!window
->GetClipPaintRegion())
2388 m_paintClippingRegion
= window
->GetUpdateRegion();
2389 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2392 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2394 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2395 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2396 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2397 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2399 #endif // USE_PAINT_REGION
2402 // ----------------------------------------------------------------------------
2404 // ----------------------------------------------------------------------------
2406 class wxDCModule
: public wxModule
2409 // we must be cleaned up before wxDisplayModule which closes the global
2413 AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule")));
2416 bool OnInit() { wxInitGCPool(); return true; }
2417 void OnExit() { wxCleanUpGCPool(); }
2420 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2423 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)