1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
21 #pragma implementation "dc.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
32 #include "wx/window.h"
35 #include "wx/dialog.h"
37 #include "wx/bitmap.h"
38 #include "wx/dcmemory.h"
43 #include "wx/dcprint.h"
48 #if wxUSE_COMMON_DIALOGS
56 #include "wx/msw/private.h"
58 #if !USE_SHARED_LIBRARY
59 IMPLEMENT_ABSTRACT_CLASS(wxDC
, wxObject
)
62 // ---------------------------------------------------------------------------
64 // ---------------------------------------------------------------------------
66 static const int VIEWPORT_EXTENT
= 1000;
68 static const int MM_POINTS
= 9;
69 static const int MM_METRIC
= 10;
71 // ===========================================================================
73 // ===========================================================================
75 // ---------------------------------------------------------------------------
77 // ---------------------------------------------------------------------------
79 // Default constructor
93 m_windowExtX
= VIEWPORT_EXTENT
;
94 m_windowExtY
= VIEWPORT_EXTENT
;
103 SelectOldObjects(m_hDC
);
105 if ( m_canvas
== NULL
)
106 ::DeleteDC(GetHdc());
108 ::ReleaseDC((HWND
)m_canvas
->GetHWND(), GetHdc());
114 // This will select current objects out of the DC,
115 // which is what you have to do before deleting the
117 void wxDC::SelectOldObjects(WXHDC dc
)
123 ::SelectObject((HDC
) dc
, (HBITMAP
) m_oldBitmap
);
124 if (m_selectedBitmap
.Ok())
126 m_selectedBitmap
.SetSelectedInto(NULL
);
132 ::SelectObject((HDC
) dc
, (HPEN
) m_oldPen
);
137 ::SelectObject((HDC
) dc
, (HBRUSH
) m_oldBrush
);
142 ::SelectObject((HDC
) dc
, (HFONT
) m_oldFont
);
147 ::SelectPalette((HDC
) dc
, (HPALETTE
) m_oldPalette
, TRUE
);
152 m_brush
= wxNullBrush
;
154 m_palette
= wxNullPalette
;
156 m_backgroundBrush
= wxNullBrush
;
157 m_selectedBitmap
= wxNullBitmap
;
160 // ---------------------------------------------------------------------------
162 // ---------------------------------------------------------------------------
164 void wxDC::DoSetClippingRegion(long cx
, long cy
, long cw
, long ch
)
169 m_clipX2
= (int)(cx
+ cw
);
170 m_clipY2
= (int)(cy
+ ch
);
172 DoClipping((WXHDC
) m_hDC
);
175 void wxDC::DoSetClippingRegionAsRegion(const wxRegion
& region
)
177 wxCHECK_RET( region
.GetHRGN(), _T("invalid clipping region") );
179 wxRect box
= region
.GetBox();
184 m_clipX2
= box
.x
+ box
.width
;
185 m_clipY2
= box
.y
+ box
.height
;
188 SelectClipRgn(GetHdc(), (HRGN
) region
.GetHRGN());
190 ExtSelectClipRgn(GetHdc(), (HRGN
) region
.GetHRGN(), RGN_AND
);
194 void wxDC::DoClipping(WXHDC dc
)
196 if (m_clipping
&& dc
)
198 IntersectClipRect((HDC
) dc
, XLOG2DEV(m_clipX1
), YLOG2DEV(m_clipY1
),
199 XLOG2DEV(m_clipX2
), YLOG2DEV(m_clipY2
));
203 void wxDC::DestroyClippingRegion()
205 if (m_clipping
&& m_hDC
)
207 // TODO: this should restore the previous clipping region,
208 // so that OnPaint processing works correctly, and the update clipping region
209 // doesn't get destroyed after the first DestroyClippingRegion.
210 HRGN rgn
= CreateRectRgn(0, 0, 32000, 32000);
211 SelectClipRgn(GetHdc(), rgn
);
217 // ---------------------------------------------------------------------------
218 // query capabilities
219 // ---------------------------------------------------------------------------
221 bool wxDC::CanDrawBitmap() const
226 bool wxDC::CanGetTextExtent() const
228 // What sort of display is it?
229 int technology
= ::GetDeviceCaps(GetHdc(), TECHNOLOGY
);
231 return (technology
== DT_RASDISPLAY
) || (technology
== DT_RASPRINTER
);
234 int wxDC::GetDepth() const
236 return (int)::GetDeviceCaps(GetHdc(), BITSPIXEL
);
239 // ---------------------------------------------------------------------------
241 // ---------------------------------------------------------------------------
248 GetClientRect((HWND
) m_canvas
->GetHWND(), &rect
);
252 wxCHECK_RET( m_selectedBitmap
.Ok(), _T("this DC can't be cleared") );
254 rect
.left
= 0; rect
.top
= 0;
255 rect
.right
= m_selectedBitmap
.GetWidth();
256 rect
.bottom
= m_selectedBitmap
.GetHeight();
259 (void) ::SetMapMode(GetHdc(), MM_TEXT
);
261 DWORD colour
= GetBkColor(GetHdc());
262 HBRUSH brush
= CreateSolidBrush(colour
);
263 FillRect(GetHdc(), &rect
, brush
);
266 ::SetMapMode(GetHdc(), MM_ANISOTROPIC
);
267 ::SetViewportExtEx(GetHdc(), VIEWPORT_EXTENT
, VIEWPORT_EXTENT
, NULL
);
268 ::SetWindowExtEx(GetHdc(), m_windowExtX
, m_windowExtY
, NULL
);
269 ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX
, (int)m_deviceOriginY
, NULL
);
270 ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX
, (int)m_logicalOriginY
, NULL
);
273 void wxDC::DoFloodFill(long x
, long y
, const wxColour
& col
, int style
)
275 (void)ExtFloodFill(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
),
277 style
== wxFLOOD_SURFACE
? FLOODFILLSURFACE
280 CalcBoundingBox(x
, y
);
283 bool wxDC::DoGetPixel(long x
, long y
, wxColour
*col
) const
285 // added by steve 29.12.94 (copied from DrawPoint)
286 // returns TRUE for pixels in the color of the current pen
287 // and FALSE for all other pixels colors
288 // if col is non-NULL return the color of the pixel
290 // get the color of the pixel
291 COLORREF pixelcolor
= ::GetPixel(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
));
292 // get the color of the pen
293 COLORREF pencolor
= 0x00ffffff;
296 pencolor
= m_pen
.GetColour().GetPixel();
299 // return the color of the pixel
301 col
->Set(GetRValue(pixelcolor
),GetGValue(pixelcolor
),GetBValue(pixelcolor
));
303 // check, if color of the pixels is the same as the color
304 // of the current pen
305 return(pixelcolor
==pencolor
);
308 void wxDC::DoCrossHair(long x
, long y
)
310 long x1
= x
-VIEWPORT_EXTENT
;
311 long y1
= y
-VIEWPORT_EXTENT
;
312 long x2
= x
+VIEWPORT_EXTENT
;
313 long y2
= y
+VIEWPORT_EXTENT
;
315 (void)MoveToEx(GetHdc(), XLOG2DEV(x1
), YLOG2DEV(y
), NULL
);
316 (void)LineTo(GetHdc(), XLOG2DEV(x2
), YLOG2DEV(y
));
318 (void)MoveToEx(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y1
), NULL
);
319 (void)LineTo(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y2
));
321 CalcBoundingBox(x1
, y1
);
322 CalcBoundingBox(x2
, y2
);
325 void wxDC::DoDrawLine(long x1
, long y1
, long x2
, long y2
)
327 (void)MoveToEx(GetHdc(), XLOG2DEV(x1
), YLOG2DEV(y1
), NULL
);
328 (void)LineTo(GetHdc(), XLOG2DEV(x2
), YLOG2DEV(y2
));
330 /* MATTHEW: [6] New normalization */
331 #if WX_STANDARD_GRAPHICS
332 (void)LineTo(GetHdc(), XLOG2DEV(x2
) + 1, YLOG2DEV(y2
));
335 CalcBoundingBox(x1
, y1
);
336 CalcBoundingBox(x2
, y2
);
339 void wxDC::DoDrawArc(long x1
,long y1
,long x2
,long y2
, long xc
, long yc
)
343 double radius
= (double)sqrt(dx
*dx
+dy
*dy
) ;;
344 if (x1
==x2
&& x2
==y2
)
346 DrawEllipse(xc
,yc
,(long)(radius
*2.0),(long)(radius
*2.0));
350 long xx1
= XLOG2DEV(x1
);
351 long yy1
= YLOG2DEV(y1
);
352 long xx2
= XLOG2DEV(x2
);
353 long yy2
= YLOG2DEV(y2
);
354 long xxc
= XLOG2DEV(xc
);
355 long yyc
= YLOG2DEV(yc
);
356 long ray
= (long) sqrt(double((xxc
-xx1
)*(xxc
-xx1
)+(yyc
-yy1
)*(yyc
-yy1
)));
358 (void)MoveToEx(GetHdc(), (int) xx1
, (int) yy1
, NULL
);
359 long xxx1
= (long) (xxc
-ray
);
360 long yyy1
= (long) (yyc
-ray
);
361 long xxx2
= (long) (xxc
+ray
);
362 long yyy2
= (long) (yyc
+ray
);
363 if (m_brush
.Ok() && m_brush
.GetStyle() !=wxTRANSPARENT
)
365 // Have to add 1 to bottom-right corner of rectangle
366 // to make semi-circles look right (crooked line otherwise).
367 // Unfortunately this is not a reliable method, depends
368 // on the size of shape.
369 // TODO: figure out why this happens!
370 Pie(GetHdc(),xxx1
,yyy1
,xxx2
+1,yyy2
+1,
374 Arc(GetHdc(),xxx1
,yyy1
,xxx2
,yyy2
,
377 CalcBoundingBox((xc
-radius
), (yc
-radius
));
378 CalcBoundingBox((xc
+radius
), (yc
+radius
));
381 void wxDC::DoDrawPoint(long x
, long y
)
383 COLORREF color
= 0x00ffffff;
386 color
= m_pen
.GetColour().GetPixel();
389 SetPixel(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), color
);
391 CalcBoundingBox(x
, y
);
394 void wxDC::DoDrawPolygon(int n
, wxPoint points
[], long xoffset
, long yoffset
,int fillStyle
)
396 // Do things less efficiently if we have offsets
397 if (xoffset
!= 0 || yoffset
!= 0)
399 POINT
*cpoints
= new POINT
[n
];
401 for (i
= 0; i
< n
; i
++)
403 cpoints
[i
].x
= (int)(points
[i
].x
+ xoffset
);
404 cpoints
[i
].y
= (int)(points
[i
].y
+ yoffset
);
406 CalcBoundingBox(cpoints
[i
].x
, cpoints
[i
].y
);
408 int prev
= SetPolyFillMode(GetHdc(),fillStyle
==wxODDEVEN_RULE
?ALTERNATE
:WINDING
);
409 (void)Polygon(GetHdc(), cpoints
, n
);
410 SetPolyFillMode(GetHdc(),prev
);
416 for (i
= 0; i
< n
; i
++)
417 CalcBoundingBox(points
[i
].x
, points
[i
].y
);
419 int prev
= SetPolyFillMode(GetHdc(),fillStyle
==wxODDEVEN_RULE
?ALTERNATE
:WINDING
);
420 (void)Polygon(GetHdc(), (POINT
*) points
, n
);
421 SetPolyFillMode(GetHdc(),prev
);
425 void wxDC::DoDrawLines(int n
, wxPoint points
[], long xoffset
, long yoffset
)
427 // Do things less efficiently if we have offsets
428 if (xoffset
!= 0 || yoffset
!= 0)
430 POINT
*cpoints
= new POINT
[n
];
432 for (i
= 0; i
< n
; i
++)
434 cpoints
[i
].x
= (int)(points
[i
].x
+ xoffset
);
435 cpoints
[i
].y
= (int)(points
[i
].y
+ yoffset
);
437 CalcBoundingBox(cpoints
[i
].x
, cpoints
[i
].y
);
439 (void)Polyline(GetHdc(), cpoints
, n
);
445 for (i
= 0; i
< n
; i
++)
446 CalcBoundingBox(points
[i
].x
, points
[i
].y
);
448 (void)Polyline(GetHdc(), (POINT
*) points
, n
);
452 void wxDC::DoDrawRectangle(long x
, long y
, long width
, long height
)
455 long y2
= y
+ height
;
457 /* MATTHEW: [6] new normalization */
458 #if WX_STANDARD_GRAPHICS
459 bool do_brush
, do_pen
;
461 do_brush
= m_brush
.Ok() && m_brush
.GetStyle() != wxTRANSPARENT
;
462 do_pen
= m_pen
.Ok() && m_pen
.GetStyle() != wxTRANSPARENT
;
465 HPEN orig_pen
= NULL
;
467 if (do_pen
|| !m_pen
.Ok())
468 orig_pen
= (HPEN
) ::SelectObject(GetHdc(), (HPEN
) ::GetStockObject(NULL_PEN
));
470 (void)Rectangle(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
),
471 XLOG2DEV(x2
) + 1, YLOG2DEV(y2
) + 1);
473 if (do_pen
|| !m_pen
.Ok())
474 ::SelectObject(GetHdc() , orig_pen
);
477 HBRUSH orig_brush
= NULL
;
479 if (do_brush
|| !m_brush
.Ok())
480 orig_brush
= (HBRUSH
) ::SelectObject(GetHdc(), (HBRUSH
) ::GetStockObject(NULL_BRUSH
));
482 (void)Rectangle(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
),
483 XLOG2DEV(x2
), YLOG2DEV(y2
));
485 if (do_brush
|| !m_brush
.Ok())
486 ::SelectObject(GetHdc(), orig_brush
);
489 (void)Rectangle(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
), YLOG2DEV(y2
));
492 CalcBoundingBox(x
, y
);
493 CalcBoundingBox(x2
, y2
);
496 void wxDC::DoDrawRoundedRectangle(long x
, long y
, long width
, long height
, double radius
)
498 // Now, a negative radius value is interpreted to mean
499 // 'the proportion of the smallest X or Y dimension'
503 double smallest
= 0.0;
508 radius
= (- radius
* smallest
);
512 long y2
= (y
+height
);
514 (void)RoundRect(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
),
515 YLOG2DEV(y2
), (int) (2*XLOG2DEV(radius
)), (int)( 2*YLOG2DEV(radius
)));
517 CalcBoundingBox(x
, y
);
518 CalcBoundingBox(x2
, y2
);
521 void wxDC::DoDrawEllipse(long x
, long y
, long width
, long height
)
524 long y2
= (y
+height
);
526 (void)Ellipse(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
), YLOG2DEV(y2
));
528 CalcBoundingBox(x
, y
);
529 CalcBoundingBox(x2
, y2
);
532 // Chris Breeze 20/5/98: first implementation of DrawEllipticArc on Windows
533 void wxDC::DoDrawEllipticArc(long x
,long y
,long w
,long h
,double sa
,double ea
)
538 const double deg2rad
= 3.14159265359 / 180.0;
539 int rx1
= XLOG2DEV(x
+w
/2);
540 int ry1
= YLOG2DEV(y
+h
/2);
543 rx1
+= (int)(100.0 * abs(w
) * cos(sa
* deg2rad
));
544 ry1
-= (int)(100.0 * abs(h
) * m_signY
* sin(sa
* deg2rad
));
545 rx2
+= (int)(100.0 * abs(w
) * cos(ea
* deg2rad
));
546 ry2
-= (int)(100.0 * abs(h
) * m_signY
* sin(ea
* deg2rad
));
548 // draw pie with NULL_PEN first and then outline otherwise a line is
549 // drawn from the start and end points to the centre
550 HPEN orig_pen
= (HPEN
) ::SelectObject(GetHdc(), (HPEN
) ::GetStockObject(NULL_PEN
));
553 (void)Pie(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
)+1, YLOG2DEV(y2
)+1,
558 (void)Pie(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
)-1, XLOG2DEV(x2
)+1, YLOG2DEV(y2
),
559 rx1
, ry1
-1, rx2
, ry2
-1);
561 ::SelectObject(GetHdc(), orig_pen
);
562 (void)Arc(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
), YLOG2DEV(y2
),
565 CalcBoundingBox(x
, y
);
566 CalcBoundingBox(x2
, y2
);
569 void wxDC::DoDrawIcon(const wxIcon
& icon
, long x
, long y
)
571 #if defined(__WIN32__) && !defined(__SC__) && !defined(__TWIN32__)
572 ::DrawIconEx(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), (HICON
) icon
.GetHICON(),
573 icon
.GetWidth(), icon
.GetHeight(), 0, 0, DI_NORMAL
);
575 ::DrawIcon(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), (HICON
) icon
.GetHICON());
578 CalcBoundingBox(x
, y
);
579 CalcBoundingBox(x
+icon
.GetWidth(), y
+icon
.GetHeight());
582 void wxDC::DoDrawBitmap( const wxBitmap
&bmp
, long x
, long y
, bool useMask
)
587 // If we're not drawing transparently, and not drawing to a printer,
588 // optimize this function to use Windows functions.
589 if (!useMask
&& !IsKindOf(CLASSINFO(wxPrinterDC
)))
592 HDC memdc
= ::CreateCompatibleDC( cdc
);
593 HBITMAP hbitmap
= (HBITMAP
) bmp
.GetHBITMAP( );
594 ::SelectObject( memdc
, hbitmap
);
595 ::BitBlt( cdc
, x
, y
, bmp
.GetWidth(), bmp
.GetHeight(), memdc
, 0, 0, SRCCOPY
);
600 // Rather than reproduce wxDC::Blit, let's do it at the wxWin API level
602 memDC
.SelectObject(bmp
);
604 /* Not sure if we need this. The mask should leave the
605 * masked areas as per the original background of this DC.
608 // There might be transparent areas, so make these
609 // the same colour as this DC
610 memDC.SetBackground(* GetBackground());
614 Blit(x
, y
, bmp
.GetWidth(), bmp
.GetHeight(), & memDC
, 0, 0, wxCOPY
, useMask
);
616 memDC
.SelectObject(wxNullBitmap
);
620 void wxDC::DoDrawText(const wxString
& text
, long x
, long y
)
622 if (m_textForegroundColour
.Ok())
623 SetTextColor(GetHdc(), m_textForegroundColour
.GetPixel() );
625 DWORD old_background
= 0;
626 if (m_textBackgroundColour
.Ok())
628 old_background
= SetBkColor(GetHdc(), m_textBackgroundColour
.GetPixel() );
631 if (m_backgroundMode
== wxTRANSPARENT
)
632 SetBkMode(GetHdc(), TRANSPARENT
);
634 SetBkMode(GetHdc(), OPAQUE
);
636 (void)TextOut(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), WXSTRINGCAST text
, wxStrlen(WXSTRINGCAST text
));
638 if (m_textBackgroundColour
.Ok())
639 (void)SetBkColor(GetHdc(), old_background
);
641 CalcBoundingBox(x
, y
);
644 GetTextExtent(text
, &w
, &h
);
645 CalcBoundingBox((x
+ w
), (y
+ h
));
648 // ---------------------------------------------------------------------------
650 // ---------------------------------------------------------------------------
652 void wxDC::SetPalette(const wxPalette
& palette
)
654 // Set the old object temporarily, in case the assignment deletes an object
655 // that's not yet selected out.
658 ::SelectPalette(GetHdc(), (HPALETTE
) m_oldPalette
, TRUE
);
666 // Setting a NULL colourmap is a way of restoring
667 // the original colourmap
670 ::SelectPalette(GetHdc(), (HPALETTE
) m_oldPalette
, TRUE
);
677 if (m_palette
.Ok() && m_palette
.GetHPALETTE())
679 HPALETTE oldPal
= ::SelectPalette(GetHdc(), (HPALETTE
) m_palette
.GetHPALETTE(), TRUE
);
681 m_oldPalette
= (WXHPALETTE
) oldPal
;
683 ::RealizePalette(GetHdc());
687 void wxDC::SetFont(const wxFont
& the_font
)
689 // Set the old object temporarily, in case the assignment deletes an object
690 // that's not yet selected out.
693 ::SelectObject(GetHdc(), (HFONT
) m_oldFont
);
702 ::SelectObject(GetHdc(), (HFONT
) m_oldFont
);
706 if (m_font
.Ok() && m_font
.GetResourceHandle())
708 HFONT f
= (HFONT
) ::SelectObject(GetHdc(), (HFONT
) m_font
.GetResourceHandle());
709 if (f
== (HFONT
) NULL
)
711 wxLogDebug(_T("::SelectObject failed in wxDC::SetFont."));
714 m_oldFont
= (WXHFONT
) f
;
718 void wxDC::SetPen(const wxPen
& pen
)
720 // Set the old object temporarily, in case the assignment deletes an object
721 // that's not yet selected out.
724 ::SelectObject(GetHdc(), (HPEN
) m_oldPen
);
733 ::SelectObject(GetHdc(), (HPEN
) m_oldPen
);
739 if (m_pen
.GetResourceHandle())
741 HPEN p
= (HPEN
) ::SelectObject(GetHdc(), (HPEN
)m_pen
.GetResourceHandle());
743 m_oldPen
= (WXHPEN
) p
;
748 void wxDC::SetBrush(const wxBrush
& brush
)
750 // Set the old object temporarily, in case the assignment deletes an object
751 // that's not yet selected out.
754 ::SelectObject(GetHdc(), (HBRUSH
) m_oldBrush
);
763 ::SelectObject(GetHdc(), (HBRUSH
) m_oldBrush
);
769 if (m_brush
.GetResourceHandle())
772 b
= (HBRUSH
) ::SelectObject(GetHdc(), (HBRUSH
)m_brush
.GetResourceHandle());
774 m_oldBrush
= (WXHBRUSH
) b
;
779 void wxDC::SetBackground(const wxBrush
& brush
)
781 m_backgroundBrush
= brush
;
783 if (!m_backgroundBrush
.Ok())
788 bool customColours
= TRUE
;
789 // If we haven't specified wxUSER_COLOURS, don't allow the panel/dialog box to
790 // change background colours from the control-panel specified colours.
791 if (m_canvas
->IsKindOf(CLASSINFO(wxWindow
)) && ((m_canvas
->GetWindowStyleFlag() & wxUSER_COLOURS
) != wxUSER_COLOURS
))
792 customColours
= FALSE
;
796 if (m_backgroundBrush
.GetStyle()==wxTRANSPARENT
)
798 m_canvas
->SetTransparent(TRUE
);
802 // New behaviour, 10/2/99: setting the background brush of a DC
803 // doesn't affect the window background colour. However,
804 // I'm leaving in the transparency setting because it's needed by
805 // various controls (e.g. wxStaticText) to determine whether to draw
806 // transparently or not. TODO: maybe this should be a new function
807 // wxWindow::SetTransparency(). Should that apply to the child itself, or the
809 // m_canvas->SetBackgroundColour(m_backgroundBrush.GetColour());
810 m_canvas
->SetTransparent(FALSE
);
814 COLORREF new_color
= m_backgroundBrush
.GetColour().GetPixel();
816 (void)SetBkColor(GetHdc(), new_color
);
820 void wxDC::SetBackgroundMode(int mode
)
822 m_backgroundMode
= mode
;
824 if (m_backgroundMode
== wxTRANSPARENT
)
825 ::SetBkMode(GetHdc(), TRANSPARENT
);
827 ::SetBkMode(GetHdc(), OPAQUE
);
830 void wxDC::SetLogicalFunction(int function
)
832 m_logicalFunction
= function
;
834 SetRop((WXHDC
) m_hDC
);
837 void wxDC::SetRop(WXHDC dc
)
839 if (!dc
|| m_logicalFunction
< 0)
843 // These may be wrong
844 switch (m_logicalFunction
)
846 // case wxXOR: c_rop = R2_XORPEN; break;
847 case wxXOR
: c_rop
= R2_NOTXORPEN
; break;
848 case wxINVERT
: c_rop
= R2_NOT
; break;
849 case wxOR_REVERSE
: c_rop
= R2_MERGEPENNOT
; break;
850 case wxAND_REVERSE
: c_rop
= R2_MASKPENNOT
; break;
851 case wxCLEAR
: c_rop
= R2_WHITE
; break;
852 case wxSET
: c_rop
= R2_BLACK
; break;
853 case wxSRC_INVERT
: c_rop
= R2_NOTCOPYPEN
; break;
854 case wxOR_INVERT
: c_rop
= R2_MERGENOTPEN
; break;
855 case wxAND
: c_rop
= R2_MASKPEN
; break;
856 case wxOR
: c_rop
= R2_MERGEPEN
; break;
857 case wxAND_INVERT
: c_rop
= R2_MASKNOTPEN
; break;
862 c_rop
= R2_COPYPEN
; break;
864 SetROP2((HDC
) dc
, c_rop
);
867 bool wxDC::StartDoc(const wxString
& message
)
869 // We might be previewing, so return TRUE to let it continue.
877 void wxDC::StartPage()
885 // ---------------------------------------------------------------------------
887 // ---------------------------------------------------------------------------
889 long wxDC::GetCharHeight() const
891 TEXTMETRIC lpTextMetric
;
893 GetTextMetrics(GetHdc(), &lpTextMetric
);
895 return YDEV2LOGREL(lpTextMetric
.tmHeight
);
898 long wxDC::GetCharWidth() const
900 TEXTMETRIC lpTextMetric
;
902 GetTextMetrics(GetHdc(), &lpTextMetric
);
904 return XDEV2LOGREL(lpTextMetric
.tmAveCharWidth
);
907 void wxDC::GetTextExtent(const wxString
& string
, long *x
, long *y
,
908 long *descent
, long *externalLeading
,
909 wxFont
*theFont
) const
911 wxFont
*fontToUse
= (wxFont
*) theFont
;
913 fontToUse
= (wxFont
*) &m_font
;
918 GetTextExtentPoint(GetHdc(), WXSTRINGCAST string
, wxStrlen(WXSTRINGCAST string
), &sizeRect
);
919 GetTextMetrics(GetHdc(), &tm
);
921 if (x
) *x
= XDEV2LOGREL(sizeRect
.cx
);
922 if (y
) *y
= YDEV2LOGREL(sizeRect
.cy
);
923 if (descent
) *descent
= tm
.tmDescent
;
924 if (externalLeading
) *externalLeading
= tm
.tmExternalLeading
;
927 void wxDC::SetMapMode(int mode
)
929 m_mappingMode
= mode
;
932 int pixel_height
= 0;
936 pixel_width
= GetDeviceCaps(GetHdc(), HORZRES
);
937 pixel_height
= GetDeviceCaps(GetHdc(), VERTRES
);
938 mm_width
= GetDeviceCaps(GetHdc(), HORZSIZE
);
939 mm_height
= GetDeviceCaps(GetHdc(), VERTSIZE
);
941 if ((pixel_width
== 0) || (pixel_height
== 0) || (mm_width
== 0) || (mm_height
== 0))
946 double mm2pixelsX
= pixel_width
/mm_width
;
947 double mm2pixelsY
= pixel_height
/mm_height
;
953 m_logicalScaleX
= (twips2mm
* mm2pixelsX
);
954 m_logicalScaleY
= (twips2mm
* mm2pixelsY
);
959 m_logicalScaleX
= (pt2mm
* mm2pixelsX
);
960 m_logicalScaleY
= (pt2mm
* mm2pixelsY
);
965 m_logicalScaleX
= mm2pixelsX
;
966 m_logicalScaleY
= mm2pixelsY
;
971 m_logicalScaleX
= (mm2pixelsX
/10.0);
972 m_logicalScaleY
= (mm2pixelsY
/10.0);
978 m_logicalScaleX
= 1.0;
979 m_logicalScaleY
= 1.0;
984 if (::GetMapMode(GetHdc()) != MM_ANISOTROPIC
)
985 ::SetMapMode(GetHdc(), MM_ANISOTROPIC
);
987 SetViewportExtEx(GetHdc(), VIEWPORT_EXTENT
, VIEWPORT_EXTENT
, NULL
);
988 m_windowExtX
= (int)MS_XDEV2LOGREL(VIEWPORT_EXTENT
);
989 m_windowExtY
= (int)MS_YDEV2LOGREL(VIEWPORT_EXTENT
);
990 ::SetWindowExtEx(GetHdc(), m_windowExtX
, m_windowExtY
, NULL
);
991 ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX
, (int)m_deviceOriginY
, NULL
);
992 ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX
, (int)m_logicalOriginY
, NULL
);
995 void wxDC::SetUserScale(double x
, double y
)
1000 SetMapMode(m_mappingMode
);
1003 void wxDC::SetAxisOrientation(bool xLeftRight
, bool yBottomUp
)
1005 m_signX
= xLeftRight
? 1 : -1;
1006 m_signY
= yBottomUp
? -1 : 1;
1008 SetMapMode(m_mappingMode
);
1011 void wxDC::SetSystemScale(double x
, double y
)
1016 SetMapMode(m_mappingMode
);
1019 void wxDC::SetLogicalOrigin(long x
, long y
)
1021 m_logicalOriginX
= x
;
1022 m_logicalOriginY
= y
;
1024 ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX
, (int)m_logicalOriginY
, NULL
);
1027 void wxDC::SetDeviceOrigin(long x
, long y
)
1029 m_deviceOriginX
= x
;
1030 m_deviceOriginY
= y
;
1032 ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX
, (int)m_deviceOriginY
, NULL
);
1035 // ---------------------------------------------------------------------------
1036 // coordinates transformations
1037 // ---------------------------------------------------------------------------
1039 long wxDCBase::DeviceToLogicalX(long x
) const
1041 return (long) (((x
) - m_deviceOriginX
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
) - m_logicalOriginX
);
1044 long wxDCBase::DeviceToLogicalXRel(long x
) const
1046 return (long) ((x
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
));
1049 long wxDCBase::DeviceToLogicalY(long y
) const
1051 return (long) (((y
) - m_deviceOriginY
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
) - m_logicalOriginY
);
1054 long wxDCBase::DeviceToLogicalYRel(long y
) const
1056 return (long) ((y
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
));
1059 long wxDCBase::LogicalToDeviceX(long x
) const
1061 return (long) ((x
- m_logicalOriginX
)*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
+ m_deviceOriginX
);
1064 long wxDCBase::LogicalToDeviceXRel(long x
) const
1066 return (long) (x
*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
);
1069 long wxDCBase::LogicalToDeviceY(long y
) const
1071 return (long) ((y
- m_logicalOriginY
)*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
+ m_deviceOriginY
);
1074 long wxDCBase::LogicalToDeviceYRel(long y
) const
1076 return (long) (y
*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
);
1079 // ---------------------------------------------------------------------------
1081 // ---------------------------------------------------------------------------
1082 bool wxDC::DoBlit(long xdest
, long ydest
, long width
, long height
,
1083 wxDC
*source
, long xsrc
, long ysrc
, int rop
, bool useMask
)
1085 long xdest1
= xdest
;
1086 long ydest1
= ydest
;
1090 // Chris Breeze 18/5/98: use text foreground/background colours
1091 // when blitting from 1-bit bitmaps
1092 COLORREF old_textground
= ::GetTextColor(GetHdc());
1093 COLORREF old_background
= ::GetBkColor(GetHdc());
1094 if (m_textForegroundColour
.Ok())
1096 ::SetTextColor(GetHdc(), m_textForegroundColour
.GetPixel() );
1098 if (m_textBackgroundColour
.Ok())
1100 ::SetBkColor(GetHdc(), m_textBackgroundColour
.GetPixel() );
1103 DWORD dwRop
= rop
== wxCOPY
? SRCCOPY
:
1104 rop
== wxCLEAR
? WHITENESS
:
1105 rop
== wxSET
? BLACKNESS
:
1106 rop
== wxINVERT
? DSTINVERT
:
1107 rop
== wxAND
? MERGECOPY
:
1108 rop
== wxOR
? MERGEPAINT
:
1109 rop
== wxSRC_INVERT
? NOTSRCCOPY
:
1110 rop
== wxXOR
? SRCINVERT
:
1111 rop
== wxOR_REVERSE
? MERGEPAINT
:
1112 rop
== wxAND_REVERSE
? SRCERASE
:
1113 rop
== wxSRC_OR
? SRCPAINT
:
1114 rop
== wxSRC_AND
? SRCAND
:
1117 bool success
= TRUE
;
1118 if (useMask
&& source
->m_selectedBitmap
.Ok() && source
->m_selectedBitmap
.GetMask())
1122 // Not implemented under Win95 (or maybe a specific device?)
1123 if (MaskBlt(GetHdc(), xdest1
, ydest1
, (int)width
, (int)height
,
1124 (HDC
) source
->m_hDC
, xsrc1
, ysrc1
, (HBITMAP
) source
->m_selectedBitmap
.GetMask()->GetMaskBitmap(),
1134 HDC dc_mask
= CreateCompatibleDC((HDC
) source
->m_hDC
);
1135 ::SelectObject(dc_mask
, (HBITMAP
) source
->m_selectedBitmap
.GetMask()->GetMaskBitmap());
1136 success
= (BitBlt(GetHdc(), xdest1
, ydest1
, (int)width
, (int)height
,
1137 dc_mask
, xsrc1
, ysrc1
, 0x00220326 /* NOTSRCAND */) != 0);
1138 success
= (BitBlt(GetHdc(), xdest1
, ydest1
, (int)width
, (int)height
,
1139 (HDC
) source
->m_hDC
, xsrc1
, ysrc1
, SRCPAINT
) != 0);
1140 ::SelectObject(dc_mask
, 0);
1141 ::DeleteDC(dc_mask
);
1143 // New code from Chris Breeze, 15/7/98
1144 // Blit bitmap with mask
1146 if (IsKindOf(CLASSINFO(wxPrinterDC
)))
1148 // If we are printing source colours are screen colours
1149 // not printer colours and so we need copy the bitmap
1152 HDC dc_mask
= ::CreateCompatibleDC((HDC
) source
->m_hDC
);
1153 HDC dc_src
= (HDC
) source
->m_hDC
;
1155 ::SelectObject(dc_mask
, (HBITMAP
) source
->m_selectedBitmap
.GetMask()->GetMaskBitmap());
1156 for (int x
= 0; x
< width
; x
++)
1158 for (int y
= 0; y
< height
; y
++)
1160 COLORREF cref
= ::GetPixel(dc_mask
, x
, y
);
1163 HBRUSH brush
= ::CreateSolidBrush(::GetPixel(dc_src
, x
, y
));
1164 rect
.left
= xdest1
+ x
; rect
.right
= rect
.left
+ 1;
1165 rect
.top
= ydest1
+ y
; rect
.bottom
= rect
.top
+ 1;
1166 ::FillRect(GetHdc(), &rect
, brush
);
1167 ::DeleteObject(brush
);
1171 ::SelectObject(dc_mask
, 0);
1172 ::DeleteDC(dc_mask
);
1176 // create a temp buffer bitmap and DCs to access it and the mask
1177 HDC dc_mask
= ::CreateCompatibleDC((HDC
) source
->m_hDC
);
1178 HDC dc_buffer
= ::CreateCompatibleDC(GetHdc());
1179 HBITMAP buffer_bmap
= ::CreateCompatibleBitmap(GetHdc(), width
, height
);
1180 ::SelectObject(dc_mask
, (HBITMAP
) source
->m_selectedBitmap
.GetMask()->GetMaskBitmap());
1181 ::SelectObject(dc_buffer
, buffer_bmap
);
1183 // copy dest to buffer
1184 ::BitBlt(dc_buffer
, 0, 0, (int)width
, (int)height
,
1185 GetHdc(), xdest1
, ydest1
, SRCCOPY
);
1187 // copy src to buffer using selected raster op
1188 ::BitBlt(dc_buffer
, 0, 0, (int)width
, (int)height
,
1189 (HDC
) source
->m_hDC
, xsrc1
, ysrc1
, dwRop
);
1191 // set masked area in buffer to BLACK (pixel value 0)
1192 COLORREF prevBkCol
= ::SetBkColor(GetHdc(), RGB(255, 255, 255));
1193 COLORREF prevCol
= ::SetTextColor(GetHdc(), RGB(0, 0, 0));
1194 ::BitBlt(dc_buffer
, 0, 0, (int)width
, (int)height
,
1195 dc_mask
, xsrc1
, ysrc1
, SRCAND
);
1197 // set unmasked area in dest to BLACK
1198 ::SetBkColor(GetHdc(), RGB(0, 0, 0));
1199 ::SetTextColor(GetHdc(), RGB(255, 255, 255));
1200 ::BitBlt(GetHdc(), xdest1
, ydest1
, (int)width
, (int)height
,
1201 dc_mask
, xsrc1
, ysrc1
, SRCAND
);
1202 ::SetBkColor(GetHdc(), prevBkCol
); // restore colours to original values
1203 ::SetTextColor(GetHdc(), prevCol
);
1205 // OR buffer to dest
1206 success
= (::BitBlt(GetHdc(), xdest1
, ydest1
, (int)width
, (int)height
,
1207 dc_buffer
, 0, 0, SRCPAINT
) != 0);
1209 // tidy up temporary DCs and bitmap
1210 ::SelectObject(dc_mask
, 0);
1211 ::DeleteDC(dc_mask
);
1212 ::SelectObject(dc_buffer
, 0);
1213 ::DeleteDC(dc_buffer
);
1214 ::DeleteObject(buffer_bmap
);
1220 if (IsKindOf(CLASSINFO(wxPrinterDC
)))
1222 // If we are printing, source colours are screen colours
1223 // not printer colours and so we need copy the bitmap
1225 HDC dc_src
= (HDC
) source
->m_hDC
;
1227 for (int x
= 0; x
< width
; x
++)
1229 for (int y
= 0; y
< height
; y
++)
1231 HBRUSH brush
= ::CreateSolidBrush(::GetPixel(dc_src
, x
, y
));
1232 rect
.left
= xdest1
+ x
; rect
.right
= rect
.left
+ 1;
1233 rect
.top
= ydest1
+ y
; rect
.bottom
= rect
.top
+ 1;
1234 ::FillRect(GetHdc(), &rect
, brush
);
1235 ::DeleteObject(brush
);
1241 success
= (BitBlt(GetHdc(), xdest1
, ydest1
, (int)width
, (int)height
, (HDC
) source
->m_hDC
,
1242 xsrc1
, ysrc1
, dwRop
) != 0);
1245 ::SetTextColor(GetHdc(), old_textground
);
1246 ::SetBkColor(GetHdc(), old_background
);
1251 void wxDC::DoGetSize(int *w
, int *h
) const
1253 if ( w
) *w
= ::GetDeviceCaps(GetHdc(), HORZRES
);
1254 if ( h
) *h
= ::GetDeviceCaps(GetHdc(), VERTRES
);
1257 void wxDC::DoGetSizeMM(int *w
, int *h
) const
1259 if ( w
) *w
= ::GetDeviceCaps(GetHdc(), HORZSIZE
);
1260 if ( h
) *h
= ::GetDeviceCaps(GetHdc(), VERTSIZE
);
1263 wxSize
wxDC::GetPPI() const
1265 int x
= ::GetDeviceCaps(GetHdc(), LOGPIXELSX
);
1266 int y
= ::GetDeviceCaps(GetHdc(), LOGPIXELSY
);
1268 return wxSize(x
, y
);
1271 // For use by wxWindows only, unless custom units are required.
1272 void wxDC::SetLogicalScale(double x
, double y
)
1274 m_logicalScaleX
= x
;
1275 m_logicalScaleY
= y
;
1278 #if WXWIN_COMPATIBILITY
1279 void wxDC::DoGetTextExtent(const wxString
& string
, float *x
, float *y
,
1280 float *descent
, float *externalLeading
,
1281 wxFont
*theFont
, bool use16bit
) const
1283 long x1
, y1
, descent1
, externalLeading1
;
1284 GetTextExtent(string
, & x1
, & y1
, & descent1
, & externalLeading1
, theFont
, use16bit
);
1287 *descent
= descent1
;
1288 if (externalLeading
)
1289 *externalLeading
= externalLeading1
;
1293 // ---------------------------------------------------------------------------
1294 // spline drawing code
1295 // ---------------------------------------------------------------------------
1299 class wxSpline
: public wxObject
1305 wxSpline(wxList
*list
);
1306 void DeletePoints();
1308 // Doesn't delete points
1312 void wx_draw_open_spline(wxDC
*dc
, wxSpline
*spline
);
1314 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
1315 double a3
, double b3
, double a4
, double b4
);
1316 void wx_clear_stack();
1317 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
1318 double *y3
, double *x4
, double *y4
);
1319 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
1320 double x4
, double y4
);
1321 static bool wx_spline_add_point(double x
, double y
);
1322 static void wx_spline_draw_point_array(wxDC
*dc
);
1323 wxSpline
*wx_make_spline(int x1
, int y1
, int x2
, int y2
, int x3
, int y3
);
1325 void wxDC::DoDrawSpline(wxList
*list
)
1327 wxSpline
spline(list
);
1329 wx_draw_open_spline(this, &spline
);
1332 wxList wx_spline_point_list
;
1334 void wx_draw_open_spline(wxDC
*dc
, wxSpline
*spline
)
1337 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
1338 double x1
, y1
, x2
, y2
;
1340 wxNode
*node
= spline
->points
->First();
1341 p
= (wxPoint
*)node
->Data();
1346 node
= node
->Next();
1347 p
= (wxPoint
*)node
->Data();
1351 cx1
= (double)((x1
+ x2
) / 2);
1352 cy1
= (double)((y1
+ y2
) / 2);
1353 cx2
= (double)((cx1
+ x2
) / 2);
1354 cy2
= (double)((cy1
+ y2
) / 2);
1356 wx_spline_add_point(x1
, y1
);
1358 while ((node
= node
->Next()) != NULL
)
1360 p
= (wxPoint
*)node
->Data();
1365 cx4
= (double)(x1
+ x2
) / 2;
1366 cy4
= (double)(y1
+ y2
) / 2;
1367 cx3
= (double)(x1
+ cx4
) / 2;
1368 cy3
= (double)(y1
+ cy4
) / 2;
1370 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
1374 cx2
= (double)(cx1
+ x2
) / 2;
1375 cy2
= (double)(cy1
+ y2
) / 2;
1378 wx_spline_add_point((double)wx_round(cx1
), (double)wx_round(cy1
));
1379 wx_spline_add_point(x2
, y2
);
1381 wx_spline_draw_point_array(dc
);
1385 /********************* CURVES FOR SPLINES *****************************
1387 The following spline drawing routine is from
1389 "An Algorithm for High-Speed Curve Generation"
1390 by George Merrill Chaikin,
1391 Computer Graphics and Image Processing, 3, Academic Press,
1396 "On Chaikin's Algorithm" by R. F. Riesenfeld,
1397 Computer Graphics and Image Processing, 4, Academic Press,
1400 ***********************************************************************/
1402 #define half(z1, z2) ((z1+z2)/2.0)
1405 /* iterative version */
1407 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
1410 register double xmid
, ymid
;
1411 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
1414 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
1416 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
1417 xmid
= (double)half(x2
, x3
);
1418 ymid
= (double)half(y2
, y3
);
1419 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
1420 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
1421 wx_spline_add_point((double)wx_round(x1
), (double)wx_round(y1
));
1422 wx_spline_add_point((double)wx_round(xmid
), (double)wx_round(ymid
));
1424 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
1425 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
1426 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
1427 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
1433 /* utilities used by spline drawing routines */
1436 typedef struct wx_spline_stack_struct
{
1437 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
1441 #define SPLINE_STACK_DEPTH 20
1442 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
1443 static Stack
*wx_stack_top
;
1444 static int wx_stack_count
;
1446 void wx_clear_stack()
1448 wx_stack_top
= wx_spline_stack
;
1452 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
1454 wx_stack_top
->x1
= x1
;
1455 wx_stack_top
->y1
= y1
;
1456 wx_stack_top
->x2
= x2
;
1457 wx_stack_top
->y2
= y2
;
1458 wx_stack_top
->x3
= x3
;
1459 wx_stack_top
->y3
= y3
;
1460 wx_stack_top
->x4
= x4
;
1461 wx_stack_top
->y4
= y4
;
1466 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
1467 double *x3
, double *y3
, double *x4
, double *y4
)
1469 if (wx_stack_count
== 0)
1473 *x1
= wx_stack_top
->x1
;
1474 *y1
= wx_stack_top
->y1
;
1475 *x2
= wx_stack_top
->x2
;
1476 *y2
= wx_stack_top
->y2
;
1477 *x3
= wx_stack_top
->x3
;
1478 *y3
= wx_stack_top
->y3
;
1479 *x4
= wx_stack_top
->x4
;
1480 *y4
= wx_stack_top
->y4
;
1484 static bool wx_spline_add_point(double x
, double y
)
1486 wxPoint
*point
= new wxPoint
;
1489 wx_spline_point_list
.Append((wxObject
*)point
);
1493 static void wx_spline_draw_point_array(wxDC
*dc
)
1495 dc
->DrawLines(&wx_spline_point_list
, 0, 0);
1496 wxNode
*node
= wx_spline_point_list
.First();
1499 wxPoint
*point
= (wxPoint
*)node
->Data();
1502 node
= wx_spline_point_list
.First();
1506 wxSpline::wxSpline(wxList
*list
)
1511 wxSpline::~wxSpline()
1515 void wxSpline::DeletePoints()
1517 for(wxNode
*node
= points
->First(); node
; node
= points
->First())
1519 wxPoint
*point
= (wxPoint
*)node
->Data();
1527 #endif // wxUSE_SPLINES