Bug 1936278 - Prevent search mode chiclet from being dismissed when clicking in page...
[gecko.git] / dom / svg / SVGFEConvolveMatrixElement.cpp
blob5550fa53a985db58484c7915ca2ab0d684efc40f
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/SVGFilterInstance.h"
10 #include "mozilla/SVGUtils.h"
11 #include "mozilla/UniquePtr.h"
12 #include "mozilla/UniquePtrExtensions.h"
13 #include "DOMSVGAnimatedNumberList.h"
14 #include "mozilla/dom/Document.h"
15 #include "mozilla/dom/BindContext.h"
16 #include <numeric>
18 NS_IMPL_NS_NEW_SVG_ELEMENT(FEConvolveMatrix)
20 using namespace mozilla::gfx;
22 namespace mozilla::dom {
24 JSObject* SVGFEConvolveMatrixElement::WrapNode(
25 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
26 return SVGFEConvolveMatrixElement_Binding::Wrap(aCx, this, aGivenProto);
29 SVGElement::NumberInfo SVGFEConvolveMatrixElement::sNumberInfo[2] = {
30 {nsGkAtoms::divisor, 1}, {nsGkAtoms::bias, 0}};
32 SVGElement::NumberPairInfo SVGFEConvolveMatrixElement::sNumberPairInfo[1] = {
33 {nsGkAtoms::kernelUnitLength, 0, 0}};
35 SVGElement::IntegerInfo SVGFEConvolveMatrixElement::sIntegerInfo[2] = {
36 {nsGkAtoms::targetX, 0}, {nsGkAtoms::targetY, 0}};
38 SVGElement::IntegerPairInfo SVGFEConvolveMatrixElement::sIntegerPairInfo[1] = {
39 {nsGkAtoms::order, 3, 3}};
41 SVGElement::BooleanInfo SVGFEConvolveMatrixElement::sBooleanInfo[1] = {
42 {nsGkAtoms::preserveAlpha, false}};
44 SVGEnumMapping SVGFEConvolveMatrixElement::sEdgeModeMap[] = {
45 {nsGkAtoms::duplicate, SVG_EDGEMODE_DUPLICATE},
46 {nsGkAtoms::wrap, SVG_EDGEMODE_WRAP},
47 {nsGkAtoms::none, SVG_EDGEMODE_NONE},
48 {nullptr, 0}};
50 SVGElement::EnumInfo SVGFEConvolveMatrixElement::sEnumInfo[1] = {
51 {nsGkAtoms::edgeMode, sEdgeModeMap, SVG_EDGEMODE_DUPLICATE}};
53 SVGElement::StringInfo SVGFEConvolveMatrixElement::sStringInfo[2] = {
54 {nsGkAtoms::result, kNameSpaceID_None, true},
55 {nsGkAtoms::in, kNameSpaceID_None, true}};
57 SVGElement::NumberListInfo SVGFEConvolveMatrixElement::sNumberListInfo[1] = {
58 {nsGkAtoms::kernelMatrix}};
60 //----------------------------------------------------------------------
61 // nsINode methods
63 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEConvolveMatrixElement)
65 //----------------------------------------------------------------------
67 already_AddRefed<DOMSVGAnimatedString> SVGFEConvolveMatrixElement::In1() {
68 return mStringAttributes[IN1].ToDOMAnimatedString(this);
71 already_AddRefed<DOMSVGAnimatedInteger> SVGFEConvolveMatrixElement::OrderX() {
72 return mIntegerPairAttributes[ORDER].ToDOMAnimatedInteger(
73 SVGAnimatedIntegerPair::eFirst, this);
76 already_AddRefed<DOMSVGAnimatedInteger> SVGFEConvolveMatrixElement::OrderY() {
77 return mIntegerPairAttributes[ORDER].ToDOMAnimatedInteger(
78 SVGAnimatedIntegerPair::eSecond, this);
81 already_AddRefed<DOMSVGAnimatedNumberList>
82 SVGFEConvolveMatrixElement::KernelMatrix() {
83 return DOMSVGAnimatedNumberList::GetDOMWrapper(
84 &mNumberListAttributes[KERNELMATRIX], this, KERNELMATRIX);
87 already_AddRefed<DOMSVGAnimatedInteger> SVGFEConvolveMatrixElement::TargetX() {
88 return mIntegerAttributes[TARGET_X].ToDOMAnimatedInteger(this);
91 already_AddRefed<DOMSVGAnimatedInteger> SVGFEConvolveMatrixElement::TargetY() {
92 return mIntegerAttributes[TARGET_Y].ToDOMAnimatedInteger(this);
95 already_AddRefed<DOMSVGAnimatedEnumeration>
96 SVGFEConvolveMatrixElement::EdgeMode() {
97 return mEnumAttributes[EDGEMODE].ToDOMAnimatedEnum(this);
100 already_AddRefed<DOMSVGAnimatedBoolean>
101 SVGFEConvolveMatrixElement::PreserveAlpha() {
102 return mBooleanAttributes[PRESERVEALPHA].ToDOMAnimatedBoolean(this);
105 already_AddRefed<DOMSVGAnimatedNumber> SVGFEConvolveMatrixElement::Divisor() {
106 return mNumberAttributes[DIVISOR].ToDOMAnimatedNumber(this);
109 already_AddRefed<DOMSVGAnimatedNumber> SVGFEConvolveMatrixElement::Bias() {
110 return mNumberAttributes[BIAS].ToDOMAnimatedNumber(this);
113 already_AddRefed<DOMSVGAnimatedNumber>
114 SVGFEConvolveMatrixElement::KernelUnitLengthX() {
115 return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(
116 SVGAnimatedNumberPair::eFirst, this);
119 already_AddRefed<DOMSVGAnimatedNumber>
120 SVGFEConvolveMatrixElement::KernelUnitLengthY() {
121 return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(
122 SVGAnimatedNumberPair::eSecond, this);
125 void SVGFEConvolveMatrixElement::GetSourceImageNames(
126 nsTArray<SVGStringInfo>& aSources) {
127 aSources.AppendElement(SVGStringInfo(&mStringAttributes[IN1], this));
130 FilterPrimitiveDescription SVGFEConvolveMatrixElement::GetPrimitiveDescription(
131 SVGFilterInstance* aInstance, const IntRect& aFilterSubregion,
132 const nsTArray<bool>& aInputsAreTainted,
133 nsTArray<RefPtr<SourceSurface>>& aInputImages) {
134 FilterPrimitiveDescription failureDescription;
136 const SVGNumberList& kernelMatrix =
137 mNumberListAttributes[KERNELMATRIX].GetAnimValue();
138 uint32_t kmLength = kernelMatrix.Length();
140 int32_t orderX = mIntegerPairAttributes[ORDER].GetAnimValue(
141 SVGAnimatedIntegerPair::eFirst);
142 int32_t orderY = mIntegerPairAttributes[ORDER].GetAnimValue(
143 SVGAnimatedIntegerPair::eSecond);
145 if (orderX <= 0 || orderY <= 0 ||
146 static_cast<uint32_t>(orderX * orderY) != kmLength) {
147 return failureDescription;
150 int32_t targetX, targetY;
151 GetAnimatedIntegerValues(&targetX, &targetY, nullptr);
153 if (mIntegerAttributes[TARGET_X].IsExplicitlySet()) {
154 if (targetX < 0 || targetX >= orderX) return failureDescription;
155 } else {
156 targetX = orderX / 2;
158 if (mIntegerAttributes[TARGET_Y].IsExplicitlySet()) {
159 if (targetY < 0 || targetY >= orderY) return failureDescription;
160 } else {
161 targetY = orderY / 2;
164 if (orderX > NS_SVG_OFFSCREEN_MAX_DIMENSION ||
165 orderY > NS_SVG_OFFSCREEN_MAX_DIMENSION)
166 return failureDescription;
168 float divisor;
169 if (mNumberAttributes[DIVISOR].IsExplicitlySet()) {
170 divisor = mNumberAttributes[DIVISOR].GetAnimValue();
171 if (divisor == 0) return failureDescription;
172 } else {
173 divisor = std::accumulate(kernelMatrix.begin(), kernelMatrix.end(), 0.0f);
174 if (divisor == 0) divisor = 1;
177 uint32_t edgeMode = mEnumAttributes[EDGEMODE].GetAnimValue();
178 bool preserveAlpha = mBooleanAttributes[PRESERVEALPHA].GetAnimValue();
179 float bias = mNumberAttributes[BIAS].GetAnimValue();
181 Size kernelUnitLength = GetKernelUnitLength(
182 aInstance, &mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
184 if (kernelUnitLength.width <= 0 || kernelUnitLength.height <= 0) {
185 // According to spec, A negative or zero value is an error. See link below
186 // for details.
187 // https://www.w3.org/TR/SVG/filters.html#feConvolveMatrixElementKernelUnitLengthAttribute
188 return failureDescription;
191 ConvolveMatrixAttributes atts;
192 atts.mKernelSize = IntSize(orderX, orderY);
193 atts.mKernelMatrix.AppendElements(&kernelMatrix[0], kmLength);
194 atts.mDivisor = divisor;
195 atts.mBias = bias;
196 atts.mTarget = IntPoint(targetX, targetY);
197 atts.mEdgeMode = edgeMode;
198 atts.mKernelUnitLength = kernelUnitLength;
199 atts.mPreserveAlpha = preserveAlpha;
201 return FilterPrimitiveDescription(AsVariant(std::move(atts)));
204 bool SVGFEConvolveMatrixElement::AttributeAffectsRendering(
205 int32_t aNameSpaceID, nsAtom* aAttribute) const {
206 return SVGFEConvolveMatrixElementBase::AttributeAffectsRendering(
207 aNameSpaceID, aAttribute) ||
208 (aNameSpaceID == kNameSpaceID_None &&
209 (aAttribute == nsGkAtoms::in || aAttribute == nsGkAtoms::divisor ||
210 aAttribute == nsGkAtoms::bias ||
211 aAttribute == nsGkAtoms::kernelUnitLength ||
212 aAttribute == nsGkAtoms::targetX ||
213 aAttribute == nsGkAtoms::targetY || aAttribute == nsGkAtoms::order ||
214 aAttribute == nsGkAtoms::preserveAlpha ||
215 aAttribute == nsGkAtoms::edgeMode ||
216 aAttribute == nsGkAtoms::kernelMatrix));
219 nsresult SVGFEConvolveMatrixElement::BindToTree(BindContext& aCtx,
220 nsINode& aParent) {
221 if (aCtx.InComposedDoc()) {
222 aCtx.OwnerDoc().SetUseCounter(eUseCounter_custom_feConvolveMatrix);
225 return SVGFEConvolveMatrixElementBase::BindToTree(aCtx, aParent);
228 //----------------------------------------------------------------------
229 // SVGElement methods
231 SVGElement::NumberAttributesInfo SVGFEConvolveMatrixElement::GetNumberInfo() {
232 return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
233 std::size(sNumberInfo));
236 SVGElement::NumberPairAttributesInfo
237 SVGFEConvolveMatrixElement::GetNumberPairInfo() {
238 return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
239 std::size(sNumberPairInfo));
242 SVGElement::IntegerAttributesInfo SVGFEConvolveMatrixElement::GetIntegerInfo() {
243 return IntegerAttributesInfo(mIntegerAttributes, sIntegerInfo,
244 std::size(sIntegerInfo));
247 SVGElement::IntegerPairAttributesInfo
248 SVGFEConvolveMatrixElement::GetIntegerPairInfo() {
249 return IntegerPairAttributesInfo(mIntegerPairAttributes, sIntegerPairInfo,
250 std::size(sIntegerPairInfo));
253 SVGElement::BooleanAttributesInfo SVGFEConvolveMatrixElement::GetBooleanInfo() {
254 return BooleanAttributesInfo(mBooleanAttributes, sBooleanInfo,
255 std::size(sBooleanInfo));
258 SVGElement::EnumAttributesInfo SVGFEConvolveMatrixElement::GetEnumInfo() {
259 return EnumAttributesInfo(mEnumAttributes, sEnumInfo, std::size(sEnumInfo));
262 SVGElement::StringAttributesInfo SVGFEConvolveMatrixElement::GetStringInfo() {
263 return StringAttributesInfo(mStringAttributes, sStringInfo,
264 std::size(sStringInfo));
267 SVGElement::NumberListAttributesInfo
268 SVGFEConvolveMatrixElement::GetNumberListInfo() {
269 return NumberListAttributesInfo(mNumberListAttributes, sNumberListInfo,
270 std::size(sNumberListInfo));
273 } // namespace mozilla::dom