SVGFEMorphologyElement.cpp (5404B)
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/SVGFEMorphologyElement.h" 8 9 #include "mozilla/SVGFilterInstance.h" 10 #include "mozilla/dom/BindContext.h" 11 #include "mozilla/dom/Document.h" 12 #include "mozilla/dom/SVGFEMorphologyElementBinding.h" 13 14 NS_IMPL_NS_NEW_SVG_ELEMENT(FEMorphology) 15 16 using namespace mozilla::gfx; 17 18 namespace mozilla::dom { 19 20 JSObject* SVGFEMorphologyElement::WrapNode(JSContext* aCx, 21 JS::Handle<JSObject*> aGivenProto) { 22 return SVGFEMorphologyElement_Binding::Wrap(aCx, this, aGivenProto); 23 } 24 25 SVGElement::NumberPairInfo SVGFEMorphologyElement::sNumberPairInfo[1] = { 26 {nsGkAtoms::radius, 0, 0}}; 27 28 SVGEnumMapping SVGFEMorphologyElement::sOperatorMap[] = { 29 {nsGkAtoms::erode, SVG_OPERATOR_ERODE}, 30 {nsGkAtoms::dilate, SVG_OPERATOR_DILATE}, 31 {nullptr, 0}}; 32 33 SVGElement::EnumInfo SVGFEMorphologyElement::sEnumInfo[1] = { 34 {nsGkAtoms::_operator, sOperatorMap, SVG_OPERATOR_ERODE}}; 35 36 SVGElement::StringInfo SVGFEMorphologyElement::sStringInfo[2] = { 37 {nsGkAtoms::result, kNameSpaceID_None, true}, 38 {nsGkAtoms::in, kNameSpaceID_None, true}}; 39 40 //---------------------------------------------------------------------- 41 // nsINode methods 42 43 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEMorphologyElement) 44 45 //---------------------------------------------------------------------- 46 // SVGFEMorphologyElement methods 47 48 already_AddRefed<DOMSVGAnimatedString> SVGFEMorphologyElement::In1() { 49 return mStringAttributes[IN1].ToDOMAnimatedString(this); 50 } 51 52 already_AddRefed<DOMSVGAnimatedEnumeration> SVGFEMorphologyElement::Operator() { 53 return mEnumAttributes[OPERATOR].ToDOMAnimatedEnum(this); 54 } 55 56 already_AddRefed<DOMSVGAnimatedNumber> SVGFEMorphologyElement::RadiusX() { 57 return mNumberPairAttributes[RADIUS].ToDOMAnimatedNumber( 58 SVGAnimatedNumberPair::eFirst, this); 59 } 60 61 already_AddRefed<DOMSVGAnimatedNumber> SVGFEMorphologyElement::RadiusY() { 62 return mNumberPairAttributes[RADIUS].ToDOMAnimatedNumber( 63 SVGAnimatedNumberPair::eSecond, this); 64 } 65 66 void SVGFEMorphologyElement::SetRadius(float rx, float ry) { 67 mNumberPairAttributes[RADIUS].SetBaseValues(rx, ry, this); 68 } 69 70 void SVGFEMorphologyElement::GetSourceImageNames( 71 nsTArray<SVGStringInfo>& aSources) { 72 aSources.AppendElement(SVGStringInfo(&mStringAttributes[IN1], this)); 73 } 74 75 #define MORPHOLOGY_EPSILON 0.0001 76 77 void SVGFEMorphologyElement::GetRXY(int32_t* aRX, int32_t* aRY, 78 const SVGFilterInstance& aInstance) { 79 // Subtract an epsilon here because we don't want a value that's just 80 // slightly larger than an integer to round up to the next integer; it's 81 // probably meant to be the integer it's close to, modulo machine precision 82 // issues. 83 *aRX = NSToIntCeil(aInstance.GetPrimitiveNumber( 84 SVGContentUtils::X, &mNumberPairAttributes[RADIUS], 85 SVGAnimatedNumberPair::eFirst) - 86 MORPHOLOGY_EPSILON); 87 *aRY = NSToIntCeil(aInstance.GetPrimitiveNumber( 88 SVGContentUtils::Y, &mNumberPairAttributes[RADIUS], 89 SVGAnimatedNumberPair::eSecond) - 90 MORPHOLOGY_EPSILON); 91 } 92 93 FilterPrimitiveDescription SVGFEMorphologyElement::GetPrimitiveDescription( 94 SVGFilterInstance* aInstance, const IntRect& aFilterSubregion, 95 const nsTArray<bool>& aInputsAreTainted, 96 nsTArray<RefPtr<SourceSurface>>& aInputImages) { 97 int32_t rx, ry; 98 GetRXY(&rx, &ry, *aInstance); 99 MorphologyAttributes atts; 100 atts.mRadii = Size(rx, ry); 101 atts.mOperator = (uint32_t)mEnumAttributes[OPERATOR].GetAnimValue(); 102 return FilterPrimitiveDescription(AsVariant(std::move(atts))); 103 } 104 105 bool SVGFEMorphologyElement::AttributeAffectsRendering( 106 int32_t aNameSpaceID, nsAtom* aAttribute) const { 107 return SVGFEMorphologyElementBase::AttributeAffectsRendering(aNameSpaceID, 108 aAttribute) || 109 (aNameSpaceID == kNameSpaceID_None && 110 (aAttribute == nsGkAtoms::in || aAttribute == nsGkAtoms::radius || 111 aAttribute == nsGkAtoms::_operator)); 112 } 113 114 nsresult SVGFEMorphologyElement::BindToTree(BindContext& aCtx, 115 nsINode& aParent) { 116 if (aCtx.InComposedDoc()) { 117 aCtx.OwnerDoc().SetUseCounter(eUseCounter_custom_feMorphology); 118 } 119 120 return SVGFEMorphologyElementBase::BindToTree(aCtx, aParent); 121 } 122 123 //---------------------------------------------------------------------- 124 // SVGElement methods 125 126 SVGElement::NumberPairAttributesInfo 127 SVGFEMorphologyElement::GetNumberPairInfo() { 128 return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo, 129 std::size(sNumberPairInfo)); 130 } 131 132 SVGElement::EnumAttributesInfo SVGFEMorphologyElement::GetEnumInfo() { 133 return EnumAttributesInfo(mEnumAttributes, sEnumInfo, std::size(sEnumInfo)); 134 } 135 136 SVGElement::StringAttributesInfo SVGFEMorphologyElement::GetStringInfo() { 137 return StringAttributesInfo(mStringAttributes, sStringInfo, 138 std::size(sStringInfo)); 139 } 140 141 } // namespace mozilla::dom