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
, 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 wxFAIL_MSG("set a valid font before calling GetTextExtent!");
1239 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1241 int direction
, ascent
, descent2
;
1242 XCharStruct overall
;
1245 if (use16
) slen
= str16len(string
); else slen
= strlen(string
);
1248 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1249 &ascent
, &descent2
, &overall
);
1251 XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) string
, slen
, &direction
,
1252 &ascent
, &descent2
, &overall
);
1254 *width
= XDEV2LOGREL (overall
.width
);
1255 *height
= YDEV2LOGREL (ascent
+ descent2
);
1257 *descent
= descent2
;
1258 if (externalLeading
)
1259 *externalLeading
= 0;
1262 long wxWindowDC::GetCharWidth(void)
1264 if (!Ok()) return 0;
1269 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
* m_logicalScaleY
, m_display
);
1271 int direction
, ascent
, descent
;
1272 XCharStruct overall
;
1273 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1274 &descent
, &overall
);
1275 return XDEV2LOGREL(overall
.width
);
1278 long wxWindowDC::GetCharHeight(void)
1280 if (!Ok()) return 0;
1285 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1287 int direction
, ascent
, descent
;
1288 XCharStruct overall
;
1289 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1290 &descent
, &overall
);
1291 // return XDEV2LOGREL(overall.ascent + overall.descent);
1292 return XDEV2LOGREL(ascent
+ descent
);
1295 void wxWindowDC::Clear(void)
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::Clear(const wxRect
& rect
)
1337 int x
= rect
.x
; int y
= rect
.y
;
1338 int w
= rect
.width
; int h
= rect
.height
;
1340 wxBrush saveBrush
= m_brush
;
1341 SetBrush (m_backgroundBrush
);
1343 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x
, y
, w
, h
);
1345 if (m_window
&& m_window
->GetBackingPixmap())
1346 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, x
, y
, w
, h
);
1348 m_brush
= saveBrush
;
1351 void wxWindowDC::SetFont( const wxFont
&font
)
1359 if ((m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
1361 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
1363 if (m_window
&& m_window
->GetBackingPixmap())
1364 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
1369 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1371 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1372 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1374 if (m_window
&& m_window
->GetBackingPixmap())
1375 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1378 void wxWindowDC::SetPen( const wxPen
&pen
)
1386 wxBitmap oldStipple
= m_currentStipple
;
1387 int oldStyle
= m_currentStyle
;
1388 int oldFill
= m_currentFill
;
1389 int old_pen_width
= m_currentPenWidth
;
1390 int old_pen_join
= m_currentPenJoin
;
1391 int old_pen_cap
= m_currentPenCap
;
1392 int old_pen_nb_dash
= m_currentPenDashCount
;
1393 char *old_pen_dash
= m_currentPenDash
;
1395 wxColour oldPenColour
= m_currentColour
;
1396 m_currentColour
= m_pen
.GetColour ();
1397 m_currentStyle
= m_pen
.GetStyle ();
1398 m_currentFill
= m_pen
.GetStyle (); // TODO?
1399 m_currentPenWidth
= m_pen
.GetWidth ();
1400 m_currentPenJoin
= m_pen
.GetJoin ();
1401 m_currentPenCap
= m_pen
.GetCap ();
1402 m_currentPenDashCount
= m_pen
.GetDashCount();
1403 m_currentPenDash
= m_pen
.GetDash();
1405 if (m_currentStyle
== wxSTIPPLE
)
1406 m_currentStipple
= * m_pen
.GetStipple ();
1408 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1409 oldFill
== m_currentFill
&&
1410 old_pen_join
== m_currentPenJoin
&&
1411 old_pen_cap
== m_currentPenCap
&&
1412 old_pen_nb_dash
== m_currentPenDashCount
&&
1413 old_pen_dash
== m_currentPenDash
&&
1414 old_pen_width
== m_currentPenWidth
);
1416 bool sameColour
= (oldPenColour
.Ok () &&
1417 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1418 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1419 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1420 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1422 if (!sameStyle
|| !GetOptimization())
1424 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1425 if (scaled_width
< 0)
1431 static char dotted
[] =
1433 static char short_dashed
[] =
1435 static char long_dashed
[] =
1437 static char dotted_dashed
[] =
1440 // We express dash pattern in pen width unit, so we are
1441 // independent of zoom factor and so on...
1445 switch (m_pen
.GetStyle ())
1448 req_nb_dash
= m_currentPenDashCount
;
1449 req_dash
= m_currentPenDash
;
1450 style
= LineOnOffDash
;
1455 style
= LineOnOffDash
;
1459 req_dash
= short_dashed
;
1460 style
= LineOnOffDash
;
1464 req_dash
= long_dashed
;
1465 style
= LineOnOffDash
;
1469 req_dash
= dotted_dashed
;
1470 style
= LineOnOffDash
;
1481 if (req_dash
&& req_nb_dash
)
1483 char *real_req_dash
= new char[req_nb_dash
];
1486 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1487 for (int i
= 0; i
< req_nb_dash
; i
++)
1488 real_req_dash
[i
] = req_dash
[i
] * factor
;
1489 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1491 if (m_window
&& m_window
->GetBackingPixmap())
1492 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1493 delete[]real_req_dash
;
1497 // No Memory. We use non-scaled dash pattern...
1498 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1500 if (m_window
&& m_window
->GetBackingPixmap())
1501 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1505 switch (m_pen
.GetCap ())
1507 case wxCAP_PROJECTING
:
1508 cap
= CapProjecting
;
1519 switch (m_pen
.GetJoin ())
1533 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1535 if (m_window
&& m_window
->GetBackingPixmap())
1536 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1539 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1543 oldStipple
= wxNullBitmap
; // For later reset!!
1545 switch (m_currentFill
)
1547 case wxBDIAGONAL_HATCH
:
1548 if (bdiag
== (Pixmap
) 0)
1549 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1550 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1551 bdiag_bits
, bdiag_width
, bdiag_height
);
1554 case wxFDIAGONAL_HATCH
:
1555 if (fdiag
== (Pixmap
) 0)
1556 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1557 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1558 fdiag_bits
, fdiag_width
, fdiag_height
);
1562 if (cross
== (Pixmap
) 0)
1563 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1564 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1565 cross_bits
, cross_width
, cross_height
);
1568 case wxHORIZONTAL_HATCH
:
1569 if (horiz
== (Pixmap
) 0)
1570 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1571 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1572 horiz_bits
, horiz_width
, horiz_height
);
1575 case wxVERTICAL_HATCH
:
1576 if (verti
== (Pixmap
) 0)
1577 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1578 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1579 verti_bits
, verti_width
, verti_height
);
1582 case wxCROSSDIAG_HATCH
:
1584 if (cdiag
== (Pixmap
) 0)
1585 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1586 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1587 cdiag_bits
, cdiag_width
, cdiag_height
);
1591 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1593 if (m_window
&& m_window
->GetBackingPixmap())
1594 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1596 else if (m_currentStipple
.Ok()
1597 && ((m_currentStipple
!= oldStipple
) || !GetOptimization()))
1599 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1601 if (m_window
&& m_window
->GetBackingPixmap())
1602 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1605 if ((m_currentFill
!= oldFill
) || !GetOptimization())
1609 if (m_currentFill
== wxSTIPPLE
)
1610 fill_style
= FillStippled
;
1611 else if (IS_HATCH (m_currentFill
))
1612 fill_style
= FillStippled
;
1614 fill_style
= FillSolid
;
1615 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1616 if (m_window
&& m_window
->GetBackingPixmap())
1617 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1620 // must test m_logicalFunction, because it involves background!
1621 if (!sameColour
|| !GetOptimization()
1622 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1625 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1626 pixel
= m_backgroundPixel
;
1629 unsigned char red
= m_pen
.GetColour ().Red ();
1630 unsigned char blue
= m_pen
.GetColour ().Blue ();
1631 unsigned char green
= m_pen
.GetColour ().Green ();
1632 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1633 && green
== (unsigned char) 255)
1635 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1636 m_currentColour
= *wxWHITE
;
1637 m_pen
.GetColour().SetPixel(pixel
);
1638 m_currentColour
.SetPixel(pixel
);
1642 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1643 m_currentColour
= *wxBLACK
;
1644 m_pen
.GetColour().SetPixel(pixel
);
1649 pixel
= m_pen
.GetColour ().AllocColour(m_display
);
1650 m_currentColour
.SetPixel(pixel
);
1653 // Finally, set the GC to the required colour
1656 if (m_logicalFunction
== wxXOR
)
1659 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1660 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1661 if (m_window
&& m_window
->GetBackingPixmap())
1662 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1666 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1667 if (m_window
&& m_window
->GetBackingPixmap())
1668 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1673 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1678 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1684 if (!m_brush
.Ok() || m_brush
.GetStyle () == wxTRANSPARENT
)
1687 int oldFill
= m_currentFill
;
1688 wxBitmap oldStipple
= m_currentStipple
;
1690 m_autoSetting
|= 0x1;
1692 m_currentFill
= m_brush
.GetStyle ();
1693 if (m_currentFill
== wxSTIPPLE
)
1694 m_currentStipple
= * m_brush
.GetStipple ();
1696 wxColour
oldBrushColour(m_currentColour
);
1697 m_currentColour
= m_brush
.GetColour ();
1699 bool sameColour
= (oldBrushColour
.Ok () &&
1700 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1701 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1702 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1703 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1705 if ((oldFill
!= m_brush
.GetStyle ()) || !GetOptimization())
1707 switch (brush
.GetStyle ())
1711 case wxBDIAGONAL_HATCH
:
1712 case wxCROSSDIAG_HATCH
:
1713 case wxFDIAGONAL_HATCH
:
1715 case wxHORIZONTAL_HATCH
:
1716 case wxVERTICAL_HATCH
:
1719 // Chris Breeze 23/07/97: use background mode to determine whether
1720 // fill style should be solid or transparent
1721 int style
= (m_backgroundMode
== wxSOLID
? FillOpaqueStippled
: FillStippled
);
1722 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1723 if (m_window
&& m_window
->GetBackingPixmap())
1724 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1729 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1730 if (m_window
&& m_window
->GetBackingPixmap())
1731 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, FillSolid
);
1735 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1739 switch (m_currentFill
)
1741 case wxBDIAGONAL_HATCH
:
1742 if (bdiag
== (Pixmap
) 0)
1743 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1744 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1745 bdiag_bits
, bdiag_width
, bdiag_height
);
1748 case wxFDIAGONAL_HATCH
:
1749 if (fdiag
== (Pixmap
) 0)
1750 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1751 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1752 fdiag_bits
, fdiag_width
, fdiag_height
);
1756 if (cross
== (Pixmap
) 0)
1757 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1758 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1759 cross_bits
, cross_width
, cross_height
);
1762 case wxHORIZONTAL_HATCH
:
1763 if (horiz
== (Pixmap
) 0)
1764 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1765 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1766 horiz_bits
, horiz_width
, horiz_height
);
1769 case wxVERTICAL_HATCH
:
1770 if (verti
== (Pixmap
) 0)
1771 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1772 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1773 verti_bits
, verti_width
, verti_height
);
1776 case wxCROSSDIAG_HATCH
:
1778 if (cdiag
== (Pixmap
) 0)
1779 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1780 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1781 cdiag_bits
, cdiag_width
, cdiag_height
);
1785 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1787 if (m_window
&& m_window
->GetBackingPixmap())
1788 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1790 // X can forget the stipple value when resizing a window (apparently)
1791 // so always set the stipple.
1792 else if (m_currentStipple
.Ok()) // && m_currentStipple != oldStipple)
1794 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1795 if (m_window
&& m_window
->GetBackingPixmap())
1796 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1799 // must test m_logicalFunction, because it involves background!
1800 if (!sameColour
|| !GetOptimization() || m_logicalFunction
== wxXOR
)
1805 // Policy - on a monochrome screen, all brushes are white,
1806 // except when they're REALLY black!!!
1807 unsigned char red
= m_brush
.GetColour ().Red ();
1808 unsigned char blue
= m_brush
.GetColour ().Blue ();
1809 unsigned char green
= m_brush
.GetColour ().Green ();
1811 if (red
== (unsigned char) 0 && blue
== (unsigned char) 0
1812 && green
== (unsigned char) 0)
1814 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1815 m_currentColour
= *wxBLACK
;
1816 m_brush
.GetColour().SetPixel(pixel
);
1817 m_currentColour
.SetPixel(pixel
);
1821 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1822 m_currentColour
= *wxWHITE
;
1823 m_brush
.GetColour().SetPixel(pixel
);
1824 m_currentColour
.SetPixel(pixel
);
1827 // N.B. comment out the above line and uncomment the following lines
1828 // if you want non-white colours to be black on a monochrome display.
1830 if (red == (unsigned char )255 && blue == (unsigned char)255
1831 && green == (unsigned char)255)
1832 pixel = (int)WhitePixel((Display*) m_display, DefaultScreen((Display*) m_display));
1834 pixel = (int)BlackPixel((Display*) m_display, DefaultScreen((Display*) m_display));
1837 else if (m_brush
.GetStyle () != wxTRANSPARENT
)
1839 pixel
= m_brush
.GetColour().AllocColour(m_display
);
1840 m_currentColour
.SetPixel(pixel
);
1844 // Finally, set the GC to the required colour
1845 if (m_logicalFunction
== wxXOR
)
1848 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1849 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1850 if (m_window
&& m_window
->GetBackingPixmap())
1851 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1855 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1856 if (m_window
&& m_window
->GetBackingPixmap())
1857 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1862 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1865 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1869 m_backgroundBrush
= brush
;
1871 if (!m_backgroundBrush
.Ok())
1874 int pixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
1876 // XSetWindowBackground doesn't work for non-Window pixmaps
1877 if (!this->IsKindOf(CLASSINFO(wxMemoryDC
)))
1878 XSetWindowBackground ((Display
*) m_display
, (Pixmap
) m_pixmap
, pixel
);
1880 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
1881 // And Blit,... (Any fct that use XCopyPlane, in fact.)
1882 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1883 if (m_window
&& m_window
->GetBackingPixmap())
1884 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1887 void wxWindowDC::SetLogicalFunction( int function
)
1892 if (m_logicalFunction
== function
)
1898 x_function
= GXclear
;
1904 x_function
= GXinvert
;
1907 x_function
= GXorReverse
;
1910 x_function
= GXandReverse
;
1919 x_function
= GXandInverted
;
1922 x_function
= GXnoop
;
1928 x_function
= GXequiv
;
1931 x_function
= GXcopyInverted
;
1934 x_function
= GXorInverted
;
1937 x_function
= GXnand
;
1944 x_function
= GXcopy
;
1948 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
1949 if (m_window
&& m_window
->GetBackingPixmap())
1950 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
1952 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
1953 /* MATTHEW: [9] Need to redo pen simply */
1954 m_autoSetting
|= 0x2;
1956 m_logicalFunction
= function
;
1960 void wxWindowDC::SetTextForeground( const wxColour
&col
)
1964 if (m_textForegroundColour
== col
) return;
1966 m_textForegroundColour
= col
;
1970 void wxWindowDC::SetTextBackground( const wxColour
&col
)
1974 if (m_textBackgroundColour
== col
) return;
1976 m_textBackgroundColour
= col
;
1977 if (!m_textBackgroundColour
.Ok()) return;
1980 void wxWindowDC::SetBackgroundMode( int mode
)
1982 m_backgroundMode
= mode
;
1986 void wxWindowDC::SetPalette( const wxPalette
& palette
)
1991 /* Use GetXColormap */
1992 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1993 (Colormap
) palette
.GetXColormap());
1995 /* Use wxGetMainColormap */
1996 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1997 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2002 void wxWindowDC:: SetDCClipping ()
2004 // m_userRegion is the region set by calling SetClippingRegion
2006 if (m_currentRegion
)
2007 XDestroyRegion ((Region
) m_currentRegion
);
2009 // We need to take into account
2010 // clipping imposed on a window by a repaint.
2011 // We'll combine it with the user region. But for now,
2012 // just use the currently-defined user clipping region.
2013 if (m_userRegion
|| (m_window
&& m_window
->GetUpdateRegion().Ok()) )
2014 m_currentRegion
= (WXRegion
) XCreateRegion ();
2016 m_currentRegion
= (WXRegion
) NULL
;
2018 if ((m_window
&& m_window
->GetUpdateRegion().Ok()) && m_userRegion
)
2019 XIntersectRegion ((Region
) m_window
->GetUpdateRegion().GetXRegion(), (Region
) m_userRegion
, (Region
) m_currentRegion
);
2020 else if (m_userRegion
)
2021 XIntersectRegion ((Region
) m_userRegion
, (Region
) m_userRegion
, (Region
) m_currentRegion
);
2022 else if (m_window
&& m_window
->GetUpdateRegion().Ok())
2023 XIntersectRegion ((Region
) m_window
->GetUpdateRegion().GetXRegion(), (Region
) m_window
->GetUpdateRegion().GetXRegion(),
2024 (Region
) m_currentRegion
);
2026 if (m_currentRegion
)
2028 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) m_currentRegion
);
2032 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
2037 void wxWindowDC::SetClippingRegion( long x
, long y
, long width
, long height
)
2039 wxDC::SetClippingRegion( x
, y
, width
, height
);
2042 XDestroyRegion ((Region
) m_userRegion
);
2043 m_userRegion
= (WXRegion
) XCreateRegion ();
2047 r
.width
= XLOG2DEVREL(width
);
2048 r
.height
= YLOG2DEVREL(height
);
2049 XUnionRectWithRegion (&r
, (Region
) m_userRegion
, (Region
) m_userRegion
);
2053 // Needs to work differently for Pixmap: without this,
2054 // there's a nasty (Display*) m_display bug. 8/12/94
2055 if (m_window
&& m_window
->GetBackingPixmap())
2057 XRectangle rects
[1];
2058 rects
[0].x
= XLOG2DEV_2(x
);
2059 rects
[0].y
= YLOG2DEV_2(y
);
2060 rects
[0].width
= XLOG2DEVREL(width
);
2061 rects
[0].height
= YLOG2DEVREL(height
);
2062 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 0, 0, rects
, 1, Unsorted
);
2066 void wxWindowDC::SetClippingRegion( const wxRegion
& region
)
2068 wxRect box
= region
.GetBox();
2070 wxDC::SetClippingRegion( box
.x
, box
.y
, box
.width
, box
.height
);
2073 XDestroyRegion ((Region
) m_userRegion
);
2074 m_userRegion
= (WXRegion
) XCreateRegion ();
2076 XUnionRegion((Region
) m_userRegion
, (Region
) region
.GetXRegion(), (Region
) m_userRegion
);
2080 // Needs to work differently for Pixmap: without this,
2081 // there's a nasty (Display*) m_display bug. 8/12/94
2082 if (m_window
&& m_window
->GetBackingPixmap())
2084 XRectangle rects
[1];
2085 rects
[0].x
= XLOG2DEV_2(box
.x
);
2086 rects
[0].y
= YLOG2DEV_2(box
.y
);
2087 rects
[0].width
= XLOG2DEVREL(box
.width
);
2088 rects
[0].height
= YLOG2DEVREL(box
.height
);
2089 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 0, 0, rects
, 1, Unsorted
);
2094 void wxWindowDC::DestroyClippingRegion(void)
2096 wxDC::DestroyClippingRegion();
2099 XDestroyRegion ((Region
) m_userRegion
);
2100 m_userRegion
= NULL
;
2105 gc_val
.clip_mask
= None
;
2106 if (m_window
&& m_window
->GetBackingPixmap())
2107 XChangeGC((Display
*) m_display
, (GC
) m_gcBacking
, GCClipMask
, &gc_val
);
2110 // ----------------------------------- spline code ----------------------------------------
2112 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
2113 double a3
, double b3
, double a4
, double b4
);
2114 void wx_clear_stack(void);
2115 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
2116 double *y3
, double *x4
, double *y4
);
2117 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
2118 double x4
, double y4
);
2119 static bool wx_spline_add_point(double x
, double y
);
2120 static void wx_spline_draw_point_array(wxDC
*dc
);
2122 wxList wx_spline_point_list
;
2124 #define half(z1, z2) ((z1+z2)/2.0)
2127 /* iterative version */
2129 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
2132 register double xmid
, ymid
;
2133 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
2136 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
2138 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
2139 xmid
= (double)half(x2
, x3
);
2140 ymid
= (double)half(y2
, y3
);
2141 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
2142 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
2143 wx_spline_add_point( x1
, y1
);
2144 wx_spline_add_point( xmid
, ymid
);
2146 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
2147 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
2148 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
2149 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
2154 /* utilities used by spline drawing routines */
2156 typedef struct wx_spline_stack_struct
{
2157 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
2160 #define SPLINE_STACK_DEPTH 20
2161 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
2162 static Stack
*wx_stack_top
;
2163 static int wx_stack_count
;
2165 void wx_clear_stack(void)
2167 wx_stack_top
= wx_spline_stack
;
2171 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
2173 wx_stack_top
->x1
= x1
;
2174 wx_stack_top
->y1
= y1
;
2175 wx_stack_top
->x2
= x2
;
2176 wx_stack_top
->y2
= y2
;
2177 wx_stack_top
->x3
= x3
;
2178 wx_stack_top
->y3
= y3
;
2179 wx_stack_top
->x4
= x4
;
2180 wx_stack_top
->y4
= y4
;
2185 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
2186 double *x3
, double *y3
, double *x4
, double *y4
)
2188 if (wx_stack_count
== 0)
2192 *x1
= wx_stack_top
->x1
;
2193 *y1
= wx_stack_top
->y1
;
2194 *x2
= wx_stack_top
->x2
;
2195 *y2
= wx_stack_top
->y2
;
2196 *x3
= wx_stack_top
->x3
;
2197 *y3
= wx_stack_top
->y3
;
2198 *x4
= wx_stack_top
->x4
;
2199 *y4
= wx_stack_top
->y4
;
2203 static bool wx_spline_add_point(double x
, double y
)
2205 wxPoint
*point
= new wxPoint
;
2208 wx_spline_point_list
.Append((wxObject
*)point
);
2212 static void wx_spline_draw_point_array(wxDC
*dc
)
2214 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
2215 wxNode
*node
= wx_spline_point_list
.First();
2218 wxPoint
*point
= (wxPoint
*)node
->Data();
2221 node
= wx_spline_point_list
.First();
2225 void wxWindowDC::DrawSpline( wxList
*points
)
2228 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
2229 double x1
, y1
, x2
, y2
;
2231 wxNode
*node
= points
->First();
2232 p
= (wxPoint
*)node
->Data();
2237 node
= node
->Next();
2238 p
= (wxPoint
*)node
->Data();
2242 cx1
= (double)((x1
+ x2
) / 2);
2243 cy1
= (double)((y1
+ y2
) / 2);
2244 cx2
= (double)((cx1
+ x2
) / 2);
2245 cy2
= (double)((cy1
+ y2
) / 2);
2247 wx_spline_add_point(x1
, y1
);
2249 while ((node
= node
->Next()) != NULL
)
2251 p
= (wxPoint
*)node
->Data();
2256 cx4
= (double)(x1
+ x2
) / 2;
2257 cy4
= (double)(y1
+ y2
) / 2;
2258 cx3
= (double)(x1
+ cx4
) / 2;
2259 cy3
= (double)(y1
+ cy4
) / 2;
2261 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
2265 cx2
= (double)(cx1
+ x2
) / 2;
2266 cy2
= (double)(cy1
+ y2
) / 2;
2269 wx_spline_add_point( cx1
, cy1
);
2270 wx_spline_add_point( x2
, y2
);
2272 wx_spline_draw_point_array( this );
2279 wxPaintDC::wxPaintDC(wxWindow
* win
): wxWindowDC(win
)
2281 wxRegion
* region
= NULL
;
2283 // Combine all the update rects into a region
2284 if (win
->m_updateRects
.Number() > 0)
2287 for (i
= 0; i
< win
->m_updateRects
.Number(); i
++)
2289 wxRect
* rect
= (wxRect
*) win
->m_updateRects
.Nth(i
)->Data();
2291 cout << "wxPaintDC. wxRect: " << rect->x << ", " << rect->y << ", ";
2292 cout << rect->width << ", " << rect->height << "\n\n";
2296 region
= new wxRegion(*rect
);
2298 // TODO: is this correct? In SetDCClipping above,
2299 // XIntersectRegion is used to combine paint and user
2300 // regions. XIntersectRegion appears to work in that case...
2301 region
->Union(*rect
);
2307 win
->GetClientSize(&cw
, &ch
);
2308 region
= new wxRegion(wxRect(0, 0, cw
, ch
));
2311 win
->m_updateRegion
= *region
;
2313 // Set the clipping region. Any user-defined region will be combined with this
2314 // one in SetDCClipping.
2315 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) region
->GetXRegion());
2320 wxPaintDC::~wxPaintDC()
2322 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
2324 m_window
->m_updateRegion
.Clear();