LCOV - code coverage report
Current view: top level - layout/svg - nsSVGImageFrame.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 235 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 23 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "nsSVGImageFrame.h"
       7             : 
       8             : // Keep in (case-insensitive) order:
       9             : #include "gfxContext.h"
      10             : #include "gfxPlatform.h"
      11             : #include "mozilla/gfx/2D.h"
      12             : #include "imgIContainer.h"
      13             : #include "nsContainerFrame.h"
      14             : #include "nsIDOMMutationEvent.h"
      15             : #include "nsIImageLoadingContent.h"
      16             : #include "nsLayoutUtils.h"
      17             : #include "imgINotificationObserver.h"
      18             : #include "nsSVGEffects.h"
      19             : #include "mozilla/dom/SVGSVGElement.h"
      20             : #include "nsSVGUtils.h"
      21             : #include "SVGContentUtils.h"
      22             : #include "SVGGeometryFrame.h"
      23             : #include "SVGImageContext.h"
      24             : #include "mozilla/dom/SVGImageElement.h"
      25             : #include "nsContentUtils.h"
      26             : #include "nsIReflowCallback.h"
      27             : #include "mozilla/Unused.h"
      28             : 
      29             : using namespace mozilla;
      30             : using namespace mozilla::dom;
      31             : using namespace mozilla::gfx;
      32             : using namespace mozilla::image;
      33             : 
      34             : // ---------------------------------------------------------------------
      35             : // nsQueryFrame methods
      36           0 : NS_QUERYFRAME_HEAD(nsSVGImageFrame)
      37           0 :   NS_QUERYFRAME_ENTRY(nsSVGImageFrame)
      38           0 : NS_QUERYFRAME_TAIL_INHERITING(SVGGeometryFrame)
      39             : 
      40             : nsIFrame*
      41           0 : NS_NewSVGImageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
      42             : {
      43           0 :   return new (aPresShell) nsSVGImageFrame(aContext);
      44             : }
      45             : 
      46           0 : NS_IMPL_FRAMEARENA_HELPERS(nsSVGImageFrame)
      47             : 
      48           0 : nsSVGImageFrame::~nsSVGImageFrame()
      49             : {
      50             :   // set the frame to null so we don't send messages to a dead object.
      51           0 :   if (mListener) {
      52           0 :     nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
      53           0 :     if (imageLoader) {
      54           0 :       imageLoader->RemoveObserver(mListener);
      55             :     }
      56           0 :     reinterpret_cast<nsSVGImageListener*>(mListener.get())->SetFrame(nullptr);
      57             :   }
      58           0 :   mListener = nullptr;
      59           0 : }
      60             : 
      61             : void
      62           0 : nsSVGImageFrame::Init(nsIContent*       aContent,
      63             :                       nsContainerFrame* aParent,
      64             :                       nsIFrame*         aPrevInFlow)
      65             : {
      66           0 :   NS_ASSERTION(aContent->IsSVGElement(nsGkAtoms::image),
      67             :                "Content is not an SVG image!");
      68             : 
      69           0 :   SVGGeometryFrame::Init(aContent, aParent, aPrevInFlow);
      70             : 
      71           0 :   if (GetStateBits() & NS_FRAME_IS_NONDISPLAY) {
      72             :     // Non-display frames are likely to be patterns, masks or the like.
      73             :     // Treat them as always visible.
      74             :     // This call must happen before the FrameCreated. This is because the
      75             :     // primary frame pointer on our content node isn't set until after this
      76             :     // function ends, so there is no way for the resulting OnVisibilityChange
      77             :     // notification to get a frame. FrameCreated has a workaround for this in
      78             :     // that it passes our frame around so it can be accessed. OnVisibilityChange
      79             :     // doesn't have that workaround.
      80           0 :     IncApproximateVisibleCount();
      81             :   }
      82             : 
      83           0 :   mListener = new nsSVGImageListener(this);
      84           0 :   nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
      85           0 :   if (!imageLoader) {
      86           0 :     MOZ_CRASH("Why is this not an image loading content?");
      87             :   }
      88             : 
      89             :   // We should have a PresContext now, so let's notify our image loader that
      90             :   // we need to register any image animations with the refresh driver.
      91           0 :   imageLoader->FrameCreated(this);
      92             : 
      93           0 :   imageLoader->AddObserver(mListener);
      94           0 : }
      95             : 
      96             : /* virtual */ void
      97           0 : nsSVGImageFrame::DestroyFrom(nsIFrame* aDestructRoot)
      98             : {
      99           0 :   if (GetStateBits() & NS_FRAME_IS_NONDISPLAY) {
     100           0 :     DecApproximateVisibleCount();
     101             :   }
     102             : 
     103           0 :   if (mReflowCallbackPosted) {
     104           0 :     PresContext()->PresShell()->CancelReflowCallback(this);
     105           0 :     mReflowCallbackPosted = false;
     106             :   }
     107             : 
     108             :   nsCOMPtr<nsIImageLoadingContent> imageLoader =
     109           0 :     do_QueryInterface(nsFrame::mContent);
     110             : 
     111           0 :   if (imageLoader) {
     112           0 :     imageLoader->FrameDestroyed(this);
     113             :   }
     114             : 
     115           0 :   nsFrame::DestroyFrom(aDestructRoot);
     116           0 : }
     117             : 
     118             : //----------------------------------------------------------------------
     119             : // nsIFrame methods:
     120             : 
     121             : nsresult
     122           0 : nsSVGImageFrame::AttributeChanged(int32_t         aNameSpaceID,
     123             :                                   nsIAtom*        aAttribute,
     124             :                                   int32_t         aModType)
     125             : {
     126           0 :   if (aNameSpaceID == kNameSpaceID_None) {
     127           0 :     if (aAttribute == nsGkAtoms::x ||
     128           0 :         aAttribute == nsGkAtoms::y ||
     129           0 :         aAttribute == nsGkAtoms::width ||
     130           0 :         aAttribute == nsGkAtoms::height) {
     131           0 :       nsLayoutUtils::PostRestyleEvent(
     132           0 :         mContent->AsElement(), nsRestyleHint(0),
     133           0 :         nsChangeHint_InvalidateRenderingObservers);
     134           0 :       nsSVGUtils::ScheduleReflowSVG(this);
     135           0 :       return NS_OK;
     136             :     }
     137           0 :     else if (aAttribute == nsGkAtoms::preserveAspectRatio) {
     138             :       // We don't paint the content of the image using display lists, therefore
     139             :       // we have to invalidate for this children-only transform changes since
     140             :       // there is no layer tree to notice that the transform changed and
     141             :       // recomposite.
     142           0 :       InvalidateFrame();
     143           0 :       return NS_OK;
     144             :     }
     145             :   }
     146             : 
     147             :   // Currently our SMIL implementation does not modify the DOM attributes. Once
     148             :   // we implement the SVG 2 SMIL behaviour this can be removed
     149             :   // SVGImageElement::AfterSetAttr's implementation will be sufficient.
     150           0 :   if (aModType == nsIDOMMutationEvent::SMIL &&
     151           0 :       aAttribute == nsGkAtoms::href &&
     152           0 :       (aNameSpaceID == kNameSpaceID_XLink ||
     153             :        aNameSpaceID == kNameSpaceID_None)) {
     154           0 :     SVGImageElement* element = static_cast<SVGImageElement*>(mContent);
     155             : 
     156             :     bool hrefIsSet =
     157           0 :       element->mStringAttributes[SVGImageElement::HREF].IsExplicitlySet() ||
     158           0 :       element->mStringAttributes[SVGImageElement::XLINK_HREF].IsExplicitlySet();
     159           0 :     if (hrefIsSet) {
     160           0 :       element->LoadSVGImage(true, true);
     161             :     } else {
     162           0 :       element->CancelImageRequests(true);
     163             :     }
     164             :   }
     165             : 
     166           0 :   return SVGGeometryFrame::AttributeChanged(aNameSpaceID,
     167           0 :                                             aAttribute, aModType);
     168             : }
     169             : 
     170             : void
     171           0 : nsSVGImageFrame::OnVisibilityChange(Visibility aNewVisibility,
     172             :                                     const Maybe<OnNonvisible>& aNonvisibleAction)
     173             : {
     174           0 :   nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
     175           0 :   if (!imageLoader) {
     176           0 :     SVGGeometryFrame::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
     177           0 :     return;
     178             :   }
     179             : 
     180           0 :   imageLoader->OnVisibilityChange(aNewVisibility, aNonvisibleAction);
     181             : 
     182           0 :   SVGGeometryFrame::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
     183             : }
     184             : 
     185             : gfx::Matrix
     186           0 : nsSVGImageFrame::GetRasterImageTransform(int32_t aNativeWidth,
     187             :                                          int32_t aNativeHeight)
     188             : {
     189             :   float x, y, width, height;
     190           0 :   SVGImageElement *element = static_cast<SVGImageElement*>(mContent);
     191           0 :   element->GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
     192             : 
     193             :   Matrix viewBoxTM =
     194             :     SVGContentUtils::GetViewBoxTransform(width, height,
     195             :                                          0, 0, aNativeWidth, aNativeHeight,
     196           0 :                                          element->mPreserveAspectRatio);
     197             : 
     198           0 :   return viewBoxTM * gfx::Matrix::Translation(x, y);
     199             : }
     200             : 
     201             : gfx::Matrix
     202           0 : nsSVGImageFrame::GetVectorImageTransform()
     203             : {
     204             :   float x, y, width, height;
     205           0 :   SVGImageElement *element = static_cast<SVGImageElement*>(mContent);
     206           0 :   element->GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
     207             : 
     208             :   // No viewBoxTM needed here -- our height/width overrides any concept of
     209             :   // "native size" that the SVG image has, and it will handle viewBox and
     210             :   // preserveAspectRatio on its own once we give it a region to draw into.
     211             : 
     212           0 :   return gfx::Matrix::Translation(x, y);
     213             : }
     214             : 
     215             : bool
     216           0 : nsSVGImageFrame::TransformContextForPainting(gfxContext* aGfxContext,
     217             :                                              const gfxMatrix& aTransform)
     218             : {
     219           0 :   gfx::Matrix imageTransform;
     220           0 :   if (mImageContainer->GetType() == imgIContainer::TYPE_VECTOR) {
     221           0 :     imageTransform = GetVectorImageTransform() * ToMatrix(aTransform);
     222             :   } else {
     223             :     int32_t nativeWidth, nativeHeight;
     224           0 :     if (NS_FAILED(mImageContainer->GetWidth(&nativeWidth)) ||
     225           0 :         NS_FAILED(mImageContainer->GetHeight(&nativeHeight)) ||
     226           0 :         nativeWidth == 0 || nativeHeight == 0) {
     227           0 :       return false;
     228             :     }
     229             :     imageTransform =
     230           0 :       GetRasterImageTransform(nativeWidth, nativeHeight) * ToMatrix(aTransform);
     231             : 
     232             :     // NOTE: We need to cancel out the effects of Full-Page-Zoom, or else
     233             :     // it'll get applied an extra time by DrawSingleUnscaledImage.
     234           0 :     nscoord appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel();
     235             :     gfxFloat pageZoomFactor =
     236           0 :       nsPresContext::AppUnitsToFloatCSSPixels(appUnitsPerDevPx);
     237           0 :     imageTransform.PreScale(pageZoomFactor, pageZoomFactor);
     238             :   }
     239             : 
     240           0 :   if (imageTransform.IsSingular()) {
     241           0 :     return false;
     242             :   }
     243             : 
     244           0 :   aGfxContext->Multiply(ThebesMatrix(imageTransform));
     245           0 :   return true;
     246             : }
     247             : 
     248             : //----------------------------------------------------------------------
     249             : // nsSVGDisplayableFrame methods:
     250             : void
     251           0 : nsSVGImageFrame::PaintSVG(gfxContext& aContext,
     252             :                           const gfxMatrix& aTransform,
     253             :                           imgDrawingParams& aImgParams,
     254             :                           const nsIntRect *aDirtyRect)
     255             : {
     256           0 :   if (!StyleVisibility()->IsVisible()) {
     257           0 :     return;
     258             :   }
     259             : 
     260             :   float x, y, width, height;
     261           0 :   SVGImageElement *imgElem = static_cast<SVGImageElement*>(mContent);
     262           0 :   imgElem->GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
     263           0 :   NS_ASSERTION(width > 0 && height > 0,
     264             :                "Should only be painting things with valid width/height");
     265             : 
     266           0 :   if (!mImageContainer) {
     267           0 :     nsCOMPtr<imgIRequest> currentRequest;
     268           0 :     nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
     269           0 :     if (imageLoader)
     270           0 :       imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
     271           0 :                               getter_AddRefs(currentRequest));
     272             : 
     273           0 :     if (currentRequest)
     274           0 :       currentRequest->GetImage(getter_AddRefs(mImageContainer));
     275             :   }
     276             : 
     277           0 :   if (mImageContainer) {
     278           0 :     gfxContextAutoSaveRestore autoRestorer(&aContext);
     279             : 
     280           0 :     if (StyleDisplay()->IsScrollableOverflow()) {
     281             :       gfxRect clipRect = nsSVGUtils::GetClipRectForFrame(this, x, y,
     282           0 :                                                          width, height);
     283           0 :       nsSVGUtils::SetClipRect(&aContext, aTransform, clipRect);
     284             :     }
     285             : 
     286           0 :     if (!TransformContextForPainting(&aContext, aTransform)) {
     287           0 :       return ;
     288             :     }
     289             : 
     290             :     // fill-opacity doesn't affect <image>, so if we're allowed to
     291             :     // optimize group opacity, the opacity used for compositing the
     292             :     // image into the current canvas is just the group opacity.
     293           0 :     float opacity = 1.0f;
     294           0 :     if (nsSVGUtils::CanOptimizeOpacity(this)) {
     295           0 :       opacity = StyleEffects()->mOpacity;
     296             :     }
     297             : 
     298           0 :     if (opacity != 1.0f || StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
     299           0 :       aContext.PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity);
     300             :     }
     301             : 
     302           0 :     nscoord appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel();
     303           0 :     nsRect dirtyRect; // only used if aDirtyRect is non-null
     304           0 :     if (aDirtyRect) {
     305           0 :       NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
     306             :                    (mState & NS_FRAME_IS_NONDISPLAY),
     307             :                    "Display lists handle dirty rect intersection test");
     308           0 :       dirtyRect = ToAppUnits(*aDirtyRect, appUnitsPerDevPx);
     309             :       // Adjust dirtyRect to match our local coordinate system.
     310             :       nsRect rootRect =
     311             :         nsSVGUtils::TransformFrameRectToOuterSVG(mRect, aTransform,
     312           0 :                                                  PresContext());
     313           0 :       dirtyRect.MoveBy(-rootRect.TopLeft());
     314             :     }
     315             : 
     316           0 :     uint32_t flags = aImgParams.imageFlags;
     317           0 :     if (mForceSyncDecoding) {
     318           0 :       flags |= imgIContainer::FLAG_SYNC_DECODE;
     319             :     }
     320             : 
     321           0 :     if (mImageContainer->GetType() == imgIContainer::TYPE_VECTOR) {
     322             :       // Package up the attributes of this image element which can override the
     323             :       // attributes of mImageContainer's internal SVG document.  The 'width' &
     324             :       // 'height' values we're passing in here are in CSS units (though they
     325             :       // come from width/height *attributes* in SVG). They influence the region
     326             :       // of the SVG image's internal document that is visible, in combination
     327             :       // with preserveAspectRatio and viewBox.
     328             :       const Maybe<SVGImageContext> context(
     329           0 :         Some(SVGImageContext(Some(CSSIntSize::Truncate(width, height)),
     330           0 :                              Some(imgElem->mPreserveAspectRatio.GetAnimValue()))));
     331             : 
     332             :       // For the actual draw operation to draw crisply (and at the right size),
     333             :       // our destination rect needs to be |width|x|height|, *in dev pixels*.
     334           0 :       LayoutDeviceSize devPxSize(width, height);
     335           0 :       nsRect destRect(nsPoint(),
     336           0 :                       LayoutDevicePixel::ToAppUnits(devPxSize,
     337           0 :                                                     appUnitsPerDevPx));
     338             : 
     339             :       // Note: Can't use DrawSingleUnscaledImage for the TYPE_VECTOR case.
     340             :       // That method needs our image to have a fixed native width & height,
     341             :       // and that's not always true for TYPE_VECTOR images.
     342             :       aImgParams.result &= nsLayoutUtils::DrawSingleImage(
     343             :         aContext,
     344             :         PresContext(),
     345             :         mImageContainer,
     346             :         nsLayoutUtils::GetSamplingFilterForFrame(this),
     347             :         destRect,
     348             :         aDirtyRect ? dirtyRect : destRect,
     349             :         context,
     350           0 :         flags);
     351             :     } else { // mImageContainer->GetType() == TYPE_RASTER
     352             :       aImgParams.result &= nsLayoutUtils::DrawSingleUnscaledImage(
     353             :         aContext,
     354             :         PresContext(),
     355             :         mImageContainer,
     356             :         nsLayoutUtils::GetSamplingFilterForFrame(this),
     357           0 :         nsPoint(0, 0),
     358             :         aDirtyRect ? &dirtyRect : nullptr,
     359           0 :         flags);
     360             :     }
     361             : 
     362           0 :     if (opacity != 1.0f || StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
     363           0 :       aContext.PopGroupAndBlend();
     364             :     }
     365             :     // gfxContextAutoSaveRestore goes out of scope & cleans up our gfxContext
     366             :   }
     367             : }
     368             : 
     369             : nsIFrame*
     370           0 : nsSVGImageFrame::GetFrameForPoint(const gfxPoint& aPoint)
     371             : {
     372           0 :   if (!(GetStateBits() & NS_STATE_SVG_CLIPPATH_CHILD) && !GetHitTestFlags()) {
     373           0 :     return nullptr;
     374             :   }
     375             : 
     376           0 :   Rect rect;
     377           0 :   SVGImageElement *element = static_cast<SVGImageElement*>(mContent);
     378           0 :   element->GetAnimatedLengthValues(&rect.x, &rect.y,
     379           0 :                                    &rect.width, &rect.height, nullptr);
     380             : 
     381           0 :   if (!rect.Contains(ToPoint(aPoint))) {
     382           0 :     return nullptr;
     383             :   }
     384             : 
     385             :   // Special case for raster images -- we only want to accept points that fall
     386             :   // in the underlying image's (scaled to fit) native bounds.  That region
     387             :   // doesn't necessarily map to our <image> element's [x,y,width,height] if the
     388             :   // raster image's aspect ratio is being preserved.  We have to look up the
     389             :   // native image size & our viewBox transform in order to filter out points
     390             :   // that fall outside that area.  (This special case doesn't apply to vector
     391             :   // images because they don't limit their drawing to explicit "native
     392             :   // bounds" -- they have an infinite canvas on which to place content.)
     393           0 :   if (StyleDisplay()->IsScrollableOverflow() && mImageContainer) {
     394           0 :     if (mImageContainer->GetType() == imgIContainer::TYPE_RASTER) {
     395             :       int32_t nativeWidth, nativeHeight;
     396           0 :       if (NS_FAILED(mImageContainer->GetWidth(&nativeWidth)) ||
     397           0 :           NS_FAILED(mImageContainer->GetHeight(&nativeHeight)) ||
     398           0 :           nativeWidth == 0 || nativeHeight == 0) {
     399           0 :         return nullptr;
     400             :       }
     401             :       Matrix viewBoxTM =
     402             :         SVGContentUtils::GetViewBoxTransform(rect.width, rect.height,
     403             :                                              0, 0, nativeWidth, nativeHeight,
     404           0 :                                              element->mPreserveAspectRatio);
     405           0 :       if (!nsSVGUtils::HitTestRect(viewBoxTM,
     406             :                                    0, 0, nativeWidth, nativeHeight,
     407           0 :                                    aPoint.x - rect.x, aPoint.y - rect.y)) {
     408           0 :         return nullptr;
     409             :       }
     410             :     }
     411             :   }
     412             : 
     413           0 :   return this;
     414             : }
     415             : 
     416             : //----------------------------------------------------------------------
     417             : // SVGGeometryFrame methods:
     418             : 
     419             : // Lie about our fill/stroke so that covered region and hit detection work properly
     420             : 
     421             : void
     422           0 : nsSVGImageFrame::ReflowSVG()
     423             : {
     424           0 :   NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingReflowSVG(this),
     425             :                "This call is probably a wasteful mistake");
     426             : 
     427           0 :   MOZ_ASSERT(!(GetStateBits() & NS_FRAME_IS_NONDISPLAY),
     428             :              "ReflowSVG mechanism not designed for this");
     429             : 
     430           0 :   if (!nsSVGUtils::NeedsReflowSVG(this)) {
     431           0 :     return;
     432             :   }
     433             : 
     434             :   float x, y, width, height;
     435           0 :   SVGImageElement *element = static_cast<SVGImageElement*>(mContent);
     436           0 :   element->GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
     437             : 
     438           0 :   Rect extent(x, y, width, height);
     439             : 
     440           0 :   if (!extent.IsEmpty()) {
     441           0 :     mRect = nsLayoutUtils::RoundGfxRectToAppRect(extent,
     442           0 :               PresContext()->AppUnitsPerCSSPixel());
     443             :   } else {
     444           0 :     mRect.SetEmpty();
     445             :   }
     446             : 
     447           0 :   if (mState & NS_FRAME_FIRST_REFLOW) {
     448             :     // Make sure we have our filter property (if any) before calling
     449             :     // FinishAndStoreOverflow (subsequent filter changes are handled off
     450             :     // nsChangeHint_UpdateEffects):
     451           0 :     nsSVGEffects::UpdateEffects(this);
     452             : 
     453           0 :     if (!mReflowCallbackPosted) {
     454           0 :       nsIPresShell* shell = PresContext()->PresShell();
     455           0 :       mReflowCallbackPosted = true;
     456           0 :       shell->PostReflowCallback(this);
     457             :     }
     458             :   }
     459             : 
     460           0 :   nsRect overflow = nsRect(nsPoint(0,0), mRect.Size());
     461           0 :   nsOverflowAreas overflowAreas(overflow, overflow);
     462           0 :   FinishAndStoreOverflow(overflowAreas, mRect.Size());
     463             : 
     464             :   mState &= ~(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY |
     465           0 :               NS_FRAME_HAS_DIRTY_CHILDREN);
     466             : 
     467             :   // Invalidate, but only if this is not our first reflow (since if it is our
     468             :   // first reflow then we haven't had our first paint yet).
     469           0 :   if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
     470           0 :     InvalidateFrame();
     471             :   }
     472             : }
     473             : 
     474             : bool
     475           0 : nsSVGImageFrame::ReflowFinished()
     476             : {
     477           0 :   mReflowCallbackPosted = false;
     478             : 
     479             :   // XXX(seth): We don't need this. The purpose of updating visibility
     480             :   // synchronously is to ensure that animated images start animating
     481             :   // immediately. In the short term, however,
     482             :   // nsImageLoadingContent::OnUnlockedDraw() is enough to ensure that
     483             :   // animations start as soon as the image is painted for the first time, and in
     484             :   // the long term we want to update visibility information from the display
     485             :   // list whenever we paint, so we don't actually need to do this. However, to
     486             :   // avoid behavior changes during the transition from the old image visibility
     487             :   // code, we'll leave it in for now.
     488           0 :   UpdateVisibilitySynchronously();
     489             : 
     490           0 :   return false;
     491             : }
     492             : 
     493             : void
     494           0 : nsSVGImageFrame::ReflowCallbackCanceled()
     495             : {
     496           0 :   mReflowCallbackPosted = false;
     497           0 : }
     498             : 
     499             : uint16_t
     500           0 : nsSVGImageFrame::GetHitTestFlags()
     501             : {
     502           0 :   uint16_t flags = 0;
     503             : 
     504           0 :   switch (StyleUserInterface()->mPointerEvents) {
     505             :     case NS_STYLE_POINTER_EVENTS_NONE:
     506           0 :       break;
     507             :     case NS_STYLE_POINTER_EVENTS_VISIBLEPAINTED:
     508             :     case NS_STYLE_POINTER_EVENTS_AUTO:
     509           0 :       if (StyleVisibility()->IsVisible()) {
     510             :         /* XXX: should check pixel transparency */
     511           0 :         flags |= SVG_HIT_TEST_FILL;
     512             :       }
     513           0 :       break;
     514             :     case NS_STYLE_POINTER_EVENTS_VISIBLEFILL:
     515             :     case NS_STYLE_POINTER_EVENTS_VISIBLESTROKE:
     516             :     case NS_STYLE_POINTER_EVENTS_VISIBLE:
     517           0 :       if (StyleVisibility()->IsVisible()) {
     518           0 :         flags |= SVG_HIT_TEST_FILL;
     519             :       }
     520           0 :       break;
     521             :     case NS_STYLE_POINTER_EVENTS_PAINTED:
     522             :       /* XXX: should check pixel transparency */
     523           0 :       flags |= SVG_HIT_TEST_FILL;
     524           0 :       break;
     525             :     case NS_STYLE_POINTER_EVENTS_FILL:
     526             :     case NS_STYLE_POINTER_EVENTS_STROKE:
     527             :     case NS_STYLE_POINTER_EVENTS_ALL:
     528           0 :       flags |= SVG_HIT_TEST_FILL;
     529           0 :       break;
     530             :     default:
     531           0 :       NS_ERROR("not reached");
     532           0 :       break;
     533             :   }
     534             : 
     535           0 :   return flags;
     536             : }
     537             : 
     538             : //----------------------------------------------------------------------
     539             : // nsSVGImageListener implementation
     540             : 
     541           0 : NS_IMPL_ISUPPORTS(nsSVGImageListener, imgINotificationObserver)
     542             : 
     543           0 : nsSVGImageListener::nsSVGImageListener(nsSVGImageFrame *aFrame) :  mFrame(aFrame)
     544             : {
     545           0 : }
     546             : 
     547             : NS_IMETHODIMP
     548           0 : nsSVGImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
     549             : {
     550           0 :   if (!mFrame)
     551           0 :     return NS_ERROR_FAILURE;
     552             : 
     553           0 :   if (aType == imgINotificationObserver::LOAD_COMPLETE) {
     554           0 :     mFrame->InvalidateFrame();
     555           0 :     nsLayoutUtils::PostRestyleEvent(
     556           0 :       mFrame->GetContent()->AsElement(), nsRestyleHint(0),
     557           0 :       nsChangeHint_InvalidateRenderingObservers);
     558           0 :     nsSVGUtils::ScheduleReflowSVG(mFrame);
     559             :   }
     560             : 
     561           0 :   if (aType == imgINotificationObserver::FRAME_UPDATE) {
     562             :     // No new dimensions, so we don't need to call
     563             :     // nsSVGUtils::InvalidateAndScheduleBoundsUpdate.
     564           0 :     nsLayoutUtils::PostRestyleEvent(
     565           0 :       mFrame->GetContent()->AsElement(), nsRestyleHint(0),
     566           0 :       nsChangeHint_InvalidateRenderingObservers);
     567           0 :     mFrame->InvalidateFrame();
     568             :   }
     569             : 
     570           0 :   if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
     571             :     // Called once the resource's dimensions have been obtained.
     572           0 :     aRequest->GetImage(getter_AddRefs(mFrame->mImageContainer));
     573           0 :     mFrame->InvalidateFrame();
     574           0 :     nsLayoutUtils::PostRestyleEvent(
     575           0 :       mFrame->GetContent()->AsElement(), nsRestyleHint(0),
     576           0 :       nsChangeHint_InvalidateRenderingObservers);
     577           0 :     nsSVGUtils::ScheduleReflowSVG(mFrame);
     578             :   }
     579             : 
     580           0 :   return NS_OK;
     581             : }
     582             : 

Generated by: LCOV version 1.13