SVGFEDisplacementMapElement.cpp (5283B)
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/dom/SVGFEDisplacementMapElement.h" 8 9 #include "mozilla/SVGFilterInstance.h" 10 #include "mozilla/dom/BindContext.h" 11 #include "mozilla/dom/Document.h" 12 #include "mozilla/dom/SVGFEDisplacementMapElementBinding.h" 13 14 NS_IMPL_NS_NEW_SVG_ELEMENT(FEDisplacementMap) 15 16 using namespace mozilla::gfx; 17 18 namespace mozilla::dom { 19 20 JSObject* SVGFEDisplacementMapElement::WrapNode( 21 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { 22 return SVGFEDisplacementMapElement_Binding::Wrap(aCx, this, aGivenProto); 23 } 24 25 SVGElement::NumberInfo SVGFEDisplacementMapElement::sNumberInfo[1] = { 26 {nsGkAtoms::scale, 0}, 27 }; 28 29 SVGEnumMapping SVGFEDisplacementMapElement::sChannelMap[] = { 30 {nsGkAtoms::R, SVG_CHANNEL_R}, 31 {nsGkAtoms::G, SVG_CHANNEL_G}, 32 {nsGkAtoms::B, SVG_CHANNEL_B}, 33 {nsGkAtoms::A, SVG_CHANNEL_A}, 34 {nullptr, 0}}; 35 36 SVGElement::EnumInfo SVGFEDisplacementMapElement::sEnumInfo[2] = { 37 {nsGkAtoms::xChannelSelector, sChannelMap, SVG_CHANNEL_A}, 38 {nsGkAtoms::yChannelSelector, sChannelMap, SVG_CHANNEL_A}}; 39 40 SVGElement::StringInfo SVGFEDisplacementMapElement::sStringInfo[3] = { 41 {nsGkAtoms::result, kNameSpaceID_None, true}, 42 {nsGkAtoms::in, kNameSpaceID_None, true}, 43 {nsGkAtoms::in2, kNameSpaceID_None, true}}; 44 45 //---------------------------------------------------------------------- 46 // nsINode methods 47 48 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEDisplacementMapElement) 49 50 //---------------------------------------------------------------------- 51 52 already_AddRefed<DOMSVGAnimatedString> SVGFEDisplacementMapElement::In1() { 53 return mStringAttributes[IN1].ToDOMAnimatedString(this); 54 } 55 56 already_AddRefed<DOMSVGAnimatedString> SVGFEDisplacementMapElement::In2() { 57 return mStringAttributes[IN2].ToDOMAnimatedString(this); 58 } 59 60 already_AddRefed<DOMSVGAnimatedNumber> SVGFEDisplacementMapElement::Scale() { 61 return mNumberAttributes[SCALE].ToDOMAnimatedNumber(this); 62 } 63 64 already_AddRefed<DOMSVGAnimatedEnumeration> 65 SVGFEDisplacementMapElement::XChannelSelector() { 66 return mEnumAttributes[CHANNEL_X].ToDOMAnimatedEnum(this); 67 } 68 69 already_AddRefed<DOMSVGAnimatedEnumeration> 70 SVGFEDisplacementMapElement::YChannelSelector() { 71 return mEnumAttributes[CHANNEL_Y].ToDOMAnimatedEnum(this); 72 } 73 74 FilterPrimitiveDescription SVGFEDisplacementMapElement::GetPrimitiveDescription( 75 SVGFilterInstance* aInstance, const IntRect& aFilterSubregion, 76 const nsTArray<bool>& aInputsAreTainted, 77 nsTArray<RefPtr<SourceSurface>>& aInputImages) { 78 if (aInputsAreTainted[1]) { 79 // If the map is tainted, refuse to apply the effect and act as a 80 // pass-through filter instead, as required by the spec. 81 OffsetAttributes atts; 82 atts.mValue = IntPoint(0, 0); 83 return FilterPrimitiveDescription(AsVariant(std::move(atts))); 84 } 85 86 float scale = aInstance->GetPrimitiveNumber(SVGContentUtils::XY, 87 &mNumberAttributes[SCALE]); 88 uint32_t xChannel = mEnumAttributes[CHANNEL_X].GetAnimValue(); 89 uint32_t yChannel = mEnumAttributes[CHANNEL_Y].GetAnimValue(); 90 DisplacementMapAttributes atts; 91 atts.mScale = scale; 92 atts.mXChannel = xChannel; 93 atts.mYChannel = yChannel; 94 return FilterPrimitiveDescription(AsVariant(std::move(atts))); 95 } 96 97 bool SVGFEDisplacementMapElement::AttributeAffectsRendering( 98 int32_t aNameSpaceID, nsAtom* aAttribute) const { 99 return SVGFEDisplacementMapElementBase::AttributeAffectsRendering( 100 aNameSpaceID, aAttribute) || 101 (aNameSpaceID == kNameSpaceID_None && 102 (aAttribute == nsGkAtoms::in || aAttribute == nsGkAtoms::in2 || 103 aAttribute == nsGkAtoms::scale || 104 aAttribute == nsGkAtoms::xChannelSelector || 105 aAttribute == nsGkAtoms::yChannelSelector)); 106 } 107 108 void SVGFEDisplacementMapElement::GetSourceImageNames( 109 nsTArray<SVGStringInfo>& aSources) { 110 aSources.AppendElement(SVGStringInfo(&mStringAttributes[IN1], this)); 111 aSources.AppendElement(SVGStringInfo(&mStringAttributes[IN2], this)); 112 } 113 114 nsresult SVGFEDisplacementMapElement::BindToTree(BindContext& aCtx, 115 nsINode& aParent) { 116 if (aCtx.InComposedDoc()) { 117 aCtx.OwnerDoc().SetUseCounter(eUseCounter_custom_feDisplacementMap); 118 } 119 120 return SVGFEDisplacementMapElementBase::BindToTree(aCtx, aParent); 121 } 122 123 //---------------------------------------------------------------------- 124 // SVGElement methods 125 126 SVGElement::NumberAttributesInfo SVGFEDisplacementMapElement::GetNumberInfo() { 127 return NumberAttributesInfo(mNumberAttributes, sNumberInfo, 128 std::size(sNumberInfo)); 129 } 130 131 SVGElement::EnumAttributesInfo SVGFEDisplacementMapElement::GetEnumInfo() { 132 return EnumAttributesInfo(mEnumAttributes, sEnumInfo, std::size(sEnumInfo)); 133 } 134 135 SVGElement::StringAttributesInfo SVGFEDisplacementMapElement::GetStringInfo() { 136 return StringAttributesInfo(mStringAttributes, sStringInfo, 137 std::size(sStringInfo)); 138 } 139 140 } // namespace mozilla::dom