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
= 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
->X11GetMainWindow();
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()
232 m_isScreenDC
= false;
236 m_context
= wxTheApp
->GetPangoContext();
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
, wxT("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 wxScopedCharBuffer
data(text
.utf8_str());
1574 pango_layout_set_text(layout
, data
, data
.length());
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 // Do not test for DC validity here, querying text extents is supposed to
1662 // work even with a non-initialized wxMemoryDC. And the code below does
1663 // actually work in this case.
1667 if (width
) (*width
) = 0;
1668 if (height
) (*height
) = 0;
1673 PangoLayout
*layout
= pango_layout_new( m_context
);
1676 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1678 pango_layout_set_font_description(layout
, m_fontdesc
);
1680 const wxScopedCharBuffer
data(string
.utf8_str());
1681 pango_layout_set_text(layout
, data
, data
.length());
1685 pango_layout_get_pixel_size(layout
, &w
, &h
);
1687 if (width
) (*width
) = (wxCoord
) w
;
1688 if (height
) (*height
) = (wxCoord
) h
;
1691 // Do something about metrics here. TODO.
1694 if (externalLeading
) (*externalLeading
) = 0; // ??
1696 g_object_unref( G_OBJECT( layout
) );
1698 wxFont fontToUse
= m_font
;
1699 if (font
) fontToUse
= *font
;
1701 wxCHECK_RET( fontToUse
.IsOk(), wxT("invalid font") );
1703 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1705 wxCHECK_RET( xfont
, wxT("invalid font") );
1707 int direction
, ascent
, descent2
;
1708 XCharStruct overall
;
1710 XTextExtents( xfont
, (const char*) string
.c_str(), string
.length(), &direction
,
1711 &ascent
, &descent2
, &overall
);
1714 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1716 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1718 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1719 if (externalLeading
)
1720 *externalLeading
= 0; // ??
1724 wxCoord
wxWindowDCImpl::GetCharWidth() const
1726 // Do not test for DC validity here for the same reasons as in
1727 // DoGetTextExtent() above.
1730 PangoLayout
*layout
= pango_layout_new( m_context
);
1733 pango_layout_set_font_description(layout
, m_fontdesc
);
1735 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1737 pango_layout_set_text(layout
, "H", 1 );
1739 pango_layout_get_pixel_size(layout
, &w
, &h
);
1740 g_object_unref( G_OBJECT( layout
) );
1744 wxCHECK_MSG( m_font
.IsOk(), 0, wxT("invalid font") );
1746 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1748 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1750 int direction
, ascent
, descent
;
1751 XCharStruct overall
;
1753 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1755 return (wxCoord
)(overall
.width
/ m_scaleX
);
1759 wxCoord
wxWindowDCImpl::GetCharHeight() const
1761 // Do not test for DC validity here for the same reasons as in
1762 // DoGetTextExtent() above.
1765 PangoLayout
*layout
= pango_layout_new( m_context
);
1768 pango_layout_set_font_description(layout
, m_fontdesc
);
1770 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1772 pango_layout_set_text(layout
, "H", 1 );
1774 pango_layout_get_pixel_size(layout
, &w
, &h
);
1775 g_object_unref( G_OBJECT( layout
) );
1779 wxCHECK_MSG( m_font
.IsOk(), 0, wxT("invalid font") );
1781 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1783 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1785 int direction
, ascent
, descent
;
1786 XCharStruct overall
;
1788 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1790 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1794 void wxWindowDCImpl::Clear()
1796 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1798 if (!m_x11window
) return;
1800 /* - we either are a memory dc or have a window as the
1801 owner. anything else shouldn't happen.
1802 - we don't use gdk_window_clear() as we don't set
1803 the window's background colour anymore. it is too
1804 much pain to keep the DC's and the window's back-
1805 ground colour in synch. */
1810 m_window
->GetSize( &width
, &height
);
1811 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1818 DoGetSize( &width
, &height
);
1819 XFillRectangle( (Display
*) m_display
, (Window
) m_x11window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1824 void wxWindowDCImpl::SetFont( const wxFont
&font
)
1826 wxCHECK_RET( IsOk(), wxT("invalid dc") );
1831 m_fontdesc
= font
.GetNativeFontInfo()->description
;
1835 void wxWindowDCImpl::SetPen( const wxPen
&pen
)
1837 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1839 if (m_pen
== pen
) return;
1843 if (!m_pen
.IsOk()) return;
1845 if (!m_x11window
) return;
1847 int width
= m_pen
.GetWidth();
1850 // CMB: if width is non-zero scale it with the dc
1855 // X doesn't allow different width in x and y and so we take
1858 ( fabs((double) XLOG2DEVREL(width
)) +
1859 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1863 static const wxX11Dash dotted
[] = {1, 1};
1864 static const wxX11Dash short_dashed
[] = {2, 2};
1865 static const wxX11Dash long_dashed
[] = {2, 4};
1866 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1868 // We express dash pattern in pen width unit, so we are
1869 // independent of zoom factor and so on...
1871 const wxX11Dash
*req_dash
;
1873 int lineStyle
= LineSolid
;
1874 switch (m_pen
.GetStyle())
1878 lineStyle
= LineOnOffDash
;
1879 req_nb_dash
= m_pen
.GetDashCount();
1880 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1885 lineStyle
= LineOnOffDash
;
1892 lineStyle
= LineOnOffDash
;
1894 req_dash
= long_dashed
;
1899 lineStyle
= LineOnOffDash
;
1901 req_dash
= short_dashed
;
1906 // lineStyle = LineDoubleDash;
1907 lineStyle
= LineOnOffDash
;
1909 req_dash
= dotted_dashed
;
1914 case wxSTIPPLE_MASK_OPAQUE
:
1919 lineStyle
= LineSolid
;
1926 int capStyle
= CapRound
;
1927 switch (m_pen
.GetCap())
1929 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1930 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1937 capStyle
= CapNotLast
;
1941 capStyle
= CapRound
;
1947 int joinStyle
= JoinRound
;
1948 switch (m_pen
.GetJoin())
1950 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1951 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1953 default: { joinStyle
= JoinRound
; break; }
1956 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1958 m_pen
.GetColour().CalcPixel( m_cmap
);
1959 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1962 void wxWindowDCImpl::SetBrush( const wxBrush
&brush
)
1964 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
1966 if (m_brush
== brush
) return;
1970 if (!m_brush
.IsOk()) return;
1972 if (!m_x11window
) return;
1974 m_brush
.GetColour().CalcPixel( m_cmap
);
1975 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1977 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1979 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->IsOk()))
1981 if (m_brush
.GetStipple()->GetPixmap())
1983 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1984 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1988 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1989 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1993 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1995 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1996 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1999 if (m_brush
.IsHatch())
2001 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
2002 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
2003 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
2007 void wxWindowDCImpl::SetBackground( const wxBrush
&brush
)
2009 /* CMB 21/7/98: Added SetBackground. Sets background brush
2010 * for Clear() and bg colour for shapes filled with cross-hatch brush */
2012 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2014 if (m_backgroundBrush
== brush
) return;
2016 m_backgroundBrush
= brush
;
2018 if (!m_backgroundBrush
.IsOk()) return;
2020 if (!m_x11window
) return;
2022 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
2023 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
2024 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
2025 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
2026 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
2028 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
2030 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->IsOk()))
2032 if (m_backgroundBrush
.GetStipple()->GetPixmap())
2034 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
2035 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
2039 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2040 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
2044 if (m_backgroundBrush
.IsHatch())
2046 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2047 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
2048 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
2052 void wxWindowDCImpl::SetLogicalFunction( wxRasterOperationMode function
)
2054 wxCHECK_RET( IsOk(), wxT("invalid dc") );
2058 if (m_logicalFunction
== function
)
2061 // VZ: shouldn't this be a CHECK?
2068 x_function
= GXclear
;
2074 x_function
= GXinvert
;
2077 x_function
= GXorReverse
;
2080 x_function
= GXandReverse
;
2089 x_function
= GXandInverted
;
2092 x_function
= GXnoop
;
2098 x_function
= GXequiv
;
2101 x_function
= GXcopyInverted
;
2104 x_function
= GXorInverted
;
2107 x_function
= GXnand
;
2114 x_function
= GXcopy
;
2118 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2119 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2121 // to stay compatible with wxMSW, we don't apply ROPs to the text
2122 // operations (i.e. DrawText/DrawRotatedText).
2123 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2124 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2126 m_logicalFunction
= function
;
2129 void wxWindowDCImpl::SetTextForeground( const wxColour
&col
)
2131 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2133 // don't set m_textForegroundColour to an invalid colour as we'd crash
2134 // later then (we use m_textForegroundColour.GetColor() without checking
2136 if ( !col
.IsOk() || (m_textForegroundColour
== col
) )
2139 m_textForegroundColour
= col
;
2143 m_textForegroundColour
.CalcPixel( m_cmap
);
2144 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2148 void wxWindowDCImpl::SetTextBackground( const wxColour
&col
)
2150 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2153 if ( !col
.IsOk() || (m_textBackgroundColour
== col
) )
2156 m_textBackgroundColour
= col
;
2160 m_textBackgroundColour
.CalcPixel( m_cmap
);
2161 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2165 void wxWindowDCImpl::SetBackgroundMode( int mode
)
2167 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2169 m_backgroundMode
= mode
;
2172 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2175 if (!m_x11window
) return;
2177 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2178 // transparent/solid background mode
2180 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2182 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2183 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2187 void wxWindowDCImpl::SetPalette( const wxPalette
& WXUNUSED(palette
) )
2193 /* Use GetXColormap */
2194 XSetWindowColormap ((Display
*) m_display
, (Window
) m_x11window
->GetXWindow(),
2195 (Colormap
) palette
.GetXColormap());
2197 /* Use wxGetMainColormap */
2198 XSetWindowColormap ((Display
*) m_display
, (Window
) m_x11window
->GetXWindow(),
2199 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2204 void wxWindowDCImpl::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2206 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2208 if (!m_x11window
) return;
2217 rect
.x
= XLOG2DEV(x
);
2218 rect
.y
= YLOG2DEV(y
);
2219 rect
.width
= XLOG2DEVREL(width
);
2220 rect
.height
= YLOG2DEVREL(height
);
2222 if (!m_currentClippingRegion
.IsEmpty())
2223 m_currentClippingRegion
.Intersect( rect
);
2225 m_currentClippingRegion
= rect
;
2227 #if USE_PAINT_REGION
2228 if (!m_paintClippingRegion
.IsEmpty())
2229 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2232 wxCoord xx
, yy
, ww
, hh
;
2233 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2234 wxX11DCImpl::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2236 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2237 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2238 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2239 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2242 void wxWindowDCImpl::DoSetDeviceClippingRegion( const wxRegion
& region
)
2244 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2248 DestroyClippingRegion();
2252 if (!m_x11window
) return;
2254 if (!m_currentClippingRegion
.IsEmpty())
2255 m_currentClippingRegion
.Intersect( region
);
2257 m_currentClippingRegion
= region
;
2259 #if USE_PAINT_REGION
2260 if (!m_paintClippingRegion
.IsEmpty())
2261 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2264 wxCoord xx
, yy
, ww
, hh
;
2265 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2266 wxX11DCImpl::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2268 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2269 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2270 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2271 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2274 void wxWindowDCImpl::DestroyClippingRegion()
2276 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2278 wxDCImpl::DestroyClippingRegion();
2280 m_currentClippingRegion
.Clear();
2282 #if USE_PAINT_REGION
2283 if (!m_paintClippingRegion
.IsEmpty())
2284 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2287 if (!m_x11window
) return;
2289 if (m_currentClippingRegion
.IsEmpty())
2291 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2292 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2293 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2294 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2298 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2299 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2300 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2301 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2305 void wxWindowDCImpl::Destroy()
2307 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2309 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2311 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2313 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2317 void wxWindowDCImpl::ComputeScaleAndOrigin()
2319 /* CMB: copy scale to see if it changes */
2320 double origScaleX
= m_scaleX
;
2321 double origScaleY
= m_scaleY
;
2323 wxDCImpl::ComputeScaleAndOrigin();
2325 /* CMB: if scale has changed call SetPen to recalulate the line width */
2326 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2329 /* this is a bit artificial, but we need to force wxDC to think
2330 the pen has changed */
2337 wxSize
wxWindowDCImpl::GetPPI() const
2339 return wxSize(100, 100);
2342 int wxWindowDCImpl::GetDepth() const
2344 wxFAIL_MSG(wxT("not implemented"));
2349 //-----------------------------------------------------------------------------
2351 //-----------------------------------------------------------------------------
2353 IMPLEMENT_ABSTRACT_CLASS(wxClientDCImpl
, wxWindowDCImpl
)
2355 wxClientDCImpl::wxClientDCImpl( wxDC
*owner
, wxWindow
*window
)
2356 : wxWindowDCImpl( owner
, window
)
2358 wxCHECK_RET( window
, wxT("NULL window in wxClientDC::wxClientDC") );
2360 m_x11window
= (WXWindow
*) window
->GetClientAreaWindow();
2362 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2363 if (m_x11window
== (WXWindow
*) window
->X11GetMainWindow())
2365 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2366 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2367 wxSize size
= window
->GetClientSize();
2368 DoSetClippingRegion( 0, 0, size
.x
, size
.y
);
2372 void wxClientDCImpl::DoGetSize(int *width
, int *height
) const
2374 wxCHECK_RET( m_window
, wxT("GetSize() doesn't work without window") );
2376 m_window
->GetClientSize( width
, height
);
2379 // ----------------------------------------------------------------------------
2381 // ----------------------------------------------------------------------------
2383 IMPLEMENT_ABSTRACT_CLASS(wxPaintDCImpl
, wxClientDCImpl
)
2385 wxPaintDCImpl::wxPaintDCImpl(wxDC
*owner
, wxWindow
* window
)
2386 : wxClientDCImpl(owner
, window
)
2388 #if USE_PAINT_REGION
2389 if (!window
->GetClipPaintRegion())
2392 m_paintClippingRegion
= window
->GetUpdateRegion();
2393 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2396 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2398 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2399 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2400 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2401 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2403 #endif // USE_PAINT_REGION
2406 // ----------------------------------------------------------------------------
2408 // ----------------------------------------------------------------------------
2410 class wxDCModule
: public wxModule
2413 // we must be cleaned up before wxDisplayModule which closes the global
2417 AddDependency(wxClassInfo::FindClass(wxT("wxX11DisplayModule")));
2420 bool OnInit() { wxInitGCPool(); return true; }
2421 void OnExit() { wxCleanUpGCPool(); }
2424 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2427 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)