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"
35 #include "wx/dialog.h"
37 #include "wx/bitmap.h"
38 #include "wx/dcmemory.h"
41 #include "wx/dcprint.h"
42 #include "wx/msw/private.h"
47 #if wxUSE_COMMON_DIALOGS
67 #if !USE_SHARED_LIBRARY
68 IMPLEMENT_ABSTRACT_CLASS(wxDC
, wxObject
)
71 // ---------------------------------------------------------------------------
73 // ---------------------------------------------------------------------------
75 #define VIEWPORT_EXTENT 1000
77 // ---------------------------------------------------------------------------
79 // ---------------------------------------------------------------------------
81 #define YSCALE(y) (yorigin - (y))
83 // ===========================================================================
85 // ===========================================================================
87 // ---------------------------------------------------------------------------
89 // ---------------------------------------------------------------------------
91 // Default constructor
105 m_windowExtX
= VIEWPORT_EXTENT
;
106 m_windowExtY
= VIEWPORT_EXTENT
;
115 SelectOldObjects(m_hDC
);
117 if ( m_canvas
== NULL
)
118 ::DeleteDC(GetHdc());
120 ::ReleaseDC((HWND
)m_canvas
->GetHWND(), GetHdc());
126 // This will select current objects out of the DC,
127 // which is what you have to do before deleting the
129 void wxDC::SelectOldObjects(WXHDC dc
)
135 ::SelectObject((HDC
) dc
, (HBITMAP
) m_oldBitmap
);
136 if (m_selectedBitmap
.Ok())
138 m_selectedBitmap
.SetSelectedInto(NULL
);
144 ::SelectObject((HDC
) dc
, (HPEN
) m_oldPen
);
149 ::SelectObject((HDC
) dc
, (HBRUSH
) m_oldBrush
);
154 ::SelectObject((HDC
) dc
, (HFONT
) m_oldFont
);
159 ::SelectPalette((HDC
) dc
, (HPALETTE
) m_oldPalette
, TRUE
);
164 m_brush
= wxNullBrush
;
166 m_palette
= wxNullPalette
;
168 m_backgroundBrush
= wxNullBrush
;
169 m_selectedBitmap
= wxNullBitmap
;
172 // ---------------------------------------------------------------------------
174 // ---------------------------------------------------------------------------
176 void wxDC::DoSetClippingRegion(long cx
, long cy
, long cw
, long ch
)
181 m_clipX2
= (int)(cx
+ cw
);
182 m_clipY2
= (int)(cy
+ ch
);
184 DoClipping((WXHDC
) m_hDC
);
187 void wxDC::DoSetClippingRegionAsRegion(const wxRegion
& region
)
189 wxCHECK_RET( region
.GetHRGN(), _T("invalid clipping region") );
191 wxRect box
= region
.GetBox();
196 m_clipX2
= box
.x
+ box
.width
;
197 m_clipY2
= box
.y
+ box
.height
;
200 SelectClipRgn(GetHdc(), (HRGN
) region
.GetHRGN());
202 ExtSelectClipRgn(GetHdc(), (HRGN
) region
.GetHRGN(), RGN_AND
);
206 void wxDC::DoClipping(WXHDC dc
)
208 if (m_clipping
&& dc
)
210 IntersectClipRect((HDC
) dc
, XLOG2DEV(m_clipX1
), YLOG2DEV(m_clipY1
),
211 XLOG2DEV(m_clipX2
), YLOG2DEV(m_clipY2
));
215 void wxDC::DestroyClippingRegion()
217 if (m_clipping
&& m_hDC
)
219 // TODO: this should restore the previous clipping region,
220 // so that OnPaint processing works correctly, and the update clipping region
221 // doesn't get destroyed after the first DestroyClippingRegion.
222 HRGN rgn
= CreateRectRgn(0, 0, 32000, 32000);
223 SelectClipRgn(GetHdc(), rgn
);
229 // ---------------------------------------------------------------------------
230 // query capabilities
231 // ---------------------------------------------------------------------------
233 bool wxDC::CanDrawBitmap() const
238 bool wxDC::CanGetTextExtent() const
240 // What sort of display is it?
241 int technology
= ::GetDeviceCaps(GetHdc(), TECHNOLOGY
);
243 return (technology
== DT_RASDISPLAY
) || (technology
== DT_RASPRINTER
);
246 int wxDC::GetDepth() const
248 return (int)::GetDeviceCaps(GetHdc(), BITSPIXEL
);
251 // ---------------------------------------------------------------------------
253 // ---------------------------------------------------------------------------
259 GetClientRect((HWND
) m_canvas
->GetHWND(), &rect
);
260 else if (m_selectedBitmap
.Ok())
262 rect
.left
= 0; rect
.top
= 0;
263 rect
.right
= m_selectedBitmap
.GetWidth();
264 rect
.bottom
= m_selectedBitmap
.GetHeight();
266 (void) ::SetMapMode(GetHdc(), MM_TEXT
);
268 DWORD colour
= GetBkColor(GetHdc());
269 HBRUSH brush
= CreateSolidBrush(colour
);
270 FillRect(GetHdc(), &rect
, brush
);
273 ::SetMapMode(GetHdc(), MM_ANISOTROPIC
);
274 ::SetViewportExtEx(GetHdc(), VIEWPORT_EXTENT
, VIEWPORT_EXTENT
, NULL
);
275 ::SetWindowExtEx(GetHdc(), m_windowExtX
, m_windowExtY
, NULL
);
276 ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX
, (int)m_deviceOriginY
, NULL
);
277 ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX
, (int)m_logicalOriginY
, NULL
);
280 void wxDC::DoFloodFill(long x
, long y
, const wxColour
& col
, int style
)
282 (void)ExtFloodFill(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
),
284 style
== wxFLOOD_SURFACE
? FLOODFILLSURFACE
287 CalcBoundingBox(x
, y
);
290 bool wxDC::DoGetPixel(long x
, long y
, wxColour
*col
) const
292 // added by steve 29.12.94 (copied from DrawPoint)
293 // returns TRUE for pixels in the color of the current pen
294 // and FALSE for all other pixels colors
295 // if col is non-NULL return the color of the pixel
297 // get the color of the pixel
298 COLORREF pixelcolor
= ::GetPixel(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
));
299 // get the color of the pen
300 COLORREF pencolor
= 0x00ffffff;
303 pencolor
= m_pen
.GetColour().GetPixel();
306 // return the color of the pixel
308 col
->Set(GetRValue(pixelcolor
),GetGValue(pixelcolor
),GetBValue(pixelcolor
));
310 // check, if color of the pixels is the same as the color
311 // of the current pen
312 return(pixelcolor
==pencolor
);
315 void wxDC::DoCrossHair(long x
, long y
)
317 long x1
= x
-VIEWPORT_EXTENT
;
318 long y1
= y
-VIEWPORT_EXTENT
;
319 long x2
= x
+VIEWPORT_EXTENT
;
320 long y2
= y
+VIEWPORT_EXTENT
;
322 (void)MoveToEx(GetHdc(), XLOG2DEV(x1
), YLOG2DEV(y
), NULL
);
323 (void)LineTo(GetHdc(), XLOG2DEV(x2
), YLOG2DEV(y
));
325 (void)MoveToEx(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y1
), NULL
);
326 (void)LineTo(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y2
));
328 CalcBoundingBox(x1
, y1
);
329 CalcBoundingBox(x2
, y2
);
332 void wxDC::DoDrawLine(long x1
, long y1
, long x2
, long y2
)
334 (void)MoveToEx(GetHdc(), XLOG2DEV(x1
), YLOG2DEV(y1
), NULL
);
335 (void)LineTo(GetHdc(), XLOG2DEV(x2
), YLOG2DEV(y2
));
337 /* MATTHEW: [6] New normalization */
338 #if WX_STANDARD_GRAPHICS
339 (void)LineTo(GetHdc(), XLOG2DEV(x2
) + 1, YLOG2DEV(y2
));
342 CalcBoundingBox(x1
, y1
);
343 CalcBoundingBox(x2
, y2
);
346 void wxDC::DoDrawArc(long x1
,long y1
,long x2
,long y2
, long xc
, long yc
)
350 double radius
= (double)sqrt(dx
*dx
+dy
*dy
) ;;
351 if (x1
==x2
&& x2
==y2
)
353 DrawEllipse(xc
,yc
,(long)(radius
*2.0),(long)(radius
*2.0));
357 long xx1
= XLOG2DEV(x1
);
358 long yy1
= YLOG2DEV(y1
);
359 long xx2
= XLOG2DEV(x2
);
360 long yy2
= YLOG2DEV(y2
);
361 long xxc
= XLOG2DEV(xc
);
362 long yyc
= YLOG2DEV(yc
);
363 long ray
= (long) sqrt(double((xxc
-xx1
)*(xxc
-xx1
)+(yyc
-yy1
)*(yyc
-yy1
)));
365 (void)MoveToEx(GetHdc(), (int) xx1
, (int) yy1
, NULL
);
366 long xxx1
= (long) (xxc
-ray
);
367 long yyy1
= (long) (yyc
-ray
);
368 long xxx2
= (long) (xxc
+ray
);
369 long yyy2
= (long) (yyc
+ray
);
370 if (m_brush
.Ok() && m_brush
.GetStyle() !=wxTRANSPARENT
)
372 // Have to add 1 to bottom-right corner of rectangle
373 // to make semi-circles look right (crooked line otherwise).
374 // Unfortunately this is not a reliable method, depends
375 // on the size of shape.
376 // TODO: figure out why this happens!
377 Pie(GetHdc(),xxx1
,yyy1
,xxx2
+1,yyy2
+1,
381 Arc(GetHdc(),xxx1
,yyy1
,xxx2
,yyy2
,
384 CalcBoundingBox((xc
-radius
), (yc
-radius
));
385 CalcBoundingBox((xc
+radius
), (yc
+radius
));
388 void wxDC::DoDrawPoint(long x
, long y
)
390 COLORREF color
= 0x00ffffff;
393 color
= m_pen
.GetColour().GetPixel();
396 SetPixel(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), color
);
398 CalcBoundingBox(x
, y
);
401 void wxDC::DoDrawPolygon(int n
, wxPoint points
[], long xoffset
, long yoffset
,int fillStyle
)
403 // Do things less efficiently if we have offsets
404 if (xoffset
!= 0 || yoffset
!= 0)
406 POINT
*cpoints
= new POINT
[n
];
408 for (i
= 0; i
< n
; i
++)
410 cpoints
[i
].x
= (int)(points
[i
].x
+ xoffset
);
411 cpoints
[i
].y
= (int)(points
[i
].y
+ yoffset
);
413 CalcBoundingBox(cpoints
[i
].x
, cpoints
[i
].y
);
415 int prev
= SetPolyFillMode(GetHdc(),fillStyle
==wxODDEVEN_RULE
?ALTERNATE
:WINDING
);
416 (void)Polygon(GetHdc(), cpoints
, n
);
417 SetPolyFillMode(GetHdc(),prev
);
423 for (i
= 0; i
< n
; i
++)
424 CalcBoundingBox(points
[i
].x
, points
[i
].y
);
426 int prev
= SetPolyFillMode(GetHdc(),fillStyle
==wxODDEVEN_RULE
?ALTERNATE
:WINDING
);
427 (void)Polygon(GetHdc(), (POINT
*) points
, n
);
428 SetPolyFillMode(GetHdc(),prev
);
432 void wxDC::DoDrawLines(int n
, wxPoint points
[], long xoffset
, long yoffset
)
434 // Do things less efficiently if we have offsets
435 if (xoffset
!= 0 || yoffset
!= 0)
437 POINT
*cpoints
= new POINT
[n
];
439 for (i
= 0; i
< n
; i
++)
441 cpoints
[i
].x
= (int)(points
[i
].x
+ xoffset
);
442 cpoints
[i
].y
= (int)(points
[i
].y
+ yoffset
);
444 CalcBoundingBox(cpoints
[i
].x
, cpoints
[i
].y
);
446 (void)Polyline(GetHdc(), cpoints
, n
);
452 for (i
= 0; i
< n
; i
++)
453 CalcBoundingBox(points
[i
].x
, points
[i
].y
);
455 (void)Polyline(GetHdc(), (POINT
*) points
, n
);
459 void wxDC::DoDrawRectangle(long x
, long y
, long width
, long height
)
462 long y2
= y
+ height
;
464 /* MATTHEW: [6] new normalization */
465 #if WX_STANDARD_GRAPHICS
466 bool do_brush
, do_pen
;
468 do_brush
= m_brush
.Ok() && m_brush
.GetStyle() != wxTRANSPARENT
;
469 do_pen
= m_pen
.Ok() && m_pen
.GetStyle() != wxTRANSPARENT
;
472 HPEN orig_pen
= NULL
;
474 if (do_pen
|| !m_pen
.Ok())
475 orig_pen
= (HPEN
) ::SelectObject(GetHdc(), (HPEN
) ::GetStockObject(NULL_PEN
));
477 (void)Rectangle(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
),
478 XLOG2DEV(x2
) + 1, YLOG2DEV(y2
) + 1);
480 if (do_pen
|| !m_pen
.Ok())
481 ::SelectObject(GetHdc() , orig_pen
);
484 HBRUSH orig_brush
= NULL
;
486 if (do_brush
|| !m_brush
.Ok())
487 orig_brush
= (HBRUSH
) ::SelectObject(GetHdc(), (HBRUSH
) ::GetStockObject(NULL_BRUSH
));
489 (void)Rectangle(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
),
490 XLOG2DEV(x2
), YLOG2DEV(y2
));
492 if (do_brush
|| !m_brush
.Ok())
493 ::SelectObject(GetHdc(), orig_brush
);
496 (void)Rectangle(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
), YLOG2DEV(y2
));
499 CalcBoundingBox(x
, y
);
500 CalcBoundingBox(x2
, y2
);
503 void wxDC::DoDrawRoundedRectangle(long x
, long y
, long width
, long height
, double radius
)
505 // Now, a negative radius value is interpreted to mean
506 // 'the proportion of the smallest X or Y dimension'
510 double smallest
= 0.0;
515 radius
= (- radius
* smallest
);
519 long y2
= (y
+height
);
521 (void)RoundRect(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
),
522 YLOG2DEV(y2
), 2*XLOG2DEV(radius
), 2*YLOG2DEV(radius
));
524 CalcBoundingBox(x
, y
);
525 CalcBoundingBox(x2
, y2
);
528 void wxDC::DoDrawEllipse(long x
, long y
, long width
, long height
)
531 long y2
= (y
+height
);
533 (void)Ellipse(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
), YLOG2DEV(y2
));
535 CalcBoundingBox(x
, y
);
536 CalcBoundingBox(x2
, y2
);
539 // Chris Breeze 20/5/98: first implementation of DrawEllipticArc on Windows
540 void wxDC::DoDrawEllipticArc(long x
,long y
,long w
,long h
,double sa
,double ea
)
545 const double deg2rad
= 3.14159265359 / 180.0;
546 int rx1
= XLOG2DEV(x
+w
/2);
547 int ry1
= YLOG2DEV(y
+h
/2);
550 rx1
+= (int)(100.0 * abs(w
) * cos(sa
* deg2rad
));
551 ry1
-= (int)(100.0 * abs(h
) * m_signY
* sin(sa
* deg2rad
));
552 rx2
+= (int)(100.0 * abs(w
) * cos(ea
* deg2rad
));
553 ry2
-= (int)(100.0 * abs(h
) * m_signY
* sin(ea
* deg2rad
));
555 // draw pie with NULL_PEN first and then outline otherwise a line is
556 // drawn from the start and end points to the centre
557 HPEN orig_pen
= (HPEN
) ::SelectObject(GetHdc(), (HPEN
) ::GetStockObject(NULL_PEN
));
560 (void)Pie(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
)+1, YLOG2DEV(y2
)+1,
565 (void)Pie(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
)-1, XLOG2DEV(x2
)+1, YLOG2DEV(y2
),
566 rx1
, ry1
-1, rx2
, ry2
-1);
568 ::SelectObject(GetHdc(), orig_pen
);
569 (void)Arc(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
), YLOG2DEV(y2
),
572 CalcBoundingBox(x
, y
);
573 CalcBoundingBox(x2
, y2
);
576 void wxDC::DoDrawIcon(const wxIcon
& icon
, long x
, long y
)
578 #if defined(__WIN32__) && !defined(__SC__) && !defined(__TWIN32__)
579 ::DrawIconEx(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), (HICON
) icon
.GetHICON(),
580 icon
.GetWidth(), icon
.GetHeight(), 0, 0, DI_NORMAL
);
582 ::DrawIcon(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), (HICON
) icon
.GetHICON());
585 CalcBoundingBox(x
, y
);
586 CalcBoundingBox(x
+icon
.GetWidth(), y
+icon
.GetHeight());
589 void wxDC::DoDrawBitmap( const wxBitmap
&bmp
, long x
, long y
, bool useMask
)
594 // If we're not drawing transparently, and not drawing to a printer,
595 // optimize this function to use Windows functions.
596 if (!useMask
&& !IsKindOf(CLASSINFO(wxPrinterDC
)))
599 HDC memdc
= ::CreateCompatibleDC( cdc
);
600 HBITMAP hbitmap
= (HBITMAP
) bmp
.GetHBITMAP( );
601 ::SelectObject( memdc
, hbitmap
);
602 ::BitBlt( cdc
, x
, y
, bmp
.GetWidth(), bmp
.GetHeight(), memdc
, 0, 0, SRCCOPY
);
603 ::SelectObject( memdc
, 0 );
608 // Rather than reproduce wxDC::Blit, let's do it at the wxWin API level
610 memDC
.SelectObject(bmp
);
612 /* Not sure if we need this. The mask should leave the
613 * masked areas as per the original background of this DC.
616 // There might be transparent areas, so make these
617 // the same colour as this DC
618 memDC.SetBackground(* GetBackground());
622 Blit(x
, y
, bmp
.GetWidth(), bmp
.GetHeight(), & memDC
, 0, 0, wxCOPY
, useMask
);
624 memDC
.SelectObject(wxNullBitmap
);
628 void wxDC::DoDrawText(const wxString
& text
, long x
, long y
)
630 if (m_textForegroundColour
.Ok())
631 SetTextColor(GetHdc(), m_textForegroundColour
.GetPixel() );
633 DWORD old_background
= 0;
634 if (m_textBackgroundColour
.Ok())
636 old_background
= SetBkColor(GetHdc(), m_textBackgroundColour
.GetPixel() );
639 if (m_backgroundMode
== wxTRANSPARENT
)
640 SetBkMode(GetHdc(), TRANSPARENT
);
642 SetBkMode(GetHdc(), OPAQUE
);
644 (void)TextOut(GetHdc(), XLOG2DEV(x
), YLOG2DEV(y
), (char *) (const char *)text
, strlen((const char *)text
));
646 if (m_textBackgroundColour
.Ok())
647 (void)SetBkColor(GetHdc(), old_background
);
649 CalcBoundingBox(x
, y
);
652 GetTextExtent(text
, &w
, &h
);
653 CalcBoundingBox((x
+ w
), (y
+ h
));
656 // ---------------------------------------------------------------------------
658 // ---------------------------------------------------------------------------
660 void wxDC::SetPalette(const wxPalette
& palette
)
662 // Set the old object temporarily, in case the assignment deletes an object
663 // that's not yet selected out.
666 ::SelectPalette(GetHdc(), (HPALETTE
) m_oldPalette
, TRUE
);
674 // Setting a NULL colourmap is a way of restoring
675 // the original colourmap
678 ::SelectPalette(GetHdc(), (HPALETTE
) m_oldPalette
, TRUE
);
685 if (m_palette
.Ok() && m_palette
.GetHPALETTE())
687 HPALETTE oldPal
= ::SelectPalette(GetHdc(), (HPALETTE
) m_palette
.GetHPALETTE(), TRUE
);
689 m_oldPalette
= (WXHPALETTE
) oldPal
;
691 ::RealizePalette(GetHdc());
695 void wxDC::SetFont(const wxFont
& the_font
)
697 // Set the old object temporarily, in case the assignment deletes an object
698 // that's not yet selected out.
701 ::SelectObject(GetHdc(), (HFONT
) m_oldFont
);
710 ::SelectObject(GetHdc(), (HFONT
) m_oldFont
);
714 if (m_font
.Ok() && m_font
.GetResourceHandle())
716 HFONT f
= (HFONT
) ::SelectObject(GetHdc(), (HFONT
) m_font
.GetResourceHandle());
717 if (f
== (HFONT
) NULL
)
719 wxLogDebug("::SelectObject failed in wxDC::SetFont.");
722 m_oldFont
= (WXHFONT
) f
;
726 void wxDC::SetPen(const wxPen
& pen
)
728 // Set the old object temporarily, in case the assignment deletes an object
729 // that's not yet selected out.
732 ::SelectObject(GetHdc(), (HPEN
) m_oldPen
);
741 ::SelectObject(GetHdc(), (HPEN
) m_oldPen
);
747 if (m_pen
.GetResourceHandle())
749 HPEN p
= (HPEN
) ::SelectObject(GetHdc(), (HPEN
)m_pen
.GetResourceHandle());
751 m_oldPen
= (WXHPEN
) p
;
756 void wxDC::SetBrush(const wxBrush
& brush
)
758 // Set the old object temporarily, in case the assignment deletes an object
759 // that's not yet selected out.
762 ::SelectObject(GetHdc(), (HBRUSH
) m_oldBrush
);
771 ::SelectObject(GetHdc(), (HBRUSH
) m_oldBrush
);
777 if (m_brush
.GetResourceHandle())
780 b
= (HBRUSH
) ::SelectObject(GetHdc(), (HBRUSH
)m_brush
.GetResourceHandle());
782 m_oldBrush
= (WXHBRUSH
) b
;
787 void wxDC::SetBackground(const wxBrush
& brush
)
789 m_backgroundBrush
= brush
;
791 if (!m_backgroundBrush
.Ok())
796 bool customColours
= TRUE
;
797 // If we haven't specified wxUSER_COLOURS, don't allow the panel/dialog box to
798 // change background colours from the control-panel specified colours.
799 if (m_canvas
->IsKindOf(CLASSINFO(wxWindow
)) && ((m_canvas
->GetWindowStyleFlag() & wxUSER_COLOURS
) != wxUSER_COLOURS
))
800 customColours
= FALSE
;
804 if (m_backgroundBrush
.GetStyle()==wxTRANSPARENT
)
806 m_canvas
->SetTransparent(TRUE
);
810 // New behaviour, 10/2/99: setting the background brush of a DC
811 // doesn't affect the window background colour. However,
812 // I'm leaving in the transparency setting because it's needed by
813 // various controls (e.g. wxStaticText) to determine whether to draw
814 // transparently or not. TODO: maybe this should be a new function
815 // wxWindow::SetTransparency(). Should that apply to the child itself, or the
817 // m_canvas->SetBackgroundColour(m_backgroundBrush.GetColour());
818 m_canvas
->SetTransparent(FALSE
);
822 COLORREF new_color
= m_backgroundBrush
.GetColour().GetPixel();
824 (void)SetBkColor(GetHdc(), new_color
);
828 void wxDC::SetBackgroundMode(int mode
)
830 m_backgroundMode
= mode
;
832 if (m_backgroundMode
== wxTRANSPARENT
)
833 ::SetBkMode(GetHdc(), TRANSPARENT
);
835 ::SetBkMode(GetHdc(), OPAQUE
);
838 void wxDC::SetLogicalFunction(int function
)
840 m_logicalFunction
= function
;
842 SetRop((WXHDC
) m_hDC
);
845 void wxDC::SetRop(WXHDC dc
)
847 if (!dc
|| m_logicalFunction
< 0)
851 // These may be wrong
852 switch (m_logicalFunction
)
854 // case wxXOR: c_rop = R2_XORPEN; break;
855 case wxXOR
: c_rop
= R2_NOTXORPEN
; break;
856 case wxINVERT
: c_rop
= R2_NOT
; break;
857 case wxOR_REVERSE
: c_rop
= R2_MERGEPENNOT
; break;
858 case wxAND_REVERSE
: c_rop
= R2_MASKPENNOT
; break;
859 case wxCLEAR
: c_rop
= R2_WHITE
; break;
860 case wxSET
: c_rop
= R2_BLACK
; break;
861 case wxSRC_INVERT
: c_rop
= R2_NOTCOPYPEN
; break;
862 case wxOR_INVERT
: c_rop
= R2_MERGENOTPEN
; break;
863 case wxAND
: c_rop
= R2_MASKPEN
; break;
864 case wxOR
: c_rop
= R2_MERGEPEN
; break;
865 case wxAND_INVERT
: c_rop
= R2_MASKNOTPEN
; break;
870 c_rop
= R2_COPYPEN
; break;
872 SetROP2((HDC
) dc
, c_rop
);
875 bool wxDC::StartDoc(const wxString
& message
)
877 // We might be previewing, so return TRUE to let it continue.
885 void wxDC::StartPage()
893 // ---------------------------------------------------------------------------
895 // ---------------------------------------------------------------------------
897 long wxDC::GetCharHeight() const
899 TEXTMETRIC lpTextMetric
;
901 GetTextMetrics(GetHdc(), &lpTextMetric
);
903 return YDEV2LOGREL(lpTextMetric
.tmHeight
);
906 long wxDC::GetCharWidth() const
908 TEXTMETRIC lpTextMetric
;
910 GetTextMetrics(GetHdc(), &lpTextMetric
);
912 return XDEV2LOGREL(lpTextMetric
.tmAveCharWidth
);
915 void wxDC::GetTextExtent(const wxString
& string
, long *x
, long *y
,
916 long *descent
, long *externalLeading
,
917 wxFont
*theFont
) const
919 wxFont
*fontToUse
= (wxFont
*) theFont
;
921 fontToUse
= (wxFont
*) &m_font
;
926 GetTextExtentPoint(GetHdc(), (char *)(const char *) string
, strlen((char *)(const char *) string
), &sizeRect
);
927 GetTextMetrics(GetHdc(), &tm
);
929 if (x
) *x
= XDEV2LOGREL(sizeRect
.cx
);
930 if (y
) *y
= YDEV2LOGREL(sizeRect
.cy
);
931 if (descent
) *descent
= tm
.tmDescent
;
932 if (externalLeading
) *externalLeading
= tm
.tmExternalLeading
;
935 void wxDC::SetMapMode(int mode
)
937 m_mappingMode
= mode
;
940 int pixel_height
= 0;
944 pixel_width
= GetDeviceCaps(GetHdc(), HORZRES
);
945 pixel_height
= GetDeviceCaps(GetHdc(), VERTRES
);
946 mm_width
= GetDeviceCaps(GetHdc(), HORZSIZE
);
947 mm_height
= GetDeviceCaps(GetHdc(), VERTSIZE
);
949 if ((pixel_width
== 0) || (pixel_height
== 0) || (mm_width
== 0) || (mm_height
== 0))
954 double mm2pixelsX
= pixel_width
/mm_width
;
955 double mm2pixelsY
= pixel_height
/mm_height
;
961 m_logicalScaleX
= (twips2mm
* mm2pixelsX
);
962 m_logicalScaleY
= (twips2mm
* mm2pixelsY
);
967 m_logicalScaleX
= (pt2mm
* mm2pixelsX
);
968 m_logicalScaleY
= (pt2mm
* mm2pixelsY
);
973 m_logicalScaleX
= mm2pixelsX
;
974 m_logicalScaleY
= mm2pixelsY
;
979 m_logicalScaleX
= (mm2pixelsX
/10.0);
980 m_logicalScaleY
= (mm2pixelsY
/10.0);
986 m_logicalScaleX
= 1.0;
987 m_logicalScaleY
= 1.0;
992 if (::GetMapMode(GetHdc()) != MM_ANISOTROPIC
)
993 ::SetMapMode(GetHdc(), MM_ANISOTROPIC
);
995 SetViewportExtEx(GetHdc(), VIEWPORT_EXTENT
, VIEWPORT_EXTENT
, NULL
);
996 m_windowExtX
= (int)MS_XDEV2LOGREL(VIEWPORT_EXTENT
);
997 m_windowExtY
= (int)MS_YDEV2LOGREL(VIEWPORT_EXTENT
);
998 ::SetWindowExtEx(GetHdc(), m_windowExtX
, m_windowExtY
, NULL
);
999 ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX
, (int)m_deviceOriginY
, NULL
);
1000 ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX
, (int)m_logicalOriginY
, NULL
);
1003 void wxDC::SetUserScale(double x
, double y
)
1008 SetMapMode(m_mappingMode
);
1011 void wxDC::SetAxisOrientation(bool xLeftRight
, bool yBottomUp
)
1013 m_signX
= xLeftRight
? 1 : -1;
1014 m_signY
= yBottomUp
? -1 : 1;
1016 SetMapMode(m_mappingMode
);
1019 void wxDC::SetSystemScale(double x
, double y
)
1024 SetMapMode(m_mappingMode
);
1027 void wxDC::SetLogicalOrigin(long x
, long y
)
1029 m_logicalOriginX
= x
;
1030 m_logicalOriginY
= y
;
1032 ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX
, (int)m_logicalOriginY
, NULL
);
1035 void wxDC::SetDeviceOrigin(long x
, long y
)
1037 m_deviceOriginX
= x
;
1038 m_deviceOriginY
= y
;
1040 ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX
, (int)m_deviceOriginY
, NULL
);
1043 // ---------------------------------------------------------------------------
1044 // coordinates transformations
1045 // ---------------------------------------------------------------------------
1047 long wxDCBase::DeviceToLogicalX(long x
) const
1049 return (long) (((x
) - m_deviceOriginX
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
) - m_logicalOriginX
);
1052 long wxDCBase::DeviceToLogicalXRel(long x
) const
1054 return (long) ((x
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
));
1057 long wxDCBase::DeviceToLogicalY(long y
) const
1059 return (long) (((y
) - m_deviceOriginY
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
) - m_logicalOriginY
);
1062 long wxDCBase::DeviceToLogicalYRel(long y
) const
1064 return (long) ((y
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
));
1067 long wxDCBase::LogicalToDeviceX(long x
) const
1069 return (long) (floor((x
) - m_logicalOriginX
)*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
+ m_deviceOriginX
);
1072 long wxDCBase::LogicalToDeviceXRel(long x
) const
1074 return (long) (floor(x
)*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
);
1077 long wxDCBase::LogicalToDeviceY(long y
) const
1079 return (long) (floor((y
) - m_logicalOriginY
)*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
+ m_deviceOriginY
);
1082 long wxDCBase::LogicalToDeviceYRel(long y
) const
1084 return (long) (floor(y
)*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
);
1087 // ---------------------------------------------------------------------------
1089 // ---------------------------------------------------------------------------
1090 bool wxDC::DoBlit(long xdest
, long ydest
, long width
, long height
,
1091 wxDC
*source
, long xsrc
, long ysrc
, int rop
, bool useMask
)
1093 long xdest1
= xdest
;
1094 long ydest1
= ydest
;
1098 // Chris Breeze 18/5/98: use text foreground/background colours
1099 // when blitting from 1-bit bitmaps
1100 COLORREF old_textground
= ::GetTextColor(GetHdc());
1101 COLORREF old_background
= ::GetBkColor(GetHdc());
1102 if (m_textForegroundColour
.Ok())
1104 ::SetTextColor(GetHdc(), m_textForegroundColour
.GetPixel() );
1106 if (m_textBackgroundColour
.Ok())
1108 ::SetBkColor(GetHdc(), m_textBackgroundColour
.GetPixel() );
1111 DWORD dwRop
= rop
== wxCOPY
? SRCCOPY
:
1112 rop
== wxCLEAR
? WHITENESS
:
1113 rop
== wxSET
? BLACKNESS
:
1114 rop
== wxINVERT
? DSTINVERT
:
1115 rop
== wxAND
? MERGECOPY
:
1116 rop
== wxOR
? MERGEPAINT
:
1117 rop
== wxSRC_INVERT
? NOTSRCCOPY
:
1118 rop
== wxXOR
? SRCINVERT
:
1119 rop
== wxOR_REVERSE
? MERGEPAINT
:
1120 rop
== wxAND_REVERSE
? SRCERASE
:
1121 rop
== wxSRC_OR
? SRCPAINT
:
1122 rop
== wxSRC_AND
? SRCAND
:
1125 bool success
= TRUE
;
1126 if (useMask
&& source
->m_selectedBitmap
.Ok() && source
->m_selectedBitmap
.GetMask())
1130 // Not implemented under Win95 (or maybe a specific device?)
1131 if (MaskBlt(GetHdc(), xdest1
, ydest1
, (int)width
, (int)height
,
1132 (HDC
) source
->m_hDC
, xsrc1
, ysrc1
, (HBITMAP
) source
->m_selectedBitmap
.GetMask()->GetMaskBitmap(),
1142 HDC dc_mask
= CreateCompatibleDC((HDC
) source
->m_hDC
);
1143 ::SelectObject(dc_mask
, (HBITMAP
) source
->m_selectedBitmap
.GetMask()->GetMaskBitmap());
1144 success
= (BitBlt(GetHdc(), xdest1
, ydest1
, (int)width
, (int)height
,
1145 dc_mask
, xsrc1
, ysrc1
, 0x00220326 /* NOTSRCAND */) != 0);
1146 success
= (BitBlt(GetHdc(), xdest1
, ydest1
, (int)width
, (int)height
,
1147 (HDC
) source
->m_hDC
, xsrc1
, ysrc1
, SRCPAINT
) != 0);
1148 ::SelectObject(dc_mask
, 0);
1149 ::DeleteDC(dc_mask
);
1151 // New code from Chris Breeze, 15/7/98
1152 // Blit bitmap with mask
1154 if (IsKindOf(CLASSINFO(wxPrinterDC
)))
1156 // If we are printing source colours are screen colours
1157 // not printer colours and so we need copy the bitmap
1160 HDC dc_mask
= ::CreateCompatibleDC((HDC
) source
->m_hDC
);
1161 HDC dc_src
= (HDC
) source
->m_hDC
;
1163 ::SelectObject(dc_mask
, (HBITMAP
) source
->m_selectedBitmap
.GetMask()->GetMaskBitmap());
1164 for (int x
= 0; x
< width
; x
++)
1166 for (int y
= 0; y
< height
; y
++)
1168 COLORREF cref
= ::GetPixel(dc_mask
, x
, y
);
1171 HBRUSH brush
= ::CreateSolidBrush(::GetPixel(dc_src
, x
, y
));
1172 rect
.left
= xdest1
+ x
; rect
.right
= rect
.left
+ 1;
1173 rect
.top
= ydest1
+ y
; rect
.bottom
= rect
.top
+ 1;
1174 ::FillRect(GetHdc(), &rect
, brush
);
1175 ::DeleteObject(brush
);
1179 ::SelectObject(dc_mask
, 0);
1180 ::DeleteDC(dc_mask
);
1184 // create a temp buffer bitmap and DCs to access it and the mask
1185 HDC dc_mask
= ::CreateCompatibleDC((HDC
) source
->m_hDC
);
1186 HDC dc_buffer
= ::CreateCompatibleDC(GetHdc());
1187 HBITMAP buffer_bmap
= ::CreateCompatibleBitmap(GetHdc(), width
, height
);
1188 ::SelectObject(dc_mask
, (HBITMAP
) source
->m_selectedBitmap
.GetMask()->GetMaskBitmap());
1189 ::SelectObject(dc_buffer
, buffer_bmap
);
1191 // copy dest to buffer
1192 ::BitBlt(dc_buffer
, 0, 0, (int)width
, (int)height
,
1193 GetHdc(), xdest1
, ydest1
, SRCCOPY
);
1195 // copy src to buffer using selected raster op
1196 ::BitBlt(dc_buffer
, 0, 0, (int)width
, (int)height
,
1197 (HDC
) source
->m_hDC
, xsrc1
, ysrc1
, dwRop
);
1199 // set masked area in buffer to BLACK (pixel value 0)
1200 COLORREF prevBkCol
= ::SetBkColor(GetHdc(), RGB(255, 255, 255));
1201 COLORREF prevCol
= ::SetTextColor(GetHdc(), RGB(0, 0, 0));
1202 ::BitBlt(dc_buffer
, 0, 0, (int)width
, (int)height
,
1203 dc_mask
, xsrc1
, ysrc1
, SRCAND
);
1205 // set unmasked area in dest to BLACK
1206 ::SetBkColor(GetHdc(), RGB(0, 0, 0));
1207 ::SetTextColor(GetHdc(), RGB(255, 255, 255));
1208 ::BitBlt(GetHdc(), xdest1
, ydest1
, (int)width
, (int)height
,
1209 dc_mask
, xsrc1
, ysrc1
, SRCAND
);
1210 ::SetBkColor(GetHdc(), prevBkCol
); // restore colours to original values
1211 ::SetTextColor(GetHdc(), prevCol
);
1213 // OR buffer to dest
1214 success
= (::BitBlt(GetHdc(), xdest1
, ydest1
, (int)width
, (int)height
,
1215 dc_buffer
, 0, 0, SRCPAINT
) != 0);
1217 // tidy up temporary DCs and bitmap
1218 ::SelectObject(dc_mask
, 0);
1219 ::DeleteDC(dc_mask
);
1220 ::SelectObject(dc_buffer
, 0);
1221 ::DeleteDC(dc_buffer
);
1222 ::DeleteObject(buffer_bmap
);
1228 if (IsKindOf(CLASSINFO(wxPrinterDC
)))
1230 // If we are printing, source colours are screen colours
1231 // not printer colours and so we need copy the bitmap
1233 HDC dc_src
= (HDC
) source
->m_hDC
;
1235 for (int x
= 0; x
< width
; x
++)
1237 for (int y
= 0; y
< height
; y
++)
1239 HBRUSH brush
= ::CreateSolidBrush(::GetPixel(dc_src
, x
, y
));
1240 rect
.left
= xdest1
+ x
; rect
.right
= rect
.left
+ 1;
1241 rect
.top
= ydest1
+ y
; rect
.bottom
= rect
.top
+ 1;
1242 ::FillRect(GetHdc(), &rect
, brush
);
1243 ::DeleteObject(brush
);
1249 success
= (BitBlt(GetHdc(), xdest1
, ydest1
, (int)width
, (int)height
, (HDC
) source
->m_hDC
,
1250 xsrc1
, ysrc1
, dwRop
) != 0);
1253 ::SetTextColor(GetHdc(), old_textground
);
1254 ::SetBkColor(GetHdc(), old_background
);
1259 void wxDC::DoGetSize(int *w
, int *h
) const
1261 if ( w
) *w
= ::GetDeviceCaps(GetHdc(), HORZRES
);
1262 if ( h
) *h
= ::GetDeviceCaps(GetHdc(), VERTRES
);
1265 void wxDC::DoGetSizeMM(int *w
, int *h
) const
1267 if ( w
) *w
= ::GetDeviceCaps(GetHdc(), HORZSIZE
);
1268 if ( h
) *h
= ::GetDeviceCaps(GetHdc(), VERTSIZE
);
1271 wxSize
wxDC::GetPPI() const
1273 int x
= ::GetDeviceCaps(GetHdc(), LOGPIXELSX
);
1274 int y
= ::GetDeviceCaps(GetHdc(), LOGPIXELSY
);
1276 return wxSize(x
, y
);
1279 // For use by wxWindows only, unless custom units are required.
1280 void wxDC::SetLogicalScale(double x
, double y
)
1282 m_logicalScaleX
= x
;
1283 m_logicalScaleY
= y
;
1286 #if WXWIN_COMPATIBILITY
1287 void wxDC::DoGetTextExtent(const wxString
& string
, float *x
, float *y
,
1288 float *descent
, float *externalLeading
,
1289 wxFont
*theFont
, bool use16bit
) const
1291 long x1
, y1
, descent1
, externalLeading1
;
1292 GetTextExtent(string
, & x1
, & y1
, & descent1
, & externalLeading1
, theFont
, use16bit
);
1295 *descent
= descent1
;
1296 if (externalLeading
)
1297 *externalLeading
= externalLeading1
;
1301 // ---------------------------------------------------------------------------
1302 // spline drawing code
1303 // ---------------------------------------------------------------------------
1307 class wxSpline
: public wxObject
1313 wxSpline(wxList
*list
);
1314 void DeletePoints();
1316 // Doesn't delete points
1320 void wx_draw_open_spline(wxDC
*dc
, wxSpline
*spline
);
1322 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
1323 double a3
, double b3
, double a4
, double b4
);
1324 void wx_clear_stack();
1325 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
1326 double *y3
, double *x4
, double *y4
);
1327 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
1328 double x4
, double y4
);
1329 static bool wx_spline_add_point(double x
, double y
);
1330 static void wx_spline_draw_point_array(wxDC
*dc
);
1331 wxSpline
*wx_make_spline(int x1
, int y1
, int x2
, int y2
, int x3
, int y3
);
1333 void wxDC::DoDrawSpline(wxList
*list
)
1335 wxSpline
spline(list
);
1337 wx_draw_open_spline(this, &spline
);
1340 wxList wx_spline_point_list
;
1342 void wx_draw_open_spline(wxDC
*dc
, wxSpline
*spline
)
1345 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
1346 double x1
, y1
, x2
, y2
;
1348 wxNode
*node
= spline
->points
->First();
1349 p
= (wxPoint
*)node
->Data();
1354 node
= node
->Next();
1355 p
= (wxPoint
*)node
->Data();
1359 cx1
= (double)((x1
+ x2
) / 2);
1360 cy1
= (double)((y1
+ y2
) / 2);
1361 cx2
= (double)((cx1
+ x2
) / 2);
1362 cy2
= (double)((cy1
+ y2
) / 2);
1364 wx_spline_add_point(x1
, y1
);
1366 while ((node
= node
->Next()) != NULL
)
1368 p
= (wxPoint
*)node
->Data();
1373 cx4
= (double)(x1
+ x2
) / 2;
1374 cy4
= (double)(y1
+ y2
) / 2;
1375 cx3
= (double)(x1
+ cx4
) / 2;
1376 cy3
= (double)(y1
+ cy4
) / 2;
1378 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
1382 cx2
= (double)(cx1
+ x2
) / 2;
1383 cy2
= (double)(cy1
+ y2
) / 2;
1386 wx_spline_add_point((double)wx_round(cx1
), (double)wx_round(cy1
));
1387 wx_spline_add_point(x2
, y2
);
1389 wx_spline_draw_point_array(dc
);
1393 /********************* CURVES FOR SPLINES *****************************
1395 The following spline drawing routine is from
1397 "An Algorithm for High-Speed Curve Generation"
1398 by George Merrill Chaikin,
1399 Computer Graphics and Image Processing, 3, Academic Press,
1404 "On Chaikin's Algorithm" by R. F. Riesenfeld,
1405 Computer Graphics and Image Processing, 4, Academic Press,
1408 ***********************************************************************/
1410 #define half(z1, z2) ((z1+z2)/2.0)
1413 /* iterative version */
1415 void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
1418 register double xmid
, ymid
;
1419 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
1422 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
1424 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
1425 xmid
= (double)half(x2
, x3
);
1426 ymid
= (double)half(y2
, y3
);
1427 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
1428 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
1429 wx_spline_add_point((double)wx_round(x1
), (double)wx_round(y1
));
1430 wx_spline_add_point((double)wx_round(xmid
), (double)wx_round(ymid
));
1432 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
1433 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
1434 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
1435 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
1441 /* utilities used by spline drawing routines */
1444 typedef struct wx_spline_stack_struct
{
1445 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
1449 #define SPLINE_STACK_DEPTH 20
1450 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
1451 static Stack
*wx_stack_top
;
1452 static int wx_stack_count
;
1454 void wx_clear_stack()
1456 wx_stack_top
= wx_spline_stack
;
1460 void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
1462 wx_stack_top
->x1
= x1
;
1463 wx_stack_top
->y1
= y1
;
1464 wx_stack_top
->x2
= x2
;
1465 wx_stack_top
->y2
= y2
;
1466 wx_stack_top
->x3
= x3
;
1467 wx_stack_top
->y3
= y3
;
1468 wx_stack_top
->x4
= x4
;
1469 wx_stack_top
->y4
= y4
;
1474 int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
1475 double *x3
, double *y3
, double *x4
, double *y4
)
1477 if (wx_stack_count
== 0)
1481 *x1
= wx_stack_top
->x1
;
1482 *y1
= wx_stack_top
->y1
;
1483 *x2
= wx_stack_top
->x2
;
1484 *y2
= wx_stack_top
->y2
;
1485 *x3
= wx_stack_top
->x3
;
1486 *y3
= wx_stack_top
->y3
;
1487 *x4
= wx_stack_top
->x4
;
1488 *y4
= wx_stack_top
->y4
;
1492 static bool wx_spline_add_point(double x
, double y
)
1494 wxPoint
*point
= new wxPoint
;
1497 wx_spline_point_list
.Append((wxObject
*)point
);
1501 static void wx_spline_draw_point_array(wxDC
*dc
)
1503 dc
->DrawLines(&wx_spline_point_list
, 0, 0);
1504 wxNode
*node
= wx_spline_point_list
.First();
1507 wxPoint
*point
= (wxPoint
*)node
->Data();
1510 node
= wx_spline_point_list
.First();
1514 wxSpline::wxSpline(wxList
*list
)
1519 wxSpline::~wxSpline()
1523 void wxSpline::DeletePoints()
1525 for(wxNode
*node
= points
->First(); node
; node
= points
->First())
1527 wxPoint
*point
= (wxPoint
*)node
->Data();
1535 #endif // wxUSE_SPLINES