1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxClientDC class
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 About pens, brushes, and the autoSetting flag:
15 Under X, pens and brushes control some of the same X drawing
16 parameters. Therefore, it is impossible to independently maintain
17 the current pen and the current brush. Also, some settings depend on
18 the current logical function. The m_currentFill, etc. instance
19 variables remember state across the brush and pen.
21 Since pens are used more than brushes, the autoSetting flag is used to
22 indicate that a brush was recently used, and SetPen must be called to
23 reinstall the current pen's parameters. If autoSetting includes 0x2, then the
24 pens color may need to be set based on XOR.
26 There is, unfortunately, some confusion between setting the current pen/brush
27 and actually installing the brush/pen parameters. Both functionalies are
28 perform by SetPen and SetBrush. C'est la vie.
31 // ============================================================================
33 // ============================================================================
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
40 #pragma implementation "dcclient.h"
43 // For compilers that support precompilation, includes "wx.h".
44 #include "wx/wxprec.h"
46 #include "wx/dcclient.h"
47 #include "wx/dcmemory.h"
48 #include "wx/window.h"
56 #pragma message disable nosimpint
60 #pragma message enable nosimpint
63 #include "wx/motif/private.h"
66 #include <float.h> // for M_PI
76 static Pixmap bdiag
, cdiag
, fdiag
, cross
, horiz
, verti
;
78 // ----------------------------------------------------------------------------
80 // ----------------------------------------------------------------------------
82 // Fudge factor (VZ: what??)
85 // ----------------------------------------------------------------------------
87 // ----------------------------------------------------------------------------
89 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
90 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxWindowDC
)
91 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
94 // IS_HATCH exists for WXWIN_COMPATIBILITY_2_4 only
95 // but wxMotif needs it for its internals here
96 #define IS_HATCH(s) ((s)>=wxBDIAGONAL_HATCH && (s)<=wxVERTICAL_HATCH)
99 // ----------------------------------------------------------------------------
101 // ----------------------------------------------------------------------------
103 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
104 Drawable src
, Drawable dest
,
107 unsigned int w
, unsigned int h
,
108 int destx
, int desty
,
109 bool more
, XImage
**cache
);
111 // ============================================================================
113 // ============================================================================
116 * compare two doubles and return the larger rounded
119 static int roundmax(double a
, double b
)
121 return (int)((a
> b
? a
: b
) + 0.5);
125 * compare two doubles and return the smaller rounded
128 static int roundmin(double a
, double b
)
130 return (int)((a
< b
? a
: b
) - 0.5);
134 // ----------------------------------------------------------------------------
136 // ----------------------------------------------------------------------------
138 void wxWindowDC::Init()
141 m_gcBacking
= (WXGC
) 0;
143 m_backgroundPixel
= -1;
144 m_currentPenWidth
= 1;
145 m_currentPenJoin
= -1;
146 m_currentPenDashCount
= -1;
147 m_currentPenDash
= (wxX11Dash
*) NULL
;
150 m_colour
= wxColourDisplay();
151 m_display
= (WXDisplay
*) NULL
;
152 m_pixmap
= (WXPixmap
) 0;
154 m_oldFont
= (WXFont
) 0;
156 m_clipRegion
= (WXRegion
) 0;
159 wxWindowDC::wxWindowDC()
164 wxWindowDC::wxWindowDC( wxWindow
*window
)
166 wxASSERT_MSG( (window
!= (wxWindow
*) NULL
), "You must pass a valid wxWindow to wxWindowDC/wxClientDC/wxPaintDC constructor." );
171 m_font
= window
->GetFont();
174 m_display
= window
->GetXDisplay();
175 m_pixmap
= window
->GetXWindow();
176 Display
* display
= (Display
*) m_display
;
178 XSetWindowColormap (display
, (Pixmap
) m_pixmap
, (Colormap
) wxTheApp
->GetMainColormap(m_display
));
181 gcvalues
.foreground
= BlackPixel (display
, DefaultScreen (display
));
182 gcvalues
.background
= WhitePixel (display
, DefaultScreen (display
));
183 gcvalues
.graphics_exposures
= False
;
184 gcvalues
.subwindow_mode
= IncludeInferiors
;
185 gcvalues
.line_width
= 1;
186 m_gc
= (WXGC
) XCreateGC (display
, RootWindow (display
, DefaultScreen (display
)),
187 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
190 if (m_window
->GetBackingPixmap())
192 m_gcBacking
= (WXGC
) XCreateGC (display
, RootWindow (display
,
193 DefaultScreen (display
)),
194 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
198 m_backgroundPixel
= (int) gcvalues
.background
;
200 // Get the current Font so we can set it back later
202 XGetGCValues((Display
*) m_display
, (GC
) m_gc
, GCFont
, &valReturn
);
203 m_oldFont
= (WXFont
) valReturn
.font
;
205 SetBackground(wxBrush(m_window
->GetBackgroundColour(), wxSOLID
));
208 wxWindowDC::~wxWindowDC()
210 if (m_gc
&& (m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
212 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
214 if (m_window
&& m_window
->GetBackingPixmap())
215 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
219 XFreeGC ((Display
*) m_display
, (GC
) m_gc
);
223 XFreeGC ((Display
*) m_display
, (GC
) m_gcBacking
);
224 m_gcBacking
= (WXGC
) 0;
227 XDestroyRegion ((Region
) m_clipRegion
);
228 m_clipRegion
= (WXRegion
) 0;
231 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
232 const wxColour
& col
, int style
);
234 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
235 const wxColour
& col
, int style
)
237 return wxDoFloodFill(this, x
, y
, col
, style
);
240 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
242 // Generic (and therefore rather inefficient) method.
243 // Could be improved.
245 wxBitmap
bitmap(1, 1);
246 memdc
.SelectObject(bitmap
);
247 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
248 memdc
.SelectObject(wxNullBitmap
);
249 wxImage image
= bitmap
.ConvertToImage();
250 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
254 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
256 wxCHECK_RET( Ok(), "invalid dc" );
258 int x1d
, y1d
, x2d
, y2d
;
268 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x1d
, y1d
, x2d
, y2d
);
270 if (m_window
&& m_window
->GetBackingPixmap())
271 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
272 XLOG2DEV_2(x1
), YLOG2DEV_2(y1
),
273 XLOG2DEV_2(x2
), YLOG2DEV_2(y2
));
275 CalcBoundingBox(x1
, y1
);
276 CalcBoundingBox(x2
, y2
);
279 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
281 wxCHECK_RET( Ok(), "invalid dc" );
286 int xx
= XLOG2DEV (x
);
287 int yy
= YLOG2DEV (y
);
289 wxDisplaySize (&ww
, &hh
);
290 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, yy
,
292 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xx
, 0,
295 if (m_window
&& m_window
->GetBackingPixmap())
299 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
302 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
308 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
310 wxCHECK_RET( Ok(), "invalid dc" );
312 int xx1
= XLOG2DEV (x1
);
313 int yy1
= YLOG2DEV (y1
);
314 int xx2
= XLOG2DEV (x2
);
315 int yy2
= YLOG2DEV (y2
);
316 int xxc
= XLOG2DEV (xc
);
317 int yyc
= YLOG2DEV (yc
);
318 int xxc_2
= XLOG2DEV_2 (xc
);
319 int yyc_2
= YLOG2DEV_2 (yc
);
321 wxCoord dx
= xx1
- xxc
;
322 wxCoord dy
= yy1
- yyc
;
323 double radius
= sqrt ((double)(dx
* dx
+ dy
* dy
));
324 wxCoord r
= (wxCoord
) radius
;
326 double radius1
, radius2
;
328 if (xx1
== xx2
&& yy1
== yy2
)
333 else if (radius
== 0.0)
334 radius1
= radius2
= 0.0;
343 radius1
= -atan2 ((double) (yy1
- yyc
), (double) (xx1
- xxc
)) * 360.0 / (2 * M_PI
);
351 radius2
= -atan2 ((double) (yy2
- yyc
), (double) (xx2
- xxc
)) * 360.0 / (2 * M_PI
);
355 int alpha1
= (int) radius1
;
356 int alpha2
= (int) (radius2
- radius1
);
359 while (alpha2
> 360 * 64)
362 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
365 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) (GC
) m_gc
,
366 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
368 if (m_window
&& m_window
->GetBackingPixmap())
369 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
370 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
374 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
378 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
379 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
381 if (m_window
&& m_window
->GetBackingPixmap())
382 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
383 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
385 CalcBoundingBox (x1
, y1
);
386 CalcBoundingBox (x2
, y2
);
389 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
391 wxCHECK_RET( Ok(), "invalid dc" );
397 wd
= XLOG2DEVREL(width
);
398 hd
= YLOG2DEVREL(height
);
400 if (sa
>=360 || sa
<=-360) sa
=sa
-int(sa
/360)*360;
401 if (ea
>=360 || ea
<=-360) ea
=ea
-int(ea
/360)*360;
402 int start
= int(sa
*64);
403 int end
= int(ea
*64);
404 if (start
<0) start
+=360*64;
405 if (end
<0) end
+=360*64;
406 if (end
>start
) end
-=start
;
407 else end
+=360*64-start
;
409 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
411 m_autoSetting
= TRUE
; // must be reset
414 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
, end
);
416 if (m_window
&& m_window
->GetBackingPixmap())
417 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
418 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
421 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
425 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
,end
);
426 if (m_window
&& m_window
->GetBackingPixmap())
427 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
428 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
430 CalcBoundingBox (x
, y
);
431 CalcBoundingBox (x
+ width
, y
+ height
);
434 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
436 wxCHECK_RET( Ok(), "invalid dc" );
438 if (m_pen
.Ok() && m_autoSetting
)
441 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
));
442 if (m_window
&& m_window
->GetBackingPixmap())
443 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, XLOG2DEV_2 (x
), YLOG2DEV_2 (y
));
445 CalcBoundingBox (x
, y
);
448 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
450 wxCHECK_RET( Ok(), "invalid dc" );
452 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
457 XPoint
*xpoints
= new XPoint
[n
];
460 for (i
= 0; i
< n
; i
++)
462 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
463 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
465 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints
, n
, 0);
467 if (m_window
&& m_window
->GetBackingPixmap())
469 for (i
= 0; i
< n
; i
++)
471 xpoints
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
472 xpoints
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
474 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints
, n
, 0);
480 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
481 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
483 wxCHECK_RET( Ok(), "invalid dc" );
485 XPoint
*xpoints1
= new XPoint
[n
+ 1];
486 XPoint
*xpoints2
= new XPoint
[n
+ 1];
488 for (i
= 0; i
< n
; i
++)
490 xpoints1
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
491 xpoints1
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
492 xpoints2
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
493 xpoints2
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
494 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
497 // Close figure for XDrawLines (not needed for XFillPolygon)
498 xpoints1
[i
].x
= xpoints1
[0].x
;
499 xpoints1
[i
].y
= xpoints1
[0].y
;
500 xpoints2
[i
].x
= xpoints2
[0].x
;
501 xpoints2
[i
].y
= xpoints2
[0].y
;
503 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
506 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
507 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
, Complex
, 0);
508 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, EvenOddRule
); // default mode
509 if (m_window
&& m_window
->GetBackingPixmap())
511 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
,
512 fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
513 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
, Complex
, 0);
514 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
, EvenOddRule
); // default mode
518 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
522 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
+ 1, 0);
524 if (m_window
&& m_window
->GetBackingPixmap())
525 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
+ 1, 0);
532 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
534 wxCHECK_RET( Ok(), "invalid dc" );
536 int xd
, yd
, wfd
, hfd
, wd
, hd
;
540 wfd
= XLOG2DEVREL(width
);
542 hfd
= YLOG2DEVREL(height
);
545 if (wfd
== 0 || hfd
== 0) return;
546 if (wd
< 0) { wd
= - wd
; xd
= xd
- wd
; }
547 if (hd
< 0) { hd
= - hd
; yd
= yd
- hd
; }
549 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
552 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wfd
, hfd
);
554 if (m_window
&& m_window
->GetBackingPixmap())
555 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
556 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
560 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
564 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
);
566 if (m_window
&& m_window
->GetBackingPixmap())
567 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
568 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
571 CalcBoundingBox (x
, y
);
572 CalcBoundingBox (x
+ width
, y
+ height
);
575 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
577 wxCHECK_RET( Ok(), "invalid dc" );
579 // If radius is negative, it's a proportion of the smaller dimension.
581 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
583 int xd
= XLOG2DEV (x
);
584 int yd
= YLOG2DEV (y
);
585 int rd
= XLOG2DEVREL ((long) radius
);
586 int wd
= XLOG2DEVREL (width
) - WX_GC_CF
;
587 int hd
= YLOG2DEVREL (height
) - WX_GC_CF
;
592 // If radius is zero use DrawRectangle() instead to avoid
593 // X drawing errors with small radii
596 DrawRectangle( x
, y
, width
, height
);
600 // Draw nothing if transformed w or h is 0
601 if (wd
== 0 || hd
== 0) return;
603 // CMB: adjust size if outline is drawn otherwise the result is
604 // 1 pixel too wide and high
605 if (m_pen
.GetStyle() != wxTRANSPARENT
)
611 // CMB: ensure dd is not larger than rectangle otherwise we
612 // get an hour glass shape
613 if (rw_d
> wd
) rw_d
= wd
;
614 if (rw_d
> hd
) rw_d
= hd
;
617 // For backing pixmap
618 int xd2
= XLOG2DEV_2 (x
);
619 int yd2
= YLOG2DEV_2 (y
);
620 int rd2
= XLOG2DEVREL ((long) radius
);
621 int wd2
= XLOG2DEVREL (width
) ;
622 int hd2
= YLOG2DEVREL (height
) ;
627 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
631 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
633 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
636 // Arcs start from 3 o'clock, positive angles anticlockwise
638 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
639 rw_d
, rh_d
, 90 * 64, 90 * 64);
641 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
642 // rw_d, rh_d, 0, 90 * 64);
643 rw_d
, rh_d
, 0, 91 * 64);
645 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
647 // rw_d, rh_d, 270 * 64, 90 * 64);
648 rw_d
, rh_d
, 269 * 64, 92 * 64);
650 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
651 rw_d
, rh_d
, 180 * 64, 90 * 64);
653 if (m_window
&& m_window
->GetBackingPixmap())
655 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
656 xd2
+ rd2
, yd2
, wd2
- rw_d2
, hd2
);
657 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
658 xd2
, yd2
+ rd2
, wd2
, hd2
- rh_d2
);
660 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
661 xd2
, yd2
, rw_d2
, rh_d2
, 90 * 64, 90 * 64);
662 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
663 xd2
+ wd2
- rw_d2
, yd2
,
664 // rw_d2, rh_d2, 0, 90 * 64);
665 rw_d2
, rh_d2
, 0, 91 * 64);
666 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
669 // rw_d2, rh_d2, 270 * 64, 90 * 64);
670 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
671 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
672 xd2
, yd2
+ hd2
- rh_d2
,
673 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
677 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
680 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
681 xd
+ wd
- rd
+ 1, yd
);
682 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
+ hd
,
683 xd
+ wd
- rd
, yd
+ hd
);
685 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
687 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
, yd
+ rd
,
688 xd
+ wd
, yd
+ hd
- rd
+ 1);
689 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
690 rw_d
, rh_d
, 90 * 64, 90 * 64);
691 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
692 // rw_d, rh_d, 0, 90 * 64);
693 rw_d
, rh_d
, 0, 91 * 64);
694 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
696 rw_d
, rh_d
, 269 * 64, 92 * 64);
697 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
698 rw_d
, rh_d
, 180 * 64, 90 * 64);
700 if (m_window
&& m_window
->GetBackingPixmap())
702 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
704 xd2
+ wd2
- rd2
+ 1, yd2
);
705 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
706 xd2
+ rd2
, yd2
+ hd2
,
707 xd2
+ wd2
- rd2
, yd2
+ hd2
);
709 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
711 xd2
, yd2
+ hd2
- rd2
);
712 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
713 xd2
+ wd2
, yd2
+ rd2
,
714 xd2
+ wd2
, yd2
+ hd2
- rd2
+ 1);
715 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
717 rw_d2
, rh_d2
, 90 * 64, 90 * 64);
718 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
719 xd2
+ wd2
- rw_d2
, yd2
,
720 // rw_d2, rh_d2, 0, 90 * 64);
721 rw_d2
, rh_d2
, 0, 91 * 64);
722 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
725 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
726 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
727 xd2
, yd2
+ hd2
- rh_d2
,
728 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
731 CalcBoundingBox (x
, y
);
732 CalcBoundingBox (x
+ width
, y
+ height
);
735 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
737 wxCHECK_RET( Ok(), "invalid dc" );
739 // Check for negative width and height
752 static const int angle
= 23040;
758 wd
= XLOG2DEVREL(width
) ;
759 hd
= YLOG2DEVREL(height
) ;
761 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
764 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
765 if (m_window
&& m_window
->GetBackingPixmap())
766 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
767 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
768 XLOG2DEVREL (width
) - WX_GC_CF
,
769 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
772 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
776 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
777 if (m_window
&& m_window
->GetBackingPixmap())
778 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
779 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
780 XLOG2DEVREL (width
) - WX_GC_CF
,
781 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
783 CalcBoundingBox (x
, y
);
784 CalcBoundingBox (x
+ width
, y
+ height
);
788 bool wxWindowDC::CanDrawBitmap() const
790 wxCHECK_MSG( Ok(), false, "invalid dc" );
795 // TODO: use scaled Blit e.g. as per John Price's implementation
796 // in Contrib/Utilities
797 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
,
798 wxCoord width
, wxCoord height
,
799 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
,
800 int rop
, bool useMask
,
801 wxCoord xsrcMask
, wxCoord ysrcMask
)
803 wxCHECK_MSG( Ok(), false, "invalid dc" );
805 wxWindowDC
* sourceDC
= wxDynamicCast(source
, wxWindowDC
);
807 wxASSERT_MSG( sourceDC
, "Blit source DC must be wxWindowDC or derived class." );
809 // Be sure that foreground pixels (1) of the Icon will be painted with
810 // foreground colour. [m_textForegroundColour] Background pixels (0)
811 // will be painted with backgound colour (m_textBackgroundColour)
812 // Using ::SetPen is horribly slow, so avoid doing it
813 int oldBackgroundPixel
= -1;
814 int oldForegroundPixel
= -1;
816 if (m_textBackgroundColour
.Ok())
818 oldBackgroundPixel
= m_backgroundPixel
;
819 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
821 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
822 if (m_window
&& m_window
->GetBackingPixmap())
823 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
826 if (m_textForegroundColour
.Ok())
828 oldForegroundPixel
= m_currentColour
.GetPixel();
830 if( m_textForegroundColour
.GetPixel() <= -1 )
831 CalculatePixel( m_textForegroundColour
,
832 m_textForegroundColour
, true);
834 int pixel
= m_textForegroundColour
.GetPixel();
836 SetForegroundPixelWithLogicalFunction(pixel
);
839 // Do bitmap scaling if necessary
841 wxBitmap
*scaledBitmap
= (wxBitmap
*) NULL
;
842 Pixmap sourcePixmap
= (Pixmap
) NULL
;
843 double scaleX
, scaleY
;
844 GetUserScale(& scaleX
, & scaleY
);
847 /* TODO: use the mask origin when drawing transparently */
848 if (xsrcMask
== -1 && ysrcMask
== -1)
850 xsrcMask
= xsrc
; ysrcMask
= ysrc
;
853 // Sorry, can't scale masks just yet
854 if (!useMask
&& (scaleX
!= 1.0 || scaleY
!= 1.0) && sourceDC
->IsKindOf(CLASSINFO(wxMemoryDC
)))
856 wxMemoryDC
* memDC
= (wxMemoryDC
*) sourceDC
;
857 wxBitmap
& bitmap
= memDC
->GetBitmap();
859 wxASSERT_MSG( (bitmap
.Ok()), "Bad source bitmap in wxWindowDC::Blit");
861 wxImage image
= bitmap
.ConvertToImage();
864 sourcePixmap
= (Pixmap
) bitmap
.GetDrawable();
868 int scaledW
= (int) (bitmap
.GetWidth() * scaleX
);
869 int scaledH
= (int) (bitmap
.GetHeight() * scaleY
);
871 image
= image
.Scale(scaledW
, scaledH
);
872 scaledBitmap
= new wxBitmap(image
);
873 sourcePixmap
= (Pixmap
) scaledBitmap
->GetDrawable();
877 sourcePixmap
= (Pixmap
) sourceDC
->m_pixmap
;
879 if (m_pixmap
&& sourcePixmap
)
882 int orig
= m_logicalFunction
;
884 SetLogicalFunction (rop
);
886 if (m_display
!= sourceDC
->m_display
)
888 XImage
*cache
= NULL
;
890 if (m_window
&& m_window
->GetBackingPixmap())
891 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
,
892 (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
894 source
->LogicalToDeviceX (xsrc
),
895 source
->LogicalToDeviceY (ysrc
),
896 source
->LogicalToDeviceXRel(width
),
897 source
->LogicalToDeviceYRel(height
),
898 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
),
901 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
903 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
904 wxBitmap
& sel
= memDC
->GetBitmap();
905 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetBitmap() )
907 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap());
908 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
912 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
913 source
->LogicalToDeviceX (xsrc
),
914 source
->LogicalToDeviceY (ysrc
),
915 source
->LogicalToDeviceXRel(width
),
916 source
->LogicalToDeviceYRel(height
),
917 XLOG2DEV (xdest
), YLOG2DEV (ydest
),
923 XSetRegion ((Display
*) m_display
, (GC
) m_gc
,
924 (Region
) m_clipRegion
);
926 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
928 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
932 { //XGCValues values;
933 //XGetGCValues((Display*)m_display, (GC)m_gc, GCForeground, &values);
935 if (m_window
&& m_window
->GetBackingPixmap())
937 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1
938 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetBitmap().GetDepth() == 1)
940 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
941 source
->LogicalToDeviceX (xsrc
),
942 source
->LogicalToDeviceY (ysrc
),
943 source
->LogicalToDeviceXRel(width
),
944 source
->LogicalToDeviceYRel(height
),
945 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 1);
949 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
950 source
->LogicalToDeviceX (xsrc
),
951 source
->LogicalToDeviceY (ysrc
),
952 source
->LogicalToDeviceXRel(width
),
953 source
->LogicalToDeviceYRel(height
),
954 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
));
957 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
959 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
960 wxBitmap
& sel
= memDC
->GetBitmap();
961 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetBitmap() )
963 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap());
964 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
968 // Check if we're copying from a mono bitmap
969 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) &&
970 ((wxMemoryDC
*)source
)->GetBitmap().Ok() && (((wxMemoryDC
*)source
)->GetBitmap().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 wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1030 wxCHECK_RET( Ok(), "invalid dc" );
1032 // Since X draws from the baseline of the text, must add the text height
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
);
1050 slen
= strlen(text
);
1054 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1055 int direction
, descent
;
1056 XCharStruct overall_return
;
1059 (void)XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*)(const char*) text
, slen
, &direction
,
1060 &ascent
, &descent
, &overall_return
);
1063 (void)XTextExtents((XFontStruct
*) pFontStruct
,
1064 wxConstCast(text
.c_str(), char),
1066 &ascent
, &descent
, &overall_return
);
1068 cx
= overall_return
.width
;
1069 cy
= ascent
+ descent
;
1072 // First draw a rectangle representing the text background, if a text
1073 // background is specified
1074 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1076 wxColour oldPenColour
= m_currentColour
;
1077 m_currentColour
= m_textBackgroundColour
;
1078 bool sameColour
= (oldPenColour
.Ok () && m_textBackgroundColour
.Ok () &&
1079 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1080 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1081 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1083 // This separation of the big && test required for gcc2.7/HP UX 9.02
1084 // or pixel value can be corrupted!
1085 sameColour
= (sameColour
&&
1086 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1088 if (!sameColour
|| !GetOptimization())
1090 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1091 m_currentColour
= m_textBackgroundColour
;
1093 // Set the GC to the required colour
1096 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1097 if (m_window
&& m_window
->GetBackingPixmap())
1098 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1102 m_textBackgroundColour
= oldPenColour
;
1104 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1105 if (m_window
&& m_window
->GetBackingPixmap())
1106 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1107 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1110 // Now set the text foreground and draw the text
1111 if (m_textForegroundColour
.Ok ())
1113 wxColour oldPenColour
= m_currentColour
;
1114 m_currentColour
= m_textForegroundColour
;
1115 bool sameColour
= (oldPenColour
.Ok () && m_currentColour
.Ok () &&
1116 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1117 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1118 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1119 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1121 if (!sameColour
|| !GetOptimization())
1123 int pixel
= CalculatePixel(m_textForegroundColour
,
1124 m_currentColour
, false);
1126 // Set the GC to the required colour
1129 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1130 if (m_window
&& m_window
->GetBackingPixmap())
1131 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1135 m_textForegroundColour
= oldPenColour
;
1138 // We need to add the ascent, not the whole height, since X draws at the
1139 // point above the descender.
1142 XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1143 (XChar2b
*)(char*) (const char*) text
, slen
);
1146 XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
, text
, slen
);
1148 if (m_window
&& m_window
->GetBackingPixmap()) {
1151 XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1152 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1153 (XChar2b
*)(char*) (const char*) text
, slen
);
1156 XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1157 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1158 wxConstCast(text
.c_str(), char), slen
);
1161 // restore fill style
1162 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, gcV
.fill_style
);
1163 if (m_window
&& m_window
->GetBackingPixmap())
1164 XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
,
1165 gcBackingV
.fill_style
);
1168 GetTextExtent (text
, &w
, &h
);
1169 CalcBoundingBox (x
+ w
, y
+ h
);
1170 CalcBoundingBox (x
, y
);
1173 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
,
1178 DrawText(text
, x
, y
);
1182 wxCHECK_RET( Ok(), "invalid dc" );
1184 int oldBackgroundPixel
= -1;
1185 int oldForegroundPixel
= -1;
1186 int foregroundPixel
= -1;
1187 int backgroundPixel
= -1;
1189 if (m_textBackgroundColour
.Ok())
1191 oldBackgroundPixel
= m_backgroundPixel
;
1192 backgroundPixel
= m_textBackgroundColour
.AllocColour(m_display
);
1194 if (m_textForegroundColour
.Ok())
1196 oldForegroundPixel
= m_currentColour
.GetPixel();
1198 if( m_textForegroundColour
.GetPixel() <= -1 )
1199 CalculatePixel( m_textForegroundColour
,
1200 m_textForegroundColour
, true);
1202 foregroundPixel
= m_textForegroundColour
.GetPixel();
1205 // Since X draws from the baseline of the text, must add the text height
1209 int slen
= text
.length();
1213 // Calculate text extent.
1214 WXFontStructPtr pFontStruct
=
1215 m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1216 int direction
, descent
;
1217 XCharStruct overall_return
;
1220 (void)XTextExtents16((XFontStruct
*) pFontStruct
,
1221 (XChar2b
*)(const char*) text
,
1223 &ascent
, &descent
, &overall_return
);
1226 (void)XTextExtents((XFontStruct
*) pFontStruct
,
1227 wxConstCast(text
.c_str(), char),
1229 &ascent
, &descent
, &overall_return
);
1231 cx
= overall_return
.width
;
1232 cy
= ascent
+ descent
;
1235 wxBitmap
src(cx
, cy
);
1237 dc
.SelectObject(src
);
1238 dc
.SetFont(GetFont());
1239 dc
.SetBackground(*wxWHITE_BRUSH
);
1240 dc
.SetBrush(*wxBLACK_BRUSH
);
1242 dc
.DrawText(text
, 0, 0);
1243 dc
.SetFont(wxNullFont
);
1245 // Calculate the size of the rotated bounding box.
1246 double dx
= cos(angle
/ 180.0 * M_PI
);
1247 double dy
= sin(angle
/ 180.0 * M_PI
);
1248 double x4
= cy
* dy
;
1249 double y4
= cy
* dx
;
1250 double x3
= cx
* dx
;
1251 double y3
= -cx
* dy
;
1252 double x2
= x3
+ x4
;
1253 double y2
= y3
+ y4
;
1257 // Create image from the source bitmap after writing the text into it.
1258 wxImage image
= src
.ConvertToImage();
1260 int minx
= roundmin(0, roundmin(x4
, roundmin(x2
, x3
)));
1261 int miny
= roundmin(0, roundmin(y4
, roundmin(y2
, y3
)));
1262 int maxx
= roundmax(0, roundmax(x4
, roundmax(x2
, x3
)));
1263 int maxy
= roundmax(0, roundmax(y4
, roundmax(y2
, y3
)));
1265 bool lastFore
= false, lastBack
= false;
1267 // This rotates counterclockwise around the top left corner.
1268 for (int rx
= minx
; rx
< maxx
; rx
++)
1270 for (int ry
= miny
; ry
< maxy
; ry
++)
1272 // transform dest coords to source coords
1273 int sx
= (int) (rx
* dx
- ry
* dy
+ 0.5);
1274 int sy
= - (int) (-ry
* dx
- rx
* dy
+ 0.5);
1275 if (sx
>= 0 && sx
< cx
&& sy
>= 0 && sy
< cy
)
1277 bool textPixel
= image
.GetRed(sx
, sy
) == 0;
1279 if (!textPixel
&& m_backgroundMode
!= wxSOLID
)
1282 wxCoord ox
= (wxCoord
) (x1
+ rx
),
1283 oy
= (wxCoord
) (y1
+ ry
);
1284 // draw black pixels, ignore white ones (i.e. transparent b/g)
1285 if (textPixel
&& !lastFore
)
1287 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1292 else if (!textPixel
&& !lastBack
)
1294 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1300 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
,
1301 (GC
) m_gc
, XLOG2DEV (ox
), YLOG2DEV (oy
));
1302 if (m_window
&& m_window
->GetBackingPixmap())
1303 XDrawPoint ((Display
*) m_display
,
1304 (Pixmap
) m_window
->GetBackingPixmap(),
1306 XLOG2DEV_2 (ox
), YLOG2DEV_2 (oy
));
1311 if (oldBackgroundPixel
> -1)
1313 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
);
1314 if (m_window
&& m_window
->GetBackingPixmap())
1315 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1316 oldBackgroundPixel
);
1318 if (oldForegroundPixel
> -1)
1320 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
);
1321 if (m_window
&& m_window
->GetBackingPixmap())
1322 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1323 oldForegroundPixel
);
1326 CalcBoundingBox (minx
, miny
);
1327 CalcBoundingBox (maxx
, maxy
);
1330 bool wxWindowDC::CanGetTextExtent() const
1335 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1336 wxCoord
*descent
, wxCoord
*externalLeading
,
1337 wxFont
*font
) const
1339 wxCHECK_RET( Ok(), "invalid dc" );
1341 wxFont
* theFont
= font
;
1343 theFont
= (wxFont
*)&m_font
; // const_cast
1347 // TODO: this should be an error log function
1348 wxFAIL_MSG("set a valid font before calling GetTextExtent!");
1350 if (width
) *width
= -1;
1351 if (height
) *height
= -1;
1355 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1357 int direction
, ascent
, descent2
;
1358 XCharStruct overall
;
1363 slen
= str16len(string
);
1366 slen
= strlen(string
);
1370 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1371 &ascent
, &descent2
, &overall
);
1374 XTextExtents((XFontStruct
*) pFontStruct
,
1375 wxConstCast(string
.c_str(), char), slen
, &direction
,
1376 &ascent
, &descent2
, &overall
);
1378 if (width
) *width
= XDEV2LOGREL (overall
.width
);
1379 if (height
) *height
= YDEV2LOGREL (ascent
+ descent2
);
1381 *descent
= descent2
;
1382 if (externalLeading
)
1383 *externalLeading
= 0;
1386 wxCoord
wxWindowDC::GetCharWidth() const
1388 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1389 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1391 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
* m_logicalScaleY
, m_display
);
1393 int direction
, ascent
, descent
;
1394 XCharStruct overall
;
1395 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1396 &descent
, &overall
);
1397 return XDEV2LOGREL(overall
.width
);
1400 wxCoord
wxWindowDC::GetCharHeight() const
1402 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1403 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1405 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1407 int direction
, ascent
, descent
;
1408 XCharStruct overall
;
1409 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1410 &descent
, &overall
);
1411 // return XDEV2LOGREL(overall.ascent + overall.descent);
1412 return XDEV2LOGREL(ascent
+ descent
);
1415 void wxWindowDC::DoGetSize( int *width
, int *height
) const
1421 if( m_window
->GetBackingPixmap() )
1423 w
= m_window
->GetPixmapWidth();
1424 h
= m_window
->GetPixmapHeight();
1427 m_window
->GetSize( &w
, &h
);
1430 if( width
) *width
= w
;
1431 if( height
) *height
= h
;
1434 void wxWindowDC::Clear()
1436 wxCHECK_RET( Ok(), "invalid dc" );
1438 wxRect
rect( GetSize() );
1442 void wxWindowDC::Clear(const wxRect
& rect
)
1444 wxCHECK_RET( Ok(), "invalid dc" );
1446 int x
= rect
.x
; int y
= rect
.y
;
1447 int w
= rect
.width
; int h
= rect
.height
;
1449 wxBrush saveBrush
= m_brush
;
1450 SetBrush (m_backgroundBrush
);
1452 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1455 if (m_window
&& m_window
->GetBackingPixmap())
1456 XFillRectangle ((Display
*) m_display
,
1457 (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1460 m_brush
= saveBrush
;
1463 void wxWindowDC::SetFont( const wxFont
&font
)
1465 wxCHECK_RET( Ok(), "invalid dc" );
1471 if ((m_oldFont
!= (WXFont
) 0) && ((wxCoord
) m_oldFont
!= -1))
1473 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
1475 if (m_window
&& m_window
->GetBackingPixmap())
1476 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
1481 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1483 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1484 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1486 if (m_window
&& m_window
->GetBackingPixmap())
1487 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1490 void wxWindowDC::SetForegroundPixelWithLogicalFunction(int pixel
)
1492 if (m_logicalFunction
== wxXOR
)
1495 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1496 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1497 pixel
^ values
.background
);
1498 if (m_window
&& m_window
->GetBackingPixmap())
1499 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1500 pixel
^ values
.background
);
1504 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1505 if (m_window
&& m_window
->GetBackingPixmap())
1506 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1510 int wxWindowDC::CalculatePixel(wxColour
& colour
, wxColour
& curCol
,
1511 bool roundToWhite
) const
1513 const unsigned char wp
= (unsigned char)255;
1516 if(!m_colour
) // Mono display
1518 unsigned char red
= colour
.Red ();
1519 unsigned char blue
= colour
.Blue ();
1520 unsigned char green
= colour
.Green ();
1522 if((red
== wp
&& blue
== wp
&& green
== wp
) ||
1523 // not black and roundToWhite was specified
1524 ((red
!= 0 || blue
!= 0 || green
!= 0) && roundToWhite
))
1527 pixel
= (int)WhitePixel((Display
*) m_display
,
1528 DefaultScreen((Display
*) m_display
));
1529 curCol
.SetPixel(pixel
);
1530 colour
.SetPixel(pixel
);
1535 pixel
= (int)BlackPixel((Display
*) m_display
,
1536 DefaultScreen((Display
*) m_display
));
1537 curCol
.SetPixel(pixel
);
1538 colour
.SetPixel(pixel
);
1544 pixel
= colour
.AllocColour((Display
*) m_display
);
1545 curCol
.SetPixel(pixel
);
1551 void wxWindowDC::SetPen( const wxPen
&pen
)
1553 wxCHECK_RET( Ok(), "invalid dc" );
1559 wxBitmap oldStipple
= m_currentStipple
;
1560 int oldStyle
= m_currentStyle
;
1561 int oldFill
= m_currentFill
;
1562 int old_pen_width
= m_currentPenWidth
;
1563 int old_pen_join
= m_currentPenJoin
;
1564 int old_pen_cap
= m_currentPenCap
;
1565 int old_pen_nb_dash
= m_currentPenDashCount
;
1566 wxX11Dash
*old_pen_dash
= m_currentPenDash
;
1568 wxColour oldPenColour
= m_currentColour
;
1569 m_currentColour
= m_pen
.GetColour ();
1570 m_currentStyle
= m_pen
.GetStyle ();
1571 m_currentFill
= m_pen
.GetStyle (); // TODO?
1572 m_currentPenWidth
= m_pen
.GetWidth ();
1573 m_currentPenJoin
= m_pen
.GetJoin ();
1574 m_currentPenCap
= m_pen
.GetCap ();
1575 m_currentPenDashCount
= m_pen
.GetDashCount();
1576 m_currentPenDash
= (wxX11Dash
*)m_pen
.GetDash();
1578 if (m_currentStyle
== wxSTIPPLE
)
1579 m_currentStipple
= * m_pen
.GetStipple ();
1581 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1582 oldFill
== m_currentFill
&&
1583 old_pen_join
== m_currentPenJoin
&&
1584 old_pen_cap
== m_currentPenCap
&&
1585 old_pen_nb_dash
== m_currentPenDashCount
&&
1586 old_pen_dash
== m_currentPenDash
&&
1587 old_pen_width
== m_currentPenWidth
);
1589 bool sameColour
= (oldPenColour
.Ok () &&
1590 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1591 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1592 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1593 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1595 if (!sameStyle
|| !GetOptimization())
1597 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1598 if (scaled_width
< 0)
1604 static const wxX11Dash dotted
[] = {2, 5};
1605 static const wxX11Dash short_dashed
[] = {4, 4};
1606 static const wxX11Dash long_dashed
[] = {4, 8};
1607 static const wxX11Dash dotted_dashed
[] = {6, 6, 2, 6};
1609 // We express dash pattern in pen width unit, so we are
1610 // independent of zoom factor and so on...
1612 const wxX11Dash
*req_dash
;
1614 switch (m_pen
.GetStyle ())
1617 req_nb_dash
= m_currentPenDashCount
;
1618 req_dash
= m_currentPenDash
;
1619 style
= LineOnOffDash
;
1624 style
= LineOnOffDash
;
1628 req_dash
= short_dashed
;
1629 style
= LineOnOffDash
;
1633 req_dash
= long_dashed
;
1634 style
= LineOnOffDash
;
1638 req_dash
= dotted_dashed
;
1639 style
= LineOnOffDash
;
1646 req_dash
= (wxX11Dash
*)NULL
;
1650 if (req_dash
&& req_nb_dash
)
1652 wxX11Dash
*real_req_dash
= new wxX11Dash
[req_nb_dash
];
1655 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1656 for (int i
= 0; i
< req_nb_dash
; i
++)
1657 real_req_dash
[i
] = req_dash
[i
] * factor
;
1658 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1660 if (m_window
&& m_window
->GetBackingPixmap())
1661 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1662 delete[]real_req_dash
;
1666 // No Memory. We use non-scaled dash pattern...
1667 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1669 if (m_window
&& m_window
->GetBackingPixmap())
1670 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1674 switch (m_pen
.GetCap ())
1676 case wxCAP_PROJECTING
:
1677 cap
= CapProjecting
;
1684 cap
= (scaled_width
<= 1) ? CapNotLast
: CapRound
;
1688 switch (m_pen
.GetJoin ())
1702 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1704 if (m_window
&& m_window
->GetBackingPixmap())
1705 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1708 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1712 oldStipple
= wxNullBitmap
; // For later reset!!
1714 switch (m_currentFill
)
1716 case wxBDIAGONAL_HATCH
:
1717 if (bdiag
== (Pixmap
) 0)
1718 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1719 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1720 bdiag_bits
, bdiag_width
, bdiag_height
);
1723 case wxFDIAGONAL_HATCH
:
1724 if (fdiag
== (Pixmap
) 0)
1725 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1726 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1727 fdiag_bits
, fdiag_width
, fdiag_height
);
1731 if (cross
== (Pixmap
) 0)
1732 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1733 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1734 cross_bits
, cross_width
, cross_height
);
1737 case wxHORIZONTAL_HATCH
:
1738 if (horiz
== (Pixmap
) 0)
1739 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1740 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1741 horiz_bits
, horiz_width
, horiz_height
);
1744 case wxVERTICAL_HATCH
:
1745 if (verti
== (Pixmap
) 0)
1746 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1747 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1748 verti_bits
, verti_width
, verti_height
);
1751 case wxCROSSDIAG_HATCH
:
1753 if (cdiag
== (Pixmap
) 0)
1754 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1755 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1756 cdiag_bits
, cdiag_width
, cdiag_height
);
1760 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1762 if (m_window
&& m_window
->GetBackingPixmap())
1763 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1765 else if (m_currentStipple
.Ok()
1766 && ((m_currentStipple
!= oldStipple
) || !GetOptimization()))
1768 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetDrawable());
1770 if (m_window
&& m_window
->GetBackingPixmap())
1771 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetDrawable());
1774 if ((m_currentFill
!= oldFill
) || !GetOptimization())
1778 if (m_currentFill
== wxSTIPPLE
)
1779 fill_style
= FillStippled
;
1780 else if (IS_HATCH (m_currentFill
))
1781 fill_style
= FillStippled
;
1783 fill_style
= FillSolid
;
1784 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1785 if (m_window
&& m_window
->GetBackingPixmap())
1786 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1789 // must test m_logicalFunction, because it involves background!
1790 if (!sameColour
|| !GetOptimization()
1791 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1794 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1795 pixel
= m_backgroundPixel
;
1798 pixel
= CalculatePixel(m_pen
.GetColour(), m_currentColour
, false);
1801 // Finally, set the GC to the required colour
1803 SetForegroundPixelWithLogicalFunction(pixel
);
1806 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1811 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1813 wxCHECK_RET( Ok(), "invalid dc" );
1817 if (!m_brush
.Ok() || m_brush
.GetStyle () == wxTRANSPARENT
)
1820 int oldFill
= m_currentFill
;
1821 wxBitmap oldStipple
= m_currentStipple
;
1823 m_autoSetting
|= 0x1;
1825 m_currentFill
= m_brush
.GetStyle ();
1826 if (m_currentFill
== wxSTIPPLE
)
1827 m_currentStipple
= * m_brush
.GetStipple ();
1829 wxColour
oldBrushColour(m_currentColour
);
1830 m_currentColour
= m_brush
.GetColour ();
1832 bool sameColour
= (oldBrushColour
.Ok () &&
1833 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1834 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1835 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1836 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1838 int stippleDepth
= -1;
1840 if ((oldFill
!= m_brush
.GetStyle ()) || !GetOptimization())
1842 switch (brush
.GetStyle ())
1847 stippleDepth
= m_currentStipple
.GetDepth();
1849 case wxBDIAGONAL_HATCH
:
1850 case wxCROSSDIAG_HATCH
:
1851 case wxFDIAGONAL_HATCH
:
1853 case wxHORIZONTAL_HATCH
:
1854 case wxVERTICAL_HATCH
:
1856 if (stippleDepth
== -1) stippleDepth
= 1;
1858 // Chris Breeze 23/07/97: use background mode to
1859 // determine whether fill style should be solid or
1861 int style
= stippleDepth
== 1 ?
1862 (m_backgroundMode
== wxSOLID
?
1863 FillOpaqueStippled
: FillStippled
) :
1865 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1866 if (m_window
&& m_window
->GetBackingPixmap())
1867 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1872 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1873 if (m_window
&& m_window
->GetBackingPixmap())
1874 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
,
1879 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1883 switch (m_currentFill
)
1885 case wxBDIAGONAL_HATCH
:
1886 if (bdiag
== (Pixmap
) 0)
1887 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1888 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1889 bdiag_bits
, bdiag_width
, bdiag_height
);
1892 case wxFDIAGONAL_HATCH
:
1893 if (fdiag
== (Pixmap
) 0)
1894 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1895 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1896 fdiag_bits
, fdiag_width
, fdiag_height
);
1900 if (cross
== (Pixmap
) 0)
1901 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1902 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1903 cross_bits
, cross_width
, cross_height
);
1906 case wxHORIZONTAL_HATCH
:
1907 if (horiz
== (Pixmap
) 0)
1908 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1909 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1910 horiz_bits
, horiz_width
, horiz_height
);
1913 case wxVERTICAL_HATCH
:
1914 if (verti
== (Pixmap
) 0)
1915 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1916 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1917 verti_bits
, verti_width
, verti_height
);
1920 case wxCROSSDIAG_HATCH
:
1922 if (cdiag
== (Pixmap
) 0)
1923 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1924 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1925 cdiag_bits
, cdiag_width
, cdiag_height
);
1929 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1931 if (m_window
&& m_window
->GetBackingPixmap())
1932 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1934 // X can forget the stipple value when resizing a window (apparently)
1935 // so always set the stipple.
1936 else if (m_currentFill
!= wxSOLID
&& m_currentFill
!= wxTRANSPARENT
&&
1937 m_currentStipple
.Ok()) // && m_currentStipple != oldStipple)
1939 if (m_currentStipple
.GetDepth() == 1)
1941 XSetStipple ((Display
*) m_display
, (GC
) m_gc
,
1942 (Pixmap
) m_currentStipple
.GetDrawable());
1943 if (m_window
&& m_window
->GetBackingPixmap())
1944 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
,
1945 (Pixmap
) m_currentStipple
.GetDrawable());
1949 XSetTile ((Display
*) m_display
, (GC
) m_gc
,
1950 (Pixmap
) m_currentStipple
.GetDrawable());
1951 if (m_window
&& m_window
->GetBackingPixmap())
1952 XSetTile ((Display
*) m_display
,(GC
) m_gcBacking
,
1953 (Pixmap
) m_currentStipple
.GetDrawable());
1957 // must test m_logicalFunction, because it involves background!
1958 if (!sameColour
|| !GetOptimization() || m_logicalFunction
== wxXOR
)
1960 int pixel
= CalculatePixel(m_brush
.GetColour(), m_currentColour
, true);
1963 SetForegroundPixelWithLogicalFunction(pixel
);
1966 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1969 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1971 wxCHECK_RET( Ok(), "invalid dc" );
1973 m_backgroundBrush
= brush
;
1975 if (!m_backgroundBrush
.Ok())
1978 m_backgroundPixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
1980 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
1981 // And Blit,... (Any fct that use XCopyPlane, in fact.)
1982 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, m_backgroundPixel
);
1983 if (m_window
&& m_window
->GetBackingPixmap())
1984 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1988 void wxWindowDC::SetLogicalFunction( int function
)
1990 wxCHECK_RET( Ok(), "invalid dc" );
1995 if (m_logicalFunction
== function
)
2001 x_function
= GXclear
;
2007 x_function
= GXinvert
;
2010 x_function
= GXorReverse
;
2013 x_function
= GXandReverse
;
2022 x_function
= GXandInverted
;
2025 x_function
= GXnoop
;
2031 x_function
= GXequiv
;
2034 x_function
= GXcopyInverted
;
2037 x_function
= GXorInverted
;
2040 x_function
= GXnand
;
2047 x_function
= GXcopy
;
2051 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
2052 if (m_window
&& m_window
->GetBackingPixmap())
2053 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
2055 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
2056 /* MATTHEW: [9] Need to redo pen simply */
2057 m_autoSetting
|= 0x2;
2059 m_logicalFunction
= function
;
2063 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2065 wxCHECK_RET( Ok(), "invalid dc" );
2067 m_textForegroundColour
= col
;
2070 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2072 wxCHECK_RET( Ok(), "invalid dc" );
2074 m_textBackgroundColour
= col
;
2077 void wxWindowDC::SetBackgroundMode( int mode
)
2079 m_backgroundMode
= mode
;
2082 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2087 /* Use GetXColormap */
2088 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2089 (Colormap
) palette
.GetXColormap());
2091 /* Use wxGetMainColormap */
2092 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2093 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2097 static void wxCopyRegion( WXRegion src
, WXRegion
& dst
)
2100 dst
= XCreateRegion();
2101 XUnionRegion( (Region
)src
, (Region
)src
, (Region
)dst
);
2104 // Helper function; userRegion is the region set by calling SetClippingRegion
2105 void wxWindowDC::SetDCClipping( WXRegion userRegion
)
2107 bool hasUpdateRegion
= m_window
&& m_window
->GetUpdateRegion().Ok();
2108 // this means that we should start the clip region from scratch,
2109 // or from the update region, if any
2113 XDestroyRegion( (Region
)m_clipRegion
);
2114 m_clipRegion
= (WXRegion
)NULL
;
2116 if( hasUpdateRegion
)
2117 wxCopyRegion( m_window
->GetUpdateRegion().GetX11Region(),
2120 // intersect the user region, if any, with the
2121 // exisiting clip region
2122 else // if( userRegion )
2125 wxCopyRegion( userRegion
, m_clipRegion
);
2127 XIntersectRegion( (Region
)m_clipRegion
,
2128 (Region
)userRegion
, (Region
)m_clipRegion
);
2132 XSetRegion( (Display
*)m_display
, (GC
)m_gc
, (Region
)m_clipRegion
);
2134 XSetClipMask( (Display
*)m_display
, (GC
)m_gc
, None
);
2137 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
,
2138 wxCoord width
, wxCoord height
)
2140 wxDC::DoSetClippingRegion( x
, y
, width
, height
);
2142 wxRegion
temp(x
, y
, width
, height
);
2144 SetDCClipping(temp
.GetX11Region());
2146 // Needs to work differently for Pixmap: without this,
2147 // there's a nasty (Display*) m_display bug. 8/12/94
2148 if (m_window
&& m_window
->GetBackingPixmap())
2150 XRectangle rects
[1];
2151 rects
[0].x
= XLOG2DEV_2(x
);
2152 rects
[0].y
= YLOG2DEV_2(y
);
2153 rects
[0].width
= XLOG2DEVREL(width
);
2154 rects
[0].height
= YLOG2DEVREL(height
);
2155 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
,
2156 0, 0, rects
, 1, Unsorted
);
2160 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2162 wxRect box
= region
.GetBox();
2164 wxDC::DoSetClippingRegion( box
.x
, box
.y
, box
.width
, box
.height
);
2166 SetDCClipping(region
.GetX11Region());
2168 // Needs to work differently for Pixmap: without this,
2169 // there's a nasty (Display*) m_display bug. 8/12/94
2170 if (m_window
&& m_window
->GetBackingPixmap())
2172 XRectangle rects
[1];
2173 rects
[0].x
= XLOG2DEV_2(box
.x
);
2174 rects
[0].y
= YLOG2DEV_2(box
.y
);
2175 rects
[0].width
= XLOG2DEVREL(box
.width
);
2176 rects
[0].height
= YLOG2DEVREL(box
.height
);
2177 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
,
2178 0, 0, rects
, 1, Unsorted
);
2183 void wxWindowDC::DestroyClippingRegion()
2185 wxDC::DestroyClippingRegion();
2187 SetDCClipping(NULL
);
2189 if (m_window
&& m_window
->GetBackingPixmap())
2190 XSetClipMask ((Display
*) m_display
, (GC
) m_gcBacking
, None
);
2193 // Resolution in pixels per logical inch
2194 wxSize
wxWindowDC::GetPPI() const
2197 return wxSize(100, 100);
2200 int wxWindowDC::GetDepth() const
2209 // ----------------------------------------------------------------------------
2211 // ----------------------------------------------------------------------------
2213 wxPaintDC::wxPaintDC(wxWindow
* win
) : wxWindowDC(win
)
2215 // Set the clipping region.to the update region
2216 SetDCClipping((WXRegion
)NULL
);
2219 wxPaintDC::~wxPaintDC()
2222 m_window
->ClearUpdateRegion();
2223 SetDCClipping((WXRegion
)NULL
);
2226 // ----------------------------------------------------------------------------
2227 // private functions
2228 // ----------------------------------------------------------------------------
2231 Used when copying between drawables on different (Display*) m_displays. Not
2232 very fast, but better than giving up.
2235 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
2236 Drawable src
, Drawable dest
,
2239 unsigned int w
, unsigned int h
,
2240 int destx
, int desty
,
2241 bool more
, XImage
**cache
)
2243 XImage
*image
, *destimage
;
2244 Colormap destcm
, srccm
;
2245 static const int CACHE_SIZE
= 256;
2248 unsigned long cachesrc
[CACHE_SIZE
], cachedest
[CACHE_SIZE
];
2249 int k
, cache_pos
, all_cache
;
2251 if (!cache
|| !*cache
)
2252 image
= XGetImage(src_display
, src
, srcx
, srcy
, w
, h
, AllPlanes
, ZPixmap
);
2256 destimage
= XGetImage(dest_display
, dest
, destx
, desty
, w
, h
, AllPlanes
, ZPixmap
);
2258 srccm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) src_display
);
2259 destcm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dest_display
);
2264 for (i
= 0; i
< w
; i
++)
2265 for (j
= 0; j
< h
; j
++) {
2266 unsigned long pixel
;
2269 pixel
= XGetPixel(image
, i
, j
);
2270 for (k
= cache_pos
; k
--; )
2271 if (cachesrc
[k
] == pixel
) {
2272 pixel
= cachedest
[k
];
2276 for (k
= CACHE_SIZE
; k
-- > cache_pos
; )
2277 if (cachesrc
[k
] == pixel
) {
2278 pixel
= cachedest
[k
];
2282 cachesrc
[cache_pos
] = xcol
.pixel
= pixel
;
2283 XQueryColor(src_display
, srccm
, &xcol
);
2284 if (!XAllocColor(dest_display
, destcm
, &xcol
))
2286 cachedest
[cache_pos
] = pixel
= xcol
.pixel
;
2288 if (++cache_pos
>= CACHE_SIZE
) {
2294 XPutPixel(destimage
, i
, j
, pixel
);
2297 XPutImage(dest_display
, dest
, destgc
, destimage
, 0, 0, destx
, desty
, w
, h
);
2298 XDestroyImage(destimage
);
2303 XDestroyImage(image
);
2308 /* Helper function for 16-bit fonts */
2309 static int str16len(const char *s
)
2313 while (s
[0] && s
[1]) {