Add support for gradient stops to wxGraphicsContext.

Allow specifying a set of gradient stops instead of just the beginning and
ending colours. Add the new wxGraphicsGradientStop(s) classes and new
wxGraphicsContext::Create{Linear,Radial}GradientBrush() overloads. Also change
the same methods of wxGraphicsRenderer to take wxGraphicsGradientStops instead
of a pair of colours.

Implement the new API for MSW and Cairo. OS X still uses just the two colours
for now.

Closes #11897.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63857 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2010-04-05 12:15:11 +00:00
parent cd300ef760
commit 4ee4c7b948
8 changed files with 714 additions and 184 deletions

View File

@ -499,6 +499,7 @@ All (GUI):
- Add "initial selection" parameter to wxGetSingleChoice() (Nikolay Tjushkov).
- Implement wxDocument::Revert() (troelsk).
- Allow overriding print preview frame creation in docview (troelsk).
- Added support for gradient stops in wxGraphicsContext (Kit Bishop).
- Added wxTransparentColour.
GTK:

View File

@ -19,6 +19,7 @@
#include "wx/geometry.h"
#include "wx/dynarray.h"
#include "wx/dc.h"
#include "wx/vector.h"
enum wxAntialiasMode
{
@ -304,6 +305,81 @@ private:
extern WXDLLIMPEXP_DATA_CORE(wxGraphicsPath) wxNullGraphicsPath;
// Describes a single gradient stop.
class wxGraphicsGradientStop
{
public:
wxGraphicsGradientStop(wxColour col, float pos)
: m_col(col),
m_pos(pos)
{
}
// default copy ctor, assignment operator and dtor are ok
const wxColour& GetColour() const { return m_col; }
void SetColour(const wxColour& col) { m_col = col; }
float GetPosition() const { return m_pos; }
void SetPosition(float pos)
{
wxASSERT_MSG( pos >= 0 && pos < 1, "invalid gradient stop position" );
m_pos = pos;
}
private:
// The colour of this gradient band.
wxColour m_col;
// Its starting position: 0 is the beginning and 1 is the end.
float m_pos;
};
// A collection of gradient stops ordered by their positions (from lowest to
// highest). The first stop (index 0, position 0.0) is always the starting
// colour and the last one (index GetCount() - 1, position 1.0) is the end
// colour.
class WXDLLIMPEXP_CORE wxGraphicsGradientStops
{
public:
wxGraphicsGradientStops(wxColour startCol = wxTransparentColour,
wxColour endCol = wxTransparentColour)
{
// we can't use Add() here as it relies on having start/end stops as
// first/last array elements so do it manually
m_stops.push_back(wxGraphicsGradientStop(startCol, 0.));
m_stops.push_back(wxGraphicsGradientStop(endCol, 1.));
}
// default copy ctor, assignment operator and dtor are ok for this class
// Add a stop in correct order.
void Add(const wxGraphicsGradientStop& stop);
void Add(wxColour col, float pos) { Add(wxGraphicsGradientStop(col, pos)); }
// Get the number of stops.
unsigned GetCount() const { return m_stops.size(); }
// Return the stop at the given index (which must be valid).
wxGraphicsGradientStop Item(unsigned n) const { return m_stops.at(n); }
// Get/set start and end colours.
void SetStartColour(wxColour col)
{ m_stops[0].SetColour(col); }
wxColour GetStartColour() const
{ return m_stops[0].GetColour(); }
void SetEndColour(wxColour col)
{ m_stops[m_stops.size() - 1].SetColour(col); }
wxColour GetEndColour() const
{ return m_stops[m_stops.size() - 1].GetColour(); }
private:
// All the stops stored in ascending order of positions.
wxVector<wxGraphicsGradientStop> m_stops;
};
class WXDLLIMPEXP_CORE wxGraphicsContext : public wxGraphicsObject
{
public:
@ -348,14 +424,29 @@ public:
virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) const;
// sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2) const;
// sets the brush to a linear gradient, starting at (x1,y1) and ending at
// (x2,y2) with the given boundary colours or the specified stops
wxGraphicsBrush
CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxColour& c1, const wxColour& c2) const;
wxGraphicsBrush
CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops) const;
// sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
// with radius r and color cColor
virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor) const;
// sets the brush to a radial gradient originating at (xo,yc) and ending
// on a circle around (xc,yc) with the given radius; the colours may be
// specified by just the two extremes or the full array of gradient stops
wxGraphicsBrush
CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour& oColor, const wxColour& cColor) const;
wxGraphicsBrush
CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc, wxDouble radius,
const wxGraphicsGradientStops& stops) const;
// sets the font
virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) const;
@ -644,21 +735,26 @@ public:
virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) = 0;
// sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2) = 0;
// Gradient brush creation functions may not honour all the stops specified
// stops and use just its boundary colours (this is currently the case
// under OS X)
virtual wxGraphicsBrush
CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops) = 0;
// sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
// with radius r and color cColor
virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor) = 0;
virtual wxGraphicsBrush
CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxGraphicsGradientStops& stops) = 0;
// sets the font
// sets the font
virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) = 0;
// create a native bitmap representation
virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) = 0;
// create a graphics bitmap from a native bitmap
virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap ) = 0;

View File

