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