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
60 // Fudge factor. Obsolete?
63 //-----------------------------------------------------------------------------
65 //-----------------------------------------------------------------------------
67 #if !USE_SHARED_LIBRARY
68 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
69 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxWindowDC
)
70 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
73 wxWindowDC::wxWindowDC(void)
76 m_gcBacking
= (WXGC
) 0;
78 m_backgroundPixel
= -1;
79 m_currentPenWidth
= 1;
80 m_currentPenJoin
= -1;
81 m_currentPenDashCount
= -1;
82 m_currentPenDash
= (char*) NULL
;
85 // m_currentBkMode = wxTRANSPARENT;
86 m_colour
= wxColourDisplay();
87 m_display
= (WXDisplay
*) NULL
;
88 m_currentRegion
= (WXRegion
) 0;
89 m_userRegion
= (WXRegion
) 0;
90 m_pixmap
= (WXPixmap
) 0;
92 m_oldFont
= (WXFont
) 0;
95 wxWindowDC::wxWindowDC( wxWindow
*window
)
97 wxASSERT_MSG( (window
!= (wxWindow
*) NULL
), "You must pass a valid wxWindow to wxWindowDC/wxClientDC/wxPaintDC constructor." );
101 m_gcBacking
= (WXGC
) 0;
102 m_backgroundPixel
= -1;
103 m_currentPenWidth
= 1;
104 m_currentPenJoin
= -1;
105 m_currentPenDashCount
= -1;
106 m_currentPenDash
= (char*) NULL
;
109 // m_currentBkMode = wxTRANSPARENT;
110 m_colour
= wxColourDisplay();
111 m_currentRegion
= (WXRegion
) 0;
112 m_userRegion
= (WXRegion
) 0;
116 m_display
= window
->GetXDisplay();
117 m_pixmap
= window
->GetXWindow();
118 Display
* display
= (Display
*) m_display
;
120 XSetWindowColormap (display
, (Pixmap
) m_pixmap
, (Colormap
) wxTheApp
->GetMainColormap(m_display
));
123 gcvalues
.foreground
= BlackPixel (display
, DefaultScreen (display
));
124 gcvalues
.background
= WhitePixel (display
, DefaultScreen (display
));
125 gcvalues
.graphics_exposures
= False
;
126 gcvalues
.line_width
= 1;
127 m_gc
= (WXGC
) XCreateGC (display
, RootWindow (display
, DefaultScreen (display
)),
128 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
,
131 if (m_window
->GetBackingPixmap())
133 m_gcBacking
= (WXGC
) XCreateGC (display
, RootWindow (display
,
134 DefaultScreen (display
)),
135 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
,
139 m_backgroundPixel
= (int) gcvalues
.background
;
141 // Get the current Font so we can set it back later
143 XGetGCValues((Display
*) m_display
, (GC
) m_gc
, GCFont
, &valReturn
);
144 m_oldFont
= (WXFont
) valReturn
.font
;
147 wxWindowDC::~wxWindowDC(void)
149 if (m_gc
&& (m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
151 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
153 if (m_window
&& m_window
->GetBackingPixmap())
154 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
158 XFreeGC ((Display
*) m_display
, (GC
) m_gc
);
162 XFreeGC ((Display
*) m_display
, (GC
) m_gcBacking
);
163 m_gcBacking
= (WXGC
) 0;
166 XDestroyRegion ((Region
) m_currentRegion
);
167 m_currentRegion
= (WXRegion
) 0;
170 XDestroyRegion ((Region
) m_userRegion
);
171 m_userRegion
= (WXRegion
) 0;
174 void wxWindowDC::FloodFill( long WXUNUSED(x1
), long WXUNUSED(y1
),
175 const wxColour
& WXUNUSED(col
), int WXUNUSED(style
) )
180 bool wxWindowDC::GetPixel( long WXUNUSED(x1
), long WXUNUSED(y1
), wxColour
*WXUNUSED(col
) ) const
186 void wxWindowDC::DrawLine( long x1
, long y1
, long x2
, long y2
)
190 int x1d
, y1d
, x2d
, y2d
;
192 // FreeGetPixelCache();
202 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x1d
, y1d
, x2d
, y2d
);
204 if (m_window
&& m_window
->GetBackingPixmap())
205 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
206 XLOG2DEV_2(x1
), YLOG2DEV_2(y1
),
207 XLOG2DEV_2(x2
), YLOG2DEV_2(y2
));
209 CalcBoundingBox(x1
, y1
);
210 CalcBoundingBox(x2
, y2
);
213 void wxWindowDC::CrossHair( long x
, long y
)
220 int xx
= XLOG2DEV (x
);
221 int yy
= YLOG2DEV (y
);
223 wxDisplaySize (&ww
, &hh
);
224 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, yy
,
226 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xx
, 0,
229 if (m_window
&& m_window
->GetBackingPixmap())
233 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
236 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
242 void wxWindowDC::DrawArc( long x1
, long y1
, long x2
, long y2
, long xc
, long yc
)
246 // FreeGetPixelCache();
248 int xx1
= XLOG2DEV (x1
);
249 int yy1
= YLOG2DEV (y1
);
250 int xx2
= XLOG2DEV (x2
);
251 int yy2
= YLOG2DEV (y2
);
252 int xxc
= XLOG2DEV (xc
);
253 int yyc
= YLOG2DEV (yc
);
254 int xxc_2
= XLOG2DEV_2 (xc
);
255 int yyc_2
= YLOG2DEV_2 (yc
);
259 double radius
= sqrt (dx
* dx
+ dy
* dy
);
260 long r
= (long) radius
;
262 double radius1
, radius2
;
264 if (xx1
== xx2
&& yy1
== yy2
)
269 else if (radius
== 0.0)
270 radius1
= radius2
= 0.0;
279 radius1
= -atan2 ((double) (yy1
- yyc
), (double) (xx1
- xxc
)) * 360.0 / (2 * M_PI
);
287 radius2
= -atan2 ((double) (yy2
- yyc
), (double) (xx2
- xxc
)) * 360.0 / (2 * M_PI
);
291 int alpha1
= (int) radius1
;
292 int alpha2
= (int) (radius2
- radius1
);
295 while (alpha2
> 360 * 64)
298 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
301 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) (GC
) m_gc
,
302 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
304 if (m_window
&& m_window
->GetBackingPixmap())
305 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
306 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
310 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
314 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
315 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
317 if (m_window
&& m_window
->GetBackingPixmap())
318 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
319 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
321 CalcBoundingBox (x1
, y1
);
322 CalcBoundingBox (x2
, y2
);
325 void wxWindowDC::DrawEllipticArc( long x
, long y
, long width
, long height
, double sa
, double ea
)
333 wd
= XLOG2DEVREL(width
);
334 hd
= YLOG2DEVREL(height
);
336 if (sa
>=360 || sa
<=-360) sa
=sa
-int(sa
/360)*360;
337 if (ea
>=360 || ea
<=-360) ea
=ea
-int(ea
/360)*360;
338 int start
= int(sa
*64);
339 int end
= int(ea
*64);
340 if (start
<0) start
+=360*64;
341 if (end
<0) end
+=360*64;
342 if (end
>start
) end
-=start
;
343 else end
+=360*64-start
;
345 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
347 m_autoSetting
= TRUE
; // must be reset
350 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
, end
);
352 if (m_window
&& m_window
->GetBackingPixmap())
353 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
354 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
357 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
361 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
,end
);
362 if (m_window
&& m_window
->GetBackingPixmap())
363 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
364 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
366 CalcBoundingBox (x
, y
);
367 CalcBoundingBox (x
+ width
, y
+ height
);
370 void wxWindowDC::DrawPoint( long x
, long y
)
374 // FreeGetPixelCache();
376 if (m_pen
.Ok() && m_autoSetting
)
379 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
));
380 if (m_window
&& m_window
->GetBackingPixmap())
381 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, XLOG2DEV_2 (x
), YLOG2DEV_2 (y
));
383 CalcBoundingBox (x
, y
);
386 void wxWindowDC::DrawLines( int n
, wxPoint points
[], long xoffset
, long yoffset
)
390 // FreeGetPixelCache();
392 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
397 XPoint
*xpoints
= new XPoint
[n
];
400 for (i
= 0; i
< n
; i
++)
402 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
403 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
405 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints
, n
, 0);
407 if (m_window
&& m_window
->GetBackingPixmap())
409 for (i
= 0; i
< n
; i
++)
411 xpoints
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
412 xpoints
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
414 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints
, n
, 0);
420 void wxWindowDC::DrawLines( wxList
*list
, long xoffset
, long yoffset
)
424 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
426 int n
= list
->Number();
427 wxPoint
*points
= new wxPoint
[n
];
430 for(wxNode
*node
= list
->First(); node
; node
= node
->Next()) {
431 wxPoint
*point
= (wxPoint
*)node
->Data();
432 points
[i
].x
= point
->x
;
433 points
[i
++].y
= point
->y
;
435 DrawLines(n
, points
, xoffset
, yoffset
);
439 void wxWindowDC::DrawPolygon( int n
, wxPoint points
[],
440 long xoffset
, long yoffset
, int fillStyle
)
442 // FreeGetPixelCache();
444 XPoint
*xpoints1
= new XPoint
[n
+ 1];
445 XPoint
*xpoints2
= new XPoint
[n
+ 1];
447 for (i
= 0; i
< n
; i
++)
449 xpoints1
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
450 xpoints1
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
451 xpoints2
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
452 xpoints2
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
453 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
456 // Close figure for XDrawLines (not needed for XFillPolygon)
457 xpoints1
[i
].x
= xpoints1
[0].x
;
458 xpoints1
[i
].y
= xpoints1
[0].y
;
459 xpoints2
[i
].x
= xpoints2
[0].x
;
460 xpoints2
[i
].y
= xpoints2
[0].y
;
462 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
465 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
466 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
, Complex
, 0);
467 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, EvenOddRule
); // default mode
468 if (m_window
&& m_window
->GetBackingPixmap())
470 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
,
471 fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
472 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
, Complex
, 0);
473 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
, EvenOddRule
); // default mode
477 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
481 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
+ 1, 0);
483 if (m_window
&& m_window
->GetBackingPixmap())
484 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
+ 1, 0);
491 void wxWindowDC::DrawPolygon( wxList
*list
, long xoffset
,
492 long yoffset
, int fillStyle
)
496 int n
= list
->Number();
497 wxPoint
*points
= new wxPoint
[n
];
500 for(wxNode
*node
= list
->First(); node
; node
= node
->Next()) {
501 wxPoint
*point
= (wxPoint
*)node
->Data();
502 points
[i
].x
= point
->x
;
503 points
[i
++].y
= point
->y
;
505 DrawPolygon(n
, points
, xoffset
, yoffset
,fillStyle
);
509 void wxWindowDC::DrawRectangle( long x
, long y
, long width
, long height
)
513 // FreeGetPixelCache();
515 int xd
, yd
, wfd
, hfd
, wd
, hd
;
519 wfd
= XLOG2DEVREL(width
);
521 hfd
= YLOG2DEVREL(height
);
524 if (wfd
== 0 || hfd
== 0) return;
525 if (wd
< 0) { wd
= - wd
; xd
= xd
- wd
; }
526 if (hd
< 0) { hd
= - hd
; yd
= yd
- hd
; }
528 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
531 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wfd
, hfd
);
533 if (m_window
&& m_window
->GetBackingPixmap())
534 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
535 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
539 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
543 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
);
545 if (m_window
&& m_window
->GetBackingPixmap())
546 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
547 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
550 CalcBoundingBox (x
, y
);
551 CalcBoundingBox (x
+ width
, y
+ height
);
554 void wxWindowDC::DrawRoundedRectangle( long x
, long y
, long width
, long height
, double radius
)
558 // FreeGetPixelCache();
560 // If radius is negative, it's a proportion of the smaller dimension.
562 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
564 int xd
= XLOG2DEV (x
);
565 int yd
= YLOG2DEV (y
);
566 int rd
= XLOG2DEVREL ((long) radius
);
567 int wd
= XLOG2DEVREL (width
) - WX_GC_CF
;
568 int hd
= YLOG2DEVREL (height
) - WX_GC_CF
;
573 // If radius is zero use DrawRectangle() instead to avoid
574 // X drawing errors with small radii
577 DrawRectangle( x
, y
, width
, height
);
581 // Draw nothing if transformed w or h is 0
582 if (wd
== 0 || hd
== 0) return;
584 // CMB: adjust size if outline is drawn otherwise the result is
585 // 1 pixel too wide and high
586 if (m_pen
.GetStyle() != wxTRANSPARENT
)
592 // CMB: ensure dd is not larger than rectangle otherwise we
593 // get an hour glass shape
594 if (rw_d
> wd
) rw_d
= wd
;
595 if (rw_d
> hd
) rw_d
= hd
;
598 // For backing pixmap
599 int xd2
= XLOG2DEV_2 (x
);
600 int yd2
= YLOG2DEV_2 (y
);
601 int rd2
= XLOG2DEVREL ((long) radius
);
602 int wd2
= XLOG2DEVREL (width
) ;
603 int hd2
= YLOG2DEVREL (height
) ;
608 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
612 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
614 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
617 // Arcs start from 3 o'clock, positive angles anticlockwise
619 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
620 rw_d
, rh_d
, 90 * 64, 90 * 64);
622 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
623 // rw_d, rh_d, 0, 90 * 64);
624 rw_d
, rh_d
, 0, 91 * 64);
626 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
628 // rw_d, rh_d, 270 * 64, 90 * 64);
629 rw_d
, rh_d
, 269 * 64, 92 * 64);
631 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
632 rw_d
, rh_d
, 180 * 64, 90 * 64);
634 if (m_window
&& m_window
->GetBackingPixmap())
636 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
637 xd2
+ rd2
, yd2
, wd2
- rw_d2
, hd2
);
638 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
639 xd2
, yd2
+ rd2
, wd2
, hd2
- rh_d2
);
641 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
642 xd2
, yd2
, rw_d2
, rh_d2
, 90 * 64, 90 * 64);
643 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
644 xd2
+ wd2
- rw_d2
, yd2
,
645 // rw_d2, rh_d2, 0, 90 * 64);
646 rw_d2
, rh_d2
, 0, 91 * 64);
647 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
650 // rw_d2, rh_d2, 270 * 64, 90 * 64);
651 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
652 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
653 xd2
, yd2
+ hd2
- rh_d2
,
654 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
658 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
661 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
662 xd
+ wd
- rd
+ 1, yd
);
663 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
+ hd
,
664 xd
+ wd
- rd
, yd
+ hd
);
666 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
668 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
, yd
+ rd
,
669 xd
+ wd
, yd
+ hd
- rd
+ 1);
670 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
671 rw_d
, rh_d
, 90 * 64, 90 * 64);
672 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
673 // rw_d, rh_d, 0, 90 * 64);
674 rw_d
, rh_d
, 0, 91 * 64);
675 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
677 rw_d
, rh_d
, 269 * 64, 92 * 64);
678 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
679 rw_d
, rh_d
, 180 * 64, 90 * 64);
681 if (m_window
&& m_window
->GetBackingPixmap())
683 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
685 xd2
+ wd2
- rd2
+ 1, yd2
);
686 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
687 xd2
+ rd2
, yd2
+ hd2
,
688 xd2
+ wd2
- rd2
, yd2
+ hd2
);
690 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
692 xd2
, yd2
+ hd2
- rd2
);
693 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
694 xd2
+ wd2
, yd2
+ rd2
,
695 xd2
+ wd2
, yd2
+ hd2
- rd2
+ 1);
696 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
698 rw_d2
, rh_d2
, 90 * 64, 90 * 64);
699 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
700 xd2
+ wd2
- rw_d2
, yd2
,
701 // rw_d2, rh_d2, 0, 90 * 64);
702 rw_d2
, rh_d2
, 0, 91 * 64);
703 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
706 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
707 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
708 xd2
, yd2
+ hd2
- rh_d2
,
709 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
712 CalcBoundingBox (x
, y
);
713 CalcBoundingBox (x
+ width
, y
+ height
);
718 void wxWindowDC::DrawEllipse( long x
, long y
, long width
, long height
)
722 // Check for negative width and height
735 // FreeGetPixelCache();
737 static const int angle
= 23040;
743 wd
= XLOG2DEVREL(width
) ;
744 hd
= YLOG2DEVREL(height
) ;
746 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
749 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
750 if (m_window
&& m_window
->GetBackingPixmap())
751 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
752 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
753 XLOG2DEVREL (width
) - WX_GC_CF
,
754 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
757 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
761 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
762 if (m_window
&& m_window
->GetBackingPixmap())
763 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
764 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
765 XLOG2DEVREL (width
) - WX_GC_CF
,
766 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
768 CalcBoundingBox (x
, y
);
769 CalcBoundingBox (x
+ width
, y
+ height
);
773 bool wxWindowDC::CanDrawBitmap(void) const
778 /* Used when copying between drawables on different (Display*) m_displays.
779 Not very fast, but better than giving up.
782 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
783 Drawable src
, Drawable dest
,
786 unsigned int w
, unsigned int h
,
787 int destx
, int desty
,
788 bool more
, XImage
**cache
)
790 XImage
*image
, *destimage
;
791 Colormap destcm
, srccm
;
792 #define CACHE_SIZE 256
794 unsigned long cachesrc
[CACHE_SIZE
], cachedest
[CACHE_SIZE
];
795 int k
, cache_pos
, all_cache
;
797 if (!cache
|| !*cache
)
798 image
= XGetImage(src_display
, src
, srcx
, srcy
, w
, h
, AllPlanes
, ZPixmap
);
802 destimage
= XGetImage(dest_display
, dest
, destx
, desty
, w
, h
, AllPlanes
, ZPixmap
);
804 srccm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) src_display
);
805 destcm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dest_display
);
810 for (i
= 0; i
< w
; i
++)
811 for (j
= 0; j
< h
; j
++) {
815 pixel
= XGetPixel(image
, i
, j
);
816 for (k
= cache_pos
; k
--; )
817 if (cachesrc
[k
] == pixel
) {
818 pixel
= cachedest
[k
];
822 for (k
= CACHE_SIZE
; k
-- > cache_pos
; )
823 if (cachesrc
[k
] == pixel
) {
824 pixel
= cachedest
[k
];
828 cachesrc
[cache_pos
] = xcol
.pixel
= pixel
;
829 XQueryColor(src_display
, srccm
, &xcol
);
830 if (!XAllocColor(dest_display
, destcm
, &xcol
))
832 cachedest
[cache_pos
] = pixel
= xcol
.pixel
;
834 if (++cache_pos
>= CACHE_SIZE
) {
840 XPutPixel(destimage
, i
, j
, pixel
);
843 XPutImage(dest_display
, dest
, destgc
, destimage
, 0, 0, destx
, desty
, w
, h
);
844 XDestroyImage(destimage
);
849 XDestroyImage(image
);
852 void wxWindowDC::DrawIcon( const wxIcon
&icon
, long x
, long y
)
856 if (!icon
.Ok()) return;
858 DrawBitmap(icon
, x
, y
, TRUE
);
861 // FreeGetPixelCache();
863 // Be sure that foreground pixels (1) of
864 // the Icon will be painted with pen colour. [m_pen.SetColour()]
865 // Background pixels (0) will be painted with
866 // last selected background color. [::SetBackground]
867 if (m_pen
.Ok() && m_autoSetting
)
871 Pixmap iconPixmap
= (Pixmap
) icon
.GetPixmap();
872 width
= icon
.GetWidth();
873 height
= icon
.GetHeight();
874 if (icon
.GetDisplay() == m_display
)
876 if (icon
.GetDepth() <= 1)
878 XCopyPlane ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
880 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
), 1);
884 XCopyArea ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
886 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
));
890 if (m_window
&& m_window
->GetBackingPixmap())
892 if (icon
.GetDepth() <= 1)
894 XCopyPlane ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
895 0, 0, width
, height
, (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
), 1);
899 XCopyArea ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
901 (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
));
904 } else { /* Remote copy (different (Display*) m_displays) */
905 XImage
*cache
= NULL
;
906 if (m_window
&& m_window
->GetBackingPixmap())
907 XCopyRemote((Display
*) icon
.GetDisplay(), (Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
908 (GC
) m_gcBacking
, 0, 0, width
, height
,
909 (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
), TRUE
, &cache
);
910 XCopyRemote((Display
*) icon
.GetDisplay(), (Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
912 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
), FALSE
, &cache
);
914 CalcBoundingBox (x
, y
);
918 bool wxWindowDC::Blit( long xdest
, long ydest
, long width
, long height
,
919 wxDC
*source
, long xsrc
, long ysrc
, int rop
, bool useMask
)
921 if (!Ok()) return FALSE
;
923 wxASSERT_MSG( (source
->IsKindOf(CLASSINFO(wxWindowDC
))), "Blit source DC must be wxWindowDC or derived class." );
925 wxWindowDC
* sourceDC
= (wxWindowDC
*) source
;
927 // FreeGetPixelCache();
929 // Be sure that foreground pixels (1) of
930 // the Icon will be painted with pen colour. [m_pen.SetColour()]
931 // Background pixels (0) will be painted with
932 // last selected background color. [::SetBackground]
933 if (m_pen
.Ok() && m_autoSetting
)
936 if (m_pixmap
&& sourceDC
->m_pixmap
)
939 int orig
= m_logicalFunction
;
941 SetLogicalFunction (rop
);
943 if (m_display
!= sourceDC
->m_display
)
945 XImage
*cache
= NULL
;
947 if (m_window
&& m_window
->GetBackingPixmap())
948 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
,
949 (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
951 source
->LogicalToDeviceX (xsrc
),
952 source
->LogicalToDeviceY (ysrc
),
953 source
->LogicalToDeviceXRel(width
),
954 source
->LogicalToDeviceYRel(height
),
955 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
),
958 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
960 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
961 wxBitmap
& sel
= memDC
->GetBitmap();
962 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetPixmap() )
964 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetPixmap());
965 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
969 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
970 source
->LogicalToDeviceX (xsrc
),
971 source
->LogicalToDeviceY (ysrc
),
972 source
->LogicalToDeviceXRel(width
),
973 source
->LogicalToDeviceYRel(height
),
974 XLOG2DEV (xdest
), YLOG2DEV (ydest
),
979 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
980 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
985 if (m_window
&& m_window
->GetBackingPixmap())
987 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1
988 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetBitmap().GetDepth() == 1)
990 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
991 source
->LogicalToDeviceX (xsrc
),
992 source
->LogicalToDeviceY (ysrc
),
993 source
->LogicalToDeviceXRel(width
),
994 source
->LogicalToDeviceYRel(height
),
995 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 1);
999 XCopyArea ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1000 source
->LogicalToDeviceX (xsrc
),
1001 source
->LogicalToDeviceY (ysrc
),
1002 source
->LogicalToDeviceXRel(width
),
1003 source
->LogicalToDeviceYRel(height
),
1004 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
));
1007 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
1009 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1010 wxBitmap
& sel
= memDC
->GetBitmap();
1011 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetPixmap() )
1013 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetPixmap());
1014 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
1018 // Check if we're copying from a mono bitmap
1019 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) &&
1020 ((wxMemoryDC
*)source
)->GetBitmap().Ok() && (((wxMemoryDC
*)source
)->GetBitmap().GetDepth () == 1))
1022 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1023 source
->LogicalToDeviceX (xsrc
),
1024 source
->LogicalToDeviceY (ysrc
),
1025 source
->LogicalToDeviceXRel(width
),
1026 source
->LogicalToDeviceYRel(height
),
1027 XLOG2DEV (xdest
), YLOG2DEV (ydest
), 1);
1031 XCopyArea ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1032 source
->LogicalToDeviceX (xsrc
),
1033 source
->LogicalToDeviceY (ysrc
),
1034 source
->LogicalToDeviceXRel(width
),
1035 source
->LogicalToDeviceYRel(height
),
1036 XLOG2DEV (xdest
), YLOG2DEV (ydest
));
1041 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
1042 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
1045 } /* Remote/local (Display*) m_display */
1046 CalcBoundingBox (xdest
, ydest
);
1047 CalcBoundingBox (xdest
+ width
, ydest
+ height
);
1049 SetLogicalFunction(orig
);
1056 /* Helper function for 16-bit fonts */
1057 static int str16len(const char *s
)
1061 while (s
[0] && s
[1]) {
1069 void wxWindowDC::DrawText( const wxString
&text
, long x
, long y
, bool use16
)
1073 // Since X draws from the baseline of the text, must
1074 // add the text height
1081 slen
= str16len(text
);
1083 slen
= strlen(text
);
1087 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1088 int direction
, descent
;
1089 XCharStruct overall_return
;
1091 (void)XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*)(const char*) text
, slen
, &direction
,
1092 &ascent
, &descent
, &overall_return
);
1094 (void)XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) text
, slen
, &direction
,
1095 &ascent
, &descent
, &overall_return
);
1096 cx
= overall_return
.width
;
1097 cy
= ascent
+ descent
;
1100 // First draw a rectangle representing the text background,
1101 // if a text background is specified
1102 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1104 wxColour oldPenColour
= m_currentColour
;
1105 m_currentColour
= m_textBackgroundColour
;
1106 bool sameColour
= (oldPenColour
.Ok () && m_textBackgroundColour
.Ok () &&
1107 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1108 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1109 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1111 // This separation of the big && test required for gcc2.7/HP UX 9.02
1112 // or pixel value can be corrupted!
1113 sameColour
= (sameColour
&&
1114 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1116 if (!sameColour
|| !GetOptimization())
1118 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1119 m_currentColour
= m_textBackgroundColour
;
1121 // Set the GC to the required colour
1124 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1125 if (m_window
&& m_window
->GetBackingPixmap())
1126 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1130 m_textBackgroundColour
= oldPenColour
;
1132 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1133 if (m_window
&& m_window
->GetBackingPixmap())
1134 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1135 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1138 // Now set the text foreground and draw the text
1139 if (m_textForegroundColour
.Ok ())
1141 wxColour oldPenColour
= m_currentColour
;
1142 m_currentColour
= m_textForegroundColour
;
1143 bool sameColour
= (oldPenColour
.Ok () && m_currentColour
.Ok () &&
1144 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1145 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1146 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1147 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1149 if (!sameColour
|| !GetOptimization())
1152 if (!m_colour
) // Mono display
1154 // Unless foreground is really white, draw it in black
1155 unsigned char red
= m_textForegroundColour
.Red ();
1156 unsigned char blue
= m_textForegroundColour
.Blue ();
1157 unsigned char green
= m_textForegroundColour
.Green ();
1158 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1159 && green
== (unsigned char) 255)
1161 m_currentColour
= *wxWHITE
;
1162 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1163 m_currentColour
.SetPixel(pixel
);
1164 m_textForegroundColour
.SetPixel(pixel
);
1168 m_currentColour
= *wxBLACK
;
1169 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1170 m_currentColour
.SetPixel(pixel
);
1171 m_textForegroundColour
.SetPixel(pixel
);
1176 pixel
= m_textForegroundColour
.AllocColour((Display
*) m_display
);
1177 m_currentColour
.SetPixel(pixel
);
1180 // Set the GC to the required colour
1183 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1184 if (m_window
&& m_window
->GetBackingPixmap())
1185 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1189 m_textForegroundColour
= oldPenColour
;
1192 // We need to add the ascent, not the whole height, since X draws
1193 // at the point above the descender.
1195 XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1196 (XChar2b
*)(char*) (const char*) text
, slen
);
1198 XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1201 if (m_window
&& m_window
->GetBackingPixmap()) {
1203 XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1204 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1205 (XChar2b
*)(char*) (const char*) text
, slen
);
1207 XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1208 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
, (char*) (const char*) text
, slen
);
1212 GetTextExtent (text
, &w
, &h
);
1213 CalcBoundingBox (x
+ w
, y
+ h
);
1214 CalcBoundingBox (x
, y
);
1217 bool wxWindowDC::CanGetTextExtent(void) const
1222 void wxWindowDC::GetTextExtent( const wxString
&string
, long *width
, long *height
,
1223 long *descent
, long *externalLeading
,
1224 wxFont
*font
, bool use16
)
1228 wxFont
* theFont
= font
;
1234 // TODO: this should be an error log function
1235 wxFAIL_MSG("set a valid font before calling GetTextExtent!");
1242 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1244 int direction
, ascent
, descent2
;
1245 XCharStruct overall
;
1248 if (use16
) slen
= str16len(string
); else slen
= strlen(string
);
1251 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1252 &ascent
, &descent2
, &overall
);
1254 XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) string
, slen
, &direction
,
1255 &ascent
, &descent2
, &overall
);
1257 *width
= XDEV2LOGREL (overall
.width
);
1258 *height
= YDEV2LOGREL (ascent
+ descent2
);
1260 *descent
= descent2
;
1261 if (externalLeading
)
1262 *externalLeading
= 0;
1265 long wxWindowDC::GetCharWidth(void)
1267 if (!Ok()) return 0;
1272 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
* m_logicalScaleY
, m_display
);
1274 int direction
, ascent
, descent
;
1275 XCharStruct overall
;
1276 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1277 &descent
, &overall
);
1278 return XDEV2LOGREL(overall
.width
);
1281 long wxWindowDC::GetCharHeight(void)
1283 if (!Ok()) return 0;
1288 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1290 int direction
, ascent
, descent
;
1291 XCharStruct overall
;
1292 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1293 &descent
, &overall
);
1294 // return XDEV2LOGREL(overall.ascent + overall.descent);
1295 return XDEV2LOGREL(ascent
+ descent
);
1298 void wxWindowDC::Clear(void)
1305 m_window
->GetSize(&w
, &h
);
1307 if (m_window
&& m_window
->GetBackingPixmap())
1309 w
= m_window
->GetPixmapWidth();
1310 h
= m_window
->GetPixmapHeight();
1315 if (this->IsKindOf(CLASSINFO(wxMemoryDC
)))
1317 wxMemoryDC
* memDC
= (wxMemoryDC
*) this;
1318 w
= memDC
->GetBitmap().GetWidth();
1319 h
= memDC
->GetBitmap().GetHeight();
1325 wxBrush saveBrush
= m_brush
;
1326 SetBrush (m_backgroundBrush
);
1328 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, 0, w
, h
);
1330 if (m_window
&& m_window
->GetBackingPixmap())
1331 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 0, 0, w
, h
);
1333 m_brush
= saveBrush
;
1336 void wxWindowDC::Clear(const wxRect
& rect
)
1340 int x
= rect
.x
; int y
= rect
.y
;
1341 int w
= rect
.width
; int h
= rect
.height
;
1343 wxBrush saveBrush
= m_brush
;
1344 SetBrush (m_backgroundBrush
);
1346 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x
, y
, w
, h
);
1348 if (m_window
&& m_window
->GetBackingPixmap())
1349 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, x
, y
, w
, h
);
1351 m_brush
= saveBrush
;
1354 void wxWindowDC::SetFont( const wxFont
&font
)
1362 if ((m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
1364 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
1366 if (m_window
&& m_window
->GetBackingPixmap())
1367 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
1372 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1374 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1375 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1377 if (m_window
&& m_window
->GetBackingPixmap())
1378 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1381 void wxWindowDC::SetPen( const wxPen
&pen
)
1389 wxBitmap oldStipple
= m_currentStipple
;
1390 int oldStyle
= m_currentStyle
;
1391 int oldFill
= m_currentFill
;
1392 int old_pen_width
= m_currentPenWidth
;
1393 int old_pen_join
= m_currentPenJoin
;
1394 int old_pen_cap
= m_currentPenCap
;
1395 int old_pen_nb_dash
= m_currentPenDashCount
;
1396 char *old_pen_dash
= m_currentPenDash
;
1398 wxColour oldPenColour
= m_currentColour
;
1399 m_currentColour
= m_pen
.GetColour ();
1400 m_currentStyle
= m_pen
.GetStyle ();
1401 m_currentFill
= m_pen
.GetStyle (); // TODO?
1402 m_currentPenWidth
= m_pen
.GetWidth ();
1403 m_currentPenJoin
= m_pen
.GetJoin ();
1404 m_currentPenCap
= m_pen
.GetCap ();
1405 m_currentPenDashCount
= m_pen
.GetDashCount();
1406 m_currentPenDash
= m_pen
.GetDash();
1408 if (m_currentStyle
== wxSTIPPLE
)
1409 m_currentStipple
= * m_pen
.GetStipple ();
1411 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1412 oldFill
== m_currentFill
&&
1413 old_pen_join
== m_currentPenJoin
&&
1414 old_pen_cap
== m_currentPenCap
&&
1415 old_pen_nb_dash
== m_currentPenDashCount
&&
1416 old_pen_dash
== m_currentPenDash
&&
1417 old_pen_width
== m_currentPenWidth
);
1419 bool sameColour
= (oldPenColour
.Ok () &&
1420 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1421 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1422 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1423 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1425 if (!sameStyle
|| !GetOptimization())
1427 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1428 if (scaled_width
< 0)
1434 static char dotted
[] =
1436 static char short_dashed
[] =
1438 static char long_dashed
[] =
1440 static char dotted_dashed
[] =
1443 // We express dash pattern in pen width unit, so we are
1444 // independent of zoom factor and so on...
1448 switch (m_pen
.GetStyle ())
1451 req_nb_dash
= m_currentPenDashCount
;
1452 req_dash
= m_currentPenDash
;
1453 style
= LineOnOffDash
;
1458 style
= LineOnOffDash
;
1462 req_dash
= short_dashed
;
1463 style
= LineOnOffDash
;
1467 req_dash
= long_dashed
;
1468 style
= LineOnOffDash
;
1472 req_dash
= dotted_dashed
;
1473 style
= LineOnOffDash
;
1484 if (req_dash
&& req_nb_dash
)
1486 char *real_req_dash
= new char[req_nb_dash
];
1489 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1490 for (int i
= 0; i
< req_nb_dash
; i
++)
1491 real_req_dash
[i
] = req_dash
[i
] * factor
;
1492 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1494 if (m_window
&& m_window
->GetBackingPixmap())
1495 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1496 delete[]real_req_dash
;
1500 // No Memory. We use non-scaled dash pattern...
1501 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1503 if (m_window
&& m_window
->GetBackingPixmap())
1504 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1508 switch (m_pen
.GetCap ())
1510 case wxCAP_PROJECTING
:
1511 cap
= CapProjecting
;
1522 switch (m_pen
.GetJoin ())
1536 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1538 if (m_window
&& m_window
->GetBackingPixmap())
1539 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1542 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1546 oldStipple
= wxNullBitmap
; // For later reset!!
1548 switch (m_currentFill
)
1550 case wxBDIAGONAL_HATCH
:
1551 if (bdiag
== (Pixmap
) 0)
1552 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1553 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1554 bdiag_bits
, bdiag_width
, bdiag_height
);
1557 case wxFDIAGONAL_HATCH
:
1558 if (fdiag
== (Pixmap
) 0)
1559 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1560 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1561 fdiag_bits
, fdiag_width
, fdiag_height
);
1565 if (cross
== (Pixmap
) 0)
1566 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1567 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1568 cross_bits
, cross_width
, cross_height
);
1571 case wxHORIZONTAL_HATCH
:
1572 if (horiz
== (Pixmap
) 0)
1573 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1574 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1575 horiz_bits
, horiz_width
, horiz_height
);
1578 case wxVERTICAL_HATCH
:
1579 if (verti
== (Pixmap
) 0)
1580 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1581 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1582 verti_bits
, verti_width
, verti_height
);
1585 case wxCROSSDIAG_HATCH
:
1587 if (cdiag
== (Pixmap
) 0)
1588 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1589 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1590 cdiag_bits
, cdiag_width
, cdiag_height
);
1594 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1596 if (m_window
&& m_window
->GetBackingPixmap())
1597 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1599 else if (m_currentStipple
.Ok()
1600 && ((m_currentStipple
!= oldStipple
) || !GetOptimization()))
1602 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1604 if (m_window
&& m_window
->GetBackingPixmap())
1605 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1608 if ((m_currentFill
!= oldFill
) || !GetOptimization())
1612 if (m_currentFill
== wxSTIPPLE
)
1613 fill_style
= FillStippled
;
1614 else if (IS_HATCH (m_currentFill
))
1615 fill_style
= FillStippled
;
1617 fill_style
= FillSolid
;
1618 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1619 if (m_window
&& m_window
->GetBackingPixmap())
1620 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1623 // must test m_logicalFunction, because it involves background!
1624 if (!sameColour
|| !GetOptimization()
1625 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1628 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1629 pixel
= m_backgroundPixel
;
1632 unsigned char red
= m_pen
.GetColour ().Red ();
1633 unsigned char blue
= m_pen
.GetColour ().Blue ();
1634 unsigned char green
= m_pen
.GetColour ().Green ();
1635 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1636 && green
== (unsigned char) 255)
1638 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1639 m_currentColour
= *wxWHITE
;
1640 m_pen
.GetColour().SetPixel(pixel
);
1641 m_currentColour
.SetPixel(pixel
);
1645 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1646 m_currentColour
= *wxBLACK
;
1647 m_pen
.GetColour().SetPixel(pixel
);
1652 pixel
= m_pen
.GetColour ().AllocColour(m_display
);
1653 m_currentColour
.SetPixel(pixel
);
1656 // Finally, set the GC to the required colour
1659 if (m_logicalFunction
== wxXOR
)
1662 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1663 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1664 if (m_window
&& m_window
->GetBackingPixmap())
1665 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1669 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1670 if (m_window
&& m_window
->GetBackingPixmap())
1671 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1676 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1681 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1687 if (!m_brush
.Ok() || m_brush
.GetStyle () == wxTRANSPARENT
)
1690 int oldFill
= m_currentFill
;
1691 wxBitmap oldStipple
= m_currentStipple
;
1693 m_autoSetting
|= 0x1;
1695 m_currentFill
= m_brush
.GetStyle ();
1696 if (m_currentFill
== wxSTIPPLE
)
1697 m_currentStipple
= * m_brush
.GetStipple ();
1699 wxColour
oldBrushColour(m_currentColour
);
1700 m_currentColour
= m_brush
.GetColour ();
1702 bool sameColour
= (oldBrushColour
.Ok () &&
1703 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1704 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1705 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1706 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1708 if ((oldFill
!= m_brush
.GetStyle ()) || !GetOptimization())
1710 switch (brush
.GetStyle ())
1714 case wxBDIAGONAL_HATCH
:
1715 case wxCROSSDIAG_HATCH
:
1716 case wxFDIAGONAL_HATCH
:
1718 case wxHORIZONTAL_HATCH
:
1719 case wxVERTICAL_HATCH
:
1722 // Chris Breeze 23/07/97: use background mode to determine whether
1723 // fill style should be solid or transparent
1724 int style
= (m_backgroundMode
== wxSOLID
? FillOpaqueStippled
: FillStippled
);
1725 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1726 if (m_window
&& m_window
->GetBackingPixmap())
1727 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1732 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1733 if (m_window
&& m_window
->GetBackingPixmap())
1734 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, FillSolid
);
1738 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1742 switch (m_currentFill
)
1744 case wxBDIAGONAL_HATCH
:
1745 if (bdiag
== (Pixmap
) 0)
1746 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1747 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1748 bdiag_bits
, bdiag_width
, bdiag_height
);
1751 case wxFDIAGONAL_HATCH
:
1752 if (fdiag
== (Pixmap
) 0)
1753 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1754 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1755 fdiag_bits
, fdiag_width
, fdiag_height
);
1759 if (cross
== (Pixmap
) 0)
1760 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1761 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1762 cross_bits
, cross_width
, cross_height
);
1765 case wxHORIZONTAL_HATCH
:
1766 if (horiz
== (Pixmap
) 0)
1767 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1768 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1769 horiz_bits
, horiz_width
, horiz_height
);
1772 case wxVERTICAL_HATCH
:
1773 if (verti
== (Pixmap
) 0)
1774 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1775 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1776 verti_bits
, verti_width
, verti_height
);
1779 case wxCROSSDIAG_HATCH
:
1781 if (cdiag
== (Pixmap
) 0)
1782 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1783 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1784 cdiag_bits
, cdiag_width
, cdiag_height
);
1788 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1790 if (m_window
&& m_window
->GetBackingPixmap())
1791 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1793 // X can forget the stipple value when resizing a window (apparently)
1794 // so always set the stipple.
1795 else if (m_currentStipple
.Ok()) // && m_currentStipple != oldStipple)
1797 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1798 if (m_window
&& m_window
->GetBackingPixmap())
1799 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1802 // must test m_logicalFunction, because it involves background!
1803 if (!sameColour
|| !GetOptimization() || m_logicalFunction
== wxXOR
)
1808 // Policy - on a monochrome screen, all brushes are white,
1809 // except when they're REALLY black!!!
1810 unsigned char red
= m_brush
.GetColour ().Red ();
1811 unsigned char blue
= m_brush
.GetColour ().Blue ();
1812 unsigned char green
= m_brush
.GetColour ().Green ();
1814 if (red
== (unsigned char) 0 && blue
== (unsigned char) 0
1815 && green
== (unsigned char) 0)
1817 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1818 m_currentColour
= *wxBLACK
;
1819 m_brush
.GetColour().SetPixel(pixel
);
1820 m_currentColour
.SetPixel(pixel
);
1824 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1825 m_currentColour
= *wxWHITE
;
1826 m_brush
.GetColour().SetPixel(pixel
);
1827 m_currentColour
.SetPixel(pixel
);
1830 // N.B. comment out the above line and uncomment the following lines
1831 // if you want non-white colours to be black on a monochrome display.
1833 if (red == (unsigned char )255 && blue == (unsigned char)255
1834 && green == (unsigned char)255)
1835 pixel = (int)WhitePixel((Display*) m_display, DefaultScreen((Display*) m_display));
1837 pixel = (int)BlackPixel((Display*) m_display, DefaultScreen((Display*) m_display));
1840 else if (m_brush
.GetStyle () != wxTRANSPARENT
)
1842 pixel
= m_brush
.GetColour().AllocColour(m_display
);
1843 m_currentColour
.SetPixel(pixel
);
1847 // Finally, set the GC to the required colour
1848 if (m_logicalFunction
== wxXOR
)
1851 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1852 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1853 if (m_window
&& m_window
->GetBackingPixmap())
1854 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1858 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1859 if (m_window
&& m_window
->GetBackingPixmap())
1860 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1865 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1868 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1872 m_backgroundBrush
= brush
;
1874 if (!m_backgroundBrush
.Ok())
1877 int pixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
1879 // XSetWindowBackground doesn't work for non-Window pixmaps
1880 if (!this->IsKindOf(CLASSINFO(wxMemoryDC
)))
1881 XSetWindowBackground ((Display
*) m_display
, (Pixmap
) m_pixmap
, pixel
);
1883 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
1884 // And Blit,... (Any fct that use XCopyPlane, in fact.)
1885 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1886 if (m_window
&& m_window
->GetBackingPixmap())
1887 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1890 void wxWindowDC::SetLogicalFunction( int function
)
1895 if (m_logicalFunction
== function
)
1901 x_function
= GXclear
;
1907 x_function
= GXinvert
;
1910 x_function
= GXorReverse
;
1913 x_function
= GXandReverse
;
1922 x_function
= GXandInverted
;
1925 x_function
= GXnoop
;
1931 x_function
= GXequiv
;
1934 x_function
= GXcopyInverted
;
1937 x_function
= GXorInverted
;
1940 x_function
= GXnand
;
1947 x_function
= GXcopy
;
1951 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
1952 if (m_window
&& m_window
->GetBackingPixmap())
1953 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
1955 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
1956 /* MATTHEW: [9] Need to redo pen simply */
1957 m_autoSetting
|= 0x2;
1959 m_logicalFunction
= function
;
1963 void wxWindowDC::SetTextForeground( const wxColour
&col
)
1967 if (m_textForegroundColour
== col
) return;
1969 m_textForegroundColour
= col
;
1973 void wxWindowDC::SetTextBackground( const wxColour
&col
)
1977 if (m_textBackgroundColour
== col
) return;
1979 m_textBackgroundColour
= col
;
1980 if (!m_textBackgroundColour
.Ok()) return;
1983 void wxWindowDC::SetBackgroundMode( int mode
)
1985 m_backgroundMode
= mode
;
1989 void wxWindowDC::SetPalette( const wxPalette
& palette
)
1994 /* Use GetXColormap */
1995 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1996 (Colormap
) palette
.GetXColormap());
1998 /* Use wxGetMainColormap */
1999 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2000 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2005 void wxWindowDC:: SetDCClipping ()
2007 // m_userRegion is the region set by calling SetClippingRegion
2009 if (m_currentRegion
)
2010 XDestroyRegion ((Region
) m_currentRegion
);
2012 // We need to take into account
2013 // clipping imposed on a window by a repaint.
2014 // We'll combine it with the user region. But for now,
2015 // just use the currently-defined user clipping region.
2016 if (m_userRegion
|| (m_window
&& m_window
->GetUpdateRegion().Ok()) )
2017 m_currentRegion
= (WXRegion
) XCreateRegion ();
2019 m_currentRegion
= (WXRegion
) NULL
;
2021 if ((m_window
&& m_window
->GetUpdateRegion().Ok()) && m_userRegion
)
2022 XIntersectRegion ((Region
) m_window
->GetUpdateRegion().GetXRegion(), (Region
) m_userRegion
, (Region
) m_currentRegion
);
2023 else if (m_userRegion
)
2024 XIntersectRegion ((Region
) m_userRegion
, (Region
) m_userRegion
, (Region
) m_currentRegion
);
2025 else if (m_window
&& m_window
->GetUpdateRegion().Ok())
2026 XIntersectRegion ((Region
) m_window
->GetUpdateRegion().GetXRegion(), (Region
) m_window
->GetUpdateRegion().GetXRegion(),
2027 (Region
) m_currentRegion
);
2029 if (m_currentRegion
)
2031 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) m_currentRegion
);
2035 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
2040 void wxWindowDC::SetClippingRegion( long x
, long y
, long width
, long height
)
2042 wxDC::SetClippingRegion( x
, y
, width
, height
);
2045 XDestroyRegion ((Region
) m_userRegion
);
2046 m_userRegion
= (WXRegion
) XCreateRegion ();
2050 r
.width
= XLOG2DEVREL(width
);
2051 r
.height
= YLOG2DEVREL(height
);
2052 XUnionRectWithRegion (&r
, (Region
) m_userRegion
, (Region
) m_userRegion
);
2056 // Needs to work differently for Pixmap: without this,
2057 // there's a nasty (Display*) m_display bug. 8/12/94
2058 if (m_window
&& m_window
->GetBackingPixmap())
2060 XRectangle rects
[1];
2061 rects
[0].x
= XLOG2DEV_2(x
);
2062 rects
[0].y
= YLOG2DEV_2(y
);
2063 rects
[0].width
= XLOG2DEVREL(width
);
2064 rects
[0].height
= YLOG2DEVREL(height
);
2065 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 0, 0, rects
, 1, Unsorted
);
2069 void wxWindowDC::SetClippingRegion( const wxRegion
& region
)
2071 wxRect box
= region
.GetBox();
2073 wxDC::SetClippingRegion( box
.x
, box
.y
, box
.width
, box
.height
);
2076 XDestroyRegion ((Region
) m_userRegion
);
2077 m_userRegion
= (WXRegion
) XCreateRegion ();
2079 XUnionRegion((Region
) m_userRegion
, (Region
) region
.GetXRegion(), (Region
) m_userRegion
);
2083 // Needs to work differently for Pixmap: without this,
2084 // there's a nasty (Display*) m_display bug. 8/12/94
2085 if (m_window
&& m_window
->GetBackingPixmap())
2087 XRectangle rects
[1];
2088 rects
[0].x
= XLOG2DEV_2(box
.x
);
2089 rects
[0].y
= YLOG2DEV_2(box
.y
);
2090 rects
[0].width
= XLOG2DEVREL(box
.width
);
2091 rects
[0].height
= YLOG2DEVREL(box
.height
);
2092 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 0, 0, rects
, 1, Unsorted
);
2097 void wxWindowDC::DestroyClippingRegion(void)
2099 wxDC::DestroyClippingRegion();
2102 XDestroyRegion ((Region
) m_userRegion
);
2103 m_userRegion
= NULL
;
2108 gc_val
.clip_mask
= None
;
2109 if (m_window
&& m_window
->GetBackingPixmap())
2110 XChangeGC((Display
*) m_display
, (GC
) m_gcBacking
, GCClipMask
, &gc_val
);
2113 // ----------------------------------- spline code ----------------------------------------
2115 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
2116 double a3
, double b3
, double a4
, double b4
);
2117 void wx_clear_stack(void);
2118 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
2119 double *y3
, double *x4
, double *y4
);
2120 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
2121 double x4
, double y4
);
2122 static bool wx_spline_add_point(double x
, double y
);
2123 static void wx_spline_draw_point_array(wxDC
*dc
);
2125 wxList wx_spline_point_list
;
2127 #define half(z1, z2) ((z1+z2)/2.0)
2130 /* iterative version */
2132 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
2135 register double xmid
, ymid
;
2136 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
2139 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
2141 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
2142 xmid
= (double)half(x2
, x3
);
2143 ymid
= (double)half(y2
, y3
);
2144 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
2145 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
2146 wx_spline_add_point( x1
, y1
);
2147 wx_spline_add_point( xmid
, ymid
);
2149 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
2150 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
2151 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
2152 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
2157 /* utilities used by spline drawing routines */
2159 typedef struct wx_spline_stack_struct
{
2160 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
2163 #define SPLINE_STACK_DEPTH 20
2164 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
2165 static Stack
*wx_stack_top
;
2166 static int wx_stack_count
;
2168 void wx_clear_stack(void)
2170 wx_stack_top
= wx_spline_stack
;
2174 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
2176 wx_stack_top
->x1
= x1
;
2177 wx_stack_top
->y1
= y1
;
2178 wx_stack_top
->x2
= x2
;
2179 wx_stack_top
->y2
= y2
;
2180 wx_stack_top
->x3
= x3
;
2181 wx_stack_top
->y3
= y3
;
2182 wx_stack_top
->x4
= x4
;
2183 wx_stack_top
->y4
= y4
;
2188 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
2189 double *x3
, double *y3
, double *x4
, double *y4
)
2191 if (wx_stack_count
== 0)
2195 *x1
= wx_stack_top
->x1
;
2196 *y1
= wx_stack_top
->y1
;
2197 *x2
= wx_stack_top
->x2
;
2198 *y2
= wx_stack_top
->y2
;
2199 *x3
= wx_stack_top
->x3
;
2200 *y3
= wx_stack_top
->y3
;
2201 *x4
= wx_stack_top
->x4
;
2202 *y4
= wx_stack_top
->y4
;
2206 static bool wx_spline_add_point(double x
, double y
)
2208 wxPoint
*point
= new wxPoint
;
2211 wx_spline_point_list
.Append((wxObject
*)point
);
2215 static void wx_spline_draw_point_array(wxDC
*dc
)
2217 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
2218 wxNode
*node
= wx_spline_point_list
.First();
2221 wxPoint
*point
= (wxPoint
*)node
->Data();
2224 node
= wx_spline_point_list
.First();
2228 void wxWindowDC::DrawSpline( wxList
*points
)
2231 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
2232 double x1
, y1
, x2
, y2
;
2234 wxNode
*node
= points
->First();
2235 p
= (wxPoint
*)node
->Data();
2240 node
= node
->Next();
2241 p
= (wxPoint
*)node
->Data();
2245 cx1
= (double)((x1
+ x2
) / 2);
2246 cy1
= (double)((y1
+ y2
) / 2);
2247 cx2
= (double)((cx1
+ x2
) / 2);
2248 cy2
= (double)((cy1
+ y2
) / 2);
2250 wx_spline_add_point(x1
, y1
);
2252 while ((node
= node
->Next()) != NULL
)
2254 p
= (wxPoint
*)node
->Data();
2259 cx4
= (double)(x1
+ x2
) / 2;
2260 cy4
= (double)(y1
+ y2
) / 2;
2261 cx3
= (double)(x1
+ cx4
) / 2;
2262 cy3
= (double)(y1
+ cy4
) / 2;
2264 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
2268 cx2
= (double)(cx1
+ x2
) / 2;
2269 cy2
= (double)(cy1
+ y2
) / 2;
2272 wx_spline_add_point( cx1
, cy1
);
2273 wx_spline_add_point( x2
, y2
);
2275 wx_spline_draw_point_array( this );
2282 wxPaintDC::wxPaintDC(wxWindow
* win
): wxWindowDC(win
)
2284 wxRegion
* region
= NULL
;
2286 // Combine all the update rects into a region
2287 if (win
->m_updateRects
.Number() > 0)
2290 for (i
= 0; i
< win
->m_updateRects
.Number(); i
++)
2292 wxRect
* rect
= (wxRect
*) win
->m_updateRects
.Nth(i
)->Data();
2294 cout << "wxPaintDC. wxRect: " << rect->x << ", " << rect->y << ", ";
2295 cout << rect->width << ", " << rect->height << "\n\n";
2299 region
= new wxRegion(*rect
);
2301 // TODO: is this correct? In SetDCClipping above,
2302 // XIntersectRegion is used to combine paint and user
2303 // regions. XIntersectRegion appears to work in that case...
2304 region
->Union(*rect
);
2310 win
->GetClientSize(&cw
, &ch
);
2311 region
= new wxRegion(wxRect(0, 0, cw
, ch
));
2314 win
->m_updateRegion
= *region
;
2316 // Set the clipping region. Any user-defined region will be combined with this
2317 // one in SetDCClipping.
2318 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) region
->GetXRegion());
2323 wxPaintDC::~wxPaintDC()
2325 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
2327 m_window
->m_updateRegion
.Clear();