LCOV - code coverage report
Current view: top level - layout/svg - nsSVGSwitchFrame.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 83 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 14 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             : // Keep in (case-insensitive) order:
       7             : #include "gfxRect.h"
       8             : #include "nsSVGEffects.h"
       9             : #include "nsSVGGFrame.h"
      10             : #include "mozilla/dom/SVGSwitchElement.h"
      11             : #include "nsSVGUtils.h"
      12             : 
      13             : using namespace mozilla::gfx;
      14             : using namespace mozilla::image;
      15             : 
      16           0 : class nsSVGSwitchFrame final : public nsSVGGFrame
      17             : {
      18             :   friend nsIFrame*
      19             :   NS_NewSVGSwitchFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
      20             : protected:
      21           0 :   explicit nsSVGSwitchFrame(nsStyleContext* aContext)
      22           0 :     : nsSVGGFrame(aContext, kClassID)
      23           0 :   {}
      24             : 
      25             : public:
      26           0 :   NS_DECL_FRAMEARENA_HELPERS(nsSVGSwitchFrame)
      27             : 
      28             : #ifdef DEBUG
      29             :   virtual void Init(nsIContent*       aContent,
      30             :                     nsContainerFrame* aParent,
      31             :                     nsIFrame*         aPrevInFlow) override;
      32             : #endif
      33             : 
      34             : #ifdef DEBUG_FRAME_DUMP
      35           0 :   virtual nsresult GetFrameName(nsAString& aResult) const override
      36             :   {
      37           0 :     return MakeFrameName(NS_LITERAL_STRING("SVGSwitch"), aResult);
      38             :   }
      39             : #endif
      40             : 
      41             :   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
      42             :                                 const nsRect&           aDirtyRect,
      43             :                                 const nsDisplayListSet& aLists) override;
      44             : 
      45             :   // nsSVGDisplayableFrame interface:
      46             :   virtual void PaintSVG(gfxContext& aContext,
      47             :                         const gfxMatrix& aTransform,
      48             :                         imgDrawingParams& aPackage,
      49             :                         const nsIntRect* aDirtyRect = nullptr) override;
      50             :   nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) override;
      51             :   virtual void ReflowSVG() override;
      52             :   virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace,
      53             :                                       uint32_t aFlags) override;
      54             : 
      55             : private:
      56             :   nsIFrame *GetActiveChildFrame();
      57             : };
      58             : 
      59             : //----------------------------------------------------------------------
      60             : // Implementation
      61             : 
      62             : nsIFrame*
      63           0 : NS_NewSVGSwitchFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
      64             : {
      65           0 :   return new (aPresShell) nsSVGSwitchFrame(aContext);
      66             : }
      67             : 
      68           0 : NS_IMPL_FRAMEARENA_HELPERS(nsSVGSwitchFrame)
      69             : 
      70             : #ifdef DEBUG
      71             : void
      72           0 : nsSVGSwitchFrame::Init(nsIContent*       aContent,
      73             :                        nsContainerFrame* aParent,
      74             :                        nsIFrame*         aPrevInFlow)
      75             : {
      76           0 :   NS_ASSERTION(aContent->IsSVGElement(nsGkAtoms::svgSwitch),
      77             :                "Content is not an SVG switch");
      78             : 
      79           0 :   nsSVGGFrame::Init(aContent, aParent, aPrevInFlow);
      80           0 : }
      81             : #endif /* DEBUG */
      82             : 
      83             : void
      84           0 : nsSVGSwitchFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
      85             :                                    const nsRect&           aDirtyRect,
      86             :                                    const nsDisplayListSet& aLists)
      87             : {
      88           0 :   nsIFrame* kid = GetActiveChildFrame();
      89           0 :   if (kid) {
      90           0 :     BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
      91             :   }
      92           0 : }
      93             : 
      94             : void
      95           0 : nsSVGSwitchFrame::PaintSVG(gfxContext& aContext,
      96             :                            const gfxMatrix& aTransform,
      97             :                            imgDrawingParams& aImgParams,
      98             :                            const nsIntRect* aDirtyRect)
      99             : {
     100           0 :   NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
     101             :                (mState & NS_FRAME_IS_NONDISPLAY),
     102             :                "If display lists are enabled, only painting of non-display "
     103             :                "SVG should take this code path");
     104             : 
     105           0 :   if (StyleEffects()->mOpacity == 0.0){
     106           0 :     return;
     107             :   }
     108             : 
     109           0 :   nsIFrame *kid = GetActiveChildFrame();
     110           0 :   if (kid) {
     111           0 :     gfxMatrix tm = aTransform;
     112           0 :     if (kid->GetContent()->IsSVGElement()) {
     113           0 :       tm = static_cast<nsSVGElement*>(kid->GetContent())->
     114           0 :              PrependLocalTransformsTo(tm, eUserSpaceToParent);
     115             :     }
     116           0 :     nsSVGUtils::PaintFrameWithEffects(kid, aContext, tm, aImgParams, aDirtyRect);
     117             :   }
     118             : }
     119             : 
     120             : 
     121             : nsIFrame*
     122           0 : nsSVGSwitchFrame::GetFrameForPoint(const gfxPoint& aPoint)
     123             : {
     124           0 :   NS_ASSERTION(!NS_SVGDisplayListHitTestingEnabled() ||
     125             :                (mState & NS_FRAME_IS_NONDISPLAY),
     126             :                "If display lists are enabled, only hit-testing of non-display "
     127             :                "SVG should take this code path");
     128             : 
     129           0 :   nsIFrame *kid = GetActiveChildFrame();
     130           0 :   nsSVGDisplayableFrame* svgFrame = do_QueryFrame(kid);
     131           0 :   if (svgFrame) {
     132             :     // Transform the point from our SVG user space to our child's.
     133           0 :     gfxPoint point = aPoint;
     134             :     gfxMatrix m =
     135           0 :       static_cast<const nsSVGElement*>(mContent)->
     136           0 :         PrependLocalTransformsTo(gfxMatrix(), eChildToUserSpace);
     137           0 :     m = static_cast<const nsSVGElement*>(kid->GetContent())->
     138           0 :           PrependLocalTransformsTo(m, eUserSpaceToParent);
     139           0 :     if (!m.IsIdentity()) {
     140           0 :       if (!m.Invert()) {
     141           0 :         return nullptr;
     142             :       }
     143           0 :       point = m.TransformPoint(point);
     144             :     }
     145           0 :     return svgFrame->GetFrameForPoint(point);
     146             :   }
     147             : 
     148           0 :   return nullptr;
     149             : }
     150             : 
     151             : void
     152           0 : nsSVGSwitchFrame::ReflowSVG()
     153             : {
     154           0 :   NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingReflowSVG(this),
     155             :                "This call is probably a wasteful mistake");
     156             : 
     157           0 :   MOZ_ASSERT(!(GetStateBits() & NS_FRAME_IS_NONDISPLAY),
     158             :              "ReflowSVG mechanism not designed for this");
     159             : 
     160           0 :   if (!nsSVGUtils::NeedsReflowSVG(this)) {
     161           0 :     return;
     162             :   }
     163             : 
     164             :   // If the NS_FRAME_FIRST_REFLOW bit has been removed from our parent frame,
     165             :   // then our outer-<svg> has previously had its initial reflow. In that case
     166             :   // we need to make sure that that bit has been removed from ourself _before_
     167             :   // recursing over our children to ensure that they know too. Otherwise, we
     168             :   // need to remove it _after_ recursing over our children so that they know
     169             :   // the initial reflow is currently underway.
     170             : 
     171           0 :   bool isFirstReflow = (mState & NS_FRAME_FIRST_REFLOW);
     172             : 
     173             :   bool outerSVGHasHadFirstReflow =
     174           0 :     (GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW) == 0;
     175             : 
     176           0 :   if (outerSVGHasHadFirstReflow) {
     177           0 :     mState &= ~NS_FRAME_FIRST_REFLOW; // tell our children
     178             :   }
     179             : 
     180           0 :   nsOverflowAreas overflowRects;
     181             : 
     182           0 :   nsIFrame *child = GetActiveChildFrame();
     183           0 :   nsSVGDisplayableFrame* svgChild = do_QueryFrame(child);
     184           0 :   if (svgChild) {
     185           0 :     MOZ_ASSERT(!(child->GetStateBits() & NS_FRAME_IS_NONDISPLAY),
     186             :                "Check for this explicitly in the |if|, then");
     187           0 :     svgChild->ReflowSVG();
     188             : 
     189             :     // We build up our child frame overflows here instead of using
     190             :     // nsLayoutUtils::UnionChildOverflow since SVG frame's all use the same
     191             :     // frame list, and we're iterating over that list now anyway.
     192           0 :     ConsiderChildOverflow(overflowRects, child);
     193             :   }
     194             : 
     195           0 :   if (isFirstReflow) {
     196             :     // Make sure we have our filter property (if any) before calling
     197             :     // FinishAndStoreOverflow (subsequent filter changes are handled off
     198             :     // nsChangeHint_UpdateEffects):
     199           0 :     nsSVGEffects::UpdateEffects(this);
     200             :   }
     201             : 
     202           0 :   FinishAndStoreOverflow(overflowRects, mRect.Size());
     203             : 
     204             :   // Remove state bits after FinishAndStoreOverflow so that it doesn't
     205             :   // invalidate on first reflow:
     206             :   mState &= ~(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY |
     207           0 :               NS_FRAME_HAS_DIRTY_CHILDREN);
     208             : }
     209             : 
     210             : SVGBBox
     211           0 : nsSVGSwitchFrame::GetBBoxContribution(const Matrix &aToBBoxUserspace,
     212             :                                       uint32_t aFlags)
     213             : {
     214           0 :   nsIFrame* kid = GetActiveChildFrame();
     215           0 :   nsSVGDisplayableFrame* svgKid = do_QueryFrame(kid);
     216           0 :   if (svgKid) {
     217           0 :     nsIContent *content = kid->GetContent();
     218           0 :     gfxMatrix transform = ThebesMatrix(aToBBoxUserspace);
     219           0 :     if (content->IsSVGElement()) {
     220             :       transform = static_cast<nsSVGElement*>(content)->
     221           0 :                     PrependLocalTransformsTo(transform);
     222             :     }
     223           0 :     return svgKid->GetBBoxContribution(ToMatrix(transform), aFlags);
     224             :   }
     225           0 :   return SVGBBox();
     226             : }
     227             : 
     228             : nsIFrame *
     229           0 : nsSVGSwitchFrame::GetActiveChildFrame()
     230             : {
     231             :   nsIContent *activeChild =
     232           0 :     static_cast<mozilla::dom::SVGSwitchElement*>(mContent)->GetActiveChild();
     233             : 
     234           0 :   if (activeChild) {
     235           0 :     for (nsIFrame* kid = mFrames.FirstChild(); kid;
     236             :          kid = kid->GetNextSibling()) {
     237             : 
     238           0 :       if (activeChild == kid->GetContent()) {
     239           0 :         return kid;
     240             :       }
     241             :     }
     242             :   }
     243           0 :   return nullptr;
     244             : }

Generated by: LCOV version 1.13