123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "mozilla/dom/SVGFEConvolveMatrixElement.h"
- #include "mozilla/dom/SVGFEConvolveMatrixElementBinding.h"
- #include "mozilla/UniquePtr.h"
- #include "mozilla/UniquePtrExtensions.h"
- #include "DOMSVGAnimatedNumberList.h"
- #include "nsSVGUtils.h"
- #include "nsSVGFilterInstance.h"
- NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEConvolveMatrix)
- using namespace mozilla::gfx;
- namespace mozilla {
- namespace dom {
- JSObject*
- SVGFEConvolveMatrixElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
- {
- return SVGFEConvolveMatrixElementBinding::Wrap(aCx, this, aGivenProto);
- }
- nsSVGElement::NumberInfo SVGFEConvolveMatrixElement::sNumberInfo[2] =
- {
- { &nsGkAtoms::divisor, 1, false },
- { &nsGkAtoms::bias, 0, false }
- };
- nsSVGElement::NumberPairInfo SVGFEConvolveMatrixElement::sNumberPairInfo[1] =
- {
- { &nsGkAtoms::kernelUnitLength, 0, 0 }
- };
- nsSVGElement::IntegerInfo SVGFEConvolveMatrixElement::sIntegerInfo[2] =
- {
- { &nsGkAtoms::targetX, 0 },
- { &nsGkAtoms::targetY, 0 }
- };
- nsSVGElement::IntegerPairInfo SVGFEConvolveMatrixElement::sIntegerPairInfo[1] =
- {
- { &nsGkAtoms::order, 3, 3 }
- };
- nsSVGElement::BooleanInfo SVGFEConvolveMatrixElement::sBooleanInfo[1] =
- {
- { &nsGkAtoms::preserveAlpha, false }
- };
- nsSVGEnumMapping SVGFEConvolveMatrixElement::sEdgeModeMap[] = {
- {&nsGkAtoms::duplicate, SVG_EDGEMODE_DUPLICATE},
- {&nsGkAtoms::wrap, SVG_EDGEMODE_WRAP},
- {&nsGkAtoms::none, SVG_EDGEMODE_NONE},
- {nullptr, 0}
- };
- nsSVGElement::EnumInfo SVGFEConvolveMatrixElement::sEnumInfo[1] =
- {
- { &nsGkAtoms::edgeMode,
- sEdgeModeMap,
- SVG_EDGEMODE_DUPLICATE
- }
- };
- nsSVGElement::StringInfo SVGFEConvolveMatrixElement::sStringInfo[2] =
- {
- { &nsGkAtoms::result, kNameSpaceID_None, true },
- { &nsGkAtoms::in, kNameSpaceID_None, true }
- };
- nsSVGElement::NumberListInfo SVGFEConvolveMatrixElement::sNumberListInfo[1] =
- {
- { &nsGkAtoms::kernelMatrix }
- };
- //----------------------------------------------------------------------
- // nsIDOMNode methods
- NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEConvolveMatrixElement)
- //----------------------------------------------------------------------
- already_AddRefed<SVGAnimatedString>
- SVGFEConvolveMatrixElement::In1()
- {
- return mStringAttributes[IN1].ToDOMAnimatedString(this);
- }
- already_AddRefed<SVGAnimatedInteger>
- SVGFEConvolveMatrixElement::OrderX()
- {
- return mIntegerPairAttributes[ORDER].ToDOMAnimatedInteger(nsSVGIntegerPair::eFirst, this);
- }
- already_AddRefed<SVGAnimatedInteger>
- SVGFEConvolveMatrixElement::OrderY()
- {
- return mIntegerPairAttributes[ORDER].ToDOMAnimatedInteger(nsSVGIntegerPair::eSecond, this);
- }
- already_AddRefed<DOMSVGAnimatedNumberList>
- SVGFEConvolveMatrixElement::KernelMatrix()
- {
- return DOMSVGAnimatedNumberList::GetDOMWrapper(&mNumberListAttributes[KERNELMATRIX],
- this, KERNELMATRIX);
- }
- already_AddRefed<SVGAnimatedInteger>
- SVGFEConvolveMatrixElement::TargetX()
- {
- return mIntegerAttributes[TARGET_X].ToDOMAnimatedInteger(this);
- }
- already_AddRefed<SVGAnimatedInteger>
- SVGFEConvolveMatrixElement::TargetY()
- {
- return mIntegerAttributes[TARGET_Y].ToDOMAnimatedInteger(this);
- }
- already_AddRefed<SVGAnimatedEnumeration>
- SVGFEConvolveMatrixElement::EdgeMode()
- {
- return mEnumAttributes[EDGEMODE].ToDOMAnimatedEnum(this);
- }
- already_AddRefed<SVGAnimatedBoolean>
- SVGFEConvolveMatrixElement::PreserveAlpha()
- {
- return mBooleanAttributes[PRESERVEALPHA].ToDOMAnimatedBoolean(this);
- }
- already_AddRefed<SVGAnimatedNumber>
- SVGFEConvolveMatrixElement::Divisor()
- {
- return mNumberAttributes[DIVISOR].ToDOMAnimatedNumber(this);
- }
- already_AddRefed<SVGAnimatedNumber>
- SVGFEConvolveMatrixElement::Bias()
- {
- return mNumberAttributes[BIAS].ToDOMAnimatedNumber(this);
- }
- already_AddRefed<SVGAnimatedNumber>
- SVGFEConvolveMatrixElement::KernelUnitLengthX()
- {
- return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(nsSVGNumberPair::eFirst,
- this);
- }
- already_AddRefed<SVGAnimatedNumber>
- SVGFEConvolveMatrixElement::KernelUnitLengthY()
- {
- return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(nsSVGNumberPair::eSecond,
- this);
- }
- void
- SVGFEConvolveMatrixElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
- {
- aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
- }
- FilterPrimitiveDescription
- SVGFEConvolveMatrixElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
- const IntRect& aFilterSubregion,
- const nsTArray<bool>& aInputsAreTainted,
- nsTArray<RefPtr<SourceSurface>>& aInputImages)
- {
- const FilterPrimitiveDescription failureDescription(PrimitiveType::Empty);
- const SVGNumberList &kernelMatrix =
- mNumberListAttributes[KERNELMATRIX].GetAnimValue();
- uint32_t kmLength = kernelMatrix.Length();
- int32_t orderX = mIntegerPairAttributes[ORDER].GetAnimValue(nsSVGIntegerPair::eFirst);
- int32_t orderY = mIntegerPairAttributes[ORDER].GetAnimValue(nsSVGIntegerPair::eSecond);
- if (orderX <= 0 || orderY <= 0 ||
- static_cast<uint32_t>(orderX * orderY) != kmLength) {
- return failureDescription;
- }
- int32_t targetX, targetY;
- GetAnimatedIntegerValues(&targetX, &targetY, nullptr);
- if (mIntegerAttributes[TARGET_X].IsExplicitlySet()) {
- if (targetX < 0 || targetX >= orderX)
- return failureDescription;
- } else {
- targetX = orderX / 2;
- }
- if (mIntegerAttributes[TARGET_Y].IsExplicitlySet()) {
- if (targetY < 0 || targetY >= orderY)
- return failureDescription;
- } else {
- targetY = orderY / 2;
- }
- if (orderX > NS_SVG_OFFSCREEN_MAX_DIMENSION ||
- orderY > NS_SVG_OFFSCREEN_MAX_DIMENSION)
- return failureDescription;
- UniquePtr<float[]> kernel = MakeUniqueFallible<float[]>(orderX * orderY);
- if (!kernel)
- return failureDescription;
- for (uint32_t i = 0; i < kmLength; i++) {
- kernel[kmLength - 1 - i] = kernelMatrix[i];
- }
- float divisor;
- if (mNumberAttributes[DIVISOR].IsExplicitlySet()) {
- divisor = mNumberAttributes[DIVISOR].GetAnimValue();
- if (divisor == 0)
- return failureDescription;
- } else {
- divisor = kernel[0];
- for (uint32_t i = 1; i < kmLength; i++)
- divisor += kernel[i];
- if (divisor == 0)
- divisor = 1;
- }
- uint32_t edgeMode = mEnumAttributes[EDGEMODE].GetAnimValue();
- bool preserveAlpha = mBooleanAttributes[PRESERVEALPHA].GetAnimValue();
- float bias = mNumberAttributes[BIAS].GetAnimValue();
- Size kernelUnitLength =
- GetKernelUnitLength(aInstance, &mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
- if (kernelUnitLength.width <= 0 || kernelUnitLength.height <= 0) {
- // According to spec, A negative or zero value is an error. See link below for details.
- // https://www.w3.org/TR/SVG/filters.html#feConvolveMatrixElementKernelUnitLengthAttribute
- return failureDescription;
- }
- FilterPrimitiveDescription descr(PrimitiveType::ConvolveMatrix);
- AttributeMap& atts = descr.Attributes();
- atts.Set(eConvolveMatrixKernelSize, IntSize(orderX, orderY));
- atts.Set(eConvolveMatrixKernelMatrix, &kernelMatrix[0], kmLength);
- atts.Set(eConvolveMatrixDivisor, divisor);
- atts.Set(eConvolveMatrixBias, bias);
- atts.Set(eConvolveMatrixTarget, IntPoint(targetX, targetY));
- atts.Set(eConvolveMatrixEdgeMode, edgeMode);
- atts.Set(eConvolveMatrixKernelUnitLength, kernelUnitLength);
- atts.Set(eConvolveMatrixPreserveAlpha, preserveAlpha);
- return descr;
- }
- bool
- SVGFEConvolveMatrixElement::AttributeAffectsRendering(int32_t aNameSpaceID,
- nsIAtom* aAttribute) const
- {
- return SVGFEConvolveMatrixElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
- (aNameSpaceID == kNameSpaceID_None &&
- (aAttribute == nsGkAtoms::in ||
- aAttribute == nsGkAtoms::divisor ||
- aAttribute == nsGkAtoms::bias ||
- aAttribute == nsGkAtoms::kernelUnitLength ||
- aAttribute == nsGkAtoms::targetX ||
- aAttribute == nsGkAtoms::targetY ||
- aAttribute == nsGkAtoms::order ||
- aAttribute == nsGkAtoms::preserveAlpha||
- aAttribute == nsGkAtoms::edgeMode ||
- aAttribute == nsGkAtoms::kernelMatrix));
- }
- //----------------------------------------------------------------------
- // nsSVGElement methods
- nsSVGElement::NumberAttributesInfo
- SVGFEConvolveMatrixElement::GetNumberInfo()
- {
- return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
- ArrayLength(sNumberInfo));
- }
- nsSVGElement::NumberPairAttributesInfo
- SVGFEConvolveMatrixElement::GetNumberPairInfo()
- {
- return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
- ArrayLength(sNumberPairInfo));
- }
- nsSVGElement::IntegerAttributesInfo
- SVGFEConvolveMatrixElement::GetIntegerInfo()
- {
- return IntegerAttributesInfo(mIntegerAttributes, sIntegerInfo,
- ArrayLength(sIntegerInfo));
- }
- nsSVGElement::IntegerPairAttributesInfo
- SVGFEConvolveMatrixElement::GetIntegerPairInfo()
- {
- return IntegerPairAttributesInfo(mIntegerPairAttributes, sIntegerPairInfo,
- ArrayLength(sIntegerPairInfo));
- }
- nsSVGElement::BooleanAttributesInfo
- SVGFEConvolveMatrixElement::GetBooleanInfo()
- {
- return BooleanAttributesInfo(mBooleanAttributes, sBooleanInfo,
- ArrayLength(sBooleanInfo));
- }
- nsSVGElement::EnumAttributesInfo
- SVGFEConvolveMatrixElement::GetEnumInfo()
- {
- return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
- ArrayLength(sEnumInfo));
- }
- nsSVGElement::StringAttributesInfo
- SVGFEConvolveMatrixElement::GetStringInfo()
- {
- return StringAttributesInfo(mStringAttributes, sStringInfo,
- ArrayLength(sStringInfo));
- }
- nsSVGElement::NumberListAttributesInfo
- SVGFEConvolveMatrixElement::GetNumberListInfo()
- {
- return NumberListAttributesInfo(mNumberListAttributes, sNumberListInfo,
- ArrayLength(sNumberListInfo));
- }
- } // namespace dom
- } // namespace mozilla
|