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") );
1776 void wxWindowDC::SetPen( const wxPen
&pen
)
1778 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1780 if (m_pen
== pen
) return;
1784 if (!m_pen
.Ok()) return;
1786 if (!m_window
) return;
1788 int width
= m_pen
.GetWidth();
1791 // CMB: if width is non-zero scale it with the dc
1796 // X doesn't allow different width in x and y and so we take
1799 ( fabs((double) XLOG2DEVREL(width
)) +
1800 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1804 static const wxX11Dash dotted
[] = {1, 1};
1805 static const wxX11Dash short_dashed
[] = {2, 2};
1806 static const wxX11Dash long_dashed
[] = {2, 4};
1807 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1809 // We express dash pattern in pen width unit, so we are
1810 // independent of zoom factor and so on...
1812 const wxX11Dash
*req_dash
;
1814 int lineStyle
= LineSolid
;
1815 switch (m_pen
.GetStyle())
1819 lineStyle
= LineOnOffDash
;
1820 req_nb_dash
= m_pen
.GetDashCount();
1821 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1826 lineStyle
= LineOnOffDash
;
1833 lineStyle
= LineOnOffDash
;
1835 req_dash
= long_dashed
;
1840 lineStyle
= LineOnOffDash
;
1842 req_dash
= short_dashed
;
1847 // lineStyle = LineDoubleDash;
1848 lineStyle
= LineOnOffDash
;
1850 req_dash
= dotted_dashed
;
1855 case wxSTIPPLE_MASK_OPAQUE
:
1860 lineStyle
= LineSolid
;
1861 req_dash
= (wxX11Dash
*)NULL
;
1867 int capStyle
= CapRound
;
1868 switch (m_pen
.GetCap())
1870 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1871 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1878 capStyle
= CapNotLast
;
1882 capStyle
= CapRound
;
1888 int joinStyle
= JoinRound
;
1889 switch (m_pen
.GetJoin())
1891 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1892 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1894 default: { joinStyle
= JoinRound
; break; }
1897 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1899 m_pen
.GetColour().CalcPixel( m_cmap
);
1900 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1903 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1905 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1907 if (m_brush
== brush
) return;
1911 if (!m_brush
.Ok()) return;
1913 if (!m_window
) return;
1915 m_brush
.GetColour().CalcPixel( m_cmap
);
1916 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1918 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1920 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1922 if (m_brush
.GetStipple()->GetPixmap())
1924 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1925 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1929 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1930 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1934 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1936 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1937 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1940 if (m_brush
.IsHatch())
1942 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1943 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1944 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1948 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1950 /* CMB 21/7/98: Added SetBackground. Sets background brush
1951 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1953 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1955 if (m_backgroundBrush
== brush
) return;
1957 m_backgroundBrush
= brush
;
1959 if (!m_backgroundBrush
.Ok()) return;
1961 if (!m_window
) return;
1963 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1964 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1965 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1966 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1967 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1969 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1971 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1973 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1975 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1976 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1980 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1981 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
1985 if (m_backgroundBrush
.IsHatch())
1987 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1988 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
1989 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
1993 void wxWindowDC::SetLogicalFunction( int function
)
1995 wxCHECK_RET( Ok(), wxT("invalid dc") );
1999 if (m_logicalFunction
== function
)
2002 // VZ: shouldn't this be a CHECK?
2009 x_function
= GXclear
;
2015 x_function
= GXinvert
;
2018 x_function
= GXorReverse
;
2021 x_function
= GXandReverse
;
2030 x_function
= GXandInverted
;
2033 x_function
= GXnoop
;
2039 x_function
= GXequiv
;
2042 x_function
= GXcopyInverted
;
2045 x_function
= GXorInverted
;
2048 x_function
= GXnand
;
2055 x_function
= GXcopy
;
2059 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2060 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2062 // to stay compatible with wxMSW, we don't apply ROPs to the text
2063 // operations (i.e. DrawText/DrawRotatedText).
2064 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2065 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2067 m_logicalFunction
= function
;
2070 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2072 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2074 // don't set m_textForegroundColour to an invalid colour as we'd crash
2075 // later then (we use m_textForegroundColour.GetColor() without checking
2077 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
2080 m_textForegroundColour
= col
;
2084 m_textForegroundColour
.CalcPixel( m_cmap
);
2085 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2089 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2091 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2094 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
2097 m_textBackgroundColour
= col
;
2101 m_textBackgroundColour
.CalcPixel( m_cmap
);
2102 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2106 void wxWindowDC::SetBackgroundMode( int mode
)
2108 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2110 m_backgroundMode
= mode
;
2113 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2116 if (!m_window
) return;
2118 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2119 // transparent/solid background mode
2121 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2123 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2124 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2128 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2134 /* Use GetXColormap */
2135 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2136 (Colormap
) palette
.GetXColormap());
2138 /* Use wxGetMainColormap */
2139 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2140 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2145 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2147 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2149 if (!m_window
) return;
2152 rect
.x
= XLOG2DEV(x
);
2153 rect
.y
= YLOG2DEV(y
);
2154 rect
.width
= XLOG2DEVREL(width
);
2155 rect
.height
= YLOG2DEVREL(height
);
2157 if (!m_currentClippingRegion
.IsNull())
2158 m_currentClippingRegion
.Intersect( rect
);
2160 m_currentClippingRegion
.Union( rect
);
2162 #if USE_PAINT_REGION
2163 if (!m_paintClippingRegion
.IsNull())
2164 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2167 wxCoord xx
, yy
, ww
, hh
;
2168 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2169 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2171 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2172 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2173 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2174 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2177 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2179 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2183 DestroyClippingRegion();
2187 if (!m_window
) return;
2189 if (!m_currentClippingRegion
.IsNull())
2190 m_currentClippingRegion
.Intersect( region
);
2192 m_currentClippingRegion
.Union( region
);
2194 #if USE_PAINT_REGION
2195 if (!m_paintClippingRegion
.IsNull())
2196 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2199 wxCoord xx
, yy
, ww
, hh
;
2200 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2201 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2203 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2204 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2205 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2206 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2209 void wxWindowDC::DestroyClippingRegion()
2211 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2213 wxDC::DestroyClippingRegion();
2215 m_currentClippingRegion
.Clear();
2217 #if USE_PAINT_REGION
2218 if (!m_paintClippingRegion
.IsEmpty())
2219 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2222 if (!m_window
) return;
2224 if (m_currentClippingRegion
.IsEmpty())
2226 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2227 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2228 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2229 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2233 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2234 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2235 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2236 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2240 void wxWindowDC::Destroy()
2242 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2244 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2246 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2248 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2252 void wxWindowDC::ComputeScaleAndOrigin()
2254 /* CMB: copy scale to see if it changes */
2255 double origScaleX
= m_scaleX
;
2256 double origScaleY
= m_scaleY
;
2258 wxDC::ComputeScaleAndOrigin();
2260 /* CMB: if scale has changed call SetPen to recalulate the line width */
2261 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2264 /* this is a bit artificial, but we need to force wxDC to think
2265 the pen has changed */
2272 wxSize
wxWindowDC::GetPPI() const
2274 return wxSize(100, 100);
2277 int wxWindowDC::GetDepth() const
2279 wxFAIL_MSG(wxT("not implemented"));
2284 //-----------------------------------------------------------------------------
2286 //-----------------------------------------------------------------------------
2288 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2290 wxClientDC::wxClientDC( wxWindow
*window
)
2291 : wxWindowDC( window
)
2293 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2295 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2297 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2298 if (m_window
== (WXWindow
*) window
->GetMainWindow())
2300 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2301 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2302 wxSize size
= window
->GetClientSize();
2303 SetClippingRegion(wxPoint(0, 0), size
);
2307 void wxClientDC::DoGetSize(int *width
, int *height
) const
2309 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2311 m_owner
->GetClientSize( width
, height
);
2314 // ----------------------------------------------------------------------------
2316 // ----------------------------------------------------------------------------
2318 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2320 wxPaintDC::wxPaintDC(wxWindow
* window
)
2321 : wxClientDC(window
)
2323 #if USE_PAINT_REGION
2324 if (!window
->GetClipPaintRegion())
2327 m_paintClippingRegion
= window
->GetUpdateRegion();
2328 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2331 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2333 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2334 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2335 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2336 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2338 #endif // USE_PAINT_REGION
2341 // ----------------------------------------------------------------------------
2343 // ----------------------------------------------------------------------------
2345 class wxDCModule
: public wxModule
2352 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2355 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)
2357 bool wxDCModule::OnInit()
2363 void wxDCModule::OnExit()