1 /* a*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/ArrayUtils.h"
8 #include "nsSVGElement.h"
10 #include "nsSVGNumber2.h"
11 #include "nsSVGNumberPair.h"
12 #include "nsSVGInteger.h"
13 #include "nsSVGIntegerPair.h"
14 #include "nsSVGBoolean.h"
16 #include "nsSVGFilterInstance.h"
17 #include "nsSVGEnum.h"
18 #include "SVGNumberList.h"
19 #include "SVGAnimatedNumberList.h"
20 #include "DOMSVGAnimatedNumberList.h"
21 #include "nsSVGFilters.h"
22 #include "nsLayoutUtils.h"
23 #include "nsSVGUtils.h"
24 #include "nsStyleContext.h"
26 #include "imgIContainer.h"
27 #include "nsNetUtil.h"
28 #include "mozilla/dom/SVGFilterElement.h"
29 #include "nsSVGString.h"
30 #include "SVGContentUtils.h"
32 #include "mozilla/dom/SVGAnimatedLength.h"
33 #include "mozilla/dom/SVGComponentTransferFunctionElement.h"
34 #include "mozilla/dom/SVGFEDistantLightElement.h"
35 #include "mozilla/dom/SVGFEFuncAElementBinding.h"
36 #include "mozilla/dom/SVGFEFuncBElementBinding.h"
37 #include "mozilla/dom/SVGFEFuncGElementBinding.h"
38 #include "mozilla/dom/SVGFEFuncRElementBinding.h"
39 #include "mozilla/dom/SVGFEPointLightElement.h"
40 #include "mozilla/dom/SVGFESpotLightElement.h"
43 // Prevent Windows redefining LoadImage
47 using namespace mozilla
;
48 using namespace mozilla::dom
;
49 using namespace mozilla::gfx
;
51 //--------------------Filter Element Base Class-----------------------
53 nsSVGElement::LengthInfo
nsSVGFE::sLengthInfo
[4] =
55 { &nsGkAtoms::x
, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE
, SVGContentUtils::X
},
56 { &nsGkAtoms::y
, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE
, SVGContentUtils::Y
},
57 { &nsGkAtoms::width
, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE
, SVGContentUtils::X
},
58 { &nsGkAtoms::height
, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE
, SVGContentUtils::Y
}
61 //----------------------------------------------------------------------
62 // nsISupports methods
64 NS_IMPL_ADDREF_INHERITED(nsSVGFE
,nsSVGFEBase
)
65 NS_IMPL_RELEASE_INHERITED(nsSVGFE
,nsSVGFEBase
)
67 NS_INTERFACE_MAP_BEGIN(nsSVGFE
)
68 // nsISupports is an ambiguous base of nsSVGFE so we have to work
70 if ( aIID
.Equals(NS_GET_IID(nsSVGFE
)) )
71 foundInterface
= static_cast<nsISupports
*>(static_cast<void*>(this));
73 NS_INTERFACE_MAP_END_INHERITING(nsSVGFEBase
)
75 //----------------------------------------------------------------------
79 nsSVGFE::GetSourceImageNames(nsTArray
<nsSVGStringInfo
>& aSources
)
84 nsSVGFE::OutputIsTainted(const nsTArray
<bool>& aInputsAreTainted
,
85 nsIPrincipal
* aReferencePrincipal
)
87 // This is the default implementation for OutputIsTainted.
88 // Our output is tainted if we have at least one tainted input.
89 for (uint32_t i
= 0; i
< aInputsAreTainted
.Length(); i
++) {
90 if (aInputsAreTainted
[i
]) {
98 nsSVGFE::AttributeAffectsRendering(int32_t aNameSpaceID
,
99 nsIAtom
* aAttribute
) const
101 return aNameSpaceID
== kNameSpaceID_None
&&
102 (aAttribute
== nsGkAtoms::x
||
103 aAttribute
== nsGkAtoms::y
||
104 aAttribute
== nsGkAtoms::width
||
105 aAttribute
== nsGkAtoms::height
||
106 aAttribute
== nsGkAtoms::result
);
109 already_AddRefed
<SVGAnimatedLength
>
112 return mLengthAttributes
[ATTR_X
].ToDOMAnimatedLength(this);
115 already_AddRefed
<SVGAnimatedLength
>
118 return mLengthAttributes
[ATTR_Y
].ToDOMAnimatedLength(this);
121 already_AddRefed
<SVGAnimatedLength
>
124 return mLengthAttributes
[ATTR_WIDTH
].ToDOMAnimatedLength(this);
127 already_AddRefed
<SVGAnimatedLength
>
130 return mLengthAttributes
[ATTR_HEIGHT
].ToDOMAnimatedLength(this);
133 already_AddRefed
<SVGAnimatedString
>
136 return GetResultImageName().ToDOMAnimatedString(this);
139 //----------------------------------------------------------------------
140 // nsIContent methods
143 nsSVGFE::IsAttributeMapped(const nsIAtom
* name
) const
145 static const MappedAttributeEntry
* const map
[] = {
149 return FindAttributeDependence(name
, map
) ||
150 nsSVGFEBase::IsAttributeMapped(name
);
153 //----------------------------------------------------------------------
154 // nsSVGElement methods
158 nsSVGFE::StyleIsSetToSRGB()
160 nsIFrame
* frame
= GetPrimaryFrame();
161 if (!frame
) return false;
163 nsStyleContext
* style
= frame
->StyleContext();
164 return style
->StyleSVG()->mColorInterpolationFilters
==
165 NS_STYLE_COLOR_INTERPOLATION_SRGB
;
169 nsSVGFE::HasValidDimensions() const
171 return (!mLengthAttributes
[ATTR_WIDTH
].IsExplicitlySet() ||
172 mLengthAttributes
[ATTR_WIDTH
].GetAnimValInSpecifiedUnits() > 0) &&
173 (!mLengthAttributes
[ATTR_HEIGHT
].IsExplicitlySet() ||
174 mLengthAttributes
[ATTR_HEIGHT
].GetAnimValInSpecifiedUnits() > 0);
178 nsSVGFE::GetKernelUnitLength(nsSVGFilterInstance
* aInstance
,
179 nsSVGNumberPair
*aKernelUnitLength
)
181 if (!aKernelUnitLength
->IsExplicitlySet()) {
185 float kernelX
= aInstance
->GetPrimitiveNumber(SVGContentUtils::X
,
187 nsSVGNumberPair::eFirst
);
188 float kernelY
= aInstance
->GetPrimitiveNumber(SVGContentUtils::Y
,
190 nsSVGNumberPair::eSecond
);
191 return Size(kernelX
, kernelY
);
194 nsSVGElement::LengthAttributesInfo
195 nsSVGFE::GetLengthInfo()
197 return LengthAttributesInfo(mLengthAttributes
, sLengthInfo
,
198 ArrayLength(sLengthInfo
));
204 nsSVGElement::NumberListInfo
SVGComponentTransferFunctionElement::sNumberListInfo
[1] =
206 { &nsGkAtoms::tableValues
}
209 nsSVGElement::NumberInfo
SVGComponentTransferFunctionElement::sNumberInfo
[5] =
211 { &nsGkAtoms::slope
, 1, false },
212 { &nsGkAtoms::intercept
, 0, false },
213 { &nsGkAtoms::amplitude
, 1, false },
214 { &nsGkAtoms::exponent
, 1, false },
215 { &nsGkAtoms::offset
, 0, false }
218 nsSVGEnumMapping
SVGComponentTransferFunctionElement::sTypeMap
[] = {
219 {&nsGkAtoms::identity
,
220 SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY
},
222 SVG_FECOMPONENTTRANSFER_TYPE_TABLE
},
223 {&nsGkAtoms::discrete
,
224 SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE
},
226 SVG_FECOMPONENTTRANSFER_TYPE_LINEAR
},
228 SVG_FECOMPONENTTRANSFER_TYPE_GAMMA
},
232 nsSVGElement::EnumInfo
SVGComponentTransferFunctionElement::sEnumInfo
[1] =
236 SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY
240 //----------------------------------------------------------------------
241 // nsISupports methods
243 NS_IMPL_ADDREF_INHERITED(SVGComponentTransferFunctionElement
,SVGComponentTransferFunctionElementBase
)
244 NS_IMPL_RELEASE_INHERITED(SVGComponentTransferFunctionElement
,SVGComponentTransferFunctionElementBase
)
246 NS_INTERFACE_MAP_BEGIN(SVGComponentTransferFunctionElement
)
247 // nsISupports is an ambiguous base of nsSVGFE so we have to work
249 if ( aIID
.Equals(NS_GET_IID(SVGComponentTransferFunctionElement
)) )
250 foundInterface
= static_cast<nsISupports
*>(static_cast<void*>(this));
252 NS_INTERFACE_MAP_END_INHERITING(SVGComponentTransferFunctionElementBase
)
255 //----------------------------------------------------------------------
256 // nsFEUnstyledElement methods
259 SVGComponentTransferFunctionElement::AttributeAffectsRendering(int32_t aNameSpaceID
,
260 nsIAtom
* aAttribute
) const
262 return aNameSpaceID
== kNameSpaceID_None
&&
263 (aAttribute
== nsGkAtoms::tableValues
||
264 aAttribute
== nsGkAtoms::slope
||
265 aAttribute
== nsGkAtoms::intercept
||
266 aAttribute
== nsGkAtoms::amplitude
||
267 aAttribute
== nsGkAtoms::exponent
||
268 aAttribute
== nsGkAtoms::offset
||
269 aAttribute
== nsGkAtoms::type
);
272 //----------------------------------------------------------------------
274 already_AddRefed
<SVGAnimatedEnumeration
>
275 SVGComponentTransferFunctionElement::Type()
277 return mEnumAttributes
[TYPE
].ToDOMAnimatedEnum(this);
280 already_AddRefed
<DOMSVGAnimatedNumberList
>
281 SVGComponentTransferFunctionElement::TableValues()
283 return DOMSVGAnimatedNumberList::GetDOMWrapper(
284 &mNumberListAttributes
[TABLEVALUES
], this, TABLEVALUES
);
287 already_AddRefed
<SVGAnimatedNumber
>
288 SVGComponentTransferFunctionElement::Slope()
290 return mNumberAttributes
[SLOPE
].ToDOMAnimatedNumber(this);
293 already_AddRefed
<SVGAnimatedNumber
>
294 SVGComponentTransferFunctionElement::Intercept()
296 return mNumberAttributes
[INTERCEPT
].ToDOMAnimatedNumber(this);
299 already_AddRefed
<SVGAnimatedNumber
>
300 SVGComponentTransferFunctionElement::Amplitude()
302 return mNumberAttributes
[AMPLITUDE
].ToDOMAnimatedNumber(this);
305 already_AddRefed
<SVGAnimatedNumber
>
306 SVGComponentTransferFunctionElement::Exponent()
308 return mNumberAttributes
[EXPONENT
].ToDOMAnimatedNumber(this);
311 already_AddRefed
<SVGAnimatedNumber
>
312 SVGComponentTransferFunctionElement::Offset()
314 return mNumberAttributes
[OFFSET
].ToDOMAnimatedNumber(this);
318 SVGComponentTransferFunctionElement::ComputeAttributes()
320 uint32_t type
= mEnumAttributes
[TYPE
].GetAnimValue();
322 float slope
, intercept
, amplitude
, exponent
, offset
;
323 GetAnimatedNumberValues(&slope
, &intercept
, &litude
,
324 &exponent
, &offset
, nullptr);
326 const SVGNumberList
&tableValues
=
327 mNumberListAttributes
[TABLEVALUES
].GetAnimValue();
330 map
.Set(eComponentTransferFunctionType
, type
);
331 map
.Set(eComponentTransferFunctionSlope
, slope
);
332 map
.Set(eComponentTransferFunctionIntercept
, intercept
);
333 map
.Set(eComponentTransferFunctionAmplitude
, amplitude
);
334 map
.Set(eComponentTransferFunctionExponent
, exponent
);
335 map
.Set(eComponentTransferFunctionOffset
, offset
);
336 if (tableValues
.Length()) {
337 map
.Set(eComponentTransferFunctionTableValues
, &tableValues
[0], tableValues
.Length());
339 map
.Set(eComponentTransferFunctionTableValues
, nullptr, 0);
344 //----------------------------------------------------------------------
345 // nsSVGElement methods
347 nsSVGElement::NumberListAttributesInfo
348 SVGComponentTransferFunctionElement::GetNumberListInfo()
350 return NumberListAttributesInfo(mNumberListAttributes
, sNumberListInfo
,
351 ArrayLength(sNumberListInfo
));
354 nsSVGElement::EnumAttributesInfo
355 SVGComponentTransferFunctionElement::GetEnumInfo()
357 return EnumAttributesInfo(mEnumAttributes
, sEnumInfo
,
358 ArrayLength(sEnumInfo
));
361 nsSVGElement::NumberAttributesInfo
362 SVGComponentTransferFunctionElement::GetNumberInfo()
364 return NumberAttributesInfo(mNumberAttributes
, sNumberInfo
,
365 ArrayLength(sNumberInfo
));
368 /* virtual */ JSObject
*
369 SVGFEFuncRElement::WrapNode(JSContext
* aCx
)
371 return SVGFEFuncRElementBinding::Wrap(aCx
, this);
375 } // namespace mozilla
377 NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFuncR
)
382 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFuncRElement
)
384 /* virtual */ JSObject
*
385 SVGFEFuncGElement::WrapNode(JSContext
* aCx
)
387 return SVGFEFuncGElementBinding::Wrap(aCx
, this);
391 } // namespace mozilla
393 NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFuncG
)
398 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFuncGElement
)
400 /* virtual */ JSObject
*
401 SVGFEFuncBElement::WrapNode(JSContext
* aCx
)
403 return SVGFEFuncBElementBinding::Wrap(aCx
, this);
407 } // namespace mozilla
409 NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFuncB
)
414 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFuncBElement
)
416 /* virtual */ JSObject
*
417 SVGFEFuncAElement::WrapNode(JSContext
* aCx
)
419 return SVGFEFuncAElementBinding::Wrap(aCx
, this);
423 } // namespace mozilla
425 NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFuncA
)
430 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFuncAElement
)
433 } // namespace mozilla
435 //--------------------------------------------------------------------
437 nsSVGElement::NumberInfo
nsSVGFELightingElement::sNumberInfo
[4] =
439 { &nsGkAtoms::surfaceScale
, 1, false },
440 { &nsGkAtoms::diffuseConstant
, 1, false },
441 { &nsGkAtoms::specularConstant
, 1, false },
442 { &nsGkAtoms::specularExponent
, 1, false }
445 nsSVGElement::NumberPairInfo
nsSVGFELightingElement::sNumberPairInfo
[1] =
447 { &nsGkAtoms::kernelUnitLength
, 0, 0 }
450 nsSVGElement::StringInfo
nsSVGFELightingElement::sStringInfo
[2] =
452 { &nsGkAtoms::result
, kNameSpaceID_None
, true },
453 { &nsGkAtoms::in
, kNameSpaceID_None
, true }
456 //----------------------------------------------------------------------
457 // nsISupports methods
459 NS_IMPL_ADDREF_INHERITED(nsSVGFELightingElement
,nsSVGFELightingElementBase
)
460 NS_IMPL_RELEASE_INHERITED(nsSVGFELightingElement
,nsSVGFELightingElementBase
)
462 NS_INTERFACE_MAP_BEGIN(nsSVGFELightingElement
)
463 NS_INTERFACE_MAP_END_INHERITING(nsSVGFELightingElementBase
)
465 //----------------------------------------------------------------------
469 nsSVGFELightingElement::IsAttributeMapped(const nsIAtom
* name
) const
471 static const MappedAttributeEntry
* const map
[] = {
475 return FindAttributeDependence(name
, map
) ||
476 nsSVGFELightingElementBase::IsAttributeMapped(name
);
480 nsSVGFELightingElement::GetSourceImageNames(nsTArray
<nsSVGStringInfo
>& aSources
)
482 aSources
.AppendElement(nsSVGStringInfo(&mStringAttributes
[IN1
], this));
486 nsSVGFELightingElement::ComputeLightAttributes(nsSVGFilterInstance
* aInstance
)
488 // find specified light
489 for (nsCOMPtr
<nsIContent
> child
= nsINode::GetFirstChild();
491 child
= child
->GetNextSibling()) {
492 if (child
->IsSVG(nsGkAtoms::feDistantLight
) ||
493 child
->IsSVG(nsGkAtoms::fePointLight
) ||
494 child
->IsSVG(nsGkAtoms::feSpotLight
)) {
495 return static_cast<SVGFELightElement
*>(child
.get())->ComputeLightAttributes(aInstance
);
500 map
.Set(eLightType
, (uint32_t)eLightTypeNone
);
504 FilterPrimitiveDescription
505 nsSVGFELightingElement::AddLightingAttributes(FilterPrimitiveDescription aDescription
,
506 nsSVGFilterInstance
* aInstance
)
508 nsIFrame
* frame
= GetPrimaryFrame();
510 return FilterPrimitiveDescription(PrimitiveType::Empty
);
513 nsStyleContext
* style
= frame
->StyleContext();
514 Color
color(Color::FromABGR(style
->StyleSVGReset()->mLightingColor
));
516 float surfaceScale
= mNumberAttributes
[SURFACE_SCALE
].GetAnimValue();
517 Size kernelUnitLength
=
518 GetKernelUnitLength(aInstance
, &mNumberPairAttributes
[KERNEL_UNIT_LENGTH
]);
520 FilterPrimitiveDescription
& descr
= aDescription
;
521 descr
.Attributes().Set(eLightingLight
, ComputeLightAttributes(aInstance
));
522 descr
.Attributes().Set(eLightingSurfaceScale
, surfaceScale
);
523 descr
.Attributes().Set(eLightingKernelUnitLength
, kernelUnitLength
);
524 descr
.Attributes().Set(eLightingColor
, color
);
529 nsSVGFELightingElement::AttributeAffectsRendering(int32_t aNameSpaceID
,
530 nsIAtom
* aAttribute
) const
532 return nsSVGFELightingElementBase::AttributeAffectsRendering(aNameSpaceID
, aAttribute
) ||
533 (aNameSpaceID
== kNameSpaceID_None
&&
534 (aAttribute
== nsGkAtoms::in
||
535 aAttribute
== nsGkAtoms::surfaceScale
||
536 aAttribute
== nsGkAtoms::kernelUnitLength
));
539 //----------------------------------------------------------------------
540 // nsSVGElement methods
542 nsSVGElement::NumberAttributesInfo
543 nsSVGFELightingElement::GetNumberInfo()
545 return NumberAttributesInfo(mNumberAttributes
, sNumberInfo
,
546 ArrayLength(sNumberInfo
));
549 nsSVGElement::NumberPairAttributesInfo
550 nsSVGFELightingElement::GetNumberPairInfo()
552 return NumberPairAttributesInfo(mNumberPairAttributes
, sNumberPairInfo
,
553 ArrayLength(sNumberPairInfo
));
556 nsSVGElement::StringAttributesInfo
557 nsSVGFELightingElement::GetStringInfo()
559 return StringAttributesInfo(mStringAttributes
, sStringInfo
,
560 ArrayLength(sStringInfo
));