1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "dcclient.h"
15 #include "wx/dcclient.h"
17 //-----------------------------------------------------------------------------
19 //-----------------------------------------------------------------------------
29 static GdkPixmap
*hatches
[num_hatches
];
30 static GdkPixmap
**hatch_bitmap
= NULL
;
32 //-----------------------------------------------------------------------------
34 //-----------------------------------------------------------------------------
36 #define RAD2DEG 57.2957795131
38 //-----------------------------------------------------------------------------
40 //-----------------------------------------------------------------------------
42 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC
,wxDC
)
44 wxPaintDC::wxPaintDC(void)
48 wxPaintDC::wxPaintDC( wxWindow
*window
)
51 GtkWidget
*widget
= window
->m_wxwindow
;
53 m_window
= widget
->window
;
54 if (!m_window
) return;
55 if (window
->m_wxwindow
)
56 m_cmap
= gtk_widget_get_colormap( window
->m_wxwindow
);
58 m_cmap
= gtk_widget_get_colormap( window
->m_widget
);
63 window
->GetDrawingOffset( &x
, &y
);
64 SetInternalDeviceOrigin( -x
, -y
);
67 wxPaintDC::~wxPaintDC(void)
71 void wxPaintDC::FloodFill( long WXUNUSED(x1
), long WXUNUSED(y1
),
72 wxColour
*WXUNUSED(col
), int WXUNUSED(style
) )
76 bool wxPaintDC::GetPixel( long WXUNUSED(x1
), long WXUNUSED(y1
), wxColour
*WXUNUSED(col
) ) const
81 void wxPaintDC::DrawLine( long x1
, long y1
, long x2
, long y2
)
85 if (m_pen
.GetStyle() != wxTRANSPARENT
)
87 gdk_draw_line( m_window
, m_penGC
,
88 XLOG2DEV(x1
), YLOG2DEV(y1
), XLOG2DEV(x2
), YLOG2DEV(y2
) );
92 void wxPaintDC::CrossHair( long x
, long y
)
96 if (m_pen
.GetStyle() != wxTRANSPARENT
)
101 long xx
= XLOG2DEV(x
);
102 long yy
= YLOG2DEV(y
);
103 gdk_draw_line( m_window
, m_penGC
,
104 0, yy
, XLOG2DEVREL(w
), yy
);
105 gdk_draw_line( m_window
, m_penGC
,
106 xx
, 0, xx
, YLOG2DEVREL(h
) );
110 void wxPaintDC::DrawArc( long x1
, long y1
, long x2
, long y2
, double xc
, double yc
)
114 long xx1
= XLOG2DEV(x1
);
115 long yy1
= YLOG2DEV(y1
);
116 long xx2
= XLOG2DEV(x2
);
117 long yy2
= YLOG2DEV(y2
);
118 long xxc
= XLOG2DEV((long)xc
);
119 long yyc
= YLOG2DEV((long)yc
);
120 double dx
= xx1
- xxc
;
121 double dy
= yy1
- yyc
;
122 double radius
= sqrt(dx
*dx
+dy
*dy
);
123 long r
= (long)radius
;
124 double radius1
, radius2
;
126 if (xx1
== xx2
&& yy1
== yy2
)
134 radius1
= radius2
= 0.0;
138 radius1
= (xx1
- xxc
== 0) ?
139 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
140 -atan2(double(yy1
-yyc
), double(xx1
-xxc
)) * RAD2DEG
;
141 radius2
= (xx2
- xxc
== 0) ?
142 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
143 -atan2(double(yy2
-yyc
), double(xx2
-xxc
)) * RAD2DEG
;
145 long alpha1
= long(radius1
* 64.0);
146 long alpha2
= long((radius2
- radius1
) * 64.0);
147 while (alpha2
<= 0) alpha2
+= 360*64;
148 while (alpha1
> 360*64) alpha1
-= 360*64;
150 if (m_brush
.GetStyle() != wxTRANSPARENT
)
151 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
153 if (m_pen
.GetStyle() != wxTRANSPARENT
)
154 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xxc
-r
, yyc
-r
, 2*r
,2*r
, alpha1
, alpha2
);
158 void wxPaintDC::DrawEllipticArc( long x
, long y
, long width
, long height
, double sa
, double ea
)
162 if (width
<0) { width
=-width
; x
=x
-width
; }
163 if (height
<0) { height
=-height
; y
=y
-height
; }
165 long xx
= XLOG2DEV(x
);
166 long yy
= YLOG2DEV(y
);
167 long ww
= XLOG2DEVREL(width
);
168 long hh
= YLOG2DEVREL(height
);
170 if (m_brush
.GetStyle() != wxTRANSPARENT
)
171 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
-1, hh
-1, 0, long(sa
*64) );
173 if (m_pen
.GetStyle() != wxTRANSPARENT
)
174 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, 0, long(ea
*64) );
177 void wxPaintDC::DrawPoint( long x
, long y
)
181 if (m_pen
.GetStyle() != wxTRANSPARENT
)
182 gdk_draw_point( m_window
, m_penGC
, XLOG2DEV(x
), YLOG2DEV(y
) );
185 void wxPaintDC::DrawLines( int n
, wxPoint points
[], long xoffset
, long yoffset
)
189 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
191 for (int i
= 0; i
< n
-1; i
++)
193 long x1
= XLOG2DEV(points
[i
].x
+ xoffset
);
194 long x2
= XLOG2DEV(points
[i
+1].x
+ xoffset
);
195 long y1
= YLOG2DEV(points
[i
].y
+ yoffset
); // oh, what a waste
196 long y2
= YLOG2DEV(points
[i
+1].y
+ yoffset
);
197 gdk_draw_line( m_window
, m_brushGC
, x1
, y1
, x2
, y2
);
201 void wxPaintDC::DrawLines( wxList
*points
, long xoffset
, long yoffset
)
205 if (m_pen
.GetStyle() == wxTRANSPARENT
) return;
207 wxNode
*node
= points
->First();
210 wxPoint
*point
= (wxPoint
*)node
->Data();
211 wxPoint
*npoint
= (wxPoint
*)node
->Next()->Data();
212 long x1
= XLOG2DEV(point
->x
+ xoffset
);
213 long x2
= XLOG2DEV(npoint
->x
+ xoffset
);
214 long y1
= YLOG2DEV(point
->y
+ yoffset
); // and again...
215 long y2
= YLOG2DEV(npoint
->y
+ yoffset
);
216 gdk_draw_line( m_window
, m_brushGC
, x1
, y1
, x2
, y2
);
221 void wxPaintDC::DrawPolygon( int WXUNUSED(n
), wxPoint
WXUNUSED(points
)[],
222 long WXUNUSED(xoffset
), long WXUNUSED(yoffset
), int WXUNUSED(fillStyle
) )
227 void wxPaintDC::DrawPolygon( wxList
*WXUNUSED(lines
), long WXUNUSED(xoffset
),
228 long WXUNUSED(yoffset
), int WXUNUSED(fillStyle
) )
233 void wxPaintDC::DrawRectangle( long x
, long y
, long width
, long height
)
237 long xx
= XLOG2DEV(x
);
238 long yy
= YLOG2DEV(y
);
239 long ww
= XLOG2DEVREL(width
);
240 long hh
= YLOG2DEVREL(height
);
242 if (m_brush
.GetStyle() != wxTRANSPARENT
)
243 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
);
245 if (m_pen
.GetStyle() != wxTRANSPARENT
)
246 gdk_draw_rectangle( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
-1, hh
-1 );
249 void wxPaintDC::DrawRoundedRectangle( long x
, long y
, long width
, long height
, double radius
)
253 if (width
<0) { width
=-width
; x
=x
-width
; }
254 if (height
<0) { height
=-height
; y
=y
-height
; }
256 if (radius
< 0.0) radius
= - radius
* ((width
< height
) ? width
: height
);
258 long xx
= XLOG2DEV(x
);
259 long yy
= YLOG2DEV(y
);
260 long ww
= XLOG2DEVREL(width
);
261 long hh
= YLOG2DEVREL(height
);
262 long rr
= XLOG2DEVREL((long)radius
);
265 if (m_brush
.GetStyle() != wxTRANSPARENT
)
267 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
+rr
, yy
, ww
-dd
, hh
);
268 gdk_draw_rectangle( m_window
, m_brushGC
, TRUE
, xx
, yy
+rr
, ww
, hh
-dd
);
269 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
270 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
271 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
272 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
275 if (m_pen
.GetStyle() != wxTRANSPARENT
)
277 gdk_draw_line( m_window
, m_penGC
, xx
+rr
, yy
, xx
+ww
-rr
, yy
);
278 gdk_draw_line( m_window
, m_penGC
, xx
+rr
, yy
+hh
, xx
+ww
-rr
, yy
+hh
);
279 gdk_draw_line( m_window
, m_penGC
, xx
, yy
+rr
, xx
, yy
+hh
-rr
);
280 gdk_draw_line( m_window
, m_penGC
, xx
+ww
, yy
+rr
, xx
+ww
, yy
+hh
-rr
);
281 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, dd
, dd
, 90*64, 90*64 );
282 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
, dd
, dd
, 0, 90*64 );
283 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
+ww
-dd
, yy
+hh
-dd
, dd
, dd
, 270*64, 90*64 );
284 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
+hh
-dd
, dd
, dd
, 180*64, 90*64 );
288 void wxPaintDC::DrawEllipse( long x
, long y
, long width
, long height
)
292 if (width
<0) { width
=-width
; x
=x
-width
; }
293 if (height
<0) { height
=-height
; y
=y
-height
; }
295 long xx
= XLOG2DEV(x
);
296 long yy
= YLOG2DEV(y
);
297 long ww
= XLOG2DEVREL(width
);
298 long hh
= YLOG2DEVREL(height
);
300 if (m_brush
.GetStyle() != wxTRANSPARENT
)
301 gdk_draw_arc( m_window
, m_brushGC
, TRUE
, xx
, yy
, ww
, hh
, 0, 360*64 );
303 if (m_pen
.GetStyle() != wxTRANSPARENT
)
304 gdk_draw_arc( m_window
, m_penGC
, FALSE
, xx
, yy
, ww
, hh
, 0, 360*64 );
307 bool wxPaintDC::CanDrawBitmap(void) const
312 void wxPaintDC::DrawIcon( const wxIcon
&icon
, long x
, long y
, bool useMask
)
316 if (!icon
.Ok()) return;
318 int xx
= XLOG2DEV(x
);
319 int yy
= YLOG2DEV(y
);
321 GdkBitmap
*mask
= NULL
;
322 if (icon
.GetMask()) mask
= icon
.GetMask()->GetBitmap();
326 gdk_gc_set_clip_mask( m_penGC
, mask
);
327 gdk_gc_set_clip_origin( m_penGC
, xx
, yy
);
330 GdkPixmap
*pm
= icon
.GetPixmap();
331 gdk_draw_pixmap( m_window
, m_penGC
, pm
, 0, 0, xx
, yy
, -1, -1 );
335 gdk_gc_set_clip_mask( m_penGC
, NULL
);
336 gdk_gc_set_clip_origin( m_penGC
, 0, 0 );
340 bool wxPaintDC::Blit( long xdest
, long ydest
, long width
, long height
,
341 wxDC
*source
, long xsrc
, long ysrc
, int WXUNUSED(logical_func
), bool WXUNUSED(useMask
) )
343 if (!Ok()) return FALSE
;
345 wxClientDC
*csrc
= (wxClientDC
*)source
;
347 gdk_window_copy_area ( m_window
, m_penGC
,
348 XLOG2DEV(xdest
), YLOG2DEV(ydest
),
350 source
->DeviceToLogicalX(xsrc
), source
->DeviceToLogicalY(ysrc
),
351 source
->DeviceToLogicalXRel(width
), source
->DeviceToLogicalYRel(height
) );
354 gdk_window_copy_area ( m_window, m_penGC,
355 XLOG2DEV(xdest), YLOG2DEV(ydest),
364 void wxPaintDC::DrawText( const wxString
&text
, long x
, long y
, bool WXUNUSED(use16
) )
368 GdkFont
*font
= m_font
.GetInternalFont( m_scaleY
);
369 gdk_draw_string( m_window
, font
, m_textGC
,
371 YLOG2DEV(y
) + font
->ascent
, text
);
374 bool wxPaintDC::CanGetTextExtent(void) const
379 void wxPaintDC::GetTextExtent( const wxString
&string
, long *width
, long *height
,
380 long *WXUNUSED(descent
), long *WXUNUSED(externalLeading
),
381 wxFont
*WXUNUSED(theFont
), bool WXUNUSED(use16
) )
385 GdkFont
*font
= m_font
.GetInternalFont( m_scaleY
);
386 if (width
) (*width
) = gdk_string_width( font
, string
);
387 if (height
) (*height
) = font
->ascent
+ font
->descent
;
390 long wxPaintDC::GetCharWidth(void)
394 GdkFont
*font
= m_font
.GetInternalFont( m_scaleY
);
395 return gdk_string_width( font
, "H" );
398 long wxPaintDC::GetCharHeight(void)
402 GdkFont
*font
= m_font
.GetInternalFont( m_scaleY
);
403 return font
->ascent
+ font
->descent
;
406 void wxPaintDC::Clear(void)
410 DestroyClippingRegion();
411 gdk_window_clear( m_window
);
414 void wxPaintDC::SetFont( const wxFont
&font
)
421 void wxPaintDC::SetPen( const wxPen
&pen
)
425 if (m_pen
== pen
) return;
429 if (!m_pen
.Ok()) return;
431 gint width
= m_pen
.GetWidth();
433 GdkLineStyle lineStyle
= GDK_LINE_SOLID
;
434 switch (m_pen
.GetStyle())
436 case wxSOLID
: { lineStyle
= GDK_LINE_SOLID
; break; };
437 case wxDOT
: { lineStyle
= GDK_LINE_ON_OFF_DASH
; break; };
438 case wxLONG_DASH
: { lineStyle
= GDK_LINE_ON_OFF_DASH
; break; };
439 case wxSHORT_DASH
: { lineStyle
= GDK_LINE_ON_OFF_DASH
; break; };
440 case wxDOT_DASH
: { lineStyle
= GDK_LINE_DOUBLE_DASH
; break; };
443 GdkCapStyle capStyle
= GDK_CAP_ROUND
;
444 switch (m_pen
.GetCap())
446 case wxCAP_ROUND
: { capStyle
= GDK_CAP_ROUND
; break; };
447 case wxCAP_PROJECTING
: { capStyle
= GDK_CAP_PROJECTING
; break; };
448 case wxCAP_BUTT
: { capStyle
= GDK_CAP_BUTT
; break; };
451 GdkJoinStyle joinStyle
= GDK_JOIN_ROUND
;
452 switch (m_pen
.GetJoin())
454 case wxJOIN_BEVEL
: { joinStyle
= GDK_JOIN_BEVEL
; break; };
455 case wxJOIN_ROUND
: { joinStyle
= GDK_JOIN_ROUND
; break; };
456 case wxJOIN_MITER
: { joinStyle
= GDK_JOIN_MITER
; break; };
459 gdk_gc_set_line_attributes( m_penGC
, width
, lineStyle
, capStyle
, joinStyle
);
461 m_pen
.GetColour().CalcPixel( m_cmap
);
462 gdk_gc_set_foreground( m_penGC
, m_pen
.GetColour().GetColor() );
465 void wxPaintDC::SetBrush( const wxBrush
&brush
)
469 if (m_brush
== brush
) return;
473 if (!m_brush
.Ok()) return;
475 m_brush
.GetColour().CalcPixel( m_cmap
);
476 gdk_gc_set_foreground( m_brushGC
, m_brush
.GetColour().GetColor() );
478 GdkFill fillStyle
= GDK_SOLID
;
479 switch (m_brush
.GetStyle())
485 fillStyle
= GDK_STIPPLED
;
488 gdk_gc_set_fill( m_brushGC
, fillStyle
);
490 if (m_brush
.GetStyle() == wxSTIPPLE
)
492 gdk_gc_set_stipple( m_brushGC
, m_brush
.GetStipple()->GetPixmap() );
495 if (IS_HATCH(m_brush
.GetStyle()))
497 int num
= m_brush
.GetStyle() - wxBDIAGONAL_HATCH
;
498 gdk_gc_set_stipple( m_brushGC
, hatches
[num
] );
502 void wxPaintDC::SetLogicalFunction( int function
)
504 if (m_logicalFunction
== function
) return;
505 GdkFunction mode
= GDK_COPY
;
508 case wxXOR
: mode
= GDK_INVERT
; break;
509 case wxINVERT
: mode
= GDK_INVERT
; break;
512 m_logicalFunction
= function
;
513 gdk_gc_set_function( m_penGC
, mode
);
514 gdk_gc_set_function( m_brushGC
, mode
);
517 void wxPaintDC::SetTextForeground( const wxColour
&col
)
521 if (m_textForegroundColour
== col
) return;
523 m_textForegroundColour
= col
;
524 if (!m_textForegroundColour
.Ok()) return;
526 m_textForegroundColour
.CalcPixel( m_cmap
);
527 gdk_gc_set_foreground( m_textGC
, m_textForegroundColour
.GetColor() );
530 void wxPaintDC::SetTextBackground( const wxColour
&col
)
534 if (m_textBackgroundColour
== col
) return;
536 m_textBackgroundColour
= col
;
537 if (!m_textBackgroundColour
.Ok()) return;
539 m_textBackgroundColour
.CalcPixel( m_cmap
);
540 gdk_gc_set_background( m_textGC
, m_textBackgroundColour
.GetColor() );
543 void wxPaintDC::SetBackgroundMode( int WXUNUSED(mode
) )
547 void wxPaintDC::SetPalette( const wxPalette
& WXUNUSED(palette
) )
551 void wxPaintDC::SetClippingRegion( long x
, long y
, long width
, long height
)
553 wxDC::SetClippingRegion( x
, y
, width
, height
);
556 rect
.x
= XLOG2DEV(x
);
557 rect
.y
= YLOG2DEV(y
);
558 rect
.width
= XLOG2DEV(x
+width
);
559 rect
.height
= YLOG2DEV(y
+height
);
560 gdk_gc_set_clip_rectangle( m_penGC
, &rect
);
561 gdk_gc_set_clip_rectangle( m_brushGC
, &rect
);
562 gdk_gc_set_clip_rectangle( m_textGC
, &rect
);
563 gdk_gc_set_clip_rectangle( m_bgGC
, &rect
);
567 void wxPaintDC::DestroyClippingRegion(void)
569 wxDC::DestroyClippingRegion();
571 gdk_gc_set_clip_rectangle( m_penGC
, NULL
);
572 gdk_gc_set_clip_rectangle( m_brushGC
, NULL
);
573 gdk_gc_set_clip_rectangle( m_textGC
, NULL
);
574 gdk_gc_set_clip_rectangle( m_bgGC
, NULL
);
577 void wxPaintDC::SetUpDC(void)
580 m_logicalFunction
= wxCOPY
;
581 m_penGC
= gdk_gc_new( m_window
);
582 m_brushGC
= gdk_gc_new( m_window
);
583 m_textGC
= gdk_gc_new( m_window
);
584 m_bgGC
= gdk_gc_new( m_window
);
585 SetTextForeground( m_textForegroundColour
);
586 SetTextBackground( m_textBackgroundColour
);
591 gdk_gc_set_background( m_penGC
, wxWHITE
->GetColor() );
595 hatch_bitmap
= hatches
;
596 hatch_bitmap
[0] = gdk_bitmap_create_from_data( NULL
, bdiag_bits
, bdiag_width
, bdiag_height
);
597 hatch_bitmap
[1] = gdk_bitmap_create_from_data( NULL
, cdiag_bits
, cdiag_width
, cdiag_height
);
598 hatch_bitmap
[2] = gdk_bitmap_create_from_data( NULL
, fdiag_bits
, fdiag_width
, fdiag_height
);
599 hatch_bitmap
[3] = gdk_bitmap_create_from_data( NULL
, cross_bits
, cross_width
, cross_height
);
600 hatch_bitmap
[4] = gdk_bitmap_create_from_data( NULL
, horiz_bits
, horiz_width
, horiz_height
);
601 hatch_bitmap
[5] = gdk_bitmap_create_from_data( NULL
, verti_bits
, verti_width
, verti_height
);
605 GdkWindow
*wxPaintDC::GetWindow(void)
610 // ----------------------------------- spline code ----------------------------------------
612 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
613 double a3
, double b3
, double a4
, double b4
);
614 void wx_clear_stack(void);
615 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
616 double *y3
, double *x4
, double *y4
);
617 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
618 double x4
, double y4
);
619 static bool wx_spline_add_point(double x
, double y
);
620 static void wx_spline_draw_point_array(wxDC
*dc
);
622 wxList wx_spline_point_list
;
624 #define half(z1, z2) ((z1+z2)/2.0)
627 /* iterative version */
629 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
632 register double xmid
, ymid
;
633 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
636 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
638 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
639 xmid
= (double)half(x2
, x3
);
640 ymid
= (double)half(y2
, y3
);
641 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
642 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
643 wx_spline_add_point( x1
, y1
);
644 wx_spline_add_point( xmid
, ymid
);
646 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
647 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
648 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
649 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
654 /* utilities used by spline drawing routines */
656 typedef struct wx_spline_stack_struct
{
657 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
660 #define SPLINE_STACK_DEPTH 20
661 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
662 static Stack
*wx_stack_top
;
663 static int wx_stack_count
;
665 void wx_clear_stack(void)
667 wx_stack_top
= wx_spline_stack
;
671 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
673 wx_stack_top
->x1
= x1
;
674 wx_stack_top
->y1
= y1
;
675 wx_stack_top
->x2
= x2
;
676 wx_stack_top
->y2
= y2
;
677 wx_stack_top
->x3
= x3
;
678 wx_stack_top
->y3
= y3
;
679 wx_stack_top
->x4
= x4
;
680 wx_stack_top
->y4
= y4
;
685 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
686 double *x3
, double *y3
, double *x4
, double *y4
)
688 if (wx_stack_count
== 0)
692 *x1
= wx_stack_top
->x1
;
693 *y1
= wx_stack_top
->y1
;
694 *x2
= wx_stack_top
->x2
;
695 *y2
= wx_stack_top
->y2
;
696 *x3
= wx_stack_top
->x3
;
697 *y3
= wx_stack_top
->y3
;
698 *x4
= wx_stack_top
->x4
;
699 *y4
= wx_stack_top
->y4
;
703 static bool wx_spline_add_point(double x
, double y
)
705 wxPoint
*point
= new wxPoint
;
708 wx_spline_point_list
.Append((wxObject
*)point
);
712 static void wx_spline_draw_point_array(wxDC
*dc
)
714 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
715 wxNode
*node
= wx_spline_point_list
.First();
718 wxPoint
*point
= (wxPoint
*)node
->Data();
721 node
= wx_spline_point_list
.First();
725 void wxPaintDC::DrawOpenSpline( wxList
*points
)
728 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
729 double x1
, y1
, x2
, y2
;
731 wxNode
*node
= points
->First();
732 p
= (wxPoint
*)node
->Data();
738 p
= (wxPoint
*)node
->Data();
742 cx1
= (double)((x1
+ x2
) / 2);
743 cy1
= (double)((y1
+ y2
) / 2);
744 cx2
= (double)((cx1
+ x2
) / 2);
745 cy2
= (double)((cy1
+ y2
) / 2);
747 wx_spline_add_point(x1
, y1
);
749 while ((node
= node
->Next()) != NULL
)
751 p
= (wxPoint
*)node
->Data();
756 cx4
= (double)(x1
+ x2
) / 2;
757 cy4
= (double)(y1
+ y2
) / 2;
758 cx3
= (double)(x1
+ cx4
) / 2;
759 cy3
= (double)(y1
+ cy4
) / 2;
761 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
765 cx2
= (double)(cx1
+ x2
) / 2;
766 cy2
= (double)(cy1
+ y2
) / 2;
769 wx_spline_add_point( cx1
, cy1
);
770 wx_spline_add_point( x2
, y2
);
772 wx_spline_draw_point_array( this );