Vector<Gradient::ColorStop> SVGGradientElement::buildStops()
{
    Vector<Gradient::ColorStop> stops;

    float previousOffset = 0.0f;
    for (Node* n = firstChild(); n; n = n->nextSibling()) {
        SVGElement* element = n->isSVGElement() ? static_cast<SVGElement*>(n) : 0;
        if (!element || !element->isGradientStop())
            continue;

        SVGStopElement* stop = static_cast<SVGStopElement*>(element);
        Color color = stop->stopColorIncludingOpacity();

        // Figure out right monotonic offset
        float offset = stop->offset();
        offset = std::min(std::max(previousOffset, offset), 1.0f);
        previousOffset = offset;

        // Extract individual channel values
        // FIXME: Why doesn't ColorStop take a Color and an offset??
        float r, g, b, a;
        color.getRGBA(r, g, b, a);

        stops.append(Gradient::ColorStop(offset, r, g, b, a));
    }

    return stops;
}
Vector<SVGGradientStop> SVGGradientElement::buildStops() const
{
    Vector<SVGGradientStop> stops;
    RenderStyle* gradientStyle = 0;

    for (Node* n = firstChild(); n; n = n->nextSibling()) {
        SVGElement* element = n->isSVGElement() ? static_cast<SVGElement*>(n) : 0;

        if (element && element->isGradientStop()) {
            SVGStopElement* stop = static_cast<SVGStopElement*>(element);
            float stopOffset = stop->offset();

            Color color;
            float opacity;

            if (stop->renderer()) {
                RenderStyle* stopStyle = stop->renderer()->style();
                color = stopStyle->svgStyle()->stopColor();
                opacity = stopStyle->svgStyle()->stopOpacity();
            } else {
                // If there is no renderer for this stop element, then a parent element
                // set display="none" - ie. <g display="none"><linearGradient><stop>..
                // Unfortunately we have to manually rebuild the stop style. See pservers-grad-19-b.svg
                if (!gradientStyle)
                    gradientStyle = const_cast<SVGGradientElement*>(this)->styleForRenderer(parent()->renderer());

                RenderStyle* stopStyle = stop->resolveStyle(gradientStyle);

                color = stopStyle->svgStyle()->stopColor();
                opacity = stopStyle->svgStyle()->stopOpacity();

                stopStyle->deref(document()->renderArena());
            }

            stops.append(makeGradientStop(stopOffset, makeRGBA(color.red(), color.green(), color.blue(), int(opacity * 255.))));
        }
    }

    if (gradientStyle)
        gradientStyle->deref(document()->renderArena());

    return stops;
}
Example #3
0
void SVGGradientElement::rebuildStops() const
{
    if (m_resource && !ownerDocument()->parsing()) {
        Vector<KCGradientStop> stops;
         // FIXME: Manual style resolution is a hack
        RenderStyle* gradientStyle = const_cast<SVGGradientElement*>(this)->styleForRenderer(parent()->renderer());
        for (Node *n = firstChild(); n; n = n->nextSibling()) {
            SVGElement *element = svg_dynamic_cast(n);
            if (element && element->isGradientStop()) {
                SVGStopElement *stop = static_cast<SVGStopElement *>(element);
                float stopOffset = stop->offset()->baseVal();
                
                RenderStyle *stopStyle = document()->styleSelector()->styleForElement(stop, gradientStyle);
                Color c = stopStyle->svgStyle()->stopColor();
                float opacity = stopStyle->svgStyle()->stopOpacity();
                
                stops.append(makeGradientStop(stopOffset, makeRGBA(c.red(), c.green(), c.blue(), int(opacity * 255.))));
                stopStyle->deref(view()->renderArena());
            }
        }
        gradientStyle->deref(view()->renderArena());
        m_resource->setGradientStops(stops);
    }
}