1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Markus Holzem, Chris Breeze
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "dcclient.h"
14 #include "wx/dcclient.h"
15 #include "wx/dcmemory.h"
22 //-----------------------------------------------------------------------------
24 //-----------------------------------------------------------------------------
34 static GdkPixmap
*hatches
[num_hatches
];
35 static GdkPixmap
**hatch_bitmap
= (GdkPixmap
**) NULL
;
37 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
41 #define RAD2DEG 57.2957795131
43 //-----------------------------------------------------------------------------
44 // temporary implementation of the missing GDK function
45 //-----------------------------------------------------------------------------
46 #include "gdk/gdkprivate.h"
47 void gdk_draw_bitmap (GdkDrawable
*drawable
,
57 GdkWindowPrivate
*drawable_private
;
58 GdkWindowPrivate
*src_private
;
59 GdkGCPrivate
*gc_private
;
61 g_return_if_fail (drawable
!= NULL
);
62 g_return_if_fail (src
!= NULL
);
63 g_return_if_fail (gc
!= NULL
);
65 drawable_private
= (GdkWindowPrivate
*) drawable
;
66 src_private
= (GdkWindowPrivate
*) src
;
67 if (drawable_private
->destroyed
|| src_private
->destroyed
)
70 gc_private
= (GdkGCPrivate
*) gc
;
72 if (width
== -1) width
= src_private
->width
;
73 if (height
== -1) height
= src_private
->height
;
75 XCopyPlane( drawable_private
->xdisplay
,
77 drawable_private
->xwindow
,
85 //-----------------------------------------------------------------------------
87 //-----------------------------------------------------------------------------
89 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC
,wxDC
)
91 wxWindowDC::wxWindowDC()
93 m_penGC
= (GdkGC
*) NULL
;
94 m_brushGC
= (GdkGC
*) NULL
;
95 m_textGC
= (GdkGC
*) NULL
;
96 m_bgGC
= (GdkGC
*) NULL
;
97 m_cmap
= (GdkColormap
*) NULL
;
99 m_owner
= (wxWindow
*)NULL
;
102 wxWindowDC::wxWindowDC( wxWindow
*window
)
104 m_penGC
= (GdkGC
*) NULL
;
105 m_brushGC
= (GdkGC
*) NULL
;
106 m_textGC
= (GdkGC
*) NULL
;
107 m_bgGC
= (GdkGC
*) NULL
;
108 m_cmap
= (GdkColormap
*) NULL
;
109 m_owner
= (wxWindow
*)NULL
;
113 GtkWidget
*widget
= window
->m_wxwindow
;
116 m_window
= widget
->window
;
121 /* force realization */
122 gtk_widget_realize( widget
);
123 m_window
= widget
->window
;
126 /* still not realized ? */
127 if (!m_window
) return;
129 if (window
->m_wxwindow
)
130 m_cmap
= gtk_widget_get_colormap( window
->m_wxwindow
);
132 m_cmap
= gtk_widget_get_colormap( window
->m_widget
);
138 /* this must be done after SetUpDC, bacause SetUpDC calls the
139 repective SetBrush, SetPen, SetBackground etc functions
140 to set up the DC. SetBackground call m_owner->SetBackground
141 and this might not be desired as the standard dc background
142 is white whereas a window might assume gray to be the
143 standard (as e.g. wxStatusBar) */
148 wxWindowDC::~wxWindowDC()
153 void wxWindowDC::FloodFill( long WXUNUSED(x
), long WXUNUSED(y
),
154 const wxColour
&WXUNUSED(col
), int WXUNUSED(style
) )
156 wxFAIL_MSG( _T("wxWindowDC::FloodFill not implemented") );
159 bool wxWindowDC::GetPixel( long WXUNUSED(x1
), long WXUNUSED(y1
), wxColour
*WXUNUSED(col
) ) const
161 wxFAIL_MSG( _T("wxWindowDC::GetPixel not implemented") );
165 void wxWindowDC::DrawLine( long x1
, long y1
, long x2
, long y2
)
167 wxCHECK_RET( Ok(), _T("invalid window dc") );
169 if (m_pen
.GetStyle() != wxTRANSPARENT
)
171 gdk_draw_line( m_window
, m_penGC
,
172 XLOG2DEV(x1
), YLOG2DEV(y1
), XLOG2DEV(x2
), YLOG2DEV(y2
) );
174 CalcBoundingBox(x1
, y1
);
175 CalcBoundingBox(x2
, y2
);
179 void wxWindowDC::CrossHair( long x
, long y
)
181 wxCHECK_RET( Ok(), _T("invalid window dc") );
183 if (m_pen
.GetStyle() != wxTRANSPARENT
)
188 long xx
= XLOG2DEV(x
);
189 long yy
= YLOG2DEV(y
);
190 gdk_draw_line( m_window
, m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
191 gdk_draw_line( m_window
, m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
195 void wxWindowDC::DrawArc( long x1
, long y1
, long x2
, long y2
, double xc
, double yc
)
197 wxCHECK_RET( Ok(), _T("invalid window dc") );
199 long xx1
= XLOG2DEV(x1
);
200 long yy1
= YLOG2DEV(y1
);
201 long xx2
= XLOG2DEV(x2
);
202 long yy2
= YLOG2DEV(y2
);
203 long xxc
= XLOG2DEV((long)xc
);
204 long yyc
= YLOG2DEV((long)yc
);
205 double dx
= xx1
- xxc
;
206 double dy
= yy1
- yyc
;
207 double radius
= sqrt(dx
*dx
+dy
*dy
);
208 long r
= (long)radius
;
209 double radius1
, radius2
;
211 if (xx1
== xx2
&& yy1
== yy2
)
219 radius1
= radius2
= 0.0;
223 radius1
= (xx1
- xxc
== 0) ?
224 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
225 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
226 radius2
= (xx2
- xxc
== 0) ?
227 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
228 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
230 long alpha1
= long(radius1
* 64.0);
231 long alpha2
= long((radius2
- radius1
) * 64.0);
232 while (alpha2
<= 0) alpha2
+= 360*64;
233 while (alpha1
> 360*64) alpha1
-= 360*64;
235 if (m_brush
.GetStyle() != wxTRANSPARENT
)
236 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
238 if (m_pen
.GetStyle() != wxTRANSPARENT
)
239 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
241 CalcBoundingBox (x1
, y1
);
242 CalcBoundingBox (x2
, y2
);
245 void wxWindowDC::DrawEllipticArc( long x
, long y
, long width
, long height
, double sa
, double ea
)
247 wxCHECK_RET( Ok(), _T("invalid window dc") );
249 long xx
= XLOG2DEV(x
);
250 long yy
= YLOG2DEV(y
);
251 long ww
= m_signX
* XLOG2DEVREL(width
);
252 long hh
= m_signY
* YLOG2DEVREL(height
);
254 // CMB: handle -ve width and/or height
255 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
256 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
258 long start
= long(sa
* 64.0);
259 long end
= long(ea
* 64.0);
260 if (m_brush
.GetStyle() != wxTRANSPARENT
)
261 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end
);
263 if (m_pen
.GetStyle() != wxTRANSPARENT
)
264 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, start
, end
);
266 CalcBoundingBox (x
, y
);
267 CalcBoundingBox (x
+ width
, y
+ height
);
270 void wxWindowDC::DrawPoint( long x
, long y
)
272 wxCHECK_RET( Ok(), _T("invalid window dc") );
274 if (m_pen
.GetStyle() != wxTRANSPARENT
)
275 gdk_draw_point( m_window
, m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
277 CalcBoundingBox (x
, y
);
280 void wxWindowDC::DrawLines( int n
, wxPoint points
[], long xoffset
, long yoffset
)
282 wxCHECK_RET( Ok(), _T("invalid window dc") );
284 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
287 CalcBoundingBox( points
[0].x
+ xoffset
, points
[0].y
+ yoffset
);
289 for (int i
= 0; i
< n
-1; i
++)
291 long x1
= XLOG2DEV(points
[i
].x
+ xoffset
);
292 long x2
= XLOG2DEV(points
[i
+1].x
+ xoffset
);
293 long y1
= YLOG2DEV(points
[i
].y
+ yoffset
); // oh, what a waste
294 long y2
= YLOG2DEV(points
[i
+1].y
+ yoffset
);
295 gdk_draw_line( m_window
, m_penGC
, x1
, y1
, x2
, y2
);
297 CalcBoundingBox( points
[i
+1].x
+ xoffset
, points
[i
+1].y
+ yoffset
);
301 void wxWindowDC::DrawLines( wxList
*points
, long xoffset
, long yoffset
)
303 wxCHECK_RET( Ok(), _T("invalid window dc") );
305 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
307 wxNode
*node
= points
->First();
310 wxPoint
*pt
= (wxPoint
*)node
->Data();
311 CalcBoundingBox( pt
->x
+ xoffset
, pt
->y
+ yoffset
);
315 wxPoint
*point
= (wxPoint
*)node
->Data();
316 wxPoint
*npoint
= (wxPoint
*)node
->Next()->Data();
317 long x1
= XLOG2DEV(point
->x
+ xoffset
);
318 long x2
= XLOG2DEV(npoint
->x
+ xoffset
);
319 long y1
= YLOG2DEV(point
->y
+ yoffset
); // and a waste again...
320 long y2
= YLOG2DEV(npoint
->y
+ yoffset
);
321 gdk_draw_line( m_window
, m_penGC
, x1
, y1
, x2
, y2
);
324 CalcBoundingBox( npoint
->x
+ xoffset
, npoint
->y
+ yoffset
);
328 void wxWindowDC::DrawPolygon( int n
, wxPoint points
[], long xoffset
, long yoffset
, int WXUNUSED(fillStyle
) )
330 wxCHECK_RET( Ok(), _T("invalid window dc") );
334 GdkPoint
*gdkpoints
= new GdkPoint
[n
+1];
336 for (i
= 0 ; i
< n
; i
++)
338 gdkpoints
[i
].x
= XLOG2DEV(points
[i
].x
+ xoffset
);
339 gdkpoints
[i
].y
= YLOG2DEV(points
[i
].y
+ yoffset
);
341 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
344 if (m_brush
.GetStyle() != wxTRANSPARENT
)
345 gdk_draw_polygon (m_window
, m_brushGC
, TRUE
, gdkpoints
, n
);
349 if (m_pen
.GetStyle() != wxTRANSPARENT
)
350 for (i
= 0 ; i
< n
; i
++)
352 gdk_draw_line( m_window
, m_penGC
,
355 gdkpoints
[(i
+1)%n
].x
,
356 gdkpoints
[(i
+1)%n
].y
);
362 void wxWindowDC::DrawPolygon( wxList
*lines
, long xoffset
, long yoffset
, int WXUNUSED(fillStyle
))
364 wxCHECK_RET( Ok(), _T("invalid window dc") );
366 int n
= lines
->Number();
369 GdkPoint
*gdkpoints
= new GdkPoint
[n
];
370 wxNode
*node
= lines
->First();
374 wxPoint
*p
= (wxPoint
*) node
->Data();
375 gdkpoints
[cnt
].x
= XLOG2DEV(p
->x
+ xoffset
);
376 gdkpoints
[cnt
].y
= YLOG2DEV(p
->y
+ yoffset
);
380 CalcBoundingBox( p
->x
+ xoffset
, p
->y
+ yoffset
);
383 if (m_brush
.GetStyle() != wxTRANSPARENT
)
384 gdk_draw_polygon (m_window
, m_brushGC
, TRUE
, gdkpoints
, n
);
388 if (m_pen
.GetStyle() != wxTRANSPARENT
)
391 for (i
= 0 ; i
< n
; i
++)
393 gdk_draw_line( m_window
, m_penGC
,
396 gdkpoints
[(i
+1)%n
].x
,
397 gdkpoints
[(i
+1)%n
].y
);
403 void wxWindowDC::DrawRectangle( long x
, long y
, long width
, long height
)
405 wxCHECK_RET( Ok(), _T("invalid window dc") );
407 long xx
= XLOG2DEV(x
);
408 long yy
= YLOG2DEV(y
);
409 long ww
= m_signX
* XLOG2DEVREL(width
);
410 long hh
= m_signY
* YLOG2DEVREL(height
);
412 // CMB: draw nothing if transformed w or h is 0
413 if (ww
== 0 || hh
== 0) return;
415 // CMB: handle -ve width and/or height
416 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
417 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
419 if (m_brush
.GetStyle() != wxTRANSPARENT
)
420 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
);
422 if (m_pen
.GetStyle() != wxTRANSPARENT
)
423 gdk_draw_rectangle( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
-1, hh
-1 );
425 CalcBoundingBox( x
, y
);
426 CalcBoundingBox( x
+ width
, y
+ height
);
429 void wxWindowDC::DrawRoundedRectangle( long x
, long y
, long width
, long height
, double radius
)
431 wxCHECK_RET( Ok(), _T("invalid window dc") );
433 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
435 long xx
= XLOG2DEV(x
);
436 long yy
= YLOG2DEV(y
);
437 long ww
= m_signX
* XLOG2DEVREL(width
);
438 long hh
= m_signY
* YLOG2DEVREL(height
);
439 long rr
= XLOG2DEVREL((long)radius
);
441 // CMB: handle -ve width and/or height
442 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
443 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
445 // CMB: if radius is zero use DrawRectangle() instead to avoid
446 // X drawing errors with small radii
449 DrawRectangle( x
, y
, width
, height
);
453 // CMB: draw nothing if transformed w or h is 0
454 if (ww
== 0 || hh
== 0) return;
456 // CMB: adjust size if outline is drawn otherwise the result is
457 // 1 pixel too wide and high
458 if (m_pen
.GetStyle() != wxTRANSPARENT
)
464 // CMB: ensure dd is not larger than rectangle otherwise we
465 // get an hour glass shape
467 if (dd
> ww
) dd
= ww
;
468 if (dd
> hh
) dd
= hh
;
471 if (m_brush
.GetStyle() != wxTRANSPARENT
)
473 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh
);
474 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
475 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
476 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
477 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
478 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
481 if (m_pen
.GetStyle() != wxTRANSPARENT
)
483 gdk_draw_line( m_window
, m_penGC
, xx
+rr
, yy
, xx
+ww
-rr
, yy
);
484 gdk_draw_line( m_window
, m_penGC
, xx
+rr
, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
485 gdk_draw_line( m_window
, m_penGC
, xx
, yy
+rr
, xx
, yy
+hh
-rr
);
486 gdk_draw_line( m_window
, m_penGC
, xx
+ww
, yy
+rr
, xx
+ww
, yy
+hh
-rr
);
487 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
488 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
489 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
490 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
493 // this ignores the radius
494 CalcBoundingBox( x
, y
);
495 CalcBoundingBox( x
+ width
, y
+ height
);
498 void wxWindowDC::DrawEllipse( long x
, long y
, long width
, long height
)
500 wxCHECK_RET( Ok(), _T("invalid window dc") );
502 long xx
= XLOG2DEV(x
);
503 long yy
= YLOG2DEV(y
);
504 long ww
= m_signX
* XLOG2DEVREL(width
);
505 long hh
= m_signY
* YLOG2DEVREL(height
);
507 // CMB: handle -ve width and/or height
508 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
509 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
511 if (m_brush
.GetStyle() != wxTRANSPARENT
)
512 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 );
514 if (m_pen
.GetStyle() != wxTRANSPARENT
)
515 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, 0, 360*64 );
517 CalcBoundingBox( x
- width
, y
- height
);
518 CalcBoundingBox( x
+ width
, y
+ height
);
521 bool wxWindowDC::CanDrawBitmap() const
526 void wxWindowDC::DrawIcon( const wxIcon
&icon
, long x
, long y
)
528 DrawBitmap( icon
, x
, y
, TRUE
);
531 void wxWindowDC::DrawBitmap( const wxBitmap
&bitmap
, long x
, long y
, bool useMask
)
533 wxCHECK_RET( Ok(), _T("invalid window dc") );
535 if (!bitmap
.Ok()) return;
537 /* scale/translate size and position */
539 int xx
= XLOG2DEV(x
);
540 int yy
= YLOG2DEV(y
);
542 int w
= bitmap
.GetWidth();
543 int h
= bitmap
.GetHeight();
545 int ww
= XLOG2DEVREL(w
);
546 int hh
= YLOG2DEVREL(h
);
548 /* scale bitmap if required */
552 if ((w
!= ww
) || (h
!= hh
))
554 wxImage
image( bitmap
);
555 image
= image
.Scale( ww
, hh
);
557 use_bitmap
= image
.ConvertToBitmap();
564 /* apply mask if any */
566 GdkBitmap
*mask
= (GdkBitmap
*) NULL
;
567 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
571 gdk_gc_set_clip_mask( m_penGC
, mask
);
572 gdk_gc_set_clip_origin( m_penGC
, xx
, yy
);
575 /* draw XPixmap or XBitmap, depending on what the wxBitmap contains */
577 GdkPixmap
*pm
= use_bitmap
.GetPixmap();
580 gdk_draw_pixmap( m_window
, m_penGC
, pm
, 0, 0, xx
, yy
, -1, -1 );
584 GdkBitmap
*bm
= use_bitmap
.GetBitmap();
587 gdk_draw_bitmap( m_window
, m_penGC
, bm
, 0, 0, xx
, yy
, -1, -1 );
591 /* remove mask again if any */
595 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap
*) NULL
);
596 gdk_gc_set_clip_origin( m_penGC
, 0, 0 );
599 CalcBoundingBox( x
, y
);
600 CalcBoundingBox( x
+ w
, y
+ h
);
603 bool wxWindowDC::Blit( long xdest
, long ydest
, long width
, long height
,
604 wxDC
*source
, long xsrc
, long ysrc
, int logical_func
, bool useMask
)
606 /* this is the nth try to get this utterly useless function to
607 work. it now completely ignores the scaling or translation
608 of the source dc, but scales correctly on the target dc and
609 knows about possible mask information in a memory dc. */
611 wxCHECK_MSG( Ok(), FALSE
, _T("invalid window dc") );
613 wxCHECK_MSG( source
, FALSE
, _T("invalid source dc") );
615 wxClientDC
*srcDC
= (wxClientDC
*)source
;
616 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
618 bool use_bitmap_method
= FALSE
;
620 if (srcDC
->m_isMemDC
)
622 if (!memDC
->m_selected
.Ok()) return FALSE
;
624 /* we use the "XCopyArea" way to copy a memory dc into
625 y different window if the memory dc BOTH
626 a) doesn't have any mask or its mask isn't used
630 if (useMask
&& (memDC
->m_selected
.GetMask()))
632 /* we HAVE TO use the direct way for memory dcs
633 that have mask since the XCopyArea doesn't know
635 use_bitmap_method
= TRUE
;
637 else if (memDC
->m_selected
.GetDepth() == 1)
639 /* we HAVE TO use the direct way for memory dcs
640 that are bitmaps because XCopyArea doesn't cope
641 with different bit depths */
642 use_bitmap_method
= TRUE
;
644 else if ((xsrc
== 0) && (ysrc
== 0) &&
645 (width
== memDC
->m_selected
.GetWidth()) &&
646 (height
== memDC
->m_selected
.GetHeight()))
648 /* we SHOULD use the direct way if all of the bitmap
649 in the memory dc is copied in which case XCopyArea
650 wouldn't be able able to boost performace by reducing
651 the area to be scaled */
652 use_bitmap_method
= TRUE
;
656 use_bitmap_method
= FALSE
;
660 CalcBoundingBox( xdest
, ydest
);
661 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
663 int old_logical_func
= m_logicalFunction
;
664 SetLogicalFunction( logical_func
);
666 if (use_bitmap_method
)
668 /* scale/translate bitmap size */
670 long bm_width
= memDC
->m_selected
.GetWidth();
671 long bm_height
= memDC
->m_selected
.GetHeight();
673 long bm_ww
= XLOG2DEVREL( bm_width
);
674 long bm_hh
= YLOG2DEVREL( bm_height
);
676 /* scale bitmap if required */
680 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
682 wxImage
image( memDC
->m_selected
);
683 image
= image
.Scale( bm_ww
, bm_hh
);
685 use_bitmap
= image
.ConvertToBitmap();
689 use_bitmap
= memDC
->m_selected
;
692 /* scale/translate size and position */
694 long xx
= XLOG2DEV(xdest
);
695 long yy
= YLOG2DEV(ydest
);
697 long ww
= XLOG2DEVREL(width
);
698 long hh
= YLOG2DEVREL(height
);
700 /* apply mask if any */
702 GdkBitmap
*mask
= (GdkBitmap
*) NULL
;
703 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
707 gdk_gc_set_clip_mask( m_penGC
, mask
);
708 gdk_gc_set_clip_origin( m_penGC
, xx
, yy
);
711 /* draw XPixmap or XBitmap, depending on what the wxBitmap contains */
713 GdkPixmap
*pm
= use_bitmap
.GetPixmap();
716 gdk_draw_pixmap( m_window
, m_penGC
, pm
, xsrc
, ysrc
, xx
, yy
, ww
, hh
);
720 GdkBitmap
*bm
= use_bitmap
.GetBitmap();
723 /* we use the textGC here because blitting a bitmap is done
724 using the current text colour */
725 gdk_draw_bitmap( m_window
, m_textGC
, bm
, xsrc
, ysrc
, xx
, yy
, ww
, hh
);
729 /* remove mask again if any */
733 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap
*) NULL
);
734 gdk_gc_set_clip_origin( m_penGC
, 0, 0 );
737 else /* use_bitmap_method */
739 /* scale/translate size and position */
741 long xx
= XLOG2DEV(xdest
);
742 long yy
= YLOG2DEV(ydest
);
744 long ww
= XLOG2DEVREL(width
);
745 long hh
= YLOG2DEVREL(height
);
747 if ((width
!= ww
) || (height
!= hh
))
749 /* draw source window into a bitmap as we cannot scale
750 a window in contrast to a bitmap. this would actually
751 work with memory dcs as well, but we'd lose the mask
752 information and waste one step in this process since
753 a memory already has a bitmap. all this is slightly
754 inefficient as we could take an XImage directly from
755 an X window, but we'd then also have to care that
756 the window is not outside the screen (in which case
757 we'd get a BadMatch or what not).
758 Is a double XGetImage and combined XGetPixel and
759 XPutPixel really faster? I'm not sure. look at wxXt
760 for a different implementation of the same problem. */
762 wxBitmap
bitmap( width
, height
);
763 gdk_window_copy_area( bitmap
.GetPixmap(), m_penGC
, 0, 0,
765 xsrc
, ysrc
, width
, height
);
769 wxImage
image( bitmap
);
770 image
= image
.Scale( ww
, hh
);
772 /* convert to bitmap */
774 bitmap
= image
.ConvertToBitmap();
776 /* draw scaled bitmap */
778 gdk_draw_pixmap( m_window
, m_penGC
, bitmap
.GetPixmap(), 0, 0, xx
, yy
, -1, -1 );
783 /* no scaling and not a memory dc with a mask either */
785 gdk_window_copy_area( m_window
, m_penGC
, xx
, yy
,
787 xsrc
, ysrc
, width
, height
);
791 SetLogicalFunction( old_logical_func
);
795 void wxWindowDC::DrawText( const wxString
&text
, long x
, long y
, bool WXUNUSED(use16
) )
797 wxCHECK_RET( Ok(), _T("invalid window dc") );
799 GdkFont
*font
= m_font
.GetInternalFont( m_scaleY
);
804 /* CMB 21/5/98: draw text background if mode is wxSOLID */
805 if (m_backgroundMode
== wxSOLID
)
807 long width
= gdk_string_width( font
, text
.mbc_str() );
808 long height
= font
->ascent
+ font
->descent
;
809 gdk_gc_set_foreground( m_textGC
, m_textBackgroundColour
.GetColor() );
810 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, x
, y
, width
, height
);
811 gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() );
813 gdk_draw_string( m_window
, font
, m_textGC
, x
, y
+ font
->ascent
, text
.mbc_str() );
815 /* CMB 17/7/98: simple underline: ignores scaling and underlying
816 X font's XA_UNDERLINE_POSITION and XA_UNDERLINE_THICKNESS
817 properties (see wxXt implementation) */
818 if (m_font
.GetUnderlined())
820 long width
= gdk_string_width( font
, text
.mbc_str() );
821 long ul_y
= y
+ font
->ascent
;
822 if (font
->descent
> 0) ul_y
++;
823 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
827 GetTextExtent (text
, &w
, &h
);
828 CalcBoundingBox (x
+ w
, y
+ h
);
829 CalcBoundingBox (x
, y
);
832 bool wxWindowDC::CanGetTextExtent() const
837 void wxWindowDC::GetTextExtent( const wxString
&string
, long *width
, long *height
,
838 long *descent
, long *externalLeading
,
839 wxFont
*theFont
, bool WXUNUSED(use16
) )
841 wxFont fontToUse
= m_font
;
842 if (theFont
) fontToUse
= *theFont
;
844 GdkFont
*font
= fontToUse
.GetInternalFont( m_scaleY
);
845 if (width
) (*width
) = long(gdk_string_width( font
, string
.mbc_str() ) / m_scaleX
);
846 if (height
) (*height
) = long((font
->ascent
+ font
->descent
) / m_scaleY
);
847 if (descent
) (*descent
) = long(font
->descent
/ m_scaleY
);
848 if (externalLeading
) (*externalLeading
) = 0; // ??
851 long wxWindowDC::GetCharWidth()
853 GdkFont
*font
= m_font
.GetInternalFont( m_scaleY
);
854 return long(gdk_string_width( font
, "H" ) / m_scaleX
);
857 long wxWindowDC::GetCharHeight()
859 GdkFont
*font
= m_font
.GetInternalFont( m_scaleY
);
860 return long((font
->ascent
+ font
->descent
) / m_scaleY
);
863 void wxWindowDC::Clear()
865 wxCHECK_RET( Ok(), _T("invalid window dc") );
867 /* - we either are a memory dc or have a window as the
868 owner. anything else shouldn't happen.
869 - we don't use gdk_window_clear() as we don't set
870 the window's background colour anymore. it is too
871 much pain to keep the DC's and the window's back-
872 ground colour in synch. */
877 m_owner
->GetSize( &width
, &height
);
878 gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height
);
885 GetSize( &width
, &height
);
886 gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height
);
891 void wxWindowDC::SetFont( const wxFont
&font
)
896 void wxWindowDC::SetPen( const wxPen
&pen
)
898 wxCHECK_RET( Ok(), _T("invalid window dc") );
900 if (m_pen
== pen
) return;
904 if (!m_pen
.Ok()) return;
906 gint width
= m_pen
.GetWidth();
907 // CMB: if width is non-zero scale it with the dc
914 // X doesn't allow different width in x and y and so we take
916 double w
= 0.5 + (abs(XLOG2DEVREL(width
)) + abs(YLOG2DEVREL(width
))) / 2.0;
920 GdkLineStyle lineStyle
= GDK_LINE_SOLID
;
921 switch (m_pen
.GetStyle())
923 case wxSOLID
: { lineStyle
= GDK_LINE_SOLID
; break; }
924 case wxDOT
: { lineStyle
= GDK_LINE_ON_OFF_DASH
; break; }
925 case wxLONG_DASH
: { lineStyle
= GDK_LINE_ON_OFF_DASH
; break; }
926 case wxSHORT_DASH
: { lineStyle
= GDK_LINE_ON_OFF_DASH
; break; }
927 case wxDOT_DASH
: { lineStyle
= GDK_LINE_DOUBLE_DASH
; break; }
930 GdkCapStyle capStyle
= GDK_CAP_ROUND
;
931 switch (m_pen
.GetCap())
933 case wxCAP_ROUND
: { capStyle
= (width
<= 1) ? GDK_CAP_NOT_LAST
: GDK_CAP_ROUND
; break; }
934 case wxCAP_PROJECTING
: { capStyle
= GDK_CAP_PROJECTING
; break; }
935 case wxCAP_BUTT
: { capStyle
= GDK_CAP_BUTT
; break; }
938 GdkJoinStyle joinStyle
= GDK_JOIN_ROUND
;
939 switch (m_pen
.GetJoin())
941 case wxJOIN_BEVEL
: { joinStyle
= GDK_JOIN_BEVEL
; break; }
942 case wxJOIN_ROUND
: { joinStyle
= GDK_JOIN_ROUND
; break; }
943 case wxJOIN_MITER
: { joinStyle
= GDK_JOIN_MITER
; break; }
946 gdk_gc_set_line_attributes( m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
948 m_pen
.GetColour().CalcPixel( m_cmap
);
949 gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() );
952 void wxWindowDC::SetBrush( const wxBrush
&brush
)
954 wxCHECK_RET( Ok(), _T("invalid window dc") );
956 if (m_brush
== brush
) return;
960 if (!m_brush
.Ok()) return;
962 m_brush
.GetColour().CalcPixel( m_cmap
);
963 gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() );
965 GdkFill fillStyle
= GDK_SOLID
;
966 switch (m_brush
.GetStyle())
972 fillStyle
= GDK_STIPPLED
;
975 gdk_gc_set_fill( m_brushGC
, fillStyle
);
977 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
979 if (m_brush
.GetStipple()->GetPixmap())
980 gdk_gc_set_stipple( m_brushGC
, m_brush
.GetStipple()->GetPixmap() );
982 gdk_gc_set_stipple( m_brushGC
, m_brush
.GetStipple()->GetBitmap() );
985 if (IS_HATCH(m_brush
.GetStyle()))
987 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
988 gdk_gc_set_stipple( m_brushGC
, hatches
[num
] );
992 void wxWindowDC::SetBackground( const wxBrush
&brush
)
994 /* CMB 21/7/98: Added SetBackground. Sets background brush
995 * for Clear() and bg colour for shapes filled with cross-hatch brush */
997 wxCHECK_RET( Ok(), _T("invalid window dc") );
999 if (m_backgroundBrush
== brush
) return;
1001 m_backgroundBrush
= brush
;
1003 if (!m_backgroundBrush
.Ok()) return;
1005 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
1006 gdk_gc_set_background( m_brushGC
, m_backgroundBrush
.GetColour().GetColor() );
1007 gdk_gc_set_background( m_penGC
, m_backgroundBrush
.GetColour().GetColor() );
1008 gdk_gc_set_background( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() );
1009 gdk_gc_set_foreground( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() );
1011 GdkFill fillStyle
= GDK_SOLID
;
1012 switch (m_backgroundBrush
.GetStyle())
1018 fillStyle
= GDK_STIPPLED
;
1021 gdk_gc_set_fill( m_bgGC
, fillStyle
);
1023 if (m_backgroundBrush
.GetStyle() == wxSTIPPLE
)
1025 gdk_gc_set_stipple( m_bgGC
, m_backgroundBrush
.GetStipple()->GetPixmap() );
1028 if (IS_HATCH(m_backgroundBrush
.GetStyle()))
1030 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
1031 gdk_gc_set_stipple( m_bgGC
, hatches
[num
] );
1035 void wxWindowDC::SetLogicalFunction( int function
)
1037 wxCHECK_RET( Ok(), _T("invalid window dc") );
1039 if (m_logicalFunction
== function
) return;
1041 GdkFunction mode
= GDK_COPY
;
1044 case wxXOR
: mode
= GDK_INVERT
; break;
1045 case wxINVERT
: mode
= GDK_INVERT
; break;
1046 #if (GDK_MINOR_VERSION > 0)
1047 case wxOR_REVERSE
: mode
= GDK_OR_REVERSE
; break;
1048 case wxAND_REVERSE
: mode
= GDK_AND_REVERSE
; break;
1049 case wxCLEAR
: mode
= GDK_CLEAR
; break;
1050 case wxSET
: mode
= GDK_SET
; break;
1051 case wxOR_INVERT
: mode
= GDK_OR_INVERT
; break;
1052 case wxAND
: mode
= GDK_AND
; break;
1053 case wxOR
: mode
= GDK_OR
; break;
1054 case wxEQUIV
: mode
= GDK_EQUIV
; break;
1055 case wxNAND
: mode
= GDK_NAND
; break;
1056 case wxAND_INVERT
: mode
= GDK_AND_INVERT
; break;
1057 /* ? wxSRC_INVERT GDK_AND_REVERSE, GDK_OR_REVERSE, GDK_OR_INVERT */
1062 m_logicalFunction
= function
;
1063 gdk_gc_set_function( m_penGC
, mode
);
1064 gdk_gc_set_function( m_brushGC
, mode
);
1065 gdk_gc_set_function( m_textGC
, mode
);
1068 void wxWindowDC::SetTextForeground( const wxColour
&col
)
1070 wxCHECK_RET( Ok(), _T("invalid window dc") );
1072 if (m_textForegroundColour
== col
) return;
1074 m_textForegroundColour
= col
;
1075 if (!m_textForegroundColour
.Ok()) return;
1077 m_textForegroundColour
.CalcPixel( m_cmap
);
1078 gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() );
1081 void wxWindowDC::SetTextBackground( const wxColour
&col
)
1083 wxCHECK_RET( Ok(), _T("invalid window dc") );
1085 if (m_textBackgroundColour
== col
) return;
1087 m_textBackgroundColour
= col
;
1088 if (!m_textBackgroundColour
.Ok()) return;
1090 m_textBackgroundColour
.CalcPixel( m_cmap
);
1091 gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() );
1094 void wxWindowDC::SetBackgroundMode( int mode
)
1096 wxCHECK_RET( Ok(), _T("invalid window dc") );
1098 m_backgroundMode
= mode
;
1100 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
1101 // transparent/solid background mode
1103 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
1105 gdk_gc_set_fill( m_brushGC
,
1106 (m_backgroundMode
== wxTRANSPARENT
) ? GDK_STIPPLED
: GDK_OPAQUE_STIPPLED
);
1110 void wxWindowDC::SetPalette( const wxPalette
& WXUNUSED(palette
) )
1112 wxFAIL_MSG( _T("wxWindowDC::SetPalette not implemented") );
1115 void wxWindowDC::SetClippingRegion( long x
, long y
, long width
, long height
)
1117 wxCHECK_RET( Ok(), _T("invalid window dc") );
1119 wxDC::SetClippingRegion( x
, y
, width
, height
);
1122 rect
.x
= XLOG2DEV(x
);
1123 rect
.y
= YLOG2DEV(y
);
1124 rect
.width
= XLOG2DEVREL(width
);
1125 rect
.height
= YLOG2DEVREL(height
);
1126 gdk_gc_set_clip_rectangle( m_penGC
, &rect
);
1127 gdk_gc_set_clip_rectangle( m_brushGC
, &rect
);
1128 gdk_gc_set_clip_rectangle( m_textGC
, &rect
);
1129 gdk_gc_set_clip_rectangle( m_bgGC
, &rect
);
1132 void wxWindowDC::SetClippingRegion( const wxRegion
®ion
)
1134 wxCHECK_RET( Ok(), _T("invalid window dc") );
1138 DestroyClippingRegion();
1142 gdk_gc_set_clip_region( m_penGC
, region
.GetRegion() );
1143 gdk_gc_set_clip_region( m_brushGC
, region
.GetRegion() );
1144 gdk_gc_set_clip_region( m_textGC
, region
.GetRegion() );
1145 gdk_gc_set_clip_region( m_bgGC
, region
.GetRegion() );
1148 void wxWindowDC::DestroyClippingRegion()
1150 wxCHECK_RET( Ok(), _T("invalid window dc") );
1152 wxDC::DestroyClippingRegion();
1154 gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle
*) NULL
);
1155 gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle
*) NULL
);
1156 gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle
*) NULL
);
1157 gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle
*) NULL
);
1160 void wxWindowDC::SetUpDC()
1164 m_logicalFunction
= wxCOPY
;
1165 m_penGC
= gdk_gc_new( m_window
);
1166 m_brushGC
= gdk_gc_new( m_window
);
1167 m_textGC
= gdk_gc_new( m_window
);
1168 m_bgGC
= gdk_gc_new( m_window
);
1170 wxColour
tmp_col( m_textForegroundColour
);
1171 m_textForegroundColour
= wxNullColour
;
1172 SetTextForeground( tmp_col
);
1173 tmp_col
= m_textBackgroundColour
;
1174 m_textBackgroundColour
= wxNullColour
;
1175 SetTextBackground( tmp_col
);
1177 wxPen
tmp_pen( m_pen
);
1181 wxFont
tmp_font( m_font
);
1182 m_font
= wxNullFont
;
1183 SetFont( tmp_font
);
1185 wxBrush
tmp_brush( m_brush
);
1186 m_brush
= wxNullBrush
;
1187 SetBrush( tmp_brush
);
1189 tmp_brush
= m_backgroundBrush
;
1190 m_backgroundBrush
= wxNullBrush
;
1191 SetBackground( tmp_brush
);
1195 hatch_bitmap
= hatches
;
1196 hatch_bitmap
[0] = gdk_bitmap_create_from_data( (GdkWindow
*) NULL
, bdiag_bits
, bdiag_width
, bdiag_height
);
1197 hatch_bitmap
[1] = gdk_bitmap_create_from_data( (GdkWindow
*) NULL
, cdiag_bits
, cdiag_width
, cdiag_height
);
1198 hatch_bitmap
[2] = gdk_bitmap_create_from_data( (GdkWindow
*) NULL
, fdiag_bits
, fdiag_width
, fdiag_height
);
1199 hatch_bitmap
[3] = gdk_bitmap_create_from_data( (GdkWindow
*) NULL
, cross_bits
, cross_width
, cross_height
);
1200 hatch_bitmap
[4] = gdk_bitmap_create_from_data( (GdkWindow
*) NULL
, horiz_bits
, horiz_width
, horiz_height
);
1201 hatch_bitmap
[5] = gdk_bitmap_create_from_data( (GdkWindow
*) NULL
, verti_bits
, verti_width
, verti_height
);
1205 void wxWindowDC::Destroy()
1207 if (m_penGC
) gdk_gc_unref( m_penGC
);
1208 m_penGC
= (GdkGC
*) NULL
;
1209 if (m_brushGC
) gdk_gc_unref( m_brushGC
);
1210 m_brushGC
= (GdkGC
*) NULL
;
1211 if (m_textGC
) gdk_gc_unref( m_textGC
);
1212 m_textGC
= (GdkGC
*) NULL
;
1213 if (m_bgGC
) gdk_gc_unref( m_bgGC
);
1214 m_bgGC
= (GdkGC
*) NULL
;
1217 GdkWindow
*wxWindowDC::GetWindow()
1222 // ----------------------------------- spline code ----------------------------------------
1224 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
1225 double a3
, double b3
, double a4
, double b4
);
1226 void wx_clear_stack();
1227 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
1228 double *y3
, double *x4
, double *y4
);
1229 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
1230 double x4
, double y4
);
1231 static bool wx_spline_add_point(double x
, double y
);
1232 static void wx_spline_draw_point_array(wxDC
*dc
);
1234 wxList wx_spline_point_list
;
1236 #define half(z1, z2) ((z1+z2)/2.0)
1239 /* iterative version */
1241 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
1244 register double xmid
, ymid
;
1245 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
1248 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
1250 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
1251 xmid
= (double)half(x2
, x3
);
1252 ymid
= (double)half(y2
, y3
);
1253 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
1254 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
1255 wx_spline_add_point( x1
, y1
);
1256 wx_spline_add_point( xmid
, ymid
);
1258 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
1259 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
1260 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
1261 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
1266 /* utilities used by spline drawing routines */
1268 typedef struct wx_spline_stack_struct
{
1269 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
1272 #define SPLINE_STACK_DEPTH 20
1273 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
1274 static Stack
*wx_stack_top
;
1275 static int wx_stack_count
;
1277 void wx_clear_stack()
1279 wx_stack_top
= wx_spline_stack
;
1283 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
1285 wx_stack_top
->x1
= x1
;
1286 wx_stack_top
->y1
= y1
;
1287 wx_stack_top
->x2
= x2
;
1288 wx_stack_top
->y2
= y2
;
1289 wx_stack_top
->x3
= x3
;
1290 wx_stack_top
->y3
= y3
;
1291 wx_stack_top
->x4
= x4
;
1292 wx_stack_top
->y4
= y4
;
1297 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
1298 double *x3
, double *y3
, double *x4
, double *y4
)
1300 if (wx_stack_count
== 0)
1304 *x1
= wx_stack_top
->x1
;
1305 *y1
= wx_stack_top
->y1
;
1306 *x2
= wx_stack_top
->x2
;
1307 *y2
= wx_stack_top
->y2
;
1308 *x3
= wx_stack_top
->x3
;
1309 *y3
= wx_stack_top
->y3
;
1310 *x4
= wx_stack_top
->x4
;
1311 *y4
= wx_stack_top
->y4
;
1315 static bool wx_spline_add_point(double x
, double y
)
1317 wxPoint
*point
= new wxPoint
;
1320 wx_spline_point_list
.Append((wxObject
*)point
);
1324 static void wx_spline_draw_point_array(wxDC
*dc
)
1326 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
1327 wxNode
*node
= wx_spline_point_list
.First();
1330 wxPoint
*point
= (wxPoint
*)node
->Data();
1333 node
= wx_spline_point_list
.First();
1337 void wxWindowDC::DrawSpline( wxList
*points
)
1339 wxCHECK_RET( Ok(), _T("invalid window dc") );
1342 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
1343 double x1
, y1
, x2
, y2
;
1345 wxNode
*node
= points
->First();
1346 p
= (wxPoint
*)node
->Data();
1351 node
= node
->Next();
1352 p
= (wxPoint
*)node
->Data();
1356 cx1
= (double)((x1
+ x2
) / 2);
1357 cy1
= (double)((y1
+ y2
) / 2);
1358 cx2
= (double)((cx1
+ x2
) / 2);
1359 cy2
= (double)((cy1
+ y2
) / 2);
1361 wx_spline_add_point(x1
, y1
);
1363 while ((node
= node
->Next()) != NULL
)
1365 p
= (wxPoint
*)node
->Data();
1370 cx4
= (double)(x1
+ x2
) / 2;
1371 cy4
= (double)(y1
+ y2
) / 2;
1372 cx3
= (double)(x1
+ cx4
) / 2;
1373 cy3
= (double)(y1
+ cy4
) / 2;
1375 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
1379 cx2
= (double)(cx1
+ x2
) / 2;
1380 cy2
= (double)(cy1
+ y2
) / 2;
1383 wx_spline_add_point( cx1
, cy1
);
1384 wx_spline_add_point( x2
, y2
);
1386 wx_spline_draw_point_array( this );
1389 // Resolution in pixels per logical inch
1390 wxSize
wxWindowDC::GetPPI(void) const
1392 return wxSize(100, 100);
1395 //-----------------------------------------------------------------------------
1397 //-----------------------------------------------------------------------------
1399 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
,wxWindowDC
)
1401 wxPaintDC::wxPaintDC()
1406 wxPaintDC::wxPaintDC( wxWindow
*win
)
1411 //-----------------------------------------------------------------------------
1413 //-----------------------------------------------------------------------------
1415 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
,wxWindowDC
)
1417 wxClientDC::wxClientDC()
1422 wxClientDC::wxClientDC( wxWindow
*win
)