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 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
, bool useMask
)
856 if (!icon
.Ok()) return;
858 // FreeGetPixelCache();
860 // Be sure that foreground pixels (1) of
861 // the Icon will be painted with pen colour. [m_pen.SetColour()]
862 // Background pixels (0) will be painted with
863 // last selected background color. [::SetBackground]
864 if (m_pen
.Ok() && m_autoSetting
)
868 Pixmap iconPixmap
= (Pixmap
) icon
.GetPixmap();
869 width
= icon
.GetWidth();
870 height
= icon
.GetHeight();
871 if (icon
.GetDisplay() == m_display
)
873 if (icon
.GetDepth() <= 1)
875 XCopyPlane ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
877 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
), 1);
881 XCopyArea ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
883 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
));
887 if (m_window
&& m_window
->GetBackingPixmap())
889 if (icon
.GetDepth() <= 1)
891 XCopyPlane ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
892 0, 0, width
, height
, (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
), 1);
896 XCopyArea ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
898 (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
));
901 } else { /* Remote copy (different (Display*) m_displays) */
902 XImage
*cache
= NULL
;
903 if (m_window
&& m_window
->GetBackingPixmap())
904 XCopyRemote((Display
*) icon
.GetDisplay(), (Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
905 (GC
) m_gcBacking
, 0, 0, width
, height
,
906 (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
), TRUE
, &cache
);
907 XCopyRemote((Display
*) icon
.GetDisplay(), (Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
909 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
), FALSE
, &cache
);
911 CalcBoundingBox (x
, y
);
915 bool wxWindowDC::Blit( long xdest
, long ydest
, long width
, long height
,
916 wxDC
*source
, long xsrc
, long ysrc
, int rop
, bool useMask
)
918 if (!Ok()) return FALSE
;
920 wxASSERT_MSG( (source
->IsKindOf(CLASSINFO(wxWindowDC
))), "Blit source DC must be wxWindowDC or derived class." );
922 wxWindowDC
* sourceDC
= (wxWindowDC
*) source
;
924 // FreeGetPixelCache();
926 // Be sure that foreground pixels (1) of
927 // the Icon will be painted with pen colour. [m_pen.SetColour()]
928 // Background pixels (0) will be painted with
929 // last selected background color. [::SetBackground]
930 if (m_pen
.Ok() && m_autoSetting
)
933 if (m_pixmap
&& sourceDC
->m_pixmap
)
936 int orig
= m_logicalFunction
;
938 SetLogicalFunction (rop
);
940 if (m_display
!= sourceDC
->m_display
)
942 XImage
*cache
= NULL
;
944 if (m_window
&& m_window
->GetBackingPixmap())
945 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
,
946 (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
948 source
->LogicalToDeviceX (xsrc
),
949 source
->LogicalToDeviceY (ysrc
),
950 source
->LogicalToDeviceXRel(width
),
951 source
->LogicalToDeviceYRel(height
),
952 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
),
955 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
957 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
958 wxBitmap
& sel
= memDC
->GetBitmap();
959 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetPixmap() )
961 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetPixmap());
962 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
966 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
967 source
->LogicalToDeviceX (xsrc
),
968 source
->LogicalToDeviceY (ysrc
),
969 source
->LogicalToDeviceXRel(width
),
970 source
->LogicalToDeviceYRel(height
),
971 XLOG2DEV (xdest
), YLOG2DEV (ydest
),
976 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
977 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
982 if (m_window
&& m_window
->GetBackingPixmap())
984 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1
985 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetBitmap().GetDepth() == 1)
987 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
988 source
->LogicalToDeviceX (xsrc
),
989 source
->LogicalToDeviceY (ysrc
),
990 source
->LogicalToDeviceXRel(width
),
991 source
->LogicalToDeviceYRel(height
),
992 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 1);
996 XCopyArea ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
997 source
->LogicalToDeviceX (xsrc
),
998 source
->LogicalToDeviceY (ysrc
),
999 source
->LogicalToDeviceXRel(width
),
1000 source
->LogicalToDeviceYRel(height
),
1001 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
));
1004 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
1006 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1007 wxBitmap
& sel
= memDC
->GetBitmap();
1008 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetPixmap() )
1010 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetPixmap());
1011 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
1015 // Check if we're copying from a mono bitmap
1016 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) &&
1017 ((wxMemoryDC
*)source
)->GetBitmap().Ok() && (((wxMemoryDC
*)source
)->GetBitmap().GetDepth () == 1))
1019 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1020 source
->LogicalToDeviceX (xsrc
),
1021 source
->LogicalToDeviceY (ysrc
),
1022 source
->LogicalToDeviceXRel(width
),
1023 source
->LogicalToDeviceYRel(height
),
1024 XLOG2DEV (xdest
), YLOG2DEV (ydest
), 1);
1028 XCopyArea ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1029 source
->LogicalToDeviceX (xsrc
),
1030 source
->LogicalToDeviceY (ysrc
),
1031 source
->LogicalToDeviceXRel(width
),
1032 source
->LogicalToDeviceYRel(height
),
1033 XLOG2DEV (xdest
), YLOG2DEV (ydest
));
1038 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
1039 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
1042 } /* Remote/local (Display*) m_display */
1043 CalcBoundingBox (xdest
, ydest
);
1044 CalcBoundingBox (xdest
+ width
, ydest
+ height
);
1046 SetLogicalFunction(orig
);
1053 /* Helper function for 16-bit fonts */
1054 static int str16len(const char *s
)
1058 while (s
[0] && s
[1]) {
1066 void wxWindowDC::DrawText( const wxString
&text
, long x
, long y
, bool use16
)
1070 // Since X draws from the baseline of the text, must
1071 // add the text height
1078 slen
= str16len(text
);
1080 slen
= strlen(text
);
1084 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1085 int direction
, descent
;
1086 XCharStruct overall_return
;
1088 (void)XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*)(const char*) text
, slen
, &direction
,
1089 &ascent
, &descent
, &overall_return
);
1091 (void)XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) text
, slen
, &direction
,
1092 &ascent
, &descent
, &overall_return
);
1093 cx
= overall_return
.width
;
1094 cy
= ascent
+ descent
;
1097 // First draw a rectangle representing the text background,
1098 // if a text background is specified
1099 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1101 wxColour oldPenColour
= m_currentColour
;
1102 m_currentColour
= m_textBackgroundColour
;
1103 bool sameColour
= (oldPenColour
.Ok () && m_textBackgroundColour
.Ok () &&
1104 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1105 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1106 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1108 // This separation of the big && test required for gcc2.7/HP UX 9.02
1109 // or pixel value can be corrupted!
1110 sameColour
= (sameColour
&&
1111 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1113 if (!sameColour
|| !GetOptimization())
1115 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1116 m_currentColour
= m_textBackgroundColour
;
1118 // Set the GC to the required colour
1121 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1122 if (m_window
&& m_window
->GetBackingPixmap())
1123 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1127 m_textBackgroundColour
= oldPenColour
;
1129 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1130 if (m_window
&& m_window
->GetBackingPixmap())
1131 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1132 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1135 // Now set the text foreground and draw the text
1136 if (m_textForegroundColour
.Ok ())
1138 wxColour oldPenColour
= m_currentColour
;
1139 m_currentColour
= m_textForegroundColour
;
1140 bool sameColour
= (oldPenColour
.Ok () && m_currentColour
.Ok () &&
1141 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1142 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1143 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1144 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1146 if (!sameColour
|| !GetOptimization())
1149 if (!m_colour
) // Mono display
1151 // Unless foreground is really white, draw it in black
1152 unsigned char red
= m_textForegroundColour
.Red ();
1153 unsigned char blue
= m_textForegroundColour
.Blue ();
1154 unsigned char green
= m_textForegroundColour
.Green ();
1155 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1156 && green
== (unsigned char) 255)
1158 m_currentColour
= *wxWHITE
;
1159 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1160 m_currentColour
.SetPixel(pixel
);
1161 m_textForegroundColour
.SetPixel(pixel
);
1165 m_currentColour
= *wxBLACK
;
1166 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1167 m_currentColour
.SetPixel(pixel
);
1168 m_textForegroundColour
.SetPixel(pixel
);
1173 pixel
= m_textForegroundColour
.AllocColour((Display
*) m_display
);
1174 m_currentColour
.SetPixel(pixel
);
1177 // Set the GC to the required colour
1180 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1181 if (m_window
&& m_window
->GetBackingPixmap())
1182 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1186 m_textForegroundColour
= oldPenColour
;
1189 // We need to add the ascent, not the whole height, since X draws
1190 // at the point above the descender.
1192 XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1193 (XChar2b
*)(char*) (const char*) text
, slen
);
1195 XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1198 if (m_window
&& m_window
->GetBackingPixmap()) {
1200 XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1201 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1202 (XChar2b
*)(char*) (const char*) text
, slen
);
1204 XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1205 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
, (char*) (const char*) text
, slen
);
1209 GetTextExtent (text
, &w
, &h
);
1210 CalcBoundingBox (x
+ w
, y
+ h
);
1211 CalcBoundingBox (x
, y
);
1214 bool wxWindowDC::CanGetTextExtent(void) const
1219 void wxWindowDC::GetTextExtent( const wxString
&string
, long *width
, long *height
,
1220 long *descent
, long *externalLeading
,
1221 wxFont
*font
, bool use16
)
1225 wxFont
* theFont
= font
;
1231 // TODO: this should be an error log function
1232 cerr
<< "wxWindows warning - set a valid font before calling GetTextExtent!\n";
1238 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1240 int direction
, ascent
, descent2
;
1241 XCharStruct overall
;
1244 if (use16
) slen
= str16len(string
); else slen
= strlen(string
);
1247 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1248 &ascent
, &descent2
, &overall
);
1250 XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) string
, slen
, &direction
,
1251 &ascent
, &descent2
, &overall
);
1253 *width
= XDEV2LOGREL (overall
.width
);
1254 *height
= YDEV2LOGREL (ascent
+ descent2
);
1256 *descent
= descent2
;
1257 if (externalLeading
)
1258 *externalLeading
= 0;
1261 long wxWindowDC::GetCharWidth(void)
1263 if (!Ok()) return 0;
1268 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
* m_logicalScaleY
, m_display
);
1270 int direction
, ascent
, descent
;
1271 XCharStruct overall
;
1272 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1273 &descent
, &overall
);
1274 return XDEV2LOGREL(overall
.width
);
1277 long wxWindowDC::GetCharHeight(void)
1279 if (!Ok()) return 0;
1284 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1286 int direction
, ascent
, descent
;
1287 XCharStruct overall
;
1288 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1289 &descent
, &overall
);
1290 // return XDEV2LOGREL(overall.ascent + overall.descent);
1291 return XDEV2LOGREL(ascent
+ descent
);
1294 void wxWindowDC::Clear(void)
1301 // TODO: should we get the virtual size?
1302 m_window
->GetSize(&w
, &h
);
1304 if (m_window
&& m_window
->GetBackingPixmap())
1306 w
= m_window
->GetPixmapWidth();
1307 h
= m_window
->GetPixmapHeight();
1312 if (this->IsKindOf(CLASSINFO(wxMemoryDC
)))
1314 wxMemoryDC
* memDC
= (wxMemoryDC
*) this;
1315 w
= memDC
->GetBitmap().GetWidth();
1316 h
= memDC
->GetBitmap().GetHeight();
1322 wxBrush saveBrush
= m_brush
;
1323 SetBrush (m_backgroundBrush
);
1325 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, 0, w
, h
);
1327 if (m_window
&& m_window
->GetBackingPixmap())
1328 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 0, 0, w
, h
);
1330 m_brush
= saveBrush
;
1333 void wxWindowDC::SetFont( const wxFont
&font
)
1341 if ((m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
1343 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
1345 if (m_window
&& m_window
->GetBackingPixmap())
1346 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
1351 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1353 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1354 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1356 if (m_window
&& m_window
->GetBackingPixmap())
1357 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1360 void wxWindowDC::SetPen( const wxPen
&pen
)
1368 wxBitmap oldStipple
= m_currentStipple
;
1369 int oldStyle
= m_currentStyle
;
1370 int oldFill
= m_currentFill
;
1371 int old_pen_width
= m_currentPenWidth
;
1372 int old_pen_join
= m_currentPenJoin
;
1373 int old_pen_cap
= m_currentPenCap
;
1374 int old_pen_nb_dash
= m_currentPenDashCount
;
1375 char *old_pen_dash
= m_currentPenDash
;
1377 wxColour oldPenColour
= m_currentColour
;
1378 m_currentColour
= m_pen
.GetColour ();
1379 m_currentStyle
= m_pen
.GetStyle ();
1380 m_currentFill
= m_pen
.GetStyle (); // TODO?
1381 m_currentPenWidth
= m_pen
.GetWidth ();
1382 m_currentPenJoin
= m_pen
.GetJoin ();
1383 m_currentPenCap
= m_pen
.GetCap ();
1384 m_currentPenDashCount
= m_pen
.GetDashCount();
1385 m_currentPenDash
= m_pen
.GetDash();
1387 if (m_currentStyle
== wxSTIPPLE
)
1388 m_currentStipple
= m_pen
.GetStipple ();
1390 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1391 oldFill
== m_currentFill
&&
1392 old_pen_join
== m_currentPenJoin
&&
1393 old_pen_cap
== m_currentPenCap
&&
1394 old_pen_nb_dash
== m_currentPenDashCount
&&
1395 old_pen_dash
== m_currentPenDash
&&
1396 old_pen_width
== m_currentPenWidth
);
1398 bool sameColour
= (oldPenColour
.Ok () &&
1399 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1400 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1401 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1402 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1404 if (!sameStyle
|| !GetOptimization())
1406 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1407 if (scaled_width
< 0)
1413 static char dotted
[] =
1415 static char short_dashed
[] =
1417 static char long_dashed
[] =
1419 static char dotted_dashed
[] =
1422 // We express dash pattern in pen width unit, so we are
1423 // independent of zoom factor and so on...
1427 switch (m_pen
.GetStyle ())
1430 req_nb_dash
= m_currentPenDashCount
;
1431 req_dash
= m_currentPenDash
;
1432 style
= LineOnOffDash
;
1437 style
= LineOnOffDash
;
1441 req_dash
= short_dashed
;
1442 style
= LineOnOffDash
;
1446 req_dash
= long_dashed
;
1447 style
= LineOnOffDash
;
1451 req_dash
= dotted_dashed
;
1452 style
= LineOnOffDash
;
1463 if (req_dash
&& req_nb_dash
)
1465 char *real_req_dash
= new char[req_nb_dash
];
1468 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1469 for (int i
= 0; i
< req_nb_dash
; i
++)
1470 real_req_dash
[i
] = req_dash
[i
] * factor
;
1471 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1473 if (m_window
&& m_window
->GetBackingPixmap())
1474 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1475 delete[]real_req_dash
;
1479 // No Memory. We use non-scaled dash pattern...
1480 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1482 if (m_window
&& m_window
->GetBackingPixmap())
1483 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1487 switch (m_pen
.GetCap ())
1489 case wxCAP_PROJECTING
:
1490 cap
= CapProjecting
;
1501 switch (m_pen
.GetJoin ())
1515 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1517 if (m_window
&& m_window
->GetBackingPixmap())
1518 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1521 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1525 oldStipple
= NULL
; // For later reset!!
1527 switch (m_currentFill
)
1529 case wxBDIAGONAL_HATCH
:
1530 if (bdiag
== (Pixmap
) 0)
1531 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1532 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1533 bdiag_bits
, bdiag_width
, bdiag_height
);
1536 case wxFDIAGONAL_HATCH
:
1537 if (fdiag
== (Pixmap
) 0)
1538 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1539 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1540 fdiag_bits
, fdiag_width
, fdiag_height
);
1544 if (cross
== (Pixmap
) 0)
1545 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1546 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1547 cross_bits
, cross_width
, cross_height
);
1550 case wxHORIZONTAL_HATCH
:
1551 if (horiz
== (Pixmap
) 0)
1552 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1553 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1554 horiz_bits
, horiz_width
, horiz_height
);
1557 case wxVERTICAL_HATCH
:
1558 if (verti
== (Pixmap
) 0)
1559 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1560 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1561 verti_bits
, verti_width
, verti_height
);
1564 case wxCROSSDIAG_HATCH
:
1566 if (cdiag
== (Pixmap
) 0)
1567 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1568 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1569 cdiag_bits
, cdiag_width
, cdiag_height
);
1573 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1575 if (m_window
&& m_window
->GetBackingPixmap())
1576 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1578 else if (m_currentStipple
.Ok()
1579 && ((m_currentStipple
!= oldStipple
) || !GetOptimization()))
1581 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1583 if (m_window
&& m_window
->GetBackingPixmap())
1584 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1587 if ((m_currentFill
!= oldFill
) || !GetOptimization())
1591 if (m_currentFill
== wxSTIPPLE
)
1592 fill_style
= FillStippled
;
1593 else if (IS_HATCH (m_currentFill
))
1594 fill_style
= FillStippled
;
1596 fill_style
= FillSolid
;
1597 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1598 if (m_window
&& m_window
->GetBackingPixmap())
1599 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1602 // must test m_logicalFunction, because it involves background!
1603 if (!sameColour
|| !GetOptimization()
1604 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1607 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1608 pixel
= m_backgroundPixel
;
1611 unsigned char red
= m_pen
.GetColour ().Red ();
1612 unsigned char blue
= m_pen
.GetColour ().Blue ();
1613 unsigned char green
= m_pen
.GetColour ().Green ();
1614 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1615 && green
== (unsigned char) 255)
1617 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1618 m_currentColour
= *wxWHITE
;
1619 m_pen
.GetColour().SetPixel(pixel
);
1620 m_currentColour
.SetPixel(pixel
);
1624 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1625 m_currentColour
= *wxBLACK
;
1626 m_pen
.GetColour().SetPixel(pixel
);
1631 pixel
= m_pen
.GetColour ().AllocColour(m_display
);
1632 m_currentColour
.SetPixel(pixel
);
1635 // Finally, set the GC to the required colour
1638 if (m_logicalFunction
== wxXOR
)
1641 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1642 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1643 if (m_window
&& m_window
->GetBackingPixmap())
1644 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1648 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1649 if (m_window
&& m_window
->GetBackingPixmap())
1650 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1655 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1660 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1666 if (!m_brush
.Ok() || m_brush
.GetStyle () == wxTRANSPARENT
)
1669 int oldFill
= m_currentFill
;
1670 wxBitmap oldStipple
= m_currentStipple
;
1672 m_autoSetting
|= 0x1;
1674 m_currentFill
= m_brush
.GetStyle ();
1675 if (m_currentFill
== wxSTIPPLE
)
1676 m_currentStipple
= m_brush
.GetStipple ();
1678 wxColour
oldBrushColour(m_currentColour
);
1679 m_currentColour
= m_brush
.GetColour ();
1681 bool sameColour
= (oldBrushColour
.Ok () &&
1682 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1683 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1684 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1685 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1687 if ((oldFill
!= m_brush
.GetStyle ()) || !GetOptimization())
1689 switch (brush
.GetStyle ())
1693 case wxBDIAGONAL_HATCH
:
1694 case wxCROSSDIAG_HATCH
:
1695 case wxFDIAGONAL_HATCH
:
1697 case wxHORIZONTAL_HATCH
:
1698 case wxVERTICAL_HATCH
:
1701 // Chris Breeze 23/07/97: use background mode to determine whether
1702 // fill style should be solid or transparent
1703 int style
= (m_backgroundMode
== wxSOLID
? FillOpaqueStippled
: FillStippled
);
1704 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1705 if (m_window
&& m_window
->GetBackingPixmap())
1706 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1711 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1712 if (m_window
&& m_window
->GetBackingPixmap())
1713 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, FillSolid
);
1717 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1721 switch (m_currentFill
)
1723 case wxBDIAGONAL_HATCH
:
1724 if (bdiag
== (Pixmap
) 0)
1725 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1726 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1727 bdiag_bits
, bdiag_width
, bdiag_height
);
1730 case wxFDIAGONAL_HATCH
:
1731 if (fdiag
== (Pixmap
) 0)
1732 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1733 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1734 fdiag_bits
, fdiag_width
, fdiag_height
);
1738 if (cross
== (Pixmap
) 0)
1739 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1740 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1741 cross_bits
, cross_width
, cross_height
);
1744 case wxHORIZONTAL_HATCH
:
1745 if (horiz
== (Pixmap
) 0)
1746 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1747 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1748 horiz_bits
, horiz_width
, horiz_height
);
1751 case wxVERTICAL_HATCH
:
1752 if (verti
== (Pixmap
) 0)
1753 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1754 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1755 verti_bits
, verti_width
, verti_height
);
1758 case wxCROSSDIAG_HATCH
:
1760 if (cdiag
== (Pixmap
) 0)
1761 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1762 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1763 cdiag_bits
, cdiag_width
, cdiag_height
);
1767 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1769 if (m_window
&& m_window
->GetBackingPixmap())
1770 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1772 // X can forget the stipple value when resizing a window (apparently)
1773 // so always set the stipple.
1774 else if (m_currentStipple
.Ok()) // && m_currentStipple != oldStipple)
1776 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1777 if (m_window
&& m_window
->GetBackingPixmap())
1778 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1781 // must test m_logicalFunction, because it involves background!
1782 if (!sameColour
|| !GetOptimization() || m_logicalFunction
== wxXOR
)
1787 // Policy - on a monochrome screen, all brushes are white,
1788 // except when they're REALLY black!!!
1789 unsigned char red
= m_brush
.GetColour ().Red ();
1790 unsigned char blue
= m_brush
.GetColour ().Blue ();
1791 unsigned char green
= m_brush
.GetColour ().Green ();
1793 if (red
== (unsigned char) 0 && blue
== (unsigned char) 0
1794 && green
== (unsigned char) 0)
1796 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1797 m_currentColour
= *wxBLACK
;
1798 m_brush
.GetColour().SetPixel(pixel
);
1799 m_currentColour
.SetPixel(pixel
);
1803 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1804 m_currentColour
= *wxWHITE
;
1805 m_brush
.GetColour().SetPixel(pixel
);
1806 m_currentColour
.SetPixel(pixel
);
1809 // N.B. comment out the above line and uncomment the following lines
1810 // if you want non-white colours to be black on a monochrome display.
1812 if (red == (unsigned char )255 && blue == (unsigned char)255
1813 && green == (unsigned char)255)
1814 pixel = (int)WhitePixel((Display*) m_display, DefaultScreen((Display*) m_display));
1816 pixel = (int)BlackPixel((Display*) m_display, DefaultScreen((Display*) m_display));
1819 else if (m_brush
.GetStyle () != wxTRANSPARENT
)
1821 pixel
= m_brush
.GetColour().AllocColour(m_display
);
1822 m_currentColour
.SetPixel(pixel
);
1826 // Finally, set the GC to the required colour
1827 if (m_logicalFunction
== wxXOR
)
1830 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1831 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1832 if (m_window
&& m_window
->GetBackingPixmap())
1833 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1837 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1838 if (m_window
&& m_window
->GetBackingPixmap())
1839 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1844 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1847 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1851 m_backgroundBrush
= brush
;
1853 if (!m_backgroundBrush
.Ok())
1856 int pixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
1858 // XSetWindowBackground doesn't work for non-Window pixmaps
1859 if (!this->IsKindOf(CLASSINFO(wxMemoryDC
)))
1860 XSetWindowBackground ((Display
*) m_display
, (Pixmap
) m_pixmap
, pixel
);
1862 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
1863 // And Blit,... (Any fct that use XCopyPlane, in fact.)
1864 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1865 if (m_window
&& m_window
->GetBackingPixmap())
1866 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1869 void wxWindowDC::SetLogicalFunction( int function
)
1874 if (m_logicalFunction
== function
)
1880 x_function
= GXclear
;
1886 x_function
= GXinvert
;
1889 x_function
= GXorReverse
;
1892 x_function
= GXandReverse
;
1901 x_function
= GXandInverted
;
1904 x_function
= GXnoop
;
1910 x_function
= GXequiv
;
1913 x_function
= GXcopyInverted
;
1916 x_function
= GXorInverted
;
1919 x_function
= GXnand
;
1926 x_function
= GXcopy
;
1930 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
1931 if (m_window
&& m_window
->GetBackingPixmap())
1932 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
1934 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
1935 /* MATTHEW: [9] Need to redo pen simply */
1936 m_autoSetting
|= 0x2;
1938 m_logicalFunction
= function
;
1942 void wxWindowDC::SetTextForeground( const wxColour
&col
)
1946 if (m_textForegroundColour
== col
) return;
1948 m_textForegroundColour
= col
;
1952 void wxWindowDC::SetTextBackground( const wxColour
&col
)
1956 if (m_textBackgroundColour
== col
) return;
1958 m_textBackgroundColour
= col
;
1959 if (!m_textBackgroundColour
.Ok()) return;
1962 void wxWindowDC::SetBackgroundMode( int mode
)
1964 m_backgroundMode
= mode
;
1968 void wxWindowDC::SetPalette( const wxPalette
& palette
)
1973 /* Use GetXColormap */
1974 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1975 (Colormap
) palette
.GetXColormap());
1977 /* Use wxGetMainColormap */
1978 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1979 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
1984 void wxWindowDC:: SetDCClipping ()
1986 // m_userRegion is the region set by calling SetClippingRegion
1988 if (m_currentRegion
)
1989 XDestroyRegion ((Region
) m_currentRegion
);
1991 // We need to take into account
1992 // clipping imposed on a window by a repaint.
1993 // We'll combine it with the user region. But for now,
1994 // just use the currently-defined user clipping region.
1995 if (m_userRegion
|| (m_window
&& m_window
->GetUpdateRegion().Ok()) )
1996 m_currentRegion
= (WXRegion
) XCreateRegion ();
1998 m_currentRegion
= (WXRegion
) NULL
;
2000 if ((m_window
&& m_window
->GetUpdateRegion().Ok()) && m_userRegion
)
2001 XIntersectRegion ((Region
) m_window
->GetUpdateRegion().GetXRegion(), (Region
) m_userRegion
, (Region
) m_currentRegion
);
2002 else if (m_userRegion
)
2003 XIntersectRegion ((Region
) m_userRegion
, (Region
) m_userRegion
, (Region
) m_currentRegion
);
2004 else if (m_window
&& m_window
->GetUpdateRegion().Ok())
2005 XIntersectRegion ((Region
) m_window
->GetUpdateRegion().GetXRegion(), (Region
) m_window
->GetUpdateRegion().GetXRegion(),
2006 (Region
) m_currentRegion
);
2008 if (m_currentRegion
)
2010 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) m_currentRegion
);
2014 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
2019 void wxWindowDC::SetClippingRegion( long x
, long y
, long width
, long height
)
2021 wxDC::SetClippingRegion( x
, y
, width
, height
);
2024 XDestroyRegion ((Region
) m_userRegion
);
2025 m_userRegion
= (WXRegion
) XCreateRegion ();
2029 r
.width
= XLOG2DEVREL(width
);
2030 r
.height
= YLOG2DEVREL(height
);
2031 XUnionRectWithRegion (&r
, (Region
) m_userRegion
, (Region
) m_userRegion
);
2035 // Needs to work differently for Pixmap: without this,
2036 // there's a nasty (Display*) m_display bug. 8/12/94
2037 if (m_window
&& m_window
->GetBackingPixmap())
2039 XRectangle rects
[1];
2040 rects
[0].x
= XLOG2DEV_2(x
);
2041 rects
[0].y
= YLOG2DEV_2(y
);
2042 rects
[0].width
= XLOG2DEVREL(width
);
2043 rects
[0].height
= YLOG2DEVREL(height
);
2044 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 0, 0, rects
, 1, Unsorted
);
2048 void wxWindowDC::DestroyClippingRegion(void)
2050 wxDC::DestroyClippingRegion();
2053 XDestroyRegion ((Region
) m_userRegion
);
2054 m_userRegion
= NULL
;
2059 gc_val
.clip_mask
= None
;
2060 if (m_window
&& m_window
->GetBackingPixmap())
2061 XChangeGC((Display
*) m_display
, (GC
) m_gcBacking
, GCClipMask
, &gc_val
);
2064 // ----------------------------------- spline code ----------------------------------------
2066 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
2067 double a3
, double b3
, double a4
, double b4
);
2068 void wx_clear_stack(void);
2069 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
2070 double *y3
, double *x4
, double *y4
);
2071 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
2072 double x4
, double y4
);
2073 static bool wx_spline_add_point(double x
, double y
);
2074 static void wx_spline_draw_point_array(wxDC
*dc
);
2076 wxList wx_spline_point_list
;
2078 #define half(z1, z2) ((z1+z2)/2.0)
2081 /* iterative version */
2083 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
2086 register double xmid
, ymid
;
2087 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
2090 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
2092 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
2093 xmid
= (double)half(x2
, x3
);
2094 ymid
= (double)half(y2
, y3
);
2095 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
2096 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
2097 wx_spline_add_point( x1
, y1
);
2098 wx_spline_add_point( xmid
, ymid
);
2100 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
2101 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
2102 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
2103 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
2108 /* utilities used by spline drawing routines */
2110 typedef struct wx_spline_stack_struct
{
2111 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
2114 #define SPLINE_STACK_DEPTH 20
2115 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
2116 static Stack
*wx_stack_top
;
2117 static int wx_stack_count
;
2119 void wx_clear_stack(void)
2121 wx_stack_top
= wx_spline_stack
;
2125 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
2127 wx_stack_top
->x1
= x1
;
2128 wx_stack_top
->y1
= y1
;
2129 wx_stack_top
->x2
= x2
;
2130 wx_stack_top
->y2
= y2
;
2131 wx_stack_top
->x3
= x3
;
2132 wx_stack_top
->y3
= y3
;
2133 wx_stack_top
->x4
= x4
;
2134 wx_stack_top
->y4
= y4
;
2139 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
2140 double *x3
, double *y3
, double *x4
, double *y4
)
2142 if (wx_stack_count
== 0)
2146 *x1
= wx_stack_top
->x1
;
2147 *y1
= wx_stack_top
->y1
;
2148 *x2
= wx_stack_top
->x2
;
2149 *y2
= wx_stack_top
->y2
;
2150 *x3
= wx_stack_top
->x3
;
2151 *y3
= wx_stack_top
->y3
;
2152 *x4
= wx_stack_top
->x4
;
2153 *y4
= wx_stack_top
->y4
;
2157 static bool wx_spline_add_point(double x
, double y
)
2159 wxPoint
*point
= new wxPoint
;
2162 wx_spline_point_list
.Append((wxObject
*)point
);
2166 static void wx_spline_draw_point_array(wxDC
*dc
)
2168 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
2169 wxNode
*node
= wx_spline_point_list
.First();
2172 wxPoint
*point
= (wxPoint
*)node
->Data();
2175 node
= wx_spline_point_list
.First();
2179 void wxWindowDC::DrawSpline( wxList
*points
)
2182 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
2183 double x1
, y1
, x2
, y2
;
2185 wxNode
*node
= points
->First();
2186 p
= (wxPoint
*)node
->Data();
2191 node
= node
->Next();
2192 p
= (wxPoint
*)node
->Data();
2196 cx1
= (double)((x1
+ x2
) / 2);
2197 cy1
= (double)((y1
+ y2
) / 2);
2198 cx2
= (double)((cx1
+ x2
) / 2);
2199 cy2
= (double)((cy1
+ y2
) / 2);
2201 wx_spline_add_point(x1
, y1
);
2203 while ((node
= node
->Next()) != NULL
)
2205 p
= (wxPoint
*)node
->Data();
2210 cx4
= (double)(x1
+ x2
) / 2;
2211 cy4
= (double)(y1
+ y2
) / 2;
2212 cx3
= (double)(x1
+ cx4
) / 2;
2213 cy3
= (double)(y1
+ cy4
) / 2;
2215 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
2219 cx2
= (double)(cx1
+ x2
) / 2;
2220 cy2
= (double)(cy1
+ y2
) / 2;
2223 wx_spline_add_point( cx1
, cy1
);
2224 wx_spline_add_point( x2
, y2
);
2226 wx_spline_draw_point_array( this );
2233 wxPaintDC::wxPaintDC(wxWindow
* win
): wxWindowDC(win
)
2235 wxRegion
* region
= NULL
;
2237 // Combine all the update rects into a region
2238 if (win
->m_updateRects
.Number() > 0)
2241 for (i
= 0; i
< win
->m_updateRects
.Number(); i
++)
2243 wxRect
* rect
= (wxRect
*) win
->m_updateRects
.Nth(i
)->Data();
2245 cout << "wxPaintDC. wxRect: " << rect->x << ", " << rect->y << ", ";
2246 cout << rect->width << ", " << rect->height << "\n\n";
2250 region
= new wxRegion(*rect
);
2252 // TODO: is this correct? In SetDCClipping above,
2253 // XIntersectRegion is used to combine paint and user
2254 // regions. XIntersectRegion appears to work in that case...
2255 region
->Union(*rect
);
2261 win
->GetClientSize(&cw
, &ch
);
2262 region
= new wxRegion(wxRect(0, 0, cw
, ch
));
2265 win
->m_updateRegion
= *region
;
2267 // Set the clipping region. Any user-defined region will be combined with this
2268 // one in SetDCClipping.
2269 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) region
->GetXRegion());
2274 wxPaintDC::~wxPaintDC()
2276 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
2278 m_window
->m_updateRegion
.Clear();