LCOV - code coverage report
Current view: top level - dom/svg - DOMSVGPathSeg.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 150 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 131 0.0 %
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 "DOMSVGPathSeg.h"
       8             : #include "DOMSVGPathSegList.h"
       9             : #include "SVGAnimatedPathSegList.h"
      10             : #include "nsSVGElement.h"
      11             : #include "nsError.h"
      12             : 
      13             : // See the architecture comment in DOMSVGPathSegList.h.
      14             : 
      15             : namespace mozilla {
      16             : 
      17             : // We could use NS_IMPL_CYCLE_COLLECTION(, except that in Unlink() we need to
      18             : // clear our list's weak ref to us to be safe. (The other option would be to
      19             : // not unlink and rely on the breaking of the other edges in the cycle, as
      20             : // NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.)
      21             : NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGPathSeg)
      22             : 
      23           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPathSeg)
      24             :   // We may not belong to a list, so we must null check tmp->mList.
      25           0 :   if (tmp->mList) {
      26           0 :     tmp->mList->ItemAt(tmp->mListIndex) = nullptr;
      27             :   }
      28           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mList)
      29           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
      30           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      31             : 
      32           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPathSeg)
      33           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList)
      34           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      35             : 
      36           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGPathSeg)
      37           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
      38           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
      39             : 
      40           0 : NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMSVGPathSeg, AddRef)
      41           0 : NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMSVGPathSeg, Release)
      42             : 
      43             : //----------------------------------------------------------------------
      44             : // Helper class: AutoChangePathSegNotifier
      45             : // Stack-based helper class to pair calls to WillChangePathSegList
      46             : // and DidChangePathSegList.
      47             : class MOZ_RAII AutoChangePathSegNotifier
      48             : {
      49             : public:
      50           0 :   explicit AutoChangePathSegNotifier(DOMSVGPathSeg* aPathSeg MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
      51           0 :     : mPathSeg(aPathSeg)
      52             :   {
      53           0 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
      54           0 :     MOZ_ASSERT(mPathSeg, "Expecting non-null pathSeg");
      55           0 :     MOZ_ASSERT(mPathSeg->HasOwner(),
      56             :                "Expecting list to have an owner for notification");
      57             :     mEmptyOrOldValue =
      58           0 :       mPathSeg->Element()->WillChangePathSegList();
      59           0 :   }
      60             : 
      61           0 :   ~AutoChangePathSegNotifier()
      62           0 :   {
      63           0 :     mPathSeg->Element()->DidChangePathSegList(mEmptyOrOldValue);
      64           0 :     if (mPathSeg->mList->AttrIsAnimating()) {
      65           0 :       mPathSeg->Element()->AnimationNeedsResample();
      66             :     }
      67           0 :   }
      68             : 
      69             : private:
      70             :   DOMSVGPathSeg* const mPathSeg;
      71             :   nsAttrValue    mEmptyOrOldValue;
      72             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
      73             : };
      74             : 
      75           0 : DOMSVGPathSeg::DOMSVGPathSeg(DOMSVGPathSegList *aList,
      76             :                              uint32_t aListIndex,
      77           0 :                              bool aIsAnimValItem)
      78             :   : mList(aList)
      79             :   , mListIndex(aListIndex)
      80           0 :   , mIsAnimValItem(aIsAnimValItem)
      81             : {
      82             :   // These shifts are in sync with the members in the header.
      83           0 :   MOZ_ASSERT(aList && aListIndex <= MaxListIndex(), "bad arg");
      84             : 
      85           0 :   MOZ_ASSERT(IndexIsValid(), "Bad index for DOMSVGPathSeg!");
      86           0 : }
      87             : 
      88           0 : DOMSVGPathSeg::DOMSVGPathSeg()
      89             :   : mList(nullptr)
      90             :   , mListIndex(0)
      91           0 :   , mIsAnimValItem(false)
      92             : {
      93           0 : }
      94             : 
      95             : void
      96           0 : DOMSVGPathSeg::InsertingIntoList(DOMSVGPathSegList *aList,
      97             :                                  uint32_t aListIndex,
      98             :                                  bool aIsAnimValItem)
      99             : {
     100           0 :   MOZ_ASSERT(!HasOwner(), "Inserting item that is already in a list");
     101             : 
     102           0 :   mList = aList;
     103           0 :   mListIndex = aListIndex;
     104           0 :   mIsAnimValItem = aIsAnimValItem;
     105             : 
     106           0 :   MOZ_ASSERT(IndexIsValid(), "Bad index for DOMSVGPathSeg!");
     107           0 : }
     108             : 
     109             : void
     110           0 : DOMSVGPathSeg::RemovingFromList()
     111             : {
     112           0 :   uint32_t argCount = SVGPathSegUtils::ArgCountForType(Type());
     113             :   // InternalItem() + 1, because the args come after the encoded seg type
     114           0 :   memcpy(PtrToMemberArgs(), InternalItem() + 1, argCount * sizeof(float));
     115           0 :   mList = nullptr;
     116           0 :   mIsAnimValItem = false;
     117           0 : }
     118             : 
     119             : void
     120           0 : DOMSVGPathSeg::ToSVGPathSegEncodedData(float* aRaw)
     121             : {
     122           0 :   MOZ_ASSERT(aRaw, "null pointer");
     123           0 :   uint32_t argCount = SVGPathSegUtils::ArgCountForType(Type());
     124           0 :   if (IsInList()) {
     125             :     // 1 + argCount, because we're copying the encoded seg type and args
     126           0 :     memcpy(aRaw, InternalItem(), (1 + argCount) * sizeof(float));
     127             :   } else {
     128           0 :     aRaw[0] = SVGPathSegUtils::EncodeType(Type());
     129             :     // aRaw + 1, because the args go after the encoded seg type
     130           0 :     memcpy(aRaw + 1, PtrToMemberArgs(), argCount * sizeof(float));
     131             :   }
     132           0 : }
     133             : 
     134             : float*
     135           0 : DOMSVGPathSeg::InternalItem()
     136             : {
     137           0 :   uint32_t dataIndex = mList->mItems[mListIndex].mInternalDataIndex;
     138           0 :   return &(mList->InternalList().mData[dataIndex]);
     139             : }
     140             : 
     141             : #ifdef DEBUG
     142             : bool
     143           0 : DOMSVGPathSeg::IndexIsValid()
     144             : {
     145           0 :   SVGAnimatedPathSegList *alist = Element()->GetAnimPathSegList();
     146           0 :   return (mIsAnimValItem &&
     147           0 :           mListIndex < alist->GetAnimValue().CountItems()) ||
     148           0 :          (!mIsAnimValItem &&
     149           0 :           mListIndex < alist->GetBaseValue().CountItems());
     150             : }
     151             : #endif
     152             : 
     153             : 
     154             : ////////////////////////////////////////////////////////////////////////
     155             : // Implementation of DOMSVGPathSeg sub-classes below this point
     156             : 
     157             : #define IMPL_PROP_WITH_TYPE(segName, propName, index, type)                   \
     158             :   type                                                                        \
     159             :   DOMSVGPathSeg##segName::propName()                                          \
     160             :   {                                                                           \
     161             :     if (mIsAnimValItem && HasOwner()) {                                       \
     162             :       Element()->FlushAnimations(); /* May make HasOwner() == false */        \
     163             :     }                                                                         \
     164             :     return type(HasOwner() ? InternalItem()[1+index] : mArgs[index]);         \
     165             :   }                                                                           \
     166             :   void                                                                        \
     167             :   DOMSVGPathSeg##segName::Set##propName(type a##propName, ErrorResult& rv)    \
     168             :   {                                                                           \
     169             :     if (mIsAnimValItem) {                                                     \
     170             :       rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);                     \
     171             :       return;                                                                 \
     172             :     }                                                                         \
     173             :     if (HasOwner()) {                                                         \
     174             :       if (InternalItem()[1+index] == float(a##propName)) {                    \
     175             :         return;                                                               \
     176             :       }                                                                       \
     177             :       AutoChangePathSegNotifier notifier(this);                               \
     178             :       InternalItem()[1+index] = float(a##propName);                           \
     179             :     } else {                                                                  \
     180             :       mArgs[index] = float(a##propName);                                      \
     181             :     }                                                                         \
     182             :   }
     183             : 
     184             : // For float, the normal type of arguments
     185             : #define IMPL_FLOAT_PROP(segName, propName, index) \
     186             :   IMPL_PROP_WITH_TYPE(segName, propName, index, float)
     187             : 
     188             : // For the boolean flags in arc commands
     189             : #define IMPL_BOOL_PROP(segName, propName, index) \
     190             :   IMPL_PROP_WITH_TYPE(segName, propName, index, bool)
     191             : 
     192             : 
     193             : ///////////////////////////////////////////////////////////////////////
     194             : 
     195           0 : IMPL_FLOAT_PROP(MovetoAbs, X, 0)
     196           0 : IMPL_FLOAT_PROP(MovetoAbs, Y, 1)
     197             : 
     198             : 
     199             : ////////////////////////////////////////////////////////////////////////
     200             : 
     201           0 : IMPL_FLOAT_PROP(MovetoRel, X, 0)
     202           0 : IMPL_FLOAT_PROP(MovetoRel, Y, 1)
     203             : 
     204             : 
     205             : 
     206             : ////////////////////////////////////////////////////////////////////////
     207             : 
     208           0 : IMPL_FLOAT_PROP(LinetoAbs, X, 0)
     209           0 : IMPL_FLOAT_PROP(LinetoAbs, Y, 1)
     210             : 
     211             : 
     212             : ////////////////////////////////////////////////////////////////////////
     213             : 
     214           0 : IMPL_FLOAT_PROP(LinetoRel, X, 0)
     215           0 : IMPL_FLOAT_PROP(LinetoRel, Y, 1)
     216             : 
     217             : 
     218             : ////////////////////////////////////////////////////////////////////////
     219             : 
     220           0 : IMPL_FLOAT_PROP(CurvetoCubicAbs, X1, 0)
     221           0 : IMPL_FLOAT_PROP(CurvetoCubicAbs, Y1, 1)
     222           0 : IMPL_FLOAT_PROP(CurvetoCubicAbs, X2, 2)
     223           0 : IMPL_FLOAT_PROP(CurvetoCubicAbs, Y2, 3)
     224           0 : IMPL_FLOAT_PROP(CurvetoCubicAbs, X, 4)
     225           0 : IMPL_FLOAT_PROP(CurvetoCubicAbs, Y, 5)
     226             : 
     227             : 
     228             : ////////////////////////////////////////////////////////////////////////
     229             : 
     230           0 : IMPL_FLOAT_PROP(CurvetoCubicRel, X1, 0)
     231           0 : IMPL_FLOAT_PROP(CurvetoCubicRel, Y1, 1)
     232           0 : IMPL_FLOAT_PROP(CurvetoCubicRel, X2, 2)
     233           0 : IMPL_FLOAT_PROP(CurvetoCubicRel, Y2, 3)
     234           0 : IMPL_FLOAT_PROP(CurvetoCubicRel, X, 4)
     235           0 : IMPL_FLOAT_PROP(CurvetoCubicRel, Y, 5)
     236             : 
     237             : 
     238             : ////////////////////////////////////////////////////////////////////////
     239             : 
     240           0 : IMPL_FLOAT_PROP(CurvetoQuadraticAbs, X1, 0)
     241           0 : IMPL_FLOAT_PROP(CurvetoQuadraticAbs, Y1, 1)
     242           0 : IMPL_FLOAT_PROP(CurvetoQuadraticAbs, X, 2)
     243           0 : IMPL_FLOAT_PROP(CurvetoQuadraticAbs, Y, 3)
     244             : 
     245             : 
     246             : ////////////////////////////////////////////////////////////////////////
     247             : 
     248           0 : IMPL_FLOAT_PROP(CurvetoQuadraticRel, X1, 0)
     249           0 : IMPL_FLOAT_PROP(CurvetoQuadraticRel, Y1, 1)
     250           0 : IMPL_FLOAT_PROP(CurvetoQuadraticRel, X, 2)
     251           0 : IMPL_FLOAT_PROP(CurvetoQuadraticRel, Y, 3)
     252             : 
     253             : 
     254             : ////////////////////////////////////////////////////////////////////////
     255             : 
     256           0 : IMPL_FLOAT_PROP(ArcAbs, R1, 0)
     257           0 : IMPL_FLOAT_PROP(ArcAbs, R2, 1)
     258           0 : IMPL_FLOAT_PROP(ArcAbs, Angle, 2)
     259           0 : IMPL_BOOL_PROP(ArcAbs, LargeArcFlag, 3)
     260           0 : IMPL_BOOL_PROP(ArcAbs, SweepFlag, 4)
     261           0 : IMPL_FLOAT_PROP(ArcAbs, X, 5)
     262           0 : IMPL_FLOAT_PROP(ArcAbs, Y, 6)
     263             : 
     264             : 
     265             : ////////////////////////////////////////////////////////////////////////
     266             : 
     267           0 : IMPL_FLOAT_PROP(ArcRel, R1, 0)
     268           0 : IMPL_FLOAT_PROP(ArcRel, R2, 1)
     269           0 : IMPL_FLOAT_PROP(ArcRel, Angle, 2)
     270           0 : IMPL_BOOL_PROP(ArcRel, LargeArcFlag, 3)
     271           0 : IMPL_BOOL_PROP(ArcRel, SweepFlag, 4)
     272           0 : IMPL_FLOAT_PROP(ArcRel, X, 5)
     273           0 : IMPL_FLOAT_PROP(ArcRel, Y, 6)
     274             : 
     275             : 
     276             : ////////////////////////////////////////////////////////////////////////
     277             : 
     278           0 : IMPL_FLOAT_PROP(LinetoHorizontalAbs, X, 0)
     279             : 
     280             : 
     281             : ////////////////////////////////////////////////////////////////////////
     282             : 
     283           0 : IMPL_FLOAT_PROP(LinetoHorizontalRel, X, 0)
     284             : 
     285             : 
     286             : ////////////////////////////////////////////////////////////////////////
     287             : 
     288           0 : IMPL_FLOAT_PROP(LinetoVerticalAbs, Y, 0)
     289             : 
     290             : 
     291             : ////////////////////////////////////////////////////////////////////////
     292             : 
     293           0 : IMPL_FLOAT_PROP(LinetoVerticalRel, Y, 0)
     294             : 
     295             : 
     296             : ////////////////////////////////////////////////////////////////////////
     297             : 
     298           0 : IMPL_FLOAT_PROP(CurvetoCubicSmoothAbs, X2, 0)
     299           0 : IMPL_FLOAT_PROP(CurvetoCubicSmoothAbs, Y2, 1)
     300           0 : IMPL_FLOAT_PROP(CurvetoCubicSmoothAbs, X, 2)
     301           0 : IMPL_FLOAT_PROP(CurvetoCubicSmoothAbs, Y, 3)
     302             : 
     303             : 
     304             : ////////////////////////////////////////////////////////////////////////
     305             : 
     306           0 : IMPL_FLOAT_PROP(CurvetoCubicSmoothRel, X2, 0)
     307           0 : IMPL_FLOAT_PROP(CurvetoCubicSmoothRel, Y2, 1)
     308           0 : IMPL_FLOAT_PROP(CurvetoCubicSmoothRel, X, 2)
     309           0 : IMPL_FLOAT_PROP(CurvetoCubicSmoothRel, Y, 3)
     310             : 
     311             : 
     312             : ////////////////////////////////////////////////////////////////////////
     313             : 
     314           0 : IMPL_FLOAT_PROP(CurvetoQuadraticSmoothAbs, X, 0)
     315           0 : IMPL_FLOAT_PROP(CurvetoQuadraticSmoothAbs, Y, 1)
     316             : 
     317             : 
     318             : ////////////////////////////////////////////////////////////////////////
     319             : 
     320             : 
     321           0 : IMPL_FLOAT_PROP(CurvetoQuadraticSmoothRel, X, 0)
     322           0 : IMPL_FLOAT_PROP(CurvetoQuadraticSmoothRel, Y, 1)
     323             : 
     324             : 
     325             : 
     326             : // This must come after DOMSVGPathSegClosePath et. al. have been declared.
     327             : /* static */ DOMSVGPathSeg*
     328           0 : DOMSVGPathSeg::CreateFor(DOMSVGPathSegList *aList,
     329             :                          uint32_t aListIndex,
     330             :                          bool aIsAnimValItem)
     331             : {
     332           0 :   uint32_t dataIndex = aList->mItems[aListIndex].mInternalDataIndex;
     333           0 :   float *data = &aList->InternalList().mData[dataIndex];
     334           0 :   uint32_t type = SVGPathSegUtils::DecodeType(data[0]);
     335             : 
     336           0 :   switch (type)
     337             :   {
     338             :   case PATHSEG_CLOSEPATH:
     339           0 :     return new DOMSVGPathSegClosePath(aList, aListIndex, aIsAnimValItem);
     340             :   case PATHSEG_MOVETO_ABS:
     341           0 :     return new DOMSVGPathSegMovetoAbs(aList, aListIndex, aIsAnimValItem);
     342             :   case PATHSEG_MOVETO_REL:
     343           0 :     return new DOMSVGPathSegMovetoRel(aList, aListIndex, aIsAnimValItem);
     344             :   case PATHSEG_LINETO_ABS:
     345           0 :     return new DOMSVGPathSegLinetoAbs(aList, aListIndex, aIsAnimValItem);
     346             :   case PATHSEG_LINETO_REL:
     347           0 :     return new DOMSVGPathSegLinetoRel(aList, aListIndex, aIsAnimValItem);
     348             :   case PATHSEG_CURVETO_CUBIC_ABS:
     349           0 :     return new DOMSVGPathSegCurvetoCubicAbs(aList, aListIndex, aIsAnimValItem);
     350             :   case PATHSEG_CURVETO_CUBIC_REL:
     351           0 :     return new DOMSVGPathSegCurvetoCubicRel(aList, aListIndex, aIsAnimValItem);
     352             :   case PATHSEG_CURVETO_QUADRATIC_ABS:
     353           0 :     return new DOMSVGPathSegCurvetoQuadraticAbs(aList, aListIndex, aIsAnimValItem);
     354             :   case PATHSEG_CURVETO_QUADRATIC_REL:
     355           0 :     return new DOMSVGPathSegCurvetoQuadraticRel(aList, aListIndex, aIsAnimValItem);
     356             :   case PATHSEG_ARC_ABS:
     357           0 :     return new DOMSVGPathSegArcAbs(aList, aListIndex, aIsAnimValItem);
     358             :   case PATHSEG_ARC_REL:
     359           0 :     return new DOMSVGPathSegArcRel(aList, aListIndex, aIsAnimValItem);
     360             :   case PATHSEG_LINETO_HORIZONTAL_ABS:
     361           0 :     return new DOMSVGPathSegLinetoHorizontalAbs(aList, aListIndex, aIsAnimValItem);
     362             :   case PATHSEG_LINETO_HORIZONTAL_REL:
     363           0 :     return new DOMSVGPathSegLinetoHorizontalRel(aList, aListIndex, aIsAnimValItem);
     364             :   case PATHSEG_LINETO_VERTICAL_ABS:
     365           0 :     return new DOMSVGPathSegLinetoVerticalAbs(aList, aListIndex, aIsAnimValItem);
     366             :   case PATHSEG_LINETO_VERTICAL_REL:
     367           0 :     return new DOMSVGPathSegLinetoVerticalRel(aList, aListIndex, aIsAnimValItem);
     368             :   case PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
     369           0 :     return new DOMSVGPathSegCurvetoCubicSmoothAbs(aList, aListIndex, aIsAnimValItem);
     370             :   case PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
     371           0 :     return new DOMSVGPathSegCurvetoCubicSmoothRel(aList, aListIndex, aIsAnimValItem);
     372             :   case PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
     373           0 :     return new DOMSVGPathSegCurvetoQuadraticSmoothAbs(aList, aListIndex, aIsAnimValItem);
     374             :   case PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
     375           0 :     return new DOMSVGPathSegCurvetoQuadraticSmoothRel(aList, aListIndex, aIsAnimValItem);
     376             :   default:
     377           0 :     NS_NOTREACHED("Invalid path segment type");
     378           0 :     return nullptr;
     379             :   }
     380             : }
     381             : 
     382             : } // namespace mozilla

Generated by: LCOV version 1.13