Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/svg/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 11 kB image not shown  

Quelle  SVGImageElement.cpp

  Sprache: C
 

/* 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/SVGImageElement.h"

#include "SVGGeometryProperty.h"
#include "imgINotificationObserver.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/FetchPriority.h"
#include "mozilla/dom/SVGImageElementBinding.h"
#include "mozilla/dom/SVGLengthBinding.h"
#include "mozilla/dom/UserActivation.h"
#include "mozilla/gfx/2D.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
#include "nsIURIWithSizeOf.h"
#include "nsNetUtil.h"

NS_IMPL_NS_NEW_SVG_ELEMENT(Image)

using namespace mozilla::gfx;

namespace mozilla::dom {

JSObject* SVGImageElement::WrapNode(JSContext* aCx,
                                    JS::Handle<JSObject*> aGivenProto) {
  return SVGImageElement_Binding::Wrap(aCx, this, aGivenProto);
}

SVGElement::LengthInfo SVGImageElement::sLengthInfo[4] = {
    {nsGkAtoms::x, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER,
     SVGLength::Axis::X},
    {nsGkAtoms::y, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER,
     SVGLength::Axis::Y},
    {nsGkAtoms::width, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER,
     SVGLength::Axis::X},
    {nsGkAtoms::height, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER,
     SVGLength::Axis::Y},
};

SVGElement::StringInfo SVGImageElement::sStringInfo[2] = {
    {nsGkAtoms::href, kNameSpaceID_None, true},
    {nsGkAtoms::href, kNameSpaceID_XLink, true}};

//----------------------------------------------------------------------
// nsISupports methods

NS_IMPL_ISUPPORTS_INHERITED(SVGImageElement, SVGImageElementBase,
                            imgINotificationObserver, nsIImageLoadingContent)

//----------------------------------------------------------------------
// Implementation

namespace SVGT = SVGGeometryProperty::Tags;

SVGImageElement::SVGImageElement(
    already_AddRefed<mozilla::dom::NodeInfo> aNodeInfo)
    : SVGImageElementBase(std::move(aNodeInfo)) {
  // We start out broken
  AddStatesSilently(ElementState::BROKEN);
}

SVGImageElement::~SVGImageElement() { nsImageLoadingContent::Destroy(); }

NonCustomCSSPropertyId SVGImageElement::GetCSSPropertyIdForAttrEnum(
    uint8_t aAttrEnum) {
  switch (aAttrEnum) {
    case ATTR_X:
      return eCSSProperty_x;
    case ATTR_Y:
      return eCSSProperty_y;
    case ATTR_WIDTH:
      return eCSSProperty_width;
    case ATTR_HEIGHT:
      return eCSSProperty_height;
    default:
      MOZ_ASSERT_UNREACHABLE("Unknown attr enum");
      return eCSSProperty_UNKNOWN;
  }
}
//----------------------------------------------------------------------
// nsINode methods

NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGImageElement)

void SVGImageElement::NodeInfoChanged(Document* aOldDoc) {
  SVGImageElementBase::NodeInfoChanged(aOldDoc);

  // Reparse the URI if needed. Note that we can't check whether we already have
  // a parsed URI, because it might be null even if we have a valid href
  // attribute, if we tried to parse with a different base.
  UpdateSrcURI();

  QueueImageTask(mSrcURI, /* aAlwaysLoad = */ true, /* aNotify = */ false);
}

//----------------------------------------------------------------------

already_AddRefed<DOMSVGAnimatedLength> SVGImageElement::X() {
  return mLengthAttributes[ATTR_X].ToDOMAnimatedLength(this);
}

already_AddRefed<DOMSVGAnimatedLength> SVGImageElement::Y() {
  return mLengthAttributes[ATTR_Y].ToDOMAnimatedLength(this);
}

already_AddRefed<DOMSVGAnimatedLength> SVGImageElement::Width() {
  return mLengthAttributes[ATTR_WIDTH].ToDOMAnimatedLength(this);
}

already_AddRefed<DOMSVGAnimatedLength> SVGImageElement::Height() {
  return mLengthAttributes[ATTR_HEIGHT].ToDOMAnimatedLength(this);
}

already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
SVGImageElement::PreserveAspectRatio() {
  return mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(this);
}

