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"
27 #include "wx/x11/private.h"
28 #include "wx/x11/dcclient.h"
29 #include "wx/x11/dcmemory.h"
33 #include "pango/pangox.h"
35 #include "pango/pangoxft.h"
38 #include "pango_x.cpp"
41 //-----------------------------------------------------------------------------
43 //-----------------------------------------------------------------------------
45 // VZ: what is this for exactly??
46 #define USE_PAINT_REGION 0
48 //-----------------------------------------------------------------------------
50 //-----------------------------------------------------------------------------
60 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH)
61 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH)
63 static Pixmap hatches
[num_hatches
];
64 static Pixmap
*hatch_bitmap
= (Pixmap
*) NULL
;
66 //-----------------------------------------------------------------------------
68 //-----------------------------------------------------------------------------
70 const double RAD2DEG
= 180.0 / M_PI
;
72 // ----------------------------------------------------------------------------
74 // ----------------------------------------------------------------------------
76 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
77 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
79 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
81 //-----------------------------------------------------------------------------
82 // Implement Pool of Graphic contexts. Creating them takes too much time.
83 //-----------------------------------------------------------------------------
85 #define GC_POOL_SIZE 200
111 static wxGC wxGCPool
[GC_POOL_SIZE
];
113 static void wxInitGCPool()
115 memset( wxGCPool
, 0, GC_POOL_SIZE
*sizeof(wxGC
) );
118 static void wxCleanUpGCPool()
120 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
122 if (wxGCPool
[i
].m_gc
)
123 XFreeGC( wxGlobalDisplay(), wxGCPool
[i
].m_gc
);
127 static GC
wxGetPoolGC( Window window
, wxPoolGCType type
)
129 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
131 if (!wxGCPool
[i
].m_gc
)
133 wxGCPool
[i
].m_gc
= XCreateGC( wxGlobalDisplay(), window
, 0, NULL
);
134 XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool
[i
].m_gc
, FALSE
);
135 wxGCPool
[i
].m_type
= type
;
136 wxGCPool
[i
].m_used
= false;
138 if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type
== type
))
140 wxGCPool
[i
].m_used
= true;
141 return wxGCPool
[i
].m_gc
;
145 wxFAIL_MSG( wxT("No GC available") );
150 static void wxFreePoolGC( GC gc
)
152 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
154 if (wxGCPool
[i
].m_gc
== gc
)
156 wxGCPool
[i
].m_used
= false;
161 wxFAIL_MSG( wxT("Wrong GC") );
164 // ----------------------------------------------------------------------------
166 // ----------------------------------------------------------------------------
168 IMPLEMENT_ABSTRACT_CLASS(wxWindowDCImpl
, wxX11DCImpl
)
170 wxWindowDCImpl::wxWindowDCImpl( wxDC
*owner
)
171 : wxX11DCImpl( owner
)
176 wxWindowDCImpl::wxWindowDCImpl( wxDC
* owner
, wxWindow
*window
)
177 : wxX11DCImpl( owner
)
179 wxASSERT_MSG( window
, wxT("DC needs a window") );
183 m_font
= window
->GetFont();
185 m_x11window
= (WXWindow
*) window
->GetMainWindow();
190 // don't report problems
196 m_display
= (WXDisplay
*) wxGlobalDisplay();
199 m_fontdesc
= window
->GetFont().GetNativeFontInfo()->description
;
202 int screen
= DefaultScreen( (Display
*) m_display
);
203 m_cmap
= (WXColormap
) DefaultColormap( (Display
*) m_display
, screen
);
207 /* this must be done after SetUpDC, bacause SetUpDC calls the
208 repective SetBrush, SetPen, SetBackground etc functions
209 to set up the DC. SetBackground call m_window->SetBackground
210 and this might not be desired as the standard dc background
211 is white whereas a window might assume gray to be the
212 standard (as e.g. wxStatusBar) */
217 wxWindowDCImpl::~wxWindowDCImpl()
222 void wxWindowDCImpl::Init()
224 m_display
= (WXDisplay
*) NULL
;
225 m_penGC
= (WXGC
*) NULL
;
226 m_brushGC
= (WXGC
*) NULL
;
227 m_textGC
= (WXGC
*) NULL
;
228 m_bgGC
= (WXGC
*) NULL
;
229 m_cmap
= (WXColormap
*) NULL
;
231 m_isScreenDC
= false;
232 m_x11window
= (WXWindow
*) NULL
;
235 m_context
= wxTheApp
->GetPangoContext();
236 m_fontdesc
= (PangoFontDescription
*)NULL
;
240 void wxWindowDCImpl::SetUpDC()
244 wxASSERT_MSG( !m_penGC
, wxT("GCs already created") );
249 wxMemoryDCImpl
*mem_impl
= (wxMemoryDCImpl
*) this;
250 if (mem_impl
->GetSelectedBitmap().IsOk())
251 ismono
= mem_impl
->GetSelectedBitmap().GetDepth() == 1;
256 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxPEN_SCREEN
);
257 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxBRUSH_SCREEN
);
258 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxTEXT_SCREEN
);
259 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxBG_SCREEN
);
262 if (m_isMemDC
&& ismono
)
264 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxPEN_MONO
);
265 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxBRUSH_MONO
);
266 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxTEXT_MONO
);
267 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxBG_MONO
);
271 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxPEN_COLOUR
);
272 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxBRUSH_COLOUR
);
273 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxTEXT_COLOUR
);
274 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_x11window
, wxBG_COLOUR
);
277 /* background colour */
278 m_backgroundBrush
= *wxWHITE_BRUSH
;
279 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
280 unsigned long bg_col
= m_backgroundBrush
.GetColour().GetPixel();
282 m_textForegroundColour
= *wxBLACK
;
283 m_textBackgroundColour
= *wxWHITE
;
286 m_textForegroundColour
.CalcPixel( m_cmap
);
287 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
289 m_textBackgroundColour
.CalcPixel( m_cmap
);
290 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
292 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
295 // By default, draw transparently
296 GrSetGCUseBackground((GC
) m_textGC
, FALSE
);
300 m_pen
.GetColour().CalcPixel( m_cmap
);
301 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
302 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
304 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
307 m_brush
.GetColour().CalcPixel( m_cmap
);
308 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
309 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
311 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
314 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
315 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
317 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
320 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
321 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
322 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
325 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
326 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
327 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
328 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
332 int xscreen
= DefaultScreen( (Display
*) m_display
);
333 Window xroot
= RootWindow( (Display
*) m_display
, xscreen
);
335 hatch_bitmap
= hatches
;
336 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, bdiag_bits
, bdiag_width
, bdiag_height
);
337 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cdiag_bits
, cdiag_width
, cdiag_height
);
338 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, fdiag_bits
, fdiag_width
, fdiag_height
);
339 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cross_bits
, cross_width
, cross_height
);
340 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, horiz_bits
, horiz_width
, horiz_height
);
341 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, verti_bits
, verti_width
, verti_height
);
345 void wxWindowDCImpl::DoGetSize( int* width
, int* height
) const
347 wxCHECK_RET( m_window
, _T("GetSize() doesn't work without window") );
349 m_window
->GetSize(width
, height
);
352 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
353 const wxColour
& col
, int style
);
355 bool wxWindowDCImpl::DoFloodFill(wxCoord x
, wxCoord y
,
356 const wxColour
& col
, int style
)
358 return wxDoFloodFill(GetOwner(), x
, y
, col
, style
);
361 bool wxWindowDCImpl::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
363 // Generic (and therefore rather inefficient) method.
364 // Could be improved.
366 wxBitmap
bitmap(1, 1);
367 memdc
.SelectObject(bitmap
);
368 memdc
.Blit(0, 0, 1, 1, GetOwner(), x1
, y1
);
369 memdc
.SelectObject(wxNullBitmap
);
370 wxImage
image(bitmap
.ConvertToImage());
371 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
375 void wxWindowDCImpl::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
377 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
379 if (m_pen
.GetStyle() != wxTRANSPARENT
)
383 // This hack is for the iPaq: XDrawLine draws
384 // nothing, whereas XDrawLines works...
390 DoDrawLines( 2, points
, 0, 0 );
392 // XDrawLine( (Display*) m_display, (Window) m_x11window,
393 // (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
396 CalcBoundingBox(x1
, y1
);
397 CalcBoundingBox(x2
, y2
);
401 void wxWindowDCImpl::DoCrossHair( wxCoord x
, wxCoord y
)
403 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
405 if (m_pen
.GetStyle() != wxTRANSPARENT
)
410 wxCoord xx
= XLOG2DEV(x
);
411 wxCoord yy
= YLOG2DEV(y
);
414 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
,
415 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
416 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
,
417 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
422 void wxWindowDCImpl::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
424 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
426 wxCoord xx1
= XLOG2DEV(x1
);
427 wxCoord yy1
= YLOG2DEV(y1
);
428 wxCoord xx2
= XLOG2DEV(x2
);
429 wxCoord yy2
= YLOG2DEV(y2
);
430 wxCoord xxc
= XLOG2DEV(xc
);
431 wxCoord yyc
= YLOG2DEV(yc
);
432 double dx
= xx1
- xxc
;
433 double dy
= yy1
- yyc
;
434 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
435 wxCoord r
= (wxCoord
)radius
;
436 double radius1
, radius2
;
438 if (xx1
== xx2
&& yy1
== yy2
)
446 radius1
= radius2
= 0.0;
450 radius1
= (xx1
- xxc
== 0) ?
451 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
452 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
453 radius2
= (xx2
- xxc
== 0) ?
454 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
455 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
457 wxCoord alpha1
= wxCoord(radius1
* 64.0);
458 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
459 while (alpha2
<= 0) alpha2
+= 360*64;
460 while (alpha1
> 360*64) alpha1
-= 360*64;
464 if (m_brush
.GetStyle() != wxTRANSPARENT
)
466 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
468 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
469 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
470 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
472 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
473 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
475 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
477 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
479 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
480 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
482 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
483 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
485 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
487 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
489 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
490 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
492 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
493 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
495 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
497 if (m_brush
.GetStyle() == wxSTIPPLE
)
499 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
500 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
501 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
503 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
504 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
506 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
510 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
511 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
515 if (m_pen
.GetStyle() != wxTRANSPARENT
)
517 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
,
518 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
520 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
,
521 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
523 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
,
524 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
528 CalcBoundingBox (x1
, y1
);
529 CalcBoundingBox (x2
, y2
);
532 void wxWindowDCImpl::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
534 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
536 wxCoord xx
= XLOG2DEV(x
);
537 wxCoord yy
= YLOG2DEV(y
);
538 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
539 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
541 // CMB: handle -ve width and/or height
542 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
543 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
547 wxCoord start
= wxCoord(sa
* 64.0);
548 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
550 if (m_brush
.GetStyle() != wxTRANSPARENT
)
552 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
554 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
555 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
556 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
558 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
559 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
561 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
563 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
565 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
566 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
568 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
569 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
571 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
573 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
575 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
576 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
578 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
579 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
581 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
583 if (m_brush
.GetStyle() == wxSTIPPLE
)
585 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
586 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
587 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
589 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
590 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
592 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
596 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
597 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
601 if (m_pen
.GetStyle() != wxTRANSPARENT
)
603 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
,
604 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
608 CalcBoundingBox (x
, y
);
609 CalcBoundingBox (x
+ width
, y
+ height
);
612 void wxWindowDCImpl::DoDrawPoint( wxCoord x
, wxCoord y
)
614 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
616 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_x11window
)
617 XDrawPoint( (Display
*) m_display
, (Window
) m_x11window
,
618 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
620 CalcBoundingBox (x
, y
);
623 void wxWindowDCImpl::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
625 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
627 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
630 XPoint
*xpoints
= new XPoint
[n
];
631 for (int i
= 0; i
< n
; i
++)
633 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
634 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
636 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
638 XDrawLines( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xpoints
, n
, 0 );
643 void wxWindowDCImpl::DoDrawPolygon( int n
, wxPoint points
[],
644 wxCoord xoffset
, wxCoord yoffset
,
645 int WXUNUSED(fillStyle
) )
647 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
651 XPoint
*xpoints
= new XPoint
[n
+ 1];
653 for (i
= 0; i
< n
; i
++)
655 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
656 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
658 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
663 if (m_brush
.GetStyle() != wxTRANSPARENT
)
666 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
668 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
669 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
670 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
672 XFillPolygon( (Display
*) m_display
, (Window
) m_x11window
,
673 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
675 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
677 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
679 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
680 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
682 XFillPolygon( (Display
*) m_display
, (Window
) m_x11window
,
683 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
685 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
687 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
689 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
690 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
692 XFillPolygon( (Display
*) m_display
, (Window
) m_x11window
,
693 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
695 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
697 if (m_brush
.GetStyle() == wxSTIPPLE
)
699 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
700 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
701 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
703 XFillPolygon( (Display
*) m_display
, (Window
) m_x11window
,
704 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
706 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
710 XFillPolygon( (Display
*) m_display
, (Window
) m_x11window
,
711 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
715 if (m_pen
.GetStyle () != wxTRANSPARENT
)
717 // Close figure for XDrawLines
718 xpoints
[i
].x
= xpoints
[0].x
;
719 xpoints
[i
].y
= xpoints
[0].y
;
721 XDrawLines( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
728 void wxWindowDCImpl::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
730 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
732 wxCoord xx
= XLOG2DEV(x
);
733 wxCoord yy
= YLOG2DEV(y
);
734 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
735 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
737 // CMB: draw nothing if transformed w or h is 0
738 if (ww
== 0 || hh
== 0) return;
740 // CMB: handle -ve width and/or height
741 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
742 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
746 if (m_brush
.GetStyle() != wxTRANSPARENT
)
748 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
750 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
751 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
752 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
754 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
755 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
757 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
759 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
761 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
762 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
764 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
765 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
767 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
769 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
771 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
772 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
774 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
775 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
777 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
779 if (m_brush
.GetStyle() == wxSTIPPLE
)
781 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
782 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
783 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
785 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
786 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
788 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
792 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
793 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
797 if (m_pen
.GetStyle () != wxTRANSPARENT
)
799 XDrawRectangle( (Display
*) m_display
, (Window
) m_x11window
,
800 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
804 CalcBoundingBox( x
, y
);
805 CalcBoundingBox( x
+ width
, y
+ height
);
808 void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
810 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
812 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
814 wxCoord xx
= XLOG2DEV(x
);
815 wxCoord yy
= YLOG2DEV(y
);
816 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
817 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
818 wxCoord rr
= XLOG2DEVREL((wxCoord
)radius
);
820 // CMB: handle -ve width and/or height
821 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
822 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
824 // CMB: if radius is zero use DrawRectangle() instead to avoid
825 // X drawing errors with small radii
828 XDrawRectangle( (Display
*) m_display
, (Window
) m_x11window
,
829 (GC
) m_penGC
, x
, y
, width
, height
);
833 // CMB: draw nothing if transformed w or h is 0
834 if (ww
== 0 || hh
== 0) return;
836 // CMB: adjust size if outline is drawn otherwise the result is
837 // 1 pixel too wide and high
838 if (m_pen
.GetStyle() != wxTRANSPARENT
)
846 // CMB: ensure dd is not larger than rectangle otherwise we
847 // get an hour glass shape
849 if (dd
> ww
) dd
= ww
;
850 if (dd
> hh
) dd
= hh
;
853 if (m_brush
.GetStyle() != wxTRANSPARENT
)
855 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
857 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
858 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
859 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
860 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_textGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
861 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_textGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
862 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_textGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
863 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
864 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
865 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_textGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
866 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0);
868 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
870 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
871 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
872 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
873 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
874 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
875 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
876 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
877 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
879 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
881 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
882 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
883 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
884 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
885 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
886 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
887 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
888 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
890 if (m_brush
.GetStyle() == wxSTIPPLE
)
892 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
893 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
894 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
895 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
896 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
897 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
898 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
899 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
900 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
901 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
905 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
906 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
907 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
908 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
909 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
910 XFillArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
913 if (m_pen
.GetStyle() != wxTRANSPARENT
)
915 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy
);
916 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
917 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr
);
918 XDrawLine( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr
);
919 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
920 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
921 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
922 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_penGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
926 // this ignores the radius
927 CalcBoundingBox( x
, y
);
928 CalcBoundingBox( x
+ width
, y
+ height
);
931 void wxWindowDCImpl::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
933 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
935 wxCoord xx
= XLOG2DEV(x
);
936 wxCoord yy
= YLOG2DEV(y
);
937 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
938 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
940 // CMB: handle -ve width and/or height
941 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
942 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
946 if (m_brush
.GetStyle() != wxTRANSPARENT
)
948 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
950 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
951 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
952 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
954 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
955 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
957 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
959 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
961 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
962 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
964 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
965 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
967 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
969 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
971 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
972 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
974 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
975 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
977 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
979 if (m_brush
.GetStyle() == wxSTIPPLE
)
981 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
982 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
983 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
985 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
986 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
988 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
992 XFillArc( (Display
*) m_display
, (Window
) m_x11window
,
993 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
997 if (m_pen
.GetStyle () != wxTRANSPARENT
)
999 XDrawArc( (Display
*) m_display
, (Window
) m_x11window
,
1000 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
1004 CalcBoundingBox( x
, y
);
1005 CalcBoundingBox( x
+ width
, y
+ height
);
1008 void wxWindowDCImpl::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
1010 DoDrawBitmap(icon
, x
, y
, true);
1014 void wxWindowDCImpl::DoDrawBitmap( const wxBitmap
&bitmap
,
1015 wxCoord x
, wxCoord y
,
1018 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1020 wxCHECK_RET( bitmap
.IsOk(), wxT("invalid bitmap") );
1022 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1024 /* scale/translate size and position */
1025 int xx
= XLOG2DEV(x
);
1026 int yy
= YLOG2DEV(y
);
1028 int w
= bitmap
.GetWidth();
1029 int h
= bitmap
.GetHeight();
1031 CalcBoundingBox( x
, y
);
1032 CalcBoundingBox( x
+ w
, y
+ h
);
1034 if (!m_x11window
) return;
1036 int ww
= XLOG2DEVREL(w
);
1037 int hh
= YLOG2DEVREL(h
);
1039 /* compare to current clipping region */
1040 if (!m_currentClippingRegion
.IsNull())
1042 wxRegion
tmp( xx
,yy
,ww
,hh
);
1043 tmp
.Intersect( m_currentClippingRegion
);
1048 /* scale bitmap if required */
1049 wxBitmap use_bitmap
;
1050 if ((w
!= ww
) || (h
!= hh
))
1052 wxImage
image( bitmap
.ConvertToImage() );
1053 image
.Rescale( ww
, hh
);
1056 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1063 use_bitmap
= bitmap
;
1066 /* apply mask if any */
1067 WXPixmap mask
= NULL
;
1068 if (use_bitmap
.GetMask())
1069 mask
= use_bitmap
.GetMask()->GetBitmap();
1071 if (useMask
&& mask
)
1073 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
1074 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
1075 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
1077 GrSetGCUseBackground(gc
, FALSE
);
1078 GrSetGCMode(gc
, GR_MODE_COPY
);
1080 // This code assumes that background and foreground
1081 // colours are used in ROPs, like in MSW.
1082 // Not sure if this is true.
1084 // Copy destination to buffer.
1085 // In DoBlit, we need this step because Blit has
1086 // a ROP argument. Here, we don't need it.
1087 // In DoBlit, we may be able to eliminate this step
1088 // if we check if the rop = copy
1090 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_x11window
,
1091 0, 0, GR_MODE_COPY
);
1094 // Copy src to buffer using selected raster op (none selected
1095 // in DrawBitmap, so just use Gxcopy)
1096 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
1097 0, 0, GR_MODE_COPY
);
1099 // Set masked area in buffer to BLACK (pixel value 0)
1100 GrSetGCBackground(gc
, WHITE
);
1101 GrSetGCForeground(gc
, BLACK
);
1102 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
1105 // set unmasked area in dest to BLACK
1106 GrSetGCBackground(gc
, BLACK
);
1107 GrSetGCForeground(gc
, WHITE
);
1108 GrCopyArea((Window
) m_x11window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
1111 // OR buffer to dest
1112 GrCopyArea((Window
) m_x11window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
1116 GrDestroyWindow(bufPixmap
);
1119 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_x11window
,
1120 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1122 /* remove mask again if any */
1123 if (useMask
&& mask
)
1125 if (!m_currentClippingRegion
.IsNull())
1126 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1133 void wxWindowDCImpl::DoDrawBitmap( const wxBitmap
&bitmap
,
1134 wxCoord x
, wxCoord y
,
1137 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1139 wxCHECK_RET( bitmap
.IsOk(), wxT("invalid bitmap") );
1141 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1143 // scale/translate size and position
1144 int xx
= XLOG2DEV(x
);
1145 int yy
= YLOG2DEV(y
);
1147 int w
= bitmap
.GetWidth();
1148 int h
= bitmap
.GetHeight();
1150 CalcBoundingBox( x
, y
);
1151 CalcBoundingBox( x
+ w
, y
+ h
);
1153 if (!m_x11window
) return;
1155 int ww
= XLOG2DEVREL(w
);
1156 int hh
= YLOG2DEVREL(h
);
1158 // compare to current clipping region
1159 if (!m_currentClippingRegion
.IsNull())
1161 wxRegion
tmp( xx
,yy
,ww
,hh
);
1162 tmp
.Intersect( m_currentClippingRegion
);
1167 // scale bitmap if required
1168 wxBitmap use_bitmap
;
1169 if ((w
!= ww
) || (h
!= hh
))
1171 wxImage
image( bitmap
.ConvertToImage() );
1172 image
.Rescale( ww
, hh
);
1175 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1182 use_bitmap
= bitmap
;
1185 // apply mask if any
1186 WXPixmap mask
= NULL
;
1187 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1189 bool setClipMask
= false;
1191 if (!m_currentClippingRegion
.IsNull() || (useMask
&& mask
))
1193 // XSetClipMask() call is necessary (because of clip region and/or transparent mask)
1195 Pixmap new_pixmap
= 0;
1197 if (!m_currentClippingRegion
.IsNull())
1199 // clipping necessary => create new_pixmap
1200 Display
*xdisplay
= (Display
*) m_display
;
1201 int xscreen
= DefaultScreen( xdisplay
);
1202 Window xroot
= RootWindow( xdisplay
, xscreen
);
1204 new_pixmap
= XCreatePixmap( xdisplay
, xroot
, ww
, hh
, 1 );
1205 GC gc
= XCreateGC( xdisplay
, new_pixmap
, 0, NULL
);
1207 XSetForeground( xdisplay
, gc
, BlackPixel(xdisplay
,xscreen
) );
1209 XSetFillStyle( xdisplay
, gc
, FillSolid
);
1210 XFillRectangle( xdisplay
, new_pixmap
, gc
, 0, 0, ww
, hh
);
1212 XSetForeground( xdisplay
, gc
, WhitePixel(xdisplay
,xscreen
) );
1214 if (useMask
&& mask
)
1216 // transparent mask => call XSetStipple
1217 XSetFillStyle( xdisplay
, gc
, FillStippled
);
1218 XSetTSOrigin( xdisplay
, gc
, 0, 0);
1219 XSetStipple( xdisplay
, gc
, (Pixmap
) mask
);
1222 wxCoord clip_x
, clip_y
, clip_w
, clip_h
;
1223 m_currentClippingRegion
.GetBox(clip_x
, clip_y
, clip_w
, clip_h
);
1224 XFillRectangle( xdisplay
, new_pixmap
, gc
, clip_x
-xx
, clip_y
-yy
, clip_w
, clip_h
);
1226 XFreeGC( xdisplay
, gc
);
1232 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, new_pixmap
);
1234 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1235 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1240 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, new_pixmap
);
1242 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1243 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1247 XFreePixmap( (Display
*) m_display
, new_pixmap
);
1250 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1251 // drawing a mono-bitmap (XBitmap) we use the current text GC
1253 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_x11window
,
1254 (GC
) m_textGC
, 0, 0, ww
, hh
, xx
, yy
, 1 );
1256 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_x11window
,
1257 (GC
) m_penGC
, 0, 0, ww
, hh
, xx
, yy
);
1259 // remove mask again if any
1264 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1265 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1266 if (!m_currentClippingRegion
.IsNull())
1267 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1271 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1272 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1273 if (!m_currentClippingRegion
.IsNull())
1274 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1279 // wxUSE_NANOX/!wxUSE_NANOX
1281 bool wxWindowDCImpl::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1282 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1283 wxCoord xsrcMask
, wxCoord ysrcMask
)
1285 /* this is the nth try to get this utterly useless function to
1286 work. it now completely ignores the scaling or translation
1287 of the source dc, but scales correctly on the target dc and
1288 knows about possible mask information in a memory dc. */
1290 wxCHECK_MSG( IsOk(), false, wxT("invalid window dc") );
1292 wxCHECK_MSG( source
, false, wxT("invalid source dc") );
1294 if (!m_x11window
) return false;
1296 // transform the source DC coords to the device ones
1297 xsrc
= source
->LogicalToDeviceX(xsrc
);
1298 ysrc
= source
->LogicalToDeviceY(ysrc
);
1300 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1301 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1302 wxWindowDCImpl
*src_impl
= (wxWindowDCImpl
*) srcDC
->GetImpl();
1304 bool use_bitmap_method
= false;
1305 bool is_mono
= false;
1307 // TODO: use the mask origin when drawing transparently
1308 if (xsrcMask
== -1 && ysrcMask
== -1)
1314 if (src_impl
->m_isMemDC
)
1316 wxBitmap selected
= memDC
->GetSelectedBitmap();
1318 if (!selected
.IsOk()) return false;
1320 /* we use the "XCopyArea" way to copy a memory dc into
1321 y different window if the memory dc BOTH
1322 a) doesn't have any mask or its mask isn't used
1326 if (useMask
&& (selected
.GetMask()))
1328 /* we HAVE TO use the direct way for memory dcs
1329 that have mask since the XCopyArea doesn't know
1331 use_bitmap_method
= true;
1333 else if (selected
.GetDepth() == 1)
1335 /* we HAVE TO use the direct way for memory dcs
1336 that are bitmaps because XCopyArea doesn't cope
1337 with different bit depths */
1339 use_bitmap_method
= true;
1341 else if ((xsrc
== 0) && (ysrc
== 0) &&
1342 (width
== selected
.GetWidth()) &&
1343 (height
== selected
.GetHeight()))
1345 /* we SHOULD use the direct way if all of the bitmap
1346 in the memory dc is copied in which case XCopyArea
1347 wouldn't be able able to boost performace by reducing
1348 the area to be scaled */
1349 use_bitmap_method
= true;
1353 use_bitmap_method
= false;
1357 CalcBoundingBox( xdest
, ydest
);
1358 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1360 // scale/translate size and position
1361 wxCoord xx
= XLOG2DEV(xdest
);
1362 wxCoord yy
= YLOG2DEV(ydest
);
1364 wxCoord ww
= XLOG2DEVREL(width
);
1365 wxCoord hh
= YLOG2DEVREL(height
);
1367 // compare to current clipping region
1368 if (!m_currentClippingRegion
.IsNull())
1370 wxRegion
tmp( xx
,yy
,ww
,hh
);
1371 tmp
.Intersect( m_currentClippingRegion
);
1376 int old_logical_func
= m_logicalFunction
;
1377 SetLogicalFunction( logical_func
);
1379 if (use_bitmap_method
)
1381 wxBitmap selected
= memDC
->GetSelectedBitmap();
1383 // scale/translate bitmap size
1384 wxCoord bm_width
= selected
.GetWidth();
1385 wxCoord bm_height
= selected
.GetHeight();
1387 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1388 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1390 // scale bitmap if required
1391 wxBitmap use_bitmap
;
1393 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1395 wxImage
image( selected
.ConvertToImage() );
1396 image
= image
.Scale( bm_ww
, bm_hh
);
1400 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1407 use_bitmap
= selected
;
1410 // apply mask if any
1411 WXPixmap mask
= NULL
;
1412 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1414 if (useMask
&& mask
)
1416 WXPixmap new_mask
= NULL
;
1418 if (!m_currentClippingRegion
.IsNull())
1421 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1422 GdkGC
*gc
= gdk_gc_new( new_mask
);
1424 gdk_gc_set_foreground( gc
, &col
);
1425 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1427 gdk_gc_set_background( gc
, &col
);
1429 gdk_gc_set_foreground( gc
, &col
);
1430 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1431 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1432 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1433 gdk_gc_set_stipple( gc
, mask
);
1434 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1441 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1443 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1444 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1449 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1451 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1452 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1456 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1459 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1460 // drawing a mono-bitmap (XBitmap) we use the current text GC
1462 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_x11window
,
1463 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1465 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_x11window
,
1466 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1468 // remove mask again if any
1469 if (useMask
&& mask
)
1473 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1474 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1475 if (!m_currentClippingRegion
.IsNull())
1476 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1480 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1481 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1482 if (!m_currentClippingRegion
.IsNull())
1483 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1487 else // use_bitmap_method
1489 wxDCImpl
*impl
= srcDC
->GetImpl();
1490 wxWindowDCImpl
*x11_impl
= wxDynamicCast(impl
, wxWindowDCImpl
);
1493 SetLogicalFunction( old_logical_func
);
1497 if ((width
!= ww
) || (height
!= hh
))
1499 /* Draw source window into a bitmap as we cannot scale
1500 a window in contrast to a bitmap. this would actually
1501 work with memory dcs as well, but we'd lose the mask
1502 information and waste one step in this process since
1503 a memory already has a bitmap. all this is slightly
1504 inefficient as we could take an XImage directly from
1505 an X window, but we'd then also have to care that
1506 the window is not outside the screen (in which case
1507 we'd get a BadMatch or what not).
1508 Is a double XGetImage and combined XGetPixel and
1509 XPutPixel really faster? I'm not sure. look at wxXt
1510 for a different implementation of the same problem. */
1512 wxBitmap
bitmap( width
, height
);
1514 // copy including child window contents
1515 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1516 XCopyArea( (Display
*) m_display
, (Window
) x11_impl
->GetX11Window(), (Window
) bitmap
.GetPixmap(),
1517 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1518 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1521 wxImage
image( bitmap
.ConvertToImage() );
1522 image
= image
.Scale( ww
, hh
);
1524 // convert to bitmap
1527 // draw scaled bitmap
1528 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_x11window
,
1529 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1533 // No scaling and not a memory dc with a mask either
1534 // copy including child window contents
1535 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1536 XCopyArea( (Display
*) m_display
, (Window
) x11_impl
->GetX11Window(), (Window
) m_x11window
,
1537 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1538 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1542 SetLogicalFunction( old_logical_func
);
1547 void wxWindowDCImpl::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1549 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1551 if (!m_x11window
) return;
1557 PangoLayout
*layout
= pango_layout_new(m_context
);
1558 pango_layout_set_font_description(layout
, m_fontdesc
);
1560 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1561 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1565 pango_layout_get_pixel_size(layout
, &w
, &h
);
1570 x11_draw_layout( (Drawable
) m_x11window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1572 g_object_unref( G_OBJECT( layout
) );
1574 CalcBoundingBox (x
+ width
, y
+ height
);
1575 CalcBoundingBox (x
, y
);
1577 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1579 wxCHECK_RET( xfont
, wxT("invalid font") );
1581 // First draw a rectangle representing the text background, if a text
1582 // background is specified
1583 if (m_textBackgroundColour
.IsOk () && (m_backgroundMode
!= wxTRANSPARENT
))
1585 // Since X draws from the baseline of the text, must add the text height
1590 int direction
, descent
;
1592 slen
= strlen(text
);
1593 XCharStruct overall_return
;
1595 (void)XTextExtents(xfont
, (const char*) text
.c_str(), slen
, &direction
,
1596 &ascent
, &descent
, &overall_return
);
1598 cx
= overall_return
.width
;
1599 cy
= ascent
+ descent
;
1600 m_textBackgroundColour
.CalcPixel(m_cmap
);
1601 m_textForegroundColour
.CalcPixel(m_cmap
);
1602 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1603 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
,
1604 (GC
) m_textGC
, x
, y
, cx
, cy
);
1605 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1609 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1611 // This may be a test for whether the font is 16-bit, but it also
1612 // seems to fail for valid 8-bit fonts too.
1613 if (1) // (xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
1616 XDrawString( (Display
*) m_display
, (Window
) m_x11window
,
1617 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.length() );
1621 if (m_font
.GetUnderlined())
1623 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1624 if (font
->descent
> 0) ul_y
++;
1625 gdk_draw_line( m_x11window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1628 width
= wxCoord(width
/ m_scaleX
);
1629 height
= wxCoord(height
/ m_scaleY
);
1631 CalcBoundingBox (x
+ width
, y
+ height
);
1632 CalcBoundingBox (x
, y
);
1637 void wxWindowDCImpl::DoDrawRotatedText(const wxString
& WXUNUSED(text
),
1638 wxCoord
WXUNUSED(x
), wxCoord
WXUNUSED(y
),
1639 double WXUNUSED(angle
))
1641 wxFAIL_MSG( "not implemented" );
1644 void wxWindowDCImpl::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1645 wxCoord
*descent
, wxCoord
*externalLeading
,
1646 const wxFont
*font
) const
1648 wxCHECK_RET( IsOk(), wxT("invalid dc") );
1652 if (width
) (*width
) = 0;
1653 if (height
) (*height
) = 0;
1658 PangoLayout
*layout
= pango_layout_new( m_context
);
1661 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1663 pango_layout_set_font_description(layout
, m_fontdesc
);
1665 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1666 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1670 pango_layout_get_pixel_size(layout
, &w
, &h
);
1672 if (width
) (*width
) = (wxCoord
) w
;
1673 if (height
) (*height
) = (wxCoord
) h
;
1676 // Do something about metrics here. TODO.
1679 if (externalLeading
) (*externalLeading
) = 0; // ??
1681 g_object_unref( G_OBJECT( layout
) );
1683 wxFont fontToUse
= m_font
;
1684 if (font
) fontToUse
= *font
;
1686 wxCHECK_RET( fontToUse
.IsOk(), wxT("invalid font") );
1688 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1690 wxCHECK_RET( xfont
, wxT("invalid font") );
1692 int direction
, ascent
, descent2
;
1693 XCharStruct overall
;
1695 XTextExtents( xfont
, (const char*) string
.c_str(), string
.length(), &direction
,
1696 &ascent
, &descent2
, &overall
);
1699 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1701 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1703 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1704 if (externalLeading
)
1705 *externalLeading
= 0; // ??
1709 wxCoord
wxWindowDCImpl::GetCharWidth() const
1711 wxCHECK_MSG( IsOk(), 0, wxT("invalid dc") );
1714 PangoLayout
*layout
= pango_layout_new( m_context
);
1717 pango_layout_set_font_description(layout
, m_fontdesc
);
1719 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1721 pango_layout_set_text(layout
, "H", 1 );
1723 pango_layout_get_pixel_size(layout
, &w
, &h
);
1724 g_object_unref( G_OBJECT( layout
) );
1728 wxCHECK_MSG( m_font
.IsOk(), 0, wxT("invalid font") );
1730 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1732 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1734 int direction
, ascent
, descent
;
1735 XCharStruct overall
;
1737 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1739 return (wxCoord
)(overall
.width
/ m_scaleX
);
1743 wxCoord
wxWindowDCImpl::GetCharHeight() const
1745 wxCHECK_MSG( IsOk(), 0, wxT("invalid dc") );
1748 PangoLayout
*layout
= pango_layout_new( m_context
);
1751 pango_layout_set_font_description(layout
, m_fontdesc
);
1753 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1755 pango_layout_set_text(layout
, "H", 1 );
1757 pango_layout_get_pixel_size(layout
, &w
, &h
);
1758 g_object_unref( G_OBJECT( layout
) );
1762 wxCHECK_MSG( m_font
.IsOk(), 0, wxT("invalid font") );
1764 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1766 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1768 int direction
, ascent
, descent
;
1769 XCharStruct overall
;
1771 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1773 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1777 void wxWindowDCImpl::Clear()
1779 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1781 if (!m_x11window
) return;
1783 /* - we either are a memory dc or have a window as the
1784 owner. anything else shouldn't happen.
1785 - we don't use gdk_window_clear() as we don't set
1786 the window's background colour anymore. it is too
1787 much pain to keep the DC's and the window's back-
1788 ground colour in synch. */
1793 m_window
->GetSize( &width
, &height
);
1794 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1801 DoGetSize( &width
, &height
);
1802 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1807 void wxWindowDCImpl::SetFont( const wxFont
&font
)
1809 wxCHECK_RET( IsOk(), wxT("invalid dc") );
1814 m_fontdesc
= font
.GetNativeFontInfo()->description
;
1818 void wxWindowDCImpl::SetPen( const wxPen
&pen
)
1820 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1822 if (m_pen
== pen
) return;
1826 if (!m_pen
.IsOk()) return;
1828 if (!m_x11window
) return;
1830 int width
= m_pen
.GetWidth();
1833 // CMB: if width is non-zero scale it with the dc
1838 // X doesn't allow different width in x and y and so we take
1841 ( fabs((double) XLOG2DEVREL(width
)) +
1842 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1846 static const wxX11Dash dotted
[] = {1, 1};
1847 static const wxX11Dash short_dashed
[] = {2, 2};
1848 static const wxX11Dash long_dashed
[] = {2, 4};
1849 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1851 // We express dash pattern in pen width unit, so we are
1852 // independent of zoom factor and so on...
1854 const wxX11Dash
*req_dash
;
1856 int lineStyle
= LineSolid
;
1857 switch (m_pen
.GetStyle())
1861 lineStyle
= LineOnOffDash
;
1862 req_nb_dash
= m_pen
.GetDashCount();
1863 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1868 lineStyle
= LineOnOffDash
;
1875 lineStyle
= LineOnOffDash
;
1877 req_dash
= long_dashed
;
1882 lineStyle
= LineOnOffDash
;
1884 req_dash
= short_dashed
;
1889 // lineStyle = LineDoubleDash;
1890 lineStyle
= LineOnOffDash
;
1892 req_dash
= dotted_dashed
;
1897 case wxSTIPPLE_MASK_OPAQUE
:
1902 lineStyle
= LineSolid
;
1903 req_dash
= (wxX11Dash
*)NULL
;
1909 int capStyle
= CapRound
;
1910 switch (m_pen
.GetCap())
1912 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1913 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1920 capStyle
= CapNotLast
;
1924 capStyle
= CapRound
;
1930 int joinStyle
= JoinRound
;
1931 switch (m_pen
.GetJoin())
1933 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1934 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1936 default: { joinStyle
= JoinRound
; break; }
1939 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1941 m_pen
.GetColour().CalcPixel( m_cmap
);
1942 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1945 void wxWindowDCImpl::SetBrush( const wxBrush
&brush
)
1947 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1949 if (m_brush
== brush
) return;
1953 if (!m_brush
.IsOk()) return;
1955 if (!m_x11window
) return;
1957 m_brush
.GetColour().CalcPixel( m_cmap
);
1958 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1960 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1962 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->IsOk()))
1964 if (m_brush
.GetStipple()->GetPixmap())
1966 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1967 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1971 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1972 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1976 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1978 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1979 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1982 if (m_brush
.IsHatch())
1984 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1985 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1986 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1990 void wxWindowDCImpl::SetBackground( const wxBrush
&brush
)
1992 /* CMB 21/7/98: Added SetBackground. Sets background brush
1993 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1995 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1997 if (m_backgroundBrush
== brush
) return;
1999 m_backgroundBrush
= brush
;
2001 if (!m_backgroundBrush
.IsOk()) return;
2003 if (!m_x11window
) return;
2005 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
2006 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
2007 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
2008 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
2009 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
2011 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
2013 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->IsOk()))
2015 if (m_backgroundBrush
.GetStipple()->GetPixmap())
2017 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
2018 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
2022 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2023 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
2027 if (m_backgroundBrush
.IsHatch())
2029 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2030 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
2031 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
2035 void wxWindowDCImpl::SetLogicalFunction( int function
)
2037 wxCHECK_RET( IsOk(), wxT("invalid dc") );
2041 if (m_logicalFunction
== function
)
2044 // VZ: shouldn't this be a CHECK?
2051 x_function
= GXclear
;
2057 x_function
= GXinvert
;
2060 x_function
= GXorReverse
;
2063 x_function
= GXandReverse
;
2072 x_function
= GXandInverted
;
2075 x_function
= GXnoop
;
2081 x_function
= GXequiv
;
2084 x_function
= GXcopyInverted
;
2087 x_function
= GXorInverted
;
2090 x_function
= GXnand
;
2097 x_function
= GXcopy
;
2101 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2102 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2104 // to stay compatible with wxMSW, we don't apply ROPs to the text
2105 // operations (i.e. DrawText/DrawRotatedText).
2106 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2107 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2109 m_logicalFunction
= function
;
2112 void wxWindowDCImpl::SetTextForeground( const wxColour
&col
)
2114 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2116 // don't set m_textForegroundColour to an invalid colour as we'd crash
2117 // later then (we use m_textForegroundColour.GetColor() without checking
2119 if ( !col
.IsOk() || (m_textForegroundColour
== col
) )
2122 m_textForegroundColour
= col
;
2126 m_textForegroundColour
.CalcPixel( m_cmap
);
2127 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2131 void wxWindowDCImpl::SetTextBackground( const wxColour
&col
)
2133 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2136 if ( !col
.IsOk() || (m_textBackgroundColour
== col
) )
2139 m_textBackgroundColour
= col
;
2143 m_textBackgroundColour
.CalcPixel( m_cmap
);
2144 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2148 void wxWindowDCImpl::SetBackgroundMode( int mode
)
2150 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2152 m_backgroundMode
= mode
;
2155 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2158 if (!m_x11window
) return;
2160 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2161 // transparent/solid background mode
2163 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2165 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2166 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2170 void wxWindowDCImpl::SetPalette( const wxPalette
& WXUNUSED(palette
) )
2176 /* Use GetXColormap */
2177 XSetWindowColormap ((Display
*) m_display
, (Window
) m_x11window
->GetXWindow(),
2178 (Colormap
) palette
.GetXColormap());
2180 /* Use wxGetMainColormap */
2181 XSetWindowColormap ((Display
*) m_display
, (Window
) m_x11window
->GetXWindow(),
2182 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2187 void wxWindowDCImpl::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2189 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2191 if (!m_x11window
) return;
2200 rect
.x
= XLOG2DEV(x
);
2201 rect
.y
= YLOG2DEV(y
);
2202 rect
.width
= XLOG2DEVREL(width
);
2203 rect
.height
= YLOG2DEVREL(height
);
2205 if (!m_currentClippingRegion
.IsEmpty())
2206 m_currentClippingRegion
.Intersect( rect
);
2208 m_currentClippingRegion
= rect
;
2210 #if USE_PAINT_REGION
2211 if (!m_paintClippingRegion
.IsEmpty())
2212 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2215 wxCoord xx
, yy
, ww
, hh
;
2216 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2217 wxX11DCImpl::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2219 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2220 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2221 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2222 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2225 void wxWindowDCImpl::DoSetDeviceClippingRegion( const wxRegion
& region
)
2227 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2231 DestroyClippingRegion();
2235 if (!m_x11window
) return;
2237 if (!m_currentClippingRegion
.IsEmpty())
2238 m_currentClippingRegion
.Intersect( region
);
2240 m_currentClippingRegion
= region
;
2242 #if USE_PAINT_REGION
2243 if (!m_paintClippingRegion
.IsEmpty())
2244 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2247 wxCoord xx
, yy
, ww
, hh
;
2248 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2249 wxX11DCImpl::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2251 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2252 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2253 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2254 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2257 void wxWindowDCImpl::DestroyClippingRegion()
2259 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2261 wxDCImpl::DestroyClippingRegion();
2263 m_currentClippingRegion
.Clear();
2265 #if USE_PAINT_REGION
2266 if (!m_paintClippingRegion
.IsEmpty())
2267 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2270 if (!m_x11window
) return;
2272 if (m_currentClippingRegion
.IsEmpty())
2274 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2275 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2276 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2277 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2281 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2282 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2283 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2284 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2288 void wxWindowDCImpl::Destroy()
2290 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2292 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2294 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2296 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2300 void wxWindowDCImpl::ComputeScaleAndOrigin()
2302 /* CMB: copy scale to see if it changes */
2303 double origScaleX
= m_scaleX
;
2304 double origScaleY
= m_scaleY
;
2306 wxDCImpl::ComputeScaleAndOrigin();
2308 /* CMB: if scale has changed call SetPen to recalulate the line width */
2309 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2312 /* this is a bit artificial, but we need to force wxDC to think
2313 the pen has changed */
2320 wxSize
wxWindowDCImpl::GetPPI() const
2322 return wxSize(100, 100);
2325 int wxWindowDCImpl::GetDepth() const
2327 wxFAIL_MSG(wxT("not implemented"));
2332 //-----------------------------------------------------------------------------
2334 //-----------------------------------------------------------------------------
2336 IMPLEMENT_ABSTRACT_CLASS(wxClientDCImpl
, wxWindowDCImpl
)
2338 wxClientDCImpl::wxClientDCImpl( wxDC
*owner
, wxWindow
*window
)
2339 : wxWindowDCImpl( owner
, window
)
2341 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2343 m_x11window
= (WXWindow
*) window
->GetClientAreaWindow();
2345 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2346 if (m_x11window
== (WXWindow
*) window
->GetMainWindow())
2348 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2349 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2350 wxSize size
= window
->GetClientSize();
2351 DoSetClippingRegion( 0, 0, size
.x
, size
.y
);
2355 void wxClientDCImpl::DoGetSize(int *width
, int *height
) const
2357 wxCHECK_RET( m_window
, _T("GetSize() doesn't work without window") );
2359 m_window
->GetClientSize( width
, height
);
2362 // ----------------------------------------------------------------------------
2364 // ----------------------------------------------------------------------------
2366 IMPLEMENT_ABSTRACT_CLASS(wxPaintDCImpl
, wxClientDCImpl
)
2368 wxPaintDCImpl::wxPaintDCImpl(wxDC
*owner
, wxWindow
* window
)
2369 : wxClientDCImpl(owner
, window
)
2371 #if USE_PAINT_REGION
2372 if (!window
->GetClipPaintRegion())
2375 m_paintClippingRegion
= window
->GetUpdateRegion();
2376 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2379 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2381 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2382 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2383 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2384 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2386 #endif // USE_PAINT_REGION
2389 // ----------------------------------------------------------------------------
2391 // ----------------------------------------------------------------------------
2393 class wxDCModule
: public wxModule
2396 // we must be cleaned up before wxDisplayModule which closes the global
2400 AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule")));
2403 bool OnInit() { wxInitGCPool(); return true; }
2404 void OnExit() { wxCleanUpGCPool(); }
2407 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2410 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)