LCOV - code coverage report
Current view: directory - content/svg/content/src - DOMSVGLength.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 174 2 1.1 %
Date: 2012-06-02 Functions: 24 2 8.3 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla SVG Project code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is the Mozilla Foundation.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2010
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *
      23                 :  * Alternatively, the contents of this file may be used under the terms of
      24                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      25                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      26                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      27                 :  * of those above. If you wish to allow use of your version of this file only
      28                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      29                 :  * use your version of this file under the terms of the MPL, indicate your
      30                 :  * decision by deleting the provisions above and replace them with the notice
      31                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      32                 :  * the provisions above, a recipient may use your version of this file under
      33                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      34                 :  *
      35                 :  * ***** END LICENSE BLOCK ***** */
      36                 : 
      37                 : #include "DOMSVGLength.h"
      38                 : #include "DOMSVGLengthList.h"
      39                 : #include "DOMSVGAnimatedLengthList.h"
      40                 : #include "SVGLength.h"
      41                 : #include "SVGAnimatedLengthList.h"
      42                 : #include "nsSVGElement.h"
      43                 : #include "nsIDOMSVGLength.h"
      44                 : #include "nsDOMError.h"
      45                 : #include "nsMathUtils.h"
      46                 : 
      47                 : // See the architecture comment in DOMSVGAnimatedLengthList.h.
      48                 : 
      49                 : namespace mozilla {
      50                 : 
      51                 : // We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to
      52                 : // clear our list's weak ref to us to be safe. (The other option would be to
      53                 : // not unlink and rely on the breaking of the other edges in the cycle, as
      54                 : // NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.)
      55            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGLength)
      56               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGLength)
      57                 :   // We may not belong to a list, so we must null check tmp->mList.
      58               0 :   if (tmp->mList) {
      59               0 :     tmp->mList->mItems[tmp->mListIndex] = nsnull;
      60                 :   }
      61               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mList)
      62               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      63               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGLength)
      64               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mList)
      65               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      66                 : 
      67               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGLength)
      68               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGLength)
      69                 : 
      70                 : }
      71                 : DOMCI_DATA(SVGLength, mozilla::DOMSVGLength)
      72                 : namespace mozilla {
      73                 : 
      74               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGLength)
      75               0 :   NS_INTERFACE_MAP_ENTRY(mozilla::DOMSVGLength) // pseudo-interface
      76               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGLength)
      77               0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
      78               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGLength)
      79               0 : NS_INTERFACE_MAP_END
      80                 : 
      81               0 : DOMSVGLength::DOMSVGLength(DOMSVGLengthList *aList,
      82                 :                            PRUint8 aAttrEnum,
      83                 :                            PRUint32 aListIndex,
      84                 :                            PRUint8 aIsAnimValItem)
      85                 :   : mList(aList)
      86                 :   , mListIndex(aListIndex)
      87                 :   , mAttrEnum(aAttrEnum)
      88                 :   , mIsAnimValItem(aIsAnimValItem)
      89                 :   , mUnit(nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER)
      90               0 :   , mValue(0.0f)
      91                 : {
      92                 :   // These shifts are in sync with the members in the header.
      93               0 :   NS_ABORT_IF_FALSE(aList &&
      94                 :                     aAttrEnum < (1 << 4) &&
      95                 :                     aListIndex <= MaxListIndex() &&
      96                 :                     aIsAnimValItem < (1 << 1), "bad arg");
      97                 : 
      98               0 :   NS_ABORT_IF_FALSE(IndexIsValid(), "Bad index for DOMSVGNumber!");
      99               0 : }
     100                 : 
     101               0 : DOMSVGLength::DOMSVGLength()
     102                 :   : mList(nsnull)
     103                 :   , mListIndex(0)
     104                 :   , mAttrEnum(0)
     105                 :   , mIsAnimValItem(false)
     106                 :   , mUnit(nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER)
     107               0 :   , mValue(0.0f)
     108                 : {
     109               0 : }
     110                 : 
     111                 : NS_IMETHODIMP
     112               0 : DOMSVGLength::GetUnitType(PRUint16* aUnit)
     113                 : {
     114               0 :   if (mIsAnimValItem && HasOwner()) {
     115               0 :     Element()->FlushAnimations(); // May make HasOwner() == false
     116                 :   }
     117               0 :   *aUnit = HasOwner() ? InternalItem().GetUnit() : mUnit;
     118               0 :   return NS_OK;
     119                 : }
     120                 : 
     121                 : NS_IMETHODIMP
     122               0 : DOMSVGLength::GetValue(float* aValue)
     123                 : {
     124               0 :   if (mIsAnimValItem && HasOwner()) {
     125               0 :     Element()->FlushAnimations(); // May make HasOwner() == false
     126                 :   }
     127               0 :   if (HasOwner()) {
     128               0 :     *aValue = InternalItem().GetValueInUserUnits(Element(), Axis());
     129               0 :     if (NS_finite(*aValue)) {
     130               0 :       return NS_OK;
     131                 :     }
     132               0 :   } else if (mUnit == nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER ||
     133                 :              mUnit == nsIDOMSVGLength::SVG_LENGTHTYPE_PX) {
     134               0 :     *aValue = mValue;
     135               0 :     return NS_OK;
     136                 :   }
     137                 :   // else [SVGWG issue] Can't convert this length's value to user units
     138                 :   // ReportToConsole
     139               0 :   return NS_ERROR_FAILURE;
     140                 : }
     141                 : 
     142                 : NS_IMETHODIMP
     143               0 : DOMSVGLength::SetValue(float aUserUnitValue)
     144                 : {
     145               0 :   if (mIsAnimValItem) {
     146               0 :     return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
     147                 :   }
     148                 : 
     149               0 :   if (!NS_finite(aUserUnitValue)) {
     150               0 :     return NS_ERROR_ILLEGAL_VALUE;
     151                 :   }
     152                 : 
     153                 :   // Although the value passed in is in user units, this method does not turn
     154                 :   // this length into a user unit length. Instead it converts the user unit
     155                 :   // value to this length's current unit and sets that, leaving this length's
     156                 :   // unit as it is.
     157                 : 
     158               0 :   if (HasOwner()) {
     159               0 :     if (InternalItem().GetValueInUserUnits(Element(), Axis()) ==
     160                 :         aUserUnitValue) {
     161               0 :       return NS_OK;
     162                 :     }
     163               0 :     nsAttrValue emptyOrOldValue = Element()->WillChangeLengthList(mAttrEnum);
     164               0 :     if (InternalItem().SetFromUserUnitValue(aUserUnitValue, Element(), Axis()))
     165                 :     {
     166               0 :       Element()->DidChangeLengthList(mAttrEnum, emptyOrOldValue);
     167               0 :       if (mList->mAList->IsAnimating()) {
     168               0 :         Element()->AnimationNeedsResample();
     169                 :       }
     170               0 :       return NS_OK;
     171                 :     }
     172               0 :   } else if (mUnit == nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER ||
     173                 :              mUnit == nsIDOMSVGLength::SVG_LENGTHTYPE_PX) {
     174               0 :     mValue = aUserUnitValue;
     175               0 :     return NS_OK;
     176                 :   }
     177                 :   // else [SVGWG issue] Can't convert user unit value to this length's unit
     178                 :   // ReportToConsole
     179               0 :   return NS_ERROR_FAILURE;
     180                 : }
     181                 : 
     182                 : NS_IMETHODIMP
     183               0 : DOMSVGLength::GetValueInSpecifiedUnits(float* aValue)
     184                 : {
     185               0 :   if (mIsAnimValItem && HasOwner()) {
     186               0 :     Element()->FlushAnimations(); // May make HasOwner() == false
     187                 :   }
     188               0 :   *aValue = HasOwner() ? InternalItem().GetValueInCurrentUnits() : mValue;
     189               0 :   return NS_OK;
     190                 : }
     191                 : 
     192                 : NS_IMETHODIMP
     193               0 : DOMSVGLength::SetValueInSpecifiedUnits(float aValue)
     194                 : {
     195               0 :   if (mIsAnimValItem) {
     196               0 :     return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
     197                 :   }
     198                 : 
     199               0 :   if (!NS_finite(aValue)) {
     200               0 :     return NS_ERROR_ILLEGAL_VALUE;
     201                 :   }
     202                 : 
     203               0 :   if (HasOwner()) {
     204               0 :     if (InternalItem().GetValueInCurrentUnits() == aValue) {
     205               0 :       return NS_OK;
     206                 :     }
     207               0 :     nsAttrValue emptyOrOldValue = Element()->WillChangeLengthList(mAttrEnum);
     208               0 :     InternalItem().SetValueInCurrentUnits(aValue);
     209               0 :     Element()->DidChangeLengthList(mAttrEnum, emptyOrOldValue);
     210               0 :     if (mList->mAList->IsAnimating()) {
     211               0 :       Element()->AnimationNeedsResample();
     212                 :     }
     213               0 :     return NS_OK;
     214                 :   }
     215               0 :   mValue = aValue;
     216               0 :   return NS_OK;
     217                 : }
     218                 : 
     219                 : NS_IMETHODIMP
     220               0 : DOMSVGLength::SetValueAsString(const nsAString& aValue)
     221                 : {
     222               0 :   if (mIsAnimValItem) {
     223               0 :     return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
     224                 :   }
     225                 : 
     226               0 :   SVGLength value;
     227               0 :   if (!value.SetValueFromString(aValue)) {
     228               0 :     return NS_ERROR_DOM_SYNTAX_ERR;
     229                 :   }
     230               0 :   if (HasOwner()) {
     231               0 :     if (InternalItem() == value) {
     232               0 :       return NS_OK;
     233                 :     }
     234               0 :     nsAttrValue emptyOrOldValue = Element()->WillChangeLengthList(mAttrEnum);
     235               0 :     InternalItem() = value;
     236               0 :     Element()->DidChangeLengthList(mAttrEnum, emptyOrOldValue);
     237               0 :     if (mList->mAList->IsAnimating()) {
     238               0 :       Element()->AnimationNeedsResample();
     239                 :     }
     240               0 :     return NS_OK;
     241                 :   }
     242               0 :   mValue = value.GetValueInCurrentUnits();
     243               0 :   mUnit = value.GetUnit();
     244               0 :   return NS_OK;
     245                 : }
     246                 : 
     247                 : NS_IMETHODIMP
     248               0 : DOMSVGLength::GetValueAsString(nsAString& aValue)
     249                 : {
     250               0 :   if (mIsAnimValItem && HasOwner()) {
     251               0 :     Element()->FlushAnimations(); // May make HasOwner() == false
     252                 :   }
     253               0 :   if (HasOwner()) {
     254               0 :     InternalItem().GetValueAsString(aValue);
     255               0 :     return NS_OK;
     256                 :   }
     257               0 :   SVGLength(mValue, mUnit).GetValueAsString(aValue);
     258               0 :   return NS_OK;
     259                 : }
     260                 : 
     261                 : NS_IMETHODIMP
     262               0 : DOMSVGLength::NewValueSpecifiedUnits(PRUint16 aUnit, float aValue)
     263                 : {
     264               0 :   if (mIsAnimValItem) {
     265               0 :     return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
     266                 :   }
     267                 : 
     268               0 :   if (!NS_finite(aValue)) {
     269               0 :     return NS_ERROR_ILLEGAL_VALUE;
     270                 :   }
     271                 : 
     272               0 :   if (!SVGLength::IsValidUnitType(aUnit)) {
     273               0 :     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
     274                 :   }
     275               0 :   if (HasOwner()) {
     276               0 :     if (InternalItem().GetUnit() == aUnit &&
     277               0 :         InternalItem().GetValueInCurrentUnits() == aValue) {
     278               0 :       return NS_OK;
     279                 :     }
     280               0 :     nsAttrValue emptyOrOldValue = Element()->WillChangeLengthList(mAttrEnum);
     281               0 :     InternalItem().SetValueAndUnit(aValue, PRUint8(aUnit));
     282               0 :     Element()->DidChangeLengthList(mAttrEnum, emptyOrOldValue);
     283               0 :     if (mList->mAList->IsAnimating()) {
     284               0 :       Element()->AnimationNeedsResample();
     285                 :     }
     286               0 :     return NS_OK;
     287                 :   }
     288               0 :   mUnit = PRUint8(aUnit);
     289               0 :   mValue = aValue;
     290               0 :   return NS_OK;
     291                 : }
     292                 : 
     293                 : NS_IMETHODIMP
     294               0 : DOMSVGLength::ConvertToSpecifiedUnits(PRUint16 aUnit)
     295                 : {
     296               0 :   if (mIsAnimValItem) {
     297               0 :     return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
     298                 :   }
     299                 : 
     300               0 :   if (!SVGLength::IsValidUnitType(aUnit)) {
     301               0 :     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
     302                 :   }
     303               0 :   if (HasOwner()) {
     304               0 :     if (InternalItem().GetUnit() == aUnit) {
     305               0 :       return NS_OK;
     306                 :     }
     307               0 :     nsAttrValue emptyOrOldValue = Element()->WillChangeLengthList(mAttrEnum);
     308               0 :     if (InternalItem().ConvertToUnit(PRUint8(aUnit), Element(), Axis())) {
     309               0 :       Element()->DidChangeLengthList(mAttrEnum, emptyOrOldValue);
     310               0 :       return NS_OK;
     311                 :     }
     312                 :   } else {
     313               0 :     SVGLength len(mValue, mUnit);
     314               0 :     if (len.ConvertToUnit(PRUint8(aUnit), nsnull, 0)) {
     315               0 :       mValue = len.GetValueInCurrentUnits();
     316               0 :       mUnit = aUnit;
     317               0 :       return NS_OK;
     318                 :     }
     319                 :   }
     320                 :   // else [SVGWG issue] Can't convert unit
     321                 :   // ReportToConsole
     322               0 :   return NS_ERROR_FAILURE;
     323                 : }
     324                 : 
     325                 : void
     326               0 : DOMSVGLength::InsertingIntoList(DOMSVGLengthList *aList,
     327                 :                                 PRUint8 aAttrEnum,
     328                 :                                 PRUint32 aListIndex,
     329                 :                                 PRUint8 aIsAnimValItem)
     330                 : {
     331               0 :   NS_ASSERTION(!HasOwner(), "Inserting item that is already in a list");
     332                 : 
     333               0 :   mList = aList;
     334               0 :   mAttrEnum = aAttrEnum;
     335               0 :   mListIndex = aListIndex;
     336               0 :   mIsAnimValItem = aIsAnimValItem;
     337                 : 
     338               0 :   NS_ABORT_IF_FALSE(IndexIsValid(), "Bad index for DOMSVGLength!");
     339               0 : }
     340                 : 
     341                 : void
     342               0 : DOMSVGLength::RemovingFromList()
     343                 : {
     344               0 :   mValue = InternalItem().GetValueInCurrentUnits();
     345               0 :   mUnit  = InternalItem().GetUnit();
     346               0 :   mList = nsnull;
     347               0 :   mIsAnimValItem = false;
     348               0 : }
     349                 : 
     350                 : SVGLength
     351               0 : DOMSVGLength::ToSVGLength()
     352                 : {
     353               0 :   if (HasOwner()) {
     354               0 :     return SVGLength(InternalItem().GetValueInCurrentUnits(),
     355               0 :                      InternalItem().GetUnit());
     356                 :   }
     357               0 :   return SVGLength(mValue, mUnit);
     358                 : }
     359                 : 
     360                 : SVGLength&
     361               0 : DOMSVGLength::InternalItem()
     362                 : {
     363               0 :   SVGAnimatedLengthList *alist = Element()->GetAnimatedLengthList(mAttrEnum);
     364               0 :   return mIsAnimValItem && alist->mAnimVal ?
     365               0 :     (*alist->mAnimVal)[mListIndex] :
     366               0 :     alist->mBaseVal[mListIndex];
     367                 : }
     368                 : 
     369                 : #ifdef DEBUG
     370                 : bool
     371               0 : DOMSVGLength::IndexIsValid()
     372                 : {
     373               0 :   SVGAnimatedLengthList *alist = Element()->GetAnimatedLengthList(mAttrEnum);
     374                 :   return (mIsAnimValItem &&
     375               0 :           mListIndex < alist->GetAnimValue().Length()) ||
     376               0 :          (!mIsAnimValItem &&
     377               0 :           mListIndex < alist->GetBaseValue().Length());
     378                 : }
     379                 : #endif
     380                 : 
     381            4392 : } // namespace mozilla

Generated by: LCOV version 1.7