LCOV - code coverage report
Current view: directory - content/svg/content/src - nsSVGViewBox.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 146 4 2.7 %
Date: 2012-06-02 Functions: 37 2 5.4 %

       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
      18                 :  * Jonathan Watt.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2004
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Craig Topper <craig.topper@gmail.com> (original author)
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "nsSVGViewBox.h"
      40                 : #include "nsSVGUtils.h"
      41                 : #include "prdtoa.h"
      42                 : #include "nsTextFormatter.h"
      43                 : #include "nsCharSeparatedTokenizer.h"
      44                 : #include "nsMathUtils.h"
      45                 : #include "nsSMILValue.h"
      46                 : #include "SVGViewBoxSMILType.h"
      47                 : 
      48                 : #define NUM_VIEWBOX_COMPONENTS 4
      49                 : using namespace mozilla;
      50                 : 
      51                 : /* Implementation of nsSVGViewBoxRect methods */
      52                 : 
      53                 : bool
      54               0 : nsSVGViewBoxRect::operator==(const nsSVGViewBoxRect& aOther) const
      55                 : {
      56               0 :   if (&aOther == this)
      57               0 :     return true;
      58                 : 
      59                 :   return x == aOther.x &&
      60                 :     y == aOther.y &&
      61                 :     width == aOther.width &&
      62               0 :     height == aOther.height;
      63                 : }
      64                 : 
      65                 : /* Cycle collection macros for nsSVGViewBox */
      66                 : 
      67            1464 : NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGViewBox::DOMBaseVal, mSVGElement)
      68            1464 : NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGViewBox::DOMAnimVal, mSVGElement)
      69            1464 : NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGViewBox::DOMAnimatedRect, mSVGElement)
      70                 : 
      71               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGViewBox::DOMBaseVal)
      72               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGViewBox::DOMBaseVal)
      73                 : 
      74               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGViewBox::DOMAnimVal)
      75               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGViewBox::DOMAnimVal)
      76                 : 
      77               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGViewBox::DOMAnimatedRect)
      78               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGViewBox::DOMAnimatedRect)
      79                 : 
      80               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGViewBox::DOMBaseVal)
      81               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGRect)
      82               0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
      83               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGRect)
      84               0 : NS_INTERFACE_MAP_END
      85                 : 
      86               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGViewBox::DOMAnimVal)
      87               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGRect)
      88               0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
      89               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGRect)
      90               0 : NS_INTERFACE_MAP_END
      91                 : 
      92                 : DOMCI_DATA(SVGAnimatedRect, nsSVGViewBox::DOMAnimatedRect)
      93                 : 
      94               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGViewBox::DOMAnimatedRect)
      95               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedRect)
      96               0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
      97               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedRect)
      98               0 : NS_INTERFACE_MAP_END
      99                 : 
     100                 : /* Implementation of nsSVGViewBox methods */
     101                 : 
     102                 : void
     103               0 : nsSVGViewBox::Init()
     104                 : {
     105               0 :   mBaseVal = nsSVGViewBoxRect();
     106               0 :   mAnimVal = nsnull;
     107               0 :   mHasBaseVal = false;
     108               0 : }
     109                 : 
     110                 : void
     111               0 : nsSVGViewBox::SetAnimValue(float aX, float aY, float aWidth, float aHeight,
     112                 :                            nsSVGElement *aSVGElement)
     113                 : {
     114               0 :   if (!mAnimVal) {
     115                 :     // it's okay if allocation fails - and no point in reporting that
     116               0 :     mAnimVal = new nsSVGViewBoxRect(aX, aY, aWidth, aHeight);
     117                 :   } else {
     118               0 :     mAnimVal->x = aX;
     119               0 :     mAnimVal->y = aY;
     120               0 :     mAnimVal->width = aWidth;
     121               0 :     mAnimVal->height = aHeight;
     122                 :   }
     123               0 :   aSVGElement->DidAnimateViewBox();
     124               0 : }
     125                 : 
     126                 : void
     127               0 : nsSVGViewBox::SetBaseValue(float aX, float aY, float aWidth, float aHeight,
     128                 :                            nsSVGElement *aSVGElement)
     129                 : {
     130               0 :   if (mHasBaseVal && mBaseVal == nsSVGViewBoxRect(aX, aY, aWidth, aHeight)) {
     131               0 :     return;
     132                 :   }
     133                 : 
     134               0 :   nsAttrValue emptyOrOldValue = aSVGElement->WillChangeViewBox();
     135                 : 
     136               0 :   mBaseVal = nsSVGViewBoxRect(aX, aY, aWidth, aHeight);
     137               0 :   mHasBaseVal = true;
     138                 : 
     139               0 :   aSVGElement->DidChangeViewBox(emptyOrOldValue);
     140               0 :   if (mAnimVal) {
     141               0 :     aSVGElement->AnimationNeedsResample();
     142                 :   }
     143                 : }
     144                 : 
     145                 : static nsresult
     146               0 : ToSVGViewBoxRect(const nsAString& aStr, nsSVGViewBoxRect *aViewBox)
     147                 : {
     148                 :   nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
     149                 :     tokenizer(aStr, ',',
     150               0 :               nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
     151                 :   float vals[NUM_VIEWBOX_COMPONENTS];
     152                 :   PRUint32 i;
     153               0 :   for (i = 0; i < NUM_VIEWBOX_COMPONENTS && tokenizer.hasMoreTokens(); ++i) {
     154               0 :     NS_ConvertUTF16toUTF8 utf8Token(tokenizer.nextToken());
     155               0 :     const char *token = utf8Token.get();
     156               0 :     if (*token == '\0') {
     157               0 :       return NS_ERROR_DOM_SYNTAX_ERR; // empty string (e.g. two commas in a row)
     158                 :     }
     159                 : 
     160                 :     char *end;
     161               0 :     vals[i] = float(PR_strtod(token, &end));
     162               0 :     if (*end != '\0' || !NS_finite(vals[i])) {
     163               0 :       return NS_ERROR_DOM_SYNTAX_ERR; // parse error
     164                 :     }
     165                 :   }
     166                 : 
     167               0 :   if (i != NUM_VIEWBOX_COMPONENTS ||              // Too few values.
     168               0 :       tokenizer.hasMoreTokens() ||                // Too many values.
     169               0 :       tokenizer.lastTokenEndedWithSeparator()) {  // Trailing comma.
     170               0 :     return NS_ERROR_DOM_SYNTAX_ERR;
     171                 :   }
     172                 : 
     173               0 :   aViewBox->x = vals[0];
     174               0 :   aViewBox->y = vals[1];
     175               0 :   aViewBox->width = vals[2];
     176               0 :   aViewBox->height = vals[3];
     177                 : 
     178               0 :   return NS_OK;
     179                 : }
     180                 : 
     181                 : nsresult
     182               0 : nsSVGViewBox::SetBaseValueString(const nsAString& aValue,
     183                 :                                  nsSVGElement *aSVGElement)
     184                 : {
     185               0 :   nsSVGViewBoxRect viewBox;
     186               0 :   nsresult res = ToSVGViewBoxRect(aValue, &viewBox);
     187               0 :   if (NS_SUCCEEDED(res)) {
     188               0 :     mBaseVal = nsSVGViewBoxRect(viewBox.x, viewBox.y, viewBox.width, viewBox.height);
     189               0 :     mHasBaseVal = true;
     190                 : 
     191               0 :     if (mAnimVal) {
     192               0 :       aSVGElement->AnimationNeedsResample();
     193                 :     }
     194                 :     // We don't need to call Will/DidChange* here - we're only called by
     195                 :     // nsSVGElement::ParseAttribute under nsGenericElement::SetAttr,
     196                 :     // which takes care of notifying.
     197                 :   }
     198               0 :   return res;
     199                 : }
     200                 : 
     201                 : void
     202               0 : nsSVGViewBox::GetBaseValueString(nsAString& aValue) const
     203                 : {
     204                 :   PRUnichar buf[200];
     205                 :   nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
     206               0 :                             NS_LITERAL_STRING("%g %g %g %g").get(),
     207                 :                             (double)mBaseVal.x, (double)mBaseVal.y,
     208               0 :                             (double)mBaseVal.width, (double)mBaseVal.height);
     209               0 :   aValue.Assign(buf);
     210               0 : }
     211                 : 
     212                 : nsresult
     213               0 : nsSVGViewBox::ToDOMAnimatedRect(nsIDOMSVGAnimatedRect **aResult,
     214                 :                                 nsSVGElement* aSVGElement)
     215                 : {
     216               0 :   *aResult = new DOMAnimatedRect(this, aSVGElement);
     217               0 :   NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
     218                 : 
     219               0 :   NS_ADDREF(*aResult);
     220               0 :   return NS_OK;
     221                 : }
     222                 : 
     223                 : NS_IMETHODIMP
     224               0 : nsSVGViewBox::DOMAnimatedRect::GetBaseVal(nsIDOMSVGRect **aResult)
     225                 : {
     226               0 :   *aResult = new nsSVGViewBox::DOMBaseVal(mVal, mSVGElement);
     227               0 :   NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
     228                 : 
     229               0 :   NS_ADDREF(*aResult);
     230               0 :   return NS_OK;
     231                 : }
     232                 : 
     233                 : NS_IMETHODIMP
     234               0 : nsSVGViewBox::DOMAnimatedRect::GetAnimVal(nsIDOMSVGRect **aResult)
     235                 : {
     236               0 :   *aResult = new nsSVGViewBox::DOMAnimVal(mVal, mSVGElement);
     237               0 :   NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
     238                 : 
     239               0 :   NS_ADDREF(*aResult);
     240               0 :   return NS_OK;
     241                 : }
     242                 : 
     243                 : NS_IMETHODIMP
     244               0 : nsSVGViewBox::DOMBaseVal::SetX(float aX)
     245                 : {
     246               0 :   nsSVGViewBoxRect rect = mVal->GetBaseValue();
     247               0 :   rect.x = aX;
     248                 :   mVal->SetBaseValue(rect.x, rect.y, rect.width, rect.height,
     249               0 :                      mSVGElement);
     250               0 :   return NS_OK;
     251                 : }
     252                 : 
     253                 : NS_IMETHODIMP
     254               0 : nsSVGViewBox::DOMBaseVal::SetY(float aY)
     255                 : {
     256               0 :   nsSVGViewBoxRect rect = mVal->GetBaseValue();
     257               0 :   rect.y = aY;
     258                 :   mVal->SetBaseValue(rect.x, rect.y, rect.width, rect.height,
     259               0 :                      mSVGElement);
     260               0 :   return NS_OK;
     261                 : }
     262                 : 
     263                 : NS_IMETHODIMP
     264               0 : nsSVGViewBox::DOMBaseVal::SetWidth(float aWidth)
     265                 : {
     266               0 :   nsSVGViewBoxRect rect = mVal->GetBaseValue();
     267               0 :   rect.width = aWidth;
     268                 :   mVal->SetBaseValue(rect.x, rect.y, rect.width, rect.height,
     269               0 :                      mSVGElement);
     270               0 :   return NS_OK;
     271                 : }
     272                 : 
     273                 : NS_IMETHODIMP
     274               0 : nsSVGViewBox::DOMBaseVal::SetHeight(float aHeight)
     275                 : {
     276               0 :   nsSVGViewBoxRect rect = mVal->GetBaseValue();
     277               0 :   rect.height = aHeight;
     278                 :   mVal->SetBaseValue(rect.x, rect.y, rect.width, rect.height,
     279               0 :                      mSVGElement);
     280               0 :   return NS_OK;
     281                 : }
     282                 : 
     283                 : nsISMILAttr*
     284               0 : nsSVGViewBox::ToSMILAttr(nsSVGElement *aSVGElement)
     285                 : {
     286               0 :   return new SMILViewBox(this, aSVGElement);
     287                 : }
     288                 : 
     289                 : nsresult
     290               0 : nsSVGViewBox::SMILViewBox
     291                 :             ::ValueFromString(const nsAString& aStr,
     292                 :                               const nsISMILAnimationElement* /*aSrcElement*/,
     293                 :                               nsSMILValue& aValue,
     294                 :                               bool& aPreventCachingOfSandwich) const
     295                 : {
     296               0 :   nsSVGViewBoxRect viewBox;
     297               0 :   nsresult res = ToSVGViewBoxRect(aStr, &viewBox);
     298               0 :   if (NS_FAILED(res)) {
     299               0 :     return res;
     300                 :   }
     301               0 :   nsSMILValue val(&SVGViewBoxSMILType::sSingleton);
     302               0 :   *static_cast<nsSVGViewBoxRect*>(val.mU.mPtr) = viewBox;
     303               0 :   aValue.Swap(val);
     304               0 :   aPreventCachingOfSandwich = false;
     305                 :   
     306               0 :   return NS_OK;
     307                 : }
     308                 : 
     309                 : nsSMILValue
     310               0 : nsSVGViewBox::SMILViewBox::GetBaseValue() const
     311                 : {
     312               0 :   nsSMILValue val(&SVGViewBoxSMILType::sSingleton);
     313               0 :   *static_cast<nsSVGViewBoxRect*>(val.mU.mPtr) = mVal->mBaseVal;
     314                 :   return val;
     315                 : }
     316                 : 
     317                 : void
     318               0 : nsSVGViewBox::SMILViewBox::ClearAnimValue()
     319                 : {
     320               0 :   if (mVal->mAnimVal) {
     321               0 :     mVal->mAnimVal = nsnull;
     322               0 :     mSVGElement->DidAnimateViewBox();
     323                 :   }
     324               0 : }
     325                 : 
     326                 : nsresult
     327               0 : nsSVGViewBox::SMILViewBox::SetAnimValue(const nsSMILValue& aValue)
     328                 : {
     329               0 :   NS_ASSERTION(aValue.mType == &SVGViewBoxSMILType::sSingleton,
     330                 :                "Unexpected type to assign animated value");
     331               0 :   if (aValue.mType == &SVGViewBoxSMILType::sSingleton) {
     332               0 :     nsSVGViewBoxRect &vb = *static_cast<nsSVGViewBoxRect*>(aValue.mU.mPtr);
     333               0 :     mVal->SetAnimValue(vb.x, vb.y, vb.width, vb.height, mSVGElement);
     334                 :   }
     335               0 :   return NS_OK;
     336            4392 : }

Generated by: LCOV version 1.7