already_AddRefed<DOMSVGAnimatedString> SVGImageElement::Href() {
  return mStringAttributes[HREF].IsExplicitlySet() ||
                 !mStringAttributes[XLINK_HREF].IsExplicitlySet()
             ? mStringAttributes[HREF].ToDOMAnimatedString(this)
             : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
}

void SVGImageElement::GetDecoding(nsAString& aValue) {
  GetEnumAttr(nsGkAtoms::decoding, kDecodingTableDefault->tag, aValue);
}

already_AddRefed<Promise> SVGImageElement::Decode(ErrorResult& aRv) {
  return nsImageLoadingContent::QueueDecodeAsync(aRv);
}

//----------------------------------------------------------------------

void SVGImageElement::UpdateSrcURI() {
  nsAutoString href;
  if (mStringAttributes[HREF].IsExplicitlySet()) {
    mStringAttributes[HREF].GetAnimValue(href, this);
  } else {
    mStringAttributes[XLINK_HREF].GetAnimValue(href, this);
  }

  mSrcURI = nullptr;
  if (!href.IsEmpty()) {
    StringToURI(href, OwnerDoc(), getter_AddRefs(mSrcURI));
  }
}

void SVGImageElement::LoadSelectedImage(bool aAlwaysLoad,
                                        bool aStopLazyLoading) {
  nsresult rv = NS_ERROR_FAILURE;

  const bool kNotify = true;
  if (mSrcURI || (mStringAttributes[HREF].IsExplicitlySet() ||
                  mStringAttributes[XLINK_HREF].IsExplicitlySet())) {
    rv = LoadImage(mSrcURI, /* aForce = */ true, kNotify, eImageLoadType_Normal,
                   LoadFlags(), OwnerDoc());
  }

  if (NS_FAILED(rv)) {
    CancelImageRequests(kNotify);
  }
}

Rect SVGImageElement::GeometryBounds(const Matrix& aToBoundsSpace) {
  Rect rect;

  DebugOnly<bool> ok =
      SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width,
                                      SVGT::Height>(this, &rect.x, &rect.y,
                                                    &rect.width, &rect.height);
  MOZ_ASSERT(ok, "SVGGeometryProperty::ResolveAll failed");

  if (rect.IsEmpty()) {
    // Rendering of the element disabled
    rect.SetEmpty();  // Make sure width/height are zero and not negative
  }

  return aToBoundsSpace.TransformBounds(rect);
}

//----------------------------------------------------------------------
// EventTarget methods:

void SVGImageElement::AsyncEventRunning(AsyncEventDispatcher* aEvent) {
  nsImageLoadingContent::AsyncEventRunning(aEvent);
}

//----------------------------------------------------------------------
//  nsImageLoadingContent methods:

CORSMode SVGImageElement::GetCORSMode() {
  return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
}

void SVGImageElement::GetFetchPriority(nsAString& aFetchPriority) const {
  GetEnumAttr(nsGkAtoms::fetchpriority, kFetchPriorityAttributeValueAuto,
              aFetchPriority);
}

//----------------------------------------------------------------------
// nsIContent methods:

bool SVGImageElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
                                     const nsAString& aValue,
                                     nsIPrincipal* aMaybeScriptedPrincipal,
                                     nsAttrValue& aResult) {
  if (aNamespaceID == kNameSpaceID_None) {
    if (aAttribute == nsGkAtoms::crossorigin) {
      ParseCORSValue(aValue, aResult);
      return true;
    }
    if (aAttribute == nsGkAtoms::decoding) {
      return aResult.ParseEnumValue(aValue, kDecodingTable, false,
                                    kDecodingTableDefault);
    }
    if (aAttribute == nsGkAtoms::fetchpriority) {
      ParseFetchPriority(aValue, aResult);
      return true;
    }
  }

  return SVGImageElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                             aMaybeScriptedPrincipal, aResult);
}

void SVGImageElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
                                   const nsAttrValue* aValue,
                                   const nsAttrValue* aOldValue,
                                   nsIPrincipal* aSubjectPrincipal,
                                   bool aNotify) {
  bool forceReload = false;
  if (aName == nsGkAtoms::href && (aNamespaceID == kNameSpaceID_None ||
                                   aNamespaceID == kNameSpaceID_XLink)) {
    if (aNamespaceID == kNameSpaceID_XLink &&
        mStringAttributes[HREF].IsExplicitlySet()) {
      // href overrides xlink:href
      return;
    }
    UpdateSrcURI();
    forceReload = true;
  } else if (aNamespaceID == kNameSpaceID_None) {
    if (aName == nsGkAtoms::decoding) {
      // Request sync or async image decoding.
      SetSyncDecodingHint(
          aValue && static_cast<ImageDecodingType>(aValue->GetEnumValue()) ==
                        ImageDecodingType::Sync);
    } else if (aName == nsGkAtoms::crossorigin) {
      forceReload = GetCORSMode() != AttrValueToCORSMode(aOldValue);
    }
  }

  if (forceReload) {
    mUseUrgentStartForChannel = UserActivation::IsHandlingUserInput();
    QueueImageTask(mSrcURI, /* aAlwaysLoad = */ true, aNotify);
  }

  return SVGImageElementBase::AfterSetAttr(
      aNamespaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
}

nsresult SVGImageElement::BindToTree(BindContext& aContext, nsINode& aParent) {
  nsresult rv = SVGImageElementBase::BindToTree(aContext, aParent);
  NS_ENSURE_SUCCESS(rv, rv);

  nsImageLoadingContent::BindToTree(aContext, aParent);

  return rv;
}

void SVGImageElement::UnbindFromTree(UnbindContext& aContext) {
  nsImageLoadingContent::UnbindFromTree();
  SVGImageElementBase::UnbindFromTree(aContext);
}

void SVGImageElement::DestroyContent() {
  ClearImageLoadTask();

  nsImageLoadingContent::Destroy();
  SVGImageElementBase::DestroyContent();
}

NS_IMETHODIMP_(bool)
SVGImageElement::IsAttributeMapped(const nsAtom* name) const {
  return IsInLengthInfo(name, sLengthInfo) ||
         SVGImageElementBase::IsAttributeMapped(name);
}

//----------------------------------------------------------------------
// SVGElement methods

/* virtual */
bool SVGImageElement::HasValidDimensions() const {
  float width, height;

  if (SVGGeometryProperty::ResolveAll<SVGT::Width, SVGT::Height>(this, &width,
                                                                 &height)) {
    return width > 0 && height > 0;
  }
  // This function might be called for an element in display:none subtree
  // (e.g. SMIL animateMotion), we fall back to use SVG attributes.
  return (!mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() ||
          mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
         (!mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() ||
          mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0);
}

SVGElement::LengthAttributesInfo SVGImageElement::GetLengthInfo() {
  return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
                              std::size(sLengthInfo));
}

SVGAnimatedPreserveAspectRatio*
SVGImageElement::GetAnimatedPreserveAspectRatio() {
  return &mPreserveAspectRatio;
}

SVGElement::StringAttributesInfo SVGImageElement::GetStringInfo() {
  return StringAttributesInfo(mStringAttributes, sStringInfo,
                              std::size(sStringInfo));
}

void SVGImageElement::DidAnimateAttribute(int32_t aNameSpaceID,
                                          nsAtom* aAttribute) {
  if ((aNameSpaceID == kNameSpaceID_None ||
       aNameSpaceID == kNameSpaceID_XLink) &&
      aAttribute == nsGkAtoms::href) {
    UpdateSrcURI();
    mUseUrgentStartForChannel = false;
    QueueImageTask(mSrcURI, /* aAlwaysLoad = */ true, /* aNotify = */ true);
  }
  SVGImageElementBase::DidAnimateAttribute(aNameSpaceID, aAttribute);
}

void SVGImageElement::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
                                             size_t* aNodeSize) const {
  SVGElement::AddSizeOfExcludingThis(aSizes, aNodeSize);

  // It is okay to include the size of mSrcURI here even though it might have
  // strong references from elsewhere because the URI was created for this
  // object, in nsImageLoadingContent::StringToURI(). Only objects that created
  // their own URI will call nsIURIWithSizeOf::SizeOfIncludingThis().
  if (mSrcURI) {
    *aNodeSize += SizeOfIncludingThisIfURIWithSizeOf(
        mSrcURI, aSizes.mState.mMallocSizeOf);
  }
}

}  // namespace mozilla::dom

Messung V0.5 in Prozent
C=90 H=100 G=95

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-08-24) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.