1 /////////////////////////////////////////////////////////////////////////////
2 // Name: x11/dcclient.cpp
3 // Purpose: wxClientDC class
4 // Author: Julian Smart, Robert Roebling
8 // Copyright: (c) Julian Smart, Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "dcclient.h"
16 #include "wx/dcclient.h"
17 #include "wx/dcmemory.h"
18 #include "wx/window.h"
21 #include "wx/module.h"
22 #include "wx/fontutil.h"
24 #include "wx/x11/private.h"
30 #include "pango/pangox.h"
31 #include "pango/pangoxft.h"
33 #include "pango_x.cpp"
36 //-----------------------------------------------------------------------------
38 //-----------------------------------------------------------------------------
40 #define USE_PAINT_REGION 1
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
54 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH)
55 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH)
57 static Pixmap hatches
[num_hatches
];
58 static Pixmap
*hatch_bitmap
= (Pixmap
*) NULL
;
60 //-----------------------------------------------------------------------------
62 //-----------------------------------------------------------------------------
64 const double RAD2DEG
= 180.0 / M_PI
;
66 // ----------------------------------------------------------------------------
68 // ----------------------------------------------------------------------------
70 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
71 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
73 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
75 //-----------------------------------------------------------------------------
76 // Implement Pool of Graphic contexts. Creating them takes too much time.
77 //-----------------------------------------------------------------------------
79 #define GC_POOL_SIZE 200
105 static wxGC wxGCPool
[GC_POOL_SIZE
];
107 static void wxInitGCPool()
109 memset( wxGCPool
, 0, GC_POOL_SIZE
*sizeof(wxGC
) );
112 static void wxCleanUpGCPool()
114 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
116 if (wxGCPool
[i
].m_gc
)
117 XFreeGC( wxGlobalDisplay(), wxGCPool
[i
].m_gc
);
121 static GC
wxGetPoolGC( Window window
, wxPoolGCType type
)
123 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
125 if (!wxGCPool
[i
].m_gc
)
127 wxGCPool
[i
].m_gc
= XCreateGC( wxGlobalDisplay(), window
, 0, NULL
);
128 XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool
[i
].m_gc
, FALSE
);
129 wxGCPool
[i
].m_type
= type
;
130 wxGCPool
[i
].m_used
= FALSE
;
132 if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type
== type
))
134 wxGCPool
[i
].m_used
= TRUE
;
135 return wxGCPool
[i
].m_gc
;
139 wxFAIL_MSG( wxT("No GC available") );
144 static void wxFreePoolGC( GC gc
)
146 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
148 if (wxGCPool
[i
].m_gc
== gc
)
150 wxGCPool
[i
].m_used
= FALSE
;
155 wxFAIL_MSG( wxT("Wrong GC") );
158 // ----------------------------------------------------------------------------
160 // ----------------------------------------------------------------------------
162 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
164 wxWindowDC::wxWindowDC()
166 m_display
= (WXDisplay
*) NULL
;
167 m_penGC
= (WXGC
*) NULL
;
168 m_brushGC
= (WXGC
*) NULL
;
169 m_textGC
= (WXGC
*) NULL
;
170 m_bgGC
= (WXGC
*) NULL
;
171 m_cmap
= (WXColormap
*) NULL
;
173 m_isScreenDC
= FALSE
;
174 m_owner
= (wxWindow
*)NULL
;
177 m_context
= (PangoContext
*)NULL
;
178 m_fontdesc
= (PangoFontDescription
*)NULL
;
182 wxWindowDC::wxWindowDC( wxWindow
*window
)
184 wxASSERT_MSG( window
, wxT("DC needs a window") );
186 m_display
= (WXDisplay
*) NULL
;
187 m_penGC
= (WXGC
*) NULL
;
188 m_brushGC
= (WXGC
*) NULL
;
189 m_textGC
= (WXGC
*) NULL
;
190 m_bgGC
= (WXGC
*) NULL
;
191 m_cmap
= (WXColormap
*) NULL
;
192 m_owner
= (wxWindow
*)NULL
;
194 m_isScreenDC
= FALSE
;
195 m_font
= window
->GetFont();
197 m_window
= (WXWindow
*) window
->GetMainWindow();
202 // don't report problems
208 m_display
= (WXDisplay
*) wxGlobalDisplay();
211 m_context
= wxTheApp
->GetPangoContext();
212 m_fontdesc
= window
->GetFont().GetNativeFontInfo()->description
;
215 int screen
= DefaultScreen( (Display
*) m_display
);
216 m_cmap
= (WXColormap
) DefaultColormap( (Display
*) m_display
, screen
);
220 /* this must be done after SetUpDC, bacause SetUpDC calls the
221 repective SetBrush, SetPen, SetBackground etc functions
222 to set up the DC. SetBackground call m_owner->SetBackground
223 and this might not be desired as the standard dc background
224 is white whereas a window might assume gray to be the
225 standard (as e.g. wxStatusBar) */
230 wxWindowDC::~wxWindowDC()
235 void wxWindowDC::SetUpDC()
239 wxASSERT_MSG( !m_penGC
, wxT("GCs already created") );
243 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_SCREEN
);
244 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_SCREEN
);
245 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_SCREEN
);
246 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_SCREEN
);
249 if (m_isMemDC
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1))
251 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_MONO
);
252 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_MONO
);
253 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_MONO
);
254 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_MONO
);
258 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_COLOUR
);
259 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_COLOUR
);
260 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_COLOUR
);
261 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_COLOUR
);
264 /* background colour */
265 m_backgroundBrush
= *wxWHITE_BRUSH
;
266 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
267 unsigned long bg_col
= m_backgroundBrush
.GetColour().GetPixel();
269 m_textForegroundColour
= *wxBLACK
;
270 m_textBackgroundColour
= *wxWHITE
;
273 m_textForegroundColour
.CalcPixel( m_cmap
);
274 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
276 m_textBackgroundColour
.CalcPixel( m_cmap
);
277 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
279 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
282 // By default, draw transparently
283 GrSetGCUseBackground((GC
) m_textGC
, FALSE
);
287 m_pen
.GetColour().CalcPixel( m_cmap
);
288 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
289 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
291 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
294 m_brush
.GetColour().CalcPixel( m_cmap
);
295 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
296 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
298 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
301 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
302 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
304 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
307 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
308 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
309 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
312 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
313 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
314 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
315 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
319 int xscreen
= DefaultScreen( (Display
*) m_display
);
320 Window xroot
= RootWindow( (Display
*) m_display
, xscreen
);
322 hatch_bitmap
= hatches
;
323 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, bdiag_bits
, bdiag_width
, bdiag_height
);
324 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cdiag_bits
, cdiag_width
, cdiag_height
);
325 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, fdiag_bits
, fdiag_width
, fdiag_height
);
326 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cross_bits
, cross_width
, cross_height
);
327 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, horiz_bits
, horiz_width
, horiz_height
);
328 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, verti_bits
, verti_width
, verti_height
);
332 void wxWindowDC::DoGetSize( int* width
, int* height
) const
334 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
336 m_owner
->GetSize(width
, height
);
339 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
340 const wxColour
& col
, int style
);
342 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
343 const wxColour
& col
, int style
)
345 return wxDoFloodFill(this, x
, y
, col
, style
);
348 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
350 // Generic (and therefore rather inefficient) method.
351 // Could be improved.
353 wxBitmap
bitmap(1, 1);
354 memdc
.SelectObject(bitmap
);
355 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
356 memdc
.SelectObject(wxNullBitmap
);
357 wxImage
image(bitmap
.ConvertToImage());
358 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
362 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
364 wxCHECK_RET( Ok(), wxT("invalid window dc") );
366 if (m_pen
.GetStyle() != wxTRANSPARENT
)
370 // This hack is for the iPaq: XDrawLine draws
371 // nothing, whereas XDrawLines works...
377 DrawLines( 2, points
, 0, 0 );
379 // XDrawLine( (Display*) m_display, (Window) m_window,
380 // (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
383 CalcBoundingBox(x1
, y1
);
384 CalcBoundingBox(x2
, y2
);
388 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
390 wxCHECK_RET( Ok(), wxT("invalid window dc") );
392 if (m_pen
.GetStyle() != wxTRANSPARENT
)
397 wxCoord xx
= XLOG2DEV(x
);
398 wxCoord yy
= YLOG2DEV(y
);
401 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
402 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
403 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
404 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
409 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
411 wxCHECK_RET( Ok(), wxT("invalid window dc") );
413 wxCoord xx1
= XLOG2DEV(x1
);
414 wxCoord yy1
= YLOG2DEV(y1
);
415 wxCoord xx2
= XLOG2DEV(x2
);
416 wxCoord yy2
= YLOG2DEV(y2
);
417 wxCoord xxc
= XLOG2DEV(xc
);
418 wxCoord yyc
= YLOG2DEV(yc
);
419 double dx
= xx1
- xxc
;
420 double dy
= yy1
- yyc
;
421 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
422 wxCoord r
= (wxCoord
)radius
;
423 double radius1
, radius2
;
425 if (xx1
== xx2
&& yy1
== yy2
)
433 radius1
= radius2
= 0.0;
437 radius1
= (xx1
- xxc
== 0) ?
438 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
439 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
440 radius2
= (xx2
- xxc
== 0) ?
441 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
442 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
444 wxCoord alpha1
= wxCoord(radius1
* 64.0);
445 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
446 while (alpha2
<= 0) alpha2
+= 360*64;
447 while (alpha1
> 360*64) alpha1
-= 360*64;
451 if (m_brush
.GetStyle() != wxTRANSPARENT
)
453 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
455 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
456 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
457 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
459 XFillArc( (Display
*) m_display
, (Window
) m_window
,
460 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
462 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
464 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
466 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
467 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
469 XFillArc( (Display
*) m_display
, (Window
) m_window
,
470 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
472 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
474 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
476 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
477 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
479 XFillArc( (Display
*) m_display
, (Window
) m_window
,
480 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
482 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
484 if (m_brush
.GetStyle() == wxSTIPPLE
)
486 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
487 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
488 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
490 XFillArc( (Display
*) m_display
, (Window
) m_window
,
491 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
493 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
497 XFillArc( (Display
*) m_display
, (Window
) m_window
,
498 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
502 if (m_pen
.GetStyle() != wxTRANSPARENT
)
504 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
505 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
507 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
508 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
510 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
511 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
515 CalcBoundingBox (x1
, y1
);
516 CalcBoundingBox (x2
, y2
);
519 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
521 wxCHECK_RET( Ok(), wxT("invalid window dc") );
523 wxCoord xx
= XLOG2DEV(x
);
524 wxCoord yy
= YLOG2DEV(y
);
525 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
526 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
528 // CMB: handle -ve width and/or height
529 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
530 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
534 wxCoord start
= wxCoord(sa
* 64.0);
535 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
537 if (m_brush
.GetStyle() != wxTRANSPARENT
)
539 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
541 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
542 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
543 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
545 XFillArc( (Display
*) m_display
, (Window
) m_window
,
546 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
548 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
550 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
552 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
553 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
555 XFillArc( (Display
*) m_display
, (Window
) m_window
,
556 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
558 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
560 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
562 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
563 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
565 XFillArc( (Display
*) m_display
, (Window
) m_window
,
566 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
568 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
570 if (m_brush
.GetStyle() == wxSTIPPLE
)
572 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
573 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
574 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
576 XFillArc( (Display
*) m_display
, (Window
) m_window
,
577 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
579 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
583 XFillArc( (Display
*) m_display
, (Window
) m_window
,
584 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
588 if (m_pen
.GetStyle() != wxTRANSPARENT
)
590 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
591 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
595 CalcBoundingBox (x
, y
);
596 CalcBoundingBox (x
+ width
, y
+ height
);
599 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
601 wxCHECK_RET( Ok(), wxT("invalid window dc") );
603 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
)
604 XDrawPoint( (Display
*) m_display
, (Window
) m_window
,
605 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
607 CalcBoundingBox (x
, y
);
610 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
612 wxCHECK_RET( Ok(), wxT("invalid window dc") );
614 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
617 XPoint
*xpoints
= new XPoint
[n
];
618 for (int i
= 0; i
< n
; i
++)
620 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
621 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
623 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
625 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
, 0 );
630 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
631 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
633 wxCHECK_RET( Ok(), wxT("invalid window dc") );
637 XPoint
*xpoints
= new XPoint
[n
+ 1];
639 for (i
= 0; i
< n
; i
++)
641 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
642 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
644 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
649 if (m_brush
.GetStyle() != wxTRANSPARENT
)
652 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
654 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
655 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
656 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
658 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
659 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
661 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
663 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
665 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
666 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
668 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
669 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
671 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
673 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
675 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
676 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
678 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
679 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
681 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
683 if (m_brush
.GetStyle() == wxSTIPPLE
)
685 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
686 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
687 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
689 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
690 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
692 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
696 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
697 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
701 if (m_pen
.GetStyle () != wxTRANSPARENT
)
703 // Close figure for XDrawLines
704 xpoints
[i
].x
= xpoints
[0].x
;
705 xpoints
[i
].y
= xpoints
[0].y
;
707 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
714 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
716 wxCHECK_RET( Ok(), wxT("invalid window dc") );
718 wxCoord xx
= XLOG2DEV(x
);
719 wxCoord yy
= YLOG2DEV(y
);
720 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
721 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
723 // CMB: draw nothing if transformed w or h is 0
724 if (ww
== 0 || hh
== 0) return;
726 // CMB: handle -ve width and/or height
727 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
728 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
732 if (m_brush
.GetStyle() != wxTRANSPARENT
)
734 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
736 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
737 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
738 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
740 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
741 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
743 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
745 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
747 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
748 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
750 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
751 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
753 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
755 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
757 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
758 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
760 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
761 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
763 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
765 if (m_brush
.GetStyle() == wxSTIPPLE
)
767 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
768 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
769 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
771 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
772 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
774 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
778 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
779 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
783 if (m_pen
.GetStyle () != wxTRANSPARENT
)
785 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
786 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
790 CalcBoundingBox( x
, y
);
791 CalcBoundingBox( x
+ width
, y
+ height
);
794 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
796 wxCHECK_RET( Ok(), wxT("invalid window dc") );
798 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
800 wxCoord xx
= XLOG2DEV(x
);
801 wxCoord yy
= YLOG2DEV(y
);
802 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
803 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
804 wxCoord rr
= XLOG2DEVREL((wxCoord
)radius
);
806 // CMB: handle -ve width and/or height
807 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
808 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
810 // CMB: if radius is zero use DrawRectangle() instead to avoid
811 // X drawing errors with small radii
814 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
815 (GC
) m_penGC
, x
, y
, width
, height
);
819 // CMB: draw nothing if transformed w or h is 0
820 if (ww
== 0 || hh
== 0) return;
822 // CMB: adjust size if outline is drawn otherwise the result is
823 // 1 pixel too wide and high
824 if (m_pen
.GetStyle() != wxTRANSPARENT
)
832 // CMB: ensure dd is not larger than rectangle otherwise we
833 // get an hour glass shape
835 if (dd
> ww
) dd
= ww
;
836 if (dd
> hh
) dd
= hh
;
839 if (m_brush
.GetStyle() != wxTRANSPARENT
)
841 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
843 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
844 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
845 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
846 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
847 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
848 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
849 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
850 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
851 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
852 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0);
854 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
856 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
857 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
858 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
859 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
860 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
861 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
862 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
863 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
865 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
867 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
868 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
869 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
870 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
871 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
872 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
873 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
874 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
876 if (m_brush
.GetStyle() == wxSTIPPLE
)
878 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
879 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
880 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
881 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
882 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
883 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
884 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
885 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
886 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
887 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
891 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
892 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
893 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
894 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
895 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
896 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
899 if (m_pen
.GetStyle() != wxTRANSPARENT
)
901 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy
);
902 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
903 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr
);
904 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr
);
905 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
906 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
907 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
908 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
912 // this ignores the radius
913 CalcBoundingBox( x
, y
);
914 CalcBoundingBox( x
+ width
, y
+ height
);
917 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
919 wxCHECK_RET( Ok(), wxT("invalid window dc") );
921 wxCoord xx
= XLOG2DEV(x
);
922 wxCoord yy
= YLOG2DEV(y
);
923 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
924 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
926 // CMB: handle -ve width and/or height
927 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
928 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
932 if (m_brush
.GetStyle() != wxTRANSPARENT
)
934 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
936 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
937 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
938 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
940 XFillArc( (Display
*) m_display
, (Window
) m_window
,
941 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
943 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
945 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
947 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
948 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
950 XFillArc( (Display
*) m_display
, (Window
) m_window
,
951 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
953 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
955 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
957 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
958 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
960 XFillArc( (Display
*) m_display
, (Window
) m_window
,
961 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
963 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
965 if (m_brush
.GetStyle() == wxSTIPPLE
)
967 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
968 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
969 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
971 XFillArc( (Display
*) m_display
, (Window
) m_window
,
972 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
974 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
978 XFillArc( (Display
*) m_display
, (Window
) m_window
,
979 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
983 if (m_pen
.GetStyle () != wxTRANSPARENT
)
985 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
986 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
990 CalcBoundingBox( x
, y
);
991 CalcBoundingBox( x
+ width
, y
+ height
);
994 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
996 DoDrawBitmap(icon
, x
, y
, TRUE
);
1000 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1001 wxCoord x
, wxCoord y
,
1004 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1006 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1008 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1010 /* scale/translate size and position */
1011 int xx
= XLOG2DEV(x
);
1012 int yy
= YLOG2DEV(y
);
1014 int w
= bitmap
.GetWidth();
1015 int h
= bitmap
.GetHeight();
1017 CalcBoundingBox( x
, y
);
1018 CalcBoundingBox( x
+ w
, y
+ h
);
1020 if (!m_window
) return;
1022 int ww
= XLOG2DEVREL(w
);
1023 int hh
= YLOG2DEVREL(h
);
1025 /* compare to current clipping region */
1026 if (!m_currentClippingRegion
.IsNull())
1028 wxRegion
tmp( xx
,yy
,ww
,hh
);
1029 tmp
.Intersect( m_currentClippingRegion
);
1034 /* scale bitmap if required */
1035 wxBitmap use_bitmap
;
1036 if ((w
!= ww
) || (h
!= hh
))
1038 wxImage
image( bitmap
.ConvertToImage() );
1039 image
.Rescale( ww
, hh
);
1042 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1049 use_bitmap
= bitmap
;
1052 /* apply mask if any */
1053 WXPixmap mask
= NULL
;
1054 if (use_bitmap
.GetMask())
1055 mask
= use_bitmap
.GetMask()->GetBitmap();
1057 if (useMask
&& mask
)
1059 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
1060 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
1061 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
1063 GrSetGCUseBackground(gc
, FALSE
);
1064 GrSetGCMode(gc
, GR_MODE_COPY
);
1066 // This code assumes that background and foreground
1067 // colours are used in ROPs, like in MSW.
1068 // Not sure if this is true.
1070 // Copy destination to buffer.
1071 // In DoBlit, we need this step because Blit has
1072 // a ROP argument. Here, we don't need it.
1073 // In DoBlit, we may be able to eliminate this step
1074 // if we check if the rop = copy
1076 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_window
,
1077 0, 0, GR_MODE_COPY
);
1080 // Copy src to buffer using selected raster op (none selected
1081 // in DrawBitmap, so just use Gxcopy)
1082 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
1083 0, 0, GR_MODE_COPY
);
1085 // Set masked area in buffer to BLACK (pixel value 0)
1086 GrSetGCBackground(gc
, WHITE
);
1087 GrSetGCForeground(gc
, BLACK
);
1088 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
1091 // set unmasked area in dest to BLACK
1092 GrSetGCBackground(gc
, BLACK
);
1093 GrSetGCForeground(gc
, WHITE
);
1094 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
1097 // OR buffer to dest
1098 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
1102 GrDestroyWindow(bufPixmap
);
1105 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1106 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1108 /* remove mask again if any */
1109 if (useMask
&& mask
)
1111 if (!m_currentClippingRegion
.IsNull())
1112 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1119 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1120 wxCoord x
, wxCoord y
,
1123 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1125 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1127 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1129 // scale/translate size and position
1130 int xx
= XLOG2DEV(x
);
1131 int yy
= YLOG2DEV(y
);
1133 int w
= bitmap
.GetWidth();
1134 int h
= bitmap
.GetHeight();
1136 CalcBoundingBox( x
, y
);
1137 CalcBoundingBox( x
+ w
, y
+ h
);
1139 if (!m_window
) return;
1141 int ww
= XLOG2DEVREL(w
);
1142 int hh
= YLOG2DEVREL(h
);
1144 // compare to current clipping region
1145 if (!m_currentClippingRegion
.IsNull())
1147 wxRegion
tmp( xx
,yy
,ww
,hh
);
1148 tmp
.Intersect( m_currentClippingRegion
);
1153 // scale bitmap if required
1154 wxBitmap use_bitmap
;
1155 if ((w
!= ww
) || (h
!= hh
))
1157 wxImage
image( bitmap
.ConvertToImage() );
1158 image
.Rescale( ww
, hh
);
1161 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1168 use_bitmap
= bitmap
;
1171 // apply mask if any
1172 WXPixmap mask
= NULL
;
1173 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1175 if (useMask
&& mask
)
1177 WXPixmap new_mask
= NULL
;
1179 if (!m_currentClippingRegion
.IsNull())
1182 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 );
1183 GdkGC
*gc
= gdk_gc_new( new_mask
);
1185 gdk_gc_set_foreground( gc
, &col
);
1186 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1188 gdk_gc_set_background( gc
, &col
);
1190 gdk_gc_set_foreground( gc
, &col
);
1191 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1192 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1193 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1194 gdk_gc_set_stipple( gc
, mask
);
1195 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1202 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1204 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1205 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1210 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1212 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1213 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1217 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1220 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1221 // drawing a mono-bitmap (XBitmap) we use the current text GC
1223 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1224 (GC
) m_textGC
, 0, 0, w
, h
, xx
, yy
, 1 );
1226 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1227 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1229 // remove mask again if any
1230 if (useMask
&& mask
)
1234 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1235 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1236 if (!m_currentClippingRegion
.IsNull())
1237 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1241 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1242 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1243 if (!m_currentClippingRegion
.IsNull())
1244 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1249 // wxUSE_NANOX/!wxUSE_NANOX
1251 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1252 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1253 wxCoord xsrcMask
, wxCoord ysrcMask
)
1255 /* this is the nth try to get this utterly useless function to
1256 work. it now completely ignores the scaling or translation
1257 of the source dc, but scales correctly on the target dc and
1258 knows about possible mask information in a memory dc. */
1260 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid window dc") );
1262 wxCHECK_MSG( source
, FALSE
, wxT("invalid source dc") );
1264 if (!m_window
) return FALSE
;
1266 // transform the source DC coords to the device ones
1267 xsrc
= source
->XLOG2DEV(xsrc
);
1268 ysrc
= source
->YLOG2DEV(ysrc
);
1270 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1271 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1273 bool use_bitmap_method
= FALSE
;
1274 bool is_mono
= FALSE
;
1276 // TODO: use the mask origin when drawing transparently
1277 if (xsrcMask
== -1 && ysrcMask
== -1)
1283 if (srcDC
->m_isMemDC
)
1285 if (!memDC
->m_selected
.Ok()) return FALSE
;
1287 /* we use the "XCopyArea" way to copy a memory dc into
1288 y different window if the memory dc BOTH
1289 a) doesn't have any mask or its mask isn't used
1293 if (useMask
&& (memDC
->m_selected
.GetMask()))
1295 /* we HAVE TO use the direct way for memory dcs
1296 that have mask since the XCopyArea doesn't know
1298 use_bitmap_method
= TRUE
;
1300 else if (memDC
->m_selected
.GetDepth() == 1)
1302 /* we HAVE TO use the direct way for memory dcs
1303 that are bitmaps because XCopyArea doesn't cope
1304 with different bit depths */
1306 use_bitmap_method
= TRUE
;
1308 else if ((xsrc
== 0) && (ysrc
== 0) &&
1309 (width
== memDC
->m_selected
.GetWidth()) &&
1310 (height
== memDC
->m_selected
.GetHeight()))
1312 /* we SHOULD use the direct way if all of the bitmap
1313 in the memory dc is copied in which case XCopyArea
1314 wouldn't be able able to boost performace by reducing
1315 the area to be scaled */
1316 use_bitmap_method
= TRUE
;
1320 use_bitmap_method
= FALSE
;
1324 CalcBoundingBox( xdest
, ydest
);
1325 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1327 // scale/translate size and position
1328 wxCoord xx
= XLOG2DEV(xdest
);
1329 wxCoord yy
= YLOG2DEV(ydest
);
1331 wxCoord ww
= XLOG2DEVREL(width
);
1332 wxCoord hh
= YLOG2DEVREL(height
);
1334 // compare to current clipping region
1335 if (!m_currentClippingRegion
.IsNull())
1337 wxRegion
tmp( xx
,yy
,ww
,hh
);
1338 tmp
.Intersect( m_currentClippingRegion
);
1343 int old_logical_func
= m_logicalFunction
;
1344 SetLogicalFunction( logical_func
);
1346 if (use_bitmap_method
)
1348 // scale/translate bitmap size
1349 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1350 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1352 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1353 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1355 // scale bitmap if required
1356 wxBitmap use_bitmap
;
1358 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1360 wxImage
image( memDC
->m_selected
.ConvertToImage() );
1361 image
= image
.Scale( bm_ww
, bm_hh
);
1365 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1372 use_bitmap
= memDC
->m_selected
;
1375 // apply mask if any
1376 WXPixmap mask
= NULL
;
1377 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1379 if (useMask
&& mask
)
1381 WXPixmap new_mask
= NULL
;
1383 if (!m_currentClippingRegion
.IsNull())
1386 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1387 GdkGC
*gc
= gdk_gc_new( new_mask
);
1389 gdk_gc_set_foreground( gc
, &col
);
1390 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1392 gdk_gc_set_background( gc
, &col
);
1394 gdk_gc_set_foreground( gc
, &col
);
1395 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1396 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1397 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1398 gdk_gc_set_stipple( gc
, mask
);
1399 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1406 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1408 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1409 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1414 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1416 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1417 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1421 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1424 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1425 // drawing a mono-bitmap (XBitmap) we use the current text GC
1428 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1429 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1431 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1432 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1434 // remove mask again if any
1435 if (useMask
&& mask
)
1439 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1440 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1441 if (!m_currentClippingRegion
.IsNull())
1442 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1446 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1447 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1448 if (!m_currentClippingRegion
.IsNull())
1449 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1453 else // use_bitmap_method
1455 if ((width
!= ww
) || (height
!= hh
))
1457 /* Draw source window into a bitmap as we cannot scale
1458 a window in contrast to a bitmap. this would actually
1459 work with memory dcs as well, but we'd lose the mask
1460 information and waste one step in this process since
1461 a memory already has a bitmap. all this is slightly
1462 inefficient as we could take an XImage directly from
1463 an X window, but we'd then also have to care that
1464 the window is not outside the screen (in which case
1465 we'd get a BadMatch or what not).
1466 Is a double XGetImage and combined XGetPixel and
1467 XPutPixel really faster? I'm not sure. look at wxXt
1468 for a different implementation of the same problem. */
1470 wxBitmap
bitmap( width
, height
);
1472 // copy including child window contents
1473 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1474 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) bitmap
.GetPixmap(),
1475 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1476 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1479 wxImage
image( bitmap
.ConvertToImage() );
1480 image
= image
.Scale( ww
, hh
);
1482 // convert to bitmap
1485 // draw scaled bitmap
1486 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_window
,
1487 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1491 // No scaling and not a memory dc with a mask either
1493 // copy including child window contents
1494 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1495 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) m_window
,
1496 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1497 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1501 SetLogicalFunction( old_logical_func
);
1506 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1508 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1510 if (!m_window
) return;
1516 PangoLayout
*layout
= pango_layout_new(m_context
);
1517 pango_layout_set_font_description(layout
, m_fontdesc
);
1519 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1520 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1524 pango_layout_get_pixel_size(layout
, &w
, &h
);
1529 x11_draw_layout( (Drawable
) m_window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1531 g_object_unref( G_OBJECT( layout
) );
1533 CalcBoundingBox (x
+ width
, y
+ height
);
1534 CalcBoundingBox (x
, y
);
1536 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1538 wxCHECK_RET( xfont
, wxT("invalid font") );
1540 // First draw a rectangle representing the text background, if a text
1541 // background is specified
1542 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1544 // Since X draws from the baseline of the text, must add the text height
1549 int direction
, descent
;
1551 slen
= strlen(text
);
1552 XCharStruct overall_return
;
1554 (void)XTextExtents(xfont
, (char*) text
.c_str(), slen
, &direction
,
1555 &ascent
, &descent
, &overall_return
);
1557 cx
= overall_return
.width
;
1558 cy
= ascent
+ descent
;
1559 m_textBackgroundColour
.CalcPixel(m_cmap
);
1560 m_textForegroundColour
.CalcPixel(m_cmap
);
1561 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1562 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
1563 (GC
) m_textGC
, x
, y
, cx
, cy
);
1564 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1568 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1570 if ((xfont
->min_byte1
== 0) && (xfont
->max_byte1
== 0))
1573 XDrawString( (Display
*) m_display
, (Window
) m_window
,
1574 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.Len() );
1578 if (m_font
.GetUnderlined())
1580 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1581 if (font
->descent
> 0) ul_y
++;
1582 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1585 width
= wxCoord(width
/ m_scaleX
);
1586 height
= wxCoord(height
/ m_scaleY
);
1588 CalcBoundingBox (x
+ width
, y
+ height
);
1589 CalcBoundingBox (x
, y
);
1594 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
, double angle
)
1599 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1600 wxCoord
*descent
, wxCoord
*externalLeading
,
1601 wxFont
*font
) const
1603 wxCHECK_RET( Ok(), wxT("invalid dc") );
1605 if (string
.IsEmpty())
1607 if (width
) (*width
) = 0;
1608 if (height
) (*height
) = 0;
1613 PangoLayout
*layout
= pango_layout_new( m_context
);
1616 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1618 pango_layout_set_font_description(layout
, m_fontdesc
);
1620 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1621 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1625 pango_layout_get_pixel_size(layout
, &w
, &h
);
1627 if (width
) (*width
) = (wxCoord
) w
;
1628 if (height
) (*height
) = (wxCoord
) h
;
1631 // Do something about metrics here. TODO.
1634 if (externalLeading
) (*externalLeading
) = 0; // ??
1636 g_object_unref( G_OBJECT( layout
) );
1638 wxFont fontToUse
= m_font
;
1639 if (font
) fontToUse
= *font
;
1641 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
1643 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1645 wxCHECK_RET( xfont
, wxT("invalid font") );
1647 int direction
, ascent
, descent2
;
1648 XCharStruct overall
;
1650 XTextExtents( xfont
, (char*) string
.c_str(), string
.Len(), &direction
,
1651 &ascent
, &descent2
, &overall
);
1654 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1656 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1658 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1659 if (externalLeading
)
1660 *externalLeading
= 0; // ??
1664 wxCoord
wxWindowDC::GetCharWidth() const
1666 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1669 PangoLayout
*layout
= pango_layout_new( m_context
);
1677 pango_layout_set_font_description(layout
, m_fontdesc
);
1678 pango_layout_set_text(layout
, "H", 1 );
1680 pango_layout_get_pixel_size(layout
, &w
, &h
);
1681 g_object_unref( G_OBJECT( layout
) );
1685 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1687 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1689 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1691 int direction
, ascent
, descent
;
1692 XCharStruct overall
;
1694 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1696 return (wxCoord
)(overall
.width
/ m_scaleX
);
1700 wxCoord
wxWindowDC::GetCharHeight() const
1702 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1705 PangoLayout
*layout
= pango_layout_new( m_context
);
1713 pango_layout_set_font_description(layout
, m_fontdesc
);
1715 pango_layout_set_text(layout
, "H", 1 );
1717 pango_layout_get_pixel_size(layout
, &w
, &h
);
1718 g_object_unref( G_OBJECT( layout
) );
1722 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1724 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1726 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1728 int direction
, ascent
, descent
;
1729 XCharStruct overall
;
1731 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1733 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1737 void wxWindowDC::Clear()
1739 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1741 if (!m_window
) return;
1743 /* - we either are a memory dc or have a window as the
1744 owner. anything else shouldn't happen.
1745 - we don't use gdk_window_clear() as we don't set
1746 the window's background colour anymore. it is too
1747 much pain to keep the DC's and the window's back-
1748 ground colour in synch. */
1753 m_owner
->GetSize( &width
, &height
);
1754 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1761 GetSize( &width
, &height
);
1762 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1767 void wxWindowDC::SetFont( const wxFont
&font
)
1769 wxCHECK_RET( Ok(), wxT("invalid dc") );
1774 void wxWindowDC::SetPen( const wxPen
&pen
)
1776 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1778 if (m_pen
== pen
) return;
1782 if (!m_pen
.Ok()) return;
1784 if (!m_window
) return;
1786 int width
= m_pen
.GetWidth();
1789 // CMB: if width is non-zero scale it with the dc
1794 // X doesn't allow different width in x and y and so we take
1797 ( fabs((double) XLOG2DEVREL(width
)) +
1798 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1802 static const wxX11Dash dotted
[] = {1, 1};
1803 static const wxX11Dash short_dashed
[] = {2, 2};
1804 static const wxX11Dash long_dashed
[] = {2, 4};
1805 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1807 // We express dash pattern in pen width unit, so we are
1808 // independent of zoom factor and so on...
1810 const wxX11Dash
*req_dash
;
1812 int lineStyle
= LineSolid
;
1813 switch (m_pen
.GetStyle())
1817 lineStyle
= LineOnOffDash
;
1818 req_nb_dash
= m_pen
.GetDashCount();
1819 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1824 lineStyle
= LineOnOffDash
;
1831 lineStyle
= LineOnOffDash
;
1833 req_dash
= long_dashed
;
1838 lineStyle
= LineOnOffDash
;
1840 req_dash
= short_dashed
;
1845 // lineStyle = LineDoubleDash;
1846 lineStyle
= LineOnOffDash
;
1848 req_dash
= dotted_dashed
;
1853 case wxSTIPPLE_MASK_OPAQUE
:
1858 lineStyle
= LineSolid
;
1859 req_dash
= (wxX11Dash
*)NULL
;
1865 int capStyle
= CapRound
;
1866 switch (m_pen
.GetCap())
1868 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1869 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1876 capStyle
= CapNotLast
;
1880 capStyle
= CapRound
;
1886 int joinStyle
= JoinRound
;
1887 switch (m_pen
.GetJoin())
1889 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1890 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1892 default: { joinStyle
= JoinRound
; break; }
1895 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1897 m_pen
.GetColour().CalcPixel( m_cmap
);
1898 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1901 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1903 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1905 if (m_brush
== brush
) return;
1909 if (!m_brush
.Ok()) return;
1911 if (!m_window
) return;
1913 m_brush
.GetColour().CalcPixel( m_cmap
);
1914 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1916 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1918 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1920 if (m_brush
.GetStipple()->GetPixmap())
1922 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1923 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1927 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1928 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1932 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1934 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1935 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1938 if (IS_HATCH(m_brush
.GetStyle()))
1940 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1941 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1942 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1946 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1948 /* CMB 21/7/98: Added SetBackground. Sets background brush
1949 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1951 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1953 if (m_backgroundBrush
== brush
) return;
1955 m_backgroundBrush
= brush
;
1957 if (!m_backgroundBrush
.Ok()) return;
1959 if (!m_window
) return;
1961 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1962 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1963 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1964 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1965 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1967 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1969 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1971 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1973 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1974 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1978 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1979 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
1983 if (IS_HATCH(m_backgroundBrush
.GetStyle()))
1985 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1986 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
1987 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
1991 void wxWindowDC::SetLogicalFunction( int function
)
1993 wxCHECK_RET( Ok(), wxT("invalid dc") );
1997 if (m_logicalFunction
== function
)
2000 // VZ: shouldn't this be a CHECK?
2007 x_function
= GXclear
;
2013 x_function
= GXinvert
;
2016 x_function
= GXorReverse
;
2019 x_function
= GXandReverse
;
2028 x_function
= GXandInverted
;
2031 x_function
= GXnoop
;
2037 x_function
= GXequiv
;
2040 x_function
= GXcopyInverted
;
2043 x_function
= GXorInverted
;
2046 x_function
= GXnand
;
2053 x_function
= GXcopy
;
2057 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2058 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2060 // to stay compatible with wxMSW, we don't apply ROPs to the text
2061 // operations (i.e. DrawText/DrawRotatedText).
2062 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2063 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2065 m_logicalFunction
= function
;
2068 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2070 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2072 // don't set m_textForegroundColour to an invalid colour as we'd crash
2073 // later then (we use m_textForegroundColour.GetColor() without checking
2075 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
2078 m_textForegroundColour
= col
;
2082 m_textForegroundColour
.CalcPixel( m_cmap
);
2083 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2087 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2089 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2092 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
2095 m_textBackgroundColour
= col
;
2099 m_textBackgroundColour
.CalcPixel( m_cmap
);
2100 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2104 void wxWindowDC::SetBackgroundMode( int mode
)
2106 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2108 m_backgroundMode
= mode
;
2111 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2114 if (!m_window
) return;
2116 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2117 // transparent/solid background mode
2119 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2121 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2122 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2126 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2132 /* Use GetXColormap */
2133 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2134 (Colormap
) palette
.GetXColormap());
2136 /* Use wxGetMainColormap */
2137 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2138 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2143 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2145 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2147 if (!m_window
) return;
2150 rect
.x
= XLOG2DEV(x
);
2151 rect
.y
= YLOG2DEV(y
);
2152 rect
.width
= XLOG2DEVREL(width
);
2153 rect
.height
= YLOG2DEVREL(height
);
2155 if (!m_currentClippingRegion
.IsNull())
2156 m_currentClippingRegion
.Intersect( rect
);
2158 m_currentClippingRegion
.Union( rect
);
2160 #if USE_PAINT_REGION
2161 if (!m_paintClippingRegion
.IsNull())
2162 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2165 wxCoord xx
, yy
, ww
, hh
;
2166 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2167 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2169 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2170 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2171 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2172 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2175 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2177 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2181 DestroyClippingRegion();
2185 if (!m_window
) return;
2187 if (!m_currentClippingRegion
.IsNull())
2188 m_currentClippingRegion
.Intersect( region
);
2190 m_currentClippingRegion
.Union( region
);
2192 #if USE_PAINT_REGION
2193 if (!m_paintClippingRegion
.IsNull())
2194 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2197 wxCoord xx
, yy
, ww
, hh
;
2198 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2199 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2201 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2202 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2203 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2204 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2207 void wxWindowDC::DestroyClippingRegion()
2209 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2211 wxDC::DestroyClippingRegion();
2213 m_currentClippingRegion
.Clear();
2215 #if USE_PAINT_REGION
2216 if (!m_paintClippingRegion
.IsEmpty())
2217 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2220 if (!m_window
) return;
2222 if (m_currentClippingRegion
.IsEmpty())
2224 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2225 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2226 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2227 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2231 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2232 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2233 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2234 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2238 void wxWindowDC::Destroy()
2240 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2242 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2244 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2246 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2250 void wxWindowDC::ComputeScaleAndOrigin()
2252 /* CMB: copy scale to see if it changes */
2253 double origScaleX
= m_scaleX
;
2254 double origScaleY
= m_scaleY
;
2256 wxDC::ComputeScaleAndOrigin();
2258 /* CMB: if scale has changed call SetPen to recalulate the line width */
2259 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2262 /* this is a bit artificial, but we need to force wxDC to think
2263 the pen has changed */
2270 wxSize
wxWindowDC::GetPPI() const
2272 return wxSize(100, 100);
2275 int wxWindowDC::GetDepth() const
2277 wxFAIL_MSG(wxT("not implemented"));
2282 //-----------------------------------------------------------------------------
2284 //-----------------------------------------------------------------------------
2286 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2288 wxClientDC::wxClientDC( wxWindow
*window
)
2289 : wxWindowDC( window
)
2291 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2293 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2295 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2296 if (m_window
== (WXWindow
*) window
->GetMainWindow())
2298 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2299 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2300 wxSize size
= window
->GetClientSize();
2301 SetClippingRegion(wxPoint(0, 0), size
);
2305 void wxClientDC::DoGetSize(int *width
, int *height
) const
2307 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2309 m_owner
->GetClientSize( width
, height
);
2312 // ----------------------------------------------------------------------------
2314 // ----------------------------------------------------------------------------
2316 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2318 wxPaintDC::wxPaintDC(wxWindow
* window
)
2319 : wxClientDC(window
)
2321 #if USE_PAINT_REGION
2322 if (!window
->GetClipPaintRegion())
2325 m_paintClippingRegion
= window
->GetUpdateRegion();
2326 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2329 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2331 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2332 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2333 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2334 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2336 #endif // USE_PAINT_REGION
2339 // ----------------------------------------------------------------------------
2341 // ----------------------------------------------------------------------------
2343 class wxDCModule
: public wxModule
2350 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2353 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)
2355 bool wxDCModule::OnInit()
2361 void wxDCModule::OnExit()