LCOV - code coverage report
Current view: top level - layout/svg - nsSVGMarkerFrame.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 104 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 15 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             : // Main header first:
       7             : #include "nsSVGMarkerFrame.h"
       8             : 
       9             : // Keep others in (case-insensitive) order:
      10             : #include "gfxContext.h"
      11             : #include "nsSVGEffects.h"
      12             : #include "mozilla/dom/SVGMarkerElement.h"
      13             : #include "SVGGeometryElement.h"
      14             : #include "SVGGeometryFrame.h"
      15             : 
      16             : using namespace mozilla::dom;
      17             : using namespace mozilla::gfx;
      18             : using namespace mozilla::image;
      19             : 
      20             : nsContainerFrame*
      21           0 : NS_NewSVGMarkerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
      22             : {
      23           0 :   return new (aPresShell) nsSVGMarkerFrame(aContext);
      24             : }
      25             : 
      26           0 : NS_IMPL_FRAMEARENA_HELPERS(nsSVGMarkerFrame)
      27             : 
      28             : //----------------------------------------------------------------------
      29             : // nsIFrame methods:
      30             : 
      31             : nsresult
      32           0 : nsSVGMarkerFrame::AttributeChanged(int32_t  aNameSpaceID,
      33             :                                    nsIAtom* aAttribute,
      34             :                                    int32_t  aModType)
      35             : {
      36           0 :   if (aNameSpaceID == kNameSpaceID_None &&
      37           0 :       (aAttribute == nsGkAtoms::markerUnits ||
      38           0 :        aAttribute == nsGkAtoms::refX ||
      39           0 :        aAttribute == nsGkAtoms::refY ||
      40           0 :        aAttribute == nsGkAtoms::markerWidth ||
      41           0 :        aAttribute == nsGkAtoms::markerHeight ||
      42           0 :        aAttribute == nsGkAtoms::orient ||
      43           0 :        aAttribute == nsGkAtoms::preserveAspectRatio ||
      44           0 :        aAttribute == nsGkAtoms::viewBox)) {
      45           0 :     nsSVGEffects::InvalidateDirectRenderingObservers(this);
      46             :   }
      47             : 
      48           0 :   return nsSVGContainerFrame::AttributeChanged(aNameSpaceID,
      49           0 :                                                aAttribute, aModType);
      50             : }
      51             : 
      52             : #ifdef DEBUG
      53             : void
      54           0 : nsSVGMarkerFrame::Init(nsIContent*       aContent,
      55             :                        nsContainerFrame* aParent,
      56             :                        nsIFrame*         aPrevInFlow)
      57             : {
      58           0 :   NS_ASSERTION(aContent->IsSVGElement(nsGkAtoms::marker), "Content is not an SVG marker");
      59             : 
      60           0 :   nsSVGContainerFrame::Init(aContent, aParent, aPrevInFlow);
      61           0 : }
      62             : #endif /* DEBUG */
      63             : 
      64             : //----------------------------------------------------------------------
      65             : // nsSVGContainerFrame methods:
      66             : 
      67             : gfxMatrix
      68           0 : nsSVGMarkerFrame::GetCanvasTM()
      69             : {
      70           0 :   NS_ASSERTION(mMarkedFrame, "null SVGGeometry frame");
      71             : 
      72           0 :   if (mInUse2) {
      73             :     // We're going to be bailing drawing the marker, so return an identity.
      74           0 :     return gfxMatrix();
      75             :   }
      76             : 
      77           0 :   SVGMarkerElement *content = static_cast<SVGMarkerElement*>(mContent);
      78             : 
      79           0 :   mInUse2 = true;
      80           0 :   gfxMatrix markedTM = mMarkedFrame->GetCanvasTM();
      81           0 :   mInUse2 = false;
      82             : 
      83           0 :   Matrix viewBoxTM = content->GetViewBoxTransform();
      84             : 
      85           0 :   return ThebesMatrix(viewBoxTM * mMarkerTM) * markedTM;
      86             : }
      87             : 
      88             : static nsIFrame*
      89           0 : GetAnonymousChildFrame(nsIFrame* aFrame)
      90             : {
      91           0 :   nsIFrame* kid = aFrame->PrincipalChildList().FirstChild();
      92           0 :   MOZ_ASSERT(kid && kid->IsSVGMarkerAnonChildFrame(),
      93             :              "expected to find anonymous child of marker frame");
      94           0 :   return kid;
      95             : }
      96             : 
      97             : void
      98           0 : nsSVGMarkerFrame::PaintMark(gfxContext& aContext,
      99             :                             const gfxMatrix& aToMarkedFrameUserSpace,
     100             :                             SVGGeometryFrame* aMarkedFrame,
     101             :                             const nsSVGMark& aMark, float aStrokeWidth,
     102             :                             imgDrawingParams& aImgParams)
     103             : {
     104             :   // If the flag is set when we get here, it means this marker frame
     105             :   // has already been used painting the current mark, and the document
     106             :   // has a marker reference loop.
     107           0 :   if (mInUse) {
     108           0 :     return;
     109             :   }
     110             : 
     111           0 :   AutoMarkerReferencer markerRef(this, aMarkedFrame);
     112             : 
     113           0 :   SVGMarkerElement *marker = static_cast<SVGMarkerElement*>(mContent);
     114           0 :   if (!marker->HasValidDimensions()) {
     115           0 :     return;
     116             :   }
     117             : 
     118           0 :   const nsSVGViewBoxRect viewBox = marker->GetViewBoxRect();
     119             : 
     120           0 :   if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
     121             :     // We must disable rendering if the viewBox width or height are zero.
     122           0 :     return;
     123             :   }
     124             : 
     125           0 :   Matrix viewBoxTM = marker->GetViewBoxTransform();
     126             : 
     127           0 :   mMarkerTM = marker->GetMarkerTransform(aStrokeWidth, aMark);
     128             : 
     129           0 :   gfxMatrix markTM = ThebesMatrix(viewBoxTM) * ThebesMatrix(mMarkerTM) *
     130           0 :                      aToMarkedFrameUserSpace;
     131             : 
     132           0 :   if (StyleDisplay()->IsScrollableOverflow()) {
     133           0 :     aContext.Save();
     134             :     gfxRect clipRect =
     135           0 :       nsSVGUtils::GetClipRectForFrame(this, viewBox.x, viewBox.y,
     136           0 :                                       viewBox.width, viewBox.height);
     137           0 :     nsSVGUtils::SetClipRect(&aContext, markTM, clipRect);
     138             :   }
     139             : 
     140             : 
     141           0 :   nsIFrame* kid = GetAnonymousChildFrame(this);
     142           0 :   nsSVGDisplayableFrame* SVGFrame = do_QueryFrame(kid);
     143             :   // The CTM of each frame referencing us may be different.
     144           0 :   SVGFrame->NotifySVGChanged(nsSVGDisplayableFrame::TRANSFORM_CHANGED);
     145           0 :   nsSVGUtils::PaintFrameWithEffects(kid, aContext, markTM, aImgParams);
     146             : 
     147           0 :   if (StyleDisplay()->IsScrollableOverflow())
     148           0 :     aContext.Restore();
     149             : }
     150             : 
     151             : SVGBBox
     152           0 : nsSVGMarkerFrame::GetMarkBBoxContribution(const Matrix& aToBBoxUserspace,
     153             :                                           uint32_t aFlags,
     154             :                                           SVGGeometryFrame* aMarkedFrame,
     155             :                                           const nsSVGMark& aMark,
     156             :                                           float aStrokeWidth)
     157             : {
     158           0 :   SVGBBox bbox;
     159             : 
     160             :   // If the flag is set when we get here, it means this marker frame
     161             :   // has already been used in calculating the current mark bbox, and
     162             :   // the document has a marker reference loop.
     163           0 :   if (mInUse)
     164           0 :     return bbox;
     165             : 
     166           0 :   AutoMarkerReferencer markerRef(this, aMarkedFrame);
     167             : 
     168           0 :   SVGMarkerElement *content = static_cast<SVGMarkerElement*>(mContent);
     169           0 :   if (!content->HasValidDimensions()) {
     170           0 :     return bbox;
     171             :   }
     172             : 
     173           0 :   const nsSVGViewBoxRect viewBox = content->GetViewBoxRect();
     174             : 
     175           0 :   if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
     176           0 :     return bbox;
     177             :   }
     178             : 
     179           0 :   mMarkerTM = content->GetMarkerTransform(aStrokeWidth, aMark);
     180           0 :   Matrix viewBoxTM = content->GetViewBoxTransform();
     181             : 
     182           0 :   Matrix tm = viewBoxTM * mMarkerTM * aToBBoxUserspace;
     183             : 
     184           0 :   nsSVGDisplayableFrame* child = do_QueryFrame(GetAnonymousChildFrame(this));
     185             :   // When we're being called to obtain the invalidation area, we need to
     186             :   // pass down all the flags so that stroke is included. However, once DOM
     187             :   // getBBox() accepts flags, maybe we should strip some of those here?
     188             : 
     189             :   // We need to include zero width/height vertical/horizontal lines, so we have
     190             :   // to use UnionEdges.
     191           0 :   bbox.UnionEdges(child->GetBBoxContribution(tm, aFlags));
     192             : 
     193           0 :   return bbox;
     194             : }
     195             : 
     196             : void
     197           0 : nsSVGMarkerFrame::SetParentCoordCtxProvider(SVGSVGElement *aContext)
     198             : {
     199           0 :   SVGMarkerElement *marker = static_cast<SVGMarkerElement*>(mContent);
     200           0 :   marker->SetParentCoordCtxProvider(aContext);
     201           0 : }
     202             : 
     203             : void
     204           0 : nsSVGMarkerFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
     205             : {
     206           0 :   aResult.AppendElement(OwnedAnonBox(GetAnonymousChildFrame(this)));
     207           0 : }
     208             : 
     209             : //----------------------------------------------------------------------
     210             : // helper class
     211             : 
     212           0 : nsSVGMarkerFrame::AutoMarkerReferencer::AutoMarkerReferencer(
     213             :     nsSVGMarkerFrame *aFrame,
     214             :     SVGGeometryFrame *aMarkedFrame
     215           0 :     MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
     216           0 :       : mFrame(aFrame)
     217             : {
     218           0 :   MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     219           0 :   mFrame->mInUse = true;
     220           0 :   mFrame->mMarkedFrame = aMarkedFrame;
     221             : 
     222             :   SVGSVGElement *ctx =
     223           0 :     static_cast<nsSVGElement*>(aMarkedFrame->GetContent())->GetCtx();
     224           0 :   mFrame->SetParentCoordCtxProvider(ctx);
     225           0 : }
     226             : 
     227           0 : nsSVGMarkerFrame::AutoMarkerReferencer::~AutoMarkerReferencer()
     228             : {
     229           0 :   mFrame->SetParentCoordCtxProvider(nullptr);
     230             : 
     231           0 :   mFrame->mMarkedFrame = nullptr;
     232           0 :   mFrame->mInUse = false;
     233           0 : }
     234             : 
     235             : //----------------------------------------------------------------------
     236             : // Implementation of nsSVGMarkerAnonChildFrame
     237             : 
     238             : nsContainerFrame*
     239           0 : NS_NewSVGMarkerAnonChildFrame(nsIPresShell* aPresShell,
     240             :                               nsStyleContext* aContext)
     241             : {
     242           0 :   return new (aPresShell) nsSVGMarkerAnonChildFrame(aContext);
     243             : }
     244             : 
     245           0 : NS_IMPL_FRAMEARENA_HELPERS(nsSVGMarkerAnonChildFrame)
     246             : 
     247             : #ifdef DEBUG
     248             : void
     249           0 : nsSVGMarkerAnonChildFrame::Init(nsIContent*       aContent,
     250             :                                 nsContainerFrame* aParent,
     251             :                                 nsIFrame*         aPrevInFlow)
     252             : {
     253           0 :   MOZ_ASSERT(aParent->IsSVGMarkerFrame(), "Unexpected parent");
     254           0 :   nsSVGDisplayContainerFrame::Init(aContent, aParent, aPrevInFlow);
     255           0 : }
     256             : #endif

Generated by: LCOV version 1.13