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();
270 m_textForegroundColour
.CalcPixel( m_cmap
);
271 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
273 m_textBackgroundColour
.CalcPixel( m_cmap
);
274 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
276 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
279 // By default, draw transparently
280 GrSetGCUseBackground((GC
) m_textGC
, FALSE
);
284 m_pen
.GetColour().CalcPixel( m_cmap
);
285 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
286 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
288 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
291 m_brush
.GetColour().CalcPixel( m_cmap
);
292 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
293 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
295 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
298 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
299 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
301 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
304 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
305 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
306 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
309 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
310 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
311 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
312 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
316 int xscreen
= DefaultScreen( (Display
*) m_display
);
317 Window xroot
= RootWindow( (Display
*) m_display
, xscreen
);
319 hatch_bitmap
= hatches
;
320 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, bdiag_bits
, bdiag_width
, bdiag_height
);
321 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cdiag_bits
, cdiag_width
, cdiag_height
);
322 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, fdiag_bits
, fdiag_width
, fdiag_height
);
323 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cross_bits
, cross_width
, cross_height
);
324 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, horiz_bits
, horiz_width
, horiz_height
);
325 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, verti_bits
, verti_width
, verti_height
);
329 void wxWindowDC::DoGetSize( int* width
, int* height
) const
331 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
333 m_owner
->GetSize(width
, height
);
336 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
337 const wxColour
& col
, int style
);
339 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
340 const wxColour
& col
, int style
)
342 return wxDoFloodFill(this, x
, y
, col
, style
);
345 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
347 // Generic (and therefore rather inefficient) method.
348 // Could be improved.
350 wxBitmap
bitmap(1, 1);
351 memdc
.SelectObject(bitmap
);
352 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
353 memdc
.SelectObject(wxNullBitmap
);
354 wxImage
image(bitmap
.ConvertToImage());
355 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
359 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
361 wxCHECK_RET( Ok(), wxT("invalid window dc") );
363 if (m_pen
.GetStyle() != wxTRANSPARENT
)
367 // This hack is for the iPaq: XDrawLine draws
368 // nothing, whereas XDrawLines works...
374 DrawLines( 2, points
, 0, 0 );
376 // XDrawLine( (Display*) m_display, (Window) m_window,
377 // (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
380 CalcBoundingBox(x1
, y1
);
381 CalcBoundingBox(x2
, y2
);
385 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
387 wxCHECK_RET( Ok(), wxT("invalid window dc") );
389 if (m_pen
.GetStyle() != wxTRANSPARENT
)
394 wxCoord xx
= XLOG2DEV(x
);
395 wxCoord yy
= YLOG2DEV(y
);
398 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
399 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
400 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
401 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
406 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
408 wxCHECK_RET( Ok(), wxT("invalid window dc") );
410 wxCoord xx1
= XLOG2DEV(x1
);
411 wxCoord yy1
= YLOG2DEV(y1
);
412 wxCoord xx2
= XLOG2DEV(x2
);
413 wxCoord yy2
= YLOG2DEV(y2
);
414 wxCoord xxc
= XLOG2DEV(xc
);
415 wxCoord yyc
= YLOG2DEV(yc
);
416 double dx
= xx1
- xxc
;
417 double dy
= yy1
- yyc
;
418 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
419 wxCoord r
= (wxCoord
)radius
;
420 double radius1
, radius2
;
422 if (xx1
== xx2
&& yy1
== yy2
)
430 radius1
= radius2
= 0.0;
434 radius1
= (xx1
- xxc
== 0) ?
435 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
436 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
437 radius2
= (xx2
- xxc
== 0) ?
438 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
439 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
441 wxCoord alpha1
= wxCoord(radius1
* 64.0);
442 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
443 while (alpha2
<= 0) alpha2
+= 360*64;
444 while (alpha1
> 360*64) alpha1
-= 360*64;
448 if (m_brush
.GetStyle() != wxTRANSPARENT
)
450 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
452 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
453 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
454 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
456 XFillArc( (Display
*) m_display
, (Window
) m_window
,
457 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
459 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
461 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
463 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
464 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
466 XFillArc( (Display
*) m_display
, (Window
) m_window
,
467 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
469 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
471 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
473 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
474 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
476 XFillArc( (Display
*) m_display
, (Window
) m_window
,
477 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
479 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
481 if (m_brush
.GetStyle() == wxSTIPPLE
)
483 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
484 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
485 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
487 XFillArc( (Display
*) m_display
, (Window
) m_window
,
488 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
490 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
494 XFillArc( (Display
*) m_display
, (Window
) m_window
,
495 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
499 if (m_pen
.GetStyle() != wxTRANSPARENT
)
501 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
502 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
504 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
505 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
507 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
508 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
512 CalcBoundingBox (x1
, y1
);
513 CalcBoundingBox (x2
, y2
);
516 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
518 wxCHECK_RET( Ok(), wxT("invalid window dc") );
520 wxCoord xx
= XLOG2DEV(x
);
521 wxCoord yy
= YLOG2DEV(y
);
522 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
523 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
525 // CMB: handle -ve width and/or height
526 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
527 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
531 wxCoord start
= wxCoord(sa
* 64.0);
532 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
534 if (m_brush
.GetStyle() != wxTRANSPARENT
)
536 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
538 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
539 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
540 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
542 XFillArc( (Display
*) m_display
, (Window
) m_window
,
543 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
545 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
547 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
549 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
550 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
552 XFillArc( (Display
*) m_display
, (Window
) m_window
,
553 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
555 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
557 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
559 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
560 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
562 XFillArc( (Display
*) m_display
, (Window
) m_window
,
563 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
565 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
567 if (m_brush
.GetStyle() == wxSTIPPLE
)
569 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
570 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
571 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
573 XFillArc( (Display
*) m_display
, (Window
) m_window
,
574 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
576 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
580 XFillArc( (Display
*) m_display
, (Window
) m_window
,
581 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
585 if (m_pen
.GetStyle() != wxTRANSPARENT
)
587 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
588 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
592 CalcBoundingBox (x
, y
);
593 CalcBoundingBox (x
+ width
, y
+ height
);
596 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
598 wxCHECK_RET( Ok(), wxT("invalid window dc") );
600 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
)
601 XDrawPoint( (Display
*) m_display
, (Window
) m_window
,
602 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
604 CalcBoundingBox (x
, y
);
607 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
609 wxCHECK_RET( Ok(), wxT("invalid window dc") );
611 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
614 XPoint
*xpoints
= new XPoint
[n
];
615 for (int i
= 0; i
< n
; i
++)
617 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
618 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
620 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
622 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
, 0 );
627 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
628 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
630 wxCHECK_RET( Ok(), wxT("invalid window dc") );
634 XPoint
*xpoints
= new XPoint
[n
+ 1];
636 for (i
= 0; i
< n
; i
++)
638 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
639 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
641 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
646 if (m_brush
.GetStyle() != wxTRANSPARENT
)
649 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
651 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
652 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
653 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
655 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
656 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
658 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
660 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
662 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
663 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
665 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
666 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
668 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
670 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
672 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
673 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
675 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
676 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
678 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
680 if (m_brush
.GetStyle() == wxSTIPPLE
)
682 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
683 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
684 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
686 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
687 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
689 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
693 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
694 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
698 if (m_pen
.GetStyle () != wxTRANSPARENT
)
700 // Close figure for XDrawLines
701 xpoints
[i
].x
= xpoints
[0].x
;
702 xpoints
[i
].y
= xpoints
[0].y
;
704 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
711 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
713 wxCHECK_RET( Ok(), wxT("invalid window dc") );
715 wxCoord xx
= XLOG2DEV(x
);
716 wxCoord yy
= YLOG2DEV(y
);
717 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
718 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
720 // CMB: draw nothing if transformed w or h is 0
721 if (ww
== 0 || hh
== 0) return;
723 // CMB: handle -ve width and/or height
724 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
725 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
729 if (m_brush
.GetStyle() != wxTRANSPARENT
)
731 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
733 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
734 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
735 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
737 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
738 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
740 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
742 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
744 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
745 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
747 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
748 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
750 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
752 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
754 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
755 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
757 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
758 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
760 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
762 if (m_brush
.GetStyle() == wxSTIPPLE
)
764 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
765 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
766 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
768 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
769 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
771 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
775 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
776 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
780 if (m_pen
.GetStyle () != wxTRANSPARENT
)
782 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
783 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
787 CalcBoundingBox( x
, y
);
788 CalcBoundingBox( x
+ width
, y
+ height
);
791 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
793 wxCHECK_RET( Ok(), wxT("invalid window dc") );
795 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
797 wxCoord xx
= XLOG2DEV(x
);
798 wxCoord yy
= YLOG2DEV(y
);
799 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
800 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
801 wxCoord rr
= XLOG2DEVREL((wxCoord
)radius
);
803 // CMB: handle -ve width and/or height
804 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
805 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
807 // CMB: if radius is zero use DrawRectangle() instead to avoid
808 // X drawing errors with small radii
811 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
812 (GC
) m_penGC
, x
, y
, width
, height
);
816 // CMB: draw nothing if transformed w or h is 0
817 if (ww
== 0 || hh
== 0) return;
819 // CMB: adjust size if outline is drawn otherwise the result is
820 // 1 pixel too wide and high
821 if (m_pen
.GetStyle() != wxTRANSPARENT
)
829 // CMB: ensure dd is not larger than rectangle otherwise we
830 // get an hour glass shape
832 if (dd
> ww
) dd
= ww
;
833 if (dd
> hh
) dd
= hh
;
836 if (m_brush
.GetStyle() != wxTRANSPARENT
)
838 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
840 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
841 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
842 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
843 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
844 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
845 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
846 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
847 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
848 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
849 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0);
851 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
853 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
854 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
855 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
856 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
857 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
858 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
859 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
860 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
862 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
864 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
865 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
866 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
867 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
868 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
869 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
870 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
871 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
873 if (m_brush
.GetStyle() == wxSTIPPLE
)
875 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
876 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
877 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
878 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
879 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
880 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
881 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
882 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
883 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
884 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
888 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
889 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
890 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
891 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
892 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
893 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
896 if (m_pen
.GetStyle() != wxTRANSPARENT
)
898 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy
);
899 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
900 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr
);
901 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr
);
902 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
903 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
904 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
905 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
909 // this ignores the radius
910 CalcBoundingBox( x
, y
);
911 CalcBoundingBox( x
+ width
, y
+ height
);
914 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
916 wxCHECK_RET( Ok(), wxT("invalid window dc") );
918 wxCoord xx
= XLOG2DEV(x
);
919 wxCoord yy
= YLOG2DEV(y
);
920 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
921 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
923 // CMB: handle -ve width and/or height
924 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
925 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
929 if (m_brush
.GetStyle() != wxTRANSPARENT
)
931 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
933 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
934 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
935 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
937 XFillArc( (Display
*) m_display
, (Window
) m_window
,
938 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
940 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
942 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
944 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
945 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
947 XFillArc( (Display
*) m_display
, (Window
) m_window
,
948 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
950 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
952 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
954 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
955 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
957 XFillArc( (Display
*) m_display
, (Window
) m_window
,
958 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
960 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
962 if (m_brush
.GetStyle() == wxSTIPPLE
)
964 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
965 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
966 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
968 XFillArc( (Display
*) m_display
, (Window
) m_window
,
969 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
971 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
975 XFillArc( (Display
*) m_display
, (Window
) m_window
,
976 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
980 if (m_pen
.GetStyle () != wxTRANSPARENT
)
982 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
983 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
987 CalcBoundingBox( x
, y
);
988 CalcBoundingBox( x
+ width
, y
+ height
);
991 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
993 DoDrawBitmap(icon
, x
, y
, TRUE
);
997 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
998 wxCoord x
, wxCoord y
,
1001 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1003 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1005 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1007 /* scale/translate size and position */
1008 int xx
= XLOG2DEV(x
);
1009 int yy
= YLOG2DEV(y
);
1011 int w
= bitmap
.GetWidth();
1012 int h
= bitmap
.GetHeight();
1014 CalcBoundingBox( x
, y
);
1015 CalcBoundingBox( x
+ w
, y
+ h
);
1017 if (!m_window
) return;
1019 int ww
= XLOG2DEVREL(w
);
1020 int hh
= YLOG2DEVREL(h
);
1022 /* compare to current clipping region */
1023 if (!m_currentClippingRegion
.IsNull())
1025 wxRegion
tmp( xx
,yy
,ww
,hh
);
1026 tmp
.Intersect( m_currentClippingRegion
);
1031 /* scale bitmap if required */
1032 wxBitmap use_bitmap
;
1033 if ((w
!= ww
) || (h
!= hh
))
1035 wxImage
image( bitmap
.ConvertToImage() );
1036 image
.Rescale( ww
, hh
);
1039 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1046 use_bitmap
= bitmap
;
1049 /* apply mask if any */
1050 WXPixmap mask
= NULL
;
1051 if (use_bitmap
.GetMask())
1052 mask
= use_bitmap
.GetMask()->GetBitmap();
1054 if (useMask
&& mask
)
1056 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
1057 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
1058 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
1060 GrSetGCUseBackground(gc
, FALSE
);
1061 GrSetGCMode(gc
, GR_MODE_COPY
);
1063 // This code assumes that background and foreground
1064 // colours are used in ROPs, like in MSW.
1065 // Not sure if this is true.
1067 // Copy destination to buffer.
1068 // In DoBlit, we need this step because Blit has
1069 // a ROP argument. Here, we don't need it.
1070 // In DoBlit, we may be able to eliminate this step
1071 // if we check if the rop = copy
1073 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_window
,
1074 0, 0, GR_MODE_COPY
);
1077 // Copy src to buffer using selected raster op (none selected
1078 // in DrawBitmap, so just use Gxcopy)
1079 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
1080 0, 0, GR_MODE_COPY
);
1082 // Set masked area in buffer to BLACK (pixel value 0)
1083 GrSetGCBackground(gc
, WHITE
);
1084 GrSetGCForeground(gc
, BLACK
);
1085 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
1088 // set unmasked area in dest to BLACK
1089 GrSetGCBackground(gc
, BLACK
);
1090 GrSetGCForeground(gc
, WHITE
);
1091 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
1094 // OR buffer to dest
1095 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
1099 GrDestroyWindow(bufPixmap
);
1102 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1103 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1105 /* remove mask again if any */
1106 if (useMask
&& mask
)
1108 if (!m_currentClippingRegion
.IsNull())
1109 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1116 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1117 wxCoord x
, wxCoord y
,
1120 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1122 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1124 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1126 // scale/translate size and position
1127 int xx
= XLOG2DEV(x
);
1128 int yy
= YLOG2DEV(y
);
1130 int w
= bitmap
.GetWidth();
1131 int h
= bitmap
.GetHeight();
1133 CalcBoundingBox( x
, y
);
1134 CalcBoundingBox( x
+ w
, y
+ h
);
1136 if (!m_window
) return;
1138 int ww
= XLOG2DEVREL(w
);
1139 int hh
= YLOG2DEVREL(h
);
1141 // compare to current clipping region
1142 if (!m_currentClippingRegion
.IsNull())
1144 wxRegion
tmp( xx
,yy
,ww
,hh
);
1145 tmp
.Intersect( m_currentClippingRegion
);
1150 // scale bitmap if required
1151 wxBitmap use_bitmap
;
1152 if ((w
!= ww
) || (h
!= hh
))
1154 wxImage
image( bitmap
.ConvertToImage() );
1155 image
.Rescale( ww
, hh
);
1158 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1165 use_bitmap
= bitmap
;
1168 // apply mask if any
1169 WXPixmap mask
= NULL
;
1170 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1172 if (useMask
&& mask
)
1174 WXPixmap new_mask
= NULL
;
1176 if (!m_currentClippingRegion
.IsNull())
1179 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 );
1180 GdkGC
*gc
= gdk_gc_new( new_mask
);
1182 gdk_gc_set_foreground( gc
, &col
);
1183 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1185 gdk_gc_set_background( gc
, &col
);
1187 gdk_gc_set_foreground( gc
, &col
);
1188 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1189 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1190 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1191 gdk_gc_set_stipple( gc
, mask
);
1192 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1199 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1201 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1202 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1207 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1209 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1210 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1214 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1217 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1218 // drawing a mono-bitmap (XBitmap) we use the current text GC
1220 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1221 (GC
) m_textGC
, 0, 0, w
, h
, xx
, yy
, 1 );
1223 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1224 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1226 // remove mask again if any
1227 if (useMask
&& mask
)
1231 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1232 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1233 if (!m_currentClippingRegion
.IsNull())
1234 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1238 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1239 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1240 if (!m_currentClippingRegion
.IsNull())
1241 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1246 // wxUSE_NANOX/!wxUSE_NANOX
1248 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1249 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1250 wxCoord xsrcMask
, wxCoord ysrcMask
)
1252 /* this is the nth try to get this utterly useless function to
1253 work. it now completely ignores the scaling or translation
1254 of the source dc, but scales correctly on the target dc and
1255 knows about possible mask information in a memory dc. */
1257 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid window dc") );
1259 wxCHECK_MSG( source
, FALSE
, wxT("invalid source dc") );
1261 if (!m_window
) return FALSE
;
1263 // transform the source DC coords to the device ones
1264 xsrc
= source
->XLOG2DEV(xsrc
);
1265 ysrc
= source
->YLOG2DEV(ysrc
);
1267 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1268 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1270 bool use_bitmap_method
= FALSE
;
1271 bool is_mono
= FALSE
;
1273 // TODO: use the mask origin when drawing transparently
1274 if (xsrcMask
== -1 && ysrcMask
== -1)
1280 if (srcDC
->m_isMemDC
)
1282 if (!memDC
->m_selected
.Ok()) return FALSE
;
1284 /* we use the "XCopyArea" way to copy a memory dc into
1285 y different window if the memory dc BOTH
1286 a) doesn't have any mask or its mask isn't used
1290 if (useMask
&& (memDC
->m_selected
.GetMask()))
1292 /* we HAVE TO use the direct way for memory dcs
1293 that have mask since the XCopyArea doesn't know
1295 use_bitmap_method
= TRUE
;
1297 else if (memDC
->m_selected
.GetDepth() == 1)
1299 /* we HAVE TO use the direct way for memory dcs
1300 that are bitmaps because XCopyArea doesn't cope
1301 with different bit depths */
1303 use_bitmap_method
= TRUE
;
1305 else if ((xsrc
== 0) && (ysrc
== 0) &&
1306 (width
== memDC
->m_selected
.GetWidth()) &&
1307 (height
== memDC
->m_selected
.GetHeight()))
1309 /* we SHOULD use the direct way if all of the bitmap
1310 in the memory dc is copied in which case XCopyArea
1311 wouldn't be able able to boost performace by reducing
1312 the area to be scaled */
1313 use_bitmap_method
= TRUE
;
1317 use_bitmap_method
= FALSE
;
1321 CalcBoundingBox( xdest
, ydest
);
1322 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1324 // scale/translate size and position
1325 wxCoord xx
= XLOG2DEV(xdest
);
1326 wxCoord yy
= YLOG2DEV(ydest
);
1328 wxCoord ww
= XLOG2DEVREL(width
);
1329 wxCoord hh
= YLOG2DEVREL(height
);
1331 // compare to current clipping region
1332 if (!m_currentClippingRegion
.IsNull())
1334 wxRegion
tmp( xx
,yy
,ww
,hh
);
1335 tmp
.Intersect( m_currentClippingRegion
);
1340 int old_logical_func
= m_logicalFunction
;
1341 SetLogicalFunction( logical_func
);
1343 if (use_bitmap_method
)
1345 // scale/translate bitmap size
1346 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1347 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1349 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1350 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1352 // scale bitmap if required
1353 wxBitmap use_bitmap
;
1355 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1357 wxImage
image( memDC
->m_selected
.ConvertToImage() );
1358 image
= image
.Scale( bm_ww
, bm_hh
);
1362 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1369 use_bitmap
= memDC
->m_selected
;
1372 // apply mask if any
1373 WXPixmap mask
= NULL
;
1374 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1376 if (useMask
&& mask
)
1378 WXPixmap new_mask
= NULL
;
1380 if (!m_currentClippingRegion
.IsNull())
1383 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1384 GdkGC
*gc
= gdk_gc_new( new_mask
);
1386 gdk_gc_set_foreground( gc
, &col
);
1387 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1389 gdk_gc_set_background( gc
, &col
);
1391 gdk_gc_set_foreground( gc
, &col
);
1392 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1393 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1394 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1395 gdk_gc_set_stipple( gc
, mask
);
1396 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1403 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1405 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1406 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1411 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1413 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1414 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1418 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1421 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1422 // drawing a mono-bitmap (XBitmap) we use the current text GC
1425 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1426 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1428 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1429 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1431 // remove mask again if any
1432 if (useMask
&& mask
)
1436 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1437 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1438 if (!m_currentClippingRegion
.IsNull())
1439 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1443 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1444 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1445 if (!m_currentClippingRegion
.IsNull())
1446 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1450 else // use_bitmap_method
1452 if ((width
!= ww
) || (height
!= hh
))
1454 /* Draw source window into a bitmap as we cannot scale
1455 a window in contrast to a bitmap. this would actually
1456 work with memory dcs as well, but we'd lose the mask
1457 information and waste one step in this process since
1458 a memory already has a bitmap. all this is slightly
1459 inefficient as we could take an XImage directly from
1460 an X window, but we'd then also have to care that
1461 the window is not outside the screen (in which case
1462 we'd get a BadMatch or what not).
1463 Is a double XGetImage and combined XGetPixel and
1464 XPutPixel really faster? I'm not sure. look at wxXt
1465 for a different implementation of the same problem. */
1467 wxBitmap
bitmap( width
, height
);
1469 // copy including child window contents
1470 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1471 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) bitmap
.GetPixmap(),
1472 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1473 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1476 wxImage
image( bitmap
.ConvertToImage() );
1477 image
= image
.Scale( ww
, hh
);
1479 // convert to bitmap
1482 // draw scaled bitmap
1483 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_window
,
1484 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1488 // No scaling and not a memory dc with a mask either
1490 // copy including child window contents
1491 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1492 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) m_window
,
1493 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1494 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1498 SetLogicalFunction( old_logical_func
);
1503 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1505 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1507 if (!m_window
) return;
1513 PangoLayout
*layout
= pango_layout_new(m_context
);
1514 pango_layout_set_font_description(layout
, m_fontdesc
);
1516 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1517 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1521 pango_layout_get_pixel_size(layout
, &w
, &h
);
1526 x11_draw_layout( (Drawable
) m_window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1528 g_object_unref( G_OBJECT( layout
) );
1530 CalcBoundingBox (x
+ width
, y
+ height
);
1531 CalcBoundingBox (x
, y
);
1533 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1535 wxCHECK_RET( xfont
, wxT("invalid font") );
1537 // First draw a rectangle representing the text background, if a text
1538 // background is specified
1539 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1541 // Since X draws from the baseline of the text, must add the text height
1546 int direction
, descent
;
1548 slen
= strlen(text
);
1549 XCharStruct overall_return
;
1551 (void)XTextExtents(xfont
, (char*) text
.c_str(), slen
, &direction
,
1552 &ascent
, &descent
, &overall_return
);
1554 cx
= overall_return
.width
;
1555 cy
= ascent
+ descent
;
1556 m_textBackgroundColour
.CalcPixel(m_cmap
);
1557 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1558 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
1559 (GC
) m_textGC
, x
, y
, cx
, cy
);
1560 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1564 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1566 if ((xfont
->min_byte1
== 0) && (xfont
->max_byte1
== 0))
1569 XDrawString( (Display
*) m_display
, (Window
) m_window
,
1570 (GC
) m_textGC
, x
, y
+ XFontStructGetAscent(xfont
), text
.c_str(), text
.Len() );
1574 if (m_font
.GetUnderlined())
1576 wxCoord ul_y
= y
+ XFontStructGetAscent(font
);
1577 if (font
->descent
> 0) ul_y
++;
1578 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1581 width
= wxCoord(width
/ m_scaleX
);
1582 height
= wxCoord(height
/ m_scaleY
);
1584 CalcBoundingBox (x
+ width
, y
+ height
);
1585 CalcBoundingBox (x
, y
);
1590 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
, double angle
)
1595 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1596 wxCoord
*descent
, wxCoord
*externalLeading
,
1597 wxFont
*font
) const
1599 wxCHECK_RET( Ok(), wxT("invalid dc") );
1601 if (string
.IsEmpty())
1603 if (width
) (*width
) = 0;
1604 if (height
) (*height
) = 0;
1609 PangoLayout
*layout
= pango_layout_new( m_context
);
1612 pango_layout_set_font_description( layout
, font
->GetNativeFontInfo()->description
);
1614 pango_layout_set_font_description(layout
, m_fontdesc
);
1616 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( string
);
1617 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1621 pango_layout_get_pixel_size(layout
, &w
, &h
);
1623 if (width
) (*width
) = (wxCoord
) w
;
1624 if (height
) (*height
) = (wxCoord
) h
;
1627 // Do something about metrics here. TODO.
1630 if (externalLeading
) (*externalLeading
) = 0; // ??
1632 g_object_unref( G_OBJECT( layout
) );
1634 wxFont fontToUse
= m_font
;
1635 if (font
) fontToUse
= *font
;
1637 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
1639 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1641 wxCHECK_RET( xfont
, wxT("invalid font") );
1643 int direction
, ascent
, descent2
;
1644 XCharStruct overall
;
1646 XTextExtents( xfont
, (char*) string
.c_str(), string
.Len(), &direction
,
1647 &ascent
, &descent2
, &overall
);
1650 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1652 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1654 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1655 if (externalLeading
)
1656 *externalLeading
= 0; // ??
1660 wxCoord
wxWindowDC::GetCharWidth() const
1662 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1665 PangoLayout
*layout
= pango_layout_new( m_context
);
1673 pango_layout_set_font_description(layout
, m_fontdesc
);
1674 pango_layout_set_text(layout
, "H", 1 );
1676 pango_layout_get_pixel_size(layout
, &w
, &h
);
1677 g_object_unref( G_OBJECT( layout
) );
1681 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1683 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1685 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1687 int direction
, ascent
, descent
;
1688 XCharStruct overall
;
1690 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1692 return (wxCoord
)(overall
.width
/ m_scaleX
);
1696 wxCoord
wxWindowDC::GetCharHeight() const
1698 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1701 PangoLayout
*layout
= pango_layout_new( m_context
);
1709 pango_layout_set_font_description(layout
, m_fontdesc
);
1711 pango_layout_set_text(layout
, "H", 1 );
1713 pango_layout_get_pixel_size(layout
, &w
, &h
);
1714 g_object_unref( G_OBJECT( layout
) );
1718 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1720 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1722 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1724 int direction
, ascent
, descent
;
1725 XCharStruct overall
;
1727 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1729 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1733 void wxWindowDC::Clear()
1735 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1737 if (!m_window
) return;
1739 /* - we either are a memory dc or have a window as the
1740 owner. anything else shouldn't happen.
1741 - we don't use gdk_window_clear() as we don't set
1742 the window's background colour anymore. it is too
1743 much pain to keep the DC's and the window's back-
1744 ground colour in synch. */
1749 m_owner
->GetSize( &width
, &height
);
1750 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1757 GetSize( &width
, &height
);
1758 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1763 void wxWindowDC::SetFont( const wxFont
&font
)
1765 wxCHECK_RET( Ok(), wxT("invalid dc") );
1770 void wxWindowDC::SetPen( const wxPen
&pen
)
1772 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1774 if (m_pen
== pen
) return;
1778 if (!m_pen
.Ok()) return;
1780 if (!m_window
) return;
1782 int width
= m_pen
.GetWidth();
1785 // CMB: if width is non-zero scale it with the dc
1790 // X doesn't allow different width in x and y and so we take
1793 ( fabs((double) XLOG2DEVREL(width
)) +
1794 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1798 static const wxX11Dash dotted
[] = {1, 1};
1799 static const wxX11Dash short_dashed
[] = {2, 2};
1800 static const wxX11Dash long_dashed
[] = {2, 4};
1801 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1803 // We express dash pattern in pen width unit, so we are
1804 // independent of zoom factor and so on...
1806 const wxX11Dash
*req_dash
;
1808 int lineStyle
= LineSolid
;
1809 switch (m_pen
.GetStyle())
1813 lineStyle
= LineOnOffDash
;
1814 req_nb_dash
= m_pen
.GetDashCount();
1815 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1820 lineStyle
= LineOnOffDash
;
1827 lineStyle
= LineOnOffDash
;
1829 req_dash
= long_dashed
;
1834 lineStyle
= LineOnOffDash
;
1836 req_dash
= short_dashed
;
1841 // lineStyle = LineDoubleDash;
1842 lineStyle
= LineOnOffDash
;
1844 req_dash
= dotted_dashed
;
1849 case wxSTIPPLE_MASK_OPAQUE
:
1854 lineStyle
= LineSolid
;
1855 req_dash
= (wxX11Dash
*)NULL
;
1861 int capStyle
= CapRound
;
1862 switch (m_pen
.GetCap())
1864 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1865 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1872 capStyle
= CapNotLast
;
1876 capStyle
= CapRound
;
1882 int joinStyle
= JoinRound
;
1883 switch (m_pen
.GetJoin())
1885 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1886 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1888 default: { joinStyle
= JoinRound
; break; }
1891 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1893 m_pen
.GetColour().CalcPixel( m_cmap
);
1894 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1897 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1899 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1901 if (m_brush
== brush
) return;
1905 if (!m_brush
.Ok()) return;
1907 if (!m_window
) return;
1909 m_brush
.GetColour().CalcPixel( m_cmap
);
1910 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1912 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1914 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1916 if (m_brush
.GetStipple()->GetPixmap())
1918 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1919 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1923 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1924 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1928 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1930 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1931 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1934 if (IS_HATCH(m_brush
.GetStyle()))
1936 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1937 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1938 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1942 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1944 /* CMB 21/7/98: Added SetBackground. Sets background brush
1945 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1947 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1949 if (m_backgroundBrush
== brush
) return;
1951 m_backgroundBrush
= brush
;
1953 if (!m_backgroundBrush
.Ok()) return;
1955 if (!m_window
) return;
1957 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1958 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1959 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1960 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1961 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1963 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1965 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1967 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1969 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1970 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1974 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1975 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
1979 if (IS_HATCH(m_backgroundBrush
.GetStyle()))
1981 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1982 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
1983 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
1987 void wxWindowDC::SetLogicalFunction( int function
)
1989 wxCHECK_RET( Ok(), wxT("invalid dc") );
1993 if (m_logicalFunction
== function
)
1996 // VZ: shouldn't this be a CHECK?
2003 x_function
= GXclear
;
2009 x_function
= GXinvert
;
2012 x_function
= GXorReverse
;
2015 x_function
= GXandReverse
;
2024 x_function
= GXandInverted
;
2027 x_function
= GXnoop
;
2033 x_function
= GXequiv
;
2036 x_function
= GXcopyInverted
;
2039 x_function
= GXorInverted
;
2042 x_function
= GXnand
;
2049 x_function
= GXcopy
;
2053 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2054 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2056 // to stay compatible with wxMSW, we don't apply ROPs to the text
2057 // operations (i.e. DrawText/DrawRotatedText).
2058 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2059 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2061 m_logicalFunction
= function
;
2064 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2066 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2068 // don't set m_textForegroundColour to an invalid colour as we'd crash
2069 // later then (we use m_textForegroundColour.GetColor() without checking
2071 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
2074 m_textForegroundColour
= col
;
2078 m_textForegroundColour
.CalcPixel( m_cmap
);
2079 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2083 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2085 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2088 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
2091 m_textBackgroundColour
= col
;
2095 m_textBackgroundColour
.CalcPixel( m_cmap
);
2096 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2100 void wxWindowDC::SetBackgroundMode( int mode
)
2102 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2104 m_backgroundMode
= mode
;
2107 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2110 if (!m_window
) return;
2112 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2113 // transparent/solid background mode
2115 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2117 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2118 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2122 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2128 /* Use GetXColormap */
2129 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2130 (Colormap
) palette
.GetXColormap());
2132 /* Use wxGetMainColormap */
2133 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2134 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2139 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2141 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2143 if (!m_window
) return;
2146 rect
.x
= XLOG2DEV(x
);
2147 rect
.y
= YLOG2DEV(y
);
2148 rect
.width
= XLOG2DEVREL(width
);
2149 rect
.height
= YLOG2DEVREL(height
);
2151 if (!m_currentClippingRegion
.IsNull())
2152 m_currentClippingRegion
.Intersect( rect
);
2154 m_currentClippingRegion
.Union( rect
);
2156 #if USE_PAINT_REGION
2157 if (!m_paintClippingRegion
.IsNull())
2158 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2161 wxCoord xx
, yy
, ww
, hh
;
2162 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2163 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2165 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2166 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2167 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2168 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2171 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2173 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2177 DestroyClippingRegion();
2181 if (!m_window
) return;
2183 if (!m_currentClippingRegion
.IsNull())
2184 m_currentClippingRegion
.Intersect( region
);
2186 m_currentClippingRegion
.Union( region
);
2188 #if USE_PAINT_REGION
2189 if (!m_paintClippingRegion
.IsNull())
2190 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2193 wxCoord xx
, yy
, ww
, hh
;
2194 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2195 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2197 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2198 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2199 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2200 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2203 void wxWindowDC::DestroyClippingRegion()
2205 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2207 wxDC::DestroyClippingRegion();
2209 m_currentClippingRegion
.Clear();
2211 #if USE_PAINT_REGION
2212 if (!m_paintClippingRegion
.IsEmpty())
2213 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2216 if (!m_window
) return;
2218 if (m_currentClippingRegion
.IsEmpty())
2220 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2221 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2222 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2223 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2227 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2228 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2229 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2230 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2234 void wxWindowDC::Destroy()
2236 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2238 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2240 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2242 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2246 void wxWindowDC::ComputeScaleAndOrigin()
2248 /* CMB: copy scale to see if it changes */
2249 double origScaleX
= m_scaleX
;
2250 double origScaleY
= m_scaleY
;
2252 wxDC::ComputeScaleAndOrigin();
2254 /* CMB: if scale has changed call SetPen to recalulate the line width */
2255 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2258 /* this is a bit artificial, but we need to force wxDC to think
2259 the pen has changed */
2266 wxSize
wxWindowDC::GetPPI() const
2268 return wxSize(100, 100);
2271 int wxWindowDC::GetDepth() const
2273 wxFAIL_MSG(wxT("not implemented"));
2278 //-----------------------------------------------------------------------------
2280 //-----------------------------------------------------------------------------
2282 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2284 wxClientDC::wxClientDC( wxWindow
*window
)
2285 : wxWindowDC( window
)
2287 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2289 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2291 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2292 if (m_window
== (WXWindow
*) window
->GetMainWindow())
2294 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2295 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2296 wxSize size
= window
->GetClientSize();
2297 SetClippingRegion(wxPoint(0, 0), size
);
2301 void wxClientDC::DoGetSize(int *width
, int *height
) const
2303 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2305 m_owner
->GetClientSize( width
, height
);
2308 // ----------------------------------------------------------------------------
2310 // ----------------------------------------------------------------------------
2312 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2314 wxPaintDC::wxPaintDC(wxWindow
* window
)
2315 : wxClientDC(window
)
2317 #if USE_PAINT_REGION
2318 if (!window
->GetClipPaintRegion())
2321 m_paintClippingRegion
= window
->GetUpdateRegion();
2322 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2325 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2327 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2328 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2329 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2330 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2332 #endif // USE_PAINT_REGION
2335 // ----------------------------------------------------------------------------
2337 // ----------------------------------------------------------------------------
2339 class wxDCModule
: public wxModule
2346 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2349 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)
2351 bool wxDCModule::OnInit()
2357 void wxDCModule::OnExit()