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;
94 wxWindowDC::wxWindowDC( wxWindow
*window
)
96 wxASSERT_MSG( (window
!= (wxWindow
*) NULL
), "You must pass a valid wxWindow to wxWindowDC/wxClientDC/wxPaintDC constructor." );
100 m_gcBacking
= (WXGC
) 0;
101 m_backgroundPixel
= -1;
102 m_currentPenWidth
= 1;
103 m_currentPenJoin
= -1;
104 m_currentPenDashCount
= -1;
105 m_currentPenDash
= (char*) NULL
;
108 // m_currentBkMode = wxTRANSPARENT;
109 m_colour
= wxColourDisplay();
110 m_currentRegion
= (WXRegion
) 0;
111 m_userRegion
= (WXRegion
) 0;
115 m_display
= window
->GetXDisplay();
116 m_pixmap
= window
->GetXWindow();
117 Display
* display
= (Display
*) m_display
;
119 XSetWindowColormap (display
, (Pixmap
) m_pixmap
, (Colormap
) wxTheApp
->GetMainColormap(m_display
));
122 gcvalues
.foreground
= BlackPixel (display
, DefaultScreen (display
));
123 gcvalues
.background
= WhitePixel (display
, DefaultScreen (display
));
124 gcvalues
.graphics_exposures
= False
;
125 gcvalues
.line_width
= 1;
126 m_gc
= (WXGC
) XCreateGC (display
, RootWindow (display
, DefaultScreen (display
)),
127 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
,
130 if (m_window
->GetBackingPixmap())
132 m_gcBacking
= (WXGC
) XCreateGC (display
, RootWindow (display
,
133 DefaultScreen (display
)),
134 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
,
138 m_backgroundPixel
= (int) gcvalues
.background
;
141 wxWindowDC::~wxWindowDC(void)
144 XFreeGC ((Display
*) m_display
, (GC
) m_gc
);
148 XFreeGC ((Display
*) m_display
, (GC
) m_gcBacking
);
149 m_gcBacking
= (WXGC
) 0;
152 XDestroyRegion ((Region
) m_currentRegion
);
153 m_currentRegion
= (WXRegion
) 0;
156 XDestroyRegion ((Region
) m_userRegion
);
157 m_userRegion
= (WXRegion
) 0;
160 void wxWindowDC::FloodFill( long WXUNUSED(x1
), long WXUNUSED(y1
),
161 wxColour
* WXUNUSED(col
), int WXUNUSED(style
) )
166 bool wxWindowDC::GetPixel( long WXUNUSED(x1
), long WXUNUSED(y1
), wxColour
*WXUNUSED(col
) ) const
172 void wxWindowDC::DrawLine( long x1
, long y1
, long x2
, long y2
)
176 int x1d
, y1d
, x2d
, y2d
;
178 // FreeGetPixelCache();
188 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x1d
, y1d
, x2d
, y2d
);
190 if (m_window
&& m_window
->GetBackingPixmap())
191 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
192 XLOG2DEV_2(x1
), YLOG2DEV_2(y1
),
193 XLOG2DEV_2(x2
), YLOG2DEV_2(y2
));
195 CalcBoundingBox(x1
, y1
);
196 CalcBoundingBox(x2
, y2
);
199 void wxWindowDC::CrossHair( long x
, long y
)
206 int xx
= XLOG2DEV (x
);
207 int yy
= YLOG2DEV (y
);
209 wxDisplaySize (&ww
, &hh
);
210 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, yy
,
212 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xx
, 0,
215 if (m_window
&& m_window
->GetBackingPixmap())
219 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
222 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
228 void wxWindowDC::DrawArc( long x1
, long y1
, long x2
, long y2
, long xc
, long yc
)
232 // FreeGetPixelCache();
234 int xx1
= XLOG2DEV (x1
);
235 int yy1
= YLOG2DEV (y1
);
236 int xx2
= XLOG2DEV (x2
);
237 int yy2
= YLOG2DEV (y2
);
238 int xxc
= XLOG2DEV (xc
);
239 int yyc
= YLOG2DEV (yc
);
240 int xxc_2
= XLOG2DEV_2 (xc
);
241 int yyc_2
= YLOG2DEV_2 (yc
);
245 double radius
= sqrt (dx
* dx
+ dy
* dy
);
246 long r
= (long) radius
;
248 double radius1
, radius2
;
250 if (xx1
== xx2
&& yy1
== yy2
)
255 else if (radius
== 0.0)
256 radius1
= radius2
= 0.0;
265 radius1
= -atan2 ((double) (yy1
- yyc
), (double) (xx1
- xxc
)) * 360.0 / (2 * M_PI
);
273 radius2
= -atan2 ((double) (yy2
- yyc
), (double) (xx2
- xxc
)) * 360.0 / (2 * M_PI
);
277 int alpha1
= (int) radius1
;
278 int alpha2
= (int) (radius2
- radius1
);
281 while (alpha2
> 360 * 64)
284 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
287 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) (GC
) m_gc
,
288 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
290 if (m_window
&& m_window
->GetBackingPixmap())
291 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
292 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
296 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
300 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
301 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
303 if (m_window
&& m_window
->GetBackingPixmap())
304 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
305 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
307 CalcBoundingBox (x1
, y1
);
308 CalcBoundingBox (x2
, y2
);
311 void wxWindowDC::DrawEllipticArc( long x
, long y
, long width
, long height
, double sa
, double ea
)
319 wd
= XLOG2DEVREL(width
);
320 hd
= YLOG2DEVREL(height
);
322 if (sa
>=360 || sa
<=-360) sa
=sa
-int(sa
/360)*360;
323 if (ea
>=360 || ea
<=-360) ea
=ea
-int(ea
/360)*360;
324 int start
= int(sa
*64);
325 int end
= int(ea
*64);
326 if (start
<0) start
+=360*64;
327 if (end
<0) end
+=360*64;
328 if (end
>start
) end
-=start
;
329 else end
+=360*64-start
;
331 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
333 m_autoSetting
= TRUE
; // must be reset
336 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
, end
);
338 if (m_window
&& m_window
->GetBackingPixmap())
339 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
340 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
343 if (!m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
347 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
,end
);
348 if (m_window
&& m_window
->GetBackingPixmap())
349 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
350 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
352 CalcBoundingBox (x
, y
);
353 CalcBoundingBox (x
+ width
, y
+ height
);
356 void wxWindowDC::DrawPoint( long x
, long y
)
360 // FreeGetPixelCache();
362 if (m_pen
.Ok() && m_autoSetting
)
365 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
));
366 if (m_window
&& m_window
->GetBackingPixmap())
367 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, XLOG2DEV_2 (x
), YLOG2DEV_2 (y
));
369 CalcBoundingBox (x
, y
);
372 void wxWindowDC::DrawLines( int n
, wxPoint points
[], long xoffset
, long yoffset
)
376 // FreeGetPixelCache();
378 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
383 XPoint
*xpoints
= new XPoint
[n
];
386 for (i
= 0; i
< n
; i
++)
388 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
389 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
391 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints
, n
, 0);
393 if (m_window
&& m_window
->GetBackingPixmap())
395 for (i
= 0; i
< n
; i
++)
397 xpoints
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
398 xpoints
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
400 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints
, n
, 0);
406 void wxWindowDC::DrawLines( wxList
*list
, long xoffset
, long yoffset
)
410 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
412 int n
= list
->Number();
413 wxPoint
*points
= new wxPoint
[n
];
416 for(wxNode
*node
= list
->First(); node
; node
= node
->Next()) {
417 wxPoint
*point
= (wxPoint
*)node
->Data();
418 points
[i
].x
= point
->x
;
419 points
[i
++].y
= point
->y
;
421 DrawLines(n
, points
, xoffset
, yoffset
);
425 void wxWindowDC::DrawPolygon( int n
, wxPoint points
[],
426 long xoffset
, long yoffset
, int fillStyle
)
428 // FreeGetPixelCache();
430 XPoint
*xpoints1
= new XPoint
[n
+ 1];
431 XPoint
*xpoints2
= new XPoint
[n
+ 1];
433 for (i
= 0; i
< n
; i
++)
435 xpoints1
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
436 xpoints1
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
437 xpoints2
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
438 xpoints2
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
439 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
442 // Close figure for XDrawLines (not needed for XFillPolygon)
443 xpoints1
[i
].x
= xpoints1
[0].x
;
444 xpoints1
[i
].y
= xpoints1
[0].y
;
445 xpoints2
[i
].x
= xpoints2
[0].x
;
446 xpoints2
[i
].y
= xpoints2
[0].y
;
448 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
451 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
452 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
, Complex
, 0);
453 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, EvenOddRule
); // default mode
454 if (m_window
&& m_window
->GetBackingPixmap())
456 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
,
457 fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
458 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
, Complex
, 0);
459 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
, EvenOddRule
); // default mode
463 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
467 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
+ 1, 0);
469 if (m_window
&& m_window
->GetBackingPixmap())
470 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
+ 1, 0);
477 void wxWindowDC::DrawPolygon( wxList
*list
, long xoffset
,
478 long yoffset
, int fillStyle
)
482 int n
= list
->Number();
483 wxPoint
*points
= new wxPoint
[n
];
486 for(wxNode
*node
= list
->First(); node
; node
= node
->Next()) {
487 wxPoint
*point
= (wxPoint
*)node
->Data();
488 points
[i
].x
= point
->x
;
489 points
[i
++].y
= point
->y
;
491 DrawPolygon(n
, points
, xoffset
, yoffset
,fillStyle
);
495 void wxWindowDC::DrawRectangle( long x
, long y
, long width
, long height
)
499 // FreeGetPixelCache();
501 int xd
, yd
, wfd
, hfd
, wd
, hd
;
505 wfd
= XLOG2DEVREL(width
);
507 hfd
= YLOG2DEVREL(height
);
510 if (wfd
== 0 || hfd
== 0) return;
511 if (wd
< 0) { wd
= - wd
; xd
= xd
- wd
; }
512 if (hd
< 0) { hd
= - hd
; yd
= yd
- hd
; }
514 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
517 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wfd
, hfd
);
519 if (m_window
&& m_window
->GetBackingPixmap())
520 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
521 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
525 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
529 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
);
531 if (m_window
&& m_window
->GetBackingPixmap())
532 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
533 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
536 CalcBoundingBox (x
, y
);
537 CalcBoundingBox (x
+ width
, y
+ height
);
540 void wxWindowDC::DrawRoundedRectangle( long x
, long y
, long width
, long height
, double radius
)
544 // FreeGetPixelCache();
546 // If radius is negative, it's a proportion of the smaller dimension.
548 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
550 int xd
= XLOG2DEV (x
);
551 int yd
= YLOG2DEV (y
);
552 int rd
= XLOG2DEVREL ((long) radius
);
553 int wd
= XLOG2DEVREL (width
) - WX_GC_CF
;
554 int hd
= YLOG2DEVREL (height
) - WX_GC_CF
;
559 // If radius is zero use DrawRectangle() instead to avoid
560 // X drawing errors with small radii
563 DrawRectangle( x
, y
, width
, height
);
567 // Draw nothing if transformed w or h is 0
568 if (wd
== 0 || hd
== 0) return;
570 // CMB: adjust size if outline is drawn otherwise the result is
571 // 1 pixel too wide and high
572 if (m_pen
.GetStyle() != wxTRANSPARENT
)
578 // CMB: ensure dd is not larger than rectangle otherwise we
579 // get an hour glass shape
580 if (rw_d
> wd
) rw_d
= wd
;
581 if (rw_d
> hd
) rw_d
= hd
;
584 // For backing pixmap
585 int xd2
= XLOG2DEV_2 (x
);
586 int yd2
= YLOG2DEV_2 (y
);
587 int rd2
= XLOG2DEVREL ((long) radius
);
588 int wd2
= XLOG2DEVREL (width
) ;
589 int hd2
= YLOG2DEVREL (height
) ;
594 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
598 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
600 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
603 // Arcs start from 3 o'clock, positive angles anticlockwise
605 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
606 rw_d
, rh_d
, 90 * 64, 90 * 64);
608 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
609 // rw_d, rh_d, 0, 90 * 64);
610 rw_d
, rh_d
, 0, 91 * 64);
612 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
614 // rw_d, rh_d, 270 * 64, 90 * 64);
615 rw_d
, rh_d
, 269 * 64, 92 * 64);
617 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
618 rw_d
, rh_d
, 180 * 64, 90 * 64);
620 if (m_window
&& m_window
->GetBackingPixmap())
622 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
623 xd2
+ rd2
, yd2
, wd2
- rw_d2
, hd2
);
624 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
625 xd2
, yd2
+ rd2
, wd2
, hd2
- rh_d2
);
627 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
628 xd2
, yd2
, rw_d2
, rh_d2
, 90 * 64, 90 * 64);
629 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
630 xd2
+ wd2
- rw_d2
, yd2
,
631 // rw_d2, rh_d2, 0, 90 * 64);
632 rw_d2
, rh_d2
, 0, 91 * 64);
633 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
636 // rw_d2, rh_d2, 270 * 64, 90 * 64);
637 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
638 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
639 xd2
, yd2
+ hd2
- rh_d2
,
640 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
644 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
647 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
648 xd
+ wd
- rd
+ 1, yd
);
649 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
+ hd
,
650 xd
+ wd
- rd
, yd
+ hd
);
652 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
654 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
, yd
+ rd
,
655 xd
+ wd
, yd
+ hd
- rd
+ 1);
656 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
657 rw_d
, rh_d
, 90 * 64, 90 * 64);
658 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
659 // rw_d, rh_d, 0, 90 * 64);
660 rw_d
, rh_d
, 0, 91 * 64);
661 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
663 rw_d
, rh_d
, 269 * 64, 92 * 64);
664 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
665 rw_d
, rh_d
, 180 * 64, 90 * 64);
667 if (m_window
&& m_window
->GetBackingPixmap())
669 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
671 xd2
+ wd2
- rd2
+ 1, yd2
);
672 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
673 xd2
+ rd2
, yd2
+ hd2
,
674 xd2
+ wd2
- rd2
, yd2
+ hd2
);
676 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
678 xd2
, yd2
+ hd2
- rd2
);
679 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
680 xd2
+ wd2
, yd2
+ rd2
,
681 xd2
+ wd2
, yd2
+ hd2
- rd2
+ 1);
682 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
684 rw_d2
, rh_d2
, 90 * 64, 90 * 64);
685 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
686 xd2
+ wd2
- rw_d2
, yd2
,
687 // rw_d2, rh_d2, 0, 90 * 64);
688 rw_d2
, rh_d2
, 0, 91 * 64);
689 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
692 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
693 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
694 xd2
, yd2
+ hd2
- rh_d2
,
695 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
698 CalcBoundingBox (x
, y
);
699 CalcBoundingBox (x
+ width
, y
+ height
);
704 void wxWindowDC::DrawEllipse( long x
, long y
, long width
, long height
)
708 // Check for negative width and height
721 // FreeGetPixelCache();
723 static const int angle
= 23040;
729 wd
= XLOG2DEVREL(width
) ;
730 hd
= YLOG2DEVREL(height
) ;
732 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
735 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
736 if (m_window
&& m_window
->GetBackingPixmap())
737 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
738 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
739 XLOG2DEVREL (width
) - WX_GC_CF
,
740 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
743 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
747 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
748 if (m_window
&& m_window
->GetBackingPixmap())
749 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
750 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
751 XLOG2DEVREL (width
) - WX_GC_CF
,
752 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
754 CalcBoundingBox (x
, y
);
755 CalcBoundingBox (x
+ width
, y
+ height
);
759 bool wxWindowDC::CanDrawBitmap(void) const
764 /* Used when copying between drawables on different (Display*) m_displays.
765 Not very fast, but better than giving up.
768 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
769 Drawable src
, Drawable dest
,
772 unsigned int w
, unsigned int h
,
773 int destx
, int desty
,
774 bool more
, XImage
**cache
)
776 XImage
*image
, *destimage
;
777 Colormap destcm
, srccm
;
778 #define CACHE_SIZE 256
780 unsigned long cachesrc
[CACHE_SIZE
], cachedest
[CACHE_SIZE
];
781 int k
, cache_pos
, all_cache
;
783 if (!cache
|| !*cache
)
784 image
= XGetImage(src_display
, src
, srcx
, srcy
, w
, h
, AllPlanes
, ZPixmap
);
788 destimage
= XGetImage(dest_display
, dest
, destx
, desty
, w
, h
, AllPlanes
, ZPixmap
);
790 srccm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) src_display
);
791 destcm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dest_display
);
796 for (i
= 0; i
< w
; i
++)
797 for (j
= 0; j
< h
; j
++) {
801 pixel
= XGetPixel(image
, i
, j
);
802 for (k
= cache_pos
; k
--; )
803 if (cachesrc
[k
] == pixel
) {
804 pixel
= cachedest
[k
];
808 for (k
= CACHE_SIZE
; k
-- > cache_pos
; )
809 if (cachesrc
[k
] == pixel
) {
810 pixel
= cachedest
[k
];
814 cachesrc
[cache_pos
] = xcol
.pixel
= pixel
;
815 XQueryColor(src_display
, srccm
, &xcol
);
816 if (!XAllocColor(dest_display
, destcm
, &xcol
))
818 cachedest
[cache_pos
] = pixel
= xcol
.pixel
;
820 if (++cache_pos
>= CACHE_SIZE
) {
826 XPutPixel(destimage
, i
, j
, pixel
);
829 XPutImage(dest_display
, dest
, destgc
, destimage
, 0, 0, destx
, desty
, w
, h
);
830 XDestroyImage(destimage
);
835 XDestroyImage(image
);
838 void wxWindowDC::DrawIcon( const wxIcon
&icon
, long x
, long y
, bool useMask
)
842 if (!icon
.Ok()) return;
844 // FreeGetPixelCache();
846 // Be sure that foreground pixels (1) of
847 // the Icon will be painted with pen colour. [m_pen.SetColour()]
848 // Background pixels (0) will be painted with
849 // last selected background color. [::SetBackground]
850 if (m_pen
.Ok() && m_autoSetting
)
854 Pixmap iconPixmap
= (Pixmap
) icon
.GetPixmap();
855 width
= icon
.GetWidth();
856 height
= icon
.GetHeight();
857 if (icon
.GetDisplay() == m_display
)
859 if (icon
.GetDepth() <= 1)
861 XCopyPlane ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
863 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
), 1);
867 XCopyArea ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
869 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
));
873 if (m_window
&& m_window
->GetBackingPixmap())
875 if (icon
.GetDepth() <= 1)
877 XCopyPlane ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
878 0, 0, width
, height
, (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
), 1);
882 XCopyArea ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
884 (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
));
887 } else { /* Remote copy (different (Display*) m_displays) */
888 XImage
*cache
= NULL
;
889 if (m_window
&& m_window
->GetBackingPixmap())
890 XCopyRemote((Display
*) icon
.GetDisplay(), (Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
891 (GC
) m_gcBacking
, 0, 0, width
, height
,
892 (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
), TRUE
, &cache
);
893 XCopyRemote((Display
*) icon
.GetDisplay(), (Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
895 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
), FALSE
, &cache
);
897 CalcBoundingBox (x
, y
);
901 bool wxWindowDC::Blit( long xdest
, long ydest
, long width
, long height
,
902 wxDC
*source
, long xsrc
, long ysrc
, int rop
, bool useMask
)
904 if (!Ok()) return FALSE
;
906 wxASSERT_MSG( (source
->IsKindOf(CLASSINFO(wxWindowDC
))), "Blit source DC must be wxWindowDC or derived class." );
908 wxWindowDC
* sourceDC
= (wxWindowDC
*) source
;
910 // FreeGetPixelCache();
912 // Be sure that foreground pixels (1) of
913 // the Icon will be painted with pen colour. [m_pen.SetColour()]
914 // Background pixels (0) will be painted with
915 // last selected background color. [::SetBackground]
916 if (m_pen
.Ok() && m_autoSetting
)
919 if (m_pixmap
&& sourceDC
->m_pixmap
)
922 int orig
= m_logicalFunction
;
924 SetLogicalFunction (rop
);
926 if (m_display
!= sourceDC
->m_display
)
928 XImage
*cache
= NULL
;
930 if (m_window
&& m_window
->GetBackingPixmap())
931 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
,
932 (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
934 source
->LogicalToDeviceX (xsrc
),
935 source
->LogicalToDeviceY (ysrc
),
936 source
->LogicalToDeviceXRel(width
),
937 source
->LogicalToDeviceYRel(height
),
938 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
),
941 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
943 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
944 wxBitmap
& sel
= memDC
->GetBitmap();
945 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetPixmap() )
947 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetPixmap());
948 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
952 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
953 source
->LogicalToDeviceX (xsrc
),
954 source
->LogicalToDeviceY (ysrc
),
955 source
->LogicalToDeviceXRel(width
),
956 source
->LogicalToDeviceYRel(height
),
957 XLOG2DEV (xdest
), YLOG2DEV (ydest
),
962 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
963 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
968 if (m_window
&& m_window
->GetBackingPixmap())
970 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1
971 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetBitmap().GetDepth() == 1)
973 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
974 source
->LogicalToDeviceX (xsrc
),
975 source
->LogicalToDeviceY (ysrc
),
976 source
->LogicalToDeviceXRel(width
),
977 source
->LogicalToDeviceYRel(height
),
978 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 1);
982 XCopyArea ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
983 source
->LogicalToDeviceX (xsrc
),
984 source
->LogicalToDeviceY (ysrc
),
985 source
->LogicalToDeviceXRel(width
),
986 source
->LogicalToDeviceYRel(height
),
987 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
));
990 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
992 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
993 wxBitmap
& sel
= memDC
->GetBitmap();
994 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetPixmap() )
996 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetPixmap());
997 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
1001 // Check if we're copying from a mono bitmap
1002 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) &&
1003 ((wxMemoryDC
*)source
)->GetBitmap().Ok() && (((wxMemoryDC
*)source
)->GetBitmap().GetDepth () == 1))
1005 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1006 source
->LogicalToDeviceX (xsrc
),
1007 source
->LogicalToDeviceY (ysrc
),
1008 source
->LogicalToDeviceXRel(width
),
1009 source
->LogicalToDeviceYRel(height
),
1010 XLOG2DEV (xdest
), YLOG2DEV (ydest
), 1);
1014 XCopyArea ((Display
*) m_display
, (Pixmap
) sourceDC
->m_pixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1015 source
->LogicalToDeviceX (xsrc
),
1016 source
->LogicalToDeviceY (ysrc
),
1017 source
->LogicalToDeviceXRel(width
),
1018 source
->LogicalToDeviceYRel(height
),
1019 XLOG2DEV (xdest
), YLOG2DEV (ydest
));
1024 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
1025 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
1028 } /* Remote/local (Display*) m_display */
1029 CalcBoundingBox (xdest
, ydest
);
1030 CalcBoundingBox (xdest
+ width
, ydest
+ height
);
1032 SetLogicalFunction(orig
);
1039 /* Helper function for 16-bit fonts */
1040 static int str16len(const char *s
)
1044 while (s
[0] && s
[1]) {
1052 void wxWindowDC::DrawText( const wxString
&text
, long x
, long y
, bool use16
)
1056 // Since X draws from the baseline of the text, must
1057 // add the text height
1064 slen
= str16len(text
);
1066 slen
= strlen(text
);
1070 WXFontStructPtr pFontStruct
= m_font
.FindOrCreateFontStruct(m_userScaleY
*m_logicalScaleY
);
1071 int direction
, descent
;
1072 XCharStruct overall_return
;
1074 (void)XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*)(const char*) text
, slen
, &direction
,
1075 &ascent
, &descent
, &overall_return
);
1077 (void)XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) text
, slen
, &direction
,
1078 &ascent
, &descent
, &overall_return
);
1079 cx
= overall_return
.width
;
1080 cy
= ascent
+ descent
;
1083 // First draw a rectangle representing the text background,
1084 // if a text background is specified
1085 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1087 wxColour oldPenColour
= m_currentColour
;
1088 m_currentColour
= m_textBackgroundColour
;
1089 bool sameColour
= (oldPenColour
.Ok () && m_textBackgroundColour
.Ok () &&
1090 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1091 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1092 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1094 // This separation of the big && test required for gcc2.7/HP UX 9.02
1095 // or pixel value can be corrupted!
1096 sameColour
= (sameColour
&&
1097 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1099 if (!sameColour
|| !GetOptimization())
1101 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1102 m_currentColour
= m_textBackgroundColour
;
1104 // Set the GC to the required colour
1107 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1108 if (m_window
&& m_window
->GetBackingPixmap())
1109 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1113 m_textBackgroundColour
= oldPenColour
;
1115 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1116 if (m_window
&& m_window
->GetBackingPixmap())
1117 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1118 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1121 // Now set the text foreground and draw the text
1122 if (m_textForegroundColour
.Ok ())
1124 wxColour oldPenColour
= m_currentColour
;
1125 m_currentColour
= m_textForegroundColour
;
1126 bool sameColour
= (oldPenColour
.Ok () && m_currentColour
.Ok () &&
1127 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1128 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1129 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1130 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1132 if (!sameColour
|| !GetOptimization())
1135 if (!m_colour
) // Mono display
1137 // Unless foreground is really white, draw it in black
1138 unsigned char red
= m_textForegroundColour
.Red ();
1139 unsigned char blue
= m_textForegroundColour
.Blue ();
1140 unsigned char green
= m_textForegroundColour
.Green ();
1141 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1142 && green
== (unsigned char) 255)
1144 m_currentColour
= *wxWHITE
;
1145 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1146 m_currentColour
.SetPixel(pixel
);
1147 m_textForegroundColour
.SetPixel(pixel
);
1151 m_currentColour
= *wxBLACK
;
1152 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1153 m_currentColour
.SetPixel(pixel
);
1154 m_textForegroundColour
.SetPixel(pixel
);
1159 pixel
= m_textForegroundColour
.AllocColour((Display
*) m_display
);
1160 m_currentColour
.SetPixel(pixel
);
1163 // Set the GC to the required colour
1166 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1167 if (m_window
&& m_window
->GetBackingPixmap())
1168 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1172 m_textForegroundColour
= oldPenColour
;
1175 // We need to add the ascent, not the whole height, since X draws
1176 // at the point above the descender.
1178 XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1179 (XChar2b
*)(char*) (const char*) text
, slen
);
1181 XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1184 if (m_window
&& m_window
->GetBackingPixmap()) {
1186 XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1187 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1188 (XChar2b
*)(char*) (const char*) text
, slen
);
1190 XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1191 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
, (char*) (const char*) text
, slen
);
1195 GetTextExtent (text
, &w
, &h
);
1196 CalcBoundingBox (x
+ w
, y
+ h
);
1197 CalcBoundingBox (x
, y
);
1200 bool wxWindowDC::CanGetTextExtent(void) const
1205 void wxWindowDC::GetTextExtent( const wxString
&string
, long *width
, long *height
,
1206 long *descent
, long *externalLeading
,
1207 wxFont
*font
, bool use16
)
1211 wxFont
* theFont
= font
;
1217 // TODO: this should be an error log function
1218 cerr
<< "wxWindows warning - set a valid font before calling GetTextExtent!\n";
1224 WXFontStructPtr pFontStruct
= theFont
->FindOrCreateFontStruct(m_userScaleY
*m_logicalScaleY
);
1226 int direction
, ascent
, descent2
;
1227 XCharStruct overall
;
1230 if (use16
) slen
= str16len(string
); else slen
= strlen(string
);
1233 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1234 &ascent
, &descent2
, &overall
);
1236 XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) string
, slen
, &direction
,
1237 &ascent
, &descent2
, &overall
);
1239 *width
= XDEV2LOGREL (overall
.width
);
1240 *height
= YDEV2LOGREL (ascent
+ descent2
);
1242 *descent
= descent2
;
1243 if (externalLeading
)
1244 *externalLeading
= 0;
1247 long wxWindowDC::GetCharWidth(void)
1249 if (!Ok()) return 0;
1254 WXFontStructPtr pFontStruct
= m_font
.FindOrCreateFontStruct(m_userScaleY
* m_logicalScaleY
);
1256 int direction
, ascent
, descent
;
1257 XCharStruct overall
;
1258 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1259 &descent
, &overall
);
1260 return XDEV2LOGREL(overall
.width
);
1263 long wxWindowDC::GetCharHeight(void)
1265 if (!Ok()) return 0;
1270 WXFontStructPtr pFontStruct
= m_font
.FindOrCreateFontStruct(m_userScaleY
*m_logicalScaleY
);
1272 int direction
, ascent
, descent
;
1273 XCharStruct overall
;
1274 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1275 &descent
, &overall
);
1276 // return XDEV2LOGREL(overall.ascent + overall.descent);
1277 return XDEV2LOGREL(ascent
+ descent
);
1280 void wxWindowDC::Clear(void)
1287 // TODO: should we get the virtual size?
1288 m_window
->GetSize(&w
, &h
);
1290 if (m_window
&& m_window
->GetBackingPixmap())
1292 w
= m_window
->GetPixmapWidth();
1293 h
= m_window
->GetPixmapHeight();
1298 if (this->IsKindOf(CLASSINFO(wxMemoryDC
)))
1300 wxMemoryDC
* memDC
= (wxMemoryDC
*) this;
1301 w
= memDC
->GetBitmap().GetWidth();
1302 h
= memDC
->GetBitmap().GetHeight();
1308 wxBrush saveBrush
= m_brush
;
1309 SetBrush (m_backgroundBrush
);
1311 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, 0, w
, h
);
1313 if (m_window
&& m_window
->GetBackingPixmap())
1314 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 0, 0, w
, h
);
1316 m_brush
= saveBrush
;
1319 void wxWindowDC::SetFont( const wxFont
&font
)
1328 WXFontStructPtr pFontStruct
= m_font
.FindOrCreateFontStruct(m_userScaleY
*m_logicalScaleY
);
1330 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1331 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1333 if (m_window
&& m_window
->GetBackingPixmap())
1334 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1337 void wxWindowDC::SetPen( const wxPen
&pen
)
1345 wxBitmap oldStipple
= m_currentStipple
;
1346 int oldStyle
= m_currentStyle
;
1347 int oldFill
= m_currentFill
;
1348 int old_pen_width
= m_currentPenWidth
;
1349 int old_pen_join
= m_currentPenJoin
;
1350 int old_pen_cap
= m_currentPenCap
;
1351 int old_pen_nb_dash
= m_currentPenDashCount
;
1352 char *old_pen_dash
= m_currentPenDash
;
1354 wxColour oldPenColour
= m_currentColour
;
1355 m_currentColour
= m_pen
.GetColour ();
1356 m_currentStyle
= m_pen
.GetStyle ();
1357 m_currentFill
= m_pen
.GetStyle (); // TODO?
1358 m_currentPenWidth
= m_pen
.GetWidth ();
1359 m_currentPenJoin
= m_pen
.GetJoin ();
1360 m_currentPenCap
= m_pen
.GetCap ();
1361 m_currentPenDashCount
= m_pen
.GetDashCount();
1362 m_currentPenDash
= m_pen
.GetDash();
1364 if (m_currentStyle
== wxSTIPPLE
)
1365 m_currentStipple
= m_pen
.GetStipple ();
1367 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1368 oldFill
== m_currentFill
&&
1369 old_pen_join
== m_currentPenJoin
&&
1370 old_pen_cap
== m_currentPenCap
&&
1371 old_pen_nb_dash
== m_currentPenDashCount
&&
1372 old_pen_dash
== m_currentPenDash
&&
1373 old_pen_width
== m_currentPenWidth
);
1375 bool sameColour
= (oldPenColour
.Ok () &&
1376 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1377 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1378 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1379 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1381 if (!sameStyle
|| !GetOptimization())
1383 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1384 if (scaled_width
< 0)
1390 static char dotted
[] =
1392 static char short_dashed
[] =
1394 static char long_dashed
[] =
1396 static char dotted_dashed
[] =
1399 // We express dash pattern in pen width unit, so we are
1400 // independent of zoom factor and so on...
1404 switch (m_pen
.GetStyle ())
1407 req_nb_dash
= m_currentPenDashCount
;
1408 req_dash
= m_currentPenDash
;
1409 style
= LineOnOffDash
;
1414 style
= LineOnOffDash
;
1418 req_dash
= short_dashed
;
1419 style
= LineOnOffDash
;
1423 req_dash
= long_dashed
;
1424 style
= LineOnOffDash
;
1428 req_dash
= dotted_dashed
;
1429 style
= LineOnOffDash
;
1440 if (req_dash
&& req_nb_dash
)
1442 char *real_req_dash
= new char[req_nb_dash
];
1445 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1446 for (int i
= 0; i
< req_nb_dash
; i
++)
1447 real_req_dash
[i
] = req_dash
[i
] * factor
;
1448 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1450 if (m_window
&& m_window
->GetBackingPixmap())
1451 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1452 delete[]real_req_dash
;
1456 // No Memory. We use non-scaled dash pattern...
1457 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1459 if (m_window
&& m_window
->GetBackingPixmap())
1460 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1464 switch (m_pen
.GetCap ())
1466 case wxCAP_PROJECTING
:
1467 cap
= CapProjecting
;
1478 switch (m_pen
.GetJoin ())
1492 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1494 if (m_window
&& m_window
->GetBackingPixmap())
1495 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1498 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1502 oldStipple
= NULL
; // For later reset!!
1504 switch (m_currentFill
)
1506 case wxBDIAGONAL_HATCH
:
1507 if (bdiag
== (Pixmap
) 0)
1508 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1509 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1510 bdiag_bits
, bdiag_width
, bdiag_height
);
1513 case wxFDIAGONAL_HATCH
:
1514 if (fdiag
== (Pixmap
) 0)
1515 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1516 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1517 fdiag_bits
, fdiag_width
, fdiag_height
);
1521 if (cross
== (Pixmap
) 0)
1522 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1523 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1524 cross_bits
, cross_width
, cross_height
);
1527 case wxHORIZONTAL_HATCH
:
1528 if (horiz
== (Pixmap
) 0)
1529 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1530 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1531 horiz_bits
, horiz_width
, horiz_height
);
1534 case wxVERTICAL_HATCH
:
1535 if (verti
== (Pixmap
) 0)
1536 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1537 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1538 verti_bits
, verti_width
, verti_height
);
1541 case wxCROSSDIAG_HATCH
:
1543 if (cdiag
== (Pixmap
) 0)
1544 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1545 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1546 cdiag_bits
, cdiag_width
, cdiag_height
);
1550 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1552 if (m_window
&& m_window
->GetBackingPixmap())
1553 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1555 else if (m_currentStipple
.Ok()
1556 && ((m_currentStipple
!= oldStipple
) || !GetOptimization()))
1558 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1560 if (m_window
&& m_window
->GetBackingPixmap())
1561 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1564 if ((m_currentFill
!= oldFill
) || !GetOptimization())
1568 if (m_currentFill
== wxSTIPPLE
)
1569 fill_style
= FillStippled
;
1570 else if (IS_HATCH (m_currentFill
))
1571 fill_style
= FillStippled
;
1573 fill_style
= FillSolid
;
1574 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1575 if (m_window
&& m_window
->GetBackingPixmap())
1576 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1579 // must test m_logicalFunction, because it involves background!
1580 if (!sameColour
|| !GetOptimization()
1581 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1584 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1585 pixel
= m_backgroundPixel
;
1588 unsigned char red
= m_pen
.GetColour ().Red ();
1589 unsigned char blue
= m_pen
.GetColour ().Blue ();
1590 unsigned char green
= m_pen
.GetColour ().Green ();
1591 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1592 && green
== (unsigned char) 255)
1594 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1595 m_currentColour
= *wxWHITE
;
1596 m_pen
.GetColour().SetPixel(pixel
);
1597 m_currentColour
.SetPixel(pixel
);
1601 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1602 m_currentColour
= *wxBLACK
;
1603 m_pen
.GetColour().SetPixel(pixel
);
1608 pixel
= m_pen
.GetColour ().AllocColour(m_display
);
1609 m_currentColour
.SetPixel(pixel
);
1612 // Finally, set the GC to the required colour
1615 if (m_logicalFunction
== wxXOR
)
1618 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1619 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1620 if (m_window
&& m_window
->GetBackingPixmap())
1621 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1625 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1626 if (m_window
&& m_window
->GetBackingPixmap())
1627 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1632 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1637 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1643 if (!m_brush
.Ok() || m_brush
.GetStyle () == wxTRANSPARENT
)
1646 int oldFill
= m_currentFill
;
1647 wxBitmap oldStipple
= m_currentStipple
;
1649 m_autoSetting
|= 0x1;
1651 m_currentFill
= m_brush
.GetStyle ();
1652 if (m_currentFill
== wxSTIPPLE
)
1653 m_currentStipple
= m_brush
.GetStipple ();
1655 wxColour
oldBrushColour(m_currentColour
);
1656 m_currentColour
= m_brush
.GetColour ();
1658 bool sameColour
= (oldBrushColour
.Ok () &&
1659 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1660 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1661 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1662 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1664 if ((oldFill
!= m_brush
.GetStyle ()) || !GetOptimization())
1666 switch (brush
.GetStyle ())
1670 case wxBDIAGONAL_HATCH
:
1671 case wxCROSSDIAG_HATCH
:
1672 case wxFDIAGONAL_HATCH
:
1674 case wxHORIZONTAL_HATCH
:
1675 case wxVERTICAL_HATCH
:
1678 // Chris Breeze 23/07/97: use background mode to determine whether
1679 // fill style should be solid or transparent
1680 int style
= (m_backgroundMode
== wxSOLID
? FillOpaqueStippled
: FillStippled
);
1681 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1682 if (m_window
&& m_window
->GetBackingPixmap())
1683 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1688 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1689 if (m_window
&& m_window
->GetBackingPixmap())
1690 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, FillSolid
);
1694 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1698 switch (m_currentFill
)
1700 case wxBDIAGONAL_HATCH
:
1701 if (bdiag
== (Pixmap
) 0)
1702 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1703 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1704 bdiag_bits
, bdiag_width
, bdiag_height
);
1707 case wxFDIAGONAL_HATCH
:
1708 if (fdiag
== (Pixmap
) 0)
1709 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1710 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1711 fdiag_bits
, fdiag_width
, fdiag_height
);
1715 if (cross
== (Pixmap
) 0)
1716 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1717 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1718 cross_bits
, cross_width
, cross_height
);
1721 case wxHORIZONTAL_HATCH
:
1722 if (horiz
== (Pixmap
) 0)
1723 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1724 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1725 horiz_bits
, horiz_width
, horiz_height
);
1728 case wxVERTICAL_HATCH
:
1729 if (verti
== (Pixmap
) 0)
1730 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1731 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1732 verti_bits
, verti_width
, verti_height
);
1735 case wxCROSSDIAG_HATCH
:
1737 if (cdiag
== (Pixmap
) 0)
1738 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1739 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1740 cdiag_bits
, cdiag_width
, cdiag_height
);
1744 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1746 if (m_window
&& m_window
->GetBackingPixmap())
1747 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1749 // X can forget the stipple value when resizing a window (apparently)
1750 // so always set the stipple.
1751 else if (m_currentStipple
.Ok()) // && m_currentStipple != oldStipple)
1753 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1754 if (m_window
&& m_window
->GetBackingPixmap())
1755 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1758 // must test m_logicalFunction, because it involves background!
1759 if (!sameColour
|| !GetOptimization() || m_logicalFunction
== wxXOR
)
1764 // Policy - on a monochrome screen, all brushes are white,
1765 // except when they're REALLY black!!!
1766 unsigned char red
= m_brush
.GetColour ().Red ();
1767 unsigned char blue
= m_brush
.GetColour ().Blue ();
1768 unsigned char green
= m_brush
.GetColour ().Green ();
1770 if (red
== (unsigned char) 0 && blue
== (unsigned char) 0
1771 && green
== (unsigned char) 0)
1773 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1774 m_currentColour
= *wxBLACK
;
1775 m_brush
.GetColour().SetPixel(pixel
);
1776 m_currentColour
.SetPixel(pixel
);
1780 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1781 m_currentColour
= *wxWHITE
;
1782 m_brush
.GetColour().SetPixel(pixel
);
1783 m_currentColour
.SetPixel(pixel
);
1786 // N.B. comment out the above line and uncomment the following lines
1787 // if you want non-white colours to be black on a monochrome display.
1789 if (red == (unsigned char )255 && blue == (unsigned char)255
1790 && green == (unsigned char)255)
1791 pixel = (int)WhitePixel((Display*) m_display, DefaultScreen((Display*) m_display));
1793 pixel = (int)BlackPixel((Display*) m_display, DefaultScreen((Display*) m_display));
1796 else if (m_brush
.GetStyle () != wxTRANSPARENT
)
1798 pixel
= m_brush
.GetColour().AllocColour(m_display
);
1799 m_currentColour
.SetPixel(pixel
);
1803 // Finally, set the GC to the required colour
1804 if (m_logicalFunction
== wxXOR
)
1807 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1808 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1809 if (m_window
&& m_window
->GetBackingPixmap())
1810 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1814 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1815 if (m_window
&& m_window
->GetBackingPixmap())
1816 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1821 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1824 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1828 m_backgroundBrush
= brush
;
1830 if (!m_backgroundBrush
.Ok())
1833 int pixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
1835 XSetWindowBackground ((Display
*) m_display
, (Pixmap
) m_pixmap
, pixel
);
1837 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
1838 // And Blit,... (Any fct that use XCopyPlane, in fact.)
1839 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1840 if (m_window
&& m_window
->GetBackingPixmap())
1841 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1844 void wxWindowDC::SetLogicalFunction( int function
)
1849 if (m_logicalFunction
== function
)
1855 x_function
= GXclear
;
1861 x_function
= GXinvert
;
1864 x_function
= GXorReverse
;
1867 x_function
= GXandReverse
;
1876 x_function
= GXandInverted
;
1879 x_function
= GXnoop
;
1885 x_function
= GXequiv
;
1888 x_function
= GXcopyInverted
;
1891 x_function
= GXorInverted
;
1894 x_function
= GXnand
;
1901 x_function
= GXcopy
;
1905 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
1906 if (m_window
&& m_window
->GetBackingPixmap())
1907 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
1909 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
1910 /* MATTHEW: [9] Need to redo pen simply */
1911 m_autoSetting
|= 0x2;
1913 m_logicalFunction
= function
;
1917 void wxWindowDC::SetTextForeground( const wxColour
&col
)
1921 if (m_textForegroundColour
== col
) return;
1923 m_textForegroundColour
= col
;
1927 void wxWindowDC::SetTextBackground( const wxColour
&col
)
1931 if (m_textBackgroundColour
== col
) return;
1933 m_textBackgroundColour
= col
;
1934 if (!m_textBackgroundColour
.Ok()) return;
1937 void wxWindowDC::SetBackgroundMode( int mode
)
1939 m_backgroundMode
= mode
;
1943 void wxWindowDC::SetPalette( const wxPalette
& palette
)
1948 /* Use GetXColormap */
1949 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1950 (Colormap
) palette
.GetXColormap());
1952 /* Use wxGetMainColormap */
1953 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
1954 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
1959 void wxWindowDC:: SetDCClipping ()
1961 // m_userRegion is the region set by calling SetClippingRegion
1963 if (m_currentRegion
)
1964 XDestroyRegion ((Region
) m_currentRegion
);
1966 // We need to take into account
1967 // clipping imposed on a window by a repaint.
1968 // We'll combine it with the user region. But for now,
1969 // just use the currently-defined user clipping region.
1970 if (m_userRegion
|| (m_window
&& m_window
->GetPaintRegion()) )
1971 m_currentRegion
= (WXRegion
) XCreateRegion ();
1973 m_currentRegion
= (WXRegion
) NULL
;
1975 if ((m_window
&& m_window
->GetPaintRegion()) && m_userRegion
)
1976 XIntersectRegion ((Region
) m_window
->GetPaintRegion(), (Region
) m_userRegion
, (Region
) m_currentRegion
);
1977 else if (m_userRegion
)
1978 XIntersectRegion ((Region
) m_userRegion
, (Region
) m_userRegion
, (Region
) m_currentRegion
);
1979 else if (m_window
&& m_window
->GetPaintRegion())
1980 XIntersectRegion ((Region
) m_window
->GetPaintRegion(), (Region
) m_window
->GetPaintRegion(),
1981 (Region
) m_currentRegion
);
1983 if (m_currentRegion
)
1985 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) m_currentRegion
);
1989 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
1994 void wxWindowDC::SetClippingRegion( long x
, long y
, long width
, long height
)
1996 wxDC::SetClippingRegion( x
, y
, width
, height
);
1999 XDestroyRegion ((Region
) m_userRegion
);
2000 m_userRegion
= (WXRegion
) XCreateRegion ();
2004 r
.width
= XLOG2DEVREL(width
);
2005 r
.height
= YLOG2DEVREL(height
);
2006 XUnionRectWithRegion (&r
, (Region
) m_userRegion
, (Region
) m_userRegion
);
2010 // Needs to work differently for Pixmap: without this,
2011 // there's a nasty (Display*) m_display bug. 8/12/94
2012 if (m_window
&& m_window
->GetBackingPixmap())
2014 XRectangle rects
[1];
2015 rects
[0].x
= XLOG2DEV_2(x
);
2016 rects
[0].y
= YLOG2DEV_2(y
);
2017 rects
[0].width
= XLOG2DEVREL(width
);
2018 rects
[0].height
= YLOG2DEVREL(height
);
2019 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 0, 0, rects
, 1, Unsorted
);
2023 void wxWindowDC::DestroyClippingRegion(void)
2025 wxDC::DestroyClippingRegion();
2028 XDestroyRegion ((Region
) m_userRegion
);
2029 m_userRegion
= NULL
;
2034 gc_val
.clip_mask
= None
;
2035 if (m_window
&& m_window
->GetBackingPixmap())
2036 XChangeGC((Display
*) m_display
, (GC
) m_gcBacking
, GCClipMask
, &gc_val
);
2039 // ----------------------------------- spline code ----------------------------------------
2041 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
2042 double a3
, double b3
, double a4
, double b4
);
2043 void wx_clear_stack(void);
2044 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
2045 double *y3
, double *x4
, double *y4
);
2046 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
2047 double x4
, double y4
);
2048 static bool wx_spline_add_point(double x
, double y
);
2049 static void wx_spline_draw_point_array(wxDC
*dc
);
2051 wxList wx_spline_point_list
;
2053 #define half(z1, z2) ((z1+z2)/2.0)
2056 /* iterative version */
2058 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
2061 register double xmid
, ymid
;
2062 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
2065 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
2067 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
2068 xmid
= (double)half(x2
, x3
);
2069 ymid
= (double)half(y2
, y3
);
2070 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
2071 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
2072 wx_spline_add_point( x1
, y1
);
2073 wx_spline_add_point( xmid
, ymid
);
2075 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
2076 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
2077 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
2078 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
2083 /* utilities used by spline drawing routines */
2085 typedef struct wx_spline_stack_struct
{
2086 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
2089 #define SPLINE_STACK_DEPTH 20
2090 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
2091 static Stack
*wx_stack_top
;
2092 static int wx_stack_count
;
2094 void wx_clear_stack(void)
2096 wx_stack_top
= wx_spline_stack
;
2100 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
2102 wx_stack_top
->x1
= x1
;
2103 wx_stack_top
->y1
= y1
;
2104 wx_stack_top
->x2
= x2
;
2105 wx_stack_top
->y2
= y2
;
2106 wx_stack_top
->x3
= x3
;
2107 wx_stack_top
->y3
= y3
;
2108 wx_stack_top
->x4
= x4
;
2109 wx_stack_top
->y4
= y4
;
2114 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
2115 double *x3
, double *y3
, double *x4
, double *y4
)
2117 if (wx_stack_count
== 0)
2121 *x1
= wx_stack_top
->x1
;
2122 *y1
= wx_stack_top
->y1
;
2123 *x2
= wx_stack_top
->x2
;
2124 *y2
= wx_stack_top
->y2
;
2125 *x3
= wx_stack_top
->x3
;
2126 *y3
= wx_stack_top
->y3
;
2127 *x4
= wx_stack_top
->x4
;
2128 *y4
= wx_stack_top
->y4
;
2132 static bool wx_spline_add_point(double x
, double y
)
2134 wxPoint
*point
= new wxPoint
;
2137 wx_spline_point_list
.Append((wxObject
*)point
);
2141 static void wx_spline_draw_point_array(wxDC
*dc
)
2143 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
2144 wxNode
*node
= wx_spline_point_list
.First();
2147 wxPoint
*point
= (wxPoint
*)node
->Data();
2150 node
= wx_spline_point_list
.First();
2154 void wxWindowDC::DrawOpenSpline( wxList
*points
)
2157 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
2158 double x1
, y1
, x2
, y2
;
2160 wxNode
*node
= points
->First();
2161 p
= (wxPoint
*)node
->Data();
2166 node
= node
->Next();
2167 p
= (wxPoint
*)node
->Data();
2171 cx1
= (double)((x1
+ x2
) / 2);
2172 cy1
= (double)((y1
+ y2
) / 2);
2173 cx2
= (double)((cx1
+ x2
) / 2);
2174 cy2
= (double)((cy1
+ y2
) / 2);
2176 wx_spline_add_point(x1
, y1
);
2178 while ((node
= node
->Next()) != NULL
)
2180 p
= (wxPoint
*)node
->Data();
2185 cx4
= (double)(x1
+ x2
) / 2;
2186 cy4
= (double)(y1
+ y2
) / 2;
2187 cx3
= (double)(x1
+ cx4
) / 2;
2188 cy3
= (double)(y1
+ cy4
) / 2;
2190 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
2194 cx2
= (double)(cx1
+ x2
) / 2;
2195 cy2
= (double)(cy1
+ y2
) / 2;
2198 wx_spline_add_point( cx1
, cy1
);
2199 wx_spline_add_point( x2
, y2
);
2201 wx_spline_draw_point_array( this );