tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SVGFEImageFrame.cpp (4864B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 // Keep in (case-insensitive) order:
      8 #include "mozilla/PresShell.h"
      9 #include "mozilla/SVGObserverUtils.h"
     10 #include "mozilla/dom/SVGFEImageElement.h"
     11 #include "nsContainerFrame.h"
     12 #include "nsGkAtoms.h"
     13 #include "nsIFrame.h"
     14 #include "nsLiteralString.h"
     15 
     16 using namespace mozilla::dom;
     17 
     18 nsIFrame* NS_NewSVGFEImageFrame(mozilla::PresShell* aPresShell,
     19                                mozilla::ComputedStyle* aStyle);
     20 
     21 namespace mozilla {
     22 
     23 class SVGFEImageFrame final : public nsIFrame {
     24  friend nsIFrame* ::NS_NewSVGFEImageFrame(mozilla::PresShell* aPresShell,
     25                                           ComputedStyle* aStyle);
     26 
     27 protected:
     28  explicit SVGFEImageFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
     29      : nsIFrame(aStyle, aPresContext, kClassID) {
     30    AddStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_IS_NONDISPLAY);
     31 
     32    // This frame isn't actually displayed, but it contains an image and we want
     33    // to use the nsImageLoadingContent machinery for managing images, which
     34    // requires visibility tracking, so we enable visibility tracking and
     35    // forcibly mark it visible below.
     36    EnableVisibilityTracking();
     37  }
     38 
     39 public:
     40  NS_DECL_FRAMEARENA_HELPERS(SVGFEImageFrame)
     41 
     42  void Init(nsIContent* aContent, nsContainerFrame* aParent,
     43            nsIFrame* aPrevInFlow) override;
     44  void Destroy(DestroyContext&) override;
     45 
     46 #ifdef DEBUG_FRAME_DUMP
     47  nsresult GetFrameName(nsAString& aResult) const override {
     48    return MakeFrameName(u"SVGFEImage"_ns, aResult);
     49  }
     50 #endif
     51 
     52  nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
     53                            AttrModType aModType) override;
     54 
     55  void OnVisibilityChange(
     56      Visibility aNewVisibility,
     57      const Maybe<OnNonvisible>& aNonvisibleAction = Nothing()) override;
     58 
     59  bool ComputeCustomOverflow(OverflowAreas& aOverflowAreas) override {
     60    // We don't maintain a ink overflow rect
     61    return false;
     62  }
     63 };
     64 
     65 }  // namespace mozilla
     66 
     67 nsIFrame* NS_NewSVGFEImageFrame(mozilla::PresShell* aPresShell,
     68                                mozilla::ComputedStyle* aStyle) {
     69  return new (aPresShell)
     70      mozilla::SVGFEImageFrame(aStyle, aPresShell->GetPresContext());
     71 }
     72 
     73 namespace mozilla {
     74 
     75 NS_IMPL_FRAMEARENA_HELPERS(SVGFEImageFrame)
     76 
     77 /* virtual */
     78 void SVGFEImageFrame::Destroy(DestroyContext& aContext) {
     79  DecApproximateVisibleCount();
     80 
     81  nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
     82  if (imageLoader) {
     83    imageLoader->FrameDestroyed(this);
     84  }
     85 
     86  nsIFrame::Destroy(aContext);
     87 }
     88 
     89 void SVGFEImageFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
     90                           nsIFrame* aPrevInFlow) {
     91  NS_ASSERTION(aContent->IsSVGElement(nsGkAtoms::feImage),
     92               "Trying to construct an SVGFEImageFrame for a "
     93               "content element that doesn't support the right interfaces");
     94 
     95  nsIFrame::Init(aContent, aParent, aPrevInFlow);
     96 
     97  // We assume that feImage's are always visible.
     98  // This call must happen before the FrameCreated. This is because the
     99  // primary frame pointer on our content node isn't set until after this
    100  // function ends, so there is no way for the resulting OnVisibilityChange
    101  // notification to get a frame. FrameCreated has a workaround for this in
    102  // that it passes our frame around so it can be accessed. OnVisibilityChange
    103  // doesn't have that workaround.
    104  IncApproximateVisibleCount();
    105 
    106  nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
    107  if (imageLoader) {
    108    imageLoader->FrameCreated(this);
    109  }
    110 }
    111 
    112 nsresult SVGFEImageFrame::AttributeChanged(int32_t aNameSpaceID,
    113                                           nsAtom* aAttribute,
    114                                           AttrModType aModType) {
    115  SVGFEImageElement* element = static_cast<SVGFEImageElement*>(GetContent());
    116  if (element->AttributeAffectsRendering(aNameSpaceID, aAttribute)) {
    117    MOZ_ASSERT(
    118        GetParent()->IsSVGFilterFrame(),
    119        "Observers observe the filter, so that's what we must invalidate");
    120    SVGObserverUtils::InvalidateRenderingObservers(GetParent());
    121  }
    122 
    123  return nsIFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
    124 }
    125 
    126 void SVGFEImageFrame::OnVisibilityChange(
    127    Visibility aNewVisibility, const Maybe<OnNonvisible>& aNonvisibleAction) {
    128  nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
    129  if (imageLoader) {
    130    imageLoader->OnVisibilityChange(aNewVisibility, aNonvisibleAction);
    131  }
    132 
    133  nsIFrame::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
    134 }
    135 
    136 }  // namespace mozilla