1 /////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "dc.h"
18 #if !USE_SHARED_LIBRARY
19 IMPLEMENT_ABSTRACT_CLASS(wxDC
, wxObject
)
22 //-----------------------------------------------------------------------------
24 //-----------------------------------------------------------------------------
26 #define mm2inches 0.0393700787402
27 #define inches2mm 25.4
28 #define mm2twips 56.6929133859
29 #define twips2mm 0.0176388888889
30 #define mm2pt 2.83464566929
31 #define pt2mm 0.352777777778
33 long wxDC::m_macCurrentPortId
= 1 ;
35 //-----------------------------------------------------------------------------
37 //-----------------------------------------------------------------------------
43 m_autoSetting
= FALSE
;
54 m_internalDeviceOriginX
= 0;
55 m_internalDeviceOriginY
= 0;
56 m_externalDeviceOriginX
= 0;
57 m_externalDeviceOriginY
= 0;
59 m_logicalScaleX
= 1.0;
60 m_logicalScaleY
= 1.0;
66 m_mappingMode
= wxMM_TEXT
;
67 m_needComputeScaleX
= FALSE
;
68 m_needComputeScaleY
= FALSE
;
70 m_signX
= 1; // default x-axis left to right
71 m_signY
= 1; // default y-axis top down
73 m_maxX
= m_maxY
= -100000;
74 m_minY
= m_minY
= 100000;
76 m_logicalFunction
= wxCOPY
;
77 // m_textAlignment = wxALIGN_TOP_LEFT;
78 m_backgroundMode
= wxTRANSPARENT
;
80 m_textForegroundColour
= *wxBLACK
;
81 m_textBackgroundColour
= *wxWHITE
;
83 m_font
= *wxNORMAL_FONT
;
84 m_brush
= *wxTRANSPARENT_BRUSH
;
85 m_backgroundBrush
= *wxWHITE_BRUSH
;
87 // m_palette = wxAPP_COLOURMAP;
91 m_macFontInstalled
= false ;
92 m_macBrushInstalled
= false ;
93 m_macPenInstalled
= false ;
96 m_macLocalOrigin
.h
= m_macLocalOrigin
.v
= 0 ;
97 m_macClipRect
.left
= -32000 ;
98 m_macClipRect
.top
= -32000 ;
99 m_macClipRect
.right
= 32000 ;
100 m_macClipRect
.bottom
= 32000 ;
101 ::GetPort( &m_macOrigPort
) ;
108 ::SetOrigin( 0 , 0 ) ;
109 ::ClipRect( &m_macPort
->portRect
) ;
111 ::SetPort( m_macOrigPort
) ;
113 ++m_macCurrentPortId
;
116 void wxDC::MacSetupPort() const
118 m_macPortId
= ++m_macCurrentPortId
;
119 ::SetPort(m_macPort
);
120 ::SetOrigin(-m_macLocalOrigin
.h
, -m_macLocalOrigin
.v
);
121 ::ClipRect(&m_macClipRect
);
123 m_macFontInstalled
= false ;
124 m_macBrushInstalled
= false ;
125 m_macPenInstalled
= false ;
128 void wxDC::DrawBitmap( const wxBitmap
&bmp
, long x
, long y
, bool useMask
)
134 long xx1
= XLOG2DEV(x
);
135 long yy1
= YLOG2DEV(y
);
138 wxBitmapRefData
* bmap
= (wxBitmapRefData
*) ( bmp
.GetRefData()) ;
142 if ( bmap
->m_bitmapType
== kMacBitmapTypePict
)
144 Rect bitmaprect
= { 0 , 0 , bmap
->m_height
, bmap
->m_width
} ;
145 ::OffsetRect( &bitmaprect
, xx1
, yy1
) ;
146 ::DrawPicture( bmap
->m_hPict
, &bitmaprect
) ;
148 else if ( bmap
->m_bitmapType
== kMacBitmapTypeGrafWorld
)
150 if ( bmap
->m_hBitmap
)
152 GWorldPtr bmapworld
= bmap
->m_hBitmap
;
153 PixMapHandle bmappixels
;
154 RGBColor white
= { 0xFFFF, 0xFFFF,0xFFFF} ;
155 RGBColor black
= { 0,0,0} ;
156 RGBForeColor( &black
) ;
157 RGBBackColor( &white
) ;
158 // RGBForeColor( &m_textForegroundColour.GetPixel() ) ;
159 // RGBBackColor( &m_textBackgroundColour.GetPixel() ) ;
161 bmappixels
= GetGWorldPixMap( bmapworld
) ;
162 if ( LockPixels(bmappixels
) )
167 source
.right
= bmap
->m_width
;
168 source
.bottom
= bmap
->m_height
;
169 dest
.top
= YLOG2DEV(y
) ;
170 dest
.left
= XLOG2DEV(x
) ;
171 dest
.bottom
= YLOG2DEV(y
+ bmap
->m_height
) ;
172 dest
.right
= XLOG2DEV(x
+ bmap
->m_width
) ;
173 // ::ClipRect(&m_macClipRect);
174 CopyBits( &GrafPtr( bmapworld
)->portBits
, &GrafPtr( m_macPort
)->portBits
,
175 &source
, &dest
, srcCopy
, NULL
) ;
179 long x1 = XLOG2DEV(m_clipX1);
180 long y1 = YLOG2DEV(m_clipY1);
181 long x2 = XLOG2DEV(m_clipX2);
182 long y2 = YLOG2DEV(m_clipY2);
184 Rect clip = { y1 , x1 , y2 , x2 } ;
188 UnlockPixels( bmappixels
) ;
190 m_macPenInstalled
= false ;
191 m_macBrushInstalled
= false ;
192 m_macFontInstalled
= false ;
199 void wxDC::DrawIcon( const wxIcon
&icon
, long x
, long y
, bool useMask
)
205 long xx1
= XLOG2DEV(x
);
206 long yy1
= YLOG2DEV(y
);
209 wxIconRefData
* iconref
= (wxIconRefData
*) ( icon
.GetRefData()) ;
211 if ( iconref
&& iconref
->m_ok
&& iconref
->m_hIcon
)
213 Rect bitmaprect
= { 0 , 0 , iconref
->m_height
, iconref
->m_width
} ;
214 OffsetRect( &bitmaprect
, xx1
, yy1
) ;
215 PlotCIconHandle( &bitmaprect
, atNone
, ttNone
, iconref
->m_hIcon
) ;
220 void wxDC::DrawPoint( wxPoint
& point
)
222 DrawPoint( point
.x
, point
.y
);
225 void wxDC::DrawPolygon( wxList
*list
, long xoffset
, long yoffset
, int fillStyle
)
227 int n
= list
->Number();
228 wxPoint
*points
= new wxPoint
[n
];
231 for( wxNode
*node
= list
->First(); node
; node
= node
->Next() )
233 wxPoint
*point
= (wxPoint
*)node
->Data();
234 points
[i
].x
= point
->x
;
235 points
[i
++].y
= point
->y
;
237 DrawPolygon( n
, points
, xoffset
, yoffset
, fillStyle
);
241 void wxDC::DrawLines( wxList
*list
, long xoffset
, long yoffset
)
243 int n
= list
->Number();
244 wxPoint
*points
= new wxPoint
[n
];
247 for( wxNode
*node
= list
->First(); node
; node
= node
->Next() )
249 wxPoint
*point
= (wxPoint
*)node
->Data();
250 points
[i
].x
= point
->x
;
251 points
[i
++].y
= point
->y
;
253 DrawLines( n
, points
, xoffset
, yoffset
);
257 void wxDC::DrawSpline( long x1
, long y1
, long x2
, long y2
, long x3
, long y3
)
260 list
.Append( (wxObject
*)new wxPoint(x1
, y1
) );
261 list
.Append( (wxObject
*)new wxPoint(x2
, y2
) );
262 list
.Append( (wxObject
*)new wxPoint(x3
, y3
) );
264 wxNode
*node
= list
.First();
267 wxPoint
*p
= (wxPoint
*)node
->Data();
273 void wxDC::DrawSpline( int n
, wxPoint points
[] )
276 for (int i
= 0; i
< n
; i
++) list
.Append( (wxObject
*)&points
[i
] );
280 void wxDC::SetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
285 m_clipX1
= wxMax( m_clipX1
, x
) ;
286 m_clipY1
= wxMax( m_clipY1
,y
);
287 m_clipX2
= wxMin( m_clipX2
, (x
+ width
));
288 m_clipY2
= wxMin( m_clipY2
,(y
+ height
));
296 m_clipX2
= x
+ width
;
297 m_clipY2
= y
+ height
;
300 long x1
= XLOG2DEV(m_clipX1
);
301 long y1
= YLOG2DEV(m_clipY1
);
302 long x2
= XLOG2DEV(m_clipX2
);
303 long y2
= YLOG2DEV(m_clipY2
);
305 Rect clip
= { y1
, x1
, y2
, x2
} ;
307 ::ClipRect( &clip
) ;
311 void wxDC::SetClippingRegion(const wxRect
& rect
)
313 SetClippingRegion(rect
.x
, rect
.y
, rect
.width
, rect
.height
);
316 void wxDC::DestroyClippingRegion(void)
320 // Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
321 ::ClipRect(&m_macClipRect
);
324 void wxDC::GetClippingBox( wxCoord
*x
, wxCoord
*y
, wxCoord
*width
, wxCoord
*height
) const
328 if (x
) *x
= m_clipX1
;
329 if (y
) *y
= m_clipY1
;
330 if (width
) *width
= (m_clipX2
- m_clipX1
);
331 if (height
) *height
= (m_clipY2
- m_clipY1
);
334 *x
= *y
= *width
= *height
= 0;
337 void wxDC::GetClippingBox( long *x
, long *y
, long *width
, long *height
) const
341 if (x
) *x
= m_clipX1
;
342 if (y
) *y
= m_clipY1
;
343 if (width
) *width
= (m_clipX2
- m_clipX1
);
344 if (height
) *height
= (m_clipY2
- m_clipY1
);
347 *x
= *y
= *width
= *height
= 0;
350 void wxDC::GetClippingBox(wxRect
& rect
) const
352 // Necessary to use intermediate variables for 16-bit compilation
354 GetClippingBox(&x
, &y
, &w
, &h
);
355 rect
.x
= x
; rect
.y
= y
; rect
.width
= w
; rect
.height
= h
;
358 void wxDC::GetSize( int* width
, int* height
) const
360 *width
= m_maxX
-m_minX
;
361 *height
= m_maxY
-m_minY
;
364 void wxDC::GetSizeMM( long* width
, long* height
) const
369 *width
= long( double(w
) / (m_scaleX
*m_mm_to_pix_x
) );
370 *height
= long( double(h
) / (m_scaleY
*m_mm_to_pix_y
) );
373 void wxDC::SetTextForeground( const wxColour
&col
)
376 m_textForegroundColour
= col
;
377 m_macFontInstalled
= false ;
380 void wxDC::SetTextBackground( const wxColour
&col
)
383 m_textBackgroundColour
= col
;
384 m_macFontInstalled
= false ;
387 void wxDC::SetMapMode( int mode
)
392 SetLogicalScale( twips2mm
*m_mm_to_pix_x
, twips2mm
*m_mm_to_pix_y
);
395 SetLogicalScale( pt2mm
*m_mm_to_pix_x
, pt2mm
*m_mm_to_pix_y
);
398 SetLogicalScale( m_mm_to_pix_x
, m_mm_to_pix_y
);
401 SetLogicalScale( m_mm_to_pix_x
/10.0, m_mm_to_pix_y
/10.0 );
405 SetLogicalScale( 1.0, 1.0 );
408 if (mode
!= wxMM_TEXT
)
410 m_needComputeScaleX
= TRUE
;
411 m_needComputeScaleY
= TRUE
;
415 void wxDC::SetUserScale( double x
, double y
)
417 // allow negative ? -> no
420 ComputeScaleAndOrigin();
423 void wxDC::GetUserScale( double *x
, double *y
)
425 if (x
) *x
= m_userScaleX
;
426 if (y
) *y
= m_userScaleY
;
429 void wxDC::SetLogicalScale( double x
, double y
)
434 ComputeScaleAndOrigin();
437 void wxDC::GetLogicalScale( double *x
, double *y
)
439 if (x
) *x
= m_logicalScaleX
;
440 if (y
) *y
= m_logicalScaleY
;
443 void wxDC::SetLogicalOrigin( long x
, long y
)
445 m_logicalOriginX
= x
* m_signX
; // is this still correct ?
446 m_logicalOriginY
= y
* m_signY
;
447 ComputeScaleAndOrigin();
450 void wxDC::GetLogicalOrigin( long *x
, long *y
)
452 if (x
) *x
= m_logicalOriginX
;
453 if (y
) *y
= m_logicalOriginY
;
456 void wxDC::SetDeviceOrigin( long x
, long y
)
458 m_externalDeviceOriginX
= x
;
459 m_externalDeviceOriginY
= y
;
460 ComputeScaleAndOrigin();
463 void wxDC::GetDeviceOrigin( long *x
, long *y
)
465 // if (x) *x = m_externalDeviceOriginX;
466 // if (y) *y = m_externalDeviceOriginY;
467 if (x
) *x
= m_deviceOriginX
;
468 if (y
) *y
= m_deviceOriginY
;
471 void wxDC::SetInternalDeviceOrigin( long x
, long y
)
473 m_internalDeviceOriginX
= x
;
474 m_internalDeviceOriginY
= y
;
475 ComputeScaleAndOrigin();
478 void wxDC::GetInternalDeviceOrigin( long *x
, long *y
)
480 if (x
) *x
= m_internalDeviceOriginX
;
481 if (y
) *y
= m_internalDeviceOriginY
;
484 void wxDC::SetAxisOrientation( bool xLeftRight
, bool yBottomUp
)
486 m_signX
= (xLeftRight
? 1 : -1);
487 m_signY
= (yBottomUp
? -1 : 1);
488 ComputeScaleAndOrigin();
491 long wxDC::DeviceToLogicalX(long x
) const
496 long wxDC::DeviceToLogicalY(long y
) const
501 long wxDC::DeviceToLogicalXRel(long x
) const
503 return XDEV2LOGREL(x
);
506 long wxDC::DeviceToLogicalYRel(long y
) const
508 return YDEV2LOGREL(y
);
511 long wxDC::LogicalToDeviceX(long x
) const
516 long wxDC::LogicalToDeviceY(long y
) const
521 long wxDC::LogicalToDeviceXRel(long x
) const
523 return XLOG2DEVREL(x
);
526 long wxDC::LogicalToDeviceYRel(long y
) const
528 return YLOG2DEVREL(y
);
531 void wxDC::CalcBoundingBox( long x
, long y
)
533 if (x
< m_minX
) m_minX
= x
;
534 if (y
< m_minY
) m_minY
= y
;
535 if (x
> m_maxX
) m_maxX
= x
;
536 if (y
> m_maxY
) m_maxY
= y
;
539 void wxDC::ComputeScaleAndOrigin(void)
541 // CMB: copy scale to see if it changes
542 double origScaleX
= m_scaleX
;
543 double origScaleY
= m_scaleY
;
545 m_scaleX
= m_logicalScaleX
* m_userScaleX
;
546 m_scaleY
= m_logicalScaleY
* m_userScaleY
;
548 m_deviceOriginX
= m_internalDeviceOriginX
+ m_externalDeviceOriginX
;
549 m_deviceOriginY
= m_internalDeviceOriginY
+ m_externalDeviceOriginY
;
551 // CMB: if scale has changed call SetPen to recalulate the line width
552 if (m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
)
554 // this is a bit artificial, but we need to force wxDC to think
555 // the pen has changed
556 wxPen
* pen
= & GetPen();
563 void wxDC::SetPalette( const wxPalette
& palette
)
567 void wxDC::SetBackgroundMode( int mode
)
569 m_backgroundMode
= mode
;
572 void wxDC::SetFont( const wxFont
&font
)
580 m_macFontInstalled
= false ;
583 void wxDC::SetPen( const wxPen
&pen
)
598 m_macPenInstalled
= false ;
601 void wxDC::SetBrush( const wxBrush
&brush
)
607 if (m_brush
== brush
)
611 m_macBrushInstalled
= false ;
614 void wxDC::SetBackground( const wxBrush
&brush
)
620 if (m_backgroundBrush
== brush
)
623 m_backgroundBrush
= brush
;
625 if (!m_backgroundBrush
.Ok())
627 m_macBrushInstalled
= false ;
630 void wxDC::SetLogicalFunction( int function
)
632 if (m_logicalFunction
== function
)
635 m_logicalFunction
= function
;
636 m_macFontInstalled
= false ;
637 m_macBrushInstalled
= false ;
638 m_macPenInstalled
= false ;
641 void wxDC::FloodFill( long x1
, long y1
, const wxColour
& col
, int style
)
645 bool wxDC::GetPixel( long x1
, long y1
, wxColour
*col
) const
650 void wxDC::DrawLine( long x1
, long y1
, long x2
, long y2
)
657 if (m_pen
.GetStyle() != wxTRANSPARENT
)
660 int offset
= (m_pen
.GetWidth() - 1) / 2 ;
661 long xx1
= XLOG2DEV(x1
);
662 long yy1
= YLOG2DEV(y1
);
663 long xx2
= XLOG2DEV(x2
);
664 long yy2
= YLOG2DEV(y2
);
666 ::MoveTo(xx1
- offset
,yy1
- offset
);
667 ::LineTo(xx2
- offset
, yy2
- offset
);
671 void wxDC::CrossHair( long x
, long y
)
675 void wxDC::DrawArc( long x1
, long y1
, long x2
, long y2
, long xc
, long yc
)
679 void wxDC::DrawEllipticArc( long x
, long y
, long width
, long height
, double sa
, double ea
)
683 void wxDC::DrawPoint( long x
, long y
)
690 if (m_pen
.GetStyle() != wxTRANSPARENT
)
693 long xx1
= XLOG2DEV(x
);
694 long yy1
= YLOG2DEV(y
);
697 ::LineTo(xx1
+1, yy1
+1);
701 void wxDC::DrawLines( int n
, wxPoint points
[], long xoffset
, long yoffset
)
707 if (m_pen
.GetStyle() == wxTRANSPARENT
)
712 int offset
= (m_pen
.GetWidth() - 1 ) / 2 ;
713 long x1
, x2
, y1
, y2
;
714 x1
= XLOG2DEV(points
[0].x
+ xoffset
);
715 y1
= YLOG2DEV(points
[0].y
+ yoffset
);
716 ::MoveTo(x1
- offset
,y1
- offset
);
718 for (int i
= 0; i
< n
-1; i
++)
720 long x2
= XLOG2DEV(points
[i
+1].x
+ xoffset
);
721 long y2
= YLOG2DEV(points
[i
+1].y
+ yoffset
);
722 ::LineTo(x2
- offset
, y2
- offset
);
726 void wxDC::DrawPolygon( int n
, wxPoint points
[], long xoffset
, long yoffset
,
733 PolyHandle polygon
= OpenPoly() ;
734 long x1
, x2
, y1
, y2
;
735 x1
= XLOG2DEV(points
[0].x
+ xoffset
);
736 y1
= YLOG2DEV(points
[0].y
+ yoffset
);
739 for (int i
= 0; i
< n
-1; i
++)
741 long x2
= XLOG2DEV(points
[i
+1].x
+ xoffset
);
742 long y2
= YLOG2DEV(points
[i
+1].y
+ yoffset
);
747 if (m_brush
.GetStyle() != wxTRANSPARENT
)
750 ::PaintPoly( polygon
) ;
753 if (m_pen
.GetStyle() != wxTRANSPARENT
)
756 ::FramePoly( polygon
) ;
758 KillPoly( polygon
) ;
761 void wxDC::DrawRectangle( long x
, long y
, long width
, long height
)
767 long xx
= XLOG2DEV(x
);
768 long yy
= YLOG2DEV(y
);
769 long ww
= m_signX
* XLOG2DEVREL(width
);
770 long hh
= m_signY
* YLOG2DEVREL(height
);
772 // CMB: draw nothing if transformed w or h is 0
773 if (ww
== 0 || hh
== 0)
776 // CMB: handle -ve width and/or height
789 Rect rect
= { yy
, xx
, yy
+ hh
, xx
+ ww
} ;
791 if (m_brush
.GetStyle() != wxTRANSPARENT
)
794 ::PaintRect( &rect
) ;
797 if (m_pen
.GetStyle() != wxTRANSPARENT
)
800 ::FrameRect( &rect
) ;
804 void wxDC::DrawRoundedRectangle( long x
, long y
, long width
, long height
, double radius
)
811 radius
= - radius
* ((width
< height
) ? width
: height
);
813 long xx
= XLOG2DEV(x
);
814 long yy
= YLOG2DEV(y
);
815 long ww
= m_signX
* XLOG2DEVREL(width
);
816 long hh
= m_signY
* YLOG2DEVREL(height
);
818 // CMB: draw nothing if transformed w or h is 0
819 if (ww
== 0 || hh
== 0)
822 // CMB: handle -ve width and/or height
835 Rect rect
= { yy
, xx
, yy
+ hh
, xx
+ ww
} ;
837 if (m_brush
.GetStyle() != wxTRANSPARENT
)
840 ::PaintRoundRect( &rect
, radius
* 2 , radius
* 2 ) ;
843 if (m_pen
.GetStyle() != wxTRANSPARENT
)
846 ::FrameRoundRect( &rect
, radius
* 2 , radius
* 2 ) ;
850 void wxDC::DrawEllipse( long x
, long y
, long width
, long height
)
856 long xx
= XLOG2DEV(x
);
857 long yy
= YLOG2DEV(y
);
858 long ww
= m_signX
* XLOG2DEVREL(width
);
859 long hh
= m_signY
* YLOG2DEVREL(height
);
861 // CMB: draw nothing if transformed w or h is 0
862 if (ww
== 0 || hh
== 0)
865 // CMB: handle -ve width and/or height
878 Rect rect
= { yy
, xx
, yy
+ hh
, xx
+ ww
} ;
880 if (m_brush
.GetStyle() != wxTRANSPARENT
)
883 ::PaintOval( &rect
) ;
886 if (m_pen
.GetStyle() != wxTRANSPARENT
)
889 ::FrameOval( &rect
) ;
893 // ----------------------------------- spline code ----------------------------------------
895 static void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
896 double a3
, double b3
, double a4
, double b4
);
897 static void wx_clear_stack(void);
898 static int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
899 double *y3
, double *x4
, double *y4
);
900 static void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
901 double x4
, double y4
);
902 static bool wx_spline_add_point(double x
, double y
);
903 static void wx_spline_draw_point_array(wxDC
*dc
);
905 static wxList wx_spline_point_list
;
907 #define half(z1, z2) ((z1+z2)/2.0)
910 /* iterative version */
912 static void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
915 register double xmid
, ymid
;
916 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
919 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
921 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
922 xmid
= (double)half(x2
, x3
);
923 ymid
= (double)half(y2
, y3
);
924 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
925 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
926 wx_spline_add_point( x1
, y1
);
927 wx_spline_add_point( xmid
, ymid
);
929 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
930 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
931 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
932 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
937 /* utilities used by spline drawing routines */
939 typedef struct wx_spline_stack_struct
{
940 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
943 #define SPLINE_STACK_DEPTH 20
944 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
945 static Stack
*wx_stack_top
;
946 static int wx_stack_count
;
948 static void wx_clear_stack(void)
950 wx_stack_top
= wx_spline_stack
;
954 static void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
956 wx_stack_top
->x1
= x1
;
957 wx_stack_top
->y1
= y1
;
958 wx_stack_top
->x2
= x2
;
959 wx_stack_top
->y2
= y2
;
960 wx_stack_top
->x3
= x3
;
961 wx_stack_top
->y3
= y3
;
962 wx_stack_top
->x4
= x4
;
963 wx_stack_top
->y4
= y4
;
968 static int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
969 double *x3
, double *y3
, double *x4
, double *y4
)
971 if (wx_stack_count
== 0)
975 *x1
= wx_stack_top
->x1
;
976 *y1
= wx_stack_top
->y1
;
977 *x2
= wx_stack_top
->x2
;
978 *y2
= wx_stack_top
->y2
;
979 *x3
= wx_stack_top
->x3
;
980 *y3
= wx_stack_top
->y3
;
981 *x4
= wx_stack_top
->x4
;
982 *y4
= wx_stack_top
->y4
;
986 static bool wx_spline_add_point(double x
, double y
)
988 wxPoint
*point
= new wxPoint
;
991 wx_spline_point_list
.Append((wxObject
*)point
);
995 static void wx_spline_draw_point_array(wxDC
*dc
)
997 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
998 wxNode
*node
= wx_spline_point_list
.First();
1001 wxPoint
*point
= (wxPoint
*)node
->Data();
1004 node
= wx_spline_point_list
.First();
1008 void wxDC::DrawSpline( wxList
*points
)
1011 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
1012 double x1
, y1
, x2
, y2
;
1014 wxNode
*node
= points
->First();
1015 p
= (wxPoint
*)node
->Data();
1020 node
= node
->Next();
1021 p
= (wxPoint
*)node
->Data();
1025 cx1
= (double)((x1
+ x2
) / 2);
1026 cy1
= (double)((y1
+ y2
) / 2);
1027 cx2
= (double)((cx1
+ x2
) / 2);
1028 cy2
= (double)((cy1
+ y2
) / 2);
1030 wx_spline_add_point(x1
, y1
);
1032 while ((node
= node
->Next()) != NULL
)
1034 p
= (wxPoint
*)node
->Data();
1039 cx4
= (double)(x1
+ x2
) / 2;
1040 cy4
= (double)(y1
+ y2
) / 2;
1041 cx3
= (double)(x1
+ cx4
) / 2;
1042 cy3
= (double)(y1
+ cy4
) / 2;
1044 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
1048 cx2
= (double)(cx1
+ x2
) / 2;
1049 cy2
= (double)(cy1
+ y2
) / 2;
1052 wx_spline_add_point( cx1
, cy1
);
1053 wx_spline_add_point( x2
, y2
);
1055 wx_spline_draw_point_array( this );
1060 bool wxDC::CanDrawBitmap(void) const
1066 bool wxDC::Blit( long xdest
, long ydest
, long width
, long height
,
1067 wxDC
*source
, long xsrc
, long ysrc
, int logical_func
, bool useMask
)
1069 if (!Ok()) return FALSE
;
1072 CGrafPtr sourcePort
= (CGrafPtr
) source
->m_macPort
;
1073 PixMapHandle bmappixels
= GetGWorldPixMap( sourcePort
) ;
1074 RGBColor white
= { 0xFFFF, 0xFFFF,0xFFFF} ;
1075 RGBColor black
= { 0,0,0} ;
1076 // RGBForeColor( &black ) ;
1077 // RGBBackColor( &white ) ;
1078 RGBForeColor( &m_textForegroundColour
.GetPixel() ) ;
1079 RGBBackColor( &m_textBackgroundColour
.GetPixel() ) ;
1081 if ( LockPixels(bmappixels
) )
1083 Rect srcrect
, dstrect
;
1084 srcrect
.top
= source
->YLOG2DEV(ysrc
) ;
1085 srcrect
.left
= source
->XLOG2DEV(xsrc
) ;
1086 srcrect
.right
= source
->XLOG2DEV(xsrc
+ width
) ;
1087 srcrect
.bottom
= source
->YLOG2DEV(ysrc
+ height
) ;
1088 dstrect
.top
= YLOG2DEV(ydest
) ;
1089 dstrect
.left
= XLOG2DEV(xdest
) ;
1090 dstrect
.bottom
= YLOG2DEV(ydest
+ height
) ;
1091 dstrect
.right
= XLOG2DEV(xdest
+ width
) ;
1092 // ::ClipRect(&m_macClipRect);
1093 CopyBits( &GrafPtr( sourcePort
)->portBits
, &GrafPtr( m_macPort
)->portBits
,
1094 &srcrect
, &dstrect
, srcCopy
, NULL
) ;
1098 long x1 = XLOG2DEV(m_clipX1);
1099 long y1 = YLOG2DEV(m_clipY1);
1100 long x2 = XLOG2DEV(m_clipX2);
1101 long y2 = YLOG2DEV(m_clipY2);
1103 Rect clip = { y1 , x1 , y2 , x2 } ;
1107 UnlockPixels( bmappixels
) ;
1110 m_macPenInstalled
= false ;
1111 m_macBrushInstalled
= false ;
1112 m_macFontInstalled
= false ;
1117 void wxDC::DrawText( const wxString
&string
, long x
, long y
, bool use16
)
1123 long xx
= XLOG2DEV(x
);
1124 long yy
= YLOG2DEV(y
);
1126 // if (m_pen.GetStyle() != wxTRANSPARENT)
1130 Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
1132 ::ClipRect( &clip ) ;
1136 ::GetFontInfo( &fi
) ;
1139 ::MoveTo( xx
, yy
);
1140 if ( m_backgroundMode
== wxTRANSPARENT
)
1142 ::TextMode( srcOr
) ;
1146 ::TextMode( srcCopy
) ;
1149 const char *text
= NULL
;
1153 if ( wxApp::s_macDefaultEncodingIsPC
)
1155 macText
= wxMacMakeMacStringFromPC( string
) ;
1157 length
= macText
.Length() ;
1162 length
= string
.Length() ;
1171 if( text
[i
] == 13 || text
[i
] == 10)
1173 ::DrawText( text
, laststop
, i
- laststop
) ;
1175 ::MoveTo( xx
, yy
+ line
*(fi
.descent
+ fi
.ascent
+ fi
.leading
) );
1181 ::DrawText( text
, laststop
, i
- laststop
) ;
1182 ::TextMode( srcOr
) ;
1186 bool wxDC::CanGetTextExtent(void) const
1194 void wxDC::GetTextExtent( const wxString
&string
, long *width
, long *height
,
1195 long *descent
, long *externalLeading
,
1196 wxFont
*theFont
, bool use16
) const
1203 wxFont formerFont
= m_font
;
1207 wxFontRefData
* font
= (wxFontRefData
*) m_font
.GetRefData() ;
1211 long yy1
= YLOG2DEV(0);
1212 long yy2
= YLOG2DEV(font
->m_macFontSize
);
1214 ::TextFont( font
->m_macFontNum
) ;
1215 ::TextSize( abs( yy2
-yy1
) ) ;
1216 ::TextFace( font
->m_macFontStyle
) ;
1225 ::GetFontInfo( &fi
) ;
1227 *height
= fi
.descent
+ fi
.ascent
;
1228 *descent
= fi
.descent
;
1229 *externalLeading
= fi
.leading
;
1231 const char *text
= NULL
;
1234 if ( wxApp::s_macDefaultEncodingIsPC
)
1236 macText
= wxMacMakeMacStringFromPC( string
) ;
1238 length
= macText
.Length() ;
1243 length
= string
.Length() ;
1253 if( text
[i
] == 13 || text
[i
] == 10)
1255 *height
+= fi
.descent
+ fi
.ascent
+ fi
.leading
;
1256 curwidth
= ::TextWidth( text
, laststop
, i
- laststop
) ;
1257 if ( curwidth
> *width
)
1264 curwidth
= ::TextWidth( text
, laststop
, i
- laststop
) ;
1265 if ( curwidth
> *width
)
1270 m_macFontInstalled
= false ;
1274 wxCoord
wxDC::GetCharWidth(void) const
1284 ::GetFontInfo( &fi
) ;
1286 return (fi
.descent
+ fi
.ascent
) / 2 ;
1289 wxCoord
wxDC::GetCharHeight(void) const
1299 ::GetFontInfo( &fi
) ;
1301 return fi
.descent
+ fi
.ascent
;
1304 void wxDC::Clear(void)
1309 Rect rect
= { -32767 , -32767 , 32767 , 32767 } ;
1311 if (m_backgroundBrush
.GetStyle() != wxTRANSPARENT
)
1314 ::EraseRect( &rect
) ;
1318 void wxDC::MacInstallFont() const
1324 if ( m_macFontInstalled
)
1327 wxFontRefData
* font
= (wxFontRefData
*) m_font
.GetRefData() ;
1331 ::TextFont( font
->m_macFontNum
) ;
1332 ::TextSize( m_scaleY
* font
->m_macFontSize
) ;
1333 ::TextFace( font
->m_macFontStyle
) ;
1335 m_macFontInstalled
= true ;
1336 m_macBrushInstalled
= false ;
1337 m_macPenInstalled
= false ;
1339 ::RGBForeColor(&m_textForegroundColour
.GetPixel() );
1340 ::RGBBackColor(&m_textBackgroundColour
.GetPixel() );
1346 GetFNum( "\pGeneva" , &fontnum
) ;
1347 ::TextFont( fontnum
) ;
1348 ::TextSize( m_scaleY
* 10 ) ;
1351 // todo reset after spacing changes - or store the current spacing somewhere
1353 m_macFontInstalled
= true ;
1354 m_macBrushInstalled
= false ;
1355 m_macPenInstalled
= false ;
1356 ::RGBForeColor( &(m_textForegroundColour
.GetPixel()) );
1357 ::RGBBackColor(&m_textBackgroundColour
.GetPixel() );
1361 short mode
= patCopy
;
1365 switch( m_logicalFunction
)
1370 case wxINVERT
: // NOT dst
1371 ::PenPat(&qd
.black
);
1374 case wxXOR
: // src XOR dst
1377 case wxOR_REVERSE
: // src OR (NOT dst)
1380 case wxSRC_INVERT
: // (NOT src)
1387 case wxAND_REVERSE
:// src AND (NOT dst)
1388 case wxAND
: // src AND dst
1389 case wxAND_INVERT
: // (NOT src) AND dst
1390 case wxNO_OP
: // dst
1391 case wxNOR
: // (NOT src) AND (NOT dst)
1392 case wxEQUIV
: // (NOT src) XOR dst
1393 case wxOR_INVERT
: // (NOT src) OR dst
1394 case wxNAND
: // (NOT src) OR (NOT dst)
1395 case wxOR
: // src OR dst
1397 case wxSRC_OR
: // source _bitmap_ OR destination
1398 case wxSRC_AND
: // source _bitmap_ AND destination
1404 static void wxMacGetHatchPattern(int hatchStyle
, Pattern
*pattern
)
1406 int thePatListID
= sysPatListID
;
1410 case wxBDIAGONAL_HATCH
:
1411 theIndex
= 34; // WCH: this is not good
1413 case wxFDIAGONAL_HATCH
:
1419 case wxHORIZONTAL_HATCH
:
1422 case wxVERTICAL_HATCH
:
1425 case wxCROSSDIAG_HATCH
:
1426 theIndex
= 4; // WCH: this is not good
1429 theIndex
= 1; // solid pattern
1432 GetIndPattern( pattern
, thePatListID
, theIndex
);
1435 void wxDC::MacInstallPen() const
1441 if ( m_macPenInstalled
)
1444 ::RGBForeColor(&m_pen
.GetColour().GetPixel() );
1445 ::RGBBackColor(&m_backgroundBrush
.GetColour().GetPixel() );
1448 int penWidth
= m_pen
.GetWidth();
1449 ::PenSize(penWidth
, penWidth
);
1451 int penStyle
= m_pen
.GetStyle();
1453 if (penStyle
== wxSOLID
)
1454 ::PenPat(&qd
.black
);
1455 else if (IS_HATCH(penStyle
))
1458 wxMacGetHatchPattern(penStyle
, &pat
);
1463 ::PenPat(&qd
.black
);
1466 short mode
= patCopy
;
1470 switch( m_logicalFunction
)
1475 case wxINVERT
: // NOT dst
1476 ::PenPat(&qd
.black
);
1479 case wxXOR
: // src XOR dst
1482 case wxOR_REVERSE
: // src OR (NOT dst)
1485 case wxSRC_INVERT
: // (NOT src)
1492 case wxAND_REVERSE
:// src AND (NOT dst)
1493 case wxAND
: // src AND dst
1494 case wxAND_INVERT
: // (NOT src) AND dst
1495 case wxNO_OP
: // dst
1496 case wxNOR
: // (NOT src) AND (NOT dst)
1497 case wxEQUIV
: // (NOT src) XOR dst
1498 case wxOR_INVERT
: // (NOT src) OR dst
1499 case wxNAND
: // (NOT src) OR (NOT dst)
1500 case wxOR
: // src OR dst
1502 case wxSRC_OR
: // source _bitmap_ OR destination
1503 case wxSRC_AND
: // source _bitmap_ AND destination
1507 m_macPenInstalled
= true ;
1508 m_macBrushInstalled
= false ;
1509 m_macFontInstalled
= false ;
1512 void wxDC::MacInstallBrush() const
1518 if ( m_macBrushInstalled
)
1523 ::RGBForeColor(&m_brush
.GetColour().GetPixel() );
1524 ::RGBBackColor(&m_backgroundBrush
.GetColour().GetPixel() );
1526 int brushStyle
= m_brush
.GetStyle();
1527 if (brushStyle
== wxSOLID
)
1528 ::PenPat(&qd
.black
);
1529 else if (IS_HATCH(brushStyle
))
1532 wxMacGetHatchPattern(brushStyle
, &pat
);
1537 ::PenPat(&qd
.black
);
1543 brushStyle
= m_backgroundBrush
.GetStyle();
1544 if (brushStyle
== wxSOLID
)
1545 ::BackPat(&qd
.white
);
1546 else if (IS_HATCH(brushStyle
))
1549 wxMacGetHatchPattern(brushStyle
, &pat
);
1554 ::BackPat(&qd
.white
);
1557 short mode
= patCopy
;
1561 switch( m_logicalFunction
)
1566 case wxINVERT
: // NOT dst
1567 ::PenPat(&qd
.black
);
1570 case wxXOR
: // src XOR dst
1573 case wxOR_REVERSE
: // src OR (NOT dst)
1576 case wxSRC_INVERT
: // (NOT src)
1583 case wxAND_REVERSE
:// src AND (NOT dst)
1584 case wxAND
: // src AND dst
1585 case wxAND_INVERT
: // (NOT src) AND dst
1586 case wxNO_OP
: // dst
1587 case wxNOR
: // (NOT src) AND (NOT dst)
1588 case wxEQUIV
: // (NOT src) XOR dst
1589 case wxOR_INVERT
: // (NOT src) OR dst
1590 case wxNAND
: // (NOT src) OR (NOT dst)
1591 case wxOR
: // src OR dst
1593 case wxSRC_OR
: // source _bitmap_ OR destination
1594 case wxSRC_AND
: // source _bitmap_ AND destination
1598 m_macBrushInstalled
= true ;
1599 m_macPenInstalled
= false ;
1600 m_macFontInstalled
= false ;