LCOV - app.info - content/svg/content/src/nsSVGViewBox.cpp

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-04-21 | 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            1396 : NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGViewBox::DOMBaseVal, mSVGElement)
          68            1396 : NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGViewBox::DOMAnimVal, mSVGElement)
          69            1396 : 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            4188 : }

Generated by: LCOV version 1.7