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;
89 m_macFontInstalled
= false ;
90 m_macBrushInstalled
= false ;
91 m_macPenInstalled
= false ;
94 m_macLocalOrigin
.h
= m_macLocalOrigin
.v
= 0 ;
95 m_macClipRect
.left
= -32000 ;
96 m_macClipRect
.top
= -32000 ;
97 m_macClipRect
.right
= 32000 ;
98 m_macClipRect
.bottom
= 32000 ;
99 ::GetPort( &m_macOrigPort
) ;
106 ::SetOrigin( 0 , 0 ) ;
107 ::ClipRect( &m_macPort
->portRect
) ;
109 ::SetPort( m_macOrigPort
) ;
111 ++m_macCurrentPortId
;
114 void wxDC::MacSetupPort() const
116 m_macPortId
= ++m_macCurrentPortId
;
117 ::SetPort(m_macPort
);
118 ::SetOrigin(-m_macLocalOrigin
.h
, -m_macLocalOrigin
.v
);
119 ::ClipRect(&m_macClipRect
);
121 m_macFontInstalled
= false ;
122 m_macBrushInstalled
= false ;
123 m_macPenInstalled
= false ;
126 void wxDC::DrawBitmap( const wxBitmap
&bmp
, long x
, long y
, bool useMask
)
132 long xx1
= XLOG2DEV(x
);
133 long yy1
= YLOG2DEV(y
);
136 wxBitmapRefData
* bmap
= (wxBitmapRefData
*) ( bmp
.GetRefData()) ;
140 if ( bmap
->m_bitmapType
== kMacBitmapTypePict
)
142 Rect bitmaprect
= { 0 , 0 , bmap
->m_height
, bmap
->m_width
} ;
143 ::OffsetRect( &bitmaprect
, xx1
, yy1
) ;
144 ::DrawPicture( bmap
->m_hPict
, &bitmaprect
) ;
146 else if ( bmap
->m_bitmapType
== kMacBitmapTypeGrafWorld
)
148 if ( bmap
->m_hBitmap
)
150 GWorldPtr bmapworld
= bmap
->m_hBitmap
;
151 PixMapHandle bmappixels
;
152 RGBColor white
= { 0xFFFF, 0xFFFF,0xFFFF} ;
153 RGBColor black
= { 0,0,0} ;
154 RGBForeColor( &black
) ;
155 RGBBackColor( &white
) ;
156 // RGBForeColor( &m_textForegroundColour.GetPixel() ) ;
157 // RGBBackColor( &m_textBackgroundColour.GetPixel() ) ;
159 bmappixels
= GetGWorldPixMap( bmapworld
) ;
160 if ( LockPixels(bmappixels
) )
165 source
.right
= bmap
->m_width
;
166 source
.bottom
= bmap
->m_height
;
167 dest
.top
= YLOG2DEV(y
) ;
168 dest
.left
= XLOG2DEV(x
) ;
169 dest
.bottom
= YLOG2DEV(y
+ bmap
->m_height
) ;
170 dest
.right
= XLOG2DEV(x
+ bmap
->m_width
) ;
171 // ::ClipRect(&m_macClipRect);
172 CopyBits( &GrafPtr( bmapworld
)->portBits
, &GrafPtr( m_macPort
)->portBits
,
173 &source
, &dest
, srcCopy
, NULL
) ;
177 long x1 = XLOG2DEV(m_clipX1);
178 long y1 = YLOG2DEV(m_clipY1);
179 long x2 = XLOG2DEV(m_clipX2);
180 long y2 = YLOG2DEV(m_clipY2);
182 Rect clip = { y1 , x1 , y2 , x2 } ;
186 UnlockPixels( bmappixels
) ;
188 m_macPenInstalled
= false ;
189 m_macBrushInstalled
= false ;
190 m_macFontInstalled
= false ;
197 void wxDC::DrawIcon( const wxIcon
&icon
, long x
, long y
, bool useMask
)
203 long xx1
= XLOG2DEV(x
);
204 long yy1
= YLOG2DEV(y
);
207 wxIconRefData
* iconref
= (wxIconRefData
*) ( icon
.GetRefData()) ;
209 if ( iconref
&& iconref
->m_ok
&& iconref
->m_hIcon
)
211 Rect bitmaprect
= { 0 , 0 , iconref
->m_height
, iconref
->m_width
} ;
212 OffsetRect( &bitmaprect
, xx1
, yy1
) ;
213 PlotCIconHandle( &bitmaprect
, atNone
, ttNone
, iconref
->m_hIcon
) ;
218 void wxDC::DrawPoint( wxPoint
& point
)
220 DrawPoint( point
.x
, point
.y
);
223 void wxDC::DrawPolygon( wxList
*list
, long xoffset
, long yoffset
, int fillStyle
)
225 int n
= list
->Number();
226 wxPoint
*points
= new wxPoint
[n
];
229 for( wxNode
*node
= list
->First(); node
; node
= node
->Next() )
231 wxPoint
*point
= (wxPoint
*)node
->Data();
232 points
[i
].x
= point
->x
;
233 points
[i
++].y
= point
->y
;
235 DrawPolygon( n
, points
, xoffset
, yoffset
, fillStyle
);
239 void wxDC::DrawLines( wxList
*list
, long xoffset
, long yoffset
)
241 int n
= list
->Number();
242 wxPoint
*points
= new wxPoint
[n
];
245 for( wxNode
*node
= list
->First(); node
; node
= node
->Next() )
247 wxPoint
*point
= (wxPoint
*)node
->Data();
248 points
[i
].x
= point
->x
;
249 points
[i
++].y
= point
->y
;
251 DrawLines( n
, points
, xoffset
, yoffset
);
255 void wxDC::DrawSpline( long x1
, long y1
, long x2
, long y2
, long x3
, long y3
)
258 list
.Append( (wxObject
*)new wxPoint(x1
, y1
) );
259 list
.Append( (wxObject
*)new wxPoint(x2
, y2
) );
260 list
.Append( (wxObject
*)new wxPoint(x3
, y3
) );
262 wxNode
*node
= list
.First();
265 wxPoint
*p
= (wxPoint
*)node
->Data();
271 void wxDC::DrawSpline( int n
, wxPoint points
[] )
274 for (int i
= 0; i
< n
; i
++) list
.Append( (wxObject
*)&points
[i
] );
278 void wxDC::SetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
283 m_clipX1
= wxMax( m_clipX1
, x
) ;
284 m_clipY1
= wxMax( m_clipY1
,y
);
285 m_clipX2
= wxMin( m_clipX2
, (x
+ width
));
286 m_clipY2
= wxMin( m_clipY2
,(y
+ height
));
294 m_clipX2
= x
+ width
;
295 m_clipY2
= y
+ height
;
298 long x1
= XLOG2DEV(m_clipX1
);
299 long y1
= YLOG2DEV(m_clipY1
);
300 long x2
= XLOG2DEV(m_clipX2
);
301 long y2
= YLOG2DEV(m_clipY2
);
303 Rect clip
= { y1
, x1
, y2
, x2
} ;
305 ::ClipRect( &clip
) ;
309 void wxDC::SetClippingRegion(const wxRect
& rect
)
311 SetClippingRegion(rect
.x
, rect
.y
, rect
.width
, rect
.height
);
314 void wxDC::DestroyClippingRegion(void)
318 // Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
319 ::ClipRect(&m_macClipRect
);
322 void wxDC::GetClippingBox( wxCoord
*x
, wxCoord
*y
, wxCoord
*width
, wxCoord
*height
) const
326 if (x
) *x
= m_clipX1
;
327 if (y
) *y
= m_clipY1
;
328 if (width
) *width
= (m_clipX2
- m_clipX1
);
329 if (height
) *height
= (m_clipY2
- m_clipY1
);
332 *x
= *y
= *width
= *height
= 0;
335 void wxDC::GetClippingBox( long *x
, long *y
, long *width
, long *height
) const
339 if (x
) *x
= m_clipX1
;
340 if (y
) *y
= m_clipY1
;
341 if (width
) *width
= (m_clipX2
- m_clipX1
);
342 if (height
) *height
= (m_clipY2
- m_clipY1
);
345 *x
= *y
= *width
= *height
= 0;
348 void wxDC::GetClippingBox(wxRect
& rect
) const
350 // Necessary to use intermediate variables for 16-bit compilation
352 GetClippingBox(&x
, &y
, &w
, &h
);
353 rect
.x
= x
; rect
.y
= y
; rect
.width
= w
; rect
.height
= h
;
356 void wxDC::GetSize( int* width
, int* height
) const
358 *width
= m_maxX
-m_minX
;
359 *height
= m_maxY
-m_minY
;
362 void wxDC::GetSizeMM( long* width
, long* height
) const
367 *width
= long( double(w
) / (m_scaleX
*m_mm_to_pix_x
) );
368 *height
= long( double(h
) / (m_scaleY
*m_mm_to_pix_y
) );
371 void wxDC::SetTextForeground( const wxColour
&col
)
374 m_textForegroundColour
= col
;
375 m_macFontInstalled
= false ;
378 void wxDC::SetTextBackground( const wxColour
&col
)
381 m_textBackgroundColour
= col
;
382 m_macFontInstalled
= false ;
385 void wxDC::SetMapMode( int mode
)
390 SetLogicalScale( twips2mm
*m_mm_to_pix_x
, twips2mm
*m_mm_to_pix_y
);
393 SetLogicalScale( pt2mm
*m_mm_to_pix_x
, pt2mm
*m_mm_to_pix_y
);
396 SetLogicalScale( m_mm_to_pix_x
, m_mm_to_pix_y
);
399 SetLogicalScale( m_mm_to_pix_x
/10.0, m_mm_to_pix_y
/10.0 );
403 SetLogicalScale( 1.0, 1.0 );
406 if (mode
!= wxMM_TEXT
)
408 m_needComputeScaleX
= TRUE
;
409 m_needComputeScaleY
= TRUE
;
413 void wxDC::SetUserScale( double x
, double y
)
415 // allow negative ? -> no
418 ComputeScaleAndOrigin();
421 void wxDC::GetUserScale( double *x
, double *y
)
423 if (x
) *x
= m_userScaleX
;
424 if (y
) *y
= m_userScaleY
;
427 void wxDC::SetLogicalScale( double x
, double y
)
432 ComputeScaleAndOrigin();
435 void wxDC::GetLogicalScale( double *x
, double *y
)
437 if (x
) *x
= m_logicalScaleX
;
438 if (y
) *y
= m_logicalScaleY
;
441 void wxDC::SetLogicalOrigin( long x
, long y
)
443 m_logicalOriginX
= x
* m_signX
; // is this still correct ?
444 m_logicalOriginY
= y
* m_signY
;
445 ComputeScaleAndOrigin();
448 void wxDC::GetLogicalOrigin( long *x
, long *y
)
450 if (x
) *x
= m_logicalOriginX
;
451 if (y
) *y
= m_logicalOriginY
;
454 void wxDC::SetDeviceOrigin( long x
, long y
)
456 m_externalDeviceOriginX
= x
;
457 m_externalDeviceOriginY
= y
;
458 ComputeScaleAndOrigin();
461 void wxDC::GetDeviceOrigin( long *x
, long *y
)
463 // if (x) *x = m_externalDeviceOriginX;
464 // if (y) *y = m_externalDeviceOriginY;
465 if (x
) *x
= m_deviceOriginX
;
466 if (y
) *y
= m_deviceOriginY
;
469 void wxDC::SetInternalDeviceOrigin( long x
, long y
)
471 m_internalDeviceOriginX
= x
;
472 m_internalDeviceOriginY
= y
;
473 ComputeScaleAndOrigin();
476 void wxDC::GetInternalDeviceOrigin( long *x
, long *y
)
478 if (x
) *x
= m_internalDeviceOriginX
;
479 if (y
) *y
= m_internalDeviceOriginY
;
482 void wxDC::SetAxisOrientation( bool xLeftRight
, bool yBottomUp
)
484 m_signX
= (xLeftRight
? 1 : -1);
485 m_signY
= (yBottomUp
? -1 : 1);
486 ComputeScaleAndOrigin();
489 long wxDC::DeviceToLogicalX(long x
) const
494 long wxDC::DeviceToLogicalY(long y
) const
499 long wxDC::DeviceToLogicalXRel(long x
) const
501 return XDEV2LOGREL(x
);
504 long wxDC::DeviceToLogicalYRel(long y
) const
506 return YDEV2LOGREL(y
);
509 long wxDC::LogicalToDeviceX(long x
) const
514 long wxDC::LogicalToDeviceY(long y
) const
519 long wxDC::LogicalToDeviceXRel(long x
) const
521 return XLOG2DEVREL(x
);
524 long wxDC::LogicalToDeviceYRel(long y
) const
526 return YLOG2DEVREL(y
);
529 void wxDC::CalcBoundingBox( long x
, long y
)
531 if (x
< m_minX
) m_minX
= x
;
532 if (y
< m_minY
) m_minY
= y
;
533 if (x
> m_maxX
) m_maxX
= x
;
534 if (y
> m_maxY
) m_maxY
= y
;
537 void wxDC::ComputeScaleAndOrigin(void)
539 // CMB: copy scale to see if it changes
540 double origScaleX
= m_scaleX
;
541 double origScaleY
= m_scaleY
;
543 m_scaleX
= m_logicalScaleX
* m_userScaleX
;
544 m_scaleY
= m_logicalScaleY
* m_userScaleY
;
546 m_deviceOriginX
= m_internalDeviceOriginX
+ m_externalDeviceOriginX
;
547 m_deviceOriginY
= m_internalDeviceOriginY
+ m_externalDeviceOriginY
;
549 // CMB: if scale has changed call SetPen to recalulate the line width
550 if (m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
)
552 // this is a bit artificial, but we need to force wxDC to think
553 // the pen has changed
554 wxPen
* pen
= & GetPen();
561 void wxDC::SetPalette( const wxPalette
& palette
)
565 void wxDC::SetBackgroundMode( int mode
)
567 m_backgroundMode
= mode
;
570 void wxDC::SetFont( const wxFont
&font
)
578 m_macFontInstalled
= false ;
581 void wxDC::SetPen( const wxPen
&pen
)
596 m_macPenInstalled
= false ;
599 void wxDC::SetBrush( const wxBrush
&brush
)
605 if (m_brush
== brush
)
609 m_macBrushInstalled
= false ;
612 void wxDC::SetBackground( const wxBrush
&brush
)
618 if (m_backgroundBrush
== brush
)
621 m_backgroundBrush
= brush
;
623 if (!m_backgroundBrush
.Ok())
625 m_macBrushInstalled
= false ;
628 void wxDC::SetLogicalFunction( int function
)
630 if (m_logicalFunction
== function
)
633 m_logicalFunction
= function
;
634 m_macFontInstalled
= false ;
635 m_macBrushInstalled
= false ;
636 m_macPenInstalled
= false ;
639 void wxDC::FloodFill( long x1
, long y1
, const wxColour
& col
, int style
)
643 bool wxDC::GetPixel( long x1
, long y1
, wxColour
*col
) const
648 void wxDC::DrawLine( long x1
, long y1
, long x2
, long y2
)
655 if (m_pen
.GetStyle() != wxTRANSPARENT
)
658 int offset
= (m_pen
.GetWidth() - 1) / 2 ;
659 long xx1
= XLOG2DEV(x1
);
660 long yy1
= YLOG2DEV(y1
);
661 long xx2
= XLOG2DEV(x2
);
662 long yy2
= YLOG2DEV(y2
);
664 ::MoveTo(xx1
- offset
,yy1
- offset
);
665 ::LineTo(xx2
- offset
, yy2
- offset
);
669 void wxDC::CrossHair( long x
, long y
)
673 void wxDC::DrawArc( long x1
, long y1
, long x2
, long y2
, long xc
, long yc
)
677 void wxDC::DrawEllipticArc( long x
, long y
, long width
, long height
, double sa
, double ea
)
681 void wxDC::DrawPoint( long x
, long y
)
688 if (m_pen
.GetStyle() != wxTRANSPARENT
)
691 long xx1
= XLOG2DEV(x
);
692 long yy1
= YLOG2DEV(y
);
695 ::LineTo(xx1
+1, yy1
+1);
699 void wxDC::DrawLines( int n
, wxPoint points
[], long xoffset
, long yoffset
)
705 if (m_pen
.GetStyle() == wxTRANSPARENT
)
710 int offset
= (m_pen
.GetWidth() - 1 ) / 2 ;
711 long x1
, x2
, y1
, y2
;
712 x1
= XLOG2DEV(points
[0].x
+ xoffset
);
713 y1
= YLOG2DEV(points
[0].y
+ yoffset
);
714 ::MoveTo(x1
- offset
,y1
- offset
);
716 for (int i
= 0; i
< n
-1; i
++)
718 long x2
= XLOG2DEV(points
[i
+1].x
+ xoffset
);
719 long y2
= YLOG2DEV(points
[i
+1].y
+ yoffset
);
720 ::LineTo(x2
- offset
, y2
- offset
);
724 void wxDC::DrawPolygon( int n
, wxPoint points
[], long xoffset
, long yoffset
,
731 PolyHandle polygon
= OpenPoly() ;
732 long x1
, x2
, y1
, y2
;
733 x1
= XLOG2DEV(points
[0].x
+ xoffset
);
734 y1
= YLOG2DEV(points
[0].y
+ yoffset
);
737 for (int i
= 0; i
< n
-1; i
++)
739 long x2
= XLOG2DEV(points
[i
+1].x
+ xoffset
);
740 long y2
= YLOG2DEV(points
[i
+1].y
+ yoffset
);
745 if (m_brush
.GetStyle() != wxTRANSPARENT
)
748 ::PaintPoly( polygon
) ;
751 if (m_pen
.GetStyle() != wxTRANSPARENT
)
754 ::FramePoly( polygon
) ;
756 KillPoly( polygon
) ;
759 void wxDC::DrawRectangle( long x
, long y
, long width
, long height
)
765 long xx
= XLOG2DEV(x
);
766 long yy
= YLOG2DEV(y
);
767 long ww
= m_signX
* XLOG2DEVREL(width
);
768 long hh
= m_signY
* YLOG2DEVREL(height
);
770 // CMB: draw nothing if transformed w or h is 0
771 if (ww
== 0 || hh
== 0)
774 // CMB: handle -ve width and/or height
787 Rect rect
= { yy
, xx
, yy
+ hh
, xx
+ ww
} ;
789 if (m_brush
.GetStyle() != wxTRANSPARENT
)
792 ::PaintRect( &rect
) ;
795 if (m_pen
.GetStyle() != wxTRANSPARENT
)
798 ::FrameRect( &rect
) ;
802 void wxDC::DrawRoundedRectangle( long x
, long y
, long width
, long height
, double radius
)
809 radius
= - radius
* ((width
< height
) ? width
: height
);
811 long xx
= XLOG2DEV(x
);
812 long yy
= YLOG2DEV(y
);
813 long ww
= m_signX
* XLOG2DEVREL(width
);
814 long hh
= m_signY
* YLOG2DEVREL(height
);
816 // CMB: draw nothing if transformed w or h is 0
817 if (ww
== 0 || hh
== 0)
820 // CMB: handle -ve width and/or height
833 Rect rect
= { yy
, xx
, yy
+ hh
, xx
+ ww
} ;
835 if (m_brush
.GetStyle() != wxTRANSPARENT
)
838 ::PaintRoundRect( &rect
, radius
* 2 , radius
* 2 ) ;
841 if (m_pen
.GetStyle() != wxTRANSPARENT
)
844 ::FrameRoundRect( &rect
, radius
* 2 , radius
* 2 ) ;
848 void wxDC::DrawEllipse( long x
, long y
, long width
, long height
)
854 long xx
= XLOG2DEV(x
);
855 long yy
= YLOG2DEV(y
);
856 long ww
= m_signX
* XLOG2DEVREL(width
);
857 long hh
= m_signY
* YLOG2DEVREL(height
);
859 // CMB: draw nothing if transformed w or h is 0
860 if (ww
== 0 || hh
== 0)
863 // CMB: handle -ve width and/or height
876 Rect rect
= { yy
, xx
, yy
+ hh
, xx
+ ww
} ;
878 if (m_brush
.GetStyle() != wxTRANSPARENT
)
881 ::PaintOval( &rect
) ;
884 if (m_pen
.GetStyle() != wxTRANSPARENT
)
887 ::FrameOval( &rect
) ;
891 // ----------------------------------- spline code ----------------------------------------
893 static void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
894 double a3
, double b3
, double a4
, double b4
);
895 static void wx_clear_stack(void);
896 static int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
897 double *y3
, double *x4
, double *y4
);
898 static void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
899 double x4
, double y4
);
900 static bool wx_spline_add_point(double x
, double y
);
901 static void wx_spline_draw_point_array(wxDC
*dc
);
903 static wxList wx_spline_point_list
;
905 #define half(z1, z2) ((z1+z2)/2.0)
908 /* iterative version */
910 static void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
913 register double xmid
, ymid
;
914 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
917 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
919 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
920 xmid
= (double)half(x2
, x3
);
921 ymid
= (double)half(y2
, y3
);
922 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
923 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
924 wx_spline_add_point( x1
, y1
);
925 wx_spline_add_point( xmid
, ymid
);
927 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
928 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
929 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
930 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
935 /* utilities used by spline drawing routines */
937 typedef struct wx_spline_stack_struct
{
938 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
941 #define SPLINE_STACK_DEPTH 20
942 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
943 static Stack
*wx_stack_top
;
944 static int wx_stack_count
;
946 static void wx_clear_stack(void)
948 wx_stack_top
= wx_spline_stack
;
952 static void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
954 wx_stack_top
->x1
= x1
;
955 wx_stack_top
->y1
= y1
;
956 wx_stack_top
->x2
= x2
;
957 wx_stack_top
->y2
= y2
;
958 wx_stack_top
->x3
= x3
;
959 wx_stack_top
->y3
= y3
;
960 wx_stack_top
->x4
= x4
;
961 wx_stack_top
->y4
= y4
;
966 static int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
967 double *x3
, double *y3
, double *x4
, double *y4
)
969 if (wx_stack_count
== 0)
973 *x1
= wx_stack_top
->x1
;
974 *y1
= wx_stack_top
->y1
;
975 *x2
= wx_stack_top
->x2
;
976 *y2
= wx_stack_top
->y2
;
977 *x3
= wx_stack_top
->x3
;
978 *y3
= wx_stack_top
->y3
;
979 *x4
= wx_stack_top
->x4
;
980 *y4
= wx_stack_top
->y4
;
984 static bool wx_spline_add_point(double x
, double y
)
986 wxPoint
*point
= new wxPoint
;
989 wx_spline_point_list
.Append((wxObject
*)point
);
993 static void wx_spline_draw_point_array(wxDC
*dc
)
995 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
996 wxNode
*node
= wx_spline_point_list
.First();
999 wxPoint
*point
= (wxPoint
*)node
->Data();
1002 node
= wx_spline_point_list
.First();
1006 void wxDC::DrawSpline( wxList
*points
)
1009 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
1010 double x1
, y1
, x2
, y2
;
1012 wxNode
*node
= points
->First();
1013 p
= (wxPoint
*)node
->Data();
1018 node
= node
->Next();
1019 p
= (wxPoint
*)node
->Data();
1023 cx1
= (double)((x1
+ x2
) / 2);
1024 cy1
= (double)((y1
+ y2
) / 2);
1025 cx2
= (double)((cx1
+ x2
) / 2);
1026 cy2
= (double)((cy1
+ y2
) / 2);
1028 wx_spline_add_point(x1
, y1
);
1030 while ((node
= node
->Next()) != NULL
)
1032 p
= (wxPoint
*)node
->Data();
1037 cx4
= (double)(x1
+ x2
) / 2;
1038 cy4
= (double)(y1
+ y2
) / 2;
1039 cx3
= (double)(x1
+ cx4
) / 2;
1040 cy3
= (double)(y1
+ cy4
) / 2;
1042 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
1046 cx2
= (double)(cx1
+ x2
) / 2;
1047 cy2
= (double)(cy1
+ y2
) / 2;
1050 wx_spline_add_point( cx1
, cy1
);
1051 wx_spline_add_point( x2
, y2
);
1053 wx_spline_draw_point_array( this );
1058 bool wxDC::CanDrawBitmap(void) const
1064 bool wxDC::Blit( long xdest
, long ydest
, long width
, long height
,
1065 wxDC
*source
, long xsrc
, long ysrc
, int logical_func
, bool useMask
)
1067 if (!Ok()) return FALSE
;
1070 CGrafPtr sourcePort
= (CGrafPtr
) source
->m_macPort
;
1071 PixMapHandle bmappixels
= GetGWorldPixMap( sourcePort
) ;
1072 RGBColor white
= { 0xFFFF, 0xFFFF,0xFFFF} ;
1073 RGBColor black
= { 0,0,0} ;
1074 // RGBForeColor( &black ) ;
1075 // RGBBackColor( &white ) ;
1076 RGBForeColor( &m_textForegroundColour
.GetPixel() ) ;
1077 RGBBackColor( &m_textBackgroundColour
.GetPixel() ) ;
1079 if ( LockPixels(bmappixels
) )
1081 Rect srcrect
, dstrect
;
1082 srcrect
.top
= source
->YLOG2DEV(ysrc
) ;
1083 srcrect
.left
= source
->XLOG2DEV(xsrc
) ;
1084 srcrect
.right
= source
->XLOG2DEV(xsrc
+ width
) ;
1085 srcrect
.bottom
= source
->YLOG2DEV(ysrc
+ height
) ;
1086 dstrect
.top
= YLOG2DEV(ydest
) ;
1087 dstrect
.left
= XLOG2DEV(xdest
) ;
1088 dstrect
.bottom
= YLOG2DEV(ydest
+ height
) ;
1089 dstrect
.right
= XLOG2DEV(xdest
+ width
) ;
1090 // ::ClipRect(&m_macClipRect);
1091 CopyBits( &GrafPtr( sourcePort
)->portBits
, &GrafPtr( m_macPort
)->portBits
,
1092 &srcrect
, &dstrect
, srcCopy
, NULL
) ;
1096 long x1 = XLOG2DEV(m_clipX1);
1097 long y1 = YLOG2DEV(m_clipY1);
1098 long x2 = XLOG2DEV(m_clipX2);
1099 long y2 = YLOG2DEV(m_clipY2);
1101 Rect clip = { y1 , x1 , y2 , x2 } ;
1105 UnlockPixels( bmappixels
) ;
1108 m_macPenInstalled
= false ;
1109 m_macBrushInstalled
= false ;
1110 m_macFontInstalled
= false ;
1115 void wxDC::DrawText( const wxString
&string
, long x
, long y
, bool use16
)
1121 long xx
= XLOG2DEV(x
);
1122 long yy
= YLOG2DEV(y
);
1124 // if (m_pen.GetStyle() != wxTRANSPARENT)
1128 Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
1130 ::ClipRect( &clip ) ;
1134 ::GetFontInfo( &fi
) ;
1137 ::MoveTo( xx
, yy
);
1138 if ( m_backgroundMode
== wxTRANSPARENT
)
1140 ::TextMode( srcOr
) ;
1144 ::TextMode( srcCopy
) ;
1147 const char *text
= NULL
;
1151 if ( wxApp::s_macDefaultEncodingIsPC
)
1153 macText
= wxMacMakeMacStringFromPC( string
) ;
1155 length
= macText
.Length() ;
1160 length
= string
.Length() ;
1169 if( text
[i
] == 13 || text
[i
] == 10)
1171 ::DrawText( text
, laststop
, i
- laststop
) ;
1173 ::MoveTo( xx
, yy
+ line
*(fi
.descent
+ fi
.ascent
+ fi
.leading
) );
1179 ::DrawText( text
, laststop
, i
- laststop
) ;
1180 ::TextMode( srcOr
) ;
1184 bool wxDC::CanGetTextExtent(void) const
1192 void wxDC::GetTextExtent( const wxString
&string
, long *width
, long *height
,
1193 long *descent
, long *externalLeading
,
1194 wxFont
*theFont
, bool use16
) const
1201 wxFont formerFont
= m_font
;
1205 wxFontRefData
* font
= (wxFontRefData
*) m_font
.GetRefData() ;
1209 long yy1
= YLOG2DEV(0);
1210 long yy2
= YLOG2DEV(font
->m_macFontSize
);
1212 ::TextFont( font
->m_macFontNum
) ;
1213 ::TextSize( abs( yy2
-yy1
) ) ;
1214 ::TextFace( font
->m_macFontStyle
) ;
1223 ::GetFontInfo( &fi
) ;
1225 *height
= fi
.descent
+ fi
.ascent
;
1226 *descent
= fi
.descent
;
1227 *externalLeading
= fi
.leading
;
1229 const char *text
= NULL
;
1232 if ( wxApp::s_macDefaultEncodingIsPC
)
1234 macText
= wxMacMakeMacStringFromPC( string
) ;
1236 length
= macText
.Length() ;
1241 length
= string
.Length() ;
1251 if( text
[i
] == 13 || text
[i
] == 10)
1253 *height
+= fi
.descent
+ fi
.ascent
+ fi
.leading
;
1254 curwidth
= ::TextWidth( text
, laststop
, i
- laststop
) ;
1255 if ( curwidth
> *width
)
1262 curwidth
= ::TextWidth( text
, laststop
, i
- laststop
) ;
1263 if ( curwidth
> *width
)
1268 m_macFontInstalled
= false ;
1272 wxCoord
wxDC::GetCharWidth(void) const
1282 ::GetFontInfo( &fi
) ;
1284 return (fi
.descent
+ fi
.ascent
) / 2 ;
1287 wxCoord
wxDC::GetCharHeight(void) const
1297 ::GetFontInfo( &fi
) ;
1299 return fi
.descent
+ fi
.ascent
;
1302 void wxDC::Clear(void)
1307 Rect rect
= { -32767 , -32767 , 32767 , 32767 } ;
1309 if (m_backgroundBrush
.GetStyle() != wxTRANSPARENT
)
1312 ::EraseRect( &rect
) ;
1316 void wxDC::MacInstallFont() const
1322 if ( m_macFontInstalled
)
1325 wxFontRefData
* font
= (wxFontRefData
*) m_font
.GetRefData() ;
1329 ::TextFont( font
->m_macFontNum
) ;
1330 ::TextSize( m_scaleY
* font
->m_macFontSize
) ;
1331 ::TextFace( font
->m_macFontStyle
) ;
1333 m_macFontInstalled
= true ;
1334 m_macBrushInstalled
= false ;
1335 m_macPenInstalled
= false ;
1337 ::RGBForeColor(&m_textForegroundColour
.GetPixel() );
1338 ::RGBBackColor(&m_textBackgroundColour
.GetPixel() );
1344 GetFNum( "\pGeneva" , &fontnum
) ;
1345 ::TextFont( fontnum
) ;
1346 ::TextSize( m_scaleY
* 10 ) ;
1349 // todo reset after spacing changes - or store the current spacing somewhere
1351 m_macFontInstalled
= true ;
1352 m_macBrushInstalled
= false ;
1353 m_macPenInstalled
= false ;
1354 ::RGBForeColor( &(m_textForegroundColour
.GetPixel()) );
1355 ::RGBBackColor(&m_textBackgroundColour
.GetPixel() );
1359 short mode
= patCopy
;
1363 switch( m_logicalFunction
)
1368 case wxINVERT
: // NOT dst
1369 ::PenPat(&qd
.black
);
1372 case wxXOR
: // src XOR dst
1375 case wxOR_REVERSE
: // src OR (NOT dst)
1378 case wxSRC_INVERT
: // (NOT src)
1385 case wxAND_REVERSE
:// src AND (NOT dst)
1386 case wxAND
: // src AND dst
1387 case wxAND_INVERT
: // (NOT src) AND dst
1388 case wxNO_OP
: // dst
1389 case wxNOR
: // (NOT src) AND (NOT dst)
1390 case wxEQUIV
: // (NOT src) XOR dst
1391 case wxOR_INVERT
: // (NOT src) OR dst
1392 case wxNAND
: // (NOT src) OR (NOT dst)
1393 case wxOR
: // src OR dst
1395 case wxSRC_OR
: // source _bitmap_ OR destination
1396 case wxSRC_AND
: // source _bitmap_ AND destination
1402 static void wxMacGetHatchPattern(int hatchStyle
, Pattern
*pattern
)
1404 int thePatListID
= sysPatListID
;
1408 case wxBDIAGONAL_HATCH
:
1409 theIndex
= 34; // WCH: this is not good
1411 case wxFDIAGONAL_HATCH
:
1417 case wxHORIZONTAL_HATCH
:
1420 case wxVERTICAL_HATCH
:
1423 case wxCROSSDIAG_HATCH
:
1424 theIndex
= 4; // WCH: this is not good
1427 theIndex
= 1; // solid pattern
1430 GetIndPattern( pattern
, thePatListID
, theIndex
);
1433 void wxDC::MacInstallPen() const
1439 if ( m_macPenInstalled
)
1442 ::RGBForeColor(&m_pen
.GetColour().GetPixel() );
1443 ::RGBBackColor(&m_backgroundBrush
.GetColour().GetPixel() );
1446 int penWidth
= m_pen
.GetWidth();
1447 ::PenSize(penWidth
, penWidth
);
1449 int penStyle
= m_pen
.GetStyle();
1451 if (penStyle
== wxSOLID
)
1452 ::PenPat(&qd
.black
);
1453 else if (IS_HATCH(penStyle
))
1456 wxMacGetHatchPattern(penStyle
, &pat
);
1461 ::PenPat(&qd
.black
);
1464 short mode
= patCopy
;
1468 switch( m_logicalFunction
)
1473 case wxINVERT
: // NOT dst
1474 ::PenPat(&qd
.black
);
1477 case wxXOR
: // src XOR dst
1480 case wxOR_REVERSE
: // src OR (NOT dst)
1483 case wxSRC_INVERT
: // (NOT src)
1490 case wxAND_REVERSE
:// src AND (NOT dst)
1491 case wxAND
: // src AND dst
1492 case wxAND_INVERT
: // (NOT src) AND dst
1493 case wxNO_OP
: // dst
1494 case wxNOR
: // (NOT src) AND (NOT dst)
1495 case wxEQUIV
: // (NOT src) XOR dst
1496 case wxOR_INVERT
: // (NOT src) OR dst
1497 case wxNAND
: // (NOT src) OR (NOT dst)
1498 case wxOR
: // src OR dst
1500 case wxSRC_OR
: // source _bitmap_ OR destination
1501 case wxSRC_AND
: // source _bitmap_ AND destination
1505 m_macPenInstalled
= true ;
1506 m_macBrushInstalled
= false ;
1507 m_macFontInstalled
= false ;
1510 void wxDC::MacInstallBrush() const
1516 if ( m_macBrushInstalled
)
1521 ::RGBForeColor(&m_brush
.GetColour().GetPixel() );
1522 ::RGBBackColor(&m_backgroundBrush
.GetColour().GetPixel() );
1524 int brushStyle
= m_brush
.GetStyle();
1525 if (brushStyle
== wxSOLID
)
1526 ::PenPat(&qd
.black
);
1527 else if (IS_HATCH(brushStyle
))
1530 wxMacGetHatchPattern(brushStyle
, &pat
);
1535 ::PenPat(&qd
.black
);
1541 brushStyle
= m_backgroundBrush
.GetStyle();
1542 if (brushStyle
== wxSOLID
)
1543 ::BackPat(&qd
.white
);
1544 else if (IS_HATCH(brushStyle
))
1547 wxMacGetHatchPattern(brushStyle
, &pat
);
1552 ::BackPat(&qd
.white
);
1555 short mode
= patCopy
;
1559 switch( m_logicalFunction
)
1564 case wxINVERT
: // NOT dst
1565 ::PenPat(&qd
.black
);
1568 case wxXOR
: // src XOR dst
1571 case wxOR_REVERSE
: // src OR (NOT dst)
1574 case wxSRC_INVERT
: // (NOT src)
1581 case wxAND_REVERSE
:// src AND (NOT dst)
1582 case wxAND
: // src AND dst
1583 case wxAND_INVERT
: // (NOT src) AND dst
1584 case wxNO_OP
: // dst
1585 case wxNOR
: // (NOT src) AND (NOT dst)
1586 case wxEQUIV
: // (NOT src) XOR dst
1587 case wxOR_INVERT
: // (NOT src) OR dst
1588 case wxNAND
: // (NOT src) OR (NOT dst)
1589 case wxOR
: // src OR dst
1591 case wxSRC_OR
: // source _bitmap_ OR destination
1592 case wxSRC_AND
: // source _bitmap_ AND destination
1596 m_macBrushInstalled
= true ;
1597 m_macPenInstalled
= false ;
1598 m_macFontInstalled
= false ;