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"
20 #include "wx/dcmemory.h"
23 #include "wx/module.h"
26 #include "wx/fontutil.h"
28 #include "wx/x11/private.h"
32 #include "pango/pangox.h"
34 #include "pango/pangoxft.h"
37 #include "pango_x.cpp"
40 //-----------------------------------------------------------------------------
42 //-----------------------------------------------------------------------------
44 // VZ: what is this for exactly??
45 #define USE_PAINT_REGION 0
47 //-----------------------------------------------------------------------------
49 //-----------------------------------------------------------------------------
59 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH)
60 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH)
62 static Pixmap hatches
[num_hatches
];
63 static Pixmap
*hatch_bitmap
= (Pixmap
*) NULL
;
65 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
69 const double RAD2DEG
= 180.0 / M_PI
;
71 // ----------------------------------------------------------------------------
73 // ----------------------------------------------------------------------------
75 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
76 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
78 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
80 //-----------------------------------------------------------------------------
81 // Implement Pool of Graphic contexts. Creating them takes too much time.
82 //-----------------------------------------------------------------------------
84 #define GC_POOL_SIZE 200
110 static wxGC wxGCPool
[GC_POOL_SIZE
];
112 static void wxInitGCPool()
114 memset( wxGCPool
, 0, GC_POOL_SIZE
*sizeof(wxGC
) );
117 static void wxCleanUpGCPool()
119 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
121 if (wxGCPool
[i
].m_gc
)
122 XFreeGC( wxGlobalDisplay(), wxGCPool
[i
].m_gc
);
126 static GC
wxGetPoolGC( Window window
, wxPoolGCType type
)
128 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
130 if (!wxGCPool
[i
].m_gc
)
132 wxGCPool
[i
].m_gc
= XCreateGC( wxGlobalDisplay(), window
, 0, NULL
);
133 XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool
[i
].m_gc
, FALSE
);
134 wxGCPool
[i
].m_type
= type
;
135 wxGCPool
[i
].m_used
= false;
137 if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type
== type
))
139 wxGCPool
[i
].m_used
= true;
140 return wxGCPool
[i
].m_gc
;
144 wxFAIL_MSG( wxT("No GC available") );
149 static void wxFreePoolGC( GC gc
)
151 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
153 if (wxGCPool
[i
].m_gc
== gc
)
155 wxGCPool
[i
].m_used
= false;
160 wxFAIL_MSG( wxT("Wrong GC") );
163 // ----------------------------------------------------------------------------
165 // ----------------------------------------------------------------------------
167 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
169 void wxWindowDC::Init()
171 m_display
= (WXDisplay
*) NULL
;
172 m_penGC
= (WXGC
*) NULL
;
173 m_brushGC
= (WXGC
*) NULL
;
174 m_textGC
= (WXGC
*) NULL
;
175 m_bgGC
= (WXGC
*) NULL
;
176 m_cmap
= (WXColormap
*) NULL
;
178 m_isScreenDC
= false;
179 m_owner
= (wxWindow
*)NULL
;
182 m_context
= wxTheApp
->GetPangoContext();
183 m_fontdesc
= (PangoFontDescription
*)NULL
;
187 wxWindowDC::wxWindowDC( wxWindow
*window
)
189 wxASSERT_MSG( window
, wxT("DC needs a window") );
193 m_font
= window
->GetFont();
195 m_window
= (WXWindow
*) window
->GetMainWindow();
200 // don't report problems
206 m_display
= (WXDisplay
*) wxGlobalDisplay();
209 m_fontdesc
= window
->GetFont().GetNativeFontInfo()->description
;
212 int screen
= DefaultScreen( (Display
*) m_display
);
213 m_cmap
= (WXColormap
) DefaultColormap( (Display
*) m_display
, screen
);
217 /* this must be done after SetUpDC, bacause SetUpDC calls the
218 repective SetBrush, SetPen, SetBackground etc functions
219 to set up the DC. SetBackground call m_owner->SetBackground
220 and this might not be desired as the standard dc background
221 is white whereas a window might assume gray to be the
222 standard (as e.g. wxStatusBar) */
227 wxWindowDC::~wxWindowDC()
232 void wxWindowDC::SetUpDC()
236 wxASSERT_MSG( !m_penGC
, wxT("GCs already created") );
240 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_SCREEN
);
241 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_SCREEN
);
242 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_SCREEN
);
243 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_SCREEN
);
246 if (m_isMemDC
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1))
248 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_MONO
);
249 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_MONO
);
250 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_MONO
);
251 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_MONO
);
255 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_COLOUR
);
256 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_COLOUR
);
257 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_COLOUR
);
258 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_COLOUR
);
261 /* background colour */
262 m_backgroundBrush
= *wxWHITE_BRUSH
;
263 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
264 unsigned long bg_col
= m_backgroundBrush
.GetColour().GetPixel();
266 m_textForegroundColour
= *wxBLACK
;
267 m_textBackgroundColour
= *wxWHITE
;
270 m_textForegroundColour
.CalcPixel( m_cmap
);
271 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
273 m_textBackgroundColour
.CalcPixel( m_cmap
);
274 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
276 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
279 // By default, draw transparently
280 GrSetGCUseBackground((GC
) m_textGC
, FALSE
);
284 m_pen
.GetColour().CalcPixel( m_cmap
);
285 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
286 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
288 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
291 m_brush
.GetColour().CalcPixel( m_cmap
);
292 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
293 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
295 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
298 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
299 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
301 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
304 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
305 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
306 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
309 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
310 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
311 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
312 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
316 int xscreen
= DefaultScreen( (Display
*) m_display
);
317 Window xroot
= RootWindow( (Display
*) m_display
, xscreen
);
319 hatch_bitmap
= hatches
;
320 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, bdiag_bits
, bdiag_width
, bdiag_height
);
321 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cdiag_bits
, cdiag_width
, cdiag_height
);
322 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, fdiag_bits
, fdiag_width
, fdiag_height
);
323 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cross_bits
, cross_width
, cross_height
);
324 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, horiz_bits
, horiz_width
, horiz_height
);
325 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, verti_bits
, verti_width
, verti_height
);
329 void wxWindowDC::DoGetSize( int* width
, int* height
) const
331 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
333 m_owner
->GetSize(width
, height
);
336 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
337 const wxColour
& col
, int style
);
339 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
340 const wxColour
& col
, int style
)
342 return wxDoFloodFill(this, x
, y
, col
, style
);
345 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
347 // Generic (and therefore rather inefficient) method.
348 // Could be improved.
350 wxBitmap
bitmap(1, 1);
351 memdc
.SelectObject(bitmap
);
352 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
353 memdc
.SelectObject(wxNullBitmap
);
354 wxImage
image(bitmap
.ConvertToImage());
355 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
359 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
361 wxCHECK_RET( Ok(), wxT("invalid window dc") );
363 if (m_pen
.GetStyle() != wxTRANSPARENT
)
367 // This hack is for the iPaq: XDrawLine draws
368 // nothing, whereas XDrawLines works...
374 DrawLines( 2, points
, 0, 0 );
376 // XDrawLine( (Display*) m_display, (Window) m_window,
377 // (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
380 CalcBoundingBox(x1
, y1
);
381 CalcBoundingBox(x2
, y2
);
385 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
387 wxCHECK_RET( Ok(), wxT("invalid window dc") );
389 if (m_pen
.GetStyle() != wxTRANSPARENT
)
394 wxCoord xx
= XLOG2DEV(x
);
395 wxCoord yy
= YLOG2DEV(y
);
398 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
399 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
400 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
401 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
406 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
408 wxCHECK_RET( Ok(), wxT("invalid window dc") );
410 wxCoord xx1
= XLOG2DEV(x1
);
411 wxCoord yy1
= YLOG2DEV(y1
);
412 wxCoord xx2
= XLOG2DEV(x2
);
413 wxCoord yy2
= YLOG2DEV(y2
);
414 wxCoord xxc
= XLOG2DEV(xc
);
415 wxCoord yyc
= YLOG2DEV(yc
);
416 double dx
= xx1
- xxc
;
417 double dy
= yy1
- yyc
;
418 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
419 wxCoord r
= (wxCoord
)radius
;
420 double radius1
, radius2
;
422 if (xx1
== xx2
&& yy1
== yy2
)
430 radius1
= radius2
= 0.0;
434 radius1
= (xx1
- xxc
== 0) ?
435 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
436 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
437 radius2
= (xx2
- xxc
== 0) ?
438 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
439 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
441 wxCoord alpha1
= wxCoord(radius1
* 64.0);
442 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
443 while (alpha2
<= 0) alpha2
+= 360*64;
444 while (alpha1
> 360*64) alpha1
-= 360*64;
448 if (m_brush
.GetStyle() != wxTRANSPARENT
)
450 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
452 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
453 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
454 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
456 XFillArc( (Display
*) m_display
, (Window
) m_window
,
457 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
459 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
461 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
463 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
464 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
466 XFillArc( (Display
*) m_display
, (Window
) m_window
,
467 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
469 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
471 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
473 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
474 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
476 XFillArc( (Display
*) m_display
, (Window
) m_window
,
477 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
479 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
481 if (m_brush
.GetStyle() == wxSTIPPLE
)
483 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
484 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
485 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
487 XFillArc( (Display
*) m_display
, (Window
) m_window
,
488 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
490 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
494 XFillArc( (Display
*) m_display
, (Window
) m_window
,
495 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
499 if (m_pen
.GetStyle() != wxTRANSPARENT
)
501 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
502 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
504 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
505 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
507 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
508 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
512 CalcBoundingBox (x1
, y1
);
513 CalcBoundingBox (x2
, y2
);
516 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
518 wxCHECK_RET( Ok(), wxT("invalid window dc") );
520 wxCoord xx
= XLOG2DEV(x
);
521 wxCoord yy
= YLOG2DEV(y
);
522 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
523 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
525 // CMB: handle -ve width and/or height
526 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
527 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
531 wxCoord start
= wxCoord(sa
* 64.0);
532 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
534 if (m_brush
.GetStyle() != wxTRANSPARENT
)
536 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
538 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
539 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
540 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
542 XFillArc( (Display
*) m_display
, (Window
) m_window
,
543 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
545 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
547 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
549 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
550 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
552 XFillArc( (Display
*) m_display
, (Window
) m_window
,
553 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
555 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
557 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
559 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
560 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
562 XFillArc( (Display
*) m_display
, (Window
) m_window
,
563 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
565 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
567 if (m_brush
.GetStyle() == wxSTIPPLE
)
569 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
570 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
571 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
573 XFillArc( (Display
*) m_display
, (Window
) m_window
,
574 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
576 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
580 XFillArc( (Display
*) m_display
, (Window
) m_window
,
581 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
585 if (m_pen
.GetStyle() != wxTRANSPARENT
)
587 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
588 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
592 CalcBoundingBox (x
, y
);
593 CalcBoundingBox (x
+ width
, y
+ height
);
596 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
598 wxCHECK_RET( Ok(), wxT("invalid window dc") );
600 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
)
601 XDrawPoint( (Display
*) m_display
, (Window
) m_window
,
602 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
604 CalcBoundingBox (x
, y
);
607 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
609 wxCHECK_RET( Ok(), wxT("invalid window dc") );
611 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
614 XPoint
*xpoints
= new XPoint
[n
];
615 for (int i
= 0; i
< n
; i
++)
617 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
618 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
620 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
622 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
, 0 );
627 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
628 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
630 wxCHECK_RET( Ok(), wxT("invalid window dc") );
634 XPoint
*xpoints
= new XPoint
[n
+ 1];
636 for (i
= 0; i
< n
; i
++)
638 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
639 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
641 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
646 if (m_brush
.GetStyle() != wxTRANSPARENT
)
649 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
651 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
652 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
653 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
655 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
656 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
658 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
660 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
662 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
663 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
665 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
666 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
668 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
670 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
672 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
673 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
675 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
676 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
678 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
680 if (m_brush
.GetStyle() == wxSTIPPLE
)
682 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
683 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
684 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
686 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
687 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
689 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
693 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
694 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
698 if (m_pen
.GetStyle () != wxTRANSPARENT
)
700 // Close figure for XDrawLines
701 xpoints
[i
].x
= xpoints
[0].x
;
702 xpoints
[i
].y
= xpoints
[0].y
;
704 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
711 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
713 wxCHECK_RET( Ok(), wxT("invalid window dc") );
715 wxCoord xx
= XLOG2DEV(x
);
716 wxCoord yy
= YLOG2DEV(y
);
717 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
718 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
720 // CMB: draw nothing if transformed w or h is 0
721 if (ww
== 0 || hh
== 0) return;
723 // CMB: handle -ve width and/or height
724 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
725 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
729 if (m_brush
.GetStyle() != wxTRANSPARENT
)
731 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
733 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
734 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
735 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
737 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
738 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
740 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
742 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
744 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
745 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
747 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
748 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
750 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
752 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
754 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
755 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
757 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
758 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
760 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
762 if (m_brush
.GetStyle() == wxSTIPPLE
)
764 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
765 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
766 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
768 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
769 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
771 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
775 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
776 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
780 if (m_pen
.GetStyle () != wxTRANSPARENT
)
782 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
783 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
787 CalcBoundingBox( x
, y
);
788 CalcBoundingBox( x
+ width
, y
+ height
);
791 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
793 wxCHECK_RET( Ok(), wxT("invalid window dc") );
795 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
797 wxCoord xx
= XLOG2DEV(x
);
798 wxCoord yy
= YLOG2DEV(y
);
799 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
800 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
801 wxCoord rr
= XLOG2DEVREL((wxCoord
)radius
);
803 // CMB: handle -ve width and/or height
804 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
805 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
807 // CMB: if radius is zero use DrawRectangle() instead to avoid
808 // X drawing errors with small radii
811 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
812 (GC
) m_penGC
, x
, y
, width
, height
);
816 // CMB: draw nothing if transformed w or h is 0
817 if (ww
== 0 || hh
== 0) return;
819 // CMB: adjust size if outline is drawn otherwise the result is
820 // 1 pixel too wide and high
821 if (m_pen
.GetStyle() != wxTRANSPARENT
)
829 // CMB: ensure dd is not larger than rectangle otherwise we
830 // get an hour glass shape
832 if (dd
> ww
) dd
= ww
;
833 if (dd
> hh
) dd
= hh
;
836 if (m_brush
.GetStyle() != wxTRANSPARENT
)
838 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
840 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
841 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
842 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
843 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
844 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
845 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
846 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
847 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
848 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
849 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0);
851 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
853 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
854 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
855 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
856 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
857 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
858 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
859 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
860 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
862 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
864 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
865 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
866 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
867 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
868 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
869 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
870 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
871 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
873 if (m_brush
.GetStyle() == wxSTIPPLE
)
875 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
876 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
877 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
878 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
879 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
880 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
881 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
882 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
883 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
884 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
888 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
889 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
890 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
891 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
892 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
893 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
896 if (m_pen
.GetStyle() != wxTRANSPARENT
)
898 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy
);
899 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
900 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr
);
901 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr
);
902 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
903 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
904 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
905 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
909 // this ignores the radius
910 CalcBoundingBox( x
, y
);
911 CalcBoundingBox( x
+ width
, y
+ height
);
914 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
916 wxCHECK_RET( Ok(), wxT("invalid window dc") );
918 wxCoord xx
= XLOG2DEV(x
);
919 wxCoord yy
= YLOG2DEV(y
);
920 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
921 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
923 // CMB: handle -ve width and/or height
924 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
925 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
929 if (m_brush
.GetStyle() != wxTRANSPARENT
)
931 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
933 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
934 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
935 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
937 XFillArc( (Display
*) m_display
, (Window
) m_window
,
938 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
940 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
942 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
944 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
945 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
947 XFillArc( (Display
*) m_display
, (Window
) m_window
,
948 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
950 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
952 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
954 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
955 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
957 XFillArc( (Display
*) m_display
, (Window
) m_window
,
958 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
960 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
962 if (m_brush
.GetStyle() == wxSTIPPLE
)
964 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
965 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
966 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
968 XFillArc( (Display
*) m_display
, (Window
) m_window
,
969 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
971 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
975 XFillArc( (Display
*) m_display
, (Window
) m_window
,
976 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
980 if (m_pen
.GetStyle () != wxTRANSPARENT
)
982 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
983 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
987 CalcBoundingBox( x
, y
);
988 CalcBoundingBox( x
+ width
, y
+ height
);
991 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
993 DoDrawBitmap(icon
, x
, y
, true);
997 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
998 wxCoord x
, wxCoord y
,
1001 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1003 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1005 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1007 /* scale/translate size and position */
1008 int xx
= XLOG2DEV(x
);
1009 int yy
= YLOG2DEV(y
);
1011 int w
= bitmap
.GetWidth();
1012 int h
= bitmap
.GetHeight();
1014 CalcBoundingBox( x
, y
);
1015 CalcBoundingBox( x
+ w
, y
+ h
);
1017 if (!m_window
) return;
1019 int ww
= XLOG2DEVREL(w
);
1020 int hh
= YLOG2DEVREL(h
);
1022 /* compare to current clipping region */
1023 if (!m_currentClippingRegion
.IsNull())
1025 wxRegion
tmp( xx
,yy
,ww
,hh
);
1026 tmp
.Intersect( m_currentClippingRegion
);
1031 /* scale bitmap if required */
1032 wxBitmap use_bitmap
;
1033 if ((w
!= ww
) || (h
!= hh
))
1035 wxImage
image( bitmap
.ConvertToImage() );
1036 image
.Rescale( ww
, hh
);
1039 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1046 use_bitmap
= bitmap
;
1049 /* apply mask if any */
1050 WXPixmap mask
= NULL
;
1051 if (use_bitmap
.GetMask())
1052 mask
= use_bitmap
.GetMask()->GetBitmap();
1054 if (useMask
&& mask
)
1056 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
1057 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
1058 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
1060 GrSetGCUseBackground(gc
, FALSE
);
1061 GrSetGCMode(gc
, GR_MODE_COPY
);
1063 // This code assumes that background and foreground
1064 // colours are used in ROPs, like in MSW.
1065 // Not sure if this is true.
1067 // Copy destination to buffer.
1068 // In DoBlit, we need this step because Blit has
1069 // a ROP argument. Here, we don't need it.
1070 // In DoBlit, we may be able to eliminate this step
1071 // if we check if the rop = copy
1073 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_window
,
1074 0, 0, GR_MODE_COPY
);
1077 // Copy src to buffer using selected raster op (none selected
1078 // in DrawBitmap, so just use Gxcopy)
1079 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
1080 0, 0, GR_MODE_COPY
);
1082 // Set masked area in buffer to BLACK (pixel value 0)
1083 GrSetGCBackground(gc
, WHITE
);
1084 GrSetGCForeground(gc
, BLACK
);
1085 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
1088 // set unmasked area in dest to BLACK
1089 GrSetGCBackground(gc
, BLACK
);
1090 GrSetGCForeground(gc
, WHITE
);
1091 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
1094 // OR buffer to dest
1095 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
1099 GrDestroyWindow(bufPixmap
);
1102 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1103 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1105 /* remove mask again if any */
1106 if (useMask
&& mask
)
1108 if (!m_currentClippingRegion
.IsNull())
1109 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1116 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1117 wxCoord x
, wxCoord y
,
1120 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1122 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1124 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1126 // scale/translate size and position
1127 int xx
= XLOG2DEV(x
);
1128 int yy
= YLOG2DEV(y
);
1130 int w
= bitmap
.GetWidth();
1131 int h
= bitmap
.GetHeight();
1133 CalcBoundingBox( x
, y
);
1134 CalcBoundingBox( x
+ w
, y
+ h
);
1136 if (!m_window
) return;
1138 int ww
= XLOG2DEVREL(w
);
1139 int hh
= YLOG2DEVREL(h
);
1141 // compare to current clipping region
1142 if (!m_currentClippingRegion
.IsNull())
1144 wxRegion
tmp( xx
,yy
,ww
,hh
);
1145 tmp
.Intersect( m_currentClippingRegion
);
1150 // scale bitmap if required
1151 wxBitmap use_bitmap
;
1152 if ((w
!= ww
) || (h
!= hh
))
1154 wxImage
image( bitmap
.ConvertToImage() );
1155 image
.Rescale( ww
, hh
);
1158 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1165 use_bitmap
= bitmap
;
1168 // apply mask if any
1169 WXPixmap mask
= NULL
;
1170 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1172 bool setClipMask
= false;
1174 if (!m_currentClippingRegion
.IsNull() || (useMask
&& mask
))
1176 // XSetClipMask() call is necessary (because of clip region and/or transparent mask)
1178 Pixmap new_pixmap
= 0;
1180 if (!m_currentClippingRegion
.IsNull())
1182 // clipping necessary => create new_pixmap
1183 Display
*xdisplay
= (Display
*) m_display
;
1184 int xscreen
= DefaultScreen( xdisplay
);
1185 Window xroot
= RootWindow( xdisplay
, xscreen
);
1187 new_pixmap
= XCreatePixmap( xdisplay
, xroot
, ww
, hh
, 1 );
1188 GC gc
= XCreateGC( xdisplay
, new_pixmap
, 0, NULL
);
1190 XSetForeground( xdisplay
, gc
, BlackPixel(xdisplay
,xscreen
) );
1192 XSetFillStyle( xdisplay
, gc
, FillSolid
);
1193 XFillRectangle( xdisplay
, new_pixmap
, gc
, 0, 0, ww
, hh
);
1195 XSetForeground( xdisplay
, gc
, WhitePixel(xdisplay
,xscreen
) );
1197 if (useMask
&& mask
)
1199 // transparent mask => call XSetStipple
1200 XSetFillStyle( xdisplay
, gc
, FillStippled
);
1201 XSetTSOrigin( xdisplay
, gc
, 0, 0);
1202 XSetStipple( xdisplay
, gc
, (Pixmap
) mask
);
1205 wxCoord clip_x
, clip_y
, clip_w
, clip_h
;
1206 m_currentClippingRegion
.GetBox(clip_x
, clip_y
, clip_w
, clip_h
);
1207 XFillRectangle( xdisplay
, new_pixmap
, gc
, clip_x
-xx
, clip_y
-yy
, clip_w
, clip_h
);
1209 XFreeGC( xdisplay
, gc
);
1215 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, new_pixmap
);
1217 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1218 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1223 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, new_pixmap
);
1225 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1226 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1230 XFreePixmap( (Display
*) m_display
, new_pixmap
);
1233 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1234 // drawing a mono-bitmap (XBitmap) we use the current text GC
1236 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1237 (GC
) m_textGC
, 0, 0, ww
, hh
, xx
, yy
, 1 );
1239 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1240 (GC
) m_penGC
, 0, 0, ww
, hh
, xx
, yy
);
1242 // remove mask again if any
1247 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1248 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1249 if (!m_currentClippingRegion
.IsNull())
1250 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1254 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1255 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1256 if (!m_currentClippingRegion
.IsNull())
1257 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1262 // wxUSE_NANOX/!wxUSE_NANOX
1264 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1265 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1266 wxCoord xsrcMask
, wxCoord ysrcMask
)
1268 /* this is the nth try to get this utterly useless function to
1269 work. it now completely ignores the scaling or translation
1270 of the source dc, but scales correctly on the target dc and
1271 knows about possible mask information in a memory dc. */
1273 wxCHECK_MSG( Ok(), false, wxT("invalid window dc") );
1275 wxCHECK_MSG( source
, false, wxT("invalid source dc") );
1277 if (!m_window
) return false;
1279 // transform the source DC coords to the device ones
1280 xsrc
= source
->LogicalToDeviceX(xsrc
);
1281 ysrc
= source
->LogicalToDeviceY(ysrc
);
1283 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1284 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1286 bool use_bitmap_method
= false;
1287 bool is_mono
= false;
1289 // TODO: use the mask origin when drawing transparently
1290 if (xsrcMask
== -1 && ysrcMask
== -1)
1296 if (srcDC
->m_isMemDC
)
1298 if (!memDC
->m_selected
.Ok()) return false;
1300 /* we use the "XCopyArea" way to copy a memory dc into
1301 y different window if the memory dc BOTH
1302 a) doesn't have any mask or its mask isn't used
1306 if (useMask
&& (memDC
->m_selected
.GetMask()))
1308 /* we HAVE TO use the direct way for memory dcs
1309 that have mask since the XCopyArea doesn't know
1311 use_bitmap_method
= true;
1313 else if (memDC
->m_selected
.GetDepth() == 1)
1315 /* we HAVE TO use the direct way for memory dcs
1316 that are bitmaps because XCopyArea doesn't cope
1317 with different bit depths */
1319 use_bitmap_method
= true;
1321 else if ((xsrc
== 0) && (ysrc
== 0) &&
1322 (width
== memDC
->m_selected
.GetWidth()) &&
1323 (height
== memDC
->m_selected
.GetHeight()))
1325 /* we SHOULD use the direct way if all of the bitmap
1326 in the memory dc is copied in which case XCopyArea
1327 wouldn't be able able to boost performace by reducing
1328 the area to be scaled */
1329 use_bitmap_method
= true;
1333 use_bitmap_method
= false;
1337 CalcBoundingBox( xdest
, ydest
);
1338 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1340 // scale/translate size and position
1341 wxCoord xx
= XLOG2DEV(xdest
);
1342 wxCoord yy
= YLOG2DEV(ydest
);
1344 wxCoord ww
= XLOG2DEVREL(width
);
1345 wxCoord hh
= YLOG2DEVREL(height
);
1347 // compare to current clipping region
1348 if (!m_currentClippingRegion
.IsNull())
1350 wxRegion
tmp( xx
,yy
,ww
,hh
);
1351 tmp
.Intersect( m_currentClippingRegion
);
1356 int old_logical_func
= m_logicalFunction
;
1357 SetLogicalFunction( logical_func
);
1359 if (use_bitmap_method
)
1361 // scale/translate bitmap size
1362 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1363 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1365 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1366 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1368 // scale bitmap if required
1369 wxBitmap use_bitmap
;
1371 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1373 wxImage
image( memDC
->m_selected
.ConvertToImage() );
1374 image
= image
.Scale( bm_ww
, bm_hh
);
1378 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1385 use_bitmap
= memDC
->m_selected
;
1388 // apply mask if any
1389 WXPixmap mask
= NULL
;
1390 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1392 if (useMask
&& mask
)
1394 WXPixmap new_mask
= NULL
;
1396 if (!m_currentClippingRegion
.IsNull())
1399 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1400 GdkGC
*gc
= gdk_gc_new( new_mask
);
1402 gdk_gc_set_foreground( gc
, &col
);
1403 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1405 gdk_gc_set_background( gc
, &col
);
1407 gdk_gc_set_foreground( gc
, &col
);
1408 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1409 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1410 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1411 gdk_gc_set_stipple( gc
, mask
);
1412 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1419 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1421 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1422 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1427 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1429 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1430 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1434 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1437 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1438 // drawing a mono-bitmap (XBitmap) we use the current text GC
1441 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1442 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1444 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1445 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1447 // remove mask again if any
1448 if (useMask
&& mask
)
1452 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1453 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1454 if (!m_currentClippingRegion
.IsNull())
1455 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1459 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1460 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1461 if (!m_currentClippingRegion
.IsNull())
1462 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1466 else // use_bitmap_method
1468 if ((width
!= ww
) || (height
!= hh
))
1470 /* Draw source window into a bitmap as we cannot scale
1471 a window in contrast to a bitmap. this would actually
1472 work with memory dcs as well, but we'd lose the mask
1473 information and waste one step in this process since
1474 a memory already has a bitmap. all this is slightly
1475 inefficient as we could take an XImage directly from
1476 an X window, but we'd then also have to care that
1477 the window is not outside the screen (in which case
1478 we'd get a BadMatch or what not).
1479 Is a double XGetImage and combined XGetPixel and
1480 XPutPixel really faster? I'm not sure. look at wxXt
1481 for a different implementation of the same problem. */
1483 wxBitmap
bitmap( width
, height
);
1485 // copy including child window contents
1486 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1487 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) bitmap
.GetPixmap(),
1488 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1489 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1492 wxImage
image( bitmap
.ConvertToImage() );
1493 image
= image
.Scale( ww
, hh
);
1495 // convert to bitmap
1498 // draw scaled bitmap
1499 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_window
,
1500 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1504 // No scaling and not a memory dc with a mask either
1506 // copy including child window contents
1507 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1508 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) m_window
,
1509 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1510 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1514 SetLogicalFunction( old_logical_func
);
1519 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1521 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1523 if (!m_window
) return;
1529 PangoLayout
*layout
= pango_layout_new(m_context
);
1530 pango_layout_set_font_description(layout
, m_fontdesc
);
1532 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1533 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1537 pango_layout_get_pixel_size(layout
, &w
, &h
);
1542 x11_draw_layout( (Drawable
) m_window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1544 g_object_unref( G_OBJECT( layout
) );
1546 CalcBoundingBox (x
+ width
, y
+ height
);
1547 CalcBoundingBox (x
, y
);
1549 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1551 wxCHECK_RET( xfont
, wxT("invalid font") );
1553 // First draw a rectangle representing the text background, if a text
1554 // background is specified
1555 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1557 // Since X draws from the baseline of the text, must add the text height
1562 int direction
, descent
;
1564 slen
= strlen(text
);
1565 XCharStruct overall_return
;
1567 (void)XTextExtents(xfont
, (const char*) text
.c_str(), slen
, &direction
,
1568 &ascent
, &descent
, &overall_return
);
1570 cx
= overall_return
.width
;
1571 cy
= ascent
+ descent
;
1572 m_textBackgroundColour
.CalcPixel(m_cmap
);
1573 m_textForegroundColour
.CalcPixel(m_cmap
);
1574 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1575 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
1576 (GC
) m_textGC
, x
, y
, cx
, cy
);
1577 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1581 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1583 // This may be a test for whether the font is 16-bit, but it also
1584 // seems to fail for valid 8-bit fonts too.
1585 if (1) // (xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
1588 XDrawString( (Display
*) m_display
, (Window
) m_window
,
1589 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.length() );
1593 if (m_font
.GetUnderlined())
1595 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1596 if (font
->descent
> 0) ul_y
++;
1597 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1600 width
= wxCoord(width
/ m_scaleX
);
1601 height
= wxCoord(height
/ m_scaleY
);
1603 CalcBoundingBox (x
+ width
, y
+ height
);
1604 CalcBoundingBox (x
, y
);
1609 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
, double angle
)
1614 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1615 wxCoord
*descent
, wxCoord
*externalLeading
,
1616 const wxFont
*font
) const
1618 wxCHECK_RET( Ok(), wxT("invalid dc") );
1622 if (width
) (*width
) = 0;
1623 if (height
) (*height
) = 0;
1628 PangoLayout
*layout
= pango_layout_new( m_context
);
1631 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1633 pango_layout_set_font_description(layout
, m_fontdesc
);
1635 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1636 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1640 pango_layout_get_pixel_size(layout
, &w
, &h
);
1642 if (width
) (*width
) = (wxCoord
) w
;
1643 if (height
) (*height
) = (wxCoord
) h
;
1646 // Do something about metrics here. TODO.
1649 if (externalLeading
) (*externalLeading
) = 0; // ??
1651 g_object_unref( G_OBJECT( layout
) );
1653 wxFont fontToUse
= m_font
;
1654 if (font
) fontToUse
= *font
;
1656 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
1658 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1660 wxCHECK_RET( xfont
, wxT("invalid font") );
1662 int direction
, ascent
, descent2
;
1663 XCharStruct overall
;
1665 XTextExtents( xfont
, (const char*) string
.c_str(), string
.length(), &direction
,
1666 &ascent
, &descent2
, &overall
);
1669 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1671 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1673 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1674 if (externalLeading
)
1675 *externalLeading
= 0; // ??
1679 wxCoord
wxWindowDC::GetCharWidth() const
1681 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1684 PangoLayout
*layout
= pango_layout_new( m_context
);
1687 pango_layout_set_font_description(layout
, m_fontdesc
);
1689 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1691 pango_layout_set_text(layout
, "H", 1 );
1693 pango_layout_get_pixel_size(layout
, &w
, &h
);
1694 g_object_unref( G_OBJECT( layout
) );
1698 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1700 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1702 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1704 int direction
, ascent
, descent
;
1705 XCharStruct overall
;
1707 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1709 return (wxCoord
)(overall
.width
/ m_scaleX
);
1713 wxCoord
wxWindowDC::GetCharHeight() const
1715 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1718 PangoLayout
*layout
= pango_layout_new( m_context
);
1721 pango_layout_set_font_description(layout
, m_fontdesc
);
1723 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1725 pango_layout_set_text(layout
, "H", 1 );
1727 pango_layout_get_pixel_size(layout
, &w
, &h
);
1728 g_object_unref( G_OBJECT( layout
) );
1732 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1734 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1736 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1738 int direction
, ascent
, descent
;
1739 XCharStruct overall
;
1741 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1743 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1747 void wxWindowDC::Clear()
1749 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1751 if (!m_window
) return;
1753 /* - we either are a memory dc or have a window as the
1754 owner. anything else shouldn't happen.
1755 - we don't use gdk_window_clear() as we don't set
1756 the window's background colour anymore. it is too
1757 much pain to keep the DC's and the window's back-
1758 ground colour in synch. */
1763 m_owner
->GetSize( &width
, &height
);
1764 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1771 GetSize( &width
, &height
);
1772 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1777 void wxWindowDC::SetFont( const wxFont
&font
)
1779 wxCHECK_RET( Ok(), wxT("invalid dc") );
1784 m_fontdesc
= font
.GetNativeFontInfo()->description
;
1788 void wxWindowDC::SetPen( const wxPen
&pen
)
1790 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1792 if (m_pen
== pen
) return;
1796 if (!m_pen
.Ok()) return;
1798 if (!m_window
) return;
1800 int width
= m_pen
.GetWidth();
1803 // CMB: if width is non-zero scale it with the dc
1808 // X doesn't allow different width in x and y and so we take
1811 ( fabs((double) XLOG2DEVREL(width
)) +
1812 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1816 static const wxX11Dash dotted
[] = {1, 1};
1817 static const wxX11Dash short_dashed
[] = {2, 2};
1818 static const wxX11Dash long_dashed
[] = {2, 4};
1819 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1821 // We express dash pattern in pen width unit, so we are
1822 // independent of zoom factor and so on...
1824 const wxX11Dash
*req_dash
;
1826 int lineStyle
= LineSolid
;
1827 switch (m_pen
.GetStyle())
1831 lineStyle
= LineOnOffDash
;
1832 req_nb_dash
= m_pen
.GetDashCount();
1833 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1838 lineStyle
= LineOnOffDash
;
1845 lineStyle
= LineOnOffDash
;
1847 req_dash
= long_dashed
;
1852 lineStyle
= LineOnOffDash
;
1854 req_dash
= short_dashed
;
1859 // lineStyle = LineDoubleDash;
1860 lineStyle
= LineOnOffDash
;
1862 req_dash
= dotted_dashed
;
1867 case wxSTIPPLE_MASK_OPAQUE
:
1872 lineStyle
= LineSolid
;
1873 req_dash
= (wxX11Dash
*)NULL
;
1879 int capStyle
= CapRound
;
1880 switch (m_pen
.GetCap())
1882 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1883 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1890 capStyle
= CapNotLast
;
1894 capStyle
= CapRound
;
1900 int joinStyle
= JoinRound
;
1901 switch (m_pen
.GetJoin())
1903 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1904 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1906 default: { joinStyle
= JoinRound
; break; }
1909 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1911 m_pen
.GetColour().CalcPixel( m_cmap
);
1912 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1915 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1917 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1919 if (m_brush
== brush
) return;
1923 if (!m_brush
.Ok()) return;
1925 if (!m_window
) return;
1927 m_brush
.GetColour().CalcPixel( m_cmap
);
1928 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1930 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1932 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1934 if (m_brush
.GetStipple()->GetPixmap())
1936 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1937 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1941 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1942 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1946 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1948 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1949 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1952 if (m_brush
.IsHatch())
1954 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1955 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1956 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1960 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1962 /* CMB 21/7/98: Added SetBackground. Sets background brush
1963 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1965 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1967 if (m_backgroundBrush
== brush
) return;
1969 m_backgroundBrush
= brush
;
1971 if (!m_backgroundBrush
.Ok()) return;
1973 if (!m_window
) return;
1975 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1976 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1977 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1978 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1979 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1981 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1983 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1985 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1987 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1988 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1992 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1993 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
1997 if (m_backgroundBrush
.IsHatch())
1999 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2000 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
2001 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
2005 void wxWindowDC::SetLogicalFunction( int function
)
2007 wxCHECK_RET( Ok(), wxT("invalid dc") );
2011 if (m_logicalFunction
== function
)
2014 // VZ: shouldn't this be a CHECK?
2021 x_function
= GXclear
;
2027 x_function
= GXinvert
;
2030 x_function
= GXorReverse
;
2033 x_function
= GXandReverse
;
2042 x_function
= GXandInverted
;
2045 x_function
= GXnoop
;
2051 x_function
= GXequiv
;
2054 x_function
= GXcopyInverted
;
2057 x_function
= GXorInverted
;
2060 x_function
= GXnand
;
2067 x_function
= GXcopy
;
2071 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2072 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2074 // to stay compatible with wxMSW, we don't apply ROPs to the text
2075 // operations (i.e. DrawText/DrawRotatedText).
2076 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2077 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2079 m_logicalFunction
= function
;
2082 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2084 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2086 // don't set m_textForegroundColour to an invalid colour as we'd crash
2087 // later then (we use m_textForegroundColour.GetColor() without checking
2089 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
2092 m_textForegroundColour
= col
;
2096 m_textForegroundColour
.CalcPixel( m_cmap
);
2097 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2101 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2103 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2106 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
2109 m_textBackgroundColour
= col
;
2113 m_textBackgroundColour
.CalcPixel( m_cmap
);
2114 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2118 void wxWindowDC::SetBackgroundMode( int mode
)
2120 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2122 m_backgroundMode
= mode
;
2125 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2128 if (!m_window
) return;
2130 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2131 // transparent/solid background mode
2133 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2135 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2136 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2140 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2146 /* Use GetXColormap */
2147 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2148 (Colormap
) palette
.GetXColormap());
2150 /* Use wxGetMainColormap */
2151 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2152 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2157 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2159 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2161 if (!m_window
) return;
2170 rect
.x
= XLOG2DEV(x
);
2171 rect
.y
= YLOG2DEV(y
);
2172 rect
.width
= XLOG2DEVREL(width
);
2173 rect
.height
= YLOG2DEVREL(height
);
2175 if (!m_currentClippingRegion
.IsEmpty())
2176 m_currentClippingRegion
.Intersect( rect
);
2178 m_currentClippingRegion
= rect
;
2180 #if USE_PAINT_REGION
2181 if (!m_paintClippingRegion
.IsEmpty())
2182 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2185 wxCoord xx
, yy
, ww
, hh
;
2186 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2187 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2189 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2190 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2191 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2192 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2195 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2197 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2201 DestroyClippingRegion();
2205 if (!m_window
) return;
2207 if (!m_currentClippingRegion
.IsEmpty())
2208 m_currentClippingRegion
.Intersect( region
);
2210 m_currentClippingRegion
= region
;
2212 #if USE_PAINT_REGION
2213 if (!m_paintClippingRegion
.IsEmpty())
2214 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2217 wxCoord xx
, yy
, ww
, hh
;
2218 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2219 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2221 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2222 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2223 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2224 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2227 void wxWindowDC::DestroyClippingRegion()
2229 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2231 wxDC::DestroyClippingRegion();
2233 m_currentClippingRegion
.Clear();
2235 #if USE_PAINT_REGION
2236 if (!m_paintClippingRegion
.IsEmpty())
2237 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2240 if (!m_window
) return;
2242 if (m_currentClippingRegion
.IsEmpty())
2244 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2245 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2246 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2247 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
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() );
2258 void wxWindowDC::Destroy()
2260 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2262 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2264 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2266 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2270 void wxWindowDC::ComputeScaleAndOrigin()
2272 /* CMB: copy scale to see if it changes */
2273 double origScaleX
= m_scaleX
;
2274 double origScaleY
= m_scaleY
;
2276 wxDC::ComputeScaleAndOrigin();
2278 /* CMB: if scale has changed call SetPen to recalulate the line width */
2279 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2282 /* this is a bit artificial, but we need to force wxDC to think
2283 the pen has changed */
2290 wxSize
wxWindowDC::GetPPI() const
2292 return wxSize(100, 100);
2295 int wxWindowDC::GetDepth() const
2297 wxFAIL_MSG(wxT("not implemented"));
2302 //-----------------------------------------------------------------------------
2304 //-----------------------------------------------------------------------------
2306 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2308 wxClientDC::wxClientDC( wxWindow
*window
)
2309 : wxWindowDC( window
)
2311 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2313 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2315 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2316 if (m_window
== (WXWindow
*) window
->GetMainWindow())
2318 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2319 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2320 wxSize size
= window
->GetClientSize();
2321 SetClippingRegion(wxPoint(0, 0), size
);
2325 void wxClientDC::DoGetSize(int *width
, int *height
) const
2327 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2329 m_owner
->GetClientSize( width
, height
);
2332 // ----------------------------------------------------------------------------
2334 // ----------------------------------------------------------------------------
2336 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2338 wxPaintDC::wxPaintDC(wxWindow
* window
)
2339 : wxClientDC(window
)
2341 #if USE_PAINT_REGION
2342 if (!window
->GetClipPaintRegion())
2345 m_paintClippingRegion
= window
->GetUpdateRegion();
2346 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2349 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2351 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2352 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2353 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2354 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2356 #endif // USE_PAINT_REGION
2359 // ----------------------------------------------------------------------------
2361 // ----------------------------------------------------------------------------
2363 class wxDCModule
: public wxModule
2366 // we must be cleaned up before wxDisplayModule which closes the global
2370 AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule")));
2373 bool OnInit() { wxInitGCPool(); return true; }
2374 void OnExit() { wxCleanUpGCPool(); }
2377 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2380 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)