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 #include "wx/dcclient.h"
13 #include "wx/dcmemory.h"
14 #include "wx/window.h"
17 #include "wx/module.h"
18 #include "wx/fontutil.h"
20 #include "wx/x11/private.h"
26 #include "pango/pangox.h"
28 #include "pango/pangoxft.h"
31 #include "pango_x.cpp"
34 //-----------------------------------------------------------------------------
36 //-----------------------------------------------------------------------------
38 #define USE_PAINT_REGION 1
40 //-----------------------------------------------------------------------------
42 //-----------------------------------------------------------------------------
52 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH)
53 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH)
55 static Pixmap hatches
[num_hatches
];
56 static Pixmap
*hatch_bitmap
= (Pixmap
*) NULL
;
58 //-----------------------------------------------------------------------------
60 //-----------------------------------------------------------------------------
62 const double RAD2DEG
= 180.0 / M_PI
;
64 // ----------------------------------------------------------------------------
66 // ----------------------------------------------------------------------------
68 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
69 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
71 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
73 //-----------------------------------------------------------------------------
74 // Implement Pool of Graphic contexts. Creating them takes too much time.
75 //-----------------------------------------------------------------------------
77 #define GC_POOL_SIZE 200
103 static wxGC wxGCPool
[GC_POOL_SIZE
];
105 static void wxInitGCPool()
107 memset( wxGCPool
, 0, GC_POOL_SIZE
*sizeof(wxGC
) );
110 static void wxCleanUpGCPool()
112 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
114 if (wxGCPool
[i
].m_gc
)
115 XFreeGC( wxGlobalDisplay(), wxGCPool
[i
].m_gc
);
119 static GC
wxGetPoolGC( Window window
, wxPoolGCType type
)
121 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
123 if (!wxGCPool
[i
].m_gc
)
125 wxGCPool
[i
].m_gc
= XCreateGC( wxGlobalDisplay(), window
, 0, NULL
);
126 XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool
[i
].m_gc
, FALSE
);
127 wxGCPool
[i
].m_type
= type
;
128 wxGCPool
[i
].m_used
= false;
130 if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type
== type
))
132 wxGCPool
[i
].m_used
= true;
133 return wxGCPool
[i
].m_gc
;
137 wxFAIL_MSG( wxT("No GC available") );
142 static void wxFreePoolGC( GC gc
)
144 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
146 if (wxGCPool
[i
].m_gc
== gc
)
148 wxGCPool
[i
].m_used
= false;
153 wxFAIL_MSG( wxT("Wrong GC") );
156 // ----------------------------------------------------------------------------
158 // ----------------------------------------------------------------------------
160 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
162 wxWindowDC::wxWindowDC()
164 m_display
= (WXDisplay
*) NULL
;
165 m_penGC
= (WXGC
*) NULL
;
166 m_brushGC
= (WXGC
*) NULL
;
167 m_textGC
= (WXGC
*) NULL
;
168 m_bgGC
= (WXGC
*) NULL
;
169 m_cmap
= (WXColormap
*) NULL
;
171 m_isScreenDC
= false;
172 m_owner
= (wxWindow
*)NULL
;
175 m_context
= (PangoContext
*)NULL
;
176 m_fontdesc
= (PangoFontDescription
*)NULL
;
180 wxWindowDC::wxWindowDC( wxWindow
*window
)
182 wxASSERT_MSG( window
, wxT("DC needs a window") );
184 m_display
= (WXDisplay
*) NULL
;
185 m_penGC
= (WXGC
*) NULL
;
186 m_brushGC
= (WXGC
*) NULL
;
187 m_textGC
= (WXGC
*) NULL
;
188 m_bgGC
= (WXGC
*) NULL
;
189 m_cmap
= (WXColormap
*) NULL
;
190 m_owner
= (wxWindow
*)NULL
;
192 m_isScreenDC
= false;
193 m_font
= window
->GetFont();
195 m_window
= (WXWindow
*) window
->GetMainWindow();
200 // don't report problems
206 m_display
= (WXDisplay
*) wxGlobalDisplay();
209 m_context
= wxTheApp
->GetPangoContext();
210 m_fontdesc
= window
->GetFont().GetNativeFontInfo()->description
;
213 int screen
= DefaultScreen( (Display
*) m_display
);
214 m_cmap
= (WXColormap
) DefaultColormap( (Display
*) m_display
, screen
);
218 /* this must be done after SetUpDC, bacause SetUpDC calls the
219 repective SetBrush, SetPen, SetBackground etc functions
220 to set up the DC. SetBackground call m_owner->SetBackground
221 and this might not be desired as the standard dc background
222 is white whereas a window might assume gray to be the
223 standard (as e.g. wxStatusBar) */
228 wxWindowDC::~wxWindowDC()
233 void wxWindowDC::SetUpDC()
237 wxASSERT_MSG( !m_penGC
, wxT("GCs already created") );
241 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_SCREEN
);
242 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_SCREEN
);
243 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_SCREEN
);
244 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_SCREEN
);
247 if (m_isMemDC
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1))
249 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_MONO
);
250 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_MONO
);
251 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_MONO
);
252 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_MONO
);
256 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_COLOUR
);
257 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_COLOUR
);
258 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_COLOUR
);
259 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_COLOUR
);
262 /* background colour */
263 m_backgroundBrush
= *wxWHITE_BRUSH
;
264 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
265 unsigned long bg_col
= m_backgroundBrush
.GetColour().GetPixel();
267 m_textForegroundColour
= *wxBLACK
;
268 m_textBackgroundColour
= *wxWHITE
;
271 m_textForegroundColour
.CalcPixel( m_cmap
);
272 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
274 m_textBackgroundColour
.CalcPixel( m_cmap
);
275 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
277 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
280 // By default, draw transparently
281 GrSetGCUseBackground((GC
) m_textGC
, FALSE
);
285 m_pen
.GetColour().CalcPixel( m_cmap
);
286 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
287 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
289 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
292 m_brush
.GetColour().CalcPixel( m_cmap
);
293 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
294 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
296 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
299 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
300 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
302 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
305 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
306 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
307 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
310 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
311 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
312 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
313 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
317 int xscreen
= DefaultScreen( (Display
*) m_display
);
318 Window xroot
= RootWindow( (Display
*) m_display
, xscreen
);
320 hatch_bitmap
= hatches
;
321 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, bdiag_bits
, bdiag_width
, bdiag_height
);
322 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cdiag_bits
, cdiag_width
, cdiag_height
);
323 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, fdiag_bits
, fdiag_width
, fdiag_height
);
324 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, cross_bits
, cross_width
, cross_height
);
325 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, horiz_bits
, horiz_width
, horiz_height
);
326 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, xroot
, verti_bits
, verti_width
, verti_height
);
330 void wxWindowDC::DoGetSize( int* width
, int* height
) const
332 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
334 m_owner
->GetSize(width
, height
);
337 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
338 const wxColour
& col
, int style
);
340 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
341 const wxColour
& col
, int style
)
343 return wxDoFloodFill(this, x
, y
, col
, style
);
346 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
348 // Generic (and therefore rather inefficient) method.
349 // Could be improved.
351 wxBitmap
bitmap(1, 1);
352 memdc
.SelectObject(bitmap
);
353 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
354 memdc
.SelectObject(wxNullBitmap
);
355 wxImage
image(bitmap
.ConvertToImage());
356 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
360 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
362 wxCHECK_RET( Ok(), wxT("invalid window dc") );
364 if (m_pen
.GetStyle() != wxTRANSPARENT
)
368 // This hack is for the iPaq: XDrawLine draws
369 // nothing, whereas XDrawLines works...
375 DrawLines( 2, points
, 0, 0 );
377 // XDrawLine( (Display*) m_display, (Window) m_window,
378 // (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
381 CalcBoundingBox(x1
, y1
);
382 CalcBoundingBox(x2
, y2
);
386 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
388 wxCHECK_RET( Ok(), wxT("invalid window dc") );
390 if (m_pen
.GetStyle() != wxTRANSPARENT
)
395 wxCoord xx
= XLOG2DEV(x
);
396 wxCoord yy
= YLOG2DEV(y
);
399 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
400 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
401 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
402 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
407 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
409 wxCHECK_RET( Ok(), wxT("invalid window dc") );
411 wxCoord xx1
= XLOG2DEV(x1
);
412 wxCoord yy1
= YLOG2DEV(y1
);
413 wxCoord xx2
= XLOG2DEV(x2
);
414 wxCoord yy2
= YLOG2DEV(y2
);
415 wxCoord xxc
= XLOG2DEV(xc
);
416 wxCoord yyc
= YLOG2DEV(yc
);
417 double dx
= xx1
- xxc
;
418 double dy
= yy1
- yyc
;
419 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
420 wxCoord r
= (wxCoord
)radius
;
421 double radius1
, radius2
;
423 if (xx1
== xx2
&& yy1
== yy2
)
431 radius1
= radius2
= 0.0;
435 radius1
= (xx1
- xxc
== 0) ?
436 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
437 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
438 radius2
= (xx2
- xxc
== 0) ?
439 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
440 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
442 wxCoord alpha1
= wxCoord(radius1
* 64.0);
443 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
444 while (alpha2
<= 0) alpha2
+= 360*64;
445 while (alpha1
> 360*64) alpha1
-= 360*64;
449 if (m_brush
.GetStyle() != wxTRANSPARENT
)
451 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
453 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
454 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
455 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
457 XFillArc( (Display
*) m_display
, (Window
) m_window
,
458 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
460 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
462 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
464 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
465 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
467 XFillArc( (Display
*) m_display
, (Window
) m_window
,
468 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
470 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
472 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
474 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
475 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
477 XFillArc( (Display
*) m_display
, (Window
) m_window
,
478 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
480 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
482 if (m_brush
.GetStyle() == wxSTIPPLE
)
484 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
485 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
486 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
488 XFillArc( (Display
*) m_display
, (Window
) m_window
,
489 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
491 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
495 XFillArc( (Display
*) m_display
, (Window
) m_window
,
496 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
500 if (m_pen
.GetStyle() != wxTRANSPARENT
)
502 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
503 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
505 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
506 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
508 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
509 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
513 CalcBoundingBox (x1
, y1
);
514 CalcBoundingBox (x2
, y2
);
517 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
519 wxCHECK_RET( Ok(), wxT("invalid window dc") );
521 wxCoord xx
= XLOG2DEV(x
);
522 wxCoord yy
= YLOG2DEV(y
);
523 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
524 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
526 // CMB: handle -ve width and/or height
527 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
528 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
532 wxCoord start
= wxCoord(sa
* 64.0);
533 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
535 if (m_brush
.GetStyle() != wxTRANSPARENT
)
537 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
539 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
540 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
541 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
543 XFillArc( (Display
*) m_display
, (Window
) m_window
,
544 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
546 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
548 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
550 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
551 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
553 XFillArc( (Display
*) m_display
, (Window
) m_window
,
554 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
556 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
558 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
560 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
561 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
563 XFillArc( (Display
*) m_display
, (Window
) m_window
,
564 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
566 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
568 if (m_brush
.GetStyle() == wxSTIPPLE
)
570 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
571 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
572 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
574 XFillArc( (Display
*) m_display
, (Window
) m_window
,
575 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
577 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
581 XFillArc( (Display
*) m_display
, (Window
) m_window
,
582 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
586 if (m_pen
.GetStyle() != wxTRANSPARENT
)
588 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
589 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
593 CalcBoundingBox (x
, y
);
594 CalcBoundingBox (x
+ width
, y
+ height
);
597 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
599 wxCHECK_RET( Ok(), wxT("invalid window dc") );
601 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
)
602 XDrawPoint( (Display
*) m_display
, (Window
) m_window
,
603 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
605 CalcBoundingBox (x
, y
);
608 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
610 wxCHECK_RET( Ok(), wxT("invalid window dc") );
612 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
615 XPoint
*xpoints
= new XPoint
[n
];
616 for (int i
= 0; i
< n
; i
++)
618 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
619 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
621 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
623 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
, 0 );
628 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
629 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
631 wxCHECK_RET( Ok(), wxT("invalid window dc") );
635 XPoint
*xpoints
= new XPoint
[n
+ 1];
637 for (i
= 0; i
< n
; i
++)
639 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
640 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
642 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
647 if (m_brush
.GetStyle() != wxTRANSPARENT
)
650 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
652 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
653 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
654 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
656 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
657 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
659 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
661 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
663 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
664 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
666 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
667 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
669 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
671 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
673 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
674 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
676 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
677 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
679 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
681 if (m_brush
.GetStyle() == wxSTIPPLE
)
683 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
684 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
685 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
687 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
688 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
690 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
694 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
695 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
699 if (m_pen
.GetStyle () != wxTRANSPARENT
)
701 // Close figure for XDrawLines
702 xpoints
[i
].x
= xpoints
[0].x
;
703 xpoints
[i
].y
= xpoints
[0].y
;
705 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
712 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
714 wxCHECK_RET( Ok(), wxT("invalid window dc") );
716 wxCoord xx
= XLOG2DEV(x
);
717 wxCoord yy
= YLOG2DEV(y
);
718 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
719 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
721 // CMB: draw nothing if transformed w or h is 0
722 if (ww
== 0 || hh
== 0) return;
724 // CMB: handle -ve width and/or height
725 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
726 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
730 if (m_brush
.GetStyle() != wxTRANSPARENT
)
732 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
734 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
735 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
736 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
738 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
739 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
741 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
743 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
745 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
746 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
748 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
749 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
751 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
753 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
755 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
756 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
758 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
759 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
761 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
763 if (m_brush
.GetStyle() == wxSTIPPLE
)
765 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
766 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
767 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
769 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
770 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
772 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
776 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
777 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
781 if (m_pen
.GetStyle () != wxTRANSPARENT
)
783 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
784 (GC
) m_penGC
, xx
, yy
, ww
-1, hh
-1 );
788 CalcBoundingBox( x
, y
);
789 CalcBoundingBox( x
+ width
, y
+ height
);
792 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
794 wxCHECK_RET( Ok(), wxT("invalid window dc") );
796 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
798 wxCoord xx
= XLOG2DEV(x
);
799 wxCoord yy
= YLOG2DEV(y
);
800 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
801 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
802 wxCoord rr
= XLOG2DEVREL((wxCoord
)radius
);
804 // CMB: handle -ve width and/or height
805 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
806 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
808 // CMB: if radius is zero use DrawRectangle() instead to avoid
809 // X drawing errors with small radii
812 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
813 (GC
) m_penGC
, x
, y
, width
, height
);
817 // CMB: draw nothing if transformed w or h is 0
818 if (ww
== 0 || hh
== 0) return;
820 // CMB: adjust size if outline is drawn otherwise the result is
821 // 1 pixel too wide and high
822 if (m_pen
.GetStyle() != wxTRANSPARENT
)
830 // CMB: ensure dd is not larger than rectangle otherwise we
831 // get an hour glass shape
833 if (dd
> ww
) dd
= ww
;
834 if (dd
> hh
) dd
= hh
;
837 if (m_brush
.GetStyle() != wxTRANSPARENT
)
839 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
841 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
842 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
843 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
844 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
845 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
846 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
847 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
848 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
849 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_textGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
850 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0);
852 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
854 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
855 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
856 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
857 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
858 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
859 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
860 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
861 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
863 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
865 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
866 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
867 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
868 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
869 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
870 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
871 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
872 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
874 if (m_brush
.GetStyle() == wxSTIPPLE
)
876 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
877 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
878 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
879 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
880 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
881 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
882 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
883 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
884 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
885 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0);
889 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+rr
, yy
, ww
-dd
+1, hh
);
890 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
891 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
892 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
893 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
894 XFillArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_brushGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
897 if (m_pen
.GetStyle() != wxTRANSPARENT
)
899 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
, xx
+ww
-rr
, yy
);
900 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+rr
+1, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
901 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+rr
+1, xx
, yy
+hh
-rr
);
902 XDrawLine( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
, yy
+rr
+1, xx
+ww
, yy
+hh
-rr
);
903 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
904 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
905 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
906 XDrawArc( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
910 // this ignores the radius
911 CalcBoundingBox( x
, y
);
912 CalcBoundingBox( x
+ width
, y
+ height
);
915 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
917 wxCHECK_RET( Ok(), wxT("invalid window dc") );
919 wxCoord xx
= XLOG2DEV(x
);
920 wxCoord yy
= YLOG2DEV(y
);
921 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
922 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
924 // CMB: handle -ve width and/or height
925 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
926 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
930 if (m_brush
.GetStyle() != wxTRANSPARENT
)
932 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
934 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
935 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
936 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
938 XFillArc( (Display
*) m_display
, (Window
) m_window
,
939 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
941 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
943 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
945 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
946 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
948 XFillArc( (Display
*) m_display
, (Window
) m_window
,
949 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
951 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
953 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
955 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
956 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
958 XFillArc( (Display
*) m_display
, (Window
) m_window
,
959 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
961 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
963 if (m_brush
.GetStyle() == wxSTIPPLE
)
965 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
966 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
967 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
969 XFillArc( (Display
*) m_display
, (Window
) m_window
,
970 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
972 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
976 XFillArc( (Display
*) m_display
, (Window
) m_window
,
977 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
981 if (m_pen
.GetStyle () != wxTRANSPARENT
)
983 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
984 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
988 CalcBoundingBox( x
, y
);
989 CalcBoundingBox( x
+ width
, y
+ height
);
992 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
994 DoDrawBitmap(icon
, x
, y
, true);
998 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
999 wxCoord x
, wxCoord y
,
1002 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1004 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1006 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1008 /* scale/translate size and position */
1009 int xx
= XLOG2DEV(x
);
1010 int yy
= YLOG2DEV(y
);
1012 int w
= bitmap
.GetWidth();
1013 int h
= bitmap
.GetHeight();
1015 CalcBoundingBox( x
, y
);
1016 CalcBoundingBox( x
+ w
, y
+ h
);
1018 if (!m_window
) return;
1020 int ww
= XLOG2DEVREL(w
);
1021 int hh
= YLOG2DEVREL(h
);
1023 /* compare to current clipping region */
1024 if (!m_currentClippingRegion
.IsNull())
1026 wxRegion
tmp( xx
,yy
,ww
,hh
);
1027 tmp
.Intersect( m_currentClippingRegion
);
1032 /* scale bitmap if required */
1033 wxBitmap use_bitmap
;
1034 if ((w
!= ww
) || (h
!= hh
))
1036 wxImage
image( bitmap
.ConvertToImage() );
1037 image
.Rescale( ww
, hh
);
1040 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1047 use_bitmap
= bitmap
;
1050 /* apply mask if any */
1051 WXPixmap mask
= NULL
;
1052 if (use_bitmap
.GetMask())
1053 mask
= use_bitmap
.GetMask()->GetBitmap();
1055 if (useMask
&& mask
)
1057 Pixmap pixmap
= (Pixmap
) use_bitmap
.GetPixmap() ;
1058 Pixmap maskPixmap
= (Pixmap
) use_bitmap
.GetMask()->GetBitmap() ;
1059 Pixmap bufPixmap
= GrNewPixmap(w
, h
, 0);
1061 GrSetGCUseBackground(gc
, FALSE
);
1062 GrSetGCMode(gc
, GR_MODE_COPY
);
1064 // This code assumes that background and foreground
1065 // colours are used in ROPs, like in MSW.
1066 // Not sure if this is true.
1068 // Copy destination to buffer.
1069 // In DoBlit, we need this step because Blit has
1070 // a ROP argument. Here, we don't need it.
1071 // In DoBlit, we may be able to eliminate this step
1072 // if we check if the rop = copy
1074 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, (Window
) m_window
,
1075 0, 0, GR_MODE_COPY
);
1078 // Copy src to buffer using selected raster op (none selected
1079 // in DrawBitmap, so just use Gxcopy)
1080 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, pixmap
,
1081 0, 0, GR_MODE_COPY
);
1083 // Set masked area in buffer to BLACK (pixel value 0)
1084 GrSetGCBackground(gc
, WHITE
);
1085 GrSetGCForeground(gc
, BLACK
);
1086 GrCopyArea(bufPixmap
, gc
, 0, 0, w
, h
, maskPixmap
,
1089 // set unmasked area in dest to BLACK
1090 GrSetGCBackground(gc
, BLACK
);
1091 GrSetGCForeground(gc
, WHITE
);
1092 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, maskPixmap
,
1095 // OR buffer to dest
1096 GrCopyArea((Window
) m_window
, gc
, xx
, yy
, w
, h
, bufPixmap
,
1100 GrDestroyWindow(bufPixmap
);
1103 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1104 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1106 /* remove mask again if any */
1107 if (useMask
&& mask
)
1109 if (!m_currentClippingRegion
.IsNull())
1110 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1117 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
1118 wxCoord x
, wxCoord y
,
1121 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1123 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
1125 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
1127 // scale/translate size and position
1128 int xx
= XLOG2DEV(x
);
1129 int yy
= YLOG2DEV(y
);
1131 int w
= bitmap
.GetWidth();
1132 int h
= bitmap
.GetHeight();
1134 CalcBoundingBox( x
, y
);
1135 CalcBoundingBox( x
+ w
, y
+ h
);
1137 if (!m_window
) return;
1139 int ww
= XLOG2DEVREL(w
);
1140 int hh
= YLOG2DEVREL(h
);
1142 // compare to current clipping region
1143 if (!m_currentClippingRegion
.IsNull())
1145 wxRegion
tmp( xx
,yy
,ww
,hh
);
1146 tmp
.Intersect( m_currentClippingRegion
);
1151 // scale bitmap if required
1152 wxBitmap use_bitmap
;
1153 if ((w
!= ww
) || (h
!= hh
))
1155 wxImage
image( bitmap
.ConvertToImage() );
1156 image
.Rescale( ww
, hh
);
1159 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1166 use_bitmap
= bitmap
;
1169 // apply mask if any
1170 WXPixmap mask
= NULL
;
1171 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1173 if (useMask
&& mask
)
1175 WXPixmap new_mask
= NULL
;
1177 if (!m_currentClippingRegion
.IsNull())
1180 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 );
1181 GdkGC
*gc
= gdk_gc_new( new_mask
);
1183 gdk_gc_set_foreground( gc
, &col
);
1184 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1186 gdk_gc_set_background( gc
, &col
);
1188 gdk_gc_set_foreground( gc
, &col
);
1189 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1190 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1191 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1192 gdk_gc_set_stipple( gc
, mask
);
1193 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
1200 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1202 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1203 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1208 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1210 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1211 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1215 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1218 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1219 // drawing a mono-bitmap (XBitmap) we use the current text GC
1221 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1222 (GC
) m_textGC
, 0, 0, w
, h
, xx
, yy
, 1 );
1224 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1225 (GC
) m_penGC
, 0, 0, w
, h
, xx
, yy
);
1227 // remove mask again if any
1228 if (useMask
&& mask
)
1232 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1233 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1234 if (!m_currentClippingRegion
.IsNull())
1235 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1239 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1240 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1241 if (!m_currentClippingRegion
.IsNull())
1242 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1247 // wxUSE_NANOX/!wxUSE_NANOX
1249 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1250 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1251 wxCoord xsrcMask
, wxCoord ysrcMask
)
1253 /* this is the nth try to get this utterly useless function to
1254 work. it now completely ignores the scaling or translation
1255 of the source dc, but scales correctly on the target dc and
1256 knows about possible mask information in a memory dc. */
1258 wxCHECK_MSG( Ok(), false, wxT("invalid window dc") );
1260 wxCHECK_MSG( source
, false, wxT("invalid source dc") );
1262 if (!m_window
) return false;
1264 // transform the source DC coords to the device ones
1265 xsrc
= source
->XLOG2DEV(xsrc
);
1266 ysrc
= source
->YLOG2DEV(ysrc
);
1268 wxClientDC
*srcDC
= (wxClientDC
*)source
;
1269 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1271 bool use_bitmap_method
= false;
1272 bool is_mono
= false;
1274 // TODO: use the mask origin when drawing transparently
1275 if (xsrcMask
== -1 && ysrcMask
== -1)
1281 if (srcDC
->m_isMemDC
)
1283 if (!memDC
->m_selected
.Ok()) return false;
1285 /* we use the "XCopyArea" way to copy a memory dc into
1286 y different window if the memory dc BOTH
1287 a) doesn't have any mask or its mask isn't used
1291 if (useMask
&& (memDC
->m_selected
.GetMask()))
1293 /* we HAVE TO use the direct way for memory dcs
1294 that have mask since the XCopyArea doesn't know
1296 use_bitmap_method
= true;
1298 else if (memDC
->m_selected
.GetDepth() == 1)
1300 /* we HAVE TO use the direct way for memory dcs
1301 that are bitmaps because XCopyArea doesn't cope
1302 with different bit depths */
1304 use_bitmap_method
= true;
1306 else if ((xsrc
== 0) && (ysrc
== 0) &&
1307 (width
== memDC
->m_selected
.GetWidth()) &&
1308 (height
== memDC
->m_selected
.GetHeight()))
1310 /* we SHOULD use the direct way if all of the bitmap
1311 in the memory dc is copied in which case XCopyArea
1312 wouldn't be able able to boost performace by reducing
1313 the area to be scaled */
1314 use_bitmap_method
= true;
1318 use_bitmap_method
= false;
1322 CalcBoundingBox( xdest
, ydest
);
1323 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1325 // scale/translate size and position
1326 wxCoord xx
= XLOG2DEV(xdest
);
1327 wxCoord yy
= YLOG2DEV(ydest
);
1329 wxCoord ww
= XLOG2DEVREL(width
);
1330 wxCoord hh
= YLOG2DEVREL(height
);
1332 // compare to current clipping region
1333 if (!m_currentClippingRegion
.IsNull())
1335 wxRegion
tmp( xx
,yy
,ww
,hh
);
1336 tmp
.Intersect( m_currentClippingRegion
);
1341 int old_logical_func
= m_logicalFunction
;
1342 SetLogicalFunction( logical_func
);
1344 if (use_bitmap_method
)
1346 // scale/translate bitmap size
1347 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1348 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1350 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1351 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1353 // scale bitmap if required
1354 wxBitmap use_bitmap
;
1356 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1358 wxImage
image( memDC
->m_selected
.ConvertToImage() );
1359 image
= image
.Scale( bm_ww
, bm_hh
);
1363 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1370 use_bitmap
= memDC
->m_selected
;
1373 // apply mask if any
1374 WXPixmap mask
= NULL
;
1375 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1377 if (useMask
&& mask
)
1379 WXPixmap new_mask
= NULL
;
1381 if (!m_currentClippingRegion
.IsNull())
1384 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1385 GdkGC
*gc
= gdk_gc_new( new_mask
);
1387 gdk_gc_set_foreground( gc
, &col
);
1388 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1390 gdk_gc_set_background( gc
, &col
);
1392 gdk_gc_set_foreground( gc
, &col
);
1393 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1394 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1395 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1396 gdk_gc_set_stipple( gc
, mask
);
1397 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1404 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) new_mask
);
1406 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) mask
);
1407 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, xx
, yy
);
1412 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) new_mask
);
1414 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, (Pixmap
) mask
);
1415 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, xx
, yy
);
1419 XFreePixmap( (Display
*) m_display
, (Pixmap
) new_mask
);
1422 // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1423 // drawing a mono-bitmap (XBitmap) we use the current text GC
1426 XCopyPlane( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetBitmap(), (Window
) m_window
,
1427 (GC
) m_textGC
, xsrc
, ysrc
, width
, height
, xx
, yy
, 1 );
1429 XCopyArea( (Display
*) m_display
, (Pixmap
) use_bitmap
.GetPixmap(), (Window
) m_window
,
1430 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1432 // remove mask again if any
1433 if (useMask
&& mask
)
1437 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1438 XSetClipOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
1439 if (!m_currentClippingRegion
.IsNull())
1440 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1444 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1445 XSetClipOrigin( (Display
*) m_display
, (GC
) m_penGC
, 0, 0 );
1446 if (!m_currentClippingRegion
.IsNull())
1447 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1451 else // use_bitmap_method
1453 if ((width
!= ww
) || (height
!= hh
))
1455 /* Draw source window into a bitmap as we cannot scale
1456 a window in contrast to a bitmap. this would actually
1457 work with memory dcs as well, but we'd lose the mask
1458 information and waste one step in this process since
1459 a memory already has a bitmap. all this is slightly
1460 inefficient as we could take an XImage directly from
1461 an X window, but we'd then also have to care that
1462 the window is not outside the screen (in which case
1463 we'd get a BadMatch or what not).
1464 Is a double XGetImage and combined XGetPixel and
1465 XPutPixel really faster? I'm not sure. look at wxXt
1466 for a different implementation of the same problem. */
1468 wxBitmap
bitmap( width
, height
);
1470 // copy including child window contents
1471 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1472 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) bitmap
.GetPixmap(),
1473 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, 0, 0 );
1474 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1477 wxImage
image( bitmap
.ConvertToImage() );
1478 image
= image
.Scale( ww
, hh
);
1480 // convert to bitmap
1483 // draw scaled bitmap
1484 XCopyArea( (Display
*) m_display
, (Window
) bitmap
.GetPixmap(), (Window
) m_window
,
1485 (GC
) m_penGC
, 0, 0, width
, height
, xx
, yy
);
1489 // No scaling and not a memory dc with a mask either
1491 // copy including child window contents
1492 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, IncludeInferiors
);
1493 XCopyArea( (Display
*) m_display
, (Window
) srcDC
->GetWindow(), (Window
) m_window
,
1494 (GC
) m_penGC
, xsrc
, ysrc
, width
, height
, xx
, yy
);
1495 XSetSubwindowMode( (Display
*) m_display
, (GC
) m_penGC
, ClipByChildren
);
1499 SetLogicalFunction( old_logical_func
);
1504 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1506 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1508 if (!m_window
) return;
1514 PangoLayout
*layout
= pango_layout_new(m_context
);
1515 pango_layout_set_font_description(layout
, m_fontdesc
);
1517 const wxCharBuffer data
= wxConvUTF8
.cWC2MB( text
);
1518 pango_layout_set_text(layout
, (const char*) data
, strlen( (const char*) data
));
1522 pango_layout_get_pixel_size(layout
, &w
, &h
);
1527 x11_draw_layout( (Drawable
) m_window
, (GC
) m_textGC
, x
, y
, layout
, m_textForegroundColour
);
1529 g_object_unref( G_OBJECT( layout
) );
1531 CalcBoundingBox (x
+ width
, y
+ height
);
1532 CalcBoundingBox (x
, y
);
1534 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1536 wxCHECK_RET( xfont
, wxT("invalid font") );
1538 // First draw a rectangle representing the text background, if a text
1539 // background is specified
1540 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1542 // Since X draws from the baseline of the text, must add the text height
1547 int direction
, descent
;
1549 slen
= strlen(text
);
1550 XCharStruct overall_return
;
1552 (void)XTextExtents(xfont
, (char*) text
.c_str(), slen
, &direction
,
1553 &ascent
, &descent
, &overall_return
);
1555 cx
= overall_return
.width
;
1556 cy
= ascent
+ descent
;
1557 m_textBackgroundColour
.CalcPixel(m_cmap
);
1558 m_textForegroundColour
.CalcPixel(m_cmap
);
1559 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel());
1560 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
1561 (GC
) m_textGC
, x
, y
, cx
, cy
);
1562 XSetForeground ((Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel());
1566 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1568 // This may be a test for whether the font is 16-bit, but it also
1569 // seems to fail for valid 8-bit fonts too.
1570 if (1) // (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") );
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
);
1672 pango_layout_set_font_description(layout
, m_fontdesc
);
1674 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1676 pango_layout_set_text(layout
, "H", 1 );
1678 pango_layout_get_pixel_size(layout
, &w
, &h
);
1679 g_object_unref( G_OBJECT( layout
) );
1683 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1685 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1687 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1689 int direction
, ascent
, descent
;
1690 XCharStruct overall
;
1692 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1694 return (wxCoord
)(overall
.width
/ m_scaleX
);
1698 wxCoord
wxWindowDC::GetCharHeight() const
1700 wxCHECK_MSG( Ok(), 0, wxT("invalid dc") );
1703 PangoLayout
*layout
= pango_layout_new( m_context
);
1706 pango_layout_set_font_description(layout
, m_fontdesc
);
1708 pango_layout_set_font_description(layout
, this->GetFont().GetNativeFontInfo()->description
);
1710 pango_layout_set_text(layout
, "H", 1 );
1712 pango_layout_get_pixel_size(layout
, &w
, &h
);
1713 g_object_unref( G_OBJECT( layout
) );
1717 wxCHECK_MSG( m_font
.Ok(), 0, wxT("invalid font") );
1719 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1721 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1723 int direction
, ascent
, descent
;
1724 XCharStruct overall
;
1726 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1728 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1732 void wxWindowDC::Clear()
1734 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1736 if (!m_window
) return;
1738 /* - we either are a memory dc or have a window as the
1739 owner. anything else shouldn't happen.
1740 - we don't use gdk_window_clear() as we don't set
1741 the window's background colour anymore. it is too
1742 much pain to keep the DC's and the window's back-
1743 ground colour in synch. */
1748 m_owner
->GetSize( &width
, &height
);
1749 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1756 GetSize( &width
, &height
);
1757 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1762 void wxWindowDC::SetFont( const wxFont
&font
)
1764 wxCHECK_RET( Ok(), wxT("invalid dc") );
1771 m_fontdesc
= font
.GetNativeFontInfo()->description
;
1775 void wxWindowDC::SetPen( const wxPen
&pen
)
1777 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1779 if (m_pen
== pen
) return;
1783 if (!m_pen
.Ok()) return;
1785 if (!m_window
) return;
1787 int width
= m_pen
.GetWidth();
1790 // CMB: if width is non-zero scale it with the dc
1795 // X doesn't allow different width in x and y and so we take
1798 ( fabs((double) XLOG2DEVREL(width
)) +
1799 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1803 static const wxX11Dash dotted
[] = {1, 1};
1804 static const wxX11Dash short_dashed
[] = {2, 2};
1805 static const wxX11Dash long_dashed
[] = {2, 4};
1806 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1808 // We express dash pattern in pen width unit, so we are
1809 // independent of zoom factor and so on...
1811 const wxX11Dash
*req_dash
;
1813 int lineStyle
= LineSolid
;
1814 switch (m_pen
.GetStyle())
1818 lineStyle
= LineOnOffDash
;
1819 req_nb_dash
= m_pen
.GetDashCount();
1820 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1825 lineStyle
= LineOnOffDash
;
1832 lineStyle
= LineOnOffDash
;
1834 req_dash
= long_dashed
;
1839 lineStyle
= LineOnOffDash
;
1841 req_dash
= short_dashed
;
1846 // lineStyle = LineDoubleDash;
1847 lineStyle
= LineOnOffDash
;
1849 req_dash
= dotted_dashed
;
1854 case wxSTIPPLE_MASK_OPAQUE
:
1859 lineStyle
= LineSolid
;
1860 req_dash
= (wxX11Dash
*)NULL
;
1866 int capStyle
= CapRound
;
1867 switch (m_pen
.GetCap())
1869 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1870 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1877 capStyle
= CapNotLast
;
1881 capStyle
= CapRound
;
1887 int joinStyle
= JoinRound
;
1888 switch (m_pen
.GetJoin())
1890 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1891 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1893 default: { joinStyle
= JoinRound
; break; }
1896 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1898 m_pen
.GetColour().CalcPixel( m_cmap
);
1899 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1902 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1904 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1906 if (m_brush
== brush
) return;
1910 if (!m_brush
.Ok()) return;
1912 if (!m_window
) return;
1914 m_brush
.GetColour().CalcPixel( m_cmap
);
1915 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1917 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1919 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1921 if (m_brush
.GetStipple()->GetPixmap())
1923 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1924 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1928 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1929 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetBitmap() );
1933 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1935 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1936 XSetStipple( (Display
*) m_display
, (GC
) m_textGC
, (Pixmap
) m_brush
.GetStipple()->GetMask()->GetBitmap() );
1939 if (m_brush
.IsHatch())
1941 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1942 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1943 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1947 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1949 /* CMB 21/7/98: Added SetBackground. Sets background brush
1950 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1952 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1954 if (m_backgroundBrush
== brush
) return;
1956 m_backgroundBrush
= brush
;
1958 if (!m_backgroundBrush
.Ok()) return;
1960 if (!m_window
) return;
1962 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1963 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1964 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1965 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1966 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1968 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1970 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1972 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1974 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1975 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1979 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1980 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetBitmap() );
1984 if (m_backgroundBrush
.IsHatch())
1986 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1987 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
1988 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
1992 void wxWindowDC::SetLogicalFunction( int function
)
1994 wxCHECK_RET( Ok(), wxT("invalid dc") );
1998 if (m_logicalFunction
== function
)
2001 // VZ: shouldn't this be a CHECK?
2008 x_function
= GXclear
;
2014 x_function
= GXinvert
;
2017 x_function
= GXorReverse
;
2020 x_function
= GXandReverse
;
2029 x_function
= GXandInverted
;
2032 x_function
= GXnoop
;
2038 x_function
= GXequiv
;
2041 x_function
= GXcopyInverted
;
2044 x_function
= GXorInverted
;
2047 x_function
= GXnand
;
2054 x_function
= GXcopy
;
2058 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
2059 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
2061 // to stay compatible with wxMSW, we don't apply ROPs to the text
2062 // operations (i.e. DrawText/DrawRotatedText).
2063 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
2064 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
2066 m_logicalFunction
= function
;
2069 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2071 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2073 // don't set m_textForegroundColour to an invalid colour as we'd crash
2074 // later then (we use m_textForegroundColour.GetColor() without checking
2076 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
2079 m_textForegroundColour
= col
;
2083 m_textForegroundColour
.CalcPixel( m_cmap
);
2084 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
2088 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2090 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2093 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
2096 m_textBackgroundColour
= col
;
2100 m_textBackgroundColour
.CalcPixel( m_cmap
);
2101 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
2105 void wxWindowDC::SetBackgroundMode( int mode
)
2107 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2109 m_backgroundMode
= mode
;
2112 GrSetGCUseBackground((GC
) m_textGC
, mode
== wxTRANSPARENT
? FALSE
: TRUE
);
2115 if (!m_window
) return;
2117 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
2118 // transparent/solid background mode
2120 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
2122 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
2123 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
2127 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2133 /* Use GetXColormap */
2134 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2135 (Colormap
) palette
.GetXColormap());
2137 /* Use wxGetMainColormap */
2138 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2139 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2144 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2146 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2148 if (!m_window
) return;
2151 rect
.x
= XLOG2DEV(x
);
2152 rect
.y
= YLOG2DEV(y
);
2153 rect
.width
= XLOG2DEVREL(width
);
2154 rect
.height
= YLOG2DEVREL(height
);
2156 if (!m_currentClippingRegion
.IsNull())
2157 m_currentClippingRegion
.Intersect( rect
);
2159 m_currentClippingRegion
.Union( rect
);
2161 #if USE_PAINT_REGION
2162 if (!m_paintClippingRegion
.IsNull())
2163 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2166 wxCoord xx
, yy
, ww
, hh
;
2167 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2168 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2170 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2171 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2172 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2173 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2176 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2178 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2182 DestroyClippingRegion();
2186 if (!m_window
) return;
2188 if (!m_currentClippingRegion
.IsNull())
2189 m_currentClippingRegion
.Intersect( region
);
2191 m_currentClippingRegion
.Union( region
);
2193 #if USE_PAINT_REGION
2194 if (!m_paintClippingRegion
.IsNull())
2195 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
2198 wxCoord xx
, yy
, ww
, hh
;
2199 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
2200 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
2202 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2203 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2204 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2205 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2208 void wxWindowDC::DestroyClippingRegion()
2210 wxCHECK_RET( Ok(), wxT("invalid window dc") );
2212 wxDC::DestroyClippingRegion();
2214 m_currentClippingRegion
.Clear();
2216 #if USE_PAINT_REGION
2217 if (!m_paintClippingRegion
.IsEmpty())
2218 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2221 if (!m_window
) return;
2223 if (m_currentClippingRegion
.IsEmpty())
2225 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
2226 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
2227 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
2228 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
2232 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2233 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2234 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2235 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
2239 void wxWindowDC::Destroy()
2241 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
2243 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
2245 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
2247 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
2251 void wxWindowDC::ComputeScaleAndOrigin()
2253 /* CMB: copy scale to see if it changes */
2254 double origScaleX
= m_scaleX
;
2255 double origScaleY
= m_scaleY
;
2257 wxDC::ComputeScaleAndOrigin();
2259 /* CMB: if scale has changed call SetPen to recalulate the line width */
2260 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
2263 /* this is a bit artificial, but we need to force wxDC to think
2264 the pen has changed */
2271 wxSize
wxWindowDC::GetPPI() const
2273 return wxSize(100, 100);
2276 int wxWindowDC::GetDepth() const
2278 wxFAIL_MSG(wxT("not implemented"));
2283 //-----------------------------------------------------------------------------
2285 //-----------------------------------------------------------------------------
2287 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
2289 wxClientDC::wxClientDC( wxWindow
*window
)
2290 : wxWindowDC( window
)
2292 wxCHECK_RET( window
, _T("NULL window in wxClientDC::wxClientDC") );
2294 m_window
= (WXWindow
*) window
->GetClientAreaWindow();
2296 // Adjust the client area when the wxWindow is not using 2 X11 windows.
2297 if (m_window
== (WXWindow
*) window
->GetMainWindow())
2299 wxPoint ptOrigin
= window
->GetClientAreaOrigin();
2300 SetDeviceOrigin(ptOrigin
.x
, ptOrigin
.y
);
2301 wxSize size
= window
->GetClientSize();
2302 SetClippingRegion(wxPoint(0, 0), size
);
2306 void wxClientDC::DoGetSize(int *width
, int *height
) const
2308 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
2310 m_owner
->GetClientSize( width
, height
);
2313 // ----------------------------------------------------------------------------
2315 // ----------------------------------------------------------------------------
2317 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
2319 wxPaintDC::wxPaintDC(wxWindow
* window
)
2320 : wxClientDC(window
)
2322 #if USE_PAINT_REGION
2323 if (!window
->GetClipPaintRegion())
2326 m_paintClippingRegion
= window
->GetUpdateRegion();
2327 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
2330 m_currentClippingRegion
.Union( m_paintClippingRegion
);
2332 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region
);
2333 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region
);
2334 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region
);
2335 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region
);
2337 #endif // USE_PAINT_REGION
2340 // ----------------------------------------------------------------------------
2342 // ----------------------------------------------------------------------------
2344 class wxDCModule
: public wxModule
2351 DECLARE_DYNAMIC_CLASS(wxDCModule
)
2354 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)
2356 bool wxDCModule::OnInit()
2362 void wxDCModule::OnExit()