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 "nsSVGElement.h"
10 : #include "nsGkAtoms.h"
11 : #include "nsSVGNumber2.h"
12 : #include "nsSVGNumberPair.h"
13 : #include "nsSVGInteger.h"
14 : #include "nsSVGIntegerPair.h"
15 : #include "nsSVGBoolean.h"
16 : #include "nsCOMPtr.h"
17 : #include "nsSVGFilterInstance.h"
18 : #include "nsSVGEnum.h"
19 : #include "SVGNumberList.h"
20 : #include "SVGAnimatedNumberList.h"
21 : #include "DOMSVGAnimatedNumberList.h"
22 : #include "nsSVGFilters.h"
23 : #include "nsLayoutUtils.h"
24 : #include "nsSVGUtils.h"
25 : #include "nsStyleContext.h"
26 : #include "nsIFrame.h"
27 : #include "imgIContainer.h"
28 : #include "mozilla/dom/SVGFilterElement.h"
29 : #include "nsSVGString.h"
30 : #include "SVGContentUtils.h"
31 : #include <algorithm>
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"
41 :
42 : #if defined(XP_WIN)
43 : // Prevent Windows redefining LoadImage
44 : #undef LoadImage
45 : #endif
46 :
47 : using namespace mozilla;
48 : using namespace mozilla::dom;
49 : using namespace mozilla::gfx;
50 :
51 : //--------------------Filter Element Base Class-----------------------
52 :
53 : nsSVGElement::LengthInfo nsSVGFE::sLengthInfo[4] =
54 : {
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 }
59 : };
60 :
61 : //----------------------------------------------------------------------
62 : // nsISupports methods
63 :
64 0 : NS_IMPL_ADDREF_INHERITED(nsSVGFE,nsSVGFEBase)
65 0 : NS_IMPL_RELEASE_INHERITED(nsSVGFE,nsSVGFEBase)
66 :
67 0 : NS_INTERFACE_MAP_BEGIN(nsSVGFE)
68 : // nsISupports is an ambiguous base of nsSVGFE so we have to work
69 : // around that
70 0 : if ( aIID.Equals(NS_GET_IID(nsSVGFE)) )
71 0 : foundInterface = static_cast<nsISupports*>(static_cast<void*>(this));
72 : else
73 0 : NS_INTERFACE_MAP_END_INHERITING(nsSVGFEBase)
74 :
75 : //----------------------------------------------------------------------
76 : // Implementation
77 :
78 : void
79 0 : nsSVGFE::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
80 : {
81 0 : }
82 :
83 : bool
84 0 : nsSVGFE::OutputIsTainted(const nsTArray<bool>& aInputsAreTainted,
85 : nsIPrincipal* aReferencePrincipal)
86 : {
87 : // This is the default implementation for OutputIsTainted.
88 : // Our output is tainted if we have at least one tainted input.
89 0 : for (uint32_t i = 0; i < aInputsAreTainted.Length(); i++) {
90 0 : if (aInputsAreTainted[i]) {
91 0 : return true;
92 : }
93 : }
94 0 : return false;
95 : }
96 :
97 : bool
98 0 : nsSVGFE::AttributeAffectsRendering(int32_t aNameSpaceID,
99 : nsIAtom* aAttribute) const
100 : {
101 0 : return aNameSpaceID == kNameSpaceID_None &&
102 0 : (aAttribute == nsGkAtoms::x ||
103 0 : aAttribute == nsGkAtoms::y ||
104 0 : aAttribute == nsGkAtoms::width ||
105 0 : aAttribute == nsGkAtoms::height ||
106 0 : aAttribute == nsGkAtoms::result);
107 : }
108 :
109 : already_AddRefed<SVGAnimatedLength>
110 0 : nsSVGFE::X()
111 : {
112 0 : return mLengthAttributes[ATTR_X].ToDOMAnimatedLength(this);
113 : }
114 :
115 : already_AddRefed<SVGAnimatedLength>
116 0 : nsSVGFE::Y()
117 : {
118 0 : return mLengthAttributes[ATTR_Y].ToDOMAnimatedLength(this);
119 : }
120 :
121 : already_AddRefed<SVGAnimatedLength>
122 0 : nsSVGFE::Width()
123 : {
124 0 : return mLengthAttributes[ATTR_WIDTH].ToDOMAnimatedLength(this);
125 : }
126 :
127 : already_AddRefed<SVGAnimatedLength>
128 0 : nsSVGFE::Height()
129 : {
130 0 : return mLengthAttributes[ATTR_HEIGHT].ToDOMAnimatedLength(this);
131 : }
132 :
133 : already_AddRefed<SVGAnimatedString>
134 0 : nsSVGFE::Result()
135 : {
136 0 : return GetResultImageName().ToDOMAnimatedString(this);
137 : }
138 :
139 : //----------------------------------------------------------------------
140 : // nsIContent methods
141 :
142 : NS_IMETHODIMP_(bool)
143 0 : nsSVGFE::IsAttributeMapped(const nsIAtom* name) const
144 : {
145 : static const MappedAttributeEntry* const map[] = {
146 : sFiltersMap
147 : };
148 :
149 0 : return FindAttributeDependence(name, map) ||
150 0 : nsSVGFEBase::IsAttributeMapped(name);
151 : }
152 :
153 : //----------------------------------------------------------------------
154 : // nsSVGElement methods
155 :
156 :
157 : bool
158 0 : nsSVGFE::StyleIsSetToSRGB()
159 : {
160 0 : nsIFrame* frame = GetPrimaryFrame();
161 0 : if (!frame) return false;
162 :
163 0 : nsStyleContext* style = frame->StyleContext();
164 0 : return style->StyleSVG()->mColorInterpolationFilters ==
165 0 : NS_STYLE_COLOR_INTERPOLATION_SRGB;
166 : }
167 :
168 : /* virtual */ bool
169 0 : nsSVGFE::HasValidDimensions() const
170 : {
171 0 : return (!mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() ||
172 0 : mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
173 0 : (!mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() ||
174 0 : mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0);
175 : }
176 :
177 : Size
178 0 : nsSVGFE::GetKernelUnitLength(nsSVGFilterInstance* aInstance,
179 : nsSVGNumberPair *aKernelUnitLength)
180 : {
181 0 : if (!aKernelUnitLength->IsExplicitlySet()) {
182 0 : return Size(1, 1);
183 : }
184 :
185 : float kernelX = aInstance->GetPrimitiveNumber(SVGContentUtils::X,
186 : aKernelUnitLength,
187 0 : nsSVGNumberPair::eFirst);
188 : float kernelY = aInstance->GetPrimitiveNumber(SVGContentUtils::Y,
189 : aKernelUnitLength,
190 0 : nsSVGNumberPair::eSecond);
191 0 : return Size(kernelX, kernelY);
192 : }
193 :
194 : nsSVGElement::LengthAttributesInfo
195 0 : nsSVGFE::GetLengthInfo()
196 : {
197 : return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
198 0 : ArrayLength(sLengthInfo));
199 : }
200 :
201 : namespace mozilla {
202 : namespace dom {
203 :
204 : nsSVGElement::NumberListInfo SVGComponentTransferFunctionElement::sNumberListInfo[1] =
205 : {
206 : { &nsGkAtoms::tableValues }
207 : };
208 :
209 : nsSVGElement::NumberInfo SVGComponentTransferFunctionElement::sNumberInfo[5] =
210 : {
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 }
216 : };
217 :
218 : nsSVGEnumMapping SVGComponentTransferFunctionElement::sTypeMap[] = {
219 : {&nsGkAtoms::identity,
220 : SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY},
221 : {&nsGkAtoms::table,
222 : SVG_FECOMPONENTTRANSFER_TYPE_TABLE},
223 : {&nsGkAtoms::discrete,
224 : SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE},
225 : {&nsGkAtoms::linear,
226 : SVG_FECOMPONENTTRANSFER_TYPE_LINEAR},
227 : {&nsGkAtoms::gamma,
228 : SVG_FECOMPONENTTRANSFER_TYPE_GAMMA},
229 : {nullptr, 0}
230 : };
231 :
232 : nsSVGElement::EnumInfo SVGComponentTransferFunctionElement::sEnumInfo[1] =
233 : {
234 : { &nsGkAtoms::type,
235 : sTypeMap,
236 : SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY
237 : }
238 : };
239 :
240 : //----------------------------------------------------------------------
241 : // nsISupports methods
242 :
243 0 : NS_IMPL_ADDREF_INHERITED(SVGComponentTransferFunctionElement,SVGComponentTransferFunctionElementBase)
244 0 : NS_IMPL_RELEASE_INHERITED(SVGComponentTransferFunctionElement,SVGComponentTransferFunctionElementBase)
245 :
246 0 : NS_INTERFACE_MAP_BEGIN(SVGComponentTransferFunctionElement)
247 : // nsISupports is an ambiguous base of nsSVGFE so we have to work
248 : // around that
249 0 : if ( aIID.Equals(NS_GET_IID(SVGComponentTransferFunctionElement)) )
250 0 : foundInterface = static_cast<nsISupports*>(static_cast<void*>(this));
251 : else
252 0 : NS_INTERFACE_MAP_END_INHERITING(SVGComponentTransferFunctionElementBase)
253 :
254 :
255 : //----------------------------------------------------------------------
256 : // nsFEUnstyledElement methods
257 :
258 : bool
259 0 : SVGComponentTransferFunctionElement::AttributeAffectsRendering(int32_t aNameSpaceID,
260 : nsIAtom* aAttribute) const
261 : {
262 0 : return aNameSpaceID == kNameSpaceID_None &&
263 0 : (aAttribute == nsGkAtoms::tableValues ||
264 0 : aAttribute == nsGkAtoms::slope ||
265 0 : aAttribute == nsGkAtoms::intercept ||
266 0 : aAttribute == nsGkAtoms::amplitude ||
267 0 : aAttribute == nsGkAtoms::exponent ||
268 0 : aAttribute == nsGkAtoms::offset ||
269 0 : aAttribute == nsGkAtoms::type);
270 : }
271 :
272 : //----------------------------------------------------------------------
273 :
274 : already_AddRefed<SVGAnimatedEnumeration>
275 0 : SVGComponentTransferFunctionElement::Type()
276 : {
277 0 : return mEnumAttributes[TYPE].ToDOMAnimatedEnum(this);
278 : }
279 :
280 : already_AddRefed<DOMSVGAnimatedNumberList>
281 0 : SVGComponentTransferFunctionElement::TableValues()
282 : {
283 : return DOMSVGAnimatedNumberList::GetDOMWrapper(
284 0 : &mNumberListAttributes[TABLEVALUES], this, TABLEVALUES);
285 : }
286 :
287 : already_AddRefed<SVGAnimatedNumber>
288 0 : SVGComponentTransferFunctionElement::Slope()
289 : {
290 0 : return mNumberAttributes[SLOPE].ToDOMAnimatedNumber(this);
291 : }
292 :
293 : already_AddRefed<SVGAnimatedNumber>
294 0 : SVGComponentTransferFunctionElement::Intercept()
295 : {
296 0 : return mNumberAttributes[INTERCEPT].ToDOMAnimatedNumber(this);
297 : }
298 :
299 : already_AddRefed<SVGAnimatedNumber>
300 0 : SVGComponentTransferFunctionElement::Amplitude()
301 : {
302 0 : return mNumberAttributes[AMPLITUDE].ToDOMAnimatedNumber(this);
303 : }
304 :
305 : already_AddRefed<SVGAnimatedNumber>
306 0 : SVGComponentTransferFunctionElement::Exponent()
307 : {
308 0 : return mNumberAttributes[EXPONENT].ToDOMAnimatedNumber(this);
309 : }
310 :
311 : already_AddRefed<SVGAnimatedNumber>
312 0 : SVGComponentTransferFunctionElement::Offset()
313 : {
314 0 : return mNumberAttributes[OFFSET].ToDOMAnimatedNumber(this);
315 : }
316 :
317 : AttributeMap
318 0 : SVGComponentTransferFunctionElement::ComputeAttributes()
319 : {
320 0 : uint32_t type = mEnumAttributes[TYPE].GetAnimValue();
321 :
322 : float slope, intercept, amplitude, exponent, offset;
323 0 : GetAnimatedNumberValues(&slope, &intercept, &litude,
324 0 : &exponent, &offset, nullptr);
325 :
326 : const SVGNumberList &tableValues =
327 0 : mNumberListAttributes[TABLEVALUES].GetAnimValue();
328 :
329 0 : AttributeMap map;
330 0 : map.Set(eComponentTransferFunctionType, type);
331 0 : map.Set(eComponentTransferFunctionSlope, slope);
332 0 : map.Set(eComponentTransferFunctionIntercept, intercept);
333 0 : map.Set(eComponentTransferFunctionAmplitude, amplitude);
334 0 : map.Set(eComponentTransferFunctionExponent, exponent);
335 0 : map.Set(eComponentTransferFunctionOffset, offset);
336 0 : if (tableValues.Length()) {
337 0 : map.Set(eComponentTransferFunctionTableValues, &tableValues[0], tableValues.Length());
338 : } else {
339 0 : map.Set(eComponentTransferFunctionTableValues, nullptr, 0);
340 : }
341 0 : return map;
342 : }
343 :
344 : //----------------------------------------------------------------------
345 : // nsSVGElement methods
346 :
347 : nsSVGElement::NumberListAttributesInfo
348 0 : SVGComponentTransferFunctionElement::GetNumberListInfo()
349 : {
350 : return NumberListAttributesInfo(mNumberListAttributes, sNumberListInfo,
351 0 : ArrayLength(sNumberListInfo));
352 : }
353 :
354 : nsSVGElement::EnumAttributesInfo
355 0 : SVGComponentTransferFunctionElement::GetEnumInfo()
356 : {
357 : return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
358 0 : ArrayLength(sEnumInfo));
359 : }
360 :
361 : nsSVGElement::NumberAttributesInfo
362 0 : SVGComponentTransferFunctionElement::GetNumberInfo()
363 : {
364 : return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
365 0 : ArrayLength(sNumberInfo));
366 : }
367 :
368 : /* virtual */ JSObject*
369 0 : SVGFEFuncRElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
370 : {
371 0 : return SVGFEFuncRElementBinding::Wrap(aCx, this, aGivenProto);
372 : }
373 :
374 : } // namespace dom
375 : } // namespace mozilla
376 :
377 0 : NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFuncR)
378 :
379 : namespace mozilla {
380 : namespace dom {
381 :
382 0 : NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFuncRElement)
383 :
384 : /* virtual */ JSObject*
385 0 : SVGFEFuncGElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
386 : {
387 0 : return SVGFEFuncGElementBinding::Wrap(aCx, this, aGivenProto);
388 : }
389 :
390 : } // namespace dom
391 : } // namespace mozilla
392 :
393 0 : NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFuncG)
394 :
395 : namespace mozilla {
396 : namespace dom {
397 :
398 0 : NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFuncGElement)
399 :
400 : /* virtual */ JSObject*
401 0 : SVGFEFuncBElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
402 : {
403 0 : return SVGFEFuncBElementBinding::Wrap(aCx, this, aGivenProto);
404 : }
405 :
406 : } // namespace dom
407 : } // namespace mozilla
408 :
409 0 : NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFuncB)
410 :
411 : namespace mozilla {
412 : namespace dom {
413 :
414 0 : NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFuncBElement)
415 :
416 : /* virtual */ JSObject*
417 0 : SVGFEFuncAElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
418 : {
419 0 : return SVGFEFuncAElementBinding::Wrap(aCx, this, aGivenProto);
420 : }
421 :
422 : } // namespace dom
423 : } // namespace mozilla
424 :
425 0 : NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFuncA)
426 :
427 : namespace mozilla {
428 : namespace dom {
429 :
430 0 : NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFuncAElement)
431 :
432 : } // namespace dom
433 : } // namespace mozilla
434 :
435 : //--------------------------------------------------------------------
436 : //
437 : nsSVGElement::NumberInfo nsSVGFELightingElement::sNumberInfo[4] =
438 : {
439 : { &nsGkAtoms::surfaceScale, 1, false },
440 : { &nsGkAtoms::diffuseConstant, 1, false },
441 : { &nsGkAtoms::specularConstant, 1, false },
442 : { &nsGkAtoms::specularExponent, 1, false }
443 : };
444 :
445 : nsSVGElement::NumberPairInfo nsSVGFELightingElement::sNumberPairInfo[1] =
446 : {
447 : { &nsGkAtoms::kernelUnitLength, 0, 0 }
448 : };
449 :
450 : nsSVGElement::StringInfo nsSVGFELightingElement::sStringInfo[2] =
451 : {
452 : { &nsGkAtoms::result, kNameSpaceID_None, true },
453 : { &nsGkAtoms::in, kNameSpaceID_None, true }
454 : };
455 :
456 : //----------------------------------------------------------------------
457 : // nsISupports methods
458 :
459 0 : NS_IMPL_ADDREF_INHERITED(nsSVGFELightingElement,nsSVGFELightingElementBase)
460 0 : NS_IMPL_RELEASE_INHERITED(nsSVGFELightingElement,nsSVGFELightingElementBase)
461 :
462 0 : NS_INTERFACE_MAP_BEGIN(nsSVGFELightingElement)
463 0 : NS_INTERFACE_MAP_END_INHERITING(nsSVGFELightingElementBase)
464 :
465 : //----------------------------------------------------------------------
466 : // Implementation
467 :
468 : NS_IMETHODIMP_(bool)
469 0 : nsSVGFELightingElement::IsAttributeMapped(const nsIAtom* name) const
470 : {
471 : static const MappedAttributeEntry* const map[] = {
472 : sLightingEffectsMap
473 : };
474 :
475 0 : return FindAttributeDependence(name, map) ||
476 0 : nsSVGFELightingElementBase::IsAttributeMapped(name);
477 : }
478 :
479 : void
480 0 : nsSVGFELightingElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
481 : {
482 0 : aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
483 0 : }
484 :
485 : AttributeMap
486 0 : nsSVGFELightingElement::ComputeLightAttributes(nsSVGFilterInstance* aInstance)
487 : {
488 : // find specified light
489 0 : for (nsCOMPtr<nsIContent> child = nsINode::GetFirstChild();
490 : child;
491 0 : child = child->GetNextSibling()) {
492 0 : if (child->IsAnyOfSVGElements(nsGkAtoms::feDistantLight,
493 : nsGkAtoms::fePointLight,
494 : nsGkAtoms::feSpotLight)) {
495 0 : return static_cast<SVGFELightElement*>(child.get())->ComputeLightAttributes(aInstance);
496 : }
497 : }
498 :
499 0 : AttributeMap map;
500 0 : map.Set(eLightType, (uint32_t)eLightTypeNone);
501 0 : return map;
502 : }
503 :
504 : FilterPrimitiveDescription
505 0 : nsSVGFELightingElement::AddLightingAttributes(const FilterPrimitiveDescription& aDescription,
506 : nsSVGFilterInstance* aInstance)
507 : {
508 0 : nsIFrame* frame = GetPrimaryFrame();
509 0 : if (!frame) {
510 0 : return FilterPrimitiveDescription(PrimitiveType::Empty);
511 : }
512 :
513 0 : nsStyleContext* style = frame->StyleContext();
514 0 : Color color(Color::FromABGR(style->StyleSVGReset()->mLightingColor));
515 0 : color.a = 1.f;
516 0 : float surfaceScale = mNumberAttributes[SURFACE_SCALE].GetAnimValue();
517 : Size kernelUnitLength =
518 0 : GetKernelUnitLength(aInstance, &mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
519 :
520 0 : if (kernelUnitLength.width <= 0 || kernelUnitLength.height <= 0) {
521 : // According to spec, A negative or zero value is an error. See link below for details.
522 : // https://www.w3.org/TR/SVG/filters.html#feSpecularLightingKernelUnitLengthAttribute
523 0 : return FilterPrimitiveDescription(PrimitiveType::Empty);
524 : }
525 :
526 0 : FilterPrimitiveDescription descr = aDescription;
527 0 : descr.Attributes().Set(eLightingLight, ComputeLightAttributes(aInstance));
528 0 : descr.Attributes().Set(eLightingSurfaceScale, surfaceScale);
529 0 : descr.Attributes().Set(eLightingKernelUnitLength, kernelUnitLength);
530 0 : descr.Attributes().Set(eLightingColor, color);
531 0 : return descr;
532 : }
533 :
534 : bool
535 0 : nsSVGFELightingElement::AttributeAffectsRendering(int32_t aNameSpaceID,
536 : nsIAtom* aAttribute) const
537 : {
538 0 : return nsSVGFELightingElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
539 0 : (aNameSpaceID == kNameSpaceID_None &&
540 0 : (aAttribute == nsGkAtoms::in ||
541 0 : aAttribute == nsGkAtoms::surfaceScale ||
542 0 : aAttribute == nsGkAtoms::kernelUnitLength));
543 : }
544 :
545 : //----------------------------------------------------------------------
546 : // nsSVGElement methods
547 :
548 : nsSVGElement::NumberAttributesInfo
549 0 : nsSVGFELightingElement::GetNumberInfo()
550 : {
551 : return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
552 0 : ArrayLength(sNumberInfo));
553 : }
554 :
555 : nsSVGElement::NumberPairAttributesInfo
556 0 : nsSVGFELightingElement::GetNumberPairInfo()
557 : {
558 : return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
559 0 : ArrayLength(sNumberPairInfo));
560 : }
561 :
562 : nsSVGElement::StringAttributesInfo
563 0 : nsSVGFELightingElement::GetStringInfo()
564 : {
565 : return StringAttributesInfo(mStringAttributes, sStringInfo,
566 0 : ArrayLength(sStringInfo));
567 : }
|