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 #define USE_PAINT_REGION 1
46 //-----------------------------------------------------------------------------
48 //-----------------------------------------------------------------------------
58 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH)
59 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH)
61 static Pixmap hatches
[num_hatches
];
62 static Pixmap
*hatch_bitmap
= (Pixmap
*) NULL
;
64 //-----------------------------------------------------------------------------
66 //-----------------------------------------------------------------------------
68 const double RAD2DEG
= 180.0 / M_PI
;
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
74 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
75 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
77 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
79 //-----------------------------------------------------------------------------
80 // Implement Pool of Graphic contexts. Creating them takes too much time.
81 //-----------------------------------------------------------------------------
83 #define GC_POOL_SIZE 200
109 static wxGC wxGCPool
[GC_POOL_SIZE
];
111 static void wxInitGCPool()
113 memset( wxGCPool
, 0, GC_POOL_SIZE
*sizeof(wxGC
) );
116 static void wxCleanUpGCPool()
118 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
120 if (wxGCPool
[i
].m_gc
)
121 XFreeGC( wxGlobalDisplay(), wxGCPool
[i
].m_gc
);
125 static GC
wxGetPoolGC( Window window
, wxPoolGCType type
)
127 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
129 if (!wxGCPool
[i
].m_gc
)
131 wxGCPool
[i
].m_gc
= XCreateGC( wxGlobalDisplay(), window
, 0, NULL
);
132 XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool
[i
].m_gc
, FALSE
);
133 wxGCPool
[i
].m_type
= type
;
134 wxGCPool
[i
].m_used
= false;
136 if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type
== type
))
138 wxGCPool
[i
].m_used
= true;
139 return wxGCPool
[i
].m_gc
;
143 wxFAIL_MSG( wxT("No GC available") );
148 static void wxFreePoolGC( GC gc
)
150 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
152 if (wxGCPool
[i
].m_gc
== gc
)
154 wxGCPool
[i
].m_used
= false;
159 wxFAIL_MSG( wxT("Wrong GC") );
162 // ----------------------------------------------------------------------------
164 // ----------------------------------------------------------------------------
166 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
168 void wxWindowDC::Init()
170 m_display
= (WXDisplay
*) NULL
;
171 m_penGC
= (WXGC
*) NULL
;
172 m_brushGC
= (WXGC
*) NULL
;
173 m_textGC
= (WXGC
*) NULL
;
174 m_bgGC
= (WXGC
*) NULL
;
175 m_cmap
= (WXColormap
*) NULL
;
177 m_isScreenDC
= false;
178 m_owner
= (wxWindow
*)NULL
;
181 m_context
= wxTheApp
->GetPangoContext();
182 m_fontdesc
= (PangoFontDescription
*)NULL
;
186 wxWindowDC::wxWindowDC( wxWindow
*window
)
188 wxASSERT_MSG( window
, wxT("DC needs a window") );
192 m_font
= window
->GetFont();
194 m_window
= (WXWindow
*) window
->GetMainWindow();
199 // don't report problems
205 m_display
= (WXDisplay
*) wxGlobalDisplay();
208 m_fontdesc
= window
->GetFont().GetNativeFontInfo()->description
;
211 int screen
= DefaultScreen( (Display
*) m_display
);
212 m_cmap
= (WXColormap
) DefaultColormap( (Display
*) m_display
, screen
);
216 /* this must be done after SetUpDC, bacause SetUpDC calls the
217 repective SetBrush, SetPen, SetBackground etc functions
218 to set up the DC. SetBackground call m_owner->SetBackground
219 and this might not be desired as the standard dc background
220 is white whereas a window might assume gray to be the
221 standard (as e.g. wxStatusBar) */
226 wxWindowDC::~wxWindowDC()
231 void wxWindowDC::SetUpDC()
235 wxASSERT_MSG( !m_penGC
, wxT("GCs already created") );
239 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_SCREEN
);
240 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_SCREEN
);
241 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_SCREEN
);
242 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_SCREEN
);
245 if (m_isMemDC
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1))
247 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_MONO
);
248 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_MONO
);
249 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_MONO
);
250 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_MONO
);
254 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_COLOUR
);
255 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_COLOUR
);
256 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_COLOUR
);
257 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_COLOUR
);
260 /* background colour */
261 m_backgroundBrush
= *wxWHITE_BRUSH
;
262 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
263 unsigned long bg_col
= m_backgroundBrush
.GetColour().GetPixel();
265 m_textForegroundColour
= *wxBLACK
;
266 m_textBackgroundColour
= *wxWHITE
;
269 m_textForegroundColour
.CalcPixel( m_cmap
);
270 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
272 m_textBackgroundColour
.CalcPixel( m_cmap
);
273 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
275 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
278 // By default, draw transparently
279 GrSetGCUseBackground((GC
) m_textGC
, FALSE
);
283 m_pen
.GetColour().CalcPixel( m_cmap
);
284 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
285 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
287 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
290 m_brush
.GetColour().CalcPixel( m_cmap
);
291 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
292 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
294 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
297 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
298 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
300 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
303 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
304 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
305 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
308 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
309 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
310 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
311 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
315 int xscreen
= DefaultScreen( (Display
*) m_display
);
316 Window xroot
= RootWindow( (Display
*) m_display
, xscreen
);
318 hatch_bitmap
= hatches
;
319 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, bdiag_bits
, bdiag_width
, bdiag_height
);
320 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cdiag_bits
, cdiag_width
, cdiag_height
);
321 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, fdiag_bits
, fdiag_width
, fdiag_height
);
322 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cross_bits
, cross_width
, cross_height
);
323 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, horiz_bits
, horiz_width
, horiz_height
);
324 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, verti_bits
, verti_width
, verti_height
);
328 void wxWindowDC::DoGetSize( int* width
, int* height
) const
330 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
332 m_owner
->GetSize(width
, height
);
335 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
336 const wxColour
& col
, int style
);
338 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
339 const wxColour
& col
, int style
)
341 return wxDoFloodFill(this, x
, y
, col
, style
);
344 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
346 // Generic (and therefore rather inefficient) method.
347 // Could be improved.
349 wxBitmap
bitmap(1, 1);
350 memdc
.SelectObject(bitmap
);
351 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
352 memdc
.SelectObject(wxNullBitmap
);
353 wxImage
image(bitmap
.ConvertToImage());
354 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
358 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
360 wxCHECK_RET( Ok(), wxT("invalid window dc") );
362 if (m_pen
.GetStyle() != wxTRANSPARENT
)
366 // This hack is for the iPaq: XDrawLine draws
367 // nothing, whereas XDrawLines works...
373 DrawLines( 2, points
, 0, 0 );
375 // XDrawLine( (Display*) m_display, (Window) m_window,
376 // (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
379 CalcBoundingBox(x1
, y1
);
380 CalcBoundingBox(x2
, y2
);
384 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
386 wxCHECK_RET( Ok(), wxT("invalid window dc") );
388 if (m_pen
.GetStyle() != wxTRANSPARENT
)
393 wxCoord xx
= XLOG2DEV(x
);
394 wxCoord yy
= YLOG2DEV(y
);
397 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
398 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
399 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
400 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
405 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
407 wxCHECK_RET( Ok(), wxT("invalid window dc") );
409 wxCoord xx1
= XLOG2DEV(x1
);
410 wxCoord yy1
= YLOG2DEV(y1
);
411 wxCoord xx2
= XLOG2DEV(x2
);
412 wxCoord yy2
= YLOG2DEV(y2
);
413 wxCoord xxc
= XLOG2DEV(xc
);
414 wxCoord yyc
= YLOG2DEV(yc
);
415 double dx
= xx1
- xxc
;
416 double dy
= yy1
- yyc
;
417 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
418 wxCoord r
= (wxCoord
)radius
;
419 double radius1
, radius2
;
421 if (xx1
== xx2
&& yy1
== yy2
)
429 radius1
= radius2
= 0.0;
433 radius1
= (xx1
- xxc
== 0) ?
434 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
435 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
436 radius2
= (xx2
- xxc
== 0) ?
437 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
438 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
440 wxCoord alpha1
= wxCoord(radius1
* 64.0);
441 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
442 while (alpha2
<= 0) alpha2
+= 360*64;
443 while (alpha1
> 360*64) alpha1
-= 360*64;
447 if (m_brush
.GetStyle() != wxTRANSPARENT
)
449 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
451 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
452 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
453 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
455 XFillArc( (Display
*) m_display
, (Window
) m_window
,
456 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
458 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
460 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
462 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
463 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
465 XFillArc( (Display
*) m_display
, (Window
) m_window
,
466 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
468 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
470 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
472 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
473 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
475 XFillArc( (Display
*) m_display
, (Window
) m_window
,
476 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
478 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
480 if (m_brush
.GetStyle() == wxSTIPPLE
)
482 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
483 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
484 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
486 XFillArc( (Display
*) m_display
, (Window
) m_window
,
487 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
489 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
493 XFillArc( (Display
*) m_display
, (Window
) m_window
,
494 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
498 if (m_pen
.GetStyle() != wxTRANSPARENT
)
500 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
501 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
503 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
504 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
506 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
507 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
511 CalcBoundingBox (x1
, y1
);
512 CalcBoundingBox (x2
, y2
);
515 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
517 wxCHECK_RET( Ok(), wxT("invalid window dc") );
519 wxCoord xx
= XLOG2DEV(x
);
520 wxCoord yy
= YLOG2DEV(y
);
521 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
522 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
524 // CMB: handle -ve width and/or height
525 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
526 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
530 wxCoord start
= wxCoord(sa
* 64.0);
531 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
533 if (m_brush
.GetStyle() != wxTRANSPARENT
)
535 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
537 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
538 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
539 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
541 XFillArc( (Display
*) m_display
, (Window
) m_window
,
542 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
544 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
546 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
548 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
549 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
551 XFillArc( (Display
*) m_display
, (Window
) m_window
,
552 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
554 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
556 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
558 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
559 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
561 XFillArc( (Display
*) m_display
, (Window
) m_window
,
562 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
564 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
566 if (m_brush
.GetStyle() == wxSTIPPLE
)
568 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
569 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
570 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
572 XFillArc( (Display
*) m_display
, (Window
) m_window
,
573 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
575 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
579 XFillArc( (Display
*) m_display
, (Window
) m_window
,
580 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
584 if (m_pen
.GetStyle() != wxTRANSPARENT
)
586 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
587 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
591 CalcBoundingBox (x
, y
);
592 CalcBoundingBox (x
+ width
, y
+ height
);
595 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
597 wxCHECK_RET( Ok(), wxT("invalid window dc") );
599 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
)
600 XDrawPoint( (Display
*) m_display
, (Window
) m_window
,
601 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
603 CalcBoundingBox (x
, y
);
606 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
608 wxCHECK_RET( Ok(), wxT("invalid window dc") );
610 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
613 XPoint
*xpoints
= new XPoint
[n
];
614 for (int i
= 0; i
< n
; i
++)
616 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
617 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
619 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
621 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
, 0 );
626 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
627 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
629 wxCHECK_RET( Ok(), wxT("invalid window dc") );
633 XPoint
*xpoints
= new XPoint
[n
+ 1];
635 for (i
= 0; i
< n
; i
++)
637 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
638 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
640 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
645 if (m_brush
.GetStyle() != wxTRANSPARENT
)
648 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
650 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
651 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
652 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
654 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
655 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
657 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
659 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
661 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
662 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
664 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
665 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
667 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
669 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
671 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
672 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
674 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
675 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
677 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
679 if (m_brush
.GetStyle() == wxSTIPPLE
)
681 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
682 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
683 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
685 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
686 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
688 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
692 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
693 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
697 if (m_pen
.GetStyle () != wxTRANSPARENT
)
699 // Close figure for XDrawLines
700 xpoints
[i
].x
= xpoints
[0].x
;
701 xpoints
[i
].y
= xpoints
[0].y
;
703 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
710 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
712 wxCHECK_RET( Ok(), wxT("invalid window dc") );
714 wxCoord xx
= XLOG2DEV(x
);
715 wxCoord yy
= YLOG2DEV(y
);
716 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
717 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
719 // CMB: draw nothing if transformed w or h is 0
720 if (ww
== 0 || hh
== 0) return;
722 // CMB: handle -ve width and/or height
723 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
724 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
728 if (m_brush
.GetStyle() != wxTRANSPARENT
)
730 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
732 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
733 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
734 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
736 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
737 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
739 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
741 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
743 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
744 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
746 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
747 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
749 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
751 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
753 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
754 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
756 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
757 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
759 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
761 if (m_brush
.GetStyle() == wxSTIPPLE
)
763 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
764 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
765 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
767 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
768 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
770 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
774 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
775 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
779 if (m_pen
.GetStyle () != wxTRANSPARENT
)
781 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
782 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
786 CalcBoundingBox( x
, y
);
787 CalcBoundingBox( x
+ width
, y
+ height
);
790 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
792 wxCHECK_RET( Ok(), wxT("invalid window dc") );
794 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
796 wxCoord xx
= XLOG2DEV(x
);
797 wxCoord yy
= YLOG2DEV(y
);
798 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
799 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
800 wxCoord rr
= XLOG2DEVREL((wxCoord
)radius
);
802 // CMB: handle -ve width and/or height
803 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
804 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
806 // CMB: if radius is zero use DrawRectangle() instead to avoid
807 // X drawing errors with small radii
810 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
811 (GC
) m_penGC
, x
, y
, width
, height
);
815 // CMB: draw nothing if transformed w or h is 0
816 if (ww
== 0 || hh
== 0) return;
818 // CMB: adjust size if outline is drawn otherwise the result is
819 // 1 pixel too wide and high
820 if (m_pen
.GetStyle() != wxTRANSPARENT
)
828 // CMB: ensure dd is not larger than rectangle otherwise we
829 // get an hour glass shape
831 if (dd
> ww
) dd
= ww
;
832 if (dd
> hh
) dd
= hh
;
835 if (m_brush
.GetStyle() != wxTRANSPARENT
)
837 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
839 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
840 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
841 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
842 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
843 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
844 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
845 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
846 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
847 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
848 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0);
850 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
852 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
853 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
854 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
855 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
856 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
857 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
858 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
859 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
861 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
863 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
864 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
865 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
866 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
867 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
868 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
869 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
870 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
872 if (m_brush
.GetStyle() == wxSTIPPLE
)
874 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
875 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
876 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
877 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
878 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
879 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
880 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
881 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
882 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
883 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
887 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
888 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
889 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
890 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
891 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
892 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
895 if (m_pen
.GetStyle() != wxTRANSPARENT
)
897 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy
);
898 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
899 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr
);
900 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr
);
901 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
902 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
903 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
904 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
908 // this ignores the radius
909 CalcBoundingBox( x
, y
);
910 CalcBoundingBox( x
+ width
, y
+ height
);
913 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
915 wxCHECK_RET( Ok(), wxT("invalid window dc") );
917 wxCoord xx
= XLOG2DEV(x
);
918 wxCoord yy
= YLOG2DEV(y
);
919 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
920 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
922 // CMB: handle -ve width and/or height
923 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
924 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
928 if (m_brush
.GetStyle() != wxTRANSPARENT
)
930 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
932 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
933 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
934 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
936 XFillArc( (Display
*) m_display
, (Window
) m_window
,
937 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
939 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
941 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
943 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
944 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
946 XFillArc( (Display
*) m_display
, (Window
) m_window
,
947 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
949 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
951 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
953 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
954 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
956 XFillArc( (Display
*) m_display
, (Window
) m_window
,
957 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
959 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
961 if (m_brush
.GetStyle() == wxSTIPPLE
)
963 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
964 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
965 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
967 XFillArc( (Display
*) m_display
, (Window
) m_window
,
968 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
970 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
974 XFillArc( (Display
*) m_display
, (Window
) m_window
,
975 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
979 if (m_pen
.GetStyle () != wxTRANSPARENT
)
981 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
982 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
986 CalcBoundingBox( x
, y
);
987 CalcBoundingBox( x
+ width
, y
+ height
);
990 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
992 DoDrawBitmap(icon
, x
, y
, true);
996 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
997 wxCoord x
, wxCoord y
,
1000 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1002 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1004 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1006 /* scale/translate size and position */
1007 int xx
= XLOG2DEV(x
);
1008 int yy
= YLOG2DEV(y
);
1010 int w
= bitmap
.GetWidth();
1011 int h
= bitmap
.GetHeight();
1013 CalcBoundingBox( x
, y
);
1014 CalcBoundingBox( x
+ w
, y
+ h
);
1016 if (!m_window
) return;
1018 int ww
= XLOG2DEVREL(w
);
1019 int hh
= YLOG2DEVREL(h
);
1021 /* compare to current clipping region */
1022 if (!m_currentClippingRegion
.IsNull())
1024 wxRegion
tmp( xx
,yy
,ww
,hh
);
1025 tmp
.Intersect( m_currentClippingRegion
);
1030 /* scale bitmap if required */
1031 wxBitmap use_bitmap
;
1032 if ((w
!= ww
) || (h
!= hh
))
1034 wxImage
image( bitmap
.ConvertToImage() );
1035 image
.Rescale( ww
, hh
);
1038 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1045 use_bitmap
= bitmap
;
1048 /* apply mask if any */
1049 WXPixmap mask
= NULL
;
1050 if (use_bitmap
.GetMask())
1051 mask
= use_bitmap
.GetMask()->GetBitmap();
1053 if (useMask
&& mask
)
1055 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
1056 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
1057 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
1059 GrSetGCUseBackground(gc
, FALSE
);
1060 GrSetGCMode(gc
, GR_MODE_COPY
);
1062 // This code assumes that background and foreground
1063 // colours are used in ROPs, like in MSW.
1064 // Not sure if this is true.
1066 // Copy destination to buffer.
1067 // In DoBlit, we need this step because Blit has
1068 // a ROP argument. Here, we don't need it.
1069 // In DoBlit, we may be able to eliminate this step
1070 // if we check if the rop = copy
1072 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_window
,
1073 0, 0, GR_MODE_COPY
);
1076 // Copy src to buffer using selected raster op (none selected
1077 // in DrawBitmap, so just use Gxcopy)
1078 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
1079 0, 0, GR_MODE_COPY
);
1081 // Set masked area in buffer to BLACK (pixel value 0)
1082 GrSetGCBackground(gc
, WHITE
);
1083 GrSetGCForeground(gc
, BLACK
);
1084 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
1087 // set unmasked area in dest to BLACK
1088 GrSetGCBackground(gc
, BLACK
);
1089 GrSetGCForeground(gc
, WHITE
);
1090 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
1093 // OR buffer to dest
1094 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
1098 GrDestroyWindow(bufPixmap
);
1101 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1102 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1104 /* remove mask again if any */
1105 if (useMask
&& mask
)
1107 if (!m_currentClippingRegion
.IsNull())
1108 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1115 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1116 wxCoord x
, wxCoord y
,
1119 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1121 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1123 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1125 // scale/translate size and position
1126 int xx
= XLOG2DEV(x
);
1127 int yy
= YLOG2DEV(y
);
1129 int w
= bitmap
.GetWidth();
1130 int h
= bitmap
.GetHeight();
1132 CalcBoundingBox( x
, y
);
1133 CalcBoundingBox( x
+ w
, y
+ h
);
1135 if (!m_window
) return;
1137 int ww
= XLOG2DEVREL(w
);
1138 int hh
= YLOG2DEVREL(h
);
1140 // compare to current clipping region
1141 if (!m_currentClippingRegion
.IsNull())
1143 wxRegion
tmp( xx
,yy
,ww
,hh
);
1144 tmp
.Intersect( m_currentClippingRegion
);
1149 // scale bitmap if required
1150 wxBitmap use_bitmap
;
1151 if ((w
!= ww
) || (h
!= hh
))
1153 wxImage
image( bitmap
.ConvertToImage() );
1154 image
.Rescale( ww
, hh
);
1157 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1164 use_bitmap
= bitmap
;
1167 // apply mask if any
1168 WXPixmap mask
= NULL
;
1169 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1171 bool setClipMask
= false;
1173 if (!m_currentClippingRegion
.IsNull() || (useMask
&& mask
))
1175 // XSetClipMask() call is necessary (because of clip region and/or transparent mask)
1177 Pixmap new_pixmap
= 0;
1179 if (!m_currentClippingRegion
.IsNull())
1181 // clipping necessary => create new_pixmap
1182 Display
*xdisplay
= (Display
*) m_display
;
1183 int xscreen
= DefaultScreen( xdisplay
);
1184 Window xroot
= RootWindow( xdisplay
, xscreen
);
1186 new_pixmap
= XCreatePixmap( xdisplay
, xroot
, ww
, hh
, 1 );
1187 GC gc
= XCreateGC( xdisplay
, new_pixmap
, 0, NULL
);
1189 XSetForeground( xdisplay
, gc
, BlackPixel(xdisplay
,xscreen
) );
1191 XSetFillStyle( xdisplay
, gc
, FillSolid
);
1192 XFillRectangle( xdisplay
, new_pixmap
, gc
, 0, 0, ww
, hh
);
1194 XSetForeground( xdisplay
, gc
, WhitePixel(xdisplay
,xscreen
) );
1196 if (useMask
&& mask
)
1198 // transparent mask => call XSetStipple
1199 XSetFillStyle( xdisplay
, gc
, FillStippled
);
1200 XSetTSOrigin( xdisplay
, gc
, 0, 0);
1201 XSetStipple( xdisplay
, gc
, (Pixmap
) mask
);
1204 wxCoord clip_x
, clip_y
, clip_w
, clip_h
;
1205 m_currentClippingRegion
.GetBox(clip_x
, clip_y
, clip_w
, clip_h
);
1206 XFillRectangle( xdisplay
, new_pixmap
, gc
, clip_x
-xx
, clip_y
-yy
, clip_w
, clip_h
);
1208 XFreeGC( xdisplay
, gc
);
1214 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, new_pixmap
);
1216 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1217 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1222 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, new_pixmap
);
1224 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1225 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1229 XFreePixmap( (Display
*) m_display
, new_pixmap
);
1232 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1233 // drawing a mono-bitmap (XBitmap) we use the current text GC
1235 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1236 (GC
) m_textGC
, 0, 0, ww
, hh
, xx
, yy
, 1 );
1238 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1239 (GC
) m_penGC
, 0, 0, ww
, hh
, xx
, yy
);
1241 // remove mask again if any
1246 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1247 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1248 if (!m_currentClippingRegion
.IsNull())
1249 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1253 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1254 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1255 if (!m_currentClippingRegion
.IsNull())
1256 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1261 // wxUSE_NANOX/!wxUSE_NANOX
1263 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1264 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1265 wxCoord xsrcMask
, wxCoord ysrcMask
)
1267 /* this is the nth try to get this utterly useless function to
1268 work. it now completely ignores the scaling or translation
1269 of the source dc, but scales correctly on the target dc and
1270 knows about possible mask information in a memory dc. */
1272 wxCHECK_MSG( Ok(), false, wxT("invalid window dc") );
1274 wxCHECK_MSG( source
, false, wxT("invalid source dc") );
1276 if (!m_window
) return false;
1278 // transform the source DC coords to the device ones
1279 xsrc
= source
->LogicalToDeviceX(xsrc
);
1280 ysrc
= source
->LogicalToDeviceY(ysrc
);
1282 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1283 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1285 bool use_bitmap_method
= false;
1286 bool is_mono
= false;
1288 // TODO: use the mask origin when drawing transparently
1289 if (xsrcMask
== -1 && ysrcMask
== -1)
1295 if (srcDC
->m_isMemDC
)
1297 if (!memDC
->m_selected
.Ok()) return false;
1299 /* we use the "XCopyArea" way to copy a memory dc into
1300 y different window if the memory dc BOTH
1301 a) doesn't have any mask or its mask isn't used
1305 if (useMask
&& (memDC
->m_selected
.GetMask()))
1307 /* we HAVE TO use the direct way for memory dcs
1308 that have mask since the XCopyArea doesn't know
1310 use_bitmap_method
= true;
1312 else if (memDC
->m_selected
.GetDepth() == 1)
1314 /* we HAVE TO use the direct way for memory dcs
1315 that are bitmaps because XCopyArea doesn't cope
1316 with different bit depths */
1318 use_bitmap_method
= true;
1320 else if ((xsrc
== 0) && (ysrc
== 0) &&
1321 (width
== memDC
->m_selected
.GetWidth()) &&
1322 (height
== memDC
->m_selected
.GetHeight()))
1324 /* we SHOULD use the direct way if all of the bitmap
1325 in the memory dc is copied in which case XCopyArea
1326 wouldn't be able able to boost performace by reducing
1327 the area to be scaled */
1328 use_bitmap_method
= true;
1332 use_bitmap_method
= false;
1336 CalcBoundingBox( xdest
, ydest
);
1337 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1339 // scale/translate size and position
1340 wxCoord xx
= XLOG2DEV(xdest
);
1341 wxCoord yy
= YLOG2DEV(ydest
);
1343 wxCoord ww
= XLOG2DEVREL(width
);
1344 wxCoord hh
= YLOG2DEVREL(height
);
1346 // compare to current clipping region
1347 if (!m_currentClippingRegion
.IsNull())
1349 wxRegion
tmp( xx
,yy
,ww
,hh
);
1350 tmp
.Intersect( m_currentClippingRegion
);
1355 int old_logical_func
= m_logicalFunction
;
1356 SetLogicalFunction( logical_func
);
1358 if (use_bitmap_method
)
1360 // scale/translate bitmap size
1361 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1362 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1364 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1365 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1367 // scale bitmap if required
1368 wxBitmap use_bitmap
;
1370 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1372 wxImage
image( memDC
->m_selected
.ConvertToImage() );
1373 image
= image
.Scale( bm_ww
, bm_hh
);
1377 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1384 use_bitmap
= memDC
->m_selected
;
1387 // apply mask if any
1388 WXPixmap mask
= NULL
;
1389 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1391 if (useMask
&& mask
)
1393 WXPixmap new_mask
= NULL
;
1395 if (!m_currentClippingRegion
.IsNull())
1398 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1399 GdkGC
*gc
= gdk_gc_new( new_mask
);
1401 gdk_gc_set_foreground( gc
, &col
);
1402 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1404 gdk_gc_set_background( gc
, &col
);
1406 gdk_gc_set_foreground( gc
, &col
);
1407 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1408 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1409 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1410 gdk_gc_set_stipple( gc
, mask
);
1411 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1418 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1420 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1421 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1426 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1428 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1429 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1433 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1436 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1437 // drawing a mono-bitmap (XBitmap) we use the current text GC
1440 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1441 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1443 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1444 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1446 // remove mask again if any
1447 if (useMask
&& mask
)
1451 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1452 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1453 if (!m_currentClippingRegion
.IsNull())
1454 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1458 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1459 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1460 if (!m_currentClippingRegion
.IsNull())
1461 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1465 else // use_bitmap_method
1467 if ((width
!= ww
) || (height
!= hh
))
1469 /* Draw source window into a bitmap as we cannot scale
1470 a window in contrast to a bitmap. this would actually
1471 work with memory dcs as well, but we'd lose the mask
1472 information and waste one step in this process since
1473 a memory already has a bitmap. all this is slightly
1474 inefficient as we could take an XImage directly from
1475 an X window, but we'd then also have to care that
1476 the window is not outside the screen (in which case
1477 we'd get a BadMatch or what not).
1478 Is a double XGetImage and combined XGetPixel and
1479 XPutPixel really faster? I'm not sure. look at wxXt
1480 for a different implementation of the same problem. */
1482 wxBitmap
bitmap( width
, height
);
1484 // copy including child window contents
1485 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1486 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) bitmap
.GetPixmap(),
1487 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1488 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1491 wxImage
image( bitmap
.ConvertToImage() );
1492 image
= image
.Scale( ww
, hh
);
1494 // convert to bitmap
1497 // draw scaled bitmap
1498 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_window
,
1499 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1503 // No scaling and not a memory dc with a mask either
1505 // copy including child window contents
1506 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1507 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) m_window
,
1508 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1509 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1513 SetLogicalFunction( old_logical_func
);
1518 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1520 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1522 if (!m_window
) return;
1528 PangoLayout
*layout
= pango_layout_new(m_context
);
1529 pango_layout_set_font_description(layout
, m_fontdesc
);
1531 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1532 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1536 pango_layout_get_pixel_size(layout
, &w
, &h
);
1541 x11_draw_layout( (Drawable
) m_window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1543 g_object_unref( G_OBJECT( layout
) );
1545 CalcBoundingBox (x
+ width
, y
+ height
);
1546 CalcBoundingBox (x
, y
);
1548 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1550 wxCHECK_RET( xfont
, wxT("invalid font") );
1552 // First draw a rectangle representing the text background, if a text
1553 // background is specified
1554 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1556 // Since X draws from the baseline of the text, must add the text height
1561 int direction
, descent
;
1563 slen
= strlen(text
);
1564 XCharStruct overall_return
;
1566 (void)XTextExtents(xfont
, (const char*) text
.c_str(), slen
, &direction
,
1567 &ascent
, &descent
, &overall_return
);
1569 cx
= overall_return
.width
;
1570 cy
= ascent
+ descent
;
1571 m_textBackgroundColour
.CalcPixel(m_cmap
);
1572 m_textForegroundColour
.CalcPixel(m_cmap
);
1573 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1574 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
1575 (GC
) m_textGC
, x
, y
, cx
, cy
);
1576 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1580 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1582 // This may be a test for whether the font is 16-bit, but it also
1583 // seems to fail for valid 8-bit fonts too.
1584 if (1) // (xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
1587 XDrawString( (Display
*) m_display
, (Window
) m_window
,
1588 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.length() );
1592 if (m_font
.GetUnderlined())
1594 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1595 if (font
->descent
> 0) ul_y
++;
1596 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1599 width
= wxCoord(width
/ m_scaleX
);
1600 height
= wxCoord(height
/ m_scaleY
);
1602 CalcBoundingBox (x
+ width
, y
+ height
);
1603 CalcBoundingBox (x
, y
);
1608 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
, double angle
)
1613 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1614 wxCoord
*descent
, wxCoord
*externalLeading
,
1615 const wxFont
*font
) const
1617 wxCHECK_RET( Ok(), wxT("invalid dc") );
1621 if (width
) (*width
) = 0;
1622 if (height
) (*height
) = 0;
1627 PangoLayout
*layout
= pango_layout_new( m_context
);
1630 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1632 pango_layout_set_font_description(layout
, m_fontdesc
);
1634 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1635 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1639 pango_layout_get_pixel_size(layout
, &w
, &h
);
1641 if (width
) (*width
) = (wxCoord
) w
;
1642 if (height
) (*height
) = (wxCoord
) h
;
1645 // Do something about metrics here. TODO.
1648 if (externalLeading
) (*externalLeading
) = 0; // ??
1650 g_object_unref( G_OBJECT( layout
) );
1652 wxFont fontToUse
= m_font
;
1653 if (font
) fontToUse
= *font
;
1655 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
1657 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1659 wxCHECK_RET( xfont
, wxT("invalid font") );
1661 int direction
, ascent
, descent2
;
1662 XCharStruct overall
;
1664 XTextExtents( xfont
, (const char*) string
.c_str(), string
.length(), &direction
,
1665 &ascent
, &descent2
, &overall
);
1668 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1670 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1672 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1673 if (externalLeading
)
1674 *externalLeading
= 0; // ??
1678 wxCoord
wxWindowDC::GetCharWidth() const
1680 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1683 PangoLayout
*layout
= pango_layout_new( m_context
);
1686 pango_layout_set_font_description(layout
, m_fontdesc
);
1688 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1690 pango_layout_set_text(layout
, "H", 1 );
1692 pango_layout_get_pixel_size(layout
, &w
, &h
);
1693 g_object_unref( G_OBJECT( layout
) );
1697 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1699 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1701 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1703 int direction
, ascent
, descent
;
1704 XCharStruct overall
;
1706 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1708 return (wxCoord
)(overall
.width
/ m_scaleX
);
1712 wxCoord
wxWindowDC::GetCharHeight() const
1714 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1717 PangoLayout
*layout
= pango_layout_new( m_context
);
1720 pango_layout_set_font_description(layout
, m_fontdesc
);
1722 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1724 pango_layout_set_text(layout
, "H", 1 );
1726 pango_layout_get_pixel_size(layout
, &w
, &h
);
1727 g_object_unref( G_OBJECT( layout
) );
1731 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1733 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1735 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1737 int direction
, ascent
, descent
;
1738 XCharStruct overall
;
1740 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1742 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1746 void wxWindowDC::Clear()
1748 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1750 if (!m_window
) return;
1752 /* - we either are a memory dc or have a window as the
1753 owner. anything else shouldn't happen.
1754 - we don't use gdk_window_clear() as we don't set
1755 the window's background colour anymore. it is too
1756 much pain to keep the DC's and the window's back-
1757 ground colour in synch. */
1762 m_owner
->GetSize( &width
, &height
);
1763 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1770 GetSize( &width
, &height
);
1771 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1776 void wxWindowDC::SetFont( const wxFont
&font
)
1778 wxCHECK_RET( Ok(), wxT("invalid dc") );
1783 m_fontdesc
= font
.GetNativeFontInfo()->description
;
1787 void wxWindowDC::SetPen( const wxPen
&pen
)
1789 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1791 if (m_pen
== pen
) return;
1795 if (!m_pen
.Ok()) return;
1797 if (!m_window
) return;
1799 int width
= m_pen
.GetWidth();
1802 // CMB: if width is non-zero scale it with the dc
1807 // X doesn't allow different width in x and y and so we take
1810 ( fabs((double) XLOG2DEVREL(width
)) +
1811 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1815 static const wxX11Dash dotted
[] = {1, 1};
1816 static const wxX11Dash short_dashed
[] = {2, 2};
1817 static const wxX11Dash long_dashed
[] = {2, 4};
1818 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1820 // We express dash pattern in pen width unit, so we are
1821 // independent of zoom factor and so on...
1823 const wxX11Dash
*req_dash
;
1825 int lineStyle
= LineSolid
;
1826 switch (m_pen
.GetStyle())
1830 lineStyle
= LineOnOffDash
;
1831 req_nb_dash
= m_pen
.GetDashCount();
1832 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1837 lineStyle
= LineOnOffDash
;
1844 lineStyle
= LineOnOffDash
;
1846 req_dash
= long_dashed
;
1851 lineStyle
= LineOnOffDash
;
1853 req_dash
= short_dashed
;
1858 // lineStyle = LineDoubleDash;
1859 lineStyle
= LineOnOffDash
;
1861 req_dash
= dotted_dashed
;
1866 case wxSTIPPLE_MASK_OPAQUE
:
1871 lineStyle
= LineSolid
;
1872 req_dash
= (wxX11Dash
*)NULL
;
1878 int capStyle
= CapRound
;
1879 switch (m_pen
.GetCap())
1881 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1882 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1889 capStyle
= CapNotLast
;
1893 capStyle
= CapRound
;
1899 int joinStyle
= JoinRound
;
1900 switch (m_pen
.GetJoin())
1902 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1903 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1905 default: { joinStyle
= JoinRound
; break; }
1908 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1910 m_pen
.GetColour().CalcPixel( m_cmap
);
1911 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1914 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1916 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1918 if (m_brush
== brush
) return;
1922 if (!m_brush
.Ok()) return;
1924 if (!m_window
) return;
1926 m_brush
.GetColour().CalcPixel( m_cmap
);
1927 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1929 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1931 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1933 if (m_brush
.GetStipple()->GetPixmap())
1935 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1936 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1940 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1941 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1945 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1947 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1948 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1951 if (m_brush
.IsHatch())
1953 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1954 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1955 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1959 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1961 /* CMB 21/7/98: Added SetBackground. Sets background brush
1962 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1964 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1966 if (m_backgroundBrush
== brush
) return;
1968 m_backgroundBrush
= brush
;
1970 if (!m_backgroundBrush
.Ok()) return;
1972 if (!m_window
) return;
1974 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1975 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1976 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1977 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1978 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1980 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1982 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1984 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1986 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1987 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1991 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1992 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
1996 if (m_backgroundBrush
.IsHatch())
1998 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1999 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
2000 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
2004 void wxWindowDC::SetLogicalFunction( int function
)
2006 wxCHECK_RET( Ok(), wxT("invalid dc") );
2010 if (m_logicalFunction
== function
)
2013 // VZ: shouldn't this be a CHECK?
2020 x_function
= GXclear
;
2026 x_function
= GXinvert
;
2029 x_function
= GXorReverse
;
2032 x_function
= GXandReverse
;
2041 x_function
= GXandInverted
;
2044 x_function
= GXnoop
;
2050 x_function
= GXequiv
;
2053 x_function
= GXcopyInverted
;
2056 x_function
= GXorInverted
;
2059 x_function
= GXnand
;
2066 x_function
= GXcopy
;
2070 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2071 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2073 // to stay compatible with wxMSW, we don't apply ROPs to the text
2074 // operations (i.e. DrawText/DrawRotatedText).
2075 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2076 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2078 m_logicalFunction
= function
;
2081 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2083 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2085 // don't set m_textForegroundColour to an invalid colour as we'd crash
2086 // later then (we use m_textForegroundColour.GetColor() without checking
2088 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
2091 m_textForegroundColour
= col
;
2095 m_textForegroundColour
.CalcPixel( m_cmap
);
2096 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2100 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2102 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2105 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
2108 m_textBackgroundColour
= col
;
2112 m_textBackgroundColour
.CalcPixel( m_cmap
);
2113 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2117 void wxWindowDC::SetBackgroundMode( int mode
)
2119 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2121 m_backgroundMode
= mode
;
2124 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2127 if (!m_window
) return;
2129 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2130 // transparent/solid background mode
2132 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2134 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2135 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2139 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2145 /* Use GetXColormap */
2146 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2147 (Colormap
) palette
.GetXColormap());
2149 /* Use wxGetMainColormap */
2150 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2151 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2156 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2158 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2160 if (!m_window
) return;
2169 rect
.x
= XLOG2DEV(x
);
2170 rect
.y
= YLOG2DEV(y
);
2171 rect
.width
= XLOG2DEVREL(width
);
2172 rect
.height
= YLOG2DEVREL(height
);
2174 if (!m_currentClippingRegion
.IsNull())
2175 m_currentClippingRegion
.Intersect( rect
);
2177 m_currentClippingRegion
.Union( rect
);
2179 #if USE_PAINT_REGION
2180 if (!m_paintClippingRegion
.IsNull())
2181 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2184 wxCoord xx
, yy
, ww
, hh
;
2185 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2186 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2188 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2189 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2190 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2191 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2194 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2196 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2200 DestroyClippingRegion();
2204 if (!m_window
) return;
2206 if (!m_currentClippingRegion
.IsNull())
2207 m_currentClippingRegion
.Intersect( region
);
2209 m_currentClippingRegion
.Union( region
);
2211 #if USE_PAINT_REGION
2212 if (!m_paintClippingRegion
.IsNull())
2213 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2216 wxCoord xx
, yy
, ww
, hh
;
2217 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2218 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2220 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2221 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2222 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2223 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2226 void wxWindowDC::DestroyClippingRegion()
2228 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2230 wxDC::DestroyClippingRegion();
2232 m_currentClippingRegion
.Clear();
2234 #if USE_PAINT_REGION
2235 if (!m_paintClippingRegion
.IsEmpty())
2236 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2239 if (!m_window
) return;
2241 if (m_currentClippingRegion
.IsEmpty())
2243 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2244 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2245 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2246 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2250 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2251 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2252 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2253 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2257 void wxWindowDC::Destroy()
2259 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2261 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2263 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2265 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2269 void wxWindowDC::ComputeScaleAndOrigin()
2271 /* CMB: copy scale to see if it changes */
2272 double origScaleX
= m_scaleX
;
2273 double origScaleY
= m_scaleY
;
2275 wxDC::ComputeScaleAndOrigin();
2277 /* CMB: if scale has changed call SetPen to recalulate the line width */
2278 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2281 /* this is a bit artificial, but we need to force wxDC to think
2282 the pen has changed */
2289 wxSize
wxWindowDC::GetPPI() const
2291 return wxSize(100, 100);
2294 int wxWindowDC::GetDepth() const
2296 wxFAIL_MSG(wxT("not implemented"));
2301 //-----------------------------------------------------------------------------
2303 //-----------------------------------------------------------------------------
2305 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2307 wxClientDC::wxClientDC( wxWindow
*window
)
2308 : wxWindowDC( window
)
2310 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2312 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2314 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2315 if (m_window
== (WXWindow
*) window
->GetMainWindow())
2317 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2318 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2319 wxSize size
= window
->GetClientSize();
2320 SetClippingRegion(wxPoint(0, 0), size
);
2324 void wxClientDC::DoGetSize(int *width
, int *height
) const
2326 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2328 m_owner
->GetClientSize( width
, height
);
2331 // ----------------------------------------------------------------------------
2333 // ----------------------------------------------------------------------------
2335 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2337 wxPaintDC::wxPaintDC(wxWindow
* window
)
2338 : wxClientDC(window
)
2340 #if USE_PAINT_REGION
2341 if (!window
->GetClipPaintRegion())
2344 m_paintClippingRegion
= window
->GetUpdateRegion();
2345 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2348 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2350 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2351 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2352 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2353 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2355 #endif // USE_PAINT_REGION
2358 // ----------------------------------------------------------------------------
2360 // ----------------------------------------------------------------------------
2362 class wxDCModule
: public wxModule
2365 // we must be cleaned up before wxDisplayModule which closes the global
2369 AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule")));
2372 bool OnInit() { wxInitGCPool(); return true; }
2373 void OnExit() { wxCleanUpGCPool(); }
2376 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2379 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)