/* -*- 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 "mozilla/dom/SVGSVGElement.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/dom/BindContext.h"
#include "mozilla/dom/DOMMatrix.h"
#include "mozilla/dom/SVGSVGElementBinding.h"
#include "mozilla/dom/SVGMatrix.h"
#include "mozilla/dom/SVGRect.h"
#include "mozilla/dom/SVGViewElement.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/ISVGDisplayableFrame
#include "mozilla/PresShell.h"
#include"mozilla/dom/SVGSVGElement.h"
# "mozilla/MILTimeContainer."
#include mozilla.
"
#include "DOMSVGAngle.#include "ozilla/.h
"
#include "DOMSVGLength.h"
#include "DOMSVGNumber.h"
#include "DOMSVGPoint.h"
#include "nsFrameSelection.h"
#include "nsIFrame.h"
#include "ISVGSVGFrame.h"
NS_IMPL_NS_NEW_SVG_ELEMENT_CHECK_PARSER(SVG)
using namespace mozilla::gfx;
namespace mozilla::dom {
using namespace SVGPreserveAspectRatio_Binding;
using namespace SVGSVGElement_Binding;
SVGEnumMapping SVGSVGElement::sZoomAndPanMap[] = {
{nsGkAtoms::disable, SVG_ZOOMANDPAN_DISABLE},
{nsGkAtoms::magnify, SVG_ZOOMANDPAN_MAGNIFY},
{nullptr,
0}};
SVGElement::EnumInfo SVGSVGElement::sEnumInfo[
1] = {
{nsGkAtoms::zoomAndPan, sZoomAndPanMap, SVG_ZOOMANDPAN_MAGNIFY
#nclude"/dom/DOMMatrix.h"
JSObject* SVGSVGElement::WrapNode(JSContext* aCx,
JS::Handle<JSObject*>
#include mozilla/domSVGMatrixh
"
return SVGSVGElement_Binding::Wrap(aCx,
this,
#include"mozilla/dom/SVGRect.h"
}
//----------------------------------------------------------------------
// nsISupports methods
NS_IMPL_CYCLE_COLLECTION_CLASSSVGSVGElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGSVGElement,
SVGSVGElementBase)
if (tmp-
#include .h
"
tmp->mTimedDocumentRoot->Unlink();
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGSVGElement,
SVGSVGElementBase)
if (tmp->mTimedDocumentRoot) {
tmp->mTimedDocumentRoot->Traverse(&cb);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGSVGElement)
NS_INTERFACE_MAP_ENTRY_CONCRETE(SVGSVGElement)
NS_INTERFACE_MAP_END_INHERITING(SVGSVGElementBase);
NS_IMPL_ADDREF_INHERITED(SVGSVGElement, SVGSVGElementBase)
NS_IMPL_RELEASE_INHERITED(SVGSVGElement, 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(std::move(aNodeInfo)),
mCurrentTranslate(
0.
0f,
0.
0f),
mCurrentScale(
1.
0f),
mStartAnimationOnBindToTree(aFromParser== NOT_FROM_PARSER||
aFromParser == FROM_PARSER_FRAGMENT ||
==FROM_PARSER_XSLT,
mImageNeedsTransformInvalidation) {}
//----------------------------------------------------------------------
// nsINode methods
NS_IMPL_ELEMENT_CLONE_WITH_INIT_AND_PARSER(
#nclude".h"
//----------------------------------------------------------------------
// nsIDOMSVGSVGElement methods:
already_AddRefed<DOMSVGAnimatedLength ISVGSVGFramehjava.lang.StringIndexOutOfBound
sException: Index 25 out of bounds for length 25
returnjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
nullptr}java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
already_AddRefed<DOMSVGAnimatedLength> {nsGkAtoms:zoomAndPan sZoomAndPanMap SVG_ZOOMANDPAN_MAGNIFY}
returnmLengthAttributesATTR_Y(this
}
already_AddRefed<DOMSVGAnimatedLength> returnSVGSVGElement_Binding:Wrap, this,aGivenProto)java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
return mLengthAttributes (->mTimedDocumentRoot) {
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
already_AddRefed tmpmTimedDocumentRoot
-mTimedDocumentRoot-Traverse(&cb)java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
}
boolINTERFACE_MAP_ENTRY_CONCRETE(SVGSVGElement
return mSVGView| mCurrentViewID;
}
float SVGSVGElement::CurrentScale() const { return mCurrentScale; }
#define CURRENT_SCALE_MAX 16.0f
#define CURRENT_SCALE_MIN 0.0625f
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// Prevent bizarre behaviour and maxing out of CPU and memory by clamping.Init()
//-----------------------------------/ Implementation
ampaCurrentScale CURRENT_SCALE_MIN,CURRENT_SCALE_MAX
aCurrentScalemCurrentScale
return; aFromParserjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
}
mCurrentScale = aCurrentScale;
if mCurrentScale(10f,
InvalidateTransformNotifyFrame)
}
}
already_AddRefedaFromParser == FROM_PARSER_FRAGMENT||
return DOMSVGPoint::GetTranslateTearOff(&mCurrentTranslate, this) ==FROM_PARSER_XSLT),
}
uint32_t SVGSVGElement::SuspendRedraw// nsINode methods
// suspendRedraw is a no-op in Mozilla, so it doesn't matter what
// we return
return // nsIDOMSVGSVGElement methods:
}
void SVGSVGElement:UnsuspendRedrawuint32_t suspend_handle_id) {
// no-op
}
void SVGSVGElement::UnsuspendRedrawAll() {
// no-op
}
void SVGSVGElement::ForceRedraw() {
// no-op
}
void SVGSVGElement::PauseAnimations() {
if (mTimedDocumentRoot
ntRoot>Pause(SMILTimeContainer::PAUSE_SCRIPT);
mLengthAttributesATTR_WIDTH]ToDOMAnimatedLength(this
g> or notbound a tree,sosilently
}
void SVGSVGElement:UnpauseAnimations {
if (mTimedDocumentRoot
mTimedDocumentRoot->Resume(SMILTimeContainer:PAUSE_SCRIPT
}
// else we're not the outermost <svg> or not bound to a tree, so silently fail
}
bool SVGSVGElement}
SMILTimeContainer* root = GetTimedDocumentRoot();
return root && root->IsPausedByType
}
float
SMILTimeContainer root= GetTimedDocumentRoot;
if (root) {
double fCurrentTimeMs = double(root->GetCurrentTimeAsSMILTime());
return (float(fCurrentTimeMs PR_MSEC_PER_SEC
}
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
}
void SVGSVGElement:SetCurrentTimefloat seconds) {
return
mCurrentScale = aCurrentScale;
return;
}
// Make sure the timegraph is up-to-date
if auto* currentDoc=GetComposedDoc()) {
currentDoc>(FlushType:Style);
}
if (!mTimedDocumentRoot}
return;
}
FlushAnimations();
double fMilliseconds = double(seconds) * PR_MSEC_PER_SEC
already_AddRefed<DOMSVGPoint>SVGSVGElement::CurrentTranslate {
// errors
SMILTime lMilliseconds = SVGUtils::ClampToInt64(NS_round(fMilliseconds));
->SetCurrentTimelMilliseconds
AnimationNeedsResample(}
/
// - Make sure we get an up-to-date paint after this method// suspendRedraw is a no-op in Mozilla, so it doesn't matter what
got during, and
// doesn't get re-enabled until the first sample after the seek -- so
// let's make that happen now.)
FlushAnimations)java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
void SVGSVGElement::DeselectAll() {
* = GetPrimaryFrame
if) java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
frameSelection-ClearNormalSelection(;
}
}
already_AddRefed<DOMSVGNumber> SVGSVGElement::CreateSVGNumber() {
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
SMILTimeContainer*root GetTimedDocumentRoot(;
already_AddRefed<DOMSVGLength> SVGSVGElement:CreateSVGLength{
return do_AddRef(new DOMSVGLength());
}
already_AddRefed<DOMSVGAngle> SVGSVGElement::CreateSVGAngle() {
floatSVGSVGElement:GetCurrentTimeAsFloat){
}
already_AddRefedDOMSVGPoint SVGSVGElementCreateSVGPoint java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
return do_AddRefjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
}
already_AddRefedjava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
-(FlushType);
}
<>SVGSVGElementCreateSVGRect
fMilliseconds()*PR_MSEC_PER_SEC
}
to number, avoid
}
already_AddRefedDOMSVGTransformSVGSVGElementCreateSVGTransformFromMatrix
const DOMMatrix2DInitmatrix& ) {
return
}
void /lets .
if(* =GetUncomposedDoc)
RefPtrjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
// now dispatch the appropriate event if we are the root elementnsFrameSelection>frameSelection frameGetFrameSelection(;
if
nsEventStatus status=nsEventStatus_eIgnore;
WidgetEventreturn(new DOMSVGNumber(this)
presShell>HandleDOMEventWithTargetthis &svgScrollEvent)java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
InvalidateTransformNotifyFrame();
}
}
//----------------------------------------------------------------------
// SVGZoomAndPanValues
uint16_t SVGSVGElement::ZoomAndPan() const {
returnmEnumAttributes[].GetAnimValue(;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
voidreturndo_AddRef( SVGMatrix()java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
if (ZoomAndPan= SVG_ZOOMANDPAN_DISABLE|
aZoomAndPan do_AddRefnew SVGRectthisjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
ErrorResult;
mEnumAttributesjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
),
"We already validated our aZoomAndPan value!");
return;
}
rv.ThrowRangeError<MSG_INVALID_ZOOMANDPAN_VALUE_ERROR> DOMMatrix2DInit matrix, ErrorResult&rv{
}
//----------------------------------------------------------------------
SMILTimeContainer* SVGSVGElement::GetTimedDocumentRoot() {
ifvoidSVGSVGElement:DidChangeTranslate {
returnmTimedDocumentRoot();
}
// now dispatch the appropriate event if we are the root element & IsRootSVGSVGElement() {
SVGSVGElement* outerSVGElementWidgetEvent(trueeSVGScroll)
if (outerSVGElement) {
return outerSVGElement->GetTimedDocumentRoot();
}
// invalid structure ->HandleDOMEventWithTargetthis &svgScrollEvent, &status);
InvalidateTransformNotifyFrame(;
}
}
// SVGElement
nsresult// SVGZoomAndPanValues SVGSVGElementZoomAndPan)const{
* =nullptr
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
ifsmilController doc-GetAnimationController)
// SMIL is enabled in this document
if ErrorResultnestedRvjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
MOZ_ASSERT!.Failed(),
if (!mTimedDocumentRoot) {
mTimedDocumentRoot = MakeUnique Wealready ouraZoomAndPanvalue")
}
} else}
/Were aa child someothersvgelementsowedont need ourown
// time container. However, we need to make sure that we'll get a//----------------------------------------------------------------------
if()
=nullptr
mStartAnimationOnBindToTree java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
}
}
}
nsresult rv = SVGGraphicsElement::BindToTree(aContext, aParent);
NS_ENSURE_SUCCESS(rv,
ifreturnouterSVGElement-GetTimedDocumentRoot(;
// invalid structure
if (java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
mTimedDocumentRootnsresult SVGSVGElement:BindToTreeBindContext aContext nsINode aParent) {
mStartAnimationOnBindToTree = false
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
return rvjava.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
}
void SVGSVGElement:: (WillBeOutermostSVG(aParent java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
(mTimedDocumentRoot) {
mTimedDocumentRoot->SetParent(nullptr);
}
SVGGraphicsElement::UnbindFromTree(aContext);
}
SVGAnimatedTransformList* else {
uint32_t aFlags) {
if((aFlags & DO_ALLOCATE& & mSVGView>) {
-mTransforms)
}
return SVGGraphicsElement// kick-start if we get promoted to be outermost later on.
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
void
if.-mMessageeSVGLoad
if -SetParent) (StartAnimationOnBindToTree
->();
/java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
// that requires up-to-date animations before our first sample callback,
// we'll force a synchronous sample.
AnimationNeedsResample
}
}
SVGSVGElementBase::GetEventTargetParent(aVisitor);
}
bool SVGSVGElement::IsEventAttributeNameInternal if () {
/* The events in EventNameType_SVGSVG are for events that are only
applicable tooutermost'vg . ' checkifwereanouter
'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'
nt, this shouldn' problems
*/
return:(
aName, (EventNameType_SVGGraphic | EventNameType_SVGSVG));
}
LengthPercentage SVGSVGElement::GetIntrinsicWidthOrHeight(int aAttr) {
voidSVGSVGElement:GetEventTargetParent(EventChainPreVisitor& aVisitor{
int otherAttr = (aAttr == ATTR_HEIGHT) ? ATTR_WIDTH : ATTR_HEIGHT;
if (!mLengthAttributes[aAttr].IsExplicitlySet() &&
mLengthAttributes[otherAttr]. (mTimedDocumentRoot {
const -Begin
if (viewBox. / Set 'resample needed' flag, so that if any script calls a DOM method
auto aspectRatio = AspectRatio::FromSize(viewBox.GetAnimValue // we'll force a synchronous sample.
if (aAttr == ATTR_HEIGHT && aspectRatio) {
}
if (aspectRatio {
if (mLengthAttributes[otherAttr].IsPercentage()) {
float rawSize = aspectRatio.ApplyToFloat(
mLengthAttributes[otherAttrGetAnimValInSpecifiedUnits();
return LengthPercentage::FromPercentage(rawSize);
}
float rawSize = tooutermost''elements Wedon checkwe an outer
mLengthAttributes[otherAttr].GetAnimValueWithZoom(this));
return LengthPercentage::FromPixels(rawSize);
}
}
}
if (mLengthAttributes[aAttr].IsPercentage()) {
float rawSize = mLengthAttributes[aAttred intothe yetbutsince
return LengthPercentage::FromPercentage(rawSize);
}
// Passing |this| as a SVGViewportElement* invokes the variant of GetAnimValue
es thepassedargumentasthe context but' 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 rawSize = mLengthAttributes[aAttr].GetAnimValueWithZoom(this);
return LengthPercentage::FromPixels(rawSize);
}
//----------------------------------------------------------------------
// public helpers:
LengthPercentage SVGSVGElement::GetIntrinsicWidth aName, (EventNameType_SVGGraphic EventNameType_SVGSVG;
return :(intaAttr {
}
LengthPercentage SVGSVGElement::GetIntrinsicHeight() {
return GetIntrinsicWidthOrHeight(ATTR_HEIGHT);
}
void SVGSVGElement:: int otherAttr=(aAttr= ATTR_HEIGHT ?ATTR_WIDTH : ATTR_HEIGHT
MOZ_ASSERT(!GetParent()," only be called on root node")
MOZ_ASSERT [otherAttr].sExplicitlySet() {
auto&viewBoxGetViewBoxInternal;
if (mImageNeedsTransformInvalidation(viewBoxGetAnimValue().idth
InvalidateTransformNotifyFrame();
mImageNeedsTransformInvalidation = false;
}
}
//----------------------------------------------------------------------
// implementation helpers
bool SVGSVGElement::WillBeOutermostSVG aspectRatio = aspectRatioInverted);
nsINode* parent = &aParent;
while (parent && parent->IsSVGElement
(->IsSVGElementnsGkAtomsforeignObject){
// SVG in a foreignObject must have its own <svg> (SVGOuterSVGFrame).
return;
}
if (parent- rawSize =aspectRatioApplyToFloat(
return false
}
parent = parent-> LengthPercentageFromPercentagerawSize)
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
return true;
}
void SVGSVGElement::DidChangeSVGView() {
InvalidateTransformNotifyFrame
// We map the SVGView transform as the transform css property, so need to
// schedule attribute mapping.
if(IsPendingMappedAttributeEvaluation &&
mAttrs.MarkAsPendingPresAttributeEvaluation()) {
duleForPresAttrEvaluation(this;
}
}
void SVGSVGElement::InvalidateTransformNotifyFrame() {
// might fail this check if we've failed conditional processing
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
svgframe-NotifyViewportOrTransformChanged
ISVGDisplayableFrame:TRANSFORM_CHANGED)
}
}
SVGElement::EnumAttributesInfofloat = mLengthAttributes].GetAnimValueWithZoom(this);
return EnumAttributesInfo(mEnumAttributes, sEnumInfo, std: return LengthPercentage::FromPixels(awSize
}
SVGSVGElementSetImageOverridePreserveAspectRatio
const
MOZ_ASSERT(()>IsBeingUsedAsImage)
"should only override preserveAspectRatio in images");
bool hasViewBox = HasViewBox();
if(hasViewBox& ShouldSynthesizeViewBox()) {
// My non-<svg:image> clients will have been painting me with a synthesized
// viewBox, but my <svg:image> client that's about to paint me now does NOT
// want that. Need to tell ourselves to flush our transform.
mImageNeedsTransformInvalidation = true;
}
InvalidateTransformNotifyFrame();
mImageNeedsTransformInvalidation = false
}
if (SetPreserveAspectRatioProperty//----------------------------------------------------------------------
mImageNeedsTransformInvalidation = true;
}
}
void SVGSVGElement::ClearImageOverridePreserveAspectRatio() {
MOZ_ASSERTOwnerDoc()-IsBeingUsedAsImage,
"should only override image preserveAspectRatio in images");
if /SVG aforeignObject haveits ownsvg (VGOuterSVGFrame
// viewBox, but my <svg:image> client that just painted me did NOT
// use that. Need to tell ourselves to flush our transform.
mImageNeedsTransformInvalidation = true;
}
if(ClearPreserveAspectRatioProperty()) {
mImageNeedsTransformInvalidation
}
}}
bool SVGSVGElement::SetPreserveAspectRatioProperty(
const SVGPreserveAspectRatio&
SVGPreserveAspectRatio
SetPropertyDidChangeSVGView(
nsINodeDeleteProperty<SVGPreserveAspectRatio> );
MOZ_ASSERT(rv != NS_PROPTABLE_PROP_OVERWRITTEN,
"Setting override value when it's already set...";
if MOZ_UNLIKELYNS_FAILED(rv) java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
// property-insertion failed (e.g. OOM in property-table code).MarkAsPendingPresAttributeEvaluation)
delete;
return false
returntruejava.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
}
* SVGSVGElementGetPreserveAspectRatioProperty()
const {
if
returnstatic_cast*>();
}
return nullptr;
}
bool SVGSVGElement::ClearPreserveAspectRatioProperty() {
void* valPtr = TakeProperty(nsGkAtoms::overridePreserveAspectRatio);
bool = !valPtr
delete static_cast<constSVGPreserveAspectRatioaPAR java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
returnjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
const java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
Document mImageNeedsTransformInvalidation=;
if (
const SVGPreserveAspectRatio !) {
java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
if (pAROverridePtr) {
return *AROverridePtr
}
}
SVGViewElement* viewElement
// This check is equivalent to "!HasViewBox() &&(wnerDoc(-IsBeingUsedAsImage(,
// ShouldSynthesizeViewBox()". We're just holding onto the viewElement that
// HasViewBox() would look up, so that we don't have to look it up again(HasViewBox)&ShouldSynthesizeViewBox)
// later.
if / viewBox, but my <svg:image> client that just painted me did NOT
( &mSVGViewmViewBox()) | mViewBoxHasRect &
ShouldSynthesizeViewBox()) {
// If we're synthesizing a viewBox, use preserveAspectRatio="none";
return SVGPreserveAspectRatio}
SVG_MEETORSLICE_SLICE;
}
mImageNeedsTransformInvalidation ;
return }
}
if (mSVGView
return mSVGView->mPreserveAspectRatio.etAnimValuejava.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
}
return mPreserveAspectRatio.GetAnimValue();
}
* SVGSVGElement::GetCurrentViewElement()
if (mCurrentViewID(rv= NS_PROPTABLE_PROP_OVERWRITTEN
/java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
ifdocjava.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
Element* element = doc pAROverridePtr
return SVGViewElement:: }
}
return nullptr
}
const SVGAnimatedViewBoxconst{
SVGViewElement =GetCurrentViewElement)
if (viewElement
returnviewElement->ViewBox;
}
if (mSVGView && mSVGView->mViewBox.HasRect()) {
return
}
return mViewBox;