Bug 1444460 [wpt PR 9948] - gyroscope: Rename LocalCoordinateSystem to GyroscopeLocal...
[gecko.git] / dom / svg / SVGFEConvolveMatrixElement.cpp
blobc3d2f01506c9fa62a0948ffbb4734e12841a51d1
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/. */
7 #include "mozilla/dom/SVGFEConvolveMatrixElement.h"
8 #include "mozilla/dom/SVGFEConvolveMatrixElementBinding.h"
9 #include "mozilla/UniquePtr.h"
10 #include "mozilla/UniquePtrExtensions.h"
11 #include "DOMSVGAnimatedNumberList.h"
12 #include "nsSVGUtils.h"
13 #include "nsSVGFilterInstance.h"
15 NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEConvolveMatrix)
17 using namespace mozilla::gfx;
19 namespace mozilla {
20 namespace dom {
22 JSObject*
23 SVGFEConvolveMatrixElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
25 return SVGFEConvolveMatrixElementBinding::Wrap(aCx, this, aGivenProto);
28 nsSVGElement::NumberInfo SVGFEConvolveMatrixElement::sNumberInfo[2] =
30 { &nsGkAtoms::divisor, 1, false },
31 { &nsGkAtoms::bias, 0, false }
34 nsSVGElement::NumberPairInfo SVGFEConvolveMatrixElement::sNumberPairInfo[1] =
36 { &nsGkAtoms::kernelUnitLength, 0, 0 }
39 nsSVGElement::IntegerInfo SVGFEConvolveMatrixElement::sIntegerInfo[2] =
41 { &nsGkAtoms::targetX, 0 },
42 { &nsGkAtoms::targetY, 0 }
45 nsSVGElement::IntegerPairInfo SVGFEConvolveMatrixElement::sIntegerPairInfo[1] =
47 { &nsGkAtoms::order, 3, 3 }
50 nsSVGElement::BooleanInfo SVGFEConvolveMatrixElement::sBooleanInfo[1] =
52 { &nsGkAtoms::preserveAlpha, false }
55 nsSVGEnumMapping SVGFEConvolveMatrixElement::sEdgeModeMap[] = {
56 {&nsGkAtoms::duplicate, SVG_EDGEMODE_DUPLICATE},
57 {&nsGkAtoms::wrap, SVG_EDGEMODE_WRAP},
58 {&nsGkAtoms::none, SVG_EDGEMODE_NONE},
59 {nullptr, 0}
62 nsSVGElement::EnumInfo SVGFEConvolveMatrixElement::sEnumInfo[1] =
64 { &nsGkAtoms::edgeMode,
65 sEdgeModeMap,
66 SVG_EDGEMODE_DUPLICATE
70 nsSVGElement::StringInfo SVGFEConvolveMatrixElement::sStringInfo[2] =
72 { &nsGkAtoms::result, kNameSpaceID_None, true },
73 { &nsGkAtoms::in, kNameSpaceID_None, true }
76 nsSVGElement::NumberListInfo SVGFEConvolveMatrixElement::sNumberListInfo[1] =
78 { &nsGkAtoms::kernelMatrix }
81 //----------------------------------------------------------------------
82 // nsIDOMNode methods
84 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEConvolveMatrixElement)
86 //----------------------------------------------------------------------
88 already_AddRefed<SVGAnimatedString>
89 SVGFEConvolveMatrixElement::In1()
91 return mStringAttributes[IN1].ToDOMAnimatedString(this);
94 already_AddRefed<SVGAnimatedInteger>
95 SVGFEConvolveMatrixElement::OrderX()
97 return mIntegerPairAttributes[ORDER].ToDOMAnimatedInteger(nsSVGIntegerPair::eFirst, this);
100 already_AddRefed<SVGAnimatedInteger>
101 SVGFEConvolveMatrixElement::OrderY()
103 return mIntegerPairAttributes[ORDER].ToDOMAnimatedInteger(nsSVGIntegerPair::eSecond, this);
106 already_AddRefed<DOMSVGAnimatedNumberList>
107 SVGFEConvolveMatrixElement::KernelMatrix()
109 return DOMSVGAnimatedNumberList::GetDOMWrapper(&mNumberListAttributes[KERNELMATRIX],
110 this, KERNELMATRIX);
113 already_AddRefed<SVGAnimatedInteger>
114 SVGFEConvolveMatrixElement::TargetX()
116 return mIntegerAttributes[TARGET_X].ToDOMAnimatedInteger(this);
119 already_AddRefed<SVGAnimatedInteger>
120 SVGFEConvolveMatrixElement::TargetY()
122 return mIntegerAttributes[TARGET_Y].ToDOMAnimatedInteger(this);
125 already_AddRefed<SVGAnimatedEnumeration>
126 SVGFEConvolveMatrixElement::EdgeMode()
128 return mEnumAttributes[EDGEMODE].ToDOMAnimatedEnum(this);
131 already_AddRefed<SVGAnimatedBoolean>
132 SVGFEConvolveMatrixElement::PreserveAlpha()
134 return mBooleanAttributes[PRESERVEALPHA].ToDOMAnimatedBoolean(this);
137 already_AddRefed<SVGAnimatedNumber>
138 SVGFEConvolveMatrixElement::Divisor()
140 return mNumberAttributes[DIVISOR].ToDOMAnimatedNumber(this);
143 already_AddRefed<SVGAnimatedNumber>
144 SVGFEConvolveMatrixElement::Bias()
146 return mNumberAttributes[BIAS].ToDOMAnimatedNumber(this);
149 already_AddRefed<SVGAnimatedNumber>
150 SVGFEConvolveMatrixElement::KernelUnitLengthX()
152 return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(nsSVGNumberPair::eFirst,
153 this);
156 already_AddRefed<SVGAnimatedNumber>
157 SVGFEConvolveMatrixElement::KernelUnitLengthY()
159 return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(nsSVGNumberPair::eSecond,
160 this);
163 void
164 SVGFEConvolveMatrixElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
166 aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
169 FilterPrimitiveDescription
170 SVGFEConvolveMatrixElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
171 const IntRect& aFilterSubregion,
172 const nsTArray<bool>& aInputsAreTainted,
173 nsTArray<RefPtr<SourceSurface>>& aInputImages)
175 const FilterPrimitiveDescription failureDescription(PrimitiveType::Empty);
177 const SVGNumberList &kernelMatrix =
178 mNumberListAttributes[KERNELMATRIX].GetAnimValue();
179 uint32_t kmLength = kernelMatrix.Length();
181 int32_t orderX = mIntegerPairAttributes[ORDER].GetAnimValue(nsSVGIntegerPair::eFirst);
182 int32_t orderY = mIntegerPairAttributes[ORDER].GetAnimValue(nsSVGIntegerPair::eSecond);
184 if (orderX <= 0 || orderY <= 0 ||
185 static_cast<uint32_t>(orderX * orderY) != kmLength) {
186 return failureDescription;
189 int32_t targetX, targetY;
190 GetAnimatedIntegerValues(&targetX, &targetY, nullptr);
192 if (mIntegerAttributes[TARGET_X].IsExplicitlySet()) {
193 if (targetX < 0 || targetX >= orderX)
194 return failureDescription;
195 } else {
196 targetX = orderX / 2;
198 if (mIntegerAttributes[TARGET_Y].IsExplicitlySet()) {
199 if (targetY < 0 || targetY >= orderY)
200 return failureDescription;
201 } else {
202 targetY = orderY / 2;
205 if (orderX > NS_SVG_OFFSCREEN_MAX_DIMENSION ||
206 orderY > NS_SVG_OFFSCREEN_MAX_DIMENSION)
207 return failureDescription;
208 UniquePtr<float[]> kernel = MakeUniqueFallible<float[]>(orderX * orderY);
209 if (!kernel)
210 return failureDescription;
211 for (uint32_t i = 0; i < kmLength; i++) {
212 kernel[kmLength - 1 - i] = kernelMatrix[i];
215 float divisor;
216 if (mNumberAttributes[DIVISOR].IsExplicitlySet()) {
217 divisor = mNumberAttributes[DIVISOR].GetAnimValue();
218 if (divisor == 0)
219 return failureDescription;
220 } else {
221 divisor = kernel[0];
222 for (uint32_t i = 1; i < kmLength; i++)
223 divisor += kernel[i];
224 if (divisor == 0)
225 divisor = 1;
228 uint32_t edgeMode = mEnumAttributes[EDGEMODE].GetAnimValue();
229 bool preserveAlpha = mBooleanAttributes[PRESERVEALPHA].GetAnimValue();
230 float bias = mNumberAttributes[BIAS].GetAnimValue();
232 Size kernelUnitLength =
233 GetKernelUnitLength(aInstance, &mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
235 if (kernelUnitLength.width <= 0 || kernelUnitLength.height <= 0) {
236 // According to spec, A negative or zero value is an error. See link below for details.
237 // https://www.w3.org/TR/SVG/filters.html#feConvolveMatrixElementKernelUnitLengthAttribute
238 return failureDescription;
241 FilterPrimitiveDescription descr(PrimitiveType::ConvolveMatrix);
242 AttributeMap& atts = descr.Attributes();
243 atts.Set(eConvolveMatrixKernelSize, IntSize(orderX, orderY));
244 atts.Set(eConvolveMatrixKernelMatrix, &kernelMatrix[0], kmLength);
245 atts.Set(eConvolveMatrixDivisor, divisor);
246 atts.Set(eConvolveMatrixBias, bias);
247 atts.Set(eConvolveMatrixTarget, IntPoint(targetX, targetY));
248 atts.Set(eConvolveMatrixEdgeMode, edgeMode);
249 atts.Set(eConvolveMatrixKernelUnitLength, kernelUnitLength);
250 atts.Set(eConvolveMatrixPreserveAlpha, preserveAlpha);
252 return descr;
255 bool
256 SVGFEConvolveMatrixElement::AttributeAffectsRendering(int32_t aNameSpaceID,
257 nsAtom* aAttribute) const
259 return SVGFEConvolveMatrixElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
260 (aNameSpaceID == kNameSpaceID_None &&
261 (aAttribute == nsGkAtoms::in ||
262 aAttribute == nsGkAtoms::divisor ||
263 aAttribute == nsGkAtoms::bias ||
264 aAttribute == nsGkAtoms::kernelUnitLength ||
265 aAttribute == nsGkAtoms::targetX ||
266 aAttribute == nsGkAtoms::targetY ||
267 aAttribute == nsGkAtoms::order ||
268 aAttribute == nsGkAtoms::preserveAlpha||
269 aAttribute == nsGkAtoms::edgeMode ||
270 aAttribute == nsGkAtoms::kernelMatrix));
273 //----------------------------------------------------------------------
274 // nsSVGElement methods
276 nsSVGElement::NumberAttributesInfo
277 SVGFEConvolveMatrixElement::GetNumberInfo()
279 return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
280 ArrayLength(sNumberInfo));
283 nsSVGElement::NumberPairAttributesInfo
284 SVGFEConvolveMatrixElement::GetNumberPairInfo()
286 return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
287 ArrayLength(sNumberPairInfo));
290 nsSVGElement::IntegerAttributesInfo
291 SVGFEConvolveMatrixElement::GetIntegerInfo()
293 return IntegerAttributesInfo(mIntegerAttributes, sIntegerInfo,
294 ArrayLength(sIntegerInfo));
297 nsSVGElement::IntegerPairAttributesInfo
298 SVGFEConvolveMatrixElement::GetIntegerPairInfo()
300 return IntegerPairAttributesInfo(mIntegerPairAttributes, sIntegerPairInfo,
301 ArrayLength(sIntegerPairInfo));
304 nsSVGElement::BooleanAttributesInfo
305 SVGFEConvolveMatrixElement::GetBooleanInfo()
307 return BooleanAttributesInfo(mBooleanAttributes, sBooleanInfo,
308 ArrayLength(sBooleanInfo));
311 nsSVGElement::EnumAttributesInfo
312 SVGFEConvolveMatrixElement::GetEnumInfo()
314 return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
315 ArrayLength(sEnumInfo));
318 nsSVGElement::StringAttributesInfo
319 SVGFEConvolveMatrixElement::GetStringInfo()
321 return StringAttributesInfo(mStringAttributes, sStringInfo,
322 ArrayLength(sStringInfo));
325 nsSVGElement::NumberListAttributesInfo
326 SVGFEConvolveMatrixElement::GetNumberListInfo()
328 return NumberListAttributesInfo(mNumberListAttributes, sNumberListInfo,
329 ArrayLength(sNumberListInfo));
332 } // namespace dom
333 } // namespace mozilla