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"
55 #pragma message disable nosimpint
59 #pragma message enable nosimpint
62 #include "wx/motif/private.h"
65 #include <float.h> // for M_PI
75 static Pixmap bdiag
, cdiag
, fdiag
, cross
, horiz
, verti
;
77 // ----------------------------------------------------------------------------
79 // ----------------------------------------------------------------------------
81 // Fudge factor (VZ: what??)
84 // ----------------------------------------------------------------------------
86 // ----------------------------------------------------------------------------
88 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
89 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxWindowDC
)
90 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
93 // IS_HATCH exists for WXWIN_COMPATIBILITY_2_4 only
94 // but wxMotif needs it for its internals here
95 #define IS_HATCH(s) ((s)>=wxFIRST_HATCH && (s)<=wxLAST_HATCH)
98 // FIXME: left over after removal of wxDC::GetOptimization()
99 #define GET_OPTIMIZATION false
101 // ----------------------------------------------------------------------------
103 // ----------------------------------------------------------------------------
105 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
106 Drawable src
, Drawable dest
,
109 unsigned int w
, unsigned int h
,
110 int destx
, int desty
,
111 bool more
, XImage
**cache
);
113 // ============================================================================
115 // ============================================================================
118 * compare two doubles and return the larger rounded
121 static int roundmax(double a
, double b
)
123 return (int)((a
> b
? a
: b
) + 0.5);
127 * compare two doubles and return the smaller rounded
130 static int roundmin(double a
, double b
)
132 return (int)((a
< b
? a
: b
) - 0.5);
136 // ----------------------------------------------------------------------------
138 // ----------------------------------------------------------------------------
140 void wxWindowDC::Init()
143 m_gcBacking
= (WXGC
) 0;
145 m_backgroundPixel
= -1;
146 m_currentPenWidth
= 1;
147 m_currentPenJoin
= -1;
148 m_currentPenDashCount
= -1;
149 m_currentPenDash
= (wxX11Dash
*) NULL
;
152 m_colour
= wxColourDisplay();
153 m_display
= (WXDisplay
*) NULL
;
154 m_pixmap
= (WXPixmap
) 0;
156 m_oldFont
= (WXFont
) 0;
158 m_clipRegion
= (WXRegion
) 0;
161 wxWindowDC::wxWindowDC()
166 wxWindowDC::wxWindowDC( wxWindow
*window
)
168 wxASSERT_MSG( (window
!= (wxWindow
*) NULL
), "You must pass a valid wxWindow to wxWindowDC/wxClientDC/wxPaintDC constructor." );
173 m_font
= window
->GetFont();
176 m_display
= window
->GetXDisplay();
177 m_pixmap
= window
->GetXWindow();
178 Display
* display
= (Display
*) m_display
;
180 XSetWindowColormap (display
, (Pixmap
) m_pixmap
, (Colormap
) wxTheApp
->GetMainColormap(m_display
));
183 gcvalues
.foreground
= BlackPixel (display
, DefaultScreen (display
));
184 gcvalues
.background
= WhitePixel (display
, DefaultScreen (display
));
185 gcvalues
.graphics_exposures
= False
;
186 gcvalues
.subwindow_mode
= IncludeInferiors
;
187 gcvalues
.line_width
= 1;
188 m_gc
= (WXGC
) XCreateGC (display
, RootWindow (display
, DefaultScreen (display
)),
189 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
192 if (m_window
->GetBackingPixmap())
194 m_gcBacking
= (WXGC
) XCreateGC (display
, RootWindow (display
,
195 DefaultScreen (display
)),
196 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
200 m_backgroundPixel
= (int) gcvalues
.background
;
202 // Get the current Font so we can set it back later
204 XGetGCValues((Display
*) m_display
, (GC
) m_gc
, GCFont
, &valReturn
);
205 m_oldFont
= (WXFont
) valReturn
.font
;
207 SetBackground(wxBrush(m_window
->GetBackgroundColour(), wxSOLID
));
210 wxWindowDC::~wxWindowDC()
212 if (m_gc
&& (m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
214 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
216 if (m_window
&& m_window
->GetBackingPixmap())
217 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
221 XFreeGC ((Display
*) m_display
, (GC
) m_gc
);
225 XFreeGC ((Display
*) m_display
, (GC
) m_gcBacking
);
226 m_gcBacking
= (WXGC
) 0;
229 XDestroyRegion ((Region
) m_clipRegion
);
230 m_clipRegion
= (WXRegion
) 0;
233 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
234 const wxColour
& col
, int style
);
236 bool wxWindowDC::DoFloodFill(wxCoord x
, wxCoord y
,
237 const wxColour
& col
, int style
)
239 return wxDoFloodFill(this, x
, y
, col
, style
);
242 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
244 // Generic (and therefore rather inefficient) method.
245 // Could be improved.
247 wxBitmap
bitmap(1, 1);
248 memdc
.SelectObject(bitmap
);
249 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
250 memdc
.SelectObject(wxNullBitmap
);
251 wxImage image
= bitmap
.ConvertToImage();
252 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
256 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
258 wxCHECK_RET( Ok(), "invalid dc" );
260 int x1d
, y1d
, x2d
, y2d
;
270 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x1d
, y1d
, x2d
, y2d
);
272 if (m_window
&& m_window
->GetBackingPixmap())
273 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
274 XLOG2DEV_2(x1
), YLOG2DEV_2(y1
),
275 XLOG2DEV_2(x2
), YLOG2DEV_2(y2
));
277 CalcBoundingBox(x1
, y1
);
278 CalcBoundingBox(x2
, y2
);
281 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
283 wxCHECK_RET( Ok(), "invalid dc" );
288 int xx
= XLOG2DEV (x
);
289 int yy
= YLOG2DEV (y
);
291 wxDisplaySize (&ww
, &hh
);
292 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, yy
,
294 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xx
, 0,
297 if (m_window
&& m_window
->GetBackingPixmap())
301 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
304 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
310 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
312 wxCHECK_RET( Ok(), "invalid dc" );
314 int xx1
= XLOG2DEV (x1
);
315 int yy1
= YLOG2DEV (y1
);
316 int xx2
= XLOG2DEV (x2
);
317 int yy2
= YLOG2DEV (y2
);
318 int xxc
= XLOG2DEV (xc
);
319 int yyc
= YLOG2DEV (yc
);
320 int xxc_2
= XLOG2DEV_2 (xc
);
321 int yyc_2
= YLOG2DEV_2 (yc
);
323 wxCoord dx
= xx1
- xxc
;
324 wxCoord dy
= yy1
- yyc
;
325 double radius
= sqrt ((double)(dx
* dx
+ dy
* dy
));
326 wxCoord r
= (wxCoord
) radius
;
328 double radius1
, radius2
;
330 if (xx1
== xx2
&& yy1
== yy2
)
335 else if (radius
== 0.0)
336 radius1
= radius2
= 0.0;
345 radius1
= -atan2 ((double) (yy1
- yyc
), (double) (xx1
- xxc
)) * 360.0 / (2 * M_PI
);
353 radius2
= -atan2 ((double) (yy2
- yyc
), (double) (xx2
- xxc
)) * 360.0 / (2 * M_PI
);
357 int alpha1
= (int) radius1
;
358 int alpha2
= (int) (radius2
- radius1
);
361 while (alpha2
> 360 * 64)
364 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
367 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) (GC
) m_gc
,
368 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
370 if (m_window
&& m_window
->GetBackingPixmap())
371 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
372 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
376 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
380 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
381 xxc
- r
, yyc
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
383 if (m_window
&& m_window
->GetBackingPixmap())
384 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
385 xxc_2
- r
, yyc_2
- r
, 2 * r
, 2 * r
, alpha1
, alpha2
);
387 CalcBoundingBox (x1
, y1
);
388 CalcBoundingBox (x2
, y2
);
391 void wxWindowDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double sa
, double ea
)
393 wxCHECK_RET( Ok(), "invalid dc" );
399 wd
= XLOG2DEVREL(width
);
400 hd
= YLOG2DEVREL(height
);
402 if (sa
>=360 || sa
<=-360) sa
=sa
-int(sa
/360)*360;
403 if (ea
>=360 || ea
<=-360) ea
=ea
-int(ea
/360)*360;
404 int start
= int(sa
*64);
405 int end
= int(ea
*64);
406 if (start
<0) start
+=360*64;
407 if (end
<0) end
+=360*64;
408 if (end
>start
) end
-=start
;
409 else end
+=360*64-start
;
411 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
413 m_autoSetting
= TRUE
; // must be reset
416 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
, end
);
418 if (m_window
&& m_window
->GetBackingPixmap())
419 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
420 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
423 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
427 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, start
,end
);
428 if (m_window
&& m_window
->GetBackingPixmap())
429 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
430 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),wd
,hd
,start
,end
);
432 CalcBoundingBox (x
, y
);
433 CalcBoundingBox (x
+ width
, y
+ height
);
436 void wxWindowDC::DoDrawPoint( wxCoord x
, wxCoord y
)
438 wxCHECK_RET( Ok(), "invalid dc" );
440 if (m_pen
.Ok() && m_autoSetting
)
443 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
));
444 if (m_window
&& m_window
->GetBackingPixmap())
445 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, XLOG2DEV_2 (x
), YLOG2DEV_2 (y
));
447 CalcBoundingBox (x
, y
);
450 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
452 wxCHECK_RET( Ok(), "invalid dc" );
454 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
459 XPoint
*xpoints
= new XPoint
[n
];
462 for (i
= 0; i
< n
; i
++)
464 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
465 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
467 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints
, n
, 0);
469 if (m_window
&& m_window
->GetBackingPixmap())
471 for (i
= 0; i
< n
; i
++)
473 xpoints
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
474 xpoints
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
476 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints
, n
, 0);
482 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
483 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
485 wxCHECK_RET( Ok(), "invalid dc" );
487 XPoint
*xpoints1
= new XPoint
[n
+ 1];
488 XPoint
*xpoints2
= new XPoint
[n
+ 1];
490 for (i
= 0; i
< n
; i
++)
492 xpoints1
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
493 xpoints1
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
494 xpoints2
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
495 xpoints2
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
496 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
499 // Close figure for XDrawLines (not needed for XFillPolygon)
500 xpoints1
[i
].x
= xpoints1
[0].x
;
501 xpoints1
[i
].y
= xpoints1
[0].y
;
502 xpoints2
[i
].x
= xpoints2
[0].x
;
503 xpoints2
[i
].y
= xpoints2
[0].y
;
505 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
508 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
509 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
, Complex
, 0);
510 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, EvenOddRule
); // default mode
511 if (m_window
&& m_window
->GetBackingPixmap())
513 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
,
514 fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
515 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
, Complex
, 0);
516 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
, EvenOddRule
); // default mode
520 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
524 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
+ 1, 0);
526 if (m_window
&& m_window
->GetBackingPixmap())
527 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
+ 1, 0);
534 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
536 wxCHECK_RET( Ok(), "invalid dc" );
538 int xd
, yd
, wfd
, hfd
, wd
, hd
;
542 wfd
= XLOG2DEVREL(width
);
544 hfd
= YLOG2DEVREL(height
);
547 if (wfd
== 0 || hfd
== 0) return;
548 if (wd
< 0) { wd
= - wd
; xd
= xd
- wd
; }
549 if (hd
< 0) { hd
= - hd
; yd
= yd
- hd
; }
551 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
554 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wfd
, hfd
);
556 if (m_window
&& m_window
->GetBackingPixmap())
557 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
558 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
562 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
566 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
);
568 if (m_window
&& m_window
->GetBackingPixmap())
569 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
570 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
573 CalcBoundingBox (x
, y
);
574 CalcBoundingBox (x
+ width
, y
+ height
);
577 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
579 wxCHECK_RET( Ok(), "invalid dc" );
581 // If radius is negative, it's a proportion of the smaller dimension.
583 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
585 int xd
= XLOG2DEV (x
);
586 int yd
= YLOG2DEV (y
);
587 int rd
= XLOG2DEVREL ((long) radius
);
588 int wd
= XLOG2DEVREL (width
) - WX_GC_CF
;
589 int hd
= YLOG2DEVREL (height
) - WX_GC_CF
;
594 // If radius is zero use DrawRectangle() instead to avoid
595 // X drawing errors with small radii
598 DrawRectangle( x
, y
, width
, height
);
602 // Draw nothing if transformed w or h is 0
603 if (wd
== 0 || hd
== 0) return;
605 // CMB: adjust size if outline is drawn otherwise the result is
606 // 1 pixel too wide and high
607 if (m_pen
.GetStyle() != wxTRANSPARENT
)
613 // CMB: ensure dd is not larger than rectangle otherwise we
614 // get an hour glass shape
615 if (rw_d
> wd
) rw_d
= wd
;
616 if (rw_d
> hd
) rw_d
= hd
;
619 // For backing pixmap
620 int xd2
= XLOG2DEV_2 (x
);
621 int yd2
= YLOG2DEV_2 (y
);
622 int rd2
= XLOG2DEVREL ((long) radius
);
623 int wd2
= XLOG2DEVREL (width
) ;
624 int hd2
= YLOG2DEVREL (height
) ;
629 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
633 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
635 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
638 // Arcs start from 3 o'clock, positive angles anticlockwise
640 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
641 rw_d
, rh_d
, 90 * 64, 90 * 64);
643 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
644 // rw_d, rh_d, 0, 90 * 64);
645 rw_d
, rh_d
, 0, 91 * 64);
647 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
649 // rw_d, rh_d, 270 * 64, 90 * 64);
650 rw_d
, rh_d
, 269 * 64, 92 * 64);
652 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
653 rw_d
, rh_d
, 180 * 64, 90 * 64);
655 if (m_window
&& m_window
->GetBackingPixmap())
657 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
658 xd2
+ rd2
, yd2
, wd2
- rw_d2
, hd2
);
659 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
660 xd2
, yd2
+ rd2
, wd2
, hd2
- rh_d2
);
662 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
663 xd2
, yd2
, rw_d2
, rh_d2
, 90 * 64, 90 * 64);
664 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
665 xd2
+ wd2
- rw_d2
, yd2
,
666 // rw_d2, rh_d2, 0, 90 * 64);
667 rw_d2
, rh_d2
, 0, 91 * 64);
668 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
671 // rw_d2, rh_d2, 270 * 64, 90 * 64);
672 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
673 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
674 xd2
, yd2
+ hd2
- rh_d2
,
675 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
679 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
682 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
683 xd
+ wd
- rd
+ 1, yd
);
684 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
+ hd
,
685 xd
+ wd
- rd
, yd
+ hd
);
687 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
689 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
, yd
+ rd
,
690 xd
+ wd
, yd
+ hd
- rd
+ 1);
691 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
692 rw_d
, rh_d
, 90 * 64, 90 * 64);
693 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
694 // rw_d, rh_d, 0, 90 * 64);
695 rw_d
, rh_d
, 0, 91 * 64);
696 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
698 rw_d
, rh_d
, 269 * 64, 92 * 64);
699 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
700 rw_d
, rh_d
, 180 * 64, 90 * 64);
702 if (m_window
&& m_window
->GetBackingPixmap())
704 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
706 xd2
+ wd2
- rd2
+ 1, yd2
);
707 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
708 xd2
+ rd2
, yd2
+ hd2
,
709 xd2
+ wd2
- rd2
, yd2
+ hd2
);
711 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
713 xd2
, yd2
+ hd2
- rd2
);
714 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
715 xd2
+ wd2
, yd2
+ rd2
,
716 xd2
+ wd2
, yd2
+ hd2
- rd2
+ 1);
717 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
719 rw_d2
, rh_d2
, 90 * 64, 90 * 64);
720 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
721 xd2
+ wd2
- rw_d2
, yd2
,
722 // rw_d2, rh_d2, 0, 90 * 64);
723 rw_d2
, rh_d2
, 0, 91 * 64);
724 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
727 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
728 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
729 xd2
, yd2
+ hd2
- rh_d2
,
730 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
733 CalcBoundingBox (x
, y
);
734 CalcBoundingBox (x
+ width
, y
+ height
);
737 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
739 wxCHECK_RET( Ok(), "invalid dc" );
741 // Check for negative width and height
754 static const int angle
= 23040;
760 wd
= XLOG2DEVREL(width
) ;
761 hd
= YLOG2DEVREL(height
) ;
763 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
766 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
767 if (m_window
&& m_window
->GetBackingPixmap())
768 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
769 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
770 XLOG2DEVREL (width
) - WX_GC_CF
,
771 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
774 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
778 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
779 if (m_window
&& m_window
->GetBackingPixmap())
780 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
781 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
782 XLOG2DEVREL (width
) - WX_GC_CF
,
783 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
785 CalcBoundingBox (x
, y
);
786 CalcBoundingBox (x
+ width
, y
+ height
);
790 bool wxWindowDC::CanDrawBitmap() const
792 wxCHECK_MSG( Ok(), false, "invalid dc" );
797 // TODO: use scaled Blit e.g. as per John Price's implementation
798 // in Contrib/Utilities
799 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
,
800 wxCoord width
, wxCoord height
,
801 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
,
802 int rop
, bool useMask
,
803 wxCoord xsrcMask
, wxCoord ysrcMask
)
805 wxCHECK_MSG( Ok(), false, "invalid dc" );
807 wxWindowDC
* sourceDC
= wxDynamicCast(source
, wxWindowDC
);
809 wxASSERT_MSG( sourceDC
, "Blit source DC must be wxWindowDC or derived class." );
811 // Be sure that foreground pixels (1) of the Icon will be painted with
812 // foreground colour. [m_textForegroundColour] Background pixels (0)
813 // will be painted with backgound colour (m_textBackgroundColour)
814 // Using ::SetPen is horribly slow, so avoid doing it
815 int oldBackgroundPixel
= -1;
816 int oldForegroundPixel
= -1;
818 if (m_textBackgroundColour
.Ok())
820 oldBackgroundPixel
= m_backgroundPixel
;
821 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
823 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
824 if (m_window
&& m_window
->GetBackingPixmap())
825 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
828 if (m_textForegroundColour
.Ok())
830 oldForegroundPixel
= m_currentColour
.GetPixel();
832 if( m_textForegroundColour
.GetPixel() <= -1 )
833 CalculatePixel( m_textForegroundColour
,
834 m_textForegroundColour
, true);
836 int pixel
= m_textForegroundColour
.GetPixel();
838 SetForegroundPixelWithLogicalFunction(pixel
);
841 // Do bitmap scaling if necessary
843 wxBitmap
*scaledBitmap
= (wxBitmap
*) NULL
;
844 Pixmap sourcePixmap
= (Pixmap
) NULL
;
845 double scaleX
, scaleY
;
846 GetUserScale(& scaleX
, & scaleY
);
849 /* TODO: use the mask origin when drawing transparently */
850 if (xsrcMask
== -1 && ysrcMask
== -1)
852 xsrcMask
= xsrc
; ysrcMask
= ysrc
;
855 // Sorry, can't scale masks just yet
856 if (!useMask
&& (scaleX
!= 1.0 || scaleY
!= 1.0) && sourceDC
->IsKindOf(CLASSINFO(wxMemoryDC
)))
858 wxMemoryDC
* memDC
= (wxMemoryDC
*) sourceDC
;
859 wxBitmap
& bitmap
= memDC
->GetBitmap();
861 wxASSERT_MSG( (bitmap
.Ok()), "Bad source bitmap in wxWindowDC::Blit");
863 wxImage image
= bitmap
.ConvertToImage();
866 sourcePixmap
= (Pixmap
) bitmap
.GetDrawable();
870 int scaledW
= (int) (bitmap
.GetWidth() * scaleX
);
871 int scaledH
= (int) (bitmap
.GetHeight() * scaleY
);
873 image
= image
.Scale(scaledW
, scaledH
);
874 scaledBitmap
= new wxBitmap(image
);
875 sourcePixmap
= (Pixmap
) scaledBitmap
->GetDrawable();
879 sourcePixmap
= (Pixmap
) sourceDC
->m_pixmap
;
881 if (m_pixmap
&& sourcePixmap
)
884 int orig
= m_logicalFunction
;
886 SetLogicalFunction (rop
);
888 if (m_display
!= sourceDC
->m_display
)
890 XImage
*cache
= NULL
;
892 if (m_window
&& m_window
->GetBackingPixmap())
893 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
,
894 (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
896 source
->LogicalToDeviceX (xsrc
),
897 source
->LogicalToDeviceY (ysrc
),
898 source
->LogicalToDeviceXRel(width
),
899 source
->LogicalToDeviceYRel(height
),
900 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
),
903 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
905 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
906 wxBitmap
& sel
= memDC
->GetBitmap();
907 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetBitmap() )
909 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap());
910 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
914 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
915 source
->LogicalToDeviceX (xsrc
),
916 source
->LogicalToDeviceY (ysrc
),
917 source
->LogicalToDeviceXRel(width
),
918 source
->LogicalToDeviceYRel(height
),
919 XLOG2DEV (xdest
), YLOG2DEV (ydest
),
925 XSetRegion ((Display
*) m_display
, (GC
) m_gc
,
926 (Region
) m_clipRegion
);
928 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
930 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
934 { //XGCValues values;
935 //XGetGCValues((Display*)m_display, (GC)m_gc, GCForeground, &values);
937 if (m_window
&& m_window
->GetBackingPixmap())
939 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1
940 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetBitmap().GetDepth() == 1)
942 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
943 source
->LogicalToDeviceX (xsrc
),
944 source
->LogicalToDeviceY (ysrc
),
945 source
->LogicalToDeviceXRel(width
),
946 source
->LogicalToDeviceYRel(height
),
947 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 1);
951 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
952 source
->LogicalToDeviceX (xsrc
),
953 source
->LogicalToDeviceY (ysrc
),
954 source
->LogicalToDeviceXRel(width
),
955 source
->LogicalToDeviceYRel(height
),
956 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
));
959 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
961 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
962 wxBitmap
& sel
= memDC
->GetBitmap();
963 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetBitmap() )
965 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetBitmap());
966 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
970 // Check if we're copying from a mono bitmap
971 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) &&
972 ((wxMemoryDC
*)source
)->GetBitmap().Ok() && (((wxMemoryDC
*)source
)->GetBitmap().GetDepth () == 1))
974 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
975 source
->LogicalToDeviceX (xsrc
),
976 source
->LogicalToDeviceY (ysrc
),
977 source
->LogicalToDeviceXRel(width
),
978 source
->LogicalToDeviceYRel(height
),
979 XLOG2DEV (xdest
), YLOG2DEV (ydest
), 1);
983 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
984 source
->LogicalToDeviceX (xsrc
),
985 source
->LogicalToDeviceY (ysrc
),
986 source
->LogicalToDeviceXRel(width
),
987 source
->LogicalToDeviceYRel(height
),
988 XLOG2DEV (xdest
), YLOG2DEV (ydest
));
994 XSetRegion ((Display
*) m_display
, (GC
) m_gc
,
995 (Region
) m_clipRegion
);
997 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
999 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
1002 } /* Remote/local (Display*) m_display */
1003 CalcBoundingBox (xdest
, ydest
);
1004 CalcBoundingBox (xdest
+ width
, ydest
+ height
);
1006 SetLogicalFunction(orig
);
1010 if (scaledBitmap
) delete scaledBitmap
;
1012 if (oldBackgroundPixel
> -1)
1014 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
);
1015 if (m_window
&& m_window
->GetBackingPixmap())
1016 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1017 oldBackgroundPixel
);
1019 if (oldForegroundPixel
> -1)
1021 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
);
1022 if (m_window
&& m_window
->GetBackingPixmap())
1023 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1024 oldForegroundPixel
);
1030 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1032 wxCHECK_RET( Ok(), "invalid dc" );
1034 // Since X draws from the baseline of the text, must add the text height
1040 // Set FillStyle, otherwise X will use current stipple!
1041 XGCValues gcV
, gcBackingV
;
1043 XGetGCValues ((Display
*) m_display
, (GC
)m_gc
, GCFillStyle
, &gcV
);
1044 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1045 if (m_window
&& m_window
->GetBackingPixmap())
1047 XGetGCValues ((Display
*) m_display
, (GC
)m_gcBacking
, GCFillStyle
,
1049 XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
, FillSolid
);
1052 slen
= strlen(text
);
1056 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1057 int direction
, descent
;
1058 XCharStruct overall_return
;
1061 (void)XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*)(const char*) text
, slen
, &direction
,
1062 &ascent
, &descent
, &overall_return
);
1065 (void)XTextExtents((XFontStruct
*) pFontStruct
,
1066 wxConstCast(text
.c_str(), char),
1068 &ascent
, &descent
, &overall_return
);
1070 cx
= overall_return
.width
;
1071 cy
= ascent
+ descent
;
1074 // First draw a rectangle representing the text background, if a text
1075 // background is specified
1076 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1078 wxColour oldPenColour
= m_currentColour
;
1079 m_currentColour
= m_textBackgroundColour
;
1080 bool sameColour
= (oldPenColour
.Ok () && m_textBackgroundColour
.Ok () &&
1081 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1082 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1083 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1085 // This separation of the big && test required for gcc2.7/HP UX 9.02
1086 // or pixel value can be corrupted!
1087 sameColour
= (sameColour
&&
1088 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1090 if (!sameColour
|| !GET_OPTIMIZATION
)
1092 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1093 m_currentColour
= m_textBackgroundColour
;
1095 // Set the GC to the required colour
1098 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1099 if (m_window
&& m_window
->GetBackingPixmap())
1100 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1104 m_textBackgroundColour
= oldPenColour
;
1106 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1107 if (m_window
&& m_window
->GetBackingPixmap())
1108 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1109 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1112 // Now set the text foreground and draw the text
1113 if (m_textForegroundColour
.Ok ())
1115 wxColour oldPenColour
= m_currentColour
;
1116 m_currentColour
= m_textForegroundColour
;
1117 bool sameColour
= (oldPenColour
.Ok () && m_currentColour
.Ok () &&
1118 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1119 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1120 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1121 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1123 if (!sameColour
|| !GET_OPTIMIZATION
)
1125 int pixel
= CalculatePixel(m_textForegroundColour
,
1126 m_currentColour
, false);
1128 // Set the GC to the required colour
1131 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1132 if (m_window
&& m_window
->GetBackingPixmap())
1133 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1137 m_textForegroundColour
= oldPenColour
;
1140 // We need to add the ascent, not the whole height, since X draws at the
1141 // point above the descender.
1144 XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1145 (XChar2b
*)(char*) (const char*) text
, slen
);
1148 XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
, text
, slen
);
1150 if (m_window
&& m_window
->GetBackingPixmap()) {
1153 XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1154 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1155 (XChar2b
*)(char*) (const char*) text
, slen
);
1158 XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1159 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1160 wxConstCast(text
.c_str(), char), slen
);
1163 // restore fill style
1164 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, gcV
.fill_style
);
1165 if (m_window
&& m_window
->GetBackingPixmap())
1166 XSetFillStyle ((Display
*) m_display
, (GC
) m_gcBacking
,
1167 gcBackingV
.fill_style
);
1170 GetTextExtent (text
, &w
, &h
);
1171 CalcBoundingBox (x
+ w
, y
+ h
);
1172 CalcBoundingBox (x
, y
);
1175 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
,
1180 DrawText(text
, x
, y
);
1184 wxCHECK_RET( Ok(), "invalid dc" );
1186 int oldBackgroundPixel
= -1;
1187 int oldForegroundPixel
= -1;
1188 int foregroundPixel
= -1;
1189 int backgroundPixel
= -1;
1191 if (m_textBackgroundColour
.Ok())
1193 oldBackgroundPixel
= m_backgroundPixel
;
1194 backgroundPixel
= m_textBackgroundColour
.AllocColour(m_display
);
1196 if (m_textForegroundColour
.Ok())
1198 oldForegroundPixel
= m_currentColour
.GetPixel();
1200 if( m_textForegroundColour
.GetPixel() <= -1 )
1201 CalculatePixel( m_textForegroundColour
,
1202 m_textForegroundColour
, true);
1204 foregroundPixel
= m_textForegroundColour
.GetPixel();
1207 // Since X draws from the baseline of the text, must add the text height
1211 int slen
= text
.length();
1215 // Calculate text extent.
1216 WXFontStructPtr pFontStruct
=
1217 m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1218 int direction
, descent
;
1219 XCharStruct overall_return
;
1222 (void)XTextExtents16((XFontStruct
*) pFontStruct
,
1223 (XChar2b
*)(const char*) text
,
1225 &ascent
, &descent
, &overall_return
);
1228 (void)XTextExtents((XFontStruct
*) pFontStruct
,
1229 wxConstCast(text
.c_str(), char),
1231 &ascent
, &descent
, &overall_return
);
1233 cx
= overall_return
.width
;
1234 cy
= ascent
+ descent
;
1237 wxBitmap
src(cx
, cy
);
1239 dc
.SelectObject(src
);
1240 dc
.SetFont(GetFont());
1241 dc
.SetBackground(*wxWHITE_BRUSH
);
1242 dc
.SetBrush(*wxBLACK_BRUSH
);
1244 dc
.DrawText(text
, 0, 0);
1245 dc
.SetFont(wxNullFont
);
1247 // Calculate the size of the rotated bounding box.
1248 double dx
= cos(angle
/ 180.0 * M_PI
);
1249 double dy
= sin(angle
/ 180.0 * M_PI
);
1250 double x4
= cy
* dy
;
1251 double y4
= cy
* dx
;
1252 double x3
= cx
* dx
;
1253 double y3
= -cx
* dy
;
1254 double x2
= x3
+ x4
;
1255 double y2
= y3
+ y4
;
1259 // Create image from the source bitmap after writing the text into it.
1260 wxImage image
= src
.ConvertToImage();
1262 int minx
= roundmin(0, roundmin(x4
, roundmin(x2
, x3
)));
1263 int miny
= roundmin(0, roundmin(y4
, roundmin(y2
, y3
)));
1264 int maxx
= roundmax(0, roundmax(x4
, roundmax(x2
, x3
)));
1265 int maxy
= roundmax(0, roundmax(y4
, roundmax(y2
, y3
)));
1267 bool lastFore
= false, lastBack
= false;
1269 // This rotates counterclockwise around the top left corner.
1270 for (int rx
= minx
; rx
< maxx
; rx
++)
1272 for (int ry
= miny
; ry
< maxy
; ry
++)
1274 // transform dest coords to source coords
1275 int sx
= (int) (rx
* dx
- ry
* dy
+ 0.5);
1276 int sy
= - (int) (-ry
* dx
- rx
* dy
+ 0.5);
1277 if (sx
>= 0 && sx
< cx
&& sy
>= 0 && sy
< cy
)
1279 bool textPixel
= image
.GetRed(sx
, sy
) == 0;
1281 if (!textPixel
&& m_backgroundMode
!= wxSOLID
)
1284 wxCoord ox
= (wxCoord
) (x1
+ rx
),
1285 oy
= (wxCoord
) (y1
+ ry
);
1286 // draw black pixels, ignore white ones (i.e. transparent b/g)
1287 if (textPixel
&& !lastFore
)
1289 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1294 else if (!textPixel
&& !lastBack
)
1296 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1302 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
,
1303 (GC
) m_gc
, XLOG2DEV (ox
), YLOG2DEV (oy
));
1304 if (m_window
&& m_window
->GetBackingPixmap())
1305 XDrawPoint ((Display
*) m_display
,
1306 (Pixmap
) m_window
->GetBackingPixmap(),
1308 XLOG2DEV_2 (ox
), YLOG2DEV_2 (oy
));
1313 if (oldBackgroundPixel
> -1)
1315 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, oldBackgroundPixel
);
1316 if (m_window
&& m_window
->GetBackingPixmap())
1317 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1318 oldBackgroundPixel
);
1320 if (oldForegroundPixel
> -1)
1322 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, oldForegroundPixel
);
1323 if (m_window
&& m_window
->GetBackingPixmap())
1324 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1325 oldForegroundPixel
);
1328 CalcBoundingBox (minx
, miny
);
1329 CalcBoundingBox (maxx
, maxy
);
1332 bool wxWindowDC::CanGetTextExtent() const
1337 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1338 wxCoord
*descent
, wxCoord
*externalLeading
,
1339 wxFont
*font
) const
1341 wxCHECK_RET( Ok(), "invalid dc" );
1343 wxFont
* theFont
= font
;
1345 theFont
= (wxFont
*)&m_font
; // const_cast
1349 // TODO: this should be an error log function
1350 wxFAIL_MSG("set a valid font before calling GetTextExtent!");
1352 if (width
) *width
= -1;
1353 if (height
) *height
= -1;
1357 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1359 int direction
, ascent
, descent2
;
1360 XCharStruct overall
;
1365 slen
= str16len(string
);
1368 slen
= strlen(string
);
1372 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1373 &ascent
, &descent2
, &overall
);
1376 XTextExtents((XFontStruct
*) pFontStruct
,
1377 wxConstCast(string
.c_str(), char), slen
, &direction
,
1378 &ascent
, &descent2
, &overall
);
1380 if (width
) *width
= XDEV2LOGREL (overall
.width
);
1381 if (height
) *height
= YDEV2LOGREL (ascent
+ descent2
);
1383 *descent
= descent2
;
1384 if (externalLeading
)
1385 *externalLeading
= 0;
1388 wxCoord
wxWindowDC::GetCharWidth() const
1390 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1391 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1393 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
* m_logicalScaleY
, m_display
);
1395 int direction
, ascent
, descent
;
1396 XCharStruct overall
;
1397 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1398 &descent
, &overall
);
1399 return XDEV2LOGREL(overall
.width
);
1402 wxCoord
wxWindowDC::GetCharHeight() const
1404 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1405 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1407 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1409 int direction
, ascent
, descent
;
1410 XCharStruct overall
;
1411 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1412 &descent
, &overall
);
1413 // return XDEV2LOGREL(overall.ascent + overall.descent);
1414 return XDEV2LOGREL(ascent
+ descent
);
1417 void wxWindowDC::DoGetSize( int *width
, int *height
) const
1423 if( m_window
->GetBackingPixmap() )
1425 w
= m_window
->GetPixmapWidth();
1426 h
= m_window
->GetPixmapHeight();
1429 m_window
->GetSize( &w
, &h
);
1432 if( width
) *width
= w
;
1433 if( height
) *height
= h
;
1436 void wxWindowDC::Clear()
1438 wxCHECK_RET( Ok(), "invalid dc" );
1440 wxRect
rect( GetSize() );
1444 void wxWindowDC::Clear(const wxRect
& rect
)
1446 wxCHECK_RET( Ok(), "invalid dc" );
1448 int x
= rect
.x
; int y
= rect
.y
;
1449 int w
= rect
.width
; int h
= rect
.height
;
1451 wxBrush saveBrush
= m_brush
;
1452 SetBrush (m_backgroundBrush
);
1454 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1457 if (m_window
&& m_window
->GetBackingPixmap())
1458 XFillRectangle ((Display
*) m_display
,
1459 (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1462 m_brush
= saveBrush
;
1465 void wxWindowDC::SetFont( const wxFont
&font
)
1467 wxCHECK_RET( Ok(), "invalid dc" );
1473 if ((m_oldFont
!= (WXFont
) 0) && ((wxCoord
) m_oldFont
!= -1))
1475 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
1477 if (m_window
&& m_window
->GetBackingPixmap())
1478 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
1483 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1485 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1486 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1488 if (m_window
&& m_window
->GetBackingPixmap())
1489 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1492 void wxWindowDC::SetForegroundPixelWithLogicalFunction(int pixel
)
1494 if (m_logicalFunction
== wxXOR
)
1497 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1498 XSetForeground ((Display
*) m_display
, (GC
) m_gc
,
1499 pixel
^ values
.background
);
1500 if (m_window
&& m_window
->GetBackingPixmap())
1501 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
,
1502 pixel
^ values
.background
);
1506 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1507 if (m_window
&& m_window
->GetBackingPixmap())
1508 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1512 int wxWindowDC::CalculatePixel(wxColour
& colour
, wxColour
& curCol
,
1513 bool roundToWhite
) const
1515 const unsigned char wp
= (unsigned char)255;
1518 if(!m_colour
) // Mono display
1520 unsigned char red
= colour
.Red ();
1521 unsigned char blue
= colour
.Blue ();
1522 unsigned char green
= colour
.Green ();
1524 if((red
== wp
&& blue
== wp
&& green
== wp
) ||
1525 // not black and roundToWhite was specified
1526 ((red
!= 0 || blue
!= 0 || green
!= 0) && roundToWhite
))
1529 pixel
= (int)WhitePixel((Display
*) m_display
,
1530 DefaultScreen((Display
*) m_display
));
1531 curCol
.SetPixel(pixel
);
1532 colour
.SetPixel(pixel
);
1537 pixel
= (int)BlackPixel((Display
*) m_display
,
1538 DefaultScreen((Display
*) m_display
));
1539 curCol
.SetPixel(pixel
);
1540 colour
.SetPixel(pixel
);
1546 pixel
= colour
.AllocColour((Display
*) m_display
);
1547 curCol
.SetPixel(pixel
);
1553 void wxWindowDC::SetPen( const wxPen
&pen
)
1555 wxCHECK_RET( Ok(), "invalid dc" );
1561 wxBitmap oldStipple
= m_currentStipple
;
1562 int oldStyle
= m_currentStyle
;
1563 int oldFill
= m_currentFill
;
1564 int old_pen_width
= m_currentPenWidth
;
1565 int old_pen_join
= m_currentPenJoin
;
1566 int old_pen_cap
= m_currentPenCap
;
1567 int old_pen_nb_dash
= m_currentPenDashCount
;
1568 wxX11Dash
*old_pen_dash
= m_currentPenDash
;
1570 wxColour oldPenColour
= m_currentColour
;
1571 m_currentColour
= m_pen
.GetColour ();
1572 m_currentStyle
= m_pen
.GetStyle ();
1573 m_currentFill
= m_pen
.GetStyle (); // TODO?
1574 m_currentPenWidth
= m_pen
.GetWidth ();
1575 m_currentPenJoin
= m_pen
.GetJoin ();
1576 m_currentPenCap
= m_pen
.GetCap ();
1577 m_currentPenDashCount
= m_pen
.GetDashCount();
1578 m_currentPenDash
= (wxX11Dash
*)m_pen
.GetDash();
1580 if (m_currentStyle
== wxSTIPPLE
)
1581 m_currentStipple
= * m_pen
.GetStipple ();
1583 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1584 oldFill
== m_currentFill
&&
1585 old_pen_join
== m_currentPenJoin
&&
1586 old_pen_cap
== m_currentPenCap
&&
1587 old_pen_nb_dash
== m_currentPenDashCount
&&
1588 old_pen_dash
== m_currentPenDash
&&
1589 old_pen_width
== m_currentPenWidth
);
1591 bool sameColour
= (oldPenColour
.Ok () &&
1592 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1593 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1594 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1595 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1597 if (!sameStyle
|| !GET_OPTIMIZATION
)
1599 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1600 if (scaled_width
< 0)
1606 static const wxX11Dash dotted
[] = {2, 5};
1607 static const wxX11Dash short_dashed
[] = {4, 4};
1608 static const wxX11Dash long_dashed
[] = {4, 8};
1609 static const wxX11Dash dotted_dashed
[] = {6, 6, 2, 6};
1611 // We express dash pattern in pen width unit, so we are
1612 // independent of zoom factor and so on...
1614 const wxX11Dash
*req_dash
;
1616 switch (m_pen
.GetStyle ())
1619 req_nb_dash
= m_currentPenDashCount
;
1620 req_dash
= m_currentPenDash
;
1621 style
= LineOnOffDash
;
1626 style
= LineOnOffDash
;
1630 req_dash
= short_dashed
;
1631 style
= LineOnOffDash
;
1635 req_dash
= long_dashed
;
1636 style
= LineOnOffDash
;
1640 req_dash
= dotted_dashed
;
1641 style
= LineOnOffDash
;
1648 req_dash
= (wxX11Dash
*)NULL
;
1652 if (req_dash
&& req_nb_dash
)
1654 wxX11Dash
*real_req_dash
= new wxX11Dash
[req_nb_dash
];
1657 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1658 for (int i
= 0; i
< req_nb_dash
; i
++)
1659 real_req_dash
[i
] = req_dash
[i
] * factor
;
1660 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1662 if (m_window
&& m_window
->GetBackingPixmap())
1663 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1664 delete[]real_req_dash
;
1668 // No Memory. We use non-scaled dash pattern...
1669 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1671 if (m_window
&& m_window
->GetBackingPixmap())
1672 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1676 switch (m_pen
.GetCap ())
1678 case wxCAP_PROJECTING
:
1679 cap
= CapProjecting
;
1686 cap
= (scaled_width
<= 1) ? CapNotLast
: CapRound
;
1690 switch (m_pen
.GetJoin ())
1704 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1706 if (m_window
&& m_window
->GetBackingPixmap())
1707 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1710 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GET_OPTIMIZATION
))
1714 oldStipple
= wxNullBitmap
; // For later reset!!
1716 switch (m_currentFill
)
1718 case wxBDIAGONAL_HATCH
:
1719 if (bdiag
== (Pixmap
) 0)
1720 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1721 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1722 bdiag_bits
, bdiag_width
, bdiag_height
);
1725 case wxFDIAGONAL_HATCH
:
1726 if (fdiag
== (Pixmap
) 0)
1727 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1728 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1729 fdiag_bits
, fdiag_width
, fdiag_height
);
1733 if (cross
== (Pixmap
) 0)
1734 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1735 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1736 cross_bits
, cross_width
, cross_height
);
1739 case wxHORIZONTAL_HATCH
:
1740 if (horiz
== (Pixmap
) 0)
1741 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1742 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1743 horiz_bits
, horiz_width
, horiz_height
);
1746 case wxVERTICAL_HATCH
:
1747 if (verti
== (Pixmap
) 0)
1748 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1749 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1750 verti_bits
, verti_width
, verti_height
);
1753 case wxCROSSDIAG_HATCH
:
1755 if (cdiag
== (Pixmap
) 0)
1756 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1757 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1758 cdiag_bits
, cdiag_width
, cdiag_height
);
1762 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1764 if (m_window
&& m_window
->GetBackingPixmap())
1765 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1767 else if (m_currentStipple
.Ok()
1768 && ((m_currentStipple
!= oldStipple
) || !GET_OPTIMIZATION
))
1770 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetDrawable());
1772 if (m_window
&& m_window
->GetBackingPixmap())
1773 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetDrawable());
1776 if ((m_currentFill
!= oldFill
) || !GET_OPTIMIZATION
)
1780 if (m_currentFill
== wxSTIPPLE
)
1781 fill_style
= FillStippled
;
1782 else if (IS_HATCH (m_currentFill
))
1783 fill_style
= FillStippled
;
1785 fill_style
= FillSolid
;
1786 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1787 if (m_window
&& m_window
->GetBackingPixmap())
1788 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1791 // must test m_logicalFunction, because it involves background!
1792 if (!sameColour
|| !GET_OPTIMIZATION
1793 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1796 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1797 pixel
= m_backgroundPixel
;
1800 pixel
= CalculatePixel(m_pen
.GetColour(), m_currentColour
, false);
1803 // Finally, set the GC to the required colour
1805 SetForegroundPixelWithLogicalFunction(pixel
);
1808 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1813 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1815 wxCHECK_RET( Ok(), "invalid dc" );
1819 if (!m_brush
.Ok() || m_brush
.GetStyle () == wxTRANSPARENT
)
1822 int oldFill
= m_currentFill
;
1823 wxBitmap oldStipple
= m_currentStipple
;
1825 m_autoSetting
|= 0x1;
1827 m_currentFill
= m_brush
.GetStyle ();
1828 if (m_currentFill
== wxSTIPPLE
)
1829 m_currentStipple
= * m_brush
.GetStipple ();
1831 wxColour
oldBrushColour(m_currentColour
);
1832 m_currentColour
= m_brush
.GetColour ();
1834 bool sameColour
= (oldBrushColour
.Ok () &&
1835 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1836 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1837 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1838 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1840 int stippleDepth
= -1;
1842 if ((oldFill
!= m_brush
.GetStyle ()) || !GET_OPTIMIZATION
)
1844 switch (brush
.GetStyle ())
1849 stippleDepth
= m_currentStipple
.GetDepth();
1851 case wxBDIAGONAL_HATCH
:
1852 case wxCROSSDIAG_HATCH
:
1853 case wxFDIAGONAL_HATCH
:
1855 case wxHORIZONTAL_HATCH
:
1856 case wxVERTICAL_HATCH
:
1858 if (stippleDepth
== -1) stippleDepth
= 1;
1860 // Chris Breeze 23/07/97: use background mode to
1861 // determine whether fill style should be solid or
1863 int style
= stippleDepth
== 1 ?
1864 (m_backgroundMode
== wxSOLID
?
1865 FillOpaqueStippled
: FillStippled
) :
1867 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1868 if (m_window
&& m_window
->GetBackingPixmap())
1869 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1874 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1875 if (m_window
&& m_window
->GetBackingPixmap())
1876 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
,
1881 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GET_OPTIMIZATION
))
1885 switch (m_currentFill
)
1887 case wxBDIAGONAL_HATCH
:
1888 if (bdiag
== (Pixmap
) 0)
1889 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1890 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1891 bdiag_bits
, bdiag_width
, bdiag_height
);
1894 case wxFDIAGONAL_HATCH
:
1895 if (fdiag
== (Pixmap
) 0)
1896 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1897 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1898 fdiag_bits
, fdiag_width
, fdiag_height
);
1902 if (cross
== (Pixmap
) 0)
1903 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1904 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1905 cross_bits
, cross_width
, cross_height
);
1908 case wxHORIZONTAL_HATCH
:
1909 if (horiz
== (Pixmap
) 0)
1910 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1911 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1912 horiz_bits
, horiz_width
, horiz_height
);
1915 case wxVERTICAL_HATCH
:
1916 if (verti
== (Pixmap
) 0)
1917 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1918 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1919 verti_bits
, verti_width
, verti_height
);
1922 case wxCROSSDIAG_HATCH
:
1924 if (cdiag
== (Pixmap
) 0)
1925 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1926 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1927 cdiag_bits
, cdiag_width
, cdiag_height
);
1931 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1933 if (m_window
&& m_window
->GetBackingPixmap())
1934 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1936 // X can forget the stipple value when resizing a window (apparently)
1937 // so always set the stipple.
1938 else if (m_currentFill
!= wxSOLID
&& m_currentFill
!= wxTRANSPARENT
&&
1939 m_currentStipple
.Ok()) // && m_currentStipple != oldStipple)
1941 if (m_currentStipple
.GetDepth() == 1)
1943 XSetStipple ((Display
*) m_display
, (GC
) m_gc
,
1944 (Pixmap
) m_currentStipple
.GetDrawable());
1945 if (m_window
&& m_window
->GetBackingPixmap())
1946 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
,
1947 (Pixmap
) m_currentStipple
.GetDrawable());
1951 XSetTile ((Display
*) m_display
, (GC
) m_gc
,
1952 (Pixmap
) m_currentStipple
.GetDrawable());
1953 if (m_window
&& m_window
->GetBackingPixmap())
1954 XSetTile ((Display
*) m_display
,(GC
) m_gcBacking
,
1955 (Pixmap
) m_currentStipple
.GetDrawable());
1959 // must test m_logicalFunction, because it involves background!
1960 if (!sameColour
|| !GET_OPTIMIZATION
|| m_logicalFunction
== wxXOR
)
1962 int pixel
= CalculatePixel(m_brush
.GetColour(), m_currentColour
, true);
1965 SetForegroundPixelWithLogicalFunction(pixel
);
1968 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1971 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1973 wxCHECK_RET( Ok(), "invalid dc" );
1975 m_backgroundBrush
= brush
;
1977 if (!m_backgroundBrush
.Ok())
1980 m_backgroundPixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
1982 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
1983 // And Blit,... (Any fct that use XCopyPlane, in fact.)
1984 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, m_backgroundPixel
);
1985 if (m_window
&& m_window
->GetBackingPixmap())
1986 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
,
1990 void wxWindowDC::SetLogicalFunction( int function
)
1992 wxCHECK_RET( Ok(), "invalid dc" );
1997 if (m_logicalFunction
== function
)
2003 x_function
= GXclear
;
2009 x_function
= GXinvert
;
2012 x_function
= GXorReverse
;
2015 x_function
= GXandReverse
;
2024 x_function
= GXandInverted
;
2027 x_function
= GXnoop
;
2033 x_function
= GXequiv
;
2036 x_function
= GXcopyInverted
;
2039 x_function
= GXorInverted
;
2042 x_function
= GXnand
;
2049 x_function
= GXcopy
;
2053 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
2054 if (m_window
&& m_window
->GetBackingPixmap())
2055 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
2057 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
2058 /* MATTHEW: [9] Need to redo pen simply */
2059 m_autoSetting
|= 0x2;
2061 m_logicalFunction
= function
;
2065 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2067 wxCHECK_RET( Ok(), "invalid dc" );
2069 m_textForegroundColour
= col
;
2072 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2074 wxCHECK_RET( Ok(), "invalid dc" );
2076 m_textBackgroundColour
= col
;
2079 void wxWindowDC::SetBackgroundMode( int mode
)
2081 m_backgroundMode
= mode
;
2084 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2089 /* Use GetXColormap */
2090 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2091 (Colormap
) palette
.GetXColormap());
2093 /* Use wxGetMainColormap */
2094 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2095 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2099 static void wxCopyRegion( WXRegion src
, WXRegion
& dst
)
2102 dst
= XCreateRegion();
2103 XUnionRegion( (Region
)src
, (Region
)src
, (Region
)dst
);
2106 // Helper function; userRegion is the region set by calling SetClippingRegion
2107 void wxWindowDC::SetDCClipping( WXRegion userRegion
)
2109 bool hasUpdateRegion
= m_window
&& m_window
->GetUpdateRegion().Ok();
2110 // this means that we should start the clip region from scratch,
2111 // or from the update region, if any
2115 XDestroyRegion( (Region
)m_clipRegion
);
2116 m_clipRegion
= (WXRegion
)NULL
;
2118 if( hasUpdateRegion
)
2119 wxCopyRegion( m_window
->GetUpdateRegion().GetX11Region(),
2122 // intersect the user region, if any, with the
2123 // exisiting clip region
2124 else // if( userRegion )
2127 wxCopyRegion( userRegion
, m_clipRegion
);
2129 XIntersectRegion( (Region
)m_clipRegion
,
2130 (Region
)userRegion
, (Region
)m_clipRegion
);
2134 XSetRegion( (Display
*)m_display
, (GC
)m_gc
, (Region
)m_clipRegion
);
2136 XSetClipMask( (Display
*)m_display
, (GC
)m_gc
, None
);
2139 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
,
2140 wxCoord width
, wxCoord height
)
2142 wxDC::DoSetClippingRegion( x
, y
, width
, height
);
2144 wxRegion
temp(x
, y
, width
, height
);
2146 SetDCClipping(temp
.GetX11Region());
2148 // Needs to work differently for Pixmap: without this,
2149 // there's a nasty (Display*) m_display bug. 8/12/94
2150 if (m_window
&& m_window
->GetBackingPixmap())
2152 XRectangle rects
[1];
2153 rects
[0].x
= XLOG2DEV_2(x
);
2154 rects
[0].y
= YLOG2DEV_2(y
);
2155 rects
[0].width
= XLOG2DEVREL(width
);
2156 rects
[0].height
= YLOG2DEVREL(height
);
2157 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
,
2158 0, 0, rects
, 1, Unsorted
);
2162 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2164 wxRect box
= region
.GetBox();
2166 wxDC::DoSetClippingRegion( box
.x
, box
.y
, box
.width
, box
.height
);
2168 SetDCClipping(region
.GetX11Region());
2170 // Needs to work differently for Pixmap: without this,
2171 // there's a nasty (Display*) m_display bug. 8/12/94
2172 if (m_window
&& m_window
->GetBackingPixmap())
2174 XRectangle rects
[1];
2175 rects
[0].x
= XLOG2DEV_2(box
.x
);
2176 rects
[0].y
= YLOG2DEV_2(box
.y
);
2177 rects
[0].width
= XLOG2DEVREL(box
.width
);
2178 rects
[0].height
= YLOG2DEVREL(box
.height
);
2179 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
,
2180 0, 0, rects
, 1, Unsorted
);
2185 void wxWindowDC::DestroyClippingRegion()
2187 wxDC::DestroyClippingRegion();
2189 SetDCClipping(NULL
);
2191 if (m_window
&& m_window
->GetBackingPixmap())
2192 XSetClipMask ((Display
*) m_display
, (GC
) m_gcBacking
, None
);
2195 // Resolution in pixels per logical inch
2196 wxSize
wxWindowDC::GetPPI() const
2199 return wxSize(100, 100);
2202 int wxWindowDC::GetDepth() const
2211 // ----------------------------------------------------------------------------
2213 // ----------------------------------------------------------------------------
2215 wxPaintDC::wxPaintDC(wxWindow
* win
) : wxWindowDC(win
)
2217 // Set the clipping region.to the update region
2218 SetDCClipping((WXRegion
)NULL
);
2221 wxPaintDC::~wxPaintDC()
2224 m_window
->ClearUpdateRegion();
2225 SetDCClipping((WXRegion
)NULL
);
2228 // ----------------------------------------------------------------------------
2229 // private functions
2230 // ----------------------------------------------------------------------------
2233 Used when copying between drawables on different (Display*) m_displays. Not
2234 very fast, but better than giving up.
2237 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
2238 Drawable src
, Drawable dest
,
2241 unsigned int w
, unsigned int h
,
2242 int destx
, int desty
,
2243 bool more
, XImage
**cache
)
2245 XImage
*image
, *destimage
;
2246 Colormap destcm
, srccm
;
2247 static const int CACHE_SIZE
= 256;
2250 unsigned long cachesrc
[CACHE_SIZE
], cachedest
[CACHE_SIZE
];
2251 int k
, cache_pos
, all_cache
;
2253 if (!cache
|| !*cache
)
2254 image
= XGetImage(src_display
, src
, srcx
, srcy
, w
, h
, AllPlanes
, ZPixmap
);
2258 destimage
= XGetImage(dest_display
, dest
, destx
, desty
, w
, h
, AllPlanes
, ZPixmap
);
2260 srccm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) src_display
);
2261 destcm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dest_display
);
2266 for (i
= 0; i
< w
; i
++)
2267 for (j
= 0; j
< h
; j
++) {
2268 unsigned long pixel
;
2271 pixel
= XGetPixel(image
, i
, j
);
2272 for (k
= cache_pos
; k
--; )
2273 if (cachesrc
[k
] == pixel
) {
2274 pixel
= cachedest
[k
];
2278 for (k
= CACHE_SIZE
; k
-- > cache_pos
; )
2279 if (cachesrc
[k
] == pixel
) {
2280 pixel
= cachedest
[k
];
2284 cachesrc
[cache_pos
] = xcol
.pixel
= pixel
;
2285 XQueryColor(src_display
, srccm
, &xcol
);
2286 if (!XAllocColor(dest_display
, destcm
, &xcol
))
2288 cachedest
[cache_pos
] = pixel
= xcol
.pixel
;
2290 if (++cache_pos
>= CACHE_SIZE
) {
2296 XPutPixel(destimage
, i
, j
, pixel
);
2299 XPutImage(dest_display
, dest
, destgc
, destimage
, 0, 0, destx
, desty
, w
, h
);
2300 XDestroyImage(destimage
);
2305 XDestroyImage(image
);
2310 /* Helper function for 16-bit fonts */
2311 static int str16len(const char *s
)
2315 while (s
[0] && s
[1]) {