1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/svg/nsSVGAFrame.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,157 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +// Keep in (case-insensitive) order: 1.10 +#include "gfxMatrix.h" 1.11 +#include "mozilla/dom/SVGAElement.h" 1.12 +#include "nsSVGContainerFrame.h" 1.13 +#include "nsSVGIntegrationUtils.h" 1.14 +#include "nsSVGUtils.h" 1.15 +#include "SVGLengthList.h" 1.16 + 1.17 +using namespace mozilla; 1.18 + 1.19 +typedef nsSVGDisplayContainerFrame nsSVGAFrameBase; 1.20 + 1.21 +class nsSVGAFrame : public nsSVGAFrameBase 1.22 +{ 1.23 + friend nsIFrame* 1.24 + NS_NewSVGAFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); 1.25 +protected: 1.26 + nsSVGAFrame(nsStyleContext* aContext) : 1.27 + nsSVGAFrameBase(aContext) {} 1.28 + 1.29 +public: 1.30 + NS_DECL_FRAMEARENA_HELPERS 1.31 + 1.32 +#ifdef DEBUG 1.33 + virtual void Init(nsIContent* aContent, 1.34 + nsIFrame* aParent, 1.35 + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; 1.36 +#endif 1.37 + 1.38 + // nsIFrame: 1.39 + virtual nsresult AttributeChanged(int32_t aNameSpaceID, 1.40 + nsIAtom* aAttribute, 1.41 + int32_t aModType) MOZ_OVERRIDE; 1.42 + 1.43 + /** 1.44 + * Get the "type" of the frame 1.45 + * 1.46 + * @see nsGkAtoms::svgAFrame 1.47 + */ 1.48 + virtual nsIAtom* GetType() const MOZ_OVERRIDE; 1.49 + 1.50 +#ifdef DEBUG_FRAME_DUMP 1.51 + virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE 1.52 + { 1.53 + return MakeFrameName(NS_LITERAL_STRING("SVGA"), aResult); 1.54 + } 1.55 +#endif 1.56 + // nsISVGChildFrame interface: 1.57 + virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE; 1.58 + 1.59 + // nsSVGContainerFrame methods: 1.60 + virtual gfxMatrix GetCanvasTM(uint32_t aFor, 1.61 + nsIFrame* aTransformRoot = nullptr) MOZ_OVERRIDE; 1.62 + 1.63 +private: 1.64 + nsAutoPtr<gfxMatrix> mCanvasTM; 1.65 +}; 1.66 + 1.67 +//---------------------------------------------------------------------- 1.68 +// Implementation 1.69 + 1.70 +nsIFrame* 1.71 +NS_NewSVGAFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) 1.72 +{ 1.73 + return new (aPresShell) nsSVGAFrame(aContext); 1.74 +} 1.75 + 1.76 +NS_IMPL_FRAMEARENA_HELPERS(nsSVGAFrame) 1.77 + 1.78 +//---------------------------------------------------------------------- 1.79 +// nsIFrame methods 1.80 +#ifdef DEBUG 1.81 +void 1.82 +nsSVGAFrame::Init(nsIContent* aContent, 1.83 + nsIFrame* aParent, 1.84 + nsIFrame* aPrevInFlow) 1.85 +{ 1.86 + NS_ASSERTION(aContent->IsSVG(nsGkAtoms::a), 1.87 + "Trying to construct an SVGAFrame for a " 1.88 + "content element that doesn't support the right interfaces"); 1.89 + 1.90 + nsSVGAFrameBase::Init(aContent, aParent, aPrevInFlow); 1.91 +} 1.92 +#endif /* DEBUG */ 1.93 + 1.94 +nsresult 1.95 +nsSVGAFrame::AttributeChanged(int32_t aNameSpaceID, 1.96 + nsIAtom* aAttribute, 1.97 + int32_t aModType) 1.98 +{ 1.99 + if (aNameSpaceID == kNameSpaceID_None && 1.100 + aAttribute == nsGkAtoms::transform) { 1.101 + // We don't invalidate for transform changes (the layers code does that). 1.102 + // Also note that SVGTransformableElement::GetAttributeChangeHint will 1.103 + // return nsChangeHint_UpdateOverflow for "transform" attribute changes 1.104 + // and cause DoApplyRenderingChangeToTree to make the SchedulePaint call. 1.105 + NotifySVGChanged(TRANSFORM_CHANGED); 1.106 + } 1.107 + 1.108 + return NS_OK; 1.109 +} 1.110 + 1.111 +nsIAtom * 1.112 +nsSVGAFrame::GetType() const 1.113 +{ 1.114 + return nsGkAtoms::svgAFrame; 1.115 +} 1.116 + 1.117 +//---------------------------------------------------------------------- 1.118 +// nsISVGChildFrame methods 1.119 + 1.120 +void 1.121 +nsSVGAFrame::NotifySVGChanged(uint32_t aFlags) 1.122 +{ 1.123 + NS_ABORT_IF_FALSE(aFlags & (TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED), 1.124 + "Invalidation logic may need adjusting"); 1.125 + 1.126 + if (aFlags & TRANSFORM_CHANGED) { 1.127 + // make sure our cached transform matrix gets (lazily) updated 1.128 + mCanvasTM = nullptr; 1.129 + } 1.130 + 1.131 + nsSVGAFrameBase::NotifySVGChanged(aFlags); 1.132 +} 1.133 + 1.134 +//---------------------------------------------------------------------- 1.135 +// nsSVGContainerFrame methods: 1.136 + 1.137 +gfxMatrix 1.138 +nsSVGAFrame::GetCanvasTM(uint32_t aFor, nsIFrame* aTransformRoot) 1.139 +{ 1.140 + if (!(GetStateBits() & NS_FRAME_IS_NONDISPLAY) && !aTransformRoot) { 1.141 + if ((aFor == FOR_PAINTING && NS_SVGDisplayListPaintingEnabled()) || 1.142 + (aFor == FOR_HIT_TESTING && NS_SVGDisplayListHitTestingEnabled())) { 1.143 + return nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(this); 1.144 + } 1.145 + } 1.146 + if (!mCanvasTM) { 1.147 + NS_ASSERTION(mParent, "null parent"); 1.148 + 1.149 + nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(mParent); 1.150 + dom::SVGAElement *content = static_cast<dom::SVGAElement*>(mContent); 1.151 + 1.152 + gfxMatrix tm = content->PrependLocalTransformsTo( 1.153 + this == aTransformRoot ? gfxMatrix() : 1.154 + parent->GetCanvasTM(aFor, aTransformRoot)); 1.155 + 1.156 + mCanvasTM = new gfxMatrix(tm); 1.157 + } 1.158 + 1.159 + return *mCanvasTM; 1.160 +}