@ -206,14 +206,14 @@ public:
enum wxAntialiasMode
{
/** No anti-aliasing */
wxANTIALIAS_NONE,
wxANTIALIAS_NONE,
/** The default anti-aliasing */
wxANTIALIAS_DEFAULT,
};
/**
Compositing is done using Porter-Duff compositions
Compositing is done using Porter-Duff compositions
(see http://keithp.com/~keithp/porterduff/p253-porter.pdf) with
wxGraphicsContext::SetCompositionMode
@ -361,15 +361,25 @@ public:
static wxGraphicsContext* CreateFromNativeWindow(void* window);
/**
Creates a native brush, having a linear gradient, starting at
(@a x1, @a y1) with color @a c1 to (@a x2, @a y2) with color @a c2.
Creates a native brush with a linear gradient.
The brush starts at (@a x1, @a y1) and ends at (@a x2, @a y2). Either
just the start and end gradient colours (@a c1 and @a c2) or full set
of gradient @a stops can be specified.
The version taking wxGraphicsGradientStops is new in wxWidgets 2.9.1.
*/
virtual wxGraphicsBrush CreateLinearGradientBrush(wxDouble x1,
wxDouble y1,
wxDouble x2,
wxDouble y2,
const wxColour& c1,
const wxColour& c2) const;
//@{
wxGraphicsBrush
CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxColour& c1, const wxColour& c2) const;
wxGraphicsBrush
CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops) const;
//@}
/**
Creates a native affine transformation matrix from the passed in
@ -391,15 +401,30 @@ public:
virtual wxGraphicsPen CreatePen(const wxPen& pen) const;
/**
Creates a native brush, having a radial gradient originating at
(@a xo, @a yc) with color @a oColour and ends on a circle around
(@a xc, @a yc) with the given @a radius and color @a cColour.
Creates a native brush with a radial gradient.
The brush originats at (@a xo, @a yc) and ends on a circle around
(@a xc, @a yc) with the given @a radius.
The gradient may be specified either by its start and end colours @a
oColor and @a cColor or by a full set of gradient @a stops.
The version taking wxGraphicsGradientStops is new in wxWidgets 2.9.1.
*/
virtual wxGraphicsBrush CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxColour& oColor,
const wxColour& cColor) const;
//@{
virtual wxGraphicsBrush
CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxColour& oColor,
const wxColour& cColor) const;
virtual wxGraphicsBrush
CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxGraphicsGradientStops& stops) = 0;
//@}
/**
Draws the bitmap. In case of a mono bitmap, this is treated as a mask
@ -611,39 +636,152 @@ public:
virtual void Translate(wxDouble dx, wxDouble dy) = 0;
/**
Redirects all rendering is done into a fully transparent temporary context
Redirects all rendering is done into a fully transparent temporary context
*/
virtual void BeginLayer(wxDouble opacity) = 0;
/**
Composites back the drawings into the context with the opacity given at
/**
Composites back the drawings into the context with the opacity given at
the BeginLayer call
*/
virtual void EndLayer() = 0;
/**
/**
Sets the antialiasing mode, returns true if it supported
*/
virtual bool SetAntialiasMode(wxAntialiasMode antialias) = 0;
/**
/**
Returns the current shape antialiasing mode
*/
virtual wxAntialiasMode GetAntialiasMode() const ;
/**
Sets the compositing operator, returns true if it supported
*/
virtual bool SetCompositionMode(wxCompositionMode op) = 0;
/**
/**
Returns the current compositing operator
*/
virtual wxCompositionMode GetCompositionMode() const;
};
/**
Represents a single gradient stop in a collection of gradient stops as
represented by wxGraphicsGradientStops.
@library{wxcore}
@category{gdi}
@since 2.9.1
*/
class wxGraphicsGradientStop
{
public:
/**
Creates a stop with the given colour and position.
@param col The colour of this stop. Note that the alpha component of
the colour is honoured thus allowing the background colours to
partially show through the gradient.
@param pos The stop position, must be in [0, 1) range with 0 being the
beginning and 1 the end of the gradient (but it doesn't make sense
to create a stop at position 1 because it would never be visible
anyhow).
*/
wxGraphicsGradientStop(wxColour col, float pos);
/// Return the stop colour.
const wxColour& GetColour() const;
/**
Change the stop colour.
@param col The new colour.
*/
void SetColour(const wxColour& col);
/// Return the stop position.
float GetPosition() const;
/**
Change the stop position.
@param pos The new position, must always be in [0, 1) range.
*/
void SetPosition(float pos);
};
/**
Represents a collection of wxGraphicGradientStop values for use with
CreateLinearGradientBrush and CreateRadialGradientBrush.
The stops are maintained in order of position. If two or more stops are
added with the same position then the one(s) added later come later.
This can be useful for producing discontinuities in the colour gradient.
Notice that this class is write-once, you can't modify the stops once they
had been added.
@library{wxcore}
@category{gdi}
@since 2.9.1
*/
class wxGraphicsGradientStops
{
public:
/**
Initializes the gradient stops with the given boundary colours.
Creates a wxGraphicsGradientStops instance with start colour given
by @a startCol and end colour given by @a endCol.
*/
wxGraphicsGradientStops(wxColour startCol = wxTransparentColour,
wxColour endCol = wxTransparentColour);
/**
Add a new stop.
*/
//@{
void Add(const wxGraphicsGradientStop& stop);
void Add(wxColour col, float pos);
//@}
/**
Returns the stop at the given index.
@param n The index, must be in [0, GetCount()) range.
*/
wxGraphicsGradientStop Item(unsigned n) const;
/**
Returns the number of stops.
*/
unsigned GetCount() const;
/**
Set the start colour to @a col
*/
void SetStartColour(wxColour col);
/**
Returns the start colour.
*/
wxColour GetStartColour() const;
/**
Set the end colour to @a col
*/
void SetEndColour(wxColour col);
/**
Returns the end colour.
*/
wxColour GetEndColour() const;
};
/**
@class wxGraphicsRenderer
@ -707,7 +845,7 @@ public:
virtual wxGraphicsContext* CreateContextFromNativeWindow(void* window) = 0;
/**
Creates a wxGraphicsContext that can be used for measuring texts only.
Creates a wxGraphicsContext that can be used for measuring texts only.
No drawing commands are allowed.
*/
virtual wxGraphicsContext * CreateMeasuringContext() = 0;
@ -718,16 +856,18 @@ public:
virtual wxGraphicsFont CreateFont(const wxFont& font,
const wxColour& col = *wxBLACK) = 0;
/**
Creates a native brush, having a linear gradient, starting at
(@a x1, @a y1) with color @a c1 to (@a x2, @a y2) with color @a c2.
Creates a native brush with a linear gradient.
Stops support is new since wxWidgets 2.9.1, previously only the start
and end colours could be specified.
*/
virtual wxGraphicsBrush CreateLinearGradientBrush(wxDouble x1,
wxDouble y1,
wxDouble x2,
wxDouble y2,
const wxColour& c1,
const wxColour& c2) = 0;
const wxGraphicsGradientStops& stops) = 0;
/**
Creates a native affine transformation matrix from the passed in
@ -749,15 +889,15 @@ public:
virtual wxGraphicsPen CreatePen(const wxPen& pen) = 0;
/**
Creates a native brush, having a radial gradient originating at
(@a xo, @a yc) with color @a oColour and ends on a circle around
(@a xc, @a yc) with the given @a radius and color @a cColour.
Creates a native brush with a radial gradient.
Stops support is new since wxWidgets 2.9.1, previously only the start
and end colours could be specified.
*/
virtual wxGraphicsBrush CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxColour& oColour,
const wxColour& cColour) = 0;
const wxGraphicsGradientStops& stops) = 0;
/**
Returns the default renderer on this platform. On OS X this is the Core

View File

@ -955,7 +955,7 @@ void MyCanvas::DrawGraphics(wxGraphicsContext* gc)
{
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
gc->SetFont(font,*wxBLACK);
// make a path that contains a circle and some lines, centered at 0,0
wxGraphicsPath path = gc->CreatePath() ;
path.AddCircle( 0, 0, BASE2 );
@ -965,14 +965,14 @@ void MyCanvas::DrawGraphics(wxGraphicsContext* gc)
path.AddLineToPoint(BASE2, 0);
path.CloseSubpath();
path.AddRectangle(-BASE4, -BASE4/2, BASE2, BASE4);
// Now use that path to demonstrate various capbilites of the grpahics context
gc->PushState(); // save current translation/scale/other state
gc->PushState(); // save current translation/scale/other state
gc->Translate(60, 75); // reposition the context origin
gc->SetPen(wxPen("navy", 1));
gc->SetBrush(wxBrush("pink"));
for( int i = 0 ; i < 3 ; ++i )
{
wxString label;
@ -1005,11 +1005,11 @@ void MyCanvas::DrawGraphics(wxGraphicsContext* gc)
}
gc->Translate(2*BASE, 0);
}
gc->PopState(); // restore saved state
gc->PushState(); // save it again
gc->Translate(60, 200); // offset to the lower part of the window
gc->DrawText("Scale", 0, -BASE2);
gc->Translate(0, 20);
@ -1017,14 +1017,14 @@ void MyCanvas::DrawGraphics(wxGraphicsContext* gc)
for( int i = 0 ; i < 8 ; ++i )
{
gc->Scale(1.08, 1.08); // increase scale by 8%
gc->Translate(5,5);
gc->Translate(5,5);
gc->DrawPath(path);
}
gc->PopState(); // restore saved state
gc->PushState(); // save it again
gc->Translate(400, 200);
gc->Translate(400, 200);
gc->DrawText("Rotate", 0, -BASE2);
// Move the origin over to the next location
@ -1034,16 +1034,16 @@ void MyCanvas::DrawGraphics(wxGraphicsContext* gc)
// and changing colors as we go
for ( int angle = 0 ; angle < 360 ; angle += 30 )
{
gc->PushState(); // save this new current state so we can
gc->PushState(); // save this new current state so we can
// pop back to it at the end of the loop
wxImage::RGBValue val = wxImage::HSVtoRGB(wxImage::HSVValue(float(angle)/360, 1, 1));
gc->SetBrush(wxBrush(wxColour(val.red, val.green, val.blue, 64)));
gc->SetPen(wxPen(wxColour(val.red, val.green, val.blue, 128)));
// use translate to artfully reposition each drawn path
gc->Translate(1.5 * BASE2 * cos(DegToRad(angle)),
1.5 * BASE2 * sin(DegToRad(angle)));
// use Rotate to rotate the path
gc->Rotate(DegToRad(angle));
@ -1231,6 +1231,7 @@ void MyCanvas::DrawGradients(wxDC& dc)
r.Offset(0, TEXT_HEIGHT);
dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxUP);
wxRect gfr = wxRect(r);
// RHS: concentric
r = wxRect(200, 10, 50, 50);
@ -1283,6 +1284,127 @@ void MyCanvas::DrawGradients(wxDC& dc)
dc.DrawRectangle(r4);
r4.Deflate(1);
dc.GradientFillLinear(r4, wxColour(0,0,0), wxColour(0,255,0), wxWEST);
#if wxUSE_GRAPHICS_CONTEXT
if (m_useContext)
{
wxGCDC &gdc = (wxGCDC&)dc;
wxGraphicsContext *gc = gdc.GetGraphicsContext();
wxGraphicsPath pth;
wxGraphicsGradientStops stops;
gfr.Offset(0, gfr.height + 10);
dc.DrawText(wxT("Linear Gradient with Stops"), gfr.x, gfr.y);
gfr.Offset(0, TEXT_HEIGHT);
stops = wxGraphicsGradientStops(wxColour(255,0,0), wxColour(0,0,255));
stops.Add(wxColour(255,255,0), 0.33f);
stops.Add(wxColour(0,255,0), 0.67f);
gc->SetBrush(gc->CreateLinearGradientBrush(gfr.x, gfr.y,
gfr.x + gfr.width, gfr.y + gfr.height,
stops));
pth = gc->CreatePath();
pth.MoveToPoint(gfr.x,gfr.y);
pth.AddLineToPoint(gfr.x + gfr.width,gfr.y);
pth.AddLineToPoint(gfr.x + gfr.width,gfr.y+gfr.height);
pth.AddLineToPoint(gfr.x,gfr.y+gfr.height);
pth.CloseSubpath();
gc->FillPath(pth);
gfr.Offset(0, gfr.height + 10);
dc.DrawText(wxT("Radial Gradient with Stops"), gfr.x, gfr.y);
gfr.Offset(0, TEXT_HEIGHT);
gc->SetBrush(gc->CreateRadialGradientBrush(gfr.x + gfr.width / 2,
gfr.y + gfr.height / 2,
gfr.x + gfr.width / 2,
gfr.y + gfr.height / 2,
gfr.width / 2,
stops));
pth = gc->CreatePath();
pth.MoveToPoint(gfr.x,gfr.y);
pth.AddLineToPoint(gfr.x + gfr.width,gfr.y);
pth.AddLineToPoint(gfr.x + gfr.width,gfr.y+gfr.height);
pth.AddLineToPoint(gfr.x,gfr.y+gfr.height);
pth.CloseSubpath();
gc->FillPath(pth);
gfr.Offset(0, gfr.height + 10);
dc.DrawText(wxT("Linear Gradient with Stops and Gaps"), gfr.x, gfr.y);
gfr.Offset(0, TEXT_HEIGHT);
stops = wxGraphicsGradientStops(wxColour(255,0,0), wxColour(0,0,255));
stops.Add(wxColour(255,255,0), 0.33f);
stops.Add(wxTransparentColour, 0.33f);
stops.Add(wxTransparentColour, 0.67f);
stops.Add(wxColour(0,255,0), 0.67f);
gc->SetBrush(gc->CreateLinearGradientBrush(gfr.x, gfr.y + gfr.height,
gfr.x + gfr.width, gfr.y,
stops));
pth = gc->CreatePath();
pth.MoveToPoint(gfr.x,gfr.y);
pth.AddLineToPoint(gfr.x + gfr.width,gfr.y);
pth.AddLineToPoint(gfr.x + gfr.width,gfr.y+gfr.height);
pth.AddLineToPoint(gfr.x,gfr.y+gfr.height);
pth.CloseSubpath();
gc->FillPath(pth);
gfr.Offset(0, gfr.height + 10);
dc.DrawText(wxT("Radial Gradient with Stops and Gaps"), gfr.x, gfr.y);
gfr.Offset(0, TEXT_HEIGHT);
gc->SetBrush(gc->CreateRadialGradientBrush(gfr.x + gfr.width / 2,
gfr.y + gfr.height / 2,
gfr.x + gfr.width / 2,
gfr.y + gfr.height / 2,
gfr.width / 2,
stops));
pth = gc->CreatePath();
pth.MoveToPoint(gfr.x,gfr.y);
pth.AddLineToPoint(gfr.x + gfr.width,gfr.y);
pth.AddLineToPoint(gfr.x + gfr.width,gfr.y+gfr.height);
pth.AddLineToPoint(gfr.x,gfr.y+gfr.height);
pth.CloseSubpath();
gc->FillPath(pth);
gfr.Offset(0, gfr.height + 10);
dc.DrawText(wxT("Gradients with Stops and Transparency"), gfr.x, gfr.y);
gfr.Offset(0, TEXT_HEIGHT);
stops = wxGraphicsGradientStops(wxColour(255,0,0), wxTransparentColour);
stops.Add(wxColour(255,0,0), 0.33f);
stops.Add(wxTransparentColour, 0.33f);
stops.Add(wxTransparentColour, 0.67f);
stops.Add(wxColour(0,0,255), 0.67f);
stops.Add(wxColour(0,0,255), 1.0f);
pth = gc->CreatePath();
pth.MoveToPoint(gfr.x,gfr.y);
pth.AddLineToPoint(gfr.x + gfr.width,gfr.y);
pth.AddLineToPoint(gfr.x + gfr.width,gfr.y+gfr.height);
pth.AddLineToPoint(gfr.x,gfr.y+gfr.height);
pth.CloseSubpath();
gc->SetBrush(gc->CreateRadialGradientBrush(gfr.x + gfr.width / 2,
gfr.y + gfr.height / 2,
gfr.x + gfr.width / 2,
gfr.y + gfr.height / 2,
gfr.width / 2,
stops));
gc->FillPath(pth);
stops = wxGraphicsGradientStops(wxColour(255,0,0, 128), wxColour(0,0,255, 128));
stops.Add(wxColour(255,255,0,128), 0.33f);
stops.Add(wxColour(0,255,0,128), 0.67f);
gc->SetBrush(gc->CreateLinearGradientBrush(gfr.x, gfr.y,
gfr.x + gfr.width, gfr.y,
stops));
gc->FillPath(pth);
}
#endif // wxUSE_GRAPHICS_CONTEXT
}
void MyCanvas::DrawRegions(wxDC& dc)
@ -1474,7 +1596,7 @@ void MyCanvas::OnMouseMove(wxMouseEvent &event)
str.Printf( wxT("Current mouse position: %d,%d"), (int)x, (int)y );
m_owner->SetStatusText( str );
}
if ( m_rubberBand )
{
int x,y, xx, yy ;
@ -1504,8 +1626,8 @@ void MyCanvas::OnMouseMove(wxMouseEvent &event)
void MyCanvas::OnMouseDown(wxMouseEvent &event)
{
int x,y,xx,yy ;
event.GetPosition(&x,&y);
int x,y,xx,yy ;
event.GetPosition(&x,&y);
CalcUnscrolledPosition( x, y, &xx, &yy );
m_anchorpoint = wxPoint( xx , yy ) ;
m_currentpoint = m_anchorpoint ;
@ -1530,9 +1652,9 @@ void MyCanvas::OnMouseUp(wxMouseEvent &event)
int x,y,xx,yy ;
event.GetPosition(&x,&y);
CalcUnscrolledPosition( x, y, &xx, &yy );
wxString str;
str.Printf( wxT("Rectangle selection from %d,%d to %d,%d"),
str.Printf( wxT("Rectangle selection from %d,%d to %d,%d"),
m_anchorpoint.x, m_anchorpoint.y , (int)xx, (int)yy );
wxMessageBox( str , wxT("Rubber-Banding") );
@ -1658,8 +1780,8 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
m_xAxisReversed =
m_yAxisReversed = false;
m_backgroundMode = wxSOLID;
m_colourForeground = *wxRED;
m_colourBackground = *wxBLUE;
m_colourForeground = *wxBLACK;
m_colourBackground = *wxLIGHT_GREY;
m_textureBackground = false;
m_canvas = new MyCanvas( this );

View File

@ -489,6 +489,41 @@ void wxGraphicsPathData::AddArcToPoint( wxDouble x1, wxDouble y1 , wxDouble x2,
AddLineToPoint(p2.m_x,p2.m_y);
}
//-----------------------------------------------------------------------------
// wxGraphicsGradientStops
//-----------------------------------------------------------------------------
void wxGraphicsGradientStops::Add(const wxGraphicsGradientStop& stop)
{
for ( wxVector<wxGraphicsGradientStop>::iterator it = m_stops.begin();
it != m_stops.end();
++it )
{
if ( stop.GetPosition() < it->GetPosition() )
{
if ( it != m_stops.begin() )
{
m_stops.insert(it, stop);
}
else // we shouldn't be inserting it at the beginning
{
wxFAIL_MSG( "invalid gradient stop position < 0" );
}
return;
}
}
if ( stop.GetPosition() == 1. )
{
m_stops.insert(m_stops.end() - 1, stop);
}
else
{
wxFAIL_MSG( "invalid gradient stop position >= 1" );
}
}
//-----------------------------------------------------------------------------
// wxGraphicsContext Convenience Methods
//-----------------------------------------------------------------------------
@ -753,19 +788,55 @@ wxGraphicsBrush wxGraphicsContext::CreateBrush(const wxBrush& brush ) const
return GetRenderer()->CreateBrush(brush);
}
// sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
wxGraphicsBrush wxGraphicsContext::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2) const
wxGraphicsBrush
wxGraphicsContext::CreateLinearGradientBrush(
wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxColour& c1, const wxColour& c2) const
{
return GetRenderer()->CreateLinearGradientBrush(x1,y1,x2,y2,c1,c2);
return GetRenderer()->CreateLinearGradientBrush
(
x1, y1,
x2, y2,
wxGraphicsGradientStops(c1,c2)
);
}
// sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
// with radius r and color cColor
wxGraphicsBrush wxGraphicsContext::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor) const
wxGraphicsBrush
wxGraphicsContext::CreateLinearGradientBrush(
wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& gradientStops) const
{
return GetRenderer()->CreateRadialGradientBrush(xo,yo,xc,yc,radius,oColor,cColor);
return GetRenderer()->CreateLinearGradientBrush(x1,y1,x2,y2, gradientStops);
}
wxGraphicsBrush
wxGraphicsContext::CreateRadialGradientBrush(
wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor) const
{
return GetRenderer()->CreateRadialGradientBrush
(
xo, yo,
xc, yc, radius,
wxGraphicsGradientStops(oColor, cColor)
);
}
wxGraphicsBrush
wxGraphicsContext::CreateRadialGradientBrush(
wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc, wxDouble radius,
const wxGraphicsGradientStops& gradientStops) const
{
return GetRenderer()->CreateRadialGradientBrush
(
xo, yo,
xc, yc, radius,
gradientStops
);
}
// sets the font

View File

@ -248,14 +248,20 @@ public:
~wxCairoBrushData ();
virtual void Apply( wxGraphicsContext* context );
void CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2 );
void CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor );
void CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops);
void CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc, wxDouble radius,
const wxGraphicsGradientStops& stops);
protected:
virtual void Init();
// common part of Create{Linear,Radial}GradientBrush()
void AddGradientStops(const wxGraphicsGradientStops& stops);
private :
double m_red;
double m_green;
@ -683,26 +689,50 @@ void wxCairoBrushData::Apply( wxGraphicsContext* context )
}
}
void wxCairoBrushData::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2 )
void wxCairoBrushData::AddGradientStops(const wxGraphicsGradientStops& stops)
{
m_brushPattern = cairo_pattern_create_linear(x1,y1,x2,y2);
cairo_pattern_add_color_stop_rgba(m_brushPattern,0.0,c1.Red()/255.0,
c1.Green()/255.0, c1.Blue()/255.0,c1.Alpha()/255.0);
cairo_pattern_add_color_stop_rgba(m_brushPattern,1.0,c2.Red()/255.0,
c2.Green()/255.0, c2.Blue()/255.0,c2.Alpha()/255.0);
wxASSERT_MSG(cairo_pattern_status(m_brushPattern) == CAIRO_STATUS_SUCCESS, wxT("Couldn't create cairo pattern"));
// loop over all the stops, they include the beginning and ending ones
const unsigned numStops = stops.GetCount();
for ( unsigned n = 0; n < numStops; n++ )
{
const wxGraphicsGradientStop stop = stops.Item(n);
const wxColour col = stop.GetColour();
cairo_pattern_add_color_stop_rgba
(
m_brushPattern,
stop.GetPosition(),
col.Red()/255.0,
col.Green()/255.0,
col.Blue()/255.0,
col.Alpha()/255.0
);
}
wxASSERT_MSG(cairo_pattern_status(m_brushPattern) == CAIRO_STATUS_SUCCESS,
wxT("Couldn't create cairo pattern"));
}
void wxCairoBrushData::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor )
void
wxCairoBrushData::CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops)
{
m_brushPattern = cairo_pattern_create_linear(x1,y1,x2,y2);
AddGradientStops(stops);
}
void
wxCairoBrushData::CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxGraphicsGradientStops& stops)
{
m_brushPattern = cairo_pattern_create_radial(xo,yo,0.0,xc,yc,radius);
cairo_pattern_add_color_stop_rgba(m_brushPattern,0.0,oColor.Red()/255.0,
oColor.Green()/255.0, oColor.Blue()/255.0,oColor.Alpha()/255.0);
cairo_pattern_add_color_stop_rgba(m_brushPattern,1.0,cColor.Red()/255.0,
cColor.Green()/255.0, cColor.Blue()/255.0,cColor.Alpha()/255.0);
wxASSERT_MSG(cairo_pattern_status(m_brushPattern) == CAIRO_STATUS_SUCCESS, wxT("Couldn't create cairo pattern"));
AddGradientStops(stops);
}
void wxCairoBrushData::Init()
@ -1113,10 +1143,10 @@ wxCairoBitmapData::~wxCairoBitmapData()
{
if (m_pattern)
cairo_pattern_destroy(m_pattern);
if (m_surface)
cairo_surface_destroy(m_surface);
delete [] m_buffer;
}
@ -1735,14 +1765,16 @@ public :
virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) ;
// sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2) ;
virtual wxGraphicsBrush
CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops);
// sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
// with radius r and color cColor
virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor) ;
virtual wxGraphicsBrush
CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxGraphicsGradientStops& stops);
// sets the font
virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ;
@ -1874,25 +1906,26 @@ wxGraphicsBrush wxCairoRenderer::CreateBrush(const wxBrush& brush )
}
}
// sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
wxGraphicsBrush wxCairoRenderer::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2)
wxGraphicsBrush
wxCairoRenderer::CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops)
{
wxGraphicsBrush p;
wxCairoBrushData* d = new wxCairoBrushData( this );
d->CreateLinearGradientBrush(x1, y1, x2, y2, c1, c2);
d->CreateLinearGradientBrush(x1, y1, x2, y2, stops);
p.SetRefData(d);
return p;
}
// sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
// with radius r and color cColor
wxGraphicsBrush wxCairoRenderer::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor)
wxGraphicsBrush
wxCairoRenderer::CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc, wxDouble r,
const wxGraphicsGradientStops& stops)
{
wxGraphicsBrush p;
wxCairoBrushData* d = new wxCairoBrushData( this );
d->CreateRadialGradientBrush(xo,yo,xc,yc,radius,oColor,cColor);
d->CreateRadialGradientBrush(xo, yo, xc, yc, r, stops);
p.SetRefData(d);
return p;
}

View File

@ -246,16 +246,24 @@ public:
wxGDIPlusBrushData( wxGraphicsRenderer* renderer, const wxBrush &brush );
~wxGDIPlusBrushData ();
void CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2 );
void CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor );
void CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops);
void CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxGraphicsGradientStops& stops);
virtual Brush* GetGDIPlusBrush() { return m_brush; }
protected:
virtual void Init();
private :
private:
// common part of Create{Linear,Radial}GradientBrush()
template <typename T>
void SetGradientStops(T *brush, const wxGraphicsGradientStops& stops);
Brush* m_brush;
Image* m_brushImage;
GraphicsPath* m_brushPath;
@ -628,28 +636,67 @@ void wxGDIPlusBrushData::Init()
m_brushPath= NULL;
}
void wxGDIPlusBrushData::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, const wxColour&c1, const wxColour&c2)
template <typename T>
void
wxGDIPlusBrushData::SetGradientStops(T *brush,
const wxGraphicsGradientStops& stops)
{
m_brush = new LinearGradientBrush( PointF( x1,y1) , PointF( x2,y2),
Color( c1.Alpha(), c1.Red(),c1.Green() , c1.Blue() ),
Color( c2.Alpha(), c2.Red(),c2.Green() , c2.Blue() ));
const unsigned numStops = stops.GetCount();
if ( numStops <= 2 )
{
// initial and final colours are set during the brush creation, nothing
// more to do
return;
}
wxVector<Color> colors(numStops);
wxVector<REAL> positions(numStops);
for ( unsigned i = 0; i < numStops; i++ )
{
wxGraphicsGradientStop stop = stops.Item(i);
colors[i] = wxColourToColor(stop.GetColour());
positions[i] = stop.GetPosition();
}
brush->SetInterpolationColors(&colors[0], &positions[0], numStops);
}
void wxGDIPlusBrushData::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor)
void
wxGDIPlusBrushData::CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops)
{
LinearGradientBrush * const
brush = new LinearGradientBrush(PointF(x1, y1) , PointF(x2, y2),
wxColourToColor(stops.GetStartColour()),
wxColourToColor(stops.GetEndColour()));
m_brush = brush;
SetGradientStops(brush, stops);
}
void
wxGDIPlusBrushData::CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxGraphicsGradientStops& stops)
{
// Create a path that consists of a single circle.
m_brushPath = new GraphicsPath();
m_brushPath->AddEllipse( (REAL)(xc-radius), (REAL)(yc-radius), (REAL)(2*radius), (REAL)(2*radius));
m_brushPath->AddEllipse( (REAL)(xc-radius), (REAL)(yc-radius),
(REAL)(2*radius), (REAL)(2*radius));
PathGradientBrush *b = new PathGradientBrush(m_brushPath);
m_brush = b;
b->SetCenterPoint( PointF(xo,yo));
b->SetCenterColor(Color( oColor.Alpha(), oColor.Red(),oColor.Green() , oColor.Blue() ));
PathGradientBrush * const brush = new PathGradientBrush(m_brushPath);
m_brush = brush;
brush->SetCenterPoint(PointF(xo, yo));
brush->SetCenterColor(wxColourToColor(stops.GetStartColour()));
Color colors[] = {Color( cColor.Alpha(), cColor.Red(),cColor.Green() , cColor.Blue() )};
const Color col(wxColourToColor(stops.GetEndColour()));
int count = 1;
b->SetSurroundColors(colors, &count);
brush->SetSurroundColors(&col, &count);
SetGradientStops(brush, stops);
}
//-----------------------------------------------------------------------------
@ -1596,15 +1643,16 @@ public :
virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) ;
// sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2) ;
// sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
// with radius r and color cColor
virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor) ;
virtual wxGraphicsBrush
CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops);
virtual wxGraphicsBrush
CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxGraphicsGradientStops& stops);
// sets the font
virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ;
@ -1613,7 +1661,7 @@ public :
// create a graphics bitmap from a native bitmap
virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap );
// create a subimage from a native image representation
virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h );
@ -1789,27 +1837,29 @@ wxGraphicsBrush wxGDIPlusRenderer::CreateBrush(const wxBrush& brush )
}
}
// sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
wxGraphicsBrush wxGDIPlusRenderer::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2)
wxGraphicsBrush
wxGDIPlusRenderer::CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops)
{
ENSURE_LOADED_OR_RETURN(wxNullGraphicsBrush);
wxGraphicsBrush p;
wxGDIPlusBrushData* d = new wxGDIPlusBrushData( this );
d->CreateLinearGradientBrush(x1, y1, x2, y2, c1, c2);
d->CreateLinearGradientBrush(x1, y1, x2, y2, stops);
p.SetRefData(d);
return p;
}
// sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
// with radius r and color cColor
wxGraphicsBrush wxGDIPlusRenderer::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor)
wxGraphicsBrush
wxGDIPlusRenderer::CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxGraphicsGradientStops& stops)
{
ENSURE_LOADED_OR_RETURN(wxNullGraphicsBrush);
wxGraphicsBrush p;
wxGDIPlusBrushData* d = new wxGDIPlusBrushData( this );
d->CreateRadialGradientBrush(xo,yo,xc,yc,radius,oColor,cColor);
d->CreateRadialGradientBrush(xo,yo,xc,yc,radius,stops);
p.SetRefData(d);
return p;
}

View File

@ -666,15 +666,18 @@ public:
~wxMacCoreGraphicsBrushData ();
virtual void Apply( wxGraphicsContext* context );
void CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2 );
void CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor );
void CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops);
void CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc, wxDouble radius,
const wxGraphicsGradientStops& stops);
virtual bool IsShading() { return m_isShading; }
CGShadingRef GetShading() { return m_shading; }
protected:
CGFunctionRef CreateGradientFunction( const wxColour& c1, const wxColour& c2 );
CGFunctionRef CreateGradientFunction(const wxGraphicsGradientStops& stops);
static void CalculateShadingValues (void *info, const CGFloat *in, CGFloat *out);
virtual void Init();
@ -691,19 +694,24 @@ wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData( wxGraphicsRenderer* rend
Init();
}
void wxMacCoreGraphicsBrushData::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2 )
void
wxMacCoreGraphicsBrushData::CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops)
{
m_gradientFunction = CreateGradientFunction( c1, c2 );
m_gradientFunction = CreateGradientFunction(stops);
m_shading = CGShadingCreateAxial( wxMacGetGenericRGBColorSpace(), CGPointMake((CGFloat) x1, (CGFloat) y1),
CGPointMake((CGFloat) x2,(CGFloat) y2), m_gradientFunction, true, true ) ;
m_isShading = true ;
}
void wxMacCoreGraphicsBrushData::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor )
void
wxMacCoreGraphicsBrushData::CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxGraphicsGradientStops& stops)
{
m_gradientFunction = CreateGradientFunction( oColor, cColor );
m_gradientFunction = CreateGradientFunction(stops);
m_shading = CGShadingCreateRadial( wxMacGetGenericRGBColorSpace(), CGPointMake((CGFloat) xo,(CGFloat) yo), 0,
CGPointMake((CGFloat) xc,(CGFloat) yc), (CGFloat) radius, m_gradientFunction, true, true ) ;
m_isShading = true ;
@ -759,8 +767,13 @@ void wxMacCoreGraphicsBrushData::CalculateShadingValues (void *info, const CGFlo
}
}
CGFunctionRef wxMacCoreGraphicsBrushData::CreateGradientFunction( const wxColour& c1, const wxColour& c2 )
CGFunctionRef
wxMacCoreGraphicsBrushData::CreateGradientFunction(const wxGraphicsGradientStops& stops)
{
// TODO: implement support for intermediate gradient stops
const wxColour c1 = stops.GetStartColour();
const wxColour c2 = stops.GetEndColour();
static const CGFunctionCallbacks callbacks = { 0, &CalculateShadingValues, NULL };
static const CGFloat input_value_range [2] = { 0, 1 };
static const CGFloat output_value_ranges [8] = { 0, 1, 0, 1, 0, 1, 0, 1 };
@ -1138,7 +1151,7 @@ public :
// appends a rectangle as a new closed subpath
virtual void AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h );
// appends a circle as a new closed subpath
// appends a circle as a new closed subpath
virtual void AddCircle( wxDouble x, wxDouble y, wxDouble r );
// appends an ellipsis as a new closed subpath fitting the passed rectangle
@ -2618,14 +2631,16 @@ public :
virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) ;
// sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2) ;
virtual wxGraphicsBrush
CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops);
// sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
// with radius r and color cColor
virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor) ;
virtual wxGraphicsBrush
CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxGraphicsGradientStops& stops);
// sets the font
virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ;
@ -2819,25 +2834,27 @@ wxGraphicsBitmap wxMacCoreGraphicsRenderer::CreateSubBitmap( const wxGraphicsBit
return wxNullGraphicsBitmap;
}
// sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2
wxGraphicsBrush wxMacCoreGraphicsRenderer::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2)
wxGraphicsBrush
wxMacCoreGraphicsRenderer::CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops)
{
wxGraphicsBrush p;
wxMacCoreGraphicsBrushData* d = new wxMacCoreGraphicsBrushData( this );
d->CreateLinearGradientBrush(x1, y1, x2, y2, c1, c2);
d->CreateLinearGradientBrush(x1, y1, x2, y2, stops);
p.SetRefData(d);
return p;
}
// sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc)
// with radius r and color cColor
wxGraphicsBrush wxMacCoreGraphicsRenderer::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor)
wxGraphicsBrush
wxMacCoreGraphicsRenderer::CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
wxDouble xc, wxDouble yc,
wxDouble radius,
const wxGraphicsGradientStops& stops)
{
wxGraphicsBrush p;
wxMacCoreGraphicsBrushData* d = new wxMacCoreGraphicsBrushData( this );
d->CreateRadialGradientBrush(xo,yo,xc,yc,radius,oColor,cColor);
d->CreateRadialGradientBrush(xo, yo, xc, yc, radius, stops);
p.SetRefData(d);
return p;
}