static CGShadingRef CGShadingRefForRadialGradient(const SVGPaintServerRadialGradient* server)
{
    CGPoint center = CGPoint(server->gradientCenter());
    CGPoint focus = CGPoint(server->gradientFocal());
    double radius = server->gradientRadius();

    double fdx = focus.x - center.x;
    double fdy = focus.y - center.y;

    // Spec: If (fx, fy) lies outside the circle defined by (cx, cy) and r, set (fx, fy)
    // to the point of intersection of the line through (fx, fy) and the circle.
    if (sqrtf(fdx * fdx + fdy * fdy) > radius) { 
        double angle = atan2(focus.y * 100.0, focus.x * 100.0);
        focus.x = cos(angle) * radius;
        focus.y = sin(angle) * radius;
    }

    CGFunctionCallbacks callbacks = {0, cgGradientCallback, NULL};
    CGFloat domainLimits[2] = {0, 1};
    CGFloat rangeLimits[8] = {0, 1, 0, 1, 0, 1, 0, 1};
    CGFunctionRef shadingFunction = CGFunctionCreate((void *)server, 1, domainLimits, 4, rangeLimits, &callbacks);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGShadingRef shading = CGShadingCreateRadial(colorSpace, focus, 0, center, radius, shadingFunction, true, true);
    CGColorSpaceRelease(colorSpace);
    CGFunctionRelease(shadingFunction);
    return shading;
}
Exemplo n.º 2
0
void TIPGradientSetBlendingMode( TIPMutableGradientRef aGradient, TIPGradientBlendingMode blendingMode )
{
    aGradient->blendingMode = blendingMode;

    void *evaluationFunction = NULL;
    switch( aGradient->blendingMode ) {
    case TIPLinearBlendingMode:
        evaluationFunction = &TIPGradientLinearEvaluation;
        break;
    case TIPChromaticBlendingMode:
        evaluationFunction = &TIPGradientChromaticEvaluation;
        break;
    case TIPInverseChromaticBlendingMode:
        evaluationFunction = &TIPGradientInverseChromaticEvaluation;
        break;
    default:
        evaluationFunction = &TIPGradientLinearEvaluation;
        break;
    }

    if( aGradient->gradientFunction != NULL )
        CGFunctionRelease(aGradient->gradientFunction);

    CGFunctionCallbacks evaluationCallbackInfo = {0, evaluationFunction, NULL};

    static const CGFloat input_value_range[2] = {0.0f, 1.0f}; // range for the evaluator input
    static const CGFloat output_value_ranges[8] = {0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f}; // ranges for the evaluator output

    aGradient->gradientFunction = CGFunctionCreate(&(aGradient->elementList),
                                  1, input_value_range,
                                  4, output_value_ranges,
                                  &evaluationCallbackInfo);
}
static CGShadingRef CGShadingRefForLinearGradient(const SVGPaintServerLinearGradient* server)
{
    CGPoint start = CGPoint(server->gradientStart());
    CGPoint end = CGPoint(server->gradientEnd());

    CGFunctionCallbacks callbacks = {0, cgGradientCallback, NULL};
    CGFloat domainLimits[2] = {0, 1};
    CGFloat rangeLimits[8] = {0, 1, 0, 1, 0, 1, 0, 1};
    CGFunctionRef shadingFunction = CGFunctionCreate((void *)server, 1, domainLimits, 4, rangeLimits, &callbacks);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGShadingRef shading = CGShadingCreateAxial(colorSpace, start, end, shadingFunction, true, true);
    CGColorSpaceRelease(colorSpace);
    CGFunctionRelease(shadingFunction);
    return shading;
}
Exemplo n.º 4
0
CGShadingRef CanvasGradient::platformShading()
{
    if (m_shading)
        return m_shading;

    const CGFloat intervalRanges[2] = { 0, 1 };
    const CGFloat colorComponentRanges[4 * 2] = { 0, 1, 0, 1, 0, 1, 0, 1 };
    const CGFunctionCallbacks gradientCallbacks = { 0, gradientCallback, 0 };
    CGFunctionRef colorFunction = CGFunctionCreate(this, 1, intervalRanges, 4, colorComponentRanges, &gradientCallbacks);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    if (m_radial)
        m_shading = CGShadingCreateRadial(colorSpace, m_p0, m_r0, m_p1, m_r1, colorFunction, true, true);
    else
        m_shading = CGShadingCreateAxial(colorSpace, m_p0, m_p1, colorFunction, true, true);

    CGColorSpaceRelease(colorSpace);
    CGFunctionRelease(colorFunction);

    return m_shading;
}