LCOV - code coverage report
Current view: top level - dom/svg - SVGGeometryElement.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 29 74 39.2 %
Date: 2017-07-14 16:53:18 Functions: 6 13 46.2 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #include "SVGGeometryElement.h"
       8             : 
       9             : #include "DOMSVGPoint.h"
      10             : #include "gfxPlatform.h"
      11             : #include "mozilla/gfx/2D.h"
      12             : #include "nsComputedDOMStyle.h"
      13             : #include "nsSVGUtils.h"
      14             : #include "nsSVGLength2.h"
      15             : #include "SVGContentUtils.h"
      16             : 
      17             : using namespace mozilla;
      18             : using namespace mozilla::gfx;
      19             : 
      20             : nsSVGElement::NumberInfo SVGGeometryElement::sNumberInfo =
      21             : { &nsGkAtoms::pathLength, 0, false };
      22             : 
      23             : //----------------------------------------------------------------------
      24             : // Implementation
      25             : 
      26          73 : SVGGeometryElement::SVGGeometryElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
      27          73 :   : SVGGeometryElementBase(aNodeInfo)
      28             : {
      29          73 : }
      30             : 
      31             : nsSVGElement::NumberAttributesInfo
      32         138 : SVGGeometryElement::GetNumberInfo()
      33             : {
      34         138 :   return NumberAttributesInfo(&mPathLength, &sNumberInfo, 1);
      35             : }
      36             : 
      37             : nsresult
      38         184 : SVGGeometryElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
      39             :                                  const nsAttrValue* aValue,
      40             :                                  const nsAttrValue* aOldValue, bool aNotify)
      41             : {
      42         184 :   if (mCachedPath &&
      43         184 :       aNamespaceID == kNameSpaceID_None &&
      44           0 :       AttributeDefinesGeometry(aName)) {
      45           0 :     mCachedPath = nullptr;
      46             :   }
      47         184 :   return SVGGeometryElementBase::AfterSetAttr(aNamespaceID, aName,
      48         184 :                                               aValue, aOldValue, aNotify);
      49             : }
      50             : 
      51             : bool
      52           0 : SVGGeometryElement::AttributeDefinesGeometry(const nsIAtom *aName)
      53             : {
      54           0 :   if (aName == nsGkAtoms::pathLength) {
      55           0 :     return true;
      56             :   }
      57             : 
      58             :   // Check for nsSVGLength2 attribute
      59           0 :   LengthAttributesInfo info = GetLengthInfo();
      60           0 :   for (uint32_t i = 0; i < info.mLengthCount; i++) {
      61           0 :     if (aName == *info.mLengthInfo[i].mName) {
      62           0 :       return true;
      63             :     }
      64             :   }
      65             : 
      66           0 :   return false;
      67             : }
      68             : 
      69             : bool
      70          17 : SVGGeometryElement::GeometryDependsOnCoordCtx()
      71             : {
      72             :   // Check the nsSVGLength2 attribute
      73          17 :   LengthAttributesInfo info = const_cast<SVGGeometryElement*>(this)->GetLengthInfo();
      74          53 :   for (uint32_t i = 0; i < info.mLengthCount; i++) {
      75          36 :     if (info.mLengths[i].GetSpecifiedUnitType() == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE) {
      76           0 :       return true;
      77             :     }
      78             :   }
      79          17 :   return false;
      80             : }
      81             : 
      82             : bool
      83          36 : SVGGeometryElement::IsMarkable()
      84             : {
      85          36 :   return false;
      86             : }
      87             : 
      88             : void
      89           0 : SVGGeometryElement::GetMarkPoints(nsTArray<nsSVGMark> *aMarks)
      90             : {
      91           0 : }
      92             : 
      93             : already_AddRefed<Path>
      94          72 : SVGGeometryElement::GetOrBuildPath(const DrawTarget& aDrawTarget,
      95             :                                    FillRule aFillRule)
      96             : {
      97             :   // We only cache the path if it matches the backend used for screen painting:
      98          72 :   bool cacheable  = aDrawTarget.GetBackendType() ==
      99          72 :                     gfxPlatform::GetPlatform()->GetDefaultContentBackend();
     100             : 
     101             :   // Checking for and returning mCachedPath before checking the pref means
     102             :   // that the pref is only live on page reload (or app restart for SVG in
     103             :   // chrome). The benefit is that we avoid causing a CPU memory cache miss by
     104             :   // looking at the global variable that the pref's stored in.
     105          72 :   if (cacheable && mCachedPath) {
     106          28 :     if (aDrawTarget.GetBackendType() == mCachedPath->GetBackendType()) {
     107          56 :       RefPtr<Path> path(mCachedPath);
     108          28 :       return path.forget();
     109             :     }
     110             :   }
     111          88 :   RefPtr<PathBuilder> builder = aDrawTarget.CreatePathBuilder(aFillRule);
     112          88 :   RefPtr<Path> path = BuildPath(builder);
     113          44 :   if (cacheable && NS_SVGPathCachingEnabled()) {
     114          44 :     mCachedPath = path;
     115             :   }
     116          44 :   return path.forget();
     117             : }
     118             : 
     119             : already_AddRefed<Path>
     120           0 : SVGGeometryElement::GetOrBuildPathForMeasuring()
     121             : {
     122           0 :   return nullptr;
     123             : }
     124             : 
     125             : FillRule
     126           0 : SVGGeometryElement::GetFillRule()
     127             : {
     128           0 :   FillRule fillRule = FillRule::FILL_WINDING; // Equivalent to StyleFillRule::Nonzero
     129             : 
     130             :   RefPtr<nsStyleContext> styleContext =
     131           0 :     nsComputedDOMStyle::GetStyleContextNoFlush(this, nullptr, nullptr);
     132             : 
     133           0 :   if (styleContext) {
     134           0 :     MOZ_ASSERT(styleContext->StyleSVG()->mFillRule == StyleFillRule::Nonzero ||
     135             :                styleContext->StyleSVG()->mFillRule == StyleFillRule::Evenodd);
     136             : 
     137           0 :     if (styleContext->StyleSVG()->mFillRule == StyleFillRule::Evenodd) {
     138           0 :       fillRule = FillRule::FILL_EVEN_ODD;
     139             :     }
     140             :   } else {
     141             :     // ReportToConsole
     142           0 :     NS_WARNING("Couldn't get style context for content in GetFillRule");
     143             :   }
     144             : 
     145           0 :   return fillRule;
     146             : }
     147             : 
     148             : float
     149           0 : SVGGeometryElement::GetTotalLength()
     150             : {
     151           0 :   RefPtr<Path> flat = GetOrBuildPathForMeasuring();
     152           0 :   return flat ? flat->ComputeLength() : 0.f;
     153             : }
     154             : 
     155             : already_AddRefed<nsISVGPoint>
     156           0 : SVGGeometryElement::GetPointAtLength(float distance, ErrorResult& rv)
     157             : {
     158           0 :   RefPtr<Path> path = GetOrBuildPathForMeasuring();
     159           0 :   if (!path) {
     160           0 :     rv.Throw(NS_ERROR_FAILURE);
     161           0 :     return nullptr;
     162             :   }
     163             : 
     164           0 :   float totalLength = path->ComputeLength();
     165           0 :   if (mPathLength.IsExplicitlySet()) {
     166           0 :     float pathLength = mPathLength.GetAnimValue();
     167           0 :     if (pathLength <= 0) {
     168           0 :       rv.Throw(NS_ERROR_FAILURE);
     169           0 :       return nullptr;
     170             :     }
     171           0 :     distance *= totalLength / pathLength;
     172             :   }
     173           0 :   distance = std::max(0.f,         distance);
     174           0 :   distance = std::min(totalLength, distance);
     175             : 
     176             :   nsCOMPtr<nsISVGPoint> point =
     177           0 :     new DOMSVGPoint(path->ComputePointAtLength(distance));
     178           0 :   return point.forget();
     179             : }
     180             : 
     181             : already_AddRefed<SVGAnimatedNumber>
     182           0 : SVGGeometryElement::PathLength()
     183             : {
     184           0 :   return mPathLength.ToDOMAnimatedNumber(this);
     185             : }

Generated by: LCOV version 1.13