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 on
18 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 is used to
22 indicate that a brush was recently used, and SetPen must be called to
23 reinstall the current pen's parameters. If autoSetting includes 0x2, then the
24 pens color may need to be set based on XOR.
26 There is, unfortunately, some confusion between setting the current pen/brush
27 and actually installing the brush/pen parameters. Both functionalies are
28 perform by SetPen and SetBrush. C'est la vie.
31 // ============================================================================
33 // ============================================================================
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
40 #pragma implementation "dcclient.h"
43 #include "wx/dcclient.h"
44 #include "wx/dcmemory.h"
45 #include "wx/window.h"
53 #pragma message disable nosimpint
57 #pragma message enable nosimpint
60 #include "wx/motif/private.h"
63 #include <float.h> // for M_PI
73 static Pixmap bdiag
, cdiag
, fdiag
, cross
, horiz
, verti
;
75 // ----------------------------------------------------------------------------
77 // ----------------------------------------------------------------------------
79 // Fudge factor (VZ: what??)
82 // ----------------------------------------------------------------------------
84 // ----------------------------------------------------------------------------
86 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
87 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxWindowDC
)
88 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
90 // ----------------------------------------------------------------------------
92 // ----------------------------------------------------------------------------
94 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
95 Drawable src
, Drawable dest
,
98 unsigned int w
, unsigned int h
,
100 bool more
, XImage
**cache
);
102 // ============================================================================
104 // ============================================================================
107 * compare two doubles and return the larger rounded
110 static int roundmax(double a
, double b
)
112 return (int)((a
> b
? a
: b
) + 0.5);
116 * compare two doubles and return the smaller rounded
119 static int roundmin(double a
, double b
)
121 return (int)((a
< b
? a
: b
) - 0.5);
125 // ----------------------------------------------------------------------------
127 // ----------------------------------------------------------------------------
129 void wxWindowDC::Init()
132 m_gcBacking
= (WXGC
) 0;
134 m_backgroundPixel
= -1;
135 m_currentPenWidth
= 1;
136 m_currentPenJoin
= -1;
137 m_currentPenDashCount
= -1;
138 m_currentPenDash
= (wxX11Dash
*) NULL
;
141 m_colour
= wxColourDisplay();
142 m_display
= (WXDisplay
*) NULL
;
143 m_pixmap
= (WXPixmap
) 0;
145 m_oldFont
= (WXFont
) 0;
147 m_clipRegion
= (WXRegion
) 0;
150 wxWindowDC::wxWindowDC()
155 wxWindowDC::wxWindowDC( wxWindow
*window
)
157 wxASSERT_MSG( (window
!= (wxWindow
*) NULL
), "You must pass a valid wxWindow to wxWindowDC/wxClientDC/wxPaintDC constructor." );
162 m_font
= window
->GetFont();
165 m_display
= window
->GetXDisplay();
166 m_pixmap
= window
->GetXWindow();
167 Display
* display
= (Display
*) m_display
;
169 XSetWindowColormap (display
, (Pixmap
) m_pixmap
, (Colormap
) wxTheApp
->GetMainColormap(m_display
));
172 gcvalues
.foreground
= BlackPixel (display
, DefaultScreen (display
));
173 gcvalues
.background
= WhitePixel (display
, DefaultScreen (display
));
174 gcvalues
.graphics_exposures
= False
;
175 gcvalues
.subwindow_mode
= IncludeInferiors
;
176 gcvalues
.line_width
= 1;
177 m_gc
= (WXGC
) XCreateGC (display
, RootWindow (display
, DefaultScreen (display
)),
178 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
181 if (m_window
->GetBackingPixmap())
183 m_gcBacking
= (WXGC
) XCreateGC (display
, RootWindow (display
,
184 DefaultScreen (display
)),
185 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
189 m_backgroundPixel
= (int) gcvalues
.background
;
191 // Get the current Font so we can set it back later
193 XGetGCValues((Display
*) m_display
, (GC
) m_gc
, GCFont
, &valReturn
);
194 m_oldFont
= (WXFont
) valReturn
.font
;
196 SetBackground(wxBrush(m_window
->GetBackgroundColour(), wxSOLID
));
199 wxWindowDC::~wxWindowDC()
201 if (m_gc
&& (m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
203 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
205 if (m_window
&& m_window
->GetBackingPixmap())
206 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
210 XFreeGC ((Display
*) m_display
, (GC
) m_gc
);
214 XFreeGC ((Display
*) m_display
, (GC
) m_gcBacking
);
215 m_gcBacking
= (WXGC
) 0;
218 XDestroyRegion ((Region
) m_clipRegion
);
219 m_clipRegion
= (WXRegion
) 0;
222 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
223 const wxColour
& col
, int style
);
225 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
226 const wxColour
& col
, int style
)
228 return wxDoFloodFill(this, x
, y
, col
, style
);
231 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
233 // Generic (and therefore rather inefficient) method.
234 // Could be improved.
236 wxBitmap
bitmap(1, 1);
237 memdc
.SelectObject(bitmap
);
238 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
239 memdc
.SelectObject(wxNullBitmap
);
240 wxImage image
= bitmap
.ConvertToImage();
241 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
245 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
247 wxCHECK_RET( Ok(), "invalid dc" );
249 int x1d
, y1d
, x2d
, y2d
;
259 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x1d
, y1d
, x2d
, y2d
);
261 if (m_window
&& m_window
->GetBackingPixmap())
262 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
263 XLOG2DEV_2(x1
), YLOG2DEV_2(y1
),
264 XLOG2DEV_2(x2
), YLOG2DEV_2(y2
));
266 CalcBoundingBox(x1
, y1
);
267 CalcBoundingBox(x2
, y2
);
270 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
272 wxCHECK_RET( Ok(), "invalid dc" );
277 int xx
= XLOG2DEV (x
);
278 int yy
= YLOG2DEV (y
);
280 wxDisplaySize (&ww
, &hh
);
281 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, yy
,
283 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xx
, 0,
286 if (m_window
&& m_window
->GetBackingPixmap())
290 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
293 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
299 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
301 wxCHECK_RET( Ok(), "invalid dc" );
303 int xx1
= XLOG2DEV (x1
);
304 int yy1
= YLOG2DEV (y1
);
305 int xx2
= XLOG2DEV (x2
);
306 int yy2
= YLOG2DEV (y2
);
307 int xxc
= XLOG2DEV (xc
);
308 int yyc
= YLOG2DEV (yc
);
309 int xxc_2
= XLOG2DEV_2 (xc
);
310 int yyc_2
= YLOG2DEV_2 (yc
);
312 wxCoord dx
= xx1
- xxc
;
313 wxCoord dy
= yy1
- yyc
;
314 double radius
= sqrt ((double)(dx
* dx
+ dy
* dy
));
315 wxCoord r
= (wxCoord
) radius
;
317 double radius1
, radius2
;
319 if (xx1
== xx2
&& yy1
== yy2
)
324 else if (radius
== 0.0)
325 radius1
= radius2
= 0.0;
334 radius1
= -atan2 ((double) (yy1
- yyc
), (double) (xx1
- xxc
)) * 360.0 / (2 * M_PI
);
342 radius2
= -atan2 ((double) (yy2
- yyc
), (double) (xx2
- xxc
)) * 360.0 / (2 * M_PI
);
346 int alpha1
= (int) radius1
;
347 int alpha2
= (int) (radius2
- radius1
);
350 while (alpha2
> 360 * 64)
353 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
356 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) (GC
) m_gc
,
357 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
359 if (m_window
&& m_window
->GetBackingPixmap())
360 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
361 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
365 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
369 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
370 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
372 if (m_window
&& m_window
->GetBackingPixmap())
373 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
374 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
376 CalcBoundingBox (x1
, y1
);
377 CalcBoundingBox (x2
, y2
);
380 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
382 wxCHECK_RET( Ok(), "invalid dc" );
388 wd
= XLOG2DEVREL(width
);
389 hd
= YLOG2DEVREL(height
);
391 if (sa
>=360 || sa
<=-360) sa
=sa
-int(sa
/360)*360;
392 if (ea
>=360 || ea
<=-360) ea
=ea
-int(ea
/360)*360;
393 int start
= int(sa
*64);
394 int end
= int(ea
*64);
395 if (start
<0) start
+=360*64;
396 if (end
<0) end
+=360*64;
397 if (end
>start
) end
-=start
;
398 else end
+=360*64-start
;
400 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
402 m_autoSetting
= TRUE
; // must be reset
405 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
, end
);
407 if (m_window
&& m_window
->GetBackingPixmap())
408 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
409 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
412 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
416 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
,end
);
417 if (m_window
&& m_window
->GetBackingPixmap())
418 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
419 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
421 CalcBoundingBox (x
, y
);
422 CalcBoundingBox (x
+ width
, y
+ height
);
425 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
427 wxCHECK_RET( Ok(), "invalid dc" );
429 if (m_pen
.Ok() && m_autoSetting
)
432 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
));
433 if (m_window
&& m_window
->GetBackingPixmap())
434 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, XLOG2DEV_2 (x
), YLOG2DEV_2 (y
));
436 CalcBoundingBox (x
, y
);
439 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
441 wxCHECK_RET( Ok(), "invalid dc" );
443 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
448 XPoint
*xpoints
= new XPoint
[n
];
451 for (i
= 0; i
< n
; i
++)
453 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
454 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
456 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints
, n
, 0);
458 if (m_window
&& m_window
->GetBackingPixmap())
460 for (i
= 0; i
< n
; i
++)
462 xpoints
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
463 xpoints
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
465 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints
, n
, 0);
471 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
472 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
474 wxCHECK_RET( Ok(), "invalid dc" );
476 XPoint
*xpoints1
= new XPoint
[n
+ 1];
477 XPoint
*xpoints2
= new XPoint
[n
+ 1];
479 for (i
= 0; i
< n
; i
++)
481 xpoints1
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
482 xpoints1
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
483 xpoints2
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
484 xpoints2
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
485 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
488 // Close figure for XDrawLines (not needed for XFillPolygon)
489 xpoints1
[i
].x
= xpoints1
[0].x
;
490 xpoints1
[i
].y
= xpoints1
[0].y
;
491 xpoints2
[i
].x
= xpoints2
[0].x
;
492 xpoints2
[i
].y
= xpoints2
[0].y
;
494 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
497 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
498 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
, Complex
, 0);
499 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, EvenOddRule
); // default mode
500 if (m_window
&& m_window
->GetBackingPixmap())
502 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
,
503 fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
504 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
, Complex
, 0);
505 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
, EvenOddRule
); // default mode
509 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
513 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
+ 1, 0);
515 if (m_window
&& m_window
->GetBackingPixmap())
516 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
+ 1, 0);
523 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
525 wxCHECK_RET( Ok(), "invalid dc" );
527 int xd
, yd
, wfd
, hfd
, wd
, hd
;
531 wfd
= XLOG2DEVREL(width
);
533 hfd
= YLOG2DEVREL(height
);
536 if (wfd
== 0 || hfd
== 0) return;
537 if (wd
< 0) { wd
= - wd
; xd
= xd
- wd
; }
538 if (hd
< 0) { hd
= - hd
; yd
= yd
- hd
; }
540 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
543 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wfd
, hfd
);
545 if (m_window
&& m_window
->GetBackingPixmap())
546 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
547 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
551 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
555 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
);
557 if (m_window
&& m_window
->GetBackingPixmap())
558 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
559 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
562 CalcBoundingBox (x
, y
);
563 CalcBoundingBox (x
+ width
, y
+ height
);
566 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
568 wxCHECK_RET( Ok(), "invalid dc" );
570 // If radius is negative, it's a proportion of the smaller dimension.
572 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
574 int xd
= XLOG2DEV (x
);
575 int yd
= YLOG2DEV (y
);
576 int rd
= XLOG2DEVREL ((long) radius
);
577 int wd
= XLOG2DEVREL (width
) - WX_GC_CF
;
578 int hd
= YLOG2DEVREL (height
) - WX_GC_CF
;
583 // If radius is zero use DrawRectangle() instead to avoid
584 // X drawing errors with small radii
587 DrawRectangle( x
, y
, width
, height
);
591 // Draw nothing if transformed w or h is 0
592 if (wd
== 0 || hd
== 0) return;
594 // CMB: adjust size if outline is drawn otherwise the result is
595 // 1 pixel too wide and high
596 if (m_pen
.GetStyle() != wxTRANSPARENT
)
602 // CMB: ensure dd is not larger than rectangle otherwise we
603 // get an hour glass shape
604 if (rw_d
> wd
) rw_d
= wd
;
605 if (rw_d
> hd
) rw_d
= hd
;
608 // For backing pixmap
609 int xd2
= XLOG2DEV_2 (x
);
610 int yd2
= YLOG2DEV_2 (y
);
611 int rd2
= XLOG2DEVREL ((long) radius
);
612 int wd2
= XLOG2DEVREL (width
) ;
613 int hd2
= YLOG2DEVREL (height
) ;
618 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
622 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
624 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
627 // Arcs start from 3 o'clock, positive angles anticlockwise
629 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
630 rw_d
, rh_d
, 90 * 64, 90 * 64);
632 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
633 // rw_d, rh_d, 0, 90 * 64);
634 rw_d
, rh_d
, 0, 91 * 64);
636 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
638 // rw_d, rh_d, 270 * 64, 90 * 64);
639 rw_d
, rh_d
, 269 * 64, 92 * 64);
641 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
642 rw_d
, rh_d
, 180 * 64, 90 * 64);
644 if (m_window
&& m_window
->GetBackingPixmap())
646 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
647 xd2
+ rd2
, yd2
, wd2
- rw_d2
, hd2
);
648 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
649 xd2
, yd2
+ rd2
, wd2
, hd2
- rh_d2
);
651 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
652 xd2
, yd2
, rw_d2
, rh_d2
, 90 * 64, 90 * 64);
653 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
654 xd2
+ wd2
- rw_d2
, yd2
,
655 // rw_d2, rh_d2, 0, 90 * 64);
656 rw_d2
, rh_d2
, 0, 91 * 64);
657 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
660 // rw_d2, rh_d2, 270 * 64, 90 * 64);
661 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
662 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
663 xd2
, yd2
+ hd2
- rh_d2
,
664 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
668 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
671 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
672 xd
+ wd
- rd
+ 1, yd
);
673 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
+ hd
,
674 xd
+ wd
- rd
, yd
+ hd
);
676 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
678 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
, yd
+ rd
,
679 xd
+ wd
, yd
+ hd
- rd
+ 1);
680 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
681 rw_d
, rh_d
, 90 * 64, 90 * 64);
682 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
683 // rw_d, rh_d, 0, 90 * 64);
684 rw_d
, rh_d
, 0, 91 * 64);
685 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
687 rw_d
, rh_d
, 269 * 64, 92 * 64);
688 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
689 rw_d
, rh_d
, 180 * 64, 90 * 64);
691 if (m_window
&& m_window
->GetBackingPixmap())
693 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
695 xd2
+ wd2
- rd2
+ 1, yd2
);
696 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
697 xd2
+ rd2
, yd2
+ hd2
,
698 xd2
+ wd2
- rd2
, yd2
+ hd2
);
700 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
702 xd2
, yd2
+ hd2
- rd2
);
703 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
704 xd2
+ wd2
, yd2
+ rd2
,
705 xd2
+ wd2
, yd2
+ hd2
- rd2
+ 1);
706 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
708 rw_d2
, rh_d2
, 90 * 64, 90 * 64);
709 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
710 xd2
+ wd2
- rw_d2
, yd2
,
711 // rw_d2, rh_d2, 0, 90 * 64);
712 rw_d2
, rh_d2
, 0, 91 * 64);
713 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
716 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
717 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
718 xd2
, yd2
+ hd2
- rh_d2
,
719 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
722 CalcBoundingBox (x
, y
);
723 CalcBoundingBox (x
+ width
, y
+ height
);
726 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
728 wxCHECK_RET( Ok(), "invalid dc" );
730 // Check for negative width and height
743 static const int angle
= 23040;
749 wd
= XLOG2DEVREL(width
) ;
750 hd
= YLOG2DEVREL(height
) ;
752 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
755 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
756 if (m_window
&& m_window
->GetBackingPixmap())
757 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
758 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
759 XLOG2DEVREL (width
) - WX_GC_CF
,
760 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
763 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
767 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
768 if (m_window
&& m_window
->GetBackingPixmap())
769 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
770 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
771 XLOG2DEVREL (width
) - WX_GC_CF
,
772 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
774 CalcBoundingBox (x
, y
);
775 CalcBoundingBox (x
+ width
, y
+ height
);
779 bool wxWindowDC::CanDrawBitmap() const
781 wxCHECK_MSG( Ok(), FALSE
, "invalid dc" );
786 // TODO: use scaled Blit e.g. as per John Price's implementation
787 // in Contrib/Utilities
788 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
,
789 wxCoord width
, wxCoord height
,
790 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
,
791 int rop
, bool useMask
,
792 wxCoord xsrcMask
, wxCoord ysrcMask
)
794 wxCHECK_MSG( Ok(), FALSE
, "invalid dc" );
796 wxWindowDC
* sourceDC
= wxDynamicCast(source
, wxWindowDC
);
798 wxASSERT_MSG( sourceDC
, "Blit source DC must be wxWindowDC or derived class." );
800 // Be sure that foreground pixels (1) of the Icon will be painted with
801 // foreground colour. [m_textForegroundColour] Background pixels (0)
802 // will be painted with backgound colour (m_textBackgroundColour)
803 // Using ::SetPen is horribly slow, so avoid doing it
804 int oldBackgroundPixel
= -1;
805 int oldForegroundPixel
= -1;
807 if (m_textBackgroundColour
.Ok())
809 oldBackgroundPixel
= m_backgroundPixel
;
810 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
812 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
813 if (m_window
&& m_window
->GetBackingPixmap())
814 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
817 if (m_textForegroundColour
.Ok())
819 oldForegroundPixel
= m_currentColour
.GetPixel();
821 if( m_textForegroundColour
.GetPixel() <= -1 )
822 CalculatePixel( m_textForegroundColour
,
823 m_textForegroundColour
, TRUE
);
825 int pixel
= m_textForegroundColour
.GetPixel();
827 SetForegroundPixelWithLogicalFunction(pixel
);
830 // Do bitmap scaling if necessary
832 wxBitmap
*scaledBitmap
= (wxBitmap
*) NULL
;
833 Pixmap sourcePixmap
= (Pixmap
) NULL
;
834 double scaleX
, scaleY
;
835 GetUserScale(& scaleX
, & scaleY
);
838 /* TODO: use the mask origin when drawing transparently */
839 if (xsrcMask
== -1 && ysrcMask
== -1)
841 xsrcMask
= xsrc
; ysrcMask
= ysrc
;
844 // Sorry, can't scale masks just yet
845 if (!useMask
&& (scaleX
!= 1.0 || scaleY
!= 1.0) && sourceDC
->IsKindOf(CLASSINFO(wxMemoryDC
)))
847 wxMemoryDC
* memDC
= (wxMemoryDC
*) sourceDC
;
848 wxBitmap
& bitmap
= memDC
->GetBitmap();
850 wxASSERT_MSG( (bitmap
.Ok()), "Bad source bitmap in wxWindowDC::Blit");
852 wxImage image
= bitmap
.ConvertToImage();
855 sourcePixmap
= (Pixmap
) bitmap
.GetDrawable();
859 int scaledW
= (int) (bitmap
.GetWidth() * scaleX
);
860 int scaledH
= (int) (bitmap
.GetHeight() * scaleY
);
862 image
= image
.Scale(scaledW
, scaledH
);
863 scaledBitmap
= new wxBitmap(image
);
864 sourcePixmap
= (Pixmap
) scaledBitmap
->GetDrawable();
868 sourcePixmap
= (Pixmap
) sourceDC
->m_pixmap
;
870 if (m_pixmap
&& sourcePixmap
)
873 int orig
= m_logicalFunction
;
875 SetLogicalFunction (rop
);
877 if (m_display
!= sourceDC
->m_display
)
879 XImage
*cache
= NULL
;
881 if (m_window
&& m_window
->GetBackingPixmap())
882 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
,
883 (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
885 source
->LogicalToDeviceX (xsrc
),
886 source
->LogicalToDeviceY (ysrc
),
887 source
->LogicalToDeviceXRel(width
),
888 source
->LogicalToDeviceYRel(height
),
889 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
),
892 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
894 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
895 wxBitmap
& sel
= memDC
->GetBitmap();
896 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetBitmap() )
898 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap());
899 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
903 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
904 source
->LogicalToDeviceX (xsrc
),
905 source
->LogicalToDeviceY (ysrc
),
906 source
->LogicalToDeviceXRel(width
),
907 source
->LogicalToDeviceYRel(height
),
908 XLOG2DEV (xdest
), YLOG2DEV (ydest
),
914 XSetRegion ((Display
*) m_display
, (GC
) m_gc
,
915 (Region
) m_clipRegion
);
917 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
919 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
923 { //XGCValues values;
924 //XGetGCValues((Display*)m_display, (GC)m_gc, GCForeground, &values);
926 if (m_window
&& m_window
->GetBackingPixmap())
928 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1
929 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetBitmap().GetDepth() == 1)
931 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
932 source
->LogicalToDeviceX (xsrc
),
933 source
->LogicalToDeviceY (ysrc
),
934 source
->LogicalToDeviceXRel(width
),
935 source
->LogicalToDeviceYRel(height
),
936 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 1);
940 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
941 source
->LogicalToDeviceX (xsrc
),
942 source
->LogicalToDeviceY (ysrc
),
943 source
->LogicalToDeviceXRel(width
),
944 source
->LogicalToDeviceYRel(height
),
945 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
));
948 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
950 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
951 wxBitmap
& sel
= memDC
->GetBitmap();
952 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetBitmap() )
954 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap());
955 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
959 // Check if we're copying from a mono bitmap
960 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) &&
961 ((wxMemoryDC
*)source
)->GetBitmap().Ok() && (((wxMemoryDC
*)source
)->GetBitmap().GetDepth () == 1))
963 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
964 source
->LogicalToDeviceX (xsrc
),
965 source
->LogicalToDeviceY (ysrc
),
966 source
->LogicalToDeviceXRel(width
),
967 source
->LogicalToDeviceYRel(height
),
968 XLOG2DEV (xdest
), YLOG2DEV (ydest
), 1);
972 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
973 source
->LogicalToDeviceX (xsrc
),
974 source
->LogicalToDeviceY (ysrc
),
975 source
->LogicalToDeviceXRel(width
),
976 source
->LogicalToDeviceYRel(height
),
977 XLOG2DEV (xdest
), YLOG2DEV (ydest
));
983 XSetRegion ((Display
*) m_display
, (GC
) m_gc
,
984 (Region
) m_clipRegion
);
986 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
988 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
991 } /* Remote/local (Display*) m_display */
992 CalcBoundingBox (xdest
, ydest
);
993 CalcBoundingBox (xdest
+ width
, ydest
+ height
);
995 SetLogicalFunction(orig
);
999 if (scaledBitmap
) delete scaledBitmap
;
1001 if (oldBackgroundPixel
> -1)
1003 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
);
1004 if (m_window
&& m_window
->GetBackingPixmap())
1005 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1006 oldBackgroundPixel
);
1008 if (oldForegroundPixel
> -1)
1010 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
);
1011 if (m_window
&& m_window
->GetBackingPixmap())
1012 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1013 oldForegroundPixel
);
1019 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1021 wxCHECK_RET( Ok(), "invalid dc" );
1023 // Since X draws from the baseline of the text, must add the text height
1029 // Set FillStyle, otherwise X will use current stipple!
1030 XGCValues gcV
, gcBackingV
;
1032 XGetGCValues ((Display
*) m_display
, (GC
)m_gc
, GCFillStyle
, &gcV
);
1033 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1034 if (m_window
&& m_window
->GetBackingPixmap())
1036 XGetGCValues ((Display
*) m_display
, (GC
)m_gcBacking
, GCFillStyle
,
1038 XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
, FillSolid
);
1041 slen
= strlen(text
);
1045 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1046 int direction
, descent
;
1047 XCharStruct overall_return
;
1050 (void)XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*)(const char*) text
, slen
, &direction
,
1051 &ascent
, &descent
, &overall_return
);
1054 (void)XTextExtents((XFontStruct
*) pFontStruct
,
1055 wxConstCast(text
.c_str(), char),
1057 &ascent
, &descent
, &overall_return
);
1059 cx
= overall_return
.width
;
1060 cy
= ascent
+ descent
;
1063 // First draw a rectangle representing the text background, if a text
1064 // background is specified
1065 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1067 wxColour oldPenColour
= m_currentColour
;
1068 m_currentColour
= m_textBackgroundColour
;
1069 bool sameColour
= (oldPenColour
.Ok () && m_textBackgroundColour
.Ok () &&
1070 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1071 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1072 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1074 // This separation of the big && test required for gcc2.7/HP UX 9.02
1075 // or pixel value can be corrupted!
1076 sameColour
= (sameColour
&&
1077 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1079 if (!sameColour
|| !GetOptimization())
1081 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1082 m_currentColour
= m_textBackgroundColour
;
1084 // Set the GC to the required colour
1087 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1088 if (m_window
&& m_window
->GetBackingPixmap())
1089 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1093 m_textBackgroundColour
= oldPenColour
;
1095 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1096 if (m_window
&& m_window
->GetBackingPixmap())
1097 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1098 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1101 // Now set the text foreground and draw the text
1102 if (m_textForegroundColour
.Ok ())
1104 wxColour oldPenColour
= m_currentColour
;
1105 m_currentColour
= m_textForegroundColour
;
1106 bool sameColour
= (oldPenColour
.Ok () && m_currentColour
.Ok () &&
1107 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1108 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1109 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1110 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1112 if (!sameColour
|| !GetOptimization())
1114 int pixel
= CalculatePixel(m_textForegroundColour
,
1115 m_currentColour
, FALSE
);
1117 // Set the GC to the required colour
1120 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1121 if (m_window
&& m_window
->GetBackingPixmap())
1122 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1126 m_textForegroundColour
= oldPenColour
;
1129 // We need to add the ascent, not the whole height, since X draws at the
1130 // point above the descender.
1133 XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1134 (XChar2b
*)(char*) (const char*) text
, slen
);
1137 XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
, text
, slen
);
1139 if (m_window
&& m_window
->GetBackingPixmap()) {
1142 XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1143 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1144 (XChar2b
*)(char*) (const char*) text
, slen
);
1147 XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1148 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1149 wxConstCast(text
.c_str(), char), slen
);
1152 // restore fill style
1153 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, gcV
.fill_style
);
1154 if (m_window
&& m_window
->GetBackingPixmap())
1155 XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
,
1156 gcBackingV
.fill_style
);
1159 GetTextExtent (text
, &w
, &h
);
1160 CalcBoundingBox (x
+ w
, y
+ h
);
1161 CalcBoundingBox (x
, y
);
1164 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
,
1169 DrawText(text
, x
, y
);
1173 wxCHECK_RET( Ok(), "invalid dc" );
1175 int oldBackgroundPixel
= -1;
1176 int oldForegroundPixel
= -1;
1177 int foregroundPixel
= -1;
1178 int backgroundPixel
= -1;
1180 if (m_textBackgroundColour
.Ok())
1182 oldBackgroundPixel
= m_backgroundPixel
;
1183 backgroundPixel
= m_textBackgroundColour
.AllocColour(m_display
);
1185 if (m_textForegroundColour
.Ok())
1187 oldForegroundPixel
= m_currentColour
.GetPixel();
1189 if( m_textForegroundColour
.GetPixel() <= -1 )
1190 CalculatePixel( m_textForegroundColour
,
1191 m_textForegroundColour
, TRUE
);
1193 foregroundPixel
= m_textForegroundColour
.GetPixel();
1196 // Since X draws from the baseline of the text, must add the text height
1200 int slen
= text
.length();
1204 // Calculate text extent.
1205 WXFontStructPtr pFontStruct
=
1206 m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1207 int direction
, descent
;
1208 XCharStruct overall_return
;
1211 (void)XTextExtents16((XFontStruct
*) pFontStruct
,
1212 (XChar2b
*)(const char*) text
,
1214 &ascent
, &descent
, &overall_return
);
1217 (void)XTextExtents((XFontStruct
*) pFontStruct
,
1218 wxConstCast(text
.c_str(), char),
1220 &ascent
, &descent
, &overall_return
);
1222 cx
= overall_return
.width
;
1223 cy
= ascent
+ descent
;
1226 wxBitmap
src(cx
, cy
);
1228 dc
.SelectObject(src
);
1229 dc
.SetFont(GetFont());
1230 dc
.SetBackground(*wxWHITE_BRUSH
);
1231 dc
.SetBrush(*wxBLACK_BRUSH
);
1233 dc
.DrawText(text
, 0, 0);
1234 dc
.SetFont(wxNullFont
);
1236 // Calculate the size of the rotated bounding box.
1237 double dx
= cos(angle
/ 180.0 * M_PI
);
1238 double dy
= sin(angle
/ 180.0 * M_PI
);
1239 double x4
= cy
* dy
;
1240 double y4
= cy
* dx
;
1241 double x3
= cx
* dx
;
1242 double y3
= -cx
* dy
;
1243 double x2
= x3
+ x4
;
1244 double y2
= y3
+ y4
;
1248 // Create image from the source bitmap after writing the text into it.
1249 wxImage image
= src
.ConvertToImage();
1251 int minx
= roundmin(0, roundmin(x4
, roundmin(x2
, x3
)));
1252 int miny
= roundmin(0, roundmin(y4
, roundmin(y2
, y3
)));
1253 int maxx
= roundmax(0, roundmax(x4
, roundmax(x2
, x3
)));
1254 int maxy
= roundmax(0, roundmax(y4
, roundmax(y2
, y3
)));
1256 bool lastFore
= false, lastBack
= false;
1258 // This rotates counterclockwise around the top left corner.
1259 for (int rx
= minx
; rx
< maxx
; rx
++)
1261 for (int ry
= miny
; ry
< maxy
; ry
++)
1263 // transform dest coords to source coords
1264 int sx
= (int) (rx
* dx
- ry
* dy
+ 0.5);
1265 int sy
= - (int) (-ry
* dx
- rx
* dy
+ 0.5);
1266 if (sx
>= 0 && sx
< cx
&& sy
>= 0 && sy
< cy
)
1268 bool textPixel
= image
.GetRed(sx
, sy
) == 0;
1270 if (!textPixel
&& m_backgroundMode
!= wxSOLID
)
1273 wxCoord ox
= (wxCoord
) (x1
+ rx
),
1274 oy
= (wxCoord
) (y1
+ ry
);
1275 // draw black pixels, ignore white ones (i.e. transparent b/g)
1276 if (textPixel
&& !lastFore
)
1278 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1283 else if (!textPixel
&& !lastBack
)
1285 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1291 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
,
1292 (GC
) m_gc
, XLOG2DEV (ox
), YLOG2DEV (oy
));
1293 if (m_window
&& m_window
->GetBackingPixmap())
1294 XDrawPoint ((Display
*) m_display
,
1295 (Pixmap
) m_window
->GetBackingPixmap(),
1297 XLOG2DEV_2 (ox
), YLOG2DEV_2 (oy
));
1302 if (oldBackgroundPixel
> -1)
1304 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
);
1305 if (m_window
&& m_window
->GetBackingPixmap())
1306 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1307 oldBackgroundPixel
);
1309 if (oldForegroundPixel
> -1)
1311 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
);
1312 if (m_window
&& m_window
->GetBackingPixmap())
1313 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1314 oldForegroundPixel
);
1317 CalcBoundingBox (minx
, miny
);
1318 CalcBoundingBox (maxx
, maxy
);
1321 bool wxWindowDC::CanGetTextExtent() const
1326 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1327 wxCoord
*descent
, wxCoord
*externalLeading
,
1328 wxFont
*font
) const
1330 wxCHECK_RET( Ok(), "invalid dc" );
1332 wxFont
* theFont
= font
;
1334 theFont
= (wxFont
*)&m_font
; // const_cast
1338 // TODO: this should be an error log function
1339 wxFAIL_MSG("set a valid font before calling GetTextExtent!");
1341 if (width
) *width
= -1;
1342 if (height
) *height
= -1;
1346 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1348 int direction
, ascent
, descent2
;
1349 XCharStruct overall
;
1354 slen
= str16len(string
);
1357 slen
= strlen(string
);
1361 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1362 &ascent
, &descent2
, &overall
);
1365 XTextExtents((XFontStruct
*) pFontStruct
,
1366 wxConstCast(string
.c_str(), char), slen
, &direction
,
1367 &ascent
, &descent2
, &overall
);
1369 if (width
) *width
= XDEV2LOGREL (overall
.width
);
1370 if (height
) *height
= YDEV2LOGREL (ascent
+ descent2
);
1372 *descent
= descent2
;
1373 if (externalLeading
)
1374 *externalLeading
= 0;
1377 wxCoord
wxWindowDC::GetCharWidth() const
1379 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1380 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1382 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
* m_logicalScaleY
, m_display
);
1384 int direction
, ascent
, descent
;
1385 XCharStruct overall
;
1386 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1387 &descent
, &overall
);
1388 return XDEV2LOGREL(overall
.width
);
1391 wxCoord
wxWindowDC::GetCharHeight() const
1393 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1394 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1396 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1398 int direction
, ascent
, descent
;
1399 XCharStruct overall
;
1400 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1401 &descent
, &overall
);
1402 // return XDEV2LOGREL(overall.ascent + overall.descent);
1403 return XDEV2LOGREL(ascent
+ descent
);
1406 void wxWindowDC::DoGetSize( int *width
, int *height
) const
1412 if( m_window
->GetBackingPixmap() )
1414 w
= m_window
->GetPixmapWidth();
1415 h
= m_window
->GetPixmapHeight();
1418 m_window
->GetSize( &w
, &h
);
1421 if( width
) *width
= w
;
1422 if( height
) *height
= h
;
1425 void wxWindowDC::Clear()
1427 wxCHECK_RET( Ok(), "invalid dc" );
1429 wxRect
rect( wxPoint( 0, 0 ), GetSize() );
1433 void wxWindowDC::Clear(const wxRect
& rect
)
1435 wxCHECK_RET( Ok(), "invalid dc" );
1437 int x
= rect
.x
; int y
= rect
.y
;
1438 int w
= rect
.width
; int h
= rect
.height
;
1440 wxBrush saveBrush
= m_brush
;
1441 SetBrush (m_backgroundBrush
);
1443 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1446 if (m_window
&& m_window
->GetBackingPixmap())
1447 XFillRectangle ((Display
*) m_display
,
1448 (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1451 m_brush
= saveBrush
;
1454 void wxWindowDC::SetFont( const wxFont
&font
)
1456 wxCHECK_RET( Ok(), "invalid dc" );
1462 if ((m_oldFont
!= (WXFont
) 0) && ((wxCoord
) m_oldFont
!= -1))
1464 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
1466 if (m_window
&& m_window
->GetBackingPixmap())
1467 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
1472 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1474 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1475 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1477 if (m_window
&& m_window
->GetBackingPixmap())
1478 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1481 void wxWindowDC::SetForegroundPixelWithLogicalFunction(int pixel
)
1483 if (m_logicalFunction
== wxXOR
)
1486 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1487 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1488 pixel
^ values
.background
);
1489 if (m_window
&& m_window
->GetBackingPixmap())
1490 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1491 pixel
^ values
.background
);
1495 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1496 if (m_window
&& m_window
->GetBackingPixmap())
1497 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1501 int wxWindowDC::CalculatePixel(wxColour
& colour
, wxColour
& curCol
,
1502 bool roundToWhite
) const
1504 const unsigned char wp
= (unsigned char)255;
1507 if(!m_colour
) // Mono display
1509 unsigned char red
= colour
.Red ();
1510 unsigned char blue
= colour
.Blue ();
1511 unsigned char green
= colour
.Green ();
1513 if((red
== wp
&& blue
== wp
&& green
== wp
) ||
1514 // not black and roundToWhite was specified
1515 ((red
!= 0 || blue
!= 0 || green
!= 0) && roundToWhite
))
1518 pixel
= (int)WhitePixel((Display
*) m_display
,
1519 DefaultScreen((Display
*) m_display
));
1520 curCol
.SetPixel(pixel
);
1521 colour
.SetPixel(pixel
);
1526 pixel
= (int)BlackPixel((Display
*) m_display
,
1527 DefaultScreen((Display
*) m_display
));
1528 curCol
.SetPixel(pixel
);
1529 colour
.SetPixel(pixel
);
1535 pixel
= colour
.AllocColour((Display
*) m_display
);
1536 curCol
.SetPixel(pixel
);
1542 void wxWindowDC::SetPen( const wxPen
&pen
)
1544 wxCHECK_RET( Ok(), "invalid dc" );
1550 wxBitmap oldStipple
= m_currentStipple
;
1551 int oldStyle
= m_currentStyle
;
1552 int oldFill
= m_currentFill
;
1553 int old_pen_width
= m_currentPenWidth
;
1554 int old_pen_join
= m_currentPenJoin
;
1555 int old_pen_cap
= m_currentPenCap
;
1556 int old_pen_nb_dash
= m_currentPenDashCount
;
1557 wxX11Dash
*old_pen_dash
= m_currentPenDash
;
1559 wxColour oldPenColour
= m_currentColour
;
1560 m_currentColour
= m_pen
.GetColour ();
1561 m_currentStyle
= m_pen
.GetStyle ();
1562 m_currentFill
= m_pen
.GetStyle (); // TODO?
1563 m_currentPenWidth
= m_pen
.GetWidth ();
1564 m_currentPenJoin
= m_pen
.GetJoin ();
1565 m_currentPenCap
= m_pen
.GetCap ();
1566 m_currentPenDashCount
= m_pen
.GetDashCount();
1567 m_currentPenDash
= (wxX11Dash
*)m_pen
.GetDash();
1569 if (m_currentStyle
== wxSTIPPLE
)
1570 m_currentStipple
= * m_pen
.GetStipple ();
1572 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1573 oldFill
== m_currentFill
&&
1574 old_pen_join
== m_currentPenJoin
&&
1575 old_pen_cap
== m_currentPenCap
&&
1576 old_pen_nb_dash
== m_currentPenDashCount
&&
1577 old_pen_dash
== m_currentPenDash
&&
1578 old_pen_width
== m_currentPenWidth
);
1580 bool sameColour
= (oldPenColour
.Ok () &&
1581 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1582 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1583 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1584 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1586 if (!sameStyle
|| !GetOptimization())
1588 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1589 if (scaled_width
< 0)
1595 static const wxX11Dash dotted
[] = {2, 5};
1596 static const wxX11Dash short_dashed
[] = {4, 4};
1597 static const wxX11Dash long_dashed
[] = {4, 8};
1598 static const wxX11Dash dotted_dashed
[] = {6, 6, 2, 6};
1600 // We express dash pattern in pen width unit, so we are
1601 // independent of zoom factor and so on...
1603 const wxX11Dash
*req_dash
;
1605 switch (m_pen
.GetStyle ())
1608 req_nb_dash
= m_currentPenDashCount
;
1609 req_dash
= m_currentPenDash
;
1610 style
= LineOnOffDash
;
1615 style
= LineOnOffDash
;
1619 req_dash
= short_dashed
;
1620 style
= LineOnOffDash
;
1624 req_dash
= long_dashed
;
1625 style
= LineOnOffDash
;
1629 req_dash
= dotted_dashed
;
1630 style
= LineOnOffDash
;
1637 req_dash
= (wxX11Dash
*)NULL
;
1641 if (req_dash
&& req_nb_dash
)
1643 wxX11Dash
*real_req_dash
= new wxX11Dash
[req_nb_dash
];
1646 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1647 for (int i
= 0; i
< req_nb_dash
; i
++)
1648 real_req_dash
[i
] = req_dash
[i
] * factor
;
1649 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1651 if (m_window
&& m_window
->GetBackingPixmap())
1652 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1653 delete[]real_req_dash
;
1657 // No Memory. We use non-scaled dash pattern...
1658 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1660 if (m_window
&& m_window
->GetBackingPixmap())
1661 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1665 switch (m_pen
.GetCap ())
1667 case wxCAP_PROJECTING
:
1668 cap
= CapProjecting
;
1675 cap
= (scaled_width
<= 1) ? CapNotLast
: CapRound
;
1679 switch (m_pen
.GetJoin ())
1693 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1695 if (m_window
&& m_window
->GetBackingPixmap())
1696 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1699 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1703 oldStipple
= wxNullBitmap
; // For later reset!!
1705 switch (m_currentFill
)
1707 case wxBDIAGONAL_HATCH
:
1708 if (bdiag
== (Pixmap
) 0)
1709 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1710 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1711 bdiag_bits
, bdiag_width
, bdiag_height
);
1714 case wxFDIAGONAL_HATCH
:
1715 if (fdiag
== (Pixmap
) 0)
1716 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1717 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1718 fdiag_bits
, fdiag_width
, fdiag_height
);
1722 if (cross
== (Pixmap
) 0)
1723 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1724 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1725 cross_bits
, cross_width
, cross_height
);
1728 case wxHORIZONTAL_HATCH
:
1729 if (horiz
== (Pixmap
) 0)
1730 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1731 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1732 horiz_bits
, horiz_width
, horiz_height
);
1735 case wxVERTICAL_HATCH
:
1736 if (verti
== (Pixmap
) 0)
1737 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1738 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1739 verti_bits
, verti_width
, verti_height
);
1742 case wxCROSSDIAG_HATCH
:
1744 if (cdiag
== (Pixmap
) 0)
1745 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1746 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1747 cdiag_bits
, cdiag_width
, cdiag_height
);
1751 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1753 if (m_window
&& m_window
->GetBackingPixmap())
1754 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1756 else if (m_currentStipple
.Ok()
1757 && ((m_currentStipple
!= oldStipple
) || !GetOptimization()))
1759 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetDrawable());
1761 if (m_window
&& m_window
->GetBackingPixmap())
1762 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetDrawable());
1765 if ((m_currentFill
!= oldFill
) || !GetOptimization())
1769 if (m_currentFill
== wxSTIPPLE
)
1770 fill_style
= FillStippled
;
1771 else if (IS_HATCH (m_currentFill
))
1772 fill_style
= FillStippled
;
1774 fill_style
= FillSolid
;
1775 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1776 if (m_window
&& m_window
->GetBackingPixmap())
1777 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1780 // must test m_logicalFunction, because it involves background!
1781 if (!sameColour
|| !GetOptimization()
1782 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1785 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1786 pixel
= m_backgroundPixel
;
1789 pixel
= CalculatePixel(m_pen
.GetColour(), m_currentColour
, FALSE
);
1792 // Finally, set the GC to the required colour
1794 SetForegroundPixelWithLogicalFunction(pixel
);
1797 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1802 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1804 wxCHECK_RET( Ok(), "invalid dc" );
1808 if (!m_brush
.Ok() || m_brush
.GetStyle () == wxTRANSPARENT
)
1811 int oldFill
= m_currentFill
;
1812 wxBitmap oldStipple
= m_currentStipple
;
1814 m_autoSetting
|= 0x1;
1816 m_currentFill
= m_brush
.GetStyle ();
1817 if (m_currentFill
== wxSTIPPLE
)
1818 m_currentStipple
= * m_brush
.GetStipple ();
1820 wxColour
oldBrushColour(m_currentColour
);
1821 m_currentColour
= m_brush
.GetColour ();
1823 bool sameColour
= (oldBrushColour
.Ok () &&
1824 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1825 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1826 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1827 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1829 int stippleDepth
= -1;
1831 if ((oldFill
!= m_brush
.GetStyle ()) || !GetOptimization())
1833 switch (brush
.GetStyle ())
1838 stippleDepth
= m_currentStipple
.GetDepth();
1840 case wxBDIAGONAL_HATCH
:
1841 case wxCROSSDIAG_HATCH
:
1842 case wxFDIAGONAL_HATCH
:
1844 case wxHORIZONTAL_HATCH
:
1845 case wxVERTICAL_HATCH
:
1847 if (stippleDepth
== -1) stippleDepth
= 1;
1849 // Chris Breeze 23/07/97: use background mode to
1850 // determine whether fill style should be solid or
1852 int style
= stippleDepth
== 1 ?
1853 (m_backgroundMode
== wxSOLID
?
1854 FillOpaqueStippled
: FillStippled
) :
1856 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1857 if (m_window
&& m_window
->GetBackingPixmap())
1858 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1863 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1864 if (m_window
&& m_window
->GetBackingPixmap())
1865 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
,
1870 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1874 switch (m_currentFill
)
1876 case wxBDIAGONAL_HATCH
:
1877 if (bdiag
== (Pixmap
) 0)
1878 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1879 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1880 bdiag_bits
, bdiag_width
, bdiag_height
);
1883 case wxFDIAGONAL_HATCH
:
1884 if (fdiag
== (Pixmap
) 0)
1885 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1886 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1887 fdiag_bits
, fdiag_width
, fdiag_height
);
1891 if (cross
== (Pixmap
) 0)
1892 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1893 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1894 cross_bits
, cross_width
, cross_height
);
1897 case wxHORIZONTAL_HATCH
:
1898 if (horiz
== (Pixmap
) 0)
1899 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1900 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1901 horiz_bits
, horiz_width
, horiz_height
);
1904 case wxVERTICAL_HATCH
:
1905 if (verti
== (Pixmap
) 0)
1906 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1907 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1908 verti_bits
, verti_width
, verti_height
);
1911 case wxCROSSDIAG_HATCH
:
1913 if (cdiag
== (Pixmap
) 0)
1914 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1915 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1916 cdiag_bits
, cdiag_width
, cdiag_height
);
1920 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1922 if (m_window
&& m_window
->GetBackingPixmap())
1923 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1925 // X can forget the stipple value when resizing a window (apparently)
1926 // so always set the stipple.
1927 else if (m_currentFill
!= wxSOLID
&& m_currentFill
!= wxTRANSPARENT
&&
1928 m_currentStipple
.Ok()) // && m_currentStipple != oldStipple)
1930 if (m_currentStipple
.GetDepth() == 1)
1932 XSetStipple ((Display
*) m_display
, (GC
) m_gc
,
1933 (Pixmap
) m_currentStipple
.GetDrawable());
1934 if (m_window
&& m_window
->GetBackingPixmap())
1935 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
,
1936 (Pixmap
) m_currentStipple
.GetDrawable());
1940 XSetTile ((Display
*) m_display
, (GC
) m_gc
,
1941 (Pixmap
) m_currentStipple
.GetDrawable());
1942 if (m_window
&& m_window
->GetBackingPixmap())
1943 XSetTile ((Display
*) m_display
,(GC
) m_gcBacking
,
1944 (Pixmap
) m_currentStipple
.GetDrawable());
1948 // must test m_logicalFunction, because it involves background!
1949 if (!sameColour
|| !GetOptimization() || m_logicalFunction
== wxXOR
)
1951 int pixel
= CalculatePixel(m_brush
.GetColour(), m_currentColour
, TRUE
);
1954 SetForegroundPixelWithLogicalFunction(pixel
);
1957 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1960 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1962 wxCHECK_RET( Ok(), "invalid dc" );
1964 m_backgroundBrush
= brush
;
1966 if (!m_backgroundBrush
.Ok())
1969 m_backgroundPixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
1971 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
1972 // And Blit,... (Any fct that use XCopyPlane, in fact.)
1973 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, m_backgroundPixel
);
1974 if (m_window
&& m_window
->GetBackingPixmap())
1975 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1979 void wxWindowDC::SetLogicalFunction( int function
)
1981 wxCHECK_RET( Ok(), "invalid dc" );
1986 if (m_logicalFunction
== function
)
1992 x_function
= GXclear
;
1998 x_function
= GXinvert
;
2001 x_function
= GXorReverse
;
2004 x_function
= GXandReverse
;
2013 x_function
= GXandInverted
;
2016 x_function
= GXnoop
;
2022 x_function
= GXequiv
;
2025 x_function
= GXcopyInverted
;
2028 x_function
= GXorInverted
;
2031 x_function
= GXnand
;
2038 x_function
= GXcopy
;
2042 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
2043 if (m_window
&& m_window
->GetBackingPixmap())
2044 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
2046 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
2047 /* MATTHEW: [9] Need to redo pen simply */
2048 m_autoSetting
|= 0x2;
2050 m_logicalFunction
= function
;
2054 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2056 wxCHECK_RET( Ok(), "invalid dc" );
2058 m_textForegroundColour
= col
;
2061 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2063 wxCHECK_RET( Ok(), "invalid dc" );
2065 m_textBackgroundColour
= col
;
2068 void wxWindowDC::SetBackgroundMode( int mode
)
2070 m_backgroundMode
= mode
;
2073 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2078 /* Use GetXColormap */
2079 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2080 (Colormap
) palette
.GetXColormap());
2082 /* Use wxGetMainColormap */
2083 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2084 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2088 static void wxCopyRegion( WXRegion src
, WXRegion
& dst
)
2091 dst
= XCreateRegion();
2092 XUnionRegion( (Region
)src
, (Region
)src
, (Region
)dst
);
2095 // Helper function; userRegion is the region set by calling SetClippingRegion
2096 void wxWindowDC::SetDCClipping( WXRegion userRegion
)
2098 bool hasUpdateRegion
= m_window
&& m_window
->GetUpdateRegion().Ok();
2099 // this means that we should start the clip region from scratch,
2100 // or from the update region, if any
2104 XDestroyRegion( (Region
)m_clipRegion
);
2105 m_clipRegion
= (WXRegion
)NULL
;
2107 if( hasUpdateRegion
)
2108 wxCopyRegion( m_window
->GetUpdateRegion().GetX11Region(),
2111 // intersect the user region, if any, with the
2112 // exisiting clip region
2113 else // if( userRegion )
2116 wxCopyRegion( userRegion
, m_clipRegion
);
2118 XIntersectRegion( (Region
)m_clipRegion
,
2119 (Region
)userRegion
, (Region
)m_clipRegion
);
2123 XSetRegion( (Display
*)m_display
, (GC
)m_gc
, (Region
)m_clipRegion
);
2125 XSetClipMask( (Display
*)m_display
, (GC
)m_gc
, None
);
2128 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
,
2129 wxCoord width
, wxCoord height
)
2131 wxDC::DoSetClippingRegion( x
, y
, width
, height
);
2133 wxRegion
temp(x
, y
, width
, height
);
2135 SetDCClipping(temp
.GetX11Region());
2137 // Needs to work differently for Pixmap: without this,
2138 // there's a nasty (Display*) m_display bug. 8/12/94
2139 if (m_window
&& m_window
->GetBackingPixmap())
2141 XRectangle rects
[1];
2142 rects
[0].x
= XLOG2DEV_2(x
);
2143 rects
[0].y
= YLOG2DEV_2(y
);
2144 rects
[0].width
= XLOG2DEVREL(width
);
2145 rects
[0].height
= YLOG2DEVREL(height
);
2146 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
,
2147 0, 0, rects
, 1, Unsorted
);
2151 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2153 wxRect box
= region
.GetBox();
2155 wxDC::DoSetClippingRegion( box
.x
, box
.y
, box
.width
, box
.height
);
2157 SetDCClipping(region
.GetX11Region());
2159 // Needs to work differently for Pixmap: without this,
2160 // there's a nasty (Display*) m_display bug. 8/12/94
2161 if (m_window
&& m_window
->GetBackingPixmap())
2163 XRectangle rects
[1];
2164 rects
[0].x
= XLOG2DEV_2(box
.x
);
2165 rects
[0].y
= YLOG2DEV_2(box
.y
);
2166 rects
[0].width
= XLOG2DEVREL(box
.width
);
2167 rects
[0].height
= YLOG2DEVREL(box
.height
);
2168 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
,
2169 0, 0, rects
, 1, Unsorted
);
2174 void wxWindowDC::DestroyClippingRegion()
2176 wxDC::DestroyClippingRegion();
2178 SetDCClipping(NULL
);
2180 if (m_window
&& m_window
->GetBackingPixmap())
2181 XSetClipMask ((Display
*) m_display
, (GC
) m_gcBacking
, None
);
2184 // Resolution in pixels per logical inch
2185 wxSize
wxWindowDC::GetPPI() const
2188 return wxSize(100, 100);
2191 int wxWindowDC::GetDepth() const
2200 // ----------------------------------------------------------------------------
2202 // ----------------------------------------------------------------------------
2204 wxPaintDC::wxPaintDC(wxWindow
* win
) : wxWindowDC(win
)
2206 // Set the clipping region.to the update region
2207 SetDCClipping((WXRegion
)NULL
);
2210 wxPaintDC::~wxPaintDC()
2213 m_window
->ClearUpdateRegion();
2214 SetDCClipping((WXRegion
)NULL
);
2217 // ----------------------------------------------------------------------------
2218 // private functions
2219 // ----------------------------------------------------------------------------
2222 Used when copying between drawables on different (Display*) m_displays. Not
2223 very fast, but better than giving up.
2226 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
2227 Drawable src
, Drawable dest
,
2230 unsigned int w
, unsigned int h
,
2231 int destx
, int desty
,
2232 bool more
, XImage
**cache
)
2234 XImage
*image
, *destimage
;
2235 Colormap destcm
, srccm
;
2236 static const int CACHE_SIZE
= 256;
2239 unsigned long cachesrc
[CACHE_SIZE
], cachedest
[CACHE_SIZE
];
2240 int k
, cache_pos
, all_cache
;
2242 if (!cache
|| !*cache
)
2243 image
= XGetImage(src_display
, src
, srcx
, srcy
, w
, h
, AllPlanes
, ZPixmap
);
2247 destimage
= XGetImage(dest_display
, dest
, destx
, desty
, w
, h
, AllPlanes
, ZPixmap
);
2249 srccm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) src_display
);
2250 destcm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dest_display
);
2255 for (i
= 0; i
< w
; i
++)
2256 for (j
= 0; j
< h
; j
++) {
2257 unsigned long pixel
;
2260 pixel
= XGetPixel(image
, i
, j
);
2261 for (k
= cache_pos
; k
--; )
2262 if (cachesrc
[k
] == pixel
) {
2263 pixel
= cachedest
[k
];
2267 for (k
= CACHE_SIZE
; k
-- > cache_pos
; )
2268 if (cachesrc
[k
] == pixel
) {
2269 pixel
= cachedest
[k
];
2273 cachesrc
[cache_pos
] = xcol
.pixel
= pixel
;
2274 XQueryColor(src_display
, srccm
, &xcol
);
2275 if (!XAllocColor(dest_display
, destcm
, &xcol
))
2277 cachedest
[cache_pos
] = pixel
= xcol
.pixel
;
2279 if (++cache_pos
>= CACHE_SIZE
) {
2285 XPutPixel(destimage
, i
, j
, pixel
);
2288 XPutImage(dest_display
, dest
, destgc
, destimage
, 0, 0, destx
, desty
, w
, h
);
2289 XDestroyImage(destimage
);
2294 XDestroyImage(image
);
2299 /* Helper function for 16-bit fonts */
2300 static int str16len(const char *s
)
2304 while (s
[0] && s
[1]) {