]>
git.saurik.com Git - wxWidgets.git/blob - src/x11/dcclient.cpp
44b06b29b722b83dddfd675d3a9e3493f6f45214
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 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "dcclient.h"
16 #include "wx/dcclient.h"
17 #include "wx/dcmemory.h"
18 #include "wx/window.h"
22 #include "wx/x11/private.h"
26 //-----------------------------------------------------------------------------
28 //-----------------------------------------------------------------------------
30 #define USE_PAINT_REGION 1
32 //-----------------------------------------------------------------------------
34 //-----------------------------------------------------------------------------
44 #define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH)
45 #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH)
47 static Pixmap hatches
[num_hatches
];
48 static Pixmap
*hatch_bitmap
= (Pixmap
*) NULL
;
50 //-----------------------------------------------------------------------------
52 //-----------------------------------------------------------------------------
54 const double RAD2DEG
= 180.0 / M_PI
;
56 // ----------------------------------------------------------------------------
58 // ----------------------------------------------------------------------------
60 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
61 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
63 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
65 //-----------------------------------------------------------------------------
66 // Implement Pool of Graphic contexts. Creating them takes too much time.
67 //-----------------------------------------------------------------------------
69 #define GC_POOL_SIZE 200
95 static wxGC wxGCPool
[GC_POOL_SIZE
];
97 static void wxInitGCPool()
99 memset( wxGCPool
, 0, GC_POOL_SIZE
*sizeof(wxGC
) );
102 static void wxCleanUpGCPool()
104 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
106 if (wxGCPool
[i
].m_gc
)
107 XFreeGC( wxGlobalDisplay(), wxGCPool
[i
].m_gc
);
111 static GC
wxGetPoolGC( Window window
, wxPoolGCType type
)
113 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
115 if (!wxGCPool
[i
].m_gc
)
117 wxGCPool
[i
].m_gc
= XCreateGC( wxGlobalDisplay(), window
, 0, NULL
);
118 XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool
[i
].m_gc
, FALSE
);
119 wxGCPool
[i
].m_type
= type
;
120 wxGCPool
[i
].m_used
= FALSE
;
122 if ((!wxGCPool
[i
].m_used
) && (wxGCPool
[i
].m_type
== type
))
124 wxGCPool
[i
].m_used
= TRUE
;
125 return wxGCPool
[i
].m_gc
;
129 wxFAIL_MSG( wxT("No GC available") );
134 static void wxFreePoolGC( GC gc
)
136 for (int i
= 0; i
< GC_POOL_SIZE
; i
++)
138 if (wxGCPool
[i
].m_gc
== gc
)
140 wxGCPool
[i
].m_used
= FALSE
;
145 wxFAIL_MSG( wxT("Wrong GC") );
148 // ----------------------------------------------------------------------------
150 // ----------------------------------------------------------------------------
152 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
154 wxWindowDC::wxWindowDC()
156 m_display
= (WXDisplay
*) NULL
;
157 m_penGC
= (WXGC
*) NULL
;
158 m_brushGC
= (WXGC
*) NULL
;
159 m_textGC
= (WXGC
*) NULL
;
160 m_bgGC
= (WXGC
*) NULL
;
161 m_cmap
= (WXColormap
*) NULL
;
163 m_isScreenDC
= FALSE
;
164 m_owner
= (wxWindow
*)NULL
;
167 wxWindowDC::wxWindowDC( wxWindow
*window
)
169 wxASSERT_MSG( window
, wxT("DC needs a window") );
171 m_display
= (WXDisplay
*) NULL
;
172 m_penGC
= (WXGC
*) NULL
;
173 m_brushGC
= (WXGC
*) NULL
;
174 m_textGC
= (WXGC
*) NULL
;
175 m_bgGC
= (WXGC
*) NULL
;
176 m_cmap
= (WXColormap
*) NULL
;
177 m_owner
= (wxWindow
*)NULL
;
179 m_isScreenDC
= FALSE
;
180 m_font
= window
->GetFont();
182 m_window
= (WXWindow
*) window
->GetMainWindow();
187 // don't report problems
193 m_display
= (WXDisplay
*) wxGlobalDisplay();
195 int screen
= DefaultScreen( (Display
*) m_display
);
196 m_cmap
= (WXColormap
) DefaultColormap( (Display
*) m_display
, screen
);
200 /* this must be done after SetUpDC, bacause SetUpDC calls the
201 repective SetBrush, SetPen, SetBackground etc functions
202 to set up the DC. SetBackground call m_owner->SetBackground
203 and this might not be desired as the standard dc background
204 is white whereas a window might assume gray to be the
205 standard (as e.g. wxStatusBar) */
210 wxWindowDC::~wxWindowDC()
215 void wxWindowDC::SetUpDC()
219 wxASSERT_MSG( !m_penGC
, wxT("GCs already created") );
223 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_SCREEN
);
224 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_SCREEN
);
225 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_SCREEN
);
226 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_SCREEN
);
230 if (m_isMemDC
&& (((wxMemoryDC
*)this)->m_selected
.GetDepth() == 1))
232 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_MONO
);
233 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_MONO
);
234 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_MONO
);
235 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_MONO
);
240 m_penGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxPEN_COLOUR
);
241 m_brushGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBRUSH_COLOUR
);
242 m_textGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxTEXT_COLOUR
);
243 m_bgGC
= (WXGC
*) wxGetPoolGC( (Window
) m_window
, wxBG_COLOUR
);
246 /* background colour */
247 m_backgroundBrush
= *wxWHITE_BRUSH
;
248 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
249 unsigned long bg_col
= m_backgroundBrush
.GetColour().GetPixel();
252 m_textForegroundColour
.CalcPixel( m_cmap
);
253 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
255 m_textBackgroundColour
.CalcPixel( m_cmap
);
256 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
258 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillSolid
);
261 m_pen
.GetColour().CalcPixel( m_cmap
);
262 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
263 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, bg_col
);
265 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, 0, LineSolid
, CapNotLast
, JoinRound
);
268 m_brush
.GetColour().CalcPixel( m_cmap
);
269 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
270 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, bg_col
);
272 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
275 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
276 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, bg_col
);
278 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
281 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, GXcopy
);
282 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, GXcopy
);
283 XSetFunction( (Display
*) m_display
, (GC
)m_penGC
, GXcopy
);
286 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
287 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
288 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
289 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
293 hatch_bitmap
= hatches
;
294 hatch_bitmap
[0] = XCreateBitmapFromData( (Display
*) m_display
, None
, bdiag_bits
, bdiag_width
, bdiag_height
);
295 hatch_bitmap
[1] = XCreateBitmapFromData( (Display
*) m_display
, None
, cdiag_bits
, cdiag_width
, cdiag_height
);
296 hatch_bitmap
[2] = XCreateBitmapFromData( (Display
*) m_display
, None
, fdiag_bits
, fdiag_width
, fdiag_height
);
297 hatch_bitmap
[3] = XCreateBitmapFromData( (Display
*) m_display
, None
, cross_bits
, cross_width
, cross_height
);
298 hatch_bitmap
[4] = XCreateBitmapFromData( (Display
*) m_display
, None
, horiz_bits
, horiz_width
, horiz_height
);
299 hatch_bitmap
[5] = XCreateBitmapFromData( (Display
*) m_display
, None
, verti_bits
, verti_width
, verti_height
);
303 void wxWindowDC::DoGetSize( int* width
, int* height
) const
305 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
307 m_owner
->GetSize(width
, height
);
310 void wxWindowDC::DoFloodFill( wxCoord
WXUNUSED(x1
), wxCoord
WXUNUSED(y1
),
311 const wxColour
& WXUNUSED(col
), int WXUNUSED(style
) )
313 wxFAIL_MSG("not implemented");
316 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
318 // Generic (and therefore rather inefficient) method.
319 // Could be improved.
321 wxBitmap
bitmap(1, 1);
322 memdc
.SelectObject(bitmap
);
323 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
324 memdc
.SelectObject(wxNullBitmap
);
325 wxImage
image(bitmap
);
326 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
330 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
332 wxCHECK_RET( Ok(), wxT("invalid window dc") );
334 if (m_pen
.GetStyle() != wxTRANSPARENT
)
337 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
338 (GC
) m_penGC
, XLOG2DEV(x1
), YLOG2DEV(y1
), XLOG2DEV(x2
), YLOG2DEV(y2
) );
340 CalcBoundingBox(x1
, y1
);
341 CalcBoundingBox(x2
, y2
);
345 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
347 wxCHECK_RET( Ok(), wxT("invalid window dc") );
349 if (m_pen
.GetStyle() != wxTRANSPARENT
)
354 wxCoord xx
= XLOG2DEV(x
);
355 wxCoord yy
= YLOG2DEV(y
);
358 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
359 (GC
) m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
360 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
361 (GC
) m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
366 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
368 wxCHECK_RET( Ok(), wxT("invalid window dc") );
370 wxCoord xx1
= XLOG2DEV(x1
);
371 wxCoord yy1
= YLOG2DEV(y1
);
372 wxCoord xx2
= XLOG2DEV(x2
);
373 wxCoord yy2
= YLOG2DEV(y2
);
374 wxCoord xxc
= XLOG2DEV(xc
);
375 wxCoord yyc
= YLOG2DEV(yc
);
376 double dx
= xx1
- xxc
;
377 double dy
= yy1
- yyc
;
378 double radius
= sqrt((double)(dx
*dx
+dy
*dy
));
379 wxCoord r
= (wxCoord
)radius
;
380 double radius1
, radius2
;
382 if (xx1
== xx2
&& yy1
== yy2
)
390 radius1
= radius2
= 0.0;
394 radius1
= (xx1
- xxc
== 0) ?
395 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
396 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
397 radius2
= (xx2
- xxc
== 0) ?
398 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
399 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
401 wxCoord alpha1
= wxCoord(radius1
* 64.0);
402 wxCoord alpha2
= wxCoord((radius2
- radius1
) * 64.0);
403 while (alpha2
<= 0) alpha2
+= 360*64;
404 while (alpha1
> 360*64) alpha1
-= 360*64;
408 if (m_brush
.GetStyle() != wxTRANSPARENT
)
410 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
412 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
413 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
414 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
416 XFillArc( (Display
*) m_display
, (Window
) m_window
,
417 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
419 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
421 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
423 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
424 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
426 XFillArc( (Display
*) m_display
, (Window
) m_window
,
427 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
429 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
431 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
433 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
434 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
436 XFillArc( (Display
*) m_display
, (Window
) m_window
,
437 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
439 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
441 if (m_brush
.GetStyle() == wxSTIPPLE
)
443 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
444 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
445 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
447 XFillArc( (Display
*) m_display
, (Window
) m_window
,
448 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
450 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
454 XFillArc( (Display
*) m_display
, (Window
) m_window
,
455 (GC
) m_brushGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
459 if (m_pen
.GetStyle() != wxTRANSPARENT
)
461 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
462 (GC
) m_penGC
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
464 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
465 (GC
) m_penGC
, xx1
, yy1
, xxc
, yyc
);
467 XDrawLine( (Display
*) m_display
, (Window
) m_window
,
468 (GC
) m_penGC
, xxc
, yyc
, xx2
, yy2
);
472 CalcBoundingBox (x1
, y1
);
473 CalcBoundingBox (x2
, y2
);
476 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
478 wxCHECK_RET( Ok(), wxT("invalid window dc") );
480 wxCoord xx
= XLOG2DEV(x
);
481 wxCoord yy
= YLOG2DEV(y
);
482 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
483 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
485 // CMB: handle -ve width and/or height
486 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
487 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
491 wxCoord start
= wxCoord(sa
* 64.0);
492 wxCoord end
= wxCoord((ea
-sa
) * 64.0);
494 if (m_brush
.GetStyle() != wxTRANSPARENT
)
496 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
498 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
499 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
500 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
502 XFillArc( (Display
*) m_display
, (Window
) m_window
,
503 (GC
) m_textGC
, xx
, yy
, ww
, hh
, start
, end
);
505 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
507 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
509 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
510 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
512 XFillArc( (Display
*) m_display
, (Window
) m_window
,
513 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
515 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
517 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
519 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
520 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
522 XFillArc( (Display
*) m_display
, (Window
) m_window
,
523 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
525 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
527 if (m_brush
.GetStyle() == wxSTIPPLE
)
529 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
530 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
531 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
533 XFillArc( (Display
*) m_display
, (Window
) m_window
,
534 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
536 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
540 XFillArc( (Display
*) m_display
, (Window
) m_window
,
541 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, start
, end
);
545 if (m_pen
.GetStyle() != wxTRANSPARENT
)
547 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
548 (GC
) m_penGC
, xx
, yy
, ww
, hh
, start
, end
);
552 CalcBoundingBox (x
, y
);
553 CalcBoundingBox (x
+ width
, y
+ height
);
556 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
558 wxCHECK_RET( Ok(), wxT("invalid window dc") );
560 if ((m_pen
.GetStyle() != wxTRANSPARENT
) && m_window
)
561 XDrawPoint( (Display
*) m_display
, (Window
) m_window
,
562 (GC
) m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
564 CalcBoundingBox (x
, y
);
567 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
569 wxCHECK_RET( Ok(), wxT("invalid window dc") );
571 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
574 XPoint
*xpoints
= new XPoint
[n
];
575 for (int i
= 0; i
< n
; i
++)
577 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
578 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
580 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
582 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
, 0 );
587 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
588 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
590 wxCHECK_RET( Ok(), wxT("invalid window dc") );
594 XPoint
*xpoints
= new XPoint
[n
+ 1];
596 for (i
= 0; i
< n
; i
++)
598 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
599 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
601 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
606 if (m_brush
.GetStyle() != wxTRANSPARENT
)
609 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
611 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
612 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
613 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
615 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
616 (GC
) m_textGC
, xpoints
, n
, Complex
, 0);
618 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
620 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
622 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
623 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
625 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
626 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
628 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
630 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
632 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
633 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
635 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
636 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
638 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
640 if (m_brush
.GetStyle() == wxSTIPPLE
)
642 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
643 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
644 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
646 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
647 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
649 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
653 XFillPolygon( (Display
*) m_display
, (Window
) m_window
,
654 (GC
) m_brushGC
, xpoints
, n
, Complex
, 0);
658 if (m_pen
.GetStyle () != wxTRANSPARENT
)
660 // Close figure for XDrawLines
661 xpoints
[i
].x
= xpoints
[0].x
;
662 xpoints
[i
].y
= xpoints
[0].y
;
664 XDrawLines( (Display
*) m_display
, (Window
) m_window
, (GC
) m_penGC
, xpoints
, n
+ 1, 0);
671 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
673 wxCHECK_RET( Ok(), wxT("invalid window dc") );
675 wxCoord xx
= XLOG2DEV(x
);
676 wxCoord yy
= YLOG2DEV(y
);
677 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
678 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
680 // CMB: draw nothing if transformed w or h is 0
681 if (ww
== 0 || hh
== 0) return;
683 // CMB: handle -ve width and/or height
684 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
685 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
689 if (m_brush
.GetStyle() != wxTRANSPARENT
)
691 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
693 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
694 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
695 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
697 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
698 (GC
) m_textGC
, xx
, yy
, ww
, hh
);
700 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
702 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
704 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
705 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
707 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
708 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
710 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
712 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
714 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
715 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
717 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
718 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
720 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
722 if (m_brush
.GetStyle() == wxSTIPPLE
)
724 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
725 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
726 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
728 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
729 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
731 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
735 XFillRectangle( (Display
*) m_display
, (Window
) m_window
,
736 (GC
) m_brushGC
, xx
, yy
, ww
, hh
);
740 if (m_pen
.GetStyle () != wxTRANSPARENT
)
742 XDrawRectangle( (Display
*) m_display
, (Window
) m_window
,
743 (GC
) m_penGC
, xx
, yy
, ww
, hh
);
747 CalcBoundingBox( x
, y
);
748 CalcBoundingBox( x
+ width
, y
+ height
);
751 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
756 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
758 wxCHECK_RET( Ok(), wxT("invalid window dc") );
760 wxCoord xx
= XLOG2DEV(x
);
761 wxCoord yy
= YLOG2DEV(y
);
762 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
763 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
765 // CMB: handle -ve width and/or height
766 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
767 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
771 if (m_brush
.GetStyle() != wxTRANSPARENT
)
773 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
775 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
,
776 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
777 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
779 XFillArc( (Display
*) m_display
, (Window
) m_window
,
780 (GC
) m_textGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
782 XSetTSOrigin( (Display
*) m_display
, (GC
) m_textGC
, 0, 0 );
784 if (IS_15_PIX_HATCH(m_brush
.GetStyle()))
786 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
787 m_deviceOriginX
% 15, m_deviceOriginY
% 15 );
789 XFillArc( (Display
*) m_display
, (Window
) m_window
,
790 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
792 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
794 if (IS_16_PIX_HATCH(m_brush
.GetStyle()))
796 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
797 m_deviceOriginX
% 16, m_deviceOriginY
% 16 );
799 XFillArc( (Display
*) m_display
, (Window
) m_window
,
800 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
802 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
804 if (m_brush
.GetStyle() == wxSTIPPLE
)
806 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
,
807 m_deviceOriginX
% m_brush
.GetStipple()->GetWidth(),
808 m_deviceOriginY
% m_brush
.GetStipple()->GetHeight() );
810 XFillArc( (Display
*) m_display
, (Window
) m_window
,
811 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
813 XSetTSOrigin( (Display
*) m_display
, (GC
) m_brushGC
, 0, 0 );
817 XFillArc( (Display
*) m_display
, (Window
) m_window
,
818 (GC
) m_brushGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
822 if (m_pen
.GetStyle () != wxTRANSPARENT
)
824 XDrawArc( (Display
*) m_display
, (Window
) m_window
,
825 (GC
) m_penGC
, xx
, yy
, ww
, hh
, 0, 360*64 );
829 CalcBoundingBox( x
, y
);
830 CalcBoundingBox( x
+ width
, y
+ height
);
833 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
837 void wxWindowDC::DoDrawBitmap( const wxBitmap
&bitmap
,
838 wxCoord x
, wxCoord y
,
841 wxCHECK_RET( Ok(), wxT("invalid window dc") );
843 wxCHECK_RET( bitmap
.Ok(), wxT("invalid bitmap") );
846 bool is_mono
= (bitmap
.GetBitmap() != NULL
);
848 /* scale/translate size and position */
849 int xx
= XLOG2DEV(x
);
850 int yy
= YLOG2DEV(y
);
852 int w
= bitmap
.GetWidth();
853 int h
= bitmap
.GetHeight();
855 CalcBoundingBox( x
, y
);
856 CalcBoundingBox( x
+ w
, y
+ h
);
858 if (!m_window
) return;
860 int ww
= XLOG2DEVREL(w
);
861 int hh
= YLOG2DEVREL(h
);
863 /* compare to current clipping region */
864 if (!m_currentClippingRegion
.IsNull())
866 wxRegion
tmp( xx
,yy
,ww
,hh
);
867 tmp
.Intersect( m_currentClippingRegion
);
872 /* scale bitmap if required */
874 if ((w
!= ww
) || (h
!= hh
))
876 wxImage
image( bitmap
);
877 image
.Rescale( ww
, hh
);
879 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
881 use_bitmap
= image
.ConvertToBitmap();
888 /* apply mask if any */
889 GdkBitmap
*mask
= (GdkBitmap
*) NULL
;
890 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
894 GdkBitmap
*new_mask
= (GdkBitmap
*) NULL
;
895 if (!m_currentClippingRegion
.IsNull())
898 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, ww
, hh
, 1 );
899 GdkGC
*gc
= gdk_gc_new( new_mask
);
901 gdk_gc_set_foreground( gc
, &col
);
902 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
904 gdk_gc_set_background( gc
, &col
);
906 gdk_gc_set_foreground( gc
, &col
);
907 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
908 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
909 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
910 gdk_gc_set_stipple( gc
, mask
);
911 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, ww
, hh
);
918 gdk_gc_set_clip_mask( m_textGC
, new_mask
);
920 gdk_gc_set_clip_mask( m_textGC
, mask
);
921 gdk_gc_set_clip_origin( m_textGC
, xx
, yy
);
926 gdk_gc_set_clip_mask( m_penGC
, new_mask
);
928 gdk_gc_set_clip_mask( m_penGC
, mask
);
929 gdk_gc_set_clip_origin( m_penGC
, xx
, yy
);
932 gdk_bitmap_unref( new_mask
);
935 /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
936 drawing a mono-bitmap (XBitmap) we use the current text GC */
938 gdk_wx_draw_bitmap( m_window
, m_textGC
, use_bitmap
.GetBitmap(), 0, 0, xx
, yy
, -1, -1 );
940 gdk_draw_pixmap( m_window
, m_penGC
, use_bitmap
.GetPixmap(), 0, 0, xx
, yy
, -1, -1 );
942 /* remove mask again if any */
947 gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap
*) NULL
);
948 gdk_gc_set_clip_origin( m_textGC
, 0, 0 );
949 if (!m_currentClippingRegion
.IsNull())
950 gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() );
954 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap
*) NULL
);
955 gdk_gc_set_clip_origin( m_penGC
, 0, 0 );
956 if (!m_currentClippingRegion
.IsNull())
957 gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() );
963 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
964 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int rop
, bool useMask
,
965 wxCoord xsrcMask
, wxCoord ysrcMask
)
967 /* this is the nth try to get this utterly useless function to
968 work. it now completely ignores the scaling or translation
969 of the source dc, but scales correctly on the target dc and
970 knows about possible mask information in a memory dc. */
972 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid window dc") );
974 wxCHECK_MSG( source
, FALSE
, wxT("invalid source dc") );
976 if (!m_window
) return FALSE
;
978 // transform the source DC coords to the device ones
979 xsrc
= source
->XLOG2DEV(xsrc
);
980 ysrc
= source
->YLOG2DEV(ysrc
);
982 wxClientDC
*srcDC
= (wxClientDC
*)source
;
983 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
985 bool use_bitmap_method
= FALSE
;
986 bool is_mono
= FALSE
;
988 /* TODO: use the mask origin when drawing transparently */
989 if (xsrcMask
== -1 && ysrcMask
== -1)
991 xsrcMask
= xsrc
; ysrcMask
= ysrc
;
995 if (srcDC
->m_isMemDC
)
997 if (!memDC
->m_selected
.Ok()) return FALSE
;
999 /* we use the "XCopyArea" way to copy a memory dc into
1000 y different window if the memory dc BOTH
1001 a) doesn't have any mask or its mask isn't used
1005 if (useMask
&& (memDC
->m_selected
.GetMask()))
1007 /* we HAVE TO use the direct way for memory dcs
1008 that have mask since the XCopyArea doesn't know
1010 use_bitmap_method
= TRUE
;
1012 else if (memDC
->m_selected
.GetDepth() == 1)
1014 /* we HAVE TO use the direct way for memory dcs
1015 that are bitmaps because XCopyArea doesn't cope
1016 with different bit depths */
1018 use_bitmap_method
= TRUE
;
1020 else if ((xsrc
== 0) && (ysrc
== 0) &&
1021 (width
== memDC
->m_selected
.GetWidth()) &&
1022 (height
== memDC
->m_selected
.GetHeight()))
1024 /* we SHOULD use the direct way if all of the bitmap
1025 in the memory dc is copied in which case XCopyArea
1026 wouldn't be able able to boost performace by reducing
1027 the area to be scaled */
1028 use_bitmap_method
= TRUE
;
1032 use_bitmap_method
= FALSE
;
1036 CalcBoundingBox( xdest
, ydest
);
1037 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
1039 /* scale/translate size and position */
1040 wxCoord xx
= XLOG2DEV(xdest
);
1041 wxCoord yy
= YLOG2DEV(ydest
);
1043 wxCoord ww
= XLOG2DEVREL(width
);
1044 wxCoord hh
= YLOG2DEVREL(height
);
1046 /* compare to current clipping region */
1047 if (!m_currentClippingRegion
.IsNull())
1049 wxRegion
tmp( xx
,yy
,ww
,hh
);
1050 tmp
.Intersect( m_currentClippingRegion
);
1055 int old_logical_func
= m_logicalFunction
;
1056 SetLogicalFunction( logical_func
);
1058 if (use_bitmap_method
)
1060 /* scale/translate bitmap size */
1061 wxCoord bm_width
= memDC
->m_selected
.GetWidth();
1062 wxCoord bm_height
= memDC
->m_selected
.GetHeight();
1064 wxCoord bm_ww
= XLOG2DEVREL( bm_width
);
1065 wxCoord bm_hh
= YLOG2DEVREL( bm_height
);
1067 /* scale bitmap if required */
1068 wxBitmap use_bitmap
;
1070 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
1072 wxImage
image( memDC
->m_selected
);
1073 image
= image
.Scale( bm_ww
, bm_hh
);
1076 use_bitmap
= image
.ConvertToMonoBitmap(255,255,255);
1078 use_bitmap
= image
.ConvertToBitmap();
1082 use_bitmap
= memDC
->m_selected
;
1085 /* apply mask if any */
1086 GdkBitmap
*mask
= (GdkBitmap
*) NULL
;
1087 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
1089 if (useMask
&& mask
)
1091 GdkBitmap
*new_mask
= (GdkBitmap
*) NULL
;
1092 if (!m_currentClippingRegion
.IsNull())
1095 new_mask
= gdk_pixmap_new( wxGetRootWindow()->window
, bm_ww
, bm_hh
, 1 );
1096 GdkGC
*gc
= gdk_gc_new( new_mask
);
1098 gdk_gc_set_foreground( gc
, &col
);
1099 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1101 gdk_gc_set_background( gc
, &col
);
1103 gdk_gc_set_foreground( gc
, &col
);
1104 gdk_gc_set_clip_region( gc
, m_currentClippingRegion
.GetRegion() );
1105 gdk_gc_set_clip_origin( gc
, -xx
, -yy
);
1106 gdk_gc_set_fill( gc
, GDK_OPAQUE_STIPPLED
);
1107 gdk_gc_set_stipple( gc
, mask
);
1108 gdk_draw_rectangle( new_mask
, gc
, TRUE
, 0, 0, bm_ww
, bm_hh
);
1115 gdk_gc_set_clip_mask( m_textGC
, new_mask
);
1117 gdk_gc_set_clip_mask( m_textGC
, mask
);
1118 gdk_gc_set_clip_origin( m_textGC
, xx
, yy
);
1123 gdk_gc_set_clip_mask( m_penGC
, new_mask
);
1125 gdk_gc_set_clip_mask( m_penGC
, mask
);
1126 gdk_gc_set_clip_origin( m_penGC
, xx
, yy
);
1129 gdk_bitmap_unref( new_mask
);
1132 /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
1133 drawing a mono-bitmap (XBitmap) we use the current text GC */
1136 gdk_wx_draw_bitmap( m_window
, m_textGC
, use_bitmap
.GetBitmap(), xsrc
, ysrc
, xx
, yy
, ww
, hh
);
1138 gdk_draw_pixmap( m_window
, m_penGC
, use_bitmap
.GetPixmap(), xsrc
, ysrc
, xx
, yy
, ww
, hh
);
1140 /* remove mask again if any */
1141 if (useMask
&& mask
)
1145 gdk_gc_set_clip_mask( m_textGC
, (GdkBitmap
*) NULL
);
1146 gdk_gc_set_clip_origin( m_textGC
, 0, 0 );
1147 if (!m_currentClippingRegion
.IsNull())
1148 gdk_gc_set_clip_region( m_textGC
, m_currentClippingRegion
.GetRegion() );
1152 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap
*) NULL
);
1153 gdk_gc_set_clip_origin( m_penGC
, 0, 0 );
1154 if (!m_currentClippingRegion
.IsNull())
1155 gdk_gc_set_clip_region( m_penGC
, m_currentClippingRegion
.GetRegion() );
1159 else /* use_bitmap_method */
1161 if ((width
!= ww
) || (height
!= hh
))
1163 /* draw source window into a bitmap as we cannot scale
1164 a window in contrast to a bitmap. this would actually
1165 work with memory dcs as well, but we'd lose the mask
1166 information and waste one step in this process since
1167 a memory already has a bitmap. all this is slightly
1168 inefficient as we could take an XImage directly from
1169 an X window, but we'd then also have to care that
1170 the window is not outside the screen (in which case
1171 we'd get a BadMatch or what not).
1172 Is a double XGetImage and combined XGetPixel and
1173 XPutPixel really faster? I'm not sure. look at wxXt
1174 for a different implementation of the same problem. */
1176 wxBitmap
bitmap( width
, height
);
1178 /* copy including child window contents */
1179 gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS
);
1180 gdk_window_copy_area( bitmap
.GetPixmap(), m_penGC
, 0, 0,
1182 xsrc
, ysrc
, width
, height
);
1183 gdk_gc_set_subwindow( m_penGC
, GDK_CLIP_BY_CHILDREN
);
1186 wxImage
image( bitmap
);
1187 image
= image
.Scale( ww
, hh
);
1189 /* convert to bitmap */
1190 bitmap
= image
.ConvertToBitmap();
1192 /* draw scaled bitmap */
1193 gdk_draw_pixmap( m_window
, m_penGC
, bitmap
.GetPixmap(), 0, 0, xx
, yy
, -1, -1 );
1198 /* No scaling and not a memory dc with a mask either */
1200 /* copy including child window contents */
1201 gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS
);
1202 gdk_window_copy_area( m_window
, m_penGC
, xx
, yy
,
1204 xsrc
, ysrc
, width
, height
);
1205 gdk_gc_set_subwindow( m_penGC
, GDK_CLIP_BY_CHILDREN
);
1209 SetLogicalFunction( old_logical_func
);
1216 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1218 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1220 if (!m_window
) return;
1222 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1224 wxCHECK_RET( xfont
, wxT("invalid font") );
1230 wxCoord width
= gdk_string_width( font
, text
.mbc_str() );
1231 wxCoord height
= font
->ascent
+ font
->descent
;
1233 if ( m_backgroundMode
== wxSOLID
)
1235 gdk_gc_set_foreground( m_textGC
, m_textBackgroundColour
.GetColor() );
1236 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, x
, y
, width
, height
);
1237 gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() );
1241 XSetFont( (Display
*) m_display
, (GC
) m_textGC
, xfont
->fid
);
1242 if ((xfont
->min_byte1
== 0) && (xfont
->max_byte1
== 0))
1244 XDrawString( (Display
*) m_display
, (Window
) m_window
,
1245 (GC
) m_textGC
, x
, y
, text
.c_str(), text
.Len() );
1249 if (m_font
.GetUnderlined())
1251 wxCoord ul_y
= y
+ font
->ascent
;
1252 if (font
->descent
> 0) ul_y
++;
1253 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
1256 width
= wxCoord(width
/ m_scaleX
);
1257 height
= wxCoord(height
/ m_scaleY
);
1259 CalcBoundingBox (x
+ width
, y
+ height
);
1260 CalcBoundingBox (x
, y
);
1264 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
, double angle
)
1269 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1270 wxCoord
*descent
, wxCoord
*externalLeading
,
1271 wxFont
*font
) const
1273 wxCHECK_RET( Ok(), "invalid dc" );
1275 wxFont fontToUse
= m_font
;
1276 if (font
) fontToUse
= *font
;
1278 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
1280 XFontStruct
*xfont
= (XFontStruct
*) fontToUse
.GetFontStruct( m_scaleY
, m_display
);
1282 wxCHECK_RET( xfont
, wxT("invalid font") );
1284 int direction
, ascent
, descent2
;
1285 XCharStruct overall
;
1287 XTextExtents( xfont
, string
.c_str(), string
.Len(), &direction
,
1288 &ascent
, &descent2
, &overall
);
1291 *width
= (wxCoord
)( overall
.width
/ m_scaleX
);
1293 *height
= (wxCoord
)((ascent
+ descent2
) / m_scaleY
);
1295 *descent
= (wxCoord
)(descent2
/ m_scaleY
);
1296 if (externalLeading
)
1297 *externalLeading
= 0; // ??
1300 wxCoord
wxWindowDC::GetCharWidth() const
1302 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1304 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1306 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1308 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1310 int direction
, ascent
, descent
;
1311 XCharStruct overall
;
1313 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1315 return (wxCoord
)(overall
.width
/ m_scaleX
);
1318 wxCoord
wxWindowDC::GetCharHeight() const
1320 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1322 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1324 XFontStruct
*xfont
= (XFontStruct
*) m_font
.GetFontStruct( m_scaleY
, m_display
);
1326 wxCHECK_MSG( xfont
, 0, wxT("invalid font") );
1328 int direction
, ascent
, descent
;
1329 XCharStruct overall
;
1331 XTextExtents( xfont
, "H", 1, &direction
, &ascent
, &descent
, &overall
);
1333 return (wxCoord
)((ascent
+descent
) / m_scaleY
);
1336 void wxWindowDC::Clear()
1338 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1340 if (!m_window
) return;
1342 /* - we either are a memory dc or have a window as the
1343 owner. anything else shouldn't happen.
1344 - we don't use gdk_window_clear() as we don't set
1345 the window's background colour anymore. it is too
1346 much pain to keep the DC's and the window's back-
1347 ground colour in synch. */
1352 m_owner
->GetSize( &width
, &height
);
1353 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1360 GetSize( &width
, &height
);
1361 XFillRectangle( (Display
*) m_display
, (Window
) m_window
, (GC
) m_bgGC
, 0, 0, width
, height
);
1366 void wxWindowDC::SetFont( const wxFont
&font
)
1368 wxCHECK_RET( Ok(), "invalid dc" );
1373 void wxWindowDC::SetPen( const wxPen
&pen
)
1375 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1377 if (m_pen
== pen
) return;
1381 if (!m_pen
.Ok()) return;
1383 if (!m_window
) return;
1385 int width
= m_pen
.GetWidth();
1388 // CMB: if width is non-zero scale it with the dc
1393 // X doesn't allow different width in x and y and so we take
1396 ( fabs((double) XLOG2DEVREL(width
)) +
1397 fabs((double) YLOG2DEVREL(width
)) ) / 2.0;
1401 static const wxX11Dash dotted
[] = {1, 1};
1402 static const wxX11Dash short_dashed
[] = {2, 2};
1403 static const wxX11Dash long_dashed
[] = {2, 4};
1404 static const wxX11Dash dotted_dashed
[] = {3, 3, 1, 3};
1406 // We express dash pattern in pen width unit, so we are
1407 // independent of zoom factor and so on...
1409 const wxX11Dash
*req_dash
;
1411 int lineStyle
= LineSolid
;
1412 switch (m_pen
.GetStyle())
1416 lineStyle
= LineOnOffDash
;
1417 req_nb_dash
= m_pen
.GetDashCount();
1418 req_dash
= (wxX11Dash
*)m_pen
.GetDash();
1423 lineStyle
= LineOnOffDash
;
1430 lineStyle
= LineOnOffDash
;
1432 req_dash
= long_dashed
;
1437 lineStyle
= LineOnOffDash
;
1439 req_dash
= short_dashed
;
1444 // lineStyle = LineDoubleDash;
1445 lineStyle
= LineOnOffDash
;
1447 req_dash
= dotted_dashed
;
1452 case wxSTIPPLE_MASK_OPAQUE
:
1457 lineStyle
= LineSolid
;
1458 req_dash
= (wxX11Dash
*)NULL
;
1464 int capStyle
= CapRound
;
1465 switch (m_pen
.GetCap())
1467 case wxCAP_PROJECTING
: { capStyle
= CapProjecting
; break; }
1468 case wxCAP_BUTT
: { capStyle
= CapButt
; break; }
1475 capStyle
= CapNotLast
;
1479 capStyle
= CapRound
;
1485 int joinStyle
= JoinRound
;
1486 switch (m_pen
.GetJoin())
1488 case wxJOIN_BEVEL
: { joinStyle
= JoinBevel
; break; }
1489 case wxJOIN_MITER
: { joinStyle
= JoinMiter
; break; }
1491 default: { joinStyle
= JoinRound
; break; }
1494 XSetLineAttributes( (Display
*) m_display
, (GC
) m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
1496 m_pen
.GetColour().CalcPixel( m_cmap
);
1497 XSetForeground( (Display
*) m_display
, (GC
) m_penGC
, m_pen
.GetColour().GetPixel() );
1500 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1502 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1504 if (m_brush
== brush
) return;
1508 if (!m_brush
.Ok()) return;
1510 if (!m_window
) return;
1512 m_brush
.GetColour().CalcPixel( m_cmap
);
1513 XSetForeground( (Display
*) m_display
, (GC
) m_brushGC
, m_brush
.GetColour().GetPixel() );
1515 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillSolid
);
1517 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
1519 if (m_brush
.GetStipple()->GetPixmap())
1521 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillTiled
);
1522 XSetTile( (Display
*) m_display
, (GC
) m_brushGC
, (Pixmap
) m_brush
.GetStipple()->GetPixmap() );
1526 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1527 // XSetStipple( (Display*) m_display, (GC) m_brushGC, (Pixmap) m_brush.GetStipple()->GetBitmap() );
1531 if ((m_brush
.GetStyle() == wxSTIPPLE_MASK_OPAQUE
) && (m_brush
.GetStipple()->GetMask()))
1533 XSetFillStyle( (Display
*) m_display
, (GC
) m_textGC
, FillOpaqueStippled
);
1534 // XSetStipple( (Display*) m_display, (GC) m_textGC, (Pixmap) m_brush.GetStipple()->GetMask()->GetBitmap() );
1537 if (IS_HATCH(m_brush
.GetStyle()))
1539 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
, FillStippled
);
1540 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
1541 XSetStipple( (Display
*) m_display
, (GC
) m_brushGC
, hatches
[num
] );
1545 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1547 /* CMB 21/7/98: Added SetBackground. Sets background brush
1548 * for Clear() and bg colour for shapes filled with cross-hatch brush */
1550 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1552 if (m_backgroundBrush
== brush
) return;
1554 m_backgroundBrush
= brush
;
1556 if (!m_backgroundBrush
.Ok()) return;
1558 if (!m_window
) return;
1560 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1561 XSetBackground( (Display
*) m_display
, (GC
) m_brushGC
, m_backgroundBrush
.GetColour().GetPixel() );
1562 XSetBackground( (Display
*) m_display
, (GC
) m_penGC
, m_backgroundBrush
.GetColour().GetPixel() );
1563 XSetBackground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1564 XSetForeground( (Display
*) m_display
, (GC
) m_bgGC
, m_backgroundBrush
.GetColour().GetPixel() );
1566 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillSolid
);
1568 if ((m_backgroundBrush
.GetStyle() == wxSTIPPLE
) && (m_backgroundBrush
.GetStipple()->Ok()))
1570 if (m_backgroundBrush
.GetStipple()->GetPixmap())
1572 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillTiled
);
1573 XSetTile( (Display
*) m_display
, (GC
) m_bgGC
, (Pixmap
) m_backgroundBrush
.GetStipple()->GetPixmap() );
1577 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1578 // XSetStipple( (Display*) m_display, (GC) m_bgGC, (Pixmap) m_backgroundBrush.GetStipple()->GetBitmap() );
1582 if (IS_HATCH(m_backgroundBrush
.GetStyle()))
1584 XSetFillStyle( (Display
*) m_display
, (GC
) m_bgGC
, FillStippled
);
1585 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
1586 XSetStipple( (Display
*) m_display
, (GC
) m_bgGC
, hatches
[num
] );
1590 void wxWindowDC::SetLogicalFunction( int function
)
1592 wxCHECK_RET( Ok(), "invalid dc" );
1596 if (m_logicalFunction
== function
)
1599 // VZ: shouldn't this be a CHECK?
1606 x_function
= GXclear
;
1612 x_function
= GXinvert
;
1615 x_function
= GXorReverse
;
1618 x_function
= GXandReverse
;
1627 x_function
= GXandInverted
;
1630 x_function
= GXnoop
;
1636 x_function
= GXequiv
;
1639 x_function
= GXcopyInverted
;
1642 x_function
= GXorInverted
;
1645 x_function
= GXnand
;
1652 x_function
= GXcopy
;
1656 XSetFunction( (Display
*) m_display
, (GC
) m_penGC
, x_function
);
1657 XSetFunction( (Display
*) m_display
, (GC
) m_brushGC
, x_function
);
1659 // to stay compatible with wxMSW, we don't apply ROPs to the text
1660 // operations (i.e. DrawText/DrawRotatedText).
1661 // True, but mono-bitmaps use the m_textGC and they use ROPs as well.
1662 XSetFunction( (Display
*) m_display
, (GC
) m_textGC
, x_function
);
1664 m_logicalFunction
= function
;
1667 void wxWindowDC::SetTextForeground( const wxColour
&col
)
1669 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1671 // don't set m_textForegroundColour to an invalid colour as we'd crash
1672 // later then (we use m_textForegroundColour.GetColor() without checking
1674 if ( !col
.Ok() || (m_textForegroundColour
== col
) )
1677 m_textForegroundColour
= col
;
1681 m_textForegroundColour
.CalcPixel( m_cmap
);
1682 XSetForeground( (Display
*) m_display
, (GC
) m_textGC
, m_textForegroundColour
.GetPixel() );
1686 void wxWindowDC::SetTextBackground( const wxColour
&col
)
1688 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1691 if ( !col
.Ok() || (m_textBackgroundColour
== col
) )
1694 m_textBackgroundColour
= col
;
1698 m_textBackgroundColour
.CalcPixel( m_cmap
);
1699 XSetBackground( (Display
*) m_display
, (GC
) m_textGC
, m_textBackgroundColour
.GetPixel() );
1703 void wxWindowDC::SetBackgroundMode( int mode
)
1705 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1707 m_backgroundMode
= mode
;
1709 if (!m_window
) return;
1711 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
1712 // transparent/solid background mode
1714 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
1716 XSetFillStyle( (Display
*) m_display
, (GC
) m_brushGC
,
1717 (m_backgroundMode
== wxTRANSPARENT
) ? FillStippled
: FillOpaqueStippled
);
1721 void wxWindowDC::SetPalette( const wxPalette
& palette
)
1727 /* Use GetXColormap */
1728 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1729 (Colormap
) palette
.GetXColormap());
1731 /* Use wxGetMainColormap */
1732 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1733 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
1738 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
1740 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1742 if (!m_window
) return;
1745 rect
.x
= XLOG2DEV(x
);
1746 rect
.y
= YLOG2DEV(y
);
1747 rect
.width
= XLOG2DEVREL(width
);
1748 rect
.height
= YLOG2DEVREL(height
);
1750 if (!m_currentClippingRegion
.IsNull())
1751 m_currentClippingRegion
.Intersect( rect
);
1753 m_currentClippingRegion
.Union( rect
);
1755 #if USE_PAINT_REGION
1756 if (!m_paintClippingRegion
.IsNull())
1757 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
1760 wxCoord xx
, yy
, ww
, hh
;
1761 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
1762 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
1764 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1765 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1766 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1767 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1770 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
1772 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1776 DestroyClippingRegion();
1780 if (!m_window
) return;
1782 if (!m_currentClippingRegion
.IsNull())
1783 m_currentClippingRegion
.Intersect( region
);
1785 m_currentClippingRegion
.Union( region
);
1787 #if USE_PAINT_REGION
1788 if (!m_paintClippingRegion
.IsNull())
1789 m_currentClippingRegion
.Intersect( m_paintClippingRegion
);
1792 wxCoord xx
, yy
, ww
, hh
;
1793 m_currentClippingRegion
.GetBox( xx
, yy
, ww
, hh
);
1794 wxDC::DoSetClippingRegion( xx
, yy
, ww
, hh
);
1796 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1797 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1798 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1799 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1802 void wxWindowDC::DestroyClippingRegion()
1804 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1806 wxDC::DestroyClippingRegion();
1808 m_currentClippingRegion
.Clear();
1810 #if USE_PAINT_REGION
1811 if (!m_paintClippingRegion
.IsEmpty())
1812 m_currentClippingRegion
.Union( m_paintClippingRegion
);
1815 if (!m_window
) return;
1817 if (m_currentClippingRegion
.IsEmpty())
1819 XSetClipMask( (Display
*) m_display
, (GC
) m_penGC
, None
);
1820 XSetClipMask( (Display
*) m_display
, (GC
) m_brushGC
, None
);
1821 XSetClipMask( (Display
*) m_display
, (GC
) m_textGC
, None
);
1822 XSetClipMask( (Display
*) m_display
, (GC
) m_bgGC
, None
);
1826 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1827 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1828 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1829 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, (Region
) m_currentClippingRegion
.GetX11Region() );
1833 void wxWindowDC::Destroy()
1835 if (m_penGC
) wxFreePoolGC( (GC
) m_penGC
);
1837 if (m_brushGC
) wxFreePoolGC( (GC
) m_brushGC
);
1839 if (m_textGC
) wxFreePoolGC( (GC
) m_textGC
);
1841 if (m_bgGC
) wxFreePoolGC( (GC
) m_bgGC
);
1845 void wxWindowDC::ComputeScaleAndOrigin()
1847 /* CMB: copy scale to see if it changes */
1848 double origScaleX
= m_scaleX
;
1849 double origScaleY
= m_scaleY
;
1851 wxDC::ComputeScaleAndOrigin();
1853 /* CMB: if scale has changed call SetPen to recalulate the line width */
1854 if ((m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
) &&
1857 /* this is a bit artificial, but we need to force wxDC to think
1858 the pen has changed */
1865 wxSize
wxWindowDC::GetPPI() const
1867 return wxSize(100, 100);
1870 int wxWindowDC::GetDepth() const
1872 wxFAIL_MSG(wxT("not implemented"));
1877 // ----------------------------------------------------------------------------
1879 // ----------------------------------------------------------------------------
1881 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxClientDC
)
1883 wxPaintDC::wxPaintDC(wxWindow
* win
)
1886 #if USE_PAINT_REGION
1887 if (!win
->GetClipPaintRegion())
1890 m_paintClippingRegion
= win
->GetUpdateRegion();
1891 Region region
= (Region
) m_paintClippingRegion
.GetX11Region();
1894 m_paintClippingRegion
= win
->GetUpdateRegion();
1895 Region region2
= (Region
) m_paintClippingRegion
.GetX11Region();
1898 m_currentClippingRegion
.Union( m_paintClippingRegion
);
1900 XSetRegion( (Display
*) m_display
, (GC
) m_penGC
, region2
);
1901 XSetRegion( (Display
*) m_display
, (GC
) m_brushGC
, region2
);
1902 XSetRegion( (Display
*) m_display
, (GC
) m_textGC
, region2
);
1903 XSetRegion( (Display
*) m_display
, (GC
) m_bgGC
, region2
);
1906 #endif // USE_PAINT_REGION
1909 //-----------------------------------------------------------------------------
1911 //-----------------------------------------------------------------------------
1913 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
1915 wxClientDC::wxClientDC( wxWindow
*win
)
1918 wxCHECK_RET( win
, _T("NULL window in wxClientDC::wxClientDC") );
1921 void wxClientDC::DoGetSize(int *width
, int *height
) const
1923 wxCHECK_RET( m_owner
, _T("GetSize() doesn't work without window") );
1925 m_owner
->GetClientSize( width
, height
);
1928 // ----------------------------------------------------------------------------
1930 // ----------------------------------------------------------------------------
1932 class wxDCModule
: public wxModule
1939 DECLARE_DYNAMIC_CLASS(wxDCModule
)
1942 IMPLEMENT_DYNAMIC_CLASS(wxDCModule
, wxModule
)
1944 bool wxDCModule::OnInit()
1950 void wxDCModule::OnExit()