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 parameters.
16 Therefore, it is impossible to independently maintain the current pen and the
17 current brush. Also, some settings depend on the current logical function. The
18 m_currentFill, etc. instance variables remember state across the brush and
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 // ----------------------------------------------------------------------------
40 #pragma implementation "dcclient.h"
43 #include "wx/dcclient.h"
44 #include "wx/dcmemory.h"
45 #include "wx/window.h"
52 #pragma message disable nosimpint
56 #pragma message enable nosimpint
59 #include "wx/motif/private.h"
62 #include <float.h> // for M_PI
72 static Pixmap bdiag
, cdiag
, fdiag
, cross
, horiz
, verti
;
74 // ----------------------------------------------------------------------------
76 // ----------------------------------------------------------------------------
78 // Fudge factor (VZ: what??)
81 // ----------------------------------------------------------------------------
83 // ----------------------------------------------------------------------------
85 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
, wxWindowDC
)
86 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
, wxWindowDC
)
87 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
, wxDC
)
89 // ----------------------------------------------------------------------------
91 // ----------------------------------------------------------------------------
93 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
94 Drawable src
, Drawable dest
,
97 unsigned int w
, unsigned int h
,
99 bool more
, XImage
**cache
);
101 // ============================================================================
103 // ============================================================================
106 * compare two doubles and return the larger rounded
109 static int roundmax(double a
, double b
)
111 return (int)((a
> b
? a
: b
) + 0.5);
115 * compare two doubles and return the smaller rounded
118 static int roundmin(double a
, double b
)
120 return (int)((a
< b
? a
: b
) - 0.5);
124 // ----------------------------------------------------------------------------
126 // ----------------------------------------------------------------------------
128 wxWindowDC::wxWindowDC()
131 m_gcBacking
= (WXGC
) 0;
133 m_backgroundPixel
= -1;
134 m_currentPenWidth
= 1;
135 m_currentPenJoin
= -1;
136 m_currentPenDashCount
= -1;
137 m_currentPenDash
= (wxMOTIFDash
*) NULL
;
140 // m_currentBkMode = wxTRANSPARENT;
141 m_colour
= wxColourDisplay();
142 m_display
= (WXDisplay
*) NULL
;
143 m_currentRegion
= (WXRegion
) 0;
144 m_userRegion
= (WXRegion
) 0;
145 m_pixmap
= (WXPixmap
) 0;
147 m_oldFont
= (WXFont
) 0;
150 wxWindowDC::wxWindowDC( wxWindow
*window
)
152 wxASSERT_MSG( (window
!= (wxWindow
*) NULL
), "You must pass a valid wxWindow to wxWindowDC/wxClientDC/wxPaintDC constructor." );
155 m_font
= window
->GetFont();
157 m_gcBacking
= (WXGC
) 0;
158 m_backgroundPixel
= -1;
159 m_currentPenWidth
= 1;
160 m_currentPenJoin
= -1;
161 m_currentPenDashCount
= -1;
162 m_currentPenDash
= (wxMOTIFDash
*) NULL
;
165 // m_currentBkMode = wxTRANSPARENT;
166 m_colour
= wxColourDisplay();
167 m_currentRegion
= (WXRegion
) 0;
168 m_userRegion
= (WXRegion
) 0;
172 m_display
= window
->GetXDisplay();
173 m_pixmap
= window
->GetXWindow();
174 Display
* display
= (Display
*) m_display
;
176 XSetWindowColormap (display
, (Pixmap
) m_pixmap
, (Colormap
) wxTheApp
->GetMainColormap(m_display
));
179 gcvalues
.foreground
= BlackPixel (display
, DefaultScreen (display
));
180 gcvalues
.background
= WhitePixel (display
, DefaultScreen (display
));
181 gcvalues
.graphics_exposures
= False
;
182 gcvalues
.subwindow_mode
= IncludeInferiors
;
183 gcvalues
.line_width
= 1;
184 m_gc
= (WXGC
) XCreateGC (display
, RootWindow (display
, DefaultScreen (display
)),
185 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
188 if (m_window
->GetBackingPixmap())
190 m_gcBacking
= (WXGC
) XCreateGC (display
, RootWindow (display
,
191 DefaultScreen (display
)),
192 GCForeground
| GCBackground
| GCGraphicsExposures
| GCLineWidth
| GCSubwindowMode
,
196 m_backgroundPixel
= (int) gcvalues
.background
;
198 // Get the current Font so we can set it back later
200 XGetGCValues((Display
*) m_display
, (GC
) m_gc
, GCFont
, &valReturn
);
201 m_oldFont
= (WXFont
) valReturn
.font
;
203 SetBackground(wxBrush(m_window
->GetBackgroundColour(), wxSOLID
));
206 wxWindowDC::~wxWindowDC()
208 if (m_gc
&& (m_oldFont
!= (WXFont
) 0) && ((long) m_oldFont
!= -1))
210 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
212 if (m_window
&& m_window
->GetBackingPixmap())
213 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
217 XFreeGC ((Display
*) m_display
, (GC
) m_gc
);
221 XFreeGC ((Display
*) m_display
, (GC
) m_gcBacking
);
222 m_gcBacking
= (WXGC
) 0;
225 XDestroyRegion ((Region
) m_currentRegion
);
226 m_currentRegion
= (WXRegion
) 0;
229 XDestroyRegion ((Region
) m_userRegion
);
230 m_userRegion
= (WXRegion
) 0;
233 void wxWindowDC::DoFloodFill( wxCoord
WXUNUSED(x1
), wxCoord
WXUNUSED(y1
),
234 const wxColour
& WXUNUSED(col
), int WXUNUSED(style
) )
236 wxFAIL_MSG("not implemented");
239 bool wxWindowDC::DoGetPixel( wxCoord x1
, wxCoord y1
, wxColour
*col
) const
241 // Generic (and therefore rather inefficient) method.
242 // Could be improved.
244 wxBitmap
bitmap(1, 1);
245 memdc
.SelectObject(bitmap
);
246 memdc
.Blit(0, 0, 1, 1, (wxDC
*) this, x1
, y1
);
247 memdc
.SelectObject(wxNullBitmap
);
248 wxImage
image(bitmap
);
249 col
->Set(image
.GetRed(0, 0), image
.GetGreen(0, 0), image
.GetBlue(0, 0));
253 void wxWindowDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
255 wxCHECK_RET( Ok(), "invalid dc" );
257 int x1d
, y1d
, x2d
, y2d
;
259 // FreeGetPixelCache();
269 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x1d
, y1d
, x2d
, y2d
);
271 if (m_window
&& m_window
->GetBackingPixmap())
272 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
273 XLOG2DEV_2(x1
), YLOG2DEV_2(y1
),
274 XLOG2DEV_2(x2
), YLOG2DEV_2(y2
));
276 CalcBoundingBox(x1
, y1
);
277 CalcBoundingBox(x2
, y2
);
280 void wxWindowDC::DoCrossHair( wxCoord x
, wxCoord y
)
282 wxCHECK_RET( Ok(), "invalid dc" );
287 int xx
= XLOG2DEV (x
);
288 int yy
= YLOG2DEV (y
);
290 wxDisplaySize (&ww
, &hh
);
291 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, yy
,
293 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xx
, 0,
296 if (m_window
&& m_window
->GetBackingPixmap())
300 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
303 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
309 void wxWindowDC::DoDrawArc( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord xc
, wxCoord yc
)
311 wxCHECK_RET( Ok(), "invalid dc" );
313 // FreeGetPixelCache();
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 // FreeGetPixelCache();
443 if (m_pen
.Ok() && m_autoSetting
)
446 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
));
447 if (m_window
&& m_window
->GetBackingPixmap())
448 XDrawPoint ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, XLOG2DEV_2 (x
), YLOG2DEV_2 (y
));
450 CalcBoundingBox (x
, y
);
453 void wxWindowDC::DoDrawLines( int n
, wxPoint points
[], wxCoord xoffset
, wxCoord yoffset
)
455 wxCHECK_RET( Ok(), "invalid dc" );
457 // FreeGetPixelCache();
459 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
464 XPoint
*xpoints
= new XPoint
[n
];
467 for (i
= 0; i
< n
; i
++)
469 xpoints
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
470 xpoints
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
472 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints
, n
, 0);
474 if (m_window
&& m_window
->GetBackingPixmap())
476 for (i
= 0; i
< n
; i
++)
478 xpoints
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
479 xpoints
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
481 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints
, n
, 0);
487 void wxWindowDC::DoDrawPolygon( int n
, wxPoint points
[],
488 wxCoord xoffset
, wxCoord yoffset
, int fillStyle
)
490 wxCHECK_RET( Ok(), "invalid dc" );
492 // FreeGetPixelCache();
494 XPoint
*xpoints1
= new XPoint
[n
+ 1];
495 XPoint
*xpoints2
= new XPoint
[n
+ 1];
497 for (i
= 0; i
< n
; i
++)
499 xpoints1
[i
].x
= XLOG2DEV (points
[i
].x
+ xoffset
);
500 xpoints1
[i
].y
= YLOG2DEV (points
[i
].y
+ yoffset
);
501 xpoints2
[i
].x
= XLOG2DEV_2 (points
[i
].x
+ xoffset
);
502 xpoints2
[i
].y
= YLOG2DEV_2 (points
[i
].y
+ yoffset
);
503 CalcBoundingBox (points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
506 // Close figure for XDrawLines (not needed for XFillPolygon)
507 xpoints1
[i
].x
= xpoints1
[0].x
;
508 xpoints1
[i
].y
= xpoints1
[0].y
;
509 xpoints2
[i
].x
= xpoints2
[0].x
;
510 xpoints2
[i
].y
= xpoints2
[0].y
;
512 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
515 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
516 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
, Complex
, 0);
517 XSetFillRule ((Display
*) m_display
, (GC
) m_gc
, EvenOddRule
); // default mode
518 if (m_window
&& m_window
->GetBackingPixmap())
520 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
,
521 fillStyle
== wxODDEVEN_RULE
? EvenOddRule
: WindingRule
);
522 XFillPolygon ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
, Complex
, 0);
523 XSetFillRule ((Display
*) m_display
,(GC
) m_gcBacking
, EvenOddRule
); // default mode
527 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
531 XDrawLines ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xpoints1
, n
+ 1, 0);
533 if (m_window
&& m_window
->GetBackingPixmap())
534 XDrawLines ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, xpoints2
, n
+ 1, 0);
541 void wxWindowDC::DoDrawRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
543 wxCHECK_RET( Ok(), "invalid dc" );
545 // FreeGetPixelCache();
547 int xd
, yd
, wfd
, hfd
, wd
, hd
;
551 wfd
= XLOG2DEVREL(width
);
553 hfd
= YLOG2DEVREL(height
);
556 if (wfd
== 0 || hfd
== 0) return;
557 if (wd
< 0) { wd
= - wd
; xd
= xd
- wd
; }
558 if (hd
< 0) { hd
= - hd
; yd
= yd
- hd
; }
560 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
563 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wfd
, hfd
);
565 if (m_window
&& m_window
->GetBackingPixmap())
566 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
567 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
571 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
575 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
);
577 if (m_window
&& m_window
->GetBackingPixmap())
578 XDrawRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
579 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
582 CalcBoundingBox (x
, y
);
583 CalcBoundingBox (x
+ width
, y
+ height
);
586 void wxWindowDC::DoDrawRoundedRectangle( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
, double radius
)
588 wxCHECK_RET( Ok(), "invalid dc" );
590 // FreeGetPixelCache();
592 // If radius is negative, it's a proportion of the smaller dimension.
594 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
596 int xd
= XLOG2DEV (x
);
597 int yd
= YLOG2DEV (y
);
598 int rd
= XLOG2DEVREL ((long) radius
);
599 int wd
= XLOG2DEVREL (width
) - WX_GC_CF
;
600 int hd
= YLOG2DEVREL (height
) - WX_GC_CF
;
605 // If radius is zero use DrawRectangle() instead to avoid
606 // X drawing errors with small radii
609 DrawRectangle( x
, y
, width
, height
);
613 // Draw nothing if transformed w or h is 0
614 if (wd
== 0 || hd
== 0) return;
616 // CMB: adjust size if outline is drawn otherwise the result is
617 // 1 pixel too wide and high
618 if (m_pen
.GetStyle() != wxTRANSPARENT
)
624 // CMB: ensure dd is not larger than rectangle otherwise we
625 // get an hour glass shape
626 if (rw_d
> wd
) rw_d
= wd
;
627 if (rw_d
> hd
) rw_d
= hd
;
630 // For backing pixmap
631 int xd2
= XLOG2DEV_2 (x
);
632 int yd2
= YLOG2DEV_2 (y
);
633 int rd2
= XLOG2DEVREL ((long) radius
);
634 int wd2
= XLOG2DEVREL (width
) ;
635 int hd2
= YLOG2DEVREL (height
) ;
640 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
644 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
646 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
649 // Arcs start from 3 o'clock, positive angles anticlockwise
651 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
652 rw_d
, rh_d
, 90 * 64, 90 * 64);
654 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
655 // rw_d, rh_d, 0, 90 * 64);
656 rw_d
, rh_d
, 0, 91 * 64);
658 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
660 // rw_d, rh_d, 270 * 64, 90 * 64);
661 rw_d
, rh_d
, 269 * 64, 92 * 64);
663 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
664 rw_d
, rh_d
, 180 * 64, 90 * 64);
666 if (m_window
&& m_window
->GetBackingPixmap())
668 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
669 xd2
+ rd2
, yd2
, wd2
- rw_d2
, hd2
);
670 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
671 xd2
, yd2
+ rd2
, wd2
, hd2
- rh_d2
);
673 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
674 xd2
, yd2
, rw_d2
, rh_d2
, 90 * 64, 90 * 64);
675 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
676 xd2
+ wd2
- rw_d2
, yd2
,
677 // rw_d2, rh_d2, 0, 90 * 64);
678 rw_d2
, rh_d2
, 0, 91 * 64);
679 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
682 // rw_d2, rh_d2, 270 * 64, 90 * 64);
683 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
684 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
685 xd2
, yd2
+ hd2
- rh_d2
,
686 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
690 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
693 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
,
694 xd
+ wd
- rd
+ 1, yd
);
695 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ rd
, yd
+ hd
,
696 xd
+ wd
- rd
, yd
+ hd
);
698 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ rd
,
700 XDrawLine ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
, yd
+ rd
,
701 xd
+ wd
, yd
+ hd
- rd
+ 1);
702 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
,
703 rw_d
, rh_d
, 90 * 64, 90 * 64);
704 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
, yd
,
705 // rw_d, rh_d, 0, 90 * 64);
706 rw_d
, rh_d
, 0, 91 * 64);
707 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
+ wd
- rw_d
,
709 rw_d
, rh_d
, 269 * 64, 92 * 64);
710 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
+ hd
- rh_d
,
711 rw_d
, rh_d
, 180 * 64, 90 * 64);
713 if (m_window
&& m_window
->GetBackingPixmap())
715 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
717 xd2
+ wd2
- rd2
+ 1, yd2
);
718 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
719 xd2
+ rd2
, yd2
+ hd2
,
720 xd2
+ wd2
- rd2
, yd2
+ hd2
);
722 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
724 xd2
, yd2
+ hd2
- rd2
);
725 XDrawLine ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
726 xd2
+ wd2
, yd2
+ rd2
,
727 xd2
+ wd2
, yd2
+ hd2
- rd2
+ 1);
728 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
730 rw_d2
, rh_d2
, 90 * 64, 90 * 64);
731 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
732 xd2
+ wd2
- rw_d2
, yd2
,
733 // rw_d2, rh_d2, 0, 90 * 64);
734 rw_d2
, rh_d2
, 0, 91 * 64);
735 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
738 rw_d2
, rh_d2
, 269 * 64, 92 * 64);
739 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
740 xd2
, yd2
+ hd2
- rh_d2
,
741 rw_d2
, rh_d2
, 180 * 64, 90 * 64);
744 CalcBoundingBox (x
, y
);
745 CalcBoundingBox (x
+ width
, y
+ height
);
750 void wxWindowDC::DoDrawEllipse( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
752 wxCHECK_RET( Ok(), "invalid dc" );
754 // Check for negative width and height
767 // FreeGetPixelCache();
769 static const int angle
= 23040;
775 wd
= XLOG2DEVREL(width
) ;
776 hd
= YLOG2DEVREL(height
) ;
778 if (m_brush
.Ok() && m_brush
.GetStyle () != wxTRANSPARENT
)
781 XFillArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
782 if (m_window
&& m_window
->GetBackingPixmap())
783 XFillArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
784 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
785 XLOG2DEVREL (width
) - WX_GC_CF
,
786 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
789 if (m_pen
.Ok() && m_pen
.GetStyle () != wxTRANSPARENT
)
793 XDrawArc ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, xd
, yd
, wd
, hd
, 0, angle
);
794 if (m_window
&& m_window
->GetBackingPixmap())
795 XDrawArc ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
796 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
),
797 XLOG2DEVREL (width
) - WX_GC_CF
,
798 YLOG2DEVREL (height
) - WX_GC_CF
, 0, angle
);
800 CalcBoundingBox (x
, y
);
801 CalcBoundingBox (x
+ width
, y
+ height
);
805 bool wxWindowDC::CanDrawBitmap() const
807 wxCHECK_MSG( Ok(), FALSE
, "invalid dc" );
813 void wxWindowDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
815 // FreeGetPixelCache();
817 // Be sure that foreground pixels (1) of
818 // the Icon will be painted with pen colour. [m_pen.SetColour()]
819 // Background pixels (0) will be painted with
820 // last selected background color. [::SetBackground]
821 if (m_pen
.Ok() && m_autoSetting
)
825 Pixmap iconPixmap
= (Pixmap
) icon
.GetPixmap();
826 width
= icon
.GetWidth();
827 height
= icon
.GetHeight();
828 if (icon
.GetDisplay() == m_display
)
830 if (icon
.GetDepth() <= 1)
832 XCopyPlane ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
834 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
), 1);
838 XCopyArea ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
840 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
));
844 if (m_window
&& m_window
->GetBackingPixmap())
846 if (icon
.GetDepth() <= 1)
848 XCopyPlane ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
849 0, 0, width
, height
, (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
), 1);
853 XCopyArea ((Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
855 (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
));
858 } else { /* Remote copy (different (Display*) m_displays) */
859 XImage
*cache
= NULL
;
860 if (m_window
&& m_window
->GetBackingPixmap())
861 XCopyRemote((Display
*) icon
.GetDisplay(), (Display
*) m_display
, iconPixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
862 (GC
) m_gcBacking
, 0, 0, width
, height
,
863 (int) XLOG2DEV_2 (x
), (int) YLOG2DEV_2 (y
), TRUE
, &cache
);
864 XCopyRemote((Display
*) icon
.GetDisplay(), (Display
*) m_display
, iconPixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
866 (int) XLOG2DEV (x
), (int) YLOG2DEV (y
), FALSE
, &cache
);
868 CalcBoundingBox (x
, y
);
872 // TODO: use scaled Blit e.g. as per John Price's implementation in Contrib/Utilities
873 bool wxWindowDC::DoBlit( wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
874 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int rop
, bool useMask
,
875 wxCoord xsrcMask
, wxCoord ysrcMask
)
877 wxCHECK_MSG( Ok(), FALSE
, "invalid dc" );
879 wxWindowDC
* sourceDC
= wxDynamicCast(source
, wxWindowDC
);
881 wxASSERT_MSG( sourceDC
, "Blit source DC must be wxWindowDC or derived class." );
883 // FreeGetPixelCache();
885 // Be sure that foreground pixels (1) of the Icon will be painted with pen
886 // colour. [m_pen.SetColour()] Background pixels (0) will be painted with
887 // last selected background color. [::SetBackground]
888 if (m_pen
.Ok() && m_autoSetting
)
891 // Do bitmap scaling if necessary
893 wxBitmap
*scaledBitmap
= (wxBitmap
*) NULL
;
894 Pixmap sourcePixmap
= (Pixmap
) NULL
;
895 double scaleX
, scaleY
;
896 GetUserScale(& scaleX
, & scaleY
);
898 /* TODO: use the mask origin when drawing transparently */
899 if (xsrcMask
== -1 && ysrcMask
== -1)
901 xsrcMask
= xsrc
; ysrcMask
= ysrc
;
904 // Sorry, can't scale masks just yet
905 if (!useMask
&& (scaleX
!= 1.0 || scaleY
!= 1.0) && sourceDC
->IsKindOf(CLASSINFO(wxMemoryDC
)))
907 wxMemoryDC
* memDC
= (wxMemoryDC
*) sourceDC
;
908 wxBitmap
& bitmap
= memDC
->GetBitmap();
910 wxASSERT_MSG( (bitmap
.Ok()), "Bad source bitmap in wxWindowDC::Blit");
912 wxImage
image(bitmap
);
915 sourcePixmap
= (Pixmap
) bitmap
.GetPixmap();
919 int scaledW
= (int) (bitmap
.GetWidth() * scaleX
);
920 int scaledH
= (int) (bitmap
.GetHeight() * scaleY
);
922 image
= image
.Scale(scaledW
, scaledH
);
923 scaledBitmap
= new wxBitmap(image
.ConvertToBitmap());
924 sourcePixmap
= (Pixmap
) scaledBitmap
->GetPixmap();
928 sourcePixmap
= (Pixmap
) sourceDC
->m_pixmap
;
930 if (m_pixmap
&& sourcePixmap
)
933 int orig
= m_logicalFunction
;
935 SetLogicalFunction (rop
);
937 if (m_display
!= sourceDC
->m_display
)
939 XImage
*cache
= NULL
;
941 if (m_window
&& m_window
->GetBackingPixmap())
942 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
,
943 (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),
945 source
->LogicalToDeviceX (xsrc
),
946 source
->LogicalToDeviceY (ysrc
),
947 source
->LogicalToDeviceXRel(width
),
948 source
->LogicalToDeviceYRel(height
),
949 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
),
952 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
954 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
955 wxBitmap
& sel
= memDC
->GetBitmap();
956 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetPixmap() )
958 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetPixmap());
959 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
963 XCopyRemote((Display
*) sourceDC
->m_display
, (Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
964 source
->LogicalToDeviceX (xsrc
),
965 source
->LogicalToDeviceY (ysrc
),
966 source
->LogicalToDeviceXRel(width
),
967 source
->LogicalToDeviceYRel(height
),
968 XLOG2DEV (xdest
), YLOG2DEV (ydest
),
973 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
974 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
979 if (m_window
&& m_window
->GetBackingPixmap())
981 // +++ MARKUS (mho@comnets.rwth-aachen): error on blitting bitmaps with depth 1
982 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) && ((wxMemoryDC
*) source
)->GetBitmap().GetDepth() == 1)
984 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
985 source
->LogicalToDeviceX (xsrc
),
986 source
->LogicalToDeviceY (ysrc
),
987 source
->LogicalToDeviceXRel(width
),
988 source
->LogicalToDeviceYRel(height
),
989 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
), 1);
993 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
994 source
->LogicalToDeviceX (xsrc
),
995 source
->LogicalToDeviceY (ysrc
),
996 source
->LogicalToDeviceXRel(width
),
997 source
->LogicalToDeviceYRel(height
),
998 XLOG2DEV_2 (xdest
), YLOG2DEV_2 (ydest
));
1001 if ( useMask
&& source
->IsKindOf(CLASSINFO(wxMemoryDC
)) )
1003 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
1004 wxBitmap
& sel
= memDC
->GetBitmap();
1005 if ( sel
.Ok() && sel
.GetMask() && sel
.GetMask()->GetPixmap() )
1007 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) sel
.GetMask()->GetPixmap());
1008 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, XLOG2DEV (xdest
), YLOG2DEV (ydest
));
1012 // Check if we're copying from a mono bitmap
1013 if (source
->IsKindOf(CLASSINFO(wxMemoryDC
)) &&
1014 ((wxMemoryDC
*)source
)->GetBitmap().Ok() && (((wxMemoryDC
*)source
)->GetBitmap().GetDepth () == 1))
1016 XCopyPlane ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1017 source
->LogicalToDeviceX (xsrc
),
1018 source
->LogicalToDeviceY (ysrc
),
1019 source
->LogicalToDeviceXRel(width
),
1020 source
->LogicalToDeviceYRel(height
),
1021 XLOG2DEV (xdest
), YLOG2DEV (ydest
), 1);
1025 XCopyArea ((Display
*) m_display
, (Pixmap
) sourcePixmap
, (Pixmap
) m_pixmap
, (GC
) m_gc
,
1026 source
->LogicalToDeviceX (xsrc
),
1027 source
->LogicalToDeviceY (ysrc
),
1028 source
->LogicalToDeviceXRel(width
),
1029 source
->LogicalToDeviceYRel(height
),
1030 XLOG2DEV (xdest
), YLOG2DEV (ydest
));
1035 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
1036 XSetClipOrigin ((Display
*) m_display
, (GC
) m_gc
, 0, 0);
1039 } /* Remote/local (Display*) m_display */
1040 CalcBoundingBox (xdest
, ydest
);
1041 CalcBoundingBox (xdest
+ width
, ydest
+ height
);
1043 SetLogicalFunction(orig
);
1045 if (scaledBitmap
) delete scaledBitmap
;
1049 if (scaledBitmap
) delete scaledBitmap
;
1054 void wxWindowDC::DoDrawText( const wxString
&text
, wxCoord x
, wxCoord y
)
1056 wxCHECK_RET( Ok(), "invalid dc" );
1058 // Since X draws from the baseline of the text, must add the text height
1064 slen
= strlen(text
);
1068 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1069 int direction
, descent
;
1070 XCharStruct overall_return
;
1073 (void)XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*)(const char*) text
, slen
, &direction
,
1074 &ascent
, &descent
, &overall_return
);
1077 (void)XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) text
, slen
, &direction
,
1078 &ascent
, &descent
, &overall_return
);
1080 cx
= overall_return
.width
;
1081 cy
= ascent
+ descent
;
1084 // First draw a rectangle representing the text background, if a text
1085 // background is specified
1086 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1088 wxColour oldPenColour
= m_currentColour
;
1089 m_currentColour
= m_textBackgroundColour
;
1090 bool sameColour
= (oldPenColour
.Ok () && m_textBackgroundColour
.Ok () &&
1091 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1092 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1093 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1095 // This separation of the big && test required for gcc2.7/HP UX 9.02
1096 // or pixel value can be corrupted!
1097 sameColour
= (sameColour
&&
1098 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1100 if (!sameColour
|| !GetOptimization())
1102 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1103 m_currentColour
= m_textBackgroundColour
;
1105 // Set the GC to the required colour
1108 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1109 if (m_window
&& m_window
->GetBackingPixmap())
1110 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1114 m_textBackgroundColour
= oldPenColour
;
1116 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1117 if (m_window
&& m_window
->GetBackingPixmap())
1118 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1119 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1122 // Now set the text foreground and draw the text
1123 if (m_textForegroundColour
.Ok ())
1125 wxColour oldPenColour
= m_currentColour
;
1126 m_currentColour
= m_textForegroundColour
;
1127 bool sameColour
= (oldPenColour
.Ok () && m_currentColour
.Ok () &&
1128 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1129 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1130 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1131 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1133 if (!sameColour
|| !GetOptimization())
1136 if (!m_colour
) // Mono display
1138 // Unless foreground is really white, draw it in black
1139 unsigned char red
= m_textForegroundColour
.Red ();
1140 unsigned char blue
= m_textForegroundColour
.Blue ();
1141 unsigned char green
= m_textForegroundColour
.Green ();
1142 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1143 && green
== (unsigned char) 255)
1145 m_currentColour
= *wxWHITE
;
1146 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1147 m_currentColour
.SetPixel(pixel
);
1148 m_textForegroundColour
.SetPixel(pixel
);
1152 m_currentColour
= *wxBLACK
;
1153 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1154 m_currentColour
.SetPixel(pixel
);
1155 m_textForegroundColour
.SetPixel(pixel
);
1160 pixel
= m_textForegroundColour
.AllocColour((Display
*) m_display
);
1161 m_currentColour
.SetPixel(pixel
);
1164 // Set the GC to the required colour
1167 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1168 if (m_window
&& m_window
->GetBackingPixmap())
1169 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1173 m_textForegroundColour
= oldPenColour
;
1176 // We need to add the ascent, not the whole height, since X draws at the
1177 // point above the descender.
1180 XDrawString16((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
,
1181 (XChar2b
*)(char*) (const char*) text
, slen
);
1184 XDrawString((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
) + ascent
, text
, slen
);
1186 if (m_window
&& m_window
->GetBackingPixmap()) {
1189 XDrawString16((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1190 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
,
1191 (XChar2b
*)(char*) (const char*) text
, slen
);
1194 XDrawString((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(), (GC
) m_gcBacking
,
1195 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
) + ascent
, (char*) (const char*) text
, slen
);
1199 GetTextExtent (text
, &w
, &h
);
1200 CalcBoundingBox (x
+ w
, y
+ h
);
1201 CalcBoundingBox (x
, y
);
1204 void wxWindowDC::DoDrawRotatedText( const wxString
&text
, wxCoord x
, wxCoord y
, double angle
)
1208 DrawText(text
, x
, y
);
1212 wxCHECK_RET( Ok(), "invalid dc" );
1214 // Since X draws from the baseline of the text, must add the text height
1220 slen
= strlen(text
);
1224 // Calculate text extent.
1225 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1226 int direction
, descent
;
1227 XCharStruct overall_return
;
1230 (void)XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*)(const char*) text
, slen
, &direction
,
1231 &ascent
, &descent
, &overall_return
);
1234 (void)XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) text
, slen
, &direction
,
1235 &ascent
, &descent
, &overall_return
);
1237 cx
= overall_return
.width
;
1238 cy
= ascent
+ descent
;
1241 wxBitmap
src(cx
, cy
);
1243 dc
.SelectObject(src
);
1244 dc
.SetFont(GetFont());
1245 dc
.SetBackground(*wxWHITE_BRUSH
);
1246 dc
.SetBrush(*wxBLACK_BRUSH
);
1248 dc
.DrawText(text
, 0, 0);
1249 dc
.SetFont(wxNullFont
);
1251 // Calculate the size of the rotated bounding box.
1252 double dx
= cos(angle
/ 180.0 * M_PI
);
1253 double dy
= sin(angle
/ 180.0 * M_PI
);
1254 double x4
= -cy
* dy
;
1255 double y4
= cy
* dx
;
1256 double x3
= cx
* dx
;
1257 double y3
= cx
* dy
;
1258 double x2
= x3
+ x4
;
1259 double y2
= y3
+ y4
;
1263 // Create image from the source bitmap after writing the text into it.
1266 int minx
= roundmin(0, roundmin(x4
, roundmin(x2
, x3
)));
1267 int miny
= roundmin(0, roundmin(y4
, roundmin(y2
, y3
)));
1268 int maxx
= roundmax(0, roundmax(x4
, roundmax(x2
, x3
)));
1269 int maxy
= roundmax(0, roundmax(y4
, roundmax(y2
, y3
)));
1271 // This rotates counterclockwise around the top left corner.
1272 for (int rx
= minx
; rx
< maxx
; rx
++)
1274 for (int ry
= miny
; ry
< maxy
; ry
++)
1276 // transform dest coords to source coords
1277 int sx
= (int) (rx
* dx
+ ry
* dy
+ 0.5);
1278 int sy
= (int) (ry
* dx
- rx
* dy
+ 0.5);
1279 if (sx
>= 0 && sx
< cx
&& sy
>= 0 && sy
< cy
)
1281 // draw black pixels, ignore white ones (i.e. transparent b/g)
1282 if (image
.GetRed(sx
, sy
) == 0)
1284 DrawPoint((wxCoord
) (x1
+ maxx
- rx
), (wxCoord
) (cy
+ y1
- ry
));
1289 //DrawPoint(x1 + maxx - rx, cy + y1 + maxy - ry);
1296 // First draw a rectangle representing the text background, if a text
1297 // background is specified
1298 if (m_textBackgroundColour
.Ok () && (m_backgroundMode
!= wxTRANSPARENT
))
1300 wxColour oldPenColour
= m_currentColour
;
1301 m_currentColour
= m_textBackgroundColour
;
1302 bool sameColour
= (oldPenColour
.Ok () && m_textBackgroundColour
.Ok () &&
1303 (oldPenColour
.Red () == m_textBackgroundColour
.Red ()) &&
1304 (oldPenColour
.Blue () == m_textBackgroundColour
.Blue ()) &&
1305 (oldPenColour
.Green () == m_textBackgroundColour
.Green ()));
1307 // This separation of the big && test required for gcc2.7/HP UX 9.02
1308 // or pixel value can be corrupted!
1309 sameColour
= (sameColour
&&
1310 (oldPenColour
.GetPixel() == m_textBackgroundColour
.GetPixel()));
1312 if (!sameColour
|| !GetOptimization())
1314 int pixel
= m_textBackgroundColour
.AllocColour(m_display
);
1315 m_currentColour
= m_textBackgroundColour
;
1317 // Set the GC to the required colour
1320 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1321 if (m_window
&& m_window
->GetBackingPixmap())
1322 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1326 m_textBackgroundColour
= oldPenColour
;
1328 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, XLOG2DEV (x
), YLOG2DEV (y
), cx
, cy
);
1329 if (m_window
&& m_window
->GetBackingPixmap())
1330 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
,
1331 XLOG2DEV_2 (x
), YLOG2DEV_2 (y
), cx
, cy
);
1336 // XXX use pixmap size
1337 GetTextExtent (text
, &w
, &h
);
1338 CalcBoundingBox (x
+ w
, y
+ h
);
1339 CalcBoundingBox (x
, y
);
1342 bool wxWindowDC::CanGetTextExtent() const
1347 void wxWindowDC::DoGetTextExtent( const wxString
&string
, wxCoord
*width
, wxCoord
*height
,
1348 wxCoord
*descent
, wxCoord
*externalLeading
,
1349 wxFont
*font
) const
1351 wxCHECK_RET( Ok(), "invalid dc" );
1353 wxFont
* theFont
= font
;
1355 theFont
= (wxFont
*)&m_font
; // const_cast
1359 // TODO: this should be an error log function
1360 wxFAIL_MSG("set a valid font before calling GetTextExtent!");
1362 if (width
) *width
= -1;
1363 if (height
) *height
= -1;
1367 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1369 int direction
, ascent
, descent2
;
1370 XCharStruct overall
;
1375 slen
= str16len(string
);
1378 slen
= strlen(string
);
1382 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1383 &ascent
, &descent2
, &overall
);
1386 XTextExtents((XFontStruct
*) pFontStruct
, (char*) (const char*) string
, slen
, &direction
,
1387 &ascent
, &descent2
, &overall
);
1389 if (width
) *width
= XDEV2LOGREL (overall
.width
);
1390 if (height
) *height
= YDEV2LOGREL (ascent
+ descent2
);
1392 *descent
= descent2
;
1393 if (externalLeading
)
1394 *externalLeading
= 0;
1397 wxCoord
wxWindowDC::GetCharWidth() const
1399 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1400 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1402 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
* m_logicalScaleY
, m_display
);
1404 int direction
, ascent
, descent
;
1405 XCharStruct overall
;
1406 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1407 &descent
, &overall
);
1408 return XDEV2LOGREL(overall
.width
);
1411 wxCoord
wxWindowDC::GetCharHeight() const
1413 wxCHECK_MSG( Ok(), 0, "invalid dc" );
1414 wxCHECK_MSG( m_font
.Ok(), 0, "invalid font" );
1416 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1418 int direction
, ascent
, descent
;
1419 XCharStruct overall
;
1420 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1421 &descent
, &overall
);
1422 // return XDEV2LOGREL(overall.ascent + overall.descent);
1423 return XDEV2LOGREL(ascent
+ descent
);
1426 void wxWindowDC::Clear()
1428 wxCHECK_RET( Ok(), "invalid dc" );
1433 m_window
->GetSize(&w
, &h
);
1435 if (m_window
&& m_window
->GetBackingPixmap())
1437 w
= m_window
->GetPixmapWidth();
1438 h
= m_window
->GetPixmapHeight();
1443 if (this->IsKindOf(CLASSINFO(wxMemoryDC
)))
1445 wxMemoryDC
* memDC
= (wxMemoryDC
*) this;
1446 w
= memDC
->GetBitmap().GetWidth();
1447 h
= memDC
->GetBitmap().GetHeight();
1453 wxBrush saveBrush
= m_brush
;
1454 SetBrush (m_backgroundBrush
);
1456 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, 0, 0, w
, h
);
1458 if (m_window
&& m_window
->GetBackingPixmap())
1459 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, 0, 0, w
, h
);
1461 m_brush
= saveBrush
;
1464 void wxWindowDC::Clear(const wxRect
& rect
)
1466 wxCHECK_RET( Ok(), "invalid dc" );
1468 int x
= rect
.x
; int y
= rect
.y
;
1469 int w
= rect
.width
; int h
= rect
.height
;
1471 wxBrush saveBrush
= m_brush
;
1472 SetBrush (m_backgroundBrush
);
1474 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_pixmap
, (GC
) m_gc
, x
, y
, w
, h
);
1476 if (m_window
&& m_window
->GetBackingPixmap())
1477 XFillRectangle ((Display
*) m_display
, (Pixmap
) m_window
->GetBackingPixmap(),(GC
) m_gcBacking
, x
, y
, w
, h
);
1479 m_brush
= saveBrush
;
1482 void wxWindowDC::SetFont( const wxFont
&font
)
1484 wxCHECK_RET( Ok(), "invalid dc" );
1490 if ((m_oldFont
!= (WXFont
) 0) && ((wxCoord
) m_oldFont
!= -1))
1492 XSetFont ((Display
*) m_display
, (GC
) m_gc
, (Font
) m_oldFont
);
1494 if (m_window
&& m_window
->GetBackingPixmap())
1495 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, (Font
) m_oldFont
);
1500 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(m_userScaleY
*m_logicalScaleY
, m_display
);
1502 Font fontId
= ((XFontStruct
*)pFontStruct
)->fid
;
1503 XSetFont ((Display
*) m_display
, (GC
) m_gc
, fontId
);
1505 if (m_window
&& m_window
->GetBackingPixmap())
1506 XSetFont ((Display
*) m_display
,(GC
) m_gcBacking
, fontId
);
1509 void wxWindowDC::SetPen( const wxPen
&pen
)
1511 wxCHECK_RET( Ok(), "invalid dc" );
1517 wxBitmap oldStipple
= m_currentStipple
;
1518 int oldStyle
= m_currentStyle
;
1519 int oldFill
= m_currentFill
;
1520 int old_pen_width
= m_currentPenWidth
;
1521 int old_pen_join
= m_currentPenJoin
;
1522 int old_pen_cap
= m_currentPenCap
;
1523 int old_pen_nb_dash
= m_currentPenDashCount
;
1524 wxMOTIFDash
*old_pen_dash
= m_currentPenDash
;
1526 wxColour oldPenColour
= m_currentColour
;
1527 m_currentColour
= m_pen
.GetColour ();
1528 m_currentStyle
= m_pen
.GetStyle ();
1529 m_currentFill
= m_pen
.GetStyle (); // TODO?
1530 m_currentPenWidth
= m_pen
.GetWidth ();
1531 m_currentPenJoin
= m_pen
.GetJoin ();
1532 m_currentPenCap
= m_pen
.GetCap ();
1533 m_currentPenDashCount
= m_pen
.GetDashCount();
1534 m_currentPenDash
= (wxMOTIFDash
*)m_pen
.GetDash();
1536 if (m_currentStyle
== wxSTIPPLE
)
1537 m_currentStipple
= * m_pen
.GetStipple ();
1539 bool sameStyle
= (oldStyle
== m_currentStyle
&&
1540 oldFill
== m_currentFill
&&
1541 old_pen_join
== m_currentPenJoin
&&
1542 old_pen_cap
== m_currentPenCap
&&
1543 old_pen_nb_dash
== m_currentPenDashCount
&&
1544 old_pen_dash
== m_currentPenDash
&&
1545 old_pen_width
== m_currentPenWidth
);
1547 bool sameColour
= (oldPenColour
.Ok () &&
1548 (oldPenColour
.Red () == m_currentColour
.Red ()) &&
1549 (oldPenColour
.Blue () == m_currentColour
.Blue ()) &&
1550 (oldPenColour
.Green () == m_currentColour
.Green ()) &&
1551 (oldPenColour
.GetPixel() == m_currentColour
.GetPixel()));
1553 if (!sameStyle
|| !GetOptimization())
1555 int scaled_width
= (int) XLOG2DEVREL (m_pen
.GetWidth ());
1556 if (scaled_width
< 0)
1562 static const wxMOTIFDash dotted
[] = {2, 5};
1563 static const wxMOTIFDash short_dashed
[] = {4, 4};
1564 static const wxMOTIFDash long_dashed
[] = {4, 8};
1565 static const wxMOTIFDash dotted_dashed
[] = {6, 6, 2, 6};
1567 // We express dash pattern in pen width unit, so we are
1568 // independent of zoom factor and so on...
1570 const wxMOTIFDash
*req_dash
;
1572 switch (m_pen
.GetStyle ())
1575 req_nb_dash
= m_currentPenDashCount
;
1576 req_dash
= m_currentPenDash
;
1577 style
= LineOnOffDash
;
1582 style
= LineOnOffDash
;
1586 req_dash
= short_dashed
;
1587 style
= LineOnOffDash
;
1591 req_dash
= long_dashed
;
1592 style
= LineOnOffDash
;
1596 req_dash
= dotted_dashed
;
1597 style
= LineOnOffDash
;
1604 req_dash
= (wxMOTIFDash
*)NULL
;
1608 if (req_dash
&& req_nb_dash
)
1610 wxMOTIFDash
*real_req_dash
= new wxMOTIFDash
[req_nb_dash
];
1613 int factor
= scaled_width
== 0 ? 1 : scaled_width
;
1614 for (int i
= 0; i
< req_nb_dash
; i
++)
1615 real_req_dash
[i
] = req_dash
[i
] * factor
;
1616 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, real_req_dash
, req_nb_dash
);
1618 if (m_window
&& m_window
->GetBackingPixmap())
1619 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, real_req_dash
, req_nb_dash
);
1620 delete[]real_req_dash
;
1624 // No Memory. We use non-scaled dash pattern...
1625 XSetDashes ((Display
*) m_display
, (GC
) m_gc
, 0, req_dash
, req_nb_dash
);
1627 if (m_window
&& m_window
->GetBackingPixmap())
1628 XSetDashes ((Display
*) m_display
,(GC
) m_gcBacking
, 0, req_dash
, req_nb_dash
);
1632 switch (m_pen
.GetCap ())
1634 case wxCAP_PROJECTING
:
1635 cap
= CapProjecting
;
1642 cap
= (scaled_width
<= 1) ? CapNotLast
: CapRound
;
1646 switch (m_pen
.GetJoin ())
1660 XSetLineAttributes ((Display
*) m_display
, (GC
) m_gc
, scaled_width
, style
, cap
, join
);
1662 if (m_window
&& m_window
->GetBackingPixmap())
1663 XSetLineAttributes ((Display
*) m_display
,(GC
) m_gcBacking
, scaled_width
, style
, cap
, join
);
1666 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1670 oldStipple
= wxNullBitmap
; // For later reset!!
1672 switch (m_currentFill
)
1674 case wxBDIAGONAL_HATCH
:
1675 if (bdiag
== (Pixmap
) 0)
1676 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1677 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1678 bdiag_bits
, bdiag_width
, bdiag_height
);
1681 case wxFDIAGONAL_HATCH
:
1682 if (fdiag
== (Pixmap
) 0)
1683 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1684 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1685 fdiag_bits
, fdiag_width
, fdiag_height
);
1689 if (cross
== (Pixmap
) 0)
1690 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1691 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1692 cross_bits
, cross_width
, cross_height
);
1695 case wxHORIZONTAL_HATCH
:
1696 if (horiz
== (Pixmap
) 0)
1697 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1698 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1699 horiz_bits
, horiz_width
, horiz_height
);
1702 case wxVERTICAL_HATCH
:
1703 if (verti
== (Pixmap
) 0)
1704 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1705 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1706 verti_bits
, verti_width
, verti_height
);
1709 case wxCROSSDIAG_HATCH
:
1711 if (cdiag
== (Pixmap
) 0)
1712 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1713 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1714 cdiag_bits
, cdiag_width
, cdiag_height
);
1718 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1720 if (m_window
&& m_window
->GetBackingPixmap())
1721 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1723 else if (m_currentStipple
.Ok()
1724 && ((m_currentStipple
!= oldStipple
) || !GetOptimization()))
1726 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1728 if (m_window
&& m_window
->GetBackingPixmap())
1729 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1732 if ((m_currentFill
!= oldFill
) || !GetOptimization())
1736 if (m_currentFill
== wxSTIPPLE
)
1737 fill_style
= FillStippled
;
1738 else if (IS_HATCH (m_currentFill
))
1739 fill_style
= FillStippled
;
1741 fill_style
= FillSolid
;
1742 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, fill_style
);
1743 if (m_window
&& m_window
->GetBackingPixmap())
1744 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, fill_style
);
1747 // must test m_logicalFunction, because it involves background!
1748 if (!sameColour
|| !GetOptimization()
1749 || ((m_logicalFunction
== wxXOR
) || (m_autoSetting
& 0x2)))
1752 if (m_pen
.GetStyle () == wxTRANSPARENT
)
1753 pixel
= m_backgroundPixel
;
1756 unsigned char red
= m_pen
.GetColour ().Red ();
1757 unsigned char blue
= m_pen
.GetColour ().Blue ();
1758 unsigned char green
= m_pen
.GetColour ().Green ();
1759 if (red
== (unsigned char) 255 && blue
== (unsigned char) 255
1760 && green
== (unsigned char) 255)
1762 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1763 m_currentColour
= *wxWHITE
;
1764 m_pen
.GetColour().SetPixel(pixel
);
1765 m_currentColour
.SetPixel(pixel
);
1769 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1770 m_currentColour
= *wxBLACK
;
1771 m_pen
.GetColour().SetPixel(pixel
);
1776 pixel
= m_pen
.GetColour ().AllocColour(m_display
);
1777 m_currentColour
.SetPixel(pixel
);
1780 // Finally, set the GC to the required colour
1783 if (m_logicalFunction
== wxXOR
)
1786 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1787 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1788 if (m_window
&& m_window
->GetBackingPixmap())
1789 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1793 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1794 if (m_window
&& m_window
->GetBackingPixmap())
1795 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1800 m_pen
.GetColour().SetPixel(oldPenColour
.GetPixel());
1805 void wxWindowDC::SetBrush( const wxBrush
&brush
)
1807 wxCHECK_RET( Ok(), "invalid dc" );
1811 if (!m_brush
.Ok() || m_brush
.GetStyle () == wxTRANSPARENT
)
1814 int oldFill
= m_currentFill
;
1815 wxBitmap oldStipple
= m_currentStipple
;
1817 m_autoSetting
|= 0x1;
1819 m_currentFill
= m_brush
.GetStyle ();
1820 if (m_currentFill
== wxSTIPPLE
)
1821 m_currentStipple
= * m_brush
.GetStipple ();
1823 wxColour
oldBrushColour(m_currentColour
);
1824 m_currentColour
= m_brush
.GetColour ();
1826 bool sameColour
= (oldBrushColour
.Ok () &&
1827 (oldBrushColour
.Red () == m_currentColour
.Red ()) &&
1828 (oldBrushColour
.Blue () == m_currentColour
.Blue ()) &&
1829 (oldBrushColour
.Green () == m_currentColour
.Green ()) &&
1830 (oldBrushColour
.GetPixel() == m_currentColour
.GetPixel()));
1832 if ((oldFill
!= m_brush
.GetStyle ()) || !GetOptimization())
1834 switch (brush
.GetStyle ())
1838 case wxBDIAGONAL_HATCH
:
1839 case wxCROSSDIAG_HATCH
:
1840 case wxFDIAGONAL_HATCH
:
1842 case wxHORIZONTAL_HATCH
:
1843 case wxVERTICAL_HATCH
:
1846 // Chris Breeze 23/07/97: use background mode to determine whether
1847 // fill style should be solid or transparent
1848 int style
= (m_backgroundMode
== wxSOLID
? FillOpaqueStippled
: FillStippled
);
1849 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, style
);
1850 if (m_window
&& m_window
->GetBackingPixmap())
1851 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, style
);
1856 XSetFillStyle ((Display
*) m_display
, (GC
) m_gc
, FillSolid
);
1857 if (m_window
&& m_window
->GetBackingPixmap())
1858 XSetFillStyle ((Display
*) m_display
,(GC
) m_gcBacking
, FillSolid
);
1862 if (IS_HATCH(m_currentFill
) && ((m_currentFill
!= oldFill
) || !GetOptimization()))
1866 switch (m_currentFill
)
1868 case wxBDIAGONAL_HATCH
:
1869 if (bdiag
== (Pixmap
) 0)
1870 bdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1871 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1872 bdiag_bits
, bdiag_width
, bdiag_height
);
1875 case wxFDIAGONAL_HATCH
:
1876 if (fdiag
== (Pixmap
) 0)
1877 fdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1878 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1879 fdiag_bits
, fdiag_width
, fdiag_height
);
1883 if (cross
== (Pixmap
) 0)
1884 cross
= XCreateBitmapFromData ((Display
*) m_display
,
1885 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1886 cross_bits
, cross_width
, cross_height
);
1889 case wxHORIZONTAL_HATCH
:
1890 if (horiz
== (Pixmap
) 0)
1891 horiz
= XCreateBitmapFromData ((Display
*) m_display
,
1892 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1893 horiz_bits
, horiz_width
, horiz_height
);
1896 case wxVERTICAL_HATCH
:
1897 if (verti
== (Pixmap
) 0)
1898 verti
= XCreateBitmapFromData ((Display
*) m_display
,
1899 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1900 verti_bits
, verti_width
, verti_height
);
1903 case wxCROSSDIAG_HATCH
:
1905 if (cdiag
== (Pixmap
) 0)
1906 cdiag
= XCreateBitmapFromData ((Display
*) m_display
,
1907 RootWindow ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
)),
1908 cdiag_bits
, cdiag_width
, cdiag_height
);
1912 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, myStipple
);
1914 if (m_window
&& m_window
->GetBackingPixmap())
1915 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, myStipple
);
1917 // X can forget the stipple value when resizing a window (apparently)
1918 // so always set the stipple.
1919 else if (m_currentStipple
.Ok()) // && m_currentStipple != oldStipple)
1921 XSetStipple ((Display
*) m_display
, (GC
) m_gc
, (Pixmap
) m_currentStipple
.GetPixmap());
1922 if (m_window
&& m_window
->GetBackingPixmap())
1923 XSetStipple ((Display
*) m_display
,(GC
) m_gcBacking
, (Pixmap
) m_currentStipple
.GetPixmap());
1926 // must test m_logicalFunction, because it involves background!
1927 if (!sameColour
|| !GetOptimization() || m_logicalFunction
== wxXOR
)
1932 // Policy - on a monochrome screen, all brushes are white,
1933 // except when they're REALLY black!!!
1934 unsigned char red
= m_brush
.GetColour ().Red ();
1935 unsigned char blue
= m_brush
.GetColour ().Blue ();
1936 unsigned char green
= m_brush
.GetColour ().Green ();
1938 if (red
== (unsigned char) 0 && blue
== (unsigned char) 0
1939 && green
== (unsigned char) 0)
1941 pixel
= (int) BlackPixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1942 m_currentColour
= *wxBLACK
;
1943 m_brush
.GetColour().SetPixel(pixel
);
1944 m_currentColour
.SetPixel(pixel
);
1948 pixel
= (int) WhitePixel ((Display
*) m_display
, DefaultScreen ((Display
*) m_display
));
1949 m_currentColour
= *wxWHITE
;
1950 m_brush
.GetColour().SetPixel(pixel
);
1951 m_currentColour
.SetPixel(pixel
);
1954 // N.B. comment out the above line and uncomment the following lines
1955 // if you want non-white colours to be black on a monochrome display.
1957 if (red == (unsigned char )255 && blue == (unsigned char)255
1958 && green == (unsigned char)255)
1959 pixel = (int)WhitePixel((Display*) m_display, DefaultScreen((Display*) m_display));
1961 pixel = (int)BlackPixel((Display*) m_display, DefaultScreen((Display*) m_display));
1964 else if (m_brush
.GetStyle () != wxTRANSPARENT
)
1966 pixel
= m_brush
.GetColour().AllocColour(m_display
);
1967 m_currentColour
.SetPixel(pixel
);
1971 // Finally, set the GC to the required colour
1972 if (m_logicalFunction
== wxXOR
)
1975 XGetGCValues ((Display
*) m_display
, (GC
) m_gc
, GCBackground
, &values
);
1976 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
^ values
.background
);
1977 if (m_window
&& m_window
->GetBackingPixmap())
1978 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
^ values
.background
);
1982 XSetForeground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
1983 if (m_window
&& m_window
->GetBackingPixmap())
1984 XSetForeground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
1989 m_brush
.GetColour().SetPixel(oldBrushColour
.GetPixel());
1992 void wxWindowDC::SetBackground( const wxBrush
&brush
)
1994 wxCHECK_RET( Ok(), "invalid dc" );
1996 m_backgroundBrush
= brush
;
1998 if (!m_backgroundBrush
.Ok())
2001 int pixel
= m_backgroundBrush
.GetColour().AllocColour(m_display
);
2003 // New behaviour, 10/2/99: setting the background brush of a DC
2004 // doesn't affect the window background colour.
2006 // XSetWindowBackground doesn't work for non-Window pixmaps
2007 if (!this->IsKindOf(CLASSINFO(wxMemoryDC)))
2008 XSetWindowBackground ((Display*) m_display, (Pixmap) m_pixmap, pixel);
2011 // Necessary for ::DrawIcon, which use fg/bg pixel or the GC.
2012 // And Blit,... (Any fct that use XCopyPlane, in fact.)
2013 XSetBackground ((Display
*) m_display
, (GC
) m_gc
, pixel
);
2014 if (m_window
&& m_window
->GetBackingPixmap())
2015 XSetBackground ((Display
*) m_display
,(GC
) m_gcBacking
, pixel
);
2018 void wxWindowDC::SetLogicalFunction( int function
)
2020 wxCHECK_RET( Ok(), "invalid dc" );
2025 if (m_logicalFunction
== function
)
2031 x_function
= GXclear
;
2037 x_function
= GXinvert
;
2040 x_function
= GXorReverse
;
2043 x_function
= GXandReverse
;
2052 x_function
= GXandInverted
;
2055 x_function
= GXnoop
;
2061 x_function
= GXequiv
;
2064 x_function
= GXcopyInverted
;
2067 x_function
= GXorInverted
;
2070 x_function
= GXnand
;
2077 x_function
= GXcopy
;
2081 XSetFunction((Display
*) m_display
, (GC
) m_gc
, x_function
);
2082 if (m_window
&& m_window
->GetBackingPixmap())
2083 XSetFunction((Display
*) m_display
, (GC
) m_gcBacking
, x_function
);
2085 if ((m_logicalFunction
== wxXOR
) != (function
== wxXOR
))
2086 /* MATTHEW: [9] Need to redo pen simply */
2087 m_autoSetting
|= 0x2;
2089 m_logicalFunction
= function
;
2093 void wxWindowDC::SetTextForeground( const wxColour
&col
)
2095 wxCHECK_RET( Ok(), "invalid dc" );
2097 if (m_textForegroundColour
== col
)
2100 m_textForegroundColour
= col
;
2104 void wxWindowDC::SetTextBackground( const wxColour
&col
)
2106 wxCHECK_RET( Ok(), "invalid dc" );
2108 if (m_textBackgroundColour
== col
)
2111 m_textBackgroundColour
= col
;
2112 if (!m_textBackgroundColour
.Ok())
2116 void wxWindowDC::SetBackgroundMode( int mode
)
2118 m_backgroundMode
= mode
;
2121 void wxWindowDC::SetPalette( const wxPalette
& palette
)
2126 /* Use GetXColormap */
2127 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2128 (Colormap
) palette
.GetXColormap());
2130 /* Use wxGetMainColormap */
2131 XSetWindowColormap ((Display
*) m_display
, (Window
) m_window
->GetXWindow(),
2132 (Colormap
) wxTheApp
->GetMainColormap(m_display
));
2137 void wxWindowDC::SetDCClipping()
2139 // m_userRegion is the region set by calling SetClippingRegion
2141 if (m_currentRegion
)
2142 XDestroyRegion ((Region
) m_currentRegion
);
2144 // We need to take into account
2145 // clipping imposed on a window by a repaint.
2146 // We'll combine it with the user region. But for now,
2147 // just use the currently-defined user clipping region.
2148 if (m_userRegion
|| (m_window
&& m_window
->GetUpdateRegion().Ok()) )
2149 m_currentRegion
= (WXRegion
) XCreateRegion ();
2151 m_currentRegion
= (WXRegion
) NULL
;
2153 if ((m_window
&& m_window
->GetUpdateRegion().Ok()) && m_userRegion
)
2154 XIntersectRegion ((Region
) m_window
->GetUpdateRegion().GetXRegion(), (Region
) m_userRegion
, (Region
) m_currentRegion
);
2155 else if (m_userRegion
)
2156 XIntersectRegion ((Region
) m_userRegion
, (Region
) m_userRegion
, (Region
) m_currentRegion
);
2157 else if (m_window
&& m_window
->GetUpdateRegion().Ok())
2158 XIntersectRegion ((Region
) m_window
->GetUpdateRegion().GetXRegion(), (Region
) m_window
->GetUpdateRegion().GetXRegion(),
2159 (Region
) m_currentRegion
);
2161 if (m_currentRegion
)
2163 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) m_currentRegion
);
2167 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
2172 void wxWindowDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
2174 wxDC::DoSetClippingRegion( x
, y
, width
, height
);
2177 XDestroyRegion ((Region
) m_userRegion
);
2178 m_userRegion
= (WXRegion
) XCreateRegion ();
2182 r
.width
= XLOG2DEVREL(width
);
2183 r
.height
= YLOG2DEVREL(height
);
2184 XUnionRectWithRegion (&r
, (Region
) m_userRegion
, (Region
) m_userRegion
);
2188 // Needs to work differently for Pixmap: without this,
2189 // there's a nasty (Display*) m_display bug. 8/12/94
2190 if (m_window
&& m_window
->GetBackingPixmap())
2192 XRectangle rects
[1];
2193 rects
[0].x
= XLOG2DEV_2(x
);
2194 rects
[0].y
= YLOG2DEV_2(y
);
2195 rects
[0].width
= XLOG2DEVREL(width
);
2196 rects
[0].height
= YLOG2DEVREL(height
);
2197 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 0, 0, rects
, 1, Unsorted
);
2201 void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion
& region
)
2203 wxRect box
= region
.GetBox();
2205 wxDC::DoSetClippingRegion( box
.x
, box
.y
, box
.width
, box
.height
);
2208 XDestroyRegion ((Region
) m_userRegion
);
2209 m_userRegion
= (WXRegion
) XCreateRegion ();
2211 XUnionRegion((Region
) m_userRegion
, (Region
) region
.GetXRegion(), (Region
) m_userRegion
);
2215 // Needs to work differently for Pixmap: without this,
2216 // there's a nasty (Display*) m_display bug. 8/12/94
2217 if (m_window
&& m_window
->GetBackingPixmap())
2219 XRectangle rects
[1];
2220 rects
[0].x
= XLOG2DEV_2(box
.x
);
2221 rects
[0].y
= YLOG2DEV_2(box
.y
);
2222 rects
[0].width
= XLOG2DEVREL(box
.width
);
2223 rects
[0].height
= YLOG2DEVREL(box
.height
);
2224 XSetClipRectangles((Display
*) m_display
, (GC
) m_gcBacking
, 0, 0, rects
, 1, Unsorted
);
2229 void wxWindowDC::DestroyClippingRegion()
2231 wxDC::DestroyClippingRegion();
2234 XDestroyRegion ((Region
) m_userRegion
);
2235 m_userRegion
= NULL
;
2240 gc_val
.clip_mask
= None
;
2241 if (m_window
&& m_window
->GetBackingPixmap())
2242 XChangeGC((Display
*) m_display
, (GC
) m_gcBacking
, GCClipMask
, &gc_val
);
2245 // Resolution in pixels per logical inch
2246 wxSize
wxWindowDC::GetPPI() const
2248 return wxSize(100, 100);
2251 int wxWindowDC::GetDepth() const
2260 // ----------------------------------------------------------------------------
2262 // ----------------------------------------------------------------------------
2264 wxPaintDC::wxPaintDC(wxWindow
* win
) : wxWindowDC(win
)
2266 wxRegion
* region
= NULL
;
2268 // Combine all the update rects into a region
2269 const wxRectList
& updateRects(win
->GetUpdateRects());
2270 if ( updateRects
.GetCount() != 0 )
2272 for ( wxRectList::Node
*node
= updateRects
.GetFirst();
2274 node
= node
->GetNext() )
2276 wxRect
* rect
= node
->GetData();
2279 region
= new wxRegion(*rect
);
2281 // TODO: is this correct? In SetDCClipping above,
2282 // XIntersectRegion is used to combine paint and user
2283 // regions. XIntersectRegion appears to work in that case...
2284 region
->Union(*rect
);
2290 win
->GetClientSize(&cw
, &ch
);
2291 region
= new wxRegion(wxRect(0, 0, cw
, ch
));
2294 win
->SetUpdateRegion(*region
);
2296 wxRegion
& theRegion(win
->GetUpdateRegion());
2297 theRegion
.SetRects(updateRects
); // We also store in terms of rects, for iteration to work.
2299 // Set the clipping region. Any user-defined region will be combined with this
2300 // one in SetDCClipping.
2301 XSetRegion ((Display
*) m_display
, (GC
) m_gc
, (Region
) region
->GetXRegion());
2306 wxPaintDC::~wxPaintDC()
2308 XSetClipMask ((Display
*) m_display
, (GC
) m_gc
, None
);
2310 m_window
->ClearUpdateRegion();
2313 // ----------------------------------------------------------------------------
2314 // private functions
2315 // ----------------------------------------------------------------------------
2318 Used when copying between drawables on different (Display*) m_displays. Not
2319 very fast, but better than giving up.
2322 static void XCopyRemote(Display
*src_display
, Display
*dest_display
,
2323 Drawable src
, Drawable dest
,
2326 unsigned int w
, unsigned int h
,
2327 int destx
, int desty
,
2328 bool more
, XImage
**cache
)
2330 XImage
*image
, *destimage
;
2331 Colormap destcm
, srccm
;
2332 static const int CACHE_SIZE
= 256;
2335 unsigned long cachesrc
[CACHE_SIZE
], cachedest
[CACHE_SIZE
];
2336 int k
, cache_pos
, all_cache
;
2338 if (!cache
|| !*cache
)
2339 image
= XGetImage(src_display
, src
, srcx
, srcy
, w
, h
, AllPlanes
, ZPixmap
);
2343 destimage
= XGetImage(dest_display
, dest
, destx
, desty
, w
, h
, AllPlanes
, ZPixmap
);
2345 srccm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) src_display
);
2346 destcm
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dest_display
);
2351 for (i
= 0; i
< w
; i
++)
2352 for (j
= 0; j
< h
; j
++) {
2353 unsigned long pixel
;
2356 pixel
= XGetPixel(image
, i
, j
);
2357 for (k
= cache_pos
; k
--; )
2358 if (cachesrc
[k
] == pixel
) {
2359 pixel
= cachedest
[k
];
2363 for (k
= CACHE_SIZE
; k
-- > cache_pos
; )
2364 if (cachesrc
[k
] == pixel
) {
2365 pixel
= cachedest
[k
];
2369 cachesrc
[cache_pos
] = xcol
.pixel
= pixel
;
2370 XQueryColor(src_display
, srccm
, &xcol
);
2371 if (!XAllocColor(dest_display
, destcm
, &xcol
))
2373 cachedest
[cache_pos
] = pixel
= xcol
.pixel
;
2375 if (++cache_pos
>= CACHE_SIZE
) {
2381 XPutPixel(destimage
, i
, j
, pixel
);
2384 XPutImage(dest_display
, dest
, destgc
, destimage
, 0, 0, destx
, desty
, w
, h
);
2385 XDestroyImage(destimage
);
2390 XDestroyImage(image
);
2395 /* Helper function for 16-bit fonts */
2396 static int str16len(const char *s
)
2400 while (s
[0] && s
[1]) {