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( long x
, long y
, long width
, long 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::DestroyClippingRegion(void)
315 // Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
316 ::ClipRect(&m_macClipRect
);
319 void wxDC::GetClippingBox( long *x
, long *y
, long *width
, long *height
) const
323 if (x
) *x
= m_clipX1
;
324 if (y
) *y
= m_clipY1
;
325 if (width
) *width
= (m_clipX2
- m_clipX1
);
326 if (height
) *height
= (m_clipY2
- m_clipY1
);
329 *x
= *y
= *width
= *height
= 0;
332 void wxDC::GetSize( int* width
, int* height
) const
334 *width
= m_maxX
-m_minX
;
335 *height
= m_maxY
-m_minY
;
338 void wxDC::GetSizeMM( long* width
, long* height
) const
343 *width
= long( double(w
) / (m_scaleX
*m_mm_to_pix_x
) );
344 *height
= long( double(h
) / (m_scaleY
*m_mm_to_pix_y
) );
347 void wxDC::SetTextForeground( const wxColour
&col
)
350 m_textForegroundColour
= col
;
351 m_macFontInstalled
= false ;
354 void wxDC::SetTextBackground( const wxColour
&col
)
357 m_textBackgroundColour
= col
;
358 m_macFontInstalled
= false ;
361 void wxDC::SetMapMode( int mode
)
366 SetLogicalScale( twips2mm
*m_mm_to_pix_x
, twips2mm
*m_mm_to_pix_y
);
369 SetLogicalScale( pt2mm
*m_mm_to_pix_x
, pt2mm
*m_mm_to_pix_y
);
372 SetLogicalScale( m_mm_to_pix_x
, m_mm_to_pix_y
);
375 SetLogicalScale( m_mm_to_pix_x
/10.0, m_mm_to_pix_y
/10.0 );
379 SetLogicalScale( 1.0, 1.0 );
382 if (mode
!= wxMM_TEXT
)
384 m_needComputeScaleX
= TRUE
;
385 m_needComputeScaleY
= TRUE
;
389 void wxDC::SetUserScale( double x
, double y
)
391 // allow negative ? -> no
394 ComputeScaleAndOrigin();
397 void wxDC::GetUserScale( double *x
, double *y
)
399 if (x
) *x
= m_userScaleX
;
400 if (y
) *y
= m_userScaleY
;
403 void wxDC::SetLogicalScale( double x
, double y
)
408 ComputeScaleAndOrigin();
411 void wxDC::GetLogicalScale( double *x
, double *y
)
413 if (x
) *x
= m_logicalScaleX
;
414 if (y
) *y
= m_logicalScaleY
;
417 void wxDC::SetLogicalOrigin( long x
, long y
)
419 m_logicalOriginX
= x
* m_signX
; // is this still correct ?
420 m_logicalOriginY
= y
* m_signY
;
421 ComputeScaleAndOrigin();
424 void wxDC::GetLogicalOrigin( long *x
, long *y
)
426 if (x
) *x
= m_logicalOriginX
;
427 if (y
) *y
= m_logicalOriginY
;
430 void wxDC::SetDeviceOrigin( long x
, long y
)
432 m_externalDeviceOriginX
= x
;
433 m_externalDeviceOriginY
= y
;
434 ComputeScaleAndOrigin();
437 void wxDC::GetDeviceOrigin( long *x
, long *y
)
439 // if (x) *x = m_externalDeviceOriginX;
440 // if (y) *y = m_externalDeviceOriginY;
441 if (x
) *x
= m_deviceOriginX
;
442 if (y
) *y
= m_deviceOriginY
;
445 void wxDC::SetInternalDeviceOrigin( long x
, long y
)
447 m_internalDeviceOriginX
= x
;
448 m_internalDeviceOriginY
= y
;
449 ComputeScaleAndOrigin();
452 void wxDC::GetInternalDeviceOrigin( long *x
, long *y
)
454 if (x
) *x
= m_internalDeviceOriginX
;
455 if (y
) *y
= m_internalDeviceOriginY
;
458 void wxDC::SetAxisOrientation( bool xLeftRight
, bool yBottomUp
)
460 m_signX
= (xLeftRight
? 1 : -1);
461 m_signY
= (yBottomUp
? -1 : 1);
462 ComputeScaleAndOrigin();
465 long wxDC::DeviceToLogicalX(long x
) const
470 long wxDC::DeviceToLogicalY(long y
) const
475 long wxDC::DeviceToLogicalXRel(long x
) const
477 return XDEV2LOGREL(x
);
480 long wxDC::DeviceToLogicalYRel(long y
) const
482 return YDEV2LOGREL(y
);
485 long wxDC::LogicalToDeviceX(long x
) const
490 long wxDC::LogicalToDeviceY(long y
) const
495 long wxDC::LogicalToDeviceXRel(long x
) const
497 return XLOG2DEVREL(x
);
500 long wxDC::LogicalToDeviceYRel(long y
) const
502 return YLOG2DEVREL(y
);
505 void wxDC::CalcBoundingBox( long x
, long y
)
507 if (x
< m_minX
) m_minX
= x
;
508 if (y
< m_minY
) m_minY
= y
;
509 if (x
> m_maxX
) m_maxX
= x
;
510 if (y
> m_maxY
) m_maxY
= y
;
513 void wxDC::ComputeScaleAndOrigin(void)
515 // CMB: copy scale to see if it changes
516 double origScaleX
= m_scaleX
;
517 double origScaleY
= m_scaleY
;
519 m_scaleX
= m_logicalScaleX
* m_userScaleX
;
520 m_scaleY
= m_logicalScaleY
* m_userScaleY
;
522 m_deviceOriginX
= m_internalDeviceOriginX
+ m_externalDeviceOriginX
;
523 m_deviceOriginY
= m_internalDeviceOriginY
+ m_externalDeviceOriginY
;
525 // CMB: if scale has changed call SetPen to recalulate the line width
526 if (m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
)
528 // this is a bit artificial, but we need to force wxDC to think
529 // the pen has changed
530 wxPen
* pen
= & GetPen();
537 void wxDC::SetPalette( const wxPalette
& palette
)
541 void wxDC::SetBackgroundMode( int mode
)
543 m_backgroundMode
= mode
;
546 void wxDC::SetFont( const wxFont
&font
)
554 m_macFontInstalled
= false ;
557 void wxDC::SetPen( const wxPen
&pen
)
572 m_macPenInstalled
= false ;
575 void wxDC::SetBrush( const wxBrush
&brush
)
581 if (m_brush
== brush
)
585 m_macBrushInstalled
= false ;
588 void wxDC::SetBackground( const wxBrush
&brush
)
594 if (m_backgroundBrush
== brush
)
597 m_backgroundBrush
= brush
;
599 if (!m_backgroundBrush
.Ok())
601 m_macBrushInstalled
= false ;
604 void wxDC::SetLogicalFunction( int function
)
606 if (m_logicalFunction
== function
)
609 m_logicalFunction
= function
;
610 m_macFontInstalled
= false ;
611 m_macBrushInstalled
= false ;
612 m_macPenInstalled
= false ;
615 void wxDC::FloodFill( long x1
, long y1
, const wxColour
& col
, int style
)
619 bool wxDC::GetPixel( long x1
, long y1
, wxColour
*col
) const
624 void wxDC::DrawLine( long x1
, long y1
, long x2
, long y2
)
631 if (m_pen
.GetStyle() != wxTRANSPARENT
)
634 int offset
= (m_pen
.GetWidth() - 1) / 2 ;
635 long xx1
= XLOG2DEV(x1
);
636 long yy1
= YLOG2DEV(y1
);
637 long xx2
= XLOG2DEV(x2
);
638 long yy2
= YLOG2DEV(y2
);
640 ::MoveTo(xx1
- offset
,yy1
- offset
);
641 ::LineTo(xx2
- offset
, yy2
- offset
);
645 void wxDC::CrossHair( long x
, long y
)
649 void wxDC::DrawArc( long x1
, long y1
, long x2
, long y2
, long xc
, long yc
)
653 void wxDC::DrawEllipticArc( long x
, long y
, long width
, long height
, double sa
, double ea
)
657 void wxDC::DrawPoint( long x
, long y
)
664 if (m_pen
.GetStyle() != wxTRANSPARENT
)
667 long xx1
= XLOG2DEV(x
);
668 long yy1
= YLOG2DEV(y
);
671 ::LineTo(xx1
+1, yy1
+1);
675 void wxDC::DrawLines( int n
, wxPoint points
[], long xoffset
, long yoffset
)
681 if (m_pen
.GetStyle() == wxTRANSPARENT
)
686 int offset
= (m_pen
.GetWidth() - 1 ) / 2 ;
687 long x1
, x2
, y1
, y2
;
688 x1
= XLOG2DEV(points
[0].x
+ xoffset
);
689 y1
= YLOG2DEV(points
[0].y
+ yoffset
);
690 ::MoveTo(x1
- offset
,y1
- offset
);
692 for (int i
= 0; i
< n
-1; i
++)
694 long x2
= XLOG2DEV(points
[i
+1].x
+ xoffset
);
695 long y2
= YLOG2DEV(points
[i
+1].y
+ yoffset
);
696 ::LineTo(x2
- offset
, y2
- offset
);
700 void wxDC::DrawPolygon( int n
, wxPoint points
[], long xoffset
, long yoffset
,
707 PolyHandle polygon
= OpenPoly() ;
708 long x1
, x2
, y1
, y2
;
709 x1
= XLOG2DEV(points
[0].x
+ xoffset
);
710 y1
= YLOG2DEV(points
[0].y
+ yoffset
);
713 for (int i
= 0; i
< n
-1; i
++)
715 long x2
= XLOG2DEV(points
[i
+1].x
+ xoffset
);
716 long y2
= YLOG2DEV(points
[i
+1].y
+ yoffset
);
721 if (m_brush
.GetStyle() != wxTRANSPARENT
)
724 ::PaintPoly( polygon
) ;
727 if (m_pen
.GetStyle() != wxTRANSPARENT
)
730 ::FramePoly( polygon
) ;
732 KillPoly( polygon
) ;
735 void wxDC::DrawRectangle( long x
, long y
, long width
, long height
)
741 long xx
= XLOG2DEV(x
);
742 long yy
= YLOG2DEV(y
);
743 long ww
= m_signX
* XLOG2DEVREL(width
);
744 long hh
= m_signY
* YLOG2DEVREL(height
);
746 // CMB: draw nothing if transformed w or h is 0
747 if (ww
== 0 || hh
== 0)
750 // CMB: handle -ve width and/or height
763 Rect rect
= { yy
, xx
, yy
+ hh
, xx
+ ww
} ;
765 if (m_brush
.GetStyle() != wxTRANSPARENT
)
768 ::PaintRect( &rect
) ;
771 if (m_pen
.GetStyle() != wxTRANSPARENT
)
774 ::FrameRect( &rect
) ;
778 void wxDC::DrawRoundedRectangle( long x
, long y
, long width
, long height
, double radius
)
785 radius
= - radius
* ((width
< height
) ? width
: height
);
787 long xx
= XLOG2DEV(x
);
788 long yy
= YLOG2DEV(y
);
789 long ww
= m_signX
* XLOG2DEVREL(width
);
790 long hh
= m_signY
* YLOG2DEVREL(height
);
792 // CMB: draw nothing if transformed w or h is 0
793 if (ww
== 0 || hh
== 0)
796 // CMB: handle -ve width and/or height
809 Rect rect
= { yy
, xx
, yy
+ hh
, xx
+ ww
} ;
811 if (m_brush
.GetStyle() != wxTRANSPARENT
)
814 ::PaintRoundRect( &rect
, radius
* 2 , radius
* 2 ) ;
817 if (m_pen
.GetStyle() != wxTRANSPARENT
)
820 ::FrameRoundRect( &rect
, radius
* 2 , radius
* 2 ) ;
824 void wxDC::DrawEllipse( long x
, long y
, long width
, long height
)
830 long xx
= XLOG2DEV(x
);
831 long yy
= YLOG2DEV(y
);
832 long ww
= m_signX
* XLOG2DEVREL(width
);
833 long hh
= m_signY
* YLOG2DEVREL(height
);
835 // CMB: draw nothing if transformed w or h is 0
836 if (ww
== 0 || hh
== 0)
839 // CMB: handle -ve width and/or height
852 Rect rect
= { yy
, xx
, yy
+ hh
, xx
+ ww
} ;
854 if (m_brush
.GetStyle() != wxTRANSPARENT
)
857 ::PaintOval( &rect
) ;
860 if (m_pen
.GetStyle() != wxTRANSPARENT
)
863 ::FrameOval( &rect
) ;
867 // ----------------------------------- spline code ----------------------------------------
869 static void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
,
870 double a3
, double b3
, double a4
, double b4
);
871 static void wx_clear_stack(void);
872 static int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
, double *x3
,
873 double *y3
, double *x4
, double *y4
);
874 static void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
,
875 double x4
, double y4
);
876 static bool wx_spline_add_point(double x
, double y
);
877 static void wx_spline_draw_point_array(wxDC
*dc
);
879 static wxList wx_spline_point_list
;
881 #define half(z1, z2) ((z1+z2)/2.0)
884 /* iterative version */
886 static void wx_quadratic_spline(double a1
, double b1
, double a2
, double b2
, double a3
, double b3
, double a4
,
889 register double xmid
, ymid
;
890 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
893 wx_spline_push(a1
, b1
, a2
, b2
, a3
, b3
, a4
, b4
);
895 while (wx_spline_pop(&x1
, &y1
, &x2
, &y2
, &x3
, &y3
, &x4
, &y4
)) {
896 xmid
= (double)half(x2
, x3
);
897 ymid
= (double)half(y2
, y3
);
898 if (fabs(x1
- xmid
) < THRESHOLD
&& fabs(y1
- ymid
) < THRESHOLD
&&
899 fabs(xmid
- x4
) < THRESHOLD
&& fabs(ymid
- y4
) < THRESHOLD
) {
900 wx_spline_add_point( x1
, y1
);
901 wx_spline_add_point( xmid
, ymid
);
903 wx_spline_push(xmid
, ymid
, (double)half(xmid
, x3
), (double)half(ymid
, y3
),
904 (double)half(x3
, x4
), (double)half(y3
, y4
), x4
, y4
);
905 wx_spline_push(x1
, y1
, (double)half(x1
, x2
), (double)half(y1
, y2
),
906 (double)half(x2
, xmid
), (double)half(y2
, ymid
), xmid
, ymid
);
911 /* utilities used by spline drawing routines */
913 typedef struct wx_spline_stack_struct
{
914 double x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
;
917 #define SPLINE_STACK_DEPTH 20
918 static Stack wx_spline_stack
[SPLINE_STACK_DEPTH
];
919 static Stack
*wx_stack_top
;
920 static int wx_stack_count
;
922 static void wx_clear_stack(void)
924 wx_stack_top
= wx_spline_stack
;
928 static void wx_spline_push(double x1
, double y1
, double x2
, double y2
, double x3
, double y3
, double x4
, double y4
)
930 wx_stack_top
->x1
= x1
;
931 wx_stack_top
->y1
= y1
;
932 wx_stack_top
->x2
= x2
;
933 wx_stack_top
->y2
= y2
;
934 wx_stack_top
->x3
= x3
;
935 wx_stack_top
->y3
= y3
;
936 wx_stack_top
->x4
= x4
;
937 wx_stack_top
->y4
= y4
;
942 static int wx_spline_pop(double *x1
, double *y1
, double *x2
, double *y2
,
943 double *x3
, double *y3
, double *x4
, double *y4
)
945 if (wx_stack_count
== 0)
949 *x1
= wx_stack_top
->x1
;
950 *y1
= wx_stack_top
->y1
;
951 *x2
= wx_stack_top
->x2
;
952 *y2
= wx_stack_top
->y2
;
953 *x3
= wx_stack_top
->x3
;
954 *y3
= wx_stack_top
->y3
;
955 *x4
= wx_stack_top
->x4
;
956 *y4
= wx_stack_top
->y4
;
960 static bool wx_spline_add_point(double x
, double y
)
962 wxPoint
*point
= new wxPoint
;
965 wx_spline_point_list
.Append((wxObject
*)point
);
969 static void wx_spline_draw_point_array(wxDC
*dc
)
971 dc
->DrawLines(&wx_spline_point_list
, 0, 0 );
972 wxNode
*node
= wx_spline_point_list
.First();
975 wxPoint
*point
= (wxPoint
*)node
->Data();
978 node
= wx_spline_point_list
.First();
982 void wxDC::DrawSpline( wxList
*points
)
985 double cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
;
986 double x1
, y1
, x2
, y2
;
988 wxNode
*node
= points
->First();
989 p
= (wxPoint
*)node
->Data();
995 p
= (wxPoint
*)node
->Data();
999 cx1
= (double)((x1
+ x2
) / 2);
1000 cy1
= (double)((y1
+ y2
) / 2);
1001 cx2
= (double)((cx1
+ x2
) / 2);
1002 cy2
= (double)((cy1
+ y2
) / 2);
1004 wx_spline_add_point(x1
, y1
);
1006 while ((node
= node
->Next()) != NULL
)
1008 p
= (wxPoint
*)node
->Data();
1013 cx4
= (double)(x1
+ x2
) / 2;
1014 cy4
= (double)(y1
+ y2
) / 2;
1015 cx3
= (double)(x1
+ cx4
) / 2;
1016 cy3
= (double)(y1
+ cy4
) / 2;
1018 wx_quadratic_spline(cx1
, cy1
, cx2
, cy2
, cx3
, cy3
, cx4
, cy4
);
1022 cx2
= (double)(cx1
+ x2
) / 2;
1023 cy2
= (double)(cy1
+ y2
) / 2;
1026 wx_spline_add_point( cx1
, cy1
);
1027 wx_spline_add_point( x2
, y2
);
1029 wx_spline_draw_point_array( this );
1034 bool wxDC::CanDrawBitmap(void) const
1040 bool wxDC::Blit( long xdest
, long ydest
, long width
, long height
,
1041 wxDC
*source
, long xsrc
, long ysrc
, int logical_func
, bool useMask
)
1043 if (!Ok()) return FALSE
;
1046 CGrafPtr sourcePort
= (CGrafPtr
) source
->m_macPort
;
1047 PixMapHandle bmappixels
= GetGWorldPixMap( sourcePort
) ;
1048 RGBColor white
= { 0xFFFF, 0xFFFF,0xFFFF} ;
1049 RGBColor black
= { 0,0,0} ;
1050 // RGBForeColor( &black ) ;
1051 // RGBBackColor( &white ) ;
1052 RGBForeColor( &m_textForegroundColour
.GetPixel() ) ;
1053 RGBBackColor( &m_textBackgroundColour
.GetPixel() ) ;
1055 if ( LockPixels(bmappixels
) )
1057 Rect srcrect
, dstrect
;
1058 srcrect
.top
= source
->YLOG2DEV(ysrc
) ;
1059 srcrect
.left
= source
->XLOG2DEV(xsrc
) ;
1060 srcrect
.right
= source
->XLOG2DEV(xsrc
+ width
) ;
1061 srcrect
.bottom
= source
->YLOG2DEV(ysrc
+ height
) ;
1062 dstrect
.top
= YLOG2DEV(ydest
) ;
1063 dstrect
.left
= XLOG2DEV(xdest
) ;
1064 dstrect
.bottom
= YLOG2DEV(ydest
+ height
) ;
1065 dstrect
.right
= XLOG2DEV(xdest
+ width
) ;
1066 // ::ClipRect(&m_macClipRect);
1067 CopyBits( &GrafPtr( sourcePort
)->portBits
, &GrafPtr( m_macPort
)->portBits
,
1068 &srcrect
, &dstrect
, srcCopy
, NULL
) ;
1072 long x1 = XLOG2DEV(m_clipX1);
1073 long y1 = YLOG2DEV(m_clipY1);
1074 long x2 = XLOG2DEV(m_clipX2);
1075 long y2 = YLOG2DEV(m_clipY2);
1077 Rect clip = { y1 , x1 , y2 , x2 } ;
1081 UnlockPixels( bmappixels
) ;
1084 m_macPenInstalled
= false ;
1085 m_macBrushInstalled
= false ;
1086 m_macFontInstalled
= false ;
1091 void wxDC::DrawText( const wxString
&string
, long x
, long y
, bool use16
)
1097 long xx
= XLOG2DEV(x
);
1098 long yy
= YLOG2DEV(y
);
1100 // if (m_pen.GetStyle() != wxTRANSPARENT)
1104 Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
1106 ::ClipRect( &clip ) ;
1110 ::GetFontInfo( &fi
) ;
1113 ::MoveTo( xx
, yy
);
1114 if ( m_backgroundMode
== wxTRANSPARENT
)
1116 ::TextMode( srcOr
) ;
1120 ::TextMode( srcCopy
) ;
1123 const char *text
= NULL
;
1127 if ( wxApp::s_macDefaultEncodingIsPC
)
1129 macText
= wxMacMakeMacStringFromPC( string
) ;
1131 length
= macText
.Length() ;
1136 length
= string
.Length() ;
1145 if( text
[i
] == 13 || text
[i
] == 10)
1147 ::DrawText( text
, laststop
, i
- laststop
) ;
1149 ::MoveTo( xx
, yy
+ line
*(fi
.descent
+ fi
.ascent
+ fi
.leading
) );
1155 ::DrawText( text
, laststop
, i
- laststop
) ;
1156 ::TextMode( srcOr
) ;
1160 bool wxDC::CanGetTextExtent(void) const
1168 void wxDC::GetTextExtent( const wxString
&string
, long *width
, long *height
,
1169 long *descent
, long *externalLeading
,
1170 wxFont
*theFont
, bool use16
) const
1177 wxFont formerFont
= m_font
;
1181 wxFontRefData
* font
= (wxFontRefData
*) m_font
.GetRefData() ;
1185 long yy1
= YLOG2DEV(0);
1186 long yy2
= YLOG2DEV(font
->m_macFontSize
);
1188 ::TextFont( font
->m_macFontNum
) ;
1189 ::TextSize( abs( yy2
-yy1
) ) ;
1190 ::TextFace( font
->m_macFontStyle
) ;
1199 ::GetFontInfo( &fi
) ;
1201 *height
= fi
.descent
+ fi
.ascent
;
1202 *descent
= fi
.descent
;
1203 *externalLeading
= fi
.leading
;
1205 const char *text
= NULL
;
1208 if ( wxApp::s_macDefaultEncodingIsPC
)
1210 macText
= wxMacMakeMacStringFromPC( string
) ;
1212 length
= macText
.Length() ;
1217 length
= string
.Length() ;
1227 if( text
[i
] == 13 || text
[i
] == 10)
1229 *height
+= fi
.descent
+ fi
.ascent
+ fi
.leading
;
1230 curwidth
= ::TextWidth( text
, laststop
, i
- laststop
) ;
1231 if ( curwidth
> *width
)
1238 curwidth
= ::TextWidth( text
, laststop
, i
- laststop
) ;
1239 if ( curwidth
> *width
)
1244 m_macFontInstalled
= false ;
1248 long wxDC::GetCharWidth(void)
1258 ::GetFontInfo( &fi
) ;
1260 return (fi
.descent
+ fi
.ascent
) / 2 ;
1263 long wxDC::GetCharHeight(void)
1273 ::GetFontInfo( &fi
) ;
1275 return fi
.descent
+ fi
.ascent
;
1278 void wxDC::Clear(void)
1283 Rect rect
= { -32767 , -32767 , 32767 , 32767 } ;
1285 if (m_backgroundBrush
.GetStyle() != wxTRANSPARENT
)
1288 ::EraseRect( &rect
) ;
1292 void wxDC::MacInstallFont() const
1298 if ( m_macFontInstalled
)
1301 wxFontRefData
* font
= (wxFontRefData
*) m_font
.GetRefData() ;
1305 ::TextFont( font
->m_macFontNum
) ;
1306 ::TextSize( m_scaleY
* font
->m_macFontSize
) ;
1307 ::TextFace( font
->m_macFontStyle
) ;
1309 m_macFontInstalled
= true ;
1310 m_macBrushInstalled
= false ;
1311 m_macPenInstalled
= false ;
1313 ::RGBForeColor(&m_textForegroundColour
.GetPixel() );
1314 ::RGBBackColor(&m_textBackgroundColour
.GetPixel() );
1320 GetFNum( "\pGeneva" , &fontnum
) ;
1321 ::TextFont( fontnum
) ;
1322 ::TextSize( m_scaleY
* 10 ) ;
1325 // todo reset after spacing changes - or store the current spacing somewhere
1327 m_macFontInstalled
= true ;
1328 m_macBrushInstalled
= false ;
1329 m_macPenInstalled
= false ;
1330 ::RGBForeColor( &(m_textForegroundColour
.GetPixel()) );
1331 ::RGBBackColor(&m_textBackgroundColour
.GetPixel() );
1335 short mode
= patCopy
;
1339 switch( m_logicalFunction
)
1344 case wxINVERT
: // NOT dst
1345 ::PenPat(&qd
.black
);
1348 case wxXOR
: // src XOR dst
1351 case wxOR_REVERSE
: // src OR (NOT dst)
1354 case wxSRC_INVERT
: // (NOT src)
1361 case wxAND_REVERSE
:// src AND (NOT dst)
1362 case wxAND
: // src AND dst
1363 case wxAND_INVERT
: // (NOT src) AND dst
1364 case wxNO_OP
: // dst
1365 case wxNOR
: // (NOT src) AND (NOT dst)
1366 case wxEQUIV
: // (NOT src) XOR dst
1367 case wxOR_INVERT
: // (NOT src) OR dst
1368 case wxNAND
: // (NOT src) OR (NOT dst)
1369 case wxOR
: // src OR dst
1371 case wxSRC_OR
: // source _bitmap_ OR destination
1372 case wxSRC_AND
: // source _bitmap_ AND destination
1378 static void wxMacGetHatchPattern(int hatchStyle
, Pattern
*pattern
)
1380 int thePatListID
= sysPatListID
;
1384 case wxBDIAGONAL_HATCH
:
1385 theIndex
= 34; // WCH: this is not good
1387 case wxFDIAGONAL_HATCH
:
1393 case wxHORIZONTAL_HATCH
:
1396 case wxVERTICAL_HATCH
:
1399 case wxCROSSDIAG_HATCH
:
1400 theIndex
= 4; // WCH: this is not good
1403 theIndex
= 1; // solid pattern
1406 GetIndPattern( pattern
, thePatListID
, theIndex
);
1409 void wxDC::MacInstallPen() const
1415 if ( m_macPenInstalled
)
1418 ::RGBForeColor(&m_pen
.GetColour().GetPixel() );
1419 ::RGBBackColor(&m_backgroundBrush
.GetColour().GetPixel() );
1422 int penWidth
= m_pen
.GetWidth();
1423 ::PenSize(penWidth
, penWidth
);
1425 int penStyle
= m_pen
.GetStyle();
1427 if (penStyle
== wxSOLID
)
1428 ::PenPat(&qd
.black
);
1429 else if (IS_HATCH(penStyle
))
1432 wxMacGetHatchPattern(penStyle
, &pat
);
1437 ::PenPat(&qd
.black
);
1440 short mode
= patCopy
;
1444 switch( m_logicalFunction
)
1449 case wxINVERT
: // NOT dst
1450 ::PenPat(&qd
.black
);
1453 case wxXOR
: // src XOR dst
1456 case wxOR_REVERSE
: // src OR (NOT dst)
1459 case wxSRC_INVERT
: // (NOT src)
1466 case wxAND_REVERSE
:// src AND (NOT dst)
1467 case wxAND
: // src AND dst
1468 case wxAND_INVERT
: // (NOT src) AND dst
1469 case wxNO_OP
: // dst
1470 case wxNOR
: // (NOT src) AND (NOT dst)
1471 case wxEQUIV
: // (NOT src) XOR dst
1472 case wxOR_INVERT
: // (NOT src) OR dst
1473 case wxNAND
: // (NOT src) OR (NOT dst)
1474 case wxOR
: // src OR dst
1476 case wxSRC_OR
: // source _bitmap_ OR destination
1477 case wxSRC_AND
: // source _bitmap_ AND destination
1481 m_macPenInstalled
= true ;
1482 m_macBrushInstalled
= false ;
1483 m_macFontInstalled
= false ;
1486 void wxDC::MacInstallBrush() const
1492 if ( m_macBrushInstalled
)
1497 ::RGBForeColor(&m_brush
.GetColour().GetPixel() );
1498 ::RGBBackColor(&m_backgroundBrush
.GetColour().GetPixel() );
1500 int brushStyle
= m_brush
.GetStyle();
1501 if (brushStyle
== wxSOLID
)
1502 ::PenPat(&qd
.black
);
1503 else if (IS_HATCH(brushStyle
))
1506 wxMacGetHatchPattern(brushStyle
, &pat
);
1511 ::PenPat(&qd
.black
);
1517 brushStyle
= m_backgroundBrush
.GetStyle();
1518 if (brushStyle
== wxSOLID
)
1519 ::BackPat(&qd
.white
);
1520 else if (IS_HATCH(brushStyle
))
1523 wxMacGetHatchPattern(brushStyle
, &pat
);
1528 ::BackPat(&qd
.white
);
1531 short mode
= patCopy
;
1535 switch( m_logicalFunction
)
1540 case wxINVERT
: // NOT dst
1541 ::PenPat(&qd
.black
);
1544 case wxXOR
: // src XOR dst
1547 case wxOR_REVERSE
: // src OR (NOT dst)
1550 case wxSRC_INVERT
: // (NOT src)
1557 case wxAND_REVERSE
:// src AND (NOT dst)
1558 case wxAND
: // src AND dst
1559 case wxAND_INVERT
: // (NOT src) AND dst
1560 case wxNO_OP
: // dst
1561 case wxNOR
: // (NOT src) AND (NOT dst)
1562 case wxEQUIV
: // (NOT src) XOR dst
1563 case wxOR_INVERT
: // (NOT src) OR dst
1564 case wxNAND
: // (NOT src) OR (NOT dst)
1565 case wxOR
: // src OR dst
1567 case wxSRC_OR
: // source _bitmap_ OR destination
1568 case wxSRC_AND
: // source _bitmap_ AND destination
1572 m_macBrushInstalled
= true ;
1573 m_macPenInstalled
= false ;
1574 m_macFontInstalled
= false ;