LCOV - code coverage report
Current view: directory - content/svg/content/src - nsSVGMarkerElement.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 129 2 1.6 %
Date: 2012-06-02 Functions: 42 2 4.8 %

       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 the Mozilla SVG project.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is IBM Corporation.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2004
      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 of the GNU General Public License Version 2 or later (the "GPL"),
      25                 :  * or 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 "mozilla/Util.h"
      38                 : 
      39                 : #include "nsGkAtoms.h"
      40                 : #include "nsCOMPtr.h"
      41                 : #include "SVGAnimatedPreserveAspectRatio.h"
      42                 : #include "nsDOMError.h"
      43                 : #include "nsSVGUtils.h"
      44                 : #include "nsSVGMarkerElement.h"
      45                 : #include "gfxMatrix.h"
      46                 : #include "nsContentUtils.h" // NS_ENSURE_FINITE
      47                 : 
      48                 : using namespace mozilla;
      49                 : 
      50                 : nsSVGElement::LengthInfo nsSVGMarkerElement::sLengthInfo[4] =
      51                 : {
      52                 :   { &nsGkAtoms::refX, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, nsSVGUtils::X },
      53                 :   { &nsGkAtoms::refY, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, nsSVGUtils::Y },
      54                 :   { &nsGkAtoms::markerWidth, 3, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, nsSVGUtils::X },
      55                 :   { &nsGkAtoms::markerHeight, 3, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, nsSVGUtils::Y },
      56                 : };
      57                 : 
      58                 : nsSVGEnumMapping nsSVGMarkerElement::sUnitsMap[] = {
      59                 :   {&nsGkAtoms::strokeWidth, nsIDOMSVGMarkerElement::SVG_MARKERUNITS_STROKEWIDTH},
      60                 :   {&nsGkAtoms::userSpaceOnUse, nsIDOMSVGMarkerElement::SVG_MARKERUNITS_USERSPACEONUSE},
      61                 :   {nsnull, 0}
      62                 : };
      63                 : 
      64                 : nsSVGElement::EnumInfo nsSVGMarkerElement::sEnumInfo[1] =
      65                 : {
      66                 :   { &nsGkAtoms::markerUnits,
      67                 :     sUnitsMap,
      68                 :     nsIDOMSVGMarkerElement::SVG_MARKERUNITS_STROKEWIDTH
      69                 :   }
      70                 : };
      71                 : 
      72                 : nsSVGElement::AngleInfo nsSVGMarkerElement::sAngleInfo[1] =
      73                 : {
      74                 :   { &nsGkAtoms::orient, 0, nsIDOMSVGAngle::SVG_ANGLETYPE_UNSPECIFIED }
      75                 : };
      76                 : 
      77               0 : NS_IMPL_NS_NEW_SVG_ELEMENT(Marker)
      78                 : 
      79                 : //----------------------------------------------------------------------
      80                 : // nsISupports methods
      81                 : 
      82            1464 : NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGOrientType::DOMAnimatedEnum, mSVGElement)
      83                 : 
      84               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGOrientType::DOMAnimatedEnum)
      85               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGOrientType::DOMAnimatedEnum)
      86                 : 
      87               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGOrientType::DOMAnimatedEnum)
      88               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedEnumeration)
      89               0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
      90               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedEnumeration)
      91               0 : NS_INTERFACE_MAP_END
      92                 : 
      93               0 : NS_IMPL_ADDREF_INHERITED(nsSVGMarkerElement,nsSVGMarkerElementBase)
      94               0 : NS_IMPL_RELEASE_INHERITED(nsSVGMarkerElement,nsSVGMarkerElementBase)
      95                 : 
      96               0 : DOMCI_NODE_DATA(SVGMarkerElement, nsSVGMarkerElement)
      97                 : 
      98               0 : NS_INTERFACE_TABLE_HEAD(nsSVGMarkerElement)
      99               0 :   NS_NODE_INTERFACE_TABLE5(nsSVGMarkerElement, nsIDOMNode, nsIDOMElement,
     100                 :                            nsIDOMSVGElement, nsIDOMSVGFitToViewBox,
     101                 :                            nsIDOMSVGMarkerElement)
     102               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGMarkerElement)
     103               0 : NS_INTERFACE_MAP_END_INHERITING(nsSVGMarkerElementBase)
     104                 : 
     105                 : //----------------------------------------------------------------------
     106                 : // Implementation
     107                 : 
     108                 : nsresult
     109               0 : nsSVGOrientType::SetBaseValue(PRUint16 aValue,
     110                 :                               nsSVGElement *aSVGElement)
     111                 : {
     112               0 :   if (aValue == nsIDOMSVGMarkerElement::SVG_MARKER_ORIENT_AUTO ||
     113                 :       aValue == nsIDOMSVGMarkerElement::SVG_MARKER_ORIENT_ANGLE) {
     114               0 :     SetBaseValue(aValue);
     115                 :     aSVGElement->SetAttr(
     116                 :       kNameSpaceID_None, nsGkAtoms::orient, nsnull,
     117                 :       (aValue ==nsIDOMSVGMarkerElement::SVG_MARKER_ORIENT_AUTO ?
     118               0 :         NS_LITERAL_STRING("auto") : NS_LITERAL_STRING("0")),
     119               0 :       true);
     120               0 :     return NS_OK;
     121                 :   }
     122               0 :   return NS_ERROR_DOM_SYNTAX_ERR;
     123                 : }
     124                 : 
     125                 : nsresult
     126               0 : nsSVGOrientType::ToDOMAnimatedEnum(nsIDOMSVGAnimatedEnumeration **aResult,
     127                 :                                    nsSVGElement *aSVGElement)
     128                 : {
     129               0 :   *aResult = new DOMAnimatedEnum(this, aSVGElement);
     130               0 :   if (!*aResult)
     131               0 :     return NS_ERROR_OUT_OF_MEMORY;
     132                 : 
     133               0 :   NS_ADDREF(*aResult);
     134               0 :   return NS_OK;
     135                 : }
     136                 : 
     137               0 : nsSVGMarkerElement::nsSVGMarkerElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     138               0 :   : nsSVGMarkerElementBase(aNodeInfo), mCoordCtx(nsnull)
     139                 : {
     140               0 : }
     141                 : 
     142                 : //----------------------------------------------------------------------
     143                 : // nsIDOMNode methods
     144                 : 
     145               0 : NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGMarkerElement)
     146                 : 
     147                 : //----------------------------------------------------------------------
     148                 : // nsIDOMSVGFitToViewBox methods
     149                 : 
     150                 : /* readonly attribute nsIDOMSVGAnimatedRect viewBox; */
     151               0 :   NS_IMETHODIMP nsSVGMarkerElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox)
     152                 : {
     153               0 :   return mViewBox.ToDOMAnimatedRect(aViewBox, this);
     154                 : }
     155                 : 
     156                 : /* readonly attribute nsIDOMSVGAnimatedPreserveAspectRatio preserveAspectRatio; */
     157                 : NS_IMETHODIMP
     158               0 : nsSVGMarkerElement::GetPreserveAspectRatio(nsIDOMSVGAnimatedPreserveAspectRatio
     159                 :                                            **aPreserveAspectRatio)
     160                 : {
     161               0 :   return mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(aPreserveAspectRatio, this);
     162                 : }
     163                 : 
     164                 : //----------------------------------------------------------------------
     165                 : // nsIDOMSVGMarkerElement methods
     166                 : 
     167                 : /* readonly attribute nsIDOMSVGAnimatedLength refX; */
     168               0 : NS_IMETHODIMP nsSVGMarkerElement::GetRefX(nsIDOMSVGAnimatedLength * *aRefX)
     169                 : {
     170               0 :   return mLengthAttributes[REFX].ToDOMAnimatedLength(aRefX, this);
     171                 : }
     172                 : 
     173                 : /* readonly attribute nsIDOMSVGAnimatedLength refY; */
     174               0 : NS_IMETHODIMP nsSVGMarkerElement::GetRefY(nsIDOMSVGAnimatedLength * *aRefY)
     175                 : {
     176               0 :   return mLengthAttributes[REFY].ToDOMAnimatedLength(aRefY, this);
     177                 : }
     178                 : 
     179                 : /* readonly attribute nsIDOMSVGAnimatedEnumeration markerUnits; */
     180               0 : NS_IMETHODIMP nsSVGMarkerElement::GetMarkerUnits(nsIDOMSVGAnimatedEnumeration * *aMarkerUnits)
     181                 : {
     182               0 :   return mEnumAttributes[MARKERUNITS].ToDOMAnimatedEnum(aMarkerUnits, this);
     183                 : }
     184                 : 
     185                 : /* readonly attribute nsIDOMSVGAnimatedLength markerWidth; */
     186               0 : NS_IMETHODIMP nsSVGMarkerElement::GetMarkerWidth(nsIDOMSVGAnimatedLength * *aMarkerWidth)
     187                 : {
     188               0 :   return mLengthAttributes[MARKERWIDTH].ToDOMAnimatedLength(aMarkerWidth, this);
     189                 : }
     190                 : 
     191                 : /* readonly attribute nsIDOMSVGAnimatedLength markerHeight; */
     192               0 : NS_IMETHODIMP nsSVGMarkerElement::GetMarkerHeight(nsIDOMSVGAnimatedLength * *aMarkerHeight)
     193                 : {
     194               0 :   return mLengthAttributes[MARKERHEIGHT].ToDOMAnimatedLength(aMarkerHeight, this);
     195                 : }
     196                 : 
     197                 : /* readonly attribute nsIDOMSVGAnimatedEnumeration orientType; */
     198               0 : NS_IMETHODIMP nsSVGMarkerElement::GetOrientType(nsIDOMSVGAnimatedEnumeration * *aOrientType)
     199                 : {
     200               0 :   return mOrientType.ToDOMAnimatedEnum(aOrientType, this);
     201                 : }
     202                 : 
     203                 : /* readonly attribute nsIDOMSVGAnimatedLength orientAngle; */
     204               0 : NS_IMETHODIMP nsSVGMarkerElement::GetOrientAngle(nsIDOMSVGAnimatedAngle * *aOrientAngle)
     205                 : {
     206               0 :   return mAngleAttributes[ORIENT].ToDOMAnimatedAngle(aOrientAngle, this);
     207                 : }
     208                 : 
     209                 : /* void setOrientToAuto (); */
     210               0 : NS_IMETHODIMP nsSVGMarkerElement::SetOrientToAuto()
     211                 : {
     212                 :   SetAttr(kNameSpaceID_None, nsGkAtoms::orient, nsnull,
     213               0 :           NS_LITERAL_STRING("auto"), true);
     214               0 :   return NS_OK;
     215                 : }
     216                 : 
     217                 : /* void setOrientToAngle (in nsIDOMSVGAngle angle); */
     218               0 : NS_IMETHODIMP nsSVGMarkerElement::SetOrientToAngle(nsIDOMSVGAngle *angle)
     219                 : {
     220               0 :   if (!angle)
     221               0 :     return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
     222                 : 
     223                 :   float f;
     224               0 :   nsresult rv = angle->GetValue(&f);
     225               0 :   NS_ENSURE_SUCCESS(rv, rv);
     226               0 :   NS_ENSURE_FINITE(f, NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
     227               0 :   mAngleAttributes[ORIENT].SetBaseValue(f, this, true);
     228                 : 
     229               0 :   return NS_OK;
     230                 : }
     231                 : 
     232                 : //----------------------------------------------------------------------
     233                 : // nsIContent methods
     234                 : 
     235                 : NS_IMETHODIMP_(bool)
     236               0 : nsSVGMarkerElement::IsAttributeMapped(const nsIAtom* name) const
     237                 : {
     238                 :   static const MappedAttributeEntry* const map[] = {
     239                 :     sFEFloodMap,
     240                 :     sFiltersMap,
     241                 :     sFontSpecificationMap,
     242                 :     sGradientStopMap,
     243                 :     sLightingEffectsMap,
     244                 :     sMarkersMap,
     245                 :     sTextContentElementsMap,
     246                 :     sViewportsMap
     247                 :   };
     248                 : 
     249               0 :   return FindAttributeDependence(name, map) ||
     250               0 :     nsSVGMarkerElementBase::IsAttributeMapped(name);
     251                 : }
     252                 : 
     253                 : //----------------------------------------------------------------------
     254                 : // nsSVGElement methods
     255                 : 
     256                 : bool
     257               0 : nsSVGMarkerElement::GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
     258                 :                             nsAString &aResult) const
     259                 : {
     260               0 :   if (aNameSpaceID == kNameSpaceID_None &&
     261                 :       aName == nsGkAtoms::orient &&
     262               0 :       mOrientType.GetBaseValue() == SVG_MARKER_ORIENT_AUTO) {
     263               0 :     aResult.AssignLiteral("auto");
     264               0 :     return true;
     265                 :   }
     266               0 :   return nsSVGMarkerElementBase::GetAttr(aNameSpaceID, aName, aResult);
     267                 : }
     268                 : 
     269                 : bool
     270               0 : nsSVGMarkerElement::ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
     271                 :                                    const nsAString& aValue,
     272                 :                                    nsAttrValue& aResult)
     273                 : {
     274               0 :   if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::orient) {
     275               0 :     if (aValue.EqualsLiteral("auto")) {
     276               0 :       mOrientType.SetBaseValue(SVG_MARKER_ORIENT_AUTO);
     277               0 :       aResult.SetTo(aValue);
     278               0 :       return true;
     279                 :     }
     280               0 :     mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE);
     281                 :   }
     282                 :   return nsSVGMarkerElementBase::ParseAttribute(aNameSpaceID, aName,
     283               0 :                                                 aValue, aResult);
     284                 : }
     285                 : 
     286                 : nsresult
     287               0 : nsSVGMarkerElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
     288                 :                               bool aNotify)
     289                 : {
     290               0 :   if (aNamespaceID == kNameSpaceID_None) {
     291               0 :     if (aName == nsGkAtoms::orient) {
     292               0 :       mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE);
     293                 :     }
     294                 :   }
     295                 : 
     296               0 :   return nsSVGMarkerElementBase::UnsetAttr(aNamespaceID, aName, aNotify);
     297                 : }
     298                 : 
     299                 : //----------------------------------------------------------------------
     300                 : // nsSVGElement methods
     301                 : 
     302                 : void 
     303               0 : nsSVGMarkerElement::SetParentCoordCtxProvider(nsSVGSVGElement *aContext)
     304                 : {
     305               0 :   mCoordCtx = aContext;
     306               0 :   mViewBoxToViewportTransform = nsnull;
     307               0 : }
     308                 : 
     309                 : /* virtual */ bool
     310               0 : nsSVGMarkerElement::HasValidDimensions() const
     311                 : {
     312               0 :   return (!mLengthAttributes[MARKERWIDTH].IsExplicitlySet() ||
     313               0 :            mLengthAttributes[MARKERWIDTH].GetAnimValInSpecifiedUnits() > 0) &&
     314               0 :          (!mLengthAttributes[MARKERHEIGHT].IsExplicitlySet() || 
     315               0 :            mLengthAttributes[MARKERHEIGHT].GetAnimValInSpecifiedUnits() > 0);
     316                 : }
     317                 : 
     318                 : nsSVGElement::LengthAttributesInfo
     319               0 : nsSVGMarkerElement::GetLengthInfo()
     320                 : {
     321                 :   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
     322               0 :                               ArrayLength(sLengthInfo));
     323                 : }
     324                 : 
     325                 : nsSVGElement::AngleAttributesInfo
     326               0 : nsSVGMarkerElement::GetAngleInfo()
     327                 : {
     328                 :   return AngleAttributesInfo(mAngleAttributes, sAngleInfo,
     329               0 :                              ArrayLength(sAngleInfo));
     330                 : }
     331                 : 
     332                 : nsSVGElement::EnumAttributesInfo
     333               0 : nsSVGMarkerElement::GetEnumInfo()
     334                 : {
     335                 :   return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
     336               0 :                             ArrayLength(sEnumInfo));
     337                 : }
     338                 : 
     339                 : nsSVGViewBox *
     340               0 : nsSVGMarkerElement::GetViewBox()
     341                 : {
     342               0 :   return &mViewBox;
     343                 : }
     344                 : 
     345                 : SVGAnimatedPreserveAspectRatio *
     346               0 : nsSVGMarkerElement::GetPreserveAspectRatio()
     347                 : {
     348               0 :   return &mPreserveAspectRatio;
     349                 : }
     350                 : 
     351                 : //----------------------------------------------------------------------
     352                 : // public helpers
     353                 : 
     354                 : gfxMatrix
     355               0 : nsSVGMarkerElement::GetMarkerTransform(float aStrokeWidth,
     356                 :                                        float aX, float aY, float aAutoAngle)
     357                 : {
     358               0 :   gfxFloat scale = mEnumAttributes[MARKERUNITS].GetAnimValue() ==
     359               0 :                      SVG_MARKERUNITS_STROKEWIDTH ? aStrokeWidth : 1.0;
     360                 : 
     361               0 :   gfxFloat angle = mOrientType.GetAnimValue() == SVG_MARKER_ORIENT_AUTO ?
     362                 :                     aAutoAngle :
     363               0 :                     mAngleAttributes[ORIENT].GetAnimValue() * M_PI / 180.0;
     364                 : 
     365               0 :   return gfxMatrix(cos(angle) * scale,   sin(angle) * scale,
     366               0 :                    -sin(angle) * scale,  cos(angle) * scale,
     367               0 :                    aX,                    aY);
     368                 : }
     369                 : 
     370                 : nsSVGViewBoxRect
     371               0 : nsSVGMarkerElement::GetViewBoxRect()
     372                 : {
     373               0 :   if (mViewBox.IsValid()) {
     374               0 :     return mViewBox.GetAnimValue();
     375                 :   }
     376                 :   return nsSVGViewBoxRect(
     377                 :            0, 0,
     378                 :            mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx),
     379               0 :            mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx));
     380                 : }
     381                 : 
     382                 : gfxMatrix
     383               0 : nsSVGMarkerElement::GetViewBoxTransform()
     384                 : {
     385               0 :   if (!mViewBoxToViewportTransform) {
     386                 :     float viewportWidth =
     387               0 :       mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx);
     388                 :     float viewportHeight = 
     389               0 :       mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx);
     390                 :    
     391               0 :     nsSVGViewBoxRect viewbox = GetViewBoxRect();
     392                 : 
     393               0 :     NS_ABORT_IF_FALSE(viewbox.width > 0.0f && viewbox.height > 0.0f,
     394                 :                       "Rendering should be disabled");
     395                 : 
     396                 :     gfxMatrix viewBoxTM =
     397                 :       nsSVGUtils::GetViewBoxTransform(this,
     398                 :                                       viewportWidth, viewportHeight,
     399                 :                                       viewbox.x, viewbox.y,
     400                 :                                       viewbox.width, viewbox.height,
     401               0 :                                       mPreserveAspectRatio);
     402                 : 
     403               0 :     float refX = mLengthAttributes[REFX].GetAnimValue(mCoordCtx);
     404               0 :     float refY = mLengthAttributes[REFY].GetAnimValue(mCoordCtx);
     405                 : 
     406               0 :     gfxPoint ref = viewBoxTM.Transform(gfxPoint(refX, refY));
     407                 : 
     408               0 :     gfxMatrix TM = viewBoxTM * gfxMatrix().Translate(gfxPoint(-ref.x, -ref.y));
     409                 : 
     410               0 :     mViewBoxToViewportTransform = new gfxMatrix(TM);
     411                 :   }
     412                 : 
     413               0 :   return *mViewBoxToViewportTransform;
     414            4392 : }
     415                 : 
     416                 : 

Generated by: LCOV version 1.7