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 // For compilers that support precompilation, includes "wx.h".
44 #include "wx/wxprec.h"
46 #include "wx/dcclient.h"
47 #include "wx/dcmemory.h"
48 #include "wx/window.h"
56 #pragma message disable nosimpint
60 #pragma message enable nosimpint
63 #include "wx/motif/private.h"
66 #include <float.h> // for M_PI
76 static Pixmap bdiag
, cdiag
, fdiag
, cross
, horiz
, verti
;
78 // ----------------------------------------------------------------------------
80 // ----------------------------------------------------------------------------
82 // Fudge factor (VZ: what??)
85 // ----------------------------------------------------------------------------
87 // ----------------------------------------------------------------------------
89 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
90 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxWindowDC
)
91 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
93 // ----------------------------------------------------------------------------
95 // ----------------------------------------------------------------------------
97 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
98 Drawable src
, Drawable dest
,
101 unsigned int w
, unsigned int h
,
102 int destx
, int desty
,
103 bool more
, XImage
**cache
);
105 // ============================================================================
107 // ============================================================================
110 * compare two doubles and return the larger rounded
113 static int roundmax(double a
, double b
)
115 return (int)((a
> b
? a
: b
) + 0.5);
119 * compare two doubles and return the smaller rounded
122 static int roundmin(double a
, double b
)
124 return (int)((a
< b
? a
: b
) - 0.5);
128 // ----------------------------------------------------------------------------
130 // ----------------------------------------------------------------------------
132 void wxWindowDC::Init()
135 m_gcBacking
= (WXGC
) 0;
137 m_backgroundPixel
= -1;
138 m_currentPenWidth
= 1;
139 m_currentPenJoin
= -1;
140 m_currentPenDashCount
= -1;
141 m_currentPenDash
= (wxX11Dash
*) NULL
;
144 m_colour
= wxColourDisplay();
145 m_display
= (WXDisplay
*) NULL
;
146 m_pixmap
= (WXPixmap
) 0;
148 m_oldFont
= (WXFont
) 0;
150 m_clipRegion
= (WXRegion
) 0;
153 wxWindowDC::wxWindowDC()
158 wxWindowDC::wxWindowDC( wxWindow
*window
)
160 wxASSERT_MSG( (window
!= (wxWindow
*) NULL
), "You must pass a valid wxWindow to wxWindowDC/wxClientDC/wxPaintDC constructor." );
165 m_font
= window
->GetFont();
168 m_display
= window
->GetXDisplay();
169 m_pixmap
= window
->GetXWindow();
170 Display
* display
= (Display
*) m_display
;
172 XSetWindowColormap (display
, (Pixmap
) m_pixmap
, (Colormap
) wxTheApp
->GetMainColormap(m_display
));
175 gcvalues
.foreground
= BlackPixel (display
, DefaultScreen (display
));
176 gcvalues
.background
= WhitePixel (display
, DefaultScreen (display
));
177 gcvalues
.graphics_exposures
= False
;
178 gcvalues
.subwindow_mode
= IncludeInferiors
;
179 gcvalues
.line_width
= 1;
180 m_gc
= (WXGC
) XCreateGC (display
, RootWindow (display
, DefaultScreen (display
)),
181 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
184 if (m_window
->GetBackingPixmap())
186 m_gcBacking
= (WXGC
) XCreateGC (display
, RootWindow (display
,
187 DefaultScreen (display
)),
188 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
192 m_backgroundPixel
= (int) gcvalues
.background
;
194 // Get the current Font so we can set it back later
196 XGetGCValues((Display
*) m_display
, (GC
) m_gc
, GCFont
, &valReturn
);
197 m_oldFont
= (WXFont
) valReturn
.font
;
199 SetBackground(wxBrush(m_window
->GetBackgroundColour(), wxSOLID
));
202 wxWindowDC::~wxWindowDC()
204 if (m_gc
&& (m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
206 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
208 if (m_window
&& m_window
->GetBackingPixmap())
209 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
213 XFreeGC ((Display
*) m_display
, (GC
) m_gc
);
217 XFreeGC ((Display
*) m_display
, (GC
) m_gcBacking
);
218 m_gcBacking
= (WXGC
) 0;
221 XDestroyRegion ((Region
) m_clipRegion
);
222 m_clipRegion
= (WXRegion
) 0;
225 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
226 const wxColour
& col
, int style
);
228 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
229 const wxColour
& col
, int style
)
231 return wxDoFloodFill(this, x
, y
, col
, style
);
234 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
236 // Generic (and therefore rather inefficient) method.
237 // Could be improved.
239 wxBitmap
bitmap(1, 1);
240 memdc
.SelectObject(bitmap
);
241 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
242 memdc
.SelectObject(wxNullBitmap
);
243 wxImage image
= bitmap
.ConvertToImage();
244 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
248 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
250 wxCHECK_RET( Ok(), "invalid dc" );
252 int x1d
, y1d
, x2d
, y2d
;
262 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x1d
, y1d
, x2d
, y2d
);
264 if (m_window
&& m_window
->GetBackingPixmap())
265 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
266 XLOG2DEV_2(x1
), YLOG2DEV_2(y1
),
267 XLOG2DEV_2(x2
), YLOG2DEV_2(y2
));
269 CalcBoundingBox(x1
, y1
);
270 CalcBoundingBox(x2
, y2
);
273 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
275 wxCHECK_RET( Ok(), "invalid dc" );
280 int xx
= XLOG2DEV (x
);
281 int yy
= YLOG2DEV (y
);
283 wxDisplaySize (&ww
, &hh
);
284 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, yy
,
286 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xx
, 0,
289 if (m_window
&& m_window
->GetBackingPixmap())
293 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
296 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
302 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
304 wxCHECK_RET( Ok(), "invalid dc" );
306 int xx1
= XLOG2DEV (x1
);
307 int yy1
= YLOG2DEV (y1
);
308 int xx2
= XLOG2DEV (x2
);
309 int yy2
= YLOG2DEV (y2
);
310 int xxc
= XLOG2DEV (xc
);
311 int yyc
= YLOG2DEV (yc
);
312 int xxc_2
= XLOG2DEV_2 (xc
);
313 int yyc_2
= YLOG2DEV_2 (yc
);
315 wxCoord dx
= xx1
- xxc
;
316 wxCoord dy
= yy1
- yyc
;
317 double radius
= sqrt ((double)(dx
* dx
+ dy
* dy
));
318 wxCoord r
= (wxCoord
) radius
;
320 double radius1
, radius2
;
322 if (xx1
== xx2
&& yy1
== yy2
)
327 else if (radius
== 0.0)
328 radius1
= radius2
= 0.0;
337 radius1
= -atan2 ((double) (yy1
- yyc
), (double) (xx1
- xxc
)) * 360.0 / (2 * M_PI
);
345 radius2
= -atan2 ((double) (yy2
- yyc
), (double) (xx2
- xxc
)) * 360.0 / (2 * M_PI
);
349 int alpha1
= (int) radius1
;
350 int alpha2
= (int) (radius2
- radius1
);
353 while (alpha2
> 360 * 64)
356 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
359 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) (GC
) m_gc
,
360 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
362 if (m_window
&& m_window
->GetBackingPixmap())
363 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
364 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
368 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
372 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
373 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
375 if (m_window
&& m_window
->GetBackingPixmap())
376 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
377 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
379 CalcBoundingBox (x1
, y1
);
380 CalcBoundingBox (x2
, y2
);
383 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
385 wxCHECK_RET( Ok(), "invalid dc" );
391 wd
= XLOG2DEVREL(width
);
392 hd
= YLOG2DEVREL(height
);
394 if (sa
>=360 || sa
<=-360) sa
=sa
-int(sa
/360)*360;
395 if (ea
>=360 || ea
<=-360) ea
=ea
-int(ea
/360)*360;
396 int start
= int(sa
*64);
397 int end
= int(ea
*64);
398 if (start
<0) start
+=360*64;
399 if (end
<0) end
+=360*64;
400 if (end
>start
) end
-=start
;
401 else end
+=360*64-start
;
403 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
405 m_autoSetting
= TRUE
; // must be reset
408 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
, end
);
410 if (m_window
&& m_window
->GetBackingPixmap())
411 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
412 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
415 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
419 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
,end
);
420 if (m_window
&& m_window
->GetBackingPixmap())
421 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
422 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
424 CalcBoundingBox (x
, y
);
425 CalcBoundingBox (x
+ width
, y
+ height
);
428 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
430 wxCHECK_RET( Ok(), "invalid dc" );
432 if (m_pen
.Ok() && m_autoSetting
)
435 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
));
436 if (m_window
&& m_window
->GetBackingPixmap())
437 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, XLOG2DEV_2 (x
), YLOG2DEV_2 (y
));
439 CalcBoundingBox (x
, y
);
442 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
444 wxCHECK_RET( Ok(), "invalid dc" );
446 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
451 XPoint
*xpoints
= new XPoint
[n
];
454 for (i
= 0; i
< n
; i
++)
456 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
457 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
459 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints
, n
, 0);
461 if (m_window
&& m_window
->GetBackingPixmap())
463 for (i
= 0; i
< n
; i
++)
465 xpoints
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
466 xpoints
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
468 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints
, n
, 0);
474 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
475 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
477 wxCHECK_RET( Ok(), "invalid dc" );
479 XPoint
*xpoints1
= new XPoint
[n
+ 1];
480 XPoint
*xpoints2
= new XPoint
[n
+ 1];
482 for (i
= 0; i
< n
; i
++)
484 xpoints1
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
485 xpoints1
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
486 xpoints2
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
487 xpoints2
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
488 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
491 // Close figure for XDrawLines (not needed for XFillPolygon)
492 xpoints1
[i
].x
= xpoints1
[0].x
;
493 xpoints1
[i
].y
= xpoints1
[0].y
;
494 xpoints2
[i
].x
= xpoints2
[0].x
;
495 xpoints2
[i
].y
= xpoints2
[0].y
;
497 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
500 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
501 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
, Complex
, 0);
502 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, EvenOddRule
); // default mode
503 if (m_window
&& m_window
->GetBackingPixmap())
505 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
,
506 fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
507 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
, Complex
, 0);
508 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
, EvenOddRule
); // default mode
512 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
516 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
+ 1, 0);
518 if (m_window
&& m_window
->GetBackingPixmap())
519 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
+ 1, 0);
526 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
528 wxCHECK_RET( Ok(), "invalid dc" );
530 int xd
, yd
, wfd
, hfd
, wd
, hd
;
534 wfd
= XLOG2DEVREL(width
);
536 hfd
= YLOG2DEVREL(height
);
539 if (wfd
== 0 || hfd
== 0) return;
540 if (wd
< 0) { wd
= - wd
; xd
= xd
- wd
; }
541 if (hd
< 0) { hd
= - hd
; yd
= yd
- hd
; }
543 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
546 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wfd
, hfd
);
548 if (m_window
&& m_window
->GetBackingPixmap())
549 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
550 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
554 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
558 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
);
560 if (m_window
&& m_window
->GetBackingPixmap())
561 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
562 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
565 CalcBoundingBox (x
, y
);
566 CalcBoundingBox (x
+ width
, y
+ height
);
569 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
571 wxCHECK_RET( Ok(), "invalid dc" );
573 // If radius is negative, it's a proportion of the smaller dimension.
575 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
577 int xd
= XLOG2DEV (x
);
578 int yd
= YLOG2DEV (y
);
579 int rd
= XLOG2DEVREL ((long) radius
);
580 int wd
= XLOG2DEVREL (width
) - WX_GC_CF
;
581 int hd
= YLOG2DEVREL (height
) - WX_GC_CF
;
586 // If radius is zero use DrawRectangle() instead to avoid
587 // X drawing errors with small radii
590 DrawRectangle( x
, y
, width
, height
);
594 // Draw nothing if transformed w or h is 0
595 if (wd
== 0 || hd
== 0) return;
597 // CMB: adjust size if outline is drawn otherwise the result is
598 // 1 pixel too wide and high
599 if (m_pen
.GetStyle() != wxTRANSPARENT
)
605 // CMB: ensure dd is not larger than rectangle otherwise we
606 // get an hour glass shape
607 if (rw_d
> wd
) rw_d
= wd
;
608 if (rw_d
> hd
) rw_d
= hd
;
611 // For backing pixmap
612 int xd2
= XLOG2DEV_2 (x
);
613 int yd2
= YLOG2DEV_2 (y
);
614 int rd2
= XLOG2DEVREL ((long) radius
);
615 int wd2
= XLOG2DEVREL (width
) ;
616 int hd2
= YLOG2DEVREL (height
) ;
621 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
625 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
627 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
630 // Arcs start from 3 o'clock, positive angles anticlockwise
632 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
633 rw_d
, rh_d
, 90 * 64, 90 * 64);
635 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
636 // rw_d, rh_d, 0, 90 * 64);
637 rw_d
, rh_d
, 0, 91 * 64);
639 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
641 // rw_d, rh_d, 270 * 64, 90 * 64);
642 rw_d
, rh_d
, 269 * 64, 92 * 64);
644 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
645 rw_d
, rh_d
, 180 * 64, 90 * 64);
647 if (m_window
&& m_window
->GetBackingPixmap())
649 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
650 xd2
+ rd2
, yd2
, wd2
- rw_d2
, hd2
);
651 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
652 xd2
, yd2
+ rd2
, wd2
, hd2
- rh_d2
);
654 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
655 xd2
, yd2
, rw_d2
, rh_d2
, 90 * 64, 90 * 64);
656 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
657 xd2
+ wd2
- rw_d2
, yd2
,
658 // rw_d2, rh_d2, 0, 90 * 64);
659 rw_d2
, rh_d2
, 0, 91 * 64);
660 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
663 // rw_d2, rh_d2, 270 * 64, 90 * 64);
664 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
665 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
666 xd2
, yd2
+ hd2
- rh_d2
,
667 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
671 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
674 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
675 xd
+ wd
- rd
+ 1, yd
);
676 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
+ hd
,
677 xd
+ wd
- rd
, yd
+ hd
);
679 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
681 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
, yd
+ rd
,
682 xd
+ wd
, yd
+ hd
- rd
+ 1);
683 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
684 rw_d
, rh_d
, 90 * 64, 90 * 64);
685 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
686 // rw_d, rh_d, 0, 90 * 64);
687 rw_d
, rh_d
, 0, 91 * 64);
688 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
690 rw_d
, rh_d
, 269 * 64, 92 * 64);
691 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
692 rw_d
, rh_d
, 180 * 64, 90 * 64);
694 if (m_window
&& m_window
->GetBackingPixmap())
696 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
698 xd2
+ wd2
- rd2
+ 1, yd2
);
699 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
700 xd2
+ rd2
, yd2
+ hd2
,
701 xd2
+ wd2
- rd2
, yd2
+ hd2
);
703 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
705 xd2
, yd2
+ hd2
- rd2
);
706 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
707 xd2
+ wd2
, yd2
+ rd2
,
708 xd2
+ wd2
, yd2
+ hd2
- rd2
+ 1);
709 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
711 rw_d2
, rh_d2
, 90 * 64, 90 * 64);
712 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
713 xd2
+ wd2
- rw_d2
, yd2
,
714 // rw_d2, rh_d2, 0, 90 * 64);
715 rw_d2
, rh_d2
, 0, 91 * 64);
716 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
719 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
720 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
721 xd2
, yd2
+ hd2
- rh_d2
,
722 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
725 CalcBoundingBox (x
, y
);
726 CalcBoundingBox (x
+ width
, y
+ height
);
729 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
731 wxCHECK_RET( Ok(), "invalid dc" );
733 // Check for negative width and height
746 static const int angle
= 23040;
752 wd
= XLOG2DEVREL(width
) ;
753 hd
= YLOG2DEVREL(height
) ;
755 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
758 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
759 if (m_window
&& m_window
->GetBackingPixmap())
760 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
761 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
762 XLOG2DEVREL (width
) - WX_GC_CF
,
763 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
766 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
770 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
771 if (m_window
&& m_window
->GetBackingPixmap())
772 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
773 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
774 XLOG2DEVREL (width
) - WX_GC_CF
,
775 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
777 CalcBoundingBox (x
, y
);
778 CalcBoundingBox (x
+ width
, y
+ height
);
782 bool wxWindowDC::CanDrawBitmap() const
784 wxCHECK_MSG( Ok(), FALSE
, "invalid dc" );
789 // TODO: use scaled Blit e.g. as per John Price's implementation
790 // in Contrib/Utilities
791 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
,
792 wxCoord width
, wxCoord height
,
793 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
,
794 int rop
, bool useMask
,
795 wxCoord xsrcMask
, wxCoord ysrcMask
)
797 wxCHECK_MSG( Ok(), FALSE
, "invalid dc" );
799 wxWindowDC
* sourceDC
= wxDynamicCast(source
, wxWindowDC
);
801 wxASSERT_MSG( sourceDC
, "Blit source DC must be wxWindowDC or derived class." );
803 // Be sure that foreground pixels (1) of the Icon will be painted with
804 // foreground colour. [m_textForegroundColour] Background pixels (0)
805 // will be painted with backgound colour (m_textBackgroundColour)
806 // Using ::SetPen is horribly slow, so avoid doing it
807 int oldBackgroundPixel
= -1;
808 int oldForegroundPixel
= -1;
810 if (m_textBackgroundColour
.Ok())
812 oldBackgroundPixel
= m_backgroundPixel
;
813 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
815 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
816 if (m_window
&& m_window
->GetBackingPixmap())
817 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
820 if (m_textForegroundColour
.Ok())
822 oldForegroundPixel
= m_currentColour
.GetPixel();
824 if( m_textForegroundColour
.GetPixel() <= -1 )
825 CalculatePixel( m_textForegroundColour
,
826 m_textForegroundColour
, TRUE
);
828 int pixel
= m_textForegroundColour
.GetPixel();
830 SetForegroundPixelWithLogicalFunction(pixel
);
833 // Do bitmap scaling if necessary
835 wxBitmap
*scaledBitmap
= (wxBitmap
*) NULL
;
836 Pixmap sourcePixmap
= (Pixmap
) NULL
;
837 double scaleX
, scaleY
;
838 GetUserScale(& scaleX
, & scaleY
);
841 /* TODO: use the mask origin when drawing transparently */
842 if (xsrcMask
== -1 && ysrcMask
== -1)
844 xsrcMask
= xsrc
; ysrcMask
= ysrc
;
847 // Sorry, can't scale masks just yet
848 if (!useMask
&& (scaleX
!= 1.0 || scaleY
!= 1.0) && sourceDC
->IsKindOf(CLASSINFO(wxMemoryDC
)))
850 wxMemoryDC
* memDC
= (wxMemoryDC
*) sourceDC
;
851 wxBitmap
& bitmap
= memDC
->GetBitmap();
853 wxASSERT_MSG( (bitmap
.Ok()), "Bad source bitmap in wxWindowDC::Blit");
855 wxImage image
= bitmap
.ConvertToImage();
858 sourcePixmap
= (Pixmap
) bitmap
.GetDrawable();
862 int scaledW
= (int) (bitmap
.GetWidth() * scaleX
);
863 int scaledH
= (int) (bitmap
.GetHeight() * scaleY
);
865 image
= image
.Scale(scaledW
, scaledH
);
866 scaledBitmap
= new wxBitmap(image
);
867 sourcePixmap
= (Pixmap
) scaledBitmap
->GetDrawable();
871 sourcePixmap
= (Pixmap
) sourceDC
->m_pixmap
;
873 if (m_pixmap
&& sourcePixmap
)
876 int orig
= m_logicalFunction
;
878 SetLogicalFunction (rop
);
880 if (m_display
!= sourceDC
->m_display
)
882 XImage
*cache
= NULL
;
884 if (m_window
&& m_window
->GetBackingPixmap())
885 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
,
886 (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
888 source
->LogicalToDeviceX (xsrc
),
889 source
->LogicalToDeviceY (ysrc
),
890 source
->LogicalToDeviceXRel(width
),
891 source
->LogicalToDeviceYRel(height
),
892 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
),
895 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
897 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
898 wxBitmap
& sel
= memDC
->GetBitmap();
899 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetBitmap() )
901 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap());
902 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
906 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
907 source
->LogicalToDeviceX (xsrc
),
908 source
->LogicalToDeviceY (ysrc
),
909 source
->LogicalToDeviceXRel(width
),
910 source
->LogicalToDeviceYRel(height
),
911 XLOG2DEV (xdest
), YLOG2DEV (ydest
),
917 XSetRegion ((Display
*) m_display
, (GC
) m_gc
,
918 (Region
) m_clipRegion
);
920 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
922 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
926 { //XGCValues values;
927 //XGetGCValues((Display*)m_display, (GC)m_gc, GCForeground, &values);
929 if (m_window
&& m_window
->GetBackingPixmap())
931 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1
932 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetBitmap().GetDepth() == 1)
934 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
935 source
->LogicalToDeviceX (xsrc
),
936 source
->LogicalToDeviceY (ysrc
),
937 source
->LogicalToDeviceXRel(width
),
938 source
->LogicalToDeviceYRel(height
),
939 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 1);
943 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
944 source
->LogicalToDeviceX (xsrc
),
945 source
->LogicalToDeviceY (ysrc
),
946 source
->LogicalToDeviceXRel(width
),
947 source
->LogicalToDeviceYRel(height
),
948 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
));
951 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
953 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
954 wxBitmap
& sel
= memDC
->GetBitmap();
955 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetBitmap() )
957 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap());
958 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
962 // Check if we're copying from a mono bitmap
963 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) &&
964 ((wxMemoryDC
*)source
)->GetBitmap().Ok() && (((wxMemoryDC
*)source
)->GetBitmap().GetDepth () == 1))
966 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
967 source
->LogicalToDeviceX (xsrc
),
968 source
->LogicalToDeviceY (ysrc
),
969 source
->LogicalToDeviceXRel(width
),
970 source
->LogicalToDeviceYRel(height
),
971 XLOG2DEV (xdest
), YLOG2DEV (ydest
), 1);
975 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
976 source
->LogicalToDeviceX (xsrc
),
977 source
->LogicalToDeviceY (ysrc
),
978 source
->LogicalToDeviceXRel(width
),
979 source
->LogicalToDeviceYRel(height
),
980 XLOG2DEV (xdest
), YLOG2DEV (ydest
));
986 XSetRegion ((Display
*) m_display
, (GC
) m_gc
,
987 (Region
) m_clipRegion
);
989 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
991 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
994 } /* Remote/local (Display*) m_display */
995 CalcBoundingBox (xdest
, ydest
);
996 CalcBoundingBox (xdest
+ width
, ydest
+ height
);
998 SetLogicalFunction(orig
);
1002 if (scaledBitmap
) delete scaledBitmap
;
1004 if (oldBackgroundPixel
> -1)
1006 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
);
1007 if (m_window
&& m_window
->GetBackingPixmap())
1008 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1009 oldBackgroundPixel
);
1011 if (oldForegroundPixel
> -1)
1013 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
);
1014 if (m_window
&& m_window
->GetBackingPixmap())
1015 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1016 oldForegroundPixel
);
1022 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1024 wxCHECK_RET( Ok(), "invalid dc" );
1026 // Since X draws from the baseline of the text, must add the text height
1032 // Set FillStyle, otherwise X will use current stipple!
1033 XGCValues gcV
, gcBackingV
;
1035 XGetGCValues ((Display
*) m_display
, (GC
)m_gc
, GCFillStyle
, &gcV
);
1036 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1037 if (m_window
&& m_window
->GetBackingPixmap())
1039 XGetGCValues ((Display
*) m_display
, (GC
)m_gcBacking
, GCFillStyle
,
1041 XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
, FillSolid
);
1044 slen
= strlen(text
);
1048 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1049 int direction
, descent
;
1050 XCharStruct overall_return
;
1053 (void)XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*)(const char*) text
, slen
, &direction
,
1054 &ascent
, &descent
, &overall_return
);
1057 (void)XTextExtents((XFontStruct
*) pFontStruct
,
1058 wxConstCast(text
.c_str(), char),
1060 &ascent
, &descent
, &overall_return
);
1062 cx
= overall_return
.width
;
1063 cy
= ascent
+ descent
;
1066 // First draw a rectangle representing the text background, if a text
1067 // background is specified
1068 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1070 wxColour oldPenColour
= m_currentColour
;
1071 m_currentColour
= m_textBackgroundColour
;
1072 bool sameColour
= (oldPenColour
.Ok () && m_textBackgroundColour
.Ok () &&
1073 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1074 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1075 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1077 // This separation of the big && test required for gcc2.7/HP UX 9.02
1078 // or pixel value can be corrupted!
1079 sameColour
= (sameColour
&&
1080 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1082 if (!sameColour
|| !GetOptimization())
1084 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1085 m_currentColour
= m_textBackgroundColour
;
1087 // Set the GC to the required colour
1090 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1091 if (m_window
&& m_window
->GetBackingPixmap())
1092 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1096 m_textBackgroundColour
= oldPenColour
;
1098 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1099 if (m_window
&& m_window
->GetBackingPixmap())
1100 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1101 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1104 // Now set the text foreground and draw the text
1105 if (m_textForegroundColour
.Ok ())
1107 wxColour oldPenColour
= m_currentColour
;
1108 m_currentColour
= m_textForegroundColour
;
1109 bool sameColour
= (oldPenColour
.Ok () && m_currentColour
.Ok () &&
1110 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1111 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1112 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1113 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1115 if (!sameColour
|| !GetOptimization())
1117 int pixel
= CalculatePixel(m_textForegroundColour
,
1118 m_currentColour
, FALSE
);
1120 // Set the GC to the required colour
1123 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1124 if (m_window
&& m_window
->GetBackingPixmap())
1125 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1129 m_textForegroundColour
= oldPenColour
;
1132 // We need to add the ascent, not the whole height, since X draws at the
1133 // point above the descender.
1136 XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1137 (XChar2b
*)(char*) (const char*) text
, slen
);
1140 XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
, text
, slen
);
1142 if (m_window
&& m_window
->GetBackingPixmap()) {
1145 XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1146 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1147 (XChar2b
*)(char*) (const char*) text
, slen
);
1150 XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1151 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1152 wxConstCast(text
.c_str(), char), slen
);
1155 // restore fill style
1156 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, gcV
.fill_style
);
1157 if (m_window
&& m_window
->GetBackingPixmap())
1158 XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
,
1159 gcBackingV
.fill_style
);
1162 GetTextExtent (text
, &w
, &h
);
1163 CalcBoundingBox (x
+ w
, y
+ h
);
1164 CalcBoundingBox (x
, y
);
1167 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
,
1172 DrawText(text
, x
, y
);
1176 wxCHECK_RET( Ok(), "invalid dc" );
1178 int oldBackgroundPixel
= -1;
1179 int oldForegroundPixel
= -1;
1180 int foregroundPixel
= -1;
1181 int backgroundPixel
= -1;
1183 if (m_textBackgroundColour
.Ok())
1185 oldBackgroundPixel
= m_backgroundPixel
;
1186 backgroundPixel
= m_textBackgroundColour
.AllocColour(m_display
);
1188 if (m_textForegroundColour
.Ok())
1190 oldForegroundPixel
= m_currentColour
.GetPixel();
1192 if( m_textForegroundColour
.GetPixel() <= -1 )
1193 CalculatePixel( m_textForegroundColour
,
1194 m_textForegroundColour
, TRUE
);
1196 foregroundPixel
= m_textForegroundColour
.GetPixel();
1199 // Since X draws from the baseline of the text, must add the text height
1203 int slen
= text
.length();
1207 // Calculate text extent.
1208 WXFontStructPtr pFontStruct
=
1209 m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1210 int direction
, descent
;
1211 XCharStruct overall_return
;
1214 (void)XTextExtents16((XFontStruct
*) pFontStruct
,
1215 (XChar2b
*)(const char*) text
,
1217 &ascent
, &descent
, &overall_return
);
1220 (void)XTextExtents((XFontStruct
*) pFontStruct
,
1221 wxConstCast(text
.c_str(), char),
1223 &ascent
, &descent
, &overall_return
);
1225 cx
= overall_return
.width
;
1226 cy
= ascent
+ descent
;
1229 wxBitmap
src(cx
, cy
);
1231 dc
.SelectObject(src
);
1232 dc
.SetFont(GetFont());
1233 dc
.SetBackground(*wxWHITE_BRUSH
);
1234 dc
.SetBrush(*wxBLACK_BRUSH
);
1236 dc
.DrawText(text
, 0, 0);
1237 dc
.SetFont(wxNullFont
);
1239 // Calculate the size of the rotated bounding box.
1240 double dx
= cos(angle
/ 180.0 * M_PI
);
1241 double dy
= sin(angle
/ 180.0 * M_PI
);
1242 double x4
= cy
* dy
;
1243 double y4
= cy
* dx
;
1244 double x3
= cx
* dx
;
1245 double y3
= -cx
* dy
;
1246 double x2
= x3
+ x4
;
1247 double y2
= y3
+ y4
;
1251 // Create image from the source bitmap after writing the text into it.
1252 wxImage image
= src
.ConvertToImage();
1254 int minx
= roundmin(0, roundmin(x4
, roundmin(x2
, x3
)));
1255 int miny
= roundmin(0, roundmin(y4
, roundmin(y2
, y3
)));
1256 int maxx
= roundmax(0, roundmax(x4
, roundmax(x2
, x3
)));
1257 int maxy
= roundmax(0, roundmax(y4
, roundmax(y2
, y3
)));
1259 bool lastFore
= false, lastBack
= false;
1261 // This rotates counterclockwise around the top left corner.
1262 for (int rx
= minx
; rx
< maxx
; rx
++)
1264 for (int ry
= miny
; ry
< maxy
; ry
++)
1266 // transform dest coords to source coords
1267 int sx
= (int) (rx
* dx
- ry
* dy
+ 0.5);
1268 int sy
= - (int) (-ry
* dx
- rx
* dy
+ 0.5);
1269 if (sx
>= 0 && sx
< cx
&& sy
>= 0 && sy
< cy
)
1271 bool textPixel
= image
.GetRed(sx
, sy
) == 0;
1273 if (!textPixel
&& m_backgroundMode
!= wxSOLID
)
1276 wxCoord ox
= (wxCoord
) (x1
+ rx
),
1277 oy
= (wxCoord
) (y1
+ ry
);
1278 // draw black pixels, ignore white ones (i.e. transparent b/g)
1279 if (textPixel
&& !lastFore
)
1281 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1286 else if (!textPixel
&& !lastBack
)
1288 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1294 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
,
1295 (GC
) m_gc
, XLOG2DEV (ox
), YLOG2DEV (oy
));
1296 if (m_window
&& m_window
->GetBackingPixmap())
1297 XDrawPoint ((Display
*) m_display
,
1298 (Pixmap
) m_window
->GetBackingPixmap(),
1300 XLOG2DEV_2 (ox
), YLOG2DEV_2 (oy
));
1305 if (oldBackgroundPixel
> -1)
1307 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
);
1308 if (m_window
&& m_window
->GetBackingPixmap())
1309 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1310 oldBackgroundPixel
);
1312 if (oldForegroundPixel
> -1)
1314 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
);
1315 if (m_window
&& m_window
->GetBackingPixmap())
1316 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1317 oldForegroundPixel
);
1320 CalcBoundingBox (minx
, miny
);
1321 CalcBoundingBox (maxx
, maxy
);
1324 bool wxWindowDC::CanGetTextExtent() const
1329 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1330 wxCoord
*descent
, wxCoord
*externalLeading
,
1331 wxFont
*font
) const
1333 wxCHECK_RET( Ok(), "invalid dc" );
1335 wxFont
* theFont
= font
;
1337 theFont
= (wxFont
*)&m_font
; // const_cast
1341 // TODO: this should be an error log function
1342 wxFAIL_MSG("set a valid font before calling GetTextExtent!");
1344 if (width
) *width
= -1;
1345 if (height
) *height
= -1;
1349 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1351 int direction
, ascent
, descent2
;
1352 XCharStruct overall
;
1357 slen
= str16len(string
);
1360 slen
= strlen(string
);
1364 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1365 &ascent
, &descent2
, &overall
);
1368 XTextExtents((XFontStruct
*) pFontStruct
,
1369 wxConstCast(string
.c_str(), char), slen
, &direction
,
1370 &ascent
, &descent2
, &overall
);
1372 if (width
) *width
= XDEV2LOGREL (overall
.width
);
1373 if (height
) *height
= YDEV2LOGREL (ascent
+ descent2
);
1375 *descent
= descent2
;
1376 if (externalLeading
)
1377 *externalLeading
= 0;
1380 wxCoord
wxWindowDC::GetCharWidth() const
1382 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1383 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1385 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
* m_logicalScaleY
, m_display
);
1387 int direction
, ascent
, descent
;
1388 XCharStruct overall
;
1389 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1390 &descent
, &overall
);
1391 return XDEV2LOGREL(overall
.width
);
1394 wxCoord
wxWindowDC::GetCharHeight() const
1396 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1397 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1399 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1401 int direction
, ascent
, descent
;
1402 XCharStruct overall
;
1403 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1404 &descent
, &overall
);
1405 // return XDEV2LOGREL(overall.ascent + overall.descent);
1406 return XDEV2LOGREL(ascent
+ descent
);
1409 void wxWindowDC::DoGetSize( int *width
, int *height
) const
1415 if( m_window
->GetBackingPixmap() )
1417 w
= m_window
->GetPixmapWidth();
1418 h
= m_window
->GetPixmapHeight();
1421 m_window
->GetSize( &w
, &h
);
1424 if( width
) *width
= w
;
1425 if( height
) *height
= h
;
1428 void wxWindowDC::Clear()
1430 wxCHECK_RET( Ok(), "invalid dc" );
1432 wxRect
rect( wxPoint( 0, 0 ), GetSize() );
1436 void wxWindowDC::Clear(const wxRect
& rect
)
1438 wxCHECK_RET( Ok(), "invalid dc" );
1440 int x
= rect
.x
; int y
= rect
.y
;
1441 int w
= rect
.width
; int h
= rect
.height
;
1443 wxBrush saveBrush
= m_brush
;
1444 SetBrush (m_backgroundBrush
);
1446 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1449 if (m_window
&& m_window
->GetBackingPixmap())
1450 XFillRectangle ((Display
*) m_display
,
1451 (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1454 m_brush
= saveBrush
;
1457 void wxWindowDC::SetFont( const wxFont
&font
)
1459 wxCHECK_RET( Ok(), "invalid dc" );
1465 if ((m_oldFont
!= (WXFont
) 0) && ((wxCoord
) m_oldFont
!= -1))
1467 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
1469 if (m_window
&& m_window
->GetBackingPixmap())
1470 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
1475 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1477 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1478 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1480 if (m_window
&& m_window
->GetBackingPixmap())
1481 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1484 void wxWindowDC::SetForegroundPixelWithLogicalFunction(int pixel
)
1486 if (m_logicalFunction
== wxXOR
)
1489 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1490 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1491 pixel
^ values
.background
);
1492 if (m_window
&& m_window
->GetBackingPixmap())
1493 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1494 pixel
^ values
.background
);
1498 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1499 if (m_window
&& m_window
->GetBackingPixmap())
1500 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1504 int wxWindowDC::CalculatePixel(wxColour
& colour
, wxColour
& curCol
,
1505 bool roundToWhite
) const
1507 const unsigned char wp
= (unsigned char)255;
1510 if(!m_colour
) // Mono display
1512 unsigned char red
= colour
.Red ();
1513 unsigned char blue
= colour
.Blue ();
1514 unsigned char green
= colour
.Green ();
1516 if((red
== wp
&& blue
== wp
&& green
== wp
) ||
1517 // not black and roundToWhite was specified
1518 ((red
!= 0 || blue
!= 0 || green
!= 0) && roundToWhite
))
1521 pixel
= (int)WhitePixel((Display
*) m_display
,
1522 DefaultScreen((Display
*) m_display
));
1523 curCol
.SetPixel(pixel
);
1524 colour
.SetPixel(pixel
);
1529 pixel
= (int)BlackPixel((Display
*) m_display
,
1530 DefaultScreen((Display
*) m_display
));
1531 curCol
.SetPixel(pixel
);
1532 colour
.SetPixel(pixel
);
1538 pixel
= colour
.AllocColour((Display
*) m_display
);
1539 curCol
.SetPixel(pixel
);
1545 void wxWindowDC::SetPen( const wxPen
&pen
)
1547 wxCHECK_RET( Ok(), "invalid dc" );
1553 wxBitmap oldStipple
= m_currentStipple
;
1554 int oldStyle
= m_currentStyle
;
1555 int oldFill
= m_currentFill
;
1556 int old_pen_width
= m_currentPenWidth
;
1557 int old_pen_join
= m_currentPenJoin
;
1558 int old_pen_cap
= m_currentPenCap
;
1559 int old_pen_nb_dash
= m_currentPenDashCount
;
1560 wxX11Dash
*old_pen_dash
= m_currentPenDash
;
1562 wxColour oldPenColour
= m_currentColour
;
1563 m_currentColour
= m_pen
.GetColour ();
1564 m_currentStyle
= m_pen
.GetStyle ();
1565 m_currentFill
= m_pen
.GetStyle (); // TODO?
1566 m_currentPenWidth
= m_pen
.GetWidth ();
1567 m_currentPenJoin
= m_pen
.GetJoin ();
1568 m_currentPenCap
= m_pen
.GetCap ();
1569 m_currentPenDashCount
= m_pen
.GetDashCount();
1570 m_currentPenDash
= (wxX11Dash
*)m_pen
.GetDash();
1572 if (m_currentStyle
== wxSTIPPLE
)
1573 m_currentStipple
= * m_pen
.GetStipple ();
1575 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1576 oldFill
== m_currentFill
&&
1577 old_pen_join
== m_currentPenJoin
&&
1578 old_pen_cap
== m_currentPenCap
&&
1579 old_pen_nb_dash
== m_currentPenDashCount
&&
1580 old_pen_dash
== m_currentPenDash
&&
1581 old_pen_width
== m_currentPenWidth
);
1583 bool sameColour
= (oldPenColour
.Ok () &&
1584 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1585 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1586 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1587 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1589 if (!sameStyle
|| !GetOptimization())
1591 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1592 if (scaled_width
< 0)
1598 static const wxX11Dash dotted
[] = {2, 5};
1599 static const wxX11Dash short_dashed
[] = {4, 4};
1600 static const wxX11Dash long_dashed
[] = {4, 8};
1601 static const wxX11Dash dotted_dashed
[] = {6, 6, 2, 6};
1603 // We express dash pattern in pen width unit, so we are
1604 // independent of zoom factor and so on...
1606 const wxX11Dash
*req_dash
;
1608 switch (m_pen
.GetStyle ())
1611 req_nb_dash
= m_currentPenDashCount
;
1612 req_dash
= m_currentPenDash
;
1613 style
= LineOnOffDash
;
1618 style
= LineOnOffDash
;
1622 req_dash
= short_dashed
;
1623 style
= LineOnOffDash
;
1627 req_dash
= long_dashed
;
1628 style
= LineOnOffDash
;
1632 req_dash
= dotted_dashed
;
1633 style
= LineOnOffDash
;
1640 req_dash
= (wxX11Dash
*)NULL
;
1644 if (req_dash
&& req_nb_dash
)
1646 wxX11Dash
*real_req_dash
= new wxX11Dash
[req_nb_dash
];
1649 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1650 for (int i
= 0; i
< req_nb_dash
; i
++)
1651 real_req_dash
[i
] = req_dash
[i
] * factor
;
1652 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1654 if (m_window
&& m_window
->GetBackingPixmap())
1655 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1656 delete[]real_req_dash
;
1660 // No Memory. We use non-scaled dash pattern...
1661 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1663 if (m_window
&& m_window
->GetBackingPixmap())
1664 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1668 switch (m_pen
.GetCap ())
1670 case wxCAP_PROJECTING
:
1671 cap
= CapProjecting
;
1678 cap
= (scaled_width
<= 1) ? CapNotLast
: CapRound
;
1682 switch (m_pen
.GetJoin ())
1696 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1698 if (m_window
&& m_window
->GetBackingPixmap())
1699 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1702 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1706 oldStipple
= wxNullBitmap
; // For later reset!!
1708 switch (m_currentFill
)
1710 case wxBDIAGONAL_HATCH
:
1711 if (bdiag
== (Pixmap
) 0)
1712 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1713 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1714 bdiag_bits
, bdiag_width
, bdiag_height
);
1717 case wxFDIAGONAL_HATCH
:
1718 if (fdiag
== (Pixmap
) 0)
1719 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1720 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1721 fdiag_bits
, fdiag_width
, fdiag_height
);
1725 if (cross
== (Pixmap
) 0)
1726 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1727 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1728 cross_bits
, cross_width
, cross_height
);
1731 case wxHORIZONTAL_HATCH
:
1732 if (horiz
== (Pixmap
) 0)
1733 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1734 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1735 horiz_bits
, horiz_width
, horiz_height
);
1738 case wxVERTICAL_HATCH
:
1739 if (verti
== (Pixmap
) 0)
1740 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1741 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1742 verti_bits
, verti_width
, verti_height
);
1745 case wxCROSSDIAG_HATCH
:
1747 if (cdiag
== (Pixmap
) 0)
1748 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1749 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1750 cdiag_bits
, cdiag_width
, cdiag_height
);
1754 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1756 if (m_window
&& m_window
->GetBackingPixmap())
1757 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1759 else if (m_currentStipple
.Ok()
1760 && ((m_currentStipple
!= oldStipple
) || !GetOptimization()))
1762 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetDrawable());
1764 if (m_window
&& m_window
->GetBackingPixmap())
1765 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetDrawable());
1768 if ((m_currentFill
!= oldFill
) || !GetOptimization())
1772 if (m_currentFill
== wxSTIPPLE
)
1773 fill_style
= FillStippled
;
1774 else if (IS_HATCH (m_currentFill
))
1775 fill_style
= FillStippled
;
1777 fill_style
= FillSolid
;
1778 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1779 if (m_window
&& m_window
->GetBackingPixmap())
1780 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1783 // must test m_logicalFunction, because it involves background!
1784 if (!sameColour
|| !GetOptimization()
1785 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1788 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1789 pixel
= m_backgroundPixel
;
1792 pixel
= CalculatePixel(m_pen
.GetColour(), m_currentColour
, FALSE
);
1795 // Finally, set the GC to the required colour
1797 SetForegroundPixelWithLogicalFunction(pixel
);
1800 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1805 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1807 wxCHECK_RET( Ok(), "invalid dc" );
1811 if (!m_brush
.Ok() || m_brush
.GetStyle () == wxTRANSPARENT
)
1814 int oldFill
= m_currentFill
;
1815 wxBitmap oldStipple
= m_currentStipple
;
1817 m_autoSetting
|= 0x1;
1819 m_currentFill
= m_brush
.GetStyle ();
1820 if (m_currentFill
== wxSTIPPLE
)
1821 m_currentStipple
= * m_brush
.GetStipple ();
1823 wxColour
oldBrushColour(m_currentColour
);
1824 m_currentColour
= m_brush
.GetColour ();
1826 bool sameColour
= (oldBrushColour
.Ok () &&
1827 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1828 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1829 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1830 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1832 int stippleDepth
= -1;
1834 if ((oldFill
!= m_brush
.GetStyle ()) || !GetOptimization())
1836 switch (brush
.GetStyle ())
1841 stippleDepth
= m_currentStipple
.GetDepth();
1843 case wxBDIAGONAL_HATCH
:
1844 case wxCROSSDIAG_HATCH
:
1845 case wxFDIAGONAL_HATCH
:
1847 case wxHORIZONTAL_HATCH
:
1848 case wxVERTICAL_HATCH
:
1850 if (stippleDepth
== -1) stippleDepth
= 1;
1852 // Chris Breeze 23/07/97: use background mode to
1853 // determine whether fill style should be solid or
1855 int style
= stippleDepth
== 1 ?
1856 (m_backgroundMode
== wxSOLID
?
1857 FillOpaqueStippled
: FillStippled
) :
1859 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1860 if (m_window
&& m_window
->GetBackingPixmap())
1861 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1866 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1867 if (m_window
&& m_window
->GetBackingPixmap())
1868 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
,
1873 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1877 switch (m_currentFill
)
1879 case wxBDIAGONAL_HATCH
:
1880 if (bdiag
== (Pixmap
) 0)
1881 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1882 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1883 bdiag_bits
, bdiag_width
, bdiag_height
);
1886 case wxFDIAGONAL_HATCH
:
1887 if (fdiag
== (Pixmap
) 0)
1888 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1889 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1890 fdiag_bits
, fdiag_width
, fdiag_height
);
1894 if (cross
== (Pixmap
) 0)
1895 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1896 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1897 cross_bits
, cross_width
, cross_height
);
1900 case wxHORIZONTAL_HATCH
:
1901 if (horiz
== (Pixmap
) 0)
1902 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1903 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1904 horiz_bits
, horiz_width
, horiz_height
);
1907 case wxVERTICAL_HATCH
:
1908 if (verti
== (Pixmap
) 0)
1909 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1910 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1911 verti_bits
, verti_width
, verti_height
);
1914 case wxCROSSDIAG_HATCH
:
1916 if (cdiag
== (Pixmap
) 0)
1917 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1918 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1919 cdiag_bits
, cdiag_width
, cdiag_height
);
1923 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1925 if (m_window
&& m_window
->GetBackingPixmap())
1926 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1928 // X can forget the stipple value when resizing a window (apparently)
1929 // so always set the stipple.
1930 else if (m_currentFill
!= wxSOLID
&& m_currentFill
!= wxTRANSPARENT
&&
1931 m_currentStipple
.Ok()) // && m_currentStipple != oldStipple)
1933 if (m_currentStipple
.GetDepth() == 1)
1935 XSetStipple ((Display
*) m_display
, (GC
) m_gc
,
1936 (Pixmap
) m_currentStipple
.GetDrawable());
1937 if (m_window
&& m_window
->GetBackingPixmap())
1938 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
,
1939 (Pixmap
) m_currentStipple
.GetDrawable());
1943 XSetTile ((Display
*) m_display
, (GC
) m_gc
,
1944 (Pixmap
) m_currentStipple
.GetDrawable());
1945 if (m_window
&& m_window
->GetBackingPixmap())
1946 XSetTile ((Display
*) m_display
,(GC
) m_gcBacking
,
1947 (Pixmap
) m_currentStipple
.GetDrawable());
1951 // must test m_logicalFunction, because it involves background!
1952 if (!sameColour
|| !GetOptimization() || m_logicalFunction
== wxXOR
)
1954 int pixel
= CalculatePixel(m_brush
.GetColour(), m_currentColour
, TRUE
);
1957 SetForegroundPixelWithLogicalFunction(pixel
);
1960 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1963 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1965 wxCHECK_RET( Ok(), "invalid dc" );
1967 m_backgroundBrush
= brush
;
1969 if (!m_backgroundBrush
.Ok())
1972 m_backgroundPixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
1974 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
1975 // And Blit,... (Any fct that use XCopyPlane, in fact.)
1976 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, m_backgroundPixel
);
1977 if (m_window
&& m_window
->GetBackingPixmap())
1978 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1982 void wxWindowDC::SetLogicalFunction( int function
)
1984 wxCHECK_RET( Ok(), "invalid dc" );
1989 if (m_logicalFunction
== function
)
1995 x_function
= GXclear
;
2001 x_function
= GXinvert
;
2004 x_function
= GXorReverse
;
2007 x_function
= GXandReverse
;
2016 x_function
= GXandInverted
;
2019 x_function
= GXnoop
;
2025 x_function
= GXequiv
;
2028 x_function
= GXcopyInverted
;
2031 x_function
= GXorInverted
;
2034 x_function
= GXnand
;
2041 x_function
= GXcopy
;
2045 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
2046 if (m_window
&& m_window
->GetBackingPixmap())
2047 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
2049 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
2050 /* MATTHEW: [9] Need to redo pen simply */
2051 m_autoSetting
|= 0x2;
2053 m_logicalFunction
= function
;
2057 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2059 wxCHECK_RET( Ok(), "invalid dc" );
2061 m_textForegroundColour
= col
;
2064 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2066 wxCHECK_RET( Ok(), "invalid dc" );
2068 m_textBackgroundColour
= col
;
2071 void wxWindowDC::SetBackgroundMode( int mode
)
2073 m_backgroundMode
= mode
;
2076 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2081 /* Use GetXColormap */
2082 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2083 (Colormap
) palette
.GetXColormap());
2085 /* Use wxGetMainColormap */
2086 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2087 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2091 static void wxCopyRegion( WXRegion src
, WXRegion
& dst
)
2094 dst
= XCreateRegion();
2095 XUnionRegion( (Region
)src
, (Region
)src
, (Region
)dst
);
2098 // Helper function; userRegion is the region set by calling SetClippingRegion
2099 void wxWindowDC::SetDCClipping( WXRegion userRegion
)
2101 bool hasUpdateRegion
= m_window
&& m_window
->GetUpdateRegion().Ok();
2102 // this means that we should start the clip region from scratch,
2103 // or from the update region, if any
2107 XDestroyRegion( (Region
)m_clipRegion
);
2108 m_clipRegion
= (WXRegion
)NULL
;
2110 if( hasUpdateRegion
)
2111 wxCopyRegion( m_window
->GetUpdateRegion().GetX11Region(),
2114 // intersect the user region, if any, with the
2115 // exisiting clip region
2116 else // if( userRegion )
2119 wxCopyRegion( userRegion
, m_clipRegion
);
2121 XIntersectRegion( (Region
)m_clipRegion
,
2122 (Region
)userRegion
, (Region
)m_clipRegion
);
2126 XSetRegion( (Display
*)m_display
, (GC
)m_gc
, (Region
)m_clipRegion
);
2128 XSetClipMask( (Display
*)m_display
, (GC
)m_gc
, None
);
2131 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
,
2132 wxCoord width
, wxCoord height
)
2134 wxDC::DoSetClippingRegion( x
, y
, width
, height
);
2136 wxRegion
temp(x
, y
, width
, height
);
2138 SetDCClipping(temp
.GetX11Region());
2140 // Needs to work differently for Pixmap: without this,
2141 // there's a nasty (Display*) m_display bug. 8/12/94
2142 if (m_window
&& m_window
->GetBackingPixmap())
2144 XRectangle rects
[1];
2145 rects
[0].x
= XLOG2DEV_2(x
);
2146 rects
[0].y
= YLOG2DEV_2(y
);
2147 rects
[0].width
= XLOG2DEVREL(width
);
2148 rects
[0].height
= YLOG2DEVREL(height
);
2149 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
,
2150 0, 0, rects
, 1, Unsorted
);
2154 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2156 wxRect box
= region
.GetBox();
2158 wxDC::DoSetClippingRegion( box
.x
, box
.y
, box
.width
, box
.height
);
2160 SetDCClipping(region
.GetX11Region());
2162 // Needs to work differently for Pixmap: without this,
2163 // there's a nasty (Display*) m_display bug. 8/12/94
2164 if (m_window
&& m_window
->GetBackingPixmap())
2166 XRectangle rects
[1];
2167 rects
[0].x
= XLOG2DEV_2(box
.x
);
2168 rects
[0].y
= YLOG2DEV_2(box
.y
);
2169 rects
[0].width
= XLOG2DEVREL(box
.width
);
2170 rects
[0].height
= YLOG2DEVREL(box
.height
);
2171 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
,
2172 0, 0, rects
, 1, Unsorted
);
2177 void wxWindowDC::DestroyClippingRegion()
2179 wxDC::DestroyClippingRegion();
2181 SetDCClipping(NULL
);
2183 if (m_window
&& m_window
->GetBackingPixmap())
2184 XSetClipMask ((Display
*) m_display
, (GC
) m_gcBacking
, None
);
2187 // Resolution in pixels per logical inch
2188 wxSize
wxWindowDC::GetPPI() const
2191 return wxSize(100, 100);
2194 int wxWindowDC::GetDepth() const
2203 // ----------------------------------------------------------------------------
2205 // ----------------------------------------------------------------------------
2207 wxPaintDC::wxPaintDC(wxWindow
* win
) : wxWindowDC(win
)
2209 // Set the clipping region.to the update region
2210 SetDCClipping((WXRegion
)NULL
);
2213 wxPaintDC::~wxPaintDC()
2216 m_window
->ClearUpdateRegion();
2217 SetDCClipping((WXRegion
)NULL
);
2220 // ----------------------------------------------------------------------------
2221 // private functions
2222 // ----------------------------------------------------------------------------
2225 Used when copying between drawables on different (Display*) m_displays. Not
2226 very fast, but better than giving up.
2229 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
2230 Drawable src
, Drawable dest
,
2233 unsigned int w
, unsigned int h
,
2234 int destx
, int desty
,
2235 bool more
, XImage
**cache
)
2237 XImage
*image
, *destimage
;
2238 Colormap destcm
, srccm
;
2239 static const int CACHE_SIZE
= 256;
2242 unsigned long cachesrc
[CACHE_SIZE
], cachedest
[CACHE_SIZE
];
2243 int k
, cache_pos
, all_cache
;
2245 if (!cache
|| !*cache
)
2246 image
= XGetImage(src_display
, src
, srcx
, srcy
, w
, h
, AllPlanes
, ZPixmap
);
2250 destimage
= XGetImage(dest_display
, dest
, destx
, desty
, w
, h
, AllPlanes
, ZPixmap
);
2252 srccm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) src_display
);
2253 destcm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dest_display
);
2258 for (i
= 0; i
< w
; i
++)
2259 for (j
= 0; j
< h
; j
++) {
2260 unsigned long pixel
;
2263 pixel
= XGetPixel(image
, i
, j
);
2264 for (k
= cache_pos
; k
--; )
2265 if (cachesrc
[k
] == pixel
) {
2266 pixel
= cachedest
[k
];
2270 for (k
= CACHE_SIZE
; k
-- > cache_pos
; )
2271 if (cachesrc
[k
] == pixel
) {
2272 pixel
= cachedest
[k
];
2276 cachesrc
[cache_pos
] = xcol
.pixel
= pixel
;
2277 XQueryColor(src_display
, srccm
, &xcol
);
2278 if (!XAllocColor(dest_display
, destcm
, &xcol
))
2280 cachedest
[cache_pos
] = pixel
= xcol
.pixel
;
2282 if (++cache_pos
>= CACHE_SIZE
) {
2288 XPutPixel(destimage
, i
, j
, pixel
);
2291 XPutImage(dest_display
, dest
, destgc
, destimage
, 0, 0, destx
, desty
, w
, h
);
2292 XDestroyImage(destimage
);
2297 XDestroyImage(image
);
2302 /* Helper function for 16-bit fonts */
2303 static int str16len(const char *s
)
2307 while (s
[0] && s
[1]) {