LCOV - code coverage report
Current view: top level - dom/svg - SVGMarkerElement.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 130 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 31 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/ArrayUtils.h"
       8             : 
       9             : #include "nsGkAtoms.h"
      10             : #include "nsCOMPtr.h"
      11             : #include "SVGAnimatedPreserveAspectRatio.h"
      12             : #include "nsError.h"
      13             : #include "mozilla/dom/SVGAngle.h"
      14             : #include "mozilla/dom/SVGMarkerElement.h"
      15             : #include "mozilla/dom/SVGMarkerElementBinding.h"
      16             : #include "mozilla/Preferences.h"
      17             : #include "mozilla/gfx/Matrix.h"
      18             : #include "mozilla/FloatingPoint.h"
      19             : #include "SVGContentUtils.h"
      20             : 
      21             : using namespace mozilla::gfx;
      22             : 
      23           0 : NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Marker)
      24             : 
      25             : namespace mozilla {
      26             : namespace dom {
      27             : 
      28             : JSObject*
      29           0 : SVGMarkerElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
      30             : {
      31           0 :   return SVGMarkerElementBinding::Wrap(aCx, this, aGivenProto);
      32             : }
      33             : 
      34             : nsSVGElement::LengthInfo SVGMarkerElement::sLengthInfo[4] =
      35             : {
      36             :   { &nsGkAtoms::refX, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
      37             :   { &nsGkAtoms::refY, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
      38             :   { &nsGkAtoms::markerWidth, 3, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
      39             :   { &nsGkAtoms::markerHeight, 3, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
      40             : };
      41             : 
      42             : nsSVGEnumMapping SVGMarkerElement::sUnitsMap[] = {
      43             :   {&nsGkAtoms::strokeWidth, SVG_MARKERUNITS_STROKEWIDTH},
      44             :   {&nsGkAtoms::userSpaceOnUse, SVG_MARKERUNITS_USERSPACEONUSE},
      45             :   {nullptr, 0}
      46             : };
      47             : 
      48             : nsSVGElement::EnumInfo SVGMarkerElement::sEnumInfo[1] =
      49             : {
      50             :   { &nsGkAtoms::markerUnits,
      51             :     sUnitsMap,
      52             :     SVG_MARKERUNITS_STROKEWIDTH
      53             :   }
      54             : };
      55             : 
      56             : nsSVGElement::AngleInfo SVGMarkerElement::sAngleInfo[1] =
      57             : {
      58             :   { &nsGkAtoms::orient, 0, SVG_ANGLETYPE_UNSPECIFIED }
      59             : };
      60             : 
      61             : //----------------------------------------------------------------------
      62             : // Implementation
      63             : 
      64             : nsresult
      65           0 : nsSVGOrientType::SetBaseValue(uint16_t aValue,
      66             :                               nsSVGElement *aSVGElement)
      67             : {
      68           0 :   if (aValue == SVG_MARKER_ORIENT_AUTO_START_REVERSE &&
      69           0 :       !SVGMarkerElement::MarkerImprovementsPrefEnabled()) {
      70           0 :     return NS_ERROR_DOM_SYNTAX_ERR;
      71             :   }
      72             : 
      73           0 :   if (aValue == SVG_MARKER_ORIENT_AUTO ||
      74           0 :       aValue == SVG_MARKER_ORIENT_ANGLE ||
      75             :       aValue == SVG_MARKER_ORIENT_AUTO_START_REVERSE) {
      76           0 :     SetBaseValue(aValue);
      77           0 :     aSVGElement->SetAttr(
      78             :       kNameSpaceID_None, nsGkAtoms::orient, nullptr,
      79             :       (aValue == SVG_MARKER_ORIENT_AUTO ?
      80           0 :         NS_LITERAL_STRING("auto") :
      81           0 :         aValue == SVG_MARKER_ORIENT_ANGLE ?
      82           0 :           NS_LITERAL_STRING("0") :
      83           0 :           NS_LITERAL_STRING("auto-start-reverse")),
      84           0 :       true);
      85           0 :     return NS_OK;
      86             :   }
      87           0 :   return NS_ERROR_DOM_SYNTAX_ERR;
      88             : }
      89             : 
      90             : already_AddRefed<SVGAnimatedEnumeration>
      91           0 : nsSVGOrientType::ToDOMAnimatedEnum(nsSVGElement *aSVGElement)
      92             : {
      93             :   RefPtr<SVGAnimatedEnumeration> toReturn =
      94           0 :     new DOMAnimatedEnum(this, aSVGElement);
      95           0 :   return toReturn.forget();
      96             : }
      97             : 
      98           0 : SVGMarkerElement::SVGMarkerElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
      99           0 :   : SVGMarkerElementBase(aNodeInfo), mCoordCtx(nullptr)
     100             : {
     101           0 : }
     102             : 
     103             : //----------------------------------------------------------------------
     104             : // nsIDOMNode methods
     105             : 
     106           0 : NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGMarkerElement)
     107             : 
     108             : //----------------------------------------------------------------------
     109             : 
     110             : already_AddRefed<SVGAnimatedRect>
     111           0 : SVGMarkerElement::ViewBox()
     112             : {
     113           0 :   return mViewBox.ToSVGAnimatedRect(this);
     114             : }
     115             : 
     116             : already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
     117           0 : SVGMarkerElement::PreserveAspectRatio()
     118             : {
     119           0 :   return mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(this);
     120             : }
     121             : 
     122             : //----------------------------------------------------------------------
     123             : 
     124             : already_AddRefed<SVGAnimatedLength>
     125           0 : SVGMarkerElement::RefX()
     126             : {
     127           0 :   return mLengthAttributes[REFX].ToDOMAnimatedLength(this);
     128             : }
     129             : 
     130             : already_AddRefed<SVGAnimatedLength>
     131           0 : SVGMarkerElement::RefY()
     132             : {
     133           0 :   return mLengthAttributes[REFY].ToDOMAnimatedLength(this);
     134             : }
     135             : 
     136             : already_AddRefed<SVGAnimatedEnumeration>
     137           0 : SVGMarkerElement::MarkerUnits()
     138             : {
     139           0 :   return mEnumAttributes[MARKERUNITS].ToDOMAnimatedEnum(this);
     140             : }
     141             : 
     142             : already_AddRefed<SVGAnimatedLength>
     143           0 : SVGMarkerElement::MarkerWidth()
     144             : {
     145           0 :   return mLengthAttributes[MARKERWIDTH].ToDOMAnimatedLength(this);
     146             : }
     147             : 
     148             : already_AddRefed<SVGAnimatedLength>
     149           0 : SVGMarkerElement::MarkerHeight()
     150             : {
     151           0 :   return mLengthAttributes[MARKERHEIGHT].ToDOMAnimatedLength(this);
     152             : }
     153             : 
     154             : already_AddRefed<SVGAnimatedEnumeration>
     155           0 : SVGMarkerElement::OrientType()
     156             : {
     157           0 :   return mOrientType.ToDOMAnimatedEnum(this);
     158             : }
     159             : 
     160             : already_AddRefed<SVGAnimatedAngle>
     161           0 : SVGMarkerElement::OrientAngle()
     162             : {
     163           0 :   return mAngleAttributes[ORIENT].ToDOMAnimatedAngle(this);
     164             : }
     165             : 
     166           0 : void SVGMarkerElement::SetOrientToAuto()
     167             : {
     168           0 :   SetAttr(kNameSpaceID_None, nsGkAtoms::orient, nullptr,
     169           0 :           NS_LITERAL_STRING("auto"), true);
     170           0 : }
     171             : 
     172             : void
     173           0 : SVGMarkerElement::SetOrientToAngle(SVGAngle& angle, ErrorResult& rv)
     174             : {
     175           0 :   float f = angle.Value();
     176           0 :   if (!IsFinite(f)) {
     177           0 :     rv.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
     178           0 :     return;
     179             :   }
     180           0 :   mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE);
     181           0 :   mAngleAttributes[ORIENT].SetBaseValue(f, this, true);
     182             : }
     183             : 
     184             : //----------------------------------------------------------------------
     185             : // nsIContent methods
     186             : 
     187             : NS_IMETHODIMP_(bool)
     188           0 : SVGMarkerElement::IsAttributeMapped(const nsIAtom* name) const
     189             : {
     190             :   static const MappedAttributeEntry* const map[] = {
     191             :     sFEFloodMap,
     192             :     sFiltersMap,
     193             :     sFontSpecificationMap,
     194             :     sGradientStopMap,
     195             :     sLightingEffectsMap,
     196             :     sMarkersMap,
     197             :     sTextContentElementsMap,
     198             :     sViewportsMap,
     199             :     sColorMap,
     200             :     sFillStrokeMap,
     201             :     sGraphicsMap
     202             :   };
     203             : 
     204           0 :   return FindAttributeDependence(name, map) ||
     205           0 :     SVGMarkerElementBase::IsAttributeMapped(name);
     206             : }
     207             : 
     208             : //----------------------------------------------------------------------
     209             : // nsSVGElement methods
     210             : 
     211             : bool
     212           0 : SVGMarkerElement::ParseAttribute(int32_t aNameSpaceID, nsIAtom* aName,
     213             :                                  const nsAString& aValue,
     214             :                                  nsAttrValue& aResult)
     215             : {
     216           0 :   if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::orient) {
     217           0 :     if (aValue.EqualsLiteral("auto")) {
     218           0 :       mOrientType.SetBaseValue(SVG_MARKER_ORIENT_AUTO);
     219           0 :       aResult.SetTo(aValue);
     220           0 :       mAngleAttributes[ORIENT].SetBaseValue(0.f, this, false);
     221           0 :       return true;
     222             :     }
     223           0 :     if (aValue.EqualsLiteral("auto-start-reverse") &&
     224           0 :         MarkerImprovementsPrefEnabled()) {
     225           0 :       mOrientType.SetBaseValue(SVG_MARKER_ORIENT_AUTO_START_REVERSE);
     226           0 :       aResult.SetTo(aValue);
     227           0 :       mAngleAttributes[ORIENT].SetBaseValue(0.f, this, false);
     228           0 :       return true;
     229             :     }
     230           0 :     mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE);
     231             :   }
     232           0 :   return SVGMarkerElementBase::ParseAttribute(aNameSpaceID, aName,
     233           0 :                                               aValue, aResult);
     234             : }
     235             : 
     236             : nsresult
     237           0 : SVGMarkerElement::UnsetAttr(int32_t aNamespaceID, nsIAtom* aName,
     238             :                             bool aNotify)
     239             : {
     240           0 :   if (aNamespaceID == kNameSpaceID_None) {
     241           0 :     if (aName == nsGkAtoms::orient) {
     242           0 :       mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE);
     243             :     }
     244             :   }
     245             : 
     246           0 :   return nsSVGElement::UnsetAttr(aNamespaceID, aName, aNotify);
     247             : }
     248             : 
     249             : //----------------------------------------------------------------------
     250             : // nsSVGElement methods
     251             : 
     252             : void
     253           0 : SVGMarkerElement::SetParentCoordCtxProvider(SVGSVGElement *aContext)
     254             : {
     255           0 :   mCoordCtx = aContext;
     256           0 :   mViewBoxToViewportTransform = nullptr;
     257           0 : }
     258             : 
     259             : /* virtual */ bool
     260           0 : SVGMarkerElement::HasValidDimensions() const
     261             : {
     262           0 :   return (!mLengthAttributes[MARKERWIDTH].IsExplicitlySet() ||
     263           0 :            mLengthAttributes[MARKERWIDTH].GetAnimValInSpecifiedUnits() > 0) &&
     264           0 :          (!mLengthAttributes[MARKERHEIGHT].IsExplicitlySet() ||
     265           0 :            mLengthAttributes[MARKERHEIGHT].GetAnimValInSpecifiedUnits() > 0);
     266             : }
     267             : 
     268             : nsSVGElement::LengthAttributesInfo
     269           0 : SVGMarkerElement::GetLengthInfo()
     270             : {
     271             :   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
     272           0 :                               ArrayLength(sLengthInfo));
     273             : }
     274             : 
     275             : nsSVGElement::AngleAttributesInfo
     276           0 : SVGMarkerElement::GetAngleInfo()
     277             : {
     278             :   return AngleAttributesInfo(mAngleAttributes, sAngleInfo,
     279           0 :                              ArrayLength(sAngleInfo));
     280             : }
     281             : 
     282             : nsSVGElement::EnumAttributesInfo
     283           0 : SVGMarkerElement::GetEnumInfo()
     284             : {
     285             :   return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
     286           0 :                             ArrayLength(sEnumInfo));
     287             : }
     288             : 
     289             : nsSVGViewBox *
     290           0 : SVGMarkerElement::GetViewBox()
     291             : {
     292           0 :   return &mViewBox;
     293             : }
     294             : 
     295             : SVGAnimatedPreserveAspectRatio *
     296           0 : SVGMarkerElement::GetPreserveAspectRatio()
     297             : {
     298           0 :   return &mPreserveAspectRatio;
     299             : }
     300             : 
     301             : //----------------------------------------------------------------------
     302             : // public helpers
     303             : 
     304             : gfx::Matrix
     305           0 : SVGMarkerElement::GetMarkerTransform(float aStrokeWidth,
     306             :                                      const nsSVGMark& aMark)
     307             : {
     308           0 :   float scale = mEnumAttributes[MARKERUNITS].GetAnimValue() ==
     309           0 :                      SVG_MARKERUNITS_STROKEWIDTH ? aStrokeWidth : 1.0f;
     310             : 
     311             :   float angle;
     312           0 :   switch (mOrientType.GetAnimValueInternal()) {
     313             :     case SVG_MARKER_ORIENT_AUTO:
     314           0 :       angle = aMark.angle;
     315           0 :       break;
     316             :     case SVG_MARKER_ORIENT_AUTO_START_REVERSE:
     317           0 :       angle = aMark.angle + (aMark.type == nsSVGMark::eStart ? M_PI : 0.0f);
     318           0 :       break;
     319             :     default: // SVG_MARKER_ORIENT_ANGLE
     320           0 :       angle = mAngleAttributes[ORIENT].GetAnimValue() * M_PI / 180.0f;
     321           0 :       break;
     322             :   }
     323             : 
     324           0 :   return gfx::Matrix(cos(angle) * scale,   sin(angle) * scale,
     325           0 :                      -sin(angle) * scale,  cos(angle) * scale,
     326           0 :                      aMark.x,              aMark.y);
     327             : }
     328             : 
     329             : nsSVGViewBoxRect
     330           0 : SVGMarkerElement::GetViewBoxRect()
     331             : {
     332           0 :   if (mViewBox.HasRect()) {
     333           0 :     return mViewBox.GetAnimValue();
     334             :   }
     335             :   return nsSVGViewBoxRect(
     336             :            0, 0,
     337             :            mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx),
     338           0 :            mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx));
     339             : }
     340             : 
     341             : gfx::Matrix
     342           0 : SVGMarkerElement::GetViewBoxTransform()
     343             : {
     344           0 :   if (!mViewBoxToViewportTransform) {
     345             :     float viewportWidth =
     346           0 :       mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx);
     347             :     float viewportHeight =
     348           0 :       mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx);
     349             : 
     350           0 :     nsSVGViewBoxRect viewbox = GetViewBoxRect();
     351             : 
     352           0 :     MOZ_ASSERT(viewbox.width > 0.0f && viewbox.height > 0.0f,
     353             :                "Rendering should be disabled");
     354             : 
     355             :     gfx::Matrix viewBoxTM =
     356             :       SVGContentUtils::GetViewBoxTransform(viewportWidth, viewportHeight,
     357             :                                            viewbox.x, viewbox.y,
     358             :                                            viewbox.width, viewbox.height,
     359           0 :                                            mPreserveAspectRatio);
     360             : 
     361           0 :     float refX = mLengthAttributes[REFX].GetAnimValue(mCoordCtx);
     362           0 :     float refY = mLengthAttributes[REFY].GetAnimValue(mCoordCtx);
     363             : 
     364           0 :     gfx::Point ref = viewBoxTM.TransformPoint(gfx::Point(refX, refY));
     365             : 
     366           0 :     Matrix TM = viewBoxTM;
     367           0 :     TM.PostTranslate(-ref.x, -ref.y);
     368             : 
     369           0 :     mViewBoxToViewportTransform = new gfx::Matrix(TM);
     370             :   }
     371             : 
     372           0 :   return *mViewBoxToViewportTransform;
     373             : }
     374             : 
     375             : /* static */ bool
     376           0 : SVGMarkerElement::MarkerImprovementsPrefEnabled()
     377             : {
     378           0 :   return Preferences::GetBool("svg.marker-improvements.enabled", false);
     379             : }
     380             : 
     381             : } // namespace dom
     382             : } // namespace mozilla

Generated by: LCOV version 1.13