| Index: Source/core/svg/SVGSVGElement.cpp
|
| diff --git a/Source/core/svg/SVGSVGElement.cpp b/Source/core/svg/SVGSVGElement.cpp
|
| index 6e407203f3d155a745ad9100436d685a0f559cd0..0de4dbd7f4c1f51af322eeb568ff88b43cefb261 100644
|
| --- a/Source/core/svg/SVGSVGElement.cpp
|
| +++ b/Source/core/svg/SVGSVGElement.cpp
|
| @@ -258,24 +258,54 @@ void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString
|
| reportAttributeParsingError(parseError, name, value);
|
| }
|
|
|
| +bool SVGSVGElement::isPresentationAttribute(const QualifiedName& name) const
|
| +{
|
| + if (isOutermostSVGSVGElement() && (name == SVGNames::widthAttr || name == SVGNames::heightAttr))
|
| + return true;
|
| + return SVGGraphicsElement::isPresentationAttribute(name);
|
| +}
|
| +
|
| +void SVGSVGElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
|
| +{
|
| + if (isOutermostSVGSVGElement() && (name == SVGNames::widthAttr || name == SVGNames::heightAttr)) {
|
| + RefPtr<SVGLength> length = SVGLength::create(LengthModeOther);
|
| + length->setValueAsString(value, IGNORE_EXCEPTION);
|
| + if (length->unitType() != LengthTypeUnknown) {
|
| + if (name == SVGNames::widthAttr)
|
| + addPropertyToPresentationAttributeStyle(style, CSSPropertyWidth, value);
|
| + else if (name == SVGNames::heightAttr)
|
| + addPropertyToPresentationAttributeStyle(style, CSSPropertyHeight, value);
|
| + }
|
| + } else {
|
| + SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style);
|
| + }
|
| +}
|
| +
|
| void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
|
| {
|
| bool updateRelativeLengthsOrViewBox = false;
|
| bool widthChanged = attrName == SVGNames::widthAttr;
|
| - if (widthChanged
|
| - || attrName == SVGNames::heightAttr
|
| + bool heightChanged = attrName == SVGNames::heightAttr;
|
| + if (widthChanged || heightChanged
|
| || attrName == SVGNames::xAttr
|
| || attrName == SVGNames::yAttr) {
|
| updateRelativeLengthsOrViewBox = true;
|
| updateRelativeLengthsInformation();
|
| invalidateRelativeLengthClients();
|
|
|
| - // At the SVG/HTML boundary (aka RenderSVGRoot), the width attribute can
|
| - // affect the replaced size so we need to mark it for updating.
|
| - if (widthChanged) {
|
| + // At the SVG/HTML boundary (aka RenderSVGRoot), the width and
|
| + // height attributes can affect the replaced size so we need
|
| + // to mark it for updating.
|
| + //
|
| + // FIXME: For width/height animated as XML attributes on SVG
|
| + // roots, there is an attribute synchronization missing. See
|
| + // http://crbug.com/364807
|
| + if (widthChanged || heightChanged) {
|
| RenderObject* renderObject = renderer();
|
| - if (renderObject && renderObject->isSVGRoot())
|
| - toRenderSVGRoot(renderObject)->setNeedsLayoutAndPrefWidthsRecalc();
|
| + if (renderObject && renderObject->isSVGRoot()) {
|
| + invalidateSVGPresentationAttributeStyle();
|
| + setNeedsStyleRecalc(LocalStyleChange);
|
| + }
|
| }
|
| }
|
|
|
| @@ -595,22 +625,18 @@ FloatRect SVGSVGElement::currentViewBoxRect() const
|
| if (!toRenderSVGRoot(renderer())->isEmbeddedThroughSVGImage())
|
| return FloatRect();
|
|
|
| - Length intrinsicWidth = this->intrinsicWidth();
|
| - Length intrinsicHeight = this->intrinsicHeight();
|
| - if (!intrinsicWidth.isFixed() || !intrinsicHeight.isFixed())
|
| - return FloatRect();
|
| -
|
| // If no viewBox is specified but non-relative width/height values, then we
|
| // should always synthesize a viewBox if we're embedded through a SVGImage.
|
| - return FloatRect(FloatPoint(), FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0)));
|
| + return FloatRect(FloatPoint(), FloatSize(floatValueForLength(intrinsicWidth(), 0), floatValueForLength(intrinsicHeight(), 0)));
|
| }
|
|
|
| FloatSize SVGSVGElement::currentViewportSize() const
|
| {
|
| - Length intrinsicWidth = this->intrinsicWidth();
|
| - Length intrinsicHeight = this->intrinsicHeight();
|
| - if (intrinsicWidth.isFixed() && intrinsicHeight.isFixed())
|
| + if (hasIntrinsicWidth() && hasIntrinsicHeight()) {
|
| + Length intrinsicWidth = this->intrinsicWidth();
|
| + Length intrinsicHeight = this->intrinsicHeight();
|
| return FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0));
|
| + }
|
|
|
| if (!renderer())
|
| return FloatSize();
|
| @@ -624,80 +650,32 @@ FloatSize SVGSVGElement::currentViewportSize() const
|
| return FloatSize(viewportRect.width(), viewportRect.height());
|
| }
|
|
|
| -bool SVGSVGElement::widthAttributeEstablishesViewport() const
|
| +bool SVGSVGElement::hasIntrinsicWidth() 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;
|
| + return width()->currentValue()->unitType() != LengthTypePercentage;
|
| }
|
|
|
| -bool SVGSVGElement::heightAttributeEstablishesViewport() const
|
| +bool SVGSVGElement::hasIntrinsicHeight() 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;
|
| + return height()->currentValue()->unitType() != LengthTypePercentage;
|
| }
|
|
|
| -Length SVGSVGElement::intrinsicWidth(ConsiderCSSMode mode) const
|
| +Length SVGSVGElement::intrinsicWidth() const
|
| {
|
| - if (widthAttributeEstablishesViewport() || mode == IgnoreCSSProperties) {
|
| - if (m_width->currentValue()->unitType() == LengthTypePercentage)
|
| - return Length(m_width->currentValue()->valueAsPercentage() * 100, Percent);
|
| -
|
| - SVGLengthContext lengthContext(this);
|
| - return Length(m_width->currentValue()->value(lengthContext), Fixed);
|
| - }
|
| + if (width()->currentValue()->unitType() == LengthTypePercentage)
|
| + return Length(0, Fixed);
|
|
|
| - ASSERT(renderer());
|
| - return renderer()->style()->width();
|
| + SVGLengthContext lengthContext(this);
|
| + return Length(width()->currentValue()->value(lengthContext), Fixed);
|
| }
|
|
|
| -Length SVGSVGElement::intrinsicHeight(ConsiderCSSMode mode) const
|
| +Length SVGSVGElement::intrinsicHeight() const
|
| {
|
| - if (heightAttributeEstablishesViewport() || mode == IgnoreCSSProperties) {
|
| - if (m_height->currentValue()->unitType() == LengthTypePercentage)
|
| - return Length(m_height->currentValue()->valueAsPercentage() * 100, Percent);
|
| -
|
| - SVGLengthContext lengthContext(this);
|
| - return Length(m_height->currentValue()->value(lengthContext), Fixed);
|
| - }
|
| + if (height()->currentValue()->unitType() == LengthTypePercentage)
|
| + return Length(0, Fixed);
|
|
|
| - ASSERT(renderer());
|
| - return renderer()->style()->height();
|
| + SVGLengthContext lengthContext(this);
|
| + return Length(height()->currentValue()->value(lengthContext), Fixed);
|
| }
|
|
|
| AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const
|
|
|