Ejemplo n.º 1
0
AffineTransform RenderSVGContainer::absoluteTransform() const
{
    AffineTransform ctm = RenderContainer::absoluteTransform();
    if (!parent()->isSVGContainer()) {
        SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
        ctm.scale(svg->currentScale());
        ctm.translate(svg->currentTranslate().x(), svg->currentTranslate().y());
    }
    ctm.translate(viewport().x(), viewport().y());
    return viewportTransform() * ctm;
}
Ejemplo n.º 2
0
JSValue jsSVGSVGElementCurrentScale(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
    UNUSED_PARAM(exec);
    SVGSVGElement* imp = static_cast<SVGSVGElement*>(static_cast<JSSVGSVGElement*>(asObject(slot.slotBase()))->impl());
    return jsNumber(exec, imp->currentScale());
}
Ejemplo n.º 3
0
void RenderSVGContainer::paint(PaintInfo& paintInfo, int parentX, int parentY)
{
    if (paintInfo.context->paintingDisabled())
        return;

    // This should only exist for <svg> renderers
    if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection)) 
        paintBoxDecorations(paintInfo, m_x + parentX, m_y + parentY);

    if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE)
        paintOutline(paintInfo.context, parentX, parentY, width(), height(), style());
    
    if (paintInfo.phase != PaintPhaseForeground || !drawsContents())
        return;

    const SVGRenderStyle* svgStyle = style()->svgStyle();
    AtomicString filterId(SVGURIReference::getTarget(svgStyle->filter()));

#if ENABLE(SVG_EXPERIMENTAL_FEATURES) 
    SVGResourceFilter* filter = getFilterById(document(), filterId);
#endif

    if (!firstChild()
#if ENABLE(SVG_EXPERIMENTAL_FEATURES) 
        && !filter
#endif
        )
        return; // Spec: groups w/o children still may render filter content.
    
    paintInfo.context->save();

    if (!parent()->isSVGContainer()) {
        // Translate from parent offsets (html renderers) to a relative transform (svg renderers)
        IntPoint origin;
        origin.move(parentX, parentY);
        origin.move(m_x, m_y);
        origin.move(borderLeft(), borderTop());
        origin.move(paddingLeft(), paddingTop());
        if (origin.x() || origin.y()) {
            paintInfo.context->concatCTM(AffineTransform().translate(origin.x(), origin.y()));
            paintInfo.rect.move(-origin.x(), -origin.y());
        }
        parentX = parentY = 0;
        SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
        paintInfo.context->concatCTM(AffineTransform().scale(svg->currentScale()));
    } else {
        // Only the root <svg> element should need any translations using the HTML/CSS system
        // parentX, parentY are also non-zero for first-level kids of these
        // CSS-transformed <svg> root-elements (due to RenderBox::paint) for any other element
        // they should be 0.   m_x, m_y should always be 0 for non-root svg containers
        ASSERT(m_x == 0);
        ASSERT(m_y == 0);
    }

    if (!viewport().isEmpty()) {
        if (style()->overflowX() != OVISIBLE)
            paintInfo.context->clip(enclosingIntRect(viewport())); // FIXME: Eventually we'll want float-precision clipping

        paintInfo.context->concatCTM(AffineTransform().translate(viewport().x(), viewport().y()));
    }
    if (!localTransform().isIdentity())
        paintInfo.context->concatCTM(localTransform());
    if (!parent()->isSVGContainer()) {
        SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
        paintInfo.context->concatCTM(AffineTransform().translate(svg->currentTranslate().x(), svg->currentTranslate().y()));
    }

    FloatRect strokeBBox = relativeBBox(true);

    SVGElement* svgElement = static_cast<SVGElement*>(element());
    ASSERT(svgElement && svgElement->document() && svgElement->isStyled());

    SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
 
    AtomicString clipperId(SVGURIReference::getTarget(svgStyle->clipPath()));
    AtomicString maskerId(SVGURIReference::getTarget(svgStyle->maskElement()));

    SVGResourceClipper* clipper = getClipperById(document(), clipperId);
    SVGResourceMasker* masker = getMaskerById(document(), maskerId);

    if (clipper) {
        clipper->addClient(styledElement);
        clipper->applyClip(paintInfo.context, strokeBBox);
    } else if (!clipperId.isEmpty())
        svgElement->document()->accessSVGExtensions()->addPendingResource(clipperId, styledElement);

    if (masker) {
        masker->addClient(styledElement);
        masker->applyMask(paintInfo.context, strokeBBox);
    } else if (!maskerId.isEmpty())
        svgElement->document()->accessSVGExtensions()->addPendingResource(maskerId, styledElement);

    float opacity = style()->opacity();
    if (opacity < 1.0f) {
        paintInfo.context->clip(enclosingIntRect(strokeBBox));
        paintInfo.context->beginTransparencyLayer(opacity);
    }

#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
    if (filter)
        filter->prepareFilter(paintInfo.context, strokeBBox);
    else if (!filterId.isEmpty())
        svgElement->document()->accessSVGExtensions()->addPendingResource(filterId, styledElement);
#endif

    if (!viewBox().isEmpty())
        paintInfo.context->concatCTM(viewportTransform());

    RenderContainer::paint(paintInfo, 0, 0);

#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
    if (filter)
        filter->applyFilter(paintInfo.context, strokeBBox);
#endif

    if (opacity < 1.0f)
        paintInfo.context->endTransparencyLayer();

    paintInfo.context->restore();
}