LCOV - code coverage report
Current view: directory - content/svg/content/src - SVGTransformListParser.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 146 0 0.0 %
Date: 2012-06-02 Functions: 13 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2                 :  * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
       3                 :  * ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is the Mozilla SVG project.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * IBM Corporation
      20                 :  * Portions created by the Initial Developer are Copyright (C) 2006
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      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 "mozilla/Util.h"
      40                 : 
      41                 : #include "SVGTransformListParser.h"
      42                 : #include "SVGTransform.h"
      43                 : #include "prdtoa.h"
      44                 : #include "nsDOMError.h"
      45                 : #include "nsGkAtoms.h"
      46                 : #include "nsReadableUtils.h"
      47                 : #include "nsCRT.h"
      48                 : #include "nsContentUtils.h"
      49                 : #include "nsDOMClassInfoID.h"
      50                 : #include "nsIAtom.h"
      51                 : 
      52                 : using namespace mozilla;
      53                 : 
      54                 : //----------------------------------------------------------------------
      55                 : // private methods
      56                 : 
      57                 : nsresult
      58               0 : SVGTransformListParser::Match()
      59                 : {
      60               0 :   mTransforms.Clear();
      61               0 :   return MatchTransformList();
      62                 : }
      63                 : 
      64                 : 
      65                 : nsresult
      66               0 : SVGTransformListParser::MatchTransformList()
      67                 : {
      68               0 :   MatchWsp();
      69                 : 
      70               0 :   if (IsTokenTransformStarter()) {
      71               0 :     ENSURE_MATCHED(MatchTransforms());
      72                 :   }
      73                 : 
      74               0 :   MatchWsp();
      75                 : 
      76               0 :   return NS_OK;
      77                 : }
      78                 : 
      79                 : 
      80                 : nsresult
      81               0 : SVGTransformListParser::MatchTransforms()
      82                 : {
      83               0 :   ENSURE_MATCHED(MatchTransform());
      84                 : 
      85               0 :   while (mTokenType != END) {
      86               0 :     const char* pos = mTokenPos;
      87                 : 
      88                 :     /* Curiously the SVG BNF allows multiple comma-wsp between transforms */
      89               0 :     while (IsTokenCommaWspStarter()) {
      90               0 :       ENSURE_MATCHED(MatchCommaWsp());
      91                 :     }
      92                 : 
      93               0 :     if (IsTokenTransformStarter()) {
      94               0 :       ENSURE_MATCHED(MatchTransform());
      95                 :     } else {
      96               0 :       if (pos != mTokenPos) RewindTo(pos);
      97               0 :       break;
      98                 :     }
      99                 :   }
     100                 : 
     101               0 :   return NS_OK;
     102                 : }
     103                 : 
     104                 : 
     105                 : nsresult
     106               0 : SVGTransformListParser::GetTransformToken(nsIAtom** aKeyAtom,
     107                 :                                           bool aAdvancePos)
     108                 : {
     109               0 :   if (mTokenType != OTHER || *mTokenPos == '\0') {
     110               0 :     return NS_ERROR_FAILURE;
     111                 :   }
     112                 : 
     113               0 :   nsresult rv = NS_OK;
     114                 : 
     115               0 :   const char* delimiters = "\x20\x9\xD\xA,(";
     116               0 :   char* delimiterStart = PL_strnpbrk(mTokenPos, delimiters, 11);
     117               0 :   if (delimiterStart != 0) {
     118                 :     /* save this character and null it out */
     119               0 :     char holdingChar = *delimiterStart;
     120               0 :     *delimiterStart = '\0';
     121                 : 
     122                 :     PRUint32 len;
     123               0 :     if ((len = nsCRT::strlen(mTokenPos)) > 0) {
     124               0 :       *aKeyAtom = NS_NewAtom(Substring(mTokenPos, mTokenPos + len));
     125                 : 
     126               0 :       if (aAdvancePos) {
     127               0 :          mInputPos = mTokenPos + len;
     128               0 :          mTokenPos = mInputPos;
     129                 :       }
     130                 :     } else {
     131               0 :       rv = NS_ERROR_FAILURE;
     132                 :     }
     133                 :     /* reset character back to original */
     134               0 :     *delimiterStart = holdingChar;
     135                 :   } else {
     136               0 :     rv = NS_ERROR_FAILURE;
     137                 :   }
     138                 : 
     139               0 :   return rv;
     140                 : }
     141                 : 
     142                 : 
     143                 : nsresult
     144               0 : SVGTransformListParser::MatchTransform()
     145                 : {
     146               0 :   nsCOMPtr<nsIAtom> keyatom;
     147                 : 
     148               0 :   nsresult rv = GetTransformToken(getter_AddRefs(keyatom), true);
     149               0 :   if (NS_FAILED(rv)) {
     150               0 :     return rv;
     151                 :   }
     152                 : 
     153               0 :   if (keyatom == nsGkAtoms::translate) {
     154               0 :     ENSURE_MATCHED(MatchTranslate());
     155               0 :   } else if (keyatom == nsGkAtoms::scale) {
     156               0 :     ENSURE_MATCHED(MatchScale());
     157               0 :   } else if (keyatom == nsGkAtoms::rotate) {
     158               0 :     ENSURE_MATCHED(MatchRotate());
     159               0 :   } else if (keyatom == nsGkAtoms::skewX) {
     160               0 :     ENSURE_MATCHED(MatchSkewX());
     161               0 :   } else if (keyatom == nsGkAtoms::skewY) {
     162               0 :     ENSURE_MATCHED(MatchSkewY());
     163               0 :   } else if (keyatom == nsGkAtoms::matrix) {
     164               0 :     ENSURE_MATCHED(MatchMatrix());
     165                 :   } else {
     166               0 :     return NS_ERROR_FAILURE;
     167                 :   }
     168                 : 
     169               0 :   return NS_OK;
     170                 : }
     171                 : 
     172                 : 
     173                 : bool
     174               0 : SVGTransformListParser::IsTokenTransformStarter()
     175                 : {
     176               0 :   nsCOMPtr<nsIAtom> keyatom;
     177                 : 
     178               0 :   nsresult rv = GetTransformToken(getter_AddRefs(keyatom), false);
     179               0 :   if (NS_FAILED(rv)) {
     180               0 :     return false;
     181                 :   }
     182                 : 
     183               0 :   if (keyatom == nsGkAtoms::translate ||
     184               0 :       keyatom == nsGkAtoms::scale     ||
     185               0 :       keyatom == nsGkAtoms::rotate    ||
     186               0 :       keyatom == nsGkAtoms::skewX     ||
     187               0 :       keyatom == nsGkAtoms::skewY     ||
     188               0 :       keyatom == nsGkAtoms::matrix) {
     189               0 :     return true;
     190                 :   }
     191                 : 
     192               0 :   return false;
     193                 : }
     194                 : 
     195                 : nsresult
     196               0 : SVGTransformListParser::MatchNumberArguments(float *aResult,
     197                 :                                              PRUint32 aMaxNum,
     198                 :                                              PRUint32 *aParsedNum)
     199                 : {
     200               0 :   *aParsedNum = 0;
     201                 : 
     202               0 :   MatchWsp();
     203                 : 
     204               0 :   ENSURE_MATCHED(MatchLeftParen());
     205                 : 
     206               0 :   MatchWsp();
     207                 : 
     208               0 :   ENSURE_MATCHED(MatchNumber(&aResult[0]));
     209               0 :   *aParsedNum = 1;
     210                 : 
     211               0 :   while (IsTokenCommaWspStarter()) {
     212               0 :     MatchWsp();
     213               0 :     if (mTokenType == RIGHT_PAREN) {
     214               0 :       break;
     215                 :     }
     216               0 :     if (*aParsedNum == aMaxNum) {
     217               0 :       return NS_ERROR_FAILURE;
     218                 :     }
     219               0 :     if (IsTokenCommaWspStarter()) {
     220               0 :       MatchCommaWsp();
     221                 :     }
     222               0 :     ENSURE_MATCHED(MatchNumber(&aResult[(*aParsedNum)++]));
     223                 :   }
     224                 : 
     225               0 :   MatchWsp();
     226                 : 
     227               0 :   ENSURE_MATCHED(MatchRightParen());
     228                 : 
     229               0 :   return NS_OK;
     230                 : }
     231                 : 
     232                 : nsresult
     233               0 : SVGTransformListParser::MatchTranslate()
     234                 : {
     235               0 :   GetNextToken();
     236                 : 
     237                 :   float t[2];
     238                 :   PRUint32 count;
     239                 : 
     240               0 :   ENSURE_MATCHED(MatchNumberArguments(t, ArrayLength(t), &count));
     241                 : 
     242               0 :   switch (count) {
     243                 :     case 1:
     244               0 :       t[1] = 0.f;
     245                 :       // fall-through
     246                 :     case 2:
     247                 :     {
     248               0 :       SVGTransform* transform = mTransforms.AppendElement();
     249               0 :       NS_ENSURE_TRUE(transform, NS_ERROR_OUT_OF_MEMORY);
     250               0 :       transform->SetTranslate(t[0], t[1]);
     251                 :       break;
     252                 :     }
     253                 :     default:
     254               0 :       return NS_ERROR_FAILURE;
     255                 :   }
     256                 : 
     257               0 :   return NS_OK;
     258                 : }
     259                 : 
     260                 : 
     261                 : nsresult
     262               0 : SVGTransformListParser::MatchScale()
     263                 : {
     264               0 :   GetNextToken();
     265                 : 
     266                 :   float s[2];
     267                 :   PRUint32 count;
     268                 : 
     269               0 :   ENSURE_MATCHED(MatchNumberArguments(s, ArrayLength(s), &count));
     270                 : 
     271               0 :   switch (count) {
     272                 :     case 1:
     273               0 :       s[1] = s[0];
     274                 :       // fall-through
     275                 :     case 2:
     276                 :     {
     277               0 :       SVGTransform* transform = mTransforms.AppendElement();
     278               0 :       NS_ENSURE_TRUE(transform, NS_ERROR_OUT_OF_MEMORY);
     279               0 :       transform->SetScale(s[0], s[1]);
     280                 :       break;
     281                 :     }
     282                 :     default:
     283               0 :       return NS_ERROR_FAILURE;
     284                 :   }
     285                 : 
     286               0 :   return NS_OK;
     287                 : }
     288                 : 
     289                 : 
     290                 : nsresult
     291               0 : SVGTransformListParser::MatchRotate()
     292                 : {
     293               0 :   GetNextToken();
     294                 : 
     295                 :   float r[3];
     296                 :   PRUint32 count;
     297                 : 
     298               0 :   ENSURE_MATCHED(MatchNumberArguments(r, ArrayLength(r), &count));
     299                 : 
     300               0 :   switch (count) {
     301                 :     case 1:
     302               0 :       r[1] = r[2] = 0.f;
     303                 :       // fall-through
     304                 :     case 3:
     305                 :     {
     306               0 :       SVGTransform* transform = mTransforms.AppendElement();
     307               0 :       NS_ENSURE_TRUE(transform, NS_ERROR_OUT_OF_MEMORY);
     308               0 :       transform->SetRotate(r[0], r[1], r[2]);
     309                 :       break;
     310                 :     }
     311                 :     default:
     312               0 :       return NS_ERROR_FAILURE;
     313                 :   }
     314                 : 
     315               0 :   return NS_OK;
     316                 : }
     317                 : 
     318                 : 
     319                 : nsresult
     320               0 : SVGTransformListParser::MatchSkewX()
     321                 : {
     322               0 :   GetNextToken();
     323                 : 
     324                 :   float skew;
     325                 :   PRUint32 count;
     326                 : 
     327               0 :   ENSURE_MATCHED(MatchNumberArguments(&skew, 1, &count));
     328                 : 
     329               0 :   if (count != 1) {
     330               0 :     return NS_ERROR_FAILURE;
     331                 :   }
     332                 : 
     333               0 :   SVGTransform* transform = mTransforms.AppendElement();
     334               0 :   NS_ENSURE_TRUE(transform, NS_ERROR_OUT_OF_MEMORY);
     335               0 :   transform->SetSkewX(skew);
     336                 : 
     337               0 :   return NS_OK;
     338                 : }
     339                 : 
     340                 : 
     341                 : nsresult
     342               0 : SVGTransformListParser::MatchSkewY()
     343                 : {
     344               0 :   GetNextToken();
     345                 : 
     346                 :   float skew;
     347                 :   PRUint32 count;
     348                 : 
     349               0 :   ENSURE_MATCHED(MatchNumberArguments(&skew, 1, &count));
     350                 : 
     351               0 :   if (count != 1) {
     352               0 :     return NS_ERROR_FAILURE;
     353                 :   }
     354                 : 
     355               0 :   SVGTransform* transform = mTransforms.AppendElement();
     356               0 :   NS_ENSURE_TRUE(transform, NS_ERROR_OUT_OF_MEMORY);
     357               0 :   transform->SetSkewY(skew);
     358                 : 
     359               0 :   return NS_OK;
     360                 : }
     361                 : 
     362                 : 
     363                 : nsresult
     364               0 : SVGTransformListParser::MatchMatrix()
     365                 : {
     366               0 :   GetNextToken();
     367                 : 
     368                 :   float m[6];
     369                 :   PRUint32 count;
     370                 : 
     371               0 :   ENSURE_MATCHED(MatchNumberArguments(m, ArrayLength(m), &count));
     372                 : 
     373               0 :   if (count != 6) {
     374               0 :     return NS_ERROR_FAILURE;
     375                 :   }
     376                 : 
     377               0 :   SVGTransform* transform = mTransforms.AppendElement();
     378               0 :   NS_ENSURE_TRUE(transform, NS_ERROR_OUT_OF_MEMORY);
     379               0 :   transform->SetMatrix(gfxMatrix(m[0], m[1], m[2], m[3], m[4], m[5]));
     380                 : 
     381               0 :   return NS_OK;
     382                 : }

Generated by: LCOV version 1.7