]> git.saurik.com Git - wxWidgets.git/blame - src/generic/graphicc.cpp
For streams smaller than the buffer reduce the buffer to length + 1 instead of
[wxWidgets.git] / src / generic / graphicc.cpp
CommitLineData
184fc6c8
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/generic/graphicc.cpp
3// Purpose: cairo device context class
4// Author: Stefan Csomor
5// Modified by:
e0876d73 6// Created: 2006-10-03
184fc6c8 7// RCS-ID: $Id$
e0876d73 8// Copyright: (c) 2006 Stefan Csomor
184fc6c8
SC
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#include "wx/dc.h"
15
184fc6c8
SC
16#ifdef __BORLANDC__
17#pragma hdrstop
18#endif
19
20#ifndef WX_PRECOMP
21#include "wx/image.h"
22#include "wx/window.h"
23#include "wx/dc.h"
24#include "wx/utils.h"
25#include "wx/dialog.h"
26#include "wx/app.h"
27#include "wx/bitmap.h"
28#include "wx/dcmemory.h"
29#include "wx/log.h"
30#include "wx/icon.h"
31#include "wx/dcprint.h"
32#include "wx/module.h"
33#endif
34
35#include "wx/graphics.h"
36
7ba86d93
RD
37#if wxUSE_GRAPHICS_CONTEXT
38
184fc6c8
SC
39#include <vector>
40
41using namespace std;
42
43//-----------------------------------------------------------------------------
44// constants
45//-----------------------------------------------------------------------------
46
47const double RAD2DEG = 180.0 / M_PI;
48
49//-----------------------------------------------------------------------------
50// Local functions
51//-----------------------------------------------------------------------------
52
53static inline double dmin(double a, double b)
54{
55 return a < b ? a : b;
56}
57static inline double dmax(double a, double b)
58{
59 return a > b ? a : b;
60}
61
62static inline double DegToRad(double deg)
63{
64 return (deg * M_PI) / 180.0;
65}
66static inline double RadToDeg(double deg)
67{
68 return (deg * 180.0) / M_PI;
69}
70
71//-----------------------------------------------------------------------------
72// device context implementation
73//
74// more and more of the dc functionality should be implemented by calling
75// the appropricate wxCairoContext, but we will have to do that step by step
76// also coordinate conversions should be moved to native matrix ops
77//-----------------------------------------------------------------------------
78
79// we always stock two context states, one at entry, to be able to preserve the
80// state we were called with, the other one after changing to HI Graphics orientation
81// (this one is used for getting back clippings etc)
82
83//-----------------------------------------------------------------------------
84// wxGraphicsPath implementation
85//-----------------------------------------------------------------------------
86
87// TODO remove this dependency (gdiplus needs the macros)
88
89#ifndef max
90#define max(a,b) (((a) > (b)) ? (a) : (b))
91#endif
92
93#ifndef min
94#define min(a,b) (((a) < (b)) ? (a) : (b))
95#endif
96
97#include <cairo.h>
00bd8e72 98#ifdef __WXGTK__
184fc6c8 99#include <gtk/gtk.h>
00bd8e72 100#endif
184fc6c8 101
00bd8e72 102class WXDLLIMPEXP_CORE wxCairoPath : public wxGraphicsPath
184fc6c8 103{
184fc6c8
SC
104public :
105 wxCairoPath();
00bd8e72 106 wxCairoPath(wxGraphicsRenderer* renderer, cairo_t* pathcontext = NULL);
184fc6c8
SC
107 ~wxCairoPath();
108
00bd8e72 109 virtual wxGraphicsPath *Clone() const;
184fc6c8
SC
110
111 //
112 // These are the path primitives from which everything else can be constructed
113 //
114
115 // begins a new subpath at (x,y)
116 virtual void MoveToPoint( wxDouble x, wxDouble y );
117
118 // adds a straight line from the current point to (x,y)
119 virtual void AddLineToPoint( wxDouble x, wxDouble y );
120
121 // adds a cubic Bezier curve from the current point, using two control points and an end point
122 virtual void AddCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble cx2, wxDouble cy2, wxDouble x, wxDouble y );
123
124
125 // adds an arc of a circle centering at (x,y) with radius (r) from startAngle to endAngle
126 virtual void AddArc( wxDouble x, wxDouble y, wxDouble r, wxDouble startAngle, wxDouble endAngle, bool clockwise ) ;
127
128 // gets the last point of the current path, (0,0) if not yet set
129 virtual void GetCurrentPoint( wxDouble& x, wxDouble&y) ;
130
00bd8e72
SC
131 // adds another path
132 virtual void AddPath( const wxGraphicsPath* path );
133
184fc6c8
SC
134 // closes the current sub-path
135 virtual void CloseSubpath();
136
137 //
138 // These are convenience functions which - if not available natively will be assembled
139 // using the primitives from above
140 //
141
142 /*
143
144 // appends a rectangle as a new closed subpath
145 virtual void AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) ;
146 // appends an ellipsis as a new closed subpath fitting the passed rectangle
147 virtual void AddEllipsis( wxDouble x, wxDouble y, wxDouble w , wxDouble h ) ;
148
149 // 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)
150 virtual void AddArcToPoint( wxDouble x1, wxDouble y1 , wxDouble x2, wxDouble y2, wxDouble r ) ;
151 */
152
cd5adaa6
RD
153 // returns the native path
154 virtual void * GetNativePath() const ;
155
156 // give the native path returned by GetNativePath() back (there might be some deallocations necessary)
157 virtual void UnGetNativePath(void *p) ;
f540e5bd 158
00bd8e72
SC
159 // transforms each point of this path by the matrix
160 virtual void Transform( wxGraphicsMatrix* matrix ) ;
161
162 // gets the bounding box enclosing all points (possibly including control points)
163 virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) ;
164
165 virtual bool Contains( wxDouble x, wxDouble y, int fillStyle = wxWINDING_RULE) ;
166
184fc6c8
SC
167private :
168 cairo_t* m_pathContext;
00bd8e72 169 DECLARE_DYNAMIC_CLASS_NO_COPY(wxCairoPath)
184fc6c8
SC
170};
171
00bd8e72 172class WXDLLIMPEXP_CORE wxCairoMatrix : public wxGraphicsMatrix
184fc6c8 173{
00bd8e72
SC
174public :
175 wxCairoMatrix() ;
184fc6c8 176
00bd8e72
SC
177 wxCairoMatrix(wxGraphicsRenderer* renderer, const cairo_matrix_t* matrix = NULL ) ;
178 virtual ~wxCairoMatrix() ;
184fc6c8 179
00bd8e72 180 virtual wxGraphicsMatrix *Clone() const ;
184fc6c8 181
00bd8e72
SC
182 // concatenates the matrix
183 virtual void Concat( const wxGraphicsMatrix *t );
f540e5bd 184
00bd8e72
SC
185 // copies the passed in matrix
186 virtual void Copy( const wxGraphicsMatrix *t );
184fc6c8 187
00bd8e72
SC
188 // sets the matrix to the respective values
189 virtual void Set(wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0,
190 wxDouble tx=0.0, wxDouble ty=0.0);
184fc6c8 191
00bd8e72
SC
192 // makes this the inverse matrix
193 virtual void Invert();
184fc6c8 194
00bd8e72
SC
195 // returns true if the elements of the transformation matrix are equal ?
196 virtual bool IsEqual( const wxGraphicsMatrix* t) const ;
184fc6c8 197
00bd8e72
SC
198 // return true if this is the identity matrix
199 virtual bool IsIdentity();
184fc6c8 200
00bd8e72
SC
201 //
202 // transformation
203 //
184fc6c8 204
00bd8e72
SC
205 // add the translation to this matrix
206 virtual void Translate( wxDouble dx , wxDouble dy );
207
208 // add the scale to this matrix
209 virtual void Scale( wxDouble xScale , wxDouble yScale );
210
211 // add the rotation to this matrix (radians)
212 virtual void Rotate( wxDouble angle );
213
214 //
215 // apply the transforms
216 //
217
218 // applies that matrix to the point
219 virtual void TransformPoint( wxDouble *x, wxDouble *y );
220
221 // applies the matrix except for translations
222 virtual void TransformDistance( wxDouble *dx, wxDouble *dy );
223
224 // returns the native representation
225 virtual void * GetNativeMatrix() const;
226private:
227 cairo_matrix_t m_matrix ;
228
229 DECLARE_DYNAMIC_CLASS_NO_COPY(wxCairoMatrix)
230} ;
231
232class WXDLLIMPEXP_CORE wxCairoPen : public wxGraphicsPen
184fc6c8 233{
00bd8e72
SC
234public:
235 wxCairoPen();
236 wxCairoPen( wxGraphicsRenderer* renderer, const wxPen &pen );
237 ~wxCairoPen();
238
239 void Init();
240
241 virtual void Apply( wxGraphicsContext* context );
242 virtual wxDouble GetWidth() { return m_width; }
243
244private :
245 double m_width;
246
247 double m_red;
248 double m_green;
249 double m_blue;
250 double m_alpha;
251
252 cairo_line_cap_t m_cap;
253 cairo_line_join_t m_join;
254
255 int m_count;
256 const double *m_lengths;
257 double *m_userLengths;
184fc6c8 258
00bd8e72
SC
259 wxPen m_pen;
260 DECLARE_DYNAMIC_CLASS_NO_COPY(wxCairoPen)
261};
262
263class WXDLLIMPEXP_CORE wxCairoBrush : public wxGraphicsBrush
184fc6c8 264{
00bd8e72
SC
265public:
266 wxCairoBrush();
267 wxCairoBrush( wxGraphicsRenderer* renderer );
268 wxCairoBrush( wxGraphicsRenderer* renderer, const wxBrush &brush );
269 ~wxCairoBrush ();
270
271 virtual void Apply( wxGraphicsContext* context );
272 void CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
273 const wxColour&c1, const wxColour&c2 );
274 void CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
275 const wxColour &oColor, const wxColour &cColor );
276
277protected:
278 virtual void Init();
279
280private :
281 double m_red;
282 double m_green;
283 double m_blue;
284 double m_alpha;
285
286 cairo_pattern_t* m_brushPattern;
287
288 DECLARE_DYNAMIC_CLASS_NO_COPY(wxCairoBrush)
289};
290
291class wxCairoFont : public wxGraphicsFont
184fc6c8 292{
00bd8e72
SC
293public:
294 wxCairoFont();
295 wxCairoFont( wxGraphicsRenderer* renderer, const wxFont &font, const wxColour& col );
296 ~wxCairoFont();
297
298 virtual void Apply( wxGraphicsContext* context );
299private :
300 wxCharBuffer m_fontName;
301 double m_size;
302 cairo_font_slant_t m_slant;
303 cairo_font_weight_t m_weight;
304 double m_red;
305 double m_green;
306 double m_blue;
307 double m_alpha;
308 DECLARE_DYNAMIC_CLASS_NO_COPY(wxCairoFont)
309};
184fc6c8 310
00bd8e72 311class WXDLLIMPEXP_CORE wxCairoContext : public wxGraphicsContext
184fc6c8
SC
312{
313 DECLARE_NO_COPY_CLASS(wxCairoContext)
314
315public:
00bd8e72
SC
316 wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC& dc );
317#ifdef __WXGTK__
318 wxCairoContext( wxGraphicsRenderer* renderer, GdkDrawable *drawable );
319#endif
320 wxCairoContext( wxGraphicsRenderer* renderer, cairo_t *context );
321 wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window);
184fc6c8
SC
322 wxCairoContext();
323 virtual ~wxCairoContext();
324
325 virtual void Clip( const wxRegion &region );
539e2795
SC
326
327 // clips drawings to the rect
328 virtual void Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h );
539e2795 329
cd5adaa6
RD
330 // resets the clipping to original extent
331 virtual void ResetClip();
332
333 virtual void * GetNativeContext();
334
184fc6c8
SC
335 virtual void StrokePath( const wxGraphicsPath *p );
336 virtual void FillPath( const wxGraphicsPath *p , int fillStyle = wxWINDING_RULE );
337
184fc6c8
SC
338 virtual void Translate( wxDouble dx , wxDouble dy );
339 virtual void Scale( wxDouble xScale , wxDouble yScale );
340 virtual void Rotate( wxDouble angle );
341
00bd8e72
SC
342 // concatenates this transform with the current transform of this context
343 virtual void ConcatTransform( const wxGraphicsMatrix* matrix );
344
345 // sets the transform of this context
346 virtual void SetTransform( const wxGraphicsMatrix* matrix );
347
348 // gets the matrix of this context
349 virtual void GetTransform( wxGraphicsMatrix* matrix );
350
184fc6c8
SC
351 virtual void DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h );
352 virtual void DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h );
353 virtual void PushState();
354 virtual void PopState();
355
184fc6c8
SC
356 virtual void DrawText( const wxString &str, wxDouble x, wxDouble y);
357 virtual void GetTextExtent( const wxString &str, wxDouble *width, wxDouble *height,
358 wxDouble *descent, wxDouble *externalLeading ) const;
359 virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const;
360
361private:
362 cairo_t* m_context;
184fc6c8
SC
363};
364
184fc6c8 365//-----------------------------------------------------------------------------
00bd8e72 366// wxCairoPen implementation
184fc6c8
SC
367//-----------------------------------------------------------------------------
368
00bd8e72 369IMPLEMENT_DYNAMIC_CLASS(wxCairoPen,wxGraphicsPen)
184fc6c8 370
00bd8e72 371wxCairoPen::wxCairoPen() : wxGraphicsPen(NULL)
184fc6c8 372{
00bd8e72 373 wxLogDebug(wxT("Illegal Constructor called"));
184fc6c8
SC
374}
375
00bd8e72 376wxCairoPen::~wxCairoPen()
539e2795 377{
00bd8e72 378 delete[] m_userLengths;
539e2795 379}
cd5adaa6 380
00bd8e72 381void wxCairoPen::Init()
539e2795 382{
00bd8e72
SC
383 m_lengths = NULL;
384 m_userLengths = NULL;
385 m_width = 0;
386 m_count = 0;
539e2795
SC
387}
388
00bd8e72
SC
389wxCairoPen::wxCairoPen( wxGraphicsRenderer* renderer, const wxPen &pen )
390: wxGraphicsPen(renderer)
391{
392 Init();
393 m_width = pen.GetWidth();
394 if (m_width <= 0.0)
395 m_width = 0.1;
539e2795 396
00bd8e72
SC
397 m_red = m_pen.GetColour().Red()/255.0;
398 m_green = m_pen.GetColour().Green()/255.0;
399 m_blue = m_pen.GetColour().Blue()/255.0;
400 m_alpha = m_pen.GetColour().Alpha()/255.0;
184fc6c8 401
184fc6c8
SC
402 switch ( m_pen.GetCap() )
403 {
404 case wxCAP_ROUND :
00bd8e72 405 m_cap = CAIRO_LINE_CAP_ROUND;
184fc6c8
SC
406 break;
407
408 case wxCAP_PROJECTING :
00bd8e72 409 m_cap = CAIRO_LINE_CAP_SQUARE;
184fc6c8
SC
410 break;
411
412 case wxCAP_BUTT :
00bd8e72 413 m_cap = CAIRO_LINE_CAP_BUTT;
184fc6c8
SC
414 break;
415
416 default :
00bd8e72 417 m_cap = CAIRO_LINE_CAP_BUTT;
184fc6c8
SC
418 break;
419 }
184fc6c8 420
184fc6c8
SC
421 switch ( m_pen.GetJoin() )
422 {
423 case wxJOIN_BEVEL :
00bd8e72 424 m_join = CAIRO_LINE_JOIN_BEVEL;
184fc6c8
SC
425 break;
426
427 case wxJOIN_MITER :
00bd8e72 428 m_join = CAIRO_LINE_JOIN_MITER;
184fc6c8
SC
429 break;
430
431 case wxJOIN_ROUND :
00bd8e72 432 m_join = CAIRO_LINE_JOIN_ROUND;
184fc6c8
SC
433 break;
434
435 default :
00bd8e72 436 m_join = CAIRO_LINE_JOIN_MITER;
184fc6c8
SC
437 break;
438 }
184fc6c8 439
00bd8e72 440 const double dashUnit = m_width < 1.0 ? 1.0 : m_width;
184fc6c8 441 const double dotted[] =
00bd8e72
SC
442 {
443 dashUnit , dashUnit + 2.0
444 };
445 static const double short_dashed[] =
446 {
447 9.0 , 6.0
448 };
449 static const double dashed[] =
450 {
451 19.0 , 9.0
452 };
453 static const double dotted_dashed[] =
454 {
455 9.0 , 6.0 , 3.0 , 3.0
456 };
184fc6c8
SC
457
458 switch ( m_pen.GetStyle() )
459 {
460 case wxSOLID :
461 break;
462
463 case wxDOT :
00bd8e72
SC
464 m_count = WXSIZEOF(dotted);
465 m_userLengths = new double[ m_count ] ;
466 memcpy( m_userLengths, dotted, sizeof(dotted) );
467 m_lengths = m_userLengths;
184fc6c8
SC
468 break;
469
470 case wxLONG_DASH :
00bd8e72
SC
471 m_lengths = dotted ;
472 m_count = WXSIZEOF(dashed);
184fc6c8
SC
473 break;
474
475 case wxSHORT_DASH :
00bd8e72
SC
476 m_lengths = dotted ;
477 m_count = WXSIZEOF(short_dashed);
184fc6c8
SC
478 break;
479
480 case wxDOT_DASH :
00bd8e72
SC
481 m_lengths = dotted ;
482 m_count = WXSIZEOF(dotted_dashed);
184fc6c8
SC
483 break;
484
485 case wxUSER_DASH :
486 {
487 wxDash *wxdashes ;
00bd8e72
SC
488 m_count = m_pen.GetDashes( &wxdashes ) ;
489 if ((wxdashes != NULL) && (m_count > 0))
184fc6c8 490 {
00bd8e72
SC
491 m_userLengths = new double[m_count] ;
492 for ( int i = 0 ; i < m_count ; ++i )
184fc6c8 493 {
00bd8e72 494 m_userLengths[i] = wxdashes[i] * dashUnit ;
184fc6c8 495
00bd8e72
SC
496 if ( i % 2 == 1 && m_userLengths[i] < dashUnit + 2.0 )
497 m_userLengths[i] = dashUnit + 2.0 ;
498 else if ( i % 2 == 0 && m_userLengths[i] < dashUnit )
499 m_userLengths[i] = dashUnit ;
184fc6c8
SC
500 }
501 }
00bd8e72 502 m_lengths = m_userLengths ;
184fc6c8
SC
503 }
504 break;
505 case wxSTIPPLE :
506 {
507 /*
00bd8e72
SC
508 wxBitmap* bmp = pen.GetStipple();
509 if ( bmp && bmp->Ok() )
510 {
511 wxDELETE( m_penImage );
512 wxDELETE( m_penBrush );
513 m_penImage = Bitmap::FromHBITMAP((HBITMAP)bmp->GetHBITMAP(),(HPALETTE)bmp->GetPalette()->GetHPALETTE());
514 m_penBrush = new TextureBrush(m_penImage);
515 m_pen->SetBrush( m_penBrush );
516 }
184fc6c8
SC
517 */
518 }
519 break;
520 default :
521 if ( m_pen.GetStyle() >= wxFIRST_HATCH && m_pen.GetStyle() <= wxLAST_HATCH )
522 {
523 /*
00bd8e72
SC
524 wxDELETE( m_penBrush );
525 HatchStyle style = HatchStyleHorizontal;
526 switch( pen.GetStyle() )
527 {
528 case wxBDIAGONAL_HATCH :
529 style = HatchStyleBackwardDiagonal;
530 break ;
531 case wxCROSSDIAG_HATCH :
532 style = HatchStyleDiagonalCross;
533 break ;
534 case wxFDIAGONAL_HATCH :
535 style = HatchStyleForwardDiagonal;
536 break ;
537 case wxCROSS_HATCH :
538 style = HatchStyleCross;
539 break ;
540 case wxHORIZONTAL_HATCH :
541 style = HatchStyleHorizontal;
542 break ;
543 case wxVERTICAL_HATCH :
544 style = HatchStyleVertical;
545 break ;
546
547 }
548 m_penBrush = new HatchBrush(style,Color( pen.GetColour().Alpha() , pen.GetColour().Red() ,
549 pen.GetColour().Green() , pen.GetColour().Blue() ), Color.Transparent );
550 m_pen->SetBrush( m_penBrush )
184fc6c8
SC
551 */
552 }
553 break;
554 }
00bd8e72 555}
184fc6c8 556
00bd8e72
SC
557void wxCairoPen::Apply( wxGraphicsContext* context )
558{
559 cairo_t * ctext = (cairo_t*) context->GetNativeContext();
560 cairo_set_line_width(ctext,m_width);
561 cairo_set_source_rgba(ctext,m_red,m_green, m_blue,m_alpha);
562 cairo_set_line_cap(ctext,m_cap);
563 cairo_set_line_join(ctext,m_join);
564 cairo_set_dash(ctext,(double*)m_lengths,m_count,0.0);
184fc6c8
SC
565}
566
00bd8e72
SC
567//-----------------------------------------------------------------------------
568// wxCairoBrush implementation
569//-----------------------------------------------------------------------------
570
571IMPLEMENT_DYNAMIC_CLASS(wxCairoBrush,wxGraphicsBrush)
572
573wxCairoBrush::wxCairoBrush() : wxGraphicsBrush( NULL )
184fc6c8 574{
00bd8e72
SC
575 wxLogDebug(wxT("Illegal Constructor called"));
576}
184fc6c8 577
00bd8e72
SC
578wxCairoBrush::wxCairoBrush( wxGraphicsRenderer* renderer ) : wxGraphicsBrush( renderer )
579{
580 Init();
581}
184fc6c8 582
00bd8e72
SC
583wxCairoBrush::wxCairoBrush( wxGraphicsRenderer* renderer, const wxBrush &brush )
584: wxGraphicsBrush(renderer)
585{
586 m_red = brush.GetColour().Red()/255.0;
587 m_green = brush.GetColour().Green()/255.0;
588 m_blue = brush.GetColour().Blue()/255.0;
589 m_alpha = brush.GetColour().Alpha()/255.0;
590 /*
591 if ( brush.GetStyle() == wxSOLID)
592 {
593 m_brush = new SolidBrush( Color( brush.GetColour().Alpha() , brush.GetColour().Red() ,
594 brush.GetColour().Green() , brush.GetColour().Blue() ) );
595 }
596 else if ( brush.IsHatch() )
597 {
598 HatchStyle style = HatchStyleHorizontal;
599 switch( brush.GetStyle() )
600 {
601 case wxBDIAGONAL_HATCH :
602 style = HatchStyleBackwardDiagonal;
603 break ;
604 case wxCROSSDIAG_HATCH :
605 style = HatchStyleDiagonalCross;
606 break ;
607 case wxFDIAGONAL_HATCH :
608 style = HatchStyleForwardDiagonal;
609 break ;
610 case wxCROSS_HATCH :
611 style = HatchStyleCross;
612 break ;
613 case wxHORIZONTAL_HATCH :
614 style = HatchStyleHorizontal;
615 break ;
616 case wxVERTICAL_HATCH :
617 style = HatchStyleVertical;
618 break ;
619
620 }
621 m_brush = new HatchBrush(style,Color( brush.GetColour().Alpha() , brush.GetColour().Red() ,
622 brush.GetColour().Green() , brush.GetColour().Blue() ), Color.Transparent );
623 }
624 else
625 {
626 wxBitmap* bmp = brush.GetStipple();
627 if ( bmp && bmp->Ok() )
628 {
629 wxDELETE( m_brushImage );
630 m_brushImage = Bitmap::FromHBITMAP((HBITMAP)bmp->GetHBITMAP(),(HPALETTE)bmp->GetPalette()->GetHPALETTE());
631 m_brush = new TextureBrush(m_brushImage);
632 }
184fc6c8 633 }
00bd8e72 634 */
184fc6c8
SC
635}
636
00bd8e72 637wxCairoBrush::~wxCairoBrush ()
184fc6c8 638{
00bd8e72
SC
639 if (m_brushPattern)
640 cairo_pattern_destroy(m_brushPattern);
184fc6c8
SC
641}
642
00bd8e72 643void wxCairoBrush::Apply( wxGraphicsContext* context )
184fc6c8 644{
00bd8e72
SC
645 cairo_t * ctext = (cairo_t*) context->GetNativeContext();
646 if ( m_brushPattern )
647 {
648 cairo_set_source(ctext,m_brushPattern);
649 }
650 else
651 {
652 cairo_set_source_rgba(ctext,m_red,m_green, m_blue,m_alpha);
653 }
184fc6c8
SC
654}
655
00bd8e72
SC
656void wxCairoBrush::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
657 const wxColour&c1, const wxColour&c2 )
184fc6c8 658{
00bd8e72
SC
659 m_brushPattern = cairo_pattern_create_linear(x1,y1,x2,y2);
660 cairo_pattern_add_color_stop_rgba(m_brushPattern,0.0,c1.Red()/255.0,
661 c1.Green()/255.0, c1.Blue()/255.0,c1.Alpha()/255.0);
662 cairo_pattern_add_color_stop_rgba(m_brushPattern,1.0,c2.Red()/255.0,
663 c2.Green()/255.0, c2.Blue()/255.0,c2.Alpha()/255.0);
664 wxASSERT_MSG(cairo_pattern_status(m_brushPattern) == CAIRO_STATUS_SUCCESS, wxT("Couldn't create cairo pattern"));
184fc6c8
SC
665}
666
00bd8e72
SC
667void wxCairoBrush::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
668 const wxColour &oColor, const wxColour &cColor )
184fc6c8 669{
00bd8e72
SC
670 m_brushPattern = cairo_pattern_create_radial(xo,yo,0.0,xc,yc,radius);
671 cairo_pattern_add_color_stop_rgba(m_brushPattern,0.0,oColor.Red()/255.0,
672 oColor.Green()/255.0, oColor.Blue()/255.0,oColor.Alpha()/255.0);
673 cairo_pattern_add_color_stop_rgba(m_brushPattern,1.0,cColor.Red()/255.0,
674 cColor.Green()/255.0, cColor.Blue()/255.0,cColor.Alpha()/255.0);
675 wxASSERT_MSG(cairo_pattern_status(m_brushPattern) == CAIRO_STATUS_SUCCESS, wxT("Couldn't create cairo pattern"));
184fc6c8
SC
676}
677
00bd8e72 678void wxCairoBrush::Init()
184fc6c8 679{
00bd8e72 680 m_brushPattern = NULL;
184fc6c8
SC
681}
682
00bd8e72
SC
683//-----------------------------------------------------------------------------
684// wxCairoFont implementation
685//-----------------------------------------------------------------------------
686
687wxCairoFont::wxCairoFont() : wxGraphicsFont(NULL)
184fc6c8 688{
00bd8e72 689 wxLogDebug(wxT("Illegal Constructor called"));
184fc6c8
SC
690}
691
00bd8e72
SC
692wxCairoFont::wxCairoFont( wxGraphicsRenderer* renderer, const wxFont &font,
693 const wxColour& col ) : wxGraphicsFont(renderer)
184fc6c8 694{
00bd8e72
SC
695 m_red = col.Red()/255.0;
696 m_green = col.Green()/255.0;
697 m_blue = col.Blue()/255.0;
698 m_alpha = col.Alpha()/255.0;
699
700 m_size = font.GetPointSize();
701 m_fontName = font.GetFaceName().mb_str(wxConvUTF8);
702 m_slant = font.GetStyle() == wxFONTSTYLE_ITALIC ? CAIRO_FONT_SLANT_ITALIC:CAIRO_FONT_SLANT_NORMAL;
703 m_weight = font.GetWeight() == wxFONTWEIGHT_BOLD ? CAIRO_FONT_WEIGHT_BOLD:CAIRO_FONT_WEIGHT_NORMAL;
184fc6c8
SC
704}
705
00bd8e72 706wxCairoFont::~wxCairoFont()
184fc6c8 707{
00bd8e72 708}
184fc6c8 709
00bd8e72
SC
710void wxCairoFont::Apply( wxGraphicsContext* context )
711{
712 cairo_t * ctext = (cairo_t*) context->GetNativeContext();
713 cairo_set_source_rgba(ctext,m_red,m_green, m_blue,m_alpha);
714 cairo_select_font_face(ctext,m_fontName,m_slant,m_weight);
715 cairo_set_font_size(ctext,m_size);
716 // TODO UNDERLINE
717 // TODO FIX SIZE
718}
719
720//-----------------------------------------------------------------------------
721// wxCairoPath implementation
722//-----------------------------------------------------------------------------
723
724wxCairoPath::wxCairoPath() : wxGraphicsPath(NULL)
725{
726 wxLogDebug(wxT("Illegal Constructor called"));
184fc6c8
SC
727}
728
00bd8e72
SC
729wxCairoPath::wxCairoPath( wxGraphicsRenderer* renderer, cairo_t* pathcontext)
730 : wxGraphicsPath(renderer)
184fc6c8 731{
00bd8e72 732 if (pathcontext)
184fc6c8 733 {
00bd8e72
SC
734 m_pathContext = pathcontext;
735 }
736 else
737 {
738 cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,1,1);
739 m_pathContext = cairo_create(surface);
740 cairo_surface_destroy (surface);
184fc6c8 741 }
00bd8e72 742}
184fc6c8 743
00bd8e72
SC
744wxCairoPath::~wxCairoPath()
745{
746 cairo_destroy(m_pathContext);
184fc6c8
SC
747}
748
00bd8e72 749wxGraphicsPath *wxCairoPath::Clone() const
184fc6c8 750{
00bd8e72
SC
751 cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,1,1);
752 cairo_t* pathcontext = cairo_create(surface);
753 cairo_surface_destroy (surface);
754
755 cairo_path_t* path = cairo_copy_path(m_pathContext);
756 cairo_append_path(pathcontext, path);
757 cairo_path_destroy(path);
758 return new wxCairoPath( GetRenderer() ,pathcontext);
759}
760
761
762void* wxCairoPath::GetNativePath() const
763{
764 return cairo_copy_path(m_pathContext) ;
765}
766
767void wxCairoPath::UnGetNativePath(void *p)
768{
769 cairo_path_destroy((cairo_path_t*)p);
770}
771
772//
773// The Primitives
774//
775
776void wxCairoPath::MoveToPoint( wxDouble x , wxDouble y )
777{
778 cairo_move_to(m_pathContext,x,y);
779}
780
781void wxCairoPath::AddLineToPoint( wxDouble x , wxDouble y )
782{
783 cairo_line_to(m_pathContext,x,y);
784}
785
786void wxCairoPath::CloseSubpath()
787{
788 cairo_close_path(m_pathContext);
789}
790
791void wxCairoPath::AddCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble cx2, wxDouble cy2, wxDouble x, wxDouble y )
792{
793 cairo_curve_to(m_pathContext,cx1,cy1,cx2,cy2,x,y);
794}
795
796// gets the last point of the current path, (0,0) if not yet set
797void wxCairoPath::GetCurrentPoint( wxDouble& x, wxDouble&y)
798{
799 double dx,dy;
800 cairo_get_current_point(m_pathContext,&dx,&dy);
801 x = dx;
802 y = dy;
803}
804
805void wxCairoPath::AddArc( wxDouble x, wxDouble y, wxDouble r, double startAngle, double endAngle, bool clockwise )
806{
807 // as clockwise means positive in our system (y pointing downwards)
808 // TODO make this interpretation dependent of the
809 // real device trans
810 if ( clockwise||(endAngle-startAngle)>=2*M_PI)
811 cairo_arc(m_pathContext,x,y,r,startAngle,endAngle);
812 else
813 cairo_arc_negative(m_pathContext,x,y,r,startAngle,endAngle);
814}
815
816// transforms each point of this path by the matrix
817void wxCairoPath::Transform( wxGraphicsMatrix* matrix )
818{
819 // as we don't have a true path object, we have to apply the inverse
820 // matrix to the context
821 cairo_matrix_t m = *((cairo_matrix_t*) matrix->GetNativeMatrix());
822 cairo_matrix_invert( &m );
823 cairo_transform(m_pathContext,&m);
824}
825
826// gets the bounding box enclosing all points (possibly including control points)
827void wxCairoPath::GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h)
828{
829 double x1,y1,x2,y2;
830
831 cairo_stroke_extents( m_pathContext, &x1, &y1, &x2, &y2 );
832 if ( x2 < x1 )
184fc6c8 833 {
00bd8e72
SC
834 *x = x2;
835 *w = x1-x2;
836 }
837 else
838 {
839 *x = x1;
840 *w = x2-x1;
184fc6c8
SC
841 }
842
00bd8e72
SC
843 if( y2 < y1 )
844 {
845 *y = y2;
846 *h = y1-y2;
847 }
848 else
849 {
850 *y = y1;
851 *h = y2-y1;
852 }
853}
854
855bool wxCairoPath::Contains( wxDouble x, wxDouble y, int fillStyle )
856{
857 return cairo_in_stroke( m_pathContext, x, y) != NULL;
858}
859
860//-----------------------------------------------------------------------------
861// wxCairoMatrix implementation
862//-----------------------------------------------------------------------------
863
864IMPLEMENT_DYNAMIC_CLASS(wxCairoMatrix,wxGraphicsMatrix)
865
866wxCairoMatrix::wxCairoMatrix() : wxGraphicsMatrix(NULL)
867{
868 wxLogDebug(wxT("Illegal Constructor called"));
869}
870
871wxCairoMatrix::wxCairoMatrix(wxGraphicsRenderer* renderer, const cairo_matrix_t* matrix )
872 : wxGraphicsMatrix(renderer)
873{
874 if ( matrix )
875 m_matrix = *matrix;
876}
877
878wxCairoMatrix::~wxCairoMatrix()
879{
880 // nothing to do
881}
882
883wxGraphicsMatrix *wxCairoMatrix::Clone() const
884{
885 return new wxCairoMatrix(GetRenderer(),&m_matrix);
886}
887
888// concatenates the matrix
889void wxCairoMatrix::Concat( const wxGraphicsMatrix *t )
890{
891 cairo_matrix_multiply( &m_matrix, &m_matrix, (cairo_matrix_t*) t->GetNativeMatrix());
892}
893
894// copies the passed in matrix
895void wxCairoMatrix::Copy( const wxGraphicsMatrix *t )
896{
897 m_matrix = *((cairo_matrix_t*) t->GetNativeMatrix());
898}
899
900// sets the matrix to the respective values
901void wxCairoMatrix::Set(wxDouble a, wxDouble b, wxDouble c, wxDouble d,
902 wxDouble tx, wxDouble ty)
903{
904 cairo_matrix_init( &m_matrix, a, b, c, d, tx, ty);
905}
906
907// makes this the inverse matrix
908void wxCairoMatrix::Invert()
909{
910 cairo_matrix_invert( &m_matrix );
911}
912
913// returns true if the elements of the transformation matrix are equal ?
914bool wxCairoMatrix::IsEqual( const wxGraphicsMatrix* t) const
915{
916 const cairo_matrix_t* tm = (cairo_matrix_t*) t->GetNativeMatrix();
917 return (
918 m_matrix.xx == tm->xx &&
919 m_matrix.yx == tm->yx &&
920 m_matrix.xy == tm->xy &&
921 m_matrix.yy == tm->yy &&
922 m_matrix.x0 == tm->x0 &&
923 m_matrix.y0 == tm->y0 ) ;
924}
925
926// return true if this is the identity matrix
927bool wxCairoMatrix::IsIdentity()
928{
929 return ( m_matrix.xx == 1 && m_matrix.yy == 1 &&
930 m_matrix.yx == 0 && m_matrix.xy == 0 && m_matrix.x0 == 0 && m_matrix.y0 == 0);
931}
932
933//
934// transformation
935//
936
937// add the translation to this matrix
938void wxCairoMatrix::Translate( wxDouble dx , wxDouble dy )
939{
940 cairo_matrix_translate( &m_matrix, dx, dy) ;
941}
942
943// add the scale to this matrix
944void wxCairoMatrix::Scale( wxDouble xScale , wxDouble yScale )
945{
946 cairo_matrix_scale( &m_matrix, xScale, yScale) ;
947}
948
949// add the rotation to this matrix (radians)
950void wxCairoMatrix::Rotate( wxDouble angle )
951{
952 cairo_matrix_rotate( &m_matrix, angle) ;
953}
954
955//
956// apply the transforms
957//
958
959// applies that matrix to the point
960void wxCairoMatrix::TransformPoint( wxDouble *x, wxDouble *y )
961{
962 double lx = *x, ly = *y ;
963 cairo_matrix_transform_point( &m_matrix, &lx, &ly);
964 *x = lx;
965 *y = ly;
966}
967
968// applies the matrix except for translations
969void wxCairoMatrix::TransformDistance( wxDouble *dx, wxDouble *dy )
970{
971 double lx = *dx, ly = *dy ;
972 cairo_matrix_transform_distance( &m_matrix, &lx, &ly);
973 *dx = lx;
974 *dy = ly;
975}
976
977// returns the native representation
978void * wxCairoMatrix::GetNativeMatrix() const
979{
980 return (void*) &m_matrix;
981}
982
983//-----------------------------------------------------------------------------
984// wxCairoContext implementation
985//-----------------------------------------------------------------------------
986
987wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC& dc )
988: wxGraphicsContext(renderer)
989{
990#ifdef __WXGTK__
991 m_context = gdk_cairo_create( dc.m_window ) ;
992#endif
993 PushState();
994 PushState();
995}
996
997#ifdef __WXGTK__
998wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, GdkDrawable *drawable )
999: wxGraphicsContext(renderer)
1000{
1001 m_context = gdk_cairo_create( drawable ) ;
1002 PushState();
1003 PushState();
1004}
1005#endif
1006
1007wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, cairo_t *context )
1008: wxGraphicsContext(renderer)
1009{
1010 m_context = context ;
1011 PushState();
1012 PushState();
184fc6c8
SC
1013}
1014
00bd8e72
SC
1015wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window)
1016: wxGraphicsContext(renderer)
184fc6c8 1017{
00bd8e72
SC
1018#ifdef __WXGTK__
1019 // something along these lines (copied from dcclient)
1020
1021 GtkWidget *widget = window->m_wxwindow;
1022
1023 // Some controls don't have m_wxwindow - like wxStaticBox, but the user
1024 // code should still be able to create wxClientDCs for them, so we will
1025 // use the parent window here then.
1026 if ( !widget )
184fc6c8 1027 {
00bd8e72
SC
1028 window = window->GetParent();
1029 widget = window->m_wxwindow;
184fc6c8 1030 }
00bd8e72
SC
1031
1032 wxASSERT_MSG( widget, wxT("wxCairoContext needs a widget") );
1033
1034 GtkPizza *pizza = GTK_PIZZA( widget );
1035 GdkDrawable* drawable = pizza->bin_window;
1036 m_context = gdk_cairo_create( drawable ) ;
1037#endif
1038 PushState();
1039 PushState();
1040}
1041
1042wxCairoContext::~wxCairoContext()
1043{
1044 SetPen(NULL);
1045 SetBrush(NULL);
1046 SetFont(NULL);
1047
1048 if ( m_context )
1049 {
1050 PopState();
1051 PopState();
1052 cairo_destroy(m_context);
1053 }
1054}
1055
1056
1057void wxCairoContext::Clip( const wxRegion & WXUNUSED(region) )
1058{
1059// TODO
1060}
1061
1062void wxCairoContext::Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h )
1063{
1064// TODO
1065}
1066
1067void wxCairoContext::ResetClip()
1068{
1069// TODO
1070}
1071
1072
1073void wxCairoContext::StrokePath( const wxGraphicsPath *path )
1074{
1075 if ( m_pen )
1076 {
1077 cairo_path_t* cp = (cairo_path_t*) path->GetNativePath() ;
1078 cairo_append_path(m_context,cp);
1079 m_pen->Apply(this);
1080 cairo_stroke(m_context);
1081 wxConstCast(path, wxGraphicsPath)->UnGetNativePath(cp);
1082 }
1083}
1084
1085void wxCairoContext::FillPath( const wxGraphicsPath *path , int fillStyle )
1086{
1087 if ( m_brush )
1088 {
1089 cairo_path_t* cp = (cairo_path_t*) path->GetNativePath() ;
1090 cairo_append_path(m_context,cp);
1091 m_brush->Apply(this);
1092 cairo_set_fill_rule(m_context,fillStyle==wxODDEVEN_RULE ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
1093 cairo_fill(m_context);
1094 wxConstCast(path, wxGraphicsPath)->UnGetNativePath(cp);
1095 }
1096}
1097
1098void wxCairoContext::Rotate( wxDouble angle )
1099{
1100 cairo_rotate(m_context,angle);
1101}
1102
1103void wxCairoContext::Translate( wxDouble dx , wxDouble dy )
1104{
1105 cairo_translate(m_context,dx,dy);
1106}
1107
1108void wxCairoContext::Scale( wxDouble xScale , wxDouble yScale )
1109{
1110 cairo_scale(m_context,xScale,yScale);
1111}
1112
1113// concatenates this transform with the current transform of this context
1114void wxCairoContext::ConcatTransform( const wxGraphicsMatrix* matrix )
1115{
1116 cairo_transform(m_context,(const cairo_matrix_t *) matrix->GetNativeMatrix());
1117}
1118
1119// sets the transform of this context
1120void wxCairoContext::SetTransform( const wxGraphicsMatrix* matrix )
1121{
1122 cairo_set_matrix(m_context,(const cairo_matrix_t*) matrix->GetNativeMatrix());
1123}
1124
1125// gets the matrix of this context
1126void wxCairoContext::GetTransform( wxGraphicsMatrix* matrix )
1127{
1128 cairo_get_matrix(m_context,(cairo_matrix_t*) matrix->GetNativeMatrix());
1129}
1130
1131
1132
1133void wxCairoContext::PushState()
1134{
1135 cairo_save(m_context);
1136}
1137
1138void wxCairoContext::PopState()
1139{
1140 cairo_restore(m_context);
1141}
184fc6c8
SC
1142
1143void wxCairoContext::DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
1144{
1145 /*
1146 Bitmap* image = Bitmap::FromHBITMAP((HBITMAP)bmp.GetHBITMAP(),(HPALETTE)bmp.GetPalette()->GetHPALETTE());
1147 m_context->DrawImage(image,(REAL) x,(REAL) y,(REAL) w,(REAL) h) ;
1148 delete image ;
1149 */
1150}
1151
1152void wxCairoContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
1153{
1154 /*
1155 Bitmap* image = Bitmap::FromHICON((HICON)icon.GetHICON());
1156 m_context->DrawImage(image,(REAL) x,(REAL) y,(REAL) w,(REAL) h) ;
1157 delete image ;
1158 */
1159}
1160
1161
1162void wxCairoContext::DrawText( const wxString &str, wxDouble x, wxDouble y )
1163{
00bd8e72 1164 if ( m_font == NULL || str.IsEmpty())
184fc6c8
SC
1165 return ;
1166 cairo_move_to(m_context,x,y);
1167 const wxWX2MBbuf buf(str.mb_str(wxConvUTF8));
00bd8e72 1168 m_font->Apply(this);
184fc6c8 1169 cairo_show_text(m_context,buf);
184fc6c8
SC
1170}
1171
1172void wxCairoContext::GetTextExtent( const wxString &str, wxDouble *width, wxDouble *height,
1173 wxDouble *descent, wxDouble *externalLeading ) const
1174{
00bd8e72 1175 // TODO
184fc6c8
SC
1176}
1177
1178void wxCairoContext::GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const
1179{
1180 widths.Empty();
1181 widths.Add(0, text.length());
1182
1183 if (text.empty())
1184 return;
00bd8e72
SC
1185
1186 // TODO
184fc6c8
SC
1187}
1188
00bd8e72 1189void * wxCairoContext::GetNativeContext()
184fc6c8 1190{
00bd8e72
SC
1191 return m_context;
1192}
184fc6c8 1193
00bd8e72
SC
1194//-----------------------------------------------------------------------------
1195// wxCairoRenderer declaration
1196//-----------------------------------------------------------------------------
1197
1198class WXDLLIMPEXP_CORE wxCairoRenderer : public wxGraphicsRenderer
1199{
1200public :
1201 wxCairoRenderer() {}
1202
1203 virtual ~wxCairoRenderer() {}
1204
1205 // Context
1206
1207 virtual wxGraphicsContext * CreateContext( const wxWindowDC& dc);
1208
1209 virtual wxGraphicsContext * CreateContextFromNativeContext( void * context );
1210
1211 virtual wxGraphicsContext * CreateContextFromNativeWindow( void * window );
1212
1213 virtual wxGraphicsContext * CreateContext( wxWindow* window );
1214
1215 // Path
1216
1217 virtual wxGraphicsPath * CreatePath();
1218
1219 // Matrix
1220
1221 virtual wxGraphicsMatrix * CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0,
1222 wxDouble tx=0.0, wxDouble ty=0.0);
1223
1224
1225 virtual wxGraphicsPen* CreatePen(const wxPen& pen) ;
1226
1227 virtual wxGraphicsBrush* CreateBrush(const wxBrush& brush ) ;
1228
1229 // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
1230 virtual wxGraphicsBrush* CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
1231 const wxColour&c1, const wxColour&c2) ;
1232
1233 // sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
1234 // with radius r and color cColor
1235 virtual wxGraphicsBrush* CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
1236 const wxColour &oColor, const wxColour &cColor) ;
1237
1238 // sets the font
1239 virtual wxGraphicsFont* CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ;
1240
1241private :
1242 DECLARE_DYNAMIC_CLASS_NO_COPY(wxCairoRenderer)
1243} ;
1244
1245//-----------------------------------------------------------------------------
1246// wxCairoRenderer implementation
1247//-----------------------------------------------------------------------------
1248
1249IMPLEMENT_DYNAMIC_CLASS(wxCairoRenderer,wxGraphicsRenderer)
1250
1251static wxCairoRenderer gs_cairoGraphicsRenderer;
1252
1253#ifdef __WXGTK__
1254wxGraphicsRenderer* wxGraphicsRenderer::GetDefaultRenderer()
1255{
1256 return &gs_cairoGraphicsRenderer;
184fc6c8 1257}
00bd8e72 1258#endif
184fc6c8 1259
00bd8e72 1260wxGraphicsContext * wxCairoRenderer::CreateContext( const wxWindowDC& dc)
539e2795 1261{
00bd8e72
SC
1262 return new wxCairoContext(this,dc);
1263}
1264
1265wxGraphicsContext * wxCairoRenderer::CreateContextFromNativeContext( void * context )
1266{
1267 return new wxCairoContext(this,(cairo_t*)context);
1268}
1269
1270
1271wxGraphicsContext * wxCairoRenderer::CreateContextFromNativeWindow( void * window )
1272{
1273#ifdef __WXGTK__
1274 return new wxCairoContext(this,(GdkDrawable)window);
1275#else
1276 return NULL;
1277#endif
1278}
1279
1280wxGraphicsContext * wxCairoRenderer::CreateContext( wxWindow* window )
1281{
1282 return new wxCairoContext(this, window );
1283}
1284
1285// Path
1286
1287wxGraphicsPath * wxCairoRenderer::CreatePath()
1288{
1289 return new wxCairoPath( this );
539e2795
SC
1290}
1291
00bd8e72
SC
1292
1293// Matrix
1294
1295wxGraphicsMatrix * wxCairoRenderer::CreateMatrix( wxDouble a, wxDouble b, wxDouble c, wxDouble d,
1296 wxDouble tx, wxDouble ty)
1297
184fc6c8 1298{
00bd8e72
SC
1299 wxCairoMatrix* m = new wxCairoMatrix( this );
1300 m->Set( a,b,c,d,tx,ty ) ;
1301 return m;
7ba86d93
RD
1302}
1303
00bd8e72 1304wxGraphicsPen* wxCairoRenderer::CreatePen(const wxPen& pen)
539e2795 1305{
00bd8e72
SC
1306 if ( !pen.Ok() || pen.GetStyle() == wxTRANSPARENT )
1307 return NULL;
1308 else
1309 return new wxCairoPen( this, pen );
539e2795
SC
1310}
1311
00bd8e72 1312wxGraphicsBrush* wxCairoRenderer::CreateBrush(const wxBrush& brush )
539e2795 1313{
00bd8e72
SC
1314 if ( !brush.Ok() || brush.GetStyle() == wxTRANSPARENT )
1315 return NULL;
1316 else
1317 return new wxCairoBrush( this, brush );
1318}
1319
1320// sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
1321wxGraphicsBrush* wxCairoRenderer::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
1322 const wxColour&c1, const wxColour&c2)
1323{
1324 wxCairoBrush* brush = new wxCairoBrush(this);
1325 brush->CreateLinearGradientBrush(x1, y1, x2, y2, c1, c2);
1326 return brush;
1327}
1328
1329// sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
1330// with radius r and color cColor
1331wxGraphicsBrush* wxCairoRenderer::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
1332 const wxColour &oColor, const wxColour &cColor)
1333{
1334 wxCairoBrush* brush = new wxCairoBrush(this);
1335 brush->CreateRadialGradientBrush(xo,yo,xc,yc,radius,oColor,cColor);
1336 return brush;
1337}
1338
1339// sets the font
1340wxGraphicsFont* wxCairoRenderer::CreateFont( const wxFont &font , const wxColour &col )
1341{
1342 if ( font.Ok() )
1343 return new wxCairoFont( this , font, col );
1344 else
1345 return NULL;
539e2795
SC
1346}
1347
7ba86d93 1348#endif // wxUSE_GRAPHICS_CONTEXT