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
;
112 GtkWidget
*widget
= window
->m_wxwindow
;
114 m_window
= widget
->window
;
115 if (!m_window
) return;
116 if (window
->m_wxwindow
)
117 m_cmap
= gtk_widget_get_colormap( window
->m_wxwindow
);
119 m_cmap
= gtk_widget_get_colormap( window
->m_widget
);
125 /* this must be done after SetUpDC, bacause SetUpDC calls the
126 repective SetBrush, SetPen, SetBackground etc functions
127 to set up the DC. SetBackground call m_owner->SetBackground
128 and this might not be desired as the standard dc background
129 is white whereas a window might assume gray to be the
130 standard (as e.g. wxStatusBar) */
135 wxWindowDC::~wxWindowDC()
140 void wxWindowDC::FloodFill( long WXUNUSED(x
), long WXUNUSED(y
),
141 const wxColour
&WXUNUSED(col
), int WXUNUSED(style
) )
143 wxFAIL_MSG( _T("wxWindowDC::FloodFill not implemented") );
146 bool wxWindowDC::GetPixel( long WXUNUSED(x1
), long WXUNUSED(y1
), wxColour
*WXUNUSED(col
) ) const
148 wxFAIL_MSG( _T("wxWindowDC::GetPixel not implemented") );
152 void wxWindowDC::DrawLine( long x1
, long y1
, long x2
, long y2
)
154 wxCHECK_RET( Ok(), _T("invalid window dc") );
156 if (m_pen
.GetStyle() != wxTRANSPARENT
)
158 gdk_draw_line( m_window
, m_penGC
,
159 XLOG2DEV(x1
), YLOG2DEV(y1
), XLOG2DEV(x2
), YLOG2DEV(y2
) );
161 CalcBoundingBox(x1
, y1
);
162 CalcBoundingBox(x2
, y2
);
166 void wxWindowDC::CrossHair( long x
, long y
)
168 wxCHECK_RET( Ok(), _T("invalid window dc") );
170 if (m_pen
.GetStyle() != wxTRANSPARENT
)
175 long xx
= XLOG2DEV(x
);
176 long yy
= YLOG2DEV(y
);
177 gdk_draw_line( m_window
, m_penGC
, 0, yy
, XLOG2DEVREL(w
), yy
);
178 gdk_draw_line( m_window
, m_penGC
, xx
, 0, xx
, YLOG2DEVREL(h
) );
182 void wxWindowDC::DrawArc( long x1
, long y1
, long x2
, long y2
, double xc
, double yc
)
184 wxCHECK_RET( Ok(), _T("invalid window dc") );
186 long xx1
= XLOG2DEV(x1
);
187 long yy1
= YLOG2DEV(y1
);
188 long xx2
= XLOG2DEV(x2
);
189 long yy2
= YLOG2DEV(y2
);
190 long xxc
= XLOG2DEV((long)xc
);
191 long yyc
= YLOG2DEV((long)yc
);
192 double dx
= xx1
- xxc
;
193 double dy
= yy1
- yyc
;
194 double radius
= sqrt(dx
*dx
+dy
*dy
);
195 long r
= (long)radius
;
196 double radius1
, radius2
;
198 if (xx1
== xx2
&& yy1
== yy2
)
206 radius1
= radius2
= 0.0;
210 radius1
= (xx1
- xxc
== 0) ?
211 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
212 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
213 radius2
= (xx2
- xxc
== 0) ?
214 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
215 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
217 long alpha1
= long(radius1
* 64.0);
218 long alpha2
= long((radius2
- radius1
) * 64.0);
219 while (alpha2
<= 0) alpha2
+= 360*64;
220 while (alpha1
> 360*64) alpha1
-= 360*64;
222 if (m_brush
.GetStyle() != wxTRANSPARENT
)
223 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
225 if (m_pen
.GetStyle() != wxTRANSPARENT
)
226 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
228 CalcBoundingBox (x1
, y1
);
229 CalcBoundingBox (x2
, y2
);
232 void wxWindowDC::DrawEllipticArc( long x
, long y
, long width
, long height
, double sa
, double ea
)
234 wxCHECK_RET( Ok(), _T("invalid window dc") );
236 long xx
= XLOG2DEV(x
);
237 long yy
= YLOG2DEV(y
);
238 long ww
= m_signX
* XLOG2DEVREL(width
);
239 long hh
= m_signY
* YLOG2DEVREL(height
);
241 // CMB: handle -ve width and/or height
242 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
243 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
245 long start
= long(sa
* 64.0);
246 long end
= long(ea
* 64.0);
247 if (m_brush
.GetStyle() != wxTRANSPARENT
)
248 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, start
, end
);
250 if (m_pen
.GetStyle() != wxTRANSPARENT
)
251 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, start
, end
);
253 CalcBoundingBox (x
, y
);
254 CalcBoundingBox (x
+ width
, y
+ height
);
257 void wxWindowDC::DrawPoint( long x
, long y
)
259 wxCHECK_RET( Ok(), _T("invalid window dc") );
261 if (m_pen
.GetStyle() != wxTRANSPARENT
)
262 gdk_draw_point( m_window
, m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
264 CalcBoundingBox (x
, y
);
267 void wxWindowDC::DrawLines( int n
, wxPoint points
[], long xoffset
, long yoffset
)
269 wxCHECK_RET( Ok(), _T("invalid window dc") );
271 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
274 CalcBoundingBox( points
[0].x
+ xoffset
, points
[0].y
+ yoffset
);
276 for (int i
= 0; i
< n
-1; i
++)
278 long x1
= XLOG2DEV(points
[i
].x
+ xoffset
);
279 long x2
= XLOG2DEV(points
[i
+1].x
+ xoffset
);
280 long y1
= YLOG2DEV(points
[i
].y
+ yoffset
); // oh, what a waste
281 long y2
= YLOG2DEV(points
[i
+1].y
+ yoffset
);
282 gdk_draw_line( m_window
, m_penGC
, x1
, y1
, x2
, y2
);
284 CalcBoundingBox( points
[i
+1].x
+ xoffset
, points
[i
+1].y
+ yoffset
);
288 void wxWindowDC::DrawLines( wxList
*points
, long xoffset
, long yoffset
)
290 wxCHECK_RET( Ok(), _T("invalid window dc") );
292 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
294 wxNode
*node
= points
->First();
297 wxPoint
*pt
= (wxPoint
*)node
->Data();
298 CalcBoundingBox( pt
->x
+ xoffset
, pt
->y
+ yoffset
);
302 wxPoint
*point
= (wxPoint
*)node
->Data();
303 wxPoint
*npoint
= (wxPoint
*)node
->Next()->Data();
304 long x1
= XLOG2DEV(point
->x
+ xoffset
);
305 long x2
= XLOG2DEV(npoint
->x
+ xoffset
);
306 long y1
= YLOG2DEV(point
->y
+ yoffset
); // and a waste again...
307 long y2
= YLOG2DEV(npoint
->y
+ yoffset
);
308 gdk_draw_line( m_window
, m_penGC
, x1
, y1
, x2
, y2
);
311 CalcBoundingBox( npoint
->x
+ xoffset
, npoint
->y
+ yoffset
);
315 void wxWindowDC::DrawPolygon( int n
, wxPoint points
[], long xoffset
, long yoffset
, int WXUNUSED(fillStyle
) )
317 wxCHECK_RET( Ok(), _T("invalid window dc") );
321 GdkPoint
*gdkpoints
= new GdkPoint
[n
+1];
323 for (i
= 0 ; i
< n
; i
++)
325 gdkpoints
[i
].x
= XLOG2DEV(points
[i
].x
+ xoffset
);
326 gdkpoints
[i
].y
= YLOG2DEV(points
[i
].y
+ yoffset
);
328 CalcBoundingBox( points
[i
].x
+ xoffset
, points
[i
].y
+ yoffset
);
331 if (m_brush
.GetStyle() != wxTRANSPARENT
)
332 gdk_draw_polygon (m_window
, m_brushGC
, TRUE
, gdkpoints
, n
);
336 if (m_pen
.GetStyle() != wxTRANSPARENT
)
337 for (i
= 0 ; i
< n
; i
++)
339 gdk_draw_line( m_window
, m_penGC
,
342 gdkpoints
[(i
+1)%n
].x
,
343 gdkpoints
[(i
+1)%n
].y
);
349 void wxWindowDC::DrawPolygon( wxList
*lines
, long xoffset
, long yoffset
, int WXUNUSED(fillStyle
))
351 wxCHECK_RET( Ok(), _T("invalid window dc") );
353 int n
= lines
->Number();
356 GdkPoint
*gdkpoints
= new GdkPoint
[n
];
357 wxNode
*node
= lines
->First();
361 wxPoint
*p
= (wxPoint
*) node
->Data();
362 gdkpoints
[cnt
].x
= XLOG2DEV(p
->x
+ xoffset
);
363 gdkpoints
[cnt
].y
= YLOG2DEV(p
->y
+ yoffset
);
367 CalcBoundingBox( p
->x
+ xoffset
, p
->y
+ yoffset
);
370 if (m_brush
.GetStyle() != wxTRANSPARENT
)
371 gdk_draw_polygon (m_window
, m_brushGC
, TRUE
, gdkpoints
, n
);
375 if (m_pen
.GetStyle() != wxTRANSPARENT
)
378 for (i
= 0 ; i
< n
; i
++)
380 gdk_draw_line( m_window
, m_penGC
,
383 gdkpoints
[(i
+1)%n
].x
,
384 gdkpoints
[(i
+1)%n
].y
);
390 void wxWindowDC::DrawRectangle( long x
, long y
, long width
, long height
)
392 wxCHECK_RET( Ok(), _T("invalid window dc") );
394 long xx
= XLOG2DEV(x
);
395 long yy
= YLOG2DEV(y
);
396 long ww
= m_signX
* XLOG2DEVREL(width
);
397 long hh
= m_signY
* YLOG2DEVREL(height
);
399 // CMB: draw nothing if transformed w or h is 0
400 if (ww
== 0 || hh
== 0) return;
402 // CMB: handle -ve width and/or height
403 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
404 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
406 if (m_brush
.GetStyle() != wxTRANSPARENT
)
407 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
);
409 if (m_pen
.GetStyle() != wxTRANSPARENT
)
410 gdk_draw_rectangle( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
-1, hh
-1 );
412 CalcBoundingBox( x
, y
);
413 CalcBoundingBox( x
+ width
, y
+ height
);
416 void wxWindowDC::DrawRoundedRectangle( long x
, long y
, long width
, long height
, double radius
)
418 wxCHECK_RET( Ok(), _T("invalid window dc") );
420 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
422 long xx
= XLOG2DEV(x
);
423 long yy
= YLOG2DEV(y
);
424 long ww
= m_signX
* XLOG2DEVREL(width
);
425 long hh
= m_signY
* YLOG2DEVREL(height
);
426 long rr
= XLOG2DEVREL((long)radius
);
428 // CMB: handle -ve width and/or height
429 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
430 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
432 // CMB: if radius is zero use DrawRectangle() instead to avoid
433 // X drawing errors with small radii
436 DrawRectangle( x
, y
, width
, height
);
440 // CMB: draw nothing if transformed w or h is 0
441 if (ww
== 0 || hh
== 0) return;
443 // CMB: adjust size if outline is drawn otherwise the result is
444 // 1 pixel too wide and high
445 if (m_pen
.GetStyle() != wxTRANSPARENT
)
451 // CMB: ensure dd is not larger than rectangle otherwise we
452 // get an hour glass shape
454 if (dd
> ww
) dd
= ww
;
455 if (dd
> hh
) dd
= hh
;
458 if (m_brush
.GetStyle() != wxTRANSPARENT
)
460 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
+1, hh
);
461 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
+1 );
462 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
463 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
464 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
465 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
468 if (m_pen
.GetStyle() != wxTRANSPARENT
)
470 gdk_draw_line( m_window
, m_penGC
, xx
+rr
, yy
, xx
+ww
-rr
, yy
);
471 gdk_draw_line( m_window
, m_penGC
, xx
+rr
, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
472 gdk_draw_line( m_window
, m_penGC
, xx
, yy
+rr
, xx
, yy
+hh
-rr
);
473 gdk_draw_line( m_window
, m_penGC
, xx
+ww
, yy
+rr
, xx
+ww
, yy
+hh
-rr
);
474 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
475 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
476 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
477 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
480 // this ignores the radius
481 CalcBoundingBox( x
, y
);
482 CalcBoundingBox( x
+ width
, y
+ height
);
485 void wxWindowDC::DrawEllipse( long x
, long y
, long width
, long height
)
487 wxCHECK_RET( Ok(), _T("invalid window dc") );
489 long xx
= XLOG2DEV(x
);
490 long yy
= YLOG2DEV(y
);
491 long ww
= m_signX
* XLOG2DEVREL(width
);
492 long hh
= m_signY
* YLOG2DEVREL(height
);
494 // CMB: handle -ve width and/or height
495 if (ww
< 0) { ww
= -ww
; xx
= xx
- ww
; }
496 if (hh
< 0) { hh
= -hh
; yy
= yy
- hh
; }
498 if (m_brush
.GetStyle() != wxTRANSPARENT
)
499 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 );
501 if (m_pen
.GetStyle() != wxTRANSPARENT
)
502 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, 0, 360*64 );
504 CalcBoundingBox( x
- width
, y
- height
);
505 CalcBoundingBox( x
+ width
, y
+ height
);
508 bool wxWindowDC::CanDrawBitmap() const
513 void wxWindowDC::DrawIcon( const wxIcon
&icon
, long x
, long y
)
515 DrawBitmap( icon
, x
, y
, TRUE
);
518 void wxWindowDC::DrawBitmap( const wxBitmap
&bitmap
, long x
, long y
, bool useMask
)
520 wxCHECK_RET( Ok(), _T("invalid window dc") );
522 if (!bitmap
.Ok()) return;
524 /* scale/translate size and position */
526 int xx
= XLOG2DEV(x
);
527 int yy
= YLOG2DEV(y
);
529 int w
= bitmap
.GetWidth();
530 int h
= bitmap
.GetHeight();
532 int ww
= XLOG2DEVREL(w
);
533 int hh
= YLOG2DEVREL(h
);
535 /* scale bitmap if required */
539 if ((w
!= ww
) || (h
!= hh
))
541 wxImage
image( bitmap
);
542 image
= image
.Scale( ww
, hh
);
544 use_bitmap
= image
.ConvertToBitmap();
551 /* apply mask if any */
553 GdkBitmap
*mask
= (GdkBitmap
*) NULL
;
554 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
558 gdk_gc_set_clip_mask( m_penGC
, mask
);
559 gdk_gc_set_clip_origin( m_penGC
, xx
, yy
);
562 /* draw XPixmap or XBitmap, depending on what the wxBitmap contains */
564 GdkPixmap
*pm
= use_bitmap
.GetPixmap();
567 gdk_draw_pixmap( m_window
, m_penGC
, pm
, 0, 0, xx
, yy
, -1, -1 );
571 GdkBitmap
*bm
= use_bitmap
.GetBitmap();
574 gdk_draw_bitmap( m_window
, m_penGC
, bm
, 0, 0, xx
, yy
, -1, -1 );
578 /* remove mask again if any */
582 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap
*) NULL
);
583 gdk_gc_set_clip_origin( m_penGC
, 0, 0 );
586 CalcBoundingBox( x
, y
);
587 CalcBoundingBox( x
+ w
, y
+ h
);
590 bool wxWindowDC::Blit( long xdest
, long ydest
, long width
, long height
,
591 wxDC
*source
, long xsrc
, long ysrc
, int logical_func
, bool useMask
)
593 /* this is the nth try to get this utterly useless function to
594 work. it now completely ignores the scaling or translation
595 of the source dc, but scales correctly on the target dc and
596 knows about possible mask information in a memory dc. */
598 wxCHECK_MSG( Ok(), FALSE
, _T("invalid window dc") );
600 wxCHECK_MSG( source
, FALSE
, _T("invalid source dc") );
602 wxClientDC
*srcDC
= (wxClientDC
*)source
;
603 wxMemoryDC
*memDC
= (wxMemoryDC
*)source
;
605 bool use_bitmap_method
= FALSE
;
607 if (srcDC
->m_isMemDC
)
609 if (!memDC
->m_selected
.Ok()) return FALSE
;
611 /* we use the "XCopyArea" way to copy a memory dc into
612 y different window if the memory dc BOTH
613 a) doesn't have any mask or its mask isn't used
617 if (useMask
&& (memDC
->m_selected
.GetMask()))
619 /* we HAVE TO use the direct way for memory dcs
620 that have mask since the XCopyArea doesn't know
622 use_bitmap_method
= TRUE
;
624 else if (memDC
->m_selected
.GetDepth() == 1)
626 /* we HAVE TO use the direct way for memory dcs
627 that are bitmaps because XCopyArea doesn't copy
628 with different bit depths */
629 use_bitmap_method
= TRUE
;
631 else if ((xsrc
== 0) && (ysrc
== 0) &&
632 (width
== memDC
->m_selected
.GetWidth()) &&
633 (height
== memDC
->m_selected
.GetHeight()))
635 /* we SHOULD use the direct way if all of the bitmap
636 in the memory dc is copied in which case XCopyArea
637 wouldn't be able able to boost performace by reducing
638 the area to be scaled */
639 use_bitmap_method
= TRUE
;
643 use_bitmap_method
= FALSE
;
647 CalcBoundingBox( xdest
, ydest
);
648 CalcBoundingBox( xdest
+ width
, ydest
+ height
);
650 int old_logical_func
= m_logicalFunction
;
651 SetLogicalFunction( logical_func
);
653 if (use_bitmap_method
)
655 /* scale/translate bitmap size */
657 long bm_width
= memDC
->m_selected
.GetWidth();
658 long bm_height
= memDC
->m_selected
.GetHeight();
660 long bm_ww
= XLOG2DEVREL( bm_width
);
661 long bm_hh
= YLOG2DEVREL( bm_height
);
663 /* scale bitmap if required */
667 if ((bm_width
!= bm_ww
) || (bm_height
!= bm_hh
))
669 wxImage
image( memDC
->m_selected
);
670 image
= image
.Scale( bm_ww
, bm_hh
);
672 use_bitmap
= image
.ConvertToBitmap();
676 use_bitmap
= memDC
->m_selected
;
679 /* scale/translate size and position */
681 long xx
= XLOG2DEV(xdest
);
682 long yy
= YLOG2DEV(ydest
);
684 long ww
= XLOG2DEVREL(width
);
685 long hh
= YLOG2DEVREL(height
);
687 /* apply mask if any */
689 GdkBitmap
*mask
= (GdkBitmap
*) NULL
;
690 if (use_bitmap
.GetMask()) mask
= use_bitmap
.GetMask()->GetBitmap();
694 gdk_gc_set_clip_mask( m_penGC
, mask
);
695 gdk_gc_set_clip_origin( m_penGC
, xx
, yy
);
698 /* draw XPixmap or XBitmap, depending on what the wxBitmap contains */
700 GdkPixmap
*pm
= use_bitmap
.GetPixmap();
703 gdk_draw_pixmap( m_window
, m_penGC
, pm
, xsrc
, ysrc
, xx
, yy
, ww
, hh
);
707 GdkBitmap
*bm
= use_bitmap
.GetBitmap();
710 /* we use the textGC here because blitting a bitmap is done
711 using the current text colour */
712 gdk_draw_bitmap( m_window
, m_textGC
, bm
, xsrc
, ysrc
, xx
, yy
, ww
, hh
);
716 /* remove mask again if any */
720 gdk_gc_set_clip_mask( m_penGC
, (GdkBitmap
*) NULL
);
721 gdk_gc_set_clip_origin( m_penGC
, 0, 0 );
724 else /* use_bitmap_method */
726 /* scale/translate size and position */
728 long xx
= XLOG2DEV(xdest
);
729 long yy
= YLOG2DEV(ydest
);
731 long ww
= XLOG2DEVREL(width
);
732 long hh
= YLOG2DEVREL(height
);
734 if ((width
!= ww
) || (height
!= hh
))
736 /* draw source window into a bitmap as we cannot scale
737 a window in contrast to a bitmap. this would actually
738 work with memory dcs as well, but we'd lose the mask
739 information and waste one step in this process since
740 a memory already has a bitmap. all this is slightly
741 inefficient as we could take an XImage directly from
742 an X window, but we'd then also have to care that
743 the window is not outside the screen (in which case
744 we'd get a BadMatch or what not).
745 Is a double XGetImage and combined XGetPixel and
746 XPutPixel really faster? I'm not sure. look at wxXt
747 for a different implementation of the same problem. */
749 wxBitmap
bitmap( width
, height
);
750 gdk_window_copy_area( bitmap
.GetPixmap(), m_penGC
, 0, 0,
752 xsrc
, ysrc
, width
, height
);
756 wxImage
image( bitmap
);
757 image
= image
.Scale( ww
, hh
);
759 /* convert to bitmap */
761 bitmap
= image
.ConvertToBitmap();
763 /* draw scaled bitmap */
765 gdk_draw_pixmap( m_window
, m_penGC
, bitmap
.GetPixmap(), 0, 0, xx
, yy
, -1, -1 );
770 /* no scaling and not a memory dc with a mask either */
772 gdk_window_copy_area( m_window
, m_penGC
, xx
, yy
,
774 xsrc
, ysrc
, width
, height
);
778 SetLogicalFunction( old_logical_func
);
782 void wxWindowDC::DrawText( const wxString
&text
, long x
, long y
, bool WXUNUSED(use16
) )
784 wxCHECK_RET( Ok(), _T("invalid window dc") );
786 GdkFont
*font
= m_font
.GetInternalFont( m_scaleY
);
791 /* CMB 21/5/98: draw text background if mode is wxSOLID */
792 if (m_backgroundMode
== wxSOLID
)
794 long width
= gdk_string_width( font
, text
.mbc_str() );
795 long height
= font
->ascent
+ font
->descent
;
796 gdk_gc_set_foreground( m_textGC
, m_textBackgroundColour
.GetColor() );
797 gdk_draw_rectangle( m_window
, m_textGC
, TRUE
, x
, y
, width
, height
);
798 gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() );
800 gdk_draw_string( m_window
, font
, m_textGC
, x
, y
+ font
->ascent
, text
.mbc_str() );
802 /* CMB 17/7/98: simple underline: ignores scaling and underlying
803 X font's XA_UNDERLINE_POSITION and XA_UNDERLINE_THICKNESS
804 properties (see wxXt implementation) */
805 if (m_font
.GetUnderlined())
807 long width
= gdk_string_width( font
, text
.mbc_str() );
808 long ul_y
= y
+ font
->ascent
;
809 if (font
->descent
> 0) ul_y
++;
810 gdk_draw_line( m_window
, m_textGC
, x
, ul_y
, x
+ width
, ul_y
);
814 GetTextExtent (text
, &w
, &h
);
815 CalcBoundingBox (x
+ w
, y
+ h
);
816 CalcBoundingBox (x
, y
);
819 bool wxWindowDC::CanGetTextExtent() const
824 void wxWindowDC::GetTextExtent( const wxString
&string
, long *width
, long *height
,
825 long *descent
, long *externalLeading
,
826 wxFont
*theFont
, bool WXUNUSED(use16
) )
828 wxFont fontToUse
= m_font
;
829 if (theFont
) fontToUse
= *theFont
;
831 GdkFont
*font
= fontToUse
.GetInternalFont( m_scaleY
);
832 if (width
) (*width
) = long(gdk_string_width( font
, string
.mbc_str() ) / m_scaleX
);
833 if (height
) (*height
) = long((font
->ascent
+ font
->descent
) / m_scaleY
);
834 if (descent
) (*descent
) = long(font
->descent
/ m_scaleY
);
835 if (externalLeading
) (*externalLeading
) = 0; // ??
838 long wxWindowDC::GetCharWidth()
840 GdkFont
*font
= m_font
.GetInternalFont( m_scaleY
);
841 return long(gdk_string_width( font
, "H" ) / m_scaleX
);
844 long wxWindowDC::GetCharHeight()
846 GdkFont
*font
= m_font
.GetInternalFont( m_scaleY
);
847 return long((font
->ascent
+ font
->descent
) / m_scaleY
);
850 void wxWindowDC::Clear()
852 wxCHECK_RET( Ok(), _T("invalid window dc") );
854 /* - we either are a memory dc or have a window as the
855 owner. anything else shouldn't happen.
856 - we don't use gdk_window_clear() as we don't set
857 the window's background colour anymore. it is too
858 much pain to keep the DC's and the window's back-
859 ground colour in synch. */
864 m_owner
->GetSize( &width
, &height
);
865 gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height
);
872 GetSize( &width
, &height
);
873 gdk_draw_rectangle( m_window
, m_bgGC
, TRUE
, 0, 0, width
, height
);
878 void wxWindowDC::SetFont( const wxFont
&font
)
883 void wxWindowDC::SetPen( const wxPen
&pen
)
885 wxCHECK_RET( Ok(), _T("invalid window dc") );
887 if (m_pen
== pen
) return;
891 if (!m_pen
.Ok()) return;
893 gint width
= m_pen
.GetWidth();
894 // CMB: if width is non-zero scale it with the dc
901 // X doesn't allow different width in x and y and so we take
903 double w
= 0.5 + (abs(XLOG2DEVREL(width
)) + abs(YLOG2DEVREL(width
))) / 2.0;
907 GdkLineStyle lineStyle
= GDK_LINE_SOLID
;
908 switch (m_pen
.GetStyle())
910 case wxSOLID
: { lineStyle
= GDK_LINE_SOLID
; break; }
911 case wxDOT
: { lineStyle
= GDK_LINE_ON_OFF_DASH
; break; }
912 case wxLONG_DASH
: { lineStyle
= GDK_LINE_ON_OFF_DASH
; break; }
913 case wxSHORT_DASH
: { lineStyle
= GDK_LINE_ON_OFF_DASH
; break; }
914 case wxDOT_DASH
: { lineStyle
= GDK_LINE_DOUBLE_DASH
; break; }
917 GdkCapStyle capStyle
= GDK_CAP_ROUND
;
918 switch (m_pen
.GetCap())
920 case wxCAP_ROUND
: { capStyle
= (width
<= 1) ? GDK_CAP_NOT_LAST
: GDK_CAP_ROUND
; break; }
921 case wxCAP_PROJECTING
: { capStyle
= GDK_CAP_PROJECTING
; break; }
922 case wxCAP_BUTT
: { capStyle
= GDK_CAP_BUTT
; break; }
925 GdkJoinStyle joinStyle
= GDK_JOIN_ROUND
;
926 switch (m_pen
.GetJoin())
928 case wxJOIN_BEVEL
: { joinStyle
= GDK_JOIN_BEVEL
; break; }
929 case wxJOIN_ROUND
: { joinStyle
= GDK_JOIN_ROUND
; break; }
930 case wxJOIN_MITER
: { joinStyle
= GDK_JOIN_MITER
; break; }
933 gdk_gc_set_line_attributes( m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
935 m_pen
.GetColour().CalcPixel( m_cmap
);
936 gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() );
939 void wxWindowDC::SetBrush( const wxBrush
&brush
)
941 wxCHECK_RET( Ok(), _T("invalid window dc") );
943 if (m_brush
== brush
) return;
947 if (!m_brush
.Ok()) return;
949 m_brush
.GetColour().CalcPixel( m_cmap
);
950 gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() );
952 GdkFill fillStyle
= GDK_SOLID
;
953 switch (m_brush
.GetStyle())
959 fillStyle
= GDK_STIPPLED
;
962 gdk_gc_set_fill( m_brushGC
, fillStyle
);
964 if ((m_brush
.GetStyle() == wxSTIPPLE
) && (m_brush
.GetStipple()->Ok()))
966 if (m_brush
.GetStipple()->GetPixmap())
967 gdk_gc_set_stipple( m_brushGC
, m_brush
.GetStipple()->GetPixmap() );
969 gdk_gc_set_stipple( m_brushGC
, m_brush
.GetStipple()->GetBitmap() );
972 if (IS_HATCH(m_brush
.GetStyle()))
974 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
975 gdk_gc_set_stipple( m_brushGC
, hatches
[num
] );
979 void wxWindowDC::SetBackground( const wxBrush
&brush
)
981 /* CMB 21/7/98: Added SetBackground. Sets background brush
982 * for Clear() and bg colour for shapes filled with cross-hatch brush */
984 wxCHECK_RET( Ok(), _T("invalid window dc") );
986 if (m_backgroundBrush
== brush
) return;
988 m_backgroundBrush
= brush
;
990 if (!m_backgroundBrush
.Ok()) return;
992 m_backgroundBrush
.GetColour().CalcPixel( m_cmap
);
993 gdk_gc_set_background( m_brushGC
, m_backgroundBrush
.GetColour().GetColor() );
994 gdk_gc_set_background( m_penGC
, m_backgroundBrush
.GetColour().GetColor() );
995 gdk_gc_set_background( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() );
996 gdk_gc_set_foreground( m_bgGC
, m_backgroundBrush
.GetColour().GetColor() );
998 GdkFill fillStyle
= GDK_SOLID
;
999 switch (m_backgroundBrush
.GetStyle())
1005 fillStyle
= GDK_STIPPLED
;
1008 gdk_gc_set_fill( m_bgGC
, fillStyle
);
1010 if (m_backgroundBrush
.GetStyle() == wxSTIPPLE
)
1012 gdk_gc_set_stipple( m_bgGC
, m_backgroundBrush
.GetStipple()->GetPixmap() );
1015 if (IS_HATCH(m_backgroundBrush
.GetStyle()))
1017 int num
= m_backgroundBrush
.GetStyle() - wxBDIAGONAL_HATCH
;
1018 gdk_gc_set_stipple( m_bgGC
, hatches
[num
] );
1022 void wxWindowDC::SetLogicalFunction( int function
)
1024 wxCHECK_RET( Ok(), _T("invalid window dc") );
1026 if (m_logicalFunction
== function
) return;
1028 GdkFunction mode
= GDK_COPY
;
1031 case wxXOR
: mode
= GDK_INVERT
; break;
1032 case wxINVERT
: mode
= GDK_INVERT
; break;
1033 #if (GDK_MINOR_VERSION > 0)
1034 case wxOR_REVERSE
: mode
= GDK_OR_REVERSE
; break;
1035 case wxAND_REVERSE
: mode
= GDK_AND_REVERSE
; break;
1036 case wxCLEAR
: mode
= GDK_CLEAR
; break;
1037 case wxSET
: mode
= GDK_SET
; break;
1038 case wxOR_INVERT
: mode
= GDK_OR_INVERT
; break;
1039 case wxAND
: mode
= GDK_AND
; break;
1040 case wxOR
: mode
= GDK_OR
; break;
1041 case wxEQUIV
: mode
= GDK_EQUIV
; break;
1042 case wxNAND
: mode
= GDK_NAND
; break;
1043 case wxAND_INVERT
: mode
= GDK_AND_INVERT
; break;
1044 /* ? wxSRC_INVERT GDK_AND_REVERSE, GDK_OR_REVERSE, GDK_OR_INVERT */
1049 m_logicalFunction
= function
;
1050 gdk_gc_set_function( m_penGC
, mode
);
1051 gdk_gc_set_function( m_brushGC
, mode
);
1052 gdk_gc_set_function( m_textGC
, mode
);
1055 void wxWindowDC::SetTextForeground( const wxColour
&col
)
1057 wxCHECK_RET( Ok(), _T("invalid window dc") );
1059 if (m_textForegroundColour
== col
) return;
1061 m_textForegroundColour
= col
;
1062 if (!m_textForegroundColour
.Ok()) return;
1064 m_textForegroundColour
.CalcPixel( m_cmap
);
1065 gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() );
1068 void wxWindowDC::SetTextBackground( const wxColour
&col
)
1070 wxCHECK_RET( Ok(), _T("invalid window dc") );
1072 if (m_textBackgroundColour
== col
) return;
1074 m_textBackgroundColour
= col
;
1075 if (!m_textBackgroundColour
.Ok()) return;
1077 m_textBackgroundColour
.CalcPixel( m_cmap
);
1078 gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() );
1081 void wxWindowDC::SetBackgroundMode( int mode
)
1083 wxCHECK_RET( Ok(), _T("invalid window dc") );
1085 m_backgroundMode
= mode
;
1087 // CMB 21/7/98: fill style of cross-hatch brushes is affected by
1088 // transparent/solid background mode
1090 if (m_brush
.GetStyle() != wxSOLID
&& m_brush
.GetStyle() != wxTRANSPARENT
)
1092 gdk_gc_set_fill( m_brushGC
,
1093 (m_backgroundMode
== wxTRANSPARENT
) ? GDK_STIPPLED
: GDK_OPAQUE_STIPPLED
);
1097 void wxWindowDC::SetPalette( const wxPalette
& WXUNUSED(palette
) )
1099 wxFAIL_MSG( _T("wxWindowDC::SetPalette not implemented") );
1102 void wxWindowDC::SetClippingRegion( long x
, long y
, long width
, long height
)
1104 wxCHECK_RET( Ok(), _T("invalid window dc") );
1106 wxDC::SetClippingRegion( x
, y
, width
, height
);
1109 rect
.x
= XLOG2DEV(x
);
1110 rect
.y
= YLOG2DEV(y
);
1111 rect
.width
= XLOG2DEVREL(width
);
1112 rect
.height
= YLOG2DEVREL(height
);
1113 gdk_gc_set_clip_rectangle( m_penGC
, &rect
);
1114 gdk_gc_set_clip_rectangle( m_brushGC
, &rect
);
1115 gdk_gc_set_clip_rectangle( m_textGC
, &rect
);
1116 gdk_gc_set_clip_rectangle( m_bgGC
, &rect
);
1119 void wxWindowDC::SetClippingRegion( const wxRegion
®ion
)
1121 wxCHECK_RET( Ok(), _T("invalid window dc") );
1125 DestroyClippingRegion();
1129 gdk_gc_set_clip_region( m_penGC
, region
.GetRegion() );
1130 gdk_gc_set_clip_region( m_brushGC
, region
.GetRegion() );
1131 gdk_gc_set_clip_region( m_textGC
, region
.GetRegion() );
1132 gdk_gc_set_clip_region( m_bgGC
, region
.GetRegion() );
1135 void wxWindowDC::DestroyClippingRegion()
1137 wxCHECK_RET( Ok(), _T("invalid window dc") );
1139 wxDC::DestroyClippingRegion();
1141 gdk_gc_set_clip_rectangle( m_penGC
, (GdkRectangle
*) NULL
);
1142 gdk_gc_set_clip_rectangle( m_brushGC
, (GdkRectangle
*) NULL
);
1143 gdk_gc_set_clip_rectangle( m_textGC
, (GdkRectangle
*) NULL
);
1144 gdk_gc_set_clip_rectangle( m_bgGC
, (GdkRectangle
*) NULL
);
1147 void wxWindowDC::SetUpDC()
1151 m_logicalFunction
= wxCOPY
;
1152 m_penGC
= gdk_gc_new( m_window
);
1153 m_brushGC
= gdk_gc_new( m_window
);
1154 m_textGC
= gdk_gc_new( m_window
);
1155 m_bgGC
= gdk_gc_new( m_window
);
1157 wxColour
tmp_col( m_textForegroundColour
);
1158 m_textForegroundColour
= wxNullColour
;
1159 SetTextForeground( tmp_col
);
1160 tmp_col
= m_textBackgroundColour
;
1161 m_textBackgroundColour
= wxNullColour
;
1162 SetTextBackground( tmp_col
);
1164 wxPen
tmp_pen( m_pen
);
1168 wxFont
tmp_font( m_font
);
1169 m_font
= wxNullFont
;
1170 SetFont( tmp_font
);
1172 wxBrush
tmp_brush( m_brush
);
1173 m_brush
= wxNullBrush
;
1174 SetBrush( tmp_brush
);
1176 tmp_brush
= m_backgroundBrush
;
1177 m_backgroundBrush
= wxNullBrush
;
1178 SetBackground( tmp_brush
);
1182 hatch_bitmap
= hatches
;
1183 hatch_bitmap
[0] = gdk_bitmap_create_from_data( (GdkWindow
*) NULL
, bdiag_bits
, bdiag_width
, bdiag_height
);
1184 hatch_bitmap
[1] = gdk_bitmap_create_from_data( (GdkWindow
*) NULL
, cdiag_bits
, cdiag_width
, cdiag_height
);
1185 hatch_bitmap
[2] = gdk_bitmap_create_from_data( (GdkWindow
*) NULL
, fdiag_bits
, fdiag_width
, fdiag_height
);
1186 hatch_bitmap
[3] = gdk_bitmap_create_from_data( (GdkWindow
*) NULL
, cross_bits
, cross_width
, cross_height
);
1187 hatch_bitmap
[4] = gdk_bitmap_create_from_data( (GdkWindow
*) NULL
, horiz_bits
, horiz_width
, horiz_height
);
1188 hatch_bitmap
[5] = gdk_bitmap_create_from_data( (GdkWindow
*) NULL
, verti_bits
, verti_width
, verti_height
);
1192 void wxWindowDC::Destroy()
1194 if (m_penGC
) gdk_gc_unref( m_penGC
);
1195 m_penGC
= (GdkGC
*) NULL
;
1196 if (m_brushGC
) gdk_gc_unref( m_brushGC
);
1197 m_brushGC
= (GdkGC
*) NULL
;
1198 if (m_textGC
) gdk_gc_unref( m_textGC
);
1199 m_textGC
= (GdkGC
*) NULL
;
1200 if (m_bgGC
) gdk_gc_unref( m_bgGC
);
1201 m_bgGC
= (GdkGC
*) NULL
;
1204 GdkWindow
*wxWindowDC::GetWindow()
1209 // ----------------------------------- spline code ----------------------------------------
1211 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
1212 double a3
, double b3
, double a4
, double b4
);
1213 void wx_clear_stack();
1214 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
1215 double *y3
, double *x4
, double *y4
);
1216 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
1217 double x4
, double y4
);
1218 static bool wx_spline_add_point(double x
, double y
);
1219 static void wx_spline_draw_point_array(wxDC
*dc
);
1221 wxList wx_spline_point_list
;
1223 #define half(z1, z2) ((z1+z2)/2.0)
1226 /* iterative version */
1228 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
1231 register double xmid
, ymid
;
1232 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
1235 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
1237 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
1238 xmid
= (double)half(x2
, x3
);
1239 ymid
= (double)half(y2
, y3
);
1240 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
1241 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
1242 wx_spline_add_point( x1
, y1
);
1243 wx_spline_add_point( xmid
, ymid
);
1245 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
1246 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
1247 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
1248 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
1253 /* utilities used by spline drawing routines */
1255 typedef struct wx_spline_stack_struct
{
1256 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
1259 #define SPLINE_STACK_DEPTH 20
1260 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
1261 static Stack
*wx_stack_top
;
1262 static int wx_stack_count
;
1264 void wx_clear_stack()
1266 wx_stack_top
= wx_spline_stack
;
1270 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
1272 wx_stack_top
->x1
= x1
;
1273 wx_stack_top
->y1
= y1
;
1274 wx_stack_top
->x2
= x2
;
1275 wx_stack_top
->y2
= y2
;
1276 wx_stack_top
->x3
= x3
;
1277 wx_stack_top
->y3
= y3
;
1278 wx_stack_top
->x4
= x4
;
1279 wx_stack_top
->y4
= y4
;
1284 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
1285 double *x3
, double *y3
, double *x4
, double *y4
)
1287 if (wx_stack_count
== 0)
1291 *x1
= wx_stack_top
->x1
;
1292 *y1
= wx_stack_top
->y1
;
1293 *x2
= wx_stack_top
->x2
;
1294 *y2
= wx_stack_top
->y2
;
1295 *x3
= wx_stack_top
->x3
;
1296 *y3
= wx_stack_top
->y3
;
1297 *x4
= wx_stack_top
->x4
;
1298 *y4
= wx_stack_top
->y4
;
1302 static bool wx_spline_add_point(double x
, double y
)
1304 wxPoint
*point
= new wxPoint
;
1307 wx_spline_point_list
.Append((wxObject
*)point
);
1311 static void wx_spline_draw_point_array(wxDC
*dc
)
1313 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
1314 wxNode
*node
= wx_spline_point_list
.First();
1317 wxPoint
*point
= (wxPoint
*)node
->Data();
1320 node
= wx_spline_point_list
.First();
1324 void wxWindowDC::DrawSpline( wxList
*points
)
1326 wxCHECK_RET( Ok(), _T("invalid window dc") );
1329 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
1330 double x1
, y1
, x2
, y2
;
1332 wxNode
*node
= points
->First();
1333 p
= (wxPoint
*)node
->Data();
1338 node
= node
->Next();
1339 p
= (wxPoint
*)node
->Data();
1343 cx1
= (double)((x1
+ x2
) / 2);
1344 cy1
= (double)((y1
+ y2
) / 2);
1345 cx2
= (double)((cx1
+ x2
) / 2);
1346 cy2
= (double)((cy1
+ y2
) / 2);
1348 wx_spline_add_point(x1
, y1
);
1350 while ((node
= node
->Next()) != NULL
)
1352 p
= (wxPoint
*)node
->Data();
1357 cx4
= (double)(x1
+ x2
) / 2;
1358 cy4
= (double)(y1
+ y2
) / 2;
1359 cx3
= (double)(x1
+ cx4
) / 2;
1360 cy3
= (double)(y1
+ cy4
) / 2;
1362 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
1366 cx2
= (double)(cx1
+ x2
) / 2;
1367 cy2
= (double)(cy1
+ y2
) / 2;
1370 wx_spline_add_point( cx1
, cy1
);
1371 wx_spline_add_point( x2
, y2
);
1373 wx_spline_draw_point_array( this );
1376 // Resolution in pixels per logical inch
1377 wxSize
wxWindowDC::GetPPI(void) const
1379 return wxSize(100, 100);
1382 //-----------------------------------------------------------------------------
1384 //-----------------------------------------------------------------------------
1386 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
,wxWindowDC
)
1388 wxPaintDC::wxPaintDC()
1393 wxPaintDC::wxPaintDC( wxWindow
*win
)
1398 //-----------------------------------------------------------------------------
1400 //-----------------------------------------------------------------------------
1402 IMPLEMENT_DYNAMIC_CLASS(wxClientDC
,wxWindowDC
)
1404 wxClientDC::wxClientDC()
1409 wxClientDC::wxClientDC( wxWindow
*win
)