1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/motif/dcclient.cpp
3 // Purpose: wxClientDCImpl class
4 // Author: Julian Smart
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
12 About pens, brushes, and the m_autoSetting flag:
14 Under X, pens and brushes control some of the same X drawing
15 parameters. Therefore, it is impossible to independently maintain
16 the current pen and the current brush. Also, some settings depend on
17 the current logical function. The m_currentFill, etc. instance
18 variables remember state across the brush and pen.
20 Since pens are used more than brushes, the m_autoSetting flag is used to
21 indicate that a brush was recently used, and SetPen must be called to
22 reinstall the current pen's parameters. If m_autoSetting includes 0x2, then the
23 pens color may need to be set based on XOR.
25 There is, unfortunately, some confusion between setting the current pen/brush
26 and actually installing the brush/pen parameters. Both functionalies are
27 perform by SetPen and SetBrush. C'est la vie.
30 // ============================================================================
32 // ============================================================================
34 // ----------------------------------------------------------------------------
36 // ----------------------------------------------------------------------------
38 // For compilers that support precompilation, includes "wx.h".
39 #include "wx/wxprec.h"
44 #include "wx/window.h"
45 #include "wx/dcmemory.h"
48 #include "wx/dcclient.h"
52 #pragma message disable nosimpint
56 #pragma message enable nosimpint
59 #include "wx/motif/private.h"
60 #include "wx/motif/dcclient.h"
63 #include <float.h> // for M_PI
73 static Pixmap bdiag
, cdiag
, fdiag
, cross
, horiz
, verti
;
75 // ----------------------------------------------------------------------------
77 // ----------------------------------------------------------------------------
79 // Fudge factor (VZ: what??)
82 // ----------------------------------------------------------------------------
84 // ----------------------------------------------------------------------------
86 IMPLEMENT_ABSTRACT_CLASS(wxClientDCImpl
, wxWindowDCImpl
)
87 IMPLEMENT_ABSTRACT_CLASS(wxPaintDCImpl
, wxWindowDCImpl
)
88 IMPLEMENT_ABSTRACT_CLASS(wxWindowDCImpl
, wxMotifDCImpl
)
90 #define IS_HATCH(s) ((s)>=wxFIRST_HATCH && (s)<=wxLAST_HATCH)
92 // FIXME: left over after removal of wxDC::GetOptimization()
93 #define GET_OPTIMIZATION false
95 // ----------------------------------------------------------------------------
97 // ----------------------------------------------------------------------------
99 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
100 Drawable src
, Drawable dest
,
103 unsigned int w
, unsigned int h
,
104 int destx
, int desty
,
105 bool more
, XImage
**cache
);
107 // ============================================================================
109 // ============================================================================
112 * compare two doubles and return the larger rounded
115 static int roundmax(double a
, double b
)
117 return (int)((a
> b
? a
: b
) + 0.5);
121 * compare two doubles and return the smaller rounded
124 static int roundmin(double a
, double b
)
126 return (int)((a
< b
? a
: b
) - 0.5);
130 // ----------------------------------------------------------------------------
132 // ----------------------------------------------------------------------------
134 void wxWindowDCImpl::Init()
137 m_gcBacking
= (WXGC
) 0;
139 m_backgroundPixel
= -1;
140 m_currentPenWidth
= 1;
141 m_currentPenJoin
= -1;
142 m_currentPenDashCount
= -1;
143 m_currentPenDash
= NULL
;
146 m_colour
= wxColourDisplay();
148 m_pixmap
= (WXPixmap
) 0;
151 m_clipRegion
= (WXRegion
) 0;
154 wxWindowDCImpl::wxWindowDCImpl(wxDC
*owner
)
155 : wxMotifDCImpl(owner
)
160 wxWindowDCImpl::wxWindowDCImpl(wxDC
*owner
, wxWindow
*window
)
161 : wxMotifDCImpl(owner
)
163 wxASSERT_MSG( (window
!= NULL
), "You must pass a valid wxWindow to wxWindowDCImpl/wxClientDCImpl/wxPaintDCImpl constructor." );
168 m_font
= window
->GetFont();
171 m_display
= window
->GetXDisplay();
172 m_pixmap
= window
->GetXWindow();
173 Display
* display
= (Display
*) m_display
;
175 XSetWindowColormap (display
, (Pixmap
) m_pixmap
, (Colormap
) wxTheApp
->GetMainColormap(m_display
));
178 gcvalues
.foreground
= BlackPixel (display
, DefaultScreen (display
));
179 gcvalues
.background
= WhitePixel (display
, DefaultScreen (display
));
180 gcvalues
.graphics_exposures
= False
;
181 gcvalues
.subwindow_mode
= IncludeInferiors
;
182 gcvalues
.line_width
= 1;
183 #if !wxMOTIF_NEW_FONT_HANDLING
184 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
185 gcvalues
.font
= ((XFontStruct
*)pFontStruct
)->fid
;
187 m_gc
= (WXGC
) XCreateGC (display
, RootWindow (display
, DefaultScreen (display
)),
188 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
189 #if !wxMOTIF_NEW_FONT_HANDLING
195 if (m_window
->GetBackingPixmap())
197 m_gcBacking
= (WXGC
) XCreateGC (display
, RootWindow (display
,
198 DefaultScreen (display
)),
199 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
203 m_backgroundPixel
= gcvalues
.background
;
205 SetBackground(wxBrush(m_window
->GetBackgroundColour(), wxSOLID
));
208 wxWindowDCImpl::~wxWindowDCImpl()
211 XFreeGC ((Display
*) m_display
, (GC
) m_gc
);
215 XFreeGC ((Display
*) m_display
, (GC
) m_gcBacking
);
216 m_gcBacking
= (WXGC
) 0;
219 XDestroyRegion ((Region
) m_clipRegion
);
220 m_clipRegion
= (WXRegion
) 0;
223 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
224 const wxColour
& col
, wxFloodFillStyle style
);
226 bool wxWindowDCImpl::DoFloodFill(wxCoord x
, wxCoord y
,
227 const wxColour
& col
, wxFloodFillStyle style
)
229 return wxDoFloodFill(GetOwner(), x
, y
, col
, style
);
232 bool wxWindowDCImpl::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
234 // Generic (and therefore rather inefficient) method.
235 // Could be improved.
237 wxBitmap
bitmap(1, 1);
238 memdc
.SelectObject(bitmap
);
239 memdc
.Blit(0, 0, 1, 1, GetOwner(), x1
, y1
);
240 memdc
.SelectObject(wxNullBitmap
);
241 wxImage image
= bitmap
.ConvertToImage();
242 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
246 void wxWindowDCImpl::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
248 wxCHECK_RET( IsOk(), "invalid dc" );
250 int x1d
, y1d
, x2d
, y2d
;
260 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x1d
, y1d
, x2d
, y2d
);
262 if (m_window
&& m_window
->GetBackingPixmap())
263 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
264 XLOG2DEV_2(x1
), YLOG2DEV_2(y1
),
265 XLOG2DEV_2(x2
), YLOG2DEV_2(y2
));
267 CalcBoundingBox(x1
, y1
);
268 CalcBoundingBox(x2
, y2
);
271 void wxWindowDCImpl::DoCrossHair( wxCoord x
, wxCoord y
)
273 wxCHECK_RET( IsOk(), "invalid dc" );
278 int xx
= XLOG2DEV (x
);
279 int yy
= YLOG2DEV (y
);
281 wxDisplaySize (&ww
, &hh
);
282 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, yy
,
284 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xx
, 0,
287 if (m_window
&& m_window
->GetBackingPixmap())
291 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
294 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
300 void wxWindowDCImpl::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
302 wxCHECK_RET( IsOk(), "invalid dc" );
304 int xx1
= XLOG2DEV (x1
);
305 int yy1
= YLOG2DEV (y1
);
306 int xx2
= XLOG2DEV (x2
);
307 int yy2
= YLOG2DEV (y2
);
308 int xxc
= XLOG2DEV (xc
);
309 int yyc
= YLOG2DEV (yc
);
310 int xxc_2
= XLOG2DEV_2 (xc
);
311 int yyc_2
= YLOG2DEV_2 (yc
);
313 wxCoord dx
= xx1
- xxc
;
314 wxCoord dy
= yy1
- yyc
;
315 double radius
= sqrt ((double)(dx
* dx
+ dy
* dy
));
316 wxCoord r
= (wxCoord
) radius
;
318 double radius1
, radius2
;
320 if (xx1
== xx2
&& yy1
== yy2
)
325 else if (radius
== 0.0)
326 radius1
= radius2
= 0.0;
335 radius1
= -atan2 ((double) (yy1
- yyc
), (double) (xx1
- xxc
)) * 360.0 / (2 * M_PI
);
343 radius2
= -atan2 ((double) (yy2
- yyc
), (double) (xx2
- xxc
)) * 360.0 / (2 * M_PI
);
347 int alpha1
= (int) radius1
;
348 int alpha2
= (int) (radius2
- radius1
);
351 while (alpha2
> 360 * 64)
354 if (m_brush
.IsOk() && m_brush
.GetStyle () != wxTRANSPARENT
)
357 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) (GC
) m_gc
,
358 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
360 if (m_window
&& m_window
->GetBackingPixmap())
361 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
362 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
366 if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
)
370 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
371 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
373 if (m_window
&& m_window
->GetBackingPixmap())
374 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
375 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
377 CalcBoundingBox (x1
, y1
);
378 CalcBoundingBox (x2
, y2
);
381 void wxWindowDCImpl::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
383 wxCHECK_RET( IsOk(), "invalid dc" );
389 wd
= XLOG2DEVREL(width
);
390 hd
= YLOG2DEVREL(height
);
392 if (sa
>=360 || sa
<=-360) sa
=sa
-int(sa
/360)*360;
393 if (ea
>=360 || ea
<=-360) ea
=ea
-int(ea
/360)*360;
394 int start
= int(sa
*64);
395 int end
= int(ea
*64);
396 if (start
<0) start
+=360*64;
397 if (end
<0) end
+=360*64;
398 if (end
>start
) end
-=start
;
399 else end
+=360*64-start
;
401 if (m_brush
.IsOk() && m_brush
.GetStyle () != wxTRANSPARENT
)
403 m_autoSetting
= true; // must be reset
406 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
, end
);
408 if (m_window
&& m_window
->GetBackingPixmap())
409 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
410 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
413 if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
)
417 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
,end
);
418 if (m_window
&& m_window
->GetBackingPixmap())
419 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
420 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
422 CalcBoundingBox (x
, y
);
423 CalcBoundingBox (x
+ width
, y
+ height
);
426 void wxWindowDCImpl::DoDrawPoint( wxCoord x
, wxCoord y
)
428 wxCHECK_RET( IsOk(), "invalid dc" );
430 if (m_pen
.IsOk() && m_autoSetting
)
433 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
));
434 if (m_window
&& m_window
->GetBackingPixmap())
435 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, XLOG2DEV_2 (x
), YLOG2DEV_2 (y
));
437 CalcBoundingBox (x
, y
);
440 void wxWindowDCImpl::DoDrawLines( int n
, const wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
442 wxCHECK_RET( IsOk(), "invalid dc" );
444 if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
)
449 XPoint
*xpoints
= new XPoint
[n
];
452 for (i
= 0; i
< n
; i
++)
454 xpoints
[i
].x
= (short)XLOG2DEV (points
[i
].x
+ xoffset
);
455 xpoints
[i
].y
= (short)YLOG2DEV (points
[i
].y
+ yoffset
);
457 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints
, n
, 0);
459 if (m_window
&& m_window
->GetBackingPixmap())
461 for (i
= 0; i
< n
; i
++)
463 xpoints
[i
].x
= (short)XLOG2DEV_2 (points
[i
].x
+ xoffset
);
464 xpoints
[i
].y
= (short)YLOG2DEV_2 (points
[i
].y
+ yoffset
);
466 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints
, n
, 0);
472 void wxWindowDCImpl::DoDrawPolygon( int n
, const wxPoint points
[],
473 wxCoord xoffset
, wxCoord yoffset
, wxPolygonFillMode fillStyle
)
475 wxCHECK_RET( IsOk(), "invalid dc" );
477 XPoint
*xpoints1
= new XPoint
[n
+ 1];
478 XPoint
*xpoints2
= new XPoint
[n
+ 1];
480 for (i
= 0; i
< n
; i
++)
482 xpoints1
[i
].x
= (short)XLOG2DEV (points
[i
].x
+ xoffset
);
483 xpoints1
[i
].y
= (short)YLOG2DEV (points
[i
].y
+ yoffset
);
484 xpoints2
[i
].x
= (short)XLOG2DEV_2 (points
[i
].x
+ xoffset
);
485 xpoints2
[i
].y
= (short)YLOG2DEV_2 (points
[i
].y
+ yoffset
);
486 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
489 // Close figure for XDrawLines (not needed for XFillPolygon)
490 xpoints1
[i
].x
= xpoints1
[0].x
;
491 xpoints1
[i
].y
= xpoints1
[0].y
;
492 xpoints2
[i
].x
= xpoints2
[0].x
;
493 xpoints2
[i
].y
= xpoints2
[0].y
;
495 if (m_brush
.IsOk() && m_brush
.GetStyle () != wxTRANSPARENT
)
498 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
499 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
, Complex
, 0);
500 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, EvenOddRule
); // default mode
501 if (m_window
&& m_window
->GetBackingPixmap())
503 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
,
504 fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
505 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
, Complex
, 0);
506 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
, EvenOddRule
); // default mode
510 if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
)
514 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
+ 1, 0);
516 if (m_window
&& m_window
->GetBackingPixmap())
517 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
+ 1, 0);
524 void wxWindowDCImpl::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
526 wxCHECK_RET( IsOk(), "invalid dc" );
528 int xd
, yd
, wfd
, hfd
, wd
, hd
;
532 wfd
= XLOG2DEVREL(width
);
534 hfd
= YLOG2DEVREL(height
);
537 if (wfd
== 0 || hfd
== 0) return;
538 if (wd
< 0) { wd
= - wd
; xd
= xd
- wd
; }
539 if (hd
< 0) { hd
= - hd
; yd
= yd
- hd
; }
541 if (m_brush
.IsOk() && m_brush
.GetStyle () != wxTRANSPARENT
)
544 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wfd
, hfd
);
546 if (m_window
&& m_window
->GetBackingPixmap())
547 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
548 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
552 if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
)
556 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
);
558 if (m_window
&& m_window
->GetBackingPixmap())
559 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
560 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
563 CalcBoundingBox (x
, y
);
564 CalcBoundingBox (x
+ width
, y
+ height
);
567 void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
569 wxCHECK_RET( IsOk(), "invalid dc" );
571 // If radius is negative, it's a proportion of the smaller dimension.
573 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
575 int xd
= XLOG2DEV (x
);
576 int yd
= YLOG2DEV (y
);
577 int rd
= XLOG2DEVREL ((long) radius
);
578 int wd
= XLOG2DEVREL (width
) - WX_GC_CF
;
579 int hd
= YLOG2DEVREL (height
) - WX_GC_CF
;
584 // If radius is zero use DrawRectangle() instead to avoid
585 // X drawing errors with small radii
588 DoDrawRectangle( x
, y
, width
, height
);
592 // Draw nothing if transformed w or h is 0
593 if (wd
== 0 || hd
== 0) return;
595 // CMB: adjust size if outline is drawn otherwise the result is
596 // 1 pixel too wide and high
597 if (m_pen
.GetStyle() != wxTRANSPARENT
)
603 // CMB: ensure dd is not larger than rectangle otherwise we
604 // get an hour glass shape
605 if (rw_d
> wd
) rw_d
= wd
;
606 if (rw_d
> hd
) rw_d
= hd
;
609 // For backing pixmap
610 int xd2
= XLOG2DEV_2 (x
);
611 int yd2
= YLOG2DEV_2 (y
);
612 int rd2
= XLOG2DEVREL ((long) radius
);
613 int wd2
= XLOG2DEVREL (width
) ;
614 int hd2
= YLOG2DEVREL (height
) ;
619 if (m_brush
.IsOk() && m_brush
.GetStyle () != wxTRANSPARENT
)
623 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
625 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
628 // Arcs start from 3 o'clock, positive angles anticlockwise
630 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
631 rw_d
, rh_d
, 90 * 64, 90 * 64);
633 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
634 // rw_d, rh_d, 0, 90 * 64);
635 rw_d
, rh_d
, 0, 91 * 64);
637 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
639 // rw_d, rh_d, 270 * 64, 90 * 64);
640 rw_d
, rh_d
, 269 * 64, 92 * 64);
642 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
643 rw_d
, rh_d
, 180 * 64, 90 * 64);
645 if (m_window
&& m_window
->GetBackingPixmap())
647 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
648 xd2
+ rd2
, yd2
, wd2
- rw_d2
, hd2
);
649 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
650 xd2
, yd2
+ rd2
, wd2
, hd2
- rh_d2
);
652 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
653 xd2
, yd2
, rw_d2
, rh_d2
, 90 * 64, 90 * 64);
654 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
655 xd2
+ wd2
- rw_d2
, yd2
,
656 // rw_d2, rh_d2, 0, 90 * 64);
657 rw_d2
, rh_d2
, 0, 91 * 64);
658 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
661 // rw_d2, rh_d2, 270 * 64, 90 * 64);
662 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
663 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
664 xd2
, yd2
+ hd2
- rh_d2
,
665 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
669 if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
)
672 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
673 xd
+ wd
- rd
+ 1, yd
);
674 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
+ hd
,
675 xd
+ wd
- rd
, yd
+ hd
);
677 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
679 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
, yd
+ rd
,
680 xd
+ wd
, yd
+ hd
- rd
+ 1);
681 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
682 rw_d
, rh_d
, 90 * 64, 90 * 64);
683 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
684 // rw_d, rh_d, 0, 90 * 64);
685 rw_d
, rh_d
, 0, 91 * 64);
686 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
688 rw_d
, rh_d
, 269 * 64, 92 * 64);
689 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
690 rw_d
, rh_d
, 180 * 64, 90 * 64);
692 if (m_window
&& m_window
->GetBackingPixmap())
694 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
696 xd2
+ wd2
- rd2
+ 1, yd2
);
697 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
698 xd2
+ rd2
, yd2
+ hd2
,
699 xd2
+ wd2
- rd2
, yd2
+ hd2
);
701 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
703 xd2
, yd2
+ hd2
- rd2
);
704 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
705 xd2
+ wd2
, yd2
+ rd2
,
706 xd2
+ wd2
, yd2
+ hd2
- rd2
+ 1);
707 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
709 rw_d2
, rh_d2
, 90 * 64, 90 * 64);
710 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
711 xd2
+ wd2
- rw_d2
, yd2
,
712 // rw_d2, rh_d2, 0, 90 * 64);
713 rw_d2
, rh_d2
, 0, 91 * 64);
714 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
717 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
718 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
719 xd2
, yd2
+ hd2
- rh_d2
,
720 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
723 CalcBoundingBox (x
, y
);
724 CalcBoundingBox (x
+ width
, y
+ height
);
727 void wxWindowDCImpl::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
729 wxCHECK_RET( IsOk(), "invalid dc" );
731 // Check for negative width and height
744 static const int angle
= 23040;
750 wd
= XLOG2DEVREL(width
) ;
751 hd
= YLOG2DEVREL(height
) ;
753 if (m_brush
.IsOk() && m_brush
.GetStyle () != wxTRANSPARENT
)
756 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
757 if (m_window
&& m_window
->GetBackingPixmap())
758 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
759 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
760 XLOG2DEVREL (width
) - WX_GC_CF
,
761 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
764 if (m_pen
.IsOk() && m_pen
.GetStyle () != wxTRANSPARENT
)
768 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
769 if (m_window
&& m_window
->GetBackingPixmap())
770 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
771 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
772 XLOG2DEVREL (width
) - WX_GC_CF
,
773 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
775 CalcBoundingBox (x
, y
);
776 CalcBoundingBox (x
+ width
, y
+ height
);
780 bool wxWindowDCImpl::CanDrawBitmap() const
782 wxCHECK_MSG( IsOk(), false, "invalid dc" );
787 // TODO: use scaled Blit e.g. as per John Price's implementation
788 // in Contrib/Utilities
789 bool wxWindowDCImpl::DoBlit( wxCoord xdest
, wxCoord ydest
,
790 wxCoord width
, wxCoord height
,
791 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
,
792 wxRasterOperationMode rop
, bool useMask
,
793 wxCoord xsrcMask
, wxCoord ysrcMask
)
795 wxCHECK_MSG( IsOk(), false, "invalid dc" );
797 wxWindowDC
const * sourceDC
= wxDynamicCast(source
, wxWindowDC
);
798 wxCHECK_MSG( sourceDC
, false, "Blit source DC must be wxWindowDCImpl or derived class." );
800 // cast is safe in virtue of the above wxCHECK_MSG()
801 const wxWindowDCImpl
* const
802 srcImpl
= static_cast<const wxWindowDCImpl
*>(sourceDC
->GetImpl());
803 WXDisplay
* const srcDpy
= srcImpl
->m_display
;
806 // Be sure that foreground pixels (1) of the Icon will be painted with
807 // foreground colour. [m_textForegroundColour] Background pixels (0)
808 // will be painted with backgound colour (m_textBackgroundColour)
809 // Using ::SetPen is horribly slow, so avoid doing it
810 WXPixel oldBackgroundPixel
= -1;
811 WXPixel oldForegroundPixel
= -1;
813 if (m_textBackgroundColour
.IsOk())
815 oldBackgroundPixel
= m_backgroundPixel
;
816 WXPixel pixel
= m_textBackgroundColour
.AllocColour(m_display
);
818 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
819 if (m_window
&& m_window
->GetBackingPixmap())
820 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
823 if (m_textForegroundColour
.IsOk())
825 oldForegroundPixel
= m_currentColour
.GetPixel();
827 if( m_textForegroundColour
.GetPixel() <= -1 )
828 CalculatePixel( m_textForegroundColour
,
829 m_textForegroundColour
, true);
831 WXPixel pixel
= m_textForegroundColour
.GetPixel();
833 SetForegroundPixelWithLogicalFunction(pixel
);
836 // Do bitmap scaling if necessary
838 wxBitmap
*scaledBitmap
= NULL
;
839 Pixmap sourcePixmap
= (Pixmap
) NULL
;
840 double scaleX
, scaleY
;
841 GetUserScale(& scaleX
, & scaleY
);
844 /* TODO: use the mask origin when drawing transparently */
845 if (xsrcMask
== -1 && ysrcMask
== -1)
847 xsrcMask
= xsrc
; ysrcMask
= ysrc
;
850 // Sorry, can't scale masks just yet
851 if (!useMask
&& (scaleX
!= 1.0 || scaleY
!= 1.0) && sourceDC
->IsKindOf(CLASSINFO(wxMemoryDC
)))
853 wxMemoryDC
* memDC
= (wxMemoryDC
*) sourceDC
;
854 wxBitmap
& bitmap
= memDC
->GetSelectedBitmap();
856 wxASSERT_MSG( (bitmap
.IsOk()), "Bad source bitmap in wxWindowDCImpl::Blit");
858 wxImage image
= bitmap
.ConvertToImage();
861 sourcePixmap
= (Pixmap
) bitmap
.GetDrawable();
865 int scaledW
= (int) (bitmap
.GetWidth() * scaleX
);
866 int scaledH
= (int) (bitmap
.GetHeight() * scaleY
);
868 image
= image
.Scale(scaledW
, scaledH
);
869 scaledBitmap
= new wxBitmap(image
);
870 sourcePixmap
= (Pixmap
) scaledBitmap
->GetDrawable();
875 sourcePixmap
= (Pixmap
) srcImpl
->m_pixmap
;
878 if (m_pixmap
&& sourcePixmap
)
881 wxRasterOperationMode orig
= m_logicalFunction
;
883 SetLogicalFunction (rop
);
885 if (m_display
!= srcDpy
)
887 XImage
*cache
= NULL
;
889 if (m_window
&& m_window
->GetBackingPixmap())
890 XCopyRemote((Display
*) srcDpy
, (Display
*) m_display
,
891 (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
893 source
->LogicalToDeviceX (xsrc
),
894 source
->LogicalToDeviceY (ysrc
),
895 source
->LogicalToDeviceXRel(width
),
896 source
->LogicalToDeviceYRel(height
),
897 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
),
900 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
902 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
903 wxBitmap
& sel
= memDC
->GetSelectedBitmap();
904 if ( sel
.IsOk() && sel
.GetMask() && sel
.GetMask()->GetBitmap() )
906 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap());
907 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
911 XCopyRemote((Display
*) srcDpy
, (Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
912 source
->LogicalToDeviceX (xsrc
),
913 source
->LogicalToDeviceY (ysrc
),
914 source
->LogicalToDeviceXRel(width
),
915 source
->LogicalToDeviceYRel(height
),
916 XLOG2DEV (xdest
), YLOG2DEV (ydest
),
922 XSetRegion ((Display
*) m_display
, (GC
) m_gc
,
923 (Region
) m_clipRegion
);
925 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
927 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
931 { //XGCValues values;
932 //XGetGCValues((Display*)m_display, (GC)m_gc, GCForeground, &values);
934 if (m_window
&& m_window
->GetBackingPixmap())
936 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1
937 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetSelectedBitmap().GetDepth() == 1)
939 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
940 source
->LogicalToDeviceX (xsrc
),
941 source
->LogicalToDeviceY (ysrc
),
942 source
->LogicalToDeviceXRel(width
),
943 source
->LogicalToDeviceYRel(height
),
944 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 1);
948 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
949 source
->LogicalToDeviceX (xsrc
),
950 source
->LogicalToDeviceY (ysrc
),
951 source
->LogicalToDeviceXRel(width
),
952 source
->LogicalToDeviceYRel(height
),
953 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
));
956 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
958 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
959 wxBitmap
& sel
= memDC
->GetSelectedBitmap();
960 if ( sel
.IsOk() && sel
.GetMask() && sel
.GetMask()->GetBitmap() )
962 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap());
963 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
967 // Check if we're copying from a mono bitmap
968 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) &&
969 ((wxMemoryDC
*)source
)->GetSelectedBitmap().IsOk() &&
970 (((wxMemoryDC
*)source
)->GetSelectedBitmap().GetDepth () == 1))
972 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
973 source
->LogicalToDeviceX (xsrc
),
974 source
->LogicalToDeviceY (ysrc
),
975 source
->LogicalToDeviceXRel(width
),
976 source
->LogicalToDeviceYRel(height
),
977 XLOG2DEV (xdest
), YLOG2DEV (ydest
), 1);
981 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
982 source
->LogicalToDeviceX (xsrc
),
983 source
->LogicalToDeviceY (ysrc
),
984 source
->LogicalToDeviceXRel(width
),
985 source
->LogicalToDeviceYRel(height
),
986 XLOG2DEV (xdest
), YLOG2DEV (ydest
));
992 XSetRegion ((Display
*) m_display
, (GC
) m_gc
,
993 (Region
) m_clipRegion
);
995 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
997 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
1000 } /* Remote/local (Display*) m_display */
1001 CalcBoundingBox (xdest
, ydest
);
1002 CalcBoundingBox (xdest
+ width
, ydest
+ height
);
1004 SetLogicalFunction(orig
);
1008 if (scaledBitmap
) delete scaledBitmap
;
1010 if (oldBackgroundPixel
> -1)
1012 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
);
1013 if (m_window
&& m_window
->GetBackingPixmap())
1014 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1015 oldBackgroundPixel
);
1017 if (oldForegroundPixel
> -1)
1019 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
);
1020 if (m_window
&& m_window
->GetBackingPixmap())
1021 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1022 oldForegroundPixel
);
1028 void wxWindowDCImpl::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1030 wxCHECK_RET( IsOk(), "invalid dc" );
1032 // Since X draws from the baseline of the text, must add the text height
1036 int slen
= text
.length();
1038 // Set FillStyle, otherwise X will use current stipple!
1039 XGCValues gcV
, gcBackingV
;
1041 XGetGCValues ((Display
*) m_display
, (GC
)m_gc
, GCFillStyle
, &gcV
);
1042 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1043 if (m_window
&& m_window
->GetBackingPixmap())
1045 XGetGCValues ((Display
*) m_display
, (GC
)m_gcBacking
, GCFillStyle
,
1047 XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
, FillSolid
);
1051 wxGetTextExtent (m_display
, m_font
, m_userScaleY
* m_logicalScaleY
,
1052 text
, &cx
, &cy
, &ascent
, NULL
);
1054 // First draw a rectangle representing the text background, if a text
1055 // background is specified
1056 if (m_textBackgroundColour
.IsOk () && (m_backgroundMode
!= wxTRANSPARENT
))
1058 wxColour oldPenColour
= m_currentColour
;
1059 m_currentColour
= m_textBackgroundColour
;
1060 bool sameColour
= (oldPenColour
.IsOk () && m_textBackgroundColour
.IsOk () &&
1061 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1062 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1063 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1065 // This separation of the big && test required for gcc2.7/HP UX 9.02
1066 // or pixel value can be corrupted!
1067 sameColour
= (sameColour
&&
1068 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1070 if (!sameColour
|| !GET_OPTIMIZATION
)
1072 WXPixel pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1073 m_currentColour
= m_textBackgroundColour
;
1075 // Set the GC to the required colour
1078 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1079 if (m_window
&& m_window
->GetBackingPixmap())
1080 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1084 m_textBackgroundColour
= oldPenColour
;
1086 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1087 if (m_window
&& m_window
->GetBackingPixmap())
1088 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1089 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1092 // Now set the text foreground and draw the text
1093 if (m_textForegroundColour
.IsOk ())
1095 wxColour oldPenColour
= m_currentColour
;
1096 m_currentColour
= m_textForegroundColour
;
1097 bool sameColour
= (oldPenColour
.IsOk () && m_currentColour
.IsOk () &&
1098 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1099 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1100 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1101 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1103 if (!sameColour
|| !GET_OPTIMIZATION
)
1105 WXPixel pixel
= CalculatePixel(m_textForegroundColour
,
1106 m_currentColour
, false);
1108 // Set the GC to the required colour
1111 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1112 if (m_window
&& m_window
->GetBackingPixmap())
1113 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1117 m_textForegroundColour
= oldPenColour
;
1120 // We need to add the ascent, not the whole height, since X draws at the
1121 // point above the descender.
1124 XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1125 (XChar2b
*)(char*) (const char*) text
, slen
);
1128 #if wxMOTIF_NEW_FONT_HANDLING
1129 XFontSet fset
= (XFontSet
) m_font
.GetFontSet (m_userScaleY
* m_logicalScaleY
, m_display
);
1130 XmbDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, fset
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
, text
, slen
);
1132 XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
, text
, slen
);
1135 if (m_window
&& m_window
->GetBackingPixmap()) {
1138 XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1139 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1140 (XChar2b
*)(char*) (const char*) text
, slen
);
1143 #if wxMOTIF_NEW_FONT_HANDLING
1144 XmbDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), fset
, (GC
) m_gcBacking
,
1145 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1146 text
.mb_str(), slen
);
1148 XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1149 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1150 text
.mb_str(), slen
);
1154 // restore fill style
1155 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, gcV
.fill_style
);
1156 if (m_window
&& m_window
->GetBackingPixmap())
1157 XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
,
1158 gcBackingV
.fill_style
);
1161 DoGetTextExtent (text
, &w
, &h
);
1162 CalcBoundingBox (x
+ w
, y
+ h
);
1163 CalcBoundingBox (x
, y
);
1166 void wxWindowDCImpl::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
,
1171 DoDrawText(text
, x
, y
);
1175 wxCHECK_RET( IsOk(), "invalid dc" );
1177 WXPixel oldBackgroundPixel
= -1;
1178 WXPixel oldForegroundPixel
= -1;
1179 WXPixel foregroundPixel
= -1;
1180 WXPixel backgroundPixel
= -1;
1182 if (m_textBackgroundColour
.IsOk())
1184 oldBackgroundPixel
= m_backgroundPixel
;
1185 backgroundPixel
= m_textBackgroundColour
.AllocColour(m_display
);
1187 if (m_textForegroundColour
.IsOk())
1189 oldForegroundPixel
= m_currentColour
.GetPixel();
1191 if( m_textForegroundColour
.GetPixel() <= -1 )
1192 CalculatePixel( m_textForegroundColour
,
1193 m_textForegroundColour
, true);
1195 foregroundPixel
= m_textForegroundColour
.GetPixel();
1198 // Since X draws from the baseline of the text, must add the text height
1204 wxGetTextExtent (m_display
, m_font
, m_userScaleY
* m_logicalScaleY
,
1205 text
, &cx
, &cy
, &ascent
, NULL
);
1207 wxBitmap
src(cx
, cy
);
1209 dc
.SelectObject(src
);
1210 dc
.SetFont(GetFont());
1211 dc
.SetBackground(*wxWHITE_BRUSH
);
1212 dc
.SetBrush(*wxBLACK_BRUSH
);
1214 dc
.DrawText(text
, 0, 0);
1215 dc
.SetFont(wxNullFont
);
1217 // Calculate the size of the rotated bounding box.
1218 double dx
= cos(angle
/ 180.0 * M_PI
);
1219 double dy
= sin(angle
/ 180.0 * M_PI
);
1220 double x4
= cy
* dy
;
1221 double y4
= cy
* dx
;
1222 double x3
= cx
* dx
;
1223 double y3
= -cx
* dy
;
1224 double x2
= x3
+ x4
;
1225 double y2
= y3
+ y4
;
1229 // Create image from the source bitmap after writing the text into it.
1230 wxImage image
= src
.ConvertToImage();
1232 int minx
= roundmin(0, roundmin(x4
, roundmin(x2
, x3
)));
1233 int miny
= roundmin(0, roundmin(y4
, roundmin(y2
, y3
)));
1234 int maxx
= roundmax(0, roundmax(x4
, roundmax(x2
, x3
)));
1235 int maxy
= roundmax(0, roundmax(y4
, roundmax(y2
, y3
)));
1237 bool lastFore
= false, lastBack
= false;
1239 // This rotates counterclockwise around the top left corner.
1240 for (int rx
= minx
; rx
< maxx
; rx
++)
1242 for (int ry
= miny
; ry
< maxy
; ry
++)
1244 // transform dest coords to source coords
1245 int sx
= (int) (rx
* dx
- ry
* dy
+ 0.5);
1246 int sy
= - (int) (-ry
* dx
- rx
* dy
+ 0.5);
1247 if (sx
>= 0 && sx
< cx
&& sy
>= 0 && sy
< cy
)
1249 bool textPixel
= image
.GetRed(sx
, sy
) == 0;
1251 if (!textPixel
&& m_backgroundMode
!= wxSOLID
)
1254 wxCoord ox
= (wxCoord
) (x1
+ rx
),
1255 oy
= (wxCoord
) (y1
+ ry
);
1256 // draw black pixels, ignore white ones (i.e. transparent b/g)
1257 if (textPixel
&& !lastFore
)
1259 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1264 else if (!textPixel
&& !lastBack
)
1266 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1272 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
,
1273 (GC
) m_gc
, XLOG2DEV (ox
), YLOG2DEV (oy
));
1274 if (m_window
&& m_window
->GetBackingPixmap())
1275 XDrawPoint ((Display
*) m_display
,
1276 (Pixmap
) m_window
->GetBackingPixmap(),
1278 XLOG2DEV_2 (ox
), YLOG2DEV_2 (oy
));
1283 if (oldBackgroundPixel
> -1)
1285 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
);
1286 if (m_window
&& m_window
->GetBackingPixmap())
1287 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1288 oldBackgroundPixel
);
1290 if (oldForegroundPixel
> -1)
1292 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
);
1293 if (m_window
&& m_window
->GetBackingPixmap())
1294 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1295 oldForegroundPixel
);
1298 CalcBoundingBox (minx
, miny
);
1299 CalcBoundingBox (maxx
, maxy
);
1302 bool wxWindowDCImpl::CanGetTextExtent() const
1307 void wxWindowDCImpl::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1308 wxCoord
*descent
, wxCoord
*externalLeading
,
1309 const wxFont
*font
) const
1311 wxCHECK_RET( IsOk(), "invalid dc" );
1313 const wxFont
* theFont
= font
? font
: &m_font
;
1315 if (!theFont
->IsOk())
1317 // TODO: this should be an error log function
1318 wxFAIL_MSG("set a valid font before calling GetTextExtent!");
1320 if (width
) *width
= -1;
1321 if (height
) *height
= -1;
1325 wxGetTextExtent(m_display
, *theFont
, m_userScaleY
* m_logicalScaleY
,
1326 string
, width
, height
, NULL
, descent
);
1328 if (width
) *width
= XDEV2LOGREL (*width
);
1329 if (height
) *height
= YDEV2LOGREL (*height
);
1330 if (externalLeading
)
1331 *externalLeading
= 0;
1334 wxCoord
wxWindowDCImpl::GetCharWidth() const
1336 wxCHECK_MSG( IsOk(), 0, "invalid dc" );
1337 wxCHECK_MSG( m_font
.IsOk(), 0, "invalid font" );
1341 wxGetTextExtent (m_display
, m_font
, m_userScaleY
* m_logicalScaleY
,
1342 "x", &width
, NULL
, NULL
, NULL
);
1344 return XDEV2LOGREL(width
);
1347 wxCoord
wxWindowDCImpl::GetCharHeight() const
1349 wxCHECK_MSG( IsOk(), 0, "invalid dc" );
1350 wxCHECK_MSG( m_font
.IsOk(), 0, "invalid font" );
1354 wxGetTextExtent (m_display
, m_font
, m_userScaleY
* m_logicalScaleY
,
1355 "x", NULL
, &height
, NULL
, NULL
);
1357 return XDEV2LOGREL(height
);
1360 void wxWindowDCImpl::DoGetSize( int *width
, int *height
) const
1366 if( m_window
->GetBackingPixmap() )
1368 w
= m_window
->GetPixmapWidth();
1369 h
= m_window
->GetPixmapHeight();
1372 m_window
->GetSize( &w
, &h
);
1375 if( width
) *width
= w
;
1376 if( height
) *height
= h
;
1379 void wxWindowDCImpl::Clear()
1381 wxCHECK_RET( IsOk(), "invalid dc" );
1383 wxRect
rect( GetSize() );
1387 void wxWindowDCImpl::Clear(const wxRect
& rect
)
1389 wxCHECK_RET( IsOk(), "invalid dc" );
1391 int x
= rect
.x
; int y
= rect
.y
;
1392 int w
= rect
.width
; int h
= rect
.height
;
1394 wxBrush saveBrush
= m_brush
;
1395 SetBrush (m_backgroundBrush
);
1397 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1400 if (m_window
&& m_window
->GetBackingPixmap())
1401 XFillRectangle ((Display
*) m_display
,
1402 (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1405 m_brush
= saveBrush
;
1408 void wxWindowDCImpl::SetFont( const wxFont
&font
)
1410 wxCHECK_RET( IsOk(), "invalid dc" );
1419 #if !wxMOTIF_NEW_FONT_HANDLING
1420 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1422 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1423 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1425 if (m_window
&& m_window
->GetBackingPixmap())
1426 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1430 void wxWindowDCImpl::SetForegroundPixelWithLogicalFunction(WXPixel pixel
)
1432 if (m_logicalFunction
== wxXOR
)
1435 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1436 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1437 pixel
^ values
.background
);
1438 if (m_window
&& m_window
->GetBackingPixmap())
1439 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1440 pixel
^ values
.background
);
1444 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1445 if (m_window
&& m_window
->GetBackingPixmap())
1446 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1450 WXPixel
wxWindowDCImpl::CalculatePixel(wxColour
& colour
, wxColour
& curCol
,
1451 bool roundToWhite
) const
1453 const unsigned char wp
= (unsigned char)255;
1456 if(!m_colour
) // Mono display
1458 unsigned char red
= colour
.Red ();
1459 unsigned char blue
= colour
.Blue ();
1460 unsigned char green
= colour
.Green ();
1462 if((red
== wp
&& blue
== wp
&& green
== wp
) ||
1463 // not black and roundToWhite was specified
1464 ((red
!= 0 || blue
!= 0 || green
!= 0) && roundToWhite
))
1467 pixel
= WhitePixel((Display
*) m_display
,
1468 DefaultScreen((Display
*) m_display
));
1469 curCol
.SetPixel(pixel
);
1470 colour
.SetPixel(pixel
);
1475 pixel
= BlackPixel((Display
*) m_display
,
1476 DefaultScreen((Display
*) m_display
));
1477 curCol
.SetPixel(pixel
);
1478 colour
.SetPixel(pixel
);
1484 pixel
= colour
.AllocColour((Display
*) m_display
);
1485 curCol
.SetPixel(pixel
);
1491 void wxWindowDCImpl::SetPen( const wxPen
&pen
)
1493 wxCHECK_RET( IsOk(), "invalid dc" );
1499 wxBitmap oldStipple
= m_currentStipple
;
1500 int oldStyle
= m_currentStyle
;
1501 int oldFill
= m_currentFill
;
1502 int old_pen_width
= m_currentPenWidth
;
1503 int old_pen_join
= m_currentPenJoin
;
1504 int old_pen_cap
= m_currentPenCap
;
1505 int old_pen_nb_dash
= m_currentPenDashCount
;
1506 wxX11Dash
*old_pen_dash
= m_currentPenDash
;
1508 wxColour oldPenColour
= m_currentColour
;
1509 m_currentColour
= m_pen
.GetColour ();
1510 m_currentStyle
= m_pen
.GetStyle ();
1511 m_currentFill
= m_pen
.GetStyle (); // TODO?
1512 m_currentPenWidth
= m_pen
.GetWidth ();
1513 m_currentPenJoin
= m_pen
.GetJoin ();
1514 m_currentPenCap
= m_pen
.GetCap ();
1515 m_currentPenDashCount
= m_pen
.GetDashCount();
1516 m_currentPenDash
= (wxX11Dash
*)m_pen
.GetDash();
1518 if (m_currentStyle
== wxSTIPPLE
)
1519 m_currentStipple
= * m_pen
.GetStipple ();
1521 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1522 oldFill
== m_currentFill
&&
1523 old_pen_join
== m_currentPenJoin
&&
1524 old_pen_cap
== m_currentPenCap
&&
1525 old_pen_nb_dash
== m_currentPenDashCount
&&
1526 old_pen_dash
== m_currentPenDash
&&
1527 old_pen_width
== m_currentPenWidth
);
1529 bool sameColour
= (oldPenColour
.IsOk () &&
1530 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1531 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1532 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1533 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1535 if (!sameStyle
|| !GET_OPTIMIZATION
)
1537 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1538 if (scaled_width
< 0)
1544 static const wxX11Dash dotted
[] = {2, 5};
1545 static const wxX11Dash short_dashed
[] = {4, 4};
1546 static const wxX11Dash long_dashed
[] = {4, 8};
1547 static const wxX11Dash dotted_dashed
[] = {6, 6, 2, 6};
1549 // We express dash pattern in pen width unit, so we are
1550 // independent of zoom factor and so on...
1552 const wxX11Dash
*req_dash
;
1554 switch (m_pen
.GetStyle ())
1557 req_nb_dash
= m_currentPenDashCount
;
1558 req_dash
= m_currentPenDash
;
1559 style
= LineOnOffDash
;
1564 style
= LineOnOffDash
;
1568 req_dash
= short_dashed
;
1569 style
= LineOnOffDash
;
1573 req_dash
= long_dashed
;
1574 style
= LineOnOffDash
;
1578 req_dash
= dotted_dashed
;
1579 style
= LineOnOffDash
;
1590 if (req_dash
&& req_nb_dash
)
1592 wxX11Dash
*real_req_dash
= new wxX11Dash
[req_nb_dash
];
1595 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1596 for (int i
= 0; i
< req_nb_dash
; i
++)
1597 real_req_dash
[i
] = (wxX11Dash
)(req_dash
[i
] * factor
);
1598 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1600 if (m_window
&& m_window
->GetBackingPixmap())
1601 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1602 delete[]real_req_dash
;
1606 // No Memory. We use non-scaled dash pattern...
1607 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1609 if (m_window
&& m_window
->GetBackingPixmap())
1610 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1614 switch (m_pen
.GetCap ())
1616 case wxCAP_PROJECTING
:
1617 cap
= CapProjecting
;
1624 cap
= (scaled_width
<= 1) ? CapNotLast
: CapRound
;
1628 switch (m_pen
.GetJoin ())
1642 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1644 if (m_window
&& m_window
->GetBackingPixmap())
1645 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1648 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GET_OPTIMIZATION
))
1652 oldStipple
= wxNullBitmap
; // For later reset!!
1654 switch (m_currentFill
)
1656 case wxBDIAGONAL_HATCH
:
1657 if (bdiag
== (Pixmap
) 0)
1658 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1659 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1660 bdiag_bits
, bdiag_width
, bdiag_height
);
1663 case wxFDIAGONAL_HATCH
:
1664 if (fdiag
== (Pixmap
) 0)
1665 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1666 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1667 fdiag_bits
, fdiag_width
, fdiag_height
);
1671 if (cross
== (Pixmap
) 0)
1672 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1673 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1674 cross_bits
, cross_width
, cross_height
);
1677 case wxHORIZONTAL_HATCH
:
1678 if (horiz
== (Pixmap
) 0)
1679 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1680 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1681 horiz_bits
, horiz_width
, horiz_height
);
1684 case wxVERTICAL_HATCH
:
1685 if (verti
== (Pixmap
) 0)
1686 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1687 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1688 verti_bits
, verti_width
, verti_height
);
1691 case wxCROSSDIAG_HATCH
:
1693 if (cdiag
== (Pixmap
) 0)
1694 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1695 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1696 cdiag_bits
, cdiag_width
, cdiag_height
);
1700 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1702 if (m_window
&& m_window
->GetBackingPixmap())
1703 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1705 else if (m_currentStyle
== wxSTIPPLE
&& m_currentStipple
.IsOk()
1706 && ((!m_currentStipple
.IsSameAs(oldStipple
)) || !GET_OPTIMIZATION
))
1708 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetDrawable());
1710 if (m_window
&& m_window
->GetBackingPixmap())
1711 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetDrawable());
1714 if ((m_currentFill
!= oldFill
) || !GET_OPTIMIZATION
)
1718 if (m_currentFill
== wxSTIPPLE
)
1719 fill_style
= FillStippled
;
1720 else if (IS_HATCH (m_currentFill
))
1721 fill_style
= FillStippled
;
1723 fill_style
= FillSolid
;
1724 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1725 if (m_window
&& m_window
->GetBackingPixmap())
1726 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1729 // must test m_logicalFunction, because it involves background!
1730 if (!sameColour
|| !GET_OPTIMIZATION
1731 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1734 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1735 pixel
= m_backgroundPixel
;
1738 wxColour penClr
= m_pen
.GetColour();
1739 pixel
= CalculatePixel( penClr
, m_currentColour
, false);
1740 m_pen
.SetColour(penClr
);
1743 // Finally, set the GC to the required colour
1745 SetForegroundPixelWithLogicalFunction(pixel
);
1748 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1753 void wxWindowDCImpl::SetBrush( const wxBrush
&brush
)
1755 wxCHECK_RET( IsOk(), "invalid dc" );
1759 if (!m_brush
.IsOk() || m_brush
.GetStyle () == wxTRANSPARENT
)
1762 int oldFill
= m_currentFill
;
1763 wxBitmap oldStipple
= m_currentStipple
;
1765 m_autoSetting
|= 0x1;
1767 m_currentFill
= m_brush
.GetStyle ();
1768 if (m_currentFill
== wxSTIPPLE
)
1769 m_currentStipple
= * m_brush
.GetStipple ();
1771 wxColour
oldBrushColour(m_currentColour
);
1772 m_currentColour
= m_brush
.GetColour ();
1774 bool sameColour
= (oldBrushColour
.IsOk () &&
1775 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1776 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1777 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1778 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1780 int stippleDepth
= -1;
1782 if ((oldFill
!= m_brush
.GetStyle ()) || !GET_OPTIMIZATION
)
1784 switch (brush
.GetStyle ())
1789 stippleDepth
= m_currentStipple
.GetDepth();
1791 case wxBDIAGONAL_HATCH
:
1792 case wxCROSSDIAG_HATCH
:
1793 case wxFDIAGONAL_HATCH
:
1795 case wxHORIZONTAL_HATCH
:
1796 case wxVERTICAL_HATCH
:
1798 if (stippleDepth
== -1) stippleDepth
= 1;
1800 // Chris Breeze 23/07/97: use background mode to
1801 // determine whether fill style should be solid or
1803 int style
= stippleDepth
== 1 ?
1804 (m_backgroundMode
== wxSOLID
?
1805 FillOpaqueStippled
: FillStippled
) :
1807 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1808 if (m_window
&& m_window
->GetBackingPixmap())
1809 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1814 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1815 if (m_window
&& m_window
->GetBackingPixmap())
1816 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
,
1821 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GET_OPTIMIZATION
))
1825 switch (m_currentFill
)
1827 case wxBDIAGONAL_HATCH
:
1828 if (bdiag
== (Pixmap
) 0)
1829 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1830 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1831 bdiag_bits
, bdiag_width
, bdiag_height
);
1834 case wxFDIAGONAL_HATCH
:
1835 if (fdiag
== (Pixmap
) 0)
1836 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1837 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1838 fdiag_bits
, fdiag_width
, fdiag_height
);
1842 if (cross
== (Pixmap
) 0)
1843 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1844 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1845 cross_bits
, cross_width
, cross_height
);
1848 case wxHORIZONTAL_HATCH
:
1849 if (horiz
== (Pixmap
) 0)
1850 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1851 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1852 horiz_bits
, horiz_width
, horiz_height
);
1855 case wxVERTICAL_HATCH
:
1856 if (verti
== (Pixmap
) 0)
1857 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1858 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1859 verti_bits
, verti_width
, verti_height
);
1862 case wxCROSSDIAG_HATCH
:
1864 if (cdiag
== (Pixmap
) 0)
1865 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1866 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1867 cdiag_bits
, cdiag_width
, cdiag_height
);
1871 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1873 if (m_window
&& m_window
->GetBackingPixmap())
1874 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1876 // X can forget the stipple value when resizing a window (apparently)
1877 // so always set the stipple.
1878 else if (m_currentFill
!= wxSOLID
&& m_currentFill
!= wxTRANSPARENT
&&
1879 m_currentStipple
.IsOk()) // && m_currentStipple != oldStipple)
1881 if (m_currentStipple
.GetDepth() == 1)
1883 XSetStipple ((Display
*) m_display
, (GC
) m_gc
,
1884 (Pixmap
) m_currentStipple
.GetDrawable());
1885 if (m_window
&& m_window
->GetBackingPixmap())
1886 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
,
1887 (Pixmap
) m_currentStipple
.GetDrawable());
1891 XSetTile ((Display
*) m_display
, (GC
) m_gc
,
1892 (Pixmap
) m_currentStipple
.GetDrawable());
1893 if (m_window
&& m_window
->GetBackingPixmap())
1894 XSetTile ((Display
*) m_display
,(GC
) m_gcBacking
,
1895 (Pixmap
) m_currentStipple
.GetDrawable());
1899 // must test m_logicalFunction, because it involves background!
1900 if (!sameColour
|| !GET_OPTIMIZATION
|| m_logicalFunction
== wxXOR
)
1902 wxColour brushClr
= m_brush
.GetColour();
1903 WXPixel pixel
= CalculatePixel( brushClr
, m_currentColour
, true);
1904 m_brush
.SetColour(brushClr
);
1907 SetForegroundPixelWithLogicalFunction(pixel
);
1910 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1913 void wxWindowDCImpl::SetBackground( const wxBrush
&brush
)
1915 wxCHECK_RET( IsOk(), "invalid dc" );
1917 m_backgroundBrush
= brush
;
1919 if (!m_backgroundBrush
.IsOk())
1922 m_backgroundPixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
1924 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
1925 // And Blit,... (Any fct that use XCopyPlane, in fact.)
1926 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, m_backgroundPixel
);
1927 if (m_window
&& m_window
->GetBackingPixmap())
1928 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1932 void wxWindowDCImpl::SetLogicalFunction( wxRasterOperationMode function
)
1934 wxCHECK_RET( IsOk(), "invalid dc" );
1939 if (m_logicalFunction
== function
)
1945 x_function
= GXclear
;
1951 x_function
= GXinvert
;
1954 x_function
= GXorReverse
;
1957 x_function
= GXandReverse
;
1966 x_function
= GXandInverted
;
1969 x_function
= GXnoop
;
1975 x_function
= GXequiv
;
1978 x_function
= GXcopyInverted
;
1981 x_function
= GXorInverted
;
1984 x_function
= GXnand
;
1991 x_function
= GXcopy
;
1995 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
1996 if (m_window
&& m_window
->GetBackingPixmap())
1997 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
1999 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
2000 /* MATTHEW: [9] Need to redo pen simply */
2001 m_autoSetting
|= 0x2;
2003 m_logicalFunction
= function
;
2007 void wxWindowDCImpl::SetTextForeground( const wxColour
&col
)
2009 wxCHECK_RET( IsOk(), "invalid dc" );
2011 m_textForegroundColour
= col
;
2014 void wxWindowDCImpl::SetTextBackground( const wxColour
&col
)
2016 wxCHECK_RET( IsOk(), "invalid dc" );
2018 m_textBackgroundColour
= col
;
2021 void wxWindowDCImpl::SetBackgroundMode( int mode
)
2023 m_backgroundMode
= mode
;
2026 void wxWindowDCImpl::SetPalette( const wxPalette
& palette
)
2031 /* Use GetXColormap */
2032 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2033 (Colormap
) palette
.GetXColormap());
2035 /* Use wxGetMainColormap */
2036 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2037 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2041 static void wxCopyRegion( WXRegion src
, WXRegion
& dst
)
2044 dst
= XCreateRegion();
2045 XUnionRegion( (Region
)src
, (Region
)src
, (Region
)dst
);
2048 // Helper function; userRegion is the region set by calling SetClippingRegion
2049 void wxWindowDCImpl::SetDCClipping( WXRegion userRegion
)
2051 bool hasUpdateRegion
= m_window
&& m_window
->GetUpdateRegion().IsOk();
2052 // this means that we should start the clip region from scratch,
2053 // or from the update region, if any
2057 XDestroyRegion( (Region
)m_clipRegion
);
2058 m_clipRegion
= (WXRegion
)NULL
;
2060 if( hasUpdateRegion
)
2061 wxCopyRegion( m_window
->GetUpdateRegion().GetX11Region(),
2064 // intersect the user region, if any, with the
2065 // exisiting clip region
2066 else // if( userRegion )
2069 wxCopyRegion( userRegion
, m_clipRegion
);
2071 XIntersectRegion( (Region
)m_clipRegion
,
2072 (Region
)userRegion
, (Region
)m_clipRegion
);
2076 XSetRegion( (Display
*)m_display
, (GC
)m_gc
, (Region
)m_clipRegion
);
2078 XSetClipMask( (Display
*)m_display
, (GC
)m_gc
, None
);
2081 void wxWindowDCImpl::DoSetClippingRegion( wxCoord x
, wxCoord y
,
2082 wxCoord width
, wxCoord height
)
2084 wxMotifDCImpl::DoSetClippingRegion( x
, y
, width
, height
);
2086 wxRegion
temp(XLOG2DEV(x
), YLOG2DEV(y
),
2087 XLOG2DEVREL(width
), YLOG2DEVREL(height
));
2089 SetDCClipping(temp
.GetX11Region());
2091 // Needs to work differently for Pixmap: without this,
2092 // there's a nasty (Display*) m_display bug. 8/12/94
2093 if (m_window
&& m_window
->GetBackingPixmap())
2095 XRectangle rects
[1];
2096 rects
[0].x
= (short)XLOG2DEV_2(x
);
2097 rects
[0].y
= (short)YLOG2DEV_2(y
);
2098 rects
[0].width
= (unsigned short)XLOG2DEVREL(width
);
2099 rects
[0].height
= (unsigned short)YLOG2DEVREL(height
);
2100 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
,
2101 0, 0, rects
, 1, Unsorted
);
2105 void wxWindowDCImpl::DoSetDeviceClippingRegion( const wxRegion
& region
)
2107 SetDCClipping(region
.GetX11Region());
2109 // Needs to work differently for Pixmap: without this,
2110 // there's a nasty (Display*) m_display bug. 8/12/94
2111 if (m_window
&& m_window
->GetBackingPixmap())
2113 wxRect box
= region
.GetBox();
2115 XRectangle rects
[1];
2116 rects
[0].x
= (short)box
.x
;
2117 rects
[0].y
= (short)box
.y
;
2118 rects
[0].width
= (unsigned short)box
.width
;
2119 rects
[0].height
= (unsigned short)box
.height
;
2120 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
,
2121 0, 0, rects
, 1, Unsorted
);
2126 void wxWindowDCImpl::DestroyClippingRegion()
2128 wxMotifDCImpl::DestroyClippingRegion();
2130 SetDCClipping(NULL
);
2132 if (m_window
&& m_window
->GetBackingPixmap())
2133 XSetClipMask ((Display
*) m_display
, (GC
) m_gcBacking
, None
);
2136 // Resolution in pixels per logical inch
2137 wxSize
wxWindowDCImpl::GetPPI() const
2140 return wxSize(100, 100);
2143 int wxWindowDCImpl::GetDepth() const
2152 // ----------------------------------------------------------------------------
2154 // ----------------------------------------------------------------------------
2156 wxPaintDCImpl::wxPaintDCImpl(wxDC
*owner
, wxWindow
* win
)
2157 : wxWindowDCImpl(owner
, win
)
2159 // Set the clipping region.to the update region
2160 SetDCClipping((WXRegion
)NULL
);
2163 wxPaintDCImpl::~wxPaintDCImpl()
2166 m_window
->ClearUpdateRegion();
2167 SetDCClipping((WXRegion
)NULL
);
2170 // ----------------------------------------------------------------------------
2171 // private functions
2172 // ----------------------------------------------------------------------------
2175 Used when copying between drawables on different (Display*) m_displays. Not
2176 very fast, but better than giving up.
2179 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
2180 Drawable src
, Drawable dest
,
2183 unsigned int w
, unsigned int h
,
2184 int destx
, int desty
,
2185 bool more
, XImage
**cache
)
2187 XImage
*image
, *destimage
;
2188 Colormap destcm
, srccm
;
2189 static const int CACHE_SIZE
= 256;
2192 Pixel cachesrc
[CACHE_SIZE
], cachedest
[CACHE_SIZE
];
2193 int k
, cache_pos
, all_cache
;
2195 if (!cache
|| !*cache
)
2196 image
= XGetImage(src_display
, src
, srcx
, srcy
, w
, h
, AllPlanes
, ZPixmap
);
2200 destimage
= XGetImage(dest_display
, dest
, destx
, desty
, w
, h
, AllPlanes
, ZPixmap
);
2202 srccm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) src_display
);
2203 destcm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dest_display
);
2208 for (i
= 0; i
< w
; i
++)
2209 for (j
= 0; j
< h
; j
++) {
2213 pixel
= XGetPixel(image
, i
, j
);
2214 for (k
= cache_pos
; k
--; )
2215 if (cachesrc
[k
] == pixel
) {
2216 pixel
= cachedest
[k
];
2220 for (k
= CACHE_SIZE
; k
-- > cache_pos
; )
2221 if (cachesrc
[k
] == pixel
) {
2222 pixel
= cachedest
[k
];
2226 cachesrc
[cache_pos
] = xcol
.pixel
= pixel
;
2227 XQueryColor(src_display
, srccm
, &xcol
);
2228 if (!XAllocColor(dest_display
, destcm
, &xcol
))
2230 cachedest
[cache_pos
] = pixel
= xcol
.pixel
;
2232 if (++cache_pos
>= CACHE_SIZE
) {
2238 XPutPixel(destimage
, i
, j
, pixel
);
2241 XPutImage(dest_display
, dest
, destgc
, destimage
, 0, 0, destx
, desty
, w
, h
);
2242 XDestroyImage(destimage
);
2247 XDestroyImage(image
);