1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/x11/dcclient.cpp
3 // Purpose: wxClientDC class
4 // Author: Julian Smart, Robert Roebling
8 // Copyright: (c) Julian Smart, Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // for compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
15 #include "wx/dcclient.h"
19 #include "wx/window.h"
20 #include "wx/dcmemory.h"
25 #include "wx/module.h"
26 #include "wx/fontutil.h"
28 #include "wx/x11/private.h"
32 #include "pango/pangox.h"
34 #include "pango/pangoxft.h"
37 #include "pango_x.cpp"
40 //-----------------------------------------------------------------------------
42 //-----------------------------------------------------------------------------
44 #define USE_PAINT_REGION 1
46 //-----------------------------------------------------------------------------
48 //-----------------------------------------------------------------------------
58 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH)
59 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH)
61 static Pixmap hatches
[num_hatches
];
62 static Pixmap
*hatch_bitmap
= (Pixmap
*) NULL
;
64 //-----------------------------------------------------------------------------
66 //-----------------------------------------------------------------------------
68 const double RAD2DEG
= 180.0 / M_PI
;
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
74 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
75 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
77 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
79 //-----------------------------------------------------------------------------
80 // Implement Pool of Graphic contexts. Creating them takes too much time.
81 //-----------------------------------------------------------------------------
83 #define GC_POOL_SIZE 200
109 static wxGC wxGCPool
[GC_POOL_SIZE
];
111 static void wxInitGCPool()
113 memset( wxGCPool
, 0, GC_POOL_SIZE
*sizeof(wxGC
) );
116 static void wxCleanUpGCPool()
118 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
120 if (wxGCPool
[i
].m_gc
)
121 XFreeGC( wxGlobalDisplay(), wxGCPool
[i
].m_gc
);
125 static GC
wxGetPoolGC( Window window
, wxPoolGCType type
)
127 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
129 if (!wxGCPool
[i
].m_gc
)
131 wxGCPool
[i
].m_gc
= XCreateGC( wxGlobalDisplay(), window
, 0, NULL
);
132 XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool
[i
].m_gc
, FALSE
);
133 wxGCPool
[i
].m_type
= type
;
134 wxGCPool
[i
].m_used
= false;
136 if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type
== type
))
138 wxGCPool
[i
].m_used
= true;
139 return wxGCPool
[i
].m_gc
;
143 wxFAIL_MSG( wxT("No GC available") );
148 static void wxFreePoolGC( GC gc
)
150 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
152 if (wxGCPool
[i
].m_gc
== gc
)
154 wxGCPool
[i
].m_used
= false;
159 wxFAIL_MSG( wxT("Wrong GC") );
162 // ----------------------------------------------------------------------------
164 // ----------------------------------------------------------------------------
166 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
168 wxWindowDC::wxWindowDC()
170 m_display
= (WXDisplay
*) NULL
;
171 m_penGC
= (WXGC
*) NULL
;
172 m_brushGC
= (WXGC
*) NULL
;
173 m_textGC
= (WXGC
*) NULL
;
174 m_bgGC
= (WXGC
*) NULL
;
175 m_cmap
= (WXColormap
*) NULL
;
177 m_isScreenDC
= false;
178 m_owner
= (wxWindow
*)NULL
;
181 m_context
= (PangoContext
*)NULL
;
182 m_fontdesc
= (PangoFontDescription
*)NULL
;
186 wxWindowDC::wxWindowDC( wxWindow
*window
)
188 wxASSERT_MSG( window
, wxT("DC needs a window") );
190 m_display
= (WXDisplay
*) NULL
;
191 m_penGC
= (WXGC
*) NULL
;
192 m_brushGC
= (WXGC
*) NULL
;
193 m_textGC
= (WXGC
*) NULL
;
194 m_bgGC
= (WXGC
*) NULL
;
195 m_cmap
= (WXColormap
*) NULL
;
196 m_owner
= (wxWindow
*)NULL
;
198 m_isScreenDC
= false;
199 m_font
= window
->GetFont();
201 m_window
= (WXWindow
*) window
->GetMainWindow();
206 // don't report problems
212 m_display
= (WXDisplay
*) wxGlobalDisplay();
215 m_context
= wxTheApp
->GetPangoContext();
216 m_fontdesc
= window
->GetFont().GetNativeFontInfo()->description
;
219 int screen
= DefaultScreen( (Display
*) m_display
);
220 m_cmap
= (WXColormap
) DefaultColormap( (Display
*) m_display
, screen
);
224 /* this must be done after SetUpDC, bacause SetUpDC calls the
225 repective SetBrush, SetPen, SetBackground etc functions
226 to set up the DC. SetBackground call m_owner->SetBackground
227 and this might not be desired as the standard dc background
228 is white whereas a window might assume gray to be the
229 standard (as e.g. wxStatusBar) */
234 wxWindowDC::~wxWindowDC()
239 void wxWindowDC::SetUpDC()
243 wxASSERT_MSG( !m_penGC
, wxT("GCs already created") );
247 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_SCREEN
);
248 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_SCREEN
);
249 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_SCREEN
);
250 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_SCREEN
);
253 if (m_isMemDC
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1))
255 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_MONO
);
256 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_MONO
);
257 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_MONO
);
258 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_MONO
);
262 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_COLOUR
);
263 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_COLOUR
);
264 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_COLOUR
);
265 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_COLOUR
);
268 /* background colour */
269 m_backgroundBrush
= *wxWHITE_BRUSH
;
270 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
271 unsigned long bg_col
= m_backgroundBrush
.GetColour().GetPixel();
273 m_textForegroundColour
= *wxBLACK
;
274 m_textBackgroundColour
= *wxWHITE
;
277 m_textForegroundColour
.CalcPixel( m_cmap
);
278 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
280 m_textBackgroundColour
.CalcPixel( m_cmap
);
281 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
283 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
286 // By default, draw transparently
287 GrSetGCUseBackground((GC
) m_textGC
, FALSE
);
291 m_pen
.GetColour().CalcPixel( m_cmap
);
292 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
293 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
295 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
298 m_brush
.GetColour().CalcPixel( m_cmap
);
299 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
300 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
302 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
305 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
306 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
308 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
311 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
312 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
313 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
316 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
317 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
318 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
319 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
323 int xscreen
= DefaultScreen( (Display
*) m_display
);
324 Window xroot
= RootWindow( (Display
*) m_display
, xscreen
);
326 hatch_bitmap
= hatches
;
327 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, bdiag_bits
, bdiag_width
, bdiag_height
);
328 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cdiag_bits
, cdiag_width
, cdiag_height
);
329 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, fdiag_bits
, fdiag_width
, fdiag_height
);
330 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cross_bits
, cross_width
, cross_height
);
331 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, horiz_bits
, horiz_width
, horiz_height
);
332 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, verti_bits
, verti_width
, verti_height
);
336 void wxWindowDC::DoGetSize( int* width
, int* height
) const
338 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
340 m_owner
->GetSize(width
, height
);
343 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
344 const wxColour
& col
, int style
);
346 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
347 const wxColour
& col
, int style
)
349 return wxDoFloodFill(this, x
, y
, col
, style
);
352 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
354 // Generic (and therefore rather inefficient) method.
355 // Could be improved.
357 wxBitmap
bitmap(1, 1);
358 memdc
.SelectObject(bitmap
);
359 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
360 memdc
.SelectObject(wxNullBitmap
);
361 wxImage
image(bitmap
.ConvertToImage());
362 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
366 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
368 wxCHECK_RET( Ok(), wxT("invalid window dc") );
370 if (m_pen
.GetStyle() != wxTRANSPARENT
)
374 // This hack is for the iPaq: XDrawLine draws
375 // nothing, whereas XDrawLines works...
381 DrawLines( 2, points
, 0, 0 );
383 // XDrawLine( (Display*) m_display, (Window) m_window,
384 // (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
387 CalcBoundingBox(x1
, y1
);
388 CalcBoundingBox(x2
, y2
);
392 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
394 wxCHECK_RET( Ok(), wxT("invalid window dc") );
396 if (m_pen
.GetStyle() != wxTRANSPARENT
)
401 wxCoord xx
= XLOG2DEV(x
);
402 wxCoord yy
= YLOG2DEV(y
);
405 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
406 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
407 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
408 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
413 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
415 wxCHECK_RET( Ok(), wxT("invalid window dc") );
417 wxCoord xx1
= XLOG2DEV(x1
);
418 wxCoord yy1
= YLOG2DEV(y1
);
419 wxCoord xx2
= XLOG2DEV(x2
);
420 wxCoord yy2
= YLOG2DEV(y2
);
421 wxCoord xxc
= XLOG2DEV(xc
);
422 wxCoord yyc
= YLOG2DEV(yc
);
423 double dx
= xx1
- xxc
;
424 double dy
= yy1
- yyc
;
425 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
426 wxCoord r
= (wxCoord
)radius
;
427 double radius1
, radius2
;
429 if (xx1
== xx2
&& yy1
== yy2
)
437 radius1
= radius2
= 0.0;
441 radius1
= (xx1
- xxc
== 0) ?
442 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
443 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
444 radius2
= (xx2
- xxc
== 0) ?
445 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
446 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
448 wxCoord alpha1
= wxCoord(radius1
* 64.0);
449 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
450 while (alpha2
<= 0) alpha2
+= 360*64;
451 while (alpha1
> 360*64) alpha1
-= 360*64;
455 if (m_brush
.GetStyle() != wxTRANSPARENT
)
457 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
459 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
460 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
461 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
463 XFillArc( (Display
*) m_display
, (Window
) m_window
,
464 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
466 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
468 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
470 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
471 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
473 XFillArc( (Display
*) m_display
, (Window
) m_window
,
474 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
476 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
478 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
480 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
481 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
483 XFillArc( (Display
*) m_display
, (Window
) m_window
,
484 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
486 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
488 if (m_brush
.GetStyle() == wxSTIPPLE
)
490 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
491 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
492 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
494 XFillArc( (Display
*) m_display
, (Window
) m_window
,
495 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
497 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
501 XFillArc( (Display
*) m_display
, (Window
) m_window
,
502 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
506 if (m_pen
.GetStyle() != wxTRANSPARENT
)
508 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
509 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
511 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
512 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
514 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
515 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
519 CalcBoundingBox (x1
, y1
);
520 CalcBoundingBox (x2
, y2
);
523 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
525 wxCHECK_RET( Ok(), wxT("invalid window dc") );
527 wxCoord xx
= XLOG2DEV(x
);
528 wxCoord yy
= YLOG2DEV(y
);
529 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
530 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
532 // CMB: handle -ve width and/or height
533 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
534 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
538 wxCoord start
= wxCoord(sa
* 64.0);
539 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
541 if (m_brush
.GetStyle() != wxTRANSPARENT
)
543 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
545 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
546 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
547 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
549 XFillArc( (Display
*) m_display
, (Window
) m_window
,
550 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
552 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
554 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
556 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
557 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
559 XFillArc( (Display
*) m_display
, (Window
) m_window
,
560 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
562 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
564 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
566 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
567 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
569 XFillArc( (Display
*) m_display
, (Window
) m_window
,
570 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
572 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
574 if (m_brush
.GetStyle() == wxSTIPPLE
)
576 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
577 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
578 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
580 XFillArc( (Display
*) m_display
, (Window
) m_window
,
581 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
583 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
587 XFillArc( (Display
*) m_display
, (Window
) m_window
,
588 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
592 if (m_pen
.GetStyle() != wxTRANSPARENT
)
594 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
595 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
599 CalcBoundingBox (x
, y
);
600 CalcBoundingBox (x
+ width
, y
+ height
);
603 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
605 wxCHECK_RET( Ok(), wxT("invalid window dc") );
607 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
)
608 XDrawPoint( (Display
*) m_display
, (Window
) m_window
,
609 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
611 CalcBoundingBox (x
, y
);
614 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
616 wxCHECK_RET( Ok(), wxT("invalid window dc") );
618 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
621 XPoint
*xpoints
= new XPoint
[n
];
622 for (int i
= 0; i
< n
; i
++)
624 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
625 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
627 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
629 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
, 0 );
634 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
635 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
637 wxCHECK_RET( Ok(), wxT("invalid window dc") );
641 XPoint
*xpoints
= new XPoint
[n
+ 1];
643 for (i
= 0; i
< n
; i
++)
645 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
646 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
648 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
653 if (m_brush
.GetStyle() != wxTRANSPARENT
)
656 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
658 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
659 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
660 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
662 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
663 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
665 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
667 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
669 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
670 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
672 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
673 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
675 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
677 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
679 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
680 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
682 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
683 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
685 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
687 if (m_brush
.GetStyle() == wxSTIPPLE
)
689 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
690 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
691 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
693 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
694 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
696 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
700 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
701 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
705 if (m_pen
.GetStyle () != wxTRANSPARENT
)
707 // Close figure for XDrawLines
708 xpoints
[i
].x
= xpoints
[0].x
;
709 xpoints
[i
].y
= xpoints
[0].y
;
711 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
718 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
720 wxCHECK_RET( Ok(), wxT("invalid window dc") );
722 wxCoord xx
= XLOG2DEV(x
);
723 wxCoord yy
= YLOG2DEV(y
);
724 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
725 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
727 // CMB: draw nothing if transformed w or h is 0
728 if (ww
== 0 || hh
== 0) return;
730 // CMB: handle -ve width and/or height
731 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
732 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
736 if (m_brush
.GetStyle() != wxTRANSPARENT
)
738 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
740 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
741 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
742 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
744 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
745 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
747 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
749 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
751 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
752 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
754 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
755 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
757 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
759 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
761 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
762 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
764 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
765 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
767 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
769 if (m_brush
.GetStyle() == wxSTIPPLE
)
771 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
772 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
773 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
775 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
776 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
778 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
782 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
783 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
787 if (m_pen
.GetStyle () != wxTRANSPARENT
)
789 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
790 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
794 CalcBoundingBox( x
, y
);
795 CalcBoundingBox( x
+ width
, y
+ height
);
798 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
800 wxCHECK_RET( Ok(), wxT("invalid window dc") );
802 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
804 wxCoord xx
= XLOG2DEV(x
);
805 wxCoord yy
= YLOG2DEV(y
);
806 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
807 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
808 wxCoord rr
= XLOG2DEVREL((wxCoord
)radius
);
810 // CMB: handle -ve width and/or height
811 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
812 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
814 // CMB: if radius is zero use DrawRectangle() instead to avoid
815 // X drawing errors with small radii
818 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
819 (GC
) m_penGC
, x
, y
, width
, height
);
823 // CMB: draw nothing if transformed w or h is 0
824 if (ww
== 0 || hh
== 0) return;
826 // CMB: adjust size if outline is drawn otherwise the result is
827 // 1 pixel too wide and high
828 if (m_pen
.GetStyle() != wxTRANSPARENT
)
836 // CMB: ensure dd is not larger than rectangle otherwise we
837 // get an hour glass shape
839 if (dd
> ww
) dd
= ww
;
840 if (dd
> hh
) dd
= hh
;
843 if (m_brush
.GetStyle() != wxTRANSPARENT
)
845 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
847 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
848 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
849 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
850 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
851 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
852 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
853 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
854 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
855 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
856 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0);
858 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
860 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
861 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
862 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
863 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
864 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
865 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
866 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
867 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
869 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
871 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
872 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
873 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
874 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
875 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
876 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
877 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
878 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
880 if (m_brush
.GetStyle() == wxSTIPPLE
)
882 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
883 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
884 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
885 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
886 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
887 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
888 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
889 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
890 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
891 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
895 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
896 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
897 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
898 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
899 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
900 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
903 if (m_pen
.GetStyle() != wxTRANSPARENT
)
905 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy
);
906 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
907 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr
);
908 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr
);
909 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
910 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
911 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
912 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
916 // this ignores the radius
917 CalcBoundingBox( x
, y
);
918 CalcBoundingBox( x
+ width
, y
+ height
);
921 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
923 wxCHECK_RET( Ok(), wxT("invalid window dc") );
925 wxCoord xx
= XLOG2DEV(x
);
926 wxCoord yy
= YLOG2DEV(y
);
927 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
928 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
930 // CMB: handle -ve width and/or height
931 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
932 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
936 if (m_brush
.GetStyle() != wxTRANSPARENT
)
938 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
940 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
941 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
942 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
944 XFillArc( (Display
*) m_display
, (Window
) m_window
,
945 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
947 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
949 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
951 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
952 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
954 XFillArc( (Display
*) m_display
, (Window
) m_window
,
955 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
957 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
959 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
961 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
962 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
964 XFillArc( (Display
*) m_display
, (Window
) m_window
,
965 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
967 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
969 if (m_brush
.GetStyle() == wxSTIPPLE
)
971 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
972 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
973 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
975 XFillArc( (Display
*) m_display
, (Window
) m_window
,
976 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
978 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
982 XFillArc( (Display
*) m_display
, (Window
) m_window
,
983 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
987 if (m_pen
.GetStyle () != wxTRANSPARENT
)
989 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
990 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
994 CalcBoundingBox( x
, y
);
995 CalcBoundingBox( x
+ width
, y
+ height
);
998 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
1000 DoDrawBitmap(icon
, x
, y
, true);
1004 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1005 wxCoord x
, wxCoord y
,
1008 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1010 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1012 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1014 /* scale/translate size and position */
1015 int xx
= XLOG2DEV(x
);
1016 int yy
= YLOG2DEV(y
);
1018 int w
= bitmap
.GetWidth();
1019 int h
= bitmap
.GetHeight();
1021 CalcBoundingBox( x
, y
);
1022 CalcBoundingBox( x
+ w
, y
+ h
);
1024 if (!m_window
) return;
1026 int ww
= XLOG2DEVREL(w
);
1027 int hh
= YLOG2DEVREL(h
);
1029 /* compare to current clipping region */
1030 if (!m_currentClippingRegion
.IsNull())
1032 wxRegion
tmp( xx
,yy
,ww
,hh
);
1033 tmp
.Intersect( m_currentClippingRegion
);
1038 /* scale bitmap if required */
1039 wxBitmap use_bitmap
;
1040 if ((w
!= ww
) || (h
!= hh
))
1042 wxImage
image( bitmap
.ConvertToImage() );
1043 image
.Rescale( ww
, hh
);
1046 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1053 use_bitmap
= bitmap
;
1056 /* apply mask if any */
1057 WXPixmap mask
= NULL
;
1058 if (use_bitmap
.GetMask())
1059 mask
= use_bitmap
.GetMask()->GetBitmap();
1061 if (useMask
&& mask
)
1063 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
1064 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
1065 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
1067 GrSetGCUseBackground(gc
, FALSE
);
1068 GrSetGCMode(gc
, GR_MODE_COPY
);
1070 // This code assumes that background and foreground
1071 // colours are used in ROPs, like in MSW.
1072 // Not sure if this is true.
1074 // Copy destination to buffer.
1075 // In DoBlit, we need this step because Blit has
1076 // a ROP argument. Here, we don't need it.
1077 // In DoBlit, we may be able to eliminate this step
1078 // if we check if the rop = copy
1080 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_window
,
1081 0, 0, GR_MODE_COPY
);
1084 // Copy src to buffer using selected raster op (none selected
1085 // in DrawBitmap, so just use Gxcopy)
1086 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
1087 0, 0, GR_MODE_COPY
);
1089 // Set masked area in buffer to BLACK (pixel value 0)
1090 GrSetGCBackground(gc
, WHITE
);
1091 GrSetGCForeground(gc
, BLACK
);
1092 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
1095 // set unmasked area in dest to BLACK
1096 GrSetGCBackground(gc
, BLACK
);
1097 GrSetGCForeground(gc
, WHITE
);
1098 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
1101 // OR buffer to dest
1102 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
1106 GrDestroyWindow(bufPixmap
);
1109 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1110 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1112 /* remove mask again if any */
1113 if (useMask
&& mask
)
1115 if (!m_currentClippingRegion
.IsNull())
1116 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1123 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1124 wxCoord x
, wxCoord y
,
1127 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1129 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1131 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1133 // scale/translate size and position
1134 int xx
= XLOG2DEV(x
);
1135 int yy
= YLOG2DEV(y
);
1137 int w
= bitmap
.GetWidth();
1138 int h
= bitmap
.GetHeight();
1140 CalcBoundingBox( x
, y
);
1141 CalcBoundingBox( x
+ w
, y
+ h
);
1143 if (!m_window
) return;
1145 int ww
= XLOG2DEVREL(w
);
1146 int hh
= YLOG2DEVREL(h
);
1148 // compare to current clipping region
1149 if (!m_currentClippingRegion
.IsNull())
1151 wxRegion
tmp( xx
,yy
,ww
,hh
);
1152 tmp
.Intersect( m_currentClippingRegion
);
1157 // scale bitmap if required
1158 wxBitmap use_bitmap
;
1159 if ((w
!= ww
) || (h
!= hh
))
1161 wxImage
image( bitmap
.ConvertToImage() );
1162 image
.Rescale( ww
, hh
);
1165 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1172 use_bitmap
= bitmap
;
1175 // apply mask if any
1176 WXPixmap mask
= NULL
;
1177 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1179 bool setClipMask
= false;
1181 if (!m_currentClippingRegion
.IsNull() || (useMask
&& mask
))
1183 // XSetClipMask() call is necessary (because of clip region and/or transparent mask)
1185 Pixmap new_pixmap
= 0;
1187 if (!m_currentClippingRegion
.IsNull())
1189 // clipping necessary => create new_pixmap
1190 Display
*xdisplay
= (Display
*) m_display
;
1191 int xscreen
= DefaultScreen( xdisplay
);
1192 Window xroot
= RootWindow( xdisplay
, xscreen
);
1194 new_pixmap
= XCreatePixmap( xdisplay
, xroot
, ww
, hh
, 1 );
1195 GC gc
= XCreateGC( xdisplay
, new_pixmap
, 0, NULL
);
1197 XSetForeground( xdisplay
, gc
, BlackPixel(xdisplay
,xscreen
) );
1199 XSetFillStyle( xdisplay
, gc
, FillSolid
);
1200 XFillRectangle( xdisplay
, new_pixmap
, gc
, 0, 0, ww
, hh
);
1202 XSetForeground( xdisplay
, gc
, WhitePixel(xdisplay
,xscreen
) );
1204 if (useMask
&& mask
)
1206 // transparent mask => call XSetStipple
1207 XSetFillStyle( xdisplay
, gc
, FillStippled
);
1208 XSetTSOrigin( xdisplay
, gc
, 0, 0);
1209 XSetStipple( xdisplay
, gc
, (Pixmap
) mask
);
1212 wxCoord clip_x
, clip_y
, clip_w
, clip_h
;
1213 m_currentClippingRegion
.GetBox(clip_x
, clip_y
, clip_w
, clip_h
);
1214 XFillRectangle( xdisplay
, new_pixmap
, gc
, clip_x
-xx
, clip_y
-yy
, clip_w
, clip_h
);
1216 XFreeGC( xdisplay
, gc
);
1222 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, new_pixmap
);
1224 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1225 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1230 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, new_pixmap
);
1232 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1233 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1237 XFreePixmap( (Display
*) m_display
, new_pixmap
);
1240 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1241 // drawing a mono-bitmap (XBitmap) we use the current text GC
1243 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1244 (GC
) m_textGC
, 0, 0, ww
, hh
, xx
, yy
, 1 );
1246 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1247 (GC
) m_penGC
, 0, 0, ww
, hh
, xx
, yy
);
1249 // remove mask again if any
1254 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1255 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1256 if (!m_currentClippingRegion
.IsNull())
1257 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1261 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1262 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1263 if (!m_currentClippingRegion
.IsNull())
1264 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1269 // wxUSE_NANOX/!wxUSE_NANOX
1271 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1272 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1273 wxCoord xsrcMask
, wxCoord ysrcMask
)
1275 /* this is the nth try to get this utterly useless function to
1276 work. it now completely ignores the scaling or translation
1277 of the source dc, but scales correctly on the target dc and
1278 knows about possible mask information in a memory dc. */
1280 wxCHECK_MSG( Ok(), false, wxT("invalid window dc") );
1282 wxCHECK_MSG( source
, false, wxT("invalid source dc") );
1284 if (!m_window
) return false;
1286 // transform the source DC coords to the device ones
1287 xsrc
= source
->XLOG2DEV(xsrc
);
1288 ysrc
= source
->YLOG2DEV(ysrc
);
1290 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1291 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1293 bool use_bitmap_method
= false;
1294 bool is_mono
= false;
1296 // TODO: use the mask origin when drawing transparently
1297 if (xsrcMask
== -1 && ysrcMask
== -1)
1303 if (srcDC
->m_isMemDC
)
1305 if (!memDC
->m_selected
.Ok()) return false;
1307 /* we use the "XCopyArea" way to copy a memory dc into
1308 y different window if the memory dc BOTH
1309 a) doesn't have any mask or its mask isn't used
1313 if (useMask
&& (memDC
->m_selected
.GetMask()))
1315 /* we HAVE TO use the direct way for memory dcs
1316 that have mask since the XCopyArea doesn't know
1318 use_bitmap_method
= true;
1320 else if (memDC
->m_selected
.GetDepth() == 1)
1322 /* we HAVE TO use the direct way for memory dcs
1323 that are bitmaps because XCopyArea doesn't cope
1324 with different bit depths */
1326 use_bitmap_method
= true;
1328 else if ((xsrc
== 0) && (ysrc
== 0) &&
1329 (width
== memDC
->m_selected
.GetWidth()) &&
1330 (height
== memDC
->m_selected
.GetHeight()))
1332 /* we SHOULD use the direct way if all of the bitmap
1333 in the memory dc is copied in which case XCopyArea
1334 wouldn't be able able to boost performace by reducing
1335 the area to be scaled */
1336 use_bitmap_method
= true;
1340 use_bitmap_method
= false;
1344 CalcBoundingBox( xdest
, ydest
);
1345 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1347 // scale/translate size and position
1348 wxCoord xx
= XLOG2DEV(xdest
);
1349 wxCoord yy
= YLOG2DEV(ydest
);
1351 wxCoord ww
= XLOG2DEVREL(width
);
1352 wxCoord hh
= YLOG2DEVREL(height
);
1354 // compare to current clipping region
1355 if (!m_currentClippingRegion
.IsNull())
1357 wxRegion
tmp( xx
,yy
,ww
,hh
);
1358 tmp
.Intersect( m_currentClippingRegion
);
1363 int old_logical_func
= m_logicalFunction
;
1364 SetLogicalFunction( logical_func
);
1366 if (use_bitmap_method
)
1368 // scale/translate bitmap size
1369 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1370 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1372 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1373 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1375 // scale bitmap if required
1376 wxBitmap use_bitmap
;
1378 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1380 wxImage
image( memDC
->m_selected
.ConvertToImage() );
1381 image
= image
.Scale( bm_ww
, bm_hh
);
1385 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1392 use_bitmap
= memDC
->m_selected
;
1395 // apply mask if any
1396 WXPixmap mask
= NULL
;
1397 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1399 if (useMask
&& mask
)
1401 WXPixmap new_mask
= NULL
;
1403 if (!m_currentClippingRegion
.IsNull())
1406 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1407 GdkGC
*gc
= gdk_gc_new( new_mask
);
1409 gdk_gc_set_foreground( gc
, &col
);
1410 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1412 gdk_gc_set_background( gc
, &col
);
1414 gdk_gc_set_foreground( gc
, &col
);
1415 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1416 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1417 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1418 gdk_gc_set_stipple( gc
, mask
);
1419 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1426 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1428 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1429 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1434 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1436 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1437 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1441 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1444 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1445 // drawing a mono-bitmap (XBitmap) we use the current text GC
1448 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1449 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1451 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1452 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1454 // remove mask again if any
1455 if (useMask
&& mask
)
1459 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1460 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1461 if (!m_currentClippingRegion
.IsNull())
1462 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1466 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1467 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1468 if (!m_currentClippingRegion
.IsNull())
1469 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1473 else // use_bitmap_method
1475 if ((width
!= ww
) || (height
!= hh
))
1477 /* Draw source window into a bitmap as we cannot scale
1478 a window in contrast to a bitmap. this would actually
1479 work with memory dcs as well, but we'd lose the mask
1480 information and waste one step in this process since
1481 a memory already has a bitmap. all this is slightly
1482 inefficient as we could take an XImage directly from
1483 an X window, but we'd then also have to care that
1484 the window is not outside the screen (in which case
1485 we'd get a BadMatch or what not).
1486 Is a double XGetImage and combined XGetPixel and
1487 XPutPixel really faster? I'm not sure. look at wxXt
1488 for a different implementation of the same problem. */
1490 wxBitmap
bitmap( width
, height
);
1492 // copy including child window contents
1493 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1494 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) bitmap
.GetPixmap(),
1495 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1496 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1499 wxImage
image( bitmap
.ConvertToImage() );
1500 image
= image
.Scale( ww
, hh
);
1502 // convert to bitmap
1505 // draw scaled bitmap
1506 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_window
,
1507 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1511 // No scaling and not a memory dc with a mask either
1513 // copy including child window contents
1514 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1515 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) m_window
,
1516 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1517 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1521 SetLogicalFunction( old_logical_func
);
1526 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1528 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1530 if (!m_window
) return;
1536 PangoLayout
*layout
= pango_layout_new(m_context
);
1537 pango_layout_set_font_description(layout
, m_fontdesc
);
1539 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1540 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1544 pango_layout_get_pixel_size(layout
, &w
, &h
);
1549 x11_draw_layout( (Drawable
) m_window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1551 g_object_unref( G_OBJECT( layout
) );
1553 CalcBoundingBox (x
+ width
, y
+ height
);
1554 CalcBoundingBox (x
, y
);
1556 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1558 wxCHECK_RET( xfont
, wxT("invalid font") );
1560 // First draw a rectangle representing the text background, if a text
1561 // background is specified
1562 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1564 // Since X draws from the baseline of the text, must add the text height
1569 int direction
, descent
;
1571 slen
= strlen(text
);
1572 XCharStruct overall_return
;
1574 (void)XTextExtents(xfont
, (char*) text
.c_str(), slen
, &direction
,
1575 &ascent
, &descent
, &overall_return
);
1577 cx
= overall_return
.width
;
1578 cy
= ascent
+ descent
;
1579 m_textBackgroundColour
.CalcPixel(m_cmap
);
1580 m_textForegroundColour
.CalcPixel(m_cmap
);
1581 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1582 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
1583 (GC
) m_textGC
, x
, y
, cx
, cy
);
1584 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1588 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1590 // This may be a test for whether the font is 16-bit, but it also
1591 // seems to fail for valid 8-bit fonts too.
1592 if (1) // (xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
1595 XDrawString( (Display
*) m_display
, (Window
) m_window
,
1596 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.length() );
1600 if (m_font
.GetUnderlined())
1602 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1603 if (font
->descent
> 0) ul_y
++;
1604 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1607 width
= wxCoord(width
/ m_scaleX
);
1608 height
= wxCoord(height
/ m_scaleY
);
1610 CalcBoundingBox (x
+ width
, y
+ height
);
1611 CalcBoundingBox (x
, y
);
1616 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
, double angle
)
1621 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1622 wxCoord
*descent
, wxCoord
*externalLeading
,
1623 wxFont
*font
) const
1625 wxCHECK_RET( Ok(), wxT("invalid dc") );
1629 if (width
) (*width
) = 0;
1630 if (height
) (*height
) = 0;
1635 PangoLayout
*layout
= pango_layout_new( m_context
);
1638 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1640 pango_layout_set_font_description(layout
, m_fontdesc
);
1642 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1643 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1647 pango_layout_get_pixel_size(layout
, &w
, &h
);
1649 if (width
) (*width
) = (wxCoord
) w
;
1650 if (height
) (*height
) = (wxCoord
) h
;
1653 // Do something about metrics here. TODO.
1656 if (externalLeading
) (*externalLeading
) = 0; // ??
1658 g_object_unref( G_OBJECT( layout
) );
1660 wxFont fontToUse
= m_font
;
1661 if (font
) fontToUse
= *font
;
1663 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
1665 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1667 wxCHECK_RET( xfont
, wxT("invalid font") );
1669 int direction
, ascent
, descent2
;
1670 XCharStruct overall
;
1672 XTextExtents( xfont
, (char*) string
.c_str(), string
.length(), &direction
,
1673 &ascent
, &descent2
, &overall
);
1676 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1678 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1680 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1681 if (externalLeading
)
1682 *externalLeading
= 0; // ??
1686 wxCoord
wxWindowDC::GetCharWidth() const
1688 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1691 PangoLayout
*layout
= pango_layout_new( m_context
);
1694 pango_layout_set_font_description(layout
, m_fontdesc
);
1696 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1698 pango_layout_set_text(layout
, "H", 1 );
1700 pango_layout_get_pixel_size(layout
, &w
, &h
);
1701 g_object_unref( G_OBJECT( layout
) );
1705 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1707 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1709 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1711 int direction
, ascent
, descent
;
1712 XCharStruct overall
;
1714 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1716 return (wxCoord
)(overall
.width
/ m_scaleX
);
1720 wxCoord
wxWindowDC::GetCharHeight() const
1722 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1725 PangoLayout
*layout
= pango_layout_new( m_context
);
1728 pango_layout_set_font_description(layout
, m_fontdesc
);
1730 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1732 pango_layout_set_text(layout
, "H", 1 );
1734 pango_layout_get_pixel_size(layout
, &w
, &h
);
1735 g_object_unref( G_OBJECT( layout
) );
1739 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1741 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1743 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1745 int direction
, ascent
, descent
;
1746 XCharStruct overall
;
1748 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1750 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1754 void wxWindowDC::Clear()
1756 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1758 if (!m_window
) return;
1760 /* - we either are a memory dc or have a window as the
1761 owner. anything else shouldn't happen.
1762 - we don't use gdk_window_clear() as we don't set
1763 the window's background colour anymore. it is too
1764 much pain to keep the DC's and the window's back-
1765 ground colour in synch. */
1770 m_owner
->GetSize( &width
, &height
);
1771 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1778 GetSize( &width
, &height
);
1779 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1784 void wxWindowDC::SetFont( const wxFont
&font
)
1786 wxCHECK_RET( Ok(), wxT("invalid dc") );
1793 m_fontdesc
= font
.GetNativeFontInfo()->description
;
1797 void wxWindowDC::SetPen( const wxPen
&pen
)
1799 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1801 if (m_pen
== pen
) return;
1805 if (!m_pen
.Ok()) return;
1807 if (!m_window
) return;
1809 int width
= m_pen
.GetWidth();
1812 // CMB: if width is non-zero scale it with the dc
1817 // X doesn't allow different width in x and y and so we take
1820 ( fabs((double) XLOG2DEVREL(width
)) +
1821 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1825 static const wxX11Dash dotted
[] = {1, 1};
1826 static const wxX11Dash short_dashed
[] = {2, 2};
1827 static const wxX11Dash long_dashed
[] = {2, 4};
1828 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1830 // We express dash pattern in pen width unit, so we are
1831 // independent of zoom factor and so on...
1833 const wxX11Dash
*req_dash
;
1835 int lineStyle
= LineSolid
;
1836 switch (m_pen
.GetStyle())
1840 lineStyle
= LineOnOffDash
;
1841 req_nb_dash
= m_pen
.GetDashCount();
1842 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1847 lineStyle
= LineOnOffDash
;
1854 lineStyle
= LineOnOffDash
;
1856 req_dash
= long_dashed
;
1861 lineStyle
= LineOnOffDash
;
1863 req_dash
= short_dashed
;
1868 // lineStyle = LineDoubleDash;
1869 lineStyle
= LineOnOffDash
;
1871 req_dash
= dotted_dashed
;
1876 case wxSTIPPLE_MASK_OPAQUE
:
1881 lineStyle
= LineSolid
;
1882 req_dash
= (wxX11Dash
*)NULL
;
1888 int capStyle
= CapRound
;
1889 switch (m_pen
.GetCap())
1891 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1892 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1899 capStyle
= CapNotLast
;
1903 capStyle
= CapRound
;
1909 int joinStyle
= JoinRound
;
1910 switch (m_pen
.GetJoin())
1912 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1913 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1915 default: { joinStyle
= JoinRound
; break; }
1918 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1920 m_pen
.GetColour().CalcPixel( m_cmap
);
1921 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1924 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1926 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1928 if (m_brush
== brush
) return;
1932 if (!m_brush
.Ok()) return;
1934 if (!m_window
) return;
1936 m_brush
.GetColour().CalcPixel( m_cmap
);
1937 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1939 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1941 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1943 if (m_brush
.GetStipple()->GetPixmap())
1945 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1946 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1950 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1951 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1955 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1957 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1958 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1961 if (m_brush
.IsHatch())
1963 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1964 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1965 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1969 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1971 /* CMB 21/7/98: Added SetBackground. Sets background brush
1972 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1974 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1976 if (m_backgroundBrush
== brush
) return;
1978 m_backgroundBrush
= brush
;
1980 if (!m_backgroundBrush
.Ok()) return;
1982 if (!m_window
) return;
1984 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1985 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1986 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1987 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1988 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1990 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1992 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1994 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1996 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1997 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
2001 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2002 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
2006 if (m_backgroundBrush
.IsHatch())
2008 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
2009 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
2010 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
2014 void wxWindowDC::SetLogicalFunction( int function
)
2016 wxCHECK_RET( Ok(), wxT("invalid dc") );
2020 if (m_logicalFunction
== function
)
2023 // VZ: shouldn't this be a CHECK?
2030 x_function
= GXclear
;
2036 x_function
= GXinvert
;
2039 x_function
= GXorReverse
;
2042 x_function
= GXandReverse
;
2051 x_function
= GXandInverted
;
2054 x_function
= GXnoop
;
2060 x_function
= GXequiv
;
2063 x_function
= GXcopyInverted
;
2066 x_function
= GXorInverted
;
2069 x_function
= GXnand
;
2076 x_function
= GXcopy
;
2080 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2081 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2083 // to stay compatible with wxMSW, we don't apply ROPs to the text
2084 // operations (i.e. DrawText/DrawRotatedText).
2085 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2086 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2088 m_logicalFunction
= function
;
2091 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2093 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2095 // don't set m_textForegroundColour to an invalid colour as we'd crash
2096 // later then (we use m_textForegroundColour.GetColor() without checking
2098 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
2101 m_textForegroundColour
= col
;
2105 m_textForegroundColour
.CalcPixel( m_cmap
);
2106 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2110 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2112 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2115 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
2118 m_textBackgroundColour
= col
;
2122 m_textBackgroundColour
.CalcPixel( m_cmap
);
2123 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2127 void wxWindowDC::SetBackgroundMode( int mode
)
2129 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2131 m_backgroundMode
= mode
;
2134 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2137 if (!m_window
) return;
2139 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2140 // transparent/solid background mode
2142 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2144 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2145 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2149 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2155 /* Use GetXColormap */
2156 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2157 (Colormap
) palette
.GetXColormap());
2159 /* Use wxGetMainColormap */
2160 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2161 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2166 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2168 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2170 if (!m_window
) return;
2173 rect
.x
= XLOG2DEV(x
);
2174 rect
.y
= YLOG2DEV(y
);
2175 rect
.width
= XLOG2DEVREL(width
);
2176 rect
.height
= YLOG2DEVREL(height
);
2178 if (!m_currentClippingRegion
.IsNull())
2179 m_currentClippingRegion
.Intersect( rect
);
2181 m_currentClippingRegion
.Union( rect
);
2183 #if USE_PAINT_REGION
2184 if (!m_paintClippingRegion
.IsNull())
2185 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2188 wxCoord xx
, yy
, ww
, hh
;
2189 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2190 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2192 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2193 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2194 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2195 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2198 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2200 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2204 DestroyClippingRegion();
2208 if (!m_window
) return;
2210 if (!m_currentClippingRegion
.IsNull())
2211 m_currentClippingRegion
.Intersect( region
);
2213 m_currentClippingRegion
.Union( region
);
2215 #if USE_PAINT_REGION
2216 if (!m_paintClippingRegion
.IsNull())
2217 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2220 wxCoord xx
, yy
, ww
, hh
;
2221 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2222 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2224 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2225 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2226 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2227 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2230 void wxWindowDC::DestroyClippingRegion()
2232 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2234 wxDC::DestroyClippingRegion();
2236 m_currentClippingRegion
.Clear();
2238 #if USE_PAINT_REGION
2239 if (!m_paintClippingRegion
.IsEmpty())
2240 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2243 if (!m_window
) return;
2245 if (m_currentClippingRegion
.IsEmpty())
2247 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2248 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2249 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2250 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2254 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2255 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2256 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2257 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2261 void wxWindowDC::Destroy()
2263 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2265 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2267 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2269 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2273 void wxWindowDC::ComputeScaleAndOrigin()
2275 /* CMB: copy scale to see if it changes */
2276 double origScaleX
= m_scaleX
;
2277 double origScaleY
= m_scaleY
;
2279 wxDC::ComputeScaleAndOrigin();
2281 /* CMB: if scale has changed call SetPen to recalulate the line width */
2282 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2285 /* this is a bit artificial, but we need to force wxDC to think
2286 the pen has changed */
2293 wxSize
wxWindowDC::GetPPI() const
2295 return wxSize(100, 100);
2298 int wxWindowDC::GetDepth() const
2300 wxFAIL_MSG(wxT("not implemented"));
2305 //-----------------------------------------------------------------------------
2307 //-----------------------------------------------------------------------------
2309 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2311 wxClientDC::wxClientDC( wxWindow
*window
)
2312 : wxWindowDC( window
)
2314 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2316 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2318 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2319 if (m_window
== (WXWindow
*) window
->GetMainWindow())
2321 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2322 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2323 wxSize size
= window
->GetClientSize();
2324 SetClippingRegion(wxPoint(0, 0), size
);
2328 void wxClientDC::DoGetSize(int *width
, int *height
) const
2330 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2332 m_owner
->GetClientSize( width
, height
);
2335 // ----------------------------------------------------------------------------
2337 // ----------------------------------------------------------------------------
2339 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2341 wxPaintDC::wxPaintDC(wxWindow
* window
)
2342 : wxClientDC(window
)
2344 #if USE_PAINT_REGION
2345 if (!window
->GetClipPaintRegion())
2348 m_paintClippingRegion
= window
->GetUpdateRegion();
2349 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2352 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2354 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2355 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2356 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2357 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2359 #endif // USE_PAINT_REGION
2362 // ----------------------------------------------------------------------------
2364 // ----------------------------------------------------------------------------
2366 class wxDCModule
: public wxModule
2373 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2376 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)
2378 bool wxDCModule::OnInit()
2384 void wxDCModule::OnExit()