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
,
629 int WXUNUSED(fillStyle
) )
631 wxCHECK_RET( Ok(), wxT("invalid window dc") );
635 XPoint
*xpoints
= new XPoint
[n
+ 1];
637 for (i
= 0; i
< n
; i
++)
639 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
640 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
642 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
647 if (m_brush
.GetStyle() != wxTRANSPARENT
)
650 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
652 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
653 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
654 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
656 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
657 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
659 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
661 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
663 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
664 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
666 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
667 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
669 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
671 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
673 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
674 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
676 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
677 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
679 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
681 if (m_brush
.GetStyle() == wxSTIPPLE
)
683 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
684 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
685 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
687 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
688 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
690 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
694 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
695 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
699 if (m_pen
.GetStyle () != wxTRANSPARENT
)
701 // Close figure for XDrawLines
702 xpoints
[i
].x
= xpoints
[0].x
;
703 xpoints
[i
].y
= xpoints
[0].y
;
705 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
712 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
714 wxCHECK_RET( Ok(), wxT("invalid window dc") );
716 wxCoord xx
= XLOG2DEV(x
);
717 wxCoord yy
= YLOG2DEV(y
);
718 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
719 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
721 // CMB: draw nothing if transformed w or h is 0
722 if (ww
== 0 || hh
== 0) return;
724 // CMB: handle -ve width and/or height
725 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
726 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
730 if (m_brush
.GetStyle() != wxTRANSPARENT
)
732 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
734 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
735 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
736 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
738 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
739 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
741 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
743 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
745 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
746 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
748 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
749 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
751 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
753 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
755 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
756 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
758 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
759 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
761 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
763 if (m_brush
.GetStyle() == wxSTIPPLE
)
765 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
766 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
767 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
769 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
770 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
772 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
776 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
777 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
781 if (m_pen
.GetStyle () != wxTRANSPARENT
)
783 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
784 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
788 CalcBoundingBox( x
, y
);
789 CalcBoundingBox( x
+ width
, y
+ height
);
792 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
794 wxCHECK_RET( Ok(), wxT("invalid window dc") );
796 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
798 wxCoord xx
= XLOG2DEV(x
);
799 wxCoord yy
= YLOG2DEV(y
);
800 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
801 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
802 wxCoord rr
= XLOG2DEVREL((wxCoord
)radius
);
804 // CMB: handle -ve width and/or height
805 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
806 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
808 // CMB: if radius is zero use DrawRectangle() instead to avoid
809 // X drawing errors with small radii
812 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
813 (GC
) m_penGC
, x
, y
, width
, height
);
817 // CMB: draw nothing if transformed w or h is 0
818 if (ww
== 0 || hh
== 0) return;
820 // CMB: adjust size if outline is drawn otherwise the result is
821 // 1 pixel too wide and high
822 if (m_pen
.GetStyle() != wxTRANSPARENT
)
830 // CMB: ensure dd is not larger than rectangle otherwise we
831 // get an hour glass shape
833 if (dd
> ww
) dd
= ww
;
834 if (dd
> hh
) dd
= hh
;
837 if (m_brush
.GetStyle() != wxTRANSPARENT
)
839 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
841 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
842 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
843 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
844 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
845 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
846 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
847 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
848 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
849 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
850 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0);
852 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
854 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
855 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
856 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
857 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
858 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
859 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
860 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
861 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
863 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
865 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
866 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
867 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
868 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
869 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
870 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
871 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
872 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
874 if (m_brush
.GetStyle() == wxSTIPPLE
)
876 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
877 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
878 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
879 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
880 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
881 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
882 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
883 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
884 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
885 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
889 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
890 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
891 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
892 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
893 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
894 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
897 if (m_pen
.GetStyle() != wxTRANSPARENT
)
899 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy
);
900 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
901 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr
);
902 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr
);
903 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
904 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
905 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
906 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
910 // this ignores the radius
911 CalcBoundingBox( x
, y
);
912 CalcBoundingBox( x
+ width
, y
+ height
);
915 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
917 wxCHECK_RET( Ok(), wxT("invalid window dc") );
919 wxCoord xx
= XLOG2DEV(x
);
920 wxCoord yy
= YLOG2DEV(y
);
921 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
922 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
924 // CMB: handle -ve width and/or height
925 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
926 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
930 if (m_brush
.GetStyle() != wxTRANSPARENT
)
932 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
934 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
935 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
936 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
938 XFillArc( (Display
*) m_display
, (Window
) m_window
,
939 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
941 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
943 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
945 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
946 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
948 XFillArc( (Display
*) m_display
, (Window
) m_window
,
949 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
951 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
953 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
955 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
956 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
958 XFillArc( (Display
*) m_display
, (Window
) m_window
,
959 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
961 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
963 if (m_brush
.GetStyle() == wxSTIPPLE
)
965 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
966 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
967 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
969 XFillArc( (Display
*) m_display
, (Window
) m_window
,
970 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
972 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
976 XFillArc( (Display
*) m_display
, (Window
) m_window
,
977 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
981 if (m_pen
.GetStyle () != wxTRANSPARENT
)
983 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
984 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
988 CalcBoundingBox( x
, y
);
989 CalcBoundingBox( x
+ width
, y
+ height
);
992 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
994 DoDrawBitmap(icon
, x
, y
, true);
998 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
999 wxCoord x
, wxCoord y
,
1002 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1004 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1006 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1008 /* scale/translate size and position */
1009 int xx
= XLOG2DEV(x
);
1010 int yy
= YLOG2DEV(y
);
1012 int w
= bitmap
.GetWidth();
1013 int h
= bitmap
.GetHeight();
1015 CalcBoundingBox( x
, y
);
1016 CalcBoundingBox( x
+ w
, y
+ h
);
1018 if (!m_window
) return;
1020 int ww
= XLOG2DEVREL(w
);
1021 int hh
= YLOG2DEVREL(h
);
1023 /* compare to current clipping region */
1024 if (!m_currentClippingRegion
.IsNull())
1026 wxRegion
tmp( xx
,yy
,ww
,hh
);
1027 tmp
.Intersect( m_currentClippingRegion
);
1032 /* scale bitmap if required */
1033 wxBitmap use_bitmap
;
1034 if ((w
!= ww
) || (h
!= hh
))
1036 wxImage
image( bitmap
.ConvertToImage() );
1037 image
.Rescale( ww
, hh
);
1040 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1047 use_bitmap
= bitmap
;
1050 /* apply mask if any */
1051 WXPixmap mask
= NULL
;
1052 if (use_bitmap
.GetMask())
1053 mask
= use_bitmap
.GetMask()->GetBitmap();
1055 if (useMask
&& mask
)
1057 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
1058 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
1059 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
1061 GrSetGCUseBackground(gc
, FALSE
);
1062 GrSetGCMode(gc
, GR_MODE_COPY
);
1064 // This code assumes that background and foreground
1065 // colours are used in ROPs, like in MSW.
1066 // Not sure if this is true.
1068 // Copy destination to buffer.
1069 // In DoBlit, we need this step because Blit has
1070 // a ROP argument. Here, we don't need it.
1071 // In DoBlit, we may be able to eliminate this step
1072 // if we check if the rop = copy
1074 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_window
,
1075 0, 0, GR_MODE_COPY
);
1078 // Copy src to buffer using selected raster op (none selected
1079 // in DrawBitmap, so just use Gxcopy)
1080 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
1081 0, 0, GR_MODE_COPY
);
1083 // Set masked area in buffer to BLACK (pixel value 0)
1084 GrSetGCBackground(gc
, WHITE
);
1085 GrSetGCForeground(gc
, BLACK
);
1086 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
1089 // set unmasked area in dest to BLACK
1090 GrSetGCBackground(gc
, BLACK
);
1091 GrSetGCForeground(gc
, WHITE
);
1092 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
1095 // OR buffer to dest
1096 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
1100 GrDestroyWindow(bufPixmap
);
1103 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1104 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1106 /* remove mask again if any */
1107 if (useMask
&& mask
)
1109 if (!m_currentClippingRegion
.IsNull())
1110 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1117 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1118 wxCoord x
, wxCoord y
,
1121 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1123 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1125 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1127 // scale/translate size and position
1128 int xx
= XLOG2DEV(x
);
1129 int yy
= YLOG2DEV(y
);
1131 int w
= bitmap
.GetWidth();
1132 int h
= bitmap
.GetHeight();
1134 CalcBoundingBox( x
, y
);
1135 CalcBoundingBox( x
+ w
, y
+ h
);
1137 if (!m_window
) return;
1139 int ww
= XLOG2DEVREL(w
);
1140 int hh
= YLOG2DEVREL(h
);
1142 // compare to current clipping region
1143 if (!m_currentClippingRegion
.IsNull())
1145 wxRegion
tmp( xx
,yy
,ww
,hh
);
1146 tmp
.Intersect( m_currentClippingRegion
);
1151 // scale bitmap if required
1152 wxBitmap use_bitmap
;
1153 if ((w
!= ww
) || (h
!= hh
))
1155 wxImage
image( bitmap
.ConvertToImage() );
1156 image
.Rescale( ww
, hh
);
1159 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1166 use_bitmap
= bitmap
;
1169 // apply mask if any
1170 WXPixmap mask
= NULL
;
1171 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1173 bool setClipMask
= false;
1175 if (!m_currentClippingRegion
.IsNull() || (useMask
&& mask
))
1177 // XSetClipMask() call is necessary (because of clip region and/or transparent mask)
1179 Pixmap new_pixmap
= 0;
1181 if (!m_currentClippingRegion
.IsNull())
1183 // clipping necessary => create new_pixmap
1184 Display
*xdisplay
= (Display
*) m_display
;
1185 int xscreen
= DefaultScreen( xdisplay
);
1186 Window xroot
= RootWindow( xdisplay
, xscreen
);
1188 new_pixmap
= XCreatePixmap( xdisplay
, xroot
, ww
, hh
, 1 );
1189 GC gc
= XCreateGC( xdisplay
, new_pixmap
, 0, NULL
);
1191 XSetForeground( xdisplay
, gc
, BlackPixel(xdisplay
,xscreen
) );
1193 XSetFillStyle( xdisplay
, gc
, FillSolid
);
1194 XFillRectangle( xdisplay
, new_pixmap
, gc
, 0, 0, ww
, hh
);
1196 XSetForeground( xdisplay
, gc
, WhitePixel(xdisplay
,xscreen
) );
1198 if (useMask
&& mask
)
1200 // transparent mask => call XSetStipple
1201 XSetFillStyle( xdisplay
, gc
, FillStippled
);
1202 XSetTSOrigin( xdisplay
, gc
, 0, 0);
1203 XSetStipple( xdisplay
, gc
, (Pixmap
) mask
);
1206 wxCoord clip_x
, clip_y
, clip_w
, clip_h
;
1207 m_currentClippingRegion
.GetBox(clip_x
, clip_y
, clip_w
, clip_h
);
1208 XFillRectangle( xdisplay
, new_pixmap
, gc
, clip_x
-xx
, clip_y
-yy
, clip_w
, clip_h
);
1210 XFreeGC( xdisplay
, gc
);
1216 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, new_pixmap
);
1218 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1219 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1224 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, new_pixmap
);
1226 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1227 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1231 XFreePixmap( (Display
*) m_display
, new_pixmap
);
1234 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1235 // drawing a mono-bitmap (XBitmap) we use the current text GC
1237 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1238 (GC
) m_textGC
, 0, 0, ww
, hh
, xx
, yy
, 1 );
1240 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1241 (GC
) m_penGC
, 0, 0, ww
, hh
, xx
, yy
);
1243 // remove mask again if any
1248 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1249 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1250 if (!m_currentClippingRegion
.IsNull())
1251 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1255 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1256 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1257 if (!m_currentClippingRegion
.IsNull())
1258 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1263 // wxUSE_NANOX/!wxUSE_NANOX
1265 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1266 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1267 wxCoord xsrcMask
, wxCoord ysrcMask
)
1269 /* this is the nth try to get this utterly useless function to
1270 work. it now completely ignores the scaling or translation
1271 of the source dc, but scales correctly on the target dc and
1272 knows about possible mask information in a memory dc. */
1274 wxCHECK_MSG( Ok(), false, wxT("invalid window dc") );
1276 wxCHECK_MSG( source
, false, wxT("invalid source dc") );
1278 if (!m_window
) return false;
1280 // transform the source DC coords to the device ones
1281 xsrc
= source
->LogicalToDeviceX(xsrc
);
1282 ysrc
= source
->LogicalToDeviceY(ysrc
);
1284 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1285 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1287 bool use_bitmap_method
= false;
1288 bool is_mono
= false;
1290 // TODO: use the mask origin when drawing transparently
1291 if (xsrcMask
== -1 && ysrcMask
== -1)
1297 if (srcDC
->m_isMemDC
)
1299 if (!memDC
->m_selected
.Ok()) return false;
1301 /* we use the "XCopyArea" way to copy a memory dc into
1302 y different window if the memory dc BOTH
1303 a) doesn't have any mask or its mask isn't used
1307 if (useMask
&& (memDC
->m_selected
.GetMask()))
1309 /* we HAVE TO use the direct way for memory dcs
1310 that have mask since the XCopyArea doesn't know
1312 use_bitmap_method
= true;
1314 else if (memDC
->m_selected
.GetDepth() == 1)
1316 /* we HAVE TO use the direct way for memory dcs
1317 that are bitmaps because XCopyArea doesn't cope
1318 with different bit depths */
1320 use_bitmap_method
= true;
1322 else if ((xsrc
== 0) && (ysrc
== 0) &&
1323 (width
== memDC
->m_selected
.GetWidth()) &&
1324 (height
== memDC
->m_selected
.GetHeight()))
1326 /* we SHOULD use the direct way if all of the bitmap
1327 in the memory dc is copied in which case XCopyArea
1328 wouldn't be able able to boost performace by reducing
1329 the area to be scaled */
1330 use_bitmap_method
= true;
1334 use_bitmap_method
= false;
1338 CalcBoundingBox( xdest
, ydest
);
1339 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1341 // scale/translate size and position
1342 wxCoord xx
= XLOG2DEV(xdest
);
1343 wxCoord yy
= YLOG2DEV(ydest
);
1345 wxCoord ww
= XLOG2DEVREL(width
);
1346 wxCoord hh
= YLOG2DEVREL(height
);
1348 // compare to current clipping region
1349 if (!m_currentClippingRegion
.IsNull())
1351 wxRegion
tmp( xx
,yy
,ww
,hh
);
1352 tmp
.Intersect( m_currentClippingRegion
);
1357 int old_logical_func
= m_logicalFunction
;
1358 SetLogicalFunction( logical_func
);
1360 if (use_bitmap_method
)
1362 // scale/translate bitmap size
1363 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1364 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1366 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1367 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1369 // scale bitmap if required
1370 wxBitmap use_bitmap
;
1372 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1374 wxImage
image( memDC
->m_selected
.ConvertToImage() );
1375 image
= image
.Scale( bm_ww
, bm_hh
);
1379 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1386 use_bitmap
= memDC
->m_selected
;
1389 // apply mask if any
1390 WXPixmap mask
= NULL
;
1391 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1393 if (useMask
&& mask
)
1395 WXPixmap new_mask
= NULL
;
1397 if (!m_currentClippingRegion
.IsNull())
1400 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1401 GdkGC
*gc
= gdk_gc_new( new_mask
);
1403 gdk_gc_set_foreground( gc
, &col
);
1404 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1406 gdk_gc_set_background( gc
, &col
);
1408 gdk_gc_set_foreground( gc
, &col
);
1409 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1410 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1411 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1412 gdk_gc_set_stipple( gc
, mask
);
1413 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1420 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1422 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1423 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1428 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1430 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1431 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1435 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1438 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1439 // drawing a mono-bitmap (XBitmap) we use the current text GC
1442 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1443 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1445 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1446 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1448 // remove mask again if any
1449 if (useMask
&& mask
)
1453 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1454 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1455 if (!m_currentClippingRegion
.IsNull())
1456 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1460 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1461 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1462 if (!m_currentClippingRegion
.IsNull())
1463 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1467 else // use_bitmap_method
1469 if ((width
!= ww
) || (height
!= hh
))
1471 /* Draw source window into a bitmap as we cannot scale
1472 a window in contrast to a bitmap. this would actually
1473 work with memory dcs as well, but we'd lose the mask
1474 information and waste one step in this process since
1475 a memory already has a bitmap. all this is slightly
1476 inefficient as we could take an XImage directly from
1477 an X window, but we'd then also have to care that
1478 the window is not outside the screen (in which case
1479 we'd get a BadMatch or what not).
1480 Is a double XGetImage and combined XGetPixel and
1481 XPutPixel really faster? I'm not sure. look at wxXt
1482 for a different implementation of the same problem. */
1484 wxBitmap
bitmap( width
, height
);
1486 // copy including child window contents
1487 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1488 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) bitmap
.GetPixmap(),
1489 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1490 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1493 wxImage
image( bitmap
.ConvertToImage() );
1494 image
= image
.Scale( ww
, hh
);
1496 // convert to bitmap
1499 // draw scaled bitmap
1500 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_window
,
1501 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1505 // No scaling and not a memory dc with a mask either
1507 // copy including child window contents
1508 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1509 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) m_window
,
1510 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1511 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1515 SetLogicalFunction( old_logical_func
);
1520 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1522 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1524 if (!m_window
) return;
1530 PangoLayout
*layout
= pango_layout_new(m_context
);
1531 pango_layout_set_font_description(layout
, m_fontdesc
);
1533 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1534 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1538 pango_layout_get_pixel_size(layout
, &w
, &h
);
1543 x11_draw_layout( (Drawable
) m_window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1545 g_object_unref( G_OBJECT( layout
) );
1547 CalcBoundingBox (x
+ width
, y
+ height
);
1548 CalcBoundingBox (x
, y
);
1550 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1552 wxCHECK_RET( xfont
, wxT("invalid font") );
1554 // First draw a rectangle representing the text background, if a text
1555 // background is specified
1556 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1558 // Since X draws from the baseline of the text, must add the text height
1563 int direction
, descent
;
1565 slen
= strlen(text
);
1566 XCharStruct overall_return
;
1568 (void)XTextExtents(xfont
, (const char*) text
.c_str(), slen
, &direction
,
1569 &ascent
, &descent
, &overall_return
);
1571 cx
= overall_return
.width
;
1572 cy
= ascent
+ descent
;
1573 m_textBackgroundColour
.CalcPixel(m_cmap
);
1574 m_textForegroundColour
.CalcPixel(m_cmap
);
1575 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1576 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
1577 (GC
) m_textGC
, x
, y
, cx
, cy
);
1578 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1582 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1584 // This may be a test for whether the font is 16-bit, but it also
1585 // seems to fail for valid 8-bit fonts too.
1586 if (1) // (xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
1589 XDrawString( (Display
*) m_display
, (Window
) m_window
,
1590 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.length() );
1594 if (m_font
.GetUnderlined())
1596 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1597 if (font
->descent
> 0) ul_y
++;
1598 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1601 width
= wxCoord(width
/ m_scaleX
);
1602 height
= wxCoord(height
/ m_scaleY
);
1604 CalcBoundingBox (x
+ width
, y
+ height
);
1605 CalcBoundingBox (x
, y
);
1610 void wxWindowDC::DoDrawRotatedText(const wxString
& WXUNUSED(text
),
1611 wxCoord
WXUNUSED(x
), wxCoord
WXUNUSED(y
),
1612 double WXUNUSED(angle
))
1614 wxFAIL_MSG( "not implemented" );
1617 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1618 wxCoord
*descent
, wxCoord
*externalLeading
,
1619 const wxFont
*font
) const
1621 wxCHECK_RET( Ok(), wxT("invalid dc") );
1625 if (width
) (*width
) = 0;
1626 if (height
) (*height
) = 0;
1631 PangoLayout
*layout
= pango_layout_new( m_context
);
1634 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1636 pango_layout_set_font_description(layout
, m_fontdesc
);
1638 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1639 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1643 pango_layout_get_pixel_size(layout
, &w
, &h
);
1645 if (width
) (*width
) = (wxCoord
) w
;
1646 if (height
) (*height
) = (wxCoord
) h
;
1649 // Do something about metrics here. TODO.
1652 if (externalLeading
) (*externalLeading
) = 0; // ??
1654 g_object_unref( G_OBJECT( layout
) );
1656 wxFont fontToUse
= m_font
;
1657 if (font
) fontToUse
= *font
;
1659 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
1661 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1663 wxCHECK_RET( xfont
, wxT("invalid font") );
1665 int direction
, ascent
, descent2
;
1666 XCharStruct overall
;
1668 XTextExtents( xfont
, (const char*) string
.c_str(), string
.length(), &direction
,
1669 &ascent
, &descent2
, &overall
);
1672 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1674 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1676 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1677 if (externalLeading
)
1678 *externalLeading
= 0; // ??
1682 wxCoord
wxWindowDC::GetCharWidth() const
1684 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1687 PangoLayout
*layout
= pango_layout_new( m_context
);
1690 pango_layout_set_font_description(layout
, m_fontdesc
);
1692 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1694 pango_layout_set_text(layout
, "H", 1 );
1696 pango_layout_get_pixel_size(layout
, &w
, &h
);
1697 g_object_unref( G_OBJECT( layout
) );
1701 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1703 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1705 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1707 int direction
, ascent
, descent
;
1708 XCharStruct overall
;
1710 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1712 return (wxCoord
)(overall
.width
/ m_scaleX
);
1716 wxCoord
wxWindowDC::GetCharHeight() const
1718 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1721 PangoLayout
*layout
= pango_layout_new( m_context
);
1724 pango_layout_set_font_description(layout
, m_fontdesc
);
1726 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1728 pango_layout_set_text(layout
, "H", 1 );
1730 pango_layout_get_pixel_size(layout
, &w
, &h
);
1731 g_object_unref( G_OBJECT( layout
) );
1735 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1737 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1739 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1741 int direction
, ascent
, descent
;
1742 XCharStruct overall
;
1744 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1746 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1750 void wxWindowDC::Clear()
1752 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1754 if (!m_window
) return;
1756 /* - we either are a memory dc or have a window as the
1757 owner. anything else shouldn't happen.
1758 - we don't use gdk_window_clear() as we don't set
1759 the window's background colour anymore. it is too
1760 much pain to keep the DC's and the window's back-
1761 ground colour in synch. */
1766 m_owner
->GetSize( &width
, &height
);
1767 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1774 GetSize( &width
, &height
);
1775 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1780 void wxWindowDC::SetFont( const wxFont
&font
)
1782 wxCHECK_RET( Ok(), wxT("invalid dc") );
1787 m_fontdesc
= font
.GetNativeFontInfo()->description
;
1791 void wxWindowDC::SetPen( const wxPen
&pen
)
1793 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1795 if (m_pen
== pen
) return;
1799 if (!m_pen
.Ok()) return;
1801 if (!m_window
) return;
1803 int width
= m_pen
.GetWidth();
1806 // CMB: if width is non-zero scale it with the dc
1811 // X doesn't allow different width in x and y and so we take
1814 ( fabs((double) XLOG2DEVREL(width
)) +
1815 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1819 static const wxX11Dash dotted
[] = {1, 1};
1820 static const wxX11Dash short_dashed
[] = {2, 2};
1821 static const wxX11Dash long_dashed
[] = {2, 4};
1822 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1824 // We express dash pattern in pen width unit, so we are
1825 // independent of zoom factor and so on...
1827 const wxX11Dash
*req_dash
;
1829 int lineStyle
= LineSolid
;
1830 switch (m_pen
.GetStyle())
1834 lineStyle
= LineOnOffDash
;
1835 req_nb_dash
= m_pen
.GetDashCount();
1836 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1841 lineStyle
= LineOnOffDash
;
1848 lineStyle
= LineOnOffDash
;
1850 req_dash
= long_dashed
;
1855 lineStyle
= LineOnOffDash
;
1857 req_dash
= short_dashed
;
1862 // lineStyle = LineDoubleDash;
1863 lineStyle
= LineOnOffDash
;
1865 req_dash
= dotted_dashed
;
1870 case wxSTIPPLE_MASK_OPAQUE
:
1875 lineStyle
= LineSolid
;
1876 req_dash
= (wxX11Dash
*)NULL
;
1882 int capStyle
= CapRound
;
1883 switch (m_pen
.GetCap())
1885 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1886 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1893 capStyle
= CapNotLast
;
1897 capStyle
= CapRound
;
1903 int joinStyle
= JoinRound
;
1904 switch (m_pen
.GetJoin())
1906 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1907 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1909 default: { joinStyle
= JoinRound
; break; }
1912 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1914 m_pen
.GetColour().CalcPixel( m_cmap
);
1915 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1918 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1920 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1922 if (m_brush
== brush
) return;
1926 if (!m_brush
.Ok()) return;
1928 if (!m_window
) return;
1930 m_brush
.GetColour().CalcPixel( m_cmap
);
1931 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1933 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1935 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1937 if (m_brush
.GetStipple()->GetPixmap())
1939 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1940 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1944 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1945 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1949 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1951 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1952 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1955 if (m_brush
.IsHatch())
1957 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1958 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1959 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1963 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1965 /* CMB 21/7/98: Added SetBackground. Sets background brush
1966 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1968 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1970 if (m_backgroundBrush
== brush
) return;
1972 m_backgroundBrush
= brush
;
1974 if (!m_backgroundBrush
.Ok()) return;
1976 if (!m_window
) return;
1978 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1979 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1980 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1981 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1982 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1984 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1986 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1988 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1990 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1991 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1995 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1996 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
2000 if (m_backgroundBrush
.IsHatch())
2002 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2003 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
2004 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
2008 void wxWindowDC::SetLogicalFunction( int function
)
2010 wxCHECK_RET( Ok(), wxT("invalid dc") );
2014 if (m_logicalFunction
== function
)
2017 // VZ: shouldn't this be a CHECK?
2024 x_function
= GXclear
;
2030 x_function
= GXinvert
;
2033 x_function
= GXorReverse
;
2036 x_function
= GXandReverse
;
2045 x_function
= GXandInverted
;
2048 x_function
= GXnoop
;
2054 x_function
= GXequiv
;
2057 x_function
= GXcopyInverted
;
2060 x_function
= GXorInverted
;
2063 x_function
= GXnand
;
2070 x_function
= GXcopy
;
2074 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2075 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2077 // to stay compatible with wxMSW, we don't apply ROPs to the text
2078 // operations (i.e. DrawText/DrawRotatedText).
2079 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2080 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2082 m_logicalFunction
= function
;
2085 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2087 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2089 // don't set m_textForegroundColour to an invalid colour as we'd crash
2090 // later then (we use m_textForegroundColour.GetColor() without checking
2092 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
2095 m_textForegroundColour
= col
;
2099 m_textForegroundColour
.CalcPixel( m_cmap
);
2100 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2104 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2106 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2109 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
2112 m_textBackgroundColour
= col
;
2116 m_textBackgroundColour
.CalcPixel( m_cmap
);
2117 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2121 void wxWindowDC::SetBackgroundMode( int mode
)
2123 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2125 m_backgroundMode
= mode
;
2128 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2131 if (!m_window
) return;
2133 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2134 // transparent/solid background mode
2136 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2138 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2139 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2143 void wxWindowDC::SetPalette( const wxPalette
& WXUNUSED(palette
) )
2149 /* Use GetXColormap */
2150 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2151 (Colormap
) palette
.GetXColormap());
2153 /* Use wxGetMainColormap */
2154 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2155 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2160 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2162 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2164 if (!m_window
) return;
2173 rect
.x
= XLOG2DEV(x
);
2174 rect
.y
= YLOG2DEV(y
);
2175 rect
.width
= XLOG2DEVREL(width
);
2176 rect
.height
= YLOG2DEVREL(height
);
2178 if (!m_currentClippingRegion
.IsEmpty())
2179 m_currentClippingRegion
.Intersect( rect
);
2181 m_currentClippingRegion
= rect
;
2183 #if USE_PAINT_REGION
2184 if (!m_paintClippingRegion
.IsEmpty())
2185 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2188 wxCoord xx
, yy
, ww
, hh
;
2189 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2190 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2192 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2193 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2194 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2195 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2198 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2200 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2204 DestroyClippingRegion();
2208 if (!m_window
) return;
2210 if (!m_currentClippingRegion
.IsEmpty())
2211 m_currentClippingRegion
.Intersect( region
);
2213 m_currentClippingRegion
= region
;
2215 #if USE_PAINT_REGION
2216 if (!m_paintClippingRegion
.IsEmpty())
2217 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2220 wxCoord xx
, yy
, ww
, hh
;
2221 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2222 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2224 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2225 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2226 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2227 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2230 void wxWindowDC::DestroyClippingRegion()
2232 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2234 wxDC::DestroyClippingRegion();
2236 m_currentClippingRegion
.Clear();
2238 #if USE_PAINT_REGION
2239 if (!m_paintClippingRegion
.IsEmpty())
2240 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2243 if (!m_window
) return;
2245 if (m_currentClippingRegion
.IsEmpty())
2247 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2248 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2249 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2250 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2254 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2255 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2256 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2257 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2261 void wxWindowDC::Destroy()
2263 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2265 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2267 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2269 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2273 void wxWindowDC::ComputeScaleAndOrigin()
2275 /* CMB: copy scale to see if it changes */
2276 double origScaleX
= m_scaleX
;
2277 double origScaleY
= m_scaleY
;
2279 wxDC::ComputeScaleAndOrigin();
2281 /* CMB: if scale has changed call SetPen to recalulate the line width */
2282 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2285 /* this is a bit artificial, but we need to force wxDC to think
2286 the pen has changed */
2293 wxSize
wxWindowDC::GetPPI() const
2295 return wxSize(100, 100);
2298 int wxWindowDC::GetDepth() const
2300 wxFAIL_MSG(wxT("not implemented"));
2305 //-----------------------------------------------------------------------------
2307 //-----------------------------------------------------------------------------
2309 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2311 wxClientDC::wxClientDC( wxWindow
*window
)
2312 : wxWindowDC( window
)
2314 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2316 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2318 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2319 if (m_window
== (WXWindow
*) window
->GetMainWindow())
2321 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2322 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2323 wxSize size
= window
->GetClientSize();
2324 SetClippingRegion(wxPoint(0, 0), size
);
2328 void wxClientDC::DoGetSize(int *width
, int *height
) const
2330 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2332 m_owner
->GetClientSize( width
, height
);
2335 // ----------------------------------------------------------------------------
2337 // ----------------------------------------------------------------------------
2339 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2341 wxPaintDC::wxPaintDC(wxWindow
* window
)
2342 : wxClientDC(window
)
2344 #if USE_PAINT_REGION
2345 if (!window
->GetClipPaintRegion())
2348 m_paintClippingRegion
= window
->GetUpdateRegion();
2349 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2352 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2354 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2355 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2356 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2357 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2359 #endif // USE_PAINT_REGION
2362 // ----------------------------------------------------------------------------
2364 // ----------------------------------------------------------------------------
2366 class wxDCModule
: public wxModule
2369 // we must be cleaned up before wxDisplayModule which closes the global
2373 AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule")));
2376 bool OnInit() { wxInitGCPool(); return true; }
2377 void OnExit() { wxCleanUpGCPool(); }
2380 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2383 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)