diff --git a/dom/svg/SVGSVGElement.cpp b/dom/svg/SVGSVGElement.cpp index 61b09878f5ce..6fe293300858 100644 --- a/dom/svg/SVGSVGElement.cpp +++ b/dom/svg/SVGSVGElement.cpp @@ -7,6 +7,7 @@ #include "mozilla/ArrayUtils.h" #include "mozilla/ContentEvents.h" #include "mozilla/EventDispatcher.h" +#include "mozilla/FloatingPoint.h" #include "mozilla/Likely.h" #include "nsGkAtoms.h" @@ -1247,5 +1248,31 @@ SVGSVGElement::ClearTransformProperty() return UnsetProperty(nsGkAtoms::transform); } +float +SVGSVGElement::GetIntrinsicWidth() +{ + if (mLengthAttributes[ATTR_WIDTH].IsPercentage()) { + return UnspecifiedNaN(); + } + // Passing |this| as a SVGSVGElement* invokes the variant of GetAnimValue + // that uses the passed argument as the context, but that's fine since we + // know the length isn't a percentage so the context won't be used (and we + // need to pass the element to be able to resolve em/ex units). + return std::max(mLengthAttributes[ATTR_WIDTH].GetAnimValue(this), 0.f); +} + +float +SVGSVGElement::GetIntrinsicHeight() +{ + if (mLengthAttributes[ATTR_HEIGHT].IsPercentage()) { + return UnspecifiedNaN(); + } + // Passing |this| as a SVGSVGElement* invokes the variant of GetAnimValue + // that uses the passed argument as the context, but that's fine since we + // know the length isn't a percentage so the context won't be used (and we + // need to pass the element to be able to resolve em/ex units). + return std::max(mLengthAttributes[ATTR_HEIGHT].GetAnimValue(this), 0.f); +} + } // namespace dom } // namespace mozilla diff --git a/dom/svg/SVGSVGElement.h b/dom/svg/SVGSVGElement.h index 30591581218d..0962d326c72b 100644 --- a/dom/svg/SVGSVGElement.h +++ b/dom/svg/SVGSVGElement.h @@ -147,6 +147,14 @@ public: // public helpers: + /** + * Returns the user-unit width/height if those dimensions are not specified + * as percentage values. If they are specified as percentage values then this + * element does not have intrinsic width/height and these methods return NaN. + */ + float GetIntrinsicWidth(); + float GetIntrinsicHeight(); + /** * Returns true if this element has a base/anim value for its "viewBox" * attribute that defines a viewBox rectangle with finite values, or diff --git a/image/src/SVGDocumentWrapper.cpp b/image/src/SVGDocumentWrapper.cpp index b7d086b243a8..c0a53f3b293c 100644 --- a/image/src/SVGDocumentWrapper.cpp +++ b/image/src/SVGDocumentWrapper.cpp @@ -6,6 +6,7 @@ #include "SVGDocumentWrapper.h" #include "mozilla/dom/Element.h" +#include "mozilla/FloatingPoint.h" #include "nsICategoryManager.h" #include "nsIChannel.h" #include "nsIContentViewer.h" @@ -76,34 +77,14 @@ SVGDocumentWrapper::GetWidthOrHeight(Dimension aDimension, NS_ABORT_IF_FALSE(rootElem, "root elem missing or of wrong type"); // Get the width or height SVG object - nsRefPtr domAnimLength; - if (aDimension == eWidth) { - domAnimLength = rootElem->Width(); - } else { - NS_ABORT_IF_FALSE(aDimension == eHeight, "invalid dimension"); - domAnimLength = rootElem->Height(); - } - NS_ENSURE_TRUE(domAnimLength, false); + float length = (aDimension == eWidth) ? rootElem->GetIntrinsicWidth() + : rootElem->GetIntrinsicHeight(); - // Get the animated value from the object - nsRefPtr domLength = domAnimLength->AnimVal(); - NS_ENSURE_TRUE(domLength, false); - - // Check if it's a percent value (and fail if so) - uint16_t unitType; - nsresult rv = domLength->GetUnitType(&unitType); - NS_ENSURE_SUCCESS(rv, false); - if (unitType == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE) { - return false; + if (!IsFinite(length)) { + return false; // Percentage size } - // Non-percent value - woot! Grab it & return it. - float floatLength; - rv = domLength->GetValue(&floatLength); - NS_ENSURE_SUCCESS(rv, false); - - aResult = nsSVGUtils::ClampToInt(floatLength); - + aResult = nsSVGUtils::ClampToInt(length); return true; }