예제 #1
0
void SVGSVGElement::collectStyleForPresentationAttribute(
    const QualifiedName& name,
    const AtomicString& value,
    MutableStylePropertySet* style) {
  SVGAnimatedPropertyBase* property = propertyFromAttribute(name);
  if (property == m_x) {
    addPropertyToPresentationAttributeStyle(style, CSSPropertyX,
                                            m_x->cssValue());
  } else if (property == m_y) {
    addPropertyToPresentationAttributeStyle(style, CSSPropertyY,
                                            m_y->cssValue());
  } else if (isOutermostSVGSVGElement() &&
             (property == m_width || property == m_height)) {
    if (property == m_width) {
      addPropertyToPresentationAttributeStyle(style, CSSPropertyWidth,
                                              m_width->cssValue());
    } else if (property == m_height) {
      addPropertyToPresentationAttributeStyle(style, CSSPropertyHeight,
                                              m_height->cssValue());
    }
  } else {
    SVGGraphicsElement::collectStyleForPresentationAttribute(name, value,
                                                             style);
  }
}
예제 #2
0
RenderObject* SVGSVGElement::createRenderer(RenderArena* arena, RenderStyle*)
{
    if (isOutermostSVGSVGElement())
        return new (arena) RenderSVGRoot(this);

    return new (arena) RenderSVGViewportContainer(this);
}
예제 #3
0
RenderPtr<RenderElement> SVGSVGElement::createElementRenderer(PassRef<RenderStyle> style)
{
    if (isOutermostSVGSVGElement())
        return createRenderer<RenderSVGRoot>(*this, std::move(style));

    return createRenderer<RenderSVGViewportContainer>(*this, std::move(style));
}
예제 #4
0
LayoutObject* SVGSVGElement::createLayoutObject(const ComputedStyle&)
{
    if (isOutermostSVGSVGElement())
        return new LayoutSVGRoot(this);

    return new LayoutSVGViewportContainer(this);
}
예제 #5
0
String SVGElement::title() const
{
    // According to spec, we should not return titles when hovering over root <svg> elements (those
    // <title> elements are the title of the document, not a tooltip) so we instantly return.
    if (isOutermostSVGSVGElement())
        return String();

    // Walk up the tree, to find out whether we're inside a <use> shadow tree, to find the right title.
    if (isInShadowTree()) {
        Element* shadowHostElement = toShadowRoot(treeScope().rootNode()).host();
        // At this time, SVG nodes are not allowed in non-<use> shadow trees, so any shadow root we do
        // have should be a use. The assert and following test is here to catch future shadow DOM changes
        // that do enable SVG in a shadow tree.
        ASSERT(!shadowHostElement || isSVGUseElement(*shadowHostElement));
        if (isSVGUseElement(shadowHostElement)) {
            SVGUseElement& useElement = toSVGUseElement(*shadowHostElement);

            // If the <use> title is not empty we found the title to use.
            String useTitle(useElement.title());
            if (!useTitle.isEmpty())
                return useTitle;
        }
    }

    // If we aren't an instance in a <use> or the <use> title was not found, then find the first
    // <title> child of this element.
    // If a title child was found, return the text contents.
    if (Element* titleElement = Traversal<SVGTitleElement>::firstChild(*this))
        return titleElement->innerText();

    // Otherwise return a null/empty string.
    return String();
}
예제 #6
0
Frame* SVGSVGElement::frameForCurrentScale() const
{
    // The behavior of currentScale() is undefined when we're dealing with non-standalone SVG documents.
    // If the document is embedded, the scaling is handled by the host renderer.
    if (!inDocument() || !isOutermostSVGSVGElement())
        return nullptr;
    Frame* frame = document().frame();
    return frame && frame->isMainFrame() ? frame : nullptr;
}
예제 #7
0
bool SVGSVGElement::isPresentationAttribute(const QualifiedName& name) const
{
    if (isOutermostSVGSVGElement() && (name == SVGNames::widthAttr || name == SVGNames::heightAttr))
        return true;
    else if (name == SVGNames::xAttr || name == SVGNames::yAttr)
        return true;

    return SVGGraphicsElement::isPresentationAttribute(name);
}
예제 #8
0
void SVGSVGElement::finishParsingChildren()
{
    SVGGraphicsElement::finishParsingChildren();

    // The outermost SVGSVGElement SVGLoad event is fired through Document::dispatchWindowLoadEvent.
    if (isOutermostSVGSVGElement())
        return;

    // finishParsingChildren() is called when the close tag is reached for an element (e.g. </svg>)
    // we send SVGLoad events here if we can, otherwise they'll be sent when any required loads finish
    sendSVGLoadEventIfPossible();
}
예제 #9
0
AffineTransform SVGSVGElement::localCoordinateSpaceTransform(
    SVGElement::CTMScope mode) const {
  AffineTransform viewBoxTransform;
  if (!hasEmptyViewBox()) {
    FloatSize size = currentViewportSize();
    viewBoxTransform = viewBoxToViewTransform(size.width(), size.height());
  }

  AffineTransform transform;
  if (!isOutermostSVGSVGElement()) {
    SVGLengthContext lengthContext(this);
    transform.translate(m_x->currentValue()->value(lengthContext),
                        m_y->currentValue()->value(lengthContext));
  } else if (mode == SVGElement::ScreenScope) {
    if (LayoutObject* layoutObject = this->layoutObject()) {
      FloatPoint location;
      float zoomFactor = 1;

      // At the SVG/HTML boundary (aka LayoutSVGRoot), we apply the
      // localToBorderBoxTransform to map an element from SVG viewport
      // coordinates to CSS box coordinates.  LayoutSVGRoot's localToAbsolute
      // method expects CSS box coordinates.  We also need to adjust for the
      // zoom level factored into CSS coordinates (bug #96361).
      if (layoutObject->isSVGRoot()) {
        location = toLayoutSVGRoot(layoutObject)
                       ->localToBorderBoxTransform()
                       .mapPoint(location);
        zoomFactor = 1 / layoutObject->style()->effectiveZoom();
      }

      // Translate in our CSS parent coordinate space
      // FIXME: This doesn't work correctly with CSS transforms.
      location = layoutObject->localToAbsolute(location, UseTransforms);
      location.scale(zoomFactor, zoomFactor);

      // Be careful here! localToBorderBoxTransform() included the x/y offset
      // coming from the viewBoxToViewTransform(), 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()) {
        LayoutSize scrollOffset(view->getScrollOffset());
        scrollOffset.scale(zoomFactor);
        transform.translate(-scrollOffset.width(), -scrollOffset.height());
      }
    }
  }

  return transform.multiply(viewBoxTransform);
}
예제 #10
0
float SVGSVGElement::currentScale() const
{
    if (!inDocument() || !isOutermostSVGSVGElement())
        return 1;

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

    // 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 frame->tree().parent() ? 1 : frame->pageZoomFactor();
}
예제 #11
0
void SVGSVGElement::setCurrentScale(float scale)
{
    if (!inDocument() || !isOutermostSVGSVGElement())
        return;

    Frame* frame = document().frame();
    if (!frame)
        return;

    // 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 (frame->tree().parent())
        return;

    frame->setPageZoomFactor(scale);
}
예제 #12
0
AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const
{
    AffineTransform viewBoxTransform;
    if (!hasEmptyViewBox()) {
        FloatSize size = currentViewportSize();
        viewBoxTransform = viewBoxToViewTransform(size.width(), size.height());
    }

    AffineTransform transform;
    if (!isOutermostSVGSVGElement()) {
        SVGLengthContext lengthContext(this);
        transform.translate(x().value(lengthContext), y().value(lengthContext));
    } else if (mode == SVGLocatable::ScreenScope) {
        if (auto* renderer = this->renderer()) {
            FloatPoint location;
            float zoomFactor = 1;

            // At the SVG/HTML boundary (aka RenderSVGRoot), we apply the localToBorderBoxTransform 
            // to map an element from SVG viewport coordinates to CSS box coordinates.
            // RenderSVGRoot's localToAbsolute method expects CSS box coordinates.
            // We also need to adjust for the zoom level factored into CSS coordinates (bug #96361).
            if (is<RenderSVGRoot>(*renderer)) {
                location = downcast<RenderSVGRoot>(*renderer).localToBorderBoxTransform().mapPoint(location);
                zoomFactor = 1 / renderer->style().effectiveZoom();
            }

            // Translate in our CSS parent coordinate space
            // FIXME: This doesn't work correctly with CSS transforms.
            location = renderer->localToAbsolute(location, UseTransforms);
            location.scale(zoomFactor);

            // Be careful here! localToBorderBoxTransform() included the x/y offset coming from the viewBoxToViewTransform(),
            // 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()) {
                LayoutPoint scrollPosition = view->scrollPosition();
                scrollPosition.scale(zoomFactor);
                transform.translate(-scrollPosition.x(), -scrollPosition.y());
            }
        }
    }

    return transform.multiply(viewBoxTransform);
}
예제 #13
0
AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const
{
    AffineTransform viewBoxTransform;
    if (hasAttribute(SVGNames::viewBoxAttr)) {
        FloatSize size = currentViewportSize();
        viewBoxTransform = viewBoxToViewTransform(size.width(), size.height());
    }

    AffineTransform transform;
    if (!isOutermostSVGSVGElement()) {
        SVGLengthContext lengthContext(this);
        transform.translate(x().value(lengthContext), y().value(lengthContext));
    } else if (mode == SVGLocatable::ScreenScope) {
        if (RenderObject* renderer = this->renderer()) {
            FloatPoint location;
            
            // At the SVG/HTML boundary (aka RenderSVGRoot), we apply the localToBorderBoxTransform 
            // to map an element from SVG viewport coordinates to CSS box coordinates.
            // RenderSVGRoot's localToAbsolute method expects CSS box coordinates.
            if (renderer->isSVGRoot())
                location = toRenderSVGRoot(renderer)->localToBorderBoxTransform().mapPoint(location);
            
            // Translate in our CSS parent coordinate space
            // FIXME: This doesn't work correctly with CSS transforms.
            location = renderer->localToAbsolute(location, false, true);

            // Be careful here! localToBorderBoxTransform() included the x/y offset coming from the viewBoxToViewTransform(),
            // 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()) {
                LayoutSize scrollOffset = view->scrollOffset();
                transform.translate(-scrollOffset.width(), -scrollOffset.height());
            }
        }
    }

    return transform.multiply(viewBoxTransform);
}
예제 #14
0
String SVGElement::title() const
{
    // According to spec, we should not return titles when hovering over root <svg> elements (those
    // <title> elements are the title of the document, not a tooltip) so we instantly return.
    if (isOutermostSVGSVGElement())
        return String();

    if (inUseShadowTree()) {
        String useTitle(shadowHost()->title());
        if (!useTitle.isEmpty())
            return useTitle;
    }

    // If we aren't an instance in a <use> or the <use> title was not found, then find the first
    // <title> child of this element.
    // If a title child was found, return the text contents.
    if (Element* titleElement = Traversal<SVGTitleElement>::firstChild(*this))
        return titleElement->innerText();

    // Otherwise return a null/empty string.
    return String();
}
예제 #15
0
bool SVGSVGElement::isPresentationAttribute(const QualifiedName& name) const {
  if ((name == SVGNames::widthAttr || name == SVGNames::heightAttr) &&
      !isOutermostSVGSVGElement())
    return false;
  return SVGGraphicsElement::isPresentationAttribute(name);
}
예제 #16
0
RenderPtr<RenderElement> SVGSVGElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
{
    if (isOutermostSVGSVGElement())
        return createRenderer<RenderSVGRoot>(*this, WTFMove(style));
    return createRenderer<RenderSVGViewportContainer>(*this, WTFMove(style));
}