SVGFilters.h (8342B)
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 #ifndef DOM_SVG_SVGFILTERS_H_ 8 #define DOM_SVG_SVGFILTERS_H_ 9 10 #include "FilterDescription.h" 11 #include "SVGAnimatedLength.h" 12 #include "SVGAnimatedNumber.h" 13 #include "SVGAnimatedNumberPair.h" 14 #include "SVGAnimatedString.h" 15 #include "mozilla/dom/SVGElement.h" 16 #include "nsImageLoadingContent.h" 17 18 namespace mozilla { 19 class SVGFilterInstance; 20 21 namespace dom { 22 23 struct SVGStringInfo { 24 SVGStringInfo(const SVGAnimatedString* aString, SVGElement* aElement) 25 : mString(aString), mElement(aElement) {} 26 27 const SVGAnimatedString* mString; 28 SVGElement* mElement; 29 }; 30 31 using SVGFilterPrimitiveElementBase = SVGElement; 32 33 /** 34 * Base class for filter primitive elements 35 * Children of those elements e.g. feMergeNode 36 * derive from SVGFilterPrimitiveChildElement instead 37 */ 38 class SVGFilterPrimitiveElement : public SVGFilterPrimitiveElementBase { 39 friend class mozilla::SVGFilterInstance; 40 41 protected: 42 using SourceSurface = mozilla::gfx::SourceSurface; 43 using Size = mozilla::gfx::Size; 44 using IntRect = mozilla::gfx::IntRect; 45 using ColorSpace = mozilla::gfx::ColorSpace; 46 using FilterPrimitiveDescription = mozilla::gfx::FilterPrimitiveDescription; 47 48 explicit SVGFilterPrimitiveElement( 49 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) 50 : SVGFilterPrimitiveElementBase(std::move(aNodeInfo)) {} 51 virtual ~SVGFilterPrimitiveElement() = default; 52 53 public: 54 using PrimitiveAttributes = mozilla::gfx::PrimitiveAttributes; 55 56 NS_IMPL_FROMNODE_HELPER(SVGFilterPrimitiveElement, 57 IsSVGFilterPrimitiveElement()) 58 59 ColorSpace GetInputColorSpace(int32_t aInputIndex, 60 ColorSpace aUnchangedInputColorSpace) { 61 return OperatesOnSRGB(aInputIndex, 62 aUnchangedInputColorSpace == ColorSpace::SRGB) 63 ? ColorSpace::SRGB 64 : ColorSpace::LinearRGB; 65 } 66 67 // This is only called for filter primitives without inputs. For primitives 68 // with inputs, the output color model is the same as of the first input. 69 ColorSpace GetOutputColorSpace() { 70 return ProducesSRGB() ? ColorSpace::SRGB : ColorSpace::LinearRGB; 71 } 72 73 // See http://www.w3.org/TR/SVG/filters.html#FilterPrimitiveSubRegion 74 virtual bool SubregionIsUnionOfRegions() { return true; } 75 76 bool IsSVGFilterPrimitiveElement() const final { return true; } 77 78 // SVGElement interface 79 nsresult Clone(mozilla::dom::NodeInfo*, nsINode** aResult) const override = 0; 80 81 bool HasValidDimensions() const override; 82 83 virtual SVGAnimatedString& GetResultImageName() = 0; 84 // Return a list of all image names used as sources. Default is to 85 // return no sources. 86 virtual void GetSourceImageNames(nsTArray<SVGStringInfo>& aSources); 87 88 virtual FilterPrimitiveDescription GetPrimitiveDescription( 89 SVGFilterInstance* aInstance, const IntRect& aFilterSubregion, 90 const nsTArray<bool>& aInputsAreTainted, 91 nsTArray<RefPtr<SourceSurface>>& aInputImages) = 0; 92 93 // returns true if changes to the attribute should cause us to 94 // repaint the filter 95 virtual bool AttributeAffectsRendering(int32_t aNameSpaceID, 96 nsAtom* aAttribute) const; 97 98 // Return whether this filter primitive has tainted output. A filter's 99 // output is tainted if it depends on things that the web page is not 100 // allowed to read from, e.g. the source graphic or cross-origin images. 101 // aReferencePrincipal is the node principal of the filtered frame's element. 102 virtual bool OutputIsTainted(const nsTArray<bool>& aInputsAreTainted, 103 nsIPrincipal* aReferencePrincipal); 104 105 static nsIntRect GetMaxRect() { 106 // Try to avoid overflow errors dealing with this rect. It will 107 // be intersected with some other reasonable-sized rect eventually. 108 return nsIntRect(INT32_MIN / 2, INT32_MIN / 2, INT32_MAX, INT32_MAX); 109 } 110 111 operator nsISupports*() { return static_cast<nsIContent*>(this); } 112 113 // WebIDL 114 already_AddRefed<DOMSVGAnimatedLength> X(); 115 already_AddRefed<DOMSVGAnimatedLength> Y(); 116 already_AddRefed<DOMSVGAnimatedLength> Width(); 117 already_AddRefed<DOMSVGAnimatedLength> Height(); 118 already_AddRefed<DOMSVGAnimatedString> Result(); 119 120 protected: 121 virtual bool OperatesOnSRGB(int32_t aInputIndex, bool aInputIsAlreadySRGB) { 122 return StyleIsSetToSRGB(); 123 } 124 125 // Only called for filter primitives without inputs. 126 virtual bool ProducesSRGB() { return StyleIsSetToSRGB(); } 127 128 bool StyleIsSetToSRGB(); 129 130 // SVGElement specializations: 131 LengthAttributesInfo GetLengthInfo() override; 132 133 Size GetKernelUnitLength(SVGFilterInstance* aInstance, 134 SVGAnimatedNumberPair* aKernelUnitLength); 135 136 enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT }; 137 SVGAnimatedLength mLengthAttributes[4]; 138 static LengthInfo sLengthInfo[4]; 139 }; 140 141 using SVGFilterPrimitiveChildElementBase = SVGElement; 142 143 class SVGFilterPrimitiveChildElement 144 : public SVGFilterPrimitiveChildElementBase { 145 protected: 146 explicit SVGFilterPrimitiveChildElement( 147 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) 148 : SVGFilterPrimitiveChildElementBase(std::move(aNodeInfo)) {} 149 150 public: 151 NS_IMPL_FROMNODE_HELPER(SVGFilterPrimitiveChildElement, 152 IsSVGFilterPrimitiveChildElement()) 153 154 bool IsSVGFilterPrimitiveChildElement() const final { return true; } 155 156 nsresult Clone(mozilla::dom::NodeInfo*, nsINode** aResult) const override = 0; 157 158 // returns true if changes to the attribute should cause us to 159 // repaint the filter 160 virtual bool AttributeAffectsRendering(int32_t aNameSpaceID, 161 nsAtom* aAttribute) const = 0; 162 }; 163 164 //------------------------------------------------------------ 165 166 using SVGFELightingElementBase = SVGFilterPrimitiveElement; 167 168 class SVGFELightingElement : public SVGFELightingElementBase { 169 protected: 170 explicit SVGFELightingElement( 171 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) 172 : SVGFELightingElementBase(std::move(aNodeInfo)) {} 173 174 virtual ~SVGFELightingElement() = default; 175 176 public: 177 // interfaces: 178 NS_INLINE_DECL_REFCOUNTING_INHERITED(SVGFELightingElement, 179 SVGFELightingElementBase) 180 181 bool AttributeAffectsRendering(int32_t aNameSpaceID, 182 nsAtom* aAttribute) const override; 183 SVGAnimatedString& GetResultImageName() override { 184 return mStringAttributes[RESULT]; 185 } 186 187 bool OutputIsTainted(const nsTArray<bool>& aInputsAreTainted, 188 nsIPrincipal* aReferencePrincipal) override; 189 190 void GetSourceImageNames(nsTArray<SVGStringInfo>& aSources) override; 191 192 protected: 193 NumberAttributesInfo GetNumberInfo() override; 194 NumberPairAttributesInfo GetNumberPairInfo() override; 195 StringAttributesInfo GetStringInfo() override; 196 197 mozilla::gfx::LightType ComputeLightAttributes( 198 SVGFilterInstance* aInstance, nsTArray<float>& aFloatAttributes); 199 200 bool AddLightingAttributes(mozilla::gfx::LightingAttributes* aAttributes, 201 SVGFilterInstance* aInstance); 202 203 enum { 204 SURFACE_SCALE, 205 DIFFUSE_CONSTANT, 206 SPECULAR_CONSTANT, 207 SPECULAR_EXPONENT 208 }; 209 SVGAnimatedNumber mNumberAttributes[4]; 210 static NumberInfo sNumberInfo[4]; 211 212 enum { KERNEL_UNIT_LENGTH }; 213 SVGAnimatedNumberPair mNumberPairAttributes[1]; 214 static NumberPairInfo sNumberPairInfo[1]; 215 216 enum { RESULT, IN1 }; 217 SVGAnimatedString mStringAttributes[2]; 218 static StringInfo sStringInfo[2]; 219 }; 220 221 using SVGFELightElementBase = SVGFilterPrimitiveChildElement; 222 223 class SVGFELightElement : public SVGFELightElementBase { 224 protected: 225 explicit SVGFELightElement( 226 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) 227 : SVGFELightElementBase(std::move(aNodeInfo)) {} 228 229 public: 230 using PrimitiveAttributes = gfx::PrimitiveAttributes; 231 232 virtual mozilla::gfx::LightType ComputeLightAttributes( 233 SVGFilterInstance* aInstance, nsTArray<float>& aFloatAttributes) = 0; 234 }; 235 236 } // namespace dom 237 } // namespace mozilla 238 239 #endif // DOM_SVG_SVGFILTERS_H_