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
18 on 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
22 is used to indicate that a brush was recently used, and SetPen
23 must be called to reinstall the current pen's parameters.
24 If autoSetting includes 0x2, then the pens color may need
25 to be set based on XOR.
27 There is, unfortunately, some confusion between setting the
28 current pen/brush and actually installing the brush/pen parameters.
29 Both functionalies are perform by SetPen and SetBrush. C'est la vie.
33 #pragma implementation "dcclient.h"
36 #include "wx/dcclient.h"
37 #include "wx/dcmemory.h"
38 #include "wx/window.h"
44 #include "wx/motif/private.h"
53 static Pixmap bdiag
, cdiag
, fdiag
, cross
, horiz
, verti
;
55 //-----------------------------------------------------------------------------
57 //-----------------------------------------------------------------------------
59 #define RAD2DEG 57.2957795131
61 // Fudge factor. Obsolete?
62 // No. Robert Roebling
65 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
69 #if !USE_SHARED_LIBRARY
70 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
71 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxWindowDC
)
72 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
75 wxWindowDC::wxWindowDC(void)
78 m_gcBacking
= (WXGC
) 0;
80 m_backgroundPixel
= -1;
81 m_currentPenWidth
= 1;
82 m_currentPenJoin
= -1;
83 m_currentPenDashCount
= -1;
84 m_currentPenDash
= (char*) NULL
;
87 // m_currentBkMode = wxTRANSPARENT;
88 m_colour
= wxColourDisplay();
89 m_display
= (WXDisplay
*) NULL
;
90 m_currentRegion
= (WXRegion
) 0;
91 m_userRegion
= (WXRegion
) 0;
92 m_pixmap
= (WXPixmap
) 0;
94 m_oldFont
= (WXFont
) 0;
97 wxWindowDC::wxWindowDC( wxWindow
*window
)
99 wxASSERT_MSG( (window
!= (wxWindow
*) NULL
), "You must pass a valid wxWindow to wxWindowDC/wxClientDC/wxPaintDC constructor." );
103 m_gcBacking
= (WXGC
) 0;
104 m_backgroundPixel
= -1;
105 m_currentPenWidth
= 1;
106 m_currentPenJoin
= -1;
107 m_currentPenDashCount
= -1;
108 m_currentPenDash
= (char*) NULL
;
111 // m_currentBkMode = wxTRANSPARENT;
112 m_colour
= wxColourDisplay();
113 m_currentRegion
= (WXRegion
) 0;
114 m_userRegion
= (WXRegion
) 0;
118 m_display
= window
->GetXDisplay();
119 m_pixmap
= window
->GetXWindow();
120 Display
* display
= (Display
*) m_display
;
122 XSetWindowColormap (display
, (Pixmap
) m_pixmap
, (Colormap
) wxTheApp
->GetMainColormap(m_display
));
125 gcvalues
.foreground
= BlackPixel (display
, DefaultScreen (display
));
126 gcvalues
.background
= WhitePixel (display
, DefaultScreen (display
));
127 gcvalues
.graphics_exposures
= False
;
128 gcvalues
.line_width
= 1;
129 m_gc
= (WXGC
) XCreateGC (display
, RootWindow (display
, DefaultScreen (display
)),
130 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
,
133 if (m_window
->GetBackingPixmap())
135 m_gcBacking
= (WXGC
) XCreateGC (display
, RootWindow (display
,
136 DefaultScreen (display
)),
137 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
,
141 m_backgroundPixel
= (int) gcvalues
.background
;
143 // Get the current Font so we can set it back later
145 XGetGCValues((Display
*) m_display
, (GC
) m_gc
, GCFont
, &valReturn
);
146 m_oldFont
= (WXFont
) valReturn
.font
;
149 wxWindowDC::~wxWindowDC(void)
151 if (m_gc
&& (m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
153 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
155 if (m_window
&& m_window
->GetBackingPixmap())
156 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
160 XFreeGC ((Display
*) m_display
, (GC
) m_gc
);
164 XFreeGC ((Display
*) m_display
, (GC
) m_gcBacking
);
165 m_gcBacking
= (WXGC
) 0;
168 XDestroyRegion ((Region
) m_currentRegion
);
169 m_currentRegion
= (WXRegion
) 0;
172 XDestroyRegion ((Region
) m_userRegion
);
173 m_userRegion
= (WXRegion
) 0;
176 void wxWindowDC::FloodFill( long WXUNUSED(x1
), long WXUNUSED(y1
),
177 const wxColour
& WXUNUSED(col
), int WXUNUSED(style
) )
182 bool wxWindowDC::GetPixel( long WXUNUSED(x1
), long WXUNUSED(y1
), wxColour
*WXUNUSED(col
) ) const
188 void wxWindowDC::DrawLine( long x1
, long y1
, long x2
, long y2
)
192 int x1d
, y1d
, x2d
, y2d
;
194 // FreeGetPixelCache();
204 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x1d
, y1d
, x2d
, y2d
);
206 if (m_window
&& m_window
->GetBackingPixmap())
207 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
208 XLOG2DEV_2(x1
), YLOG2DEV_2(y1
),
209 XLOG2DEV_2(x2
), YLOG2DEV_2(y2
));
211 CalcBoundingBox(x1
, y1
);
212 CalcBoundingBox(x2
, y2
);
215 void wxWindowDC::CrossHair( long x
, long y
)
222 int xx
= XLOG2DEV (x
);
223 int yy
= YLOG2DEV (y
);
225 wxDisplaySize (&ww
, &hh
);
226 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, yy
,
228 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xx
, 0,
231 if (m_window
&& m_window
->GetBackingPixmap())
235 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
238 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
244 void wxWindowDC::DrawArc( long x1
, long y1
, long x2
, long y2
, long xc
, long yc
)
248 // FreeGetPixelCache();
250 int xx1
= XLOG2DEV (x1
);
251 int yy1
= YLOG2DEV (y1
);
252 int xx2
= XLOG2DEV (x2
);
253 int yy2
= YLOG2DEV (y2
);
254 int xxc
= XLOG2DEV (xc
);
255 int yyc
= YLOG2DEV (yc
);
256 int xxc_2
= XLOG2DEV_2 (xc
);
257 int yyc_2
= YLOG2DEV_2 (yc
);
261 double radius
= sqrt (dx
* dx
+ dy
* dy
);
262 long r
= (long) radius
;
264 double radius1
, radius2
;
266 if (xx1
== xx2
&& yy1
== yy2
)
271 else if (radius
== 0.0)
272 radius1
= radius2
= 0.0;
281 radius1
= -atan2 ((double) (yy1
- yyc
), (double) (xx1
- xxc
)) * 360.0 / (2 * M_PI
);
289 radius2
= -atan2 ((double) (yy2
- yyc
), (double) (xx2
- xxc
)) * 360.0 / (2 * M_PI
);
293 int alpha1
= (int) radius1
;
294 int alpha2
= (int) (radius2
- radius1
);
297 while (alpha2
> 360 * 64)
300 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
303 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) (GC
) m_gc
,
304 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
306 if (m_window
&& m_window
->GetBackingPixmap())
307 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
308 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
312 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
316 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
317 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
319 if (m_window
&& m_window
->GetBackingPixmap())
320 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
321 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
323 CalcBoundingBox (x1
, y1
);
324 CalcBoundingBox (x2
, y2
);
327 void wxWindowDC::DrawEllipticArc( long x
, long y
, long width
, long height
, double sa
, double ea
)
335 wd
= XLOG2DEVREL(width
);
336 hd
= YLOG2DEVREL(height
);
338 if (sa
>=360 || sa
<=-360) sa
=sa
-int(sa
/360)*360;
339 if (ea
>=360 || ea
<=-360) ea
=ea
-int(ea
/360)*360;
340 int start
= int(sa
*64);
341 int end
= int(ea
*64);
342 if (start
<0) start
+=360*64;
343 if (end
<0) end
+=360*64;
344 if (end
>start
) end
-=start
;
345 else end
+=360*64-start
;
347 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
349 m_autoSetting
= TRUE
; // must be reset
352 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
, end
);
354 if (m_window
&& m_window
->GetBackingPixmap())
355 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
356 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
359 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
363 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
,end
);
364 if (m_window
&& m_window
->GetBackingPixmap())
365 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
366 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
368 CalcBoundingBox (x
, y
);
369 CalcBoundingBox (x
+ width
, y
+ height
);
372 void wxWindowDC::DrawPoint( long x
, long y
)
376 // FreeGetPixelCache();
378 if (m_pen
.Ok() && m_autoSetting
)
381 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
));
382 if (m_window
&& m_window
->GetBackingPixmap())
383 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, XLOG2DEV_2 (x
), YLOG2DEV_2 (y
));
385 CalcBoundingBox (x
, y
);
388 void wxWindowDC::DrawLines( int n
, wxPoint points
[], long xoffset
, long yoffset
)
392 // FreeGetPixelCache();
394 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
399 XPoint
*xpoints
= new XPoint
[n
];
402 for (i
= 0; i
< n
; i
++)
404 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
405 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
407 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints
, n
, 0);
409 if (m_window
&& m_window
->GetBackingPixmap())
411 for (i
= 0; i
< n
; i
++)
413 xpoints
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
414 xpoints
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
416 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints
, n
, 0);
422 void wxWindowDC::DrawLines( wxList
*list
, long xoffset
, long yoffset
)
426 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
428 int n
= list
->Number();
429 wxPoint
*points
= new wxPoint
[n
];
432 for(wxNode
*node
= list
->First(); node
; node
= node
->Next()) {
433 wxPoint
*point
= (wxPoint
*)node
->Data();
434 points
[i
].x
= point
->x
;
435 points
[i
++].y
= point
->y
;
437 DrawLines(n
, points
, xoffset
, yoffset
);
441 void wxWindowDC::DrawPolygon( int n
, wxPoint points
[],
442 long xoffset
, long yoffset
, int fillStyle
)
444 // FreeGetPixelCache();
446 XPoint
*xpoints1
= new XPoint
[n
+ 1];
447 XPoint
*xpoints2
= new XPoint
[n
+ 1];
449 for (i
= 0; i
< n
; i
++)
451 xpoints1
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
452 xpoints1
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
453 xpoints2
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
454 xpoints2
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
455 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
458 // Close figure for XDrawLines (not needed for XFillPolygon)
459 xpoints1
[i
].x
= xpoints1
[0].x
;
460 xpoints1
[i
].y
= xpoints1
[0].y
;
461 xpoints2
[i
].x
= xpoints2
[0].x
;
462 xpoints2
[i
].y
= xpoints2
[0].y
;
464 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
467 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
468 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
, Complex
, 0);
469 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, EvenOddRule
); // default mode
470 if (m_window
&& m_window
->GetBackingPixmap())
472 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
,
473 fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
474 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
, Complex
, 0);
475 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
, EvenOddRule
); // default mode
479 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
483 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
+ 1, 0);
485 if (m_window
&& m_window
->GetBackingPixmap())
486 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
+ 1, 0);
493 void wxWindowDC::DrawPolygon( wxList
*list
, long xoffset
,
494 long yoffset
, int fillStyle
)
498 int n
= list
->Number();
499 wxPoint
*points
= new wxPoint
[n
];
502 for(wxNode
*node
= list
->First(); node
; node
= node
->Next()) {
503 wxPoint
*point
= (wxPoint
*)node
->Data();
504 points
[i
].x
= point
->x
;
505 points
[i
++].y
= point
->y
;
507 DrawPolygon(n
, points
, xoffset
, yoffset
,fillStyle
);
511 void wxWindowDC::DrawRectangle( long x
, long y
, long width
, long height
)
515 // FreeGetPixelCache();
517 int xd
, yd
, wfd
, hfd
, wd
, hd
;
521 wfd
= XLOG2DEVREL(width
);
523 hfd
= YLOG2DEVREL(height
);
526 if (wfd
== 0 || hfd
== 0) return;
527 if (wd
< 0) { wd
= - wd
; xd
= xd
- wd
; }
528 if (hd
< 0) { hd
= - hd
; yd
= yd
- hd
; }
530 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
533 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wfd
, hfd
);
535 if (m_window
&& m_window
->GetBackingPixmap())
536 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
537 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
541 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
545 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
);
547 if (m_window
&& m_window
->GetBackingPixmap())
548 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
549 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
552 CalcBoundingBox (x
, y
);
553 CalcBoundingBox (x
+ width
, y
+ height
);
556 void wxWindowDC::DrawRoundedRectangle( long x
, long y
, long width
, long height
, double radius
)
560 // FreeGetPixelCache();
562 // If radius is negative, it's a proportion of the smaller dimension.
564 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
566 int xd
= XLOG2DEV (x
);
567 int yd
= YLOG2DEV (y
);
568 int rd
= XLOG2DEVREL ((long) radius
);
569 int wd
= XLOG2DEVREL (width
) - WX_GC_CF
;
570 int hd
= YLOG2DEVREL (height
) - WX_GC_CF
;
575 // If radius is zero use DrawRectangle() instead to avoid
576 // X drawing errors with small radii
579 DrawRectangle( x
, y
, width
, height
);
583 // Draw nothing if transformed w or h is 0
584 if (wd
== 0 || hd
== 0) return;
586 // CMB: adjust size if outline is drawn otherwise the result is
587 // 1 pixel too wide and high
588 if (m_pen
.GetStyle() != wxTRANSPARENT
)
594 // CMB: ensure dd is not larger than rectangle otherwise we
595 // get an hour glass shape
596 if (rw_d
> wd
) rw_d
= wd
;
597 if (rw_d
> hd
) rw_d
= hd
;
600 // For backing pixmap
601 int xd2
= XLOG2DEV_2 (x
);
602 int yd2
= YLOG2DEV_2 (y
);
603 int rd2
= XLOG2DEVREL ((long) radius
);
604 int wd2
= XLOG2DEVREL (width
) ;
605 int hd2
= YLOG2DEVREL (height
) ;
610 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
614 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
616 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
619 // Arcs start from 3 o'clock, positive angles anticlockwise
621 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
622 rw_d
, rh_d
, 90 * 64, 90 * 64);
624 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
625 // rw_d, rh_d, 0, 90 * 64);
626 rw_d
, rh_d
, 0, 91 * 64);
628 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
630 // rw_d, rh_d, 270 * 64, 90 * 64);
631 rw_d
, rh_d
, 269 * 64, 92 * 64);
633 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
634 rw_d
, rh_d
, 180 * 64, 90 * 64);
636 if (m_window
&& m_window
->GetBackingPixmap())
638 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
639 xd2
+ rd2
, yd2
, wd2
- rw_d2
, hd2
);
640 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
641 xd2
, yd2
+ rd2
, wd2
, hd2
- rh_d2
);
643 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
644 xd2
, yd2
, rw_d2
, rh_d2
, 90 * 64, 90 * 64);
645 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
646 xd2
+ wd2
- rw_d2
, yd2
,
647 // rw_d2, rh_d2, 0, 90 * 64);
648 rw_d2
, rh_d2
, 0, 91 * 64);
649 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
652 // rw_d2, rh_d2, 270 * 64, 90 * 64);
653 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
654 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
655 xd2
, yd2
+ hd2
- rh_d2
,
656 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
660 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
663 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
664 xd
+ wd
- rd
+ 1, yd
);
665 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
+ hd
,
666 xd
+ wd
- rd
, yd
+ hd
);
668 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
670 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
, yd
+ rd
,
671 xd
+ wd
, yd
+ hd
- rd
+ 1);
672 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
673 rw_d
, rh_d
, 90 * 64, 90 * 64);
674 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
675 // rw_d, rh_d, 0, 90 * 64);
676 rw_d
, rh_d
, 0, 91 * 64);
677 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
679 rw_d
, rh_d
, 269 * 64, 92 * 64);
680 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
681 rw_d
, rh_d
, 180 * 64, 90 * 64);
683 if (m_window
&& m_window
->GetBackingPixmap())
685 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
687 xd2
+ wd2
- rd2
+ 1, yd2
);
688 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
689 xd2
+ rd2
, yd2
+ hd2
,
690 xd2
+ wd2
- rd2
, yd2
+ hd2
);
692 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
694 xd2
, yd2
+ hd2
- rd2
);
695 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
696 xd2
+ wd2
, yd2
+ rd2
,
697 xd2
+ wd2
, yd2
+ hd2
- rd2
+ 1);
698 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
700 rw_d2
, rh_d2
, 90 * 64, 90 * 64);
701 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
702 xd2
+ wd2
- rw_d2
, yd2
,
703 // rw_d2, rh_d2, 0, 90 * 64);
704 rw_d2
, rh_d2
, 0, 91 * 64);
705 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
708 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
709 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
710 xd2
, yd2
+ hd2
- rh_d2
,
711 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
714 CalcBoundingBox (x
, y
);
715 CalcBoundingBox (x
+ width
, y
+ height
);
720 void wxWindowDC::DrawEllipse( long x
, long y
, long width
, long height
)
724 // Check for negative width and height
737 // FreeGetPixelCache();
739 static const int angle
= 23040;
745 wd
= XLOG2DEVREL(width
) ;
746 hd
= YLOG2DEVREL(height
) ;
748 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
751 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
752 if (m_window
&& m_window
->GetBackingPixmap())
753 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
754 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
755 XLOG2DEVREL (width
) - WX_GC_CF
,
756 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
759 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
763 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
764 if (m_window
&& m_window
->GetBackingPixmap())
765 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
766 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
767 XLOG2DEVREL (width
) - WX_GC_CF
,
768 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
770 CalcBoundingBox (x
, y
);
771 CalcBoundingBox (x
+ width
, y
+ height
);
775 bool wxWindowDC::CanDrawBitmap(void) const
780 /* Used when copying between drawables on different (Display*) m_displays.
781 Not very fast, but better than giving up.
784 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
785 Drawable src
, Drawable dest
,
788 unsigned int w
, unsigned int h
,
789 int destx
, int desty
,
790 bool more
, XImage
**cache
)
792 XImage
*image
, *destimage
;
793 Colormap destcm
, srccm
;
794 #define CACHE_SIZE 256
796 unsigned long cachesrc
[CACHE_SIZE
], cachedest
[CACHE_SIZE
];
797 int k
, cache_pos
, all_cache
;
799 if (!cache
|| !*cache
)
800 image
= XGetImage(src_display
, src
, srcx
, srcy
, w
, h
, AllPlanes
, ZPixmap
);
804 destimage
= XGetImage(dest_display
, dest
, destx
, desty
, w
, h
, AllPlanes
, ZPixmap
);
806 srccm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) src_display
);
807 destcm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dest_display
);
812 for (i
= 0; i
< w
; i
++)
813 for (j
= 0; j
< h
; j
++) {
817 pixel
= XGetPixel(image
, i
, j
);
818 for (k
= cache_pos
; k
--; )
819 if (cachesrc
[k
] == pixel
) {
820 pixel
= cachedest
[k
];
824 for (k
= CACHE_SIZE
; k
-- > cache_pos
; )
825 if (cachesrc
[k
] == pixel
) {
826 pixel
= cachedest
[k
];
830 cachesrc
[cache_pos
] = xcol
.pixel
= pixel
;
831 XQueryColor(src_display
, srccm
, &xcol
);
832 if (!XAllocColor(dest_display
, destcm
, &xcol
))
834 cachedest
[cache_pos
] = pixel
= xcol
.pixel
;
836 if (++cache_pos
>= CACHE_SIZE
) {
842 XPutPixel(destimage
, i
, j
, pixel
);
845 XPutImage(dest_display
, dest
, destgc
, destimage
, 0, 0, destx
, desty
, w
, h
);
846 XDestroyImage(destimage
);
851 XDestroyImage(image
);
854 void wxWindowDC::DrawIcon( const wxIcon
&icon
, long x
, long y
)
858 if (!icon
.Ok()) return;
860 DrawBitmap(icon
, x
, y
, TRUE
);
863 // FreeGetPixelCache();
865 // Be sure that foreground pixels (1) of
866 // the Icon will be painted with pen colour. [m_pen.SetColour()]
867 // Background pixels (0) will be painted with
868 // last selected background color. [::SetBackground]
869 if (m_pen
.Ok() && m_autoSetting
)
873 Pixmap iconPixmap
= (Pixmap
) icon
.GetPixmap();
874 width
= icon
.GetWidth();
875 height
= icon
.GetHeight();
876 if (icon
.GetDisplay() == m_display
)
878 if (icon
.GetDepth() <= 1)
880 XCopyPlane ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
882 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
), 1);
886 XCopyArea ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
888 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
));
892 if (m_window
&& m_window
->GetBackingPixmap())
894 if (icon
.GetDepth() <= 1)
896 XCopyPlane ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
897 0, 0, width
, height
, (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
), 1);
901 XCopyArea ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
903 (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
));
906 } else { /* Remote copy (different (Display*) m_displays) */
907 XImage
*cache
= NULL
;
908 if (m_window
&& m_window
->GetBackingPixmap())
909 XCopyRemote((Display
*) icon
.GetDisplay(), (Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
910 (GC
) m_gcBacking
, 0, 0, width
, height
,
911 (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
), TRUE
, &cache
);
912 XCopyRemote((Display
*) icon
.GetDisplay(), (Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
914 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
), FALSE
, &cache
);
916 CalcBoundingBox (x
, y
);
920 bool wxWindowDC::Blit( long xdest
, long ydest
, long width
, long height
,
921 wxDC
*source
, long xsrc
, long ysrc
, int rop
, bool useMask
)
923 if (!Ok()) return FALSE
;
925 wxASSERT_MSG( (source
->IsKindOf(CLASSINFO(wxWindowDC
))), "Blit source DC must be wxWindowDC or derived class." );
927 wxWindowDC
* sourceDC
= (wxWindowDC
*) source
;
929 // FreeGetPixelCache();
931 // Be sure that foreground pixels (1) of
932 // the Icon will be painted with pen colour. [m_pen.SetColour()]
933 // Background pixels (0) will be painted with
934 // last selected background color. [::SetBackground]
935 if (m_pen
.Ok() && m_autoSetting
)
938 if (m_pixmap
&& sourceDC
->m_pixmap
)
941 int orig
= m_logicalFunction
;
943 SetLogicalFunction (rop
);
945 if (m_display
!= sourceDC
->m_display
)
947 XImage
*cache
= NULL
;
949 if (m_window
&& m_window
->GetBackingPixmap())
950 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
,
951 (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
953 source
->LogicalToDeviceX (xsrc
),
954 source
->LogicalToDeviceY (ysrc
),
955 source
->LogicalToDeviceXRel(width
),
956 source
->LogicalToDeviceYRel(height
),
957 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
),
960 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
962 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
963 wxBitmap
& sel
= memDC
->GetBitmap();
964 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetPixmap() )
966 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetPixmap());
967 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
971 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
972 source
->LogicalToDeviceX (xsrc
),
973 source
->LogicalToDeviceY (ysrc
),
974 source
->LogicalToDeviceXRel(width
),
975 source
->LogicalToDeviceYRel(height
),
976 XLOG2DEV (xdest
), YLOG2DEV (ydest
),
981 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
982 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
987 if (m_window
&& m_window
->GetBackingPixmap())
989 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1
990 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetBitmap().GetDepth() == 1)
992 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
993 source
->LogicalToDeviceX (xsrc
),
994 source
->LogicalToDeviceY (ysrc
),
995 source
->LogicalToDeviceXRel(width
),
996 source
->LogicalToDeviceYRel(height
),
997 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 1);
1001 XCopyArea ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1002 source
->LogicalToDeviceX (xsrc
),
1003 source
->LogicalToDeviceY (ysrc
),
1004 source
->LogicalToDeviceXRel(width
),
1005 source
->LogicalToDeviceYRel(height
),
1006 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
));
1009 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
1011 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1012 wxBitmap
& sel
= memDC
->GetBitmap();
1013 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetPixmap() )
1015 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetPixmap());
1016 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
1020 // Check if we're copying from a mono bitmap
1021 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) &&
1022 ((wxMemoryDC
*)source
)->GetBitmap().Ok() && (((wxMemoryDC
*)source
)->GetBitmap().GetDepth () == 1))
1024 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1025 source
->LogicalToDeviceX (xsrc
),
1026 source
->LogicalToDeviceY (ysrc
),
1027 source
->LogicalToDeviceXRel(width
),
1028 source
->LogicalToDeviceYRel(height
),
1029 XLOG2DEV (xdest
), YLOG2DEV (ydest
), 1);
1033 XCopyArea ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1034 source
->LogicalToDeviceX (xsrc
),
1035 source
->LogicalToDeviceY (ysrc
),
1036 source
->LogicalToDeviceXRel(width
),
1037 source
->LogicalToDeviceYRel(height
),
1038 XLOG2DEV (xdest
), YLOG2DEV (ydest
));
1043 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
1044 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
1047 } /* Remote/local (Display*) m_display */
1048 CalcBoundingBox (xdest
, ydest
);
1049 CalcBoundingBox (xdest
+ width
, ydest
+ height
);
1051 SetLogicalFunction(orig
);
1058 /* Helper function for 16-bit fonts */
1059 static int str16len(const char *s
)
1063 while (s
[0] && s
[1]) {
1071 void wxWindowDC::DrawText( const wxString
&text
, long x
, long y
, bool use16
)
1075 // Since X draws from the baseline of the text, must
1076 // add the text height
1083 slen
= str16len(text
);
1085 slen
= strlen(text
);
1089 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1090 int direction
, descent
;
1091 XCharStruct overall_return
;
1093 (void)XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*)(const char*) text
, slen
, &direction
,
1094 &ascent
, &descent
, &overall_return
);
1096 (void)XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) text
, slen
, &direction
,
1097 &ascent
, &descent
, &overall_return
);
1098 cx
= overall_return
.width
;
1099 cy
= ascent
+ descent
;
1102 // First draw a rectangle representing the text background,
1103 // if a text background is specified
1104 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1106 wxColour oldPenColour
= m_currentColour
;
1107 m_currentColour
= m_textBackgroundColour
;
1108 bool sameColour
= (oldPenColour
.Ok () && m_textBackgroundColour
.Ok () &&
1109 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1110 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1111 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1113 // This separation of the big && test required for gcc2.7/HP UX 9.02
1114 // or pixel value can be corrupted!
1115 sameColour
= (sameColour
&&
1116 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1118 if (!sameColour
|| !GetOptimization())
1120 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1121 m_currentColour
= m_textBackgroundColour
;
1123 // Set the GC to the required colour
1126 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1127 if (m_window
&& m_window
->GetBackingPixmap())
1128 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1132 m_textBackgroundColour
= oldPenColour
;
1134 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1135 if (m_window
&& m_window
->GetBackingPixmap())
1136 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1137 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1140 // Now set the text foreground and draw the text
1141 if (m_textForegroundColour
.Ok ())
1143 wxColour oldPenColour
= m_currentColour
;
1144 m_currentColour
= m_textForegroundColour
;
1145 bool sameColour
= (oldPenColour
.Ok () && m_currentColour
.Ok () &&
1146 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1147 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1148 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1149 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1151 if (!sameColour
|| !GetOptimization())
1154 if (!m_colour
) // Mono display
1156 // Unless foreground is really white, draw it in black
1157 unsigned char red
= m_textForegroundColour
.Red ();
1158 unsigned char blue
= m_textForegroundColour
.Blue ();
1159 unsigned char green
= m_textForegroundColour
.Green ();
1160 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1161 && green
== (unsigned char) 255)
1163 m_currentColour
= *wxWHITE
;
1164 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1165 m_currentColour
.SetPixel(pixel
);
1166 m_textForegroundColour
.SetPixel(pixel
);
1170 m_currentColour
= *wxBLACK
;
1171 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1172 m_currentColour
.SetPixel(pixel
);
1173 m_textForegroundColour
.SetPixel(pixel
);
1178 pixel
= m_textForegroundColour
.AllocColour((Display
*) m_display
);
1179 m_currentColour
.SetPixel(pixel
);
1182 // Set the GC to the required colour
1185 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1186 if (m_window
&& m_window
->GetBackingPixmap())
1187 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1191 m_textForegroundColour
= oldPenColour
;
1194 // We need to add the ascent, not the whole height, since X draws
1195 // at the point above the descender.
1197 XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1198 (XChar2b
*)(char*) (const char*) text
, slen
);
1200 XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1203 if (m_window
&& m_window
->GetBackingPixmap()) {
1205 XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1206 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1207 (XChar2b
*)(char*) (const char*) text
, slen
);
1209 XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1210 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
, (char*) (const char*) text
, slen
);
1214 GetTextExtent (text
, &w
, &h
);
1215 CalcBoundingBox (x
+ w
, y
+ h
);
1216 CalcBoundingBox (x
, y
);
1219 bool wxWindowDC::CanGetTextExtent(void) const
1224 void wxWindowDC::GetTextExtent( const wxString
&string
, long *width
, long *height
,
1225 long *descent
, long *externalLeading
,
1226 wxFont
*font
, bool use16
)
1230 wxFont
* theFont
= font
;
1236 // TODO: this should be an error log function
1237 wxFAIL_MSG("set a valid font before calling GetTextExtent!");
1244 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1246 int direction
, ascent
, descent2
;
1247 XCharStruct overall
;
1250 if (use16
) slen
= str16len(string
); else slen
= strlen(string
);
1253 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1254 &ascent
, &descent2
, &overall
);
1256 XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) string
, slen
, &direction
,
1257 &ascent
, &descent2
, &overall
);
1259 *width
= XDEV2LOGREL (overall
.width
);
1260 *height
= YDEV2LOGREL (ascent
+ descent2
);
1262 *descent
= descent2
;
1263 if (externalLeading
)
1264 *externalLeading
= 0;
1267 long wxWindowDC::GetCharWidth(void)
1269 if (!Ok()) return 0;
1274 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
* m_logicalScaleY
, m_display
);
1276 int direction
, ascent
, descent
;
1277 XCharStruct overall
;
1278 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1279 &descent
, &overall
);
1280 return XDEV2LOGREL(overall
.width
);
1283 long wxWindowDC::GetCharHeight(void)
1285 if (!Ok()) return 0;
1290 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1292 int direction
, ascent
, descent
;
1293 XCharStruct overall
;
1294 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1295 &descent
, &overall
);
1296 // return XDEV2LOGREL(overall.ascent + overall.descent);
1297 return XDEV2LOGREL(ascent
+ descent
);
1300 void wxWindowDC::Clear(void)
1307 m_window
->GetSize(&w
, &h
);
1309 if (m_window
&& m_window
->GetBackingPixmap())
1311 w
= m_window
->GetPixmapWidth();
1312 h
= m_window
->GetPixmapHeight();
1317 if (this->IsKindOf(CLASSINFO(wxMemoryDC
)))
1319 wxMemoryDC
* memDC
= (wxMemoryDC
*) this;
1320 w
= memDC
->GetBitmap().GetWidth();
1321 h
= memDC
->GetBitmap().GetHeight();
1327 wxBrush saveBrush
= m_brush
;
1328 SetBrush (m_backgroundBrush
);
1330 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, 0, w
, h
);
1332 if (m_window
&& m_window
->GetBackingPixmap())
1333 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 0, 0, w
, h
);
1335 m_brush
= saveBrush
;
1338 void wxWindowDC::Clear(const wxRect
& rect
)
1342 int x
= rect
.x
; int y
= rect
.y
;
1343 int w
= rect
.width
; int h
= rect
.height
;
1345 wxBrush saveBrush
= m_brush
;
1346 SetBrush (m_backgroundBrush
);
1348 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x
, y
, w
, h
);
1350 if (m_window
&& m_window
->GetBackingPixmap())
1351 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, x
, y
, w
, h
);
1353 m_brush
= saveBrush
;
1356 void wxWindowDC::SetFont( const wxFont
&font
)
1364 if ((m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
1366 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
1368 if (m_window
&& m_window
->GetBackingPixmap())
1369 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
1374 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1376 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1377 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1379 if (m_window
&& m_window
->GetBackingPixmap())
1380 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1383 void wxWindowDC::SetPen( const wxPen
&pen
)
1391 wxBitmap oldStipple
= m_currentStipple
;
1392 int oldStyle
= m_currentStyle
;
1393 int oldFill
= m_currentFill
;
1394 int old_pen_width
= m_currentPenWidth
;
1395 int old_pen_join
= m_currentPenJoin
;
1396 int old_pen_cap
= m_currentPenCap
;
1397 int old_pen_nb_dash
= m_currentPenDashCount
;
1398 char *old_pen_dash
= m_currentPenDash
;
1400 wxColour oldPenColour
= m_currentColour
;
1401 m_currentColour
= m_pen
.GetColour ();
1402 m_currentStyle
= m_pen
.GetStyle ();
1403 m_currentFill
= m_pen
.GetStyle (); // TODO?
1404 m_currentPenWidth
= m_pen
.GetWidth ();
1405 m_currentPenJoin
= m_pen
.GetJoin ();
1406 m_currentPenCap
= m_pen
.GetCap ();
1407 m_currentPenDashCount
= m_pen
.GetDashCount();
1408 m_currentPenDash
= m_pen
.GetDash();
1410 if (m_currentStyle
== wxSTIPPLE
)
1411 m_currentStipple
= * m_pen
.GetStipple ();
1413 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1414 oldFill
== m_currentFill
&&
1415 old_pen_join
== m_currentPenJoin
&&
1416 old_pen_cap
== m_currentPenCap
&&
1417 old_pen_nb_dash
== m_currentPenDashCount
&&
1418 old_pen_dash
== m_currentPenDash
&&
1419 old_pen_width
== m_currentPenWidth
);
1421 bool sameColour
= (oldPenColour
.Ok () &&
1422 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1423 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1424 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1425 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1427 if (!sameStyle
|| !GetOptimization())
1429 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1430 if (scaled_width
< 0)
1436 static char dotted
[] =
1438 static char short_dashed
[] =
1440 static char long_dashed
[] =
1442 static char dotted_dashed
[] =
1445 // We express dash pattern in pen width unit, so we are
1446 // independent of zoom factor and so on...
1450 switch (m_pen
.GetStyle ())
1453 req_nb_dash
= m_currentPenDashCount
;
1454 req_dash
= m_currentPenDash
;
1455 style
= LineOnOffDash
;
1460 style
= LineOnOffDash
;
1464 req_dash
= short_dashed
;
1465 style
= LineOnOffDash
;
1469 req_dash
= long_dashed
;
1470 style
= LineOnOffDash
;
1474 req_dash
= dotted_dashed
;
1475 style
= LineOnOffDash
;
1486 if (req_dash
&& req_nb_dash
)
1488 char *real_req_dash
= new char[req_nb_dash
];
1491 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1492 for (int i
= 0; i
< req_nb_dash
; i
++)
1493 real_req_dash
[i
] = req_dash
[i
] * factor
;
1494 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1496 if (m_window
&& m_window
->GetBackingPixmap())
1497 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1498 delete[]real_req_dash
;
1502 // No Memory. We use non-scaled dash pattern...
1503 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1505 if (m_window
&& m_window
->GetBackingPixmap())
1506 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1510 switch (m_pen
.GetCap ())
1512 case wxCAP_PROJECTING
:
1513 cap
= CapProjecting
;
1520 cap
= (scaled_width
<= 1) ? CapNotLast
: CapRound
;
1524 switch (m_pen
.GetJoin ())
1538 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1540 if (m_window
&& m_window
->GetBackingPixmap())
1541 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1544 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1548 oldStipple
= wxNullBitmap
; // For later reset!!
1550 switch (m_currentFill
)
1552 case wxBDIAGONAL_HATCH
:
1553 if (bdiag
== (Pixmap
) 0)
1554 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1555 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1556 bdiag_bits
, bdiag_width
, bdiag_height
);
1559 case wxFDIAGONAL_HATCH
:
1560 if (fdiag
== (Pixmap
) 0)
1561 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1562 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1563 fdiag_bits
, fdiag_width
, fdiag_height
);
1567 if (cross
== (Pixmap
) 0)
1568 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1569 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1570 cross_bits
, cross_width
, cross_height
);
1573 case wxHORIZONTAL_HATCH
:
1574 if (horiz
== (Pixmap
) 0)
1575 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1576 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1577 horiz_bits
, horiz_width
, horiz_height
);
1580 case wxVERTICAL_HATCH
:
1581 if (verti
== (Pixmap
) 0)
1582 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1583 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1584 verti_bits
, verti_width
, verti_height
);
1587 case wxCROSSDIAG_HATCH
:
1589 if (cdiag
== (Pixmap
) 0)
1590 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1591 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1592 cdiag_bits
, cdiag_width
, cdiag_height
);
1596 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1598 if (m_window
&& m_window
->GetBackingPixmap())
1599 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1601 else if (m_currentStipple
.Ok()
1602 && ((m_currentStipple
!= oldStipple
) || !GetOptimization()))
1604 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1606 if (m_window
&& m_window
->GetBackingPixmap())
1607 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1610 if ((m_currentFill
!= oldFill
) || !GetOptimization())
1614 if (m_currentFill
== wxSTIPPLE
)
1615 fill_style
= FillStippled
;
1616 else if (IS_HATCH (m_currentFill
))
1617 fill_style
= FillStippled
;
1619 fill_style
= FillSolid
;
1620 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1621 if (m_window
&& m_window
->GetBackingPixmap())
1622 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1625 // must test m_logicalFunction, because it involves background!
1626 if (!sameColour
|| !GetOptimization()
1627 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1630 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1631 pixel
= m_backgroundPixel
;
1634 unsigned char red
= m_pen
.GetColour ().Red ();
1635 unsigned char blue
= m_pen
.GetColour ().Blue ();
1636 unsigned char green
= m_pen
.GetColour ().Green ();
1637 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1638 && green
== (unsigned char) 255)
1640 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1641 m_currentColour
= *wxWHITE
;
1642 m_pen
.GetColour().SetPixel(pixel
);
1643 m_currentColour
.SetPixel(pixel
);
1647 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1648 m_currentColour
= *wxBLACK
;
1649 m_pen
.GetColour().SetPixel(pixel
);
1654 pixel
= m_pen
.GetColour ().AllocColour(m_display
);
1655 m_currentColour
.SetPixel(pixel
);
1658 // Finally, set the GC to the required colour
1661 if (m_logicalFunction
== wxXOR
)
1664 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1665 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1666 if (m_window
&& m_window
->GetBackingPixmap())
1667 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1671 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1672 if (m_window
&& m_window
->GetBackingPixmap())
1673 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1678 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1683 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1689 if (!m_brush
.Ok() || m_brush
.GetStyle () == wxTRANSPARENT
)
1692 int oldFill
= m_currentFill
;
1693 wxBitmap oldStipple
= m_currentStipple
;
1695 m_autoSetting
|= 0x1;
1697 m_currentFill
= m_brush
.GetStyle ();
1698 if (m_currentFill
== wxSTIPPLE
)
1699 m_currentStipple
= * m_brush
.GetStipple ();
1701 wxColour
oldBrushColour(m_currentColour
);
1702 m_currentColour
= m_brush
.GetColour ();
1704 bool sameColour
= (oldBrushColour
.Ok () &&
1705 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1706 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1707 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1708 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1710 if ((oldFill
!= m_brush
.GetStyle ()) || !GetOptimization())
1712 switch (brush
.GetStyle ())
1716 case wxBDIAGONAL_HATCH
:
1717 case wxCROSSDIAG_HATCH
:
1718 case wxFDIAGONAL_HATCH
:
1720 case wxHORIZONTAL_HATCH
:
1721 case wxVERTICAL_HATCH
:
1724 // Chris Breeze 23/07/97: use background mode to determine whether
1725 // fill style should be solid or transparent
1726 int style
= (m_backgroundMode
== wxSOLID
? FillOpaqueStippled
: FillStippled
);
1727 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1728 if (m_window
&& m_window
->GetBackingPixmap())
1729 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1734 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1735 if (m_window
&& m_window
->GetBackingPixmap())
1736 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, FillSolid
);
1740 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1744 switch (m_currentFill
)
1746 case wxBDIAGONAL_HATCH
:
1747 if (bdiag
== (Pixmap
) 0)
1748 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1749 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1750 bdiag_bits
, bdiag_width
, bdiag_height
);
1753 case wxFDIAGONAL_HATCH
:
1754 if (fdiag
== (Pixmap
) 0)
1755 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1756 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1757 fdiag_bits
, fdiag_width
, fdiag_height
);
1761 if (cross
== (Pixmap
) 0)
1762 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1763 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1764 cross_bits
, cross_width
, cross_height
);
1767 case wxHORIZONTAL_HATCH
:
1768 if (horiz
== (Pixmap
) 0)
1769 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1770 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1771 horiz_bits
, horiz_width
, horiz_height
);
1774 case wxVERTICAL_HATCH
:
1775 if (verti
== (Pixmap
) 0)
1776 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1777 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1778 verti_bits
, verti_width
, verti_height
);
1781 case wxCROSSDIAG_HATCH
:
1783 if (cdiag
== (Pixmap
) 0)
1784 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1785 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1786 cdiag_bits
, cdiag_width
, cdiag_height
);
1790 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1792 if (m_window
&& m_window
->GetBackingPixmap())
1793 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1795 // X can forget the stipple value when resizing a window (apparently)
1796 // so always set the stipple.
1797 else if (m_currentStipple
.Ok()) // && m_currentStipple != oldStipple)
1799 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1800 if (m_window
&& m_window
->GetBackingPixmap())
1801 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1804 // must test m_logicalFunction, because it involves background!
1805 if (!sameColour
|| !GetOptimization() || m_logicalFunction
== wxXOR
)
1810 // Policy - on a monochrome screen, all brushes are white,
1811 // except when they're REALLY black!!!
1812 unsigned char red
= m_brush
.GetColour ().Red ();
1813 unsigned char blue
= m_brush
.GetColour ().Blue ();
1814 unsigned char green
= m_brush
.GetColour ().Green ();
1816 if (red
== (unsigned char) 0 && blue
== (unsigned char) 0
1817 && green
== (unsigned char) 0)
1819 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1820 m_currentColour
= *wxBLACK
;
1821 m_brush
.GetColour().SetPixel(pixel
);
1822 m_currentColour
.SetPixel(pixel
);
1826 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1827 m_currentColour
= *wxWHITE
;
1828 m_brush
.GetColour().SetPixel(pixel
);
1829 m_currentColour
.SetPixel(pixel
);
1832 // N.B. comment out the above line and uncomment the following lines
1833 // if you want non-white colours to be black on a monochrome display.
1835 if (red == (unsigned char )255 && blue == (unsigned char)255
1836 && green == (unsigned char)255)
1837 pixel = (int)WhitePixel((Display*) m_display, DefaultScreen((Display*) m_display));
1839 pixel = (int)BlackPixel((Display*) m_display, DefaultScreen((Display*) m_display));
1842 else if (m_brush
.GetStyle () != wxTRANSPARENT
)
1844 pixel
= m_brush
.GetColour().AllocColour(m_display
);
1845 m_currentColour
.SetPixel(pixel
);
1849 // Finally, set the GC to the required colour
1850 if (m_logicalFunction
== wxXOR
)
1853 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1854 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1855 if (m_window
&& m_window
->GetBackingPixmap())
1856 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1860 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1861 if (m_window
&& m_window
->GetBackingPixmap())
1862 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1867 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1870 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1874 m_backgroundBrush
= brush
;
1876 if (!m_backgroundBrush
.Ok())
1879 int pixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
1881 // XSetWindowBackground doesn't work for non-Window pixmaps
1882 if (!this->IsKindOf(CLASSINFO(wxMemoryDC
)))
1883 XSetWindowBackground ((Display
*) m_display
, (Pixmap
) m_pixmap
, pixel
);
1885 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
1886 // And Blit,... (Any fct that use XCopyPlane, in fact.)
1887 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1888 if (m_window
&& m_window
->GetBackingPixmap())
1889 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1892 void wxWindowDC::SetLogicalFunction( int function
)
1897 if (m_logicalFunction
== function
)
1903 x_function
= GXclear
;
1909 x_function
= GXinvert
;
1912 x_function
= GXorReverse
;
1915 x_function
= GXandReverse
;
1924 x_function
= GXandInverted
;
1927 x_function
= GXnoop
;
1933 x_function
= GXequiv
;
1936 x_function
= GXcopyInverted
;
1939 x_function
= GXorInverted
;
1942 x_function
= GXnand
;
1949 x_function
= GXcopy
;
1953 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
1954 if (m_window
&& m_window
->GetBackingPixmap())
1955 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
1957 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
1958 /* MATTHEW: [9] Need to redo pen simply */
1959 m_autoSetting
|= 0x2;
1961 m_logicalFunction
= function
;
1965 void wxWindowDC::SetTextForeground( const wxColour
&col
)
1969 if (m_textForegroundColour
== col
) return;
1971 m_textForegroundColour
= col
;
1975 void wxWindowDC::SetTextBackground( const wxColour
&col
)
1979 if (m_textBackgroundColour
== col
) return;
1981 m_textBackgroundColour
= col
;
1982 if (!m_textBackgroundColour
.Ok()) return;
1985 void wxWindowDC::SetBackgroundMode( int mode
)
1987 m_backgroundMode
= mode
;
1991 void wxWindowDC::SetPalette( const wxPalette
& palette
)
1996 /* Use GetXColormap */
1997 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1998 (Colormap
) palette
.GetXColormap());
2000 /* Use wxGetMainColormap */
2001 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2002 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2007 void wxWindowDC:: SetDCClipping ()
2009 // m_userRegion is the region set by calling SetClippingRegion
2011 if (m_currentRegion
)
2012 XDestroyRegion ((Region
) m_currentRegion
);
2014 // We need to take into account
2015 // clipping imposed on a window by a repaint.
2016 // We'll combine it with the user region. But for now,
2017 // just use the currently-defined user clipping region.
2018 if (m_userRegion
|| (m_window
&& m_window
->GetUpdateRegion().Ok()) )
2019 m_currentRegion
= (WXRegion
) XCreateRegion ();
2021 m_currentRegion
= (WXRegion
) NULL
;
2023 if ((m_window
&& m_window
->GetUpdateRegion().Ok()) && m_userRegion
)
2024 XIntersectRegion ((Region
) m_window
->GetUpdateRegion().GetXRegion(), (Region
) m_userRegion
, (Region
) m_currentRegion
);
2025 else if (m_userRegion
)
2026 XIntersectRegion ((Region
) m_userRegion
, (Region
) m_userRegion
, (Region
) m_currentRegion
);
2027 else if (m_window
&& m_window
->GetUpdateRegion().Ok())
2028 XIntersectRegion ((Region
) m_window
->GetUpdateRegion().GetXRegion(), (Region
) m_window
->GetUpdateRegion().GetXRegion(),
2029 (Region
) m_currentRegion
);
2031 if (m_currentRegion
)
2033 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) m_currentRegion
);
2037 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
2042 void wxWindowDC::SetClippingRegion( long x
, long y
, long width
, long height
)
2044 wxDC::SetClippingRegion( x
, y
, width
, height
);
2047 XDestroyRegion ((Region
) m_userRegion
);
2048 m_userRegion
= (WXRegion
) XCreateRegion ();
2052 r
.width
= XLOG2DEVREL(width
);
2053 r
.height
= YLOG2DEVREL(height
);
2054 XUnionRectWithRegion (&r
, (Region
) m_userRegion
, (Region
) m_userRegion
);
2058 // Needs to work differently for Pixmap: without this,
2059 // there's a nasty (Display*) m_display bug. 8/12/94
2060 if (m_window
&& m_window
->GetBackingPixmap())
2062 XRectangle rects
[1];
2063 rects
[0].x
= XLOG2DEV_2(x
);
2064 rects
[0].y
= YLOG2DEV_2(y
);
2065 rects
[0].width
= XLOG2DEVREL(width
);
2066 rects
[0].height
= YLOG2DEVREL(height
);
2067 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 0, 0, rects
, 1, Unsorted
);
2071 void wxWindowDC::SetClippingRegion( const wxRegion
& region
)
2073 wxRect box
= region
.GetBox();
2075 wxDC::SetClippingRegion( box
.x
, box
.y
, box
.width
, box
.height
);
2078 XDestroyRegion ((Region
) m_userRegion
);
2079 m_userRegion
= (WXRegion
) XCreateRegion ();
2081 XUnionRegion((Region
) m_userRegion
, (Region
) region
.GetXRegion(), (Region
) m_userRegion
);
2085 // Needs to work differently for Pixmap: without this,
2086 // there's a nasty (Display*) m_display bug. 8/12/94
2087 if (m_window
&& m_window
->GetBackingPixmap())
2089 XRectangle rects
[1];
2090 rects
[0].x
= XLOG2DEV_2(box
.x
);
2091 rects
[0].y
= YLOG2DEV_2(box
.y
);
2092 rects
[0].width
= XLOG2DEVREL(box
.width
);
2093 rects
[0].height
= YLOG2DEVREL(box
.height
);
2094 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 0, 0, rects
, 1, Unsorted
);
2099 void wxWindowDC::DestroyClippingRegion(void)
2101 wxDC::DestroyClippingRegion();
2104 XDestroyRegion ((Region
) m_userRegion
);
2105 m_userRegion
= NULL
;
2110 gc_val
.clip_mask
= None
;
2111 if (m_window
&& m_window
->GetBackingPixmap())
2112 XChangeGC((Display
*) m_display
, (GC
) m_gcBacking
, GCClipMask
, &gc_val
);
2115 // ----------------------------------- spline code ----------------------------------------
2117 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
2118 double a3
, double b3
, double a4
, double b4
);
2119 void wx_clear_stack(void);
2120 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
2121 double *y3
, double *x4
, double *y4
);
2122 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
2123 double x4
, double y4
);
2124 static bool wx_spline_add_point(double x
, double y
);
2125 static void wx_spline_draw_point_array(wxDC
*dc
);
2127 wxList wx_spline_point_list
;
2129 #define half(z1, z2) ((z1+z2)/2.0)
2132 /* iterative version */
2134 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
2137 register double xmid
, ymid
;
2138 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
2141 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
2143 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
2144 xmid
= (double)half(x2
, x3
);
2145 ymid
= (double)half(y2
, y3
);
2146 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
2147 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
2148 wx_spline_add_point( x1
, y1
);
2149 wx_spline_add_point( xmid
, ymid
);
2151 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
2152 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
2153 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
2154 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
2159 /* utilities used by spline drawing routines */
2161 typedef struct wx_spline_stack_struct
{
2162 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
2165 #define SPLINE_STACK_DEPTH 20
2166 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
2167 static Stack
*wx_stack_top
;
2168 static int wx_stack_count
;
2170 void wx_clear_stack(void)
2172 wx_stack_top
= wx_spline_stack
;
2176 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
2178 wx_stack_top
->x1
= x1
;
2179 wx_stack_top
->y1
= y1
;
2180 wx_stack_top
->x2
= x2
;
2181 wx_stack_top
->y2
= y2
;
2182 wx_stack_top
->x3
= x3
;
2183 wx_stack_top
->y3
= y3
;
2184 wx_stack_top
->x4
= x4
;
2185 wx_stack_top
->y4
= y4
;
2190 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
2191 double *x3
, double *y3
, double *x4
, double *y4
)
2193 if (wx_stack_count
== 0)
2197 *x1
= wx_stack_top
->x1
;
2198 *y1
= wx_stack_top
->y1
;
2199 *x2
= wx_stack_top
->x2
;
2200 *y2
= wx_stack_top
->y2
;
2201 *x3
= wx_stack_top
->x3
;
2202 *y3
= wx_stack_top
->y3
;
2203 *x4
= wx_stack_top
->x4
;
2204 *y4
= wx_stack_top
->y4
;
2208 static bool wx_spline_add_point(double x
, double y
)
2210 wxPoint
*point
= new wxPoint
;
2213 wx_spline_point_list
.Append((wxObject
*)point
);
2217 static void wx_spline_draw_point_array(wxDC
*dc
)
2219 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
2220 wxNode
*node
= wx_spline_point_list
.First();
2223 wxPoint
*point
= (wxPoint
*)node
->Data();
2226 node
= wx_spline_point_list
.First();
2230 void wxWindowDC::DrawSpline( wxList
*points
)
2233 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
2234 double x1
, y1
, x2
, y2
;
2236 wxNode
*node
= points
->First();
2237 p
= (wxPoint
*)node
->Data();
2242 node
= node
->Next();
2243 p
= (wxPoint
*)node
->Data();
2247 cx1
= (double)((x1
+ x2
) / 2);
2248 cy1
= (double)((y1
+ y2
) / 2);
2249 cx2
= (double)((cx1
+ x2
) / 2);
2250 cy2
= (double)((cy1
+ y2
) / 2);
2252 wx_spline_add_point(x1
, y1
);
2254 while ((node
= node
->Next()) != NULL
)
2256 p
= (wxPoint
*)node
->Data();
2261 cx4
= (double)(x1
+ x2
) / 2;
2262 cy4
= (double)(y1
+ y2
) / 2;
2263 cx3
= (double)(x1
+ cx4
) / 2;
2264 cy3
= (double)(y1
+ cy4
) / 2;
2266 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
2270 cx2
= (double)(cx1
+ x2
) / 2;
2271 cy2
= (double)(cy1
+ y2
) / 2;
2274 wx_spline_add_point( cx1
, cy1
);
2275 wx_spline_add_point( x2
, y2
);
2277 wx_spline_draw_point_array( this );
2284 wxPaintDC::wxPaintDC(wxWindow
* win
): wxWindowDC(win
)
2286 wxRegion
* region
= NULL
;
2288 // Combine all the update rects into a region
2289 if (win
->m_updateRects
.Number() > 0)
2292 for (i
= 0; i
< win
->m_updateRects
.Number(); i
++)
2294 wxRect
* rect
= (wxRect
*) win
->m_updateRects
.Nth(i
)->Data();
2296 cout << "wxPaintDC. wxRect: " << rect->x << ", " << rect->y << ", ";
2297 cout << rect->width << ", " << rect->height << "\n\n";
2301 region
= new wxRegion(*rect
);
2303 // TODO: is this correct? In SetDCClipping above,
2304 // XIntersectRegion is used to combine paint and user
2305 // regions. XIntersectRegion appears to work in that case...
2306 region
->Union(*rect
);
2312 win
->GetClientSize(&cw
, &ch
);
2313 region
= new wxRegion(wxRect(0, 0, cw
, ch
));
2316 win
->m_updateRegion
= *region
;
2318 // Set the clipping region. Any user-defined region will be combined with this
2319 // one in SetDCClipping.
2320 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) region
->GetXRegion());
2325 wxPaintDC::~wxPaintDC()
2327 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
2329 m_window
->m_updateRegion
.Clear();