Implement support for gradient stops for OS X.

Currently the code still doesn't work but OTOH it's not any worse than what it
was before.

See #11904.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63879 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2010-04-06 18:46:18 +00:00
parent 005ac806ea
commit ca1f7cb563

View File

@ -686,7 +686,42 @@ protected:
bool m_isShading;
CGFunctionRef m_gradientFunction;
CGShadingRef m_shading;
CGFloat *m_gradientComponents;
// information about a single gradient component
struct GradientComponent
{
CGFloat pos;
CGFloat red;
CGFloat green;
CGFloat blue;
CGFloat alpha;
};
// and information about all of them
struct GradientComponents
{
GradientComponents()
{
count = 0;
comps = NULL;
}
void Init(unsigned count_)
{
count = count_;
comps = new GradientComponent[count];
}
~GradientComponents()
{
delete [] comps;
}
unsigned count;
GradientComponent *comps;
};
GradientComponents m_gradientComponents;
};
wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData( wxGraphicsRenderer* renderer) : wxGraphicsObjectRefData( renderer )
@ -731,15 +766,12 @@ wxMacCoreGraphicsBrushData::~wxMacCoreGraphicsBrushData()
if( m_gradientFunction )
CGFunctionRelease(m_gradientFunction);
delete[] m_gradientComponents;
}
void wxMacCoreGraphicsBrushData::Init()
{
m_gradientFunction = NULL;
m_shading = NULL;
m_gradientComponents = NULL;
m_isShading = false;
}
@ -759,35 +791,70 @@ void wxMacCoreGraphicsBrushData::Apply( wxGraphicsContext* context )
void wxMacCoreGraphicsBrushData::CalculateShadingValues (void *info, const CGFloat *in, CGFloat *out)
{
CGFloat* colors = (CGFloat*) info ;
const GradientComponents& stops = *(GradientComponents*) info ;
CGFloat f = *in;
for( int i = 0 ; i < 4 ; ++i )
if (f <= 0.0)
{
out[i] = colors[i] + ( colors[4+i] - colors[i] ) * f;
// Start
out[0] = stops.comps[0].red;
out[1] = stops.comps[1].green;
out[2] = stops.comps[2].blue;
out[3] = stops.comps[3].alpha;
}
else if (f >= 1.0)
{
// end
out[0] = stops.comps[stops.count - 1].red;
out[1] = stops.comps[stops.count - 1].green;
out[2] = stops.comps[stops.count - 1].blue;
out[3] = stops.comps[stops.count - 1].alpha;
}
else
{
// Find first component with position greater than f
unsigned i;
for ( i = 0; i < stops.count; i++ )
{
if (stops.comps[i].pos > f)
break;
}
// Interpolated between stops
CGFloat diff = (f - stops.comps[i-1].pos);
CGFloat range = (stops.comps[i].pos - stops.comps[i-1].pos);
CGFloat fact = diff / range;
out[0] = stops.comps[i - 1].red + (stops.comps[i].red - stops.comps[i - 1].red) * fact;
out[0] = stops.comps[i - 1].green + (stops.comps[i].green - stops.comps[i - 1].green) * fact;
out[0] = stops.comps[i - 1].blue + (stops.comps[i].blue - stops.comps[i - 1].blue) * fact;
out[0] = stops.comps[i - 1].alpha + (stops.comps[i].alpha - stops.comps[i - 1].alpha) * fact;
}
}
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 };
m_gradientComponents = new CGFloat[8] ;
m_gradientComponents[0] = (CGFloat) (c1.Red() / 255.0);
m_gradientComponents[1] = (CGFloat) (c1.Green() / 255.0);
m_gradientComponents[2] = (CGFloat) (c1.Blue() / 255.0);
m_gradientComponents[3] = (CGFloat) (c1.Alpha() / 255.0);
m_gradientComponents[4] = (CGFloat) (c2.Red() / 255.0);
m_gradientComponents[5] = (CGFloat) (c2.Green() / 255.0);
m_gradientComponents[6] = (CGFloat) (c2.Blue() / 255.0);
m_gradientComponents[7] = (CGFloat) (c2.Alpha() / 255.0);
return CGFunctionCreate ( m_gradientComponents, 1,
m_gradientComponents.Init(stops.GetCount());
for ( unsigned i = 0; i < m_gradientComponents.count; i++ )
{
const wxGraphicsGradientStop stop = stops.Item(i);
m_gradientComponents.comps[i].pos = stop.GetPosition();
const wxColour col = stop.GetColour();
m_gradientComponents.comps[i].red = (CGFloat) (col.Red() / 255.0);
m_gradientComponents.comps[i].green = (CGFloat) (col.Green() / 255.0);
m_gradientComponents.comps[i].blue = (CGFloat) (col.Blue() / 255.0);
m_gradientComponents.comps[i].alpha = (CGFloat) (col.Alpha() / 255.0);
}
return CGFunctionCreate ( &m_gradientComponents, 1,
input_value_range,
4,
output_value_ranges,