1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/x11/dcclient.cpp
3 // Purpose: wxClientDC class
4 // Author: Julian Smart, Robert Roebling
8 // Copyright: (c) Julian Smart, Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // for compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
15 #include "wx/dcclient.h"
19 #include "wx/window.h"
22 #include "wx/dcmemory.h"
24 #include "wx/module.h"
25 #include "wx/fontutil.h"
27 #include "wx/x11/private.h"
33 #include "pango/pangox.h"
35 #include "pango/pangoxft.h"
38 #include "pango_x.cpp"
41 //-----------------------------------------------------------------------------
43 //-----------------------------------------------------------------------------
45 #define USE_PAINT_REGION 1
47 //-----------------------------------------------------------------------------
49 //-----------------------------------------------------------------------------
59 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH)
60 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH)
62 static Pixmap hatches
[num_hatches
];
63 static Pixmap
*hatch_bitmap
= (Pixmap
*) NULL
;
65 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
69 const double RAD2DEG
= 180.0 / M_PI
;
71 // ----------------------------------------------------------------------------
73 // ----------------------------------------------------------------------------
75 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
76 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
78 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
80 //-----------------------------------------------------------------------------
81 // Implement Pool of Graphic contexts. Creating them takes too much time.
82 //-----------------------------------------------------------------------------
84 #define GC_POOL_SIZE 200
110 static wxGC wxGCPool
[GC_POOL_SIZE
];
112 static void wxInitGCPool()
114 memset( wxGCPool
, 0, GC_POOL_SIZE
*sizeof(wxGC
) );
117 static void wxCleanUpGCPool()
119 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
121 if (wxGCPool
[i
].m_gc
)
122 XFreeGC( wxGlobalDisplay(), wxGCPool
[i
].m_gc
);
126 static GC
wxGetPoolGC( Window window
, wxPoolGCType type
)
128 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
130 if (!wxGCPool
[i
].m_gc
)
132 wxGCPool
[i
].m_gc
= XCreateGC( wxGlobalDisplay(), window
, 0, NULL
);
133 XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool
[i
].m_gc
, FALSE
);
134 wxGCPool
[i
].m_type
= type
;
135 wxGCPool
[i
].m_used
= false;
137 if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type
== type
))
139 wxGCPool
[i
].m_used
= true;
140 return wxGCPool
[i
].m_gc
;
144 wxFAIL_MSG( wxT("No GC available") );
149 static void wxFreePoolGC( GC gc
)
151 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
153 if (wxGCPool
[i
].m_gc
== gc
)
155 wxGCPool
[i
].m_used
= false;
160 wxFAIL_MSG( wxT("Wrong GC") );
163 // ----------------------------------------------------------------------------
165 // ----------------------------------------------------------------------------
167 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
169 wxWindowDC::wxWindowDC()
171 m_display
= (WXDisplay
*) NULL
;
172 m_penGC
= (WXGC
*) NULL
;
173 m_brushGC
= (WXGC
*) NULL
;
174 m_textGC
= (WXGC
*) NULL
;
175 m_bgGC
= (WXGC
*) NULL
;
176 m_cmap
= (WXColormap
*) NULL
;
178 m_isScreenDC
= false;
179 m_owner
= (wxWindow
*)NULL
;
182 m_context
= (PangoContext
*)NULL
;
183 m_fontdesc
= (PangoFontDescription
*)NULL
;
187 wxWindowDC::wxWindowDC( wxWindow
*window
)
189 wxASSERT_MSG( window
, wxT("DC needs a window") );
191 m_display
= (WXDisplay
*) NULL
;
192 m_penGC
= (WXGC
*) NULL
;
193 m_brushGC
= (WXGC
*) NULL
;
194 m_textGC
= (WXGC
*) NULL
;
195 m_bgGC
= (WXGC
*) NULL
;
196 m_cmap
= (WXColormap
*) NULL
;
197 m_owner
= (wxWindow
*)NULL
;
199 m_isScreenDC
= false;
200 m_font
= window
->GetFont();
202 m_window
= (WXWindow
*) window
->GetMainWindow();
207 // don't report problems
213 m_display
= (WXDisplay
*) wxGlobalDisplay();
216 m_context
= wxTheApp
->GetPangoContext();
217 m_fontdesc
= window
->GetFont().GetNativeFontInfo()->description
;
220 int screen
= DefaultScreen( (Display
*) m_display
);
221 m_cmap
= (WXColormap
) DefaultColormap( (Display
*) m_display
, screen
);
225 /* this must be done after SetUpDC, bacause SetUpDC calls the
226 repective SetBrush, SetPen, SetBackground etc functions
227 to set up the DC. SetBackground call m_owner->SetBackground
228 and this might not be desired as the standard dc background
229 is white whereas a window might assume gray to be the
230 standard (as e.g. wxStatusBar) */
235 wxWindowDC::~wxWindowDC()
240 void wxWindowDC::SetUpDC()
244 wxASSERT_MSG( !m_penGC
, wxT("GCs already created") );
248 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_SCREEN
);
249 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_SCREEN
);
250 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_SCREEN
);
251 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_SCREEN
);
254 if (m_isMemDC
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1))
256 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_MONO
);
257 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_MONO
);
258 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_MONO
);
259 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_MONO
);
263 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_COLOUR
);
264 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_COLOUR
);
265 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_COLOUR
);
266 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_COLOUR
);
269 /* background colour */
270 m_backgroundBrush
= *wxWHITE_BRUSH
;
271 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
272 unsigned long bg_col
= m_backgroundBrush
.GetColour().GetPixel();
274 m_textForegroundColour
= *wxBLACK
;
275 m_textBackgroundColour
= *wxWHITE
;
278 m_textForegroundColour
.CalcPixel( m_cmap
);
279 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
281 m_textBackgroundColour
.CalcPixel( m_cmap
);
282 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
284 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
287 // By default, draw transparently
288 GrSetGCUseBackground((GC
) m_textGC
, FALSE
);
292 m_pen
.GetColour().CalcPixel( m_cmap
);
293 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
294 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
296 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
299 m_brush
.GetColour().CalcPixel( m_cmap
);
300 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
301 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
303 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
306 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
307 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
309 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
312 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
313 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
314 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
317 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
318 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
319 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
320 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
324 int xscreen
= DefaultScreen( (Display
*) m_display
);
325 Window xroot
= RootWindow( (Display
*) m_display
, xscreen
);
327 hatch_bitmap
= hatches
;
328 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, bdiag_bits
, bdiag_width
, bdiag_height
);
329 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cdiag_bits
, cdiag_width
, cdiag_height
);
330 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, fdiag_bits
, fdiag_width
, fdiag_height
);
331 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cross_bits
, cross_width
, cross_height
);
332 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, horiz_bits
, horiz_width
, horiz_height
);
333 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, verti_bits
, verti_width
, verti_height
);
337 void wxWindowDC::DoGetSize( int* width
, int* height
) const
339 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
341 m_owner
->GetSize(width
, height
);
344 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
345 const wxColour
& col
, int style
);
347 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
348 const wxColour
& col
, int style
)
350 return wxDoFloodFill(this, x
, y
, col
, style
);
353 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
355 // Generic (and therefore rather inefficient) method.
356 // Could be improved.
358 wxBitmap
bitmap(1, 1);
359 memdc
.SelectObject(bitmap
);
360 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
361 memdc
.SelectObject(wxNullBitmap
);
362 wxImage
image(bitmap
.ConvertToImage());
363 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
367 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
369 wxCHECK_RET( Ok(), wxT("invalid window dc") );
371 if (m_pen
.GetStyle() != wxTRANSPARENT
)
375 // This hack is for the iPaq: XDrawLine draws
376 // nothing, whereas XDrawLines works...
382 DrawLines( 2, points
, 0, 0 );
384 // XDrawLine( (Display*) m_display, (Window) m_window,
385 // (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
388 CalcBoundingBox(x1
, y1
);
389 CalcBoundingBox(x2
, y2
);
393 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
395 wxCHECK_RET( Ok(), wxT("invalid window dc") );
397 if (m_pen
.GetStyle() != wxTRANSPARENT
)
402 wxCoord xx
= XLOG2DEV(x
);
403 wxCoord yy
= YLOG2DEV(y
);
406 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
407 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
408 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
409 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
414 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
416 wxCHECK_RET( Ok(), wxT("invalid window dc") );
418 wxCoord xx1
= XLOG2DEV(x1
);
419 wxCoord yy1
= YLOG2DEV(y1
);
420 wxCoord xx2
= XLOG2DEV(x2
);
421 wxCoord yy2
= YLOG2DEV(y2
);
422 wxCoord xxc
= XLOG2DEV(xc
);
423 wxCoord yyc
= YLOG2DEV(yc
);
424 double dx
= xx1
- xxc
;
425 double dy
= yy1
- yyc
;
426 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
427 wxCoord r
= (wxCoord
)radius
;
428 double radius1
, radius2
;
430 if (xx1
== xx2
&& yy1
== yy2
)
438 radius1
= radius2
= 0.0;
442 radius1
= (xx1
- xxc
== 0) ?
443 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
444 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
445 radius2
= (xx2
- xxc
== 0) ?
446 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
447 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
449 wxCoord alpha1
= wxCoord(radius1
* 64.0);
450 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
451 while (alpha2
<= 0) alpha2
+= 360*64;
452 while (alpha1
> 360*64) alpha1
-= 360*64;
456 if (m_brush
.GetStyle() != wxTRANSPARENT
)
458 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
460 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
461 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
462 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
464 XFillArc( (Display
*) m_display
, (Window
) m_window
,
465 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
467 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
469 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
471 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
472 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
474 XFillArc( (Display
*) m_display
, (Window
) m_window
,
475 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
477 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
479 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
481 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
482 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
484 XFillArc( (Display
*) m_display
, (Window
) m_window
,
485 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
487 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
489 if (m_brush
.GetStyle() == wxSTIPPLE
)
491 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
492 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
493 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
495 XFillArc( (Display
*) m_display
, (Window
) m_window
,
496 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
498 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
502 XFillArc( (Display
*) m_display
, (Window
) m_window
,
503 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
507 if (m_pen
.GetStyle() != wxTRANSPARENT
)
509 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
510 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
512 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
513 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
515 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
516 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
520 CalcBoundingBox (x1
, y1
);
521 CalcBoundingBox (x2
, y2
);
524 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
526 wxCHECK_RET( Ok(), wxT("invalid window dc") );
528 wxCoord xx
= XLOG2DEV(x
);
529 wxCoord yy
= YLOG2DEV(y
);
530 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
531 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
533 // CMB: handle -ve width and/or height
534 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
535 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
539 wxCoord start
= wxCoord(sa
* 64.0);
540 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
542 if (m_brush
.GetStyle() != wxTRANSPARENT
)
544 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
546 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
547 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
548 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
550 XFillArc( (Display
*) m_display
, (Window
) m_window
,
551 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
553 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
555 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
557 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
558 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
560 XFillArc( (Display
*) m_display
, (Window
) m_window
,
561 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
563 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
565 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
567 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
568 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
570 XFillArc( (Display
*) m_display
, (Window
) m_window
,
571 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
573 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
575 if (m_brush
.GetStyle() == wxSTIPPLE
)
577 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
578 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
579 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
581 XFillArc( (Display
*) m_display
, (Window
) m_window
,
582 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
584 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
588 XFillArc( (Display
*) m_display
, (Window
) m_window
,
589 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
593 if (m_pen
.GetStyle() != wxTRANSPARENT
)
595 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
596 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
600 CalcBoundingBox (x
, y
);
601 CalcBoundingBox (x
+ width
, y
+ height
);
604 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
606 wxCHECK_RET( Ok(), wxT("invalid window dc") );
608 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
)
609 XDrawPoint( (Display
*) m_display
, (Window
) m_window
,
610 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
612 CalcBoundingBox (x
, y
);
615 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
617 wxCHECK_RET( Ok(), wxT("invalid window dc") );
619 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
622 XPoint
*xpoints
= new XPoint
[n
];
623 for (int i
= 0; i
< n
; i
++)
625 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
626 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
628 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
630 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
, 0 );
635 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
636 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
638 wxCHECK_RET( Ok(), wxT("invalid window dc") );
642 XPoint
*xpoints
= new XPoint
[n
+ 1];
644 for (i
= 0; i
< n
; i
++)
646 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
647 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
649 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
654 if (m_brush
.GetStyle() != wxTRANSPARENT
)
657 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
659 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
660 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
661 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
663 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
664 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
666 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
668 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
670 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
671 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
673 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
674 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
676 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
678 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
680 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
681 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
683 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
684 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
686 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
688 if (m_brush
.GetStyle() == wxSTIPPLE
)
690 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
691 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
692 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
694 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
695 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
697 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
701 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
702 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
706 if (m_pen
.GetStyle () != wxTRANSPARENT
)
708 // Close figure for XDrawLines
709 xpoints
[i
].x
= xpoints
[0].x
;
710 xpoints
[i
].y
= xpoints
[0].y
;
712 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
719 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
721 wxCHECK_RET( Ok(), wxT("invalid window dc") );
723 wxCoord xx
= XLOG2DEV(x
);
724 wxCoord yy
= YLOG2DEV(y
);
725 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
726 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
728 // CMB: draw nothing if transformed w or h is 0
729 if (ww
== 0 || hh
== 0) return;
731 // CMB: handle -ve width and/or height
732 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
733 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
737 if (m_brush
.GetStyle() != wxTRANSPARENT
)
739 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
741 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
742 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
743 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
745 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
746 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
748 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
750 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
752 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
753 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
755 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
756 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
758 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
760 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
762 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
763 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
765 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
766 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
768 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
770 if (m_brush
.GetStyle() == wxSTIPPLE
)
772 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
773 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
774 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
776 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
777 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
779 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
783 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
784 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
788 if (m_pen
.GetStyle () != wxTRANSPARENT
)
790 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
791 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
795 CalcBoundingBox( x
, y
);
796 CalcBoundingBox( x
+ width
, y
+ height
);
799 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
801 wxCHECK_RET( Ok(), wxT("invalid window dc") );
803 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
805 wxCoord xx
= XLOG2DEV(x
);
806 wxCoord yy
= YLOG2DEV(y
);
807 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
808 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
809 wxCoord rr
= XLOG2DEVREL((wxCoord
)radius
);
811 // CMB: handle -ve width and/or height
812 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
813 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
815 // CMB: if radius is zero use DrawRectangle() instead to avoid
816 // X drawing errors with small radii
819 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
820 (GC
) m_penGC
, x
, y
, width
, height
);
824 // CMB: draw nothing if transformed w or h is 0
825 if (ww
== 0 || hh
== 0) return;
827 // CMB: adjust size if outline is drawn otherwise the result is
828 // 1 pixel too wide and high
829 if (m_pen
.GetStyle() != wxTRANSPARENT
)
837 // CMB: ensure dd is not larger than rectangle otherwise we
838 // get an hour glass shape
840 if (dd
> ww
) dd
= ww
;
841 if (dd
> hh
) dd
= hh
;
844 if (m_brush
.GetStyle() != wxTRANSPARENT
)
846 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
848 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
849 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
850 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
851 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
852 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
853 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
854 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
855 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
856 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
857 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0);
859 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
861 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
862 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
863 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
864 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
865 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
866 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
867 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
868 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
870 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
872 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
873 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
874 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
875 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
876 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
877 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
878 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
879 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
881 if (m_brush
.GetStyle() == wxSTIPPLE
)
883 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
884 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
885 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
886 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
887 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
888 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
889 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
890 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
891 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
892 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
896 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
897 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
898 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
899 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
900 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
901 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
904 if (m_pen
.GetStyle() != wxTRANSPARENT
)
906 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy
);
907 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
908 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr
);
909 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr
);
910 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
911 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
912 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
913 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
917 // this ignores the radius
918 CalcBoundingBox( x
, y
);
919 CalcBoundingBox( x
+ width
, y
+ height
);
922 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
924 wxCHECK_RET( Ok(), wxT("invalid window dc") );
926 wxCoord xx
= XLOG2DEV(x
);
927 wxCoord yy
= YLOG2DEV(y
);
928 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
929 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
931 // CMB: handle -ve width and/or height
932 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
933 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
937 if (m_brush
.GetStyle() != wxTRANSPARENT
)
939 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
941 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
942 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
943 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
945 XFillArc( (Display
*) m_display
, (Window
) m_window
,
946 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
948 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
950 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
952 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
953 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
955 XFillArc( (Display
*) m_display
, (Window
) m_window
,
956 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
958 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
960 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
962 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
963 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
965 XFillArc( (Display
*) m_display
, (Window
) m_window
,
966 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
968 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
970 if (m_brush
.GetStyle() == wxSTIPPLE
)
972 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
973 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
974 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
976 XFillArc( (Display
*) m_display
, (Window
) m_window
,
977 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
979 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
983 XFillArc( (Display
*) m_display
, (Window
) m_window
,
984 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
988 if (m_pen
.GetStyle () != wxTRANSPARENT
)
990 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
991 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
995 CalcBoundingBox( x
, y
);
996 CalcBoundingBox( x
+ width
, y
+ height
);
999 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
1001 DoDrawBitmap(icon
, x
, y
, true);
1005 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1006 wxCoord x
, wxCoord y
,
1009 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1011 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1013 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1015 /* scale/translate size and position */
1016 int xx
= XLOG2DEV(x
);
1017 int yy
= YLOG2DEV(y
);
1019 int w
= bitmap
.GetWidth();
1020 int h
= bitmap
.GetHeight();
1022 CalcBoundingBox( x
, y
);
1023 CalcBoundingBox( x
+ w
, y
+ h
);
1025 if (!m_window
) return;
1027 int ww
= XLOG2DEVREL(w
);
1028 int hh
= YLOG2DEVREL(h
);
1030 /* compare to current clipping region */
1031 if (!m_currentClippingRegion
.IsNull())
1033 wxRegion
tmp( xx
,yy
,ww
,hh
);
1034 tmp
.Intersect( m_currentClippingRegion
);
1039 /* scale bitmap if required */
1040 wxBitmap use_bitmap
;
1041 if ((w
!= ww
) || (h
!= hh
))
1043 wxImage
image( bitmap
.ConvertToImage() );
1044 image
.Rescale( ww
, hh
);
1047 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1054 use_bitmap
= bitmap
;
1057 /* apply mask if any */
1058 WXPixmap mask
= NULL
;
1059 if (use_bitmap
.GetMask())
1060 mask
= use_bitmap
.GetMask()->GetBitmap();
1062 if (useMask
&& mask
)
1064 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
1065 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
1066 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
1068 GrSetGCUseBackground(gc
, FALSE
);
1069 GrSetGCMode(gc
, GR_MODE_COPY
);
1071 // This code assumes that background and foreground
1072 // colours are used in ROPs, like in MSW.
1073 // Not sure if this is true.
1075 // Copy destination to buffer.
1076 // In DoBlit, we need this step because Blit has
1077 // a ROP argument. Here, we don't need it.
1078 // In DoBlit, we may be able to eliminate this step
1079 // if we check if the rop = copy
1081 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_window
,
1082 0, 0, GR_MODE_COPY
);
1085 // Copy src to buffer using selected raster op (none selected
1086 // in DrawBitmap, so just use Gxcopy)
1087 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
1088 0, 0, GR_MODE_COPY
);
1090 // Set masked area in buffer to BLACK (pixel value 0)
1091 GrSetGCBackground(gc
, WHITE
);
1092 GrSetGCForeground(gc
, BLACK
);
1093 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
1096 // set unmasked area in dest to BLACK
1097 GrSetGCBackground(gc
, BLACK
);
1098 GrSetGCForeground(gc
, WHITE
);
1099 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
1102 // OR buffer to dest
1103 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
1107 GrDestroyWindow(bufPixmap
);
1110 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1111 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1113 /* remove mask again if any */
1114 if (useMask
&& mask
)
1116 if (!m_currentClippingRegion
.IsNull())
1117 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1124 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1125 wxCoord x
, wxCoord y
,
1128 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1130 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1132 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1134 // scale/translate size and position
1135 int xx
= XLOG2DEV(x
);
1136 int yy
= YLOG2DEV(y
);
1138 int w
= bitmap
.GetWidth();
1139 int h
= bitmap
.GetHeight();
1141 CalcBoundingBox( x
, y
);
1142 CalcBoundingBox( x
+ w
, y
+ h
);
1144 if (!m_window
) return;
1146 int ww
= XLOG2DEVREL(w
);
1147 int hh
= YLOG2DEVREL(h
);
1149 // compare to current clipping region
1150 if (!m_currentClippingRegion
.IsNull())
1152 wxRegion
tmp( xx
,yy
,ww
,hh
);
1153 tmp
.Intersect( m_currentClippingRegion
);
1158 // scale bitmap if required
1159 wxBitmap use_bitmap
;
1160 if ((w
!= ww
) || (h
!= hh
))
1162 wxImage
image( bitmap
.ConvertToImage() );
1163 image
.Rescale( ww
, hh
);
1166 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1173 use_bitmap
= bitmap
;
1176 // apply mask if any
1177 WXPixmap mask
= NULL
;
1178 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1180 bool setClipMask
= false;
1182 if (!m_currentClippingRegion
.IsNull() || (useMask
&& mask
))
1184 // XSetClipMask() call is necessary (because of clip region and/or transparent mask)
1186 Pixmap new_pixmap
= 0;
1188 if (!m_currentClippingRegion
.IsNull())
1190 // clipping necessary => create new_pixmap
1191 Display
*xdisplay
= (Display
*) m_display
;
1192 int xscreen
= DefaultScreen( xdisplay
);
1193 Window xroot
= RootWindow( xdisplay
, xscreen
);
1195 new_pixmap
= XCreatePixmap( xdisplay
, xroot
, ww
, hh
, 1 );
1196 GC gc
= XCreateGC( xdisplay
, new_pixmap
, 0, NULL
);
1198 XSetForeground( xdisplay
, gc
, BlackPixel(xdisplay
,xscreen
) );
1200 XSetFillStyle( xdisplay
, gc
, FillSolid
);
1201 XFillRectangle( xdisplay
, new_pixmap
, gc
, 0, 0, ww
, hh
);
1203 XSetForeground( xdisplay
, gc
, WhitePixel(xdisplay
,xscreen
) );
1205 if (useMask
&& mask
)
1207 // transparent mask => call XSetStipple
1208 XSetFillStyle( xdisplay
, gc
, FillStippled
);
1209 XSetTSOrigin( xdisplay
, gc
, 0, 0);
1210 XSetStipple( xdisplay
, gc
, (Pixmap
) mask
);
1213 wxCoord clip_x
, clip_y
, clip_w
, clip_h
;
1214 m_currentClippingRegion
.GetBox(clip_x
, clip_y
, clip_w
, clip_h
);
1215 XFillRectangle( xdisplay
, new_pixmap
, gc
, clip_x
-xx
, clip_y
-yy
, clip_w
, clip_h
);
1217 XFreeGC( xdisplay
, gc
);
1223 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, new_pixmap
);
1225 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1226 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1231 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, new_pixmap
);
1233 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1234 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1238 XFreePixmap( (Display
*) m_display
, new_pixmap
);
1241 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1242 // drawing a mono-bitmap (XBitmap) we use the current text GC
1244 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1245 (GC
) m_textGC
, 0, 0, ww
, hh
, xx
, yy
, 1 );
1247 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1248 (GC
) m_penGC
, 0, 0, ww
, hh
, xx
, yy
);
1250 // remove mask again if any
1255 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1256 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1257 if (!m_currentClippingRegion
.IsNull())
1258 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1262 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1263 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1264 if (!m_currentClippingRegion
.IsNull())
1265 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1270 // wxUSE_NANOX/!wxUSE_NANOX
1272 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1273 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1274 wxCoord xsrcMask
, wxCoord ysrcMask
)
1276 /* this is the nth try to get this utterly useless function to
1277 work. it now completely ignores the scaling or translation
1278 of the source dc, but scales correctly on the target dc and
1279 knows about possible mask information in a memory dc. */
1281 wxCHECK_MSG( Ok(), false, wxT("invalid window dc") );
1283 wxCHECK_MSG( source
, false, wxT("invalid source dc") );
1285 if (!m_window
) return false;
1287 // transform the source DC coords to the device ones
1288 xsrc
= source
->XLOG2DEV(xsrc
);
1289 ysrc
= source
->YLOG2DEV(ysrc
);
1291 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1292 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1294 bool use_bitmap_method
= false;
1295 bool is_mono
= false;
1297 // TODO: use the mask origin when drawing transparently
1298 if (xsrcMask
== -1 && ysrcMask
== -1)
1304 if (srcDC
->m_isMemDC
)
1306 if (!memDC
->m_selected
.Ok()) return false;
1308 /* we use the "XCopyArea" way to copy a memory dc into
1309 y different window if the memory dc BOTH
1310 a) doesn't have any mask or its mask isn't used
1314 if (useMask
&& (memDC
->m_selected
.GetMask()))
1316 /* we HAVE TO use the direct way for memory dcs
1317 that have mask since the XCopyArea doesn't know
1319 use_bitmap_method
= true;
1321 else if (memDC
->m_selected
.GetDepth() == 1)
1323 /* we HAVE TO use the direct way for memory dcs
1324 that are bitmaps because XCopyArea doesn't cope
1325 with different bit depths */
1327 use_bitmap_method
= true;
1329 else if ((xsrc
== 0) && (ysrc
== 0) &&
1330 (width
== memDC
->m_selected
.GetWidth()) &&
1331 (height
== memDC
->m_selected
.GetHeight()))
1333 /* we SHOULD use the direct way if all of the bitmap
1334 in the memory dc is copied in which case XCopyArea
1335 wouldn't be able able to boost performace by reducing
1336 the area to be scaled */
1337 use_bitmap_method
= true;
1341 use_bitmap_method
= false;
1345 CalcBoundingBox( xdest
, ydest
);
1346 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1348 // scale/translate size and position
1349 wxCoord xx
= XLOG2DEV(xdest
);
1350 wxCoord yy
= YLOG2DEV(ydest
);
1352 wxCoord ww
= XLOG2DEVREL(width
);
1353 wxCoord hh
= YLOG2DEVREL(height
);
1355 // compare to current clipping region
1356 if (!m_currentClippingRegion
.IsNull())
1358 wxRegion
tmp( xx
,yy
,ww
,hh
);
1359 tmp
.Intersect( m_currentClippingRegion
);
1364 int old_logical_func
= m_logicalFunction
;
1365 SetLogicalFunction( logical_func
);
1367 if (use_bitmap_method
)
1369 // scale/translate bitmap size
1370 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1371 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1373 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1374 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1376 // scale bitmap if required
1377 wxBitmap use_bitmap
;
1379 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1381 wxImage
image( memDC
->m_selected
.ConvertToImage() );
1382 image
= image
.Scale( bm_ww
, bm_hh
);
1386 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1393 use_bitmap
= memDC
->m_selected
;
1396 // apply mask if any
1397 WXPixmap mask
= NULL
;
1398 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1400 if (useMask
&& mask
)
1402 WXPixmap new_mask
= NULL
;
1404 if (!m_currentClippingRegion
.IsNull())
1407 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1408 GdkGC
*gc
= gdk_gc_new( new_mask
);
1410 gdk_gc_set_foreground( gc
, &col
);
1411 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1413 gdk_gc_set_background( gc
, &col
);
1415 gdk_gc_set_foreground( gc
, &col
);
1416 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1417 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1418 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1419 gdk_gc_set_stipple( gc
, mask
);
1420 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1427 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1429 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1430 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1435 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1437 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1438 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1442 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1445 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1446 // drawing a mono-bitmap (XBitmap) we use the current text GC
1449 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1450 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1452 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1453 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1455 // remove mask again if any
1456 if (useMask
&& mask
)
1460 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1461 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1462 if (!m_currentClippingRegion
.IsNull())
1463 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1467 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1468 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1469 if (!m_currentClippingRegion
.IsNull())
1470 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1474 else // use_bitmap_method
1476 if ((width
!= ww
) || (height
!= hh
))
1478 /* Draw source window into a bitmap as we cannot scale
1479 a window in contrast to a bitmap. this would actually
1480 work with memory dcs as well, but we'd lose the mask
1481 information and waste one step in this process since
1482 a memory already has a bitmap. all this is slightly
1483 inefficient as we could take an XImage directly from
1484 an X window, but we'd then also have to care that
1485 the window is not outside the screen (in which case
1486 we'd get a BadMatch or what not).
1487 Is a double XGetImage and combined XGetPixel and
1488 XPutPixel really faster? I'm not sure. look at wxXt
1489 for a different implementation of the same problem. */
1491 wxBitmap
bitmap( width
, height
);
1493 // copy including child window contents
1494 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1495 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) bitmap
.GetPixmap(),
1496 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1497 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1500 wxImage
image( bitmap
.ConvertToImage() );
1501 image
= image
.Scale( ww
, hh
);
1503 // convert to bitmap
1506 // draw scaled bitmap
1507 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_window
,
1508 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1512 // No scaling and not a memory dc with a mask either
1514 // copy including child window contents
1515 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1516 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) m_window
,
1517 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1518 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1522 SetLogicalFunction( old_logical_func
);
1527 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1529 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1531 if (!m_window
) return;
1537 PangoLayout
*layout
= pango_layout_new(m_context
);
1538 pango_layout_set_font_description(layout
, m_fontdesc
);
1540 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1541 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1545 pango_layout_get_pixel_size(layout
, &w
, &h
);
1550 x11_draw_layout( (Drawable
) m_window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1552 g_object_unref( G_OBJECT( layout
) );
1554 CalcBoundingBox (x
+ width
, y
+ height
);
1555 CalcBoundingBox (x
, y
);
1557 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1559 wxCHECK_RET( xfont
, wxT("invalid font") );
1561 // First draw a rectangle representing the text background, if a text
1562 // background is specified
1563 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1565 // Since X draws from the baseline of the text, must add the text height
1570 int direction
, descent
;
1572 slen
= strlen(text
);
1573 XCharStruct overall_return
;
1575 (void)XTextExtents(xfont
, (char*) text
.c_str(), slen
, &direction
,
1576 &ascent
, &descent
, &overall_return
);
1578 cx
= overall_return
.width
;
1579 cy
= ascent
+ descent
;
1580 m_textBackgroundColour
.CalcPixel(m_cmap
);
1581 m_textForegroundColour
.CalcPixel(m_cmap
);
1582 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1583 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
1584 (GC
) m_textGC
, x
, y
, cx
, cy
);
1585 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1589 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1591 // This may be a test for whether the font is 16-bit, but it also
1592 // seems to fail for valid 8-bit fonts too.
1593 if (1) // (xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
1596 XDrawString( (Display
*) m_display
, (Window
) m_window
,
1597 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.Len() );
1601 if (m_font
.GetUnderlined())
1603 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1604 if (font
->descent
> 0) ul_y
++;
1605 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1608 width
= wxCoord(width
/ m_scaleX
);
1609 height
= wxCoord(height
/ m_scaleY
);
1611 CalcBoundingBox (x
+ width
, y
+ height
);
1612 CalcBoundingBox (x
, y
);
1617 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
, double angle
)
1622 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1623 wxCoord
*descent
, wxCoord
*externalLeading
,
1624 wxFont
*font
) const
1626 wxCHECK_RET( Ok(), wxT("invalid dc") );
1630 if (width
) (*width
) = 0;
1631 if (height
) (*height
) = 0;
1636 PangoLayout
*layout
= pango_layout_new( m_context
);
1639 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1641 pango_layout_set_font_description(layout
, m_fontdesc
);
1643 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1644 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1648 pango_layout_get_pixel_size(layout
, &w
, &h
);
1650 if (width
) (*width
) = (wxCoord
) w
;
1651 if (height
) (*height
) = (wxCoord
) h
;
1654 // Do something about metrics here. TODO.
1657 if (externalLeading
) (*externalLeading
) = 0; // ??
1659 g_object_unref( G_OBJECT( layout
) );
1661 wxFont fontToUse
= m_font
;
1662 if (font
) fontToUse
= *font
;
1664 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
1666 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1668 wxCHECK_RET( xfont
, wxT("invalid font") );
1670 int direction
, ascent
, descent2
;
1671 XCharStruct overall
;
1673 XTextExtents( xfont
, (char*) string
.c_str(), string
.Len(), &direction
,
1674 &ascent
, &descent2
, &overall
);
1677 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1679 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1681 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1682 if (externalLeading
)
1683 *externalLeading
= 0; // ??
1687 wxCoord
wxWindowDC::GetCharWidth() const
1689 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1692 PangoLayout
*layout
= pango_layout_new( m_context
);
1695 pango_layout_set_font_description(layout
, m_fontdesc
);
1697 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1699 pango_layout_set_text(layout
, "H", 1 );
1701 pango_layout_get_pixel_size(layout
, &w
, &h
);
1702 g_object_unref( G_OBJECT( layout
) );
1706 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1708 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1710 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1712 int direction
, ascent
, descent
;
1713 XCharStruct overall
;
1715 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1717 return (wxCoord
)(overall
.width
/ m_scaleX
);
1721 wxCoord
wxWindowDC::GetCharHeight() const
1723 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1726 PangoLayout
*layout
= pango_layout_new( m_context
);
1729 pango_layout_set_font_description(layout
, m_fontdesc
);
1731 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1733 pango_layout_set_text(layout
, "H", 1 );
1735 pango_layout_get_pixel_size(layout
, &w
, &h
);
1736 g_object_unref( G_OBJECT( layout
) );
1740 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1742 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1744 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1746 int direction
, ascent
, descent
;
1747 XCharStruct overall
;
1749 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1751 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1755 void wxWindowDC::Clear()
1757 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1759 if (!m_window
) return;
1761 /* - we either are a memory dc or have a window as the
1762 owner. anything else shouldn't happen.
1763 - we don't use gdk_window_clear() as we don't set
1764 the window's background colour anymore. it is too
1765 much pain to keep the DC's and the window's back-
1766 ground colour in synch. */
1771 m_owner
->GetSize( &width
, &height
);
1772 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1779 GetSize( &width
, &height
);
1780 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1785 void wxWindowDC::SetFont( const wxFont
&font
)
1787 wxCHECK_RET( Ok(), wxT("invalid dc") );
1794 m_fontdesc
= font
.GetNativeFontInfo()->description
;
1798 void wxWindowDC::SetPen( const wxPen
&pen
)
1800 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1802 if (m_pen
== pen
) return;
1806 if (!m_pen
.Ok()) return;
1808 if (!m_window
) return;
1810 int width
= m_pen
.GetWidth();
1813 // CMB: if width is non-zero scale it with the dc
1818 // X doesn't allow different width in x and y and so we take
1821 ( fabs((double) XLOG2DEVREL(width
)) +
1822 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1826 static const wxX11Dash dotted
[] = {1, 1};
1827 static const wxX11Dash short_dashed
[] = {2, 2};
1828 static const wxX11Dash long_dashed
[] = {2, 4};
1829 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1831 // We express dash pattern in pen width unit, so we are
1832 // independent of zoom factor and so on...
1834 const wxX11Dash
*req_dash
;
1836 int lineStyle
= LineSolid
;
1837 switch (m_pen
.GetStyle())
1841 lineStyle
= LineOnOffDash
;
1842 req_nb_dash
= m_pen
.GetDashCount();
1843 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1848 lineStyle
= LineOnOffDash
;
1855 lineStyle
= LineOnOffDash
;
1857 req_dash
= long_dashed
;
1862 lineStyle
= LineOnOffDash
;
1864 req_dash
= short_dashed
;
1869 // lineStyle = LineDoubleDash;
1870 lineStyle
= LineOnOffDash
;
1872 req_dash
= dotted_dashed
;
1877 case wxSTIPPLE_MASK_OPAQUE
:
1882 lineStyle
= LineSolid
;
1883 req_dash
= (wxX11Dash
*)NULL
;
1889 int capStyle
= CapRound
;
1890 switch (m_pen
.GetCap())
1892 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1893 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1900 capStyle
= CapNotLast
;
1904 capStyle
= CapRound
;
1910 int joinStyle
= JoinRound
;
1911 switch (m_pen
.GetJoin())
1913 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1914 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1916 default: { joinStyle
= JoinRound
; break; }
1919 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1921 m_pen
.GetColour().CalcPixel( m_cmap
);
1922 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1925 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1927 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1929 if (m_brush
== brush
) return;
1933 if (!m_brush
.Ok()) return;
1935 if (!m_window
) return;
1937 m_brush
.GetColour().CalcPixel( m_cmap
);
1938 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1940 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1942 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1944 if (m_brush
.GetStipple()->GetPixmap())
1946 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1947 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1951 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1952 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1956 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1958 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1959 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1962 if (m_brush
.IsHatch())
1964 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1965 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1966 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1970 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1972 /* CMB 21/7/98: Added SetBackground. Sets background brush
1973 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1975 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1977 if (m_backgroundBrush
== brush
) return;
1979 m_backgroundBrush
= brush
;
1981 if (!m_backgroundBrush
.Ok()) return;
1983 if (!m_window
) return;
1985 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1986 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1987 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1988 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1989 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1991 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1993 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1995 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1997 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1998 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
2002 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2003 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
2007 if (m_backgroundBrush
.IsHatch())
2009 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2010 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
2011 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
2015 void wxWindowDC::SetLogicalFunction( int function
)
2017 wxCHECK_RET( Ok(), wxT("invalid dc") );
2021 if (m_logicalFunction
== function
)
2024 // VZ: shouldn't this be a CHECK?
2031 x_function
= GXclear
;
2037 x_function
= GXinvert
;
2040 x_function
= GXorReverse
;
2043 x_function
= GXandReverse
;
2052 x_function
= GXandInverted
;
2055 x_function
= GXnoop
;
2061 x_function
= GXequiv
;
2064 x_function
= GXcopyInverted
;
2067 x_function
= GXorInverted
;
2070 x_function
= GXnand
;
2077 x_function
= GXcopy
;
2081 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2082 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2084 // to stay compatible with wxMSW, we don't apply ROPs to the text
2085 // operations (i.e. DrawText/DrawRotatedText).
2086 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2087 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2089 m_logicalFunction
= function
;
2092 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2094 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2096 // don't set m_textForegroundColour to an invalid colour as we'd crash
2097 // later then (we use m_textForegroundColour.GetColor() without checking
2099 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
2102 m_textForegroundColour
= col
;
2106 m_textForegroundColour
.CalcPixel( m_cmap
);
2107 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2111 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2113 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2116 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
2119 m_textBackgroundColour
= col
;
2123 m_textBackgroundColour
.CalcPixel( m_cmap
);
2124 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2128 void wxWindowDC::SetBackgroundMode( int mode
)
2130 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2132 m_backgroundMode
= mode
;
2135 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2138 if (!m_window
) return;
2140 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2141 // transparent/solid background mode
2143 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2145 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2146 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2150 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2156 /* Use GetXColormap */
2157 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2158 (Colormap
) palette
.GetXColormap());
2160 /* Use wxGetMainColormap */
2161 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2162 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2167 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2169 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2171 if (!m_window
) return;
2174 rect
.x
= XLOG2DEV(x
);
2175 rect
.y
= YLOG2DEV(y
);
2176 rect
.width
= XLOG2DEVREL(width
);
2177 rect
.height
= YLOG2DEVREL(height
);
2179 if (!m_currentClippingRegion
.IsNull())
2180 m_currentClippingRegion
.Intersect( rect
);
2182 m_currentClippingRegion
.Union( rect
);
2184 #if USE_PAINT_REGION
2185 if (!m_paintClippingRegion
.IsNull())
2186 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2189 wxCoord xx
, yy
, ww
, hh
;
2190 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2191 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2193 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2194 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2195 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2196 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2199 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2201 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2205 DestroyClippingRegion();
2209 if (!m_window
) return;
2211 if (!m_currentClippingRegion
.IsNull())
2212 m_currentClippingRegion
.Intersect( region
);
2214 m_currentClippingRegion
.Union( region
);
2216 #if USE_PAINT_REGION
2217 if (!m_paintClippingRegion
.IsNull())
2218 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2221 wxCoord xx
, yy
, ww
, hh
;
2222 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2223 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2225 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2226 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2227 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2228 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2231 void wxWindowDC::DestroyClippingRegion()
2233 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2235 wxDC::DestroyClippingRegion();
2237 m_currentClippingRegion
.Clear();
2239 #if USE_PAINT_REGION
2240 if (!m_paintClippingRegion
.IsEmpty())
2241 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2244 if (!m_window
) return;
2246 if (m_currentClippingRegion
.IsEmpty())
2248 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2249 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2250 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2251 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2255 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2256 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2257 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2258 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2262 void wxWindowDC::Destroy()
2264 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2266 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2268 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2270 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2274 void wxWindowDC::ComputeScaleAndOrigin()
2276 /* CMB: copy scale to see if it changes */
2277 double origScaleX
= m_scaleX
;
2278 double origScaleY
= m_scaleY
;
2280 wxDC::ComputeScaleAndOrigin();
2282 /* CMB: if scale has changed call SetPen to recalulate the line width */
2283 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2286 /* this is a bit artificial, but we need to force wxDC to think
2287 the pen has changed */
2294 wxSize
wxWindowDC::GetPPI() const
2296 return wxSize(100, 100);
2299 int wxWindowDC::GetDepth() const
2301 wxFAIL_MSG(wxT("not implemented"));
2306 //-----------------------------------------------------------------------------
2308 //-----------------------------------------------------------------------------
2310 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2312 wxClientDC::wxClientDC( wxWindow
*window
)
2313 : wxWindowDC( window
)
2315 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2317 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2319 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2320 if (m_window
== (WXWindow
*) window
->GetMainWindow())
2322 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2323 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2324 wxSize size
= window
->GetClientSize();
2325 SetClippingRegion(wxPoint(0, 0), size
);
2329 void wxClientDC::DoGetSize(int *width
, int *height
) const
2331 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2333 m_owner
->GetClientSize( width
, height
);
2336 // ----------------------------------------------------------------------------
2338 // ----------------------------------------------------------------------------
2340 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2342 wxPaintDC::wxPaintDC(wxWindow
* window
)
2343 : wxClientDC(window
)
2345 #if USE_PAINT_REGION
2346 if (!window
->GetClipPaintRegion())
2349 m_paintClippingRegion
= window
->GetUpdateRegion();
2350 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2353 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2355 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2356 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2357 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2358 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2360 #endif // USE_PAINT_REGION
2363 // ----------------------------------------------------------------------------
2365 // ----------------------------------------------------------------------------
2367 class wxDCModule
: public wxModule
2374 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2377 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)
2379 bool wxDCModule::OnInit()
2385 void wxDCModule::OnExit()