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 // TODO: use scaled Blit e.g. as per John Price's implementation in Contrib/Utilities
921 bool wxWindowDC::Blit( long xdest
, long ydest
, long width
, long height
,
922 wxDC
*source
, long xsrc
, long ysrc
, int rop
, bool useMask
)
924 if (!Ok()) return FALSE
;
926 wxASSERT_MSG( (source
->IsKindOf(CLASSINFO(wxWindowDC
))), "Blit source DC must be wxWindowDC or derived class." );
928 wxWindowDC
* sourceDC
= (wxWindowDC
*) source
;
930 // FreeGetPixelCache();
932 // Be sure that foreground pixels (1) of
933 // the Icon will be painted with pen colour. [m_pen.SetColour()]
934 // Background pixels (0) will be painted with
935 // last selected background color. [::SetBackground]
936 if (m_pen
.Ok() && m_autoSetting
)
939 if (m_pixmap
&& sourceDC
->m_pixmap
)
942 int orig
= m_logicalFunction
;
944 SetLogicalFunction (rop
);
946 if (m_display
!= sourceDC
->m_display
)
948 XImage
*cache
= NULL
;
950 if (m_window
&& m_window
->GetBackingPixmap())
951 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
,
952 (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
954 source
->LogicalToDeviceX (xsrc
),
955 source
->LogicalToDeviceY (ysrc
),
956 source
->LogicalToDeviceXRel(width
),
957 source
->LogicalToDeviceYRel(height
),
958 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
),
961 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
963 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
964 wxBitmap
& sel
= memDC
->GetBitmap();
965 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetPixmap() )
967 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetPixmap());
968 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
972 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (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
),
982 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
983 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
988 if (m_window
&& m_window
->GetBackingPixmap())
990 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1
991 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetBitmap().GetDepth() == 1)
993 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
994 source
->LogicalToDeviceX (xsrc
),
995 source
->LogicalToDeviceY (ysrc
),
996 source
->LogicalToDeviceXRel(width
),
997 source
->LogicalToDeviceYRel(height
),
998 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 1);
1002 XCopyArea ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1003 source
->LogicalToDeviceX (xsrc
),
1004 source
->LogicalToDeviceY (ysrc
),
1005 source
->LogicalToDeviceXRel(width
),
1006 source
->LogicalToDeviceYRel(height
),
1007 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
));
1010 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
1012 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1013 wxBitmap
& sel
= memDC
->GetBitmap();
1014 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetPixmap() )
1016 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetPixmap());
1017 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
1021 // Check if we're copying from a mono bitmap
1022 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) &&
1023 ((wxMemoryDC
*)source
)->GetBitmap().Ok() && (((wxMemoryDC
*)source
)->GetBitmap().GetDepth () == 1))
1025 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1026 source
->LogicalToDeviceX (xsrc
),
1027 source
->LogicalToDeviceY (ysrc
),
1028 source
->LogicalToDeviceXRel(width
),
1029 source
->LogicalToDeviceYRel(height
),
1030 XLOG2DEV (xdest
), YLOG2DEV (ydest
), 1);
1034 XCopyArea ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1035 source
->LogicalToDeviceX (xsrc
),
1036 source
->LogicalToDeviceY (ysrc
),
1037 source
->LogicalToDeviceXRel(width
),
1038 source
->LogicalToDeviceYRel(height
),
1039 XLOG2DEV (xdest
), YLOG2DEV (ydest
));
1044 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
1045 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
1048 } /* Remote/local (Display*) m_display */
1049 CalcBoundingBox (xdest
, ydest
);
1050 CalcBoundingBox (xdest
+ width
, ydest
+ height
);
1052 SetLogicalFunction(orig
);
1059 /* Helper function for 16-bit fonts */
1060 static int str16len(const char *s
)
1064 while (s
[0] && s
[1]) {
1072 void wxWindowDC::DrawText( const wxString
&text
, long x
, long y
, bool use16
)
1076 // Since X draws from the baseline of the text, must
1077 // add the text height
1084 slen
= str16len(text
);
1086 slen
= strlen(text
);
1090 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1091 int direction
, descent
;
1092 XCharStruct overall_return
;
1094 (void)XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*)(const char*) text
, slen
, &direction
,
1095 &ascent
, &descent
, &overall_return
);
1097 (void)XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) text
, slen
, &direction
,
1098 &ascent
, &descent
, &overall_return
);
1099 cx
= overall_return
.width
;
1100 cy
= ascent
+ descent
;
1103 // First draw a rectangle representing the text background,
1104 // if a text background is specified
1105 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1107 wxColour oldPenColour
= m_currentColour
;
1108 m_currentColour
= m_textBackgroundColour
;
1109 bool sameColour
= (oldPenColour
.Ok () && m_textBackgroundColour
.Ok () &&
1110 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1111 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1112 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1114 // This separation of the big && test required for gcc2.7/HP UX 9.02
1115 // or pixel value can be corrupted!
1116 sameColour
= (sameColour
&&
1117 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1119 if (!sameColour
|| !GetOptimization())
1121 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1122 m_currentColour
= m_textBackgroundColour
;
1124 // Set the GC to the required colour
1127 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1128 if (m_window
&& m_window
->GetBackingPixmap())
1129 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1133 m_textBackgroundColour
= oldPenColour
;
1135 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1136 if (m_window
&& m_window
->GetBackingPixmap())
1137 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1138 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1141 // Now set the text foreground and draw the text
1142 if (m_textForegroundColour
.Ok ())
1144 wxColour oldPenColour
= m_currentColour
;
1145 m_currentColour
= m_textForegroundColour
;
1146 bool sameColour
= (oldPenColour
.Ok () && m_currentColour
.Ok () &&
1147 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1148 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1149 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1150 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1152 if (!sameColour
|| !GetOptimization())
1155 if (!m_colour
) // Mono display
1157 // Unless foreground is really white, draw it in black
1158 unsigned char red
= m_textForegroundColour
.Red ();
1159 unsigned char blue
= m_textForegroundColour
.Blue ();
1160 unsigned char green
= m_textForegroundColour
.Green ();
1161 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1162 && green
== (unsigned char) 255)
1164 m_currentColour
= *wxWHITE
;
1165 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1166 m_currentColour
.SetPixel(pixel
);
1167 m_textForegroundColour
.SetPixel(pixel
);
1171 m_currentColour
= *wxBLACK
;
1172 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1173 m_currentColour
.SetPixel(pixel
);
1174 m_textForegroundColour
.SetPixel(pixel
);
1179 pixel
= m_textForegroundColour
.AllocColour((Display
*) m_display
);
1180 m_currentColour
.SetPixel(pixel
);
1183 // Set the GC to the required colour
1186 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1187 if (m_window
&& m_window
->GetBackingPixmap())
1188 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1192 m_textForegroundColour
= oldPenColour
;
1195 // We need to add the ascent, not the whole height, since X draws
1196 // at the point above the descender.
1198 XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1199 (XChar2b
*)(char*) (const char*) text
, slen
);
1201 XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1204 if (m_window
&& m_window
->GetBackingPixmap()) {
1206 XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1207 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1208 (XChar2b
*)(char*) (const char*) text
, slen
);
1210 XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1211 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
, (char*) (const char*) text
, slen
);
1215 GetTextExtent (text
, &w
, &h
);
1216 CalcBoundingBox (x
+ w
, y
+ h
);
1217 CalcBoundingBox (x
, y
);
1220 bool wxWindowDC::CanGetTextExtent(void) const
1225 void wxWindowDC::GetTextExtent( const wxString
&string
, long *width
, long *height
,
1226 long *descent
, long *externalLeading
,
1227 wxFont
*font
, bool use16
)
1231 wxFont
* theFont
= font
;
1237 // TODO: this should be an error log function
1238 wxFAIL_MSG("set a valid font before calling GetTextExtent!");
1245 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1247 int direction
, ascent
, descent2
;
1248 XCharStruct overall
;
1251 if (use16
) slen
= str16len(string
); else slen
= strlen(string
);
1254 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1255 &ascent
, &descent2
, &overall
);
1257 XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) string
, slen
, &direction
,
1258 &ascent
, &descent2
, &overall
);
1260 *width
= XDEV2LOGREL (overall
.width
);
1261 *height
= YDEV2LOGREL (ascent
+ descent2
);
1263 *descent
= descent2
;
1264 if (externalLeading
)
1265 *externalLeading
= 0;
1268 long wxWindowDC::GetCharWidth(void)
1270 if (!Ok()) return 0;
1275 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
* m_logicalScaleY
, m_display
);
1277 int direction
, ascent
, descent
;
1278 XCharStruct overall
;
1279 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1280 &descent
, &overall
);
1281 return XDEV2LOGREL(overall
.width
);
1284 long wxWindowDC::GetCharHeight(void)
1286 if (!Ok()) return 0;
1291 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1293 int direction
, ascent
, descent
;
1294 XCharStruct overall
;
1295 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1296 &descent
, &overall
);
1297 // return XDEV2LOGREL(overall.ascent + overall.descent);
1298 return XDEV2LOGREL(ascent
+ descent
);
1301 void wxWindowDC::Clear(void)
1308 m_window
->GetSize(&w
, &h
);
1310 if (m_window
&& m_window
->GetBackingPixmap())
1312 w
= m_window
->GetPixmapWidth();
1313 h
= m_window
->GetPixmapHeight();
1318 if (this->IsKindOf(CLASSINFO(wxMemoryDC
)))
1320 wxMemoryDC
* memDC
= (wxMemoryDC
*) this;
1321 w
= memDC
->GetBitmap().GetWidth();
1322 h
= memDC
->GetBitmap().GetHeight();
1328 wxBrush saveBrush
= m_brush
;
1329 SetBrush (m_backgroundBrush
);
1331 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, 0, w
, h
);
1333 if (m_window
&& m_window
->GetBackingPixmap())
1334 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 0, 0, w
, h
);
1336 m_brush
= saveBrush
;
1339 void wxWindowDC::Clear(const wxRect
& rect
)
1343 int x
= rect
.x
; int y
= rect
.y
;
1344 int w
= rect
.width
; int h
= rect
.height
;
1346 wxBrush saveBrush
= m_brush
;
1347 SetBrush (m_backgroundBrush
);
1349 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x
, y
, w
, h
);
1351 if (m_window
&& m_window
->GetBackingPixmap())
1352 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, x
, y
, w
, h
);
1354 m_brush
= saveBrush
;
1357 void wxWindowDC::SetFont( const wxFont
&font
)
1365 if ((m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
1367 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
1369 if (m_window
&& m_window
->GetBackingPixmap())
1370 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
1375 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1377 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1378 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1380 if (m_window
&& m_window
->GetBackingPixmap())
1381 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1384 void wxWindowDC::SetPen( const wxPen
&pen
)
1392 wxBitmap oldStipple
= m_currentStipple
;
1393 int oldStyle
= m_currentStyle
;
1394 int oldFill
= m_currentFill
;
1395 int old_pen_width
= m_currentPenWidth
;
1396 int old_pen_join
= m_currentPenJoin
;
1397 int old_pen_cap
= m_currentPenCap
;
1398 int old_pen_nb_dash
= m_currentPenDashCount
;
1399 char *old_pen_dash
= m_currentPenDash
;
1401 wxColour oldPenColour
= m_currentColour
;
1402 m_currentColour
= m_pen
.GetColour ();
1403 m_currentStyle
= m_pen
.GetStyle ();
1404 m_currentFill
= m_pen
.GetStyle (); // TODO?
1405 m_currentPenWidth
= m_pen
.GetWidth ();
1406 m_currentPenJoin
= m_pen
.GetJoin ();
1407 m_currentPenCap
= m_pen
.GetCap ();
1408 m_currentPenDashCount
= m_pen
.GetDashCount();
1409 m_currentPenDash
= m_pen
.GetDash();
1411 if (m_currentStyle
== wxSTIPPLE
)
1412 m_currentStipple
= * m_pen
.GetStipple ();
1414 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1415 oldFill
== m_currentFill
&&
1416 old_pen_join
== m_currentPenJoin
&&
1417 old_pen_cap
== m_currentPenCap
&&
1418 old_pen_nb_dash
== m_currentPenDashCount
&&
1419 old_pen_dash
== m_currentPenDash
&&
1420 old_pen_width
== m_currentPenWidth
);
1422 bool sameColour
= (oldPenColour
.Ok () &&
1423 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1424 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1425 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1426 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1428 if (!sameStyle
|| !GetOptimization())
1430 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1431 if (scaled_width
< 0)
1437 static char dotted
[] =
1439 static char short_dashed
[] =
1441 static char long_dashed
[] =
1443 static char dotted_dashed
[] =
1446 // We express dash pattern in pen width unit, so we are
1447 // independent of zoom factor and so on...
1451 switch (m_pen
.GetStyle ())
1454 req_nb_dash
= m_currentPenDashCount
;
1455 req_dash
= m_currentPenDash
;
1456 style
= LineOnOffDash
;
1461 style
= LineOnOffDash
;
1465 req_dash
= short_dashed
;
1466 style
= LineOnOffDash
;
1470 req_dash
= long_dashed
;
1471 style
= LineOnOffDash
;
1475 req_dash
= dotted_dashed
;
1476 style
= LineOnOffDash
;
1487 if (req_dash
&& req_nb_dash
)
1489 char *real_req_dash
= new char[req_nb_dash
];
1492 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1493 for (int i
= 0; i
< req_nb_dash
; i
++)
1494 real_req_dash
[i
] = req_dash
[i
] * factor
;
1495 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1497 if (m_window
&& m_window
->GetBackingPixmap())
1498 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1499 delete[]real_req_dash
;
1503 // No Memory. We use non-scaled dash pattern...
1504 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1506 if (m_window
&& m_window
->GetBackingPixmap())
1507 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1511 switch (m_pen
.GetCap ())
1513 case wxCAP_PROJECTING
:
1514 cap
= CapProjecting
;
1521 cap
= (scaled_width
<= 1) ? CapNotLast
: CapRound
;
1525 switch (m_pen
.GetJoin ())
1539 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1541 if (m_window
&& m_window
->GetBackingPixmap())
1542 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1545 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1549 oldStipple
= wxNullBitmap
; // For later reset!!
1551 switch (m_currentFill
)
1553 case wxBDIAGONAL_HATCH
:
1554 if (bdiag
== (Pixmap
) 0)
1555 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1556 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1557 bdiag_bits
, bdiag_width
, bdiag_height
);
1560 case wxFDIAGONAL_HATCH
:
1561 if (fdiag
== (Pixmap
) 0)
1562 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1563 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1564 fdiag_bits
, fdiag_width
, fdiag_height
);
1568 if (cross
== (Pixmap
) 0)
1569 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1570 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1571 cross_bits
, cross_width
, cross_height
);
1574 case wxHORIZONTAL_HATCH
:
1575 if (horiz
== (Pixmap
) 0)
1576 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1577 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1578 horiz_bits
, horiz_width
, horiz_height
);
1581 case wxVERTICAL_HATCH
:
1582 if (verti
== (Pixmap
) 0)
1583 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1584 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1585 verti_bits
, verti_width
, verti_height
);
1588 case wxCROSSDIAG_HATCH
:
1590 if (cdiag
== (Pixmap
) 0)
1591 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1592 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1593 cdiag_bits
, cdiag_width
, cdiag_height
);
1597 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1599 if (m_window
&& m_window
->GetBackingPixmap())
1600 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1602 else if (m_currentStipple
.Ok()
1603 && ((m_currentStipple
!= oldStipple
) || !GetOptimization()))
1605 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1607 if (m_window
&& m_window
->GetBackingPixmap())
1608 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1611 if ((m_currentFill
!= oldFill
) || !GetOptimization())
1615 if (m_currentFill
== wxSTIPPLE
)
1616 fill_style
= FillStippled
;
1617 else if (IS_HATCH (m_currentFill
))
1618 fill_style
= FillStippled
;
1620 fill_style
= FillSolid
;
1621 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1622 if (m_window
&& m_window
->GetBackingPixmap())
1623 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1626 // must test m_logicalFunction, because it involves background!
1627 if (!sameColour
|| !GetOptimization()
1628 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1631 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1632 pixel
= m_backgroundPixel
;
1635 unsigned char red
= m_pen
.GetColour ().Red ();
1636 unsigned char blue
= m_pen
.GetColour ().Blue ();
1637 unsigned char green
= m_pen
.GetColour ().Green ();
1638 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1639 && green
== (unsigned char) 255)
1641 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1642 m_currentColour
= *wxWHITE
;
1643 m_pen
.GetColour().SetPixel(pixel
);
1644 m_currentColour
.SetPixel(pixel
);
1648 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1649 m_currentColour
= *wxBLACK
;
1650 m_pen
.GetColour().SetPixel(pixel
);
1655 pixel
= m_pen
.GetColour ().AllocColour(m_display
);
1656 m_currentColour
.SetPixel(pixel
);
1659 // Finally, set the GC to the required colour
1662 if (m_logicalFunction
== wxXOR
)
1665 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1666 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1667 if (m_window
&& m_window
->GetBackingPixmap())
1668 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1672 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1673 if (m_window
&& m_window
->GetBackingPixmap())
1674 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1679 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1684 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1690 if (!m_brush
.Ok() || m_brush
.GetStyle () == wxTRANSPARENT
)
1693 int oldFill
= m_currentFill
;
1694 wxBitmap oldStipple
= m_currentStipple
;
1696 m_autoSetting
|= 0x1;
1698 m_currentFill
= m_brush
.GetStyle ();
1699 if (m_currentFill
== wxSTIPPLE
)
1700 m_currentStipple
= * m_brush
.GetStipple ();
1702 wxColour
oldBrushColour(m_currentColour
);
1703 m_currentColour
= m_brush
.GetColour ();
1705 bool sameColour
= (oldBrushColour
.Ok () &&
1706 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1707 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1708 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1709 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1711 if ((oldFill
!= m_brush
.GetStyle ()) || !GetOptimization())
1713 switch (brush
.GetStyle ())
1717 case wxBDIAGONAL_HATCH
:
1718 case wxCROSSDIAG_HATCH
:
1719 case wxFDIAGONAL_HATCH
:
1721 case wxHORIZONTAL_HATCH
:
1722 case wxVERTICAL_HATCH
:
1725 // Chris Breeze 23/07/97: use background mode to determine whether
1726 // fill style should be solid or transparent
1727 int style
= (m_backgroundMode
== wxSOLID
? FillOpaqueStippled
: FillStippled
);
1728 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1729 if (m_window
&& m_window
->GetBackingPixmap())
1730 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1735 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1736 if (m_window
&& m_window
->GetBackingPixmap())
1737 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, FillSolid
);
1741 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1745 switch (m_currentFill
)
1747 case wxBDIAGONAL_HATCH
:
1748 if (bdiag
== (Pixmap
) 0)
1749 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1750 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1751 bdiag_bits
, bdiag_width
, bdiag_height
);
1754 case wxFDIAGONAL_HATCH
:
1755 if (fdiag
== (Pixmap
) 0)
1756 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1757 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1758 fdiag_bits
, fdiag_width
, fdiag_height
);
1762 if (cross
== (Pixmap
) 0)
1763 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1764 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1765 cross_bits
, cross_width
, cross_height
);
1768 case wxHORIZONTAL_HATCH
:
1769 if (horiz
== (Pixmap
) 0)
1770 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1771 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1772 horiz_bits
, horiz_width
, horiz_height
);
1775 case wxVERTICAL_HATCH
:
1776 if (verti
== (Pixmap
) 0)
1777 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1778 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1779 verti_bits
, verti_width
, verti_height
);
1782 case wxCROSSDIAG_HATCH
:
1784 if (cdiag
== (Pixmap
) 0)
1785 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1786 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1787 cdiag_bits
, cdiag_width
, cdiag_height
);
1791 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1793 if (m_window
&& m_window
->GetBackingPixmap())
1794 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1796 // X can forget the stipple value when resizing a window (apparently)
1797 // so always set the stipple.
1798 else if (m_currentStipple
.Ok()) // && m_currentStipple != oldStipple)
1800 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1801 if (m_window
&& m_window
->GetBackingPixmap())
1802 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1805 // must test m_logicalFunction, because it involves background!
1806 if (!sameColour
|| !GetOptimization() || m_logicalFunction
== wxXOR
)
1811 // Policy - on a monochrome screen, all brushes are white,
1812 // except when they're REALLY black!!!
1813 unsigned char red
= m_brush
.GetColour ().Red ();
1814 unsigned char blue
= m_brush
.GetColour ().Blue ();
1815 unsigned char green
= m_brush
.GetColour ().Green ();
1817 if (red
== (unsigned char) 0 && blue
== (unsigned char) 0
1818 && green
== (unsigned char) 0)
1820 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1821 m_currentColour
= *wxBLACK
;
1822 m_brush
.GetColour().SetPixel(pixel
);
1823 m_currentColour
.SetPixel(pixel
);
1827 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1828 m_currentColour
= *wxWHITE
;
1829 m_brush
.GetColour().SetPixel(pixel
);
1830 m_currentColour
.SetPixel(pixel
);
1833 // N.B. comment out the above line and uncomment the following lines
1834 // if you want non-white colours to be black on a monochrome display.
1836 if (red == (unsigned char )255 && blue == (unsigned char)255
1837 && green == (unsigned char)255)
1838 pixel = (int)WhitePixel((Display*) m_display, DefaultScreen((Display*) m_display));
1840 pixel = (int)BlackPixel((Display*) m_display, DefaultScreen((Display*) m_display));
1843 else if (m_brush
.GetStyle () != wxTRANSPARENT
)
1845 pixel
= m_brush
.GetColour().AllocColour(m_display
);
1846 m_currentColour
.SetPixel(pixel
);
1850 // Finally, set the GC to the required colour
1851 if (m_logicalFunction
== wxXOR
)
1854 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1855 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1856 if (m_window
&& m_window
->GetBackingPixmap())
1857 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1861 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1862 if (m_window
&& m_window
->GetBackingPixmap())
1863 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1868 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1871 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1875 m_backgroundBrush
= brush
;
1877 if (!m_backgroundBrush
.Ok())
1880 int pixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
1882 // XSetWindowBackground doesn't work for non-Window pixmaps
1883 if (!this->IsKindOf(CLASSINFO(wxMemoryDC
)))
1884 XSetWindowBackground ((Display
*) m_display
, (Pixmap
) m_pixmap
, pixel
);
1886 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
1887 // And Blit,... (Any fct that use XCopyPlane, in fact.)
1888 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1889 if (m_window
&& m_window
->GetBackingPixmap())
1890 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1893 void wxWindowDC::SetLogicalFunction( int function
)
1898 if (m_logicalFunction
== function
)
1904 x_function
= GXclear
;
1910 x_function
= GXinvert
;
1913 x_function
= GXorReverse
;
1916 x_function
= GXandReverse
;
1925 x_function
= GXandInverted
;
1928 x_function
= GXnoop
;
1934 x_function
= GXequiv
;
1937 x_function
= GXcopyInverted
;
1940 x_function
= GXorInverted
;
1943 x_function
= GXnand
;
1950 x_function
= GXcopy
;
1954 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
1955 if (m_window
&& m_window
->GetBackingPixmap())
1956 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
1958 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
1959 /* MATTHEW: [9] Need to redo pen simply */
1960 m_autoSetting
|= 0x2;
1962 m_logicalFunction
= function
;
1966 void wxWindowDC::SetTextForeground( const wxColour
&col
)
1970 if (m_textForegroundColour
== col
) return;
1972 m_textForegroundColour
= col
;
1976 void wxWindowDC::SetTextBackground( const wxColour
&col
)
1980 if (m_textBackgroundColour
== col
) return;
1982 m_textBackgroundColour
= col
;
1983 if (!m_textBackgroundColour
.Ok()) return;
1986 void wxWindowDC::SetBackgroundMode( int mode
)
1988 m_backgroundMode
= mode
;
1992 void wxWindowDC::SetPalette( const wxPalette
& palette
)
1997 /* Use GetXColormap */
1998 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1999 (Colormap
) palette
.GetXColormap());
2001 /* Use wxGetMainColormap */
2002 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2003 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2008 void wxWindowDC:: SetDCClipping ()
2010 // m_userRegion is the region set by calling SetClippingRegion
2012 if (m_currentRegion
)
2013 XDestroyRegion ((Region
) m_currentRegion
);
2015 // We need to take into account
2016 // clipping imposed on a window by a repaint.
2017 // We'll combine it with the user region. But for now,
2018 // just use the currently-defined user clipping region.
2019 if (m_userRegion
|| (m_window
&& m_window
->GetUpdateRegion().Ok()) )
2020 m_currentRegion
= (WXRegion
) XCreateRegion ();
2022 m_currentRegion
= (WXRegion
) NULL
;
2024 if ((m_window
&& m_window
->GetUpdateRegion().Ok()) && m_userRegion
)
2025 XIntersectRegion ((Region
) m_window
->GetUpdateRegion().GetXRegion(), (Region
) m_userRegion
, (Region
) m_currentRegion
);
2026 else if (m_userRegion
)
2027 XIntersectRegion ((Region
) m_userRegion
, (Region
) m_userRegion
, (Region
) m_currentRegion
);
2028 else if (m_window
&& m_window
->GetUpdateRegion().Ok())
2029 XIntersectRegion ((Region
) m_window
->GetUpdateRegion().GetXRegion(), (Region
) m_window
->GetUpdateRegion().GetXRegion(),
2030 (Region
) m_currentRegion
);
2032 if (m_currentRegion
)
2034 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) m_currentRegion
);
2038 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
2043 void wxWindowDC::SetClippingRegion( long x
, long y
, long width
, long height
)
2045 wxDC::SetClippingRegion( x
, y
, width
, height
);
2048 XDestroyRegion ((Region
) m_userRegion
);
2049 m_userRegion
= (WXRegion
) XCreateRegion ();
2053 r
.width
= XLOG2DEVREL(width
);
2054 r
.height
= YLOG2DEVREL(height
);
2055 XUnionRectWithRegion (&r
, (Region
) m_userRegion
, (Region
) m_userRegion
);
2059 // Needs to work differently for Pixmap: without this,
2060 // there's a nasty (Display*) m_display bug. 8/12/94
2061 if (m_window
&& m_window
->GetBackingPixmap())
2063 XRectangle rects
[1];
2064 rects
[0].x
= XLOG2DEV_2(x
);
2065 rects
[0].y
= YLOG2DEV_2(y
);
2066 rects
[0].width
= XLOG2DEVREL(width
);
2067 rects
[0].height
= YLOG2DEVREL(height
);
2068 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 0, 0, rects
, 1, Unsorted
);
2072 void wxWindowDC::SetClippingRegion( const wxRegion
& region
)
2074 wxRect box
= region
.GetBox();
2076 wxDC::SetClippingRegion( box
.x
, box
.y
, box
.width
, box
.height
);
2079 XDestroyRegion ((Region
) m_userRegion
);
2080 m_userRegion
= (WXRegion
) XCreateRegion ();
2082 XUnionRegion((Region
) m_userRegion
, (Region
) region
.GetXRegion(), (Region
) m_userRegion
);
2086 // Needs to work differently for Pixmap: without this,
2087 // there's a nasty (Display*) m_display bug. 8/12/94
2088 if (m_window
&& m_window
->GetBackingPixmap())
2090 XRectangle rects
[1];
2091 rects
[0].x
= XLOG2DEV_2(box
.x
);
2092 rects
[0].y
= YLOG2DEV_2(box
.y
);
2093 rects
[0].width
= XLOG2DEVREL(box
.width
);
2094 rects
[0].height
= YLOG2DEVREL(box
.height
);
2095 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 0, 0, rects
, 1, Unsorted
);
2100 void wxWindowDC::DestroyClippingRegion(void)
2102 wxDC::DestroyClippingRegion();
2105 XDestroyRegion ((Region
) m_userRegion
);
2106 m_userRegion
= NULL
;
2111 gc_val
.clip_mask
= None
;
2112 if (m_window
&& m_window
->GetBackingPixmap())
2113 XChangeGC((Display
*) m_display
, (GC
) m_gcBacking
, GCClipMask
, &gc_val
);
2116 // ----------------------------------- spline code ----------------------------------------
2118 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
2119 double a3
, double b3
, double a4
, double b4
);
2120 void wx_clear_stack(void);
2121 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
2122 double *y3
, double *x4
, double *y4
);
2123 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
2124 double x4
, double y4
);
2125 static bool wx_spline_add_point(double x
, double y
);
2126 static void wx_spline_draw_point_array(wxDC
*dc
);
2128 wxList wx_spline_point_list
;
2130 #define half(z1, z2) ((z1+z2)/2.0)
2133 /* iterative version */
2135 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
2138 register double xmid
, ymid
;
2139 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
2142 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
2144 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
2145 xmid
= (double)half(x2
, x3
);
2146 ymid
= (double)half(y2
, y3
);
2147 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
2148 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
2149 wx_spline_add_point( x1
, y1
);
2150 wx_spline_add_point( xmid
, ymid
);
2152 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
2153 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
2154 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
2155 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
2160 /* utilities used by spline drawing routines */
2162 typedef struct wx_spline_stack_struct
{
2163 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
2166 #define SPLINE_STACK_DEPTH 20
2167 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
2168 static Stack
*wx_stack_top
;
2169 static int wx_stack_count
;
2171 void wx_clear_stack(void)
2173 wx_stack_top
= wx_spline_stack
;
2177 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
2179 wx_stack_top
->x1
= x1
;
2180 wx_stack_top
->y1
= y1
;
2181 wx_stack_top
->x2
= x2
;
2182 wx_stack_top
->y2
= y2
;
2183 wx_stack_top
->x3
= x3
;
2184 wx_stack_top
->y3
= y3
;
2185 wx_stack_top
->x4
= x4
;
2186 wx_stack_top
->y4
= y4
;
2191 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
2192 double *x3
, double *y3
, double *x4
, double *y4
)
2194 if (wx_stack_count
== 0)
2198 *x1
= wx_stack_top
->x1
;
2199 *y1
= wx_stack_top
->y1
;
2200 *x2
= wx_stack_top
->x2
;
2201 *y2
= wx_stack_top
->y2
;
2202 *x3
= wx_stack_top
->x3
;
2203 *y3
= wx_stack_top
->y3
;
2204 *x4
= wx_stack_top
->x4
;
2205 *y4
= wx_stack_top
->y4
;
2209 static bool wx_spline_add_point(double x
, double y
)
2211 wxPoint
*point
= new wxPoint
;
2214 wx_spline_point_list
.Append((wxObject
*)point
);
2218 static void wx_spline_draw_point_array(wxDC
*dc
)
2220 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
2221 wxNode
*node
= wx_spline_point_list
.First();
2224 wxPoint
*point
= (wxPoint
*)node
->Data();
2227 node
= wx_spline_point_list
.First();
2231 void wxWindowDC::DrawSpline( wxList
*points
)
2234 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
2235 double x1
, y1
, x2
, y2
;
2237 wxNode
*node
= points
->First();
2238 p
= (wxPoint
*)node
->Data();
2243 node
= node
->Next();
2244 p
= (wxPoint
*)node
->Data();
2248 cx1
= (double)((x1
+ x2
) / 2);
2249 cy1
= (double)((y1
+ y2
) / 2);
2250 cx2
= (double)((cx1
+ x2
) / 2);
2251 cy2
= (double)((cy1
+ y2
) / 2);
2253 wx_spline_add_point(x1
, y1
);
2255 while ((node
= node
->Next()) != NULL
)
2257 p
= (wxPoint
*)node
->Data();
2262 cx4
= (double)(x1
+ x2
) / 2;
2263 cy4
= (double)(y1
+ y2
) / 2;
2264 cx3
= (double)(x1
+ cx4
) / 2;
2265 cy3
= (double)(y1
+ cy4
) / 2;
2267 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
2271 cx2
= (double)(cx1
+ x2
) / 2;
2272 cy2
= (double)(cy1
+ y2
) / 2;
2275 wx_spline_add_point( cx1
, cy1
);
2276 wx_spline_add_point( x2
, y2
);
2278 wx_spline_draw_point_array( this );
2285 wxPaintDC::wxPaintDC(wxWindow
* win
): wxWindowDC(win
)
2287 wxRegion
* region
= NULL
;
2289 // Combine all the update rects into a region
2290 if (win
->m_updateRects
.Number() > 0)
2293 for (i
= 0; i
< win
->m_updateRects
.Number(); i
++)
2295 wxRect
* rect
= (wxRect
*) win
->m_updateRects
.Nth(i
)->Data();
2297 cout << "wxPaintDC. wxRect: " << rect->x << ", " << rect->y << ", ";
2298 cout << rect->width << ", " << rect->height << "\n\n";
2302 region
= new wxRegion(*rect
);
2304 // TODO: is this correct? In SetDCClipping above,
2305 // XIntersectRegion is used to combine paint and user
2306 // regions. XIntersectRegion appears to work in that case...
2307 region
->Union(*rect
);
2313 win
->GetClientSize(&cw
, &ch
);
2314 region
= new wxRegion(wxRect(0, 0, cw
, ch
));
2317 win
->m_updateRegion
= *region
;
2319 // Set the clipping region. Any user-defined region will be combined with this
2320 // one in SetDCClipping.
2321 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) region
->GetXRegion());
2326 wxPaintDC::~wxPaintDC()
2328 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
2330 m_window
->m_updateRegion
.Clear();