1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/svg/nsSVGGradientFrame.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,216 @@ 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 +#ifndef __NS_SVGGRADIENTFRAME_H__ 1.10 +#define __NS_SVGGRADIENTFRAME_H__ 1.11 + 1.12 +#include "mozilla/Attributes.h" 1.13 +#include "gfxMatrix.h" 1.14 +#include "nsCOMPtr.h" 1.15 +#include "nsFrame.h" 1.16 +#include "nsLiteralString.h" 1.17 +#include "nsSVGPaintServerFrame.h" 1.18 + 1.19 +class gfxPattern; 1.20 +class nsIAtom; 1.21 +class nsIContent; 1.22 +class nsIFrame; 1.23 +class nsIPresShell; 1.24 +class nsStyleContext; 1.25 + 1.26 +struct gfxRect; 1.27 + 1.28 +namespace mozilla { 1.29 +class nsSVGAnimatedTransformList; 1.30 + 1.31 +namespace dom { 1.32 +class SVGLinearGradientElement; 1.33 +class SVGRadialGradientElement; 1.34 +} // namespace dom 1.35 +} // namespace mozilla 1.36 + 1.37 +typedef nsSVGPaintServerFrame nsSVGGradientFrameBase; 1.38 + 1.39 +/** 1.40 + * Gradients can refer to other gradients. We create an nsSVGPaintingProperty 1.41 + * with property type nsGkAtoms::href to track the referenced gradient. 1.42 + */ 1.43 +class nsSVGGradientFrame : public nsSVGGradientFrameBase 1.44 +{ 1.45 +protected: 1.46 + nsSVGGradientFrame(nsStyleContext* aContext); 1.47 + 1.48 +public: 1.49 + NS_DECL_FRAMEARENA_HELPERS 1.50 + 1.51 + // nsSVGPaintServerFrame methods: 1.52 + virtual already_AddRefed<gfxPattern> 1.53 + GetPaintServerPattern(nsIFrame *aSource, 1.54 + const gfxMatrix& aContextMatrix, 1.55 + nsStyleSVGPaint nsStyleSVG::*aFillOrStroke, 1.56 + float aGraphicOpacity, 1.57 + const gfxRect *aOverrideBounds) MOZ_OVERRIDE; 1.58 + 1.59 + // nsIFrame interface: 1.60 + virtual nsresult AttributeChanged(int32_t aNameSpaceID, 1.61 + nsIAtom* aAttribute, 1.62 + int32_t aModType) MOZ_OVERRIDE; 1.63 + 1.64 +#ifdef DEBUG_FRAME_DUMP 1.65 + virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE 1.66 + { 1.67 + return MakeFrameName(NS_LITERAL_STRING("SVGGradient"), aResult); 1.68 + } 1.69 +#endif // DEBUG 1.70 + 1.71 +private: 1.72 + 1.73 + // Parse our xlink:href and set up our nsSVGPaintingProperty if we 1.74 + // reference another gradient and we don't have a property. Return 1.75 + // the referenced gradient's frame if available, null otherwise. 1.76 + nsSVGGradientFrame* GetReferencedGradient(); 1.77 + 1.78 + // Optionally get a stop frame (returns stop index/count) 1.79 + void GetStopFrames(nsTArray<nsIFrame*>* aStopFrames); 1.80 + 1.81 + const mozilla::nsSVGAnimatedTransformList* GetGradientTransformList( 1.82 + nsIContent* aDefault); 1.83 + // Will be singular for gradientUnits="objectBoundingBox" with an empty bbox. 1.84 + gfxMatrix GetGradientTransform(nsIFrame *aSource, 1.85 + const gfxRect *aOverrideBounds); 1.86 + 1.87 +protected: 1.88 + virtual bool GradientVectorLengthIsZero() = 0; 1.89 + virtual already_AddRefed<gfxPattern> CreateGradient() = 0; 1.90 + 1.91 + // Internal methods for handling referenced gradients 1.92 + class AutoGradientReferencer; 1.93 + nsSVGGradientFrame* GetReferencedGradientIfNotInUse(); 1.94 + 1.95 + // Accessors to lookup gradient attributes 1.96 + uint16_t GetEnumValue(uint32_t aIndex, nsIContent *aDefault); 1.97 + uint16_t GetEnumValue(uint32_t aIndex) 1.98 + { 1.99 + return GetEnumValue(aIndex, mContent); 1.100 + } 1.101 + uint16_t GetGradientUnits(); 1.102 + uint16_t GetSpreadMethod(); 1.103 + 1.104 + // Gradient-type-specific lookups since the length values differ between 1.105 + // linear and radial gradients 1.106 + virtual mozilla::dom::SVGLinearGradientElement * GetLinearGradientWithLength( 1.107 + uint32_t aIndex, mozilla::dom::SVGLinearGradientElement* aDefault); 1.108 + virtual mozilla::dom::SVGRadialGradientElement * GetRadialGradientWithLength( 1.109 + uint32_t aIndex, mozilla::dom::SVGRadialGradientElement* aDefault); 1.110 + 1.111 + // The frame our gradient is (currently) being applied to 1.112 + nsIFrame* mSource; 1.113 + 1.114 +private: 1.115 + // Flag to mark this frame as "in use" during recursive calls along our 1.116 + // gradient's reference chain so we can detect reference loops. See: 1.117 + // http://www.w3.org/TR/SVG11/pservers.html#LinearGradientElementHrefAttribute 1.118 + bool mLoopFlag; 1.119 + // Gradients often don't reference other gradients, so here we cache 1.120 + // the fact that that isn't happening. 1.121 + bool mNoHRefURI; 1.122 +}; 1.123 + 1.124 + 1.125 +// ------------------------------------------------------------------------- 1.126 +// Linear Gradients 1.127 +// ------------------------------------------------------------------------- 1.128 + 1.129 +typedef nsSVGGradientFrame nsSVGLinearGradientFrameBase; 1.130 + 1.131 +class nsSVGLinearGradientFrame : public nsSVGLinearGradientFrameBase 1.132 +{ 1.133 + friend nsIFrame* NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell, 1.134 + nsStyleContext* aContext); 1.135 +protected: 1.136 + nsSVGLinearGradientFrame(nsStyleContext* aContext) : 1.137 + nsSVGLinearGradientFrameBase(aContext) {} 1.138 + 1.139 +public: 1.140 + NS_DECL_FRAMEARENA_HELPERS 1.141 + 1.142 + // nsIFrame interface: 1.143 +#ifdef DEBUG 1.144 + virtual void Init(nsIContent* aContent, 1.145 + nsIFrame* aParent, 1.146 + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; 1.147 +#endif 1.148 + 1.149 + virtual nsIAtom* GetType() const MOZ_OVERRIDE; // frame type: nsGkAtoms::svgLinearGradientFrame 1.150 + 1.151 + virtual nsresult AttributeChanged(int32_t aNameSpaceID, 1.152 + nsIAtom* aAttribute, 1.153 + int32_t aModType) MOZ_OVERRIDE; 1.154 + 1.155 +#ifdef DEBUG_FRAME_DUMP 1.156 + virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE 1.157 + { 1.158 + return MakeFrameName(NS_LITERAL_STRING("SVGLinearGradient"), aResult); 1.159 + } 1.160 +#endif // DEBUG 1.161 + 1.162 +protected: 1.163 + float GetLengthValue(uint32_t aIndex); 1.164 + virtual mozilla::dom::SVGLinearGradientElement* GetLinearGradientWithLength( 1.165 + uint32_t aIndex, mozilla::dom::SVGLinearGradientElement* aDefault) MOZ_OVERRIDE; 1.166 + virtual bool GradientVectorLengthIsZero() MOZ_OVERRIDE; 1.167 + virtual already_AddRefed<gfxPattern> CreateGradient() MOZ_OVERRIDE; 1.168 +}; 1.169 + 1.170 +// ------------------------------------------------------------------------- 1.171 +// Radial Gradients 1.172 +// ------------------------------------------------------------------------- 1.173 + 1.174 +typedef nsSVGGradientFrame nsSVGRadialGradientFrameBase; 1.175 + 1.176 +class nsSVGRadialGradientFrame : public nsSVGRadialGradientFrameBase 1.177 +{ 1.178 + friend nsIFrame* NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell, 1.179 + nsStyleContext* aContext); 1.180 +protected: 1.181 + nsSVGRadialGradientFrame(nsStyleContext* aContext) : 1.182 + nsSVGRadialGradientFrameBase(aContext) {} 1.183 + 1.184 +public: 1.185 + NS_DECL_FRAMEARENA_HELPERS 1.186 + 1.187 + // nsIFrame interface: 1.188 +#ifdef DEBUG 1.189 + virtual void Init(nsIContent* aContent, 1.190 + nsIFrame* aParent, 1.191 + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; 1.192 +#endif 1.193 + 1.194 + virtual nsIAtom* GetType() const MOZ_OVERRIDE; // frame type: nsGkAtoms::svgRadialGradientFrame 1.195 + 1.196 + virtual nsresult AttributeChanged(int32_t aNameSpaceID, 1.197 + nsIAtom* aAttribute, 1.198 + int32_t aModType) MOZ_OVERRIDE; 1.199 + 1.200 +#ifdef DEBUG_FRAME_DUMP 1.201 + virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE 1.202 + { 1.203 + return MakeFrameName(NS_LITERAL_STRING("SVGRadialGradient"), aResult); 1.204 + } 1.205 +#endif // DEBUG 1.206 + 1.207 +protected: 1.208 + float GetLengthValue(uint32_t aIndex); 1.209 + float GetLengthValue(uint32_t aIndex, float aDefaultValue); 1.210 + float GetLengthValueFromElement(uint32_t aIndex, 1.211 + mozilla::dom::SVGRadialGradientElement& aElement); 1.212 + virtual mozilla::dom::SVGRadialGradientElement* GetRadialGradientWithLength( 1.213 + uint32_t aIndex, mozilla::dom::SVGRadialGradientElement* aDefault) MOZ_OVERRIDE; 1.214 + virtual bool GradientVectorLengthIsZero() MOZ_OVERRIDE; 1.215 + virtual already_AddRefed<gfxPattern> CreateGradient() MOZ_OVERRIDE; 1.216 +}; 1.217 + 1.218 +#endif // __NS_SVGGRADIENTFRAME_H__ 1.219 +