]>
git.saurik.com Git - wxWidgets.git/blob - src/common/graphcmn.cpp
9de68440ef1d6680264f004ad47668c0a058f191
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/graphcmn.cpp
3 // Purpose: graphics context methods common to all platforms
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
15 #if defined(__BORLANDC__)
19 #if wxUSE_GRAPHICS_CONTEXT
21 #include "wx/graphics.h"
25 #include "wx/bitmap.h"
26 #include "wx/dcmemory.h"
27 #include "wx/region.h"
30 #if !defined(wxMAC_USE_CORE_GRAPHICS_BLEND_MODES)
31 #define wxMAC_USE_CORE_GRAPHICS_BLEND_MODES 0
34 //-----------------------------------------------------------------------------
36 //-----------------------------------------------------------------------------
38 static const double RAD2DEG
= 180.0 / M_PI
;
40 //-----------------------------------------------------------------------------
42 //-----------------------------------------------------------------------------
44 static inline double DegToRad(double deg
)
46 return (deg
* M_PI
) / 180.0;
49 //-----------------------------------------------------------------------------
51 IMPLEMENT_DYNAMIC_CLASS(wxGraphicsObject
, wxObject
)
53 IMPLEMENT_ABSTRACT_CLASS(wxGraphicsRenderer
, wxObject
)
55 IMPLEMENT_ABSTRACT_CLASS(wxGraphicsMatrix
, wxGraphicsObject
)
57 IMPLEMENT_ABSTRACT_CLASS(wxGraphicsPath
, wxGraphicsObject
)
59 IMPLEMENT_ABSTRACT_CLASS(wxGraphicsPen
, wxGraphicsObject
)
61 IMPLEMENT_ABSTRACT_CLASS(wxGraphicsBrush
, wxGraphicsObject
)
63 IMPLEMENT_ABSTRACT_CLASS(wxGraphicsFont
, wxGraphicsObject
)
65 wxPoint2DDouble
wxGraphicsPath::GetCurrentPoint()
69 return wxPoint2DDouble(x
,y
);
72 void wxGraphicsPath::MoveToPoint( const wxPoint2DDouble
& p
)
74 MoveToPoint( p
.m_x
, p
.m_y
);
77 void wxGraphicsPath::AddLineToPoint( const wxPoint2DDouble
& p
)
79 AddLineToPoint( p
.m_x
, p
.m_y
);
82 void wxGraphicsPath::AddCurveToPoint( const wxPoint2DDouble
& c1
, const wxPoint2DDouble
& c2
, const wxPoint2DDouble
& e
)
84 AddCurveToPoint(c1
.m_x
, c1
.m_y
, c2
.m_x
, c2
.m_y
, e
.m_x
, e
.m_y
);
87 void wxGraphicsPath::AddArc( const wxPoint2DDouble
& c
, wxDouble r
, wxDouble startAngle
, wxDouble endAngle
, bool clockwise
)
89 AddArc(c
.m_x
, c
.m_y
, r
, startAngle
, endAngle
, clockwise
);
92 wxRect2DDouble
wxGraphicsPath::GetBox()
96 return wxRect2DDouble( x
,y
,w
,h
);
103 void wxGraphicsPath::AddQuadCurveToPoint( wxDouble cx
, wxDouble cy
, wxDouble x
, wxDouble y
)
105 // calculate using degree elevation to a cubic bezier
109 wxPoint2DDouble start
= GetCurrentPoint();
110 wxPoint2DDouble
end(x
,y
);
111 wxPoint2DDouble
c(cx
,cy
);
112 c1
= wxDouble(1/3.0) * start
+ wxDouble(2/3.0) * c
;
113 c2
= wxDouble(2/3.0) * c
+ wxDouble(1/3.0) * end
;
114 AddCurveToPoint(c1
.m_x
,c1
.m_y
,c2
.m_x
,c2
.m_y
,x
,y
);
117 void wxGraphicsPath::AddRectangle( wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h
)
120 AddLineToPoint(x
,y
+h
);
121 AddLineToPoint(x
+w
,y
+h
);
122 AddLineToPoint(x
+w
,y
);
126 void wxGraphicsPath::AddCircle( wxDouble x
, wxDouble y
, wxDouble r
)
129 AddArc( x
,y
,r
,0,2*M_PI
,false);
133 // draws a an arc to two tangents connecting (current) to (x1,y1) and (x1,y1) to (x2,y2), also a straight line from (current) to (x1,y1)
134 void wxGraphicsPath::AddArcToPoint( wxDouble x1
, wxDouble y1
, wxDouble x2
, wxDouble y2
, wxDouble r
)
136 wxPoint2DDouble current
= GetCurrentPoint();
137 wxPoint2DDouble
p1(x1
,y1
);
138 wxPoint2DDouble
p2(x2
,y2
);
140 wxPoint2DDouble v1
= current
- p1
;
142 wxPoint2DDouble v2
= p2
- p1
;
145 wxDouble alpha
= v1
.GetVectorAngle() - v2
.GetVectorAngle();
149 // TODO obtuse angles
151 alpha
= DegToRad(alpha
);
153 wxDouble dist
= r
/ sin(alpha
/2) * cos(alpha
/2);
154 // calculate tangential points
155 wxPoint2DDouble t1
= dist
*v1
+ p1
;
156 wxPoint2DDouble t2
= dist
*v2
+ p1
;
158 wxPoint2DDouble nv1
= v1
;
159 nv1
.SetVectorAngle(v1
.GetVectorAngle()-90);
160 wxPoint2DDouble c
= t1
+ r
*nv1
;
162 wxDouble a1
= v1
.GetVectorAngle()+90;
163 wxDouble a2
= v2
.GetVectorAngle()-90;
166 AddArc(c
.m_x
,c
.m_y
,r
,DegToRad(a1
),DegToRad(a2
),true);
170 //-----------------------------------------------------------------------------
171 // wxGraphicsContext Convenience Methods
172 //-----------------------------------------------------------------------------
174 IMPLEMENT_ABSTRACT_CLASS(wxGraphicsContext
, wxObject
)
177 wxGraphicsContext::wxGraphicsContext(wxGraphicsRenderer
* renderer
) : wxGraphicsObject(renderer
)
180 m_releasePen
= false;
182 m_releaseBrush
= false;
184 m_releaseFont
= false;
187 wxGraphicsContext::~wxGraphicsContext()
189 wxASSERT_MSG( m_pen
== NULL
, wxT("No pen should be selected during destruction") );
190 wxASSERT_MSG( m_brush
== NULL
, wxT("No pen should be selected during destruction") );
194 void wxGraphicsContext::SetPen( wxGraphicsPen
* pen
, bool release
)
199 m_releasePen
= release
;
202 void wxGraphicsContext::SetPen( const wxPen
& pen
)
204 if ( pen
.GetStyle() == wxTRANSPARENT
)
207 SetPen( CreatePen( pen
) );
210 // sets the brush for filling
211 void wxGraphicsContext::SetBrush( wxGraphicsBrush
* brush
, bool release
)
213 if ( m_releaseBrush
)
216 m_releaseBrush
= release
;
219 void wxGraphicsContext::SetBrush( const wxBrush
& brush
)
221 if ( brush
.GetStyle() == wxTRANSPARENT
)
224 SetBrush( CreateBrush( brush
) );
227 // sets the brush for filling
228 void wxGraphicsContext::SetFont( wxGraphicsFont
* font
, bool release
)
233 m_releaseFont
= release
;
236 void wxGraphicsContext::SetFont( const wxFont
& font
, const wxColour
& colour
)
238 SetFont( CreateFont( font
, colour
) );
241 void wxGraphicsContext::DrawPath( const wxGraphicsPath
*path
, int fillStyle
)
243 FillPath( path
, fillStyle
);
247 void wxGraphicsContext::DrawText( const wxString
&str
, wxDouble x
, wxDouble y
, wxDouble angle
)
251 DrawText( str
, 0, 0 );
256 void wxGraphicsContext::StrokeLine( wxDouble x1
, wxDouble y1
, wxDouble x2
, wxDouble y2
)
258 wxGraphicsPath
* path
= CreatePath();
259 path
->MoveToPoint(x1
, y1
);
260 path
->AddLineToPoint( x2
, y2
);
265 void wxGraphicsContext::DrawRectangle( wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h
)
267 wxGraphicsPath
* path
= CreatePath();
268 path
->AddRectangle( x
, y
, w
, h
);
273 void wxGraphicsContext::DrawEllipse( wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h
)
275 wxGraphicsPath
* path
= CreatePath();
278 path
->AddCircle( x
+w
/2,y
+w
/2,w
/2);
284 Translate(x
+w
/2,y
+h
/2);
285 wxDouble factor
= ((wxDouble
) w
) / h
;
286 Scale( factor
, 1.0);
287 path
->AddCircle(0,0,h
/2);
294 void wxGraphicsContext::DrawRoundedRectangle( wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h
, wxDouble radius
)
296 wxGraphicsPath
* path
= CreatePath();
299 path
->AddRectangle( x
, y
, w
, h
);
307 path
->MoveToPoint(w
, h
/ 2);
308 path
->AddArcToPoint(w
, h
, w
/ 2, h
, radius
);
309 path
->AddArcToPoint(0, h
, 0, h
/ 2, radius
);
310 path
->AddArcToPoint(0, 0, w
/ 2, 0, radius
);
311 path
->AddArcToPoint(w
, 0, w
, h
/ 2, radius
);
312 path
->CloseSubpath();
319 void wxGraphicsContext::StrokeLines( size_t n
, const wxPoint2DDouble
*points
)
322 wxGraphicsPath
* path
= CreatePath();
323 path
->MoveToPoint(points
[0].m_x
, points
[0].m_y
);
324 for ( size_t i
= 1; i
< n
; ++i
)
325 path
->AddLineToPoint( points
[i
].m_x
, points
[i
].m_y
);
330 void wxGraphicsContext::DrawLines( size_t n
, const wxPoint2DDouble
*points
, int fillStyle
)
333 wxGraphicsPath
* path
= CreatePath();
334 path
->MoveToPoint(points
[0].m_x
, points
[0].m_y
);
335 for ( size_t i
= 1; i
< n
; ++i
)
336 path
->AddLineToPoint( points
[i
].m_x
, points
[i
].m_y
);
337 DrawPath( path
, fillStyle
);
341 void wxGraphicsContext::StrokeLines( size_t n
, const wxPoint2DDouble
*beginPoints
, const wxPoint2DDouble
*endPoints
)
344 wxGraphicsPath
* path
= CreatePath();
345 for ( size_t i
= 0; i
< n
; ++i
)
347 path
->MoveToPoint(beginPoints
[i
].m_x
, beginPoints
[i
].m_y
);
348 path
->AddLineToPoint( endPoints
[i
].m_x
, endPoints
[i
].m_y
);
354 // create a 'native' matrix corresponding to these values
355 wxGraphicsMatrix
* wxGraphicsContext::CreateMatrix( wxDouble a
, wxDouble b
, wxDouble c
, wxDouble d
,
356 wxDouble tx
, wxDouble ty
)
358 return GetRenderer()->CreateMatrix(a
,b
,c
,d
,tx
,ty
);
361 wxGraphicsPath
* wxGraphicsContext::CreatePath()
363 return GetRenderer()->CreatePath();
366 wxGraphicsPen
* wxGraphicsContext::CreatePen(const wxPen
& pen
)
368 return GetRenderer()->CreatePen(pen
);
371 wxGraphicsBrush
* wxGraphicsContext::CreateBrush(const wxBrush
& brush
)
373 return GetRenderer()->CreateBrush(brush
);
376 // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
377 wxGraphicsBrush
* wxGraphicsContext::CreateLinearGradientBrush( wxDouble x1
, wxDouble y1
, wxDouble x2
, wxDouble y2
,
378 const wxColour
&c1
, const wxColour
&c2
)
380 return GetRenderer()->CreateLinearGradientBrush(x1
,y1
,x2
,y2
,c1
,c2
);
383 // sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
384 // with radius r and color cColor
385 wxGraphicsBrush
* wxGraphicsContext::CreateRadialGradientBrush( wxDouble xo
, wxDouble yo
, wxDouble xc
, wxDouble yc
, wxDouble radius
,
386 const wxColour
&oColor
, const wxColour
&cColor
)
388 return GetRenderer()->CreateRadialGradientBrush(xo
,yo
,xc
,yc
,radius
,oColor
,cColor
);
392 wxGraphicsFont
* wxGraphicsContext::CreateFont( const wxFont
&font
, const wxColour
&col
)
394 return GetRenderer()->CreateFont(font
,col
);
397 wxGraphicsContext
* wxGraphicsContext::Create( const wxWindowDC
& dc
)
399 return wxGraphicsRenderer::GetDefaultRenderer()->CreateContext(dc
);
402 wxGraphicsContext
* wxGraphicsContext::CreateFromNative( void * context
)
404 return wxGraphicsRenderer::GetDefaultRenderer()->CreateContextFromNativeContext(context
);
407 wxGraphicsContext
* wxGraphicsContext::CreateFromNativeWindow( void * window
)
409 return wxGraphicsRenderer::GetDefaultRenderer()->CreateContextFromNativeWindow(window
);
412 wxGraphicsContext
* wxGraphicsContext::Create( wxWindow
* window
)
414 return wxGraphicsRenderer::GetDefaultRenderer()->CreateContext(window
);
417 #endif // wxUSE_GRAPHICS_CONTEXT