LCOV - code coverage report
Current view: top level - svgio/source/svgreader - svggradientnode.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 116 183 63.4 %
Date: 2014-11-03 Functions: 18 18 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <svgio/svgreader/svggradientnode.hxx>
      21             : #include <svgio/svgreader/svgdocument.hxx>
      22             : #include <svgio/svgreader/svggradientstopnode.hxx>
      23             : 
      24             : namespace svgio
      25             : {
      26             :     namespace svgreader
      27             :     {
      28        1238 :         void SvgGradientNode::tryToFindLink()
      29             :         {
      30        1238 :             if(!mpXLink && !maXLink.isEmpty())
      31             :             {
      32           0 :                 mpXLink = dynamic_cast< const SvgGradientNode* >(getDocument().findSvgNodeById(maXLink));
      33             :             }
      34        1238 :         }
      35             : 
      36        1300 :         SvgGradientNode::SvgGradientNode(
      37             :             SVGToken aType,
      38             :             SvgDocument& rDocument,
      39             :             SvgNode* pParent)
      40             :         :   SvgNode(aType, rDocument, pParent),
      41             :             maSvgStyleAttributes(*this),
      42             :             maX1(),
      43             :             maY1(),
      44             :             maX2(),
      45             :             maY2(),
      46             :             maCx(),
      47             :             maCy(),
      48             :             maR(),
      49             :             maFx(),
      50             :             maFy(),
      51             :             maGradientUnits(objectBoundingBox),
      52             :             maSpreadMethod(drawinglayer::primitive2d::Spread_pad),
      53             :             mpaGradientTransform(0),
      54             :             maXLink(),
      55        1300 :             mpXLink(0)
      56             :         {
      57             :             OSL_ENSURE(aType == SVGTokenLinearGradient || aType == SVGTokenRadialGradient, "SvgGradientNode should ony be used for Linear and Radial gradient (!)");
      58        1300 :         }
      59             : 
      60        3900 :         SvgGradientNode::~SvgGradientNode()
      61             :         {
      62        1300 :             if(mpaGradientTransform) delete mpaGradientTransform;
      63             :             // do NOT delete mpXLink, it's only referenced, not owned
      64        2600 :         }
      65             : 
      66        9396 :         const SvgStyleAttributes* SvgGradientNode::getSvgStyleAttributes() const
      67             :         {
      68        9396 :             OUString aClassStrA("linearGradient");
      69       18792 :             OUString aClassStrB("radialGradient");
      70             : 
      71             :             return checkForCssStyle(
      72        9396 :                 SVGTokenLinearGradient == getType() ? aClassStrA : aClassStrB,
      73       28188 :                 maSvgStyleAttributes);
      74             :         }
      75             : 
      76        7918 :         void SvgGradientNode::parseAttribute(const OUString& rTokenName, SVGToken aSVGToken, const OUString& aContent)
      77             :         {
      78             :             // call parent
      79        7918 :             SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
      80             : 
      81             :             // read style attributes
      82        7918 :             maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent, false);
      83             : 
      84             :             // parse own
      85        7918 :             switch(aSVGToken)
      86             :             {
      87             :                 case SVGTokenStyle:
      88             :                 {
      89           0 :                     readLocalCssStyle(aContent);
      90           0 :                     break;
      91             :                 }
      92             :                 case SVGTokenX1:
      93             :                 {
      94        1197 :                     SvgNumber aNum;
      95             : 
      96        1197 :                     if(readSingleNumber(aContent, aNum))
      97             :                     {
      98        1197 :                         setX1(aNum);
      99             :                     }
     100        1197 :                     break;
     101             :                 }
     102             :                 case SVGTokenY1:
     103             :                 {
     104        1197 :                     SvgNumber aNum;
     105             : 
     106        1197 :                     if(readSingleNumber(aContent, aNum))
     107             :                     {
     108        1197 :                         setY1(aNum);
     109             :                     }
     110        1197 :                     break;
     111             :                 }
     112             :                 case SVGTokenX2:
     113             :                 {
     114        1197 :                     SvgNumber aNum;
     115             : 
     116        1197 :                     if(readSingleNumber(aContent, aNum))
     117             :                     {
     118        1197 :                         setX2(aNum);
     119             :                     }
     120        1197 :                     break;
     121             :                 }
     122             :                 case SVGTokenY2:
     123             :                 {
     124        1197 :                     SvgNumber aNum;
     125             : 
     126        1197 :                     if(readSingleNumber(aContent, aNum))
     127             :                     {
     128        1197 :                         setY2(aNum);
     129             :                     }
     130        1197 :                     break;
     131             :                 }
     132             :                 case SVGTokenCx:
     133             :                 {
     134         103 :                     SvgNumber aNum;
     135             : 
     136         103 :                     if(readSingleNumber(aContent, aNum))
     137             :                     {
     138         103 :                         setCx(aNum);
     139             :                     }
     140         103 :                     break;
     141             :                 }
     142             :                 case SVGTokenCy:
     143             :                 {
     144         103 :                     SvgNumber aNum;
     145             : 
     146         103 :                     if(readSingleNumber(aContent, aNum))
     147             :                     {
     148         103 :                         setCy(aNum);
     149             :                     }
     150         103 :                     break;
     151             :                 }
     152             :                 case SVGTokenFx:
     153             :                 {
     154           0 :                     SvgNumber aNum;
     155             : 
     156           0 :                     if(readSingleNumber(aContent, aNum))
     157             :                     {
     158           0 :                         setFx(aNum);
     159             :                     }
     160           0 :                     break;
     161             :                 }
     162             :                 case SVGTokenFy:
     163             :                 {
     164           0 :                     SvgNumber aNum;
     165             : 
     166           0 :                     if(readSingleNumber(aContent, aNum))
     167             :                     {
     168           0 :                         setFy(aNum);
     169             :                     }
     170           0 :                     break;
     171             :                 }
     172             :                 case SVGTokenR:
     173             :                 {
     174         103 :                     SvgNumber aNum;
     175             : 
     176         103 :                     if(readSingleNumber(aContent, aNum))
     177             :                     {
     178         103 :                         if(aNum.isPositive())
     179             :                         {
     180         103 :                             setR(aNum);
     181             :                         }
     182             :                     }
     183         103 :                     break;
     184             :                 }
     185             :                 case SVGTokenGradientUnits:
     186             :                 {
     187        1300 :                     if(!aContent.isEmpty())
     188             :                     {
     189        1300 :                         if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
     190             :                         {
     191        1300 :                             setGradientUnits(userSpaceOnUse);
     192             :                         }
     193           0 :                         else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
     194             :                         {
     195           0 :                             setGradientUnits(objectBoundingBox);
     196             :                         }
     197             :                     }
     198        1300 :                     break;
     199             :                 }
     200             :                 case SVGTokenSpreadMethod:
     201             :                 {
     202           0 :                     if(!aContent.isEmpty())
     203             :                     {
     204           0 :                         if(aContent.startsWith("pad"))
     205             :                         {
     206           0 :                             setSpreadMethod(drawinglayer::primitive2d::Spread_pad);
     207             :                         }
     208           0 :                         else if(aContent.startsWith("reflect"))
     209             :                         {
     210           0 :                             setSpreadMethod(drawinglayer::primitive2d::Spread_reflect);
     211             :                         }
     212           0 :                         else if(aContent.startsWith("repeat"))
     213             :                         {
     214           0 :                             setSpreadMethod(drawinglayer::primitive2d::Spread_repeat);
     215             :                         }
     216             :                     }
     217           0 :                     break;
     218             :                 }
     219             :                 case SVGTokenGradientTransform:
     220             :                 {
     221         221 :                     const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
     222             : 
     223         221 :                     if(!aMatrix.isIdentity())
     224             :                     {
     225         221 :                         setGradientTransform(&aMatrix);
     226             :                     }
     227         221 :                     break;
     228             :                 }
     229             :                 case SVGTokenXlinkHref:
     230             :                 {
     231           0 :                     const sal_Int32 nLen(aContent.getLength());
     232             : 
     233           0 :                     if(nLen && '#' == aContent[0])
     234             :                     {
     235           0 :                         maXLink = aContent.copy(1);
     236           0 :                         tryToFindLink();
     237             :                     }
     238           0 :                     break;
     239             :                 }
     240             :                 default:
     241             :                 {
     242        1300 :                     break;
     243             :                 }
     244             :             }
     245        7918 :         }
     246             : 
     247        1244 :         void SvgGradientNode::collectGradientEntries(drawinglayer::primitive2d::SvgGradientEntryVector& aVector) const
     248             :         {
     249        1244 :             if(getChildren().empty())
     250             :             {
     251           0 :                 const_cast< SvgGradientNode* >(this)->tryToFindLink();
     252             : 
     253           0 :                 if(mpXLink)
     254             :                 {
     255           0 :                     mpXLink->collectGradientEntries(aVector);
     256             :                 }
     257             :             }
     258             :             else
     259             :             {
     260        1244 :                 const sal_uInt32 nCount(getChildren().size());
     261             : 
     262        4557 :                 for(sal_uInt32 a(0); a < nCount; a++)
     263             :                 {
     264        3313 :                     const SvgGradientStopNode* pCandidate = dynamic_cast< const SvgGradientStopNode* >(getChildren()[a]);
     265             : 
     266        3313 :                     if(pCandidate)
     267             :                     {
     268        3313 :                         const SvgStyleAttributes* pStyle = pCandidate->getSvgStyleAttributes();
     269             : 
     270        3313 :                         if(pStyle)
     271             :                         {
     272        3313 :                             const SvgNumber aOffset(pCandidate->getOffset());
     273        3313 :                             double fOffset(0.0);
     274             : 
     275        3313 :                             if(Unit_percent == aOffset.getUnit())
     276             :                             {
     277             :                                 // percent is not relative to distances in ColorStop context, solve locally
     278           0 :                                 fOffset = aOffset.getNumber() * 0.01;
     279             :                             }
     280             :                             else
     281             :                             {
     282        3313 :                                 fOffset = aOffset.solve(*this);
     283             :                             }
     284             : 
     285        3313 :                             if(fOffset < 0.0)
     286             :                             {
     287             :                                 OSL_ENSURE(false, "OOps, SvgGradientStopNode with offset out of range (!)");
     288           0 :                                 fOffset = 0.0;
     289             :                             }
     290        3313 :                             else if(fOffset > 1.0)
     291             :                             {
     292             :                                 OSL_ENSURE(false, "OOps, SvgGradientStopNode with offset out of range (!)");
     293           0 :                                 fOffset = 1.0;
     294             :                             }
     295             : 
     296             :                             aVector.push_back(
     297             :                                 drawinglayer::primitive2d::SvgGradientEntry(
     298             :                                     fOffset,
     299        3313 :                                     pStyle->getStopColor(),
     300        6626 :                                     pStyle->getStopOpacity().solve(*this)));
     301             :                         }
     302             :                         else
     303             :                         {
     304             :                             OSL_ENSURE(false, "OOps, SvgGradientStopNode without Style (!)");
     305             :                         }
     306             :                     }
     307             :                 }
     308             :             }
     309        1244 :         }
     310             : 
     311        1145 :         const SvgNumber SvgGradientNode::getX1() const
     312             :         {
     313        1145 :             if(maX1.isSet())
     314             :             {
     315        1145 :                 return maX1;
     316             :             }
     317             : 
     318           0 :             const_cast< SvgGradientNode* >(this)->tryToFindLink();
     319             : 
     320           0 :             if(mpXLink)
     321             :             {
     322           0 :                 return mpXLink->getX1();
     323             :             }
     324             : 
     325             :             // default is 0%
     326           0 :             return SvgNumber(0.0, Unit_percent);
     327             :         }
     328             : 
     329        1145 :         const SvgNumber SvgGradientNode::getY1() const
     330             :         {
     331        1145 :             if(maY1.isSet())
     332             :             {
     333        1145 :                 return maY1;
     334             :             }
     335             : 
     336           0 :             const_cast< SvgGradientNode* >(this)->tryToFindLink();
     337             : 
     338           0 :             if(mpXLink)
     339             :             {
     340           0 :                 return mpXLink->getY1();
     341             :             }
     342             : 
     343             :             // default is 0%
     344           0 :             return SvgNumber(0.0, Unit_percent);
     345             :         }
     346             : 
     347        1145 :         const SvgNumber SvgGradientNode::getX2() const
     348             :         {
     349        1145 :             if(maX2.isSet())
     350             :             {
     351        1145 :                 return maX2;
     352             :             }
     353             : 
     354           0 :             const_cast< SvgGradientNode* >(this)->tryToFindLink();
     355             : 
     356           0 :             if(mpXLink)
     357             :             {
     358           0 :                 return mpXLink->getX2();
     359             :             }
     360             : 
     361             :             // default is 100%
     362           0 :             return SvgNumber(100.0, Unit_percent);
     363             :         }
     364             : 
     365        1145 :         const SvgNumber SvgGradientNode::getY2() const
     366             :         {
     367        1145 :             if(maY2.isSet())
     368             :             {
     369        1145 :                 return maY2;
     370             :             }
     371             : 
     372           0 :             const_cast< SvgGradientNode* >(this)->tryToFindLink();
     373             : 
     374           0 :             if(mpXLink)
     375             :             {
     376           0 :                 return mpXLink->getY2();
     377             :             }
     378             : 
     379             :             // default is 0%
     380           0 :             return SvgNumber(0.0, Unit_percent);
     381             :         }
     382             : 
     383          99 :         const SvgNumber SvgGradientNode::getCx() const
     384             :         {
     385          99 :             if(maCx.isSet())
     386             :             {
     387          99 :                 return maCx;
     388             :             }
     389             : 
     390           0 :             const_cast< SvgGradientNode* >(this)->tryToFindLink();
     391             : 
     392           0 :             if(mpXLink)
     393             :             {
     394           0 :                 return mpXLink->getCx();
     395             :             }
     396             : 
     397             :             // default is 50%
     398           0 :             return SvgNumber(50.0, Unit_percent);
     399             :         }
     400             : 
     401          99 :         const SvgNumber SvgGradientNode::getCy() const
     402             :         {
     403          99 :             if(maCy.isSet())
     404             :             {
     405          99 :                 return maCy;
     406             :             }
     407             : 
     408           0 :             const_cast< SvgGradientNode* >(this)->tryToFindLink();
     409             : 
     410           0 :             if(mpXLink)
     411             :             {
     412           0 :                 return mpXLink->getCy();
     413             :             }
     414             : 
     415             :             // default is 50%
     416           0 :             return SvgNumber(50.0, Unit_percent);
     417             :         }
     418             : 
     419          99 :         const SvgNumber SvgGradientNode::getR() const
     420             :         {
     421          99 :             if(maR.isSet())
     422             :             {
     423          99 :                 return maR;
     424             :             }
     425             : 
     426           0 :             const_cast< SvgGradientNode* >(this)->tryToFindLink();
     427             : 
     428           0 :             if(mpXLink)
     429             :             {
     430           0 :                 return mpXLink->getR();
     431             :             }
     432             : 
     433             :             // default is 50%
     434           0 :             return SvgNumber(50.0, Unit_percent);
     435             :         }
     436             : 
     437          99 :         const SvgNumber* SvgGradientNode::getFx() const
     438             :         {
     439          99 :             if(maFx.isSet())
     440             :             {
     441           0 :                 return &maFx;
     442             :             }
     443             : 
     444          99 :             const_cast< SvgGradientNode* >(this)->tryToFindLink();
     445             : 
     446          99 :             if(mpXLink)
     447             :             {
     448           0 :                 return mpXLink->getFx();
     449             :             }
     450             : 
     451          99 :             return 0;
     452             :         }
     453             : 
     454          99 :         const SvgNumber* SvgGradientNode::getFy() const
     455             :         {
     456          99 :             if(maFy.isSet())
     457             :             {
     458           0 :                 return &maFy;
     459             :             }
     460             : 
     461          99 :             const_cast< SvgGradientNode* >(this)->tryToFindLink();
     462             : 
     463          99 :             if(mpXLink)
     464             :             {
     465           0 :                 return mpXLink->getFy();
     466             :             }
     467             : 
     468          99 :             return 0;
     469             :         }
     470             : 
     471        1448 :         const basegfx::B2DHomMatrix* SvgGradientNode::getGradientTransform() const
     472             :         {
     473        1448 :             if(mpaGradientTransform)
     474             :             {
     475         408 :                 return mpaGradientTransform;
     476             :             }
     477             : 
     478        1040 :             const_cast< SvgGradientNode* >(this)->tryToFindLink();
     479             : 
     480        1040 :             if(mpXLink)
     481             :             {
     482           0 :                 return mpXLink->getGradientTransform();
     483             :             }
     484             : 
     485        1040 :             return 0;
     486             :         }
     487             : 
     488         221 :         void SvgGradientNode::setGradientTransform(const basegfx::B2DHomMatrix* pMatrix)
     489             :         {
     490         221 :             if(mpaGradientTransform)
     491             :             {
     492           0 :                 delete mpaGradientTransform;
     493           0 :                 mpaGradientTransform = 0;
     494             :             }
     495             : 
     496         221 :             if(pMatrix)
     497             :             {
     498         221 :                 mpaGradientTransform = new basegfx::B2DHomMatrix(*pMatrix);
     499             :             }
     500         221 :         }
     501             : 
     502             :     } // end of namespace svgreader
     503             : } // end of namespace svgio
     504             : 
     505             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10