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