1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "dcclient.h"
16 #include "wx/dcclient.h"
17 #include "wx/dcmemory.h"
18 #include "wx/window.h"
21 #include "wx/module.h"
22 #include "wx/fontutil.h"
24 #include "wx/x11/private.h"
30 #include "pango/pangox.h"
32 #include "pango/pangoxft.h"
35 #include "pango_x.cpp"
38 //-----------------------------------------------------------------------------
40 //-----------------------------------------------------------------------------
42 #define USE_PAINT_REGION 1
44 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
56 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH)
57 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH)
59 static Pixmap hatches
[num_hatches
];
60 static Pixmap
*hatch_bitmap
= (Pixmap
*) NULL
;
62 //-----------------------------------------------------------------------------
64 //-----------------------------------------------------------------------------
66 const double RAD2DEG
= 180.0 / M_PI
;
68 // ----------------------------------------------------------------------------
70 // ----------------------------------------------------------------------------
72 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
73 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
75 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
77 //-----------------------------------------------------------------------------
78 // Implement Pool of Graphic contexts. Creating them takes too much time.
79 //-----------------------------------------------------------------------------
81 #define GC_POOL_SIZE 200
107 static wxGC wxGCPool
[GC_POOL_SIZE
];
109 static void wxInitGCPool()
111 memset( wxGCPool
, 0, GC_POOL_SIZE
*sizeof(wxGC
) );
114 static void wxCleanUpGCPool()
116 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
118 if (wxGCPool
[i
].m_gc
)
119 XFreeGC( wxGlobalDisplay(), wxGCPool
[i
].m_gc
);
123 static GC
wxGetPoolGC( Window window
, wxPoolGCType type
)
125 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
127 if (!wxGCPool
[i
].m_gc
)
129 wxGCPool
[i
].m_gc
= XCreateGC( wxGlobalDisplay(), window
, 0, NULL
);
130 XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool
[i
].m_gc
, FALSE
);
131 wxGCPool
[i
].m_type
= type
;
132 wxGCPool
[i
].m_used
= false;
134 if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type
== type
))
136 wxGCPool
[i
].m_used
= true;
137 return wxGCPool
[i
].m_gc
;
141 wxFAIL_MSG( wxT("No GC available") );
146 static void wxFreePoolGC( GC gc
)
148 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
150 if (wxGCPool
[i
].m_gc
== gc
)
152 wxGCPool
[i
].m_used
= false;
157 wxFAIL_MSG( wxT("Wrong GC") );
160 // ----------------------------------------------------------------------------
162 // ----------------------------------------------------------------------------
164 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
166 wxWindowDC::wxWindowDC()
168 m_display
= (WXDisplay
*) NULL
;
169 m_penGC
= (WXGC
*) NULL
;
170 m_brushGC
= (WXGC
*) NULL
;
171 m_textGC
= (WXGC
*) NULL
;
172 m_bgGC
= (WXGC
*) NULL
;
173 m_cmap
= (WXColormap
*) NULL
;
175 m_isScreenDC
= false;
176 m_owner
= (wxWindow
*)NULL
;
179 m_context
= (PangoContext
*)NULL
;
180 m_fontdesc
= (PangoFontDescription
*)NULL
;
184 wxWindowDC::wxWindowDC( wxWindow
*window
)
186 wxASSERT_MSG( window
, wxT("DC needs a window") );
188 m_display
= (WXDisplay
*) NULL
;
189 m_penGC
= (WXGC
*) NULL
;
190 m_brushGC
= (WXGC
*) NULL
;
191 m_textGC
= (WXGC
*) NULL
;
192 m_bgGC
= (WXGC
*) NULL
;
193 m_cmap
= (WXColormap
*) NULL
;
194 m_owner
= (wxWindow
*)NULL
;
196 m_isScreenDC
= false;
197 m_font
= window
->GetFont();
199 m_window
= (WXWindow
*) window
->GetMainWindow();
204 // don't report problems
210 m_display
= (WXDisplay
*) wxGlobalDisplay();
213 m_context
= wxTheApp
->GetPangoContext();
214 m_fontdesc
= window
->GetFont().GetNativeFontInfo()->description
;
217 int screen
= DefaultScreen( (Display
*) m_display
);
218 m_cmap
= (WXColormap
) DefaultColormap( (Display
*) m_display
, screen
);
222 /* this must be done after SetUpDC, bacause SetUpDC calls the
223 repective SetBrush, SetPen, SetBackground etc functions
224 to set up the DC. SetBackground call m_owner->SetBackground
225 and this might not be desired as the standard dc background
226 is white whereas a window might assume gray to be the
227 standard (as e.g. wxStatusBar) */
232 wxWindowDC::~wxWindowDC()
237 void wxWindowDC::SetUpDC()
241 wxASSERT_MSG( !m_penGC
, wxT("GCs already created") );
245 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_SCREEN
);
246 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_SCREEN
);
247 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_SCREEN
);
248 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_SCREEN
);
251 if (m_isMemDC
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1))
253 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_MONO
);
254 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_MONO
);
255 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_MONO
);
256 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_MONO
);
260 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_COLOUR
);
261 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_COLOUR
);
262 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_COLOUR
);
263 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_COLOUR
);
266 /* background colour */
267 m_backgroundBrush
= *wxWHITE_BRUSH
;
268 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
269 unsigned long bg_col
= m_backgroundBrush
.GetColour().GetPixel();
271 m_textForegroundColour
= *wxBLACK
;
272 m_textBackgroundColour
= *wxWHITE
;
275 m_textForegroundColour
.CalcPixel( m_cmap
);
276 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
278 m_textBackgroundColour
.CalcPixel( m_cmap
);
279 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
281 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
284 // By default, draw transparently
285 GrSetGCUseBackground((GC
) m_textGC
, FALSE
);
289 m_pen
.GetColour().CalcPixel( m_cmap
);
290 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
291 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
293 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
296 m_brush
.GetColour().CalcPixel( m_cmap
);
297 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
298 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
300 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
303 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
304 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
306 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
309 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
310 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
311 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
314 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
315 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
316 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
317 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
321 int xscreen
= DefaultScreen( (Display
*) m_display
);
322 Window xroot
= RootWindow( (Display
*) m_display
, xscreen
);
324 hatch_bitmap
= hatches
;
325 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, bdiag_bits
, bdiag_width
, bdiag_height
);
326 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cdiag_bits
, cdiag_width
, cdiag_height
);
327 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, fdiag_bits
, fdiag_width
, fdiag_height
);
328 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cross_bits
, cross_width
, cross_height
);
329 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, horiz_bits
, horiz_width
, horiz_height
);
330 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, verti_bits
, verti_width
, verti_height
);
334 void wxWindowDC::DoGetSize( int* width
, int* height
) const
336 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
338 m_owner
->GetSize(width
, height
);
341 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
342 const wxColour
& col
, int style
);
344 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
345 const wxColour
& col
, int style
)
347 return wxDoFloodFill(this, x
, y
, col
, style
);
350 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
352 // Generic (and therefore rather inefficient) method.
353 // Could be improved.
355 wxBitmap
bitmap(1, 1);
356 memdc
.SelectObject(bitmap
);
357 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
358 memdc
.SelectObject(wxNullBitmap
);
359 wxImage
image(bitmap
.ConvertToImage());
360 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
364 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
366 wxCHECK_RET( Ok(), wxT("invalid window dc") );
368 if (m_pen
.GetStyle() != wxTRANSPARENT
)
372 // This hack is for the iPaq: XDrawLine draws
373 // nothing, whereas XDrawLines works...
379 DrawLines( 2, points
, 0, 0 );
381 // XDrawLine( (Display*) m_display, (Window) m_window,
382 // (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
385 CalcBoundingBox(x1
, y1
);
386 CalcBoundingBox(x2
, y2
);
390 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
392 wxCHECK_RET( Ok(), wxT("invalid window dc") );
394 if (m_pen
.GetStyle() != wxTRANSPARENT
)
399 wxCoord xx
= XLOG2DEV(x
);
400 wxCoord yy
= YLOG2DEV(y
);
403 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
404 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
405 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
406 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
411 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
413 wxCHECK_RET( Ok(), wxT("invalid window dc") );
415 wxCoord xx1
= XLOG2DEV(x1
);
416 wxCoord yy1
= YLOG2DEV(y1
);
417 wxCoord xx2
= XLOG2DEV(x2
);
418 wxCoord yy2
= YLOG2DEV(y2
);
419 wxCoord xxc
= XLOG2DEV(xc
);
420 wxCoord yyc
= YLOG2DEV(yc
);
421 double dx
= xx1
- xxc
;
422 double dy
= yy1
- yyc
;
423 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
424 wxCoord r
= (wxCoord
)radius
;
425 double radius1
, radius2
;
427 if (xx1
== xx2
&& yy1
== yy2
)
435 radius1
= radius2
= 0.0;
439 radius1
= (xx1
- xxc
== 0) ?
440 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
441 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
442 radius2
= (xx2
- xxc
== 0) ?
443 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
444 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
446 wxCoord alpha1
= wxCoord(radius1
* 64.0);
447 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
448 while (alpha2
<= 0) alpha2
+= 360*64;
449 while (alpha1
> 360*64) alpha1
-= 360*64;
453 if (m_brush
.GetStyle() != wxTRANSPARENT
)
455 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
457 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
458 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
459 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
461 XFillArc( (Display
*) m_display
, (Window
) m_window
,
462 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
464 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
466 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
468 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
469 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
471 XFillArc( (Display
*) m_display
, (Window
) m_window
,
472 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
474 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
476 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
478 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
479 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
481 XFillArc( (Display
*) m_display
, (Window
) m_window
,
482 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
484 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
486 if (m_brush
.GetStyle() == wxSTIPPLE
)
488 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
489 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
490 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
492 XFillArc( (Display
*) m_display
, (Window
) m_window
,
493 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
495 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
499 XFillArc( (Display
*) m_display
, (Window
) m_window
,
500 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
504 if (m_pen
.GetStyle() != wxTRANSPARENT
)
506 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
507 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
509 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
510 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
512 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
513 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
517 CalcBoundingBox (x1
, y1
);
518 CalcBoundingBox (x2
, y2
);
521 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
523 wxCHECK_RET( Ok(), wxT("invalid window dc") );
525 wxCoord xx
= XLOG2DEV(x
);
526 wxCoord yy
= YLOG2DEV(y
);
527 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
528 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
530 // CMB: handle -ve width and/or height
531 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
532 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
536 wxCoord start
= wxCoord(sa
* 64.0);
537 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
539 if (m_brush
.GetStyle() != wxTRANSPARENT
)
541 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
543 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
544 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
545 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
547 XFillArc( (Display
*) m_display
, (Window
) m_window
,
548 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
550 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
552 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
554 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
555 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
557 XFillArc( (Display
*) m_display
, (Window
) m_window
,
558 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
560 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
562 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
564 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
565 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
567 XFillArc( (Display
*) m_display
, (Window
) m_window
,
568 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
570 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
572 if (m_brush
.GetStyle() == wxSTIPPLE
)
574 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
575 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
576 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
578 XFillArc( (Display
*) m_display
, (Window
) m_window
,
579 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
581 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
585 XFillArc( (Display
*) m_display
, (Window
) m_window
,
586 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
590 if (m_pen
.GetStyle() != wxTRANSPARENT
)
592 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
593 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
597 CalcBoundingBox (x
, y
);
598 CalcBoundingBox (x
+ width
, y
+ height
);
601 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
603 wxCHECK_RET( Ok(), wxT("invalid window dc") );
605 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
)
606 XDrawPoint( (Display
*) m_display
, (Window
) m_window
,
607 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
609 CalcBoundingBox (x
, y
);
612 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
614 wxCHECK_RET( Ok(), wxT("invalid window dc") );
616 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
619 XPoint
*xpoints
= new XPoint
[n
];
620 for (int i
= 0; i
< n
; i
++)
622 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
623 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
625 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
627 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
, 0 );
632 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
633 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
635 wxCHECK_RET( Ok(), wxT("invalid window dc") );
639 XPoint
*xpoints
= new XPoint
[n
+ 1];
641 for (i
= 0; i
< n
; i
++)
643 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
644 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
646 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
651 if (m_brush
.GetStyle() != wxTRANSPARENT
)
654 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
656 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
657 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
658 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
660 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
661 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
663 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
665 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
667 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
668 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
670 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
671 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
673 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
675 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
677 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
678 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
680 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
681 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
683 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
685 if (m_brush
.GetStyle() == wxSTIPPLE
)
687 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
688 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
689 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
691 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
692 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
694 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
698 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
699 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
703 if (m_pen
.GetStyle () != wxTRANSPARENT
)
705 // Close figure for XDrawLines
706 xpoints
[i
].x
= xpoints
[0].x
;
707 xpoints
[i
].y
= xpoints
[0].y
;
709 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
716 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
718 wxCHECK_RET( Ok(), wxT("invalid window dc") );
720 wxCoord xx
= XLOG2DEV(x
);
721 wxCoord yy
= YLOG2DEV(y
);
722 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
723 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
725 // CMB: draw nothing if transformed w or h is 0
726 if (ww
== 0 || hh
== 0) return;
728 // CMB: handle -ve width and/or height
729 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
730 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
734 if (m_brush
.GetStyle() != wxTRANSPARENT
)
736 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
738 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
739 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
740 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
742 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
743 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
745 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
747 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
749 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
750 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
752 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
753 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
755 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
757 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
759 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
760 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
762 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
763 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
765 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
767 if (m_brush
.GetStyle() == wxSTIPPLE
)
769 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
770 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
771 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
773 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
774 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
776 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
780 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
781 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
785 if (m_pen
.GetStyle () != wxTRANSPARENT
)
787 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
788 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
792 CalcBoundingBox( x
, y
);
793 CalcBoundingBox( x
+ width
, y
+ height
);
796 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
798 wxCHECK_RET( Ok(), wxT("invalid window dc") );
800 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
802 wxCoord xx
= XLOG2DEV(x
);
803 wxCoord yy
= YLOG2DEV(y
);
804 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
805 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
806 wxCoord rr
= XLOG2DEVREL((wxCoord
)radius
);
808 // CMB: handle -ve width and/or height
809 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
810 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
812 // CMB: if radius is zero use DrawRectangle() instead to avoid
813 // X drawing errors with small radii
816 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
817 (GC
) m_penGC
, x
, y
, width
, height
);
821 // CMB: draw nothing if transformed w or h is 0
822 if (ww
== 0 || hh
== 0) return;
824 // CMB: adjust size if outline is drawn otherwise the result is
825 // 1 pixel too wide and high
826 if (m_pen
.GetStyle() != wxTRANSPARENT
)
834 // CMB: ensure dd is not larger than rectangle otherwise we
835 // get an hour glass shape
837 if (dd
> ww
) dd
= ww
;
838 if (dd
> hh
) dd
= hh
;
841 if (m_brush
.GetStyle() != wxTRANSPARENT
)
843 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
845 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
846 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
847 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
848 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
849 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
850 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
851 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
852 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
853 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
854 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0);
856 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
858 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
859 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
860 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
861 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
862 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
863 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
864 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
865 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
867 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
869 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
870 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
871 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
872 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
873 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
874 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
875 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
876 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
878 if (m_brush
.GetStyle() == wxSTIPPLE
)
880 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
881 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
882 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
883 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
884 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
885 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
886 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
887 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
888 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
889 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
893 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
894 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
895 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
896 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
897 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
898 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
901 if (m_pen
.GetStyle() != wxTRANSPARENT
)
903 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy
);
904 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
905 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr
);
906 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr
);
907 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
908 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
909 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
910 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
914 // this ignores the radius
915 CalcBoundingBox( x
, y
);
916 CalcBoundingBox( x
+ width
, y
+ height
);
919 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
921 wxCHECK_RET( Ok(), wxT("invalid window dc") );
923 wxCoord xx
= XLOG2DEV(x
);
924 wxCoord yy
= YLOG2DEV(y
);
925 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
926 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
928 // CMB: handle -ve width and/or height
929 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
930 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
934 if (m_brush
.GetStyle() != wxTRANSPARENT
)
936 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
938 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
939 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
940 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
942 XFillArc( (Display
*) m_display
, (Window
) m_window
,
943 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
945 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
947 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
949 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
950 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
952 XFillArc( (Display
*) m_display
, (Window
) m_window
,
953 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
955 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
957 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
959 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
960 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
962 XFillArc( (Display
*) m_display
, (Window
) m_window
,
963 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
965 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
967 if (m_brush
.GetStyle() == wxSTIPPLE
)
969 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
970 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
971 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
973 XFillArc( (Display
*) m_display
, (Window
) m_window
,
974 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
976 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
980 XFillArc( (Display
*) m_display
, (Window
) m_window
,
981 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
985 if (m_pen
.GetStyle () != wxTRANSPARENT
)
987 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
988 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
992 CalcBoundingBox( x
, y
);
993 CalcBoundingBox( x
+ width
, y
+ height
);
996 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
998 DoDrawBitmap(icon
, x
, y
, true);
1002 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1003 wxCoord x
, wxCoord y
,
1006 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1008 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1010 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1012 /* scale/translate size and position */
1013 int xx
= XLOG2DEV(x
);
1014 int yy
= YLOG2DEV(y
);
1016 int w
= bitmap
.GetWidth();
1017 int h
= bitmap
.GetHeight();
1019 CalcBoundingBox( x
, y
);
1020 CalcBoundingBox( x
+ w
, y
+ h
);
1022 if (!m_window
) return;
1024 int ww
= XLOG2DEVREL(w
);
1025 int hh
= YLOG2DEVREL(h
);
1027 /* compare to current clipping region */
1028 if (!m_currentClippingRegion
.IsNull())
1030 wxRegion
tmp( xx
,yy
,ww
,hh
);
1031 tmp
.Intersect( m_currentClippingRegion
);
1036 /* scale bitmap if required */
1037 wxBitmap use_bitmap
;
1038 if ((w
!= ww
) || (h
!= hh
))
1040 wxImage
image( bitmap
.ConvertToImage() );
1041 image
.Rescale( ww
, hh
);
1044 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1051 use_bitmap
= bitmap
;
1054 /* apply mask if any */
1055 WXPixmap mask
= NULL
;
1056 if (use_bitmap
.GetMask())
1057 mask
= use_bitmap
.GetMask()->GetBitmap();
1059 if (useMask
&& mask
)
1061 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
1062 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
1063 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
1065 GrSetGCUseBackground(gc
, FALSE
);
1066 GrSetGCMode(gc
, GR_MODE_COPY
);
1068 // This code assumes that background and foreground
1069 // colours are used in ROPs, like in MSW.
1070 // Not sure if this is true.
1072 // Copy destination to buffer.
1073 // In DoBlit, we need this step because Blit has
1074 // a ROP argument. Here, we don't need it.
1075 // In DoBlit, we may be able to eliminate this step
1076 // if we check if the rop = copy
1078 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_window
,
1079 0, 0, GR_MODE_COPY
);
1082 // Copy src to buffer using selected raster op (none selected
1083 // in DrawBitmap, so just use Gxcopy)
1084 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
1085 0, 0, GR_MODE_COPY
);
1087 // Set masked area in buffer to BLACK (pixel value 0)
1088 GrSetGCBackground(gc
, WHITE
);
1089 GrSetGCForeground(gc
, BLACK
);
1090 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
1093 // set unmasked area in dest to BLACK
1094 GrSetGCBackground(gc
, BLACK
);
1095 GrSetGCForeground(gc
, WHITE
);
1096 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
1099 // OR buffer to dest
1100 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
1104 GrDestroyWindow(bufPixmap
);
1107 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1108 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1110 /* remove mask again if any */
1111 if (useMask
&& mask
)
1113 if (!m_currentClippingRegion
.IsNull())
1114 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1121 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1122 wxCoord x
, wxCoord y
,
1125 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1127 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1129 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1131 // scale/translate size and position
1132 int xx
= XLOG2DEV(x
);
1133 int yy
= YLOG2DEV(y
);
1135 int w
= bitmap
.GetWidth();
1136 int h
= bitmap
.GetHeight();
1138 CalcBoundingBox( x
, y
);
1139 CalcBoundingBox( x
+ w
, y
+ h
);
1141 if (!m_window
) return;
1143 int ww
= XLOG2DEVREL(w
);
1144 int hh
= YLOG2DEVREL(h
);
1146 // compare to current clipping region
1147 if (!m_currentClippingRegion
.IsNull())
1149 wxRegion
tmp( xx
,yy
,ww
,hh
);
1150 tmp
.Intersect( m_currentClippingRegion
);
1155 // scale bitmap if required
1156 wxBitmap use_bitmap
;
1157 if ((w
!= ww
) || (h
!= hh
))
1159 wxImage
image( bitmap
.ConvertToImage() );
1160 image
.Rescale( ww
, hh
);
1163 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1170 use_bitmap
= bitmap
;
1173 // apply mask if any
1174 WXPixmap mask
= NULL
;
1175 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1177 if (useMask
&& mask
)
1179 WXPixmap new_mask
= NULL
;
1181 if (!m_currentClippingRegion
.IsNull())
1184 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 );
1185 GdkGC
*gc
= gdk_gc_new( new_mask
);
1187 gdk_gc_set_foreground( gc
, &col
);
1188 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1190 gdk_gc_set_background( gc
, &col
);
1192 gdk_gc_set_foreground( gc
, &col
);
1193 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1194 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1195 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1196 gdk_gc_set_stipple( gc
, mask
);
1197 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1204 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1206 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1207 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1212 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1214 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1215 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1219 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1222 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1223 // drawing a mono-bitmap (XBitmap) we use the current text GC
1225 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1226 (GC
) m_textGC
, 0, 0, w
, h
, xx
, yy
, 1 );
1228 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1229 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1231 // remove mask again if any
1232 if (useMask
&& mask
)
1236 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1237 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1238 if (!m_currentClippingRegion
.IsNull())
1239 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1243 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1244 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1245 if (!m_currentClippingRegion
.IsNull())
1246 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1251 // wxUSE_NANOX/!wxUSE_NANOX
1253 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1254 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1255 wxCoord xsrcMask
, wxCoord ysrcMask
)
1257 /* this is the nth try to get this utterly useless function to
1258 work. it now completely ignores the scaling or translation
1259 of the source dc, but scales correctly on the target dc and
1260 knows about possible mask information in a memory dc. */
1262 wxCHECK_MSG( Ok(), false, wxT("invalid window dc") );
1264 wxCHECK_MSG( source
, false, wxT("invalid source dc") );
1266 if (!m_window
) return false;
1268 // transform the source DC coords to the device ones
1269 xsrc
= source
->XLOG2DEV(xsrc
);
1270 ysrc
= source
->YLOG2DEV(ysrc
);
1272 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1273 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1275 bool use_bitmap_method
= false;
1276 bool is_mono
= false;
1278 // TODO: use the mask origin when drawing transparently
1279 if (xsrcMask
== -1 && ysrcMask
== -1)
1285 if (srcDC
->m_isMemDC
)
1287 if (!memDC
->m_selected
.Ok()) return false;
1289 /* we use the "XCopyArea" way to copy a memory dc into
1290 y different window if the memory dc BOTH
1291 a) doesn't have any mask or its mask isn't used
1295 if (useMask
&& (memDC
->m_selected
.GetMask()))
1297 /* we HAVE TO use the direct way for memory dcs
1298 that have mask since the XCopyArea doesn't know
1300 use_bitmap_method
= true;
1302 else if (memDC
->m_selected
.GetDepth() == 1)
1304 /* we HAVE TO use the direct way for memory dcs
1305 that are bitmaps because XCopyArea doesn't cope
1306 with different bit depths */
1308 use_bitmap_method
= true;
1310 else if ((xsrc
== 0) && (ysrc
== 0) &&
1311 (width
== memDC
->m_selected
.GetWidth()) &&
1312 (height
== memDC
->m_selected
.GetHeight()))
1314 /* we SHOULD use the direct way if all of the bitmap
1315 in the memory dc is copied in which case XCopyArea
1316 wouldn't be able able to boost performace by reducing
1317 the area to be scaled */
1318 use_bitmap_method
= true;
1322 use_bitmap_method
= false;
1326 CalcBoundingBox( xdest
, ydest
);
1327 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1329 // scale/translate size and position
1330 wxCoord xx
= XLOG2DEV(xdest
);
1331 wxCoord yy
= YLOG2DEV(ydest
);
1333 wxCoord ww
= XLOG2DEVREL(width
);
1334 wxCoord hh
= YLOG2DEVREL(height
);
1336 // compare to current clipping region
1337 if (!m_currentClippingRegion
.IsNull())
1339 wxRegion
tmp( xx
,yy
,ww
,hh
);
1340 tmp
.Intersect( m_currentClippingRegion
);
1345 int old_logical_func
= m_logicalFunction
;
1346 SetLogicalFunction( logical_func
);
1348 if (use_bitmap_method
)
1350 // scale/translate bitmap size
1351 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1352 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1354 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1355 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1357 // scale bitmap if required
1358 wxBitmap use_bitmap
;
1360 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1362 wxImage
image( memDC
->m_selected
.ConvertToImage() );
1363 image
= image
.Scale( bm_ww
, bm_hh
);
1367 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1374 use_bitmap
= memDC
->m_selected
;
1377 // apply mask if any
1378 WXPixmap mask
= NULL
;
1379 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1381 if (useMask
&& mask
)
1383 WXPixmap new_mask
= NULL
;
1385 if (!m_currentClippingRegion
.IsNull())
1388 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1389 GdkGC
*gc
= gdk_gc_new( new_mask
);
1391 gdk_gc_set_foreground( gc
, &col
);
1392 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1394 gdk_gc_set_background( gc
, &col
);
1396 gdk_gc_set_foreground( gc
, &col
);
1397 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1398 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1399 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1400 gdk_gc_set_stipple( gc
, mask
);
1401 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1408 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1410 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1411 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1416 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1418 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1419 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1423 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1426 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1427 // drawing a mono-bitmap (XBitmap) we use the current text GC
1430 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1431 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1433 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1434 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1436 // remove mask again if any
1437 if (useMask
&& mask
)
1441 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1442 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1443 if (!m_currentClippingRegion
.IsNull())
1444 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1448 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1449 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1450 if (!m_currentClippingRegion
.IsNull())
1451 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1455 else // use_bitmap_method
1457 if ((width
!= ww
) || (height
!= hh
))
1459 /* Draw source window into a bitmap as we cannot scale
1460 a window in contrast to a bitmap. this would actually
1461 work with memory dcs as well, but we'd lose the mask
1462 information and waste one step in this process since
1463 a memory already has a bitmap. all this is slightly
1464 inefficient as we could take an XImage directly from
1465 an X window, but we'd then also have to care that
1466 the window is not outside the screen (in which case
1467 we'd get a BadMatch or what not).
1468 Is a double XGetImage and combined XGetPixel and
1469 XPutPixel really faster? I'm not sure. look at wxXt
1470 for a different implementation of the same problem. */
1472 wxBitmap
bitmap( width
, height
);
1474 // copy including child window contents
1475 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1476 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) bitmap
.GetPixmap(),
1477 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1478 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1481 wxImage
image( bitmap
.ConvertToImage() );
1482 image
= image
.Scale( ww
, hh
);
1484 // convert to bitmap
1487 // draw scaled bitmap
1488 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_window
,
1489 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1493 // No scaling and not a memory dc with a mask either
1495 // copy including child window contents
1496 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1497 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) m_window
,
1498 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1499 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1503 SetLogicalFunction( old_logical_func
);
1508 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1510 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1512 if (!m_window
) return;
1518 PangoLayout
*layout
= pango_layout_new(m_context
);
1519 pango_layout_set_font_description(layout
, m_fontdesc
);
1521 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1522 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1526 pango_layout_get_pixel_size(layout
, &w
, &h
);
1531 x11_draw_layout( (Drawable
) m_window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1533 g_object_unref( G_OBJECT( layout
) );
1535 CalcBoundingBox (x
+ width
, y
+ height
);
1536 CalcBoundingBox (x
, y
);
1538 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1540 wxCHECK_RET( xfont
, wxT("invalid font") );
1542 // First draw a rectangle representing the text background, if a text
1543 // background is specified
1544 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1546 // Since X draws from the baseline of the text, must add the text height
1551 int direction
, descent
;
1553 slen
= strlen(text
);
1554 XCharStruct overall_return
;
1556 (void)XTextExtents(xfont
, (char*) text
.c_str(), slen
, &direction
,
1557 &ascent
, &descent
, &overall_return
);
1559 cx
= overall_return
.width
;
1560 cy
= ascent
+ descent
;
1561 m_textBackgroundColour
.CalcPixel(m_cmap
);
1562 m_textForegroundColour
.CalcPixel(m_cmap
);
1563 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1564 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
1565 (GC
) m_textGC
, x
, y
, cx
, cy
);
1566 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1570 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1572 if ((xfont
->min_byte1
== 0) && (xfont
->max_byte1
== 0))
1575 XDrawString( (Display
*) m_display
, (Window
) m_window
,
1576 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.Len() );
1580 if (m_font
.GetUnderlined())
1582 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1583 if (font
->descent
> 0) ul_y
++;
1584 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1587 width
= wxCoord(width
/ m_scaleX
);
1588 height
= wxCoord(height
/ m_scaleY
);
1590 CalcBoundingBox (x
+ width
, y
+ height
);
1591 CalcBoundingBox (x
, y
);
1596 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
, double angle
)
1601 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1602 wxCoord
*descent
, wxCoord
*externalLeading
,
1603 wxFont
*font
) const
1605 wxCHECK_RET( Ok(), wxT("invalid dc") );
1609 if (width
) (*width
) = 0;
1610 if (height
) (*height
) = 0;
1615 PangoLayout
*layout
= pango_layout_new( m_context
);
1618 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1620 pango_layout_set_font_description(layout
, m_fontdesc
);
1622 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1623 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1627 pango_layout_get_pixel_size(layout
, &w
, &h
);
1629 if (width
) (*width
) = (wxCoord
) w
;
1630 if (height
) (*height
) = (wxCoord
) h
;
1633 // Do something about metrics here. TODO.
1636 if (externalLeading
) (*externalLeading
) = 0; // ??
1638 g_object_unref( G_OBJECT( layout
) );
1640 wxFont fontToUse
= m_font
;
1641 if (font
) fontToUse
= *font
;
1643 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
1645 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1647 wxCHECK_RET( xfont
, wxT("invalid font") );
1649 int direction
, ascent
, descent2
;
1650 XCharStruct overall
;
1652 XTextExtents( xfont
, (char*) string
.c_str(), string
.Len(), &direction
,
1653 &ascent
, &descent2
, &overall
);
1656 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1658 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1660 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1661 if (externalLeading
)
1662 *externalLeading
= 0; // ??
1666 wxCoord
wxWindowDC::GetCharWidth() const
1668 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1671 PangoLayout
*layout
= pango_layout_new( m_context
);
1679 pango_layout_set_font_description(layout
, m_fontdesc
);
1680 pango_layout_set_text(layout
, "H", 1 );
1682 pango_layout_get_pixel_size(layout
, &w
, &h
);
1683 g_object_unref( G_OBJECT( layout
) );
1687 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1689 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1691 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1693 int direction
, ascent
, descent
;
1694 XCharStruct overall
;
1696 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1698 return (wxCoord
)(overall
.width
/ m_scaleX
);
1702 wxCoord
wxWindowDC::GetCharHeight() const
1704 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1707 PangoLayout
*layout
= pango_layout_new( m_context
);
1715 pango_layout_set_font_description(layout
, m_fontdesc
);
1717 pango_layout_set_text(layout
, "H", 1 );
1719 pango_layout_get_pixel_size(layout
, &w
, &h
);
1720 g_object_unref( G_OBJECT( layout
) );
1724 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1726 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1728 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1730 int direction
, ascent
, descent
;
1731 XCharStruct overall
;
1733 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1735 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1739 void wxWindowDC::Clear()
1741 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1743 if (!m_window
) return;
1745 /* - we either are a memory dc or have a window as the
1746 owner. anything else shouldn't happen.
1747 - we don't use gdk_window_clear() as we don't set
1748 the window's background colour anymore. it is too
1749 much pain to keep the DC's and the window's back-
1750 ground colour in synch. */
1755 m_owner
->GetSize( &width
, &height
);
1756 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1763 GetSize( &width
, &height
);
1764 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1769 void wxWindowDC::SetFont( const wxFont
&font
)
1771 wxCHECK_RET( Ok(), wxT("invalid dc") );
1779 pango_font_description_free( m_fontdesc
);
1781 m_fontdesc
= pango_font_description_copy( m_font
.GetNativeFontInfo()->description
);
1786 void wxWindowDC::SetPen( const wxPen
&pen
)
1788 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1790 if (m_pen
== pen
) return;
1794 if (!m_pen
.Ok()) return;
1796 if (!m_window
) return;
1798 int width
= m_pen
.GetWidth();
1801 // CMB: if width is non-zero scale it with the dc
1806 // X doesn't allow different width in x and y and so we take
1809 ( fabs((double) XLOG2DEVREL(width
)) +
1810 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1814 static const wxX11Dash dotted
[] = {1, 1};
1815 static const wxX11Dash short_dashed
[] = {2, 2};
1816 static const wxX11Dash long_dashed
[] = {2, 4};
1817 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1819 // We express dash pattern in pen width unit, so we are
1820 // independent of zoom factor and so on...
1822 const wxX11Dash
*req_dash
;
1824 int lineStyle
= LineSolid
;
1825 switch (m_pen
.GetStyle())
1829 lineStyle
= LineOnOffDash
;
1830 req_nb_dash
= m_pen
.GetDashCount();
1831 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1836 lineStyle
= LineOnOffDash
;
1843 lineStyle
= LineOnOffDash
;
1845 req_dash
= long_dashed
;
1850 lineStyle
= LineOnOffDash
;
1852 req_dash
= short_dashed
;
1857 // lineStyle = LineDoubleDash;
1858 lineStyle
= LineOnOffDash
;
1860 req_dash
= dotted_dashed
;
1865 case wxSTIPPLE_MASK_OPAQUE
:
1870 lineStyle
= LineSolid
;
1871 req_dash
= (wxX11Dash
*)NULL
;
1877 int capStyle
= CapRound
;
1878 switch (m_pen
.GetCap())
1880 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1881 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1888 capStyle
= CapNotLast
;
1892 capStyle
= CapRound
;
1898 int joinStyle
= JoinRound
;
1899 switch (m_pen
.GetJoin())
1901 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1902 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1904 default: { joinStyle
= JoinRound
; break; }
1907 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1909 m_pen
.GetColour().CalcPixel( m_cmap
);
1910 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1913 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1915 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1917 if (m_brush
== brush
) return;
1921 if (!m_brush
.Ok()) return;
1923 if (!m_window
) return;
1925 m_brush
.GetColour().CalcPixel( m_cmap
);
1926 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1928 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1930 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1932 if (m_brush
.GetStipple()->GetPixmap())
1934 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1935 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1939 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1940 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1944 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1946 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1947 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1950 if (m_brush
.IsHatch())
1952 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1953 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1954 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1958 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1960 /* CMB 21/7/98: Added SetBackground. Sets background brush
1961 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1963 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1965 if (m_backgroundBrush
== brush
) return;
1967 m_backgroundBrush
= brush
;
1969 if (!m_backgroundBrush
.Ok()) return;
1971 if (!m_window
) return;
1973 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1974 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1975 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1976 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1977 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1979 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1981 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1983 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1985 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1986 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1990 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1991 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
1995 if (m_backgroundBrush
.IsHatch())
1997 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1998 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
1999 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
2003 void wxWindowDC::SetLogicalFunction( int function
)
2005 wxCHECK_RET( Ok(), wxT("invalid dc") );
2009 if (m_logicalFunction
== function
)
2012 // VZ: shouldn't this be a CHECK?
2019 x_function
= GXclear
;
2025 x_function
= GXinvert
;
2028 x_function
= GXorReverse
;
2031 x_function
= GXandReverse
;
2040 x_function
= GXandInverted
;
2043 x_function
= GXnoop
;
2049 x_function
= GXequiv
;
2052 x_function
= GXcopyInverted
;
2055 x_function
= GXorInverted
;
2058 x_function
= GXnand
;
2065 x_function
= GXcopy
;
2069 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2070 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2072 // to stay compatible with wxMSW, we don't apply ROPs to the text
2073 // operations (i.e. DrawText/DrawRotatedText).
2074 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2075 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2077 m_logicalFunction
= function
;
2080 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2082 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2084 // don't set m_textForegroundColour to an invalid colour as we'd crash
2085 // later then (we use m_textForegroundColour.GetColor() without checking
2087 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
2090 m_textForegroundColour
= col
;
2094 m_textForegroundColour
.CalcPixel( m_cmap
);
2095 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2099 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2101 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2104 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
2107 m_textBackgroundColour
= col
;
2111 m_textBackgroundColour
.CalcPixel( m_cmap
);
2112 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2116 void wxWindowDC::SetBackgroundMode( int mode
)
2118 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2120 m_backgroundMode
= mode
;
2123 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2126 if (!m_window
) return;
2128 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2129 // transparent/solid background mode
2131 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2133 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2134 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2138 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2144 /* Use GetXColormap */
2145 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2146 (Colormap
) palette
.GetXColormap());
2148 /* Use wxGetMainColormap */
2149 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2150 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2155 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2157 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2159 if (!m_window
) return;
2162 rect
.x
= XLOG2DEV(x
);
2163 rect
.y
= YLOG2DEV(y
);
2164 rect
.width
= XLOG2DEVREL(width
);
2165 rect
.height
= YLOG2DEVREL(height
);
2167 if (!m_currentClippingRegion
.IsNull())
2168 m_currentClippingRegion
.Intersect( rect
);
2170 m_currentClippingRegion
.Union( rect
);
2172 #if USE_PAINT_REGION
2173 if (!m_paintClippingRegion
.IsNull())
2174 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2177 wxCoord xx
, yy
, ww
, hh
;
2178 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2179 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2181 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2182 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2183 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2184 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2187 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2189 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2193 DestroyClippingRegion();
2197 if (!m_window
) return;
2199 if (!m_currentClippingRegion
.IsNull())
2200 m_currentClippingRegion
.Intersect( region
);
2202 m_currentClippingRegion
.Union( region
);
2204 #if USE_PAINT_REGION
2205 if (!m_paintClippingRegion
.IsNull())
2206 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2209 wxCoord xx
, yy
, ww
, hh
;
2210 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2211 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2213 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2214 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2215 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2216 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2219 void wxWindowDC::DestroyClippingRegion()
2221 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2223 wxDC::DestroyClippingRegion();
2225 m_currentClippingRegion
.Clear();
2227 #if USE_PAINT_REGION
2228 if (!m_paintClippingRegion
.IsEmpty())
2229 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2232 if (!m_window
) return;
2234 if (m_currentClippingRegion
.IsEmpty())
2236 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2237 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2238 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2239 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2243 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2244 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2245 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2246 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2250 void wxWindowDC::Destroy()
2252 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2254 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2256 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2258 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2262 void wxWindowDC::ComputeScaleAndOrigin()
2264 /* CMB: copy scale to see if it changes */
2265 double origScaleX
= m_scaleX
;
2266 double origScaleY
= m_scaleY
;
2268 wxDC::ComputeScaleAndOrigin();
2270 /* CMB: if scale has changed call SetPen to recalulate the line width */
2271 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2274 /* this is a bit artificial, but we need to force wxDC to think
2275 the pen has changed */
2282 wxSize
wxWindowDC::GetPPI() const
2284 return wxSize(100, 100);
2287 int wxWindowDC::GetDepth() const
2289 wxFAIL_MSG(wxT("not implemented"));
2294 //-----------------------------------------------------------------------------
2296 //-----------------------------------------------------------------------------
2298 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2300 wxClientDC::wxClientDC( wxWindow
*window
)
2301 : wxWindowDC( window
)
2303 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2305 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2307 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2308 if (m_window
== (WXWindow
*) window
->GetMainWindow())
2310 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2311 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2312 wxSize size
= window
->GetClientSize();
2313 SetClippingRegion(wxPoint(0, 0), size
);
2317 void wxClientDC::DoGetSize(int *width
, int *height
) const
2319 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2321 m_owner
->GetClientSize( width
, height
);
2324 // ----------------------------------------------------------------------------
2326 // ----------------------------------------------------------------------------
2328 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2330 wxPaintDC::wxPaintDC(wxWindow
* window
)
2331 : wxClientDC(window
)
2333 #if USE_PAINT_REGION
2334 if (!window
->GetClipPaintRegion())
2337 m_paintClippingRegion
= window
->GetUpdateRegion();
2338 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2341 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2343 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2344 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2345 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2346 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2348 #endif // USE_PAINT_REGION
2351 // ----------------------------------------------------------------------------
2353 // ----------------------------------------------------------------------------
2355 class wxDCModule
: public wxModule
2362 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2365 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)
2367 bool wxDCModule::OnInit()
2373 void wxDCModule::OnExit()