AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const
{
    AffineTransform viewBoxTransform;
    if (attributes()->getAttributeItem(SVGNames::viewBoxAttr))
        viewBoxTransform = viewBoxToViewTransform(width().value(this), height().value(this));

    AffineTransform transform;
    if (!isOutermostSVG())
        transform.translate(x().value(this), y().value(this));
    else if (mode == SVGLocatable::ScreenScope) {
        if (RenderObject* renderer = this->renderer()) {
            // Translate in our CSS parent coordinate space
            // FIXME: This doesn't work correctly with CSS transforms.
            FloatPoint location = renderer->localToAbsolute(FloatPoint(), false, true);

            // Be careful here! localToAbsolute() includes the x/y offset coming from the viewBoxToViewTransform(), because
            // RenderSVGRoot::localToBorderBoxTransform() (called through mapLocalToContainer(), called from localToAbsolute())
            // also takes the viewBoxToViewTransform() into account, so we have to subtract it here (original cause of bug #27183)
            transform.translate(location.x() - viewBoxTransform.e(), location.y() - viewBoxTransform.f());

            // Respect scroll offset.
            if (FrameView* view = document()->view()) {
                IntSize scrollOffset = view->scrollOffset();
                transform.translate(-scrollOffset.width(), -scrollOffset.height());
            }
        }
    }

    return transform.multLeft(viewBoxTransform);
}
RenderObject* SVGSVGElement::createRenderer(RenderArena* arena, RenderStyle*)
{
    if (isOutermostSVG())
        return new (arena) RenderSVGRoot(this);

    return new (arena) RenderSVGViewportContainer(this);
}
Esempio n. 3
0
TransformationMatrix SVGSVGElement::getScreenCTM() const
{
    document()->updateLayoutIgnorePendingStylesheets();
    FloatPoint rootLocation;    

    if (RenderObject* renderer = this->renderer()) {
        if (isOutermostSVG()) {
            // FIXME: This doesn't work correctly with CSS transforms.
            FloatPoint point;
            if (renderer->parent())
                point = renderer->localToAbsolute(point, true);
            rootLocation.move(point.x(), point.y());
        } else
            rootLocation.move(x().value(this), y().value(this));
    }
    
    TransformationMatrix mat = SVGStyledLocatableElement::getScreenCTM();
    mat.translate(rootLocation.x(), rootLocation.y());

    if (attributes()->getAttributeItem(SVGNames::viewBoxAttr)) {
        TransformationMatrix viewBox = viewBoxToViewTransform(width().value(this), height().value(this));
        mat = viewBox * mat;
    }

    return mat;
}
Esempio n. 4
0
FloatRect SVGSVGElement::viewport() const
{
    FloatRect viewRectangle;
    if (!isOutermostSVG())
        viewRectangle.setLocation(FloatPoint(x().value(this), y().value(this)));

    viewRectangle.setSize(FloatSize(width().value(this), height().value(this)));    
    return viewBoxToViewTransform(viewRectangle.width(), viewRectangle.height()).mapRect(viewRectangle);
}
Esempio n. 5
0
FloatRect SVGSVGElement::viewport() const
{
    // FIXME: This method doesn't follow the spec and is basically untested. Parent documents are not considered here.
    SVGLengthContext lengthContext(this);
    FloatRect viewRectangle;
    if (!isOutermostSVG())
        viewRectangle.setLocation(FloatPoint(x().value(lengthContext), y().value(lengthContext)));

    viewRectangle.setSize(FloatSize(width().value(lengthContext), height().value(lengthContext)));    
    return viewBoxToViewTransform(viewRectangle.width(), viewRectangle.height()).mapRect(viewRectangle);
}
Esempio n. 6
0
TransformationMatrix SVGSVGElement::getCTM() const
{
    TransformationMatrix mat;
    if (!isOutermostSVG())
        mat.translate(x().value(this), y().value(this));

    if (attributes()->getAttributeItem(SVGNames::viewBoxAttr)) {
        TransformationMatrix viewBox = viewBoxToViewTransform(width().value(this), height().value(this));
        mat = viewBox * mat;
    }

    return mat;
}
FloatRect SVGSVGElement::viewport() const
{
    double _x = 0.0;
    double _y = 0.0;
    if (!isOutermostSVG()) {
        _x = x().value(this);
        _y = y().value(this);
    }
    float w = width().value(this);
    float h = height().value(this);
    AffineTransform viewBox = viewBoxToViewTransform(w, h);
    double wDouble = w;
    double hDouble = h;
    viewBox.map(_x, _y, _x, _y);
    viewBox.map(w, h, wDouble, hDouble);
    return FloatRect::narrowPrecision(_x, _y, wDouble, hDouble);
}
Esempio n. 8
0
float SVGSVGElement::currentScale() const
{
    if (!inDocument() || !isOutermostSVG())
        return 1;

    Frame* frame = document()->frame();
    if (!frame)
        return 1;

    FrameTree* frameTree = frame->tree();
    ASSERT(frameTree);

    // The behaviour of currentScale() is undefined, when we're dealing with non-standalone SVG documents.
    // If the svg is embedded, the scaling is handled by the host renderer, so when asking from inside
    // the SVG document, a scale value of 1 seems reasonable, as it doesn't know anything about the parent scale.
    return frameTree->parent() ? 1 : frame->pageZoomFactor();
}
Esempio n. 9
0
void SVGSVGElement::setCurrentScale(float scale)
{
    if (!inDocument() || !isOutermostSVG())
        return;

    Frame* frame = document()->frame();
    if (!frame)
        return;

    FrameTree* frameTree = frame->tree();
    ASSERT(frameTree);

    // The behaviour of setCurrentScale() is undefined, when we're dealing with non-standalone SVG documents.
    // We choose the ignore this call, it's pretty useless to support calling setCurrentScale() from within
    // an embedded SVG document, for the same reasons as in currentScale() - needs resolution by SVG WG.
    if (frameTree->parent())
        return;

    frame->setPageZoomFactor(scale);
}