Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Unified Diff: Source/core/svg/SVGSVGElement.cpp

Issue 26390004: Rework SVG sizing (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix mishap during rebase in svg.css Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698