1 /////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "dc.h"
18 IMPLEMENT_ABSTRACT_CLASS(wxDC
, wxObject
)
20 //-----------------------------------------------------------------------------
22 //-----------------------------------------------------------------------------
24 #define mm2inches 0.0393700787402
25 #define inches2mm 25.4
26 #define mm2twips 56.6929133859
27 #define twips2mm 0.0176388888889
28 #define mm2pt 2.83464566929
29 #define pt2mm 0.352777777778
31 long wxDC::m_macCurrentPortId
= 1 ;
33 //-----------------------------------------------------------------------------
35 //-----------------------------------------------------------------------------
41 m_autoSetting
= FALSE
;
52 m_internalDeviceOriginX
= 0;
53 m_internalDeviceOriginY
= 0;
54 m_externalDeviceOriginX
= 0;
55 m_externalDeviceOriginY
= 0;
57 m_logicalScaleX
= 1.0;
58 m_logicalScaleY
= 1.0;
64 m_mappingMode
= wxMM_TEXT
;
65 m_needComputeScaleX
= FALSE
;
66 m_needComputeScaleY
= FALSE
;
68 m_signX
= 1; // default x-axis left to right
69 m_signY
= 1; // default y-axis top down
71 m_maxX
= m_maxY
= -100000;
72 m_minY
= m_minY
= 100000;
74 m_logicalFunction
= wxCOPY
;
75 // m_textAlignment = wxALIGN_TOP_LEFT;
76 m_backgroundMode
= wxTRANSPARENT
;
78 m_textForegroundColour
= *wxBLACK
;
79 m_textBackgroundColour
= *wxWHITE
;
81 m_font
= *wxNORMAL_FONT
;
82 m_brush
= *wxTRANSPARENT_BRUSH
;
83 m_backgroundBrush
= *wxWHITE_BRUSH
;
85 // m_palette = wxAPP_COLOURMAP;
90 m_macFontInstalled
= false ;
91 m_macBrushInstalled
= false ;
92 m_macPenInstalled
= false ;
95 m_macLocalOrigin
.h
= m_macLocalOrigin
.v
= 0 ;
96 m_macClipRect
.left
= -32000 ;
97 m_macClipRect
.top
= -32000 ;
98 m_macClipRect
.right
= 32000 ;
99 m_macClipRect
.bottom
= 32000 ;
100 ::GetPort( &m_macOrigPort
) ;
107 ::SetOrigin( 0 , 0 ) ;
108 ::ClipRect( &m_macPort
->portRect
) ;
110 ::SetPort( m_macOrigPort
) ;
112 ++m_macCurrentPortId
;
115 void wxDC::MacSetupPort() const
117 m_macPortId
= ++m_macCurrentPortId
;
118 ::SetPort(m_macPort
);
119 ::SetOrigin(-m_macLocalOrigin
.h
, -m_macLocalOrigin
.v
);
120 ::ClipRect(&m_macClipRect
);
122 m_macFontInstalled
= false ;
123 m_macBrushInstalled
= false ;
124 m_macPenInstalled
= false ;
127 void wxDC::DrawBitmap( const wxBitmap
&bmp
, long x
, long y
, bool useMask
)
133 long xx1
= XLOG2DEV(x
);
134 long yy1
= YLOG2DEV(y
);
137 wxBitmapRefData
* bmap
= (wxBitmapRefData
*) ( bmp
.GetRefData()) ;
141 if ( bmap
->m_bitmapType
== kMacBitmapTypePict
)
143 Rect bitmaprect
= { 0 , 0 , bmap
->m_height
, bmap
->m_width
} ;
144 ::OffsetRect( &bitmaprect
, xx1
, yy1
) ;
145 ::DrawPicture( bmap
->m_hPict
, &bitmaprect
) ;
147 else if ( bmap
->m_bitmapType
== kMacBitmapTypeGrafWorld
)
149 if ( bmap
->m_hBitmap
)
151 GWorldPtr bmapworld
= bmap
->m_hBitmap
;
152 PixMapHandle bmappixels
;
153 RGBColor white
= { 0xFFFF, 0xFFFF,0xFFFF} ;
154 RGBColor black
= { 0,0,0} ;
155 RGBForeColor( &black
) ;
156 RGBBackColor( &white
) ;
158 bmappixels
= GetGWorldPixMap( bmapworld
) ;
159 if ( LockPixels(bmappixels
) )
164 source
.right
= bmap
->m_width
;
165 source
.bottom
= bmap
->m_height
;
166 dest
.top
= YLOG2DEV(y
) ;
167 dest
.left
= XLOG2DEV(x
) ;
168 dest
.bottom
= YLOG2DEV(y
+ bmap
->m_height
) ;
169 dest
.right
= XLOG2DEV(x
+ bmap
->m_width
) ;
171 if ( useMask
&& bmp
.GetMask() )
173 if ( LockPixels( GetGWorldPixMap( bmp
.GetMask()->GetMaskBitmap( ) ) ) )
175 CopyMask( &GrafPtr( bmapworld
)->portBits
, &GrafPtr( bmp
.GetMask()->GetMaskBitmap( ) )->portBits
, &GrafPtr( m_macPort
)->portBits
,
176 &source
, &source
, &dest
) ;
177 UnlockPixels( GetGWorldPixMap( bmp
.GetMask()->GetMaskBitmap( ) ) ) ;
181 CopyBits( &GrafPtr( bmapworld
)->portBits
, &GrafPtr( m_macPort
)->portBits
,
182 &source
, &dest
, srcCopy
, NULL
) ;
184 UnlockPixels( bmappixels
) ;
186 m_macPenInstalled
= false ;
187 m_macBrushInstalled
= false ;
188 m_macFontInstalled
= false ;
195 void wxDC::DrawIcon( const wxIcon
&icon
, long x
, long y
, bool useMask
)
201 long xx1
= XLOG2DEV(x
);
202 long yy1
= YLOG2DEV(y
);
205 wxIconRefData
* iconref
= (wxIconRefData
*) ( icon
.GetRefData()) ;
207 if ( iconref
&& iconref
->m_ok
&& iconref
->m_hIcon
)
209 Rect bitmaprect
= { 0 , 0 , iconref
->m_height
, iconref
->m_width
} ;
210 OffsetRect( &bitmaprect
, xx1
, yy1
) ;
211 PlotCIconHandle( &bitmaprect
, atNone
, ttNone
, iconref
->m_hIcon
) ;
216 void wxDC::DrawPoint( wxPoint
& point
)
218 DrawPoint( point
.x
, point
.y
);
221 void wxDC::DrawPolygon( wxList
*list
, long xoffset
, long yoffset
, int fillStyle
)
223 int n
= list
->Number();
224 wxPoint
*points
= new wxPoint
[n
];
227 for( wxNode
*node
= list
->First(); node
; node
= node
->Next() )
229 wxPoint
*point
= (wxPoint
*)node
->Data();
230 points
[i
].x
= point
->x
;
231 points
[i
++].y
= point
->y
;
233 DrawPolygon( n
, points
, xoffset
, yoffset
, fillStyle
);
237 void wxDC::DrawLines( wxList
*list
, long xoffset
, long yoffset
)
239 int n
= list
->Number();
240 wxPoint
*points
= new wxPoint
[n
];
243 for( wxNode
*node
= list
->First(); node
; node
= node
->Next() )
245 wxPoint
*point
= (wxPoint
*)node
->Data();
246 points
[i
].x
= point
->x
;
247 points
[i
++].y
= point
->y
;
249 DrawLines( n
, points
, xoffset
, yoffset
);
253 void wxDC::DrawSpline( long x1
, long y1
, long x2
, long y2
, long x3
, long y3
)
256 list
.Append( (wxObject
*)new wxPoint(x1
, y1
) );
257 list
.Append( (wxObject
*)new wxPoint(x2
, y2
) );
258 list
.Append( (wxObject
*)new wxPoint(x3
, y3
) );
260 wxNode
*node
= list
.First();
263 wxPoint
*p
= (wxPoint
*)node
->Data();
269 void wxDC::DrawSpline( int n
, wxPoint points
[] )
272 for (int i
= 0; i
< n
; i
++) list
.Append( (wxObject
*)&points
[i
] );
276 void wxDC::SetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
281 m_clipX1
= wxMax( m_clipX1
, x
) ;
282 m_clipY1
= wxMax( m_clipY1
,y
);
283 m_clipX2
= wxMin( m_clipX2
, (x
+ width
));
284 m_clipY2
= wxMin( m_clipY2
,(y
+ height
));
292 m_clipX2
= x
+ width
;
293 m_clipY2
= y
+ height
;
296 long x1
= XLOG2DEV(m_clipX1
);
297 long y1
= YLOG2DEV(m_clipY1
);
298 long x2
= XLOG2DEV(m_clipX2
);
299 long y2
= YLOG2DEV(m_clipY2
);
301 Rect clip
= { y1
, x1
, y2
, x2
} ;
303 ::ClipRect( &clip
) ;
307 void wxDC::SetClippingRegion(const wxRect
& rect
)
309 SetClippingRegion(rect
.x
, rect
.y
, rect
.width
, rect
.height
);
312 void wxDC::DestroyClippingRegion(void)
316 // Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
317 ::ClipRect(&m_macClipRect
);
320 void wxDC::GetClippingBox( wxCoord
*x
, wxCoord
*y
, wxCoord
*width
, wxCoord
*height
) const
324 if (x
) *x
= m_clipX1
;
325 if (y
) *y
= m_clipY1
;
326 if (width
) *width
= (m_clipX2
- m_clipX1
);
327 if (height
) *height
= (m_clipY2
- m_clipY1
);
330 *x
= *y
= *width
= *height
= 0;
333 void wxDC::GetClippingBox( long *x
, long *y
, long *width
, long *height
) const
337 if (x
) *x
= m_clipX1
;
338 if (y
) *y
= m_clipY1
;
339 if (width
) *width
= (m_clipX2
- m_clipX1
);
340 if (height
) *height
= (m_clipY2
- m_clipY1
);
343 *x
= *y
= *width
= *height
= 0;
346 void wxDC::GetClippingBox(wxRect
& rect
) const
348 // Necessary to use intermediate variables for 16-bit compilation
350 GetClippingBox(&x
, &y
, &w
, &h
);
351 rect
.x
= x
; rect
.y
= y
; rect
.width
= w
; rect
.height
= h
;
354 void wxDC::GetSize( int* width
, int* height
) const
356 *width
= m_maxX
-m_minX
;
357 *height
= m_maxY
-m_minY
;
360 void wxDC::GetSizeMM( long* width
, long* height
) const
365 *width
= long( double(w
) / (m_scaleX
*m_mm_to_pix_x
) );
366 *height
= long( double(h
) / (m_scaleY
*m_mm_to_pix_y
) );
369 void wxDC::SetTextForeground( const wxColour
&col
)
372 m_textForegroundColour
= col
;
373 m_macFontInstalled
= false ;
376 void wxDC::SetTextBackground( const wxColour
&col
)
379 m_textBackgroundColour
= col
;
380 m_macFontInstalled
= false ;
383 void wxDC::SetMapMode( int mode
)
388 SetLogicalScale( twips2mm
*m_mm_to_pix_x
, twips2mm
*m_mm_to_pix_y
);
391 SetLogicalScale( pt2mm
*m_mm_to_pix_x
, pt2mm
*m_mm_to_pix_y
);
394 SetLogicalScale( m_mm_to_pix_x
, m_mm_to_pix_y
);
397 SetLogicalScale( m_mm_to_pix_x
/10.0, m_mm_to_pix_y
/10.0 );
401 SetLogicalScale( 1.0, 1.0 );
404 if (mode
!= wxMM_TEXT
)
406 m_needComputeScaleX
= TRUE
;
407 m_needComputeScaleY
= TRUE
;
411 void wxDC::SetUserScale( double x
, double y
)
413 // allow negative ? -> no
416 ComputeScaleAndOrigin();
419 void wxDC::GetUserScale( double *x
, double *y
)
421 if (x
) *x
= m_userScaleX
;
422 if (y
) *y
= m_userScaleY
;
425 void wxDC::SetLogicalScale( double x
, double y
)
430 ComputeScaleAndOrigin();
433 void wxDC::GetLogicalScale( double *x
, double *y
)
435 if (x
) *x
= m_logicalScaleX
;
436 if (y
) *y
= m_logicalScaleY
;
439 void wxDC::SetLogicalOrigin( long x
, long y
)
441 m_logicalOriginX
= x
* m_signX
; // is this still correct ?
442 m_logicalOriginY
= y
* m_signY
;
443 ComputeScaleAndOrigin();
446 void wxDC::GetLogicalOrigin( long *x
, long *y
)
448 if (x
) *x
= m_logicalOriginX
;
449 if (y
) *y
= m_logicalOriginY
;
452 void wxDC::SetDeviceOrigin( long x
, long y
)
454 m_externalDeviceOriginX
= x
;
455 m_externalDeviceOriginY
= y
;
456 ComputeScaleAndOrigin();
459 void wxDC::GetDeviceOrigin( long *x
, long *y
)
461 // if (x) *x = m_externalDeviceOriginX;
462 // if (y) *y = m_externalDeviceOriginY;
463 if (x
) *x
= m_deviceOriginX
;
464 if (y
) *y
= m_deviceOriginY
;
467 void wxDC::SetInternalDeviceOrigin( long x
, long y
)
469 m_internalDeviceOriginX
= x
;
470 m_internalDeviceOriginY
= y
;
471 ComputeScaleAndOrigin();
474 void wxDC::GetInternalDeviceOrigin( long *x
, long *y
)
476 if (x
) *x
= m_internalDeviceOriginX
;
477 if (y
) *y
= m_internalDeviceOriginY
;
480 void wxDC::SetAxisOrientation( bool xLeftRight
, bool yBottomUp
)
482 m_signX
= (xLeftRight
? 1 : -1);
483 m_signY
= (yBottomUp
? -1 : 1);
484 ComputeScaleAndOrigin();
487 long wxDC::DeviceToLogicalX(long x
) const
492 long wxDC::DeviceToLogicalY(long y
) const
497 long wxDC::DeviceToLogicalXRel(long x
) const
499 return XDEV2LOGREL(x
);
502 long wxDC::DeviceToLogicalYRel(long y
) const
504 return YDEV2LOGREL(y
);
507 long wxDC::LogicalToDeviceX(long x
) const
512 long wxDC::LogicalToDeviceY(long y
) const
517 long wxDC::LogicalToDeviceXRel(long x
) const
519 return XLOG2DEVREL(x
);
522 long wxDC::LogicalToDeviceYRel(long y
) const
524 return YLOG2DEVREL(y
);
527 void wxDC::CalcBoundingBox( long x
, long y
)
529 if (x
< m_minX
) m_minX
= x
;
530 if (y
< m_minY
) m_minY
= y
;
531 if (x
> m_maxX
) m_maxX
= x
;
532 if (y
> m_maxY
) m_maxY
= y
;
535 void wxDC::ComputeScaleAndOrigin(void)
537 // CMB: copy scale to see if it changes
538 double origScaleX
= m_scaleX
;
539 double origScaleY
= m_scaleY
;
541 m_scaleX
= m_logicalScaleX
* m_userScaleX
;
542 m_scaleY
= m_logicalScaleY
* m_userScaleY
;
544 m_deviceOriginX
= m_internalDeviceOriginX
+ m_externalDeviceOriginX
;
545 m_deviceOriginY
= m_internalDeviceOriginY
+ m_externalDeviceOriginY
;
547 // CMB: if scale has changed call SetPen to recalulate the line width
548 if (m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
)
550 // this is a bit artificial, but we need to force wxDC to think
551 // the pen has changed
552 wxPen
* pen
= & GetPen();
559 void wxDC::SetPalette( const wxPalette
& palette
)
563 void wxDC::SetBackgroundMode( int mode
)
565 m_backgroundMode
= mode
;
568 void wxDC::SetFont( const wxFont
&font
)
576 m_macFontInstalled
= false ;
579 void wxDC::SetPen( const wxPen
&pen
)
594 m_macPenInstalled
= false ;
597 void wxDC::SetBrush( const wxBrush
&brush
)
603 if (m_brush
== brush
)
607 m_macBrushInstalled
= false ;
610 void wxDC::SetBackground( const wxBrush
&brush
)
616 if (m_backgroundBrush
== brush
)
619 m_backgroundBrush
= brush
;
621 if (!m_backgroundBrush
.Ok())
623 m_macBrushInstalled
= false ;
626 void wxDC::SetLogicalFunction( int function
)
628 if (m_logicalFunction
== function
)
631 m_logicalFunction
= function
;
632 m_macFontInstalled
= false ;
633 m_macBrushInstalled
= false ;
634 m_macPenInstalled
= false ;
637 void wxDC::FloodFill( long x1
, long y1
, const wxColour
& col
, int style
)
641 bool wxDC::GetPixel( long x1
, long y1
, wxColour
*col
) const
646 void wxDC::DrawLine( long x1
, long y1
, long x2
, long y2
)
653 if (m_pen
.GetStyle() != wxTRANSPARENT
)
656 int offset
= (m_pen
.GetWidth() - 1) / 2 ;
657 long xx1
= XLOG2DEV(x1
);
658 long yy1
= YLOG2DEV(y1
);
659 long xx2
= XLOG2DEV(x2
);
660 long yy2
= YLOG2DEV(y2
);
662 ::MoveTo(xx1
- offset
,yy1
- offset
);
663 ::LineTo(xx2
- offset
, yy2
- offset
);
667 void wxDC::CrossHair( long x
, long y
)
671 void wxDC::DrawArc( long x1
, long y1
, long x2
, long y2
, long xc
, long yc
)
675 void wxDC::DrawEllipticArc( long x
, long y
, long width
, long height
, double sa
, double ea
)
679 void wxDC::DrawPoint( long x
, long y
)
686 if (m_pen
.GetStyle() != wxTRANSPARENT
)
689 long xx1
= XLOG2DEV(x
);
690 long yy1
= YLOG2DEV(y
);
693 ::LineTo(xx1
+1, yy1
+1);
697 void wxDC::DrawLines( int n
, wxPoint points
[], long xoffset
, long yoffset
)
703 if (m_pen
.GetStyle() == wxTRANSPARENT
)
708 int offset
= (m_pen
.GetWidth() - 1 ) / 2 ;
709 long x1
, x2
, y1
, y2
;
710 x1
= XLOG2DEV(points
[0].x
+ xoffset
);
711 y1
= YLOG2DEV(points
[0].y
+ yoffset
);
712 ::MoveTo(x1
- offset
,y1
- offset
);
714 for (int i
= 0; i
< n
-1; i
++)
716 long x2
= XLOG2DEV(points
[i
+1].x
+ xoffset
);
717 long y2
= YLOG2DEV(points
[i
+1].y
+ yoffset
);
718 ::LineTo(x2
- offset
, y2
- offset
);
722 void wxDC::DrawPolygon( int n
, wxPoint points
[], long xoffset
, long yoffset
,
729 PolyHandle polygon
= OpenPoly() ;
730 long x1
, x2
, y1
, y2
;
731 x1
= XLOG2DEV(points
[0].x
+ xoffset
);
732 y1
= YLOG2DEV(points
[0].y
+ yoffset
);
735 for (int i
= 0; i
< n
-1; i
++)
737 long x2
= XLOG2DEV(points
[i
+1].x
+ xoffset
);
738 long y2
= YLOG2DEV(points
[i
+1].y
+ yoffset
);
743 if (m_brush
.GetStyle() != wxTRANSPARENT
)
746 ::PaintPoly( polygon
) ;
749 if (m_pen
.GetStyle() != wxTRANSPARENT
)
752 ::FramePoly( polygon
) ;
754 KillPoly( polygon
) ;
757 void wxDC::DrawRectangle( long x
, long y
, long width
, long height
)
763 long xx
= XLOG2DEV(x
);
764 long yy
= YLOG2DEV(y
);
765 long ww
= m_signX
* XLOG2DEVREL(width
);
766 long hh
= m_signY
* YLOG2DEVREL(height
);
768 // CMB: draw nothing if transformed w or h is 0
769 if (ww
== 0 || hh
== 0)
772 // CMB: handle -ve width and/or height
785 Rect rect
= { yy
, xx
, yy
+ hh
, xx
+ ww
} ;
787 if (m_brush
.GetStyle() != wxTRANSPARENT
)
790 ::PaintRect( &rect
) ;
793 if (m_pen
.GetStyle() != wxTRANSPARENT
)
796 ::FrameRect( &rect
) ;
800 void wxDC::DrawRoundedRectangle( long x
, long y
, long width
, long height
, double radius
)
807 radius
= - radius
* ((width
< height
) ? width
: height
);
809 long xx
= XLOG2DEV(x
);
810 long yy
= YLOG2DEV(y
);
811 long ww
= m_signX
* XLOG2DEVREL(width
);
812 long hh
= m_signY
* YLOG2DEVREL(height
);
814 // CMB: draw nothing if transformed w or h is 0
815 if (ww
== 0 || hh
== 0)
818 // CMB: handle -ve width and/or height
831 Rect rect
= { yy
, xx
, yy
+ hh
, xx
+ ww
} ;
833 if (m_brush
.GetStyle() != wxTRANSPARENT
)
836 ::PaintRoundRect( &rect
, radius
* 2 , radius
* 2 ) ;
839 if (m_pen
.GetStyle() != wxTRANSPARENT
)
842 ::FrameRoundRect( &rect
, radius
* 2 , radius
* 2 ) ;
846 void wxDC::DrawEllipse( long x
, long y
, long width
, long height
)
852 long xx
= XLOG2DEV(x
);
853 long yy
= YLOG2DEV(y
);
854 long ww
= m_signX
* XLOG2DEVREL(width
);
855 long hh
= m_signY
* YLOG2DEVREL(height
);
857 // CMB: draw nothing if transformed w or h is 0
858 if (ww
== 0 || hh
== 0)
861 // CMB: handle -ve width and/or height
874 Rect rect
= { yy
, xx
, yy
+ hh
, xx
+ ww
} ;
876 if (m_brush
.GetStyle() != wxTRANSPARENT
)
879 ::PaintOval( &rect
) ;
882 if (m_pen
.GetStyle() != wxTRANSPARENT
)
885 ::FrameOval( &rect
) ;
889 // ----------------------------------- spline code ----------------------------------------
891 static void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
892 double a3
, double b3
, double a4
, double b4
);
893 static void wx_clear_stack(void);
894 static int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
895 double *y3
, double *x4
, double *y4
);
896 static void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
897 double x4
, double y4
);
898 static bool wx_spline_add_point(double x
, double y
);
899 static void wx_spline_draw_point_array(wxDC
*dc
);
901 static wxList wx_spline_point_list
;
903 #define half(z1, z2) ((z1+z2)/2.0)
906 /* iterative version */
908 static void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
911 register double xmid
, ymid
;
912 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
915 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
917 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
918 xmid
= (double)half(x2
, x3
);
919 ymid
= (double)half(y2
, y3
);
920 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
921 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
922 wx_spline_add_point( x1
, y1
);
923 wx_spline_add_point( xmid
, ymid
);
925 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
926 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
927 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
928 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
933 /* utilities used by spline drawing routines */
935 typedef struct wx_spline_stack_struct
{
936 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
939 #define SPLINE_STACK_DEPTH 20
940 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
941 static Stack
*wx_stack_top
;
942 static int wx_stack_count
;
944 static void wx_clear_stack(void)
946 wx_stack_top
= wx_spline_stack
;
950 static void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
952 wx_stack_top
->x1
= x1
;
953 wx_stack_top
->y1
= y1
;
954 wx_stack_top
->x2
= x2
;
955 wx_stack_top
->y2
= y2
;
956 wx_stack_top
->x3
= x3
;
957 wx_stack_top
->y3
= y3
;
958 wx_stack_top
->x4
= x4
;
959 wx_stack_top
->y4
= y4
;
964 static int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
965 double *x3
, double *y3
, double *x4
, double *y4
)
967 if (wx_stack_count
== 0)
971 *x1
= wx_stack_top
->x1
;
972 *y1
= wx_stack_top
->y1
;
973 *x2
= wx_stack_top
->x2
;
974 *y2
= wx_stack_top
->y2
;
975 *x3
= wx_stack_top
->x3
;
976 *y3
= wx_stack_top
->y3
;
977 *x4
= wx_stack_top
->x4
;
978 *y4
= wx_stack_top
->y4
;
982 static bool wx_spline_add_point(double x
, double y
)
984 wxPoint
*point
= new wxPoint
;
987 wx_spline_point_list
.Append((wxObject
*)point
);
991 static void wx_spline_draw_point_array(wxDC
*dc
)
993 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
994 wxNode
*node
= wx_spline_point_list
.First();
997 wxPoint
*point
= (wxPoint
*)node
->Data();
1000 node
= wx_spline_point_list
.First();
1004 void wxDC::DrawSpline( wxList
*points
)
1007 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
1008 double x1
, y1
, x2
, y2
;
1010 wxNode
*node
= points
->First();
1011 p
= (wxPoint
*)node
->Data();
1016 node
= node
->Next();
1017 p
= (wxPoint
*)node
->Data();
1021 cx1
= (double)((x1
+ x2
) / 2);
1022 cy1
= (double)((y1
+ y2
) / 2);
1023 cx2
= (double)((cx1
+ x2
) / 2);
1024 cy2
= (double)((cy1
+ y2
) / 2);
1026 wx_spline_add_point(x1
, y1
);
1028 while ((node
= node
->Next()) != NULL
)
1030 p
= (wxPoint
*)node
->Data();
1035 cx4
= (double)(x1
+ x2
) / 2;
1036 cy4
= (double)(y1
+ y2
) / 2;
1037 cx3
= (double)(x1
+ cx4
) / 2;
1038 cy3
= (double)(y1
+ cy4
) / 2;
1040 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
1044 cx2
= (double)(cx1
+ x2
) / 2;
1045 cy2
= (double)(cy1
+ y2
) / 2;
1048 wx_spline_add_point( cx1
, cy1
);
1049 wx_spline_add_point( x2
, y2
);
1051 wx_spline_draw_point_array( this );
1056 bool wxDC::CanDrawBitmap(void) const
1062 bool wxDC::Blit( long xdest
, long ydest
, long width
, long height
,
1063 wxDC
*source
, long xsrc
, long ysrc
, int logical_func
, bool useMask
)
1065 if (!Ok()) return FALSE
;
1068 CGrafPtr sourcePort
= (CGrafPtr
) source
->m_macPort
;
1069 PixMapHandle bmappixels
= GetGWorldPixMap( sourcePort
) ;
1070 RGBColor white
= { 0xFFFF, 0xFFFF,0xFFFF} ;
1071 RGBColor black
= { 0,0,0} ;
1072 RGBForeColor( &m_textForegroundColour
.GetPixel() ) ;
1073 RGBBackColor( &m_textBackgroundColour
.GetPixel() ) ;
1075 if ( LockPixels(bmappixels
) )
1077 Rect srcrect
, dstrect
;
1078 srcrect
.top
= source
->YLOG2DEV(ysrc
) ;
1079 srcrect
.left
= source
->XLOG2DEV(xsrc
) ;
1080 srcrect
.right
= source
->XLOG2DEV(xsrc
+ width
) ;
1081 srcrect
.bottom
= source
->YLOG2DEV(ysrc
+ height
) ;
1082 dstrect
.top
= YLOG2DEV(ydest
) ;
1083 dstrect
.left
= XLOG2DEV(xdest
) ;
1084 dstrect
.bottom
= YLOG2DEV(ydest
+ height
) ;
1085 dstrect
.right
= XLOG2DEV(xdest
+ width
) ;
1087 short mode
= (logical_func
== wxCOPY
? srcCopy
:
1088 // logical_func == wxCLEAR ? WHITENESS :
1089 // logical_func == wxSET ? BLACKNESS :
1090 logical_func
== wxINVERT
? hilite
:
1091 // logical_func == wxAND ? MERGECOPY :
1092 logical_func
== wxOR
? srcOr
:
1093 logical_func
== wxSRC_INVERT
? notSrcCopy
:
1094 logical_func
== wxXOR
? srcXor
:
1095 // logical_func == wxOR_REVERSE ? MERGEPAINT :
1096 // logical_func == wxAND_REVERSE ? SRCERASE :
1097 logical_func
== wxSRC_OR
? srcOr
:
1098 // logical_func == wxSRC_AND ? SRCAND :
1101 if ( useMask
&& source
->m_macMask
)
1103 wxASSERT( mode
== srcCopy
) ;
1104 if ( LockPixels( GetGWorldPixMap( source
->m_macMask
) ) )
1106 CopyMask( &GrafPtr( sourcePort
)->portBits
, &GrafPtr( source
->m_macMask
)->portBits
, &GrafPtr( m_macPort
)->portBits
,
1107 &srcrect
, &srcrect
, &dstrect
) ;
1108 UnlockPixels( GetGWorldPixMap( source
->m_macMask
) ) ;
1113 CopyBits( &GrafPtr( sourcePort
)->portBits
, &GrafPtr( m_macPort
)->portBits
,
1114 &srcrect
, &dstrect
, mode
, NULL
) ;
1116 UnlockPixels( bmappixels
) ;
1119 m_macPenInstalled
= false ;
1120 m_macBrushInstalled
= false ;
1121 m_macFontInstalled
= false ;
1126 void wxDC::DrawText( const wxString
&string
, long x
, long y
, bool use16
)
1132 long xx
= XLOG2DEV(x
);
1133 long yy
= YLOG2DEV(y
);
1135 // if (m_pen.GetStyle() != wxTRANSPARENT)
1139 Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
1141 ::ClipRect( &clip ) ;
1145 ::GetFontInfo( &fi
) ;
1148 ::MoveTo( xx
, yy
);
1149 if ( m_backgroundMode
== wxTRANSPARENT
)
1151 ::TextMode( srcOr
) ;
1155 ::TextMode( srcCopy
) ;
1158 const char *text
= NULL
;
1162 if ( wxApp::s_macDefaultEncodingIsPC
)
1164 macText
= wxMacMakeMacStringFromPC( string
) ;
1166 length
= macText
.Length() ;
1171 length
= string
.Length() ;
1180 if( text
[i
] == 13 || text
[i
] == 10)
1182 ::DrawText( text
, laststop
, i
- laststop
) ;
1184 ::MoveTo( xx
, yy
+ line
*(fi
.descent
+ fi
.ascent
+ fi
.leading
) );
1190 ::DrawText( text
, laststop
, i
- laststop
) ;
1191 ::TextMode( srcOr
) ;
1195 bool wxDC::CanGetTextExtent(void) const
1203 void wxDC::GetTextExtent( const wxString
&string
, long *width
, long *height
,
1204 long *descent
, long *externalLeading
,
1205 wxFont
*theFont
, bool use16
) const
1212 wxFont formerFont
= m_font
;
1216 wxFontRefData
* font
= (wxFontRefData
*) m_font
.GetRefData() ;
1220 long yy1
= YLOG2DEV(0);
1221 long yy2
= YLOG2DEV(font
->m_macFontSize
);
1223 ::TextFont( font
->m_macFontNum
) ;
1224 ::TextSize( abs( yy2
-yy1
) ) ;
1225 ::TextFace( font
->m_macFontStyle
) ;
1234 ::GetFontInfo( &fi
) ;
1236 *height
= fi
.descent
+ fi
.ascent
;
1237 *descent
= fi
.descent
;
1238 *externalLeading
= fi
.leading
;
1240 const char *text
= NULL
;
1243 if ( wxApp::s_macDefaultEncodingIsPC
)
1245 macText
= wxMacMakeMacStringFromPC( string
) ;
1247 length
= macText
.Length() ;
1252 length
= string
.Length() ;
1262 if( text
[i
] == 13 || text
[i
] == 10)
1264 *height
+= fi
.descent
+ fi
.ascent
+ fi
.leading
;
1265 curwidth
= ::TextWidth( text
, laststop
, i
- laststop
) ;
1266 if ( curwidth
> *width
)
1273 curwidth
= ::TextWidth( text
, laststop
, i
- laststop
) ;
1274 if ( curwidth
> *width
)
1279 m_macFontInstalled
= false ;
1283 wxCoord
wxDC::GetCharWidth(void) const
1293 ::GetFontInfo( &fi
) ;
1295 return (fi
.descent
+ fi
.ascent
) / 2 ;
1298 wxCoord
wxDC::GetCharHeight(void) const
1308 ::GetFontInfo( &fi
) ;
1310 return fi
.descent
+ fi
.ascent
;
1313 void wxDC::Clear(void)
1318 Rect rect
= { -32767 , -32767 , 32767 , 32767 } ;
1320 if (m_backgroundBrush
.GetStyle() != wxTRANSPARENT
)
1323 ::EraseRect( &rect
) ;
1327 void wxDC::MacInstallFont() const
1333 if ( m_macFontInstalled
)
1336 wxFontRefData
* font
= (wxFontRefData
*) m_font
.GetRefData() ;
1340 ::TextFont( font
->m_macFontNum
) ;
1341 ::TextSize( m_scaleY
* font
->m_macFontSize
) ;
1342 ::TextFace( font
->m_macFontStyle
) ;
1344 m_macFontInstalled
= true ;
1345 m_macBrushInstalled
= false ;
1346 m_macPenInstalled
= false ;
1348 ::RGBForeColor(&m_textForegroundColour
.GetPixel() );
1349 ::RGBBackColor(&m_textBackgroundColour
.GetPixel() );
1355 GetFNum( "\pGeneva" , &fontnum
) ;
1356 ::TextFont( fontnum
) ;
1357 ::TextSize( m_scaleY
* 10 ) ;
1360 // todo reset after spacing changes - or store the current spacing somewhere
1362 m_macFontInstalled
= true ;
1363 m_macBrushInstalled
= false ;
1364 m_macPenInstalled
= false ;
1365 ::RGBForeColor( &(m_textForegroundColour
.GetPixel()) );
1366 ::RGBBackColor(&m_textBackgroundColour
.GetPixel() );
1370 short mode
= patCopy
;
1374 switch( m_logicalFunction
)
1379 case wxINVERT
: // NOT dst
1380 ::PenPat(&qd
.black
);
1383 case wxXOR
: // src XOR dst
1386 case wxOR_REVERSE
: // src OR (NOT dst)
1389 case wxSRC_INVERT
: // (NOT src)
1396 case wxAND_REVERSE
:// src AND (NOT dst)
1397 case wxAND
: // src AND dst
1398 case wxAND_INVERT
: // (NOT src) AND dst
1399 case wxNO_OP
: // dst
1400 case wxNOR
: // (NOT src) AND (NOT dst)
1401 case wxEQUIV
: // (NOT src) XOR dst
1402 case wxOR_INVERT
: // (NOT src) OR dst
1403 case wxNAND
: // (NOT src) OR (NOT dst)
1404 case wxOR
: // src OR dst
1406 case wxSRC_OR
: // source _bitmap_ OR destination
1407 case wxSRC_AND
: // source _bitmap_ AND destination
1413 static void wxMacGetHatchPattern(int hatchStyle
, Pattern
*pattern
)
1415 int thePatListID
= sysPatListID
;
1419 case wxBDIAGONAL_HATCH
:
1420 theIndex
= 34; // WCH: this is not good
1422 case wxFDIAGONAL_HATCH
:
1428 case wxHORIZONTAL_HATCH
:
1431 case wxVERTICAL_HATCH
:
1434 case wxCROSSDIAG_HATCH
:
1435 theIndex
= 4; // WCH: this is not good
1438 theIndex
= 1; // solid pattern
1441 GetIndPattern( pattern
, thePatListID
, theIndex
);
1444 void wxDC::MacInstallPen() const
1450 if ( m_macPenInstalled
)
1453 ::RGBForeColor(&m_pen
.GetColour().GetPixel() );
1454 ::RGBBackColor(&m_backgroundBrush
.GetColour().GetPixel() );
1457 int penWidth
= m_pen
.GetWidth();
1458 ::PenSize(penWidth
, penWidth
);
1460 int penStyle
= m_pen
.GetStyle();
1462 if (penStyle
== wxSOLID
)
1463 ::PenPat(&qd
.black
);
1464 else if (IS_HATCH(penStyle
))
1467 wxMacGetHatchPattern(penStyle
, &pat
);
1472 ::PenPat(&qd
.black
);
1475 short mode
= patCopy
;
1479 switch( m_logicalFunction
)
1484 case wxINVERT
: // NOT dst
1485 ::PenPat(&qd
.black
);
1488 case wxXOR
: // src XOR dst
1491 case wxOR_REVERSE
: // src OR (NOT dst)
1494 case wxSRC_INVERT
: // (NOT src)
1501 case wxAND_REVERSE
:// src AND (NOT dst)
1502 case wxAND
: // src AND dst
1503 case wxAND_INVERT
: // (NOT src) AND dst
1504 case wxNO_OP
: // dst
1505 case wxNOR
: // (NOT src) AND (NOT dst)
1506 case wxEQUIV
: // (NOT src) XOR dst
1507 case wxOR_INVERT
: // (NOT src) OR dst
1508 case wxNAND
: // (NOT src) OR (NOT dst)
1509 case wxOR
: // src OR dst
1511 case wxSRC_OR
: // source _bitmap_ OR destination
1512 case wxSRC_AND
: // source _bitmap_ AND destination
1516 m_macPenInstalled
= true ;
1517 m_macBrushInstalled
= false ;
1518 m_macFontInstalled
= false ;
1521 void wxDC::MacInstallBrush() const
1527 if ( m_macBrushInstalled
)
1532 ::RGBForeColor(&m_brush
.GetColour().GetPixel() );
1533 ::RGBBackColor(&m_backgroundBrush
.GetColour().GetPixel() );
1535 int brushStyle
= m_brush
.GetStyle();
1536 if (brushStyle
== wxSOLID
)
1537 ::PenPat(&qd
.black
);
1538 else if (IS_HATCH(brushStyle
))
1541 wxMacGetHatchPattern(brushStyle
, &pat
);
1546 ::PenPat(&qd
.black
);
1552 brushStyle
= m_backgroundBrush
.GetStyle();
1553 if (brushStyle
== wxSOLID
)
1554 ::BackPat(&qd
.white
);
1555 else if (IS_HATCH(brushStyle
))
1558 wxMacGetHatchPattern(brushStyle
, &pat
);
1563 ::BackPat(&qd
.white
);
1566 short mode
= patCopy
;
1570 switch( m_logicalFunction
)
1575 case wxINVERT
: // NOT dst
1576 ::PenPat(&qd
.black
);
1579 case wxXOR
: // src XOR dst
1582 case wxOR_REVERSE
: // src OR (NOT dst)
1585 case wxSRC_INVERT
: // (NOT src)
1592 case wxAND_REVERSE
:// src AND (NOT dst)
1593 case wxAND
: // src AND dst
1594 case wxAND_INVERT
: // (NOT src) AND dst
1595 case wxNO_OP
: // dst
1596 case wxNOR
: // (NOT src) AND (NOT dst)
1597 case wxEQUIV
: // (NOT src) XOR dst
1598 case wxOR_INVERT
: // (NOT src) OR dst
1599 case wxNAND
: // (NOT src) OR (NOT dst)
1600 case wxOR
: // src OR dst
1602 case wxSRC_OR
: // source _bitmap_ OR destination
1603 case wxSRC_AND
: // source _bitmap_ AND destination
1607 m_macBrushInstalled
= true ;
1608 m_macPenInstalled
= false ;
1609 m_macFontInstalled
= false ;