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
);
1674 pango_layout_set_font_description(layout
, m_fontdesc
);
1676 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1678 pango_layout_set_text(layout
, "H", 1 );
1680 pango_layout_get_pixel_size(layout
, &w
, &h
);
1681 g_object_unref( G_OBJECT( layout
) );
1685 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1687 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1689 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1691 int direction
, ascent
, descent
;
1692 XCharStruct overall
;
1694 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1696 return (wxCoord
)(overall
.width
/ m_scaleX
);
1700 wxCoord
wxWindowDC::GetCharHeight() const
1702 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1705 PangoLayout
*layout
= pango_layout_new( m_context
);
1708 pango_layout_set_font_description(layout
, m_fontdesc
);
1710 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1712 pango_layout_set_text(layout
, "H", 1 );
1714 pango_layout_get_pixel_size(layout
, &w
, &h
);
1715 g_object_unref( G_OBJECT( layout
) );
1719 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1721 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1723 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1725 int direction
, ascent
, descent
;
1726 XCharStruct overall
;
1728 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1730 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1734 void wxWindowDC::Clear()
1736 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1738 if (!m_window
) return;
1740 /* - we either are a memory dc or have a window as the
1741 owner. anything else shouldn't happen.
1742 - we don't use gdk_window_clear() as we don't set
1743 the window's background colour anymore. it is too
1744 much pain to keep the DC's and the window's back-
1745 ground colour in synch. */
1750 m_owner
->GetSize( &width
, &height
);
1751 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1758 GetSize( &width
, &height
);
1759 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1764 void wxWindowDC::SetFont( const wxFont
&font
)
1766 wxCHECK_RET( Ok(), wxT("invalid dc") );
1773 m_fontdesc
= font
.GetNativeFontInfo()->description
;
1777 void wxWindowDC::SetPen( const wxPen
&pen
)
1779 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1781 if (m_pen
== pen
) return;
1785 if (!m_pen
.Ok()) return;
1787 if (!m_window
) return;
1789 int width
= m_pen
.GetWidth();
1792 // CMB: if width is non-zero scale it with the dc
1797 // X doesn't allow different width in x and y and so we take
1800 ( fabs((double) XLOG2DEVREL(width
)) +
1801 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1805 static const wxX11Dash dotted
[] = {1, 1};
1806 static const wxX11Dash short_dashed
[] = {2, 2};
1807 static const wxX11Dash long_dashed
[] = {2, 4};
1808 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1810 // We express dash pattern in pen width unit, so we are
1811 // independent of zoom factor and so on...
1813 const wxX11Dash
*req_dash
;
1815 int lineStyle
= LineSolid
;
1816 switch (m_pen
.GetStyle())
1820 lineStyle
= LineOnOffDash
;
1821 req_nb_dash
= m_pen
.GetDashCount();
1822 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1827 lineStyle
= LineOnOffDash
;
1834 lineStyle
= LineOnOffDash
;
1836 req_dash
= long_dashed
;
1841 lineStyle
= LineOnOffDash
;
1843 req_dash
= short_dashed
;
1848 // lineStyle = LineDoubleDash;
1849 lineStyle
= LineOnOffDash
;
1851 req_dash
= dotted_dashed
;
1856 case wxSTIPPLE_MASK_OPAQUE
:
1861 lineStyle
= LineSolid
;
1862 req_dash
= (wxX11Dash
*)NULL
;
1868 int capStyle
= CapRound
;
1869 switch (m_pen
.GetCap())
1871 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1872 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1879 capStyle
= CapNotLast
;
1883 capStyle
= CapRound
;
1889 int joinStyle
= JoinRound
;
1890 switch (m_pen
.GetJoin())
1892 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1893 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1895 default: { joinStyle
= JoinRound
; break; }
1898 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1900 m_pen
.GetColour().CalcPixel( m_cmap
);
1901 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1904 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1906 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1908 if (m_brush
== brush
) return;
1912 if (!m_brush
.Ok()) return;
1914 if (!m_window
) return;
1916 m_brush
.GetColour().CalcPixel( m_cmap
);
1917 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1919 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1921 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1923 if (m_brush
.GetStipple()->GetPixmap())
1925 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1926 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1930 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1931 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1935 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1937 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1938 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1941 if (m_brush
.IsHatch())
1943 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1944 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1945 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1949 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1951 /* CMB 21/7/98: Added SetBackground. Sets background brush
1952 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1954 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1956 if (m_backgroundBrush
== brush
) return;
1958 m_backgroundBrush
= brush
;
1960 if (!m_backgroundBrush
.Ok()) return;
1962 if (!m_window
) return;
1964 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1965 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1966 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1967 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1968 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1970 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1972 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1974 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1976 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1977 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1981 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1982 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
1986 if (m_backgroundBrush
.IsHatch())
1988 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1989 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
1990 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
1994 void wxWindowDC::SetLogicalFunction( int function
)
1996 wxCHECK_RET( Ok(), wxT("invalid dc") );
2000 if (m_logicalFunction
== function
)
2003 // VZ: shouldn't this be a CHECK?
2010 x_function
= GXclear
;
2016 x_function
= GXinvert
;
2019 x_function
= GXorReverse
;
2022 x_function
= GXandReverse
;
2031 x_function
= GXandInverted
;
2034 x_function
= GXnoop
;
2040 x_function
= GXequiv
;
2043 x_function
= GXcopyInverted
;
2046 x_function
= GXorInverted
;
2049 x_function
= GXnand
;
2056 x_function
= GXcopy
;
2060 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2061 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2063 // to stay compatible with wxMSW, we don't apply ROPs to the text
2064 // operations (i.e. DrawText/DrawRotatedText).
2065 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2066 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2068 m_logicalFunction
= function
;
2071 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2073 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2075 // don't set m_textForegroundColour to an invalid colour as we'd crash
2076 // later then (we use m_textForegroundColour.GetColor() without checking
2078 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
2081 m_textForegroundColour
= col
;
2085 m_textForegroundColour
.CalcPixel( m_cmap
);
2086 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2090 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2092 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2095 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
2098 m_textBackgroundColour
= col
;
2102 m_textBackgroundColour
.CalcPixel( m_cmap
);
2103 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2107 void wxWindowDC::SetBackgroundMode( int mode
)
2109 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2111 m_backgroundMode
= mode
;
2114 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2117 if (!m_window
) return;
2119 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2120 // transparent/solid background mode
2122 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2124 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2125 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2129 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2135 /* Use GetXColormap */
2136 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2137 (Colormap
) palette
.GetXColormap());
2139 /* Use wxGetMainColormap */
2140 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2141 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2146 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2148 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2150 if (!m_window
) return;
2153 rect
.x
= XLOG2DEV(x
);
2154 rect
.y
= YLOG2DEV(y
);
2155 rect
.width
= XLOG2DEVREL(width
);
2156 rect
.height
= YLOG2DEVREL(height
);
2158 if (!m_currentClippingRegion
.IsNull())
2159 m_currentClippingRegion
.Intersect( rect
);
2161 m_currentClippingRegion
.Union( rect
);
2163 #if USE_PAINT_REGION
2164 if (!m_paintClippingRegion
.IsNull())
2165 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2168 wxCoord xx
, yy
, ww
, hh
;
2169 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2170 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2172 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2173 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2174 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2175 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2178 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2180 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2184 DestroyClippingRegion();
2188 if (!m_window
) return;
2190 if (!m_currentClippingRegion
.IsNull())
2191 m_currentClippingRegion
.Intersect( region
);
2193 m_currentClippingRegion
.Union( region
);
2195 #if USE_PAINT_REGION
2196 if (!m_paintClippingRegion
.IsNull())
2197 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2200 wxCoord xx
, yy
, ww
, hh
;
2201 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2202 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2204 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2205 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2206 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2207 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2210 void wxWindowDC::DestroyClippingRegion()
2212 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2214 wxDC::DestroyClippingRegion();
2216 m_currentClippingRegion
.Clear();
2218 #if USE_PAINT_REGION
2219 if (!m_paintClippingRegion
.IsEmpty())
2220 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2223 if (!m_window
) return;
2225 if (m_currentClippingRegion
.IsEmpty())
2227 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2228 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2229 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2230 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2234 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2235 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2236 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2237 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2241 void wxWindowDC::Destroy()
2243 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2245 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2247 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2249 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2253 void wxWindowDC::ComputeScaleAndOrigin()
2255 /* CMB: copy scale to see if it changes */
2256 double origScaleX
= m_scaleX
;
2257 double origScaleY
= m_scaleY
;
2259 wxDC::ComputeScaleAndOrigin();
2261 /* CMB: if scale has changed call SetPen to recalulate the line width */
2262 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2265 /* this is a bit artificial, but we need to force wxDC to think
2266 the pen has changed */
2273 wxSize
wxWindowDC::GetPPI() const
2275 return wxSize(100, 100);
2278 int wxWindowDC::GetDepth() const
2280 wxFAIL_MSG(wxT("not implemented"));
2285 //-----------------------------------------------------------------------------
2287 //-----------------------------------------------------------------------------
2289 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2291 wxClientDC::wxClientDC( wxWindow
*window
)
2292 : wxWindowDC( window
)
2294 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2296 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2298 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2299 if (m_window
== (WXWindow
*) window
->GetMainWindow())
2301 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2302 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2303 wxSize size
= window
->GetClientSize();
2304 SetClippingRegion(wxPoint(0, 0), size
);
2308 void wxClientDC::DoGetSize(int *width
, int *height
) const
2310 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2312 m_owner
->GetClientSize( width
, height
);
2315 // ----------------------------------------------------------------------------
2317 // ----------------------------------------------------------------------------
2319 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2321 wxPaintDC::wxPaintDC(wxWindow
* window
)
2322 : wxClientDC(window
)
2324 #if USE_PAINT_REGION
2325 if (!window
->GetClipPaintRegion())
2328 m_paintClippingRegion
= window
->GetUpdateRegion();
2329 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2332 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2334 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2335 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2336 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2337 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2339 #endif // USE_PAINT_REGION
2342 // ----------------------------------------------------------------------------
2344 // ----------------------------------------------------------------------------
2346 class wxDCModule
: public wxModule
2353 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2356 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)
2358 bool wxDCModule::OnInit()
2364 void wxDCModule::OnExit()