IntSize SVGImage::containerSize() const
{
    if (!m_page)
        return IntSize();
    Frame* frame = m_page->mainFrame();
    SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
    if (!rootElement)
        return IntSize();

    RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer());
    if (!renderer)
        return IntSize();

    // If a container size is available it has precedence.
    IntSize containerSize = renderer->containerSize();
    if (!containerSize.isEmpty())
        return containerSize;

    // Assure that a container size is always given for a non-identity zoom level.
    ASSERT(renderer->style()->effectiveZoom() == 1);

    FloatSize currentSize;
    if (rootElement->intrinsicWidth().isFixed() && rootElement->intrinsicHeight().isFixed())
        currentSize = rootElement->currentViewportSize();
    else
        currentSize = rootElement->currentViewBoxRect().size();

    if (!currentSize.isEmpty())
        return IntSize(static_cast<int>(ceilf(currentSize.width())), static_cast<int>(ceilf(currentSize.height())));

    // As last resort, use CSS default intrinsic size.
    return IntSize(300, 150);
}
예제 #2
0
bool SVGSVGElement::widthAttributeEstablishesViewport() const
{
    if (!renderer() || renderer()->isSVGViewportContainer())
        return true;

    // Spec: http://www.w3.org/TR/SVG/coords.html#ViewportSpace
    // The ‘width’ attribute on the outermost svg element establishes the viewport's width, unless the following conditions are met:
    // - the SVG content is a separately stored resource that is embedded by reference (such as the ‘object’ element in XHTML [XHTML]), or
    //   the SVG content is embedded inline within a containing document;
    // - and the referencing element or containing document is styled using CSS [CSS2] or XSL [XSL];
    // - and there are CSS-compatible positioning properties ([CSS2], section 9.3) specified on the referencing element (e.g., the ‘object’ element)
    //   or on the containing document's outermost svg element that are sufficient to establish the width of the viewport. Under these conditions,
    //   the positioning properties establish the viewport's width.
    RenderSVGRoot* root = toRenderSVGRoot(renderer());

    // SVG embedded through object/embed/iframe.
    if (root->isEmbeddedThroughFrameContainingSVGDocument())
        return !root->hasReplacedLogicalWidth() && !document()->frame()->ownerRenderer()->hasReplacedLogicalWidth();

    // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
    if (root->isEmbeddedThroughSVGImage() || document()->documentElement() != this)
        return !root->hasReplacedLogicalWidth();

    return true;
}
예제 #3
0
void SVGImage::drawSVGToImageBuffer(ImageBuffer* buffer, const IntSize& size, float zoom, ShouldClearBuffer shouldClear)
{
    // FIXME: This doesn't work correctly with animations. If an image contains animations, that say run for 2 seconds,
    // and we currently have one <img> that displays us. If we open another document referencing the same SVGImage it
    // will display the document at a time where animations already ran - even though it has its own ImageBuffer.
    // We currently don't implement SVGSVGElement::setCurrentTime, and can NOT go back in time, once animations started.
    // There's no way to fix this besides avoiding style/attribute mutations from SVGAnimationElement.
    ASSERT(buffer);
    ASSERT(!size.isEmpty());

    if (!m_page)
        return;

    Frame* frame = m_page->mainFrame();
    SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement();
    if (!rootElement)
        return;
    RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer());
    if (!renderer)
        return;

    // Draw image at requested size.
    ImageObserver* observer = imageObserver();
    ASSERT(observer);

    // Temporarily reset image observer, we don't want to receive any changeInRect() calls due this relayout.
    setImageObserver(0);
    renderer->setContainerSize(size);
    frame->view()->resize(this->size());
    if (zoom != 1)
        frame->setPageZoomFactor(zoom);

    // Eventually clear image buffer.
    IntRect rect(IntPoint(), size);
    if (shouldClear == ClearImageBuffer)
        buffer->context()->clearRect(rect);

    // Draw SVG on top of ImageBuffer.
    draw(buffer->context(), rect, rect, ColorSpaceDeviceRGB, CompositeSourceOver);

    // Reset container size & zoom to initial state. Otherwhise the size() of this
    // image would return whatever last size was set by drawSVGToImageBuffer().
    if (zoom != 1)
        frame->setPageZoomFactor(1);

    renderer->setContainerSize(IntSize());
    frame->view()->resize(this->size());
    if (frame->view()->needsLayout())
        frame->view()->layout();

    setImageObserver(observer); 
}
예제 #4
0
void write(TextStream& ts, const RenderSVGRoot& root, int indent)
{
    writeIndent(ts, indent);
    ts << root.renderName();

    if (root.element()) {
        String tagName = getTagName(static_cast<SVGStyledElement*>(root.element()));
        if (!tagName.isEmpty())
            ts << " {" << tagName << "}";
    }

    ts << root << "\n";

    for (RenderObject* child = root.firstChild(); child; child = child->nextSibling())
        write(ts, *child, indent + 1);
}
예제 #5
0
void SVGImage::setContainerSize(const FloatSize& size)
{
    if (!m_page || !usesContainerSize())
        return;

    SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement();
    if (!rootElement)
        return;
    RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer());
    if (!renderer)
        return;

    FrameView* view = frameView();
    view->resize(this->containerSize());

    renderer->setContainerSize(IntSize(size));
}
예제 #6
0
bool SVGSVGElement::heightAttributeEstablishesViewport() const
{
    if (!renderer() || renderer()->isSVGViewportContainer())
        return true;

    // Spec: http://www.w3.org/TR/SVG/coords.html#IntrinsicSizing
    // Similarly, if there are positioning properties specified on the referencing element or on the outermost svg element
    // that are sufficient to establish the height of the viewport, then these positioning properties establish the viewport's
    // height; otherwise, the ‘height’ attribute on the outermost svg element establishes the viewport's height.
    RenderSVGRoot* root = toRenderSVGRoot(renderer());

    // SVG embedded through object/embed/iframe.
    if (root->isEmbeddedThroughFrameContainingSVGDocument())
        return !root->hasReplacedLogicalHeight() && !document()->frame()->ownerRenderer()->hasReplacedLogicalHeight();

    // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
    if (root->isEmbeddedThroughSVGImage() || document()->documentElement() != this)
        return !root->hasReplacedLogicalHeight();

    return true;
}