--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -1,85 +1,70 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include <stdint.h>
-#include "mozilla/ArrayUtils.h"
#include "mozilla/ContentEvents.h"
-#include "mozilla/EventDispatcher.h"
-#include "mozilla/Likely.h"
-
-#include "nsGkAtoms.h"
-#include "nsLayoutUtils.h"
-#include "nsLayoutStylesheetCache.h"
-#include "DOMSVGNumber.h"
-#include "DOMSVGLength.h"
-#include "nsSVGAngle.h"
-#include "nsCOMPtr.h"
-#include "nsIPresShell.h"
-#include "nsContentUtils.h"
-#include "nsIDocument.h"
-#include "mozilla/dom/SVGMatrix.h"
-#include "DOMSVGPoint.h"
-#include "nsIFrame.h"
-#include "nsFrameSelection.h"
-#include "nsISVGSVGFrame.h" //XXX
-#include "mozilla/dom/SVGRect.h"
-#include "nsError.h"
-#include "nsSVGDisplayableFrame.h"
#include "mozilla/dom/SVGSVGElement.h"
#include "mozilla/dom/SVGSVGElementBinding.h"
-#include "nsSVGUtils.h"
+#include "mozilla/dom/SVGMatrix.h"
#include "mozilla/dom/SVGViewElement.h"
-#include "nsStyleUtil.h"
-#include "SVGContentUtils.h"
+#include "mozilla/EventDispatcher.h"
+#include "DOMSVGLength.h"
+#include "DOMSVGNumber.h"
+#include "DOMSVGPoint.h"
+#include "nsLayoutStylesheetCache.h"
+#include "nsSVGAngle.h"
+#include "nsFrameSelection.h"
+#include "nsIFrame.h"
+#include "nsISVGSVGFrame.h"
+#include "nsSMILAnimationController.h"
#include "nsSMILTimeContainer.h"
-#include "nsSMILAnimationController.h"
-#include "nsSMILTypes.h"
+#include "nsSVGDisplayableFrame.h"
+#include "nsSVGUtils.h"
#include "SVGAngle.h"
-#include <algorithm>
-#include "prtime.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT_CHECK_PARSER(SVG)
using namespace mozilla::gfx;
namespace mozilla {
namespace dom {
-class SVGAnimatedLength;
+nsSVGEnumMapping SVGSVGElement::sZoomAndPanMap[] = {
+ {&nsGkAtoms::disable, SVG_ZOOMANDPAN_DISABLE},
+ {&nsGkAtoms::magnify, SVG_ZOOMANDPAN_MAGNIFY},
+ {nullptr, 0}
+};
-JSObject*
-SVGSVGElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
+nsSVGElement::EnumInfo SVGSVGElement::sEnumInfo[1] =
{
- return SVGSVGElementBinding::Wrap(aCx, this, aGivenProto);
-}
+ { &nsGkAtoms::zoomAndPan,
+ sZoomAndPanMap,
+ SVG_ZOOMANDPAN_MAGNIFY
+ }
+};
NS_IMPL_CYCLE_COLLECTION_INHERITED(DOMSVGTranslatePoint, nsISVGPoint,
mElement)
NS_IMPL_ADDREF_INHERITED(DOMSVGTranslatePoint, nsISVGPoint)
NS_IMPL_RELEASE_INHERITED(DOMSVGTranslatePoint, nsISVGPoint)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGTranslatePoint)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
// We have to qualify nsISVGPoint because NS_GET_IID looks for a class in the
// global namespace
NS_INTERFACE_MAP_ENTRY(mozilla::nsISVGPoint)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
-SVGSVGElement::~SVGSVGElement()
-{
-}
-
DOMSVGPoint*
DOMSVGTranslatePoint::Copy()
{
return new DOMSVGPoint(mPt.GetX(), mPt.GetY());
}
nsISupports*
DOMSVGTranslatePoint::GetParentObject()
@@ -106,45 +91,21 @@ DOMSVGTranslatePoint::MatrixTransform(SV
float d = matrix.D(), e = matrix.E(), f = matrix.F();
float x = mPt.GetX();
float y = mPt.GetY();
nsCOMPtr<nsISVGPoint> point = new DOMSVGPoint(a*x + c*y + e, b*x + d*y + f);
return point.forget();
}
-SVGView::SVGView()
-{
- mZoomAndPan.Init(SVGSVGElement::ZOOMANDPAN,
- SVG_ZOOMANDPAN_MAGNIFY);
- mViewBox.Init();
- mPreserveAspectRatio.Init();
-}
-
-nsSVGElement::LengthInfo SVGSVGElement::sLengthInfo[4] =
+JSObject*
+SVGSVGElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
{
- { &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
- { &nsGkAtoms::y, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
- { &nsGkAtoms::width, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
- { &nsGkAtoms::height, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
-};
-
-nsSVGEnumMapping SVGSVGElement::sZoomAndPanMap[] = {
- {&nsGkAtoms::disable, SVG_ZOOMANDPAN_DISABLE},
- {&nsGkAtoms::magnify, SVG_ZOOMANDPAN_MAGNIFY},
- {nullptr, 0}
-};
-
-nsSVGElement::EnumInfo SVGSVGElement::sEnumInfo[1] =
-{
- { &nsGkAtoms::zoomAndPan,
- sZoomAndPanMap,
- SVG_ZOOMANDPAN_MAGNIFY
- }
-};
+ return SVGSVGElementBinding::Wrap(aCx, this, aGivenProto);
+}
//----------------------------------------------------------------------
// nsISupports methods
NS_IMPL_CYCLE_COLLECTION_CLASS(SVGSVGElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGSVGElement,
SVGSVGElementBase)
@@ -162,33 +123,42 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_ADDREF_INHERITED(SVGSVGElement,SVGSVGElementBase)
NS_IMPL_RELEASE_INHERITED(SVGSVGElement,SVGSVGElementBase)
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGSVGElement)
NS_INTERFACE_TABLE_INHERITED(SVGSVGElement, nsIDOMNode, nsIDOMElement,
nsIDOMSVGElement)
NS_INTERFACE_TABLE_TAIL_INHERITING(SVGSVGElementBase)
+SVGView::SVGView()
+{
+ mZoomAndPan.Init(SVGSVGElement::ZOOMANDPAN,
+ SVG_ZOOMANDPAN_MAGNIFY);
+ mViewBox.Init();
+ mPreserveAspectRatio.Init();
+}
+
//----------------------------------------------------------------------
// Implementation
SVGSVGElement::SVGSVGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
FromParser aFromParser)
: SVGSVGElementBase(aNodeInfo),
- mViewportWidth(0),
- mViewportHeight(0),
mCurrentTranslate(0.0f, 0.0f),
mCurrentScale(1.0f),
mPreviousTranslate(0.0f, 0.0f),
mPreviousScale(1.0f),
mStartAnimationOnBindToTree(aFromParser == NOT_FROM_PARSER ||
aFromParser == FROM_PARSER_FRAGMENT ||
aFromParser == FROM_PARSER_XSLT),
- mImageNeedsTransformInvalidation(false),
- mHasChildrenOnlyTransform(false)
+ mImageNeedsTransformInvalidation(false)
+{
+}
+
+SVGSVGElement::~SVGSVGElement()
{
}
//----------------------------------------------------------------------
// nsIDOMNode methods
NS_IMPL_ELEMENT_CLONE_WITH_INIT_AND_PARSER(SVGSVGElement)
@@ -213,17 +183,16 @@ SVGSVGElement::Width()
return mLengthAttributes[ATTR_WIDTH].ToDOMAnimatedLength(this);
}
already_AddRefed<SVGAnimatedLength>
SVGSVGElement::Height()
{
return mLengthAttributes[ATTR_HEIGHT].ToDOMAnimatedLength(this);
}
-
float
SVGSVGElement::PixelUnitToMillimeterX()
{
return MM_PER_INCH_FLOAT / 96;
}
float
SVGSVGElement::PixelUnitToMillimeterY()
@@ -237,17 +206,16 @@ SVGSVGElement::ScreenPixelToMillimeterX(
return MM_PER_INCH_FLOAT / 96;
}
float
SVGSVGElement::ScreenPixelToMillimeterY()
{
return ScreenPixelToMillimeterX();
}
-
bool
SVGSVGElement::UseCurrentView()
{
return mSVGView || mCurrentViewID;
}
float
SVGSVGElement::CurrentScale()
@@ -420,78 +388,46 @@ SVGSVGElement::CreateSVGTransform()
already_AddRefed<SVGTransform>
SVGSVGElement::CreateSVGTransformFromMatrix(SVGMatrix& matrix)
{
RefPtr<SVGTransform> transform = new SVGTransform(matrix.GetMatrix());
return transform.forget();
}
//----------------------------------------------------------------------
-
-already_AddRefed<SVGAnimatedRect>
-SVGSVGElement::ViewBox()
-{
- return mViewBox.ToSVGAnimatedRect(this);
-}
-
-already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
-SVGSVGElement::PreserveAspectRatio()
-{
- return mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(this);
-}
-
-uint16_t
-SVGSVGElement::ZoomAndPan()
-{
- return mEnumAttributes[ZOOMANDPAN].GetAnimValue();
-}
-
-void
-SVGSVGElement::SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv)
-{
- if (aZoomAndPan == SVG_ZOOMANDPAN_DISABLE ||
- aZoomAndPan == SVG_ZOOMANDPAN_MAGNIFY) {
- mEnumAttributes[ZOOMANDPAN].SetBaseValue(aZoomAndPan, this);
- return;
- }
-
- rv.ThrowRangeError<MSG_INVALID_ZOOMANDPAN_VALUE_ERROR>();
-}
-
-//----------------------------------------------------------------------
// helper method for implementing SetCurrentScale/Translate
void
SVGSVGElement::SetCurrentScaleTranslate(float s, float x, float y)
{
if (s == mCurrentScale &&
x == mCurrentTranslate.GetX() && y == mCurrentTranslate.GetY()) {
return;
}
// Prevent bizarre behaviour and maxing out of CPU and memory by clamping
if (s < CURRENT_SCALE_MIN)
s = CURRENT_SCALE_MIN;
else if (s > CURRENT_SCALE_MAX)
s = CURRENT_SCALE_MAX;
-
+
// IMPORTANT: If either mCurrentTranslate *or* mCurrentScale is changed then
// mPreviousTranslate_x, mPreviousTranslate_y *and* mPreviousScale must all
// be updated otherwise SVGZoomEvents will end up with invalid data. I.e. an
// SVGZoomEvent's properties previousScale and previousTranslate must contain
// the state of currentScale and currentTranslate immediately before the
// change that caused the event's dispatch, which is *not* necessarily the
// same thing as the values of currentScale and currentTranslate prior to
// their own last change.
//
// XXX This comment is out-of-date due to removal of SVGZoomEvent. Can we
// remove some of this code?
mPreviousScale = mCurrentScale;
mPreviousTranslate = mCurrentTranslate;
-
+
mCurrentScale = s;
mCurrentTranslate = SVGPoint(x, y);
// now dispatch the appropriate event if we are the root element
nsIDocument* doc = GetUncomposedDoc();
if (doc) {
nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
if (presShell && IsRoot()) {
@@ -506,16 +442,37 @@ SVGSVGElement::SetCurrentScaleTranslate(
}
void
SVGSVGElement::SetCurrentTranslate(float x, float y)
{
SetCurrentScaleTranslate(mCurrentScale, x, y);
}
+//----------------------------------------------------------------------
+// SVGZoomAndPanValues
+uint16_t
+SVGSVGElement::ZoomAndPan()
+{
+ return mEnumAttributes[ZOOMANDPAN].GetAnimValue();
+}
+
+void
+SVGSVGElement::SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv)
+{
+ if (aZoomAndPan == SVG_ZOOMANDPAN_DISABLE ||
+ aZoomAndPan == SVG_ZOOMANDPAN_MAGNIFY) {
+ mEnumAttributes[ZOOMANDPAN].SetBaseValue(aZoomAndPan, this);
+ return;
+ }
+
+ rv.ThrowRangeError<MSG_INVALID_ZOOMANDPAN_VALUE_ERROR>();
+}
+
+//----------------------------------------------------------------------
nsSMILTimeContainer*
SVGSVGElement::GetTimedDocumentRoot()
{
if (mTimedDocumentRoot) {
return mTimedDocumentRoot;
}
// We must not be the outermost <svg> element, try to find it
@@ -523,185 +480,18 @@ SVGSVGElement::GetTimedDocumentRoot()
SVGContentUtils::GetOuterSVGElement(this);
if (outerSVGElement) {
return outerSVGElement->GetTimedDocumentRoot();
}
// invalid structure
return nullptr;
}
-
//----------------------------------------------------------------------
-// nsIContent methods
-
-NS_IMETHODIMP_(bool)
-SVGSVGElement::IsAttributeMapped(const nsIAtom* name) const
-{
- // We want to map the 'width' and 'height' attributes into style for
- // outer-<svg>, except when the attributes aren't set (since their default
- // values of '100%' can cause unexpected and undesirable behaviour for SVG
- // inline in HTML). We rely on nsSVGElement::UpdateContentStyleRule() to
- // prevent mapping of the default values into style (it only maps attributes
- // that are set). We also rely on a check in nsSVGElement::
- // UpdateContentStyleRule() to prevent us mapping the attributes when they're
- // given a <length> value that is not currently recognized by the SVG
- // specification.
-
- if (!IsInner() && (name == nsGkAtoms::width || name == nsGkAtoms::height)) {
- return true;
- }
-
- static const MappedAttributeEntry* const map[] = {
- sColorMap,
- sFEFloodMap,
- sFillStrokeMap,
- sFiltersMap,
- sFontSpecificationMap,
- sGradientStopMap,
- sGraphicsMap,
- sLightingEffectsMap,
- sMarkersMap,
- sTextContentElementsMap,
- sViewportsMap
- };
-
- return FindAttributeDependence(name, map) ||
- SVGSVGElementBase::IsAttributeMapped(name);
-}
-
-//----------------------------------------------------------------------
-// nsIContent methods:
-
-nsresult
-SVGSVGElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
-{
- if (aVisitor.mEvent->mMessage == eSVGLoad) {
- if (mTimedDocumentRoot) {
- mTimedDocumentRoot->Begin();
- // Set 'resample needed' flag, so that if any script calls a DOM method
- // that requires up-to-date animations before our first sample callback,
- // we'll force a synchronous sample.
- AnimationNeedsResample();
- }
- }
- return SVGSVGElementBase::GetEventTargetParent(aVisitor);
-}
-
-bool
-SVGSVGElement::IsEventAttributeName(nsIAtom* aName)
-{
- /* The events in EventNameType_SVGSVG are for events that are only
- applicable to outermost 'svg' elements. We don't check if we're an outer
- 'svg' element in case we're not inserted into the document yet, but since
- the target of the events in question will always be the outermost 'svg'
- element, this shouldn't cause any real problems.
- */
- return nsContentUtils::IsEventAttributeName(aName,
- (EventNameType_SVGGraphic | EventNameType_SVGSVG));
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement overrides
-
-// Helper for GetViewBoxTransform on root <svg> node
-// * aLength: internal value for our <svg> width or height attribute.
-// * aViewportLength: length of the corresponding dimension of the viewport.
-// * aSelf: the outermost <svg> node itself.
-// NOTE: aSelf is not an ancestor viewport element, so it can't be used to
-// resolve percentage lengths. (It can only be used to resolve
-// 'em'/'ex'-valued units).
-inline float
-ComputeSynthesizedViewBoxDimension(const nsSVGLength2& aLength,
- float aViewportLength,
- const SVGSVGElement* aSelf)
-{
- if (aLength.IsPercentage()) {
- return aViewportLength * aLength.GetAnimValInSpecifiedUnits() / 100.0f;
- }
-
- return aLength.GetAnimValue(const_cast<SVGSVGElement*>(aSelf));
-}
-
-//----------------------------------------------------------------------
-// public helpers:
-
-gfx::Matrix
-SVGSVGElement::GetViewBoxTransform() const
-{
- float viewportWidth, viewportHeight;
- if (IsInner()) {
- SVGSVGElement *ctx = GetCtx();
- viewportWidth = mLengthAttributes[ATTR_WIDTH].GetAnimValue(ctx);
- viewportHeight = mLengthAttributes[ATTR_HEIGHT].GetAnimValue(ctx);
- } else {
- viewportWidth = mViewportWidth;
- viewportHeight = mViewportHeight;
- }
-
- if (viewportWidth <= 0.0f || viewportHeight <= 0.0f) {
- return gfx::Matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
- }
-
- nsSVGViewBoxRect viewBox =
- GetViewBoxWithSynthesis(viewportWidth, viewportHeight);
-
- if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
- return gfx::Matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
- }
-
- return SVGContentUtils::GetViewBoxTransform(viewportWidth, viewportHeight,
- viewBox.x, viewBox.y,
- viewBox.width, viewBox.height,
- GetPreserveAspectRatioWithOverride());
-}
-
-void
-SVGSVGElement::UpdateHasChildrenOnlyTransform()
-{
- bool hasChildrenOnlyTransform =
- HasViewBoxOrSyntheticViewBox() ||
- (IsRoot() && (mCurrentTranslate != SVGPoint(0.0f, 0.0f) ||
- mCurrentScale != 1.0f));
- mHasChildrenOnlyTransform = hasChildrenOnlyTransform;
-}
-
-void
-SVGSVGElement::ChildrenOnlyTransformChanged(uint32_t aFlags)
-{
- // Avoid wasteful calls:
- MOZ_ASSERT(!(GetPrimaryFrame()->GetStateBits() & NS_FRAME_IS_NONDISPLAY),
- "Non-display SVG frames don't maintain overflow rects");
-
- nsChangeHint changeHint;
-
- bool hadChildrenOnlyTransform = mHasChildrenOnlyTransform;
-
- UpdateHasChildrenOnlyTransform();
-
- if (hadChildrenOnlyTransform != mHasChildrenOnlyTransform) {
- // Reconstruct the frame tree to handle stacking context changes:
- // XXXjwatt don't do this for root-<svg> or even outer-<svg>?
- changeHint = nsChangeHint_ReconstructFrame;
- } else {
- // We just assume the old and new transforms are different.
- changeHint = nsChangeHint(nsChangeHint_UpdateOverflow |
- nsChangeHint_ChildrenOnlyTransform);
- }
-
- // If we're not reconstructing the frame tree, then we only call
- // PostRestyleEvent if we're not being called under reflow to avoid recursing
- // to death. See bug 767056 comments 10 and 12. Since our nsSVGOuterSVGFrame
- // is being reflowed we're going to invalidate and repaint its entire area
- // anyway (which will include our children).
- if ((changeHint & nsChangeHint_ReconstructFrame) ||
- !(aFlags & eDuringReflow)) {
- nsLayoutUtils::PostRestyleEvent(this, nsRestyleHint(0), changeHint);
- }
-}
-
+// nsSVGElement
nsresult
SVGSVGElement::BindToTree(nsIDocument* aDocument,
nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers)
{
nsSMILAnimationController* smilController = nullptr;
@@ -719,17 +509,17 @@ SVGSVGElement::BindToTree(nsIDocument* a
// time container. However, we need to make sure that we'll get a
// kick-start if we get promoted to be outermost later on.
mTimedDocumentRoot = nullptr;
mStartAnimationOnBindToTree = true;
}
}
}
- nsresult rv = SVGSVGElementBase::BindToTree(aDocument, aParent,
+ nsresult rv = SVGGraphicsElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv,rv);
nsIDocument* doc = GetComposedDoc();
if (doc) {
// Setup the style sheet during binding, not element construction,
// because we could move the root SVG element from the document
@@ -751,17 +541,98 @@ SVGSVGElement::BindToTree(nsIDocument* a
void
SVGSVGElement::UnbindFromTree(bool aDeep, bool aNullParent)
{
if (mTimedDocumentRoot) {
mTimedDocumentRoot->SetParent(nullptr);
}
- SVGSVGElementBase::UnbindFromTree(aDeep, aNullParent);
+ SVGGraphicsElement::UnbindFromTree(aDeep, aNullParent);
+}
+
+nsSVGAnimatedTransformList*
+SVGSVGElement::GetAnimatedTransformList(uint32_t aFlags)
+{
+ if (!(aFlags & DO_ALLOCATE) && mSVGView && mSVGView->mTransforms) {
+ return mSVGView->mTransforms;
+ }
+ return SVGGraphicsElement::GetAnimatedTransformList(aFlags);
+}
+
+nsresult
+SVGSVGElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
+{
+ if (aVisitor.mEvent->mMessage == eSVGLoad) {
+ if (mTimedDocumentRoot) {
+ mTimedDocumentRoot->Begin();
+ // Set 'resample needed' flag, so that if any script calls a DOM method
+ // that requires up-to-date animations before our first sample callback,
+ // we'll force a synchronous sample.
+ AnimationNeedsResample();
+ }
+ }
+ return SVGSVGElementBase::GetEventTargetParent(aVisitor);
+}
+
+bool
+SVGSVGElement::IsEventAttributeName(nsIAtom* aName)
+{
+ /* The events in EventNameType_SVGSVG are for events that are only
+ applicable to outermost 'svg' elements. We don't check if we're an outer
+ 'svg' element in case we're not inserted into the document yet, but since
+ the target of the events in question will always be the outermost 'svg'
+ element, this shouldn't cause any real problems.
+ */
+ return nsContentUtils::IsEventAttributeName(aName,
+ (EventNameType_SVGGraphic | EventNameType_SVGSVG));
+}
+
+//----------------------------------------------------------------------
+// public helpers:
+
+int32_t
+SVGSVGElement::GetIntrinsicWidth()
+{
+ if (mLengthAttributes[ATTR_WIDTH].IsPercentage()) {
+ return -1;
+ }
+ // Passing |this| as a SVGViewportElement* 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).
+ float width = mLengthAttributes[ATTR_WIDTH].GetAnimValue(this);
+ return nsSVGUtils::ClampToInt(width);
+}
+
+int32_t
+SVGSVGElement::GetIntrinsicHeight()
+{
+ if (mLengthAttributes[ATTR_HEIGHT].IsPercentage()) {
+ return -1;
+ }
+ // Passing |this| as a SVGViewportElement* 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).
+ float height = mLengthAttributes[ATTR_HEIGHT].GetAnimValue(this);
+ return nsSVGUtils::ClampToInt(height);
+}
+
+void
+SVGSVGElement::FlushImageTransformInvalidation()
+{
+ MOZ_ASSERT(!GetParent(), "Should only be called on root node");
+ MOZ_ASSERT(OwnerDoc()->IsBeingUsedAsImage(),
+ "Should only be called on image documents");
+
+ if (mImageNeedsTransformInvalidation) {
+ InvalidateTransformNotifyFrame();
+ mImageNeedsTransformInvalidation = false;
+ }
}
//----------------------------------------------------------------------
// implementation helpers
bool
SVGSVGElement::WillBeOutermostSVG(nsIContent* aParent,
nsIContent* aBindingParent) const
@@ -795,301 +666,23 @@ SVGSVGElement::InvalidateTransformNotify
bool
SVGSVGElement::HasPreserveAspectRatio()
{
return HasAttr(kNameSpaceID_None, nsGkAtoms::preserveAspectRatio) ||
mPreserveAspectRatio.IsAnimated();
}
-SVGViewElement*
-SVGSVGElement::GetCurrentViewElement() const
-{
- if (mCurrentViewID) {
- //XXXsmaug It is unclear how this should work in case we're in Shadow DOM.
- nsIDocument* doc = GetUncomposedDoc();
- if (doc) {
- Element *element = doc->GetElementById(*mCurrentViewID);
- if (element && element->IsSVGElement(nsGkAtoms::view)) {
- return static_cast<SVGViewElement*>(element);
- }
- }
- }
- return nullptr;
-}
-
-nsSVGViewBoxRect
-SVGSVGElement::GetViewBoxWithSynthesis(
- float aViewportWidth, float aViewportHeight) const
-{
- // The logic here should match HasViewBoxRect().
- SVGViewElement* viewElement = GetCurrentViewElement();
- if (viewElement && viewElement->mViewBox.HasRect()) {
- return viewElement->mViewBox.GetAnimValue();
- }
- if (mSVGView && mSVGView->mViewBox.HasRect()) {
- return mSVGView->mViewBox.GetAnimValue();
- }
- if (mViewBox.HasRect()) {
- return mViewBox.GetAnimValue();
- }
-
- if (ShouldSynthesizeViewBox()) {
- // Special case -- fake a viewBox, using height & width attrs.
- // (Use |this| as context, since if we get here, we're outermost <svg>.)
- return nsSVGViewBoxRect(0, 0,
- ComputeSynthesizedViewBoxDimension(mLengthAttributes[ATTR_WIDTH],
- mViewportWidth, this),
- ComputeSynthesizedViewBoxDimension(mLengthAttributes[ATTR_HEIGHT],
- mViewportHeight, this));
-
- }
-
- // No viewBox attribute, so we shouldn't auto-scale. This is equivalent
- // to having a viewBox that exactly matches our viewport size.
- return nsSVGViewBoxRect(0, 0, aViewportWidth, aViewportHeight);
-}
-
-SVGPreserveAspectRatio
-SVGSVGElement::GetPreserveAspectRatioWithOverride() const
-{
- nsIDocument* doc = GetUncomposedDoc();
- if (doc && doc->IsBeingUsedAsImage()) {
- const SVGPreserveAspectRatio *pAROverridePtr = GetPreserveAspectRatioProperty();
- if (pAROverridePtr) {
- return *pAROverridePtr;
- }
- }
-
- SVGViewElement* viewElement = GetCurrentViewElement();
-
- // This check is equivalent to "!HasViewBoxRect() && ShouldSynthesizeViewBox()".
- // We're just holding onto the viewElement that HasViewBoxRect() would look up,
- // so that we don't have to look it up again later.
- if (!((viewElement && viewElement->mViewBox.HasRect()) ||
- (mSVGView && mSVGView->mViewBox.HasRect()) ||
- mViewBox.HasRect()) &&
- ShouldSynthesizeViewBox()) {
- // If we're synthesizing a viewBox, use preserveAspectRatio="none";
- return SVGPreserveAspectRatio(SVG_PRESERVEASPECTRATIO_NONE, SVG_MEETORSLICE_SLICE);
- }
-
- if (viewElement && viewElement->mPreserveAspectRatio.IsExplicitlySet()) {
- return viewElement->mPreserveAspectRatio.GetAnimValue();
- }
- if (mSVGView && mSVGView->mPreserveAspectRatio.IsExplicitlySet()) {
- return mSVGView->mPreserveAspectRatio.GetAnimValue();
- }
- return mPreserveAspectRatio.GetAnimValue();
-}
-
-//----------------------------------------------------------------------
-// SVGSVGElement
-
-float
-SVGSVGElement::GetLength(uint8_t aCtxType)
-{
- float h, w;
-
- SVGViewElement* viewElement = GetCurrentViewElement();
- const nsSVGViewBoxRect* viewbox = nullptr;
-
- // The logic here should match HasViewBoxRect().
- if (viewElement && viewElement->mViewBox.HasRect()) {
- viewbox = &viewElement->mViewBox.GetAnimValue();
- } else if (mSVGView && mSVGView->mViewBox.HasRect()) {
- viewbox = &mSVGView->mViewBox.GetAnimValue();
- } else if (mViewBox.HasRect()) {
- viewbox = &mViewBox.GetAnimValue();
- }
-
- if (viewbox) {
- w = viewbox->width;
- h = viewbox->height;
- } else if (IsInner()) {
- SVGSVGElement *ctx = GetCtx();
- w = mLengthAttributes[ATTR_WIDTH].GetAnimValue(ctx);
- h = mLengthAttributes[ATTR_HEIGHT].GetAnimValue(ctx);
- } else if (ShouldSynthesizeViewBox()) {
- w = ComputeSynthesizedViewBoxDimension(mLengthAttributes[ATTR_WIDTH],
- mViewportWidth, this);
- h = ComputeSynthesizedViewBoxDimension(mLengthAttributes[ATTR_HEIGHT],
- mViewportHeight, this);
- } else {
- w = mViewportWidth;
- h = mViewportHeight;
- }
-
- w = std::max(w, 0.0f);
- h = std::max(h, 0.0f);
-
- switch (aCtxType) {
- case SVGContentUtils::X:
- return w;
- case SVGContentUtils::Y:
- return h;
- case SVGContentUtils::XY:
- return float(SVGContentUtils::ComputeNormalizedHypotenuse(w, h));
- }
- return 0;
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-/* virtual */ gfxMatrix
-SVGSVGElement::PrependLocalTransformsTo(const gfxMatrix& aMatrix,
- SVGTransformTypes aWhich) const
-{
- // 'transform' attribute (or an override from a fragment identifier):
- gfxMatrix userToParent;
-
- if (aWhich == eUserSpaceToParent || aWhich == eAllTransforms) {
- userToParent = GetUserToParentTransform(mAnimateMotionTransform,
- mSVGView && mSVGView->mTransforms
- ? mSVGView->mTransforms
- : mTransforms);
- if (aWhich == eUserSpaceToParent) {
- return userToParent * aMatrix;
- }
- }
-
- gfxMatrix childToUser;
-
- if (IsInner()) {
- float x, y;
- const_cast<SVGSVGElement*>(this)->GetAnimatedLengthValues(&x, &y, nullptr);
- childToUser = ThebesMatrix(GetViewBoxTransform().PostTranslate(x, y));
- } else if (IsRoot()) {
- childToUser = ThebesMatrix(GetViewBoxTransform()
- .PostScale(mCurrentScale, mCurrentScale)
- .PostTranslate(mCurrentTranslate.GetX(),
- mCurrentTranslate.GetY()));
- } else {
- // outer-<svg>, but inline in some other content:
- childToUser = ThebesMatrix(GetViewBoxTransform());
- }
-
- if (aWhich == eAllTransforms) {
- return childToUser * userToParent * aMatrix;
- }
-
- MOZ_ASSERT(aWhich == eChildToUserSpace, "Unknown TransformTypes");
-
- // The following may look broken because pre-multiplying our eChildToUserSpace
- // transform with another matrix without including our eUserSpaceToParent
- // transform between the two wouldn't make sense. We don't expect that to
- // ever happen though. We get here either when the identity matrix has been
- // passed because our caller just wants our eChildToUserSpace transform, or
- // when our eUserSpaceToParent transform has already been multiplied into the
- // matrix that our caller passes (such as when we're called from PaintSVG).
- return childToUser * aMatrix;
-}
-
-nsSVGAnimatedTransformList*
-SVGSVGElement::GetAnimatedTransformList(uint32_t aFlags)
-{
- if (!(aFlags & DO_ALLOCATE) && mSVGView && mSVGView->mTransforms) {
- return mSVGView->mTransforms;
- }
- return SVGSVGElementBase::GetAnimatedTransformList(aFlags);
-}
-
-/* virtual */ bool
-SVGSVGElement::HasValidDimensions() const
-{
- return !IsInner() ||
- ((!mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() ||
- mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
- (!mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() ||
- mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0));
-}
-
-nsSVGElement::LengthAttributesInfo
-SVGSVGElement::GetLengthInfo()
-{
- return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
- ArrayLength(sLengthInfo));
-}
-
nsSVGElement::EnumAttributesInfo
SVGSVGElement::GetEnumInfo()
{
return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
ArrayLength(sEnumInfo));
}
-nsSVGViewBox*
-SVGSVGElement::GetViewBox()
-{
- return &mViewBox;
-}
-
-SVGAnimatedPreserveAspectRatio *
-SVGSVGElement::GetPreserveAspectRatio()
-{
- return &mPreserveAspectRatio;
-}
-
-bool
-SVGSVGElement::HasViewBoxRect() const
-{
- SVGViewElement* viewElement = GetCurrentViewElement();
- if ((viewElement && viewElement->mViewBox.HasRect()) ||
- (mSVGView && mSVGView->mViewBox.HasRect())) {
- return true;
- }
- return mViewBox.HasRect();
-}
-
-bool
-SVGSVGElement::ShouldSynthesizeViewBox() const
-{
- MOZ_ASSERT(!HasViewBoxRect(), "Should only be called if we lack a viewBox");
-
- return IsRoot() && OwnerDoc()->IsBeingUsedAsImage();
-}
-
-bool
-SVGSVGElement::SetPreserveAspectRatioProperty(const SVGPreserveAspectRatio& aPAR)
-{
- SVGPreserveAspectRatio* pAROverridePtr = new SVGPreserveAspectRatio(aPAR);
- nsresult rv = SetProperty(nsGkAtoms::overridePreserveAspectRatio,
- pAROverridePtr,
- nsINode::DeleteProperty<SVGPreserveAspectRatio>,
- true);
- MOZ_ASSERT(rv != NS_PROPTABLE_PROP_OVERWRITTEN,
- "Setting override value when it's already set...?");
-
- if (MOZ_UNLIKELY(NS_FAILED(rv))) {
- // property-insertion failed (e.g. OOM in property-table code)
- delete pAROverridePtr;
- return false;
- }
- return true;
-}
-
-const SVGPreserveAspectRatio*
-SVGSVGElement::GetPreserveAspectRatioProperty() const
-{
- void* valPtr = GetProperty(nsGkAtoms::overridePreserveAspectRatio);
- if (valPtr) {
- return static_cast<SVGPreserveAspectRatio*>(valPtr);
- }
- return nullptr;
-}
-
-bool
-SVGSVGElement::ClearPreserveAspectRatioProperty()
-{
- void* valPtr = UnsetProperty(nsGkAtoms::overridePreserveAspectRatio);
- delete static_cast<SVGPreserveAspectRatio*>(valPtr);
- return valPtr;
-}
-
void
SVGSVGElement::
SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio& aPAR)
{
#ifdef DEBUG
MOZ_ASSERT(OwnerDoc()->IsBeingUsedAsImage(),
"should only override preserveAspectRatio in images");
#endif
@@ -1126,51 +719,118 @@ SVGSVGElement::ClearImageOverridePreserv
mImageNeedsTransformInvalidation = true;
}
if (ClearPreserveAspectRatioProperty()) {
mImageNeedsTransformInvalidation = true;
}
}
-void
-SVGSVGElement::FlushImageTransformInvalidation()
+bool
+SVGSVGElement::SetPreserveAspectRatioProperty(const SVGPreserveAspectRatio& aPAR)
{
- MOZ_ASSERT(!GetParent(), "Should only be called on root node");
- MOZ_ASSERT(OwnerDoc()->IsBeingUsedAsImage(),
- "Should only be called on image documents");
+ SVGPreserveAspectRatio* pAROverridePtr = new SVGPreserveAspectRatio(aPAR);
+ nsresult rv = SetProperty(nsGkAtoms::overridePreserveAspectRatio,
+ pAROverridePtr,
+ nsINode::DeleteProperty<SVGPreserveAspectRatio>,
+ true);
+ MOZ_ASSERT(rv != NS_PROPTABLE_PROP_OVERWRITTEN,
+ "Setting override value when it's already set...?");
+
+ if (MOZ_UNLIKELY(NS_FAILED(rv))) {
+ // property-insertion failed (e.g. OOM in property-table code)
+ delete pAROverridePtr;
+ return false;
+ }
+ return true;
+}
- if (mImageNeedsTransformInvalidation) {
- InvalidateTransformNotifyFrame();
- mImageNeedsTransformInvalidation = false;
+const SVGPreserveAspectRatio*
+SVGSVGElement::GetPreserveAspectRatioProperty() const
+{
+ void* valPtr = GetProperty(nsGkAtoms::overridePreserveAspectRatio);
+ if (valPtr) {
+ return static_cast<SVGPreserveAspectRatio*>(valPtr);
}
+ return nullptr;
+}
+
+bool
+SVGSVGElement::ClearPreserveAspectRatioProperty()
+{
+ void* valPtr = UnsetProperty(nsGkAtoms::overridePreserveAspectRatio);
+ delete static_cast<SVGPreserveAspectRatio*>(valPtr);
+ return valPtr;
}
-int32_t
-SVGSVGElement::GetIntrinsicWidth()
+
+SVGPreserveAspectRatio
+SVGSVGElement::GetPreserveAspectRatioWithOverride() const
{
- if (mLengthAttributes[ATTR_WIDTH].IsPercentage()) {
- return -1;
+ nsIDocument* doc = GetUncomposedDoc();
+ if (doc && doc->IsBeingUsedAsImage()) {
+ const SVGPreserveAspectRatio *pAROverridePtr = GetPreserveAspectRatioProperty();
+ if (pAROverridePtr) {
+ return *pAROverridePtr;
+ }
}
- // 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).
- float width = mLengthAttributes[ATTR_WIDTH].GetAnimValue(this);
- return nsSVGUtils::ClampToInt(width);
+
+ SVGViewElement* viewElement = GetCurrentViewElement();
+
+ // This check is equivalent to "!HasViewBoxRect() && ShouldSynthesizeViewBox()".
+ // We're just holding onto the viewElement that HasViewBoxRect() would look up,
+ // so that we don't have to look it up again later.
+ if (!((viewElement && viewElement->mViewBox.HasRect()) ||
+ (mSVGView && mSVGView->mViewBox.HasRect()) ||
+ mViewBox.HasRect()) &&
+ ShouldSynthesizeViewBox()) {
+ // If we're synthesizing a viewBox, use preserveAspectRatio="none";
+ return SVGPreserveAspectRatio(SVG_PRESERVEASPECTRATIO_NONE, SVG_MEETORSLICE_SLICE);
+ }
+
+ if (viewElement && viewElement->mPreserveAspectRatio.IsExplicitlySet()) {
+ return viewElement->mPreserveAspectRatio.GetAnimValue();
+ }
+ if (mSVGView && mSVGView->mPreserveAspectRatio.IsExplicitlySet()) {
+ return mSVGView->mPreserveAspectRatio.GetAnimValue();
+ }
+ return mPreserveAspectRatio.GetAnimValue();
}
-int32_t
-SVGSVGElement::GetIntrinsicHeight()
+SVGViewElement*
+SVGSVGElement::GetCurrentViewElement() const
{
- if (mLengthAttributes[ATTR_HEIGHT].IsPercentage()) {
- return -1;
+ if (mCurrentViewID) {
+ //XXXsmaug It is unclear how this should work in case we're in Shadow DOM.
+ nsIDocument* doc = GetUncomposedDoc();
+ if (doc) {
+ Element *element = doc->GetElementById(*mCurrentViewID);
+ if (element && element->IsSVGElement(nsGkAtoms::view)) {
+ return static_cast<SVGViewElement*>(element);
+ }
+ }
}
- // 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).
- float height = mLengthAttributes[ATTR_HEIGHT].GetAnimValue(this);
- return nsSVGUtils::ClampToInt(height);
+ return nullptr;
+}
+
+const nsSVGViewBox&
+SVGSVGElement::GetViewBoxInternal() const
+{
+ SVGViewElement* viewElement = GetCurrentViewElement();
+
+ if (viewElement && viewElement->mViewBox.HasRect()) {
+ return viewElement->mViewBox;
+ } else if (mSVGView && mSVGView->mViewBox.HasRect()) {
+ return mSVGView->mViewBox;
+ }
+
+ return mViewBox;
+}
+
+nsSVGAnimatedTransformList*
+SVGSVGElement::GetTransformInternal() const
+{
+ return (mSVGView && mSVGView->mTransforms)
+ ? mSVGView->mTransforms: mTransforms;
}
} // namespace dom
} // namespace mozilla
--- a/dom/svg/SVGSVGElement.h
+++ b/dom/svg/SVGSVGElement.h
@@ -2,60 +2,51 @@
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SVGSVGElement_h
#define mozilla_dom_SVGSVGElement_h
-#include "mozilla/dom/FromParser.h"
-#include "nsAutoPtr.h"
-#include "nsIContentInlines.h"
-#include "nsISVGPoint.h"
-#include "nsSVGEnum.h"
-#include "nsSVGLength2.h"
-#include "SVGGraphicsElement.h"
-#include "SVGImageContext.h"
-#include "nsSVGViewBox.h"
-#include "SVGPreserveAspectRatio.h"
-#include "SVGAnimatedPreserveAspectRatio.h"
-#include "mozilla/Attributes.h"
+#include "SVGViewportElement.h"
nsresult NS_NewSVGSVGElement(nsIContent **aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser);
class nsSMILTimeContainer;
-class nsSVGOuterSVGFrame;
-class nsSVGInnerSVGFrame;
namespace mozilla {
-class AutoPreserveAspectRatioOverride;
-class AutoSVGTimeSetRestore;
-class DOMSVGAnimatedPreserveAspectRatio;
+class AutoSVGViewHandler;
+class SVGFragmentIdentifier;
+class EventChainPreVisitor;
class DOMSVGLength;
class DOMSVGNumber;
-class EventChainPreVisitor;
-class SVGFragmentIdentifier;
-class AutoSVGViewHandler;
namespace dom {
class SVGAngle;
-class SVGAnimatedRect;
class SVGMatrix;
-class SVGTransform;
-class SVGViewElement;
class SVGIRect;
+class SVGSVGElement;
-class SVGSVGElement;
+// Stores svgView arguments of SVG fragment identifiers.
+class SVGView {
+public:
+ SVGView();
+
+ nsSVGEnum mZoomAndPan;
+ nsSVGViewBox mViewBox;
+ SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
+ nsAutoPtr<nsSVGAnimatedTransformList> mTransforms;
+};
class DOMSVGTranslatePoint final : public nsISVGPoint {
public:
- DOMSVGTranslatePoint(SVGPoint* aPt, SVGSVGElement *aElement)
+ DOMSVGTranslatePoint(SVGPoint* aPt, SVGSVGElement* aElement)
: nsISVGPoint(aPt, true), mElement(aElement) {}
explicit DOMSVGTranslatePoint(DOMSVGTranslatePoint* aPt)
: nsISVGPoint(&aPt->mPt, true), mElement(aPt->mElement) {}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMSVGTranslatePoint, nsISVGPoint)
@@ -71,55 +62,27 @@ public:
virtual nsISupports* GetParentObject() override;
RefPtr<SVGSVGElement> mElement;
private:
~DOMSVGTranslatePoint() {}
};
-class svgFloatSize {
-public:
- svgFloatSize(float aWidth, float aHeight)
- : width(aWidth)
- , height(aHeight)
- {}
- bool operator!=(const svgFloatSize& rhs) {
- return width != rhs.width || height != rhs.height;
- }
- float width;
- float height;
-};
-
-// Stores svgView arguments of SVG fragment identifiers.
-class SVGView {
- friend class mozilla::AutoSVGViewHandler;
- friend class mozilla::dom::SVGSVGElement;
-public:
- SVGView();
-
-private:
- nsSVGEnum mZoomAndPan;
- nsSVGViewBox mViewBox;
- SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
- nsAutoPtr<nsSVGAnimatedTransformList> mTransforms;
-};
-
-typedef SVGGraphicsElement SVGSVGElementBase;
+typedef SVGViewportElement SVGSVGElementBase;
class SVGSVGElement final : public SVGSVGElementBase
{
friend class ::nsSVGOuterSVGFrame;
- friend class ::nsSVGInnerSVGFrame;
- friend class mozilla::AutoPreserveAspectRatioOverride;
- friend class mozilla::AutoSVGTimeSetRestore;
- friend class mozilla::dom::SVGView;
friend class mozilla::SVGFragmentIdentifier;
friend class mozilla::AutoSVGViewHandler;
+ friend class mozilla::AutoPreserveAspectRatioOverride;
+ friend class mozilla::dom::SVGView;
+protected:
SVGSVGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
FromParser aFromParser);
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
friend nsresult (::NS_NewSVGSVGElement(nsIContent **aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser));
@@ -134,134 +97,25 @@ public:
* For use by zoom controls to allow currentScale, currentTranslate.x and
* currentTranslate.y to be set by a single operation that dispatches a
* single SVGZoom event (instead of one SVGZoom and two SVGScroll events).
*
* XXX SVGZoomEvent is no more, is this needed?
*/
void SetCurrentScaleTranslate(float s, float x, float y);
- /**
- * Retrieve the value of currentScale and currentTranslate.
- */
- const SVGPoint& GetCurrentTranslate() { return mCurrentTranslate; }
- float GetCurrentScale() { return mCurrentScale; }
-
- /**
- * Retrieve the value of currentScale, currentTranslate.x or
- * currentTranslate.y prior to the last change made to any one of them.
- */
- const SVGPoint& GetPreviousTranslate() { return mPreviousTranslate; }
- float GetPreviousScale() { return mPreviousScale; }
-
- nsSMILTimeContainer* GetTimedDocumentRoot();
-
// nsIContent interface
- NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const override;
virtual nsresult GetEventTargetParent(
EventChainPreVisitor& aVisitor) override;
-
virtual bool IsEventAttributeName(nsIAtom* aName) override;
- // nsSVGElement specializations:
- virtual gfxMatrix PrependLocalTransformsTo(
- const gfxMatrix &aMatrix,
- SVGTransformTypes aWhich = eAllTransforms) const override;
- virtual nsSVGAnimatedTransformList*
- GetAnimatedTransformList(uint32_t aFlags = 0) override;
- virtual bool HasValidDimensions() const override;
-
- // SVGSVGElement methods:
- float GetLength(uint8_t mCtxType);
-
- // public helpers:
-
- /**
- * Returns -1 if the width/height is a percentage, else returns the user unit
- * length clamped to fit in a int32_t.
- * XXX see bug 1112533 comment 3 - we should fix drawImage so that we can
- * change these methods to make zero the error flag for percentages.
- */
- int32_t GetIntrinsicWidth();
- int32_t GetIntrinsicHeight();
-
- /**
- * Returns true if this element has a base/anim value for its "viewBox"
- * attribute that defines a viewBox rectangle with finite values, or
- * if there is a view element overriding this element's viewBox and it
- * has a valid viewBox.
- *
- * Note that this does not check whether we need to synthesize a viewBox,
- * so you must call ShouldSynthesizeViewBox() if you need to check that too.
- *
- * Note also that this method does not pay attention to whether the width or
- * height values of the viewBox rect are positive!
- */
- bool HasViewBoxRect() const;
-
- /**
- * Returns true if we should synthesize a viewBox for ourselves (that is, if
- * we're the root element in an image document, and we're not currently being
- * painted for an <svg:image> element).
- *
- * Only call this method if HasViewBoxRect() returns false.
- */
- bool ShouldSynthesizeViewBox() const;
-
- bool HasViewBoxOrSyntheticViewBox() const {
- return HasViewBoxRect() || ShouldSynthesizeViewBox();
- }
-
- gfx::Matrix GetViewBoxTransform() const;
-
- bool HasChildrenOnlyTransform() const {
- return mHasChildrenOnlyTransform;
- }
-
- void UpdateHasChildrenOnlyTransform();
-
- enum ChildrenOnlyTransformChangedFlags {
- eDuringReflow = 1
- };
-
- /**
- * This method notifies the style system that the overflow rects of our
- * immediate childrens' frames need to be updated. It is called by our own
- * frame when changes (e.g. to currentScale) cause our children-only
- * transform to change.
- *
- * The reason we have this method instead of overriding
- * GetAttributeChangeHint is because we need to act on non-attribute (e.g.
- * currentScale) changes in addition to attribute (e.g. viewBox) changes.
- */
- void ChildrenOnlyTransformChanged(uint32_t aFlags = 0);
-
- // This services any pending notifications for the transform on on this root
- // <svg> node needing to be recalculated. (Only applicable in
- // SVG-as-an-image documents.)
- virtual void FlushImageTransformInvalidation();
-
+ // nsINode methods:
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
bool aPreallocateChildren) const override;
- // Returns true IFF our attributes are currently overridden by a <view>
- // element and that element's ID matches the passed-in string.
- bool IsOverriddenBy(const nsAString &aViewID) const {
- return mCurrentViewID && mCurrentViewID->Equals(aViewID);
- }
-
- svgFloatSize GetViewportSize() const {
- return svgFloatSize(mViewportWidth, mViewportHeight);
- }
-
- void SetViewportSize(const svgFloatSize& aSize) {
- mViewportWidth = aSize.width;
- mViewportHeight = aSize.height;
- }
-
// WebIDL
already_AddRefed<SVGAnimatedLength> X();
already_AddRefed<SVGAnimatedLength> Y();
already_AddRefed<SVGAnimatedLength> Width();
already_AddRefed<SVGAnimatedLength> Height();
float PixelUnitToMillimeterX();
float PixelUnitToMillimeterY();
float ScreenPixelToMillimeterX();
@@ -285,64 +139,72 @@ public:
already_AddRefed<DOMSVGLength> CreateSVGLength();
already_AddRefed<SVGAngle> CreateSVGAngle();
already_AddRefed<nsISVGPoint> CreateSVGPoint();
already_AddRefed<SVGMatrix> CreateSVGMatrix();
already_AddRefed<SVGIRect> CreateSVGRect();
already_AddRefed<SVGTransform> CreateSVGTransform();
already_AddRefed<SVGTransform> CreateSVGTransformFromMatrix(SVGMatrix& matrix);
using nsINode::GetElementById; // This does what we want
- already_AddRefed<SVGAnimatedRect> ViewBox();
- already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
uint16_t ZoomAndPan();
void SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv);
- virtual nsSVGViewBox* GetViewBox() override;
-private:
// nsSVGElement overrides
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers) override;
virtual void UnbindFromTree(bool aDeep, bool aNullParent) override;
+ virtual nsSVGAnimatedTransformList*
+ GetAnimatedTransformList(uint32_t aFlags = 0) override;
+
+ // SVGSVGElement methods:
+
+ // Returns true IFF our attributes are currently overridden by a <view>
+ // element and that element's ID matches the passed-in string.
+ bool IsOverriddenBy(const nsAString &aViewID) const {
+ return mCurrentViewID && mCurrentViewID->Equals(aViewID);
+ }
+
+ nsSMILTimeContainer* GetTimedDocumentRoot();
+
+ // public helpers:
+
+ /**
+ * Returns -1 if the width/height is a percentage, else returns the user unit
+ * length clamped to fit in a int32_t.
+ * XXX see bug 1112533 comment 3 - we should fix drawImage so that we can
+ * change these methods to make zero the error flag for percentages.
+ */
+ int32_t GetIntrinsicWidth();
+ int32_t GetIntrinsicHeight();
+
+ // This services any pending notifications for the transform on on this root
+ // <svg> node needing to be recalculated. (Only applicable in
+ // SVG-as-an-image documents.)
+ virtual void FlushImageTransformInvalidation();
+
+ svgFloatSize GetViewportSize() const {
+ return svgFloatSize(mViewportWidth, mViewportHeight);
+ }
+
+ void SetViewportSize(const svgFloatSize& aSize) {
+ mViewportWidth = aSize.width;
+ mViewportHeight = aSize.height;
+ }
+
+private:
+ // SVGViewportElement methods:
+
+ virtual SVGViewElement* GetCurrentViewElement() const;
+ virtual SVGPreserveAspectRatio GetPreserveAspectRatioWithOverride() const override;
// implementation helpers:
- SVGViewElement* GetCurrentViewElement() const;
-
- // Methods for <image> elements to override my "PreserveAspectRatio" value.
- // These are private so that only our friends
- // (AutoPreserveAspectRatioOverride in particular) have access.
- void SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio& aPAR);
- void ClearImageOverridePreserveAspectRatio();
-
- // Set/Clear properties to hold old version of preserveAspectRatio
- // when it's being overridden by an <image> element that we are inside of.
- bool SetPreserveAspectRatioProperty(const SVGPreserveAspectRatio& aPAR);
- const SVGPreserveAspectRatio* GetPreserveAspectRatioProperty() const;
- bool ClearPreserveAspectRatioProperty();
-
- bool IsRoot() const {
- NS_ASSERTION((IsInUncomposedDoc() && !GetParent()) ==
- (OwnerDoc() && (OwnerDoc()->GetRootElement() == this)),
- "Can't determine if we're root");
- return IsInUncomposedDoc() && !GetParent();
- }
-
- /**
- * Returns true if this is an SVG <svg> element that is the child of
- * another non-foreignObject SVG element.
- */
- bool IsInner() const {
- const nsIContent *parent = GetFlattenedTreeParent();
- return parent && parent->IsSVGElement() &&
- !parent->IsSVGElement(nsGkAtoms::foreignObject);
- }
-
- /*
+ /*
* While binding to the tree we need to determine if we will be the outermost
* <svg> element _before_ the children are bound (as they want to know what
* timed document root to register with) and therefore _before_ our parent is
* set (both actions are performed by Element::BindToTree) so we
* can't use GetOwnerSVGElement() as it relies on GetParent(). This code is
* basically a simplified version of GetOwnerSVGElement that uses the parent
* parameters passed in instead.
*/
@@ -352,62 +214,43 @@ private:
// invalidate viewbox -> viewport xform & inform frames
void InvalidateTransformNotifyFrame();
// Returns true if we have at least one of the following:
// - a (valid or invalid) value for the preserveAspectRatio attribute
// - a SMIL-animated value for the preserveAspectRatio attribute
bool HasPreserveAspectRatio();
- /**
- * Returns the explicit viewBox rect, if specified, or else a synthesized
- * viewBox, if appropriate, or else a viewBox matching the dimensions of the
- * SVG viewport.
- */
- nsSVGViewBoxRect GetViewBoxWithSynthesis(
- float aViewportWidth, float aViewportHeight) const;
- /**
- * Returns the explicit or default preserveAspectRatio, unless we're
- * synthesizing a viewBox, in which case it returns the "none" value.
- */
- SVGPreserveAspectRatio GetPreserveAspectRatioWithOverride() const;
+ // Methods for <image> elements to override my "PreserveAspectRatio" value.
+ // These are private so that only our friends
+ // (AutoPreserveAspectRatioOverride in particular) have access.
+ void SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio& aPAR);
+ void ClearImageOverridePreserveAspectRatio();
- virtual LengthAttributesInfo GetLengthInfo() override;
+ // Set/Clear properties to hold old version of preserveAspectRatio
+ // when it's being overridden by an <image> element that we are inside of.
+ bool SetPreserveAspectRatioProperty(const SVGPreserveAspectRatio& aPAR);
+ const SVGPreserveAspectRatio* GetPreserveAspectRatioProperty() const;
+ bool ClearPreserveAspectRatioProperty();
- enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
- nsSVGLength2 mLengthAttributes[4];
- static LengthInfo sLengthInfo[4];
+ virtual SVGPoint GetCurrentTranslate() const override
+ { return mCurrentTranslate; }
+ virtual float GetCurrentScale() const override
+ { return mCurrentScale; }
+
+ virtual const nsSVGViewBox& GetViewBoxInternal() const override;
+ virtual nsSVGAnimatedTransformList* GetTransformInternal() const override;
virtual EnumAttributesInfo GetEnumInfo() override;
enum { ZOOMANDPAN };
nsSVGEnum mEnumAttributes[1];
static nsSVGEnumMapping sZoomAndPanMap[];
static EnumInfo sEnumInfo[1];
- virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() override;
-
- nsSVGViewBox mViewBox;
- SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
-
- // mCurrentViewID and mSVGView are mutually exclusive; we can have
- // at most one non-null.
- nsAutoPtr<nsString> mCurrentViewID;
- nsAutoPtr<SVGView> mSVGView;
-
- // The size of the rectangular SVG viewport into which we render. This is
- // not (necessarily) the same as the content area. See:
- //
- // http://www.w3.org/TR/SVG11/coords.html#ViewportSpace
- //
- // XXXjwatt Currently only used for outer <svg>, but maybe we could use -1 to
- // flag this as an inner <svg> to save the overhead of GetCtx calls?
- // XXXjwatt our frame should probably reset these when it's destroyed.
- float mViewportWidth, mViewportHeight;
-
// The time container for animations within this SVG document fragment. Set
// for all outermost <svg> elements (not nested <svg> elements).
nsAutoPtr<nsSMILTimeContainer> mTimedDocumentRoot;
// zoom and pan
// IMPORTANT: see the comment in RecordCurrentScaleTranslate before writing
// code to change any of these!
SVGPoint mCurrentTranslate;
@@ -415,33 +258,62 @@ private:
SVGPoint mPreviousTranslate;
float mPreviousScale;
// For outermost <svg> elements created from parsing, animation is started by
// the onload event in accordance with the SVG spec, but for <svg> elements
// created by script or promoted from inner <svg> to outermost <svg> we need
// to manually kick off animation when they are bound to the tree.
bool mStartAnimationOnBindToTree;
+
bool mImageNeedsTransformInvalidation;
- bool mHasChildrenOnlyTransform;
+
+ // mCurrentViewID and mSVGView are mutually exclusive; we can have
+ // at most one non-null.
+ nsAutoPtr<nsString> mCurrentViewID;
+ nsAutoPtr<SVGView> mSVGView;
};
} // namespace dom
+class MOZ_RAII AutoSVGTimeSetRestore
+{
+public:
+ AutoSVGTimeSetRestore(dom::SVGSVGElement* aRootElem,
+ float aFrameTime
+ MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+ : mRootElem(aRootElem)
+ , mOriginalTime(mRootElem->GetCurrentTime())
+ {
+ MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+ mRootElem->SetCurrentTime(aFrameTime); // Does nothing if there's no change.
+ }
+
+ ~AutoSVGTimeSetRestore()
+ {
+ mRootElem->SetCurrentTime(mOriginalTime);
+ }
+
+private:
+ const RefPtr<dom::SVGSVGElement> mRootElem;
+ const float mOriginalTime;
+ MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
class MOZ_RAII AutoPreserveAspectRatioOverride
{
public:
AutoPreserveAspectRatioOverride(const Maybe<SVGImageContext>& aSVGContext,
dom::SVGSVGElement* aRootElem
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mRootElem(aRootElem)
, mDidOverride(false)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- MOZ_ASSERT(mRootElem, "No SVG node to manage?");
+ MOZ_ASSERT(mRootElem, "No SVG/Symbol node to manage?");
if (aSVGContext.isSome() &&
aSVGContext->GetPreserveAspectRatio().isSome()) {
// Override preserveAspectRatio in our helper document.
// XXXdholbert We should technically be overriding the helper doc's clip
// and overflow properties here, too. See bug 272288 comment 36.
mRootElem->SetImageOverridePreserveAspectRatio(
*aSVGContext->GetPreserveAspectRatio());
@@ -457,35 +329,11 @@ public:
}
private:
const RefPtr<dom::SVGSVGElement> mRootElem;
bool mDidOverride;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
-class MOZ_RAII AutoSVGTimeSetRestore
-{
-public:
- AutoSVGTimeSetRestore(dom::SVGSVGElement* aRootElem,
- float aFrameTime
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : mRootElem(aRootElem)
- , mOriginalTime(mRootElem->GetCurrentTime())
- {
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- mRootElem->SetCurrentTime(aFrameTime); // Does nothing if there's no change.
- }
-
- ~AutoSVGTimeSetRestore()
- {
- mRootElem->SetCurrentTime(mOriginalTime);
- }
-
-private:
- const RefPtr<dom::SVGSVGElement> mRootElem;
- const float mOriginalTime;
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-
} // namespace mozilla
#endif // SVGSVGElement_h
--- a/dom/svg/SVGSymbolElement.cpp
+++ b/dom/svg/SVGSymbolElement.cpp
@@ -38,72 +38,18 @@ SVGSymbolElement::~SVGSymbolElement()
}
//----------------------------------------------------------------------
// nsIDOMNode methods
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGSymbolElement)
//----------------------------------------------------------------------
-
-already_AddRefed<SVGAnimatedRect>
-SVGSymbolElement::ViewBox()
-{
- return mViewBox.ToSVGAnimatedRect(this);
-}
-
-already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
-SVGSymbolElement::PreserveAspectRatio()
-{
- return mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(this);
-}
-
-//----------------------------------------------------------------------
-// nsIContent methods
-
-NS_IMETHODIMP_(bool)
-SVGSymbolElement::IsAttributeMapped(const nsIAtom* name) const
-{
- static const MappedAttributeEntry* const map[] = {
- sColorMap,
- sFEFloodMap,
- sFillStrokeMap,
- sFiltersMap,
- sFontSpecificationMap,
- sGradientStopMap,
- sGraphicsMap,
- sLightingEffectsMap,
- sMarkersMap,
- sTextContentElementsMap,
- sViewportsMap
- };
-
- return FindAttributeDependence(name, map) ||
- SVGSymbolElementBase::IsAttributeMapped(name);
-}
-
-//----------------------------------------------------------------------
// SVGTests methods
bool
SVGSymbolElement::IsInChromeDoc() const
{
return nsContentUtils::IsChromeDoc(OwnerDoc());
}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGViewBox *
-SVGSymbolElement::GetViewBox()
-{
- return &mViewBox;
-}
-
-SVGAnimatedPreserveAspectRatio *
-SVGSymbolElement::GetPreserveAspectRatio()
-{
- return &mPreserveAspectRatio;
-}
-
} // namespace dom
} // namespace mozilla
--- a/dom/svg/SVGSymbolElement.h
+++ b/dom/svg/SVGSymbolElement.h
@@ -2,61 +2,42 @@
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SVGSymbolElement_h
#define mozilla_dom_SVGSymbolElement_h
-#include "mozilla/dom/SVGTests.h"
-#include "nsSVGElement.h"
-#include "nsSVGViewBox.h"
-#include "SVGAnimatedPreserveAspectRatio.h"
+#include "SVGViewportElement.h"
nsresult NS_NewSVGSymbolElement(nsIContent **aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
namespace mozilla {
namespace dom {
-typedef nsSVGElement SVGSymbolElementBase;
+typedef SVGViewportElement SVGSymbolElementBase;
-class SVGSymbolElement final : public SVGSymbolElementBase,
- public SVGTests
+class SVGSymbolElement final : public SVGSymbolElementBase
{
protected:
friend nsresult (::NS_NewSVGSymbolElement(nsIContent **aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
explicit SVGSymbolElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
~SVGSymbolElement();
virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
public:
// interfaces:
-
NS_DECL_ISUPPORTS_INHERITED
- // nsIContent interface
- NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const override;
-
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
bool aPreallocateChildren) const override;
- // WebIDL
- already_AddRefed<SVGAnimatedRect> ViewBox();
- already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
-
// SVGTests
bool IsInChromeDoc() const override;
-
-protected:
- virtual nsSVGViewBox *GetViewBox() override;
- virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() override;
-
- nsSVGViewBox mViewBox;
- SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_SVGSymbolElement_h
--- a/dom/svg/SVGViewElement.h
+++ b/dom/svg/SVGViewElement.h
@@ -23,23 +23,24 @@ class nsSVGOuterSVGFrame;
nsresult NS_NewSVGViewElement(nsIContent **aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
namespace mozilla {
class SVGFragmentIdentifier;
namespace dom {
-class SVGSVGElement;
+class SVGViewportElement;
class SVGViewElement : public SVGViewElementBase
{
protected:
friend class mozilla::SVGFragmentIdentifier;
friend class SVGSVGElement;
+ friend class SVGViewportElement;
friend class ::nsSVGOuterSVGFrame;
explicit SVGViewElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
friend nsresult (::NS_NewSVGViewElement(nsIContent **aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
public:
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
new file mode 100644
--- /dev/null
+++ b/dom/svg/SVGViewportElement.cpp
@@ -0,0 +1,374 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <stdint.h>
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/ContentEvents.h"
+#include "mozilla/EventDispatcher.h"
+#include "mozilla/Likely.h"
+#include "mozilla/dom/SVGMatrix.h"
+#include "mozilla/dom/SVGViewportElement.h"
+#include "mozilla/dom/SVGViewElement.h"
+
+#include "DOMSVGLength.h"
+#include "DOMSVGPoint.h"
+#include "nsCOMPtr.h"
+#include "nsContentUtils.h"
+#include "nsFrameSelection.h"
+#include "nsError.h"
+#include "nsGkAtoms.h"
+#include "nsIDocument.h"
+#include "nsIFrame.h"
+#include "nsIPresShell.h"
+#include "nsISVGSVGFrame.h" //XXX
+#include "nsLayoutUtils.h"
+#include "nsStyleUtil.h"
+#include "nsSMILTypes.h"
+#include "SVGContentUtils.h"
+
+#include <algorithm>
+#include "prtime.h"
+
+using namespace mozilla::gfx;
+
+namespace mozilla {
+namespace dom {
+
+nsSVGElement::LengthInfo SVGViewportElement::sLengthInfo[4] =
+{
+ { &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
+ { &nsGkAtoms::y, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
+ { &nsGkAtoms::width, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
+ { &nsGkAtoms::height, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
+};
+
+//----------------------------------------------------------------------
+// Implementation
+
+SVGViewportElement::SVGViewportElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
+ : SVGGraphicsElement(aNodeInfo),
+ mViewportWidth(0),
+ mViewportHeight(0),
+ mHasChildrenOnlyTransform(false)
+{
+}
+
+SVGViewportElement::~SVGViewportElement()
+{
+}
+
+//----------------------------------------------------------------------
+
+already_AddRefed<SVGAnimatedRect>
+SVGViewportElement::ViewBox()
+{
+ return mViewBox.ToSVGAnimatedRect(this);
+}
+
+already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
+SVGViewportElement::PreserveAspectRatio()
+{
+ return mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(this);
+}
+
+//----------------------------------------------------------------------
+// nsIContent methods
+
+NS_IMETHODIMP_(bool)
+SVGViewportElement::IsAttributeMapped(const nsIAtom* name) const
+{
+ // We want to map the 'width' and 'height' attributes into style for
+ // outer-<svg>, except when the attributes aren't set (since their default
+ // values of '100%' can cause unexpected and undesirable behaviour for SVG
+ // inline in HTML). We rely on nsSVGElement::UpdateContentStyleRule() to
+ // prevent mapping of the default values into style (it only maps attributes
+ // that are set). We also rely on a check in nsSVGElement::
+ // UpdateContentStyleRule() to prevent us mapping the attributes when they're
+ // given a <length> value that is not currently recognized by the SVG
+ // specification.
+
+ if (!IsInner() && (name == nsGkAtoms::width || name == nsGkAtoms::height)) {
+ return true;
+ }
+
+ static const MappedAttributeEntry* const map[] = {
+ sColorMap,
+ sFEFloodMap,
+ sFillStrokeMap,
+ sFiltersMap,
+ sFontSpecificationMap,
+ sGradientStopMap,
+ sGraphicsMap,
+ sLightingEffectsMap,
+ sMarkersMap,
+ sTextContentElementsMap,
+ sViewportsMap
+ };
+
+ return FindAttributeDependence(name, map) ||
+ SVGGraphicsElement::IsAttributeMapped(name);
+}
+
+//----------------------------------------------------------------------
+// nsSVGElement overrides
+
+// Helper for GetViewBoxTransform on root <svg> node
+// * aLength: internal value for our <svg> width or height attribute.
+// * aViewportLength: length of the corresponding dimension of the viewport.
+// * aSelf: the outermost <svg> node itself.
+// NOTE: aSelf is not an ancestor viewport element, so it can't be used to
+// resolve percentage lengths. (It can only be used to resolve
+// 'em'/'ex'-valued units).
+inline float
+ComputeSynthesizedViewBoxDimension(const nsSVGLength2& aLength,
+ float aViewportLength,
+ const SVGViewportElement* aSelf)
+{
+ if (aLength.IsPercentage()) {
+ return aViewportLength * aLength.GetAnimValInSpecifiedUnits() / 100.0f;
+ }
+
+ return aLength.GetAnimValue(const_cast<SVGViewportElement*>(aSelf));
+}
+
+//----------------------------------------------------------------------
+// public helpers:
+
+void
+SVGViewportElement::UpdateHasChildrenOnlyTransform()
+{
+ bool hasChildrenOnlyTransform =
+ HasViewBoxOrSyntheticViewBox() ||
+ (IsRoot() && (GetCurrentTranslate() != SVGPoint(0.0f, 0.0f) ||
+ GetCurrentScale() != 1.0f));
+ mHasChildrenOnlyTransform = hasChildrenOnlyTransform;
+}
+
+void
+SVGViewportElement::ChildrenOnlyTransformChanged(uint32_t aFlags)
+{
+ // Avoid wasteful calls:
+ MOZ_ASSERT(!(GetPrimaryFrame()->GetStateBits() & NS_FRAME_IS_NONDISPLAY),
+ "Non-display SVG frames don't maintain overflow rects");
+
+ nsChangeHint changeHint;
+
+ bool hadChildrenOnlyTransform = mHasChildrenOnlyTransform;
+
+ UpdateHasChildrenOnlyTransform();
+
+ if (hadChildrenOnlyTransform != mHasChildrenOnlyTransform) {
+ // Reconstruct the frame tree to handle stacking context changes:
+ // XXXjwatt don't do this for root-<svg> or even outer-<svg>?
+ changeHint = nsChangeHint_ReconstructFrame;
+ } else {
+ // We just assume the old and new transforms are different.
+ changeHint = nsChangeHint(nsChangeHint_UpdateOverflow |
+ nsChangeHint_ChildrenOnlyTransform);
+ }
+
+ // If we're not reconstructing the frame tree, then we only call
+ // PostRestyleEvent if we're not being called under reflow to avoid recursing
+ // to death. See bug 767056 comments 10 and 12. Since our nsSVGOuterSVGFrame
+ // is being reflowed we're going to invalidate and repaint its entire area
+ // anyway (which will include our children).
+ if ((changeHint & nsChangeHint_ReconstructFrame) ||
+ !(aFlags & eDuringReflow)) {
+ nsLayoutUtils::PostRestyleEvent(this, nsRestyleHint(0), changeHint);
+ }
+}
+
+gfx::Matrix
+SVGViewportElement::GetViewBoxTransform() const
+{
+ float viewportWidth, viewportHeight;
+ if (IsInner()) {
+ SVGViewportElement *ctx = GetCtx();
+ viewportWidth = mLengthAttributes[ATTR_WIDTH].GetAnimValue(ctx);
+ viewportHeight = mLengthAttributes[ATTR_HEIGHT].GetAnimValue(ctx);
+ } else {
+ viewportWidth = mViewportWidth;
+ viewportHeight = mViewportHeight;
+ }
+
+ if (viewportWidth <= 0.0f || viewportHeight <= 0.0f) {
+ return gfx::Matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
+ }
+
+ nsSVGViewBoxRect viewBox =
+ GetViewBoxWithSynthesis(viewportWidth, viewportHeight);
+
+ if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
+ return gfx::Matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
+ }
+
+ return SVGContentUtils::GetViewBoxTransform(viewportWidth, viewportHeight,
+ viewBox.x, viewBox.y,
+ viewBox.width, viewBox.height,
+ GetPreserveAspectRatioWithOverride());
+}
+//----------------------------------------------------------------------
+// SVGViewportElement
+
+float
+SVGViewportElement::GetLength(uint8_t aCtxType)
+{
+ const nsSVGViewBoxRect* viewbox =
+ GetViewBoxInternal().HasRect() ? &GetViewBoxInternal().GetAnimValue()
+ : nullptr;
+
+ float h, w;
+ if (viewbox) {
+ w = viewbox->width;
+ h = viewbox->height;
+ } else if (IsInner()) {
+ SVGViewportElement *ctx = GetCtx();
+ w = mLengthAttributes[ATTR_WIDTH].GetAnimValue(ctx);
+ h = mLengthAttributes[ATTR_HEIGHT].GetAnimValue(ctx);
+ } else if (ShouldSynthesizeViewBox()) {
+ w = ComputeSynthesizedViewBoxDimension(mLengthAttributes[ATTR_WIDTH],
+ mViewportWidth, this);
+ h = ComputeSynthesizedViewBoxDimension(mLengthAttributes[ATTR_HEIGHT],
+ mViewportHeight, this);
+ } else {
+ w = mViewportWidth;
+ h = mViewportHeight;
+ }
+
+ w = std::max(w, 0.0f);
+ h = std::max(h, 0.0f);
+
+ switch (aCtxType) {
+ case SVGContentUtils::X:
+ return w;
+ case SVGContentUtils::Y:
+ return h;
+ case SVGContentUtils::XY:
+ return float(SVGContentUtils::ComputeNormalizedHypotenuse(w, h));
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------
+// nsSVGElement methods
+
+/* virtual */ gfxMatrix
+SVGViewportElement::PrependLocalTransformsTo(const gfxMatrix& aMatrix,
+ SVGTransformTypes aWhich) const
+{
+ // 'transform' attribute (or an override from a fragment identifier):
+ gfxMatrix userToParent;
+
+ if (aWhich == eUserSpaceToParent || aWhich == eAllTransforms) {
+ userToParent = GetUserToParentTransform(mAnimateMotionTransform,
+ GetTransformInternal());
+ if (aWhich == eUserSpaceToParent) {
+ return userToParent * aMatrix;
+ }
+ }
+
+ gfxMatrix childToUser;
+
+ if (IsInner()) {
+ float x, y;
+ const_cast<SVGViewportElement*>(this)->GetAnimatedLengthValues(&x, &y, nullptr);
+ childToUser = ThebesMatrix(GetViewBoxTransform().PostTranslate(x, y));
+ } else if (IsRoot()) {
+ SVGPoint translate = GetCurrentTranslate();
+ float scale = GetCurrentScale();
+ childToUser = ThebesMatrix(GetViewBoxTransform()
+ .PostScale(scale, scale)
+ .PostTranslate(translate.GetX(),
+ translate.GetY()));
+ } else {
+ // outer-<svg>, but inline in some other content:
+ childToUser = ThebesMatrix(GetViewBoxTransform());
+ }
+
+ if (aWhich == eAllTransforms) {
+ return childToUser * userToParent * aMatrix;
+ }
+
+ MOZ_ASSERT(aWhich == eChildToUserSpace, "Unknown TransformTypes");
+
+ // The following may look broken because pre-multiplying our eChildToUserSpace
+ // transform with another matrix without including our eUserSpaceToParent
+ // transform between the two wouldn't make sense. We don't expect that to
+ // ever happen though. We get here either when the identity matrix has been
+ // passed because our caller just wants our eChildToUserSpace transform, or
+ // when our eUserSpaceToParent transform has already been multiplied into the
+ // matrix that our caller passes (such as when we're called from PaintSVG).
+ return childToUser * aMatrix;
+}
+
+/* virtual */ bool
+SVGViewportElement::HasValidDimensions() const
+{
+ return !IsInner() ||
+ ((!mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() ||
+ mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
+ (!mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() ||
+ mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0));
+}
+
+
+
+nsSVGViewBox*
+SVGViewportElement::GetViewBox()
+{
+ return &mViewBox;
+}
+
+SVGAnimatedPreserveAspectRatio *
+SVGViewportElement::GetPreserveAspectRatio()
+{
+ return &mPreserveAspectRatio;
+}
+
+bool
+SVGViewportElement::ShouldSynthesizeViewBox() const
+{
+ MOZ_ASSERT(!HasViewBoxRect(), "Should only be called if we lack a viewBox");
+
+ return IsRoot() && OwnerDoc()->IsBeingUsedAsImage();
+}
+
+//----------------------------------------------------------------------
+// implementation helpers
+
+nsSVGViewBoxRect
+SVGViewportElement::GetViewBoxWithSynthesis(
+ float aViewportWidth, float aViewportHeight) const
+{
+ if (GetViewBoxInternal().HasRect()) {
+ return GetViewBoxInternal().GetAnimValue();
+ }
+
+ if (ShouldSynthesizeViewBox()) {
+ // Special case -- fake a viewBox, using height & width attrs.
+ // (Use |this| as context, since if we get here, we're outermost <svg>.)
+ return nsSVGViewBoxRect(0, 0,
+ ComputeSynthesizedViewBoxDimension(mLengthAttributes[ATTR_WIDTH],
+ mViewportWidth, this),
+ ComputeSynthesizedViewBoxDimension(mLengthAttributes[ATTR_HEIGHT],
+ mViewportHeight, this));
+
+ }
+
+ // No viewBox attribute, so we shouldn't auto-scale. This is equivalent
+ // to having a viewBox that exactly matches our viewport size.
+ return nsSVGViewBoxRect(0, 0, aViewportWidth, aViewportHeight);
+}
+
+nsSVGElement::LengthAttributesInfo
+SVGViewportElement::GetLengthInfo()
+{
+ return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
+ ArrayLength(sLengthInfo));
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/svg/SVGViewportElement.h
@@ -0,0 +1,212 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_SVGViewportElement_h
+#define mozilla_dom_SVGViewportElement_h
+
+#include "mozilla/dom/FromParser.h"
+#include "nsAutoPtr.h"
+#include "nsIContentInlines.h"
+#include "nsISVGPoint.h"
+#include "nsSVGEnum.h"
+#include "nsSVGLength2.h"
+#include "SVGGraphicsElement.h"
+#include "SVGImageContext.h"
+#include "nsSVGViewBox.h"
+#include "SVGPreserveAspectRatio.h"
+#include "SVGAnimatedPreserveAspectRatio.h"
+#include "mozilla/Attributes.h"
+
+class nsSVGOuterSVGFrame;
+class nsSVGInnerSVGFrame;
+
+namespace mozilla {
+class AutoPreserveAspectRatioOverride;
+class DOMSVGAnimatedPreserveAspectRatio;
+
+namespace dom {
+class SVGAnimatedRect;
+class SVGTransform;
+class SVGViewElement;
+class SVGViewportElement;
+
+class svgFloatSize {
+public:
+ svgFloatSize(float aWidth, float aHeight)
+ : width(aWidth)
+ , height(aHeight)
+ {}
+ bool operator!=(const svgFloatSize& rhs) {
+ return width != rhs.width || height != rhs.height;
+ }
+ float width;
+ float height;
+};
+
+class SVGViewportElement : public SVGGraphicsElement
+{
+ friend class ::nsSVGOuterSVGFrame;
+ friend class ::nsSVGInnerSVGFrame;
+
+protected:
+
+ SVGViewportElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+ ~SVGViewportElement();
+
+public:
+
+ // nsIContent interface
+ NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const override;
+
+ // nsSVGElement specializations:
+ virtual gfxMatrix PrependLocalTransformsTo(
+ const gfxMatrix &aMatrix,
+ SVGTransformTypes aWhich = eAllTransforms) const override;
+
+ virtual bool HasValidDimensions() const override;
+
+ // SVGViewportElement methods:
+
+ float GetLength(uint8_t mCtxType);
+
+ // public helpers:
+
+ /**
+ * Returns true if this element has a base/anim value for its "viewBox"
+ * attribute that defines a viewBox rectangle with finite values, or
+ * if there is a view element overriding this element's viewBox and it
+ * has a valid viewBox.
+ *
+ * Note that this does not check whether we need to synthesize a viewBox,
+ * so you must call ShouldSynthesizeViewBox() if you need to chck that too.
+ *
+ * Note also that this method does not pay attention to whether the width or
+ * height values of the viewBox rect are positive!
+ */
+ bool HasViewBoxRect() const {
+ return GetViewBoxInternal().HasRect();
+ }
+
+ /**
+ * Returns true if we should synthesize a viewBox for ourselves (that is, if
+ * we're the root element in an image document, and we're not currently being
+ * painted for an <svg:image> element).
+ *
+ * Only call this method if HasViewBoxRect() returns false.
+ */
+ bool ShouldSynthesizeViewBox() const;
+
+ bool HasViewBoxOrSyntheticViewBox() const {
+ return HasViewBoxRect() || ShouldSynthesizeViewBox();
+ }
+
+ bool HasChildrenOnlyTransform() const {
+ return mHasChildrenOnlyTransform;
+ }
+
+ void UpdateHasChildrenOnlyTransform();
+
+ enum ChildrenOnlyTransformChangedFlags {
+ eDuringReflow = 1
+ };
+
+ /**
+ * This method notifies the style system that the overflow rects of our
+ * immediate childrens' frames need to be updated. It is called by our own
+ * frame when changes (e.g. to currentScale) cause our children-only
+ * transform to change.
+ *
+ * The reason we have this method instead of overriding
+ * GetAttributeChangeHint is because we need to act on non-attribute (e.g.
+ * currentScale) changes in addition to attribute (e.g. viewBox) changes.
+ */
+ void ChildrenOnlyTransformChanged(uint32_t aFlags = 0);
+
+ gfx::Matrix GetViewBoxTransform() const;
+
+ // WebIDL
+ already_AddRefed<SVGAnimatedRect> ViewBox();
+ already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
+ virtual nsSVGViewBox* GetViewBox() override;
+
+protected:
+
+ // implementation helpers:
+
+ bool IsRoot() const {
+ NS_ASSERTION((IsInUncomposedDoc() && !GetParent()) ==
+ (OwnerDoc() && (OwnerDoc()->GetRootElement() == this)),
+ "Can't determine if we're root");
+ return IsInUncomposedDoc() && !GetParent();
+ }
+
+ /**
+ * Returns true if either this is an SVG <svg> element that is the child of
+ * another non-foreignObject SVG element, or this is a SVG <symbol> element
+ * this is the root of a use-element shadow tree.
+ */
+ bool IsInner() const {
+ const nsIContent *parent = GetFlattenedTreeParent();
+ return parent && parent->IsSVGElement() &&
+ !parent->IsSVGElement(nsGkAtoms::foreignObject);
+ }
+
+ /**
+ * Returns the explicit or default preserveAspectRatio, unless we're
+ * synthesizing a viewBox, in which case it returns the "none" value.
+ */
+ virtual SVGPreserveAspectRatio GetPreserveAspectRatioWithOverride() const {
+ return mPreserveAspectRatio.GetAnimValue();
+ }
+
+ /**
+ * Returns the explicit viewBox rect, if specified, or else a synthesized
+ * viewBox, if appropriate, or else a viewBox matching the dimensions of the
+ * SVG viewport.
+ */
+ nsSVGViewBoxRect GetViewBoxWithSynthesis(
+ float aViewportWidth, float aViewportHeight) const;
+
+ /**
+ * Retrieve the value of currentScale and currentTranslate.
+ */
+ virtual SVGPoint GetCurrentTranslate() const
+ { return SVGPoint(0.0f, 0.0f); }
+ virtual float GetCurrentScale() const
+ { return 1.0f; }
+
+ enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
+ nsSVGLength2 mLengthAttributes[4];
+ static LengthInfo sLengthInfo[4];
+ virtual LengthAttributesInfo GetLengthInfo() override;
+
+ virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() override;
+
+ virtual const nsSVGViewBox& GetViewBoxInternal() const { return mViewBox; }
+ virtual nsSVGAnimatedTransformList* GetTransformInternal() const {
+ return mTransforms;
+ }
+ nsSVGViewBox mViewBox;
+ SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
+
+ // The size of the rectangular SVG viewport into which we render. This is
+ // not (necessarily) the same as the content area. See:
+ //
+ // http://www.w3.org/TR/SVG11/coords.html#ViewportSpace
+ //
+ // XXXjwatt Currently only used for outer <svg>, but maybe we could use -1 to
+ // flag this as an inner <svg> to save the overhead of GetCtx calls?
+ // XXXjwatt our frame should probably reset these when it's destroyed.
+ float mViewportWidth, mViewportHeight;
+
+ bool mHasChildrenOnlyTransform;
+};
+
+} // namespace dom
+
+} // namespace mozilla
+
+#endif // SVGViewportElement_h
--- a/dom/svg/moz.build
+++ b/dom/svg/moz.build
@@ -97,16 +97,17 @@ EXPORTS.mozilla.dom += [
'SVGTextPathElement.h',
'SVGTextPositioningElement.h',
'SVGTitleElement.h',
'SVGTransform.h',
'SVGTransformableElement.h',
'SVGTSpanElement.h',
'SVGUseElement.h',
'SVGViewElement.h',
+ 'SVGViewportElement.h',
]
UNIFIED_SOURCES += [
'DOMSVGAnimatedLengthList.cpp',
'DOMSVGAnimatedNumberList.cpp',
'DOMSVGLength.cpp',
'DOMSVGLengthList.cpp',
'DOMSVGNumber.cpp',
@@ -243,16 +244,17 @@ UNIFIED_SOURCES += [
'SVGTransformableElement.cpp',
'SVGTransformList.cpp',
'SVGTransformListParser.cpp',
'SVGTransformListSMILType.cpp',
'SVGTSpanElement.cpp',
'SVGUseElement.cpp',
'SVGViewBoxSMILType.cpp',
'SVGViewElement.cpp',
+ 'SVGViewportElement.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/dom',
'/dom/base',
--- a/layout/svg/nsSVGInnerSVGFrame.cpp
+++ b/layout/svg/nsSVGInnerSVGFrame.cpp
@@ -8,17 +8,17 @@
// Keep others in (case-insensitive) order:
#include "gfx2DGlue.h"
#include "gfxContext.h"
#include "nsIFrame.h"
#include "nsSVGDisplayableFrame.h"
#include "nsSVGContainerFrame.h"
#include "nsSVGIntegrationUtils.h"
-#include "mozilla/dom/SVGSVGElement.h"
+#include "mozilla/dom/SVGViewportElement.h"
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::gfx;
using namespace mozilla::image;
nsIFrame*
NS_NewSVGInnerSVGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@@ -62,17 +62,17 @@ nsSVGInnerSVGFrame::PaintSVG(gfxContext&
(mState & NS_FRAME_IS_NONDISPLAY),
"If display lists are enabled, only painting of non-display "
"SVG should take this code path");
gfxContextAutoSaveRestore autoSR;
if (StyleDisplay()->IsScrollableOverflow()) {
float x, y, width, height;
- static_cast<SVGSVGElement*>(mContent)->
+ static_cast<SVGViewportElement*>(mContent)->
GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
if (width <= 0 || height <= 0) {
return;
}
autoSR.SetContext(&aContext);
gfxRect clipRect =
@@ -85,17 +85,17 @@ nsSVGInnerSVGFrame::PaintSVG(gfxContext&
}
void
nsSVGInnerSVGFrame::ReflowSVG()
{
// mRect must be set before FinishAndStoreOverflow is called in order
// for our overflow areas to be clipped correctly.
float x, y, width, height;
- static_cast<SVGSVGElement*>(mContent)->
+ static_cast<SVGViewportElement*>(mContent)->
GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
mRect = nsLayoutUtils::RoundGfxRectToAppRect(
gfxRect(x, y, width, height),
PresContext()->AppUnitsPerCSSPixel());
// If we have a filter, we need to invalidate ourselves because filter
// output can change even if none of our descendants need repainting.
if (StyleEffects()->HasFilters()) {
@@ -108,24 +108,24 @@ nsSVGInnerSVGFrame::ReflowSVG()
void
nsSVGInnerSVGFrame::NotifySVGChanged(uint32_t aFlags)
{
MOZ_ASSERT(aFlags & (TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED),
"Invalidation logic may need adjusting");
if (aFlags & COORD_CONTEXT_CHANGED) {
- SVGSVGElement *svg = static_cast<SVGSVGElement*>(mContent);
+ SVGViewportElement *svg = static_cast<SVGViewportElement*>(mContent);
bool xOrYIsPercentage =
- svg->mLengthAttributes[SVGSVGElement::ATTR_X].IsPercentage() ||
- svg->mLengthAttributes[SVGSVGElement::ATTR_Y].IsPercentage();
+ svg->mLengthAttributes[SVGViewportElement::ATTR_X].IsPercentage() ||
+ svg->mLengthAttributes[SVGViewportElement::ATTR_Y].IsPercentage();
bool widthOrHeightIsPercentage =
- svg->mLengthAttributes[SVGSVGElement::ATTR_WIDTH].IsPercentage() ||
- svg->mLengthAttributes[SVGSVGElement::ATTR_HEIGHT].IsPercentage();
+ svg->mLengthAttributes[SVGViewportElement::ATTR_WIDTH].IsPercentage() ||
+ svg->mLengthAttributes[SVGViewportElement::ATTR_HEIGHT].IsPercentage();
if (xOrYIsPercentage || widthOrHeightIsPercentage) {
// Ancestor changes can't affect how we render from the perspective of
// any rendering observers that we may have, so we don't need to
// invalidate them. We also don't need to invalidate ourself, since our
// changed ancestor will have invalidated its entire area, which includes
// our area.
// For perf reasons we call this before calling NotifySVGChanged() below.
@@ -175,17 +175,17 @@ nsSVGInnerSVGFrame::GetBBoxContribution(
if (aFlags & nsSVGUtils::eForGetClientRects) {
// XXXjwatt For consistency with the old code this code includes the
// viewport we establish in the result, but only includes the bounds of our
// descendants if they are not clipped to that viewport. However, this is
// both inconsistent with Chrome and with the specs. See bug 1350755.
// Ideally getClientRects/getBoundingClientRect should be consistent with
// getBBox.
float x, y, w, h;
- static_cast<SVGSVGElement*>(mContent)->
+ static_cast<SVGViewportElement*>(mContent)->
GetAnimatedLengthValues(&x, &y, &w, &h, nullptr);
if (w < 0.0f) w = 0.0f;
if (h < 0.0f) h = 0.0f;
Rect viewport(x, y, w, h);
bbox = aToBBoxUserspace.TransformBounds(viewport);
if (StyleDisplay()->IsScrollableOverflow()) {
return bbox;
}
@@ -204,17 +204,17 @@ nsSVGInnerSVGFrame::GetBBoxContribution(
nsresult
nsSVGInnerSVGFrame::AttributeChanged(int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType)
{
if (aNameSpaceID == kNameSpaceID_None &&
!(GetStateBits() & NS_FRAME_IS_NONDISPLAY)) {
- SVGSVGElement* content = static_cast<SVGSVGElement*>(mContent);
+ SVGViewportElement* content = static_cast<SVGViewportElement*>(mContent);
if (aAttribute == nsGkAtoms::width ||
aAttribute == nsGkAtoms::height) {
nsLayoutUtils::PostRestyleEvent(
mContent->AsElement(), nsRestyleHint(0),
nsChangeHint_InvalidateRenderingObservers);
nsSVGUtils::ScheduleReflowSVG(this);
@@ -308,17 +308,17 @@ nsSVGInnerSVGFrame::NotifyViewportOrTran
gfxMatrix
nsSVGInnerSVGFrame::GetCanvasTM()
{
if (!mCanvasTM) {
NS_ASSERTION(GetParent(), "null parent");
nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(GetParent());
- SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent);
+ SVGViewportElement *content = static_cast<SVGViewportElement*>(mContent);
gfxMatrix tm = content->PrependLocalTransformsTo(parent->GetCanvasTM());
mCanvasTM = new gfxMatrix(tm);
}
return *mCanvasTM;
}