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
)
94 // IS_HATCH exists for WXWIN_COMPATIBILITY_2_4 only
95 // but wxMotif needs it for its internals here
96 #define IS_HATCH(s) ((s)>=wxFIRST_HATCH && (s)<=wxLAST_HATCH)
99 // FIXME: left over after removal of wxDC::GetOptimization()
100 #define GET_OPTIMIZATION false
102 // ----------------------------------------------------------------------------
104 // ----------------------------------------------------------------------------
106 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
107 Drawable src
, Drawable dest
,
110 unsigned int w
, unsigned int h
,
111 int destx
, int desty
,
112 bool more
, XImage
**cache
);
114 // ============================================================================
116 // ============================================================================
119 * compare two doubles and return the larger rounded
122 static int roundmax(double a
, double b
)
124 return (int)((a
> b
? a
: b
) + 0.5);
128 * compare two doubles and return the smaller rounded
131 static int roundmin(double a
, double b
)
133 return (int)((a
< b
? a
: b
) - 0.5);
137 // ----------------------------------------------------------------------------
139 // ----------------------------------------------------------------------------
141 void wxWindowDC::Init()
144 m_gcBacking
= (WXGC
) 0;
146 m_backgroundPixel
= -1;
147 m_currentPenWidth
= 1;
148 m_currentPenJoin
= -1;
149 m_currentPenDashCount
= -1;
150 m_currentPenDash
= (wxX11Dash
*) NULL
;
153 m_colour
= wxColourDisplay();
154 m_display
= (WXDisplay
*) NULL
;
155 m_pixmap
= (WXPixmap
) 0;
157 m_oldFont
= (WXFont
) 0;
159 m_clipRegion
= (WXRegion
) 0;
162 wxWindowDC::wxWindowDC()
167 wxWindowDC::wxWindowDC( wxWindow
*window
)
169 wxASSERT_MSG( (window
!= (wxWindow
*) NULL
), "You must pass a valid wxWindow to wxWindowDC/wxClientDC/wxPaintDC constructor." );
174 m_font
= window
->GetFont();
177 m_display
= window
->GetXDisplay();
178 m_pixmap
= window
->GetXWindow();
179 Display
* display
= (Display
*) m_display
;
181 XSetWindowColormap (display
, (Pixmap
) m_pixmap
, (Colormap
) wxTheApp
->GetMainColormap(m_display
));
184 gcvalues
.foreground
= BlackPixel (display
, DefaultScreen (display
));
185 gcvalues
.background
= WhitePixel (display
, DefaultScreen (display
));
186 gcvalues
.graphics_exposures
= False
;
187 gcvalues
.subwindow_mode
= IncludeInferiors
;
188 gcvalues
.line_width
= 1;
189 m_gc
= (WXGC
) XCreateGC (display
, RootWindow (display
, DefaultScreen (display
)),
190 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
193 if (m_window
->GetBackingPixmap())
195 m_gcBacking
= (WXGC
) XCreateGC (display
, RootWindow (display
,
196 DefaultScreen (display
)),
197 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
201 m_backgroundPixel
= (int) gcvalues
.background
;
203 // Get the current Font so we can set it back later
205 XGetGCValues((Display
*) m_display
, (GC
) m_gc
, GCFont
, &valReturn
);
206 m_oldFont
= (WXFont
) valReturn
.font
;
208 SetBackground(wxBrush(m_window
->GetBackgroundColour(), wxSOLID
));
211 wxWindowDC::~wxWindowDC()
213 if (m_gc
&& (m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
215 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
217 if (m_window
&& m_window
->GetBackingPixmap())
218 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
222 XFreeGC ((Display
*) m_display
, (GC
) m_gc
);
226 XFreeGC ((Display
*) m_display
, (GC
) m_gcBacking
);
227 m_gcBacking
= (WXGC
) 0;
230 XDestroyRegion ((Region
) m_clipRegion
);
231 m_clipRegion
= (WXRegion
) 0;
234 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
235 const wxColour
& col
, int style
);
237 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
238 const wxColour
& col
, int style
)
240 return wxDoFloodFill(this, x
, y
, col
, style
);
243 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
245 // Generic (and therefore rather inefficient) method.
246 // Could be improved.
248 wxBitmap
bitmap(1, 1);
249 memdc
.SelectObject(bitmap
);
250 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
251 memdc
.SelectObject(wxNullBitmap
);
252 wxImage image
= bitmap
.ConvertToImage();
253 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
257 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
259 wxCHECK_RET( Ok(), "invalid dc" );
261 int x1d
, y1d
, x2d
, y2d
;
271 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x1d
, y1d
, x2d
, y2d
);
273 if (m_window
&& m_window
->GetBackingPixmap())
274 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
275 XLOG2DEV_2(x1
), YLOG2DEV_2(y1
),
276 XLOG2DEV_2(x2
), YLOG2DEV_2(y2
));
278 CalcBoundingBox(x1
, y1
);
279 CalcBoundingBox(x2
, y2
);
282 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
284 wxCHECK_RET( Ok(), "invalid dc" );
289 int xx
= XLOG2DEV (x
);
290 int yy
= YLOG2DEV (y
);
292 wxDisplaySize (&ww
, &hh
);
293 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, yy
,
295 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xx
, 0,
298 if (m_window
&& m_window
->GetBackingPixmap())
302 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
305 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
311 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
313 wxCHECK_RET( Ok(), "invalid dc" );
315 int xx1
= XLOG2DEV (x1
);
316 int yy1
= YLOG2DEV (y1
);
317 int xx2
= XLOG2DEV (x2
);
318 int yy2
= YLOG2DEV (y2
);
319 int xxc
= XLOG2DEV (xc
);
320 int yyc
= YLOG2DEV (yc
);
321 int xxc_2
= XLOG2DEV_2 (xc
);
322 int yyc_2
= YLOG2DEV_2 (yc
);
324 wxCoord dx
= xx1
- xxc
;
325 wxCoord dy
= yy1
- yyc
;
326 double radius
= sqrt ((double)(dx
* dx
+ dy
* dy
));
327 wxCoord r
= (wxCoord
) radius
;
329 double radius1
, radius2
;
331 if (xx1
== xx2
&& yy1
== yy2
)
336 else if (radius
== 0.0)
337 radius1
= radius2
= 0.0;
346 radius1
= -atan2 ((double) (yy1
- yyc
), (double) (xx1
- xxc
)) * 360.0 / (2 * M_PI
);
354 radius2
= -atan2 ((double) (yy2
- yyc
), (double) (xx2
- xxc
)) * 360.0 / (2 * M_PI
);
358 int alpha1
= (int) radius1
;
359 int alpha2
= (int) (radius2
- radius1
);
362 while (alpha2
> 360 * 64)
365 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
368 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) (GC
) m_gc
,
369 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
371 if (m_window
&& m_window
->GetBackingPixmap())
372 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
373 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
377 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
381 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
382 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
384 if (m_window
&& m_window
->GetBackingPixmap())
385 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
386 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
388 CalcBoundingBox (x1
, y1
);
389 CalcBoundingBox (x2
, y2
);
392 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
394 wxCHECK_RET( Ok(), "invalid dc" );
400 wd
= XLOG2DEVREL(width
);
401 hd
= YLOG2DEVREL(height
);
403 if (sa
>=360 || sa
<=-360) sa
=sa
-int(sa
/360)*360;
404 if (ea
>=360 || ea
<=-360) ea
=ea
-int(ea
/360)*360;
405 int start
= int(sa
*64);
406 int end
= int(ea
*64);
407 if (start
<0) start
+=360*64;
408 if (end
<0) end
+=360*64;
409 if (end
>start
) end
-=start
;
410 else end
+=360*64-start
;
412 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
414 m_autoSetting
= TRUE
; // must be reset
417 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
, end
);
419 if (m_window
&& m_window
->GetBackingPixmap())
420 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
421 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
424 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
428 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
,end
);
429 if (m_window
&& m_window
->GetBackingPixmap())
430 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
431 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
433 CalcBoundingBox (x
, y
);
434 CalcBoundingBox (x
+ width
, y
+ height
);
437 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
439 wxCHECK_RET( Ok(), "invalid dc" );
441 if (m_pen
.Ok() && m_autoSetting
)
444 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
));
445 if (m_window
&& m_window
->GetBackingPixmap())
446 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, XLOG2DEV_2 (x
), YLOG2DEV_2 (y
));
448 CalcBoundingBox (x
, y
);
451 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
453 wxCHECK_RET( Ok(), "invalid dc" );
455 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
460 XPoint
*xpoints
= new XPoint
[n
];
463 for (i
= 0; i
< n
; i
++)
465 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
466 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
468 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints
, n
, 0);
470 if (m_window
&& m_window
->GetBackingPixmap())
472 for (i
= 0; i
< n
; i
++)
474 xpoints
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
475 xpoints
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
477 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints
, n
, 0);
483 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
484 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
486 wxCHECK_RET( Ok(), "invalid dc" );
488 XPoint
*xpoints1
= new XPoint
[n
+ 1];
489 XPoint
*xpoints2
= new XPoint
[n
+ 1];
491 for (i
= 0; i
< n
; i
++)
493 xpoints1
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
494 xpoints1
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
495 xpoints2
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
496 xpoints2
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
497 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
500 // Close figure for XDrawLines (not needed for XFillPolygon)
501 xpoints1
[i
].x
= xpoints1
[0].x
;
502 xpoints1
[i
].y
= xpoints1
[0].y
;
503 xpoints2
[i
].x
= xpoints2
[0].x
;
504 xpoints2
[i
].y
= xpoints2
[0].y
;
506 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
509 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
510 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
, Complex
, 0);
511 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, EvenOddRule
); // default mode
512 if (m_window
&& m_window
->GetBackingPixmap())
514 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
,
515 fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
516 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
, Complex
, 0);
517 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
, EvenOddRule
); // default mode
521 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
525 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
+ 1, 0);
527 if (m_window
&& m_window
->GetBackingPixmap())
528 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
+ 1, 0);
535 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
537 wxCHECK_RET( Ok(), "invalid dc" );
539 int xd
, yd
, wfd
, hfd
, wd
, hd
;
543 wfd
= XLOG2DEVREL(width
);
545 hfd
= YLOG2DEVREL(height
);
548 if (wfd
== 0 || hfd
== 0) return;
549 if (wd
< 0) { wd
= - wd
; xd
= xd
- wd
; }
550 if (hd
< 0) { hd
= - hd
; yd
= yd
- hd
; }
552 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
555 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wfd
, hfd
);
557 if (m_window
&& m_window
->GetBackingPixmap())
558 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
559 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
563 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
567 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
);
569 if (m_window
&& m_window
->GetBackingPixmap())
570 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
571 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
574 CalcBoundingBox (x
, y
);
575 CalcBoundingBox (x
+ width
, y
+ height
);
578 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
580 wxCHECK_RET( Ok(), "invalid dc" );
582 // If radius is negative, it's a proportion of the smaller dimension.
584 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
586 int xd
= XLOG2DEV (x
);
587 int yd
= YLOG2DEV (y
);
588 int rd
= XLOG2DEVREL ((long) radius
);
589 int wd
= XLOG2DEVREL (width
) - WX_GC_CF
;
590 int hd
= YLOG2DEVREL (height
) - WX_GC_CF
;
595 // If radius is zero use DrawRectangle() instead to avoid
596 // X drawing errors with small radii
599 DrawRectangle( x
, y
, width
, height
);
603 // Draw nothing if transformed w or h is 0
604 if (wd
== 0 || hd
== 0) return;
606 // CMB: adjust size if outline is drawn otherwise the result is
607 // 1 pixel too wide and high
608 if (m_pen
.GetStyle() != wxTRANSPARENT
)
614 // CMB: ensure dd is not larger than rectangle otherwise we
615 // get an hour glass shape
616 if (rw_d
> wd
) rw_d
= wd
;
617 if (rw_d
> hd
) rw_d
= hd
;
620 // For backing pixmap
621 int xd2
= XLOG2DEV_2 (x
);
622 int yd2
= YLOG2DEV_2 (y
);
623 int rd2
= XLOG2DEVREL ((long) radius
);
624 int wd2
= XLOG2DEVREL (width
) ;
625 int hd2
= YLOG2DEVREL (height
) ;
630 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
634 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
636 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
639 // Arcs start from 3 o'clock, positive angles anticlockwise
641 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
642 rw_d
, rh_d
, 90 * 64, 90 * 64);
644 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
645 // rw_d, rh_d, 0, 90 * 64);
646 rw_d
, rh_d
, 0, 91 * 64);
648 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
650 // rw_d, rh_d, 270 * 64, 90 * 64);
651 rw_d
, rh_d
, 269 * 64, 92 * 64);
653 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
654 rw_d
, rh_d
, 180 * 64, 90 * 64);
656 if (m_window
&& m_window
->GetBackingPixmap())
658 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
659 xd2
+ rd2
, yd2
, wd2
- rw_d2
, hd2
);
660 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
661 xd2
, yd2
+ rd2
, wd2
, hd2
- rh_d2
);
663 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
664 xd2
, yd2
, rw_d2
, rh_d2
, 90 * 64, 90 * 64);
665 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
666 xd2
+ wd2
- rw_d2
, yd2
,
667 // rw_d2, rh_d2, 0, 90 * 64);
668 rw_d2
, rh_d2
, 0, 91 * 64);
669 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
672 // rw_d2, rh_d2, 270 * 64, 90 * 64);
673 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
674 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
675 xd2
, yd2
+ hd2
- rh_d2
,
676 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
680 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
683 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
684 xd
+ wd
- rd
+ 1, yd
);
685 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
+ hd
,
686 xd
+ wd
- rd
, yd
+ hd
);
688 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
690 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
, yd
+ rd
,
691 xd
+ wd
, yd
+ hd
- rd
+ 1);
692 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
693 rw_d
, rh_d
, 90 * 64, 90 * 64);
694 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
695 // rw_d, rh_d, 0, 90 * 64);
696 rw_d
, rh_d
, 0, 91 * 64);
697 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
699 rw_d
, rh_d
, 269 * 64, 92 * 64);
700 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
701 rw_d
, rh_d
, 180 * 64, 90 * 64);
703 if (m_window
&& m_window
->GetBackingPixmap())
705 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
707 xd2
+ wd2
- rd2
+ 1, yd2
);
708 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
709 xd2
+ rd2
, yd2
+ hd2
,
710 xd2
+ wd2
- rd2
, yd2
+ hd2
);
712 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
714 xd2
, yd2
+ hd2
- rd2
);
715 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
716 xd2
+ wd2
, yd2
+ rd2
,
717 xd2
+ wd2
, yd2
+ hd2
- rd2
+ 1);
718 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
720 rw_d2
, rh_d2
, 90 * 64, 90 * 64);
721 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
722 xd2
+ wd2
- rw_d2
, yd2
,
723 // rw_d2, rh_d2, 0, 90 * 64);
724 rw_d2
, rh_d2
, 0, 91 * 64);
725 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
728 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
729 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
730 xd2
, yd2
+ hd2
- rh_d2
,
731 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
734 CalcBoundingBox (x
, y
);
735 CalcBoundingBox (x
+ width
, y
+ height
);
738 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
740 wxCHECK_RET( Ok(), "invalid dc" );
742 // Check for negative width and height
755 static const int angle
= 23040;
761 wd
= XLOG2DEVREL(width
) ;
762 hd
= YLOG2DEVREL(height
) ;
764 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
767 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
768 if (m_window
&& m_window
->GetBackingPixmap())
769 XFillArc ((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
);
775 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
779 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
780 if (m_window
&& m_window
->GetBackingPixmap())
781 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
782 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
783 XLOG2DEVREL (width
) - WX_GC_CF
,
784 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
786 CalcBoundingBox (x
, y
);
787 CalcBoundingBox (x
+ width
, y
+ height
);
791 bool wxWindowDC::CanDrawBitmap() const
793 wxCHECK_MSG( Ok(), false, "invalid dc" );
798 // TODO: use scaled Blit e.g. as per John Price's implementation
799 // in Contrib/Utilities
800 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
,
801 wxCoord width
, wxCoord height
,
802 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
,
803 int rop
, bool useMask
,
804 wxCoord xsrcMask
, wxCoord ysrcMask
)
806 wxCHECK_MSG( Ok(), false, "invalid dc" );
808 wxWindowDC
* sourceDC
= wxDynamicCast(source
, wxWindowDC
);
810 wxASSERT_MSG( sourceDC
, "Blit source DC must be wxWindowDC or derived class." );
812 // Be sure that foreground pixels (1) of the Icon will be painted with
813 // foreground colour. [m_textForegroundColour] Background pixels (0)
814 // will be painted with backgound colour (m_textBackgroundColour)
815 // Using ::SetPen is horribly slow, so avoid doing it
816 int oldBackgroundPixel
= -1;
817 int oldForegroundPixel
= -1;
819 if (m_textBackgroundColour
.Ok())
821 oldBackgroundPixel
= m_backgroundPixel
;
822 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
824 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
825 if (m_window
&& m_window
->GetBackingPixmap())
826 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
829 if (m_textForegroundColour
.Ok())
831 oldForegroundPixel
= m_currentColour
.GetPixel();
833 if( m_textForegroundColour
.GetPixel() <= -1 )
834 CalculatePixel( m_textForegroundColour
,
835 m_textForegroundColour
, true);
837 int pixel
= m_textForegroundColour
.GetPixel();
839 SetForegroundPixelWithLogicalFunction(pixel
);
842 // Do bitmap scaling if necessary
844 wxBitmap
*scaledBitmap
= (wxBitmap
*) NULL
;
845 Pixmap sourcePixmap
= (Pixmap
) NULL
;
846 double scaleX
, scaleY
;
847 GetUserScale(& scaleX
, & scaleY
);
850 /* TODO: use the mask origin when drawing transparently */
851 if (xsrcMask
== -1 && ysrcMask
== -1)
853 xsrcMask
= xsrc
; ysrcMask
= ysrc
;
856 // Sorry, can't scale masks just yet
857 if (!useMask
&& (scaleX
!= 1.0 || scaleY
!= 1.0) && sourceDC
->IsKindOf(CLASSINFO(wxMemoryDC
)))
859 wxMemoryDC
* memDC
= (wxMemoryDC
*) sourceDC
;
860 wxBitmap
& bitmap
= memDC
->GetBitmap();
862 wxASSERT_MSG( (bitmap
.Ok()), "Bad source bitmap in wxWindowDC::Blit");
864 wxImage image
= bitmap
.ConvertToImage();
867 sourcePixmap
= (Pixmap
) bitmap
.GetDrawable();
871 int scaledW
= (int) (bitmap
.GetWidth() * scaleX
);
872 int scaledH
= (int) (bitmap
.GetHeight() * scaleY
);
874 image
= image
.Scale(scaledW
, scaledH
);
875 scaledBitmap
= new wxBitmap(image
);
876 sourcePixmap
= (Pixmap
) scaledBitmap
->GetDrawable();
880 sourcePixmap
= (Pixmap
) sourceDC
->m_pixmap
;
882 if (m_pixmap
&& sourcePixmap
)
885 int orig
= m_logicalFunction
;
887 SetLogicalFunction (rop
);
889 if (m_display
!= sourceDC
->m_display
)
891 XImage
*cache
= NULL
;
893 if (m_window
&& m_window
->GetBackingPixmap())
894 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
,
895 (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
897 source
->LogicalToDeviceX (xsrc
),
898 source
->LogicalToDeviceY (ysrc
),
899 source
->LogicalToDeviceXRel(width
),
900 source
->LogicalToDeviceYRel(height
),
901 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
),
904 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
906 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
907 wxBitmap
& sel
= memDC
->GetBitmap();
908 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetBitmap() )
910 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap());
911 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
915 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
916 source
->LogicalToDeviceX (xsrc
),
917 source
->LogicalToDeviceY (ysrc
),
918 source
->LogicalToDeviceXRel(width
),
919 source
->LogicalToDeviceYRel(height
),
920 XLOG2DEV (xdest
), YLOG2DEV (ydest
),
926 XSetRegion ((Display
*) m_display
, (GC
) m_gc
,
927 (Region
) m_clipRegion
);
929 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
931 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
935 { //XGCValues values;
936 //XGetGCValues((Display*)m_display, (GC)m_gc, GCForeground, &values);
938 if (m_window
&& m_window
->GetBackingPixmap())
940 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1
941 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetBitmap().GetDepth() == 1)
943 XCopyPlane ((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
), 1);
952 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
953 source
->LogicalToDeviceX (xsrc
),
954 source
->LogicalToDeviceY (ysrc
),
955 source
->LogicalToDeviceXRel(width
),
956 source
->LogicalToDeviceYRel(height
),
957 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
));
960 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
962 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
963 wxBitmap
& sel
= memDC
->GetBitmap();
964 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetBitmap() )
966 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap());
967 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
971 // Check if we're copying from a mono bitmap
972 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) &&
973 ((wxMemoryDC
*)source
)->GetBitmap().Ok() && (((wxMemoryDC
*)source
)->GetBitmap().GetDepth () == 1))
975 XCopyPlane ((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
), 1);
984 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
985 source
->LogicalToDeviceX (xsrc
),
986 source
->LogicalToDeviceY (ysrc
),
987 source
->LogicalToDeviceXRel(width
),
988 source
->LogicalToDeviceYRel(height
),
989 XLOG2DEV (xdest
), YLOG2DEV (ydest
));
995 XSetRegion ((Display
*) m_display
, (GC
) m_gc
,
996 (Region
) m_clipRegion
);
998 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
1000 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
1003 } /* Remote/local (Display*) m_display */
1004 CalcBoundingBox (xdest
, ydest
);
1005 CalcBoundingBox (xdest
+ width
, ydest
+ height
);
1007 SetLogicalFunction(orig
);
1011 if (scaledBitmap
) delete scaledBitmap
;
1013 if (oldBackgroundPixel
> -1)
1015 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
);
1016 if (m_window
&& m_window
->GetBackingPixmap())
1017 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1018 oldBackgroundPixel
);
1020 if (oldForegroundPixel
> -1)
1022 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
);
1023 if (m_window
&& m_window
->GetBackingPixmap())
1024 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1025 oldForegroundPixel
);
1031 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1033 wxCHECK_RET( Ok(), "invalid dc" );
1035 // Since X draws from the baseline of the text, must add the text height
1041 // Set FillStyle, otherwise X will use current stipple!
1042 XGCValues gcV
, gcBackingV
;
1044 XGetGCValues ((Display
*) m_display
, (GC
)m_gc
, GCFillStyle
, &gcV
);
1045 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1046 if (m_window
&& m_window
->GetBackingPixmap())
1048 XGetGCValues ((Display
*) m_display
, (GC
)m_gcBacking
, GCFillStyle
,
1050 XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
, FillSolid
);
1053 slen
= strlen(text
);
1057 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1058 int direction
, descent
;
1059 XCharStruct overall_return
;
1062 (void)XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*)(const char*) text
, slen
, &direction
,
1063 &ascent
, &descent
, &overall_return
);
1066 (void)XTextExtents((XFontStruct
*) pFontStruct
,
1067 wxConstCast(text
.c_str(), char),
1069 &ascent
, &descent
, &overall_return
);
1071 cx
= overall_return
.width
;
1072 cy
= ascent
+ descent
;
1075 // First draw a rectangle representing the text background, if a text
1076 // background is specified
1077 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1079 wxColour oldPenColour
= m_currentColour
;
1080 m_currentColour
= m_textBackgroundColour
;
1081 bool sameColour
= (oldPenColour
.Ok () && m_textBackgroundColour
.Ok () &&
1082 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1083 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1084 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1086 // This separation of the big && test required for gcc2.7/HP UX 9.02
1087 // or pixel value can be corrupted!
1088 sameColour
= (sameColour
&&
1089 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1091 if (!sameColour
|| !GET_OPTIMIZATION
)
1093 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1094 m_currentColour
= m_textBackgroundColour
;
1096 // Set the GC to the required colour
1099 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1100 if (m_window
&& m_window
->GetBackingPixmap())
1101 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1105 m_textBackgroundColour
= oldPenColour
;
1107 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1108 if (m_window
&& m_window
->GetBackingPixmap())
1109 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1110 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1113 // Now set the text foreground and draw the text
1114 if (m_textForegroundColour
.Ok ())
1116 wxColour oldPenColour
= m_currentColour
;
1117 m_currentColour
= m_textForegroundColour
;
1118 bool sameColour
= (oldPenColour
.Ok () && m_currentColour
.Ok () &&
1119 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1120 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1121 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1122 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1124 if (!sameColour
|| !GET_OPTIMIZATION
)
1126 int pixel
= CalculatePixel(m_textForegroundColour
,
1127 m_currentColour
, false);
1129 // Set the GC to the required colour
1132 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1133 if (m_window
&& m_window
->GetBackingPixmap())
1134 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1138 m_textForegroundColour
= oldPenColour
;
1141 // We need to add the ascent, not the whole height, since X draws at the
1142 // point above the descender.
1145 XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1146 (XChar2b
*)(char*) (const char*) text
, slen
);
1149 XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
, text
, slen
);
1151 if (m_window
&& m_window
->GetBackingPixmap()) {
1154 XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1155 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1156 (XChar2b
*)(char*) (const char*) text
, slen
);
1159 XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1160 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1161 wxConstCast(text
.c_str(), char), slen
);
1164 // restore fill style
1165 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, gcV
.fill_style
);
1166 if (m_window
&& m_window
->GetBackingPixmap())
1167 XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
,
1168 gcBackingV
.fill_style
);
1171 GetTextExtent (text
, &w
, &h
);
1172 CalcBoundingBox (x
+ w
, y
+ h
);
1173 CalcBoundingBox (x
, y
);
1176 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
,
1181 DrawText(text
, x
, y
);
1185 wxCHECK_RET( Ok(), "invalid dc" );
1187 int oldBackgroundPixel
= -1;
1188 int oldForegroundPixel
= -1;
1189 int foregroundPixel
= -1;
1190 int backgroundPixel
= -1;
1192 if (m_textBackgroundColour
.Ok())
1194 oldBackgroundPixel
= m_backgroundPixel
;
1195 backgroundPixel
= m_textBackgroundColour
.AllocColour(m_display
);
1197 if (m_textForegroundColour
.Ok())
1199 oldForegroundPixel
= m_currentColour
.GetPixel();
1201 if( m_textForegroundColour
.GetPixel() <= -1 )
1202 CalculatePixel( m_textForegroundColour
,
1203 m_textForegroundColour
, true);
1205 foregroundPixel
= m_textForegroundColour
.GetPixel();
1208 // Since X draws from the baseline of the text, must add the text height
1212 int slen
= text
.length();
1216 // Calculate text extent.
1217 WXFontStructPtr pFontStruct
=
1218 m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1219 int direction
, descent
;
1220 XCharStruct overall_return
;
1223 (void)XTextExtents16((XFontStruct
*) pFontStruct
,
1224 (XChar2b
*)(const char*) text
,
1226 &ascent
, &descent
, &overall_return
);
1229 (void)XTextExtents((XFontStruct
*) pFontStruct
,
1230 wxConstCast(text
.c_str(), char),
1232 &ascent
, &descent
, &overall_return
);
1234 cx
= overall_return
.width
;
1235 cy
= ascent
+ descent
;
1238 wxBitmap
src(cx
, cy
);
1240 dc
.SelectObject(src
);
1241 dc
.SetFont(GetFont());
1242 dc
.SetBackground(*wxWHITE_BRUSH
);
1243 dc
.SetBrush(*wxBLACK_BRUSH
);
1245 dc
.DrawText(text
, 0, 0);
1246 dc
.SetFont(wxNullFont
);
1248 // Calculate the size of the rotated bounding box.
1249 double dx
= cos(angle
/ 180.0 * M_PI
);
1250 double dy
= sin(angle
/ 180.0 * M_PI
);
1251 double x4
= cy
* dy
;
1252 double y4
= cy
* dx
;
1253 double x3
= cx
* dx
;
1254 double y3
= -cx
* dy
;
1255 double x2
= x3
+ x4
;
1256 double y2
= y3
+ y4
;
1260 // Create image from the source bitmap after writing the text into it.
1261 wxImage image
= src
.ConvertToImage();
1263 int minx
= roundmin(0, roundmin(x4
, roundmin(x2
, x3
)));
1264 int miny
= roundmin(0, roundmin(y4
, roundmin(y2
, y3
)));
1265 int maxx
= roundmax(0, roundmax(x4
, roundmax(x2
, x3
)));
1266 int maxy
= roundmax(0, roundmax(y4
, roundmax(y2
, y3
)));
1268 bool lastFore
= false, lastBack
= false;
1270 // This rotates counterclockwise around the top left corner.
1271 for (int rx
= minx
; rx
< maxx
; rx
++)
1273 for (int ry
= miny
; ry
< maxy
; ry
++)
1275 // transform dest coords to source coords
1276 int sx
= (int) (rx
* dx
- ry
* dy
+ 0.5);
1277 int sy
= - (int) (-ry
* dx
- rx
* dy
+ 0.5);
1278 if (sx
>= 0 && sx
< cx
&& sy
>= 0 && sy
< cy
)
1280 bool textPixel
= image
.GetRed(sx
, sy
) == 0;
1282 if (!textPixel
&& m_backgroundMode
!= wxSOLID
)
1285 wxCoord ox
= (wxCoord
) (x1
+ rx
),
1286 oy
= (wxCoord
) (y1
+ ry
);
1287 // draw black pixels, ignore white ones (i.e. transparent b/g)
1288 if (textPixel
&& !lastFore
)
1290 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1295 else if (!textPixel
&& !lastBack
)
1297 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1303 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
,
1304 (GC
) m_gc
, XLOG2DEV (ox
), YLOG2DEV (oy
));
1305 if (m_window
&& m_window
->GetBackingPixmap())
1306 XDrawPoint ((Display
*) m_display
,
1307 (Pixmap
) m_window
->GetBackingPixmap(),
1309 XLOG2DEV_2 (ox
), YLOG2DEV_2 (oy
));
1314 if (oldBackgroundPixel
> -1)
1316 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
);
1317 if (m_window
&& m_window
->GetBackingPixmap())
1318 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1319 oldBackgroundPixel
);
1321 if (oldForegroundPixel
> -1)
1323 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
);
1324 if (m_window
&& m_window
->GetBackingPixmap())
1325 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1326 oldForegroundPixel
);
1329 CalcBoundingBox (minx
, miny
);
1330 CalcBoundingBox (maxx
, maxy
);
1333 bool wxWindowDC::CanGetTextExtent() const
1338 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1339 wxCoord
*descent
, wxCoord
*externalLeading
,
1340 wxFont
*font
) const
1342 wxCHECK_RET( Ok(), "invalid dc" );
1344 wxFont
* theFont
= font
;
1346 theFont
= (wxFont
*)&m_font
; // const_cast
1350 // TODO: this should be an error log function
1351 wxFAIL_MSG("set a valid font before calling GetTextExtent!");
1353 if (width
) *width
= -1;
1354 if (height
) *height
= -1;
1358 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1360 int direction
, ascent
, descent2
;
1361 XCharStruct overall
;
1366 slen
= str16len(string
);
1369 slen
= strlen(string
);
1373 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1374 &ascent
, &descent2
, &overall
);
1377 XTextExtents((XFontStruct
*) pFontStruct
,
1378 wxConstCast(string
.c_str(), char), slen
, &direction
,
1379 &ascent
, &descent2
, &overall
);
1381 if (width
) *width
= XDEV2LOGREL (overall
.width
);
1382 if (height
) *height
= YDEV2LOGREL (ascent
+ descent2
);
1384 *descent
= descent2
;
1385 if (externalLeading
)
1386 *externalLeading
= 0;
1389 wxCoord
wxWindowDC::GetCharWidth() const
1391 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1392 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1394 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
* m_logicalScaleY
, m_display
);
1396 int direction
, ascent
, descent
;
1397 XCharStruct overall
;
1398 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1399 &descent
, &overall
);
1400 return XDEV2LOGREL(overall
.width
);
1403 wxCoord
wxWindowDC::GetCharHeight() const
1405 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1406 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1408 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1410 int direction
, ascent
, descent
;
1411 XCharStruct overall
;
1412 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1413 &descent
, &overall
);
1414 // return XDEV2LOGREL(overall.ascent + overall.descent);
1415 return XDEV2LOGREL(ascent
+ descent
);
1418 void wxWindowDC::DoGetSize( int *width
, int *height
) const
1424 if( m_window
->GetBackingPixmap() )
1426 w
= m_window
->GetPixmapWidth();
1427 h
= m_window
->GetPixmapHeight();
1430 m_window
->GetSize( &w
, &h
);
1433 if( width
) *width
= w
;
1434 if( height
) *height
= h
;
1437 void wxWindowDC::Clear()
1439 wxCHECK_RET( Ok(), "invalid dc" );
1441 wxRect
rect( GetSize() );
1445 void wxWindowDC::Clear(const wxRect
& rect
)
1447 wxCHECK_RET( Ok(), "invalid dc" );
1449 int x
= rect
.x
; int y
= rect
.y
;
1450 int w
= rect
.width
; int h
= rect
.height
;
1452 wxBrush saveBrush
= m_brush
;
1453 SetBrush (m_backgroundBrush
);
1455 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1458 if (m_window
&& m_window
->GetBackingPixmap())
1459 XFillRectangle ((Display
*) m_display
,
1460 (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1463 m_brush
= saveBrush
;
1466 void wxWindowDC::SetFont( const wxFont
&font
)
1468 wxCHECK_RET( Ok(), "invalid dc" );
1474 if ((m_oldFont
!= (WXFont
) 0) && ((wxCoord
) m_oldFont
!= -1))
1476 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
1478 if (m_window
&& m_window
->GetBackingPixmap())
1479 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
1484 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1486 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1487 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1489 if (m_window
&& m_window
->GetBackingPixmap())
1490 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1493 void wxWindowDC::SetForegroundPixelWithLogicalFunction(int pixel
)
1495 if (m_logicalFunction
== wxXOR
)
1498 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1499 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1500 pixel
^ values
.background
);
1501 if (m_window
&& m_window
->GetBackingPixmap())
1502 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1503 pixel
^ values
.background
);
1507 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1508 if (m_window
&& m_window
->GetBackingPixmap())
1509 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1513 int wxWindowDC::CalculatePixel(wxColour
& colour
, wxColour
& curCol
,
1514 bool roundToWhite
) const
1516 const unsigned char wp
= (unsigned char)255;
1519 if(!m_colour
) // Mono display
1521 unsigned char red
= colour
.Red ();
1522 unsigned char blue
= colour
.Blue ();
1523 unsigned char green
= colour
.Green ();
1525 if((red
== wp
&& blue
== wp
&& green
== wp
) ||
1526 // not black and roundToWhite was specified
1527 ((red
!= 0 || blue
!= 0 || green
!= 0) && roundToWhite
))
1530 pixel
= (int)WhitePixel((Display
*) m_display
,
1531 DefaultScreen((Display
*) m_display
));
1532 curCol
.SetPixel(pixel
);
1533 colour
.SetPixel(pixel
);
1538 pixel
= (int)BlackPixel((Display
*) m_display
,
1539 DefaultScreen((Display
*) m_display
));
1540 curCol
.SetPixel(pixel
);
1541 colour
.SetPixel(pixel
);
1547 pixel
= colour
.AllocColour((Display
*) m_display
);
1548 curCol
.SetPixel(pixel
);
1554 void wxWindowDC::SetPen( const wxPen
&pen
)
1556 wxCHECK_RET( Ok(), "invalid dc" );
1562 wxBitmap oldStipple
= m_currentStipple
;
1563 int oldStyle
= m_currentStyle
;
1564 int oldFill
= m_currentFill
;
1565 int old_pen_width
= m_currentPenWidth
;
1566 int old_pen_join
= m_currentPenJoin
;
1567 int old_pen_cap
= m_currentPenCap
;
1568 int old_pen_nb_dash
= m_currentPenDashCount
;
1569 wxX11Dash
*old_pen_dash
= m_currentPenDash
;
1571 wxColour oldPenColour
= m_currentColour
;
1572 m_currentColour
= m_pen
.GetColour ();
1573 m_currentStyle
= m_pen
.GetStyle ();
1574 m_currentFill
= m_pen
.GetStyle (); // TODO?
1575 m_currentPenWidth
= m_pen
.GetWidth ();
1576 m_currentPenJoin
= m_pen
.GetJoin ();
1577 m_currentPenCap
= m_pen
.GetCap ();
1578 m_currentPenDashCount
= m_pen
.GetDashCount();
1579 m_currentPenDash
= (wxX11Dash
*)m_pen
.GetDash();
1581 if (m_currentStyle
== wxSTIPPLE
)
1582 m_currentStipple
= * m_pen
.GetStipple ();
1584 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1585 oldFill
== m_currentFill
&&
1586 old_pen_join
== m_currentPenJoin
&&
1587 old_pen_cap
== m_currentPenCap
&&
1588 old_pen_nb_dash
== m_currentPenDashCount
&&
1589 old_pen_dash
== m_currentPenDash
&&
1590 old_pen_width
== m_currentPenWidth
);
1592 bool sameColour
= (oldPenColour
.Ok () &&
1593 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1594 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1595 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1596 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1598 if (!sameStyle
|| !GET_OPTIMIZATION
)
1600 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1601 if (scaled_width
< 0)
1607 static const wxX11Dash dotted
[] = {2, 5};
1608 static const wxX11Dash short_dashed
[] = {4, 4};
1609 static const wxX11Dash long_dashed
[] = {4, 8};
1610 static const wxX11Dash dotted_dashed
[] = {6, 6, 2, 6};
1612 // We express dash pattern in pen width unit, so we are
1613 // independent of zoom factor and so on...
1615 const wxX11Dash
*req_dash
;
1617 switch (m_pen
.GetStyle ())
1620 req_nb_dash
= m_currentPenDashCount
;
1621 req_dash
= m_currentPenDash
;
1622 style
= LineOnOffDash
;
1627 style
= LineOnOffDash
;
1631 req_dash
= short_dashed
;
1632 style
= LineOnOffDash
;
1636 req_dash
= long_dashed
;
1637 style
= LineOnOffDash
;
1641 req_dash
= dotted_dashed
;
1642 style
= LineOnOffDash
;
1649 req_dash
= (wxX11Dash
*)NULL
;
1653 if (req_dash
&& req_nb_dash
)
1655 wxX11Dash
*real_req_dash
= new wxX11Dash
[req_nb_dash
];
1658 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1659 for (int i
= 0; i
< req_nb_dash
; i
++)
1660 real_req_dash
[i
] = req_dash
[i
] * factor
;
1661 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1663 if (m_window
&& m_window
->GetBackingPixmap())
1664 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1665 delete[]real_req_dash
;
1669 // No Memory. We use non-scaled dash pattern...
1670 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1672 if (m_window
&& m_window
->GetBackingPixmap())
1673 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1677 switch (m_pen
.GetCap ())
1679 case wxCAP_PROJECTING
:
1680 cap
= CapProjecting
;
1687 cap
= (scaled_width
<= 1) ? CapNotLast
: CapRound
;
1691 switch (m_pen
.GetJoin ())
1705 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1707 if (m_window
&& m_window
->GetBackingPixmap())
1708 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1711 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GET_OPTIMIZATION
))
1715 oldStipple
= wxNullBitmap
; // For later reset!!
1717 switch (m_currentFill
)
1719 case wxBDIAGONAL_HATCH
:
1720 if (bdiag
== (Pixmap
) 0)
1721 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1722 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1723 bdiag_bits
, bdiag_width
, bdiag_height
);
1726 case wxFDIAGONAL_HATCH
:
1727 if (fdiag
== (Pixmap
) 0)
1728 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1729 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1730 fdiag_bits
, fdiag_width
, fdiag_height
);
1734 if (cross
== (Pixmap
) 0)
1735 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1736 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1737 cross_bits
, cross_width
, cross_height
);
1740 case wxHORIZONTAL_HATCH
:
1741 if (horiz
== (Pixmap
) 0)
1742 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1743 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1744 horiz_bits
, horiz_width
, horiz_height
);
1747 case wxVERTICAL_HATCH
:
1748 if (verti
== (Pixmap
) 0)
1749 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1750 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1751 verti_bits
, verti_width
, verti_height
);
1754 case wxCROSSDIAG_HATCH
:
1756 if (cdiag
== (Pixmap
) 0)
1757 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1758 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1759 cdiag_bits
, cdiag_width
, cdiag_height
);
1763 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1765 if (m_window
&& m_window
->GetBackingPixmap())
1766 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1768 else if (m_currentStipple
.Ok()
1769 && ((m_currentStipple
!= oldStipple
) || !GET_OPTIMIZATION
))
1771 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetDrawable());
1773 if (m_window
&& m_window
->GetBackingPixmap())
1774 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetDrawable());
1777 if ((m_currentFill
!= oldFill
) || !GET_OPTIMIZATION
)
1781 if (m_currentFill
== wxSTIPPLE
)
1782 fill_style
= FillStippled
;
1783 else if (IS_HATCH (m_currentFill
))
1784 fill_style
= FillStippled
;
1786 fill_style
= FillSolid
;
1787 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1788 if (m_window
&& m_window
->GetBackingPixmap())
1789 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1792 // must test m_logicalFunction, because it involves background!
1793 if (!sameColour
|| !GET_OPTIMIZATION
1794 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1797 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1798 pixel
= m_backgroundPixel
;
1801 pixel
= CalculatePixel(m_pen
.GetColour(), m_currentColour
, false);
1804 // Finally, set the GC to the required colour
1806 SetForegroundPixelWithLogicalFunction(pixel
);
1809 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1814 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1816 wxCHECK_RET( Ok(), "invalid dc" );
1820 if (!m_brush
.Ok() || m_brush
.GetStyle () == wxTRANSPARENT
)
1823 int oldFill
= m_currentFill
;
1824 wxBitmap oldStipple
= m_currentStipple
;
1826 m_autoSetting
|= 0x1;
1828 m_currentFill
= m_brush
.GetStyle ();
1829 if (m_currentFill
== wxSTIPPLE
)
1830 m_currentStipple
= * m_brush
.GetStipple ();
1832 wxColour
oldBrushColour(m_currentColour
);
1833 m_currentColour
= m_brush
.GetColour ();
1835 bool sameColour
= (oldBrushColour
.Ok () &&
1836 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1837 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1838 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1839 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1841 int stippleDepth
= -1;
1843 if ((oldFill
!= m_brush
.GetStyle ()) || !GET_OPTIMIZATION
)
1845 switch (brush
.GetStyle ())
1850 stippleDepth
= m_currentStipple
.GetDepth();
1852 case wxBDIAGONAL_HATCH
:
1853 case wxCROSSDIAG_HATCH
:
1854 case wxFDIAGONAL_HATCH
:
1856 case wxHORIZONTAL_HATCH
:
1857 case wxVERTICAL_HATCH
:
1859 if (stippleDepth
== -1) stippleDepth
= 1;
1861 // Chris Breeze 23/07/97: use background mode to
1862 // determine whether fill style should be solid or
1864 int style
= stippleDepth
== 1 ?
1865 (m_backgroundMode
== wxSOLID
?
1866 FillOpaqueStippled
: FillStippled
) :
1868 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1869 if (m_window
&& m_window
->GetBackingPixmap())
1870 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1875 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1876 if (m_window
&& m_window
->GetBackingPixmap())
1877 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
,
1882 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GET_OPTIMIZATION
))
1886 switch (m_currentFill
)
1888 case wxBDIAGONAL_HATCH
:
1889 if (bdiag
== (Pixmap
) 0)
1890 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1891 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1892 bdiag_bits
, bdiag_width
, bdiag_height
);
1895 case wxFDIAGONAL_HATCH
:
1896 if (fdiag
== (Pixmap
) 0)
1897 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1898 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1899 fdiag_bits
, fdiag_width
, fdiag_height
);
1903 if (cross
== (Pixmap
) 0)
1904 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1905 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1906 cross_bits
, cross_width
, cross_height
);
1909 case wxHORIZONTAL_HATCH
:
1910 if (horiz
== (Pixmap
) 0)
1911 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1912 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1913 horiz_bits
, horiz_width
, horiz_height
);
1916 case wxVERTICAL_HATCH
:
1917 if (verti
== (Pixmap
) 0)
1918 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1919 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1920 verti_bits
, verti_width
, verti_height
);
1923 case wxCROSSDIAG_HATCH
:
1925 if (cdiag
== (Pixmap
) 0)
1926 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1927 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1928 cdiag_bits
, cdiag_width
, cdiag_height
);
1932 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1934 if (m_window
&& m_window
->GetBackingPixmap())
1935 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1937 // X can forget the stipple value when resizing a window (apparently)
1938 // so always set the stipple.
1939 else if (m_currentFill
!= wxSOLID
&& m_currentFill
!= wxTRANSPARENT
&&
1940 m_currentStipple
.Ok()) // && m_currentStipple != oldStipple)
1942 if (m_currentStipple
.GetDepth() == 1)
1944 XSetStipple ((Display
*) m_display
, (GC
) m_gc
,
1945 (Pixmap
) m_currentStipple
.GetDrawable());
1946 if (m_window
&& m_window
->GetBackingPixmap())
1947 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
,
1948 (Pixmap
) m_currentStipple
.GetDrawable());
1952 XSetTile ((Display
*) m_display
, (GC
) m_gc
,
1953 (Pixmap
) m_currentStipple
.GetDrawable());
1954 if (m_window
&& m_window
->GetBackingPixmap())
1955 XSetTile ((Display
*) m_display
,(GC
) m_gcBacking
,
1956 (Pixmap
) m_currentStipple
.GetDrawable());
1960 // must test m_logicalFunction, because it involves background!
1961 if (!sameColour
|| !GET_OPTIMIZATION
|| m_logicalFunction
== wxXOR
)
1963 int pixel
= CalculatePixel(m_brush
.GetColour(), m_currentColour
, true);
1966 SetForegroundPixelWithLogicalFunction(pixel
);
1969 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1972 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1974 wxCHECK_RET( Ok(), "invalid dc" );
1976 m_backgroundBrush
= brush
;
1978 if (!m_backgroundBrush
.Ok())
1981 m_backgroundPixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
1983 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
1984 // And Blit,... (Any fct that use XCopyPlane, in fact.)
1985 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, m_backgroundPixel
);
1986 if (m_window
&& m_window
->GetBackingPixmap())
1987 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1991 void wxWindowDC::SetLogicalFunction( int function
)
1993 wxCHECK_RET( Ok(), "invalid dc" );
1998 if (m_logicalFunction
== function
)
2004 x_function
= GXclear
;
2010 x_function
= GXinvert
;
2013 x_function
= GXorReverse
;
2016 x_function
= GXandReverse
;
2025 x_function
= GXandInverted
;
2028 x_function
= GXnoop
;
2034 x_function
= GXequiv
;
2037 x_function
= GXcopyInverted
;
2040 x_function
= GXorInverted
;
2043 x_function
= GXnand
;
2050 x_function
= GXcopy
;
2054 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
2055 if (m_window
&& m_window
->GetBackingPixmap())
2056 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
2058 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
2059 /* MATTHEW: [9] Need to redo pen simply */
2060 m_autoSetting
|= 0x2;
2062 m_logicalFunction
= function
;
2066 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2068 wxCHECK_RET( Ok(), "invalid dc" );
2070 m_textForegroundColour
= col
;
2073 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2075 wxCHECK_RET( Ok(), "invalid dc" );
2077 m_textBackgroundColour
= col
;
2080 void wxWindowDC::SetBackgroundMode( int mode
)
2082 m_backgroundMode
= mode
;
2085 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2090 /* Use GetXColormap */
2091 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2092 (Colormap
) palette
.GetXColormap());
2094 /* Use wxGetMainColormap */
2095 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2096 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2100 static void wxCopyRegion( WXRegion src
, WXRegion
& dst
)
2103 dst
= XCreateRegion();
2104 XUnionRegion( (Region
)src
, (Region
)src
, (Region
)dst
);
2107 // Helper function; userRegion is the region set by calling SetClippingRegion
2108 void wxWindowDC::SetDCClipping( WXRegion userRegion
)
2110 bool hasUpdateRegion
= m_window
&& m_window
->GetUpdateRegion().Ok();
2111 // this means that we should start the clip region from scratch,
2112 // or from the update region, if any
2116 XDestroyRegion( (Region
)m_clipRegion
);
2117 m_clipRegion
= (WXRegion
)NULL
;
2119 if( hasUpdateRegion
)
2120 wxCopyRegion( m_window
->GetUpdateRegion().GetX11Region(),
2123 // intersect the user region, if any, with the
2124 // exisiting clip region
2125 else // if( userRegion )
2128 wxCopyRegion( userRegion
, m_clipRegion
);
2130 XIntersectRegion( (Region
)m_clipRegion
,
2131 (Region
)userRegion
, (Region
)m_clipRegion
);
2135 XSetRegion( (Display
*)m_display
, (GC
)m_gc
, (Region
)m_clipRegion
);
2137 XSetClipMask( (Display
*)m_display
, (GC
)m_gc
, None
);
2140 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
,
2141 wxCoord width
, wxCoord height
)
2143 wxDC::DoSetClippingRegion( x
, y
, width
, height
);
2145 wxRegion
temp(x
, y
, width
, height
);
2147 SetDCClipping(temp
.GetX11Region());
2149 // Needs to work differently for Pixmap: without this,
2150 // there's a nasty (Display*) m_display bug. 8/12/94
2151 if (m_window
&& m_window
->GetBackingPixmap())
2153 XRectangle rects
[1];
2154 rects
[0].x
= XLOG2DEV_2(x
);
2155 rects
[0].y
= YLOG2DEV_2(y
);
2156 rects
[0].width
= XLOG2DEVREL(width
);
2157 rects
[0].height
= YLOG2DEVREL(height
);
2158 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
,
2159 0, 0, rects
, 1, Unsorted
);
2163 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2165 wxRect box
= region
.GetBox();
2167 wxDC::DoSetClippingRegion( box
.x
, box
.y
, box
.width
, box
.height
);
2169 SetDCClipping(region
.GetX11Region());
2171 // Needs to work differently for Pixmap: without this,
2172 // there's a nasty (Display*) m_display bug. 8/12/94
2173 if (m_window
&& m_window
->GetBackingPixmap())
2175 XRectangle rects
[1];
2176 rects
[0].x
= XLOG2DEV_2(box
.x
);
2177 rects
[0].y
= YLOG2DEV_2(box
.y
);
2178 rects
[0].width
= XLOG2DEVREL(box
.width
);
2179 rects
[0].height
= YLOG2DEVREL(box
.height
);
2180 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
,
2181 0, 0, rects
, 1, Unsorted
);
2186 void wxWindowDC::DestroyClippingRegion()
2188 wxDC::DestroyClippingRegion();
2190 SetDCClipping(NULL
);
2192 if (m_window
&& m_window
->GetBackingPixmap())
2193 XSetClipMask ((Display
*) m_display
, (GC
) m_gcBacking
, None
);
2196 // Resolution in pixels per logical inch
2197 wxSize
wxWindowDC::GetPPI() const
2200 return wxSize(100, 100);
2203 int wxWindowDC::GetDepth() const
2212 // ----------------------------------------------------------------------------
2214 // ----------------------------------------------------------------------------
2216 wxPaintDC::wxPaintDC(wxWindow
* win
) : wxWindowDC(win
)
2218 // Set the clipping region.to the update region
2219 SetDCClipping((WXRegion
)NULL
);
2222 wxPaintDC::~wxPaintDC()
2225 m_window
->ClearUpdateRegion();
2226 SetDCClipping((WXRegion
)NULL
);
2229 // ----------------------------------------------------------------------------
2230 // private functions
2231 // ----------------------------------------------------------------------------
2234 Used when copying between drawables on different (Display*) m_displays. Not
2235 very fast, but better than giving up.
2238 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
2239 Drawable src
, Drawable dest
,
2242 unsigned int w
, unsigned int h
,
2243 int destx
, int desty
,
2244 bool more
, XImage
**cache
)
2246 XImage
*image
, *destimage
;
2247 Colormap destcm
, srccm
;
2248 static const int CACHE_SIZE
= 256;
2251 unsigned long cachesrc
[CACHE_SIZE
], cachedest
[CACHE_SIZE
];
2252 int k
, cache_pos
, all_cache
;
2254 if (!cache
|| !*cache
)
2255 image
= XGetImage(src_display
, src
, srcx
, srcy
, w
, h
, AllPlanes
, ZPixmap
);
2259 destimage
= XGetImage(dest_display
, dest
, destx
, desty
, w
, h
, AllPlanes
, ZPixmap
);
2261 srccm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) src_display
);
2262 destcm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dest_display
);
2267 for (i
= 0; i
< w
; i
++)
2268 for (j
= 0; j
< h
; j
++) {
2269 unsigned long pixel
;
2272 pixel
= XGetPixel(image
, i
, j
);
2273 for (k
= cache_pos
; k
--; )
2274 if (cachesrc
[k
] == pixel
) {
2275 pixel
= cachedest
[k
];
2279 for (k
= CACHE_SIZE
; k
-- > cache_pos
; )
2280 if (cachesrc
[k
] == pixel
) {
2281 pixel
= cachedest
[k
];
2285 cachesrc
[cache_pos
] = xcol
.pixel
= pixel
;
2286 XQueryColor(src_display
, srccm
, &xcol
);
2287 if (!XAllocColor(dest_display
, destcm
, &xcol
))
2289 cachedest
[cache_pos
] = pixel
= xcol
.pixel
;
2291 if (++cache_pos
>= CACHE_SIZE
) {
2297 XPutPixel(destimage
, i
, j
, pixel
);
2300 XPutImage(dest_display
, dest
, destgc
, destimage
, 0, 0, destx
, desty
, w
, h
);
2301 XDestroyImage(destimage
);
2306 XDestroyImage(image
);
2311 /* Helper function for 16-bit fonts */
2312 static int str16len(const char *s
)
2316 while (s
[0] && s
[1]) {